bool ScriptController::processingUserGesture(DOMWrapperWorld*) 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 = (!jsEvent.IsEmpty() && jsEvent->IsObject()) ? 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 (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; }