Diff
Modified: trunk/LayoutTests/ChangeLog (230763 => 230764)
--- trunk/LayoutTests/ChangeLog 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/LayoutTests/ChangeLog 2018-04-18 16:50:36 UTC (rev 230764)
@@ -1,3 +1,22 @@
+2018-04-18 Chris Dumez <[email protected]>
+
+ Add support for converting a local window to a remote window
+ https://bugs.webkit.org/show_bug.cgi?id=184515
+ <rdar://problem/39011318>
+
+ Reviewed by Ryosuke Niwa.
+
+ Add layout test coverage a cross-origin window.open() to check that the
+ returned window looks like a regular cross-origin window after being
+ navigated cross-origin. We are still failing some of the checks because
+ our implementation is still incomplete. However, it mostly works as
+ expected.
+
+ * TestExpectations:
+ * http/tests/navigation/process-swap-window-open-expected.txt: Added.
+ * http/tests/navigation/process-swap-window-open.html: Added.
+ * platform/wk2/TestExpectations:
+
2018-04-18 Ms2ger <[email protected]>
Test gardening.
Modified: trunk/LayoutTests/TestExpectations (230763 => 230764)
--- trunk/LayoutTests/TestExpectations 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/LayoutTests/TestExpectations 2018-04-18 16:50:36 UTC (rev 230764)
@@ -109,6 +109,7 @@
http/tests/loading/resourceLoadStatistics/ [ Skip ]
http/tests/resourceLoadStatistics/ [ Skip ]
http/tests/storageAccess/ [ Skip ]
+http/tests/navigation/process-swap-window-open.html [ Skip ]
# Only Mac and iOS have an implementation of UIScriptController::doAsyncTask().
fast/harness/uiscriptcontroller [ Skip ]
Added: trunk/LayoutTests/http/tests/navigation/process-swap-window-open-expected.txt (0 => 230764)
--- trunk/LayoutTests/http/tests/navigation/process-swap-window-open-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/navigation/process-swap-window-open-expected.txt 2018-04-18 16:50:36 UTC (rev 230764)
@@ -0,0 +1,44 @@
+Basic testing for the window returning window.open() becoming remote when navigating cross-origin.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS w.location.href is "about:blank"
+PASS w.name threw exception SecurityError: The operation is insecure..
+FAIL w.location.href should throw a SecurityError. Threw a TypeError.
+PASS w.document threw exception SecurityError: The operation is insecure..
+PASS w.history threw exception SecurityError: The operation is insecure..
+PASS w.locationbar threw exception SecurityError: The operation is insecure..
+PASS w.status threw exception SecurityError: The operation is insecure..
+PASS w.frameElement threw exception SecurityError: The operation is insecure..
+PASS w.navigator threw exception SecurityError: The operation is insecure..
+PASS w.alert threw exception SecurityError: The operation is insecure..
+PASS w.localStorage threw exception SecurityError: The operation is insecure..
+PASS w.sessionStorage threw exception SecurityError: The operation is insecure..
+PASS w.event threw exception SecurityError: The operation is insecure..
+PASS w.window is w
+PASS w.self is w
+PASS w.top is w
+PASS w.parent is w
+PASS w.frames is w
+PASS w.closed is false
+PASS w.length is 0
+FAIL w.opener should be [object Window]. Was null.
+PASS w.close is an instance of Function
+PASS w.focus is an instance of Function
+PASS w.blur is an instance of Function
+PASS w.postMessage is an instance of Function
+PASS w.location did not throw exception.
+FAIL w.location should not be null.
+PASS areArraysEqual(actual_properties, expected_property_names) is true
+PASS Object.getPrototype(w) threw exception TypeError: Object.getPrototype is not a function. (In 'Object.getPrototype(w)', 'Object.getPrototype' is undefined).
+PASS Object.setPrototype(w, {}) threw exception TypeError: Object.setPrototype is not a function. (In 'Object.setPrototype(w, {})', 'Object.setPrototype' is undefined).
+PASS Object.preventExtensions(w) threw exception TypeError: Cannot prevent extensions on this object.
+PASS Object.defineProperty(w, 'foo', {value: 1}) threw exception SecurityError: The operation is insecure..
+PASS delete w.closed threw exception SecurityError: The operation is insecure..
+PASS w.foo = 1 threw exception SecurityError: The operation is insecure..
+PASS successfullyParsed is true
+Some tests failed.
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/http/tests/navigation/process-swap-window-open.html (0 => 230764)
--- trunk/LayoutTests/http/tests/navigation/process-swap-window-open.html (rev 0)
+++ trunk/LayoutTests/http/tests/navigation/process-swap-window-open.html 2018-04-18 16:50:36 UTC (rev 230764)
@@ -0,0 +1,71 @@
+<!DOCTYPE html><!-- webkit-test-runner [ enableProcessSwapOnNavigation=true ] -->
+<html>
+<body>
+<script src=""
+<script>
+description("Basic testing for the window returning window.open() becoming remote when navigating cross-origin.");
+jsTestIsAsync = true;
+
+if (window.testRunner)
+ testRunner.setCanOpenWindows(true);
+
+function wasWindowNavigatedCrossOrigin()
+{
+ try {
+ w.name;
+ return false;
+ } catch (e) {
+ return true;
+ }
+}
+
+function runTest() {
+ forbiddenProperties = ["name", "location.href", "document", "history", "locationbar", "status", "frameElement", "navigator", "alert", "localStorage", "sessionStorage", "event"];
+ for (forbiddenProperty of forbiddenProperties)
+ shouldThrowErrorName("w." + forbiddenProperty, "SecurityError");
+
+ shouldBe("w.window", "w");
+ shouldBe("w.self", "w");
+ shouldBe("w.top", "w");
+ shouldBe("w.parent", "w");
+ shouldBe("w.frames", "w");
+ shouldBeFalse("w.closed");
+ shouldBe("w.length", "0");
+ shouldBe("w.opener", "window");
+ shouldBeType("w.close", "Function");
+ shouldBeType("w.focus", "Function");
+ shouldBeType("w.blur", "Function");
+ shouldBeType("w.postMessage", "Function");
+
+ shouldNotThrow("w.location");
+ shouldNotBe("w.location", "null");
+
+ expected_property_names = ["blur", "close", "closed", "focus", "frames", "length", "location", "opener", "parent", "postMessage", "self", "top", "window"];
+ actual_properties = Object.getOwnPropertyNames(w);
+ shouldBeTrue("areArraysEqual(actual_properties, expected_property_names)");
+
+ shouldThrowErrorName("Object.getPrototype(w)", "TypeError");
+ shouldThrowErrorName("Object.setPrototype(w, {})", "TypeError");
+ shouldThrowErrorName("Object.preventExtensions(w)", "TypeError");
+ shouldThrowErrorName("Object.defineProperty(w, 'foo', {value: 1})", "SecurityError");
+ shouldThrowErrorName("delete w.closed", "SecurityError");
+
+ shouldThrowErrorName("w.foo = 1", "SecurityError");
+
+ finishJSTest();
+}
+
+_onload_ = function() {
+ w = window.open("http://localhost:8000/navigation/resources/success.html");
+ shouldBeEqualToString("w.location.href", "about:blank");
+
+ handle = setInterval(function() {
+ if (wasWindowNavigatedCrossOrigin()) {
+ clearInterval(handle);
+ runTest();
+ }
+ }, 5);
+}
+</script>
+</body>
+</html>
Modified: trunk/LayoutTests/platform/wk2/TestExpectations (230763 => 230764)
--- trunk/LayoutTests/platform/wk2/TestExpectations 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/LayoutTests/platform/wk2/TestExpectations 2018-04-18 16:50:36 UTC (rev 230764)
@@ -707,6 +707,9 @@
http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects.html [ Skip ]
http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests.html [ Skip ]
+# Process swapping is only implemented on WebKit2.
+http/tests/navigation/process-swap-window-open.html [ Pass ]
+
### END OF (5) Progressions, expected successes that are expected failures in WebKit1.
########################################
Modified: trunk/Source/WebCore/ChangeLog (230763 => 230764)
--- trunk/Source/WebCore/ChangeLog 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebCore/ChangeLog 2018-04-18 16:50:36 UTC (rev 230764)
@@ -1,3 +1,50 @@
+2018-04-18 Chris Dumez <[email protected]>
+
+ Add support for converting a local window to a remote window
+ https://bugs.webkit.org/show_bug.cgi?id=184515
+ <rdar://problem/39011318>
+
+ Reviewed by Ryosuke Niwa.
+
+ Add initial support for process-swapping when navigating cross-origin as a result
+ of a window.open(). The window object returned by window.open() is initially same
+ origin and is for about:blank. The navigation cross-origin then happens and the
+ JS wrappers for the window then point to a cross-origin window which is remote (i.e.
+ hosted in another WebProcess).
+
+ The RemoteDOMWindow exposed to JS looks like a regular cross-origin Window with a few
+ exceptions due to our incomplete implementation (e.g. w.location returns null) and
+ most of its API is currently not functional. The RemoteDOMWindow API will be implemented
+ in a follow-up by relying on IPC.
+
+ Test: http/tests/navigation/process-swap-window-open.html
+
+ * bindings/js/JSDOMGlobalObject.cpp:
+ (WebCore::JSDOMGlobalObject::scriptExecutionContext const):
+ * bindings/js/JSDOMPromiseDeferred.h:
+ * bindings/js/JSDOMWindowProperties.cpp:
+ (WebCore::JSDOMWindowProperties::getOwnPropertySlot):
+ * bindings/js/JSDOMWindowProxy.cpp:
+ (WebCore::JSDOMWindowProxy::finishCreation):
+ (WebCore::JSDOMWindowProxy::create):
+ * bindings/js/JSDOMWindowProxy.h:
+ * bindings/js/JSDOMWrapper.cpp:
+ (WebCore::JSDOMObject::JSDOMObject):
+ * bindings/js/JSDOMWrapper.h:
+ * bindings/js/WindowProxyController.cpp:
+ (WebCore::WindowProxyController::createWindowProxy):
+ (WebCore::WindowProxyController::setDOMWindowForWindowProxy):
+ * bridge/objc/WebScriptObject.mm:
+ (-[WebScriptObject _isSafeScript]):
+ Teach more of our bindings code about RemoteDOMWindows.
+
+ * dom/Document.cpp:
+ (WebCore::Document::createDOMWindow):
+ * loader/FrameLoaderClient.h:
+ Add FrameLoaderClient function to notify the client when a DOMWindow is constructed in
+ the frame. This is needed for WebKit2 to link the old window to its new representation
+ in the new WebProcess.
+
2018-04-17 Zan Dobersek <[email protected]>
[CMake] Add and enable the ENABLE_CSS_ANIMATIONS_LEVEL_2 feature define
Modified: trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp (230763 => 230764)
--- trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp 2018-04-18 16:50:36 UTC (rev 230764)
@@ -38,6 +38,7 @@
#include "JSRTCSessionDescription.h"
#include "JSReadableStream.h"
#include "JSReadableStreamPrivateConstructors.h"
+#include "JSRemoteDOMWindow.h"
#include "JSWorkerGlobalScope.h"
#include "RuntimeEnabledFeatures.h"
#include "StructuredClone.h"
@@ -197,11 +198,13 @@
{
if (inherits<JSDOMWindowBase>(vm()))
return jsCast<const JSDOMWindowBase*>(this)->scriptExecutionContext();
+ if (inherits<JSRemoteDOMWindowBase>(vm()))
+ return nullptr;
if (inherits<JSWorkerGlobalScopeBase>(vm()))
return jsCast<const JSWorkerGlobalScopeBase*>(this)->scriptExecutionContext();
dataLog("Unexpected global object: ", JSValue(this), "\n");
RELEASE_ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
void JSDOMGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
Modified: trunk/Source/WebCore/bindings/js/JSDOMPromiseDeferred.h (230763 => 230764)
--- trunk/Source/WebCore/bindings/js/JSDOMPromiseDeferred.h 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebCore/bindings/js/JSDOMPromiseDeferred.h 2018-04-18 16:50:36 UTC (rev 230764)
@@ -33,6 +33,8 @@
namespace WebCore {
+class JSDOMWindow;
+
class DeferredPromise : public DOMGuarded<JSC::JSPromiseDeferred> {
public:
enum class Mode {
Modified: trunk/Source/WebCore/bindings/js/JSDOMWindowProperties.cpp (230763 => 230764)
--- trunk/Source/WebCore/bindings/js/JSDOMWindowProperties.cpp 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebCore/bindings/js/JSDOMWindowProperties.cpp 2018-04-18 16:50:36 UTC (rev 230764)
@@ -89,7 +89,15 @@
if (proto.isObject() && jsCast<JSObject*>(proto)->hasProperty(state, propertyName))
return false;
- auto& window = jsCast<JSDOMWindowBase*>(thisObject->globalObject())->wrapped();
+ auto& vm = state->vm();
+
+ // FIXME: We should probably add support for JSRemoteDOMWindowBase too.
+ auto* jsWindow = jsDynamicCast<JSDOMWindowBase*>(vm, thisObject->globalObject());
+ if (!jsWindow)
+ return false;
+
+ auto& window = jsWindow->wrapped();
+
if (auto* frame = window.frame())
return jsDOMWindowPropertiesGetOwnPropertySlotNamedItemGetter(thisObject, *frame, state, propertyName, slot);
Modified: trunk/Source/WebCore/bindings/js/JSDOMWindowProxy.cpp (230763 => 230764)
--- trunk/Source/WebCore/bindings/js/JSDOMWindowProxy.cpp 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebCore/bindings/js/JSDOMWindowProxy.cpp 2018-04-18 16:50:36 UTC (rev 230764)
@@ -29,8 +29,8 @@
#include "config.h"
#include "JSDOMWindowProxy.h"
+#include "AbstractFrame.h"
#include "CommonVM.h"
-#include "Frame.h"
#include "GCController.h"
#include "JSDOMWindow.h"
#include "JSDOMWindowProperties.h"
@@ -49,7 +49,7 @@
{
}
-void JSDOMWindowProxy::finishCreation(VM& vm, DOMWindow& window)
+void JSDOMWindowProxy::finishCreation(VM& vm, AbstractDOMWindow& window)
{
Base::finishCreation(vm);
ASSERT(inherits(vm, info()));
@@ -56,7 +56,7 @@
setWindow(window);
}
-JSDOMWindowProxy& JSDOMWindowProxy::create(JSC::VM& vm, DOMWindow& window, DOMWrapperWorld& world)
+JSDOMWindowProxy& JSDOMWindowProxy::create(JSC::VM& vm, AbstractDOMWindow& window, DOMWrapperWorld& world)
{
auto& structure = *JSC::Structure::create(vm, 0, jsNull(), JSC::TypeInfo(JSC::PureForwardingProxyType, StructureFlags), info());
auto& proxy = *new (NotNull, JSC::allocateCell<JSDOMWindowProxy>(vm.heap)) JSDOMWindowProxy(vm, structure, world);
Modified: trunk/Source/WebCore/bindings/js/JSDOMWindowProxy.h (230763 => 230764)
--- trunk/Source/WebCore/bindings/js/JSDOMWindowProxy.h 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebCore/bindings/js/JSDOMWindowProxy.h 2018-04-18 16:50:36 UTC (rev 230764)
@@ -43,7 +43,7 @@
class JSDOMWindowProxy final : public JSC::JSProxy {
using Base = JSC::JSProxy;
public:
- static JSDOMWindowProxy& create(JSC::VM&, DOMWindow&, DOMWrapperWorld&);
+ static JSDOMWindowProxy& create(JSC::VM&, AbstractDOMWindow&, DOMWrapperWorld&);
static void destroy(JSCell*);
DECLARE_INFO;
@@ -61,7 +61,7 @@
private:
JSDOMWindowProxy(JSC::VM&, JSC::Structure&, DOMWrapperWorld&);
- void finishCreation(JSC::VM&, DOMWindow&);
+ void finishCreation(JSC::VM&, AbstractDOMWindow&);
Ref<DOMWrapperWorld> m_world;
};
Modified: trunk/Source/WebCore/bindings/js/JSDOMWrapper.cpp (230763 => 230764)
--- trunk/Source/WebCore/bindings/js/JSDOMWrapper.cpp 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebCore/bindings/js/JSDOMWrapper.cpp 2018-04-18 16:50:36 UTC (rev 230764)
@@ -29,6 +29,7 @@
#include "DOMWindow.h"
#include "DOMWrapperWorld.h"
#include "JSDOMWindow.h"
+#include "JSRemoteDOMWindow.h"
#include "SerializedScriptValue.h"
#include "WebCoreJSClientData.h"
#include <_javascript_Core/Error.h>
@@ -37,11 +38,10 @@
STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSDOMObject);
-JSDOMWindow& JSDOMObject::domWindow() const
+JSDOMObject::JSDOMObject(JSC::Structure* structure, JSC::JSGlobalObject& globalObject)
+ : Base(globalObject.vm(), structure)
{
- auto* domWindow = JSC::jsCast<JSDOMWindow*>(JSC::JSNonFinalObject::globalObject());
- ASSERT(domWindow);
- return *domWindow;
+ ASSERT(scriptExecutionContext() || globalObject.classInfo() == JSRemoteDOMWindow::info());
}
CompleteSubspace* outputConstraintSubspaceFor(VM& vm)
Modified: trunk/Source/WebCore/bindings/js/JSDOMWrapper.h (230763 => 230764)
--- trunk/Source/WebCore/bindings/js/JSDOMWrapper.h 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebCore/bindings/js/JSDOMWrapper.h 2018-04-18 16:50:36 UTC (rev 230764)
@@ -27,7 +27,6 @@
namespace WebCore {
-class JSDOMWindow;
class ScriptExecutionContext;
// JSC allows us to extend JSType. If the highest bit is set, we can add any Object types and they are
@@ -63,14 +62,8 @@
JSDOMGlobalObject* globalObject() const { return JSC::jsCast<JSDOMGlobalObject*>(JSC::JSNonFinalObject::globalObject()); }
ScriptExecutionContext* scriptExecutionContext() const { return globalObject()->scriptExecutionContext(); }
- JSDOMWindow& domWindow() const;
-
protected:
- JSDOMObject(JSC::Structure* structure, JSC::JSGlobalObject& globalObject)
- : Base(globalObject.vm(), structure)
- {
- ASSERT(scriptExecutionContext());
- }
+ WEBCORE_EXPORT JSDOMObject(JSC::Structure*, JSC::JSGlobalObject&);
};
WEBCORE_EXPORT JSC::CompleteSubspace* outputConstraintSubspaceFor(JSC::VM&);
Modified: trunk/Source/WebCore/bindings/js/WindowProxyController.cpp (230763 => 230764)
--- trunk/Source/WebCore/bindings/js/WindowProxyController.cpp 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebCore/bindings/js/WindowProxyController.cpp 2018-04-18 16:50:36 UTC (rev 230764)
@@ -79,10 +79,7 @@
VM& vm = world.vm();
- // FIXME: We do not support constructing a JSDOMWindowProxy for a RemoteDOMWindow yet.
- RELEASE_ASSERT(is<DOMWindow>(m_frame.window()));
-
- Strong<JSDOMWindowProxy> windowProxy(vm, &JSDOMWindowProxy::create(vm, *downcast<DOMWindow>(m_frame.window()), world));
+ Strong<JSDOMWindowProxy> windowProxy(vm, &JSDOMWindowProxy::create(vm, *m_frame.window(), world));
Strong<JSDOMWindowProxy> windowProxy2(windowProxy);
m_windowProxies.add(&world, windowProxy);
world.didCreateWindowProxy(this);
@@ -140,11 +137,8 @@
if (&windowProxy->wrapped() == newDOMWindow)
continue;
- // FIXME: We do not support setting a RemoteDOMWindow yet.
- ASSERT(is<DOMWindow>(newDOMWindow));
+ windowProxy->setWindow(*newDOMWindow);
- windowProxy->setWindow(*downcast<DOMWindow>(newDOMWindow));
-
ScriptController* scriptController = nullptr;
Page* page = nullptr;
if (is<Frame>(m_frame)) {
Modified: trunk/Source/WebCore/bridge/objc/WebScriptObject.mm (230763 => 230764)
--- trunk/Source/WebCore/bridge/objc/WebScriptObject.mm 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebCore/bridge/objc/WebScriptObject.mm 2018-04-18 16:50:36 UTC (rev 230764)
@@ -276,7 +276,9 @@
// It's not actually correct to call shouldAllowAccessToFrame in this way because
// JSDOMWindowBase* isn't the right object to represent the currently executing
// _javascript_. Instead, we should use ExecState, like we do elsewhere.
- JSDOMWindowBase* target = jsCast<JSDOMWindowBase*>(root->globalObject());
+ auto* target = JSC::jsDynamicCast<JSDOMWindowBase*>(root->globalObject()->vm(), root->globalObject());
+ if (!target)
+ return false;
return BindingSecurity::shouldAllowAccessToDOMWindow(_private->originRootObject->globalObject()->globalExec(), target->wrapped());
}
Modified: trunk/Source/WebCore/dom/Document.cpp (230763 => 230764)
--- trunk/Source/WebCore/dom/Document.cpp 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebCore/dom/Document.cpp 2018-04-18 16:50:36 UTC (rev 230764)
@@ -4261,6 +4261,8 @@
ASSERT(m_domWindow->document() == this);
ASSERT(m_domWindow->frame() == m_frame);
+
+ m_frame->loader().client().didCreateWindow(*m_domWindow);
}
void Document::takeDOMWindowFrom(Document* document)
Modified: trunk/Source/WebCore/loader/FrameLoaderClient.h (230763 => 230764)
--- trunk/Source/WebCore/loader/FrameLoaderClient.h 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebCore/loader/FrameLoaderClient.h 2018-04-18 16:50:36 UTC (rev 230764)
@@ -71,6 +71,7 @@
class CachedFrame;
class CachedResourceRequest;
class Color;
+class DOMWindow;
class DOMWindowExtension;
class DOMWrapperWorld;
class DocumentLoader;
@@ -365,6 +366,8 @@
virtual void getLoadDecisionForIcons(const Vector<std::pair<WebCore::LinkIcon&, uint64_t>>&) { }
virtual void finishedLoadingIcon(uint64_t, SharedBuffer*) { }
+ virtual void didCreateWindow(DOMWindow&) { }
+
#if ENABLE(APPLICATION_MANIFEST)
virtual void finishedLoadingApplicationManifest(uint64_t, const std::optional<ApplicationManifest>&) { }
#endif
Modified: trunk/Source/WebCore/page/Frame.h (230763 => 230764)
--- trunk/Source/WebCore/page/Frame.h 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebCore/page/Frame.h 2018-04-18 16:50:36 UTC (rev 230764)
@@ -141,7 +141,7 @@
void addDestructionObserver(FrameDestructionObserver*);
void removeDestructionObserver(FrameDestructionObserver*);
- void willDetachPage();
+ WEBCORE_EXPORT void willDetachPage();
void detachFromPage();
void disconnectOwnerElement();
Modified: trunk/Source/WebKit/ChangeLog (230763 => 230764)
--- trunk/Source/WebKit/ChangeLog 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebKit/ChangeLog 2018-04-18 16:50:36 UTC (rev 230764)
@@ -1,3 +1,77 @@
+2018-04-18 Chris Dumez <[email protected]>
+
+ Add support for converting a local window to a remote window
+ https://bugs.webkit.org/show_bug.cgi?id=184515
+ <rdar://problem/39011318>
+
+ Reviewed by Ryosuke Niwa.
+
+ Add initial support for process-swapping when navigating cross-origin as a result
+ of a window.open(). The window object returned by window.open() is initially same
+ origin and is for about:blank. The navigation cross-origin then happens and the
+ JS wrappers for the window then point to a cross-origin window which is remote (i.e.
+ hosted in another WebProcess).
+
+ The RemoteDOMWindow exposed to JS looks like a regular cross-origin Window with a few
+ exceptions due to our incomplete implementation (e.g. w.location returns null) and
+ most of its API is currently not functional. The RemoteDOMWindow API will be implemented
+ in a follow-up by relying on IPC.
+
+ * UIProcess/API/APIProcessPoolConfiguration.cpp:
+ (API::ProcessPoolConfiguration::copy):
+ * UIProcess/API/APIProcessPoolConfiguration.h:
+ * UIProcess/API/C/WKContextConfigurationRef.cpp:
+ (WKContextConfigurationProcessSwapsOnWindowOpenWithOpener):
+ (WKContextConfigurationSetProcessSwapsOnWindowOpenWithOpener):
+ * UIProcess/API/C/WKContextConfigurationRef.h:
+ * UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h:
+ * UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm:
+ (-[_WKProcessPoolConfiguration setProcessSwapsOnWindowOpenWithOpener:]):
+ (-[_WKProcessPoolConfiguration processSwapsOnWindowOpenWithOpener]):
+ Add ProcessPool configuration flag to turn on processSwap on window.open(), even
+ if there is an opener.
+
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::continueNavigationInNewProcess):
+ If the navigation was triggered via window.open(), then set up on handler for when
+ a DOMWindow is constructed for the main frame in the new process.
+
+ (WebKit::WebPageProxy::didCreateWindow):
+ When a Window is constructed for the main frame in a new process on process swap,
+ notify the old process that its representation of the window should become remote
+ and provide it with the Frame / Window identifiers it needs.
+
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/WebPageProxy.messages.in:
+
+ * UIProcess/WebProcessPool.cpp:
+ (WebKit::WebProcessPool::processForNavigation):
+ Do process swapping on cross-origin window.open() if the corresponding setting is
+ enabled.
+
+ * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+ (WebKit::WebFrameLoaderClient::didCreateWindow):
+ * WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
+
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::frameBecameRemote):
+ This is called when process swapping has happened due to a window.open() navigation
+ cross-origin, when a Frame / Window has been constructed in the new process. We do
+ the following:
+ - Construct a RemoteFrame / RemoteWindow using the provided global identifiers to
+ represent the Frame / Window in the new process.
+ - We transfer the WindowProxies from the old Frame's WindowProxyController to the
+ new RemoteFrame's WindowProxyController.
+ - We update the window proxied by those WindowProxies to be the new RemoteWindow.
+ - We detach the old Frame as it is now remote and represented by the new RemoteFrame
+ object we constructed.
+ - If the old frame was the main frame (always the case currently), we close the page
+ as it is no longer needed. The new RemoteFrame is currently owned by the RemoteWindow
+ which is kept alive by its JS wrappers.
+
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.messages.in:
+
2018-04-18 Carlos Garcia Campos <[email protected]>
Unreviewed. Update OptionsGTK.cmake and NEWS for 2.21.1 release.
Modified: trunk/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp (230763 => 230764)
--- trunk/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp 2018-04-18 16:50:36 UTC (rev 230764)
@@ -128,6 +128,7 @@
#endif
copy->m_presentingApplicationPID = this->m_presentingApplicationPID;
copy->m_processSwapsOnNavigation = this->m_processSwapsOnNavigation;
+ copy->m_processSwapsOnWindowOpenWithOpener = this->m_processSwapsOnWindowOpenWithOpener;
return copy;
}
Modified: trunk/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h (230763 => 230764)
--- trunk/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h 2018-04-18 16:50:36 UTC (rev 230764)
@@ -138,6 +138,9 @@
bool processSwapsOnNavigation() const { return m_processSwapsOnNavigation; }
void setProcessSwapsOnNavigation(bool swaps) { m_processSwapsOnNavigation = swaps; }
+ bool processSwapsOnWindowOpenWithOpener() const { return m_processSwapsOnWindowOpenWithOpener; }
+ void setProcessSwapsOnWindowOpenWithOpener(bool swaps) { m_processSwapsOnWindowOpenWithOpener = swaps; }
+
private:
bool m_shouldHaveLegacyDataStore { false };
@@ -170,6 +173,7 @@
bool m_shouldCaptureAudioInUIProcess { false };
ProcessID m_presentingApplicationPID { getCurrentProcessID() };
bool m_processSwapsOnNavigation { false };
+ bool m_processSwapsOnWindowOpenWithOpener { false };
#if PLATFORM(IOS)
WTF::String m_ctDataConnectionServiceType;
Modified: trunk/Source/WebKit/UIProcess/API/C/WKContextConfigurationRef.cpp (230763 => 230764)
--- trunk/Source/WebKit/UIProcess/API/C/WKContextConfigurationRef.cpp 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebKit/UIProcess/API/C/WKContextConfigurationRef.cpp 2018-04-18 16:50:36 UTC (rev 230764)
@@ -167,3 +167,13 @@
{
toImpl(configuration)->setProcessSwapsOnNavigation(swaps);
}
+
+bool WKContextConfigurationProcessSwapsOnWindowOpenWithOpener(WKContextConfigurationRef configuration)
+{
+ return toImpl(configuration)->processSwapsOnWindowOpenWithOpener();
+}
+
+void WKContextConfigurationSetProcessSwapsOnWindowOpenWithOpener(WKContextConfigurationRef configuration, bool swaps)
+{
+ toImpl(configuration)->setProcessSwapsOnWindowOpenWithOpener(swaps);
+}
Modified: trunk/Source/WebKit/UIProcess/API/C/WKContextConfigurationRef.h (230763 => 230764)
--- trunk/Source/WebKit/UIProcess/API/C/WKContextConfigurationRef.h 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebKit/UIProcess/API/C/WKContextConfigurationRef.h 2018-04-18 16:50:36 UTC (rev 230764)
@@ -71,6 +71,9 @@
WK_EXPORT bool WKContextConfigurationProcessSwapsOnNavigation(WKContextConfigurationRef configuration);
WK_EXPORT void WKContextConfigurationSetProcessSwapsOnNavigation(WKContextConfigurationRef configuration, bool swaps);
+WK_EXPORT bool WKContextConfigurationProcessSwapsOnWindowOpenWithOpener(WKContextConfigurationRef configuration);
+WK_EXPORT void WKContextConfigurationSetProcessSwapsOnWindowOpenWithOpener(WKContextConfigurationRef configuration, bool swaps);
+
#ifdef __cplusplus
}
#endif
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h (230763 => 230764)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h 2018-04-18 16:50:36 UTC (rev 230764)
@@ -58,6 +58,7 @@
#endif
@property (nonatomic) pid_t presentingApplicationPID WK_API_AVAILABLE(macosx(10.13), ios(11.0));
@property (nonatomic) BOOL processSwapsOnNavigation WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+@property (nonatomic) BOOL processSwapsOnWindowOpenWithOpener WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
@end
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm (230763 => 230764)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm 2018-04-18 16:50:36 UTC (rev 230764)
@@ -237,6 +237,16 @@
return _processPoolConfiguration->processSwapsOnNavigation();
}
+- (void)setProcessSwapsOnWindowOpenWithOpener:(BOOL)swaps
+{
+ _processPoolConfiguration->setProcessSwapsOnWindowOpenWithOpener(swaps);
+}
+
+- (BOOL)processSwapsOnWindowOpenWithOpener
+{
+ return _processPoolConfiguration->processSwapsOnWindowOpenWithOpener();
+}
+
#if PLATFORM(IOS)
- (NSString *)CTDataConnectionServiceType
{
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (230763 => 230764)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2018-04-18 16:50:36 UTC (rev 230764)
@@ -127,6 +127,8 @@
#include <WebCore/FloatRect.h>
#include <WebCore/FocusDirection.h>
#include <WebCore/FrameLoader.h>
+#include <WebCore/GlobalFrameIdentifier.h>
+#include <WebCore/GlobalWindowIdentifier.h>
#include <WebCore/JSDOMBinding.h>
#include <WebCore/JSDOMExceptionHandling.h>
#include <WebCore/LengthBox.h>
@@ -2413,6 +2415,11 @@
{
LOG(Loading, "Continuing navigation %" PRIu64 " '%s' in a new web process", navigation.navigationID(), navigation.loggingString().utf8().data());
+ Ref<WebProcessProxy> previousProcess = m_process.copyRef();
+ std::optional<uint64_t> navigatedFrameIdentifierInPreviousProcess;
+ if (m_mainFrame)
+ navigatedFrameIdentifierInPreviousProcess = m_mainFrame->frameID();
+
ASSERT(m_process.ptr() != process.ptr());
attachToProcessForNavigation(WTFMove(process));
@@ -2443,6 +2450,15 @@
didReceiveServerRedirectForProvisionalLoadForFrame(m_mainFrame->frameID(), navigation->navigationID(), WTFMove(request), { });
};
}
+
+ if (!navigation.isCrossOriginWindowOpenNavigation() || !navigatedFrameIdentifierInPreviousProcess)
+ return;
+
+ m_mainFrameWindowCreationHandler = [this, previousProcess = WTFMove(previousProcess), navigatedFrameIdentifierInPreviousProcess = *navigatedFrameIdentifierInPreviousProcess](const GlobalWindowIdentifier& windowIdentifier) {
+ ASSERT(m_mainFrame);
+ GlobalFrameIdentifier navigatedFrameIdentifierInNewProcess { pageID(), m_mainFrame->frameID() };
+ previousProcess->send(Messages::WebPage::FrameBecameRemote(navigatedFrameIdentifierInPreviousProcess, navigatedFrameIdentifierInNewProcess, windowIdentifier), pageID());
+ };
}
void WebPageProxy::setUserAgent(String&& userAgent)
@@ -3271,6 +3287,14 @@
m_process->frameCreated(frameID, subFrame.get());
}
+void WebPageProxy::didCreateWindow(uint64_t frameID, GlobalWindowIdentifier&& windowIdentifier)
+{
+ if (m_mainFrame && m_mainFrame->frameID() == frameID) {
+ if (auto mainFrameWindowCreationHandler = WTFMove(m_mainFrameWindowCreationHandler))
+ mainFrameWindowCreationHandler(windowIdentifier);
+ }
+}
+
double WebPageProxy::estimatedProgress() const
{
return m_pageLoadState.estimatedProgress();
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (230763 => 230764)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2018-04-18 16:50:36 UTC (rev 230764)
@@ -177,6 +177,7 @@
struct DictionaryPopupInfo;
struct ExceptionDetails;
struct FileChooserSettings;
+struct GlobalWindowIdentifier;
struct MediaStreamRequest;
struct SecurityOriginData;
struct TextAlternativeWithRange;
@@ -1338,6 +1339,7 @@
void didCreateMainFrame(uint64_t frameID);
void didCreateSubframe(uint64_t frameID);
+ void didCreateWindow(uint64_t frameID, WebCore::GlobalWindowIdentifier&&);
void didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, WebCore::URL&&, WebCore::URL&& unreachableURL, const UserData&);
void didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, WebCore::ResourceRequest&&, const UserData&);
@@ -1780,6 +1782,7 @@
RefPtr<WebFrameProxy> m_mainFrame;
Function<void()> m_mainFrameCreationHandler;
+ Function<void(const WebCore::GlobalWindowIdentifier&)> m_mainFrameWindowCreationHandler;
RefPtr<WebFrameProxy> m_focusedFrame;
RefPtr<WebFrameProxy> m_frameSetLargestFrame;
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in (230763 => 230764)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2018-04-18 16:50:36 UTC (rev 230764)
@@ -115,6 +115,8 @@
DidCreateMainFrame(uint64_t frameID)
DidCreateSubframe(uint64_t frameID)
+ DidCreateWindow(uint64_t frameID, struct WebCore::GlobalWindowIdentifier windowIdentifier)
+
# Frame load messages
DidStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, WebCore::URL url, WebCore::URL unreachableURL, WebKit::UserData userData)
DidReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, WebCore::ResourceRequest request, WebKit::UserData userData)
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (230763 => 230764)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2018-04-18 16:50:36 UTC (rev 230764)
@@ -1985,15 +1985,18 @@
if (!page.process().hasCommittedAnyProvisionalLoads())
return page.process();
- // FIXME: We should support process swap when a window has an opener.
- if (navigation.opener())
- return page.process();
+ if (navigation.isCrossOriginWindowOpenNavigation()) {
+ if (navigation.opener() && !m_configuration->processSwapsOnWindowOpenWithOpener())
+ return page.process();
- if (navigation.isCrossOriginWindowOpenNavigation()) {
action = ""
return createNewWebProcess(page.websiteDataStore());
}
+ // FIXME: We should support process swap when a window has an opener.
+ if (navigation.opener())
+ return page.process();
+
auto targetURL = navigation.currentRequest().url();
auto url = "" { ParsedURLString, page.pageLoadState().url() };
if (!url.isValid() || url.isEmpty() || url.isBlankURL() || protocolHostAndPortAreEqual(url, targetURL))
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (230763 => 230764)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2018-04-18 16:50:36 UTC (rev 230764)
@@ -1876,6 +1876,15 @@
}
}
+void WebFrameLoaderClient::didCreateWindow(DOMWindow& window)
+{
+ auto* webPage = m_frame->page();
+ if (!webPage)
+ return;
+
+ webPage->send(Messages::WebPageProxy::DidCreateWindow(m_frame->frameID(), window.identifier()));
+}
+
#if ENABLE(APPLICATION_MANIFEST)
void WebFrameLoaderClient::finishedLoadingApplicationManifest(uint64_t callbackIdentifier, const std::optional<WebCore::ApplicationManifest>& manifest)
{
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h (230763 => 230764)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h 2018-04-18 16:50:36 UTC (rev 230764)
@@ -269,6 +269,8 @@
void getLoadDecisionForIcons(const Vector<std::pair<WebCore::LinkIcon&, uint64_t>>&) final;
void finishedLoadingIcon(uint64_t callbackIdentifier, WebCore::SharedBuffer*) final;
+ void didCreateWindow(WebCore::DOMWindow&) final;
+
#if ENABLE(APPLICATION_MANIFEST)
void finishedLoadingApplicationManifest(uint64_t, const std::optional<WebCore::ApplicationManifest>&) final;
#endif
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (230763 => 230764)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2018-04-18 16:50:36 UTC (rev 230764)
@@ -182,6 +182,8 @@
#include <WebCore/PrintContext.h>
#include <WebCore/PromisedBlobInfo.h>
#include <WebCore/Range.h>
+#include <WebCore/RemoteDOMWindow.h>
+#include <WebCore/RemoteFrame.h>
#include <WebCore/RenderLayer.h>
#include <WebCore/RenderTheme.h>
#include <WebCore/RenderTreeAsText.h>
@@ -5871,6 +5873,32 @@
m_isSuspended = suspended;
}
+void WebPage::frameBecameRemote(uint64_t frameID, GlobalFrameIdentifier&& remoteFrameIdentifier, GlobalWindowIdentifier&& remoteWindowIdentifier)
+{
+ RefPtr<WebFrame> frame = WebProcess::singleton().webFrame(frameID);
+ if (!frame)
+ return;
+
+ if (frame->page() != this)
+ return;
+
+ auto remoteFrame = RemoteFrame::create(WTFMove(remoteFrameIdentifier));
+ auto remoteWindow = RemoteDOMWindow::create(remoteFrame.copyRef(), WTFMove(remoteWindowIdentifier));
+ UNUSED_PARAM(remoteWindow);
+
+ auto windowProxies = frame->coreFrame()->windowProxyController().releaseWindowProxies();
+ remoteFrame->windowProxyController().setWindowProxies(WTFMove(windowProxies));
+ remoteFrame->windowProxyController().setDOMWindowForWindowProxy(remoteWindow.ptr());
+
+ auto* coreFrame = frame->coreFrame();
+ coreFrame->setView(nullptr);
+ coreFrame->willDetachPage();
+ coreFrame->detachFromPage();
+
+ if (frame->isMainFrame())
+ close();
+}
+
#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
static uint64_t nextRequestStorageAccessContextId()
{
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (230763 => 230764)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2018-04-18 16:50:36 UTC (rev 230764)
@@ -156,6 +156,8 @@
struct CompositionUnderline;
struct DictationAlternative;
+struct GlobalFrameIdentifier;
+struct GlobalWindowIdentifier;
struct Highlight;
struct KeypressCommand;
struct PromisedBlobInfo;
@@ -1383,6 +1385,8 @@
void didReceivePasswordForQuickLookDocument(const String&);
#endif
+ void frameBecameRemote(uint64_t frameID, WebCore::GlobalFrameIdentifier&& remoteFrameIdentifier, WebCore::GlobalWindowIdentifier&& remoteWindowIdentifier);
+
void registerURLSchemeHandler(uint64_t identifier, const String& scheme);
void urlSchemeTaskDidPerformRedirection(uint64_t handlerIdentifier, uint64_t taskIdentifier, WebCore::ResourceResponse&&, WebCore::ResourceRequest&&);
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (230763 => 230764)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2018-04-18 16:50:36 UTC (rev 230764)
@@ -484,6 +484,8 @@
DidReceivePasswordForQuickLookDocument(String password)
#endif
+ FrameBecameRemote(uint64_t frameID, struct WebCore::GlobalFrameIdentifier remoteFrameIdentifier, struct WebCore::GlobalWindowIdentifier remoteWindowIdentifier)
+
RegisterURLSchemeHandler(uint64_t identifier, String scheme)
URLSchemeTaskDidPerformRedirection(uint64_t handlerIdentifier, uint64_t taskIdentifier, WebCore::ResourceResponse response, WebCore::ResourceRequest request)
Modified: trunk/Tools/ChangeLog (230763 => 230764)
--- trunk/Tools/ChangeLog 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Tools/ChangeLog 2018-04-18 16:50:36 UTC (rev 230764)
@@ -1,3 +1,39 @@
+2018-04-18 Chris Dumez <[email protected]>
+
+ Add support for converting a local window to a remote window
+ https://bugs.webkit.org/show_bug.cgi?id=184515
+ <rdar://problem/39011318>
+
+ Reviewed by Ryosuke Niwa.
+
+ * MiniBrowser/mac/AppDelegate.m:
+ (defaultConfiguration):
+ * MiniBrowser/mac/SettingsController.h:
+ * MiniBrowser/mac/SettingsController.m:
+ (-[SettingsController _populateMenu]):
+ (-[SettingsController validateMenuItem:]):
+ (-[SettingsController processSwapOnWindowOpenWithOpenerEnabled]):
+ (-[SettingsController toggleProcessSwapOnWindowOpenWithOpener:]):
+ Add menu entry in minibrowser to turn on process swap on cross-origin window.open().
+
+ * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+ Turn on process swap on cross-origin window.open() for corresponding test and update
+ test to expect that a new WebProcess is created.
+
+ * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
+ (WTR::InjectedBundlePage::decidePolicyForResponse):
+ Add null checks for injectedBundle.testRunner(). When we swap process on navigation,
+ the InjectedBundlePage::decidePolicyForResponse() gets called in the new process.
+ In this new process, we have constructed a InjectedBundlePage for the page but we
+ have not initialized the InjectedBundle members such as testRunner.
+
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::TestController::createWebViewWithOptions):
+ (WTR::updateTestOptionsFromTestHeader):
+ * WebKitTestRunner/TestOptions.h:
+ (WTR::TestOptions::hasSameInitializationOptions const):
+ Add a way for layout tests to turn on process swap on navigation via a test header.
+
2018-04-18 Yusuke Suzuki <[email protected]>
Unreviewed, reland r230697, r230720, and r230724.
Modified: trunk/Tools/MiniBrowser/mac/AppDelegate.m (230763 => 230764)
--- trunk/Tools/MiniBrowser/mac/AppDelegate.m 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Tools/MiniBrowser/mac/AppDelegate.m 2018-04-18 16:50:36 UTC (rev 230764)
@@ -100,6 +100,8 @@
processConfiguration.maximumProcessCount = 1;
if ([SettingsController shared].processSwapOnNavigationEnabled)
processConfiguration.processSwapsOnNavigation = true;
+ if ([SettingsController shared].processSwapOnWindowOpenWithOpenerEnabled)
+ processConfiguration.processSwapsOnWindowOpenWithOpener = true;
configuration.processPool = [[[WKProcessPool alloc] _initWithConfiguration:processConfiguration] autorelease];
Modified: trunk/Tools/MiniBrowser/mac/SettingsController.h (230763 => 230764)
--- trunk/Tools/MiniBrowser/mac/SettingsController.h 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Tools/MiniBrowser/mac/SettingsController.h 2018-04-18 16:50:36 UTC (rev 230764)
@@ -60,6 +60,7 @@
@property (nonatomic, readonly) BOOL usesGameControllerFramework;
@property (nonatomic, readonly) BOOL networkCacheSpeculativeRevalidationDisabled;
@property (nonatomic, readonly) BOOL processSwapOnNavigationEnabled;
+@property (nonatomic, readonly) BOOL processSwapOnWindowOpenWithOpenerEnabled;
@property (nonatomic, readonly) NSString *defaultURL;
Modified: trunk/Tools/MiniBrowser/mac/SettingsController.m (230763 => 230764)
--- trunk/Tools/MiniBrowser/mac/SettingsController.m 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Tools/MiniBrowser/mac/SettingsController.m 2018-04-18 16:50:36 UTC (rev 230764)
@@ -71,6 +71,7 @@
static NSString * const PerWindowWebProcessesDisabledKey = @"PerWindowWebProcessesDisabled";
static NSString * const NetworkCacheSpeculativeRevalidationDisabledKey = @"NetworkCacheSpeculativeRevalidationDisabled";
static NSString * const ProcessSwapOnNavigationKey = @"ProcessSwapOnNavigation";
+static NSString * const ProcessSwapOnWindowOpenWithOpenerKey = @"ProcessSwapOnWindowOpenWithOpener";
typedef NS_ENUM(NSInteger, DebugOverylayMenuItemTag) {
NonFastScrollableRegionOverlayTag = 100,
@@ -181,6 +182,7 @@
[self _addItemWithTitle:@"Use GameController.framework on macOS (Restart required)" action:@selector(toggleUsesGameControllerFramework:) indented:YES];
[self _addItemWithTitle:@"Disable network cache speculative revalidation" action:@selector(toggleNetworkCacheSpeculativeRevalidationDisabled:) indented:YES];
[self _addItemWithTitle:@"Enable Process Swap on Navigation" action:@selector(toggleProcessSwapOnNavigation:) indented:YES];
+ [self _addItemWithTitle:@"Enable Process Swap on window.open() with an opener" action:@selector(toggleProcessSwapOnWindowOpenWithOpener:) indented:YES];
NSMenuItem *debugOverlaysSubmenuItem = [[NSMenuItem alloc] initWithTitle:@"Debug Overlays" action:nil keyEquivalent:@""];
NSMenu *debugOverlaysMenu = [[NSMenu alloc] initWithTitle:@"Debug Overlays"];
@@ -274,6 +276,8 @@
[menuItem setState:[self networkCacheSpeculativeRevalidationDisabled] ? NSControlStateValueOn : NSControlStateValueOff];
else if (action == @selector(toggleProcessSwapOnNavigation:))
[menuItem setState:[self processSwapOnNavigationEnabled] ? NSControlStateValueOn : NSControlStateValueOff];
+ else if (action == @selector(toggleProcessSwapOnWindowOpenWithOpener:))
+ [menuItem setState:[self processSwapOnWindowOpenWithOpenerEnabled] ? NSControlStateValueOn : NSControlStateValueOff];
else if (action == @selector(toggleUseUISideCompositing:))
[menuItem setState:[self useUISideCompositing] ? NSControlStateValueOn : NSControlStateValueOff];
else if (action == @selector(togglePerWindowWebProcessesDisabled:))
@@ -499,6 +503,16 @@
[self _toggleBooleanDefault:ProcessSwapOnNavigationKey];
}
+- (BOOL)processSwapOnWindowOpenWithOpenerEnabled
+{
+ return [[NSUserDefaults standardUserDefaults] boolForKey:ProcessSwapOnWindowOpenWithOpenerKey];
+}
+
+- (void)toggleProcessSwapOnWindowOpenWithOpener:(id)sender
+{
+ [self _toggleBooleanDefault:ProcessSwapOnWindowOpenWithOpenerKey];
+}
+
- (BOOL)isSpaceReservedForBanners
{
return [[NSUserDefaults standardUserDefaults] boolForKey:ReserveSpaceForBannersPreferenceKey];
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm (230763 => 230764)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm 2018-04-18 16:50:36 UTC (rev 230764)
@@ -409,6 +409,7 @@
{
auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
processPoolConfiguration.get().processSwapsOnNavigation = YES;
+ processPoolConfiguration.get().processSwapsOnWindowOpenWithOpener = YES;
auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
@@ -443,8 +444,7 @@
auto pid2 = [createdWebView _webProcessIdentifier];
EXPECT_TRUE(!!pid2);
- // FIXME: This should eventually be false once we support process swapping when there is an opener.
- EXPECT_EQ(pid1, pid2);
+ EXPECT_NE(pid1, pid2);
}
TEST(ProcessSwap, SameOriginWindowOpenNoOpener)
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp (230763 => 230764)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp 2018-04-18 16:50:36 UTC (rev 230764)
@@ -1386,7 +1386,7 @@
WKBundlePagePolicyAction InjectedBundlePage::decidePolicyForResponse(WKBundlePageRef page, WKBundleFrameRef, WKURLResponseRef response, WKURLRequestRef, WKTypeRef*)
{
auto& injectedBundle = InjectedBundle::singleton();
- if (injectedBundle.testRunner()->isPolicyDelegateEnabled() && WKURLResponseIsAttachment(response)) {
+ if (injectedBundle.testRunner() && injectedBundle.testRunner()->isPolicyDelegateEnabled() && WKURLResponseIsAttachment(response)) {
StringBuilder stringBuilder;
WKRetainPtr<WKStringRef> filename = adoptWK(WKURLResponseCopySuggestedFilename(response));
stringBuilder.appendLiteral("Policy delegate: resource is an attachment, suggested file name \'");
@@ -1395,7 +1395,7 @@
InjectedBundle::singleton().outputText(stringBuilder.toString());
}
- if (injectedBundle.testRunner()->shouldDecideResponsePolicyAfterDelay())
+ if (injectedBundle.testRunner() && injectedBundle.testRunner()->shouldDecideResponsePolicyAfterDelay())
return WKBundlePagePolicyActionPassThrough;
WKRetainPtr<WKStringRef> mimeType = adoptWK(WKURLResponseCopyMIMEType(response));
Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (230763 => 230764)
--- trunk/Tools/WebKitTestRunner/TestController.cpp 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp 2018-04-18 16:50:36 UTC (rev 230764)
@@ -497,6 +497,11 @@
WKArrayAppendItem(overrideLanguages.get(), adoptWK(WKStringCreateWithUTF8CString(language.utf8().data())).get());
WKContextConfigurationSetOverrideLanguages(contextConfiguration.get(), overrideLanguages.get());
+ if (options.enableProcessSwapOnNavigation) {
+ WKContextConfigurationSetProcessSwapsOnNavigation(contextConfiguration.get(), true);
+ WKContextConfigurationSetProcessSwapsOnWindowOpenWithOpener(contextConfiguration.get(), true);
+ }
+
auto configuration = generatePageConfiguration(contextConfiguration.get());
// Some preferences (notably mock scroll bars setting) currently cannot be re-applied to an existing view, so we need to set them now.
@@ -1096,6 +1101,8 @@
testOptions.allowCrossOriginSubresourcesToAskForCredentials = parseBooleanTestHeaderValue(value);
if (key == "enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations")
testOptions.enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations = parseBooleanTestHeaderValue(value);
+ if (key == "enableProcessSwapOnNavigation")
+ testOptions.enableProcessSwapOnNavigation = parseBooleanTestHeaderValue(value);
pairStart = pairEnd + 1;
}
}
Modified: trunk/Tools/WebKitTestRunner/TestOptions.h (230763 => 230764)
--- trunk/Tools/WebKitTestRunner/TestOptions.h 2018-04-18 16:33:33 UTC (rev 230763)
+++ trunk/Tools/WebKitTestRunner/TestOptions.h 2018-04-18 16:50:36 UTC (rev 230764)
@@ -56,6 +56,7 @@
bool dumpJSConsoleLogInStdErr { false };
bool allowCrossOriginSubresourcesToAskForCredentials { false };
bool enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations { false };
+ bool enableProcessSwapOnNavigation { false };
float deviceScaleFactor { 1 };
Vector<String> overrideLanguages;
@@ -86,7 +87,8 @@
|| dumpJSConsoleLogInStdErr != options.dumpJSConsoleLogInStdErr
|| applicationManifest != options.applicationManifest
|| allowCrossOriginSubresourcesToAskForCredentials != options.allowCrossOriginSubresourcesToAskForCredentials
- || enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations != options.enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations)
+ || enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations != options.enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations
+ || enableProcessSwapOnNavigation != options.enableProcessSwapOnNavigation)
return false;
return true;