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;
}