bool ScriptController::processingUserGesture(DOMWrapperWorld*) const { Frame* activeFrame = V8Proxy::retrieveFrameForEnteredContext(); // No script is running, so it is user-initiated unless the gesture stack // explicitly says it is not. if (!activeFrame) return UserGestureIndicator::getUserGestureState() != DefinitelyNotProcessingUserGesture; V8Proxy* activeProxy = activeFrame->script()->proxy(); v8::HandleScope handleScope; v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(activeFrame); // FIXME: find all cases context can be empty: // 1) JS is disabled; // 2) page is NULL; if (v8Context.IsEmpty()) return true; v8::Context::Scope scope(v8Context); v8::Handle<v8::Object> global = v8Context->Global(); v8::Handle<v8::Value> jsEvent = global->Get(v8::String::NewSymbol("event")); Event* event = V8DOMWrapper::isValidDOMObject(jsEvent) ? V8Event::toNative(v8::Handle<v8::Object>::Cast(jsEvent)) : 0; // Based on code from kjs_bindings.cpp. // Note: This is more liberal than Firefox's implementation. if (event) { if (!UserGestureIndicator::processingUserGesture()) return false; const AtomicString& type = event->type(); bool eventOk = // mouse events type == eventNames().clickEvent || type == eventNames().mousedownEvent || type == eventNames().mouseupEvent || type == eventNames().dblclickEvent // keyboard events || type == eventNames().keydownEvent || type == eventNames().keypressEvent || type == eventNames().keyupEvent // other accepted events || type == eventNames().selectEvent || type == eventNames().changeEvent || type == eventNames().focusEvent || type == eventNames().blurEvent || type == eventNames().submitEvent; if (eventOk) return true; } else if (m_sourceURL && m_sourceURL->isNull() && !activeProxy->timerCallback()) { // This is the <a href="javascript:window.open('...')> case -> we let it through. return true; } // This is the <script>window.open(...)</script> case or a timer callback -> block it. return false; }
bool ScriptController::processingUserGesture() const { Frame* activeFrame = V8Proxy::retrieveFrameForEnteredContext(); // No script is running, so it must be run by users. if (!activeFrame) return true; V8Proxy* activeProxy = activeFrame->script()->proxy(); v8::HandleScope handleScope; v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(activeFrame); // FIXME: find all cases context can be empty: // 1) JS is disabled; // 2) page is NULL; if (v8Context.IsEmpty()) return true; v8::Context::Scope scope(v8Context); v8::Handle<v8::Object> global = v8Context->Global(); v8::Handle<v8::Value> jsEvent = global->Get(v8::String::NewSymbol("event")); Event* event = V8DOMWrapper::convertToNativeEvent(jsEvent); // Based on code from kjs_bindings.cpp. // Note: This is more liberal than Firefox's implementation. if (event) { if (event->createdByDOM()) return false; const AtomicString& type = event->type(); bool eventOk = // mouse events type == eventNames().clickEvent || type == eventNames().mousedownEvent || type == eventNames().mouseupEvent || type == eventNames().dblclickEvent // keyboard events || type == eventNames().keydownEvent || type == eventNames().keypressEvent || type == eventNames().keyupEvent // other accepted events || type == eventNames().selectEvent || type == eventNames().changeEvent || type == eventNames().focusEvent || type == eventNames().blurEvent || type == eventNames().submitEvent; if (eventOk) return true; } else if (activeProxy->inlineCode() && !activeProxy->timerCallback()) { // This is the <a href="javascript:window.open('...')> case -> we let it through. return true; } // This is the <script>window.open(...)</script> case or a timer callback -> block it. return false; }
bool ScriptController::processingUserGesture() { Frame* activeFrame = V8Proxy::retrieveFrameForEnteredContext(); // No script is running, so it is user-initiated unless the gesture stack // explicitly says it is not. if (!activeFrame) return UserGestureIndicator::getUserGestureState() != DefinitelyNotProcessingUserGesture; V8Proxy* activeProxy = activeFrame->script().proxy(); v8::HandleScope handleScope; v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(activeFrame); // FIXME: find all cases context can be empty: // 1) JS is disabled; // 2) page is NULL; if (v8Context.IsEmpty()) return true; v8::Context::Scope scope(v8Context); v8::Handle<v8::Object> global = v8Context->Global(); v8::Handle<v8::String> eventSymbol = V8HiddenPropertyName::event(); v8::Handle<v8::Value> jsEvent = global->GetHiddenValue(eventSymbol); Event* event = V8DOMWrapper::isValidDOMObject(jsEvent) ? V8Event::toNative(v8::Handle<v8::Object>::Cast(jsEvent)) : 0; // Based on code from JSC's ScriptController::processingUserGesture. // Note: This is more liberal than Firefox's implementation. if (event) { // Event::fromUserGesture will return false when UserGestureIndicator::processingUserGesture() returns false. return event->fromUserGesture(); } // FIXME: We check the javascript anchor navigation from the last entered // frame becuase it should only be initiated on the last entered frame in // which execution began if it does happen. const String* sourceURL = activeFrame->script().sourceURL(); if (sourceURL && sourceURL->isNull() && !activeProxy->timerCallback()) { // This is the <a href="javascript:window.open('...')> case -> we let it through. return true; } if (activeFrame->script().allowPopupsFromPlugin()) return true; // This is the <script>window.open(...)</script> case or a timer callback -> block it. // Based on JSC version, use returned value of UserGestureIndicator::processingUserGesture for all other situations. return UserGestureIndicator::processingUserGesture(); }