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

eric at webkit.org eric at webkit.org
Wed Dec 22 11:50:33 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit e1e963a460ae6c86cf4878473c681497bcb2d1d2
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Aug 9 17:50:41 2010 +0000

    2010-08-09  Dominic Cooney  <dominicc at google.com>
    
            Reviewed by Adam Barth.
    
            Moves window.open logic into the generic bindings.
    
            This patch moves window.open logic from V8 into the generic
            bindings so it could be shared with JSC. JSC sharing is not in
            this patch. This patch is of the same flavor/intent as 33201.
    
            https://bugs.webkit.org/show_bug.cgi?id=41392
    
            * bindings/generic/BindingDOMWindow.h:
            (WebCore::::createWindow):
            (WebCore::::open):
            (WebCore::::completeURL):
            * bindings/generic/BindingSecurity.h:
            (WebCore::::allowPopUp):
            (WebCore::::shouldAllowNavigation):
            * bindings/v8/V8Binding.h:
            (WebCore::V8Binding::emptyScriptValue):
            * bindings/v8/V8Utilities.cpp:
            (WebCore::transferHiddenDependency):
            (WebCore::processingUserGesture):
            (WebCore::shouldAllowNavigation):
            (WebCore::completeURL):
            * bindings/v8/custom/V8ArrayBufferCustom.cpp:
            * bindings/v8/custom/V8DOMWindowCustom.cpp:
            (WebCore::V8DOMWindow::showModalDialogCallback):
            (WebCore::V8DOMWindow::openCallback):
            * bindings/v8/specialization/V8BindingState.cpp:
            (WebCore::::getActiveFrame):
            (WebCore::::getFirstFrame):
            (WebCore::::processingUserGesture):
            * bindings/v8/specialization/V8BindingState.h:
            (WebCore::):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@64991 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index b518e1d..a366172 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,40 @@
+2010-08-09  Dominic Cooney  <dominicc at google.com>
+
+        Reviewed by Adam Barth.
+
+        Moves window.open logic into the generic bindings.
+
+        This patch moves window.open logic from V8 into the generic
+        bindings so it could be shared with JSC. JSC sharing is not in
+        this patch. This patch is of the same flavor/intent as 33201.
+
+        https://bugs.webkit.org/show_bug.cgi?id=41392
+
+        * bindings/generic/BindingDOMWindow.h:
+        (WebCore::::createWindow):
+        (WebCore::::open):
+        (WebCore::::completeURL):
+        * bindings/generic/BindingSecurity.h:
+        (WebCore::::allowPopUp):
+        (WebCore::::shouldAllowNavigation):
+        * bindings/v8/V8Binding.h:
+        (WebCore::V8Binding::emptyScriptValue):
+        * bindings/v8/V8Utilities.cpp:
+        (WebCore::transferHiddenDependency):
+        (WebCore::processingUserGesture):
+        (WebCore::shouldAllowNavigation):
+        (WebCore::completeURL):
+        * bindings/v8/custom/V8ArrayBufferCustom.cpp:
+        * bindings/v8/custom/V8DOMWindowCustom.cpp:
+        (WebCore::V8DOMWindow::showModalDialogCallback):
+        (WebCore::V8DOMWindow::openCallback):
+        * bindings/v8/specialization/V8BindingState.cpp:
+        (WebCore::::getActiveFrame):
+        (WebCore::::getFirstFrame):
+        (WebCore::::processingUserGesture):
+        * bindings/v8/specialization/V8BindingState.h:
+        (WebCore::):
+
 2010-08-09  Marcus Bulach  <bulach at chromium.org>
 
         Reviewed by Darin Adler.
diff --git a/WebCore/bindings/generic/BindingDOMWindow.h b/WebCore/bindings/generic/BindingDOMWindow.h
index f883d11..dda5644 100644
--- a/WebCore/bindings/generic/BindingDOMWindow.h
+++ b/WebCore/bindings/generic/BindingDOMWindow.h
@@ -1,10 +1,10 @@
 /*
  * Copyright (C) 2010 Google Inc. All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
- * 
+ *
  *     * Redistributions of source code must retain the above copyright
  * notice, this list of conditions and the following disclaimer.
  *     * Redistributions in binary form must reproduce the above
@@ -14,7 +14,7 @@
  *     * Neither the name of Google Inc. nor the names of its
  * contributors may be used to endorse or promote products derived from
  * this software without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -31,11 +31,17 @@
 #ifndef BindingDOMWindow_h
 #define BindingDOMWindow_h
 
+#include "DOMWindow.h"
 #include "Frame.h"
 #include "FrameLoadRequest.h"
+#include "FrameLoader.h"
+#include "FrameView.h"
 #include "GenericBinding.h"
 #include "Page.h"
+#include "PlatformScreen.h"
+#include "ScriptController.h"
 #include "SecurityOrigin.h"
+#include "WindowFeatures.h"
 
 namespace WebCore {
 
@@ -52,6 +58,20 @@ public:
                                const String& frameName,
                                const WindowFeatures& windowFeatures,
                                BindingValue dialogArgs);
+
+    static WebCore::DOMWindow* open(State<Binding>*,
+                                    WebCore::DOMWindow* parent,
+                                    const String& url,
+                                    const String& frameName,
+                                    const WindowFeatures& rawFeatures);
+
+    // FIXME: There should be a place for generic binding utilities.
+    static KURL completeURL(State<Binding>*, const String& relativeURL);
+
+private:
+    // Horizontal and vertical offset, from the parent content area,
+    // around newly opened popups that don't specify a location.
+    static const int popupTilePixels = 10;
 };
 
 // Implementations of templated methods must be in this file.
@@ -103,8 +123,8 @@ Frame* BindingDOMWindow<Binding>::createWindow(State<Binding>* state,
 
     if (!protocolIsJavaScript(url) || BindingSecurity<Binding>::canAccessFrame(state, newFrame, true)) {
         KURL completedUrl =
-            url.isEmpty() ? KURL(ParsedURLString, "") : completeURL(url);
-        bool userGesture = processingUserGesture();
+            url.isEmpty() ? KURL(ParsedURLString, "") : completeURL(state, url);
+        bool userGesture = state->processingUserGesture();
 
         if (created)
             newFrame->loader()->changeLocation(completedUrl, referrer, false, false, userGesture);
@@ -115,6 +135,153 @@ Frame* BindingDOMWindow<Binding>::createWindow(State<Binding>* state,
     return newFrame;
 }
 
+template<class Binding>
+WebCore::DOMWindow* BindingDOMWindow<Binding>::open(State<Binding>* state,
+                                                    WebCore::DOMWindow* parent,
+                                                    const String& urlString,
+                                                    const String& frameName,
+                                                    const WindowFeatures& rawFeatures)
+{
+    Frame* frame = parent->frame();
+
+    if (!BindingSecurity<Binding>::canAccessFrame(state, frame, true))
+        return 0;
+
+    Frame* firstFrame = state->getFirstFrame();
+    if (!firstFrame)
+        return 0;
+
+    Frame* activeFrame = state->getActiveFrame();
+    // We may not have a calling context if we are invoked by a plugin
+    // via NPAPI.
+    if (!activeFrame)
+        activeFrame = firstFrame;
+
+    Page* page = frame->page();
+    if (!page)
+        return 0;
+
+    // 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 (!BindingSecurity<Binding>::allowPopUp(state)
+        && (frameName.isEmpty() || !frame->tree()->find(frameName))) {
+        return 0;
+    }
+
+    // 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) {
+        if (!BindingSecurity<Binding>::shouldAllowNavigation(state, frame))
+            return 0;
+
+        String completedUrl;
+        if (!urlString.isEmpty())
+            completedUrl = completeURL(state, urlString);
+
+        if (!completedUrl.isEmpty()
+            && (!protocolIsJavaScript(completedUrl)
+                || BindingSecurity<Binding>::canAccessFrame(state, frame, true))) {
+            bool userGesture = state->processingUserGesture();
+
+            // For whatever reason, Firefox uses the first frame to determine
+            // the outgoingReferrer.  We replicate that behavior here.
+            String referrer = firstFrame->loader()->outgoingReferrer();
+
+            frame->redirectScheduler()->scheduleLocationChange(completedUrl, referrer, false, false, userGesture);
+        }
+        return frame->domWindow();
+    }
+
+    // In the case of a named frame or a new window, we'll use the
+    // createWindow() helper.
+
+    // Work with a copy of the parsed values so we can restore the
+    // values we may not want to overwrite after we do the multiple
+    // monitor fixes.
+    WindowFeatures windowFeatures(rawFeatures);
+    FloatRect screenRect = screenAvailableRect(page->mainFrame()->view());
+
+    // Set default size and location near parent window if none were specified.
+    // These may be further modified by adjustWindowRect, below.
+    if (!windowFeatures.xSet) {
+        windowFeatures.x = parent->screenX() - screenRect.x() + popupTilePixels;
+        windowFeatures.xSet = true;
+    }
+    if (!windowFeatures.ySet) {
+        windowFeatures.y = parent->screenY() - screenRect.y() + popupTilePixels;
+        windowFeatures.ySet = true;
+    }
+    if (!windowFeatures.widthSet) {
+        windowFeatures.width = parent->innerWidth();
+        windowFeatures.widthSet = true;
+    }
+    if (!windowFeatures.heightSet) {
+        windowFeatures.height = parent->innerHeight();
+        windowFeatures.heightSet = true;
+    }
+
+    FloatRect windowRect(windowFeatures.x, windowFeatures.y, windowFeatures.width, windowFeatures.height);
+
+    // The new window's location is relative to its current screen, so shift
+    // it in case it's on a secondary monitor. See http://b/viewIssue?id=967905.
+    windowRect.move(screenRect.x(), screenRect.y());
+    WebCore::DOMWindow::adjustWindowRect(screenRect, windowRect, windowRect);
+
+    windowFeatures.x = windowRect.x();
+    windowFeatures.y = windowRect.y();
+    windowFeatures.height = windowRect.height();
+    windowFeatures.width = windowRect.width();
+
+    // If either of the origin coordinates or dimensions weren't set
+    // in the original string, make sure they aren't set now.
+    if (!rawFeatures.xSet) {
+        windowFeatures.x = 0;
+        windowFeatures.xSet = false;
+    }
+    if (!rawFeatures.ySet) {
+        windowFeatures.y = 0;
+        windowFeatures.ySet = false;
+    }
+    if (!rawFeatures.widthSet) {
+      windowFeatures.width = 0;
+      windowFeatures.widthSet = false;
+    }
+    if (!rawFeatures.heightSet) {
+      windowFeatures.height = 0;
+      windowFeatures.heightSet = false;
+    }
+
+    frame = createWindow(state, activeFrame, firstFrame, frame, urlString, frameName, windowFeatures, Binding::emptyScriptValue());
+
+    if (!frame)
+        return 0;
+
+    return frame->domWindow();
+}
+
+template <class Binding>
+KURL BindingDOMWindow<Binding>::completeURL(State<Binding>* state,
+                                            const String& relativeURL)
+{
+    // For historical reasons, we need to complete the URL using the
+    // dynamic frame.
+    Frame* frame = state->getFirstFrame();
+    if (!frame)
+        return KURL();
+    return frame->loader()->completeURL(relativeURL);
+}
+
 } // namespace WebCore
 
 #endif // BindingDOMWindow_h
diff --git a/WebCore/bindings/generic/BindingSecurity.h b/WebCore/bindings/generic/BindingSecurity.h
index d7c9dfe..1124f7e 100644
--- a/WebCore/bindings/generic/BindingSecurity.h
+++ b/WebCore/bindings/generic/BindingSecurity.h
@@ -34,14 +34,15 @@
 #include "BindingSecurityBase.h"
 #include "CSSHelper.h"
 #include "Element.h"
+#include "Frame.h"
 #include "GenericBinding.h"
 #include "HTMLFrameElementBase.h"
 #include "HTMLNames.h"
+#include "Settings.h"
 
 namespace WebCore {
 
 class DOMWindow;
-class Frame;
 class Node;
 
 // Security functions shared by various language bindings.
@@ -55,9 +56,12 @@ public:
     // current security context.
     static bool checkNodeSecurity(State<Binding>*, Node* target);
 
+    static bool allowPopUp(State<Binding>*);
     static bool allowSettingFrameSrcToJavascriptUrl(State<Binding>*, HTMLFrameElementBase*, String value);
     static bool allowSettingSrcToJavascriptURL(State<Binding>*, Element*, String name, String value);
 
+    static bool shouldAllowNavigation(State<Binding>*, Frame*);
+
 private:
     explicit BindingSecurity() {}
     ~BindingSecurity();
@@ -110,6 +114,18 @@ bool BindingSecurity<Binding>::checkNodeSecurity(State<Binding>* state, Node* no
 }
 
 template <class Binding>
+bool BindingSecurity<Binding>::allowPopUp(State<Binding>* state)
+{
+    if (state->processingUserGesture())
+        return true;
+
+    Frame* frame = state->getFirstFrame();
+    ASSERT(frame);
+    Settings* settings = frame->settings();
+    return settings && settings->javaScriptCanOpenWindowsAutomatically();
+}
+
+template <class Binding>
 bool BindingSecurity<Binding>::allowSettingFrameSrcToJavascriptUrl(State<Binding>* state, HTMLFrameElementBase* frame, String value)
 {
     if (protocolIsJavaScript(deprecatedParseURL(value))) {
@@ -128,6 +144,13 @@ bool BindingSecurity<Binding>::allowSettingSrcToJavascriptURL(State<Binding>* st
     return true;
 }
 
+template <class Binding>
+bool BindingSecurity<Binding>::shouldAllowNavigation(State<Binding>* state, Frame* frame)
+{
+    Frame* activeFrame = state->getActiveFrame();
+    return activeFrame && activeFrame->loader()->shouldAllowNavigation(frame);
+}
+
 }
 
 #endif // BindingSecurity_h
diff --git a/WebCore/bindings/v8/V8Binding.h b/WebCore/bindings/v8/V8Binding.h
index a15ece1..8383f94 100644
--- a/WebCore/bindings/v8/V8Binding.h
+++ b/WebCore/bindings/v8/V8Binding.h
@@ -1,10 +1,10 @@
 /*
 * Copyright (C) 2009 Google Inc. All rights reserved.
-* 
+*
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
-* 
+*
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
@@ -14,7 +14,7 @@
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
-* 
+*
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -40,7 +40,7 @@
 #include <v8.h>
 
 namespace WebCore {
-    
+
     class EventListener;
     class EventTarget;
     class V8BindingDOMWindow;
@@ -50,6 +50,8 @@ namespace WebCore {
     public:
         typedef v8::Handle<v8::Value> Value;
         typedef V8BindingDOMWindow DOMWindow;
+
+        static Value emptyScriptValue() { return v8::Local<v8::Value>(); }
     };
     typedef BindingSecurity<V8Binding> V8BindingSecurity;
     
@@ -152,7 +154,7 @@ namespace WebCore {
     {
         return v8ValueToWebCoreString(object);
     }
-    
+
     String toWebCoreString(const v8::Arguments&, int index);
 
     // The string returned by this function is still owned by the argument
@@ -171,7 +173,7 @@ namespace WebCore {
     AtomicString toAtomicWebCoreStringWithNullCheck(v8::Handle<v8::Value> value);
 
     String toWebCoreStringWithNullOrUndefinedCheck(v8::Handle<v8::Value> value);
- 
+
     v8::Handle<v8::String> v8UndetectableString(const String& str);
 
     v8::Handle<v8::Value> v8StringOrNull(const String& str);
@@ -183,31 +185,31 @@ namespace WebCore {
     double toWebCoreDate(v8::Handle<v8::Value> object);
 
     v8::Handle<v8::Value> v8DateOrNull(double value);
-    
+
     v8::Persistent<v8::FunctionTemplate> createRawTemplate();
 
     struct BatchedAttribute;
     struct BatchedCallback;
-    
+
     v8::Local<v8::Signature> configureTemplate(v8::Persistent<v8::FunctionTemplate>,
                                                const char* interfaceName,
                                                v8::Persistent<v8::FunctionTemplate> parentClass,
                                                int fieldCount,
-                                               const BatchedAttribute*, 
+                                               const BatchedAttribute*,
                                                size_t attributeCount,
                                                const BatchedCallback*,
                                                size_t callbackCount);
-    
+
     v8::Handle<v8::Value> getElementStringAttr(const v8::AccessorInfo&,
                                                const QualifiedName&);
     void setElementStringAttr(const v8::AccessorInfo&,
                               const QualifiedName&,
                               v8::Local<v8::Value>);
 
-    
+
     v8::Persistent<v8::String> getToStringName();
     v8::Persistent<v8::FunctionTemplate> getToStringTemplate();
-    
+
     // V8Parameter is an adapter class that converts V8 values to Strings
     // or AtomicStrings as appropriate, using multiple typecast operators.
     enum V8ParameterMode {
@@ -224,7 +226,7 @@ namespace WebCore {
     private:
         v8::Local<v8::Value> m_v8Object;
     };
-    
+
     template<> inline V8Parameter<DefaultMode>::operator String() { return toWebCoreString(m_v8Object); }
     template<> inline V8Parameter<WithNullCheck>::operator String() { return toWebCoreStringWithNullCheck(m_v8Object); }
     template<> inline V8Parameter<WithUndefinedOrNullCheck>::operator String() { return toWebCoreStringWithNullOrUndefinedCheck(m_v8Object); }
diff --git a/WebCore/bindings/v8/V8Utilities.cpp b/WebCore/bindings/v8/V8Utilities.cpp
index f780218..2e5cf8b 100644
--- a/WebCore/bindings/v8/V8Utilities.cpp
+++ b/WebCore/bindings/v8/V8Utilities.cpp
@@ -38,6 +38,8 @@
 #include "ScriptExecutionContext.h"
 #include "ScriptState.h"
 #include "V8Binding.h"
+#include "V8BindingDOMWindow.h" // FIXME: remove when completeURL moves
+#include "V8BindingState.h"
 #include "V8Proxy.h"
 #include "WorkerContext.h"
 #include "WorkerContextExecutionProxy.h"
@@ -92,41 +94,25 @@ void transferHiddenDependency(v8::Handle<v8::Object> object,
     if (!newValue->IsNull() && !newValue->IsUndefined())
         createHiddenDependency(object, newValue, cacheIndex);
 }
-    
 
 bool processingUserGesture()
 {
-    Frame* frame = V8Proxy::retrieveFrameForEnteredContext();
-    return frame && frame->script()->processingUserGesture();
+    return V8BindingState::Only()->processingUserGesture();
 }
 
 Frame* callingOrEnteredFrame()
 {
-    Frame* frame = V8Proxy::retrieveFrameForCallingContext();
-    if (!frame) {
-        // Unfortunately, when processing script from a plug-in, we might not
-        // have a calling context.  In those cases, we fall back to the
-        // entered context for security checks.
-        // FIXME: We need a better API for retrieving frames that abstracts
-        //        away this concern.
-        frame = V8Proxy::retrieveFrameForEnteredContext();
-    }
-    return frame;
+    return V8BindingState::Only()->getActiveFrame();
 }
 
 bool shouldAllowNavigation(Frame* frame)
 {
-    Frame* callingOrEntered = callingOrEnteredFrame();
-    return callingOrEntered && callingOrEntered->loader()->shouldAllowNavigation(frame);
+    return V8BindingSecurity::shouldAllowNavigation(V8BindingState::Only(), frame);
 }
 
 KURL completeURL(const String& relativeURL)
 {
-    // For histoical reasons, we need to complete the URL using the dynamic frame.
-    Frame* frame = V8Proxy::retrieveFrameForEnteredContext();
-    if (!frame)
-        return KURL();
-    return frame->loader()->completeURL(relativeURL);
+    return V8BindingDOMWindow::completeURL(V8BindingState::Only(), relativeURL);
 }
 
 void navigateIfAllowed(Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList)
diff --git a/WebCore/bindings/v8/custom/V8ArrayBufferCustom.cpp b/WebCore/bindings/v8/custom/V8ArrayBufferCustom.cpp
index 501e5a2..305fb18 100644
--- a/WebCore/bindings/v8/custom/V8ArrayBufferCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8ArrayBufferCustom.cpp
@@ -34,6 +34,7 @@
 
 #include "ArrayBuffer.h"
 
+#include "ExceptionCode.h"
 #include "V8Binding.h"
 #include "V8ArrayBuffer.h"
 #include "V8Proxy.h"
diff --git a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
index b4fa74f..cff2523 100644
--- a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
@@ -82,10 +82,6 @@
 #endif
 #include "WindowFeatures.h"
 
-// Horizontal and vertical offset, from the parent content area, around newly
-// opened popups that don't specify a location.
-static const int popupTilePixels = 10;
-
 namespace WebCore {
 
 v8::Handle<v8::Value> WindowSetTimeoutImpl(const v8::Arguments& args, bool singleShot)
@@ -449,17 +445,6 @@ static bool canShowModalDialogNow(const Frame* frame)
     return frame->page()->chrome()->canRunModalNow();
 }
 
-static bool allowPopUp()
-{
-    Frame* frame = V8Proxy::retrieveFrameForEnteredContext();
-
-    ASSERT(frame);
-    if (frame->script()->processingUserGesture())
-        return true;
-    Settings* settings = frame->settings();
-    return settings && settings->javaScriptCanOpenWindowsAutomatically();
-}
-
 static HashMap<String, String> parseModalDialogFeatures(const String& featuresArg)
 {
     HashMap<String, String> map;
@@ -513,7 +498,7 @@ v8::Handle<v8::Value> V8DOMWindow::showModalDialogCallback(const v8::Arguments&
     if (!enteredFrame)
         return v8::Undefined();
 
-    if (!canShowModalDialogNow(frame) || !allowPopUp())
+    if (!canShowModalDialogNow(frame) || !V8BindingSecurity::allowPopUp(V8BindingState::Only()))
         return v8::Undefined();
 
     const HashMap<String, String> features = parseModalDialogFeatures(featureArgs);
@@ -584,134 +569,16 @@ v8::Handle<v8::Value> V8DOMWindow::openCallback(const v8::Arguments& args)
 {
     INC_STATS("DOM.DOMWindow.open()");
 
+    DOMWindow* parent = V8DOMWindow::toNative(args.Holder());
     String urlString = toWebCoreStringWithNullOrUndefinedCheck(args[0]);
     AtomicString frameName = (args[1]->IsUndefined() || args[1]->IsNull()) ? "_blank" : AtomicString(toWebCoreString(args[1]));
-
-    DOMWindow* parent = V8DOMWindow::toNative(args.Holder());
-    Frame* frame = parent->frame();
-
-    if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), frame, true))
-        return v8::Undefined();
-
-    Frame* enteredFrame = V8Proxy::retrieveFrameForEnteredContext();
-    if (!enteredFrame)
-        return v8::Undefined();
-
-    Frame* callingFrame = V8Proxy::retrieveFrameForCallingContext();
-    // We may not have a calling context if we are invoked by a plugin via NPAPI.
-    if (!callingFrame)
-        callingFrame = enteredFrame;
-
-    Page* page = frame->page();
-    if (!page)
-        return v8::Undefined();
-
-    // 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 (!allowPopUp() &&
-        (frameName.isEmpty() || !frame->tree()->find(frameName))) {
-        return v8::Undefined();
-    }
-
-    // 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) {
-        if (!shouldAllowNavigation(frame))
-            return v8::Undefined();
-
-        String completedUrl;
-        if (!urlString.isEmpty())
-            completedUrl = completeURL(urlString);
-
-        if (!completedUrl.isEmpty() &&
-            (!protocolIsJavaScript(completedUrl) || ScriptController::isSafeScript(frame))) {
-            bool userGesture = processingUserGesture();
-
-            // For whatever reason, Firefox uses the entered frame to determine
-            // the outgoingReferrer.  We replicate that behavior here.
-            String referrer = enteredFrame->loader()->outgoingReferrer();
-
-            frame->redirectScheduler()->scheduleLocationChange(completedUrl, referrer, false, false, userGesture);
-        }
-        return toV8(frame->domWindow());
-    }
-
-    // In the case of a named frame or a new window, we'll use the
-    // createWindow() helper.
-
-    // Parse the values, and then work with a copy of the parsed values
-    // so we can restore the values we may not want to overwrite after
-    // we do the multiple monitor fixes.
     WindowFeatures rawFeatures(toWebCoreStringWithNullOrUndefinedCheck(args[2]));
-    WindowFeatures windowFeatures(rawFeatures);
-    FloatRect screenRect = screenAvailableRect(page->mainFrame()->view());
-
-    // Set default size and location near parent window if none were specified.
-    // These may be further modified by adjustWindowRect, below.
-    if (!windowFeatures.xSet) {
-        windowFeatures.x = parent->screenX() - screenRect.x() + popupTilePixels;
-        windowFeatures.xSet = true;
-    }
-    if (!windowFeatures.ySet) {
-        windowFeatures.y = parent->screenY() - screenRect.y() + popupTilePixels;
-        windowFeatures.ySet = true;
-    }
-    if (!windowFeatures.widthSet) {
-        windowFeatures.width = parent->innerWidth();
-        windowFeatures.widthSet = true;
-    }
-    if (!windowFeatures.heightSet) {
-        windowFeatures.height = parent->innerHeight();
-        windowFeatures.heightSet = true;
-    }
-
-    FloatRect windowRect(windowFeatures.x, windowFeatures.y, windowFeatures.width, windowFeatures.height);
-
-    // The new window's location is relative to its current screen, so shift
-    // it in case it's on a secondary monitor. See http://b/viewIssue?id=967905.
-    windowRect.move(screenRect.x(), screenRect.y());
-    WebCore::DOMWindow::adjustWindowRect(screenRect, windowRect, windowRect);
-
-    windowFeatures.x = windowRect.x();
-    windowFeatures.y = windowRect.y();
-    windowFeatures.height = windowRect.height();
-    windowFeatures.width = windowRect.width();
-
-    // If either of the origin coordinates or dimensions weren't set in the original
-    // string, make sure they aren't set now.
-    if (!rawFeatures.xSet) {
-        windowFeatures.x = 0;
-        windowFeatures.xSet = false;
-    }
-    if (!rawFeatures.ySet) {
-        windowFeatures.y = 0;
-        windowFeatures.ySet = false;
-    }
-    if (!rawFeatures.widthSet) {
-      windowFeatures.width = 0;
-      windowFeatures.widthSet = false;
-    }
-    if (!rawFeatures.heightSet) {
-      windowFeatures.height = 0;
-      windowFeatures.heightSet = false;
-    }
-
-    frame = V8BindingDOMWindow::createWindow(V8BindingState::Only(), callingFrame, enteredFrame, frame, urlString, frameName, windowFeatures, v8::Local<v8::Value>());
+    DOMWindow* child = V8BindingDOMWindow::open(V8BindingState::Only(), parent, urlString, frameName, rawFeatures);
 
-    if (!frame)
+    if (!child)
         return v8::Undefined();
 
-    return toV8(frame->domWindow());
+    return toV8(child);
 }
 
 
diff --git a/WebCore/bindings/v8/specialization/V8BindingState.cpp b/WebCore/bindings/v8/specialization/V8BindingState.cpp
index 4710271..d95d578 100644
--- a/WebCore/bindings/v8/specialization/V8BindingState.cpp
+++ b/WebCore/bindings/v8/specialization/V8BindingState.cpp
@@ -1,10 +1,10 @@
 /*
  * Copyright (C) 2009 Google Inc. All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
- * 
+ *
  *     * Redistributions of source code must retain the above copyright
  * notice, this list of conditions and the following disclaimer.
  *     * Redistributions in binary form must reproduce the above
@@ -14,7 +14,7 @@
  *     * Neither the name of Google Inc. nor the names of its
  * contributors may be used to endorse or promote products derived from
  * this software without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -31,6 +31,8 @@
 #include "config.h"
 #include "V8BindingState.h"
 
+#include "Frame.h"
+#include "ScriptController.h"
 #include "V8Proxy.h"
 #include <wtf/StdLibExtras.h>
 
@@ -53,9 +55,34 @@ DOMWindow* State<V8Binding>::getActiveWindow()
     return V8Proxy::retrieveWindow(activeContext);
 }
 
+Frame* State<V8Binding>::getActiveFrame()
+{
+    Frame* frame = V8Proxy::retrieveFrameForCallingContext();
+    if (!frame) {
+        // Unfortunately, when processing script from a plug-in, we might not
+        // have a calling context.  In those cases, we fall back to the
+        // entered context for security checks.
+        // FIXME: We need a better API for retrieving frames that abstracts
+        //        away this concern.
+        frame = V8Proxy::retrieveFrameForEnteredContext();
+    }
+    return frame;
+}
+
+Frame* State<V8Binding>::getFirstFrame()
+{
+    return V8Proxy::retrieveFrameForEnteredContext();
+}
+
 void State<V8Binding>::immediatelyReportUnsafeAccessTo(Frame* target)
 {
     V8Proxy::reportUnsafeAccessTo(target, V8Proxy::ReportNow);
 }
 
+bool State<V8Binding>::processingUserGesture()
+{
+    Frame* frame = V8Proxy::retrieveFrameForEnteredContext();
+    return frame && frame->script()->processingUserGesture();
+}
+
 } // namespace WebCore
diff --git a/WebCore/bindings/v8/specialization/V8BindingState.h b/WebCore/bindings/v8/specialization/V8BindingState.h
index f305c14..baba0c6 100644
--- a/WebCore/bindings/v8/specialization/V8BindingState.h
+++ b/WebCore/bindings/v8/specialization/V8BindingState.h
@@ -1,10 +1,10 @@
 /*
  * Copyright (C) 2009 Google Inc. All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
- * 
+ *
  *     * Redistributions of source code must retain the above copyright
  * notice, this list of conditions and the following disclaimer.
  *     * Redistributions in binary form must reproduce the above
@@ -14,7 +14,7 @@
  *     * Neither the name of Google Inc. nor the names of its
  * contributors may be used to endorse or promote products derived from
  * this software without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -36,6 +36,8 @@
 
 namespace WebCore {
 
+class Frame;
+
 // Singleton implementation of State<V8Binding>.  Uses V8's global data
 // structures to return information about relevant execution state.
 template <>
@@ -44,11 +46,19 @@ public:
     // Singleton
     static State* Only();
 
+    // Reports an error message (without delay) if the security check fails.
+    static void immediatelyReportUnsafeAccessTo(Frame*);
+
     // The DOMWindow corresponding to the 'calling context' of execution.
     DOMWindow* getActiveWindow();
 
-    // Reports an error message (without delay) if the security check fails.
-    static void immediatelyReportUnsafeAccessTo(Frame*);
+    // The frame corresponding to the 'calling context' of execution.
+    Frame* getActiveFrame();
+
+    // The first frame in which execution entered user script.
+    Frame* getFirstFrame();
+
+    bool processingUserGesture();
 
 private:
     explicit State() {}

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list