Changeset 283276 in webkit
- Timestamp:
- Sep 29, 2021, 4:28:22 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 29 edited
- 2 copied
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/html/HTMLIFrameElement.idl (modified) (1 diff)
-
Source/WebCore/inspector/InspectorFrontendHost.cpp (modified) (3 diffs)
-
Source/WebCore/inspector/InspectorFrontendHost.h (modified) (3 diffs)
-
Source/WebCore/inspector/InspectorFrontendHost.idl (modified) (2 diffs)
-
Source/WebInspectorUI/ChangeLog (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Controllers/WebInspectorExtensionController.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Main.html (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Protocol/InspectorFrontendAPI.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Views/TabBrowser.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Views/WebInspectorExtensionTabContentView.js (modified) (4 diffs)
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/SourcesCocoa.txt (modified) (1 diff)
-
Source/WebKit/UIProcess/API/APIInspectorExtension.cpp (modified) (1 diff)
-
Source/WebKit/UIProcess/API/APIInspectorExtension.h (modified) (1 diff)
-
Source/WebKit/UIProcess/API/Cocoa/_WKInspectorExtensionPrivateForTesting.h (added)
-
Source/WebKit/UIProcess/API/Cocoa/_WKInspectorExtensionTesting.mm (added)
-
Source/WebKit/UIProcess/Cocoa/GroupActivities/GroupActivitiesSessionNotifier.mm (modified) (1 diff)
-
Source/WebKit/UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.cpp (modified) (1 diff)
-
Source/WebKit/UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.h (modified) (1 diff)
-
Source/WebKit/UIProcess/Inspector/mac/WKInspectorResourceURLSchemeHandler.mm (modified) (1 diff)
-
Source/WebKit/WebKit.xcodeproj/project.pbxproj (modified) (5 diffs)
-
Source/WebKit/WebProcess/Inspector/WebInspectorUIExtensionController.cpp (modified) (3 diffs)
-
Source/WebKit/WebProcess/Inspector/WebInspectorUIExtensionController.h (modified) (2 diffs)
-
Source/WebKit/WebProcess/Inspector/WebInspectorUIExtensionController.messages.in (modified) (1 diff)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/SourcesCocoa.txt (modified) (1 diff)
-
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (modified) (9 diffs)
-
Tools/TestWebKitAPI/Tests/WebKitCocoa/InspectorExtension-basic-tab.html (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtension.mm (copied) (copied from trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionDelegate.mm ) (9 diffs)
-
Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionDelegate.mm (modified) (5 diffs)
-
Tools/TestWebKitAPI/cocoa/TestInspectorURLSchemeHandler.h (added)
-
Tools/TestWebKitAPI/cocoa/TestInspectorURLSchemeHandler.mm (copied) (copied from trunk/Source/WebKit/UIProcess/Inspector/mac/WKInspectorResourceURLSchemeHandler.mm ) (6 diffs)
-
Tools/TestWebKitAPI/cocoa/TestWKWebView.mm (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r283275 r283276 1 2021-09-29 BJ Burg <bburg@apple.com> 2 3 [Cocoa] add _WKInspectorExtension SPI to evaluate script on an extension tab 4 https://bugs.webkit.org/show_bug.cgi?id=230646 5 <rdar://problem/83420328> 6 7 Reviewed by Devin Rousso. 8 9 Exercised by new API test: WKInspectorExtension.CanEvaluateScriptInExtensionTab 10 11 * inspector/InspectorFrontendHost.h: 12 * inspector/InspectorFrontendHost.idl: 13 * inspector/InspectorFrontendHost.cpp: 14 (WebCore::InspectorFrontendHost::evaluateScriptInExtensionTab): 15 Find the global object that corresponds to the passed-in <iframe> and 16 try to evaluate scriptSource in the mainThreadNormalWorld() of that <iframe>. 17 18 * html/HTMLIFrameElement.idl: Add [JSGenerateToNativeObject] so that 19 it's possible to pass HTMLIFrameElement to the IDL function and convert it 20 to the native object (HTMLIFrameElement&) from a JSValue. 21 1 22 2021-09-29 Alan Bujtas <zalan@apple.com> 2 23 -
trunk/Source/WebCore/html/HTMLIFrameElement.idl
r274832 r283276 20 20 21 21 [ 22 Exposed=Window 22 Exposed=Window, 23 JSGenerateToNativeObject 23 24 ] interface HTMLIFrameElement : HTMLElement { 24 25 [Reflect, CEReactions=NotNeeded] attribute DOMString align; -
trunk/Source/WebCore/inspector/InspectorFrontendHost.cpp
r281182 r283276 43 43 #include "FocusController.h" 44 44 #include "Frame.h" 45 #include "HTMLIFrameElement.h" 45 46 #include "HitTestResult.h" 46 47 #include "InspectorController.h" … … 70 71 71 72 using namespace Inspector; 73 using ValueOrException = Expected<JSC::JSValue, ExceptionDetails>; 72 74 73 75 #if ENABLE(CONTEXT_MENUS) … … 707 709 m_client->didHideExtensionTab(extensionID, extensionTabID); 708 710 } 711 712 ExceptionOr<JSC::JSValue> InspectorFrontendHost::evaluateScriptInExtensionTab(HTMLIFrameElement& extensionFrameElement, const String& scriptSource) 713 { 714 Frame* frame = extensionFrameElement.contentFrame(); 715 if (!frame) 716 return Exception { InvalidStateError, "Unable to find global object for <iframe>"_s }; 717 718 Ref<Frame> protectedFrame(*frame); 719 720 JSDOMGlobalObject* frameGlobalObject = frame->script().globalObject(mainThreadNormalWorld()); 721 if (!frameGlobalObject) 722 return Exception { InvalidStateError, "Unable to find global object for <iframe>"_s }; 723 724 JSC::SuspendExceptionScope scope(&frameGlobalObject->vm()); 725 ValueOrException result = frame->script().evaluateInWorld(ScriptSourceCode(scriptSource), mainThreadNormalWorld()); 726 727 if (!result) 728 return Exception { InvalidStateError, result.error().message }; 729 730 return WTFMove(result.value()); 731 } 732 709 733 #endif // ENABLE(INSPECTOR_EXTENSIONS) 710 734 -
trunk/Source/WebCore/inspector/InspectorFrontendHost.h
r278253 r283276 31 31 #include "ContextMenu.h" 32 32 #include "ContextMenuProvider.h" 33 #include "ExceptionOr.h" 33 34 #include <wtf/RefCounted.h> 34 35 #include <wtf/Vector.h> … … 40 41 class Event; 41 42 class FrontendMenuProvider; 43 class HTMLIFrameElement; 42 44 class InspectorFrontendClient; 43 45 class Page; … … 142 144 void didShowExtensionTab(const String& extensionID, const String& extensionTabID); 143 145 void didHideExtensionTab(const String& extensionID, const String& extensionTabID); 146 ExceptionOr<JSC::JSValue> evaluateScriptInExtensionTab(HTMLIFrameElement& extensionFrame, const String& scriptSource); 144 147 #endif 145 148 -
trunk/Source/WebCore/inspector/InspectorFrontendHost.idl
r275982 r283276 1 1 /* 2 * Copyright (C) 2007-202 0Apple Inc. All rights reserved.2 * Copyright (C) 2007-2021 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> 4 4 * Copyright (C) 2009 Google Inc. All rights reserved. … … 101 101 [Conditional=INSPECTOR_EXTENSIONS] undefined didShowExtensionTab(DOMString extensionID, DOMString extensionTabID); 102 102 [Conditional=INSPECTOR_EXTENSIONS] undefined didHideExtensionTab(DOMString extensionID, DOMString extensionTabID); 103 [Conditional=INSPECTOR_EXTENSIONS] any evaluateScriptInExtensionTab(HTMLIFrameElement extensionFrame, DOMString scriptSource); 103 104 }; 104 105 -
trunk/Source/WebInspectorUI/ChangeLog
r283212 r283276 1 2021-09-29 BJ Burg <bburg@apple.com> 2 3 [Cocoa] add _WKInspectorExtension SPI to evaluate script on an extension tab 4 https://bugs.webkit.org/show_bug.cgi?id=230646 5 <rdar://problem/83420328> 6 7 Reviewed by Devin Rousso. 8 9 Add a new InspectorFrontendAPI method to evaluate script on an iframe within 10 Web Inspector. This in turn calls out to InspectorFrontendHost to do the actual evaluation. 11 Otherwise, the CSP policy set by the tab content may block any such evaluation 12 if the 'script-src' directive does not include 'unsafe-eval'. 13 14 * UserInterface/Protocol/InspectorFrontendAPI.js: 15 (InspectorFrontendAPI.showExtensionTab): 16 (InspectorFrontendAPI.evaluateScriptInExtensionTab): 17 Call through to the WebInspectorExtensionController method. 18 19 * UserInterface/Controllers/WebInspectorExtensionController.js: 20 (WI.WebInspectorExtensionController.prototype.evaluateScriptInExtensionTab): Added. 21 Try to get the <iframe> for a extensionTabID, and use InspectorFrontendHost to 22 evaluate script in the context of the <iframe>. Be sure to correctly wrap the result. 23 24 * UserInterface/Views/WebInspectorExtensionTabContentView.js: 25 (WI.WebInspectorExtensionTabContentView): 26 (WI.WebInspectorExtensionTabContentView.prototype.get iframeElement): 27 (WI.WebInspectorExtensionTabContentView.shouldSaveTab): 28 (WI.WebInspectorExtensionTabContentView.prototype.initialLayout): Deleted. 29 While writing the API test, I saw that the first evaluation frequently failed 30 because the <iframe> did not exist. Change this class so that the <iframe> 31 is created in the constructor. Add a getter for the <iframe> element. 32 33 (WI.WebInspectorExtensionTabContentView.prototype._extensionFrameDidLoad): 34 (WI.WebInspectorExtensionTabContentView.prototype._maybeDispatchDidShowExtensionTab): 35 While writing this patch, it became apparent that didShowExtensionTab() was being 36 called prior to the iframe actually completing its initial load. Then, the test 37 would try to evaluate script on about:blank instead of the actual tab content. 38 To fix this, require that the <iframe> be attached and have fired the `onload` event 39 before we notify clients that it has been 'shown'. 40 41 * UserInterface/Main.html: 42 Adjust the default CSP policy to not mention img-src. This allows ports such as 43 Cocoa to set their own img-src CSP directive. These changes are necessary to allow 44 images to load from custom URL schemes. 45 46 * UserInterface/Views/TabBrowser.js: 47 (WI.TabBrowser.prototype.bestTabContentViewForRepresentedObject): 48 The new API test exposes a bug in this assertion, namely, that it does not account 49 for the situation where a tab does not wish to be saved. In that case, the displayed 50 WebInspectorExtensionTabContentView is *not* at index 0 of WI.TabBrowser.recentTabContentViews. 51 This is correctly handled with a special case in WI.TabBrowser._tabBarItemSelected, 52 so incorporate that logic into the assertion. 53 1 54 2021-09-28 BJ Burg <bburg@apple.com> 2 55 -
trunk/Source/WebInspectorUI/UserInterface/Controllers/WebInspectorExtensionController.js
r283196 r283276 171 171 } 172 172 } 173 174 evaluateScriptInExtensionTab(extensionTabID, scriptSource) 175 { 176 let tabContentView = this._extensionTabContentViewForExtensionTabIDMap.get(extensionTabID); 177 if (!tabContentView) { 178 WI.reportInternalError("Unable to evaluate with unknown extensionTabID: " + extensionTabID); 179 return WI.WebInspectorExtension.ErrorCode.InvalidRequest; 180 } 181 182 let iframe = tabContentView.iframeElement; 183 if (!(iframe instanceof HTMLIFrameElement)) { 184 WI.reportInternalError("Unable to evaluate without an <iframe> for extensionTabID: " + extensionTabID); 185 return WI.WebInspectorExtension.ErrorCode.InvalidRequest; 186 } 187 188 try { 189 return {result: InspectorFrontendHost.evaluateScriptInExtensionTab(iframe, scriptSource)}; 190 } catch (error) { 191 return {error: error.message}; 192 } 193 } 173 194 }; 174 195 -
trunk/Source/WebInspectorUI/UserInterface/Main.html
r281663 r283276 28 28 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 29 29 <!-- 30 Note that some WebKit ports may set custom 'frame-src' and 'connect-src' directives via HTTP response header.30 Note that some WebKit ports may set custom 'frame-src', 'img-src', and 'connect-src' directives via HTTP response header. 31 31 The combined CSP policy requires a request to be allowed by both directive lists, so 'default-src' is omitted. 32 32 --> 33 <meta http-equiv="Content-Security-Policy" content=" img-src * file: blob: resource:;media-src * blob:; font-src * blob:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' data:; object-src 'none'">33 <meta http-equiv="Content-Security-Policy" content="media-src * blob:; font-src * blob:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' data:; object-src 'none'"> 34 34 35 35 <link rel="stylesheet" href="External/CodeMirror/codemirror.css"> -
trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorFrontendAPI.js
r283212 r283276 236 236 { 237 237 return WI.sharedApp.extensionController.showExtensionTab(extensionTabID); 238 } 238 }, 239 240 // Returns a string (WI.WebInspectorExtension.ErrorCode) if an error occurred that prevented evaluation. 241 // Returns an object with a 'result' key and value that is the result of the script evaluation. 242 // Returns an object with an 'error' key and value in the case that an exception was thrown. 243 evaluateScriptInExtensionTab(extensionTabID, scriptSource) 244 { 245 return WI.sharedApp.extensionController.evaluateScriptInExtensionTab(extensionTabID, scriptSource); 246 }, 239 247 }; -
trunk/Source/WebInspectorUI/UserInterface/Views/TabBrowser.js
r268691 r283276 121 121 bestTabContentViewForRepresentedObject(representedObject, options = {}) 122 122 { 123 console.assert(!this.selectedTabContentView || this.selectedTabContentView === this._recentTabContentViews[0]); 123 let shouldSaveTab = this.selectedTabContentView?.constructor.shouldSaveTab() || this.selectedTabContentView?.constructor.shouldPinTab(); 124 console.assert(!this.selectedTabContentView || this.selectedTabContentView === this._recentTabContentViews[0] || !shouldSaveTab); 124 125 125 126 let tabContentView = this._recentTabContentViews.find((tabContentView) => tabContentView.type === options.preferredTabType); -
trunk/Source/WebInspectorUI/UserInterface/Views/WebInspectorExtensionTabContentView.js
r273522 r283276 40 40 this._tabInfo = tabInfo; 41 41 this._sourceURL = sourceURL; 42 43 // FIXME: the <iframe>'s document is implicitly reloaded when this 44 // content view's element is detached and later re-attached to the DOM. 45 // This is a bug and will be addressed in <https://webkit.org/b/230758>. 46 this._iframeElement = this.element.appendChild(document.createElement("iframe")); 47 this._iframeElement.addEventListener("load", this._extensionFrameDidLoad.bind(this)); 48 this._iframeElement.src = this._sourceURL; 49 50 this._frameContentDidLoad = false; 42 51 } 43 52 … … 45 54 46 55 get extensionTabID() { return this._extensionTabID; } 56 get iframeElement() { return this._iframeElement; } 47 57 48 58 get type() … … 60 70 super.attached(); 61 71 62 if (InspectorFrontendHost.supportsWebExtensions) 63 InspectorFrontendHost.didShowExtensionTab(this._extension.extensionID, this._extensionTabID); 72 this._maybeDispatchDidShowExtensionTab(); 64 73 } 65 74 … … 79 88 static shouldSaveTab() { return false; } 80 89 81 // Pr otected90 // Private 82 91 83 initialLayout()92 _extensionFrameDidLoad() 84 93 { 85 super.initialLayout(); 94 this._frameContentDidLoad = true; 95 this._maybeDispatchDidShowExtensionTab(); 96 } 86 97 87 let iframeElement = this.element.appendChild(document.createElement("iframe")); 88 iframeElement.src = this._sourceURL; 98 _maybeDispatchDidShowExtensionTab() 99 { 100 if (!this._frameContentDidLoad || !this.element.isConnected) 101 return; 102 103 if (InspectorFrontendHost.supportsWebExtensions) 104 InspectorFrontendHost.didShowExtensionTab(this._extension.extensionID, this._extensionTabID); 89 105 } 90 106 }; -
trunk/Source/WebKit/ChangeLog
r283274 r283276 1 2021-09-29 BJ Burg <bburg@apple.com> 2 3 [Cocoa] add _WKInspectorExtension SPI to evaluate script on an extension tab 4 https://bugs.webkit.org/show_bug.cgi?id=230646 5 <rdar://problem/83420328> 6 7 Reviewed by Devin Rousso. 8 9 Add new testing API for evaluating script expressions in the context of a 10 tab created by _WKInspectorExtension. For the most part, this is implemented 11 in the same way as the -evaluateScript: method, but the script is evaluated 12 within the Web Inspector frontend itself rather than in the inspected page. 13 14 To avoid CSP issues, the actual evaluation is performed on subframes using a 15 new InspectorFrontendHost method which takes an <iframe> and script source. 16 17 Along the way, tweak Web Inspector's CSP policy to allow loading images from 18 custom URL schemes as specified using _WKInspectorConfiguration. This is so 19 that tab icons from the test-resource: scheme can be loaded in the main frame 20 of Web Inspector's WKWebView under testing situations. 21 22 * SourcesCocoa.txt: 23 * WebKit.xcodeproj/project.pbxproj: 24 Add new files. 25 26 * UIProcess/API/APIInspectorExtension.h: 27 * UIProcess/API/APIInspectorExtension.cpp: 28 (API::InspectorExtension::evaluateScriptInExtensionTab): 29 Based on evaluateScript(). Call through to the shared extension controller. 30 31 * UIProcess/API/Cocoa/_WKInspectorExtensionPrivateForTesting.h: Added. 32 * UIProcess/API/Cocoa/_WKInspectorExtensionTesting.mm: Added. 33 (-[_WKInspectorExtension _evaluateScript:inExtensionTabWithIdentifier:completionHandler:]): 34 Added. Call through to the shared extension controller. 35 36 * UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.h: 37 * UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.cpp: 38 (WebKit::WebInspectorUIExtensionControllerProxy::evaluateScriptInExtensionTab): 39 Based on evaluateScript(). Send IPC to the Inspector WebProcess. 40 41 * WebProcess/Inspector/WebInspectorUIExtensionController.h: 42 * WebProcess/Inspector/WebInspectorUIExtensionController.messages.in: 43 * WebProcess/Inspector/WebInspectorUIExtensionController.cpp: 44 (WebKit::WebInspectorUIExtensionController::evaluateScriptInExtensionTab): 45 Based on evaluateScriptForExtension. Call into the frontend API 46 which will perform the actual evaluation on the <iframe> contentWindow. 47 48 * UIProcess/Inspector/mac/WKInspectorResourceURLSchemeHandler.mm: 49 (-[WKInspectorResourceURLSchemeHandler webView:startURLSchemeTask:]): 50 Specify the list of custom protocols as allowable sources for 'img-src'. 51 The 'img-src' directive also includes 'file: blob: resource:' as allowable 52 sources, since this was the previous CSP policy defined in Main.html. 53 54 * UIProcess/Cocoa/GroupActivities/GroupActivitiesSessionNotifier.mm: 55 Fix UnifiedSources fallout by including a missing header. 56 1 57 2021-09-29 Chris Dumez <cdumez@apple.com> 2 58 -
trunk/Source/WebKit/SourcesCocoa.txt
r282230 r283276 289 289 UIProcess/API/Cocoa/_WKInspectorDebuggableInfo.mm 290 290 UIProcess/API/Cocoa/_WKInspectorExtension.mm 291 UIProcess/API/Cocoa/_WKInspectorExtensionTesting.mm 291 292 UIProcess/API/Cocoa/_WKInspectorWindow.mm 292 293 UIProcess/API/Cocoa/_WKInternalDebugFeature.mm -
trunk/Source/WebKit/UIProcess/API/APIInspectorExtension.cpp
r282889 r283276 82 82 } 83 83 84 // For testing. 85 86 void InspectorExtension::evaluateScriptInExtensionTab(const Inspector::ExtensionTabID& extensionTabID, const WTF::String& scriptSource, WTF::CompletionHandler<void(Inspector::ExtensionEvaluationResult)>&& completionHandler) 87 { 88 if (!m_extensionControllerProxy) { 89 completionHandler(makeUnexpected(Inspector::ExtensionError::ContextDestroyed)); 90 return; 91 } 92 93 m_extensionControllerProxy->evaluateScriptInExtensionTab(extensionTabID, scriptSource, WTFMove(completionHandler)); 94 } 95 84 96 } // namespace API 85 97 -
trunk/Source/WebKit/UIProcess/API/APIInspectorExtension.h
r278253 r283276 50 50 void createTab(const WTF::String& tabName, const WTF::URL& tabIconURL, const WTF::URL& sourceURL, WTF::CompletionHandler<void(Expected<Inspector::ExtensionTabID, Inspector::ExtensionError>)>&&); 51 51 void evaluateScript(const WTF::String& scriptSource, const std::optional<WTF::URL>& frameURL, const std::optional<WTF::URL>& contextSecurityOrigin, const std::optional<bool>& useContentScriptContext, WTF::CompletionHandler<void(Inspector::ExtensionEvaluationResult)>&&); 52 void reloadIgnoringCache(const std::optional<bool>& ignoreCache, const std::optional<WTF::String>& userAgent, const std::optional<WTF::String>& injectedScript, WTF::CompletionHandler<void(Inspector::ExtensionEvaluationResult)>&&); 52 void reloadIgnoringCache(const std::optional<bool>& ignoreCache, const std::optional<WTF::String>& userAgent, const std::optional<WTF::String>& injectedScript, WTF::CompletionHandler<void(Inspector::ExtensionEvaluationResult)>&&); 53 54 // For testing. 55 void evaluateScriptInExtensionTab(const Inspector::ExtensionTabID&, const WTF::String& scriptSource, WTF::CompletionHandler<void(Inspector::ExtensionEvaluationResult)>&&); 53 56 54 57 InspectorExtensionClient* client() const { return m_client.get(); } -
trunk/Source/WebKit/UIProcess/Cocoa/GroupActivities/GroupActivitiesSessionNotifier.mm
r279133 r283276 29 29 #if ENABLE(MEDIA_SESSION_COORDINATOR) && HAVE(GROUP_ACTIVITIES) 30 30 31 #import "GroupActivitiesCoordinator.h" 31 32 #import "WKGroupSession.h" 32 33 #import "WebPageProxy.h" -
trunk/Source/WebKit/UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.cpp
r283220 r283276 200 200 } 201 201 202 // API for testing. 203 204 void WebInspectorUIExtensionControllerProxy::evaluateScriptInExtensionTab(const Inspector::ExtensionTabID& extensionTabID, const String& scriptSource, WTF::CompletionHandler<void(Inspector::ExtensionEvaluationResult)>&& completionHandler) 205 { 206 whenFrontendHasLoaded([weakThis = makeWeakPtr(this), extensionTabID, scriptSource, completionHandler = WTFMove(completionHandler)] () mutable { 207 if (!weakThis || !weakThis->m_inspectorPage) { 208 completionHandler(makeUnexpected(Inspector::ExtensionError::ContextDestroyed)); 209 return; 210 } 211 212 weakThis->m_inspectorPage->sendWithAsyncReply(Messages::WebInspectorUIExtensionController::EvaluateScriptInExtensionTab {extensionTabID, scriptSource}, [completionHandler = WTFMove(completionHandler)](const IPC::DataReference& dataReference, const std::optional<WebCore::ExceptionDetails>& details, const std::optional<Inspector::ExtensionError>& error) mutable { 213 if (error) { 214 completionHandler(makeUnexpected(error.value())); 215 return; 216 } 217 218 if (details) { 219 Expected<RefPtr<API::SerializedScriptValue>, WebCore::ExceptionDetails> returnedValue = makeUnexpected(details.value()); 220 return completionHandler({ returnedValue }); 221 } 222 223 completionHandler({ { API::SerializedScriptValue::adopt({ dataReference.data(), dataReference.size() }).ptr() } }); 224 }); 225 }); 226 } 202 227 203 228 // WebInspectorUIExtensionControllerProxy IPC messages. -
trunk/Source/WebKit/UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.h
r283220 r283276 63 63 void showExtensionTab(const Inspector::ExtensionTabID&, CompletionHandler<void(Expected<void, Inspector::ExtensionError>)>&&); 64 64 65 // API for testing. 66 void evaluateScriptInExtensionTab(const Inspector::ExtensionTabID&, const String& scriptSource, WTF::CompletionHandler<void(Inspector::ExtensionEvaluationResult)>&&); 67 65 68 // WebInspectorUIExtensionControllerProxy IPC messages. 66 69 void didShowExtensionTab(const Inspector::ExtensionID&, const Inspector::ExtensionTabID&); -
trunk/Source/WebKit/UIProcess/Inspector/mac/WKInspectorResourceURLSchemeHandler.mm
r276514 r283276 123 123 // Allow fetches for resources that use a registered custom URL scheme. 124 124 if (_allowedURLSchemesForCSP && [self.mainResourceURLsForCSP containsObject:requestURL]) { 125 NSString *stringForCSPPolicy = [NSString stringWithFormat:@"connect-src * %@:", [_allowedURLSchemesForCSP.get().allObjects componentsJoinedByString:@": "]]; 125 NSString *listOfCustomProtocols = [NSString stringWithFormat:@"%@:", [_allowedURLSchemesForCSP.get().allObjects componentsJoinedByString:@": "]]; 126 NSString *stringForCSPPolicy = [NSString stringWithFormat:@"connect-src * %@; img-src * file: blob: resource: %@", listOfCustomProtocols, listOfCustomProtocols]; 126 127 [headerFields setObject:stringForCSPPolicy forKey:@"Content-Security-Policy"]; 127 128 } -
trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj
r283271 r283276 1576 1576 99C3AE2D1DADA6AD00AF5C16 /* WebAutomationSessionMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 99C3AE2C1DADA6A700AF5C16 /* WebAutomationSessionMacros.h */; }; 1577 1577 99C607EB26FA9D4900A0953F /* _WKInspectorIBActions.h in Headers */ = {isa = PBXBuildFile; fileRef = 99C607EA26FA9D4800A0953F /* _WKInspectorIBActions.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1578 99C607F026FB91E800A0953F /* _WKInspectorExtensionPrivateForTesting.h in Headers */ = {isa = PBXBuildFile; fileRef = 99C607EE26FB91E800A0953F /* _WKInspectorExtensionPrivateForTesting.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1579 99C607F126FB91E900A0953F /* _WKInspectorExtensionTesting.mm in Sources */ = {isa = PBXBuildFile; fileRef = 99C607EF26FB91E800A0953F /* _WKInspectorExtensionTesting.mm */; }; 1578 1580 99C81D5A1C20E7E2005C4C82 /* AutomationClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 99C81D551C20DFBE005C4C82 /* AutomationClient.h */; }; 1579 1581 99C81D5D1C21F38B005C4C82 /* APIAutomationClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 99C81D5B1C20E817005C4C82 /* APIAutomationClient.h */; }; … … 5126 5128 99C3AE2C1DADA6A700AF5C16 /* WebAutomationSessionMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebAutomationSessionMacros.h; sourceTree = "<group>"; }; 5127 5129 99C607EA26FA9D4800A0953F /* _WKInspectorIBActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKInspectorIBActions.h; sourceTree = "<group>"; }; 5130 99C607EE26FB91E800A0953F /* _WKInspectorExtensionPrivateForTesting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKInspectorExtensionPrivateForTesting.h; sourceTree = "<group>"; }; 5131 99C607EF26FB91E800A0953F /* _WKInspectorExtensionTesting.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKInspectorExtensionTesting.mm; sourceTree = "<group>"; }; 5128 5132 99C81D551C20DFBE005C4C82 /* AutomationClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutomationClient.h; sourceTree = "<group>"; }; 5129 5133 99C81D561C20DFBE005C4C82 /* AutomationClient.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AutomationClient.mm; sourceTree = "<group>"; }; … … 8215 8219 997965A2253128C700B31AE3 /* _WKInspectorExtensionHost.h */, 8216 8220 99B16755252BB7E10073140E /* _WKInspectorExtensionInternal.h */, 8221 99C607EE26FB91E800A0953F /* _WKInspectorExtensionPrivateForTesting.h */, 8222 99C607EF26FB91E800A0953F /* _WKInspectorExtensionTesting.mm */, 8217 8223 99C607EA26FA9D4800A0953F /* _WKInspectorIBActions.h */, 8218 8224 5CAFDE442130843600B1F7E1 /* _WKInspectorInternal.h */, … … 12004 12010 997965A3253128C700B31AE3 /* _WKInspectorExtensionHost.h in Headers */, 12005 12011 99B16758252BB7E10073140E /* _WKInspectorExtensionInternal.h in Headers */, 12012 99C607F026FB91E800A0953F /* _WKInspectorExtensionPrivateForTesting.h in Headers */, 12006 12013 99C607EB26FA9D4900A0953F /* _WKInspectorIBActions.h in Headers */, 12007 12014 5CAFDE472130846A00B1F7E1 /* _WKInspectorInternal.h in Headers */, … … 14404 14411 5790A66725679CEA0077C5A7 /* _WKAuthenticatorSelectionCriteria.mm in Sources */, 14405 14412 5CBD595C2280EDF4002B22AA /* _WKCustomHeaderFields.mm in Sources */, 14413 99C607F126FB91E900A0953F /* _WKInspectorExtensionTesting.mm in Sources */, 14406 14414 5790A67525679F740077C5A7 /* _WKPublicKeyCredentialCreationOptions.mm in Sources */, 14407 14415 5790A66D25679EB70077C5A7 /* _WKPublicKeyCredentialDescriptor.mm in Sources */, -
trunk/Source/WebKit/WebProcess/Inspector/WebInspectorUIExtensionController.cpp
r283220 r283276 60 60 } 61 61 62 std::optional<Inspector::ExtensionError> WebInspectorUIExtensionController::parseExtensionErrorFromEvaluationResult(InspectorFrontendAPIDispatcher::EvaluationResult result) 62 std::optional<Inspector::ExtensionError> WebInspectorUIExtensionController::parseExtensionErrorFromEvaluationResult(InspectorFrontendAPIDispatcher::EvaluationResult result) const 63 63 { 64 64 if (!result) { … … 159 159 } 160 160 161 JSC::JSObject* WebInspectorUIExtensionController::unwrapEvaluationResultAsObject(InspectorFrontendAPIDispatcher::EvaluationResult result) 161 JSC::JSObject* WebInspectorUIExtensionController::unwrapEvaluationResultAsObject(InspectorFrontendAPIDispatcher::EvaluationResult result) const 162 162 { 163 163 if (!result) … … 360 360 } 361 361 362 // WebInspectorUIExtensionController IPC messages for testing. 363 364 void WebInspectorUIExtensionController::evaluateScriptInExtensionTab(const Inspector::ExtensionTabID& extensionTabID, const String& scriptSource, CompletionHandler<void(const IPC::DataReference&, const std::optional<WebCore::ExceptionDetails>&, const std::optional<Inspector::ExtensionError>&)>&& completionHandler) 365 { 366 if (!m_frontendClient) { 367 completionHandler({ }, std::nullopt, Inspector::ExtensionError::InvalidRequest); 368 return; 369 } 370 371 Vector<Ref<JSON::Value>> arguments { 372 JSON::Value::create(extensionTabID), 373 JSON::Value::create(scriptSource), 374 }; 375 376 m_frontendClient->frontendAPIDispatcher().dispatchCommandWithResultAsync("evaluateScriptInExtensionTab"_s, WTFMove(arguments), [weakThis = makeWeakPtr(this), completionHandler = WTFMove(completionHandler)](InspectorFrontendAPIDispatcher::EvaluationResult&& result) mutable { 377 if (!weakThis) { 378 completionHandler({ }, std::nullopt, Inspector::ExtensionError::ContextDestroyed); 379 return; 380 } 381 382 auto* frontendGlobalObject = weakThis->m_frontendClient->frontendAPIDispatcher().frontendGlobalObject(); 383 if (!frontendGlobalObject) { 384 completionHandler({ }, std::nullopt, Inspector::ExtensionError::ContextDestroyed); 385 return; 386 } 387 388 if (auto parsedError = weakThis->parseExtensionErrorFromEvaluationResult(result)) { 389 if (!result.value().has_value()) { 390 auto exceptionDetails = result.value().error(); 391 LOG(Inspector, "Internal error encountered while evaluating upon the frontend: at %s:%d:%d: %s", exceptionDetails.sourceURL.utf8().data(), exceptionDetails.lineNumber, exceptionDetails.columnNumber, exceptionDetails.message.utf8().data()); 392 } else 393 LOG(Inspector, "Internal error encountered while evaluating upon the frontend."); 394 395 completionHandler({ }, std::nullopt, parsedError); 396 return; 397 } 398 399 // Expected result is either an ErrorString or {result: <any>} or {error: string}. 400 auto objectResult = weakThis->unwrapEvaluationResultAsObject(result); 401 if (!objectResult) { 402 LOG(Inspector, "Unexpected non-object value returned from InspectorFrontendAPI.createTabForExtension()."); 403 completionHandler({ }, std::nullopt, Inspector::ExtensionError::InternalError); 404 return; 405 } 406 ASSERT(result.has_value()); 407 408 JSC::JSValue errorPayload = objectResult->get(frontendGlobalObject, JSC::Identifier::fromString(frontendGlobalObject->vm(), "error"_s)); 409 if (!errorPayload.isUndefined()) { 410 if (!errorPayload.isString()) { 411 completionHandler({ }, std::nullopt, Inspector::ExtensionError::InternalError); 412 return; 413 } 414 415 completionHandler({ }, ExceptionDetails { errorPayload.toWTFString(frontendGlobalObject) }, std::nullopt); 416 return; 417 } 418 419 JSC::JSValue resultPayload = objectResult->get(frontendGlobalObject, JSC::Identifier::fromString(frontendGlobalObject->vm(), "result"_s)); 420 auto serializedResultValue = SerializedScriptValue::create(*frontendGlobalObject, resultPayload); 421 if (!serializedResultValue) { 422 completionHandler({ }, std::nullopt, Inspector::ExtensionError::InternalError); 423 return; 424 } 425 426 completionHandler(serializedResultValue->data(), std::nullopt, std::nullopt); 427 }); 428 } 429 362 430 void WebInspectorUIExtensionController::didShowExtensionTab(const Inspector::ExtensionID& extensionID, const Inspector::ExtensionTabID& extensionTabID) 363 431 { -
trunk/Source/WebKit/WebProcess/Inspector/WebInspectorUIExtensionController.h
r283220 r283276 71 71 void showExtensionTab(const Inspector::ExtensionTabID&, CompletionHandler<void(Expected<void, Inspector::ExtensionError>)>&&); 72 72 73 // WebInspectorUIExtensionController IPC messages for testing. 74 void evaluateScriptInExtensionTab(const Inspector::ExtensionTabID&, const String& scriptSource, CompletionHandler<void(const IPC::DataReference&, const std::optional<WebCore::ExceptionDetails>&, const std::optional<Inspector::ExtensionError>&)>&&); 75 73 76 // Callbacks from the frontend. 74 77 void didShowExtensionTab(const Inspector::ExtensionID&, const Inspector::ExtensionTabID&); … … 76 79 77 80 private: 78 JSC::JSObject* unwrapEvaluationResultAsObject(WebCore::InspectorFrontendAPIDispatcher::EvaluationResult) ;79 std::optional<Inspector::ExtensionError> parseExtensionErrorFromEvaluationResult(WebCore::InspectorFrontendAPIDispatcher::EvaluationResult) ;81 JSC::JSObject* unwrapEvaluationResultAsObject(WebCore::InspectorFrontendAPIDispatcher::EvaluationResult) const; 82 std::optional<Inspector::ExtensionError> parseExtensionErrorFromEvaluationResult(WebCore::InspectorFrontendAPIDispatcher::EvaluationResult) const; 80 83 81 84 WeakPtr<WebCore::InspectorFrontendClient> m_frontendClient; -
trunk/Source/WebKit/WebProcess/Inspector/WebInspectorUIExtensionController.messages.in
r283220 r283276 31 31 ReloadForExtension(String extensionID, std::optional<bool> ignoreCache, std::optional<String> userAgent, std::optional<String> injectedScript) -> (std::optional<Inspector::ExtensionError> error) Async 32 32 ShowExtensionTab(String extensionTabIdentifier) -> (Expected<void, Inspector::ExtensionError> result) Async 33 34 // For testing. 35 EvaluateScriptInExtensionTab(String extensionTabID, String scriptSource) -> (IPC::DataReference resultData, std::optional<WebCore::ExceptionDetails> details, std::optional<Inspector::ExtensionError> error) Async 33 36 } 34 37 -
trunk/Tools/ChangeLog
r283272 r283276 1 2021-09-29 BJ Burg <bburg@apple.com> 2 3 [Cocoa] add _WKInspectorExtension SPI to evaluate script on an extension tab 4 https://bugs.webkit.org/show_bug.cgi?id=230646 5 <rdar://problem/83420328> 6 7 Reviewed by Devin Rousso. 8 9 Add a new test to exercise the SPI. The test sets up an _WKInspectorExtension, 10 creates a tab, evaluates script on the tab, and later reads back the stored value. 11 12 Notably, this test would fail if the extension tab is not currently showing. 13 This is a bug and will be addressed as part of https://bugs.webkit.org/show_bug.cgi?id=230758. 14 15 * TestWebKitAPI/SourcesCocoa.txt: 16 * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: 17 Add new files. 18 19 * TestWebKitAPI/Tests/WebKitCocoa/InspectorExtension-basic-tab.html: 20 Add inline <script> to set window._secretValue. This is checked by the API test. 21 22 * TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtension.mm: Added. 23 (resetGlobalState): 24 (-[UIDelegateForTestingInspectorExtension _webView:didAttachLocalInspector:]): 25 (-[UIDelegateForTestingInspectorExtension _webView:configurationForLocalInspector:]): 26 (-[InspectorExtensionDelegateForTestingInspectorExtension inspectorExtension:didShowTabWithIdentifier:]): 27 (-[InspectorExtensionDelegateForTestingInspectorExtension inspectorExtension:didHideTabWithIdentifier:]): 28 (TEST): 29 30 * TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionDelegate.mm: 31 (-[UIDelegateForTestingInspectorExtensionDelegate _webView:configurationForLocalInspector:]): 32 (TEST): 33 Adopt fixes from WKInspectorExtension that allow extension tab content and icons to load. 34 35 * TestWebKitAPI/cocoa/TestInspectorURLSchemeHandler.h: Added. 36 * TestWebKitAPI/cocoa/TestInspectorURLSchemeHandler.mm: Copied from Source/WebKit/UIProcess/Inspector/mac/WKInspectorResourceURLSchemeHandler.mm. 37 (-[TestInspectorURLSchemeHandler webView:startURLSchemeTask:]): 38 (-[TestInspectorURLSchemeHandler webView:stopURLSchemeTask:]): 39 Add a simple URLSchemeHandler which allows serving test resources from the TestWebKitAPI.resources directory. 40 This is necessary to test _WKInspectorExtension tabs, which must load their content from a custom URL scheme. 41 42 * TestWebKitAPI/cocoa/TestWKWebView.mm: 43 Fix UnifiedSources fallout by adding a missing include. 44 1 45 2021-09-29 Alex Christensen <achristensen@webkit.org> 2 46 -
trunk/Tools/TestWebKitAPI/SourcesCocoa.txt
r280015 r283276 28 28 cocoa/TestCocoa.mm 29 29 cocoa/TestDownloadDelegate.mm 30 cocoa/TestInspectorURLSchemeHandler.mm 30 31 cocoa/TestLegacyDownloadDelegate.mm 31 32 cocoa/TestNavigationDelegate.mm -
trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
r283196 r283276 894 894 999B7EE32551C63B00F450A4 /* WKInspectorExtensionHost.mm in Sources */ = {isa = PBXBuildFile; fileRef = 999B7EE22551C63B00F450A4 /* WKInspectorExtensionHost.mm */; }; 895 895 99B4F9C624EDED9700022B82 /* WKInspectorDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 99B4F9C524EDED9600022B82 /* WKInspectorDelegate.mm */; }; 896 99C607ED26FB90AC00A0953F /* WKInspectorExtension.mm in Sources */ = {isa = PBXBuildFile; fileRef = 99C607EC26FB90AC00A0953F /* WKInspectorExtension.mm */; }; 896 897 99E2846426F91F7F0003F1FA /* WKInspectorExtensionDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 99E2846326F91F7F0003F1FA /* WKInspectorExtensionDelegate.mm */; }; 897 898 99E2846626F93DB50003F1FA /* InspectorExtension-TabIcon-30x30.png in Copy Resources */ = {isa = PBXBuildFile; fileRef = 99E2846526F93D760003F1FA /* InspectorExtension-TabIcon-30x30.png */; }; … … 1520 1521 467C565321B5ED130057516D /* GetSessionCookie.html in Copy Resources */, 1521 1522 41661C662355E85E00D33C27 /* getUserMedia-webaudio.html in Copy Resources */, 1522 074994421EA5034B000DA44D /* invalidDeviceIDHashSalts in Copy Resources */,1523 1523 074994421EA5034B000DA44E /* getUserMedia.html in Copy Resources */, 1524 1524 074994521EA5034B000DA44E /* getUserMedia2.html in Copy Resources */, … … 1579 1579 99E2846826F941540003F1FA /* InspectorExtension-basic-tab.html in Copy Resources */, 1580 1580 99E2846626F93DB50003F1FA /* InspectorExtension-TabIcon-30x30.png in Copy Resources */, 1581 074994421EA5034B000DA44D /* invalidDeviceIDHashSalts in Copy Resources */, 1581 1582 57F56A5C1C7F8CC100F31D7E /* IsNavigationActionTrusted.html in Copy Resources */, 1582 1583 C9B4AD2C1ECA6F7F00F5FEA0 /* js-autoplay-audio.html in Copy Resources */, … … 2625 2626 999B7EE22551C63B00F450A4 /* WKInspectorExtensionHost.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKInspectorExtensionHost.mm; sourceTree = "<group>"; }; 2626 2627 99B4F9C524EDED9600022B82 /* WKInspectorDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKInspectorDelegate.mm; sourceTree = "<group>"; }; 2628 99C607EC26FB90AC00A0953F /* WKInspectorExtension.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKInspectorExtension.mm; sourceTree = "<group>"; }; 2629 99C607F426FD5A1E00A0953F /* TestInspectorURLSchemeHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestInspectorURLSchemeHandler.h; path = cocoa/TestInspectorURLSchemeHandler.h; sourceTree = "<group>"; }; 2630 99C607F526FD5A1F00A0953F /* TestInspectorURLSchemeHandler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = TestInspectorURLSchemeHandler.mm; path = cocoa/TestInspectorURLSchemeHandler.mm; sourceTree = "<group>"; }; 2627 2631 99E2846326F91F7F0003F1FA /* WKInspectorExtensionDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKInspectorExtensionDelegate.mm; sourceTree = "<group>"; }; 2628 2632 99E2846526F93D760003F1FA /* InspectorExtension-TabIcon-30x30.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "InspectorExtension-TabIcon-30x30.png"; sourceTree = "<group>"; }; … … 3324 3328 DF6BC4702534E120008F63CC /* TestDownloadDelegate.h */, 3325 3329 DF6BC46F2534E120008F63CC /* TestDownloadDelegate.mm */, 3330 99C607F426FD5A1E00A0953F /* TestInspectorURLSchemeHandler.h */, 3331 99C607F526FD5A1F00A0953F /* TestInspectorURLSchemeHandler.mm */, 3326 3332 5C72E8CD244FFCE300381EB7 /* TestLegacyDownloadDelegate.h */, 3327 3333 5C72E8CE244FFCE400381EB7 /* TestLegacyDownloadDelegate.mm */, … … 3667 3673 51D124971E763AF8002B2820 /* WKHTTPCookieStore.mm */, 3668 3674 99B4F9C524EDED9600022B82 /* WKInspectorDelegate.mm */, 3675 99C607EC26FB90AC00A0953F /* WKInspectorExtension.mm */, 3669 3676 99E2846326F91F7F0003F1FA /* WKInspectorExtensionDelegate.mm */, 3670 3677 999B7EE22551C63B00F450A4 /* WKInspectorExtensionHost.mm */, … … 4582 4589 isa = PBXGroup; 4583 4590 children = ( 4591 4A410F4D19AF7BEF002EBAB4 /* invalidDeviceIDHashSalts */, 4584 4592 C045F9461385C2F800C0F3CD /* 18-characters.html */, 4585 4593 1C2B81851C89252300A5529F /* Ahem.ttf */, … … 4630 4638 1CC80CE92474F1F7004DC489 /* idempotent-mode-autosizing-only-honors-percentages.html */, 4631 4639 CE3524F51B142BBB0028A7C5 /* input-focus-blur.html */, 4632 4A410F4D19AF7BEF002EBAB4 /* invalidDeviceIDHashSalts */,4633 4640 C9B4AD2B1ECA6F7600F5FEA0 /* js-autoplay-audio.html */, 4634 4641 C99B675B1E3971FC00FC6C80 /* js-play-with-controls.html */, … … 5948 5955 7CCE7F1D1A411AE600447C4C /* WKImageCreateCGImageCrash.cpp in Sources */, 5949 5956 99B4F9C624EDED9700022B82 /* WKInspectorDelegate.mm in Sources */, 5957 99C607ED26FB90AC00A0953F /* WKInspectorExtension.mm in Sources */, 5950 5958 99E2846426F91F7F0003F1FA /* WKInspectorExtensionDelegate.mm in Sources */, 5951 5959 999B7EE32551C63B00F450A4 /* WKInspectorExtensionHost.mm in Sources */, -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InspectorExtension-basic-tab.html
r283196 r283276 1 1 <html> 2 <head> 3 <script> 4 window._secretValue = {answer:42}; 5 </script> 2 6 <body> 3 7 <h1>This is a test extension.</h1> -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtension.mm
r283275 r283276 26 26 #import "config.h" 27 27 28 #import "Test.h" 28 #if ENABLE(INSPECTOR_EXTENSIONS) 29 30 #import "TestCocoa.h" 31 #import "TestInspectorURLSchemeHandler.h" 29 32 #import "Utilities.h" 30 33 #import <WebKit/WKPreferencesPrivate.h> 31 34 #import <WebKit/WKWebViewPrivate.h> 32 35 #import <WebKit/_WKInspector.h> 36 #import <WebKit/_WKInspectorConfiguration.h> 33 37 #import <WebKit/_WKInspectorExtension.h> 34 38 #import <WebKit/_WKInspectorExtensionDelegate.h> 39 #import <WebKit/_WKInspectorExtensionPrivateForTesting.h> 35 40 #import <WebKit/_WKInspectorPrivateForTesting.h> 36 41 #import <wtf/RetainPtr.h> 37 38 #if ENABLE(INSPECTOR_EXTENSIONS)39 42 40 43 static bool didAttachLocalInspectorCalled = false; … … 42 45 static bool didHideExtensionTabWasCalled = false; 43 46 static bool pendingCallbackWasCalled = false; 47 static RetainPtr<TestInspectorURLSchemeHandler> sharedURLSchemeHandler; 44 48 static RetainPtr<_WKInspectorExtension> sharedInspectorExtension; 45 49 static RetainPtr<NSString> sharedExtensionTabIdentifier; … … 53 57 } 54 58 55 @interface UIDelegateForTestingInspectorExtension Delegate: NSObject <WKUIDelegate>59 @interface UIDelegateForTestingInspectorExtension : NSObject <WKUIDelegate> 56 60 @end 57 61 58 @implementation UIDelegateForTestingInspectorExtension Delegate62 @implementation UIDelegateForTestingInspectorExtension 59 63 60 64 - (void)_webView:(WKWebView *)webView didAttachLocalInspector:(_WKInspector *)inspector … … 64 68 } 65 69 70 - (_WKInspectorConfiguration *)_webView:(WKWebView *)webView configurationForLocalInspector:(_WKInspector *)inspector 71 { 72 if (!sharedURLSchemeHandler) 73 sharedURLSchemeHandler = adoptNS([[TestInspectorURLSchemeHandler alloc] init]); 74 75 auto inspectorConfiguration = adoptNS([[_WKInspectorConfiguration alloc] init]); 76 [inspectorConfiguration setURLSchemeHandler:sharedURLSchemeHandler.get() forURLScheme:@"test-resource"]; 77 return inspectorConfiguration.autorelease(); 78 } 79 66 80 @end 67 81 68 82 69 @interface InspectorExtensionDelegateForTesting : NSObject <_WKInspectorExtensionDelegate>83 @interface InspectorExtensionDelegateForTestingInspectorExtension : NSObject <_WKInspectorExtensionDelegate> 70 84 @end 71 85 72 @implementation InspectorExtensionDelegateForTesting {86 @implementation InspectorExtensionDelegateForTestingInspectorExtension { 73 87 } 74 88 … … 85 99 @end 86 100 87 TEST(WKInspectorExtension Delegate, ShowAndHideTabCallbacks)101 TEST(WKInspectorExtension, CanEvaluateScriptInExtensionTab) 88 102 { 89 103 resetGlobalState(); … … 92 106 webViewConfiguration.get().preferences._developerExtrasEnabled = YES; 93 107 auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:webViewConfiguration.get()]); 94 auto uiDelegate = adoptNS([UIDelegateForTestingInspectorExtension Delegatenew]);108 auto uiDelegate = adoptNS([UIDelegateForTestingInspectorExtension new]); 95 109 96 110 [webView setUIDelegate:uiDelegate.get()]; … … 114 128 TestWebKitAPI::Util::run(&pendingCallbackWasCalled); 115 129 116 auto extensionDelegate = adoptNS([InspectorExtensionDelegateForTesting new]);130 auto extensionDelegate = adoptNS([InspectorExtensionDelegateForTestingInspectorExtension new]); 117 131 [sharedInspectorExtension setDelegate:extensionDelegate.get()]; 118 132 119 // Create an extension tab.120 auto iconURL = [ [NSBundle mainBundle] URLForResource:@"InspectorExtension-TabIcon-30x30" withExtension:@"png" subdirectory:@"TestWebKitAPI.resources"];121 auto sourceURL = [ [NSBundle mainBundle] URLForResource:@"InspectorExtension-basic-tab" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];133 // Create and show an extension tab. 134 auto iconURL = [NSURL URLWithString:@"test-resource://FirstExtension/InspectorExtension-TabIcon-30x30.png"]; 135 auto sourceURL = [NSURL URLWithString:@"test-resource://FirstExtension/InspectorExtension-basic-tab.html"]; 122 136 123 137 pendingCallbackWasCalled = false; … … 131 145 TestWebKitAPI::Util::run(&pendingCallbackWasCalled); 132 146 133 // Force a known non-extension tab to be shown before showing the extension tab. Otherwise,134 // if the extension tab was already open, then this test would hang waiting for a didShow callback.135 [[webView _inspector] showConsole];136 137 147 pendingCallbackWasCalled = false; 148 didShowExtensionTabWasCalled = false; 138 149 [[webView _inspector] showExtensionTabWithIdentifier:sharedExtensionTabIdentifier.get() completionHandler:^(NSError * _Nullable error) { 139 150 EXPECT_NULL(error); … … 144 155 TestWebKitAPI::Util::run(&didShowExtensionTabWasCalled); 145 156 146 [[webView _inspector] showConsole]; 147 TestWebKitAPI::Util::run(&didHideExtensionTabWasCalled); 157 // Read back a value that is set in the <iframe>'s script context. 158 pendingCallbackWasCalled = false; 159 auto scriptSource2 = @"window._secretValue"; 160 [sharedInspectorExtension _evaluateScript:scriptSource2 inExtensionTabWithIdentifier:sharedExtensionTabIdentifier.get() completionHandler:^(NSError * _Nullable error, NSDictionary * _Nullable result) { 161 EXPECT_NULL(error); 162 EXPECT_NOT_NULL(result); 163 EXPECT_NS_EQUAL(result[@"answer"], @42); 164 165 pendingCallbackWasCalled = true; 166 }]; 167 TestWebKitAPI::Util::run(&pendingCallbackWasCalled); 168 169 // Check to see that script is actually being evaluated in the <iframe>'s script context. 170 pendingCallbackWasCalled = false; 171 auto scriptSource3 = @"window.top !== window"; 172 [sharedInspectorExtension _evaluateScript:scriptSource3 inExtensionTabWithIdentifier:sharedExtensionTabIdentifier.get() completionHandler:^(NSError * _Nullable error, NSDictionary * _Nullable result) { 173 EXPECT_NULL(error); 174 EXPECT_NOT_NULL(result); 175 EXPECT_NS_EQUAL(result, @YES); 176 177 pendingCallbackWasCalled = true; 178 }]; 179 TestWebKitAPI::Util::run(&pendingCallbackWasCalled); 148 180 149 181 // Unregister the test extension. -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionDelegate.mm
r283196 r283276 26 26 #import "config.h" 27 27 28 #if ENABLE(INSPECTOR_EXTENSIONS) 29 28 30 #import "Test.h" 31 #import "TestInspectorURLSchemeHandler.h" 29 32 #import "Utilities.h" 30 33 #import <WebKit/WKPreferencesPrivate.h> 31 34 #import <WebKit/WKWebViewPrivate.h> 32 35 #import <WebKit/_WKInspector.h> 36 #import <WebKit/_WKInspectorConfiguration.h> 33 37 #import <WebKit/_WKInspectorExtension.h> 34 38 #import <WebKit/_WKInspectorExtensionDelegate.h> … … 36 40 #import <wtf/RetainPtr.h> 37 41 38 #if ENABLE(INSPECTOR_EXTENSIONS)39 40 42 static bool didAttachLocalInspectorCalled = false; 41 43 static bool didShowExtensionTabWasCalled = false; 42 44 static bool didHideExtensionTabWasCalled = false; 43 45 static bool pendingCallbackWasCalled = false; 46 static RetainPtr<TestInspectorURLSchemeHandler> sharedURLSchemeHandler; 44 47 static RetainPtr<_WKInspectorExtension> sharedInspectorExtension; 45 48 static RetainPtr<NSString> sharedExtensionTabIdentifier; … … 62 65 EXPECT_EQ(webView._inspector, inspector); 63 66 didAttachLocalInspectorCalled = true; 67 } 68 69 - (_WKInspectorConfiguration *)_webView:(WKWebView *)webView configurationForLocalInspector:(_WKInspector *)inspector 70 { 71 if (!sharedURLSchemeHandler) 72 sharedURLSchemeHandler = adoptNS([[TestInspectorURLSchemeHandler alloc] init]); 73 74 auto inspectorConfiguration = adoptNS([[_WKInspectorConfiguration alloc] init]); 75 [inspectorConfiguration setURLSchemeHandler:sharedURLSchemeHandler.get() forURLScheme:@"test-resource"]; 76 return inspectorConfiguration.autorelease(); 64 77 } 65 78 … … 118 131 119 132 // Create an extension tab. 120 auto iconURL = [ [NSBundle mainBundle] URLForResource:@"InspectorExtension-TabIcon-30x30" withExtension:@"png" subdirectory:@"TestWebKitAPI.resources"];121 auto sourceURL = [ [NSBundle mainBundle] URLForResource:@"InspectorExtension-basic-tab" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];133 auto iconURL = [NSURL URLWithString:@"test-resource://FirstExtension/InspectorExtension-TabIcon-30x30.png"]; 134 auto sourceURL = [NSURL URLWithString:@"test-resource://FirstExtension/InspectorExtension-basic-tab.html"]; 122 135 123 136 pendingCallbackWasCalled = false; … … 130 143 }]; 131 144 TestWebKitAPI::Util::run(&pendingCallbackWasCalled); 132 133 // Force a known non-extension tab to be shown before showing the extension tab. Otherwise,134 // if the extension tab was already open, then this test would hang waiting for a didShow callback.135 [[webView _inspector] showConsole];136 145 137 146 pendingCallbackWasCalled = false; -
trunk/Tools/TestWebKitAPI/cocoa/TestInspectorURLSchemeHandler.mm
r283275 r283276 25 25 26 26 #import "config.h" 27 #import " WKInspectorResourceURLSchemeHandler.h"27 #import "TestInspectorURLSchemeHandler.h" 28 28 29 #if PLATFORM(MAC)30 31 #import "Logging.h"32 #import "WKURLSchemeTask.h"33 #import "WebInspectorUIProxy.h"34 #import "WebURLSchemeHandlerCocoa.h"35 29 #import <WebCore/MIMETypeRegistry.h> 30 #import <WebKit/WKURLSchemeTask.h> 36 31 #import <wtf/Assertions.h> 37 32 38 @implementation WKInspectorResourceURLSchemeHandler { 33 // Note: this class is a simplified version of WKResourceURLSchemeHandler for testing purposes. 34 35 @implementation TestInspectorURLSchemeHandler { 39 36 RetainPtr<NSMapTable<id <WKURLSchemeTask>, NSOperation *>> _fileLoadOperations; 40 37 RetainPtr<NSBundle> _cachedBundle; 41 38 RetainPtr<NSOperationQueue> _operationQueue; 42 43 RetainPtr<NSSet<NSString *>> _allowedURLSchemesForCSP;44 RetainPtr<NSSet<NSURL *>> _mainResourceURLsForCSP;45 }46 47 - (NSSet<NSString *> *)allowedURLSchemesForCSP48 {49 return _allowedURLSchemesForCSP.get();50 }51 52 - (void)setAllowedURLSchemesForCSP:(NSSet<NSString *> *)allowedURLSchemes53 {54 _allowedURLSchemesForCSP = adoptNS([allowedURLSchemes copy]);55 }56 57 - (NSSet<NSURL *> *)mainResourceURLsForCSP58 {59 if (!_mainResourceURLsForCSP)60 _mainResourceURLsForCSP = adoptNS([[NSSet alloc] initWithObjects:[NSURL URLWithString:WebKit::WebInspectorUIProxy::inspectorPageURL()], [NSURL URLWithString:WebKit::WebInspectorUIProxy::inspectorTestPageURL()], nil]);61 62 return _mainResourceURLsForCSP.get();63 39 } 64 40 … … 67 43 - (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask 68 44 { 69 if (!_cachedBundle) { 70 _cachedBundle = [NSBundle bundleWithIdentifier:@"com.apple.WebInspectorUI"]; 71 72 // It is an error if WebInspectorUI has not already been soft-linked by the time 73 // we load resources from it. And if soft-linking fails, we shouldn't start loads. 74 RELEASE_ASSERT(_cachedBundle); 75 } 45 if (!_cachedBundle) 46 _cachedBundle = [NSBundle mainBundle]; 76 47 77 48 if (!_fileLoadOperations) … … 94 65 95 66 NSURL *requestURL = urlSchemeTask.request.URL; 96 NSURL *fileURLForRequest = [_cachedBundle URLForResource:requestURL.relativePath withExtension:@"" ];67 NSURL *fileURLForRequest = [_cachedBundle URLForResource:requestURL.relativePath withExtension:@"" subdirectory:@"TestWebKitAPI.resources"]; 97 68 if (!fileURLForRequest) { 98 LOG_ERROR("Unable to find Web Inspector resource: %@", requestURL.absoluteString);99 69 [urlSchemeTask didFailWithError:[NSError errorWithDomain:NSCocoaErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil]]; 100 70 return; … … 104 74 NSData *fileData = [NSData dataWithContentsOfURL:fileURLForRequest options:0 error:&readError]; 105 75 if (!fileData) { 106 LOG_ERROR("Unable to read data for Web Inspector resource: %@", requestURL.absoluteString);107 76 [urlSchemeTask didFailWithError:[NSError errorWithDomain:NSCocoaErrorDomain code:NSURLErrorResourceUnavailable userInfo:@{ 108 77 NSUnderlyingErrorKey: readError, … … 120 89 @"Content-Type": mimeType, 121 90 }.mutableCopy); 122 123 // Allow fetches for resources that use a registered custom URL scheme.124 if (_allowedURLSchemesForCSP && [self.mainResourceURLsForCSP containsObject:requestURL]) {125 NSString *stringForCSPPolicy = [NSString stringWithFormat:@"connect-src * %@:", [_allowedURLSchemesForCSP.get().allObjects componentsJoinedByString:@": "]];126 [headerFields setObject:stringForCSPPolicy forKey:@"Content-Security-Policy"];127 }128 91 129 92 RetainPtr<NSHTTPURLResponse> urlResponse = adoptNS([[NSHTTPURLResponse alloc] initWithURL:urlSchemeTask.request.URL statusCode:200 HTTPVersion:nil headerFields:headerFields.get()]); … … 149 112 150 113 @end 151 152 #endif // PLATFORM(MAC) -
trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm
r281468 r283276 34 34 #import <WebKit/WKContentWorld.h> 35 35 #import <WebKit/WKWebViewConfigurationPrivate.h> 36 #import <WebKit/WKWebViewPrivateForTesting.h> 36 37 #import <WebKit/WebKitPrivate.h> 37 38 #import <WebKit/_WKActivatedElementInfo.h>
Note:
See TracChangeset
for help on using the changeset viewer.