Diff
Modified: trunk/Source/WebKit/ChangeLog (254667 => 254668)
--- trunk/Source/WebKit/ChangeLog 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/ChangeLog 2020-01-16 05:41:03 UTC (rev 254668)
@@ -1,3 +1,85 @@
+2020-01-15 Brady Eidson <beid...@apple.com>
+
+ Add WKContentWorld SPI, and use it in _javascript_ execution.
+ https://bugs.webkit.org/show_bug.cgi?id=206310
+
+ Reviewed by Alex Christensen.
+
+ Covered by API tests.
+
+ _WKContentWorld is a UI Process wrapper for an InjectedBundleScriptWorld.
+ Much like _WKUserContentWorld is. But different in that:
+ - Its APIs are named different things
+ - Only one unique instance per string name
+ - It is used with evaluateJavascript: and callAsyncJavaScriptFunction: instead of WKUserContentController.
+
+ But _WKContentWorld and _WKUserContentWorld do have to work together a little bit to avoid conflicts in the WebProcess.
+
+ The new versions of evaluateJavascript: and callAsyncJavaScriptFunction: are also included, as well as API tests for all the new stuff.
+
+ * Shared/API/APIObject.h:
+ * Shared/Cocoa/APIObject.mm:
+ (API::Object::newObject):
+
+ * UIProcess/API/APIContentWorld.cpp: Copied from Source/WebKit/UIProcess/API/APIUserContentWorld.cpp.
+ (API::ContentWorld::sharedWorldWithName):
+ (API::ContentWorld::pageContentWorld):
+ (API::ContentWorld::defaultClientWorld):
+ (API::ContentWorld::ContentWorld):
+ (API::ContentWorld::~ContentWorld):
+ * UIProcess/API/APIContentWorld.h: Copied from Source/WebKit/UIProcess/API/APIUserContentWorld.h.
+
+ * UIProcess/API/APIUserContentWorld.cpp:
+ (API::UserContentWorld::generateIdentifier):
+ (API::UserContentWorld::UserContentWorld):
+ (API::generateIdentifier): Deleted.
+ * UIProcess/API/APIUserContentWorld.h:
+
+ * UIProcess/API/Cocoa/WKWebView.mm:
+ (-[WKWebView evaluateJavaScript:completionHandler:]):
+ (-[WKWebView _evaluateJavaScript:asAsyncFunction:withArguments:forceUserGesture:completionHandler:inWorld:]):
+ (-[WKWebView _callAsyncJavaScriptFunction:withArguments:inWorld:completionHandler:]):
+ (-[WKWebView _evaluateJavaScript:inWorld:completionHandler:]):
+ (-[WKWebView _evaluateJavaScriptWithoutUserGesture:completionHandler:]):
+ (-[WKWebView _evaluateJavaScript:asAsyncFunction:withArguments:forceUserGesture:completionHandler:]): Deleted.
+ (-[WKWebView _callAsyncFunction:withArguments:completionHandler:]): Deleted.
+ * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+
+ * UIProcess/API/Cocoa/_WKContentWorld.h: Added.
+ * UIProcess/API/Cocoa/_WKContentWorld.mm: Copied from Source/WebKit/UIProcess/API/APIUserContentWorld.h.
+ (+[_WKContentWorld pageContentWorld]):
+ (+[_WKContentWorld defaultClientWorld]):
+ (+[_WKContentWorld worldWithName:]):
+ (-[_WKContentWorld dealloc]):
+ (-[_WKContentWorld name]):
+ (-[_WKContentWorld _apiObject]):
+ * UIProcess/API/Cocoa/_WKContentWorldInternal.h: Copied from Source/WebKit/UIProcess/API/APIUserContentWorld.h.
+
+ * UIProcess/UserContent/WebUserContentControllerProxy.cpp:
+ * UIProcess/UserContent/WebUserContentControllerProxy.h:
+
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::runJavaScriptInMainFrame):
+ (WebKit::WebPageProxy::runJavaScriptInMainFrameScriptWorld):
+ * UIProcess/WebPageProxy.h:
+
+ * WebProcess/UserContent/WebUserContentController.cpp:
+ (WebKit::worldMap):
+ (WebKit::WebUserContentController::worldForIdentifier):
+ (WebKit::WebUserContentController::addUserContentWorld):
+ (WebKit::WebUserContentController::addUserContentWorlds):
+ * WebProcess/UserContent/WebUserContentController.h:
+
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::runJavaScript):
+ (WebKit::WebPage::runJavaScriptInMainFrameScriptWorld):
+ (WebKit::WebPage::runJavaScriptInFrame):
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.messages.in:
+
+ * Sources.txt:
+ * WebKit.xcodeproj/project.pbxproj:
+
2020-01-15 Ross Kirsling <ross.kirsl...@sony.com>
[PlayStation] Add stubs for WebContextMenuClient
Modified: trunk/Source/WebKit/Shared/API/APIObject.h (254667 => 254668)
--- trunk/Source/WebKit/Shared/API/APIObject.h 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/Shared/API/APIObject.h 2020-01-16 05:41:03 UTC (rev 254668)
@@ -110,6 +110,7 @@
ContentRuleList,
ContentRuleListAction,
ContentRuleListStore,
+ ContentWorld,
#if PLATFORM(IOS_FAMILY)
ContextMenuElementInfo,
#endif
Modified: trunk/Source/WebKit/Shared/Cocoa/APIObject.mm (254667 => 254668)
--- trunk/Source/WebKit/Shared/Cocoa/APIObject.mm 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/Shared/Cocoa/APIObject.mm 2020-01-16 05:41:03 UTC (rev 254668)
@@ -71,6 +71,7 @@
#import "_WKAttachmentInternal.h"
#import "_WKAutomationSessionInternal.h"
#import "_WKContentRuleListActionInternal.h"
+#import "_WKContentWorldInternal.h"
#import "_WKCustomHeaderFieldsInternal.h"
#import "_WKDownloadInternal.h"
#import "_WKExperimentalFeatureInternal.h"
@@ -346,6 +347,10 @@
wrapper = [_WKResourceLoadStatisticsThirdParty alloc];
break;
+ case Type::ContentWorld:
+ wrapper = [_WKContentWorld alloc];
+ break;
+
case Type::UserContentWorld:
wrapper = [_WKUserContentWorld alloc];
break;
Modified: trunk/Source/WebKit/Sources.txt (254667 => 254668)
--- trunk/Source/WebKit/Sources.txt 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/Sources.txt 2020-01-16 05:41:03 UTC (rev 254668)
@@ -326,6 +326,7 @@
UIProcess/API/APIContentRuleList.cpp
UIProcess/API/APIContentRuleListAction.cpp
UIProcess/API/APIContentRuleListStore.cpp
+UIProcess/API/APIContentWorld.cpp
UIProcess/API/APIContextMenuElementInfo.cpp
UIProcess/API/APIDebuggableInfo.cpp
UIProcess/API/APIExperimentalFeature.cpp
Copied: trunk/Source/WebKit/UIProcess/API/APIContentWorld.cpp (from rev 254666, trunk/Source/WebKit/UIProcess/API/APIUserContentWorld.cpp) (0 => 254668)
--- trunk/Source/WebKit/UIProcess/API/APIContentWorld.cpp (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/APIContentWorld.cpp 2020-01-16 05:41:03 UTC (rev 254668)
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "APIContentWorld.h"
+
+#include "APIUserContentWorld.h"
+
+namespace API {
+
+static HashMap<WTF::String, ContentWorld*>& sharedWorldMap()
+{
+ static HashMap<WTF::String, ContentWorld*>* sharedMap = new HashMap<WTF::String, ContentWorld*>;
+ return *sharedMap;
+}
+
+Ref<ContentWorld> ContentWorld::sharedWorldWithName(const WTF::String& name)
+{
+ auto result = sharedWorldMap().add(name, nullptr);
+ if (result.isNewEntry) {
+ result.iterator->value = new ContentWorld(name);
+ return adoptRef(*result.iterator->value);
+ }
+
+ return makeRef(*result.iterator->value);
+}
+
+ContentWorld& ContentWorld::pageContentWorld()
+{
+ static NeverDestroyed<RefPtr<ContentWorld>> world(adoptRef(new ContentWorld(API::UserContentWorld::normalWorldIdentifer())));
+ return *world.get();
+}
+
+ContentWorld& ContentWorld::defaultClientWorld()
+{
+ static NeverDestroyed<RefPtr<ContentWorld>> world(adoptRef(new ContentWorld(API::UserContentWorld::generateIdentifier())));
+ return *world.get();
+}
+
+ContentWorld::ContentWorld(const WTF::String& name)
+ : m_identifier(API::UserContentWorld::generateIdentifier())
+ , m_name(name)
+{
+}
+
+ContentWorld::ContentWorld(uint64_t identifier)
+ : m_identifier(identifier)
+{
+}
+
+ContentWorld::~ContentWorld()
+{
+ if (m_name.isNull())
+ return;
+
+ auto taken = sharedWorldMap().take(m_name);
+ ASSERT_UNUSED(taken, taken == this);
+}
+
+} // namespace API
Copied: trunk/Source/WebKit/UIProcess/API/APIContentWorld.h (from rev 254666, trunk/Source/WebKit/UIProcess/API/APIUserContentWorld.h) (0 => 254668)
--- trunk/Source/WebKit/UIProcess/API/APIContentWorld.h (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/APIContentWorld.h 2020-01-16 05:41:03 UTC (rev 254668)
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "APIObject.h"
+#include <wtf/text/WTFString.h>
+
+namespace API {
+
+class ContentWorld final : public API::ObjectImpl<API::Object::Type::ContentWorld> {
+public:
+ static Ref<ContentWorld> sharedWorldWithName(const WTF::String&);
+ static ContentWorld& pageContentWorld();
+ static ContentWorld& defaultClientWorld();
+
+ virtual ~ContentWorld();
+
+ const WTF::String& name() const { return m_name; }
+ uint64_t identifier() const { return m_identifier; }
+
+ std::pair<uint64_t, WTF::String> worldData() { return { m_identifier, m_name }; }
+
+private:
+ ContentWorld(const WTF::String&);
+ ContentWorld(uint64_t identifier);
+
+ // FIXME: This should be an ObjectIdentifier once we can get all ScriptWorld related classes to use ObjectIdentifier.
+ uint64_t m_identifier;
+ WTF::String m_name;
+};
+
+} // namespace API
Modified: trunk/Source/WebKit/UIProcess/API/APIUserContentWorld.cpp (254667 => 254668)
--- trunk/Source/WebKit/UIProcess/API/APIUserContentWorld.cpp 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/UIProcess/API/APIUserContentWorld.cpp 2020-01-16 05:41:03 UTC (rev 254668)
@@ -28,11 +28,9 @@
namespace API {
-static const uint64_t normalWorldIdentifer = 1;
-
-static uint64_t generateIdentifier()
+uint64_t UserContentWorld::generateIdentifier()
{
- static uint64_t identifier = normalWorldIdentifer;
+ static uint64_t identifier = normalWorldIdentifer();
return ++identifier;
}
@@ -55,7 +53,7 @@
}
UserContentWorld::UserContentWorld(ForNormalWorldOnly)
- : m_identifier(normalWorldIdentifer)
+ : m_identifier(normalWorldIdentifer())
{
}
Modified: trunk/Source/WebKit/UIProcess/API/APIUserContentWorld.h (254667 => 254668)
--- trunk/Source/WebKit/UIProcess/API/APIUserContentWorld.h 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/UIProcess/API/APIUserContentWorld.h 2020-01-16 05:41:03 UTC (rev 254668)
@@ -31,6 +31,8 @@
namespace API {
+class ContentWorld;
+
class UserContentWorld final : public API::ObjectImpl<API::Object::Type::UserContentWorld> {
public:
static Ref<UserContentWorld> worldWithName(const WTF::String&);
@@ -41,12 +43,18 @@
const WTF::String& name() const { return m_name; }
uint64_t identifier() const { return m_identifier; }
+ static uint64_t normalWorldIdentifer() { return 1; };
+
private:
+ friend class ContentWorld;
+
UserContentWorld(const WTF::String&);
enum class ForNormalWorldOnly { NormalWorld };
UserContentWorld(ForNormalWorldOnly);
+ static uint64_t generateIdentifier();
+
uint64_t m_identifier;
WTF::String m_name;
};
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (254667 => 254668)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2020-01-16 05:41:03 UTC (rev 254668)
@@ -91,6 +91,7 @@
#import "WebURLSchemeHandlerCocoa.h"
#import "WebViewImpl.h"
#import "_WKActivatedElementInfoInternal.h"
+#import "_WKContentWorldInternal.h"
#import "_WKDiagnosticLoggingDelegate.h"
#import "_WKFindDelegate.h"
#import "_WKFrameHandleInternal.h"
@@ -814,7 +815,7 @@
- (void)evaluateJavaScript:(NSString *)_javascript_String completionHandler:(void (^)(id, NSError *))completionHandler
{
- [self _evaluateJavaScript:_javascript_String asAsyncFunction:NO withArguments:nil forceUserGesture:YES completionHandler:completionHandler];
+ [self _evaluateJavaScript:_javascript_String asAsyncFunction:NO withArguments:nil forceUserGesture:YES completionHandler:completionHandler inWorld:_WKContentWorld.pageContentWorld];
}
static bool validateArgument(id argument)
@@ -851,7 +852,7 @@
return false;
}
-- (void)_evaluateJavaScript:(NSString *)_javascript_String asAsyncFunction:(BOOL)asAsyncFunction withArguments:(NSDictionary<NSString *, id> *)arguments forceUserGesture:(BOOL)forceUserGesture completionHandler:(void (^)(id, NSError *))completionHandler
+- (void)_evaluateJavaScript:(NSString *)_javascript_String asAsyncFunction:(BOOL)asAsyncFunction withArguments:(NSDictionary<NSString *, id> *)arguments forceUserGesture:(BOOL)forceUserGesture completionHandler:(void (^)(id, NSError *))completionHandler inWorld:(_WKContentWorld *)world
{
auto handler = adoptNS([completionHandler copy]);
@@ -888,7 +889,7 @@
return;
}
- _page->runJavaScriptInMainFrame(WebCore::RunJavaScriptParameters { _javascript_String, !!asAsyncFunction, WTFMove(argumentsMap), !!forceUserGesture }, [handler](API::SerializedScriptValue* serializedScriptValue, Optional<WebCore::ExceptionDetails> details, WebKit::ScriptValueCallback::Error errorCode) {
+ _page->runJavaScriptInMainFrameScriptWorld(WebCore::RunJavaScriptParameters { _javascript_String, !!asAsyncFunction, WTFMove(argumentsMap), !!forceUserGesture }, *world->_contentWorld.get(), [handler](API::SerializedScriptValue* serializedScriptValue, Optional<WebCore::ExceptionDetails> details, WebKit::ScriptValueCallback::Error errorCode) {
if (!handler)
return;
@@ -1504,6 +1505,16 @@
#pragma mark - macOS/iOS WKPrivate
+- (void)_callAsyncJavaScriptFunction:(NSString *)_javascript_String withArguments:(NSDictionary<NSString *, id> *)arguments inWorld:(_WKContentWorld *)contentWorld completionHandler:(void (^)(id, NSError *error))completionHandler
+{
+ [self _evaluateJavaScript:_javascript_String asAsyncFunction:YES withArguments:arguments forceUserGesture:YES completionHandler:completionHandler inWorld:contentWorld];
+}
+
+- (void)_evaluateJavaScript:(NSString *)_javascript_String inWorld:(_WKContentWorld *)contentWorld completionHandler:(void (^)(id, NSError *))completionHandler
+{
+ [self _evaluateJavaScript:_javascript_String asAsyncFunction:NO withArguments:nil forceUserGesture:YES completionHandler:completionHandler inWorld:contentWorld];
+}
+
- (_WKSelectionAttributes)_selectionAttributes
{
return _selectionAttributes;
@@ -1987,11 +1998,6 @@
[self createPDFWithConfiguration:pdfConfiguration completionHandler:completionHandler];
}
-- (void)_callAsyncFunction:(NSString *)_javascript_String withArguments:(NSDictionary<NSString *, id> *)arguments completionHandler:(void (^)(id, NSError *error))completionHandler
-{
- [self _evaluateJavaScript:_javascript_String asAsyncFunction:YES withArguments:arguments forceUserGesture:YES completionHandler:completionHandler];
-}
-
- (NSData *)_sessionStateData
{
// FIXME: This should not use the legacy session state encoder.
@@ -2134,7 +2140,7 @@
- (void)_evaluateJavaScriptWithoutUserGesture:(NSString *)_javascript_String completionHandler:(void (^)(id, NSError *))completionHandler
{
- [self _evaluateJavaScript:_javascript_String asAsyncFunction:NO withArguments:nil forceUserGesture:NO completionHandler:completionHandler];
+ [self _evaluateJavaScript:_javascript_String asAsyncFunction:NO withArguments:nil forceUserGesture:NO completionHandler:completionHandler inWorld:_WKContentWorld.pageContentWorld];
}
- (void)_updateWebsitePolicies:(_WKWebsitePolicies *)websitePolicies
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h (254667 => 254668)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h 2020-01-16 05:41:03 UTC (rev 254668)
@@ -106,6 +106,7 @@
@class WKBrowsingContextHandle;
@class WKWebpagePreferences;
@class _WKApplicationManifest;
+@class _WKContentWorld;
@class _WKFrameHandle;
@class _WKHitTestResult;
@class _WKInspector;
@@ -318,8 +319,59 @@
- (void)_takePDFSnapshotWithConfiguration:(WKSnapshotConfiguration *)snapshotConfiguration completionHandler:(void (^)(NSData *pdfSnapshotData, NSError *error))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
-- (void)_callAsyncFunction:(NSString *)_javascript_String withArguments:(NSDictionary<NSString *, id> *)arguments completionHandler:(void (^)(id, NSError *error))completionHandler;
+/* @abstract Calls the given _javascript_ string as a function, passing the given named arguments to that function.
+ @param _javascript_String The _javascript_ string to call as a function.
+ @param arguments A dictionary representing the arguments to be passed to the function call.
+ @param contentWorld The WKContentWorld in which to call the _javascript_ function.
+ @param completionHandler A block to invoke with the return value of the function call, or with the asynchronous resolution of the function's return value.
+ @discussion The _javascript_ string is treated as an anonymous _javascript_ function that can be called with named arguments.
+ Pass in _javascript_ string formatted for evaluation, not as one of the variants of function call available in _javascript_.
+ For example:
+ return x ? y : z;
+ The arguments dictionary supplies the values for those arguments which are serialized into _javascript_ equivalents.
+ For example:
+ @{ @"x" : @YES, @"y" : @1, @"z" : @2 };
+
+ Combining the above arguments dictionary with the above _javascript_ string, a function with the arguments "x", "y", and "z" is called with values YES, 1, and 2 respectively.
+
+ Allowed argument types are:
+ NSNumber, NSString, NSDate, NSArray, NSDictionary, and NSNull.
+ Any NSArray or NSDictionary containers can only contain objects of those types.
+
+ No matter which WKContentWorld you use to call your _javascript_ function, you can make changes to the underlying web content. (e.g. the Document and its DOM structure)
+ Such changes will be visible to script executing in all WKContentWorlds.
+ Calling your _javascript_ function can leave behind other changes to global state visibile to _javascript_. (e.g. `window.myVariable = 1;`)
+ Those changes will only be visibile to scripts executed in the same WKContentWorld.
+
+ Your completion handler will be called with the return value of your _javascript_ function.
+ If your _javascript_ does not explicitly return any value, that undefined result manifests as nil being passed to your completion handler.
+ If your _javascript_ returns null, that result manifests as NSNull being passed to your completion handler.
+
+ _javascript_ has the concept of a "thenable" object, which is any _javascript_ object that has a callable "then" property.
+ The most well known example of a "thenable" object is a _javascript_ promise.
+ If your _javascript_ returns a "thenable" object WebKit will call "then" on the resulting object and wait for it to be resolved.
+
+ If the object calls "fulfill", your completion handler will be called with the result.
+ If the object calls "reject", your completion handler will be called with a WKErrorJavaScriptAsyncFunctionResultRejected error containing the reject reason in the userInfo dictionary.
+ If the object is garbage collected before it is resolved, your completion handler will be called with an error indicating that it will never be resolved.
+*/
+- (void)_callAsyncJavaScriptFunction:(NSString *)_javascript_String withArguments:(NSDictionary<NSString *, id> *)arguments inWorld:(_WKContentWorld *)contentWorld completionHandler:(void (^)(id, NSError *error))completionHandler;
+
+/* @abstract Evaluates the given _javascript_ string.
+ @param _javascript_String The _javascript_ string to evaluate.
+ @param contentWorld The WKContentWorld in which to evaluate the _javascript_ string.
+ @param completionHandler A block to invoke when script evaluation completes or fails.
+ @discussion The completionHandler is passed the result of the script evaluation or an error.
+ No matter which WKContentWorld you use to evaluate your _javascript_ string, you can make changes to the underlying web content. (e.g. the Document and its DOM structure)
+ Such changes will be visible to script executing in all WKContentWorlds.
+ Evaluating your _javascript_ string can leave behind other changes to global state visibile to _javascript_. (e.g. `window.myVariable = 1;`)
+ Those changes will only be visibile to scripts executed in the same WKContentWorld.
+ evaluateJavaScript: is the best way to set up global state for future _javascript_ execution in a given world. (e.g. Importing libraries/utilities that future _javascript_ execution will rely on)
+ Once your global state is set up, consider using callAsyncJavaScriptFunction: for more flexible interaction with the _javascript_ programming model.
+*/
+- (void)_evaluateJavaScript:(NSString *)_javascript_String inWorld:(_WKContentWorld *)contentWorld completionHandler:(void (^)(id, NSError *error))completionHandler;
+
@end
#if TARGET_OS_IPHONE
Added: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKContentWorld.h (0 => 254668)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKContentWorld.h (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKContentWorld.h 2020-01-16 05:41:03 UTC (rev 254668)
@@ -0,0 +1,69 @@
+/*
+ * 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 <WebKit/WKFoundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+/*!
+A WKContentWorld object allows you to seperate your application's interaction with content displayed in a WKWebView into different roles that cannot interfere with one another.
+*/
+WK_CLASS_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA))
+@interface _WKContentWorld : NSObject
+
++ (instancetype)new NS_UNAVAILABLE;
+- (instancetype)init NS_UNAVAILABLE;
+
+/*! @abstract Retrieve the main world that page content itself uses.
+ @discussion When interacting with page content in a WKWebView using the page content world you can disrupt the operation of page content (e.g. by conflicting with variable names in _javascript_ set by the web page content itself).
+*/
+@property (class, nonatomic, readonly) _WKContentWorld *pageContentWorld;
+
+/*! @abstract Retrieve the default non-page content world for API clients.
+ @discussion Interacting with page content in a WKWebView using a content world different from the page content world enables using DOM and built-in DOM APIs
+ without conflicting with other aspects of the page content (e.g. _javascript_ from the web page content itself)
+*/
+@property (class, nonatomic, readonly) _WKContentWorld *defaultClientWorld;
+
+/*! @abstract Retrieves a named content world for API users.
+ @param name The name of the WKContentWorld to retrieve.
+ @discussion By interacting with page content in a WKWebView using a non-main content world you can interact with the DOM and built-in DOM APIs
+ without conflicting with other aspects of the page content (e.g. _javascript_ from the web content itself)
+ Repeated calls with the same name will retrieve the same WKContentWorld instance.
+ Each named content world is distinct from all other named content worlds, the defaultClientWorld, and the pageContentWorld.
+ The name can be used to keep distinct worlds identifiable anywhere a world might be surfaced in a user interface.
+ For example, the different worlds used in your application will be surfaced by name in the WebKit Web Inspector.
+*/
++ (_WKContentWorld *)worldWithName:(NSString *)name NS_REFINED_FOR_SWIFT;
+
+/*! @abstract The name of the WKContentWorld
+ @discussion The pageContentWorld and defaultClientWorld instances will have a nil name.
+ All other instances will have the non-nil name they were accessed by.
+*/
+@property (nullable, nonatomic, readonly, copy) NSString *name;
+
+@end
+
+NS_ASSUME_NONNULL_END
Copied: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKContentWorld.mm (from rev 254666, trunk/Source/WebKit/UIProcess/API/APIUserContentWorld.h) (0 => 254668)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKContentWorld.mm (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKContentWorld.mm 2020-01-16 05:41:03 UTC (rev 254668)
@@ -0,0 +1,68 @@
+/*
+ * 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 "_WKContentWorldInternal.h"
+
+@implementation _WKContentWorld
+
++ (_WKContentWorld *)pageContentWorld
+{
+ return wrapper(API::ContentWorld::pageContentWorld());
+}
+
++ (_WKContentWorld *)defaultClientWorld
+{
+ return wrapper(API::ContentWorld::defaultClientWorld());
+}
+
++ (_WKContentWorld *)worldWithName:(NSString *)name
+{
+ return wrapper(API::ContentWorld::sharedWorldWithName(name));
+}
+
+- (void)dealloc
+{
+ _contentWorld->~ContentWorld();
+
+ [super dealloc];
+}
+
+- (NSString *)name
+{
+ if (_contentWorld->name().isNull())
+ return nil;
+
+ return _contentWorld->name();
+}
+
+#pragma mark WKObject protocol implementation
+
+- (API::Object&)_apiObject
+{
+ return *_contentWorld;
+}
+
+@end
Copied: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKContentWorldInternal.h (from rev 254666, trunk/Source/WebKit/UIProcess/API/APIUserContentWorld.h) (0 => 254668)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKContentWorldInternal.h (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKContentWorldInternal.h 2020-01-16 05:41:03 UTC (rev 254668)
@@ -0,0 +1,44 @@
+/*
+ * 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 "_WKContentWorld.h"
+
+#import "APIContentWorld.h"
+#import "WKObject.h"
+#import <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+template<> struct WrapperTraits<API::ContentWorld> {
+ using WrapperClass = _WKContentWorld;
+};
+
+}
+
+@interface _WKContentWorld () <WKObject> {
+@package
+ API::ObjectStorage<API::ContentWorld> _contentWorld;
+}
+@end
Modified: trunk/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp (254667 => 254668)
--- trunk/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp 2020-01-16 05:41:03 UTC (rev 254668)
@@ -23,6 +23,7 @@
#include "config.h"
#include "WebKitWebView.h"
+#include "APIContentWorld.h"
#include "APIData.h"
#include "APINavigation.h"
#include "APISerializedScriptValue.h"
@@ -3742,7 +3743,8 @@
g_return_if_fail(worldName);
GRefPtr<GTask> task = adoptGRef(g_task_new(webView, cancellable, callback, userData));
- getPage(webView).runJavaScriptInMainFrameScriptWorld({ String::fromUTF8(script), false, WTF::nullopt, true }, String::fromUTF8(worldName), [task = WTFMove(task)](API::SerializedScriptValue* serializedScriptValue, Optional<ExceptionDetails> details, WebKit::CallbackBase::Error) {
+ auto world = API::ContentWorld::sharedWorldWithName(String::fromUTF8(worldName));
+ getPage(webView).runJavaScriptInMainFrameScriptWorld({ String::fromUTF8(script), false, WTF::nullopt, true }, world.get(), [task = WTFMove(task)](API::SerializedScriptValue* serializedScriptValue, Optional<ExceptionDetails> details, WebKit::CallbackBase::Error) {
ExceptionDetails exceptionDetails;
if (details)
exceptionDetails = *details;
Modified: trunk/Source/WebKit/UIProcess/UserContent/WebUserContentControllerProxy.cpp (254667 => 254668)
--- trunk/Source/WebKit/UIProcess/UserContent/WebUserContentControllerProxy.cpp 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/UIProcess/UserContent/WebUserContentControllerProxy.cpp 2020-01-16 05:41:03 UTC (rev 254668)
@@ -27,6 +27,7 @@
#include "WebUserContentControllerProxy.h"
#include "APIArray.h"
+#include "APIContentWorld.h"
#include "APIUserContentWorld.h"
#include "APIUserScript.h"
#include "APIUserStyleSheet.h"
Modified: trunk/Source/WebKit/UIProcess/UserContent/WebUserContentControllerProxy.h (254667 => 254668)
--- trunk/Source/WebKit/UIProcess/UserContent/WebUserContentControllerProxy.h 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/UIProcess/UserContent/WebUserContentControllerProxy.h 2020-01-16 05:41:03 UTC (rev 254668)
@@ -41,6 +41,7 @@
namespace API {
class Array;
class ContentRuleList;
+class ContentWorld;
class UserContentWorld;
class UserScript;
class UserStyleSheet;
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (254667 => 254668)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2020-01-16 05:41:03 UTC (rev 254668)
@@ -29,6 +29,7 @@
#include "APIArray.h"
#include "APIAttachment.h"
+#include "APIContentWorld.h"
#include "APIContextMenuClient.h"
#include "APIFindClient.h"
#include "APIFindMatchesClient.h"
@@ -3874,10 +3875,10 @@
void WebPageProxy::runJavaScriptInMainFrame(RunJavaScriptParameters&& parameters, WTF::Function<void (API::SerializedScriptValue*, Optional<WebCore::ExceptionDetails>, CallbackBase::Error)>&& callbackFunction)
{
- runJavaScriptInMainFrameScriptWorld(WTFMove(parameters), WTF::nullopt, WTFMove(callbackFunction));
+ runJavaScriptInMainFrameScriptWorld(WTFMove(parameters), API::ContentWorld::pageContentWorld(), WTFMove(callbackFunction));
}
-void WebPageProxy::runJavaScriptInMainFrameScriptWorld(RunJavaScriptParameters&& parameters, const Optional<String>& worldName, WTF::Function<void(API::SerializedScriptValue*, Optional<ExceptionDetails>, CallbackBase::Error)>&& callbackFunction)
+void WebPageProxy::runJavaScriptInMainFrameScriptWorld(RunJavaScriptParameters&& parameters, API::ContentWorld& world, WTF::Function<void(API::SerializedScriptValue*, Optional<ExceptionDetails>, CallbackBase::Error)>&& callbackFunction)
{
// For backward-compatibility support running script in a WebView which has not done any loads yets.
launchInitialProcessIfNecessary();
@@ -3888,7 +3889,7 @@
}
auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivity("WebPageProxy::runJavaScriptInMainFrameScriptWorld"_s));
- send(Messages::WebPage::RunJavaScriptInMainFrameScriptWorld(parameters, worldName, callbackID));
+ send(Messages::WebPage::RunJavaScriptInMainFrameScriptWorld(parameters, world.worldData(), callbackID));
}
void WebPageProxy::runJavaScriptInFrame(FrameIdentifier frameID, const String& script, bool forceUserGesture, WTF::Function<void(API::SerializedScriptValue*, Optional<ExceptionDetails>, CallbackBase::Error)>&& callbackFunction)
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (254667 => 254668)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2020-01-16 05:41:03 UTC (rev 254668)
@@ -166,6 +166,7 @@
namespace API {
class Attachment;
+class ContentWorld;
class ContextMenuClient;
class FindClient;
class FindMatchesClient;
@@ -1083,7 +1084,7 @@
void getSourceForFrame(WebFrameProxy*, WTF::Function<void (const String&, CallbackBase::Error)>&&);
void getWebArchiveOfFrame(WebFrameProxy*, Function<void (API::Data*, CallbackBase::Error)>&&);
void runJavaScriptInMainFrame(WebCore::RunJavaScriptParameters&&, WTF::Function<void (API::SerializedScriptValue*, Optional<WebCore::ExceptionDetails>, CallbackBase::Error)>&& callbackFunction);
- void runJavaScriptInMainFrameScriptWorld(WebCore::RunJavaScriptParameters&&, const Optional<String>& worldName, WTF::Function<void(API::SerializedScriptValue*, Optional<WebCore::ExceptionDetails>, CallbackBase::Error)>&& callbackFunction);
+ void runJavaScriptInMainFrameScriptWorld(WebCore::RunJavaScriptParameters&&, API::ContentWorld&, WTF::Function<void(API::SerializedScriptValue*, Optional<WebCore::ExceptionDetails>, CallbackBase::Error)>&& callbackFunction);
// For sub frames.
void runJavaScriptInFrame(WebCore::FrameIdentifier, const String& script, bool forceUserGesture, WTF::Function<void(API::SerializedScriptValue*, Optional<WebCore::ExceptionDetails>, CallbackBase::Error)>&& callbackFunction);
void forceRepaint(RefPtr<VoidCallback>&&);
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (254667 => 254668)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2020-01-16 05:41:03 UTC (rev 254668)
@@ -1030,6 +1030,10 @@
517CF0E3163A486C00C2950E /* NetworkProcessConnectionMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 517CF0E1163A486C00C2950E /* NetworkProcessConnectionMessageReceiver.cpp */; };
517CF0E3163A486C00C2950F /* CacheStorageEngineConnectionMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 517CF0E1163A486C00C2950F /* CacheStorageEngineConnectionMessageReceiver.cpp */; };
517CF0E4163A486C00C2950E /* NetworkProcessConnectionMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 517CF0E2163A486C00C2950E /* NetworkProcessConnectionMessages.h */; };
+ 5183721D23CE85F60003CF83 /* _WKContentWorld.h in Headers */ = {isa = PBXBuildFile; fileRef = 5183721A23CD49B20003CF83 /* _WKContentWorld.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 5183721E23CE85FB0003CF83 /* _WKContentWorldInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5183721C23CD4A740003CF83 /* _WKContentWorldInternal.h */; };
+ 5183721F23CE95210003CF83 /* _WKContentWorld.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5183721B23CD49B20003CF83 /* _WKContentWorld.mm */; };
+ 5183722223CE97410003CF83 /* APIContentWorld.h in Headers */ = {isa = PBXBuildFile; fileRef = 5183722023CE973A0003CF83 /* APIContentWorld.h */; };
51871B5C127CB89D00F76232 /* WebContextMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 51871B5A127CB89D00F76232 /* WebContextMenu.h */; };
518ACAEA12AEE6BB00B04B83 /* WKProtectionSpaceTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 518ACAE912AEE6BB00B04B83 /* WKProtectionSpaceTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
518ACF1112B015F800B04B83 /* WKCredentialTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 518ACF1012B015F800B04B83 /* WKCredentialTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -3620,6 +3624,11 @@
517CF0E1163A486C00C2950E /* NetworkProcessConnectionMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NetworkProcessConnectionMessageReceiver.cpp; path = DerivedSources/WebKit2/NetworkProcessConnectionMessageReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
517CF0E1163A486C00C2950F /* CacheStorageEngineConnectionMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CacheStorageEngineConnectionMessageReceiver.cpp; path = DerivedSources/WebKit2/CacheStorageEngineConnectionMessageReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
517CF0E2163A486C00C2950E /* NetworkProcessConnectionMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkProcessConnectionMessages.h; path = DerivedSources/WebKit2/NetworkProcessConnectionMessages.h; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5183721A23CD49B20003CF83 /* _WKContentWorld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKContentWorld.h; sourceTree = "<group>"; };
+ 5183721B23CD49B20003CF83 /* _WKContentWorld.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKContentWorld.mm; sourceTree = "<group>"; };
+ 5183721C23CD4A740003CF83 /* _WKContentWorldInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKContentWorldInternal.h; sourceTree = "<group>"; };
+ 5183722023CE973A0003CF83 /* APIContentWorld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIContentWorld.h; sourceTree = "<group>"; };
+ 5183722123CE973A0003CF83 /* APIContentWorld.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = APIContentWorld.cpp; sourceTree = "<group>"; };
5183B3931379F85C00E8754E /* Shim.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shim.xcconfig; sourceTree = "<group>"; };
51871B59127CB89D00F76232 /* WebContextMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebContextMenu.cpp; sourceTree = "<group>"; };
51871B5A127CB89D00F76232 /* WebContextMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebContextMenu.h; sourceTree = "<group>"; };
@@ -6793,6 +6802,9 @@
5C4609E222430E4C009943C2 /* _WKContentRuleListAction.h */,
5C4609E322430E4D009943C2 /* _WKContentRuleListAction.mm */,
5C4609E422430E4D009943C2 /* _WKContentRuleListActionInternal.h */,
+ 5183721A23CD49B20003CF83 /* _WKContentWorld.h */,
+ 5183721B23CD49B20003CF83 /* _WKContentWorld.mm */,
+ 5183721C23CD4A740003CF83 /* _WKContentWorldInternal.h */,
1A5704F61BE01FF400874AF1 /* _WKContextMenuElementInfo.h */,
1A5704F51BE01FF400874AF1 /* _WKContextMenuElementInfo.mm */,
5C5D2389227A1892000B9BDA /* _WKCustomHeaderFields.h */,
@@ -8527,6 +8539,8 @@
5C4609E622430FA7009943C2 /* APIContentRuleListAction.h */,
7C3A06A51AAB903E009D74BA /* APIContentRuleListStore.cpp */,
7C3A06A61AAB903E009D74BA /* APIContentRuleListStore.h */,
+ 5183722123CE973A0003CF83 /* APIContentWorld.cpp */,
+ 5183722023CE973A0003CF83 /* APIContentWorld.h */,
076E884D1A13CADF005E90FC /* APIContextMenuClient.h */,
5CE0C366229F2D3D003695F0 /* APIContextMenuElementInfo.cpp */,
5CE0C367229F2D3E003695F0 /* APIContextMenuElementInfo.h */,
@@ -9881,6 +9895,8 @@
990D28B11C65208D00986977 /* _WKAutomationSessionInternal.h in Headers */,
5C4609E7224317B4009943C2 /* _WKContentRuleListAction.h in Headers */,
5C4609E8224317BB009943C2 /* _WKContentRuleListActionInternal.h in Headers */,
+ 5183721D23CE85F60003CF83 /* _WKContentWorld.h in Headers */,
+ 5183721E23CE85FB0003CF83 /* _WKContentWorldInternal.h in Headers */,
1A5704F81BE01FF400874AF1 /* _WKContextMenuElementInfo.h in Headers */,
5C5D238C227A2CDA000B9BDA /* _WKCustomHeaderFields.h in Headers */,
83891B691A68BEBC0030F386 /* _WKDiagnosticLoggingDelegate.h in Headers */,
@@ -9989,6 +10005,7 @@
1A3DD206125E5A2F004515E6 /* APIClient.h in Headers */,
7C89D2B41A6B068C003A5FDE /* APIContentRuleList.h in Headers */,
7C3A06A81AAB903E009D74BA /* APIContentRuleListStore.h in Headers */,
+ 5183722223CE97410003CF83 /* APIContentWorld.h in Headers */,
076E884E1A13CADF005E90FC /* APIContextMenuClient.h in Headers */,
7A821F501E2F7A7500604577 /* APICustomProtocolManagerClient.h in Headers */,
51578B831209ECEF00A37C4A /* APIData.h in Headers */,
@@ -11965,6 +11982,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 5183721F23CE95210003CF83 /* _WKContentWorld.mm in Sources */,
5CBD595C2280EDF4002B22AA /* _WKCustomHeaderFields.mm in Sources */,
49FBEFFD239B011D00BD032F /* _WKResourceLoadStatisticsFirstParty.mm in Sources */,
49FBEFFF239B012F00BD032F /* _WKResourceLoadStatisticsThirdParty.mm in Sources */,
Modified: trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.cpp (254667 => 254668)
--- trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.cpp 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.cpp 2020-01-16 05:41:03 UTC (rev 254668)
@@ -62,7 +62,7 @@
static WorldMap& worldMap()
{
- static NeverDestroyed<WorldMap> map(std::initializer_list<WorldMap::KeyValuePairType> { { 1, std::make_pair(&InjectedBundleScriptWorld::normalWorld(), 1) } });
+ static NeverDestroyed<WorldMap> map(std::initializer_list<WorldMap::KeyValuePairType> { { WebUserContentController::identifierForNormalWorld(), std::make_pair(&InjectedBundleScriptWorld::normalWorld(), 1) } });
return map;
}
@@ -94,25 +94,35 @@
userContentControllers().remove(m_identifier);
}
-void WebUserContentController::addUserContentWorlds(const Vector<std::pair<uint64_t, String>>& worlds)
+InjectedBundleScriptWorld* WebUserContentController::worldForIdentifier(uint64_t identifier)
{
- for (auto& world : worlds) {
- ASSERT(world.first);
- ASSERT(world.first != 1);
+ auto iterator = worldMap().find(identifier);
+ return iterator == worldMap().end() ? nullptr : iterator->value.first.get();
+}
- worldMap().ensure(world.first, [&] {
+void WebUserContentController::addUserContentWorld(const std::pair<uint64_t, String>& world)
+{
+ ASSERT(world.first);
+ ASSERT(world.first != 1);
+
+ 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
- // as the identifier.
- if (auto* existingWorld = InjectedBundleScriptWorld::find(world.second))
- return std::make_pair(Ref<InjectedBundleScriptWorld>(*existingWorld), 1);
+ // 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
+ // as the identifier.
+ if (auto* existingWorld = InjectedBundleScriptWorld::find(world.second))
+ return std::make_pair(Ref<InjectedBundleScriptWorld>(*existingWorld), 1);
#endif
- return std::make_pair(InjectedBundleScriptWorld::create(world.second), 1);
- });
- }
+ return std::make_pair(InjectedBundleScriptWorld::create(world.second), 1);
+ });
}
+void WebUserContentController::addUserContentWorlds(const Vector<std::pair<uint64_t, String>>& worlds)
+{
+ for (auto& world : worlds)
+ addUserContentWorld(world);
+}
+
void WebUserContentController::removeUserContentWorlds(const Vector<uint64_t>& worldIdentifiers)
{
for (auto& worldIdentifier : worldIdentifiers) {
Modified: trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.h (254667 => 254668)
--- trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.h 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/WebProcess/UserContent/WebUserContentController.h 2020-01-16 05:41:03 UTC (rev 254668)
@@ -64,7 +64,11 @@
void removeUserStyleSheets(InjectedBundleScriptWorld&);
void removeAllUserContent();
+ static uint64_t identifierForNormalWorld() { return 1; }
+ InjectedBundleScriptWorld* worldForIdentifier(uint64_t);
+
void addUserContentWorlds(const Vector<std::pair<uint64_t, String>>&);
+ void addUserContentWorld(const std::pair<uint64_t, String>&);
void addUserScripts(Vector<WebUserScriptData>&&, InjectUserScriptImmediately);
void addUserStyleSheets(const Vector<WebUserStyleSheetData>&);
void addUserScriptMessageHandlers(const Vector<WebScriptMessageHandlerData>&);
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (254667 => 254668)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2020-01-16 05:41:03 UTC (rev 254668)
@@ -3380,17 +3380,23 @@
return static_cast<KeyboardUIMode>((fullKeyboardAccessEnabled ? KeyboardAccessFull : KeyboardAccessDefault) | (m_tabToLinks ? KeyboardAccessTabsToLinks : 0));
}
-void WebPage::runJavaScript(WebFrame* frame, RunJavaScriptParameters&& parameters, const Optional<String>& worldName, CallbackID callbackID)
+void WebPage::runJavaScript(WebFrame* frame, RunJavaScriptParameters&& parameters, uint64_t worldIdentifier, CallbackID callbackID)
{
// NOTE: We need to be careful when running scripts that the objects we depend on don't
// disappear during script execution.
- auto* world = worldName ? InjectedBundleScriptWorld::find(worldName.value()) : &InjectedBundleScriptWorld::normalWorld();
- if (!frame || !frame->coreFrame() || !world) {
+ if (!frame || !frame->coreFrame()) {
send(Messages::WebPageProxy::ScriptValueCallback({ }, ExceptionDetails { "Unable to execute _javascript_: Page is in invalid state"_s }, callbackID));
return;
}
+ ASSERT(worldIdentifier);
+ auto* world = m_userContentController->worldForIdentifier(worldIdentifier);
+ if (!world) {
+ send(Messages::WebPageProxy::ScriptValueCallback({ }, ExceptionDetails { "Unable to execute _javascript_: Cannot find specified content world"_s }, callbackID));
+ return;
+ }
+
auto resolveFunction = [protectedThis = makeRef(*this), this, world = makeRef(*world), frame = makeRef(*frame), callbackID](ValueOrException result) {
RefPtr<SerializedScriptValue> serializedResultValue;
if (result) {
@@ -3413,9 +3419,10 @@
frame->coreFrame()->script().executeAsynchronousUserAgentScriptInWorld(world->coreWorld(), WTFMove(parameters), WTFMove(resolveFunction));
}
-void WebPage::runJavaScriptInMainFrameScriptWorld(RunJavaScriptParameters&& parameters, const Optional<String>& worldName, CallbackID callbackID)
+void WebPage::runJavaScriptInMainFrameScriptWorld(RunJavaScriptParameters&& parameters, const std::pair<uint64_t, String>& worldData, CallbackID callbackID)
{
- runJavaScript(mainWebFrame(), WTFMove(parameters), worldName, callbackID);
+ m_userContentController->addUserContentWorld(worldData);
+ runJavaScript(mainWebFrame(), WTFMove(parameters), worldData.first, callbackID);
}
void WebPage::runJavaScriptInFrame(FrameIdentifier frameID, const String& script, bool forceUserGesture, CallbackID callbackID)
@@ -3422,7 +3429,7 @@
{
WebFrame* frame = WebProcess::singleton().webFrame(frameID);
ASSERT(mainWebFrame() != frame);
- runJavaScript(frame, { script, false, WTF::nullopt, forceUserGesture }, WTF::nullopt, callbackID);
+ runJavaScript(frame, { script, false, WTF::nullopt, forceUserGesture }, WebUserContentController::identifierForNormalWorld(), callbackID);
}
void WebPage::getContentsAsString(CallbackID callbackID)
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (254667 => 254668)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2020-01-16 05:41:03 UTC (rev 254668)
@@ -1461,8 +1461,8 @@
void getSelectionAsWebArchiveData(CallbackID);
void getSourceForFrame(WebCore::FrameIdentifier, CallbackID);
void getWebArchiveOfFrame(WebCore::FrameIdentifier, CallbackID);
- void runJavaScript(WebFrame*, WebCore::RunJavaScriptParameters&&, const Optional<String>& worldName, CallbackID);
- void runJavaScriptInMainFrameScriptWorld(WebCore::RunJavaScriptParameters&&, const Optional<String>& worldName, CallbackID);
+ void runJavaScript(WebFrame*, WebCore::RunJavaScriptParameters&&, uint64_t worldIdentifier, CallbackID);
+ void runJavaScriptInMainFrameScriptWorld(WebCore::RunJavaScriptParameters&&, const std::pair<uint64_t, String>& worldData, CallbackID);
void runJavaScriptInFrame(WebCore::FrameIdentifier, const String&, bool forceUserGesture, CallbackID);
void forceRepaint(CallbackID);
void takeSnapshot(WebCore::IntRect snapshotRect, WebCore::IntSize bitmapSize, uint32_t options, CallbackID);
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (254667 => 254668)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2020-01-16 05:41:03 UTC (rev 254668)
@@ -206,10 +206,12 @@
GetSelectionAsWebArchiveData(WebKit::CallbackID callbackID)
GetSourceForFrame(WebCore::FrameIdentifier frameID, WebKit::CallbackID callbackID)
GetWebArchiveOfFrame(WebCore::FrameIdentifier frameID, WebKit::CallbackID callbackID)
- RunJavaScriptInMainFrameScriptWorld(struct WebCore::RunJavaScriptParameters parameters, Optional<String> worldName, WebKit::CallbackID callbackID)
+
+ // FIXME: These should use sendWithAsyncReply instead of callbackIDs
+ RunJavaScriptInMainFrameScriptWorld(struct WebCore::RunJavaScriptParameters parameters, std::pair<uint64_t, String> world, WebKit::CallbackID callbackID)
RunJavaScriptInFrame(WebCore::FrameIdentifier frameID, String script, bool forceUserGesture, WebKit::CallbackID callbackID)
+
ForceRepaint(WebKit::CallbackID callbackID)
-
SelectAll()
ScheduleFullEditorStateUpdate()
Modified: trunk/Tools/ChangeLog (254667 => 254668)
--- trunk/Tools/ChangeLog 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Tools/ChangeLog 2020-01-16 05:41:03 UTC (rev 254668)
@@ -1,3 +1,21 @@
+2020-01-15 Brady Eidson <beid...@apple.com>
+
+ Add WKContentWorld SPI, and use it in _javascript_ execution.
+ https://bugs.webkit.org/show_bug.cgi?id=206310
+
+ Reviewed by Alex Christensen.
+
+ Update previous callAsyncFunction calls with the new signature.
+ Add tests for new _WKContentWorld class and its behavior with regard to executing _javascript_.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/AsyncFunction.mm:
+ (TestWebKitAPI::tryGCPromise):
+ (TestWebKitAPI::TEST):
+ * TestWebKitAPI/Tests/WebKitCocoa/WKWebViewEvaluateJavaScript.mm:
+ (TEST):
+ * TestWebKitAPI/cocoa/TestWKWebView.mm:
+ (-[WKWebView objectByCallingAsyncFunction:withArguments:error:]):
+
2020-01-15 Jonathan Bedard <jbed...@apple.com>
run-api-tests no longer supports wildcards in test names
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/AsyncFunction.mm (254667 => 254668)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/AsyncFunction.mm 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/AsyncFunction.mm 2020-01-16 05:41:03 UTC (rev 254668)
@@ -29,6 +29,7 @@
#import "Test.h"
#import "TestWKWebView.h"
#import <WebKit/WKWebViewPrivate.h>
+#import <WebKit/_WKContentWorld.h>
namespace TestWebKitAPI {
@@ -183,7 +184,7 @@
return;
NSString *functionBody = @"return new Promise(function(resolve, reject) { })";
- [webView _callAsyncFunction:functionBody withArguments:nil completionHandler:[&] (id result, NSError *error) {
+ [webView _callAsyncJavaScriptFunction:functionBody withArguments:nil inWorld:_WKContentWorld.pageContentWorld completionHandler:[&] (id result, NSError *error) {
EXPECT_NULL(result);
EXPECT_TRUE(error != nil);
EXPECT_TRUE([[error description] containsString:@"no longer reachable"]);
@@ -200,7 +201,7 @@
NSString *functionBody = @"return new Promise(function(resolve, reject) { setTimeout(function(){ resolve(42) }, 0); })";
bool done = false;
- [webView _callAsyncFunction:functionBody withArguments:nil completionHandler:[&] (id result, NSError *error) {
+ [webView _callAsyncJavaScriptFunction:functionBody withArguments:nil inWorld:_WKContentWorld.pageContentWorld completionHandler:[&] (id result, NSError *error) {
EXPECT_NULL(error);
EXPECT_TRUE([result isKindOfClass:[NSNumber class]]);
EXPECT_TRUE([result isEqualToNumber:@42]);
@@ -212,7 +213,7 @@
functionBody = @"return new Promise(function(resolve, reject) { setTimeout(function(){ reject('Rejected!') }, 0); })";
done = false;
- [webView _callAsyncFunction:functionBody withArguments:nil completionHandler:[&] (id result, NSError *error) {
+ [webView _callAsyncJavaScriptFunction:functionBody withArguments:nil inWorld:_WKContentWorld.pageContentWorld completionHandler:[&] (id result, NSError *error) {
EXPECT_NULL(result);
EXPECT_TRUE(error != nil);
EXPECT_TRUE([[error description] containsString:@"Rejected!"]);
@@ -223,7 +224,7 @@
functionBody = @"let p = new Proxy(function(resolve, reject) { setTimeout(function() { resolve(42); }, 0); }, { }); return { then: p };";
done = false;
- [webView _callAsyncFunction:functionBody withArguments:nil completionHandler:[&] (id result, NSError *error) {
+ [webView _callAsyncJavaScriptFunction:functionBody withArguments:nil inWorld:_WKContentWorld.pageContentWorld completionHandler:[&] (id result, NSError *error) {
EXPECT_NULL(error);
EXPECT_TRUE([result isKindOfClass:[NSNumber class]]);
EXPECT_TRUE([result isEqualToNumber:@42]);
@@ -234,7 +235,7 @@
functionBody = @"let p = new Proxy(function(resolve, reject) { setTimeout(function() { reject('Rejected!'); }, 0); }, { }); return { then: p };";
done = false;
- [webView _callAsyncFunction:functionBody withArguments:nil completionHandler:[&] (id result, NSError *error) {
+ [webView _callAsyncJavaScriptFunction:functionBody withArguments:nil inWorld:_WKContentWorld.pageContentWorld completionHandler:[&] (id result, NSError *error) {
EXPECT_NULL(result);
EXPECT_TRUE(error != nil);
EXPECT_TRUE([[error description] containsString:@"Rejected!"]);
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewEvaluateJavaScript.mm (254667 => 254668)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewEvaluateJavaScript.mm 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewEvaluateJavaScript.mm 2020-01-16 05:41:03 UTC (rev 254668)
@@ -29,8 +29,10 @@
#import "PlatformUtilities.h"
#import "Test.h"
#import "TestNavigationDelegate.h"
-#import <WebKit/WKWebView.h>
+#import "TestWKWebView.h"
#import <WebKit/WKErrorPrivate.h>
+#import <WebKit/WKWebViewPrivate.h>
+#import <WebKit/_WKContentWorld.h>
#import <wtf/RetainPtr.h>
static bool isDone;
@@ -111,3 +113,114 @@
isDone = false;
TestWebKitAPI::Util::run(&isDone);
}
+
+TEST(WKWebView, WKContentWorld)
+{
+ EXPECT_NULL(_WKContentWorld.pageContentWorld.name);
+ EXPECT_NULL(_WKContentWorld.defaultClientWorld.name);
+ EXPECT_FALSE(_WKContentWorld.pageContentWorld == _WKContentWorld.defaultClientWorld);
+
+ _WKContentWorld *namedWorld = [_WKContentWorld worldWithName:@"Name"];
+ EXPECT_TRUE([namedWorld.name isEqualToString:@"Name"]);
+ EXPECT_EQ(namedWorld, [_WKContentWorld worldWithName:@"Name"]);
+}
+
+TEST(WKWebView, EvaluateJavaScriptInWorlds)
+{
+ RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+ [webView synchronouslyLoadHTMLString:@"<html></html>"];
+
+ // Set a variable in the main world via "normal" evaluateJavaScript
+ isDone = false;
+ [webView evaluateJavaScript:@"var foo = 'bar'" completionHandler:^(id result, NSError *error) {
+ isDone = true;
+ }];
+ isDone = false;
+
+ // Verify that value is visible when evaluating in the pageContentWorld
+ [webView _evaluateJavaScript:@"foo" inWorld:_WKContentWorld.pageContentWorld completionHandler:^(id result, NSError *error) {
+ EXPECT_TRUE([result isKindOfClass:[NSString class]]);
+ EXPECT_TRUE([result isEqualToString:@"bar"]);
+ isDone = true;
+ }];
+ isDone = false;
+
+ // Verify that value is not visible when evaluating in the defaultClientWorld
+ [webView _evaluateJavaScript:@"foo" inWorld:_WKContentWorld.defaultClientWorld completionHandler:^(id result, NSError *error) {
+ EXPECT_NULL(result);
+ isDone = true;
+ }];
+ isDone = false;
+
+ // Verify that value is visible when calling a function in the pageContentWorld
+ [webView _callAsyncJavaScriptFunction:@"return foo" withArguments:nil inWorld:_WKContentWorld.pageContentWorld completionHandler:[&] (id result, NSError *error) {
+ EXPECT_TRUE([result isKindOfClass:[NSString class]]);
+ EXPECT_TRUE([result isEqualToString:@"bar"]);
+ isDone = true;
+ }];
+ isDone = false;
+
+ // Verify that value is not visible when calling a function in the defaultClientWorld
+ [webView _callAsyncJavaScriptFunction:@"return foo" withArguments:nil inWorld:_WKContentWorld.defaultClientWorld completionHandler:[&] (id result, NSError *error) {
+ EXPECT_NULL(result);
+ isDone = true;
+ }];
+ isDone = false;
+
+ // Set a varibale value in a named world.
+ RetainPtr<_WKContentWorld> namedWorld = [_WKContentWorld worldWithName:@"NamedWorld"];
+ [webView _evaluateJavaScript:@"var bar = baz" inWorld:namedWorld.get() completionHandler:^(id result, NSError *error) {
+ EXPECT_NULL(result);
+ isDone = true;
+ }];
+ isDone = false;
+
+ // Set a global varibale value in a named world via a function call.
+ [webView _callAsyncJavaScriptFunction:@"window.baz = bat" withArguments:nil inWorld:namedWorld.get() completionHandler:^(id result, NSError *error) {
+ EXPECT_NULL(result);
+ EXPECT_NULL(error);
+ isDone = true;
+ }];
+ isDone = false;
+
+ // Verify they are there in that named world.
+ [webView _evaluateJavaScript:@"bar" inWorld:namedWorld.get() completionHandler:^(id result, NSError *error) {
+ EXPECT_TRUE([result isKindOfClass:[NSString class]]);
+ EXPECT_TRUE([result isEqualToString:@"baz"]);
+ isDone = true;
+ }];
+ isDone = false;
+
+ [webView _evaluateJavaScript:@"window.baz" inWorld:namedWorld.get() completionHandler:^(id result, NSError *error) {
+ EXPECT_TRUE([result isKindOfClass:[NSString class]]);
+ EXPECT_TRUE([result isEqualToString:@"bat"]);
+ isDone = true;
+ }];
+ isDone = false;
+
+ // Verify they aren't there in the defaultClientWorld.
+ [webView _evaluateJavaScript:@"bar" inWorld:_WKContentWorld.defaultClientWorld completionHandler:^(id result, NSError *error) {
+ EXPECT_NULL(result);
+ isDone = true;
+ }];
+ isDone = false;
+
+ [webView _evaluateJavaScript:@"window.baz" inWorld:_WKContentWorld.defaultClientWorld completionHandler:^(id result, NSError *error) {
+ EXPECT_NULL(result);
+ isDone = true;
+ }];
+ isDone = false;
+
+ // Verify they aren't there in the pageContentWorld.
+ [webView _evaluateJavaScript:@"bar" inWorld:_WKContentWorld.pageContentWorld completionHandler:^(id result, NSError *error) {
+ EXPECT_NULL(result);
+ isDone = true;
+ }];
+ isDone = false;
+
+ [webView _evaluateJavaScript:@"window.baz" inWorld:_WKContentWorld.pageContentWorld completionHandler:^(id result, NSError *error) {
+ EXPECT_NULL(result);
+ isDone = true;
+ }];
+ isDone = false;
+}
Modified: trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm (254667 => 254668)
--- trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm 2020-01-16 05:08:48 UTC (rev 254667)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm 2020-01-16 05:41:03 UTC (rev 254668)
@@ -33,6 +33,7 @@
#import <WebKit/WKWebViewConfigurationPrivate.h>
#import <WebKit/WebKitPrivate.h>
#import <WebKit/_WKActivatedElementInfo.h>
+#import <WebKit/_WKContentWorld.h>
#import <WebKit/_WKProcessPoolConfiguration.h>
#import <objc/runtime.h>
#import <wtf/RetainPtr.h>
@@ -185,7 +186,7 @@
*errorOut = nil;
RetainPtr<id> evalResult;
- [self _callAsyncFunction:script withArguments:arguments completionHandler:[&] (id result, NSError *error) {
+ [self _callAsyncJavaScriptFunction:script withArguments:arguments inWorld:_WKContentWorld.pageContentWorld completionHandler:[&] (id result, NSError *error) {
evalResult = result;
if (errorOut)
*errorOut = [error retain];