void JSDOMWindow::setLocation(ExecState* exec, JSValue value)
{
    Frame* lexicalFrame = toLexicalFrame(exec);
    if (!lexicalFrame)
        return;

#if ENABLE(DASHBOARD_SUPPORT)
    // To avoid breaking old widgets, make "var location =" in a top-level frame create
    // a property named "location" instead of performing a navigation (<rdar://problem/5688039>).
    if (Settings* settings = lexicalFrame->settings()) {
        if (settings->usesDashboardBackwardCompatibilityMode() && !lexicalFrame->tree()->parent()) {
            if (allowsAccessFrom(exec))
                putDirect(Identifier(exec, "location"), value);
            return;
        }
    }
#endif

    Frame* frame = impl()->frame();
    ASSERT(frame);

    KURL url = completeURL(exec, ustringToString(value.toString(exec)));
    if (url.isNull())
        return;

    if (!shouldAllowNavigation(exec, frame))
        return;

    if (!protocolIsJavaScript(url) || allowsAccessFrom(exec)) {
        // We want a new history item if this JS was called via a user gesture
        frame->redirectScheduler()->scheduleLocationChange(url, lexicalFrame->loader()->outgoingReferrer(), !lexicalFrame->script()->anyPageIsProcessingUserGesture(), false, processingUserGesture());
    }
}
void JSLocation::setHref(ExecState* exec, JSValue value)
{
    Frame* frame = impl()->frame();
    ASSERT(frame);

    KURL url = completeURL(exec, value.toString(exec));
    if (url.isNull())
        return;

    if (!shouldAllowNavigation(exec, frame))
        return;

    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
}
void V8DOMWindowShell::setLocation(DOMWindow* window, const String& relativeURL)
{
    Frame* frame = window->frame();
    if (!frame)
        return;

    KURL url = completeURL(relativeURL);
    if (url.isNull())
        return;

    if (!shouldAllowNavigation(frame))
        return;

    navigateIfAllowed(frame, url, false, false);
}
JSValue JSLocation::replace(ExecState* exec, const ArgList& args)
{
    Frame* frame = impl()->frame();
    if (!frame)
        return jsUndefined();

    KURL url = completeURL(exec, args.at(0).toString(exec));
    if (url.isNull())
        return jsUndefined();

    if (!shouldAllowNavigation(exec, frame))
        return jsUndefined();

    navigateIfAllowed(exec, frame, url, true, true);
    return jsUndefined();
}
JSValue JSLocation::assign(ExecState* exec, const ArgList& args)
{
    Frame* frame = impl()->frame();
    if (!frame)
        return jsUndefined();

    KURL url = completeURL(exec, args.at(0).toString(exec));
    if (url.isNull())
        return jsUndefined();

    if (!shouldAllowNavigation(exec, frame))
        return jsUndefined();

    // We want a new history item if this JS was called via a user gesture
    navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
    return jsUndefined();
}
void V8Location::hrefAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
{
    INC_STATS("DOM.Location.href._set");
    v8::Handle<v8::Object> holder = info.Holder();
    Location* imp = V8Location::toNative(holder);

    Frame* frame = imp->frame();
    if (!frame)
        return;

    KURL url = completeURL(toWebCoreString(value));
    if (url.isNull())
        return;

    if (!shouldAllowNavigation(frame))
        return;

    navigateIfAllowed(frame, url, false, false);
}
v8::Handle<v8::Value> V8Location::assignCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.Location.assign");
    v8::Handle<v8::Object> holder = args.Holder();
    Location* imp = V8Location::toNative(holder);

    Frame* frame = imp->frame();
    if (!frame)
        return v8::Undefined();

    KURL url = completeURL(toWebCoreString(args[0]));
    if (url.isNull())
        return v8::Undefined();

    if (!shouldAllowNavigation(frame))
        return v8::Undefined();

    navigateIfAllowed(frame, url, false, false);
    return v8::Undefined();
}
JSValue JSDOMWindow::open(ExecState* exec)
{
    String urlString = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0));
    AtomicString frameName = exec->argument(1).isUndefinedOrNull() ? "_blank" : ustringToAtomicString(exec->argument(1).toString(exec));
    WindowFeatures windowFeatures(valueToStringWithUndefinedOrNullCheck(exec, exec->argument(2)));

    Frame* frame = impl()->frame();
    if (!frame)
        return jsUndefined();
    Frame* lexicalFrame = toLexicalFrame(exec);
    if (!lexicalFrame)
        return jsUndefined();
    Frame* dynamicFrame = toDynamicFrame(exec);
    if (!dynamicFrame)
        return jsUndefined();

    Page* page = frame->page();

    // Because FrameTree::find() returns true for empty strings, we must check for empty framenames.
    // Otherwise, illegitimate window.open() calls with no name will pass right through the popup blocker.
    if (!domWindowAllowPopUp(dynamicFrame) && (frameName.isEmpty() || !frame->tree()->find(frameName)))
        return jsUndefined();

    // Get the target frame for the special cases of _top and _parent.  In those
    // cases, we can schedule a location change right now and return early.
    bool topOrParent = false;
    if (frameName == "_top") {
        frame = frame->tree()->top();
        topOrParent = true;
    } else if (frameName == "_parent") {
        if (Frame* parent = frame->tree()->parent())
            frame = parent;
        topOrParent = true;
    }
    if (topOrParent) {
        String completedURL;
        if (!urlString.isEmpty())
            completedURL = completeURL(exec, urlString).string();

        if (!shouldAllowNavigation(exec, frame))
            return jsUndefined();

        const JSDOMWindow* targetedWindow = toJSDOMWindow(frame, currentWorld(exec));
        if (!completedURL.isEmpty() && (!protocolIsJavaScript(completedURL) || (targetedWindow && targetedWindow->allowsAccessFrom(exec)))) {
            bool userGesture = processingUserGesture();

            // For whatever reason, Firefox uses the dynamicGlobalObject to
            // determine the outgoingReferrer.  We replicate that behavior
            // here.
            String referrer = dynamicFrame->loader()->outgoingReferrer();

            frame->redirectScheduler()->scheduleLocationChange(completedURL, referrer, !lexicalFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture);
        }
        return toJS(exec, frame->domWindow());
    }

    // In the case of a named frame or a new window, we'll use the createWindow() helper
    FloatRect windowRect(windowFeatures.xSet ? windowFeatures.x : 0, windowFeatures.ySet ? windowFeatures.y : 0,
                         windowFeatures.widthSet ? windowFeatures.width : 0, windowFeatures.heightSet ? windowFeatures.height : 0);
    DOMWindow::adjustWindowRect(screenAvailableRect(page ? page->mainFrame()->view() : 0), windowRect, windowRect);

    windowFeatures.x = windowRect.x();
    windowFeatures.y = windowRect.y();
    windowFeatures.height = windowRect.height();
    windowFeatures.width = windowRect.width();

    frame = createWindow(exec, lexicalFrame, dynamicFrame, frame, urlString, frameName, windowFeatures, JSValue());

    if (!frame)
        return jsUndefined();

    return toJS(exec, frame->domWindow());
}