Changeset 253950 in webkit
- Timestamp:
- Dec 30, 2019 12:23:20 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 25 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r253949 r253950 1 2019-12-30 Brady Eidson <beidson@apple.com> 2 3 Add WKWebView SPI to evaluate a function with arguments 4 https://bugs.webkit.org/show_bug.cgi?id=205239 5 6 Reviewed by Alex Christensen. 7 8 Covered by new API tests. 9 10 * Headers.cmake: 11 * WebCore.xcodeproj/project.pbxproj: 12 13 * bindings/js/ExceptionDetails.h: 14 15 * bindings/js/RunJavaScriptParameters.h: Added. 16 (WebCore::RunJavaScriptParameters::RunJavaScriptParameters): 17 (WebCore::RunJavaScriptParameters::encode const): 18 (WebCore::RunJavaScriptParameters::decode): 19 20 * bindings/js/ScriptController.cpp: 21 (WebCore::ScriptController::executeScriptInWorldIgnoringException): 22 (WebCore::ScriptController::executeScriptInWorld): 23 (WebCore::ScriptController::callInWorld): 24 (WebCore::ScriptController::executeUserAgentScriptInWorld): 25 (WebCore::ScriptController::executeUserAgentScriptInWorldInternal): 26 (WebCore::ScriptController::executeAsynchronousUserAgentScriptInWorld): 27 * bindings/js/ScriptController.h: 28 29 XPathGrammar changes completely unrelated to the functionality of this patch, 30 but because of our poor #include hygiene these were necessary to keep linuxes building. 31 * xml/XPathGrammar.cpp: 32 * xml/XPathGrammar.y: 33 1 34 2019-12-30 Antti Koivisto <antti@apple.com> 2 35 -
trunk/Source/WebCore/Headers.cmake
r253939 r253950 241 241 bindings/js/JSWindowProxy.h 242 242 bindings/js/ReadableStreamDefaultController.h 243 bindings/js/RunJavaScriptParameters.h 243 244 bindings/js/ScriptCachedFrameData.h 244 245 bindings/js/ScriptController.h -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r253939 r253950 1534 1534 51BA4ACB1BBC5BD900DF3D6D /* MemoryIDBBackingStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 51BA4AC91BBC5B9E00DF3D6D /* MemoryIDBBackingStore.h */; }; 1535 1535 51BA4ACC1BBC5BDD00DF3D6D /* IDBBackingStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 51BA4AC71BBC5AD600DF3D6D /* IDBBackingStore.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1536 51BA947123AC305300444846 /* RunJavaScriptParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 51BA946F23AC305000444846 /* RunJavaScriptParameters.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1536 1537 51BCCE301F8F179E006BA0ED /* ServiceWorkerThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 517C87101F8EE72E00EB8076 /* ServiceWorkerThread.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1537 1538 51BE37E00DAEE00E001085FC /* StorageArea.h in Headers */ = {isa = PBXBuildFile; fileRef = 51BE37DE0DAEE00E001085FC /* StorageArea.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 8337 8338 51BA4AC81BBC5B9E00DF3D6D /* MemoryIDBBackingStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryIDBBackingStore.cpp; sourceTree = "<group>"; }; 8338 8339 51BA4AC91BBC5B9E00DF3D6D /* MemoryIDBBackingStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryIDBBackingStore.h; sourceTree = "<group>"; }; 8340 51BA946F23AC305000444846 /* RunJavaScriptParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RunJavaScriptParameters.h; sourceTree = "<group>"; }; 8339 8341 51BE37DE0DAEE00E001085FC /* StorageArea.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageArea.h; sourceTree = "<group>"; }; 8340 8342 51C0AA380F2AA10A001648C2 /* CachedFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedFrame.h; sourceTree = "<group>"; }; … … 25406 25408 418C395E1C8F0AAB0051C8A3 /* ReadableStreamDefaultController.cpp */, 25407 25409 418C395F1C8F0AAB0051C8A3 /* ReadableStreamDefaultController.h */, 25410 51BA946F23AC305000444846 /* RunJavaScriptParameters.h */, 25408 25411 41F1D21E0EF35C2A00DA8753 /* ScriptCachedFrameData.cpp */, 25409 25412 41F1D21D0EF35C2A00DA8753 /* ScriptCachedFrameData.h */, … … 32132 32135 A79BADA2161E7F3F00C2E652 /* RuleFeature.h in Headers */, 32133 32136 A79BADA4161E7F3F00C2E652 /* RuleSet.h in Headers */, 32137 51BA947123AC305300444846 /* RunJavaScriptParameters.h in Headers */, 32134 32138 2D76BB821945632400CFD29A /* RunLoopObserver.h in Headers */, 32135 32139 1A569D1F0D7E2B82007C3983 /* runtime_array.h in Headers */, -
trunk/Source/WebCore/bindings/js/ExceptionDetails.h
r251690 r253950 34 34 int lineNumber { 0 }; 35 35 int columnNumber { 0 }; 36 String sourceURL; 36 // This bizarre explicit initialization of String is because older compilers (like on High Sierra) 37 // don't properly handle partial initialization lists unless every struct member has an explicit default value. 38 // Once we stop building on those platforms we can remove this. 39 String sourceURL { }; 37 40 }; 38 41 -
trunk/Source/WebCore/bindings/js/ScriptController.cpp
r253654 r253950 48 48 #include "PaymentCoordinator.h" 49 49 #include "PluginViewBase.h" 50 #include "RunJavaScriptParameters.h" 50 51 #include "RuntimeApplicationChecks.h" 51 52 #include "ScriptDisallowedScope.h" … … 566 567 JSC::JSValue ScriptController::executeScriptInWorldIgnoringException(DOMWrapperWorld& world, const String& script, bool forceUserGesture) 567 568 { 568 auto result = executeScriptInWorld(world, script, forceUserGesture);569 auto result = executeScriptInWorld(world, RunJavaScriptParameters { script, false, WTF::nullopt, forceUserGesture }); 569 570 return result ? result.value() : JSC::JSValue { }; 570 571 } 571 572 572 ValueOrException ScriptController::executeScriptInWorld(DOMWrapperWorld& world, const String& script, bool forceUserGesture) 573 { 574 UserGestureIndicator gestureIndicator(forceUserGesture ? Optional<ProcessingUserGestureState>(ProcessingUserGesture) : WTF::nullopt); 575 ScriptSourceCode sourceCode(script, URL(m_frame.document()->url()), TextPosition(), JSC::SourceProviderSourceType::Program, CachedScriptFetcher::create(m_frame.document()->charset())); 573 ValueOrException ScriptController::executeScriptInWorld(DOMWrapperWorld& world, RunJavaScriptParameters&& parameters) 574 { 575 UserGestureIndicator gestureIndicator(parameters.forceUserGesture == ForceUserGesture::Yes ? Optional<ProcessingUserGestureState>(ProcessingUserGesture) : WTF::nullopt); 576 576 577 577 // FIXME: Instead of returning an empty JSValue, should return an ExceptionDetails. … … 579 579 return { }; 580 580 581 return evaluateInWorld(sourceCode, world); 581 switch (parameters.runAsAsyncFunction) { 582 case RunAsAsyncFunction::No: { 583 ScriptSourceCode sourceCode(parameters.source, URL(m_frame.document()->url()), TextPosition(), JSC::SourceProviderSourceType::Program, CachedScriptFetcher::create(m_frame.document()->charset())); 584 return evaluateInWorld(sourceCode, world); 585 } 586 case RunAsAsyncFunction::Yes: 587 return callInWorld(WTFMove(parameters), world); 588 default: 589 RELEASE_ASSERT_NOT_REACHED(); 590 } 591 } 592 593 ValueOrException ScriptController::callInWorld(RunJavaScriptParameters&& parameters, DOMWrapperWorld& world) 594 { 595 ASSERT(parameters.runAsAsyncFunction == RunAsAsyncFunction::Yes); 596 ASSERT(parameters.arguments); 597 598 auto& proxy = jsWindowProxy(world); 599 auto& globalObject = *proxy.window(); 600 MarkedArgumentBuffer markedArguments; 601 StringBuilder functionStringBuilder; 602 String errorMessage; 603 604 // Build up a new script string that is an async function with arguments, and deserialize those arguments. 605 functionStringBuilder.append("(function("); 606 for (auto argument = parameters.arguments->begin(); argument != parameters.arguments->end();) { 607 functionStringBuilder.append(argument->key); 608 auto serializedArgument = SerializedScriptValue::createFromWireBytes(WTFMove(argument->value)); 609 610 auto scope = DECLARE_CATCH_SCOPE(globalObject.vm()); 611 auto jsArgument = serializedArgument->deserialize(globalObject, &globalObject); 612 if (UNLIKELY(scope.exception())) { 613 errorMessage = "Unable to deserialize argument to execute asynchronous JavaScript function"; 614 break; 615 } 616 617 markedArguments.append(jsArgument); 618 619 ++argument; 620 if (argument != parameters.arguments->end()) 621 functionStringBuilder.append(','); 622 } 623 624 if (!errorMessage.isEmpty()) 625 return makeUnexpected(ExceptionDetails { errorMessage }); 626 627 functionStringBuilder.append("){", parameters.source, "})"); 628 629 auto sourceCode = ScriptSourceCode { functionStringBuilder.toString(), URL(m_frame.document()->url()), TextPosition(), JSC::SourceProviderSourceType::Program, CachedScriptFetcher::create(m_frame.document()->charset()) }; 630 const auto& jsSourceCode = sourceCode.jsSourceCode(); 631 632 String sourceURL = jsSourceCode.provider()->url(); 633 const String* savedSourceURL = m_sourceURL; 634 m_sourceURL = &sourceURL; 635 636 Ref<Frame> protector(m_frame); 637 638 InspectorInstrumentation::willEvaluateScript(m_frame, sourceURL, sourceCode.startLine(), sourceCode.startColumn()); 639 640 NakedPtr<JSC::Exception> evaluationException; 641 Optional<ExceptionDetails> optionalDetails; 642 JSValue returnValue; 643 do { 644 JSValue functionObject = JSExecState::profiledEvaluate(&globalObject, JSC::ProfilingReason::Other, jsSourceCode, &proxy, evaluationException); 645 646 if (evaluationException) 647 break; 648 649 if (!functionObject || !functionObject.isFunction(world.vm())) { 650 optionalDetails = { { "Unable to create JavaScript async function to call"_s } }; 651 break; 652 } 653 654 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=205562 655 // Getting CallData/CallType shouldn't be required to call into JS. 656 CallData callData; 657 CallType callType = getCallData(world.vm(), functionObject, callData); 658 if (callType == CallType::None) { 659 optionalDetails = { { "Unable to prepare JavaScript async function to be called"_s } }; 660 break; 661 } 662 663 returnValue = JSExecState::profiledCall(&globalObject, JSC::ProfilingReason::Other, functionObject, callType, callData, &proxy, markedArguments, evaluationException); 664 } while (false); 665 666 InspectorInstrumentation::didEvaluateScript(m_frame); 667 668 if (evaluationException && !optionalDetails) { 669 ExceptionDetails details; 670 reportException(&globalObject, evaluationException, sourceCode.cachedScript(), &details); 671 optionalDetails = WTFMove(details); 672 } 673 674 m_sourceURL = savedSourceURL; 675 676 if (optionalDetails) 677 return makeUnexpected(*optionalDetails); 678 return returnValue; 582 679 } 583 680 … … 589 686 ValueOrException ScriptController::executeUserAgentScriptInWorld(DOMWrapperWorld& world, const String& script, bool forceUserGesture) 590 687 { 688 return executeUserAgentScriptInWorldInternal(world, { script, false, WTF::nullopt, forceUserGesture }); 689 } 690 691 ValueOrException ScriptController::executeUserAgentScriptInWorldInternal(DOMWrapperWorld& world, RunJavaScriptParameters&& parameters) 692 { 591 693 auto& document = *m_frame.document(); 592 694 if (!shouldAllowUserAgentScripts(document)) 593 return makeUnexpected(ExceptionDetails { "Unable to run user agent scripts in this document for security reasons"_s , 0, 0, { }});695 return makeUnexpected(ExceptionDetails { "Unable to run user agent scripts in this document for security reasons"_s }); 594 696 595 697 document.setHasEvaluatedUserAgentScripts(); 596 return executeScriptInWorld(world, script, forceUserGesture); 698 return executeScriptInWorld(world, WTFMove(parameters)); 699 } 700 701 void ScriptController::executeAsynchronousUserAgentScriptInWorld(DOMWrapperWorld& world, RunJavaScriptParameters&& parameters, ResolveFunction&& resolveFunction) 702 { 703 auto result = executeUserAgentScriptInWorldInternal(world, WTFMove(parameters)); 704 705 // FIXME: If the result is a thenable, install the fulfill/reject handlers instead of resolving now. 706 707 resolveFunction(result); 597 708 } 598 709 -
trunk/Source/WebCore/bindings/js/ScriptController.h
r253654 r253950 24 24 #include "FrameLoaderTypes.h" 25 25 #include "JSWindowProxy.h" 26 #include "SerializedScriptValue.h" 26 27 #include "WindowProxy.h" 27 28 #include <JavaScriptCore/JSBase.h> … … 64 65 class SecurityOrigin; 65 66 class Widget; 67 68 enum class RunAsAsyncFunction : bool; 69 66 70 struct ExceptionDetails; 71 struct RunJavaScriptParameters; 67 72 68 73 enum ReasonForCallingCanExecuteScripts { … … 92 97 static void getAllWorlds(Vector<Ref<DOMWrapperWorld>>&); 93 98 99 using ResolveFunction = CompletionHandler<void(ValueOrException)>; 100 94 101 WEBCORE_EXPORT JSC::JSValue executeScriptIgnoringException(const String& script, bool forceUserGesture = false); 95 102 JSC::JSValue executeScriptInWorldIgnoringException(DOMWrapperWorld&, const String& script, bool forceUserGesture = false); 96 ValueOrException executeScriptInWorld(DOMWrapperWorld&, const String& script, bool forceUserGesture = false);97 103 WEBCORE_EXPORT JSC::JSValue executeUserAgentScriptInWorldIgnoringException(DOMWrapperWorld&, const String& script, bool forceUserGesture); 98 104 WEBCORE_EXPORT ValueOrException executeUserAgentScriptInWorld(DOMWrapperWorld&, const String& script, bool forceUserGesture); 105 WEBCORE_EXPORT void executeAsynchronousUserAgentScriptInWorld(DOMWrapperWorld&, RunJavaScriptParameters&&, ResolveFunction&&); 106 JSC::JSValue evaluateIgnoringException(const ScriptSourceCode&); 107 JSC::JSValue evaluateInWorldIgnoringException(const ScriptSourceCode&, DOMWrapperWorld&); 99 108 100 109 bool shouldAllowUserAgentScripts(Document&) const; … … 106 115 // Darwin is an exception to this rule: it is OK to call this function from any thread, even reentrantly. 107 116 static void initializeThreading(); 108 109 JSC::JSValue evaluateIgnoringException(const ScriptSourceCode&);110 JSC::JSValue evaluateInWorldIgnoringException(const ScriptSourceCode&, DOMWrapperWorld&);111 ValueOrException evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld&);112 117 113 118 void loadModuleScriptInWorld(LoadableModuleScript&, const String& moduleName, Ref<ModuleFetchParameters>&&, DOMWrapperWorld&); … … 172 177 173 178 private: 179 ValueOrException executeUserAgentScriptInWorldInternal(DOMWrapperWorld&, RunJavaScriptParameters&&); 180 ValueOrException executeScriptInWorld(DOMWrapperWorld&, RunJavaScriptParameters&&); 181 ValueOrException evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld&); 182 ValueOrException callInWorld(RunJavaScriptParameters&&, DOMWrapperWorld&); 183 174 184 void setupModuleScriptHandlers(LoadableModuleScript&, JSC::JSInternalPromise&, DOMWrapperWorld&); 175 185 -
trunk/Source/WebCore/xml/XPathGrammar.cpp
r235935 r253950 1973 1973 { 1974 1974 (yyvsp[(3) - (3)].locationPath)->setAbsolute(); 1975 (yyval.expression) = new Path(std::unique_ptr<Expression>((yyvsp[(1) - (3)].expression)), std::unique_ptr<LocationPath>((yyvsp[(3) - (3)].locationPath)));1975 (yyval.expression) = new XPath::Path(std::unique_ptr<Expression>((yyvsp[(1) - (3)].expression)), std::unique_ptr<LocationPath>((yyvsp[(3) - (3)].locationPath))); 1976 1976 ;} 1977 1977 break; … … 1982 1982 (yyvsp[(3) - (3)].locationPath)->prependStep(std::unique_ptr<Step>((yyvsp[(2) - (3)].step))); 1983 1983 (yyvsp[(3) - (3)].locationPath)->setAbsolute(); 1984 (yyval.expression) = new Path(std::unique_ptr<Expression>((yyvsp[(1) - (3)].expression)), std::unique_ptr<LocationPath>((yyvsp[(3) - (3)].locationPath)));1984 (yyval.expression) = new XPath::Path(std::unique_ptr<Expression>((yyvsp[(1) - (3)].expression)), std::unique_ptr<LocationPath>((yyvsp[(3) - (3)].locationPath))); 1985 1985 ;} 1986 1986 break; -
trunk/Source/WebCore/xml/XPathGrammar.y
r209883 r253950 402 402 { 403 403 $3->setAbsolute(); 404 $$ = new Path(std::unique_ptr<Expression>($1), std::unique_ptr<LocationPath>($3));404 $$ = new XPath::Path(std::unique_ptr<Expression>($1), std::unique_ptr<LocationPath>($3)); 405 405 } 406 406 | … … 409 409 $3->prependStep(std::unique_ptr<Step>($2)); 410 410 $3->setAbsolute(); 411 $$ = new Path(std::unique_ptr<Expression>($1), std::unique_ptr<LocationPath>($3));411 $$ = new XPath::Path(std::unique_ptr<Expression>($1), std::unique_ptr<LocationPath>($3)); 412 412 } 413 413 ; -
trunk/Source/WebKit/ChangeLog
r253941 r253950 1 2019-12-30 Brady Eidson <beidson@apple.com> 2 3 Add WKWebView SPI to evaluate a function with arguments 4 https://bugs.webkit.org/show_bug.cgi?id=205239 5 6 Reviewed by Alex Christensen. 7 8 * Shared/API/APISerializedScriptValue.h: 9 10 * UIProcess/API/C/WKPage.cpp: 11 (WKPageRunJavaScriptInMainFrame): 12 13 * UIProcess/API/Cocoa/APISerializedScriptValueCocoa.mm: 14 (API::sharedContext): 15 (API::SerializedScriptValue::deserialize): 16 (API::SerializedScriptValue::wireBytesFromNSObject): 17 18 * UIProcess/API/Cocoa/WKWebView.mm: 19 (-[WKWebView evaluateJavaScript:completionHandler:]): 20 (validateArgument): 21 (-[WKWebView _evaluateJavaScript:asAsyncFunction:withArguments:forceUserGesture:completionHandler:]): 22 (-[WKWebView _callAsyncFunction:withArguments:completionHandler:]): 23 (-[WKWebView _evaluateJavaScriptWithoutUserGesture:completionHandler:]): 24 (-[WKWebView _evaluateJavaScript:forceUserGesture:completionHandler:]): Deleted. 25 * UIProcess/API/Cocoa/WKWebViewPrivate.h: 26 27 * UIProcess/API/glib/WebKitWebView.cpp: 28 (webkit_web_view_run_javascript): 29 (webkit_web_view_run_javascript_in_world): 30 (resourcesStreamReadCallback): 31 32 * UIProcess/WebPageProxy.cpp: 33 (WebKit::WebPageProxy::runJavaScriptInMainFrame): 34 (WebKit::WebPageProxy::runJavaScriptInMainFrameScriptWorld): 35 * UIProcess/WebPageProxy.h: 36 37 * UIProcess/socket/RemoteInspectorProtocolHandler.cpp: 38 (WebKit::RemoteInspectorProtocolHandler::runScript): 39 40 * WebProcess/WebPage/WebPage.cpp: 41 (WebKit::WebPage::runJavaScript): 42 (WebKit::WebPage::runJavaScriptInMainFrameScriptWorld): 43 (WebKit::WebPage::runJavaScriptInFrame): 44 * WebProcess/WebPage/WebPage.h: 45 * WebProcess/WebPage/WebPage.messages.in: 46 1 47 2019-12-29 Peng Liu <peng.liu6@apple.com> 2 48 -
trunk/Source/WebKit/Shared/API/APISerializedScriptValue.h
r225278 r253950 62 62 #if PLATFORM(COCOA) && defined(__OBJC__) 63 63 static id deserialize(WebCore::SerializedScriptValue&, JSValueRef* exception); 64 static Optional<Vector<uint8_t>> wireBytesFromNSObject(id); 64 65 #endif 65 66 -
trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp
r253519 r253950 2473 2473 void WKPageRunJavaScriptInMainFrame(WKPageRef pageRef, WKStringRef scriptRef, void* context, WKPageRunJavaScriptFunction callback) 2474 2474 { 2475 toImpl(pageRef)->runJavaScriptInMainFrame( toImpl(scriptRef)->string(), true, [context, callback](API::SerializedScriptValue* returnValue, Optional<WebCore::ExceptionDetails>, CallbackBase::Error error) {2475 toImpl(pageRef)->runJavaScriptInMainFrame({ toImpl(scriptRef)->string(), false, WTF::nullopt, true }, [context, callback](API::SerializedScriptValue* returnValue, Optional<WebCore::ExceptionDetails>, CallbackBase::Error error) { 2476 2476 callback(toAPI(returnValue), (error != CallbackBase::Error::None) ? toAPI(API::Error::create().ptr()) : 0, context); 2477 2477 }); -
trunk/Source/WebKit/UIProcess/API/Cocoa/APISerializedScriptValueCocoa.mm
r242339 r253950 27 27 #include "APISerializedScriptValue.h" 28 28 29 #import <JavaScriptCore/APICast.h> 29 30 #import <JavaScriptCore/JSContext.h> 31 #import <JavaScriptCore/JSGlobalObjectInlines.h> 30 32 #import <JavaScriptCore/JSValue.h> 31 33 #import <wtf/NeverDestroyed.h> … … 60 62 }; 61 63 64 static SharedJSContext& sharedContext() 65 { 66 static NeverDestroyed<SharedJSContext> sharedContext; 67 return sharedContext.get(); 68 } 69 62 70 id SerializedScriptValue::deserialize(WebCore::SerializedScriptValue& serializedScriptValue, JSValueRef* exception) 63 71 { 64 72 ASSERT(RunLoop::isMain()); 65 static NeverDestroyed<SharedJSContext> sharedContext; 66 JSContext* context = sharedContext.get().ensureContext(); 73 JSContext* context = sharedContext().ensureContext(); 67 74 68 75 JSValueRef valueRef = serializedScriptValue.deserialize([context JSGlobalContextRef], exception); … … 74 81 } 75 82 83 Optional<Vector<uint8_t>> SerializedScriptValue::wireBytesFromNSObject(id object) 84 { 85 ASSERT(RunLoop::isMain()); 86 JSContext* context = sharedContext().ensureContext(); 87 JSValue *value = [JSValue valueWithObject:object inContext:context]; 88 if (!value) 89 return WTF::nullopt; 90 91 auto globalObject = toJS([context JSGlobalContextRef]); 92 ASSERT(globalObject); 93 JSC::JSLockHolder lock(globalObject); 94 95 auto coreValue = WebCore::SerializedScriptValue::create(*globalObject, toJS(globalObject, [value JSValueRef])); 96 return coreValue->toWireBytes(); 97 } 98 76 99 } // API -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
r253733 r253950 823 823 - (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^)(id, NSError *))completionHandler 824 824 { 825 [self _evaluateJavaScript:javaScriptString forceUserGesture:YES completionHandler:completionHandler]; 826 } 827 828 - (void)_evaluateJavaScript:(NSString *)javaScriptString forceUserGesture:(BOOL)forceUserGesture completionHandler:(void (^)(id, NSError *))completionHandler 825 [self _evaluateJavaScript:javaScriptString asAsyncFunction:NO withArguments:nil forceUserGesture:YES completionHandler:completionHandler]; 826 } 827 828 static bool validateArgument(id argument) 829 { 830 if ([argument isKindOfClass:[NSString class]] || [argument isKindOfClass:[NSNumber class]] || [argument isKindOfClass:[NSDate class]] || [argument isKindOfClass:[NSNull class]]) 831 return true; 832 833 if ([argument isKindOfClass:[NSArray class]]) { 834 __block BOOL valid = true; 835 836 [argument enumerateObjectsUsingBlock:^(id object, NSUInteger, BOOL *stop) { 837 if (!validateArgument(object)) { 838 valid = false; 839 *stop = YES; 840 } 841 }]; 842 843 return valid; 844 } 845 846 if ([argument isKindOfClass:[NSDictionary class]]) { 847 __block bool valid = true; 848 849 [argument enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { 850 if (!validateArgument(key) || !validateArgument(value)) { 851 valid = false; 852 *stop = YES; 853 } 854 }]; 855 856 return valid; 857 } 858 859 return false; 860 } 861 862 - (void)_evaluateJavaScript:(NSString *)javaScriptString asAsyncFunction:(BOOL)asAsyncFunction withArguments:(NSDictionary<NSString *, id> *)arguments forceUserGesture:(BOOL)forceUserGesture completionHandler:(void (^)(id, NSError *))completionHandler 829 863 { 830 864 auto handler = adoptNS([completionHandler copy]); 831 865 832 _page->runJavaScriptInMainFrame(javaScriptString, forceUserGesture, [handler](API::SerializedScriptValue* serializedScriptValue, Optional<WebCore::ExceptionDetails> details, WebKit::ScriptValueCallback::Error errorCode) { 866 Optional<WebCore::ArgumentWireBytesMap> argumentsMap; 867 if (asAsyncFunction) 868 argumentsMap = WebCore::ArgumentWireBytesMap { }; 869 NSString *errorMessage = nil; 870 871 for (id key in arguments) { 872 id value = [arguments objectForKey:key]; 873 if (!validateArgument(value)) { 874 errorMessage = @"Function argument values must be one of the following types, or contain only the following types: NSString, NSNumber, NSDate, NSArray, and NSDictionary"; 875 break; 876 } 877 878 auto wireBytes = API::SerializedScriptValue::wireBytesFromNSObject(value); 879 // Since we've validated the input dictionary above, we should never fail to serialize it into wire bytes. 880 ASSERT(wireBytes); 881 argumentsMap->set(key, *wireBytes); 882 } 883 884 if (errorMessage) { 885 RetainPtr<NSMutableDictionary> userInfo = adoptNS([[NSMutableDictionary alloc] init]); 886 887 [userInfo setObject:localizedDescriptionForErrorCode(WKErrorJavaScriptExceptionOccurred) forKey:NSLocalizedDescriptionKey]; 888 [userInfo setObject:errorMessage forKey:_WKJavaScriptExceptionMessageErrorKey]; 889 890 auto error = adoptNS([[NSError alloc] initWithDomain:WKErrorDomain code:WKErrorJavaScriptExceptionOccurred userInfo:userInfo.get()]); 891 dispatch_async(dispatch_get_main_queue(), [handler, error] { 892 auto rawHandler = (void (^)(id, NSError *))handler.get(); 893 rawHandler(nil, error.get()); 894 }); 895 896 return; 897 } 898 899 _page->runJavaScriptInMainFrame(WebCore::RunJavaScriptParameters { javaScriptString, !!asAsyncFunction, WTFMove(argumentsMap), !!forceUserGesture }, [handler](API::SerializedScriptValue* serializedScriptValue, Optional<WebCore::ExceptionDetails> details, WebKit::ScriptValueCallback::Error errorCode) { 833 900 if (!handler) 834 901 return; … … 1924 1991 } 1925 1992 1993 - (void)_callAsyncFunction:(NSString *)javaScriptString withArguments:(NSDictionary<NSString *, id> *)arguments completionHandler:(void (^)(id, NSError *error))completionHandler 1994 { 1995 [self _evaluateJavaScript:javaScriptString asAsyncFunction:YES withArguments:arguments forceUserGesture:YES completionHandler:completionHandler]; 1996 } 1997 1926 1998 - (NSData *)_sessionStateData 1927 1999 { … … 2066 2138 - (void)_evaluateJavaScriptWithoutUserGesture:(NSString *)javaScriptString completionHandler:(void (^)(id, NSError *))completionHandler 2067 2139 { 2068 [self _evaluateJavaScript:javaScriptString forceUserGesture:NO completionHandler:completionHandler];2140 [self _evaluateJavaScript:javaScriptString asAsyncFunction:NO withArguments:nil forceUserGesture:NO completionHandler:completionHandler]; 2069 2141 } 2070 2142 -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
r253733 r253950 316 316 317 317 - (void)_takePDFSnapshotWithConfiguration:(WKSnapshotConfiguration *)snapshotConfiguration completionHandler:(void (^)(NSData *pdfSnapshotData, NSError *error))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)); 318 319 - (void)_callAsyncFunction:(NSString *)javaScriptString withArguments:(NSDictionary<NSString *, id> *)arguments completionHandler:(void (^)(id, NSError *error))completionHandler; 320 318 321 @end 319 322 -
trunk/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
r253881 r253950 3637 3637 3638 3638 GRefPtr<GTask> task = adoptGRef(g_task_new(webView, cancellable, callback, userData)); 3639 getPage(webView).runJavaScriptInMainFrame( String::fromUTF8(script), true, [task = WTFMove(task)](API::SerializedScriptValue* serializedScriptValue, Optional<ExceptionDetails> details, WebKit::CallbackBase::Error) {3639 getPage(webView).runJavaScriptInMainFrame({ String::fromUTF8(script), false, WTF::nullopt, true }, [task = WTFMove(task)](API::SerializedScriptValue* serializedScriptValue, Optional<ExceptionDetails> details, WebKit::CallbackBase::Error) { 3640 3640 ExceptionDetails exceptionDetails; 3641 3641 if (details) … … 3738 3738 3739 3739 GRefPtr<GTask> task = adoptGRef(g_task_new(webView, cancellable, callback, userData)); 3740 getPage(webView).runJavaScriptInMainFrameScriptWorld( String::fromUTF8(script), true, String::fromUTF8(worldName), [task = WTFMove(task)](API::SerializedScriptValue* serializedScriptValue, Optional<ExceptionDetails> details, WebKit::CallbackBase::Error) {3740 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) { 3741 3741 ExceptionDetails exceptionDetails; 3742 3742 if (details) … … 3780 3780 WebKitWebView* webView = WEBKIT_WEB_VIEW(g_task_get_source_object(task.get())); 3781 3781 gpointer outputStreamData = g_memory_output_stream_get_data(G_MEMORY_OUTPUT_STREAM(object)); 3782 getPage(webView).runJavaScriptInMainFrame( String::fromUTF8(reinterpret_cast<const gchar*>(outputStreamData)), true,3782 getPage(webView).runJavaScriptInMainFrame({ String::fromUTF8(reinterpret_cast<const gchar*>(outputStreamData)), false, WTF::nullopt, true}, 3783 3783 [task](API::SerializedScriptValue* serializedScriptValue, Optional<ExceptionDetails> details, WebKit::CallbackBase::Error) { 3784 3784 ExceptionDetails exceptionDetails; -
trunk/Source/WebKit/UIProcess/WebPageProxy.cpp
r253881 r253950 3850 3850 } 3851 3851 3852 void WebPageProxy::runJavaScriptInMainFrame( const String& script, bool forceUserGesture, WTF::Function<void (API::SerializedScriptValue*, Optional<WebCore::ExceptionDetails>, CallbackBase::Error)>&& callbackFunction)3853 { 3854 runJavaScriptInMainFrameScriptWorld( script, forceUserGesture, WTF::nullopt, WTFMove(callbackFunction));3855 } 3856 3857 void WebPageProxy::runJavaScriptInMainFrameScriptWorld( const String& script, bool forceUserGesture, const Optional<String>& worldName, WTF::Function<void(API::SerializedScriptValue*, Optional<ExceptionDetails>, CallbackBase::Error)>&& callbackFunction)3852 void WebPageProxy::runJavaScriptInMainFrame(RunJavaScriptParameters&& parameters, WTF::Function<void (API::SerializedScriptValue*, Optional<WebCore::ExceptionDetails>, CallbackBase::Error)>&& callbackFunction) 3853 { 3854 runJavaScriptInMainFrameScriptWorld(WTFMove(parameters), WTF::nullopt, WTFMove(callbackFunction)); 3855 } 3856 3857 void WebPageProxy::runJavaScriptInMainFrameScriptWorld(RunJavaScriptParameters&& parameters, const Optional<String>& worldName, WTF::Function<void(API::SerializedScriptValue*, Optional<ExceptionDetails>, CallbackBase::Error)>&& callbackFunction) 3858 3858 { 3859 3859 // For backward-compatibility support running script in a WebView which has not done any loads yets. … … 3866 3866 3867 3867 auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivity("WebPageProxy::runJavaScriptInMainFrameScriptWorld"_s)); 3868 send(Messages::WebPage::RunJavaScriptInMainFrameScriptWorld( script, forceUserGesture, worldName, callbackID));3868 send(Messages::WebPage::RunJavaScriptInMainFrameScriptWorld(parameters, worldName, callbackID)); 3869 3869 } 3870 3870 -
trunk/Source/WebKit/UIProcess/WebPageProxy.h
r253881 r253950 93 93 #include <WebCore/PointerID.h> 94 94 #include <WebCore/RegistrableDomain.h> 95 #include <WebCore/RunJavaScriptParameters.h> 95 96 #include <WebCore/ScrollTypes.h> 96 97 #include <WebCore/SearchPopupMenu.h> … … 1063 1064 void getSourceForFrame(WebFrameProxy*, WTF::Function<void (const String&, CallbackBase::Error)>&&); 1064 1065 void getWebArchiveOfFrame(WebFrameProxy*, Function<void (API::Data*, CallbackBase::Error)>&&); 1065 void runJavaScriptInMainFrame( const String&, bool, WTF::Function<void (API::SerializedScriptValue*, Optional<WebCore::ExceptionDetails>, CallbackBase::Error)>&& callbackFunction);1066 void runJavaScriptInMainFrameScriptWorld( const String&, bool, const Optional<String>& worldName, WTF::Function<void(API::SerializedScriptValue*, Optional<WebCore::ExceptionDetails>, CallbackBase::Error)>&& callbackFunction);1066 void runJavaScriptInMainFrame(WebCore::RunJavaScriptParameters&&, WTF::Function<void (API::SerializedScriptValue*, Optional<WebCore::ExceptionDetails>, CallbackBase::Error)>&& callbackFunction); 1067 void runJavaScriptInMainFrameScriptWorld(WebCore::RunJavaScriptParameters&&, const Optional<String>& worldName, WTF::Function<void(API::SerializedScriptValue*, Optional<WebCore::ExceptionDetails>, CallbackBase::Error)>&& callbackFunction); 1067 1068 // For sub frames. 1068 1069 void runJavaScriptInFrame(WebCore::FrameIdentifier, const String& script, bool forceUserGesture, WTF::Function<void(API::SerializedScriptValue*, Optional<WebCore::ExceptionDetails>, CallbackBase::Error)>&& callbackFunction); -
trunk/Source/WebKit/UIProcess/socket/RemoteInspectorProtocolHandler.cpp
r253868 r253950 127 127 void RemoteInspectorProtocolHandler::runScript(const String& script) 128 128 { 129 m_page.runJavaScriptInMainFrame( script, false,129 m_page.runJavaScriptInMainFrame({ script, false, WTF::nullopt, false }, 130 130 [](API::SerializedScriptValue*, Optional<WebCore::ExceptionDetails> exceptionDetails, CallbackBase::Error) { 131 131 if (exceptionDetails) -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp
r253881 r253950 215 215 #include <WebCore/ResourceRequest.h> 216 216 #include <WebCore/ResourceResponse.h> 217 #include <WebCore/RunJavaScriptParameters.h> 217 218 #include <WebCore/RuntimeEnabledFeatures.h> 218 219 #include <WebCore/SWClientConnection.h> … … 3353 3354 } 3354 3355 3355 void WebPage::runJavaScript(WebFrame* frame, const String& script, bool forceUserGesture, const Optional<String>& worldName, CallbackID callbackID)3356 void WebPage::runJavaScript(WebFrame* frame, RunJavaScriptParameters&& parameters, const Optional<String>& worldName, CallbackID callbackID) 3356 3357 { 3357 3358 // NOTE: We need to be careful when running scripts that the objects we depend on don't 3358 3359 // disappear during script execution. 3359 3360 3360 JSLockHolder lock(commonVM());3361 ValueOrException result;3362 RefPtr<SerializedScriptValue> serializedResultValue;3363 3364 3361 auto* world = worldName ? InjectedBundleScriptWorld::find(worldName.value()) : &InjectedBundleScriptWorld::normalWorld(); 3365 if (frame && frame->coreFrame() && world) { 3366 result = frame->coreFrame()->script().executeUserAgentScriptInWorld(world->coreWorld(), script, forceUserGesture); 3362 if (!frame || !frame->coreFrame() || !world) { 3363 send(Messages::WebPageProxy::ScriptValueCallback({ }, ExceptionDetails { "Unable to execute JavaScript: Page is in invalid state"_s }, callbackID)); 3364 return; 3365 } 3366 3367 auto resolveFunction = [protectedThis = makeRef(*this), this, world = makeRef(*world), frame = makeRef(*frame), callbackID](ValueOrException result) { 3368 RefPtr<SerializedScriptValue> serializedResultValue; 3367 3369 if (result) { 3368 serializedResultValue = SerializedScriptValue::create(frame->jsContextForWorld(world ),3370 serializedResultValue = SerializedScriptValue::create(frame->jsContextForWorld(world.ptr()), 3369 3371 toRef(frame->coreFrame()->script().globalObject(world->coreWorld()), result.value()), nullptr); 3370 3372 } 3371 } 3372 3373 IPC::DataReference dataReference; 3374 if (serializedResultValue) 3375 dataReference = serializedResultValue->data(); 3376 3377 Optional<ExceptionDetails> details; 3378 if (!result) 3379 details = result.error(); 3380 3381 send(Messages::WebPageProxy::ScriptValueCallback(dataReference, details, callbackID)); 3382 } 3383 3384 void WebPage::runJavaScriptInMainFrameScriptWorld(const String& script, bool forceUserGesture, const Optional<String>& worldName, CallbackID callbackID) 3385 { 3386 runJavaScript(mainWebFrame(), script, forceUserGesture, worldName, callbackID); 3373 3374 IPC::DataReference dataReference; 3375 if (serializedResultValue) 3376 dataReference = serializedResultValue->data(); 3377 3378 Optional<ExceptionDetails> details; 3379 if (!result) 3380 details = result.error(); 3381 3382 send(Messages::WebPageProxy::ScriptValueCallback(dataReference, details, callbackID)); 3383 }; 3384 3385 JSLockHolder lock(commonVM()); 3386 frame->coreFrame()->script().executeAsynchronousUserAgentScriptInWorld(world->coreWorld(), WTFMove(parameters), WTFMove(resolveFunction)); 3387 } 3388 3389 void WebPage::runJavaScriptInMainFrameScriptWorld(RunJavaScriptParameters&& parameters, const Optional<String>& worldName, CallbackID callbackID) 3390 { 3391 runJavaScript(mainWebFrame(), WTFMove(parameters), worldName, callbackID); 3387 3392 } 3388 3393 … … 3391 3396 WebFrame* frame = WebProcess::singleton().webFrame(frameID); 3392 3397 ASSERT(mainWebFrame() != frame); 3393 runJavaScript(frame, script, forceUserGesture, WTF::nullopt, callbackID);3398 runJavaScript(frame, { script, false, WTF::nullopt, forceUserGesture }, WTF::nullopt, callbackID); 3394 3399 } 3395 3400 -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.h
r253881 r253950 198 198 struct KeypressCommand; 199 199 struct PromisedAttachmentInfo; 200 struct RunJavaScriptParameters; 200 201 struct TextCheckingResult; 201 202 struct ViewportArguments; … … 1436 1437 void getSourceForFrame(WebCore::FrameIdentifier, CallbackID); 1437 1438 void getWebArchiveOfFrame(WebCore::FrameIdentifier, CallbackID); 1438 void runJavaScript(WebFrame*, const String&, bool forceUserGesture, const Optional<String>& worldName, CallbackID);1439 void runJavaScriptInMainFrameScriptWorld( const String&, bool forceUserGesture, const Optional<String>& worldName, CallbackID);1439 void runJavaScript(WebFrame*, WebCore::RunJavaScriptParameters&&, const Optional<String>& worldName, CallbackID); 1440 void runJavaScriptInMainFrameScriptWorld(WebCore::RunJavaScriptParameters&&, const Optional<String>& worldName, CallbackID); 1440 1441 void runJavaScriptInFrame(WebCore::FrameIdentifier, const String&, bool forceUserGesture, CallbackID); 1441 1442 void forceRepaint(CallbackID); -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
r253881 r253950 205 205 GetSourceForFrame(WebCore::FrameIdentifier frameID, WebKit::CallbackID callbackID) 206 206 GetWebArchiveOfFrame(WebCore::FrameIdentifier frameID, WebKit::CallbackID callbackID) 207 RunJavaScriptInMainFrameScriptWorld( String script, bool forceUserGesture, Optional<String> worldName, WebKit::CallbackID callbackID)207 RunJavaScriptInMainFrameScriptWorld(struct WebCore::RunJavaScriptParameters parameters, Optional<String> worldName, WebKit::CallbackID callbackID) 208 208 RunJavaScriptInFrame(WebCore::FrameIdentifier frameID, String script, bool forceUserGesture, WebKit::CallbackID callbackID) 209 209 ForceRepaint(WebKit::CallbackID callbackID) -
trunk/Tools/ChangeLog
r253947 r253950 1 2019-12-30 Brady Eidson <beidson@apple.com> 2 3 Add WKWebView SPI to evaluate a function with arguments 4 https://bugs.webkit.org/show_bug.cgi?id=205239 5 6 Reviewed by Alex Christensen. 7 8 * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: 9 * TestWebKitAPI/Tests/WebKitCocoa/AsyncFunction.mm: Added. 10 (TestWebKitAPI::TEST): 11 * TestWebKitAPI/cocoa/TestWKWebView.h: 12 * TestWebKitAPI/cocoa/TestWKWebView.mm: 13 (-[WKWebView objectByCallingAsyncFunction:withArguments:error:]): 14 1 15 2019-12-30 Carlos Alberto Lopez Perez <clopez@igalia.com> 2 16 -
trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
r253811 r253950 291 291 51B1EE961C80FAEF0064FB98 /* IndexedDBPersistence-1.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 51B1EE941C80FADD0064FB98 /* IndexedDBPersistence-1.html */; }; 292 292 51B1EE971C80FAEF0064FB98 /* IndexedDBPersistence-2.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 51B1EE951C80FADD0064FB98 /* IndexedDBPersistence-2.html */; }; 293 51B40D9E23AC962400E05241 /* AsyncFunction.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51B40D9D23AC960E00E05241 /* AsyncFunction.mm */; }; 293 294 51BCEE4E1C84F53B0042C82E /* IndexedDBMultiProcess-1.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 51BCEE4C1C84F52C0042C82E /* IndexedDBMultiProcess-1.html */; }; 294 295 51BCEE4F1C84F53B0042C82E /* IndexedDBMultiProcess-2.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 51BCEE4D1C84F52C0042C82E /* IndexedDBMultiProcess-2.html */; }; … … 1842 1843 51B1EE941C80FADD0064FB98 /* IndexedDBPersistence-1.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "IndexedDBPersistence-1.html"; sourceTree = "<group>"; }; 1843 1844 51B1EE951C80FADD0064FB98 /* IndexedDBPersistence-2.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "IndexedDBPersistence-2.html"; sourceTree = "<group>"; }; 1845 51B40D9D23AC960E00E05241 /* AsyncFunction.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AsyncFunction.mm; sourceTree = "<group>"; }; 1844 1846 51B454EB1B4E236B0085EAA6 /* WebViewCloseInsideDidFinishLoadForFrame.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebViewCloseInsideDidFinishLoadForFrame.mm; sourceTree = "<group>"; }; 1845 1847 51BCEE491C84F4AF0042C82E /* IndexedDBMultiProcess.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IndexedDBMultiProcess.mm; sourceTree = "<group>"; }; … … 2830 2832 A1798B8122431D65000764BD /* ApplePay.mm */, 2831 2833 63F668201F97C3AA0032EE51 /* ApplicationManifest.mm */, 2834 51B40D9D23AC960E00E05241 /* AsyncFunction.mm */, 2832 2835 834138C6203261B900F26960 /* AsyncPolicyForNavigationResponse.mm */, 2833 2836 3760C4F0211249AF00233ACC /* AttrStyle.mm */, … … 4537 4540 63F668221F97F7F90032EE51 /* ApplicationManifest.mm in Sources */, 4538 4541 6354F4D11F7C3AB500D89DF3 /* ApplicationManifestParser.cpp in Sources */, 4542 51B40D9E23AC962400E05241 /* AsyncFunction.mm in Sources */, 4539 4543 834138C7203261CA00F26960 /* AsyncPolicyForNavigationResponse.mm in Sources */, 4540 4544 7CCE7EB41A411A7E00447C4C /* AttributedString.mm in Sources */, -
trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h
r252458 r253950 64 64 - (id)objectByEvaluatingJavaScriptWithUserGesture:(NSString *)script; 65 65 - (id)objectByEvaluatingJavaScript:(NSString *)script; 66 - (id)objectByCallingAsyncFunction:(NSString *)script withArguments:(NSDictionary *)arguments error:(NSError **)errorOut; 66 67 - (unsigned)waitUntilClientWidthIs:(unsigned)expectedClientWidth; 67 68 @end -
trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm
r252458 r253950 179 179 } 180 180 181 - (id)objectByCallingAsyncFunction:(NSString *)script withArguments:(NSDictionary *)arguments error:(NSError **)errorOut 182 { 183 bool isWaitingForJavaScript = false; 184 if (errorOut) 185 *errorOut = nil; 186 187 RetainPtr<id> evalResult; 188 [self _callAsyncFunction:script withArguments:arguments completionHandler:[&] (id result, NSError *error) { 189 evalResult = result; 190 if (errorOut) 191 *errorOut = [error retain]; 192 isWaitingForJavaScript = true; 193 }]; 194 TestWebKitAPI::Util::run(&isWaitingForJavaScript); 195 196 if (errorOut) 197 [*errorOut autorelease]; 198 199 return evalResult.autorelease(); 200 } 201 181 202 - (NSString *)stringByEvaluatingJavaScript:(NSString *)script 182 203 {
Note: See TracChangeset
for help on using the changeset viewer.