diff options
author | Ben Murdoch <benm@google.com> | 2010-08-11 14:44:44 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2010-08-12 19:15:41 +0100 |
commit | dd8bb3de4f353a81954234999f1fea748aee2ea9 (patch) | |
tree | 729b52bf09294f0d6c67cd5ea80aee1b727b7bd8 /WebCore/bindings/generic | |
parent | f3d41ba51d86bf719c7a65ab5297aea3c17e2d98 (diff) | |
download | external_webkit-dd8bb3de4f353a81954234999f1fea748aee2ea9.zip external_webkit-dd8bb3de4f353a81954234999f1fea748aee2ea9.tar.gz external_webkit-dd8bb3de4f353a81954234999f1fea748aee2ea9.tar.bz2 |
Merge WebKit at r65072 : Initial merge by git.
Change-Id: Ibcf418498376b2660aacb7f8d46ea7085ef91585
Diffstat (limited to 'WebCore/bindings/generic')
-rw-r--r-- | WebCore/bindings/generic/ActiveDOMCallback.cpp | 144 | ||||
-rw-r--r-- | WebCore/bindings/generic/ActiveDOMCallback.h | 58 | ||||
-rw-r--r-- | WebCore/bindings/generic/BindingDOMWindow.h | 177 | ||||
-rw-r--r-- | WebCore/bindings/generic/BindingSecurity.h | 25 | ||||
-rw-r--r-- | WebCore/bindings/generic/RuntimeEnabledFeatures.cpp | 1 | ||||
-rw-r--r-- | WebCore/bindings/generic/RuntimeEnabledFeatures.h | 6 |
6 files changed, 405 insertions, 6 deletions
diff --git a/WebCore/bindings/generic/ActiveDOMCallback.cpp b/WebCore/bindings/generic/ActiveDOMCallback.cpp new file mode 100644 index 0000000..2e69d10 --- /dev/null +++ b/WebCore/bindings/generic/ActiveDOMCallback.cpp @@ -0,0 +1,144 @@ +/* + * 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 + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * 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 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ActiveDOMCallback.h" + +#include "ActiveDOMObject.h" +#include "ScriptExecutionContext.h" +#include <wtf/PassOwnPtr.h> +#include <wtf/ThreadingPrimitives.h> + +namespace WebCore { + +static void destroyOnContextThread(PassOwnPtr<ActiveDOMObjectCallbackImpl>); + +class DestroyOnContextThreadTask : public ScriptExecutionContext::Task { +public: + static PassOwnPtr<DestroyOnContextThreadTask> create(PassOwnPtr<ActiveDOMObjectCallbackImpl> impl) + { + return adoptPtr(new DestroyOnContextThreadTask(impl)); + } + + virtual void performTask(ScriptExecutionContext*) + { + destroyOnContextThread(m_impl.release()); + } + +private: + DestroyOnContextThreadTask(PassOwnPtr<ActiveDOMObjectCallbackImpl> impl) + : m_impl(impl) + { + } + + OwnPtr<ActiveDOMObjectCallbackImpl> m_impl; +}; + +// Instances of this class are accessed only on the context thread, so we don't need to use locks. +class ActiveDOMObjectCallbackImpl : public ActiveDOMObject { +public: + ActiveDOMObjectCallbackImpl(ScriptExecutionContext* context) + : ActiveDOMObject(context, this) + , m_suspended(false) + , m_stopped(false) + { + } + + virtual void contextDestroyed() + { + MutexLocker locker(m_mutex); + ActiveDOMObject::contextDestroyed(); + } + virtual bool canSuspend() const { return false; } + virtual void suspend() + { + MutexLocker locker(m_mutex); + m_suspended = true; + } + virtual void resume() + { + MutexLocker locker(m_mutex); + m_suspended = false; + } + virtual void stop() + { + MutexLocker locker(m_mutex); + m_stopped = true; + } + bool canInvokeCallback() + { + MutexLocker locker(m_mutex); + return (!m_suspended && !m_stopped); + } + ScriptExecutionContext* scriptExecutionContext() + { + MutexLocker locker(m_mutex); + return ActiveDOMObject::scriptExecutionContext(); + } + Mutex& mutex() { return m_mutex; } + +private: + Mutex m_mutex; + bool m_suspended; + bool m_stopped; +}; + +static void destroyOnContextThread(PassOwnPtr<ActiveDOMObjectCallbackImpl> impl) +{ + OwnPtr<ActiveDOMObjectCallbackImpl> implOwnPtr = impl; + + ScriptExecutionContext* context = implOwnPtr->scriptExecutionContext(); + MutexLocker locker(implOwnPtr->mutex()); + if (context && !context->isContextThread()) + context->postTask(DestroyOnContextThreadTask::create(implOwnPtr.release())); +} + +ActiveDOMCallback::ActiveDOMCallback(ScriptExecutionContext* context) + : m_impl(new ActiveDOMObjectCallbackImpl(context)) +{ + ASSERT(context->isContextThread()); +} + +ActiveDOMCallback::~ActiveDOMCallback() +{ + destroyOnContextThread(m_impl.release()); +} + +bool ActiveDOMCallback::canInvokeCallback() const +{ + return m_impl->canInvokeCallback(); +} + +ScriptExecutionContext* ActiveDOMCallback::scriptExecutionContext() const +{ + return m_impl->scriptExecutionContext(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/generic/ActiveDOMCallback.h b/WebCore/bindings/generic/ActiveDOMCallback.h new file mode 100644 index 0000000..2fe99ab --- /dev/null +++ b/WebCore/bindings/generic/ActiveDOMCallback.h @@ -0,0 +1,58 @@ +/* + * 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 + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * 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 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ActiveDOMCallback_h +#define ActiveDOMCallback_h + +#include <wtf/OwnPtr.h> + +namespace WebCore { + +class ActiveDOMObjectCallbackImpl; +class ScriptExecutionContext; + +// A class that allows callbacks to behave like ActiveDOMObjects, and also +// be destroyed on the context thread or any other thread. +class ActiveDOMCallback { +public: + ActiveDOMCallback(ScriptExecutionContext* context); + ~ActiveDOMCallback(); + + bool canInvokeCallback() const; + ScriptExecutionContext* scriptExecutionContext() const; + +private: + // The ActiveDOMObject part of the callback. + OwnPtr<ActiveDOMObjectCallbackImpl> m_impl; +}; + +} // namespace WebCore + +#endif // ActiveDOMCallback_h 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/generic/RuntimeEnabledFeatures.cpp b/WebCore/bindings/generic/RuntimeEnabledFeatures.cpp index eb027c3..94e984f 100644 --- a/WebCore/bindings/generic/RuntimeEnabledFeatures.cpp +++ b/WebCore/bindings/generic/RuntimeEnabledFeatures.cpp @@ -47,6 +47,7 @@ bool RuntimeEnabledFeatures::isIndexedDBEnabled = false; bool RuntimeEnabledFeatures::isWebGLEnabled = false; bool RuntimeEnabledFeatures::isPushStateEnabled = false; bool RuntimeEnabledFeatures::isTouchEnabled = true; +bool RuntimeEnabledFeatures::isDeviceMotionEnabled = true; bool RuntimeEnabledFeatures::isDeviceOrientationEnabled = true; bool RuntimeEnabledFeatures::isSpeechInputEnabled = true; diff --git a/WebCore/bindings/generic/RuntimeEnabledFeatures.h b/WebCore/bindings/generic/RuntimeEnabledFeatures.h index c9eb21f..fd7308e 100644 --- a/WebCore/bindings/generic/RuntimeEnabledFeatures.h +++ b/WebCore/bindings/generic/RuntimeEnabledFeatures.h @@ -114,6 +114,11 @@ public: static bool ontouchcancelEnabled() { return isTouchEnabled; } #endif + static void setDeviceMotionEnabled(bool isEnabled) { isDeviceMotionEnabled = isEnabled; } + static bool deviceMotionEnabled() { return isDeviceMotionEnabled; } + static bool deviceMotionEventEnabled() { return isDeviceMotionEnabled; } + static bool ondevicemotionEnabled() { return isDeviceMotionEnabled; } + static void setDeviceOrientationEnabled(bool isEnabled) { isDeviceOrientationEnabled = isEnabled; } static bool deviceOrientationEnabled() { return isDeviceOrientationEnabled; } static bool deviceOrientationEventEnabled() { return isDeviceOrientationEnabled; } @@ -136,6 +141,7 @@ private: static bool isWebGLEnabled; static bool isPushStateEnabled; static bool isTouchEnabled; + static bool isDeviceMotionEnabled; static bool isDeviceOrientationEnabled; static bool isSpeechInputEnabled; }; |