Title: [278548] trunk
Revision
278548
Author
[email protected]
Date
2021-06-07 01:21:03 -0700 (Mon, 07 Jun 2021)

Log Message

[GTK][WPE] Signal "window-object-cleared" not emitted unless frame js context is get before
https://bugs.webkit.org/show_bug.cgi?id=221771

Reviewed by Michael Catanzaro.

Source/WebKit:

This is because when FrameLoader::dispatchDidClearWindowObjectInWorld() is called, the JSWindowProxy for the
world hasn't been created yet, so it returns early. But we want to dispatch it always for worlds created by the
API, to ensure that WebKitScriptWorld::window-object-cleared is emmitted.

* WebProcess/InjectedBundle/API/glib/WebKitWebPage.cpp: Implement globalObjectIsAvailableForFrame() to force the
creation of the _javascript_ context for existing WebKitScriptWorlds.

Tools:

Update window-object-cleared test to check that the signal is emitted for the WebKitScriptWorld objects created
by the extension.

* TestWebKitAPI/Tests/WebKitGLib/TestWebExtensions.cpp:
(UserMessageTest::sendMessage):
(UserMessageTest::viewUserMessageReceived):
(UserMessageTest::waitUntilViewMessagesReceived):
(UserMessageTest::waitUntilViewMessageReceived):
(testWebExtensionWindowObjectCleared):
(beforeAll):
* TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp:
(windowObjectCleared):
(isolatedWorldWindowObjectCleared):
(webkit_web_extension_initialize_with_user_data):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (278547 => 278548)


--- trunk/Source/WebKit/ChangeLog	2021-06-07 06:59:02 UTC (rev 278547)
+++ trunk/Source/WebKit/ChangeLog	2021-06-07 08:21:03 UTC (rev 278548)
@@ -1,3 +1,17 @@
+2021-06-07  Carlos Garcia Campos  <[email protected]>
+
+        [GTK][WPE] Signal "window-object-cleared" not emitted unless frame js context is get before
+        https://bugs.webkit.org/show_bug.cgi?id=221771
+
+        Reviewed by Michael Catanzaro.
+
+        This is because when FrameLoader::dispatchDidClearWindowObjectInWorld() is called, the JSWindowProxy for the
+        world hasn't been created yet, so it returns early. But we want to dispatch it always for worlds created by the
+        API, to ensure that WebKitScriptWorld::window-object-cleared is emmitted.
+
+        * WebProcess/InjectedBundle/API/glib/WebKitWebPage.cpp: Implement globalObjectIsAvailableForFrame() to force the
+        creation of the _javascript_ context for existing WebKitScriptWorlds.
+
 2021-06-06  Commit Queue  <[email protected]>
 
         Unreviewed, reverting r277464.

Modified: trunk/Source/WebKit/WebProcess/InjectedBundle/API/glib/WebKitWebPage.cpp (278547 => 278548)


--- trunk/Source/WebKit/WebProcess/InjectedBundle/API/glib/WebKitWebPage.cpp	2021-06-07 06:59:02 UTC (rev 278547)
+++ trunk/Source/WebKit/WebProcess/InjectedBundle/API/glib/WebKitWebPage.cpp	2021-06-07 08:21:03 UTC (rev 278548)
@@ -218,6 +218,15 @@
             webkitScriptWorldWindowObjectCleared(wkWorld, m_webPage, webkitFrameGetOrCreate(&frame));
     }
 
+    void globalObjectIsAvailableForFrame(WebPage&, WebFrame& frame, DOMWrapperWorld& world) override
+    {
+        // Force the creation of the _javascript_ context for existing WebKitScriptWorlds to
+        // ensure WebKitScriptWorld::window-object-cleared signal is emitted.
+        auto injectedWorld = InjectedBundleScriptWorld::getOrCreate(world);
+        if (webkitScriptWorldGet(injectedWorld.ptr()))
+            frame.jsContextForWorld(injectedWorld.ptr());
+    }
+
     WebKitWebPage* m_webPage;
 };
 

Modified: trunk/Tools/ChangeLog (278547 => 278548)


--- trunk/Tools/ChangeLog	2021-06-07 06:59:02 UTC (rev 278547)
+++ trunk/Tools/ChangeLog	2021-06-07 08:21:03 UTC (rev 278548)
@@ -1,3 +1,25 @@
+2021-06-07  Carlos Garcia Campos  <[email protected]>
+
+        [GTK][WPE] Signal "window-object-cleared" not emitted unless frame js context is get before
+        https://bugs.webkit.org/show_bug.cgi?id=221771
+
+        Reviewed by Michael Catanzaro.
+
+        Update window-object-cleared test to check that the signal is emitted for the WebKitScriptWorld objects created
+        by the extension.
+
+        * TestWebKitAPI/Tests/WebKitGLib/TestWebExtensions.cpp:
+        (UserMessageTest::sendMessage):
+        (UserMessageTest::viewUserMessageReceived):
+        (UserMessageTest::waitUntilViewMessagesReceived):
+        (UserMessageTest::waitUntilViewMessageReceived):
+        (testWebExtensionWindowObjectCleared):
+        (beforeAll):
+        * TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp:
+        (windowObjectCleared):
+        (isolatedWorldWindowObjectCleared):
+        (webkit_web_extension_initialize_with_user_data):
+
 2021-06-06  Darin Adler  <[email protected]>
 
         Handle custom identifiers and strings separately, so we can quote strings correctly consistently

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebExtensions.cpp (278547 => 278548)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebExtensions.cpp	2021-06-07 06:59:02 UTC (rev 278547)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebExtensions.cpp	2021-06-07 08:21:03 UTC (rev 278548)
@@ -165,26 +165,6 @@
     test->m_expectedWebProcessCrash = false;
 }
 
-static void testWebExtensionWindowObjectCleared(WebViewTest* test, gconstpointer)
-{
-    test->loadHtml("<html><header></header><body></body></html>", 0);
-    test->waitUntilLoadFinished();
-
-    GUniqueOutPtr<GError> error;
-    WebKitJavascriptResult* _javascript_Result = test->runJavaScriptAndWaitUntilFinished("window.echo('Foo');", &error.outPtr());
-    g_assert_nonnull(_javascript_Result);
-    g_assert_no_error(error.get());
-    GUniquePtr<char> valueString(WebViewTest::_javascript_ResultToCString(_javascript_Result));
-    g_assert_cmpstr(valueString.get(), ==, "Foo");
-
-    _javascript_Result = test->runJavaScriptAndWaitUntilFinished("var f = new GFile('.'); f.path();", &error.outPtr());
-    g_assert_nonnull(_javascript_Result);
-    g_assert_no_error(error.get());
-    valueString.reset(WebViewTest::_javascript_ResultToCString(_javascript_Result));
-    GUniquePtr<char> currentDirectory(g_get_current_dir());
-    g_assert_cmpstr(valueString.get(), ==, currentDirectory.get());
-}
-
 static gboolean scriptDialogCallback(WebKitWebView*, WebKitScriptDialog* dialog, gpointer)
 {
     g_assert_cmpuint(webkit_script_dialog_get_dialog_type(dialog), ==, WEBKIT_SCRIPT_DIALOG_ALERT);
@@ -567,12 +547,12 @@
     WebKitUserMessage* sendMessage(WebKitUserMessage* message, GError** error = nullptr)
     {
         assertObjectIsDeletedWhenTestFinishes(G_OBJECT(message));
-        m_receivedViewMessage = nullptr;
+        m_receivedViewMessages = { };
         webkit_web_view_send_message_to_page(m_webView, message, nullptr, [](GObject*, GAsyncResult* result, gpointer userData) {
             auto* test = static_cast<UserMessageTest*>(userData);
-            test->m_receivedViewMessage = adoptGRef(webkit_web_view_send_message_to_page_finish(test->m_webView, result, &test->m_receivedError.outPtr()));
-            if (test->m_receivedViewMessage)
-                test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(test->m_receivedViewMessage.get()));
+            test->m_receivedViewMessages.append(adoptGRef(webkit_web_view_send_message_to_page_finish(test->m_webView, result, &test->m_receivedError.outPtr())));
+            if (auto receivedMessage = test->m_receivedViewMessages.first())
+                test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(receivedMessage.get()));
             else
                 g_assert_nonnull(test->m_receivedError.get());
             test->quitMainLoop();
@@ -580,7 +560,7 @@
         g_main_loop_run(m_mainLoop);
         if (error)
             *error = m_receivedError.get();
-        return m_receivedViewMessage.get();
+        return m_receivedViewMessages.first().get();
     }
 
     void sendMessageToAllExtensions(WebKitUserMessage* message)
@@ -592,13 +572,15 @@
     bool viewUserMessageReceived(WebKitUserMessage* message)
     {
         assertObjectIsDeletedWhenTestFinishes(G_OBJECT(message));
-        if (!g_strcmp0(m_expectedViewMessageName.data(), webkit_user_message_get_name(message))) {
-            m_receivedViewMessage = message;
-            quitMainLoop();
+        if (m_expectedViewMessageNames.isEmpty())
+            return false;
 
+        if (m_expectedViewMessageNames.contains(webkit_user_message_get_name(message))) {
+            m_receivedViewMessages.append(message);
+            if (m_receivedViewMessages.size() == m_expectedViewMessageNames.size())
+                quitMainLoop();
             return true;
         }
-
         return false;
     }
 
@@ -615,14 +597,20 @@
         return false;
     }
 
-    WebKitUserMessage* waitUntilViewMessageReceived(const char* messageName)
+    const Vector<GRefPtr<WebKitUserMessage>>& waitUntilViewMessagesReceived(Vector<CString>&& messageNames)
     {
-        m_expectedViewMessageName = messageName;
+        m_expectedViewMessageNames = WTFMove(messageNames);
+        m_receivedViewMessages = { };
         g_main_loop_run(m_mainLoop);
-        m_expectedViewMessageName = { };
-        return m_receivedViewMessage.get();
+        m_expectedViewMessageNames = { };
+        return m_receivedViewMessages;
     }
 
+    WebKitUserMessage* waitUntilViewMessageReceived(const char* messageName)
+    {
+        return waitUntilViewMessagesReceived({ messageName }).first().get();
+    }
+
     WebKitUserMessage* waitUntilContextMessageReceived(const char* messageName)
     {
         m_expectedContextMessageName = messageName;
@@ -631,9 +619,10 @@
         return m_receivedContextMessage.get();
     }
 
-    GRefPtr<WebKitUserMessage> m_receivedViewMessage;
+    Vector<GRefPtr<WebKitUserMessage>> m_receivedViewMessages;
     GRefPtr<WebKitUserMessage> m_receivedContextMessage;
     GUniqueOutPtr<GError> m_receivedError;
+    Vector<CString> m_expectedViewMessageNames;
     CString m_expectedViewMessageName;
     CString m_expectedContextMessageName;
 };
@@ -795,6 +784,28 @@
     test->waitUntilContextMessageReceived("Test.FinishedPingRequest");
 }
 
+static void testWebExtensionWindowObjectCleared(UserMessageTest* test, gconstpointer)
+{
+    test->loadHtml("<html><header></header><body></body></html>", 0);
+
+    auto messages = test->waitUntilViewMessagesReceived({ "WindowObjectCleared", "WindowObjectClearedIsolatedWorld" });
+    g_assert_cmpuint(messages.size(), ==, 2);
+
+    GUniqueOutPtr<GError> error;
+    WebKitJavascriptResult* _javascript_Result = test->runJavaScriptAndWaitUntilFinished("window.echo('Foo');", &error.outPtr());
+    g_assert_nonnull(_javascript_Result);
+    g_assert_no_error(error.get());
+    GUniquePtr<char> valueString(WebViewTest::_javascript_ResultToCString(_javascript_Result));
+    g_assert_cmpstr(valueString.get(), ==, "Foo");
+
+    _javascript_Result = test->runJavaScriptAndWaitUntilFinished("var f = new GFile('.'); f.path();", &error.outPtr());
+    g_assert_nonnull(_javascript_Result);
+    g_assert_no_error(error.get());
+    valueString.reset(WebViewTest::_javascript_ResultToCString(_javascript_Result));
+    GUniquePtr<char> currentDirectory(g_get_current_dir());
+    g_assert_cmpstr(valueString.get(), ==, currentDirectory.get());
+}
+
 void beforeAll()
 {
     WebViewTest::add("WebKitWebExtension", "dom-document-title", testWebExtensionGetTitle);
@@ -803,7 +814,7 @@
 #endif
     WebViewTest::add("WebKitWebExtension", "document-loaded-signal", testDocumentLoadedSignal);
     WebViewTest::add("WebKitWebView", "web-process-crashed", testWebKitWebViewProcessCrashed);
-    WebViewTest::add("WebKitWebExtension", "window-object-cleared", testWebExtensionWindowObjectCleared);
+    UserMessageTest::add("WebKitWebExtension", "window-object-cleared", testWebExtensionWindowObjectCleared);
     WebViewTest::add("WebKitWebExtension", "isolated-world", testWebExtensionIsolatedWorld);
 #if PLATFORM(GTK)
     WebViewTest::add("WebKitWebView", "install-missing-plugins-permission-request", testInstallMissingPluginsPermissionRequest);

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp (278547 => 278548)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp	2021-06-07 06:59:02 UTC (rev 278547)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp	2021-06-07 08:21:03 UTC (rev 278548)
@@ -549,6 +549,7 @@
 
 static void windowObjectCleared(WebKitScriptWorld* world, WebKitWebPage* page, WebKitFrame* frame, gpointer)
 {
+    webkit_web_page_send_message_to_view(page, webkit_user_message_new("WindowObjectCleared", nullptr), nullptr, nullptr, nullptr);
     GRefPtr<JSCContext> jsContext = adoptGRef(webkit_frame_get_js_context_for_script_world(frame, world));
     g_assert_true(JSC_IS_CONTEXT(jsContext.get()));
     GRefPtr<JSCValue> function = adoptGRef(jsc_value_new_function(jsContext.get(), "echo", G_CALLBACK(echoCallback), NULL, NULL, G_TYPE_STRING, 1, G_TYPE_STRING));
@@ -560,6 +561,11 @@
     jsc_context_set_value(jsContext.get(), "GFile", constructor.get());
 }
 
+static void isolatedWorldWindowObjectCleared(WebKitScriptWorld* world, WebKitWebPage* page, WebKitFrame* frame, gpointer)
+{
+    webkit_web_page_send_message_to_view(page, webkit_user_message_new("WindowObjectClearedIsolatedWorld", nullptr), nullptr, nullptr, nullptr);
+}
+
 static WebKitWebPage* getWebPage(WebKitWebExtension* extension, uint64_t pageID, GDBusMethodInvocation* invocation)
 {
     WebKitWebPage* page = webkit_web_extension_get_page(extension, pageID);
@@ -714,6 +720,7 @@
     g_signal_connect(extension, "user-message-received", G_CALLBACK(extensionMessageReceivedCallback), nullptr);
     g_signal_connect(extension, "page-created", G_CALLBACK(pageCreatedCallback), extension);
     g_signal_connect(webkit_script_world_get_default(), "window-object-cleared", G_CALLBACK(windowObjectCleared), nullptr);
+    g_signal_connect(isolatedWorld, "window-object-cleared", G_CALLBACK(isolatedWorldWindowObjectCleared), nullptr);
 
     registerGResource();
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to