Title: [257892] trunk
Revision
257892
Author
achristen...@apple.com
Date
2020-03-04 17:13:20 -0800 (Wed, 04 Mar 2020)

Log Message

Call globalObjectIsAvailableForFrame before evaluating _javascript_ in newly created worlds
https://bugs.webkit.org/show_bug.cgi?id=208615
<rdar://problem/59406743>

Reviewed by Alex Christensen.

Source/WebKit:

globalObjectIsAvailableForFrame is often used for initialization code for a content world.
If we evaluate _javascript_ in a content world as the first thing we do in that world, 
globalObjectIsAvailableForFrame hadn't been called, so things were not initialized.
So call it when evaluating _javascript_ if we create the world to evaluate in.

Covered by new API tests.

* WebProcess/UserContent/WebUserContentController.cpp:
(WebKit::WebUserContentController::addContentWorld):
* WebProcess/UserContent/WebUserContentController.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::runJavaScriptInFrameInScriptWorld):

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/ContentWorldPlugIn.mm: Added.
(-[ContentWorldPlugIn webProcessPlugIn:didCreateBrowserContextController:]):
(-[ContentWorldPlugIn webProcessPlugInBrowserContextController:globalObjectIsAvailableForFrame:inScriptWorld:]):
* TestWebKitAPI/Tests/WebKitCocoa/WKWebViewEvaluateJavaScript.mm:
(TEST):
Also make a test written in bug 206310 actually run code.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (257891 => 257892)


--- trunk/Source/WebKit/ChangeLog	2020-03-05 01:02:51 UTC (rev 257891)
+++ trunk/Source/WebKit/ChangeLog	2020-03-05 01:13:20 UTC (rev 257892)
@@ -1,3 +1,24 @@
+2020-03-04  Alex Christensen  <achristen...@webkit.org>
+
+        Call globalObjectIsAvailableForFrame before evaluating _javascript_ in newly created worlds
+        https://bugs.webkit.org/show_bug.cgi?id=208615
+        <rdar://problem/59406743>
+
+        Reviewed by Alex Christensen.
+
+        globalObjectIsAvailableForFrame is often used for initialization code for a content world.
+        If we evaluate _javascript_ in a content world as the first thing we do in that world, 
+        globalObjectIsAvailableForFrame hadn't been called, so things were not initialized.
+        So call it when evaluating _javascript_ if we create the world to evaluate in.
+
+        Covered by new API tests.
+
+        * WebProcess/UserContent/WebUserContentController.cpp:
+        (WebKit::WebUserContentController::addContentWorld):
+        * WebProcess/UserContent/WebUserContentController.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::runJavaScriptInFrameInScriptWorld):
+
 2020-03-04  Jiewen Tan  <jiewen_...@apple.com>
 
         Unreviewed, a build fix after r257877

Modified: trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.cpp (257891 => 257892)


--- trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.cpp	2020-03-05 01:02:51 UTC (rev 257891)
+++ trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.cpp	2020-03-05 01:13:20 UTC (rev 257892)
@@ -101,13 +101,13 @@
     return iterator == worldMap().end() ? nullptr : iterator->value.first.get();
 }
 
-void WebUserContentController::addContentWorld(const std::pair<ContentWorldIdentifier, String>& world)
+InjectedBundleScriptWorld* WebUserContentController::addContentWorld(const std::pair<ContentWorldIdentifier, String>& world)
 {
     ASSERT(world.first);
     if (world.first == pageContentWorldIdentifier())
-        return;
-
-    worldMap().ensure(world.first, [&] {
+        return nullptr;
+    
+    auto addResult = worldMap().ensure(world.first, [&] {
 #if PLATFORM(GTK) || PLATFORM(WPE)
         // The GLib API doesn't allow to create script worlds from the UI process. We need to
         // use the existing world created by the web extension if any. The world name is used
@@ -117,6 +117,10 @@
 #endif
         return std::make_pair(InjectedBundleScriptWorld::create(world.second, InjectedBundleScriptWorld::Type::User), 1);
     });
+    
+    if (addResult.isNewEntry)
+        return addResult.iterator->value.first.get();
+    return nullptr;
 }
 
 void WebUserContentController::addContentWorlds(const Vector<std::pair<ContentWorldIdentifier, String>>& worlds)

Modified: trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.h (257891 => 257892)


--- trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.h	2020-03-05 01:02:51 UTC (rev 257891)
+++ trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.h	2020-03-05 01:13:20 UTC (rev 257892)
@@ -67,7 +67,7 @@
     InjectedBundleScriptWorld* worldForIdentifier(ContentWorldIdentifier);
 
     void addContentWorlds(const Vector<std::pair<ContentWorldIdentifier, String>>&);
-    void addContentWorld(const std::pair<ContentWorldIdentifier, String>&);
+    InjectedBundleScriptWorld* addContentWorld(const std::pair<ContentWorldIdentifier, String>&);
     void addUserScripts(Vector<WebUserScriptData>&&, InjectUserScriptImmediately);
     void addUserStyleSheets(const Vector<WebUserStyleSheetData>&);
     void addUserScriptMessageHandlers(const Vector<WebScriptMessageHandlerData>&);

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (257891 => 257892)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2020-03-05 01:02:51 UTC (rev 257891)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2020-03-05 01:13:20 UTC (rev 257892)
@@ -3472,7 +3472,13 @@
 void WebPage::runJavaScriptInFrameInScriptWorld(RunJavaScriptParameters&& parameters, Optional<WebCore::FrameIdentifier> frameID, const std::pair<ContentWorldIdentifier, String>& worldData, CallbackID callbackID)
 {
     auto* webFrame = frameID ? WebProcess::singleton().webFrame(*frameID) : mainWebFrame();
-    m_userContentController->addContentWorld(worldData);
+
+    if (auto* newWorld = m_userContentController->addContentWorld(worldData)) {
+        auto& coreWorld = newWorld->coreWorld();
+        for (RefPtr<Frame> frame = mainFrame(); frame; frame = frame->tree().traverseNext())
+            frame->loader().client().dispatchGlobalObjectAvailable(coreWorld);
+    }
+
     runJavaScript(webFrame, WTFMove(parameters), worldData.first, callbackID);
 }
 

Modified: trunk/Tools/ChangeLog (257891 => 257892)


--- trunk/Tools/ChangeLog	2020-03-05 01:02:51 UTC (rev 257891)
+++ trunk/Tools/ChangeLog	2020-03-05 01:13:20 UTC (rev 257892)
@@ -1,3 +1,19 @@
+2020-03-04  Alex Christensen  <achristen...@webkit.org>
+
+        Call globalObjectIsAvailableForFrame before evaluating _javascript_ in newly created worlds
+        https://bugs.webkit.org/show_bug.cgi?id=208615
+        <rdar://problem/59406743>
+
+        Reviewed by Alex Christensen.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/ContentWorldPlugIn.mm: Added.
+        (-[ContentWorldPlugIn webProcessPlugIn:didCreateBrowserContextController:]):
+        (-[ContentWorldPlugIn webProcessPlugInBrowserContextController:globalObjectIsAvailableForFrame:inScriptWorld:]):
+        * TestWebKitAPI/Tests/WebKitCocoa/WKWebViewEvaluateJavaScript.mm:
+        (TEST):
+        Also make a test written in bug 206310 actually run code.
+
 2020-03-04  Aakash Jain  <aakash_j...@apple.com>
 
         [build.webkit.org] Remove leaks queue

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (257891 => 257892)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2020-03-05 01:02:51 UTC (rev 257891)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2020-03-05 01:13:20 UTC (rev 257892)
@@ -397,6 +397,7 @@
 		5C0BF8921DD599B600B00328 /* EarlyKVOCrash.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A9FB6CC1CA34BE500966124 /* EarlyKVOCrash.mm */; };
 		5C0BF8931DD599BD00B00328 /* IsNavigationActionTrusted.mm in Sources */ = {isa = PBXBuildFile; fileRef = 57F10D921C7E7B3800ECDF30 /* IsNavigationActionTrusted.mm */; };
 		5C0BF8941DD599C900B00328 /* MenuTypesForMouseEvents.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7A99D9931AD4A29D00373141 /* MenuTypesForMouseEvents.mm */; };
+		5C121E8D2410704900486F9B /* ContentWorldPlugIn.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C121E8C2410703200486F9B /* ContentWorldPlugIn.mm */; };
 		5C16F8FC230C94370074C4A8 /* TextSize.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C16F8FB230C942B0074C4A8 /* TextSize.mm */; };
 		5C19A5241FD0F60100EEA323 /* CookiePrivateBrowsing.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C19A5231FD0F32600EEA323 /* CookiePrivateBrowsing.mm */; };
 		5C23DF0B2246015800F454B6 /* Challenge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C23DF0A2245C9D700F454B6 /* Challenge.mm */; };
@@ -2027,6 +2028,7 @@
 		5C0160C021A132320077FA32 /* JITEnabled.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JITEnabled.mm; sourceTree = "<group>"; };
 		5C0BF88C1DD5957400B00328 /* MemoryPressureHandler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MemoryPressureHandler.mm; sourceTree = "<group>"; };
 		5C0BF88F1DD5999B00B00328 /* WebViewCanPasteZeroPng.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebViewCanPasteZeroPng.mm; sourceTree = "<group>"; };
+		5C121E8C2410703200486F9B /* ContentWorldPlugIn.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ContentWorldPlugIn.mm; sourceTree = "<group>"; };
 		5C16F8FB230C942B0074C4A8 /* TextSize.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TextSize.mm; sourceTree = "<group>"; };
 		5C19A5231FD0F32600EEA323 /* CookiePrivateBrowsing.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CookiePrivateBrowsing.mm; sourceTree = "<group>"; };
 		5C23DF0A2245C9D700F454B6 /* Challenge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Challenge.mm; sourceTree = "<group>"; };
@@ -2977,6 +2979,7 @@
 				A14FC5861B8991B600D107EB /* ContentFiltering.mm */,
 				A14FC5891B89927100D107EB /* ContentFilteringPlugIn.mm */,
 				5CA1DED81F74A87100E71BD3 /* ContentRuleListNotification.mm */,
+				5C121E8C2410703200486F9B /* ContentWorldPlugIn.mm */,
 				5C3B1D2522A74EA400BCF4D0 /* ContextMenus.mm */,
 				5C2936911D5BF63E00DEAB1E /* CookieAcceptPolicy.mm */,
 				5C19A5231FD0F32600EEA323 /* CookiePrivateBrowsing.mm */,
@@ -5227,6 +5230,7 @@
 				1C2B81831C891F0900A5529F /* CancelFontSubresourcePlugIn.mm in Sources */,
 				5CB18BA81F5645E300EE23C4 /* ClickAutoFillButton.mm in Sources */,
 				A14FC58B1B89927100D107EB /* ContentFilteringPlugIn.mm in Sources */,
+				5C121E8D2410704900486F9B /* ContentWorldPlugIn.mm in Sources */,
 				CEA7F57D2089624B0078EF6E /* DidResignInputElementStrongPasswordAppearance.mm in Sources */,
 				518EE51920A78CE500E024F3 /* DoubleDefersLoadingPlugin.mm in Sources */,
 				5CB5B3C21FFC55CF00C27BB0 /* FrameHandleSerialization.mm in Sources */,

Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ContentWorldPlugIn.mm (0 => 257892)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ContentWorldPlugIn.mm	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ContentWorldPlugIn.mm	2020-03-05 01:13:20 UTC (rev 257892)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2020 Apple 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
+ */
+
+#import "config.h"
+
+#import <WebKit/WKWebProcessPlugIn.h>
+#import <WebKit/WKWebProcessPlugInBrowserContextController.h>
+#import <WebKit/WKWebProcessPlugInFrame.h>
+#import <WebKit/WKWebProcessPlugInLoadDelegate.h>
+#import <WebKit/WKWebProcessPlugInScriptWorld.h>
+
+@interface ContentWorldPlugIn : NSObject <WKWebProcessPlugIn, WKWebProcessPlugInLoadDelegate>
+@end
+
+@implementation ContentWorldPlugIn
+
+- (void)webProcessPlugIn:(WKWebProcessPlugInController *)plugInController didCreateBrowserContextController:(WKWebProcessPlugInBrowserContextController *)browserContextController
+{
+    browserContextController.loadDelegate = self;
+}
+
+- (void)webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController*)controller globalObjectIsAvailableForFrame:(WKWebProcessPlugInFrame *)frame inScriptWorld:(WKWebProcessPlugInScriptWorld *)scriptWorld
+{
+    [[frame jsContextForWorld:scriptWorld] setObject:scriptWorld.name forKeyedSubscript:@"worldName"];
+}
+
+@end

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewEvaluateJavaScript.mm (257891 => 257892)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewEvaluateJavaScript.mm	2020-03-05 01:02:51 UTC (rev 257891)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewEvaluateJavaScript.mm	2020-03-05 01:13:20 UTC (rev 257892)
@@ -31,7 +31,9 @@
 #import "TCPServer.h"
 #import "Test.h"
 #import "TestNavigationDelegate.h"
+#import "TestURLSchemeHandler.h"
 #import "TestWKWebView.h"
+#import "WKWebViewConfigurationExtras.h"
 #import <WebKit/WKWebViewConfigurationPrivate.h>
 #import <WebKit/WKContentWorld.h>
 #import <WebKit/WKErrorPrivate.h>
@@ -38,6 +40,7 @@
 #import <WebKit/WKPreferencesPrivate.h>
 #import <WebKit/WKPreferencesRef.h>
 #import <WebKit/WKWebViewPrivate.h>
+#import <WebKit/_WKFrameTreeNode.h>
 #import <wtf/RetainPtr.h>
 
 static bool isDone;
@@ -136,10 +139,12 @@
     [webView synchronouslyLoadHTMLString:@"<html></html>"];
 
     // Set a variable in the main world via "normal" evaluateJavaScript
-    isDone = false;
+    __block bool isDone = false;
+    __block size_t testsPassed = 0;
     [webView evaluateJavaScript:@"var foo = 'bar'" completionHandler:^(id result, NSError *error) {
         isDone = true;
     }];
+    TestWebKitAPI::Util::run(&isDone);
     isDone = false;
 
     // Verify that value is visible when evaluating in the pageWorld
@@ -147,7 +152,9 @@
         EXPECT_TRUE([result isKindOfClass:[NSString class]]);
         EXPECT_TRUE([result isEqualToString:@"bar"]);
         isDone = true;
+        testsPassed++;
     }];
+    TestWebKitAPI::Util::run(&isDone);
     isDone = false;
 
     // Verify that value is not visible when evaluating in the defaultClientWorld
@@ -154,38 +161,48 @@
     [webView evaluateJavaScript:@"foo" inContentWorld:WKContentWorld.defaultClientWorld completionHandler:^(id result, NSError *error) {
         EXPECT_NULL(result);
         isDone = true;
+        testsPassed++;
     }];
+    TestWebKitAPI::Util::run(&isDone);
     isDone = false;
 
     // Verify that value is visible when calling a function in the pageWorld
-    [webView callAsyncJavaScript:@"return foo" arguments:nil inContentWorld:WKContentWorld.pageWorld completionHandler:[&] (id result, NSError *error) {
+    [webView callAsyncJavaScript:@"return foo" arguments:nil inContentWorld:WKContentWorld.pageWorld completionHandler:^(id result, NSError *error) {
         EXPECT_TRUE([result isKindOfClass:[NSString class]]);
         EXPECT_TRUE([result isEqualToString:@"bar"]);
         isDone = true;
+        testsPassed++;
     }];
+    TestWebKitAPI::Util::run(&isDone);
     isDone = false;
 
     // Verify that value is not visible when calling a function in the defaultClientWorld
-    [webView callAsyncJavaScript:@"return foo" arguments:nil inContentWorld:WKContentWorld.defaultClientWorld completionHandler:[&] (id result, NSError *error) {
+    [webView callAsyncJavaScript:@"return foo" arguments:nil inContentWorld:WKContentWorld.defaultClientWorld completionHandler:^(id result, NSError *error) {
         EXPECT_NULL(result);
         isDone = true;
+        testsPassed++;
     }];
+    TestWebKitAPI::Util::run(&isDone);
     isDone = false;
 
     // Set a varibale value in a named world.
     RetainPtr<WKContentWorld> namedWorld = [WKContentWorld worldWithName:@"NamedWorld"];
-    [webView evaluateJavaScript:@"var bar = baz" inContentWorld:namedWorld.get() completionHandler:^(id result, NSError *error) {
+    [webView evaluateJavaScript:@"var bar = 'baz'" inContentWorld:namedWorld.get() completionHandler:^(id result, NSError *error) {
         EXPECT_NULL(result);
         isDone = true;
+        testsPassed++;
     }];
+    TestWebKitAPI::Util::run(&isDone);
     isDone = false;
 
-    // Set a global varibale value in a named world via a function call.
-    [webView callAsyncJavaScript:@"window.baz = bat" arguments:nil inContentWorld:namedWorld.get() completionHandler:^(id result, NSError *error) {
+    // Set a global variable value in a named world via a function call.
+    [webView callAsyncJavaScript:@"window.baz = 'bat'" arguments:nil inContentWorld:namedWorld.get() completionHandler:^(id result, NSError *error) {
         EXPECT_NULL(result);
         EXPECT_NULL(error);
         isDone = true;
+        testsPassed++;
     }];
+    TestWebKitAPI::Util::run(&isDone);
     isDone = false;
 
     // Verify they are there in that named world.
@@ -193,7 +210,9 @@
         EXPECT_TRUE([result isKindOfClass:[NSString class]]);
         EXPECT_TRUE([result isEqualToString:@"baz"]);
         isDone = true;
+        testsPassed++;
     }];
+    TestWebKitAPI::Util::run(&isDone);
     isDone = false;
 
     [webView evaluateJavaScript:@"window.baz" inContentWorld:namedWorld.get() completionHandler:^(id result, NSError *error) {
@@ -200,7 +219,9 @@
         EXPECT_TRUE([result isKindOfClass:[NSString class]]);
         EXPECT_TRUE([result isEqualToString:@"bat"]);
         isDone = true;
+        testsPassed++;
     }];
+    TestWebKitAPI::Util::run(&isDone);
     isDone = false;
 
     // Verify they aren't there in the defaultClientWorld.
@@ -207,13 +228,17 @@
     [webView evaluateJavaScript:@"bar" inContentWorld:WKContentWorld.defaultClientWorld completionHandler:^(id result, NSError *error) {
         EXPECT_NULL(result);
         isDone = true;
+        testsPassed++;
     }];
+    TestWebKitAPI::Util::run(&isDone);
     isDone = false;
 
     [webView evaluateJavaScript:@"window.baz" inContentWorld:WKContentWorld.defaultClientWorld completionHandler:^(id result, NSError *error) {
         EXPECT_NULL(result);
         isDone = true;
+        testsPassed++;
     }];
+    TestWebKitAPI::Util::run(&isDone);
     isDone = false;
 
     // Verify they aren't there in the pageWorld.
@@ -220,16 +245,74 @@
     [webView evaluateJavaScript:@"bar" inContentWorld:WKContentWorld.pageWorld completionHandler:^(id result, NSError *error) {
         EXPECT_NULL(result);
         isDone = true;
+        testsPassed++;
     }];
+    TestWebKitAPI::Util::run(&isDone);
     isDone = false;
 
     [webView evaluateJavaScript:@"window.baz" inContentWorld:WKContentWorld.pageWorld completionHandler:^(id result, NSError *error) {
         EXPECT_NULL(result);
         isDone = true;
+        testsPassed++;
     }];
+    TestWebKitAPI::Util::run(&isDone);
     isDone = false;
+    
+    EXPECT_EQ(testsPassed, 12u);
 }
 
+TEST(WKWebView, EvaluateJavaScriptInWorldsWithGlobalObjectAvailable)
+{
+    WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"ContentWorldPlugIn"];
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
+    [webView synchronouslyLoadHTMLString:@"<html></html>"];
+
+    __block bool done = false;
+    [webView evaluateJavaScript:@"window.worldName" inContentWorld:[WKContentWorld worldWithName:@"testName"] completionHandler:^(id result, NSError *error) {
+        EXPECT_WK_STREQ(result, "testName");
+        done = true;
+    }];
+    TestWebKitAPI::Util::run(&done);
+}
+
+TEST(WKWebView, EvaluateJavaScriptInWorldsWithGlobalObjectAvailableInCrossOriginIframe)
+{
+    WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"ContentWorldPlugIn"];
+    auto handler = adoptNS([TestURLSchemeHandler new]);
+    __block bool childFrameLoaded = false;
+    [handler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
+        NSString *responseString = nil;
+        if ([task.request.URL.absoluteString isEqualToString:@"frame://host1/"])
+            responseString = @"<iframe src='' _onload_='fetch(\"loadedChildFrame\")'></iframe>";
+        else if ([task.request.URL.absoluteString isEqualToString:@"frame://host2/"])
+            responseString = @"frame content";
+        else if ([task.request.URL.path isEqualToString:@"/loadedChildFrame"]) {
+            responseString = @"fetched content";
+            childFrameLoaded = true;
+        }
+
+        ASSERT(responseString);
+        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:responseString.length textEncodingName:nil]);
+        [task didReceiveResponse:response.get()];
+        [task didReceiveData:[responseString dataUsingEncoding:NSUTF8StringEncoding]];
+        [task didFinish];
+    }];
+    [configuration setURLSchemeHandler:handler.get() forURLScheme:@"frame"];
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
+    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"frame://host1/"]]];
+
+    TestWebKitAPI::Util::run(&childFrameLoaded);
+    
+    __block bool done = false;
+    [webView _frames:^(_WKFrameTreeNode *mainFrame) {
+        [webView _evaluateJavaScript:@"window.worldName" inFrame:mainFrame.childFrames[0] inContentWorld:[WKContentWorld worldWithName:@"testName"] completionHandler:^(id result, NSError *error) {
+            EXPECT_WK_STREQ(result, "testName");
+            done = true;
+        }];
+    }];
+    TestWebKitAPI::Util::run(&done);
+}
+
 TEST(WebKit, EvaluateJavaScriptInAttachments)
 {
     // Attachments displayed inline are in sandboxed documents.
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to