[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-10851-g50815da

darin at apple.com darin at apple.com
Wed Dec 22 18:27:18 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 341ee6419ff9f9d25fe635f3c31db90d261b31fe
Author: darin at apple.com <darin at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Sat Dec 11 02:20:00 2010 +0000

    2010-12-10  Darin Adler  <darin at apple.com>
    
            Reviewed by Sam Weinig.
    
            Move open and showModalDialog implementations from bindings into DOM class DOMWindow
            https://bugs.webkit.org/show_bug.cgi?id=50836
    
            * bindings/js/JSDOMWindowCustom.cpp:
            (WebCore::JSDOMWindow::open): Removed most of the code and changed to call
            DOMWindow::open.
            (WebCore::DialogHandler::DialogHandler): Added. Object is used to handle the
            arguments and return value in showModalDialog.
            (WebCore::DialogHandler::dialogCreated): Ditto.
            (WebCore::DialogHandler::returnValue): Ditto.
            (WebCore::setUpDialog): Added. Function passed to showModalDialog that just
            casts pointer to DialogHandler can calls dialogCreated.
            (WebCore::JSDOMWindow::showModalDialog): Removed most of the code and changed
            to call DOMWindow::showModalDialog.
            (WebCore::JSDOMWindow::postMessage): Made style match the rest of the file by
            renaming local variables and getting rid of a needless ones.
    
            * page/DOMWindow.cpp:
            (WebCore::DOMWindow::parseModalDialogFeatures): Moved body of this function
            to the WindowFeatures class.
            (WebCore::DOMWindow::allowPopUp): Renamed argument from activeFrame to firstFrame,
            because that's the frame we pass in here. Also added an overload so this can be
            called on a window rather than a frame.
            (WebCore::DOMWindow::setLocation): Renamed a couple variables so the names are
            the same as in open and showModalDialog. Factored the JavaScript security check
            into a new function named isInsecureScriptAccess.
            (WebCore::DOMWindow::isInsecureScriptAccess): Here is the new function.
            (WebCore::DOMWindow::createWindow): Added. Contains logic shared by open and
            showModalDialog just as the function named createWindow in JSDOMWindowCustom.cpp
            used to.
            (WebCore::DOMWindow::open): Added. Code from JSDOMWindowCustom without the
            JavaScript language binding part, and with a bit of refactoring to share code
            with the rest of the DOMWindow class.
            (WebCore::DOMWindow::showModalDialog): Ditto.
    
            * page/DOMWindow.h: Moved conditional parts of the file into separate paragraphs
            in alphabetical order so they are not scattered thorugh the file. Removed redundant
            includes. Added some blank lines for clarity. Added an open function and a
            showModalDialog function. Added private createWindow and isInsecureScriptAccess
            functions.
    
            * page/WindowFeatures.cpp:
            (WebCore::isWindowFeaturesSeparator): Renamed from isSeparator for clarity.
            (WebCore::WindowFeatures::WindowFeatures): Updated for name change. Used isEmpty
            instead of checking length. Added a new constructor for use when making dialogs,
            with code from the showModalDialog function.
            (WebCore::WindowFeatures::boolFeature): Use DialogFeaturesMap typedef.
            (WebCore::WindowFeatures::floatFeature): Use DialogFeaturesMap typedef.
            Renamed a local variable and tweaked the comments a bit.
            (WebCore::WindowFeatures::parseDialogFeatures): Added. Code moved here from
            DOMWindow::parseDialogFeatures and refactored a bit.
    
            * page/WindowFeatures.h: Added new constructor, new parseDialogFeatures
            function, DialogFeaturesMap typedef, and made setWindowFeature function private.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@73829 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 9019ff9..633d6df 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,62 @@
+2010-12-10  Darin Adler  <darin at apple.com>
+
+        Reviewed by Sam Weinig.
+
+        Move open and showModalDialog implementations from bindings into DOM class DOMWindow
+        https://bugs.webkit.org/show_bug.cgi?id=50836
+
+        * bindings/js/JSDOMWindowCustom.cpp:
+        (WebCore::JSDOMWindow::open): Removed most of the code and changed to call
+        DOMWindow::open.
+        (WebCore::DialogHandler::DialogHandler): Added. Object is used to handle the
+        arguments and return value in showModalDialog.
+        (WebCore::DialogHandler::dialogCreated): Ditto.
+        (WebCore::DialogHandler::returnValue): Ditto.
+        (WebCore::setUpDialog): Added. Function passed to showModalDialog that just
+        casts pointer to DialogHandler can calls dialogCreated.
+        (WebCore::JSDOMWindow::showModalDialog): Removed most of the code and changed
+        to call DOMWindow::showModalDialog.
+        (WebCore::JSDOMWindow::postMessage): Made style match the rest of the file by
+        renaming local variables and getting rid of a needless ones.
+
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::parseModalDialogFeatures): Moved body of this function
+        to the WindowFeatures class.
+        (WebCore::DOMWindow::allowPopUp): Renamed argument from activeFrame to firstFrame,
+        because that's the frame we pass in here. Also added an overload so this can be
+        called on a window rather than a frame.
+        (WebCore::DOMWindow::setLocation): Renamed a couple variables so the names are
+        the same as in open and showModalDialog. Factored the JavaScript security check
+        into a new function named isInsecureScriptAccess.
+        (WebCore::DOMWindow::isInsecureScriptAccess): Here is the new function.
+        (WebCore::DOMWindow::createWindow): Added. Contains logic shared by open and
+        showModalDialog just as the function named createWindow in JSDOMWindowCustom.cpp
+        used to.
+        (WebCore::DOMWindow::open): Added. Code from JSDOMWindowCustom without the
+        JavaScript language binding part, and with a bit of refactoring to share code
+        with the rest of the DOMWindow class.
+        (WebCore::DOMWindow::showModalDialog): Ditto.
+
+        * page/DOMWindow.h: Moved conditional parts of the file into separate paragraphs
+        in alphabetical order so they are not scattered thorugh the file. Removed redundant
+        includes. Added some blank lines for clarity. Added an open function and a
+        showModalDialog function. Added private createWindow and isInsecureScriptAccess
+        functions.
+
+        * page/WindowFeatures.cpp:
+        (WebCore::isWindowFeaturesSeparator): Renamed from isSeparator for clarity.
+        (WebCore::WindowFeatures::WindowFeatures): Updated for name change. Used isEmpty
+        instead of checking length. Added a new constructor for use when making dialogs,
+        with code from the showModalDialog function.
+        (WebCore::WindowFeatures::boolFeature): Use DialogFeaturesMap typedef.
+        (WebCore::WindowFeatures::floatFeature): Use DialogFeaturesMap typedef.
+        Renamed a local variable and tweaked the comments a bit.
+        (WebCore::WindowFeatures::parseDialogFeatures): Added. Code moved here from
+        DOMWindow::parseDialogFeatures and refactored a bit.
+
+        * page/WindowFeatures.h: Added new constructor, new parseDialogFeatures
+        function, DialogFeaturesMap typedef, and made setWindowFeature function private.
+
 2010-12-10  Chris Fleizach  <cfleizach at apple.com>
 
         Reviewed by Darin Adler.
diff --git a/WebCore/bindings/js/JSDOMWindowCustom.cpp b/WebCore/bindings/js/JSDOMWindowCustom.cpp
index 5373dd1..5b16ff5 100644
--- a/WebCore/bindings/js/JSDOMWindowCustom.cpp
+++ b/WebCore/bindings/js/JSDOMWindowCustom.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -667,224 +667,89 @@ JSValue JSDOMWindow::webSocket(ExecState* exec) const
 
 // Custom functions
 
-// Helper for window.open() and window.showModalDialog()
-static Frame* createWindow(ExecState* exec, Frame* lexicalFrame, Frame* dynamicFrame, Frame* openerFrame,
-    const String& url, const String& frameName, const WindowFeatures& windowFeatures, JSValue dialogArgs)
-{
-    ASSERT(lexicalFrame);
-    ASSERT(dynamicFrame);
-
-    ResourceRequest request;
-
-    // For whatever reason, Firefox uses the dynamicGlobalObject to determine
-    // the outgoingReferrer. We replicate that behavior here.
-    String referrer = dynamicFrame->loader()->outgoingReferrer();
-    request.setHTTPReferrer(referrer);
-    FrameLoader::addHTTPOriginIfNeeded(request, dynamicFrame->loader()->outgoingOrigin());
-    FrameLoadRequest frameRequest(lexicalFrame->document()->securityOrigin(), request, frameName);
-
-    // FIXME: It's much better for client API if a new window starts with a URL, here where we
-    // know what URL we are going to open. Unfortunately, this code passes the empty string
-    // for the URL, but there's a reason for that. Before loading we have to set up the opener,
-    // openedByDOM, and dialogArguments values. Also, to decide whether to use the URL we currently
-    // do an allowsAccessFrom call using the window we create, which can't be done before creating it.
-    // We'd have to resolve all those issues to pass the URL instead of "".
-
-    bool created;
-    // We pass the opener frame for the lookupFrame in case the active frame is different from
-    // the opener frame, and the name references a frame relative to the opener frame.
-    Frame* newFrame = createWindow(lexicalFrame, openerFrame, frameRequest, windowFeatures, created);
-    if (!newFrame)
-        return 0;
-
-    newFrame->loader()->setOpener(openerFrame);
-    newFrame->page()->setOpenedByDOM();
-
-    // FIXME: If a window is created from an isolated world, what are the consequences of this? 'dialogArguments' only appears back in the normal world?
-    JSDOMWindow* newWindow = toJSDOMWindow(newFrame, normalWorld(exec->globalData()));
-
-    if (dialogArgs)
-        newWindow->putDirect(Identifier(exec, "dialogArguments"), dialogArgs);
-
-    if (!protocolIsJavaScript(url) || newWindow->allowsAccessFrom(exec)) {
-        KURL completedURL = url.isEmpty() ? KURL(ParsedURLString, "") : completeURL(exec, url);
-        if (created)
-            newFrame->loader()->changeLocation(lexicalFrame->document()->securityOrigin(), completedURL, referrer, false, false);
-        else if (!url.isEmpty())
-            newFrame->navigationScheduler()->scheduleLocationChange(lexicalFrame->document()->securityOrigin(), completedURL.string(), referrer, !lexicalFrame->script()->anyPageIsProcessingUserGesture(), false);
-    }
-
-    return newFrame;
-}
-
-static bool domWindowAllowPopUp(Frame* activeFrame)
-{
-    ASSERT(activeFrame);
-    if (ScriptController::processingUserGesture())
-        return true;
-    return DOMWindow::allowPopUp(activeFrame);
-}
-
 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)));
+    DOMWindow* activeWindow = asJSDOMWindow(exec->lexicalGlobalObject())->impl();
+    DOMWindow* firstWindow = asJSDOMWindow(exec->dynamicGlobalObject())->impl();
 
-    Frame* frame = impl()->frame();
-    if (!frame)
+    String urlString = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0));
+    if (exec->hadException())
         return jsUndefined();
-    Frame* lexicalFrame = toLexicalFrame(exec);
-    if (!lexicalFrame)
+    AtomicString frameName = exec->argument(1).isUndefinedOrNull() ? "_blank" : ustringToAtomicString(exec->argument(1).toString(exec));
+    if (exec->hadException())
         return jsUndefined();
-    Frame* dynamicFrame = toDynamicFrame(exec);
-    if (!dynamicFrame)
+    String windowFeaturesString = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(2));
+    if (exec->hadException())
         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)))
+    RefPtr<DOMWindow> openedWindow = impl()->open(urlString, frameName, windowFeaturesString, activeWindow, firstWindow);
+    if (!openedWindow)
         return jsUndefined();
+    return toJS(exec, openedWindow.get());
+}
 
-    // 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)))) {
-            // For whatever reason, Firefox uses the dynamicGlobalObject to
-            // determine the outgoing referrer. We replicate that behavior here.
-            String referrer = dynamicFrame->loader()->outgoingReferrer();
-
-            frame->navigationScheduler()->scheduleLocationChange(lexicalFrame->document()->securityOrigin(),
-                completedURL, referrer, !lexicalFrame->script()->anyPageIsProcessingUserGesture(), false);
-        }
-        return toJS(exec, frame->domWindow());
+class DialogHandler {
+public:
+    explicit DialogHandler(ExecState* exec)
+        : m_exec(exec)
+        , m_globalObject(0)
+    {
     }
 
-    // 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);
+    void dialogCreated(DOMWindow*);
+    JSValue returnValue() const;
 
-    windowFeatures.x = windowRect.x();
-    windowFeatures.y = windowRect.y();
-    windowFeatures.height = windowRect.height();
-    windowFeatures.width = windowRect.width();
+private:
+    ExecState* m_exec;
+    JSDOMWindow* m_globalObject;
+};
 
-    frame = createWindow(exec, lexicalFrame, dynamicFrame, frame, urlString, frameName, windowFeatures, JSValue());
+inline void DialogHandler::dialogCreated(DOMWindow* dialog)
+{
+    m_globalObject = toJSDOMWindow(dialog->frame(), normalWorld(m_exec->globalData()));
+    if (JSValue dialogArguments = m_exec->argument(1))
+        m_globalObject->putDirect(Identifier(m_exec, "dialogArguments"), dialogArguments);
+}
 
-    if (!frame)
+inline JSValue DialogHandler::returnValue() const
+{
+    if (!m_globalObject)
         return jsUndefined();
+    Identifier identifier(m_exec, "returnValue");
+    PropertySlot slot;
+    if (!m_globalObject->JSGlobalObject::getOwnPropertySlot(m_exec, identifier, slot))
+        return jsUndefined();
+    return slot.getValue(m_exec, identifier);
+}
 
-    return toJS(exec, frame->domWindow());
+static void setUpDialog(DOMWindow* dialog, void* context)
+{
+    static_cast<DialogHandler*>(context)->dialogCreated(dialog);
 }
 
 JSValue JSDOMWindow::showModalDialog(ExecState* exec)
 {
-    String url = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0));
-    JSValue dialogArgs = exec->argument(1);
-    String featureArgs = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(2));
+    DOMWindow* activeWindow = asJSDOMWindow(exec->lexicalGlobalObject())->impl();
+    DOMWindow* firstWindow = asJSDOMWindow(exec->dynamicGlobalObject())->impl();
 
-    Frame* frame = impl()->frame();
-    if (!frame)
-        return jsUndefined();
-    Frame* lexicalFrame = toLexicalFrame(exec);
-    if (!lexicalFrame)
-        return jsUndefined();
-    Frame* dynamicFrame = toDynamicFrame(exec);
-    if (!dynamicFrame)
+    String urlString = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0));
+    if (exec->hadException())
         return jsUndefined();
-
-    if (!DOMWindow::canShowModalDialogNow(frame) || !domWindowAllowPopUp(dynamicFrame))
+    String dialogFeaturesString = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(2));
+    if (exec->hadException())
         return jsUndefined();
 
-    HashMap<String, String> features;
-    DOMWindow::parseModalDialogFeatures(featureArgs, features);
+    DialogHandler handler(exec);
 
-    const bool trusted = false;
+    impl()->showModalDialog(urlString, dialogFeaturesString, activeWindow, firstWindow, setUpDialog, &handler);
 
-    // The following features from Microsoft's documentation are not implemented:
-    // - default font settings
-    // - width, height, left, and top specified in units other than "px"
-    // - edge (sunken or raised, default is raised)
-    // - dialogHide: trusted && boolFeature(features, "dialoghide"), makes dialog hide when you print
-    // - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?)
-    // - unadorned: trusted && boolFeature(features, "unadorned");
-
-    FloatRect screenRect = screenAvailableRect(frame->view());
-
-    WindowFeatures wargs;
-    wargs.width = WindowFeatures::floatFeature(features, "dialogwidth", 100, screenRect.width(), 620); // default here came from frame size of dialog in MacIE
-    wargs.widthSet = true;
-    wargs.height = WindowFeatures::floatFeature(features, "dialogheight", 100, screenRect.height(), 450); // default here came from frame size of dialog in MacIE
-    wargs.heightSet = true;
-
-    wargs.x = WindowFeatures::floatFeature(features, "dialogleft", screenRect.x(), screenRect.right() - wargs.width, -1);
-    wargs.xSet = wargs.x > 0;
-    wargs.y = WindowFeatures::floatFeature(features, "dialogtop", screenRect.y(), screenRect.bottom() - wargs.height, -1);
-    wargs.ySet = wargs.y > 0;
-
-    if (WindowFeatures::boolFeature(features, "center", true)) {
-        if (!wargs.xSet) {
-            wargs.x = screenRect.x() + (screenRect.width() - wargs.width) / 2;
-            wargs.xSet = true;
-        }
-        if (!wargs.ySet) {
-            wargs.y = screenRect.y() + (screenRect.height() - wargs.height) / 2;
-            wargs.ySet = true;
-        }
-    }
-
-    wargs.dialog = true;
-    wargs.resizable = WindowFeatures::boolFeature(features, "resizable");
-    wargs.scrollbarsVisible = WindowFeatures::boolFeature(features, "scroll", true);
-    wargs.statusBarVisible = WindowFeatures::boolFeature(features, "status", !trusted);
-    wargs.menuBarVisible = false;
-    wargs.toolBarVisible = false;
-    wargs.locationBarVisible = false;
-    wargs.fullscreen = false;
-
-    Frame* dialogFrame = createWindow(exec, lexicalFrame, dynamicFrame, frame, url, "", wargs, dialogArgs);
-    if (!dialogFrame)
-        return jsUndefined();
-
-    JSDOMWindow* dialogWindow = toJSDOMWindow(dialogFrame, currentWorld(exec));
-    dialogFrame->page()->chrome()->runModal();
-
-    Identifier returnValue(exec, "returnValue");
-    if (dialogWindow->allowsAccessFromNoErrorMessage(exec)) {
-        PropertySlot slot;
-        // This is safe, we have already performed the origin security check and we are
-        // not interested in any of the DOM properties of the window.
-        if (dialogWindow->JSGlobalObject::getOwnPropertySlot(exec, returnValue, slot))
-            return slot.getValue(exec, returnValue);
-    }
-    return jsUndefined();
+    return handler.returnValue();
 }
 
 JSValue JSDOMWindow::postMessage(ExecState* exec)
 {
-    DOMWindow* window = impl();
+    DOMWindow* activeWindow = asJSDOMWindow(exec->lexicalGlobalObject())->impl();
 
-    DOMWindow* source = asJSDOMWindow(exec->lexicalGlobalObject())->impl();
     PassRefPtr<SerializedScriptValue> message = SerializedScriptValue::create(exec, exec->argument(0));
 
     if (exec->hadException())
@@ -901,7 +766,7 @@ JSValue JSDOMWindow::postMessage(ExecState* exec)
         return jsUndefined();
 
     ExceptionCode ec = 0;
-    window->postMessage(message, &messagePorts, targetOrigin, source, ec);
+    impl()->postMessage(message, &messagePorts, targetOrigin, activeWindow, ec);
     setDOMException(exec, ec);
 
     return jsUndefined();
diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp
index 0293a21..e62960f 100644
--- a/WebCore/page/DOMWindow.cpp
+++ b/WebCore/page/DOMWindow.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
  *
  * Redistribution and use in source and binary forms, with or without
@@ -29,15 +29,14 @@
 
 #include "AbstractDatabase.h"
 #include "BackForwardController.h"
-#include "Base64.h"
 #include "BarInfo.h"
+#include "Base64.h"
 #include "BeforeUnloadEvent.h"
 #include "CSSComputedStyleDeclaration.h"
 #include "CSSRuleList.h"
 #include "CSSStyleSelector.h"
 #include "Chrome.h"
 #include "Console.h"
-#include "DocumentLoader.h"
 #include "DOMApplicationCache.h"
 #include "DOMSelection.h"
 #include "DOMSettableTokenList.h"
@@ -48,8 +47,8 @@
 #include "DatabaseCallback.h"
 #include "DeviceMotionController.h"
 #include "DeviceOrientationController.h"
-#include "PageTransitionEvent.h"
 #include "Document.h"
+#include "DocumentLoader.h"
 #include "Element.h"
 #include "EventException.h"
 #include "EventListener.h"
@@ -57,6 +56,7 @@
 #include "ExceptionCode.h"
 #include "FloatRect.h"
 #include "Frame.h"
+#include "FrameLoadRequest.h"
 #include "FrameLoader.h"
 #include "FrameTree.h"
 #include "FrameView.h"
@@ -75,6 +75,7 @@
 #include "NotificationCenter.h"
 #include "Page.h"
 #include "PageGroup.h"
+#include "PageTransitionEvent.h"
 #include "Performance.h"
 #include "PlatformScreen.h"
 #include "PlatformString.h"
@@ -88,6 +89,7 @@
 #include "StyleMedia.h"
 #include "SuddenTermination.h"
 #include "WebKitPoint.h"
+#include "WindowFeatures.h"
 #include <algorithm>
 #include <wtf/CurrentTime.h>
 #include <wtf/MathExtras.h>
@@ -340,40 +342,28 @@ void DOMWindow::adjustWindowRect(const FloatRect& screen, FloatRect& window, con
     window.setY(max(screen.y(), min(window.y(), screen.bottom() - window.height())));
 }
 
-void DOMWindow::parseModalDialogFeatures(const String& featuresArg, HashMap<String, String>& map)
-{
-    Vector<String> features;
-    featuresArg.split(';', features);
-    Vector<String>::const_iterator end = features.end();
-    for (Vector<String>::const_iterator it = features.begin(); it != end; ++it) {
-        String s = *it;
-        size_t pos = s.find('=');
-        size_t colonPos = s.find(':');
-        if (pos != notFound && colonPos != notFound)
-            continue; // ignore any strings that have both = and :
-        if (pos == notFound)
-            pos = colonPos;
-        if (pos == notFound) {
-            // null string for value means key without value
-            map.set(s.stripWhiteSpace().lower(), String());
-        } else {
-            String key = s.left(pos).stripWhiteSpace().lower();
-            String val = s.substring(pos + 1).stripWhiteSpace().lower();
-            size_t spacePos = val.find(' ');
-            if (spacePos != notFound)
-                val = val.left(spacePos);
-            map.set(key, val);
-        }
-    }
+// FIXME: We can remove this function once V8 showModalDialog is changed to use DOMWindow.
+void DOMWindow::parseModalDialogFeatures(const String& string, HashMap<String, String>& map)
+{
+    WindowFeatures::parseDialogFeatures(string, map);
 }
 
-bool DOMWindow::allowPopUp(Frame* activeFrame)
+bool DOMWindow::allowPopUp(Frame* firstFrame)
 {
-    ASSERT(activeFrame);
-    Settings* settings = activeFrame->settings();
+    ASSERT(firstFrame);
+
+    if (ScriptController::processingUserGesture())
+        return true;
+
+    Settings* settings = firstFrame->settings();
     return settings && settings->javaScriptCanOpenWindowsAutomatically();
 }
 
+bool DOMWindow::allowPopUp()
+{
+    return m_frame && allowPopUp(m_frame);
+}
+
 bool DOMWindow::canShowModalDialog(const Frame* frame)
 {
     if (!frame)
@@ -1618,34 +1608,29 @@ void DOMWindow::revokeObjectURL(const String& blobURLString)
 }
 #endif
 
-void DOMWindow::setLocation(const String& location, DOMWindow* activeWindow, DOMWindow* firstWindow)
+void DOMWindow::setLocation(const String& urlString, DOMWindow* activeWindow, DOMWindow* firstWindow)
 {
     Frame* activeFrame = activeWindow->frame();
     if (!activeFrame)
         return;
+
     if (!activeFrame->loader()->shouldAllowNavigation(m_frame))
         return;
 
     Frame* firstFrame = firstWindow->frame();
     if (!firstFrame)
         return;
-    KURL locationURL = firstFrame->loader()->completeURL(location);
-    if (locationURL.isNull())
+
+    KURL completedURL = firstFrame->document()->completeURL(urlString);
+    if (completedURL.isNull())
         return;
 
-    if (protocolIsJavaScript(locationURL)) {
-        // FIXME: Is there some way to eliminate the need for a separate "activeWindow != this" check?
-        // FIXME: The name canAccess seems to be a roundabout way to ask "can execute script".
-        // Can we name the SecurityOrigin function better to make this more clear?
-        if (activeWindow != this && !activeWindow->securityOrigin()->canAccess(securityOrigin())) {
-            printErrorMessage(crossDomainAccessErrorMessage(activeWindow));
-            return;
-        }
-    }
+    if (isInsecureScriptAccess(activeWindow, urlString))
+        return;
 
     // We want a new history item if we are processing a user gesture.
     m_frame->navigationScheduler()->scheduleLocationChange(activeFrame->document()->securityOrigin(),
-        locationURL, activeFrame->loader()->outgoingReferrer(),
+        completedURL, activeFrame->loader()->outgoingReferrer(),
         !activeFrame->script()->anyPageIsProcessingUserGesture(), false);
 }
 
@@ -1677,4 +1662,156 @@ String DOMWindow::crossDomainAccessErrorMessage(DOMWindow* activeWindow)
         " from frame with URL ", activeWindowURL.string(), ". Domains, protocols and ports must match.\n");
 }
 
+bool DOMWindow::isInsecureScriptAccess(DOMWindow* activeWindow, const String& urlString)
+{
+    if (!protocolIsJavaScript(urlString))
+        return false;
+
+    // FIXME: Is there some way to eliminate the need for a separate "activeWindow == this" check?
+    if (activeWindow == this)
+        return false;
+
+    // FIXME: The name canAccess seems to be a roundabout way to ask "can execute script".
+    // Can we name the SecurityOrigin function better to make this more clear?
+    if (activeWindow->securityOrigin()->canAccess(securityOrigin()))
+        return false;
+
+    printErrorMessage(crossDomainAccessErrorMessage(activeWindow));
+    return true;
+}
+
+Frame* DOMWindow::createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures& windowFeatures,
+    DOMWindow* activeWindow, Frame* firstFrame, Frame* openerFrame, PrepareDialogFunction function, void* functionContext)
+{
+    Frame* activeFrame = activeWindow->frame();
+
+    // FIXME: It's much better for client API if a new window starts with a URL, here where we
+    // know what URL we are going to open. Unfortunately, this code passes the empty string
+    // for the URL, but there's a reason for that. Before loading we have to set up the opener,
+    // openedByDOM, and dialogArguments values. Also, to decide whether to use the URL we currently
+    // do an isInsecureScriptAccess call using the window we create, which can't be done before
+    // creating it. We'd have to resolve all those issues to pass the URL instead of an empty string.
+
+    // For whatever reason, Firefox uses the first frame to determine the outgoingReferrer. We replicate that behavior here.
+    String referrer = firstFrame->loader()->outgoingReferrer();
+
+    ResourceRequest request(KURL(), referrer);
+    FrameLoader::addHTTPOriginIfNeeded(request, firstFrame->loader()->outgoingOrigin());
+    FrameLoadRequest frameRequest(activeWindow->securityOrigin(), request, frameName);
+
+    // We pass the opener frame for the lookupFrame in case the active frame is different from
+    // the opener frame, and the name references a frame relative to the opener frame.
+    bool created;
+    Frame* newFrame = WebCore::createWindow(activeFrame, openerFrame, frameRequest, windowFeatures, created);
+    if (!newFrame)
+        return 0;
+
+    newFrame->loader()->setOpener(openerFrame);
+    newFrame->page()->setOpenedByDOM();
+
+    if (newFrame->domWindow()->isInsecureScriptAccess(activeWindow, urlString))
+        return newFrame;
+
+    if (function)
+        function(newFrame->domWindow(), functionContext);
+
+    KURL completedURL = urlString.isEmpty() ? KURL(ParsedURLString, "") : firstFrame->document()->completeURL(urlString);
+
+    if (created)
+        newFrame->loader()->changeLocation(activeWindow->securityOrigin(), completedURL, referrer, false, false);
+    else if (!urlString.isEmpty()) {
+        newFrame->navigationScheduler()->scheduleLocationChange(activeWindow->securityOrigin(), completedURL.string(), referrer,
+            !activeFrame->script()->anyPageIsProcessingUserGesture(), false);
+    }
+
+    return newFrame;
+}
+
+PassRefPtr<DOMWindow> DOMWindow::open(const String& urlString, const AtomicString& frameName, const String& windowFeaturesString,
+    DOMWindow* activeWindow, DOMWindow* firstWindow)
+{
+    if (!m_frame)
+        return 0;
+    Frame* activeFrame = activeWindow->frame();
+    if (!activeFrame)
+        return 0;
+    Frame* firstFrame = firstWindow->frame();
+    if (!firstFrame)
+        return 0;
+
+    if (!firstWindow->allowPopUp()) {
+        // Because FrameTree::find() returns true for empty strings, we must check for empty frame names.
+        // Otherwise, illegitimate window.open() calls with no name will pass right through the popup blocker.
+        if (frameName.isEmpty() || !m_frame->tree()->find(frameName))
+            return 0;
+    }
+
+    // Get the target frame for the special cases of _top and _parent.
+    // In those cases, we schedule a location change right now and return early.
+    Frame* targetFrame = 0;
+    if (frameName == "_top")
+        targetFrame = m_frame->tree()->top();
+    else if (frameName == "_parent") {
+        if (Frame* parent = m_frame->tree()->parent())
+            targetFrame = parent;
+        else
+            targetFrame = m_frame;
+    }
+    if (targetFrame) {
+        if (!activeFrame->loader()->shouldAllowNavigation(targetFrame))
+            return 0;
+
+        if (isInsecureScriptAccess(activeWindow, urlString))
+            return targetFrame->domWindow();
+
+        if (urlString.isEmpty())
+            return targetFrame->domWindow();
+
+        // For whatever reason, Firefox uses the first window rather than the active window to
+        // determine the outgoing referrer. We replicate that behavior here.
+        targetFrame->navigationScheduler()->scheduleLocationChange(activeFrame->document()->securityOrigin(),
+            firstFrame->document()->completeURL(urlString).string(),
+            firstFrame->loader()->outgoingReferrer(),
+            !activeFrame->script()->anyPageIsProcessingUserGesture(), false);
+
+        return targetFrame->domWindow();
+    }
+
+    WindowFeatures windowFeatures(windowFeaturesString);
+    FloatRect windowRect(windowFeatures.xSet ? windowFeatures.x : 0, windowFeatures.ySet ? windowFeatures.y : 0,
+        windowFeatures.widthSet ? windowFeatures.width : 0, windowFeatures.heightSet ? windowFeatures.height : 0);
+    Page* page = m_frame->page();
+    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* result = createWindow(urlString, frameName, windowFeatures, activeWindow, firstFrame, m_frame);
+    return result ? result->domWindow() : 0;
+}
+
+void DOMWindow::showModalDialog(const String& urlString, const String& dialogFeaturesString,
+    DOMWindow* activeWindow, DOMWindow* firstWindow, PrepareDialogFunction function, void* functionContext)
+{
+    if (!m_frame)
+        return;
+    Frame* activeFrame = activeWindow->frame();
+    if (!activeFrame)
+        return;
+    Frame* firstFrame = firstWindow->frame();
+    if (!firstFrame)
+        return;
+
+    if (!canShowModalDialogNow(m_frame) || !firstWindow->allowPopUp())
+        return;
+
+    Frame* dialogFrame = createWindow(urlString, emptyAtom, WindowFeatures(dialogFeaturesString, screenAvailableRect(m_frame->view())),
+        activeWindow, firstFrame, m_frame, function, functionContext);
+    if (!dialogFrame)
+        return;
+
+    dialogFrame->page()->chrome()->runModal();
+}
+
 } // namespace WebCore
diff --git a/WebCore/page/DOMWindow.h b/WebCore/page/DOMWindow.h
index 0e4fc27..0bffc15 100644
--- a/WebCore/page/DOMWindow.h
+++ b/WebCore/page/DOMWindow.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2009 Apple Inc.  All rights reserved.
+ * Copyright (C) 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,35 +27,27 @@
 #ifndef DOMWindow_h
 #define DOMWindow_h
 
-#include "EventTarget.h"
 #include "KURL.h"
 #include "MessagePort.h"
-#include "PlatformString.h"
-#include "RegisteredEventListener.h"
 #include "SecurityOrigin.h"
-#include <wtf/Forward.h>
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
 
 namespace WebCore {
 
     class BarInfo;
-    class BeforeUnloadEvent;
     class Blob;
     class CSSRuleList;
     class CSSStyleDeclaration;
     class Console;
+    class DOMApplicationCache;
     class DOMSelection;
     class Database;
     class DatabaseCallback;
     class Document;
     class Element;
     class ErrorCallback;
-    class Event;
     class EventListener;
     class FileSystemCallback;
     class FloatRect;
-    class Frame;
     class History;
     class IDBFactory;
     class Location;
@@ -63,25 +55,16 @@ namespace WebCore {
     class Navigator;
     class Node;
     class NotificationCenter;
-    class StyleMedia;
-
-#if ENABLE(WEB_TIMING)
     class Performance;
-#endif
-
     class PostMessageTimer;
     class ScheduledAction;
-    class SerializedScriptValue;
     class Screen;
-    class WebKitPoint;
-
-#if ENABLE(DOM_STORAGE)
+    class SerializedScriptValue;
     class Storage;
-#endif
+    class StyleMedia;
+    class WebKitPoint;
 
-#if ENABLE(OFFLINE_WEB_APPLICATIONS)
-    class DOMApplicationCache;
-#endif
+    struct WindowFeatures;
 
     typedef int ExceptionCode;
 
@@ -100,13 +83,6 @@ namespace WebCore {
 
         PassRefPtr<MediaQueryList> matchMedia(const String&);
 
-#if ENABLE(ORIENTATION_EVENTS)
-        // This is the interface orientation in degrees. Some examples are:
-        //  0 is straight up; -90 is when the device is rotated 90 clockwise;
-        //  90 is when rotated counter clockwise.
-        int orientation() const;
-#endif
-
         void setSecurityOrigin(SecurityOrigin* securityOrigin) { m_securityOrigin = securityOrigin; }
         SecurityOrigin* securityOrigin() const { return m_securityOrigin.get(); }
 
@@ -119,13 +95,17 @@ namespace WebCore {
         static void dispatchAllPendingUnloadEvents();
 
         static void adjustWindowRect(const FloatRect& screen, FloatRect& window, const FloatRect& pendingChanges);
-        static void parseModalDialogFeatures(const String& featuresArg, HashMap<String, String>& map);
 
-        static bool allowPopUp(Frame* activeFrame);
+        // FIXME: We can remove this function once V8 showModalDialog is changed to use DOMWindow.
+        static void parseModalDialogFeatures(const String&, HashMap<String, String>&);
+
+        bool allowPopUp(); // Call on first window, not target window.
+        static bool allowPopUp(Frame* firstFrame);
         static bool canShowModalDialog(const Frame*);
         static bool canShowModalDialogNow(const Frame*);
 
         // DOM Level 0
+
         Screen* screen() const;
         History* history() const;
         BarInfo* locationbar() const;
@@ -136,11 +116,8 @@ namespace WebCore {
         BarInfo* toolbar() const;
         Navigator* navigator() const;
         Navigator* clientInformation() const { return navigator(); }
-#if ENABLE(WEB_TIMING)
-        Performance* webkitPerformance() const;
-#endif
-        Location* location() const;
 
+        Location* location() const;
         void setLocation(const String& location, DOMWindow* activeWindow, DOMWindow* firstWindow);
 
         DOMSelection* getSelection();
@@ -153,6 +130,13 @@ namespace WebCore {
         void print();
         void stop();
 
+        PassRefPtr<DOMWindow> open(const String& urlString, const AtomicString& frameName, const String& windowFeaturesString,
+            DOMWindow* activeWindow, DOMWindow* firstWindow);
+
+        typedef void (*PrepareDialogFunction)(DOMWindow*, void* context);
+        void showModalDialog(const String& urlString, const String& dialogFeaturesString,
+            DOMWindow* activeWindow, DOMWindow* firstWindow, PrepareDialogFunction, void* functionContext);
+
         void alert(const String& message);
         bool confirm(const String& message);
         String prompt(const String& message, const String& defaultValue);
@@ -187,11 +171,13 @@ namespace WebCore {
         void setStatus(const String&);
         String defaultStatus() const;
         void setDefaultStatus(const String&);
+
         // This attribute is an alias of defaultStatus and is necessary for legacy uses.
         String defaultstatus() const { return defaultStatus(); }
         void setDefaultstatus(const String& status) { setDefaultStatus(status); }
 
-        // Self referential attributes
+        // Self-referential attributes
+
         DOMWindow* self() const;
         DOMWindow* window() const { return self(); }
         DOMWindow* frames() const { return self(); }
@@ -201,59 +187,32 @@ namespace WebCore {
         DOMWindow* top() const;
 
         // DOM Level 2 AbstractView Interface
+
         Document* document() const;
+
         // CSSOM View Module
+
         PassRefPtr<StyleMedia> styleMedia() const;
 
         // DOM Level 2 Style Interface
+
         PassRefPtr<CSSStyleDeclaration> getComputedStyle(Element*, const String& pseudoElt) const;
 
         // WebKit extensions
+
         PassRefPtr<CSSRuleList> getMatchedCSSRules(Element*, const String& pseudoElt, bool authorOnly = true) const;
         double devicePixelRatio() const;
 
-        PassRefPtr<WebKitPoint> webkitConvertPointFromPageToNode(Node* node, const WebKitPoint* p) const;
-        PassRefPtr<WebKitPoint> webkitConvertPointFromNodeToPage(Node* node, const WebKitPoint* p) const;        
-
-#if ENABLE(DATABASE)
-        // HTML 5 client-side database
-        PassRefPtr<Database> openDatabase(const String& name, const String& version, const String& displayName, unsigned long estimatedSize, PassRefPtr<DatabaseCallback> creationCallback, ExceptionCode&);
-#endif
-
-#if ENABLE(DOM_STORAGE)
-        // HTML 5 key/value storage
-        Storage* sessionStorage(ExceptionCode&) const;
-        Storage* localStorage(ExceptionCode&) const;
-#endif
+        PassRefPtr<WebKitPoint> webkitConvertPointFromPageToNode(Node*, const WebKitPoint*) const;
+        PassRefPtr<WebKitPoint> webkitConvertPointFromNodeToPage(Node*, const WebKitPoint*) const;        
 
         Console* console() const;
 
         void printErrorMessage(const String&);
         String crossDomainAccessErrorMessage(DOMWindow* activeWindow);
 
-#if ENABLE(OFFLINE_WEB_APPLICATIONS)
-        DOMApplicationCache* applicationCache() const;
-#endif
-
-#if ENABLE(NOTIFICATIONS)
-        NotificationCenter* webkitNotifications() const;
-#endif
-
         void pageDestroyed();
 
-#if ENABLE(INDEXED_DATABASE)
-        IDBFactory* webkitIndexedDB() const;
-#endif
-
-#if ENABLE(FILE_SYSTEM)
-        // They are placed here and in all capital letters to enforce compile-time enum checking.
-        enum FileSystemType {
-            TEMPORARY,
-            PERSISTENT,
-        };
-        void requestFileSystem(int type, long long size, PassRefPtr<FileSystemCallback>, PassRefPtr<ErrorCallback>);
-#endif
-
         void postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray*, const String& targetOrigin, DOMWindow* source, ExceptionCode&);
         // FIXME: remove this when we update the ObjC bindings (bug #28774).
         void postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort*, const String& targetOrigin, DOMWindow* source, ExceptionCode&);
@@ -352,33 +311,17 @@ namespace WebCore {
         DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitbeginfullscreen);
         DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitendfullscreen);
 
-#if ENABLE(ORIENTATION_EVENTS)
-        DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange);
-#endif
-
-#if ENABLE(DEVICE_ORIENTATION)
-        DEFINE_ATTRIBUTE_EVENT_LISTENER(devicemotion);
-        DEFINE_ATTRIBUTE_EVENT_LISTENER(deviceorientation);
-#endif
-
         DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationstart, webkitAnimationStart);
         DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationiteration, webkitAnimationIteration);
         DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationend, webkitAnimationEnd);
         DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkittransitionend, webkitTransitionEnd);
 
-#if ENABLE(TOUCH_EVENTS)
-        DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
-        DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
-        DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
-        DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
-#endif
         void captureEvents();
         void releaseEvents();
 
         void finishedLoading();
 
-        // These methods are used for GC marking. See JSDOMWindow::markChildren(MarkStack&) in
-        // JSDOMWindowCustom.cpp.
+        // These functions are used for GC marking. See JSDOMWindow::markChildren(MarkStack&) in JSDOMWindowCustom.cpp.
         Screen* optionalScreen() const { return m_screen.get(); }
         DOMSelection* optionalSelection() const { return m_selection.get(); }
         History* optionalHistory() const { return m_history.get(); }
@@ -390,25 +333,78 @@ namespace WebCore {
         BarInfo* optionalToolbar() const { return m_toolbar.get(); }
         Console* optionalConsole() const { return m_console.get(); }
         Navigator* optionalNavigator() const { return m_navigator.get(); }
-#if ENABLE(WEB_TIMING)
-        Performance* optionalWebkitPerformance() const { return m_performance.get(); }
-#endif
         Location* optionalLocation() const { return m_location.get(); }
         StyleMedia* optionalMedia() const { return m_media.get(); }
+
+        using RefCounted<DOMWindow>::ref;
+        using RefCounted<DOMWindow>::deref;
+
+#if ENABLE(BLOB)
+        String createObjectURL(Blob*);
+        void revokeObjectURL(const String&);
+#endif
+
+#if ENABLE(DATABASE)
+        // HTML 5 client-side database
+        PassRefPtr<Database> openDatabase(const String& name, const String& version, const String& displayName, unsigned long estimatedSize, PassRefPtr<DatabaseCallback> creationCallback, ExceptionCode&);
+#endif
+
+#if ENABLE(DEVICE_ORIENTATION)
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(devicemotion);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(deviceorientation);
+#endif
+
 #if ENABLE(DOM_STORAGE)
+        // HTML 5 key/value storage
+        Storage* sessionStorage(ExceptionCode&) const;
+        Storage* localStorage(ExceptionCode&) const;
         Storage* optionalSessionStorage() const { return m_sessionStorage.get(); }
         Storage* optionalLocalStorage() const { return m_localStorage.get(); }
 #endif
+
+#if ENABLE(FILE_SYSTEM)
+        // They are placed here and in all capital letters so they can be checked against the constants in the
+        // IDL at compile time.
+        enum FileSystemType {
+            TEMPORARY,
+            PERSISTENT,
+        };
+        void requestFileSystem(int type, long long size, PassRefPtr<FileSystemCallback>, PassRefPtr<ErrorCallback>);
+#endif
+
+#if ENABLE(INDEXED_DATABASE)
+        IDBFactory* webkitIndexedDB() const;
+#endif
+
+#if ENABLE(NOTIFICATIONS)
+        NotificationCenter* webkitNotifications() const;
+#endif
+
 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
+        DOMApplicationCache* applicationCache() const;
         DOMApplicationCache* optionalApplicationCache() const { return m_applicationCache.get(); }
 #endif
-#if ENABLE(BLOB)
-        String createObjectURL(Blob*);
-        void revokeObjectURL(const String&);
+
+#if ENABLE(ORIENTATION_EVENTS)
+        // This is the interface orientation in degrees. Some examples are:
+        //  0 is straight up; -90 is when the device is rotated 90 clockwise;
+        //  90 is when rotated counter clockwise.
+        int orientation() const;
+
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange);
 #endif
 
-        using RefCounted<DOMWindow>::ref;
-        using RefCounted<DOMWindow>::deref;
+#if ENABLE(TOUCH_EVENTS)
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
+#endif
+
+#if ENABLE(WEB_TIMING)
+        Performance* webkitPerformance() const;
+        Performance* optionalWebkitPerformance() const { return m_performance.get(); }
+#endif
 
     private:
         DOMWindow(Frame*);
@@ -418,6 +414,11 @@ namespace WebCore {
         virtual EventTargetData* eventTargetData();
         virtual EventTargetData* ensureEventTargetData();
 
+        static Frame* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures&,
+            DOMWindow* activeWindow, Frame* firstFrame, Frame* openerFrame,
+            PrepareDialogFunction = 0, void* functionContext = 0);
+        bool isInsecureScriptAccess(DOMWindow* activeWindow, const String& urlString);
+
         RefPtr<SecurityOrigin> m_securityOrigin;
         KURL m_url;
 
@@ -434,29 +435,34 @@ namespace WebCore {
         mutable RefPtr<BarInfo> m_toolbar;
         mutable RefPtr<Console> m_console;
         mutable RefPtr<Navigator> m_navigator;
-#if ENABLE(WEB_TIMING)
-        mutable RefPtr<Performance> m_performance;
-#endif
         mutable RefPtr<Location> m_location;
         mutable RefPtr<StyleMedia> m_media;
+
+        EventTargetData m_eventTargetData;
+
+        String m_status;
+        String m_defaultStatus;
+
 #if ENABLE(DOM_STORAGE)
         mutable RefPtr<Storage> m_sessionStorage;
         mutable RefPtr<Storage> m_localStorage;
 #endif
+
+#if ENABLE(INDEXED_DATABASE)
+        mutable RefPtr<IDBFactory> m_idbFactory;
+#endif
+
 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
         mutable RefPtr<DOMApplicationCache> m_applicationCache;
 #endif
+
 #if ENABLE(NOTIFICATIONS)
         mutable RefPtr<NotificationCenter> m_notifications;
 #endif
-#if ENABLE(INDEXED_DATABASE)
-        mutable RefPtr<IDBFactory> m_idbFactory;
-#endif
-
-        EventTargetData m_eventTargetData;
 
-        String m_status;
-        String m_defaultStatus;
+#if ENABLE(WEB_TIMING)
+        mutable RefPtr<Performance> m_performance;
+#endif
     };
 
     inline String DOMWindow::status() const
diff --git a/WebCore/page/WindowFeatures.cpp b/WebCore/page/WindowFeatures.cpp
index 82e36b9..a229ae1 100644
--- a/WebCore/page/WindowFeatures.cpp
+++ b/WebCore/page/WindowFeatures.cpp
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 2000 Harri Porten (porten at kde.org)
  *  Copyright (C) 2006 Jon Shier (jshier at iastate.edu)
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reseved.
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010 Apple Inc. All rights reseved.
  *  Copyright (C) 2006 Alexey Proskuryakov (ap at webkit.org)
  *
  *  This library is free software; you can redistribute it and/or
@@ -23,16 +23,16 @@
 #include "config.h"
 #include "WindowFeatures.h"
 
+#include "FloatRect.h"
 #include "PlatformString.h"
 #include <wtf/Assertions.h>
-#include <wtf/HashMap.h>
 #include <wtf/MathExtras.h>
 #include <wtf/text/StringHash.h>
 
 namespace WebCore {
 
-// Though isspace() considers \t and \v to be whitespace, Win IE doesn't.
-static bool isSeparator(UChar c)
+// Though isspace() considers \t and \v to be whitespace, Win IE doesn't when parsing window features.
+static bool isWindowFeaturesSeparator(UChar c)
 {
     return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '=' || c == ',' || c == '\0';
 }
@@ -80,7 +80,7 @@ WindowFeatures::WindowFeatures(const String& features)
     String buffer = features.lower();
     while (i < length) {
         // skip to first non-separator, but don't skip past the end of the string
-        while (isSeparator(buffer[i])) {
+        while (isWindowFeaturesSeparator(buffer[i])) {
             if (i >= length)
                 break;
             i++;
@@ -88,7 +88,7 @@ WindowFeatures::WindowFeatures(const String& features)
         keyBegin = i;
 
         // skip to first separator
-        while (!isSeparator(buffer[i]))
+        while (!isWindowFeaturesSeparator(buffer[i]))
             i++;
         keyEnd = i;
 
@@ -100,7 +100,7 @@ WindowFeatures::WindowFeatures(const String& features)
         }
 
         // skip to first non-separator, but don't skip past a ',' or the end of the string
-        while (isSeparator(buffer[i])) {
+        while (isWindowFeaturesSeparator(buffer[i])) {
             if (buffer[i] == ',' || i >= length)
                 break;
             i++;
@@ -108,7 +108,7 @@ WindowFeatures::WindowFeatures(const String& features)
         valueBegin = i;
 
         // skip to first separator
-        while (!isSeparator(buffer[i]))
+        while (!isWindowFeaturesSeparator(buffer[i]))
             i++;
         valueEnd = i;
 
@@ -125,12 +125,14 @@ void WindowFeatures::setWindowFeature(const String& keyString, const String& val
     int value;
 
     // Listing a key with no value is shorthand for key=yes
-    if (valueString.length() == 0 || valueString == "yes")
+    if (valueString.isEmpty() || valueString == "yes")
         value = 1;
     else
         value = valueString.toInt();
 
-    // We ignore a keyString of "resizable", which is consistent with Firefox.
+    // We treat keyString of "resizable" here as an additional feature rather than setting resizeable to true.
+    // This is consistent with Firefox, but could also be handled at another level.
+
     if (keyString == "left" || keyString == "screenx") {
         xSet = true;
         x = value;
@@ -159,32 +161,106 @@ void WindowFeatures::setWindowFeature(const String& keyString, const String& val
         additionalFeatures.append(keyString);
 }
 
-bool WindowFeatures::boolFeature(const HashMap<String, String>& features, const char* key, bool defaultValue)
+WindowFeatures::WindowFeatures(const String& dialogFeaturesString, const FloatRect& screenAvailableRect)
+    : widthSet(true)
+    , heightSet(true)
+    , menuBarVisible(false)
+    , toolBarVisible(false)
+    , locationBarVisible(false)
+    , fullscreen(false)
+    , dialog(true)
 {
-    HashMap<String, String>::const_iterator it = features.find(key);
+    DialogFeaturesMap features;
+    parseDialogFeatures(dialogFeaturesString, features);
+
+    const bool trusted = false;
+
+    // The following features from Microsoft's documentation are not implemented:
+    // - default font settings
+    // - width, height, left, and top specified in units other than "px"
+    // - edge (sunken or raised, default is raised)
+    // - dialogHide: trusted && boolFeature(features, "dialoghide"), makes dialog hide when you print
+    // - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?)
+    // - unadorned: trusted && boolFeature(features, "unadorned");
+
+    width = floatFeature(features, "dialogwidth", 100, screenAvailableRect.width(), 620); // default here came from frame size of dialog in MacIE
+    height = floatFeature(features, "dialogheight", 100, screenAvailableRect.height(), 450); // default here came from frame size of dialog in MacIE
+
+    x = floatFeature(features, "dialogleft", screenAvailableRect.x(), screenAvailableRect.right() - width, -1);
+    xSet = x > 0;
+    y = floatFeature(features, "dialogtop", screenAvailableRect.y(), screenAvailableRect.bottom() - height, -1);
+    ySet = y > 0;
+
+    if (boolFeature(features, "center", true)) {
+        if (!xSet) {
+            x = screenAvailableRect.x() + (screenAvailableRect.width() - width) / 2;
+            xSet = true;
+        }
+        if (!ySet) {
+            y = screenAvailableRect.y() + (screenAvailableRect.height() - height) / 2;
+            ySet = true;
+        }
+    }
+
+    resizable = boolFeature(features, "resizable");
+    scrollbarsVisible = boolFeature(features, "scroll", true);
+    statusBarVisible = boolFeature(features, "status", !trusted);
+}
+
+bool WindowFeatures::boolFeature(const DialogFeaturesMap& features, const char* key, bool defaultValue)
+{
+    DialogFeaturesMap::const_iterator it = features.find(key);
     if (it == features.end())
         return defaultValue;
     const String& value = it->second;
     return value.isNull() || value == "1" || value == "yes" || value == "on";
 }
 
-float WindowFeatures::floatFeature(const HashMap<String, String>& features, const char* key, float min, float max, float defaultValue)
+float WindowFeatures::floatFeature(const DialogFeaturesMap& features, const char* key, float min, float max, float defaultValue)
 {
-    HashMap<String, String>::const_iterator it = features.find(key);
+    DialogFeaturesMap::const_iterator it = features.find(key);
     if (it == features.end())
         return defaultValue;
-    // FIXME: Can't distinguish "0q" from string with no digits in it -- both return d == 0 and ok == false.
-    // Would be good to tell them apart somehow since string with no digits should be default value and
-    // "0q" should be minimum value.
+    // FIXME: The toDouble function does not offer a way to tell "0q" from string with no digits in it: Both
+    // return the number 0 and false for ok. But "0q" should yield the minimum rather than the default.
     bool ok;
-    double d = it->second.toDouble(&ok);
-    if ((d == 0 && !ok) || isnan(d))
+    double parsedNumber = it->second.toDouble(&ok);
+    if ((parsedNumber == 0 && !ok) || isnan(parsedNumber))
         return defaultValue;
-    if (d < min || max <= min)
+    if (parsedNumber < min || max <= min)
         return min;
-    if (d > max)
+    if (parsedNumber > max)
         return max;
-    return static_cast<int>(d);
+    // FIXME: Seems strange to cast a double to int and then convert back to a float. Why is this a good idea?
+    return static_cast<int>(parsedNumber);
+}
+
+void WindowFeatures::parseDialogFeatures(const String& string, DialogFeaturesMap& map)
+{
+    Vector<String> vector;
+    string.split(';', vector);
+    size_t size = vector.size();
+    for (size_t i = 0; i < size; ++i) {
+        const String& featureString = vector[i];
+
+        size_t separatorPosition = featureString.find('=');
+        size_t colonPosition = featureString.find(':');
+        if (separatorPosition != notFound && colonPosition != notFound)
+            continue; // ignore strings that have both = and :
+        if (separatorPosition == notFound)
+            separatorPosition = colonPosition;
+
+        String key = featureString.left(separatorPosition).stripWhiteSpace().lower();
+
+        // Null string for value indicates key without value.
+        String value;
+        if (separatorPosition != notFound) {
+            value = featureString.substring(separatorPosition + 1).stripWhiteSpace().lower();
+            value = value.left(value.find(' '));
+        }
+
+        map.set(key, value);
+    }
 }
 
 } // namespace WebCore
diff --git a/WebCore/page/WindowFeatures.h b/WebCore/page/WindowFeatures.h
index a414552..ea5768f 100644
--- a/WebCore/page/WindowFeatures.h
+++ b/WebCore/page/WindowFeatures.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2007, 2010 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,7 +34,10 @@
 
 namespace WebCore {
 
+    class FloatRect;
+
     struct WindowFeatures {
+        // FIXME: We can delete this constructor once V8 showModalDialog is changed to use DOMWindow.
         WindowFeatures()
             : xSet(false)
             , ySet(false)
@@ -51,12 +54,8 @@ namespace WebCore {
         {
         }
 
-        WindowFeatures(const String& features);
-
-        void setWindowFeature(const String& keyString, const String& valueString);
-
-        static bool boolFeature(const HashMap<String, String>& features, const char* key, bool defaultValue = false);
-        static float floatFeature(const HashMap<String, String>& features, const char* key, float min, float max, float defaultValue);
+        WindowFeatures(const String& windowFeaturesString);
+        WindowFeatures(const String& dialogFeaturesString, const FloatRect& screenAvailableRect);
 
         float x;
         bool xSet;
@@ -78,6 +77,15 @@ namespace WebCore {
         bool dialog;
 
         Vector<String> additionalFeatures;
+
+        // FIXME: We can make these functions private non-member functions once V8 showModalDialog is changed to use DOMWindow.
+        typedef HashMap<String, String> DialogFeaturesMap;
+        static void parseDialogFeatures(const String&, HashMap<String, String>&);
+        static bool boolFeature(const DialogFeaturesMap&, const char* key, bool defaultValue = false);
+        static float floatFeature(const DialogFeaturesMap&, const char* key, float min, float max, float defaultValue);
+
+    private:
+        void setWindowFeature(const String& keyString, const String& valueString);
     };
 
 } // namespace WebCore

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list