Changeset 270604 in webkit
- Timestamp:
- Dec 9, 2020 2:33:47 PM (20 months ago)
- Location:
- trunk
- Files:
-
- 7 added
- 8 deleted
- 45 edited
- 1 copied
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/http/tests/inspector/network/intercept-aborted-request-expected.txt (deleted)
-
LayoutTests/http/tests/inspector/network/intercept-aborted-request.html (deleted)
-
LayoutTests/http/tests/inspector/network/intercept-request-continue-expected.txt (deleted)
-
LayoutTests/http/tests/inspector/network/intercept-request-continue.html (deleted)
-
LayoutTests/http/tests/inspector/network/intercept-request-fragment.html (modified) (3 diffs)
-
LayoutTests/http/tests/inspector/network/intercept-request-main-resource-with-response.html (modified) (1 diff)
-
LayoutTests/http/tests/inspector/network/intercept-request-main-resource.html (modified) (1 diff)
-
LayoutTests/http/tests/inspector/network/intercept-request-properties-expected.txt (modified) (1 diff)
-
LayoutTests/http/tests/inspector/network/intercept-request-properties.html (modified) (11 diffs)
-
LayoutTests/http/tests/inspector/network/intercept-request-subresource-with-error-expected.txt (deleted)
-
LayoutTests/http/tests/inspector/network/intercept-request-subresource-with-error.html (deleted)
-
LayoutTests/http/tests/inspector/network/intercept-request-subresource-with-response.html (modified) (1 diff)
-
LayoutTests/http/tests/inspector/network/intercept-request-subresource.html (modified) (1 diff)
-
LayoutTests/http/tests/inspector/network/intercept-request-with-response-expected.txt (modified) (1 diff)
-
LayoutTests/http/tests/inspector/network/intercept-request-with-response.html (modified) (8 diffs)
-
LayoutTests/http/tests/inspector/network/local-resource-override-basic-expected.txt (modified) (1 diff)
-
LayoutTests/http/tests/inspector/network/local-resource-override-basic.html (modified) (13 diffs)
-
LayoutTests/http/tests/inspector/network/local-resource-override-main-resource.html (modified) (1 diff)
-
LayoutTests/http/tests/inspector/network/local-resource-override-script-tag.html (modified) (1 diff)
-
LayoutTests/http/tests/inspector/network/resource-response-inspector-override.html (modified) (1 diff)
-
LayoutTests/inspector/network/intercept-aborted-request-expected.txt (added)
-
LayoutTests/inspector/network/intercept-aborted-request.html (added)
-
LayoutTests/inspector/network/interceptContinue-expected.txt (added)
-
LayoutTests/inspector/network/interceptContinue.html (added)
-
LayoutTests/inspector/network/interceptRequestWithError-expected.txt (added)
-
LayoutTests/inspector/network/interceptRequestWithError.html (added)
-
LayoutTests/inspector/network/local-resource-override-continue-response-expected.txt (deleted)
-
LayoutTests/inspector/network/local-resource-override-continue-response.html (deleted)
-
LayoutTests/platform/mac-wk1/TestExpectations (modified) (2 diffs)
-
Source/WebInspectorUI/ChangeLog (modified) (1 diff)
-
Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (modified) (12 diffs)
-
Source/WebInspectorUI/UserInterface/Base/HTTPUtilities.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Base/ReferencePage.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Controllers/CSSManager.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Controllers/NetworkManager.js (modified) (15 diffs)
-
Source/WebInspectorUI/UserInterface/Images/DocumentIcons.svg (modified) (2 diffs)
-
Source/WebInspectorUI/UserInterface/Main.html (modified) (4 diffs)
-
Source/WebInspectorUI/UserInterface/Models/LocalResource.js (modified) (7 diffs)
-
Source/WebInspectorUI/UserInterface/Models/LocalResourceOverride.js (modified) (10 diffs)
-
Source/WebInspectorUI/UserInterface/Models/Resource.js (modified) (5 diffs)
-
Source/WebInspectorUI/UserInterface/Models/SourceCode.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Test.html (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Views/ContentView.js (modified) (5 diffs)
-
Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js (modified) (4 diffs)
-
Source/WebInspectorUI/UserInterface/Views/FontResourceContentView.js (modified) (5 diffs)
-
Source/WebInspectorUI/UserInterface/Views/ImageResourceContentView.js (modified) (5 diffs)
-
Source/WebInspectorUI/UserInterface/Views/LocalResourceOverrideLabelView.js (modified) (2 diffs)
-
Source/WebInspectorUI/UserInterface/Views/LocalResourceOverridePopover.css (modified) (3 diffs)
-
Source/WebInspectorUI/UserInterface/Views/LocalResourceOverridePopover.js (modified) (15 diffs)
-
Source/WebInspectorUI/UserInterface/Views/LocalResourceOverrideRequestContentView.css (copied) (copied from trunk/Source/WebInspectorUI/UserInterface/Base/ReferencePage.js) (1 diff)
-
Source/WebInspectorUI/UserInterface/Views/LocalResourceOverrideRequestContentView.js (added)
-
Source/WebInspectorUI/UserInterface/Views/LocalResourceOverrideTreeElement.js (modified) (4 diffs)
-
Source/WebInspectorUI/UserInterface/Views/LocalResourceOverrideWarningView.js (modified) (4 diffs)
-
Source/WebInspectorUI/UserInterface/Views/NavigationSidebarPanel.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Views/OpenResourceDialog.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Views/ResourceContentView.js (modified) (8 diffs)
-
Source/WebInspectorUI/UserInterface/Views/ResourceTreeElement.js (modified) (3 diffs)
-
Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js (modified) (5 diffs)
-
Source/WebInspectorUI/UserInterface/Views/TextResourceContentView.js (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r270598 r270604 1 2020-12-09 Devin Rousso <drousso@apple.com> 2 3 Web Inspector: add UI for request interception 4 https://bugs.webkit.org/show_bug.cgi?id=217032 5 <rdar://problem/69925768> 6 7 Reviewed by Brian Burg. 8 9 * inspector/network/intercept-aborted-request.html: Renamed from LayoutTests/http/tests/inspector/network/intercept-aborted-request.html. 10 * inspector/network/intercept-aborted-request-expected.txt: Renamed from LayoutTests/http/tests/inspector/network/intercept-aborted-request-expected.txt. 11 * inspector/network/interceptContinue.html: Renamed from LayoutTests/http/tests/inspector/network/intercept-request-continue.html. 12 * inspector/network/interceptContinue-expected.txt: Renamed from LayoutTests/http/tests/inspector/network/intercept-request-continue.html. 13 * inspector/network/interceptRequestWithError.html: Renamed from LayoutTests/http/tests/inspector/network/intercept-request-subresource-with-error.html. 14 * inspector/network/interceptRequestWithError-expected.txt: Renamed from LayoutTests/http/tests/inspector/network/intercept-request-subresource-with-error.html. 15 * http/tests/inspector/network/intercept-request-fragment.html: 16 * http/tests/inspector/network/intercept-request-main-resource.html: 17 * http/tests/inspector/network/intercept-request-main-resource-with-response.html: 18 * http/tests/inspector/network/intercept-request-properties.html: 19 * http/tests/inspector/network/intercept-request-properties-expected.txt: 20 * http/tests/inspector/network/intercept-request-subresource.html: 21 * http/tests/inspector/network/intercept-request-subresource-with-response.html: 22 * http/tests/inspector/network/intercept-request-with-response.html: 23 * http/tests/inspector/network/intercept-request-with-response-expected.txt: 24 * http/tests/inspector/network/local-resource-override-basic.html: 25 * http/tests/inspector/network/local-resource-override-basic-expected.txt: 26 * http/tests/inspector/network/local-resource-override-main-resource.html: 27 * http/tests/inspector/network/local-resource-override-script-tag.html: 28 * http/tests/inspector/network/resource-response-inspector-override.html: 29 30 * inspector/network/local-resource-override-continue-response.html: Removed. 31 * inspector/network/local-resource-override-continue-response-expected.txt: Removed. 32 Merged into LayoutTests/inspector/network/interceptContinue.html. 33 34 * platform/mac-wk1/TestExpectations: 35 1 36 2020-12-09 John Wilander <wilander@apple.com> 2 37 -
trunk/LayoutTests/http/tests/inspector/network/intercept-request-fragment.html
r263072 r270604 18 18 let suite = InspectorTest.createAsyncSuite("Network.interceptWithRequest"); 19 19 20 NetworkAgent.addInterception.invoke({21 url: "http://127.0.0.1:8000/inspector/network/resources/stylesheet.css",22 stage: InspectorBackend.Enum.Network.NetworkStage.Request,23 });24 25 20 function addBaselineTestCase({name, description, expression}) { 26 21 suite.addTestCase({ … … 29 24 async test() { 30 25 InspectorTest.log("Triggering load..."); 31 let [requestEvent, responseEvent , fetchResponse] = await Promise.all([26 let [requestEvent, responseEvent] = await Promise.all([ 32 27 WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded), 33 28 WI.Resource.awaitEvent(WI.Resource.Event.ResponseReceived), 34 RuntimeAgent.evaluate(expression),29 InspectorTest.evaluateInPage(expression), 35 30 ]); 36 31 InspectorTest.log("Request URL: " + requestEvent.data.resource.url); … … 44 39 description, 45 40 async test() { 41 let localResourceOverride = WI.LocalResourceOverride.create("http://127.0.0.1:8000/inspector/network/resources/stylesheet.css", WI.LocalResourceOverride.InterceptType.Request, { 42 requestURL: url, 43 }); 44 WI.networkManager.addLocalResourceOverride(localResourceOverride); 45 46 46 InspectorTest.log("Triggering load..."); 47 let [requestEvent, requestInterceptedEvent, fetchResponse] = await Promise.all([ 48 WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded), 49 WI.networkManager.awaitEvent(WI.NetworkManager.Event.RequestIntercepted), 50 RuntimeAgent.evaluate(expression), 47 await Promise.all([ 48 WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded).then((event) => { 49 InspectorTest.log("Request URL: " + event.data.resource.url); 50 }), 51 WI.Resource.awaitEvent(WI.Resource.Event.ResponseReceived).then((event) => { 52 InspectorTest.log("Response URL: " + event.target.url); 53 }), 54 InspectorTest.evaluateInPage(expression), 51 55 ]); 52 InspectorTest.log("Request URL: " + requestEvent.data.resource.url);53 56 54 let [responseEvent, interceptResponse] = await Promise.all([ 55 WI.Resource.awaitEvent(WI.Resource.Event.ResponseReceived), 56 NetworkAgent.interceptWithRequest.invoke({ 57 requestId: requestInterceptedEvent.data.requestId, 58 url, 59 }), 60 ]); 61 InspectorTest.log("Response URL: " + responseEvent.target.url); 57 WI.networkManager.removeLocalResourceOverride(localResourceOverride); 62 58 } 63 59 }); -
trunk/LayoutTests/http/tests/inspector/network/intercept-request-main-resource-with-response.html
r263072 r270604 13 13 description: "Main resource uses request interception on next page load and fulfills request", 14 14 async test() { 15 await NetworkAgent.addInterception.invoke({ 16 url: "http://127.0.0.1:8000/inspector/network/intercept-request-main-resource-with-response.html", 17 stage: InspectorBackend.Enum.Network.NetworkStage.Request, 15 let localResourceOverride = WI.LocalResourceOverride.create("http://127.0.0.1:8000/inspector/network/intercept-request-main-resource-with-response.html", WI.LocalResourceOverride.InterceptType.ResponseSkippingNetwork, { 16 responseMIMEType: "text/html", 17 responseContent: `<!DOCTYPE html><html><head><script src="../resources/inspector-test.js"></`+`script></head><body><p>Overridden page content</p><script>alert("REPLACED HTML CONTENT"); TestPage.completeTest();</`+`script></body></html>`, 18 responseBase64Encoded: false, 19 responseStatus: 200, 20 responseStatusText: "OK", 21 responseHeaders: {}, 18 22 }); 23 WI.networkManager.addLocalResourceOverride(localResourceOverride); 19 24 20 WI.networkManager.singleFireEventListener(WI.NetworkManager.Event.RequestIntercepted, (event) => {21 let {target, requestId, request} = event.data;22 NetworkAgent.interceptRequestWithResponse.invoke({23 requestId,24 mimeType: "text/html",25 content: `<!DOCTYPE html><html><head><script src="../resources/inspector-test.js"></`+`script></head><body><p>Overridden page content</p><script>alert("REPLACED HTML CONTENT"); TestPage.completeTest();</`+`script></body></html>`,26 base64Encoded: false,27 status: 200,28 statusText: "OK",29 headers: {},30 });31 });32 25 await InspectorTest.reloadPage({ignoreCache: false, revalidateAllResources: true}); 33 26 } -
trunk/LayoutTests/http/tests/inspector/network/intercept-request-main-resource.html
r263072 r270604 13 13 description: "Main resource uses request interception on next page load", 14 14 async test() { 15 await NetworkAgent.addInterception.invoke({ 16 url: "http://127.0.0.1:8000/inspector/network/intercept-request-main-resource.html", 17 stage: InspectorBackend.Enum.Network.NetworkStage.Request, 15 let localResourceOverride = WI.LocalResourceOverride.create("http://127.0.0.1:8000/inspector/network/intercept-request-main-resource.html", WI.LocalResourceOverride.InterceptType.Request, { 16 requestURL: "http://127.0.0.1:8000/inspector/network/resources/intercept-request-overriden-page.html", 18 17 }); 19 20 WI.networkManager.singleFireEventListener(WI.NetworkManager.Event.RequestIntercepted, (event) => { 21 let {target, requestId, request} = event.data; 22 NetworkAgent.interceptWithRequest.invoke({ 23 url: "http://127.0.0.1:8000/inspector/network/resources/intercept-request-overriden-page.html", 24 requestId, 25 }); 26 }); 18 WI.networkManager.addLocalResourceOverride(localResourceOverride); 27 19 28 20 await InspectorTest.reloadPage({ignoreCache: false, revalidateAllResources: true}); -
trunk/LayoutTests/http/tests/inspector/network/intercept-request-properties-expected.txt
r263072 r270604 59 59 Triggering load... 60 60 Request details: 61 The URL can’t be shown 61 URI: /inspector/network/resources/intercept-echo.php 62 Response URL: http://127.0.0.1:8000/inspector/network/resources/intercept-echo.php 63 Method: GET 64 Request Headers: 62 65 63 66 -- Running test case: Network.interceptRequest.Headers -
trunk/LayoutTests/http/tests/inspector/network/intercept-request-properties.html
r263072 r270604 36 36 { 37 37 let suite = InspectorTest.createAsyncSuite("Network.interceptWithRequest"); 38 39 NetworkAgent.addInterception.invoke({40 url: "http://127.0.0.1:8000/inspector/network/resources/intercept-echo.php",41 stage: InspectorBackend.Enum.Network.NetworkStage.Request,42 });43 38 44 39 function logRequest(result) { … … 83 78 } 84 79 85 function addTestCase({name, description, expression, override s}) {80 function addTestCase({name, description, expression, override}) { 86 81 suite.addTestCase({ 87 82 name, 88 83 description, 89 84 async test() { 85 let localResourceOverride = WI.LocalResourceOverride.create("http://127.0.0.1:8000/inspector/network/resources/intercept-echo.php", WI.LocalResourceOverride.InterceptType.Request, override); 86 WI.networkManager.addLocalResourceOverride(localResourceOverride); 87 90 88 InspectorTest.log("Triggering load..."); 91 let [requestInterceptedEvent, fetchResponse] = await Promise.all([ 92 WI.networkManager.awaitEvent(WI.NetworkManager.Event.RequestIntercepted), 93 RuntimeAgent.evaluate(expression), 94 ]); 95 96 await NetworkAgent.interceptWithRequest.invoke({ 97 requestId: requestInterceptedEvent.data.requestId, 98 ...overrides, 99 }); 100 101 let response = await RuntimeAgent.awaitPromise(fetchResponse.result.objectId, true); 89 let response = await InspectorTest.evaluateInPage(expression); 90 response = await RuntimeAgent.awaitPromise(response.objectId, true); 102 91 InspectorTest.log("Request details:"); 103 92 logRequest(response.result); 93 94 WI.networkManager.removeLocalResourceOverride(localResourceOverride); 104 95 } 105 96 }); … … 110 101 description: "Tests request method interception", 111 102 expression: "fetchData('resources/intercept-echo.php')", 112 override s: { method: "POST" },103 override: { requestMethod: "POST" }, 113 104 }); 114 105 … … 117 108 description: "Tests request method interception with DELETE", 118 109 expression: "fetchData('resources/intercept-echo.php')", 119 override s: { method: "DELETE" },110 override: { requestMethod: "DELETE" }, 120 111 }); 121 112 … … 124 115 description: "Tests request method interception with NONSTANDARD", 125 116 expression: "fetchData('resources/intercept-echo.php')", 126 override s: { method: "NONSTANDARD" },117 override: { requestMethod: "NONSTANDARD" }, 127 118 }); 128 119 … … 131 122 description: "Tests request method interception with empty string", 132 123 expression: "fetchData('resources/intercept-echo.php')", 133 override s: { method: "" },124 override: { requestMethod: "" }, 134 125 }); 135 126 … … 138 129 description: "Tests request method interception with different URL", 139 130 expression: "fetchData('resources/intercept-echo.php')", 140 override s: { url: "http://127.0.0.1:8000/inspector/network/resources/intercept-echo.php?newURL=value" },131 override: { requestURL: "http://127.0.0.1:8000/inspector/network/resources/intercept-echo.php?newURL=value" }, 141 132 }); 142 133 … … 145 136 description: "Tests request method interception with URL with fragment", 146 137 expression: "fetchData('resources/intercept-echo.php')", 147 override s: { url: "http://127.0.0.1:8000/inspector/network/resources/intercept-echo.php#fragment" },138 override: { requestURL: "http://127.0.0.1:8000/inspector/network/resources/intercept-echo.php#fragment" }, 148 139 }); 149 140 … … 152 143 description: "Tests request method interception with empty URL", 153 144 expression: "fetchData('resources/intercept-echo.php')", 154 override s: { url: "" },145 override: { requestURL: "" }, 155 146 }); 156 147 … … 159 150 description: "Tests request headers interception", 160 151 expression: "fetchData('resources/intercept-echo.php')", 161 override s: { headers: { "X-Value": "overridden" } },152 override: { requestHeaders: { "X-Value": "overridden" } }, 162 153 }); 163 154 … … 166 157 description: "Tests request post data interception", 167 158 expression: "postData('resources/intercept-echo.php')", 168 overrides: { 169 method: "POST", 170 postData: btoa("value=overridden"), 159 override: { 160 requestMethod: "POST", 161 requestHeaders: { 162 "Content-Type": "application/x-www-form-urlencoded", 163 "Content-Length": 16, 164 }, 165 requestData: "value=overridden", 171 166 }, 172 167 }); -
trunk/LayoutTests/http/tests/inspector/network/intercept-request-subresource-with-response.html
r263072 r270604 13 13 description: "Subresource uses request interception with response", 14 14 async test() { 15 await NetworkAgent.addInterception.invoke({ 16 url: "http://127.0.0.1:8000/inspector/network/resources/override.js", 17 stage: InspectorBackend.Enum.Network.NetworkStage.Request, 15 let localResourceOverride = WI.LocalResourceOverride.create("http://127.0.0.1:8000/inspector/network/resources/override.js", WI.LocalResourceOverride.InterceptType.ResponseSkippingNetwork, { 16 responseMIMEType: "text/javascript", 17 responseContent: `alert("OVERRIDDEN override.js TEXT"); TestPage.dispatchEventToFrontend("OverrideContentDidLoad");`, 18 responseBase64Encoded: false, 19 responseStatus: 200, 20 responseStatusText: "OK", 21 responseHeaders: {}, 18 22 }); 23 WI.networkManager.addLocalResourceOverride(localResourceOverride); 19 24 20 WI.networkManager.singleFireEventListener(WI.NetworkManager.Event.RequestIntercepted, (event) => { 21 let {target, requestId, request} = event.data; 22 NetworkAgent.interceptRequestWithResponse.invoke({ 23 requestId, 24 mimeType: "text/javascript", 25 content: `alert("OVERRIDDEN override.js TEXT"); TestPage.dispatchEventToFrontend("OverrideContentDidLoad");`, 26 base64Encoded: false, 27 status: 200, 28 statusText: "OK", 29 headers: {}, 30 }); 31 }); 25 await Promise.all([ 26 InspectorTest.awaitEvent("OverrideContentDidLoad"), 27 InspectorTest.reloadPage({ignoreCache: false, revalidateAllResources: true}), 28 ]); 32 29 33 await InspectorTest.reloadPage({ignoreCache: false, revalidateAllResources: true}); 34 await InspectorTest.awaitEvent("OverrideContentDidLoad"); 30 WI.networkManager.removeLocalResourceOverride(localResourceOverride); 35 31 } 36 32 }); -
trunk/LayoutTests/http/tests/inspector/network/intercept-request-subresource.html
r263072 r270604 13 13 description: "Subresource uses request interception", 14 14 async test() { 15 await NetworkAgent.addInterception.invoke({ 16 url: "http://127.0.0.1:8000/inspector/network/resources/override.js", 17 stage: InspectorBackend.Enum.Network.NetworkStage.Request, 15 let localResourceOverride = WI.LocalResourceOverride.create("http://127.0.0.1:8000/inspector/network/resources/override.js", WI.LocalResourceOverride.InterceptType.Request, { 16 requestURL: "http://127.0.0.1:8000/inspector/network/resources/intercept-request-overriden-script.js", 18 17 }); 19 WI.networkManager.singleFireEventListener(WI.NetworkManager.Event.RequestIntercepted, (event) => { 20 let {target, requestId, request} = event.data; 21 NetworkAgent.interceptWithRequest.invoke({ 22 url: "http://127.0.0.1:8000/inspector/network/resources/intercept-request-overriden-script.js", 23 requestId, 24 }); 25 }); 26 await InspectorTest.reloadPage({ignoreCache: false, revalidateAllResources: true}); 27 await InspectorTest.awaitEvent("OverrideContentDidLoad"); 18 WI.networkManager.addLocalResourceOverride(localResourceOverride); 19 20 await Promise.all([ 21 InspectorTest.awaitEvent("OverrideContentDidLoad"), 22 InspectorTest.reloadPage({ignoreCache: false, revalidateAllResources: true}), 23 ]); 24 25 WI.networkManager.removeLocalResourceOverride(localResourceOverride); 28 26 } 29 27 }); -
trunk/LayoutTests/http/tests/inspector/network/intercept-request-with-response-expected.txt
r263072 r270604 5 5 == Running test suite: Network.interceptRequestWithResponse 6 6 -- Running test case: Network.interceptRequestWithResponse.Text 7 Creating Local Resource Override for: http://127.0.0.1:8000/inspector/network/resources/override.txt 7 8 Triggering load... 8 Res ponse details:9 Resource Loaded: 9 10 URL: http://127.0.0.1:8000/inspector/network/resources/override.txt 10 11 MIME Type: text/plain 11 12 Status: 987 Override Status Text 13 Response Source: Symbol(inspector-override) 12 14 Response Headers: 13 content-type: text/plain14 x-override-header-1: Override-Header-Value-115 x-override-header-2: Override-Header-Value-215 Content-Type: text/plain 16 X-Override-Header-1: Override-Header-Value-1 17 X-Override-Header-2: Override-Header-Value-2 16 18 Content: PASS - OVERRIDDEN TEXT 17 19 18 20 -- Running test case: Network.interceptRequestWithResponse.JavaScript 21 Creating Local Resource Override for: http://127.0.0.1:8000/inspector/network/resources/override.txt 19 22 Triggering load... 20 Res ponse details:23 Resource Loaded: 21 24 URL: http://127.0.0.1:8000/inspector/network/resources/override.txt 22 25 MIME Type: application/javascript 23 26 Status: 200 Super OK 27 Response Source: Symbol(inspector-override) 24 28 Response Headers: 25 content-type: application/javascript26 x-custom-header: Header value29 Content-Type: application/javascript 30 X-Custom-Header: Header value 27 31 Content: /* PASS */ (function() { /* OVERRIDDEN */ })(); 28 32 29 33 -- Running test case: Network.interceptRequestWithResponse.Image 34 Creating Local Resource Override for: http://127.0.0.1:8000/inspector/network/resources/override.txt 30 35 Triggering load... 31 Res ponse details:36 Resource Loaded: 32 37 URL: http://127.0.0.1:8000/inspector/network/resources/override.txt 33 38 MIME Type: image/png 34 39 Status: 200 OK 40 Response Source: Symbol(inspector-override) 35 41 Response Headers: 36 content-type: image/png37 Content: <data>42 Content-Type: image/png 43 Content: [base64] PGRhdGE+ 38 44 39 45 -- Running test case: Network.interceptRequestWithResponse.URL.QueryString 46 Creating Local Resource Override for: http://127.0.0.1:8000/inspector/network/resources/override.txt 40 47 Triggering load... 41 Res ponse details:48 Resource Loaded: 42 49 URL: http://127.0.0.1:8000/inspector/network/resources/override.txt?s=2 43 50 MIME Type: text/plain 44 51 Status: 200 OK 52 Response Source: <not-InspectorOverride> 45 53 Response Headers: 46 content-type: text/plain 47 x-expected: PASS 54 Accept-Ranges: <filtered> 55 Connection: <filtered> 56 Content-Length: 29 57 Content-Type: text/plain 58 Date: <filtered> 59 ETag: <filtered> 60 Keep-Alive: <filtered> 61 Last-Modified: <filtered> 62 Server: <filtered> 63 Content: default override.txt content 64 65 66 -- Running test case: Network.interceptRequestWithResponse.URL.Fragment 67 Creating Local Resource Override for: http://127.0.0.1:8000/inspector/network/resources/override.txt 68 Triggering load... 69 Resource Loaded: 70 URL: http://127.0.0.1:8000/inspector/network/resources/override.txt#frag 71 MIME Type: text/plain 72 Status: 200 OK 73 Response Source: Symbol(inspector-override) 74 Response Headers: 75 Content-Type: text/plain 76 X-Expected: PASS 48 77 Content: PASS 49 78 50 -- Running test case: Network.interceptRequestWithResponse.URL.Fragment 79 -- Running test case: Network.interceptRequestWithResponse.URL.CaseSensitive 80 Creating Local Resource Override for: http://127.0.0.1:8000/inspector/network/resources/override.txt?case=sensitive 51 81 Triggering load... 52 Res ponse details:53 URL: http://127.0.0.1:8000/inspector/network/resources/override.txt 82 Resource Loaded: 83 URL: http://127.0.0.1:8000/inspector/network/resources/override.txt?CaSe=SeNsItIvE 54 84 MIME Type: text/plain 55 85 Status: 200 OK 86 Response Source: Symbol(inspector-override) 56 87 Response Headers: 57 content-type: text/plain 58 x-expected: PASS 88 Content-Type: text/plain 89 X-Expected: PASS 90 Content: PASS 91 92 -- Running test case: Network.interceptRequestWithResponse.URL.IsRegex 93 Creating Local Resource Override for: \/override\.txt\?t=\d+ 94 Triggering load... 95 Resource Loaded: 96 URL: http://127.0.0.1:8000/inspector/network/resources/override.txt?t=123456789 97 MIME Type: text/plain 98 Status: 200 OK 99 Response Source: Symbol(inspector-override) 100 Response Headers: 101 Content-Type: text/plain 102 X-Expected: PASS 103 Content: PASS 104 105 -- Running test case: Network.interceptRequestWithResponse.URL.IsCaseSensitiveRegex 106 Creating Local Resource Override for: \/OvErRiDe\.TxT\?t=\d+ 107 Triggering load... 108 Resource Loaded: 109 URL: http://127.0.0.1:8000/inspector/network/resources/override.txt?t=123456789 110 MIME Type: text/plain 111 Status: 200 OK 112 Response Source: Symbol(inspector-override) 113 Response Headers: 114 Content-Type: text/plain 115 X-Expected: PASS 59 116 Content: PASS 60 117 61 118 -- Running test case: Network.interceptRequestWithResponse.404 119 Creating Local Resource Override for: http://127.0.0.1:8000/inspector/network/resources/override.txt 62 120 Triggering load... 63 Res ponse details:121 Resource Loaded: 64 122 URL: http://127.0.0.1:8000/inspector/network/resources/override.txt 65 123 MIME Type: text/plain 66 124 Status: 404 Not Found 125 Response Source: Symbol(inspector-override) 67 126 Response Headers: 68 content-type: text/plain69 x-expected: PASS127 Content-Type: text/plain 128 X-Expected: PASS 70 129 Content: PASS 71 130 -
trunk/LayoutTests/http/tests/inspector/network/intercept-request-with-response.html
r263072 r270604 5 5 <script src="../resources/inspector-test.js"></script> 6 6 <script> 7 8 async function triggerOverrideLoad(urlSuffix) { 7 function triggerOverrideLoad(urlSuffix) { 9 8 let url = "http://127.0.0.1:8000/inspector/network/resources/override.txt"; 10 9 if (urlSuffix) 11 10 url += urlSuffix; 12 13 try { 14 let response = await fetch(url); 15 return { 16 url: response.url, 17 text: await response.text(), 18 status: response.status, 19 statusText: response.statusText, 20 headers: Array.from(response.headers), 21 }; 22 } catch (e) { 23 return { error: e.message }; 24 } 11 fetch(url).then(() => { 12 TestPage.dispatchEventToFrontend("LoadComplete"); 13 }); 25 14 } 26 15 … … 28 17 { 29 18 let suite = InspectorTest.createAsyncSuite("Network.interceptRequestWithResponse"); 30 31 NetworkAgent.addInterception.invoke({ 32 url: ".*override\.txt.*", 33 isRegex: true, 34 stage: InspectorBackend.Enum.Network.NetworkStage.Request, 35 }); 36 37 function logResponse(response) { 38 response.headers = new Map(response.headers); 39 InspectorTest.log(` URL: ${response.url}`); 40 InspectorTest.log(` MIME Type: ${response.headers.get("content-type")}`); 41 InspectorTest.log(` Status: ${response.status} ${response.statusText}`); 19 20 async function logResource(resource) { 21 let responseSource = resource.responseSource === WI.Resource.ResponseSource.InspectorOverride ? String(resource.responseSource) : "<not-InspectorOverride>"; 22 InspectorTest.log(` URL: ${resource.url}`); 23 InspectorTest.log(` MIME Type: ${resource.mimeType}`); 24 InspectorTest.log(` Status: ${resource.statusCode} ${resource.statusText}`); 25 InspectorTest.log(` Response Source: ${responseSource}`); 42 26 InspectorTest.log(` Response Headers:`); 43 let keys = Array.from(response.headers.keys());27 let keys = Object.keys(resource.responseHeaders); 44 28 keys.sort(); 45 29 for (let name of keys) { 46 let value = res ponse.headers.get(name);47 if (!name.startsWith(" x-") && !name.startsWith("content-"))48 continue;30 let value = resource.responseHeaders[name]; 31 if (!name.startsWith("X-") && !name.startsWith("Content-")) 32 value = "<filtered>"; 49 33 InspectorTest.log(` ${name}: ${value}`); 50 34 } 51 InspectorTest.log(` Content: ${response.text}`); 35 36 let {rawContent, rawBase64Encoded} = await resource.requestContent(); 37 InspectorTest.log(` Content: ${rawBase64Encoded ? "[base64] " : ""}${rawContent}`); 52 38 } 53 39 54 function addTestCase({name, description, expression, responseData}) {40 function addTestCase({name, description, expression, overrides}) { 55 41 suite.addTestCase({ 56 42 name, 57 43 description, 58 44 async test() { 45 let localResourceOverrides = overrides.map((override) => { 46 InspectorTest.log("Creating Local Resource Override for: " + override.url); 47 let localResourceOverride = WI.LocalResourceOverride.create(override.url, WI.LocalResourceOverride.InterceptType.ResponseSkippingNetwork, override); 48 WI.networkManager.addLocalResourceOverride(localResourceOverride); 49 return localResourceOverride; 50 }); 51 59 52 InspectorTest.log("Triggering load..."); 60 let [requestInterceptedEvent, fetchResponse] = await Promise.all([ 61 WI.networkManager.awaitEvent(WI.NetworkManager.Event.RequestIntercepted), 62 RuntimeAgent.evaluate(expression), 53 let [resourceWasAddedEvent, responseReceivedEvent, loadCompleteEvent] = await Promise.all([ 54 WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded), 55 WI.Resource.awaitEvent(WI.Resource.Event.ResponseReceived), 56 InspectorTest.awaitEvent("LoadComplete"), 57 InspectorTest.evaluateInPage(expression), 63 58 ]); 64 59 65 await NetworkAgent.interceptRequestWithResponse.invoke({ 66 requestId: requestInterceptedEvent.data.requestId, 67 ...responseData, 68 }); 69 70 let response = await RuntimeAgent.awaitPromise(fetchResponse.result.objectId, true); 71 InspectorTest.log("Response details:"); 72 logResponse(response.result.value); 60 InspectorTest.log("Resource Loaded:"); 61 let resource = resourceWasAddedEvent.data.resource; 62 await logResource(resource); 63 64 for (let localResourceOverride of localResourceOverrides) 65 WI.networkManager.removeLocalResourceOverride(localResourceOverride); 73 66 } 74 67 }); … … 79 72 description: "Intercept request with text content.", 80 73 expression: `triggerOverrideLoad()`, 81 responseData: { 82 content: `PASS - OVERRIDDEN TEXT`, 83 base64Encoded: false, 84 mimeType: "text/plain", 85 status: 987, 86 statusText: "Override Status Text", 87 headers: { 74 overrides: [{ 75 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt", 76 responseMIMEType: "text/plain", 77 responseContent: `PASS - OVERRIDDEN TEXT`, 78 responseBase64Encoded: false, 79 responseStatusCode: 987, 80 responseStatusText: "Override Status Text", 81 responseHeaders: { 88 82 "X-Override-Header-1": "Override-Header-Value-1", 89 83 "X-Override-Header-2": "Override-Header-Value-2", 90 84 }, 91 } ,85 }], 92 86 }); 93 87 … … 96 90 description: "Intercept request with javascript content.", 97 91 expression: `triggerOverrideLoad()`, 98 responseData: { 99 content: `/* PASS */ (function() { /* OVERRIDDEN */ })();`, 100 base64Encoded: false, 101 mimeType: "application/javascript", 102 status: 200, 103 statusText: "Super OK", 104 headers: { 92 overrides: [{ 93 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt", 94 responseMIMEType: "application/javascript", 95 responseContent: `/* PASS */ (function() { /* OVERRIDDEN */ })();`, 96 responseBase64Encoded: false, 97 responseStatusCode: 200, 98 responseStatusText: "Super OK", 99 responseHeaders: { 105 100 "X-Custom-Header": "Header value", 106 101 }, 107 } ,102 }], 108 103 }); 109 104 … … 112 107 description: "Intercept request with image content.", 113 108 expression: `triggerOverrideLoad()`, 114 responseData: { 115 content: btoa("<data>"), 116 base64Encoded: true, 117 mimeType: "image/png", 118 status: 200, 119 statusText: "OK", 120 headers: {}, 121 }, 109 overrides: [{ 110 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt", 111 responseMIMEType: "image/png", 112 responseContent: btoa("<data>"), 113 responseBase64Encoded: true, 114 responseStatusCode: 200, 115 responseStatusText: "OK", 116 responseHeaders: {}, 117 }], 122 118 }); 123 119 … … 126 122 description: "Test overrides with different query strings.", 127 123 expression: `triggerOverrideLoad("?s=2")`, 128 responseData: { 129 base64Encoded: false, 130 content: "PASS", 131 mimeType: "text/plain", 132 status: 200, 133 statusText: "OK", 134 headers: {"X-Expected": "PASS"}, 135 }, 124 overrides: [{ 125 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt", 126 responseMIMEType: "text/plain", 127 responseCase64Encoded: false, 128 responseBontent: "PASS", 129 responseStatusCode: 200, 130 responseStatusText: "OK", 131 responseHeaders: {"X-Expected": "PASS"}, 132 }], 136 133 }); 137 134 … … 140 137 description: "Test override for a load with a fragment.", 141 138 expression: `triggerOverrideLoad("#frag")`, 142 responseData: { 143 content: "PASS", 144 base64Encoded: false, 145 mimeType: "text/plain", 146 status: 200, 147 statusText: "OK", 148 headers: {"X-Expected": "PASS"}, 149 }, 139 overrides: [{ 140 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt", 141 responseMIMEType: "text/plain", 142 responseContent: "PASS", 143 responseBase64Encoded: false, 144 responseStatusCode: 200, 145 responseStatusText: "OK", 146 responseHeaders: {"X-Expected": "PASS"}, 147 }], 148 }); 149 150 addTestCase({ 151 name: "Network.interceptRequestWithResponse.URL.CaseSensitive", 152 description: "Test override for a load with a fragment.", 153 expression: `triggerOverrideLoad("?CaSe=SeNsItIvE")`, 154 overrides: [{ 155 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt?case=sensitive", 156 responseMIMEType: "text/plain", 157 responseContent: "PASS", 158 responseBase64Encoded: false, 159 responseStatusCode: 200, 160 responseStatusText: "OK", 161 responseHeaders: {"X-Expected": "PASS"}, 162 isCaseSensitive: false, 163 }] 164 }); 165 166 addTestCase({ 167 name: "Network.interceptRequestWithResponse.URL.IsRegex", 168 description: "Test override for a load with a fragment.", 169 expression: `triggerOverrideLoad("?t=123456789")`, 170 overrides: [{ 171 url: "\\/override\\.txt\\?t=\\d+", 172 responseMIMEType: "text/plain", 173 responseContent: "PASS", 174 responseBase64Encoded: false, 175 responseStatusCode: 200, 176 responseStatusText: "OK", 177 responseHeaders: {"X-Expected": "PASS"}, 178 isRegex: true, 179 }] 180 }); 181 182 addTestCase({ 183 name: "Network.interceptRequestWithResponse.URL.IsCaseSensitiveRegex", 184 description: "Test override for a load with a fragment.", 185 expression: `triggerOverrideLoad("?t=123456789")`, 186 overrides: [{ 187 url: "\\/OvErRiDe\\.TxT\\?t=\\d+", 188 responseMIMEType: "text/plain", 189 responseContent: "PASS", 190 responseBase64Encoded: false, 191 responseStatusCode: 200, 192 responseStatusText: "OK", 193 responseHeaders: {"X-Expected": "PASS"}, 194 isCaseSensitive: false, 195 isRegex: true, 196 }] 150 197 }); 151 198 … … 154 201 description: "Test for a 404 override.", 155 202 expression: `triggerOverrideLoad()`, 156 responseData: { 157 content: "PASS", 158 base64Encoded: false, 159 mimeType: "text/plain", 160 status: 404, 161 statusText: "Not Found", 162 headers: {"X-Expected": "PASS"}, 163 }, 203 overrides: [{ 204 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt", 205 responseMIMEType: "text/plain", 206 responseContent: "PASS", 207 responseBase64Encoded: false, 208 responseStatusCode: 404, 209 responseStatusText: "Not Found", 210 responseHeaders: {"X-Expected": "PASS"}, 211 }], 164 212 }); 165 213 -
trunk/LayoutTests/http/tests/inspector/network/local-resource-override-basic-expected.txt
r252614 r270604 198 198 -- Running test teardown. 199 199 200 -- Running test case: LocalResourceOverride.URL.Fragment201 PASS: LocalResourceOverride creation should strip fragments.202 -
trunk/LayoutTests/http/tests/inspector/network/local-resource-override-basic.html
r267723 r270604 46 46 for (let override of overrides) { 47 47 InspectorTest.log("Creating Local Resource Override for: " + override.url); 48 let localResourceOverride = WI.LocalResourceOverride.create( WI.LocalResourceOverride.InterceptType.Response, override);48 let localResourceOverride = WI.LocalResourceOverride.create(override.url, WI.LocalResourceOverride.InterceptType.Response, override); 49 49 WI.networkManager.addLocalResourceOverride(localResourceOverride); 50 50 localResourceOverrides.push(localResourceOverride); … … 83 83 overrides: [{ 84 84 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt", 85 mimeType: "text/plain",86 content: `PASS - OVERRIDDEN TEXT`,87 base64Encoded: false,88 statusCode: 987,89 statusText: "Override Status Text",90 headers: {85 responseMIMEType: "text/plain", 86 responseContent: `PASS - OVERRIDDEN TEXT`, 87 responseBase64Encoded: false, 88 responseStatusCode: 987, 89 responseStatusText: "Override Status Text", 90 responseHeaders: { 91 91 "X-Override-Header-1": "Override-Header-Value-1", 92 92 "X-Override-Header-2": "Override-Header-Value-2", … … 101 101 overrides: [{ 102 102 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt", 103 mimeType: "application/javascript",104 content: `/* PASS */ (function() { /* OVERRIDDEN */ })();`,105 base64Encoded: false,106 statusCode: 200,107 statusText: "Super OK",108 headers: {103 responseMIMEType: "application/javascript", 104 responseContent: `/* PASS */ (function() { /* OVERRIDDEN */ })();`, 105 responseBase64Encoded: false, 106 responseStatusCode: 200, 107 responseStatusText: "Super OK", 108 responseHeaders: { 109 109 "X-Custom-Header": "Header value", 110 110 }, … … 118 118 overrides: [{ 119 119 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt", 120 mimeType: "image/png",121 content: btoa("<data>"),122 base64Encoded: true,123 statusCode: 200,124 statusText: "OK",125 headers: {},120 responseMIMEType: "image/png", 121 responseContent: btoa("<data>"), 122 responseBase64Encoded: true, 123 responseStatusCode: 200, 124 responseStatusText: "OK", 125 responseHeaders: {}, 126 126 }] 127 127 }); … … 133 133 overrides: [{ 134 134 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt?s=1", 135 mimeType: "text/plain",136 content: "FAIL",137 base64Encoded: false,138 statusCode: 500,139 statusText: "FAIL",140 headers: {"X-Expected": "FAIL"},135 responseMIMEType: "text/plain", 136 responseContent: "FAIL", 137 responseBase64Encoded: false, 138 responseStatusCode: 500, 139 responseStatusText: "FAIL", 140 responseHeaders: {"X-Expected": "FAIL"}, 141 141 }, { 142 142 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt?s=2", 143 mimeType: "text/plain",144 content: "PASS",145 base64Encoded: false,146 statusCode: 200,147 statusText: "OK",148 headers: {"X-Expected": "PASS"},143 responseMIMEType: "text/plain", 144 responseContent: "PASS", 145 responseBase64Encoded: false, 146 responseStatusCode: 200, 147 responseStatusText: "OK", 148 responseHeaders: {"X-Expected": "PASS"}, 149 149 }] 150 150 }); … … 156 156 overrides: [{ 157 157 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt", 158 mimeType: "text/plain",159 content: "PASS",160 base64Encoded: false,161 statusCode: 200,162 statusText: "OK",163 headers: {"X-Expected": "PASS"},158 responseMIMEType: "text/plain", 159 responseContent: "PASS", 160 responseBase64Encoded: false, 161 responseStatusCode: 200, 162 responseStatusText: "OK", 163 responseHeaders: {"X-Expected": "PASS"}, 164 164 }] 165 165 }); … … 171 171 overrides: [{ 172 172 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt?case=sensitive", 173 mimeType: "text/plain",174 content: "PASS",175 base64Encoded: false,176 statusCode: 200,177 statusText: "OK",178 headers: {"X-Expected": "PASS"},173 responseMIMEType: "text/plain", 174 responseContent: "PASS", 175 responseBase64Encoded: false, 176 responseStatusCode: 200, 177 responseStatusText: "OK", 178 responseHeaders: {"X-Expected": "PASS"}, 179 179 isCaseSensitive: false, 180 180 }] … … 187 187 overrides: [{ 188 188 url: "\\/override\\.txt\\?t=\\d+", 189 mimeType: "text/plain",190 content: "PASS",191 base64Encoded: false,192 statusCode: 200,193 statusText: "OK",194 headers: {"X-Expected": "PASS"},189 responseMIMEType: "text/plain", 190 responseContent: "PASS", 191 responseBase64Encoded: false, 192 responseStatusCode: 200, 193 responseStatusText: "OK", 194 responseHeaders: {"X-Expected": "PASS"}, 195 195 isRegex: true, 196 196 }] … … 203 203 overrides: [{ 204 204 url: "\\/OvErRiDe\\.TxT\\?t=\\d+", 205 mimeType: "text/plain",206 content: "PASS",207 base64Encoded: false,208 statusCode: 200,209 statusText: "OK",210 headers: {"X-Expected": "PASS"},205 responseMIMEType: "text/plain", 206 responseContent: "PASS", 207 responseBase64Encoded: false, 208 responseStatusCode: 200, 209 responseStatusText: "OK", 210 responseHeaders: {"X-Expected": "PASS"}, 211 211 isCaseSensitive: false, 212 212 isRegex: true, … … 220 220 overrides: [{ 221 221 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt", 222 mimeType: "text/plain",223 content: "PASS",224 base64Encoded: false,225 statusCode: 404,226 statusText: "Not Found",227 headers: {"X-Expected": "PASS"},222 responseMIMEType: "text/plain", 223 responseContent: "PASS", 224 responseBase64Encoded: false, 225 responseStatusCode: 404, 226 responseStatusText: "Not Found", 227 responseHeaders: {"X-Expected": "PASS"}, 228 228 disabled: false, 229 229 }] … … 236 236 overrides: [{ 237 237 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt", 238 mimeType: "text/plain",239 content: "PASS",240 base64Encoded: false,241 statusCode: 200,242 statusText: "OK",243 headers: {"X-Expected": "PASS"},238 responseMIMEType: "text/plain", 239 responseContent: "PASS", 240 responseBase64Encoded: false, 241 responseStatusCode: 200, 242 responseStatusText: "OK", 243 responseHeaders: {"X-Expected": "PASS"}, 244 244 disabled: false, 245 245 }] … … 252 252 overrides: [{ 253 253 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt", 254 mimeType: "text/plain",255 content: "FAIL",256 base64Encoded: false,257 statusCode: 500,258 statusText: "FAIL",259 headers: {"X-Expected": "FAIL"},254 responseMIMEType: "text/plain", 255 responseContent: "FAIL", 256 responseBase64Encoded: false, 257 responseStatusCode: 500, 258 responseStatusText: "FAIL", 259 responseHeaders: {"X-Expected": "FAIL"}, 260 260 disabled: true, 261 261 }] … … 270 270 overrides: [{ 271 271 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt", 272 mimeType: "text/plain", 273 content: "FAIL", 274 base64Encoded: false, 275 statusCode: 500, 276 statusText: "FAIL", 277 headers: {"X-Expected": "FAIL"}, 278 }] 279 }); 280 281 suite.addTestCase({ 282 name: "LocalResourceOverride.URL.Fragment", 283 description: "LocalResourceOverride creation strips a fragment", 284 async test() { 285 let localResourceOverride = WI.LocalResourceOverride.create(WI.LocalResourceOverride.InterceptType.Response, { 286 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt#test", 287 mimeType: "text/plain", 288 content: "OVERRIDDEN TEXT", 289 base64Encoded: false, 290 statusCode: 200, 291 statusText: "OK", 292 headers: {}, 293 }); 294 295 InspectorTest.expectEqual(localResourceOverride.localResource.url, "http://127.0.0.1:8000/inspector/network/resources/override.txt", "LocalResourceOverride creation should strip fragments."); 296 } 272 responseMIMEType: "text/plain", 273 responseContent: "FAIL", 274 responseBase64Encoded: false, 275 responseStatusCode: 500, 276 responseStatusText: "FAIL", 277 responseHeaders: {"X-Expected": "FAIL"}, 278 }] 297 279 }); 298 280 -
trunk/LayoutTests/http/tests/inspector/network/local-resource-override-main-resource.html
r267723 r270604 13 13 description: "Main resource uses override content on next page load", 14 14 async test() { 15 WI.networkManager.addLocalResourceOverride(WI.LocalResourceOverride.create(WI.LocalResourceOverride.InterceptType.Response, { 16 url: "http://127.0.0.1:8000/inspector/network/local-resource-override-main-resource.html", 17 mimeType: "text/html", 18 content: `<!DOCTYPE html><html><head><script src="../resources/inspector-test.js"></`+`script></head><body><p>Overridden page content</p><script>alert("REPLACED HTML CONTENT"); TestPage.completeTest();</`+`script></body></html>`, 19 base64Encoded: false, 20 statusCode: 200, 21 statusText: "OK", 22 headers: {}, 15 WI.networkManager.addLocalResourceOverride(WI.LocalResourceOverride.create("http://127.0.0.1:8000/inspector/network/local-resource-override-main-resource.html", WI.LocalResourceOverride.InterceptType.Response, { 16 responseMIMEType: "text/html", 17 responseContent: `<!DOCTYPE html><html><head><script src="../resources/inspector-test.js"></`+`script></head><body><p>Overridden page content</p><script>alert("REPLACED HTML CONTENT"); TestPage.completeTest();</`+`script></body></html>`, 18 responseBase64Encoded: false, 19 responseStatusCode: 200, 20 responseStatusText: "OK", 21 responseHeaders: {}, 23 22 })); 24 23 -
trunk/LayoutTests/http/tests/inspector/network/local-resource-override-script-tag.html
r267723 r270604 13 13 description: "<script> load uses override content on next page load", 14 14 async test() { 15 WI.networkManager.addLocalResourceOverride(WI.LocalResourceOverride.create(WI.LocalResourceOverride.InterceptType.Response, { 16 url: "http://127.0.0.1:8000/inspector/network/resources/override.js", 17 mimeType: "text/javascript", 18 content: `alert("OVERRIDDEN override.js TEXT"); TestPage.dispatchEventToFrontend("OverrideContentDidLoad");`, 19 base64Encoded: false, 20 statusCode: 200, 21 statusText: "OK", 22 headers: {}, 15 WI.networkManager.addLocalResourceOverride(WI.LocalResourceOverride.create("http://127.0.0.1:8000/inspector/network/resources/override.js", WI.LocalResourceOverride.InterceptType.Response, { 16 responseMIMEType: "text/javascript", 17 responseContent: `alert("OVERRIDDEN override.js TEXT"); TestPage.dispatchEventToFrontend("OverrideContentDidLoad");`, 18 responseBase64Encoded: false, 19 responseStatusCode: 200, 20 responseStatusText: "OK", 21 responseHeaders: {}, 23 22 })); 24 23 -
trunk/LayoutTests/http/tests/inspector/network/resource-response-inspector-override.html
r267723 r270604 43 43 statusCode: 987, 44 44 async setup() { 45 WI.networkManager.addLocalResourceOverride(WI.LocalResourceOverride.create(WI.LocalResourceOverride.InterceptType.Response, { 46 url: "http://127.0.0.1:8000/inspector/network/resources/override.txt", 47 mimeType: "text/plain", 48 content: "Overridden Text", 49 base64Encoded: false, 50 statusCode: 987, 51 statusText: "Status Text", 52 headers: {}, 45 WI.networkManager.addLocalResourceOverride(WI.LocalResourceOverride.create("http://127.0.0.1:8000/inspector/network/resources/override.txt", WI.LocalResourceOverride.InterceptType.Response, { 46 responseMIMEType: "text/plain", 47 responseContent: "Overridden Text", 48 responseBase64Encoded: false, 49 responseStatusCode: 987, 50 responseStatusText: "Status Text", 51 responseHeaders: {}, 53 52 })); 54 53 } -
trunk/LayoutTests/platform/mac-wk1/TestExpectations
r270397 r270604 594 594 http/tests/performance/paint-timing [ Skip ] 595 595 596 # Local Overrides not available in WebKit1 597 http/tests/inspector/network/local-resource-override-basic.html [ Failure ] 598 http/tests/inspector/network/local-resource-override-main-resource.html [ Failure ] 599 http/tests/inspector/network/local-resource-override-script-tag.html [ Failure ] 600 http/tests/inspector/network/resource-response-inspector-override.html [ Failure ] 601 inspector/network/local-resource-override-continue-response.html [ Skip ] 602 603 # Request interception is not available in WebKit1 604 http/tests/inspector/network/intercept-aborted-request.html [ Skip ] 605 http/tests/inspector/network/intercept-request-continue.html [ Skip ] 596 # Network interception is not available in WebKit1 606 597 http/tests/inspector/network/intercept-request-fragment.html [ Skip ] 607 598 http/tests/inspector/network/intercept-request-main-resource.html [ Skip ] … … 609 600 http/tests/inspector/network/intercept-request-properties.html [ Skip ] 610 601 http/tests/inspector/network/intercept-request-subresource.html [ Skip ] 611 http/tests/inspector/network/intercept-request-subresource-with-error.html [ Skip ]612 602 http/tests/inspector/network/intercept-request-subresource-with-response.html [ Skip ] 613 603 http/tests/inspector/network/intercept-request-with-response.html [ Skip ] 604 http/tests/inspector/network/local-resource-override-basic.html [ Skip ] 605 http/tests/inspector/network/local-resource-override-main-resource.html [ Skip ] 606 http/tests/inspector/network/local-resource-override-script-tag.html [ Skip ] 607 http/tests/inspector/network/resource-response-inspector-override.html [ Skip ] 608 inspector/network/intercept-aborted-request.html [ Skip ] 609 inspector/network/interceptContinue.html [ Skip ] 610 inspector/network/interceptRequestWithError.html [ Skip ] 614 611 615 612 webkit.org/b/164933 http/tests/misc/link-rel-icon-beforeload.html [ Failure ] -
trunk/Source/WebInspectorUI/ChangeLog
r270445 r270604 1 2020-12-09 Devin Rousso <drousso@apple.com> 2 3 Web Inspector: add UI for request interception 4 https://bugs.webkit.org/show_bug.cgi?id=217032 5 <rdar://problem/69925768> 6 7 Reviewed by Brian Burg. 8 9 * UserInterface/Models/LocalResourceOverride.js: 10 (WI.LocalResourceOverride): 11 (WI.LocalResourceOverride.create): 12 (WI.LocalResourceOverride.displayNameForType): Added. 13 (WI.LocalResourceOverride.fromJSON): 14 (WI.LocalResourceOverride.prototype.toJSON): 15 (WI.LocalResourceOverride.prototype.get url): 16 (WI.LocalResourceOverride.prototype.get urlComponents): Added. 17 (WI.LocalResourceOverride.prototype.get displayName): Added. 18 (WI.LocalResourceOverride.prototype.displayURL): Added. 19 (WI.LocalResourceOverride.prototype.matches): 20 (WI.LocalResourceOverride.prototype.equals): Added. 21 (WI.LocalResourceOverride.prototype.saveIdentityToCookie): 22 Add a `WI.LocalResourceOverride.InterceptType.Request` and pass through request information 23 to the `WI.LocalResource`. 24 25 * UserInterface/Models/SourceCode.js: 26 (WI.SourceCode.prototype.get localResourceOverride): Added. 27 * UserInterface/Models/Resource.js: 28 (WI.Resource.classNamesForResource): 29 (WI.Resource.prototype.get supportsScriptBlackboxing): 30 (WI.Resource.prototype.async createLocalResourceOverride): 31 (WI.Resource.prototype.updateLocalResourceOverrideRequestData): 32 (WI.Resource.prototype.get isLocalResourceOverride): Deleted. 33 * UserInterface/Models/LocalResource.js: 34 (WI.LocalResource.prototype.toJSON): 35 (WI.LocalResource.prototype.get localResourceOverride): Added. 36 (WI.LocalResource.prototype.get isLocalResourceOverride): Deleted. 37 Replace `get isLocalResourceOverride` with `get localResourceOverride` (on `WI.SourceCode` 38 so that non-`WI.Resource` also can call it) by having the related `WI.LocalResourceOverride` 39 set `_localResourceOverride`. 40 41 * UserInterface/Controllers/NetworkManager.js: 42 (WI.NetworkManager.supportsOverridingRequests): Added. 43 (WI.NetworkManager.prototype.get localResourceOverrides): 44 (WI.NetworkManager.prototype.addLocalResourceOverride): 45 (WI.NetworkManager.prototype.removeLocalResourceOverride): 46 (WI.NetworkManager.prototype.localResourceOverridesForURL): Added. 47 (WI.NetworkManager.prototype.canBeOverridden): 48 (WI.NetworkManager.prototype.requestIntercepted): 49 (WI.NetworkManager.prototype.responseIntercepted): 50 (WI.NetworkManager.prototype._handleResourceContentChangedForLocalResourceOverride): Added. 51 (WI.NetworkManager.prototype.localResourceOverrideForURL): Deleted. 52 (WI.NetworkManager.prototype._handleResourceContentDidChange): Deleted. 53 Provide all `WI.LocalResourceOverride` that match the given URL sorted by how close/exact 54 the `WI.LocalResourceOverride` is to the given URL (i.e. exact < case-insensitive < regex). 55 Add logic to invoke `Network.interceptWithRequest` when the `WI.LocalResourceOverride` is 56 `WI.LocalResourceOverride.InterceptType.Request`. 57 58 * UserInterface/Views/LocalResourceOverridePopover.js: 59 (WI.LocalResourceOverridePopover): 60 (WI.LocalResourceOverridePopover.prototype.get serializedData): 61 (WI.LocalResourceOverridePopover.prototype.show): 62 * UserInterface/Views/LocalResourceOverridePopover.css: 63 (.popover .local-resource-override-popover-content.request .editor:is(.url, .redirect)): Added. 64 (.popover .local-resource-override-popover-content.response .editor.url): Added. 65 (.popover .local-resource-override-popover-content .data-grid): Added. 66 (.popover .local-resource-override-popover-content .reference-page-link-container): Added. 67 (body[dir=ltr] .popover .local-resource-override-popover-content .reference-page-link-container): 68 (body[dir=rtl] .popover .local-resource-override-popover-content .reference-page-link-container): 69 (.popover .local-resource-override-popover-content .editor.url): Deleted. 70 (.popover .local-resource-override-popover-content .add-header): Deleted. 71 (.popover .local-resource-override-popover-content .add-header + .reference-page-link-container): Deleted. 72 Replace the MIME type, status code, and status text inputs with redirect and method inputs 73 when editing a request override. For brand new overrides, show a type dropdown that allows 74 for dynamically updating what inputs are shown (only until the popover is dismissed, at 75 which point the type is set forever). 76 77 * UserInterface/Views/LocalResourceOverrideRequestContentView.js: Added. 78 (WI.LocalResourceOverrideRequestContentView): 79 (WI.LocalResourceOverrideRequestContentView.prototype.get navigationItems): 80 (WI.LocalResourceOverrideRequestContentView.prototype.get saveData): 81 (WI.LocalResourceOverrideRequestContentView.prototype.initialLayout): 82 (WI.LocalResourceOverrideRequestContentView.prototype._handleRemoveLocalResourceOverride): 83 (WI.LocalResourceOverrideRequestContentView.prototype._handleTextEditorContentDidChange): 84 * UserInterface/Views/LocalResourceOverrideRequestContentView.css: Added. 85 (.content-view.text.local-resource-override-request): 86 (.content-view.text.local-resource-override-request > .text-editor): 87 (.content-view.text.local-resource-override-request > .message-text-view): 88 * UserInterface/Views/ContentView.js: 89 (WI.ContentView.createFromRepresentedObject): 90 (WI.ContentView.resolvedRepresentedObjectForRepresentedObject): 91 Create a special `WI.TextContentView` for showing `WI.LocalResourceOverride` request data. 92 Only allow it to be edited if the current method allows for request data. 93 94 * UserInterface/Views/ResourceContentView.js: 95 (WI.ResourceContentView): 96 (WI.ResourceContentView.prototype.get resource): 97 (WI.ResourceContentView.prototype.requestLocalResourceOverrideInitialContent): 98 (WI.ResourceContentView.prototype.async _createAndShowLocalResourceOverride): 99 (WI.ResourceContentView.prototype._populateCreateLocalResourceOverrideContextMenu): 100 (WI.ResourceContentView.prototype._handleCreateLocalResourceOverride): 101 (WI.ResourceContentView.prototype._handleImportLocalResourceOverride): 102 (WI.ResourceContentView.prototype.async _handleRemoveLocalResourceOverride): Added. 103 (WI.ResourceContentView.prototype._handleLocalResourceOverrideChanged): Added. 104 (WI.ResourceContentView.prototype.get showingLocalResourceOverride): Deleted. 105 Show a contextmenu when clicking on the create override navigation item with items for 106 creating either a request override or a response override. 107 108 * UserInterface/Controllers/CSSManager.js: 109 (WI.CSSManager.prototype._resourceContentDidChange): 110 * UserInterface/Views/ContextMenuUtilities.js: 111 (WI.appendContextMenuItemsForSourceCode): 112 * UserInterface/Views/FontResourceContentView.js: 113 (WI.FontResourceContentView.prototype.contentAvailable): 114 (WI.FontResourceContentView.prototype.dropZoneShouldAppearForDragEvent): 115 (WI.FontResourceContentView.prototype.dropZoneHandleDragEnter): 116 (WI.FontResourceContentView.prototype.dropZoneHandleDrop): 117 * UserInterface/Views/ImageResourceContentView.js: 118 (WI.ImageResourceContentView.prototype.contentAvailable): 119 (WI.ImageResourceContentView.prototype.dropZoneShouldAppearForDragEvent): 120 (WI.ImageResourceContentView.prototype.dropZoneHandleDragEnter): 121 (WI.ImageResourceContentView.prototype.dropZoneHandleDrop): 122 * UserInterface/Views/LocalResourceOverrideLabelView.js: 123 (WI.LocalResourceOverrideLabelView): 124 (WI.LocalResourceOverrideLabelView.prototype.initialLayout): 125 * UserInterface/Views/LocalResourceOverrideTreeElement.js: 126 (WI.LocalResourceOverrideTreeElement): 127 (WI.LocalResourceOverrideTreeElement.prototype.get mainTitleText): 128 (WI.LocalResourceOverrideTreeElement.prototype.willDismissPopover): 129 * UserInterface/Views/LocalResourceOverrideWarningView.js: 130 (WI.LocalResourceOverrideWarningView): 131 (WI.LocalResourceOverrideWarningView.prototype.initialLayout): 132 (WI.LocalResourceOverrideWarningView.prototype._updateContent): 133 (WI.LocalResourceOverrideWarningView.prototype._handleLocalResourceOverrideAddedOrRemoved): 134 * UserInterface/Views/NavigationSidebarPanel.js: 135 (WI.NavigationSidebarPanel.prototype.pruneStaleResourceTreeElements): 136 * UserInterface/Views/OpenResourceDialog.js: 137 (WI.OpenResourceDialog.prototype._populateResourceTreeOutline): 138 * UserInterface/Views/SourceCodeTextEditor.js: 139 (WI.SourceCodeTextEditor.prototype.get _supportsDebugging): 140 * UserInterface/Views/SourcesNavigationSidebarPanel.js: 141 (WI.SourcesNavigationSidebarPanel.prototype._willDismissLocalOverridePopover): 142 (WI.SourcesNavigationSidebarPanel.prototype._closeContentViewsFilter): 143 (WI.SourcesNavigationSidebarPanel.prototype._addLocalOverride): 144 (WI.SourcesNavigationSidebarPanel.prototype._handleTreeSelectionDidChange): 145 * UserInterface/Views/ResourceTreeElement.js: 146 (WI.ResourceTreeElement.prototype.get mainTitleText): 147 (WI.ResourceTreeElement.prototype._updateTitles): 148 (WI.ResourceTreeElement.prototype._updateIcon): 149 * UserInterface/Views/TextResourceContentView.js: 150 (WI.TextResourceContentView): 151 (WI.TextResourceContentView.prototype.get navigationItems): 152 (WI.TextResourceContentView.prototype.requestLocalResourceOverrideInitialContent): 153 (WI.TextResourceContentView.prototype._shouldBeEditable): 154 Replace usage of `get isLocalResourceOverride` with `get localResourceOverride`. 155 156 * UserInterface/Base/HTTPUtilities.js: 157 Add constants for known request methods. 158 159 * Localizations/en.lproj/localizedStrings.js: 160 * UserInterface/Main.html: 161 * UserInterface/Test.html: 162 * UserInterface/Images/DocumentIcons.svg: 163 164 * UserInterface/Base/ReferencePage.js: 165 Add url for local overrides page. 166 1 167 2020-12-04 Adam Roben <aroben@apple.com> 2 168 -
trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
r269712 r270604 53 53 localizedStrings["%s (%s)"] = "%s (%s)"; 54 54 localizedStrings["%s (%s, %s)"] = "%s (%s, %s)"; 55 localizedStrings["%s (Case Insensitive)"] = "%s (Case Insensitive)"; 55 /* Label for case-insensitive URL match pattern of a local override. */ 56 localizedStrings["%s (Case Insensitive) @ Local Override"] = "%s (Case Insensitive)"; 56 57 localizedStrings["%s (default)"] = "%s (default)"; 57 58 localizedStrings["%s (hidden)"] = "%s (hidden)"; … … 60 61 localizedStrings["%s Fired"] = "%s Fired"; 61 62 localizedStrings["%s Prototype"] = "%s Prototype"; 63 /* Format string for the suggested filename when saving the content for a request local override. */ 64 localizedStrings["%s Request Data @ Local Override Request Content View"] = "%s Request Data"; 62 65 localizedStrings["%s Result"] = "%s Result"; 63 66 localizedStrings["%s \u2013 %s"] = "%s \u2013 %s"; … … 68 71 localizedStrings["%s eval\n%s async"] = "%s eval\n%s async"; 69 72 localizedStrings["%s interval"] = "%s interval"; 73 localizedStrings["%s requests do not have a body"] = "%s requests do not have a body"; 70 74 localizedStrings["%s total"] = "%s total"; 71 75 localizedStrings["%s transferred"] = "%s transferred"; … … 92 96 localizedStrings["1 match"] = "1 match"; 93 97 localizedStrings["1080p"] = "1080p"; 98 localizedStrings["2D"] = "2D"; 94 99 localizedStrings["720p"] = "720p"; 95 localizedStrings["Screen size:"] = "Screen size:";96 localizedStrings["2D"] = "2D";97 100 localizedStrings["Accessibility"] = "Accessibility"; 98 101 localizedStrings["Action"] = "Action"; … … 367 370 localizedStrings["Create Breakpoint"] = "Create Breakpoint"; 368 371 localizedStrings["Create Local Override"] = "Create Local Override"; 372 localizedStrings["Create Request Local Override"] = "Create Request Local Override"; 369 373 localizedStrings["Create Resource"] = "Create Resource"; 374 localizedStrings["Create Response Local Override"] = "Create Response Local Override"; 370 375 localizedStrings["Create audit:"] = "Create audit:"; 371 376 localizedStrings["Cross-Origin Restrictions"] = "Cross-Origin Restrictions"; … … 808 813 localizedStrings["Lowest: %s"] = "Lowest: %s"; 809 814 localizedStrings["MIME Type"] = "MIME Type"; 815 /* Label for MIME type input for the local override currently being edited. */ 816 localizedStrings["MIME Type @ Local Override Popover"] = "MIME Type"; 810 817 localizedStrings["MIME Type:"] = "MIME Type:"; 811 818 localizedStrings["MSE Logging:"] = "MSE Logging:"; … … 936 943 localizedStrings["Over 1 ms"] = "Over 1 ms"; 937 944 localizedStrings["Over 15 ms"] = "Over 15 ms"; 938 localizedStrings["Override"] = "Override";939 945 localizedStrings["Overview"] = "Overview"; 940 946 localizedStrings["Owns"] = "Owns"; … … 1027 1033 localizedStrings["Recording Warning: %s"] = "Recording Warning: %s"; 1028 1034 localizedStrings["Recordings"] = "Recordings"; 1035 localizedStrings["Redirect"] = "Redirect"; 1029 1036 localizedStrings["Redirect Response"] = "Redirect Response"; 1030 1037 localizedStrings["Redirects"] = "Redirects"; … … 1052 1059 localizedStrings["Request (DOM Tree)"] = "Request (DOM Tree)"; 1053 1060 localizedStrings["Request (Object Tree)"] = "Request (Object Tree)"; 1061 /* Text indicating that the local override intercepts the request phase of network activity. */ 1062 localizedStrings["Request @ Local Override Type"] = "Request"; 1054 1063 localizedStrings["Request Cookies"] = "Request Cookies"; 1055 1064 localizedStrings["Request Data"] = "Request Data"; 1056 1065 localizedStrings["Request Headers"] = "Request Headers"; 1066 /* Label indicating that the shown content is from a request local override. */ 1067 localizedStrings["Request Override @ Local Override Content View"] = "Request Override"; 1057 1068 localizedStrings["Requesting: %s"] = "Requesting: %s"; 1058 1069 localizedStrings["Required"] = "Required"; … … 1075 1086 localizedStrings["Response (Object Tree)"] = "Response (Object Tree)"; 1076 1087 localizedStrings["Response (Text)"] = "Response (Text)"; 1088 /* Text indicating that the local override will skip all network activity and instead immediately serve the response. */ 1089 localizedStrings["Response (skip network) @ Local Override Type"] = "Response (skip network)"; 1090 /* Text indicating that the local override intercepts the response phase of network activity. */ 1091 localizedStrings["Response @ Local Override Type"] = "Response"; 1077 1092 localizedStrings["Response Cookies"] = "Response Cookies"; 1078 1093 localizedStrings["Response Headers"] = "Response Headers"; 1094 /* Label indicating that the shown content is from a response local override. */ 1095 localizedStrings["Response Override @ Local Override Content View"] = "Response Override"; 1079 1096 localizedStrings["Response:"] = "Response:"; 1080 1097 localizedStrings["Restart (%s)"] = "Restart (%s)"; … … 1124 1141 localizedStrings["Scope Chain"] = "Scope Chain"; 1125 1142 localizedStrings["Screen Shot %s-%s-%s at %s.%s.%s"] = "Screen Shot %s-%s-%s at %s.%s.%s"; 1143 localizedStrings["Screen size:"] = "Screen size:"; 1126 1144 localizedStrings["Script"] = "Script"; 1127 1145 localizedStrings["Script Element %d"] = "Script Element %d"; … … 1255 1273 localizedStrings["Statistics"] = "Statistics"; 1256 1274 localizedStrings["Status"] = "Status"; 1275 /* Label for the HTTP status code input for the local override currently being edited. */ 1276 localizedStrings["Status @ Local Override Popover"] = "Status"; 1257 1277 localizedStrings["Step"] = "Step"; 1258 1278 localizedStrings["Step (%s or %s)"] = "Step (%s or %s)"; -
trunk/Source/WebInspectorUI/UserInterface/Base/HTTPUtilities.js
r249504 r270604 87 87 } 88 88 }; 89 90 WI.HTTPUtilities.RequestMethod = { 91 CONNECT: "CONNECT", 92 DELETE: "DELETE", 93 GET: "GET", 94 HEAD: "HEAD", 95 OPTIONS: "OPTIONS", 96 PATCH: "PATCH", 97 POST: "POST", 98 PUT: "PUT", 99 TRACE: "TRACE", 100 }; 101 102 WI.HTTPUtilities.RequestMethodsWithBody = new Set([ 103 WI.HTTPUtilities.RequestMethod.DELETE, 104 WI.HTTPUtilities.RequestMethod.PATCH, 105 WI.HTTPUtilities.RequestMethod.POST, 106 WI.HTTPUtilities.RequestMethod.PUT, 107 ]); -
trunk/Source/WebInspectorUI/UserInterface/Base/ReferencePage.js
r266480 r270604 28 28 EventBreakpoints: "event-breakpoints", 29 29 JavaScriptBreakpoints: "javascript-breakpoints", 30 LocalOverrides: "local-overrides", 30 31 URLBreakpoints: "url-breakpoints", 31 32 }; -
trunk/Source/WebInspectorUI/UserInterface/Controllers/CSSManager.js
r266885 r270604 570 570 571 571 // Ignore changes to resource overrides, those are not live on the page. 572 if (resource. isLocalResourceOverride)572 if (resource.localResourceOverride) 573 573 return; 574 574 -
trunk/Source/WebInspectorUI/UserInterface/Controllers/NetworkManager.js
r267723 r270604 44 44 this._downloadingSourceMaps = new Set; 45 45 46 this._localResourceOverrides = new Set;46 this._localResourceOverrides = []; 47 47 this._harImportLocalResourceMap = new Set; 48 48 … … 59 59 60 60 if (NetworkManager.supportsOverridingResponses()) { 61 WI.Resource.addEventListener(WI.SourceCode.Event.ContentDidChange, this._handleResourceContentDidChange, this); 61 WI.Resource.addEventListener(WI.SourceCode.Event.ContentDidChange, this._handleResourceContentChangedForLocalResourceOverride, this); 62 WI.Resource.addEventListener(WI.Resource.Event.RequestDataDidChange, this._handleResourceContentChangedForLocalResourceOverride, this); 62 63 WI.LocalResourceOverride.addEventListener(WI.LocalResourceOverride.Event.DisabledChanged, this._handleResourceOverrideDisabledChanged, this); 63 64 … … 71 72 let supported = false; 72 73 switch (localResourceOverride.type) { 74 case WI.LocalResourceOverride.InterceptType.Request: 75 supported = WI.NetworkManager.supportsOverridingRequests(); 76 break; 77 73 78 case WI.LocalResourceOverride.InterceptType.Response: 74 79 supported = WI.NetworkManager.supportsOverridingResponses(); … … 111 116 } 112 117 118 static supportsOverridingRequests() 119 { 120 // COMPATIBILITY (iOS 13.4): Network.interceptWithRequest did not exist yet. 121 return InspectorBackend.hasCommand("Network.interceptWithRequest"); 122 } 123 113 124 static supportsOverridingRequestsWithResponses() 114 125 { … … 201 212 202 213 get mainFrame() { return this._mainFrame; } 214 get localResourceOverrides() { return this._localResourceOverrides; } 203 215 get bootstrapScript() { return this._bootstrapScript; } 204 216 … … 206 218 { 207 219 return Array.from(this._frameIdentifierMap.values()); 208 }209 210 get localResourceOverrides()211 {212 return Array.from(this._localResourceOverrides);213 220 } 214 221 … … 373 380 console.assert(localResourceOverride instanceof WI.LocalResourceOverride); 374 381 375 console.assert(!this._localResourceOverrides. has(localResourceOverride), "Already had an existing local resource override.");376 this._localResourceOverrides. add(localResourceOverride);382 console.assert(!this._localResourceOverrides.includes(localResourceOverride)); 383 this._localResourceOverrides.push(localResourceOverride); 377 384 378 385 if (!this._restoringLocalResourceOverrides) … … 389 396 console.assert(localResourceOverride instanceof WI.LocalResourceOverride); 390 397 391 if (!this._localResourceOverrides. delete(localResourceOverride)) {398 if (!this._localResourceOverrides.remove(localResourceOverride)) { 392 399 console.assert(false, "Attempted to remove a local resource override that was not known."); 393 400 return; … … 406 413 } 407 414 408 localResourceOverrideForURL(url) 409 { 410 for (let localResourceOverride of this._localResourceOverrides) { 411 if (localResourceOverride.matches(url)) 412 return localResourceOverride; 413 } 414 return null; 415 localResourceOverridesForURL(url) 416 { 417 // Order local resource overrides based on how closely they match the given URL. As an example, 418 // a regular expression is likely going to match more URLs than a case-insensitive string. 419 const rankFunctions = [ 420 (localResourceOverride) => localResourceOverride.isCaseSensitive && !localResourceOverride.isRegex, // exact match 421 (localResourceOverride) => !localResourceOverride.isCaseSensitive && !localResourceOverride.isRegex, // case-insensitive 422 (localResourceOverride) => localResourceOverride.isCaseSensitive && localResourceOverride.isRegex, // case-sensitive regex 423 (localResourceOverride) => !localResourceOverride.isCaseSensitive && localResourceOverride.isRegex, // case-insensitive regex 424 ]; 425 return this._localResourceOverrides 426 .filter((localResourceOverride) => localResourceOverride.matches(url)) 427 .sort((a, b) => { 428 let aRank = rankFunctions.findIndex((rankFunction) => rankFunction(a)); 429 let bRank = rankFunctions.findIndex((rankFunction) => rankFunction(b)); 430 return aRank - bRank; 431 }); 415 432 } 416 433 … … 423 440 return false; 424 441 425 if (resource. isLocalResourceOverride)442 if (resource.localResourceOverride) 426 443 return false; 427 444 … … 430 447 return false; 431 448 432 let existingOverride = this.localResourceOverrideForURL(resource.url); 433 if (existingOverride) 449 if (this.localResourceOverridesForURL(resource.url).length) 434 450 return false; 435 451 … … 933 949 requestIntercepted(target, requestId, request) 934 950 { 935 if (window.InspectorTest) {936 // FIXME: <https://webkit.org/b/217032> Web Inspector: add UI for request interception937 this.dispatchEventToListeners(WI.NetworkManager.Event.RequestIntercepted, {target, requestId, request});938 return;939 }940 941 951 let url = WI.urlWithoutFragment(request.url); 942 let localResourceOverride = this.localResourceOverrideForURL(url); 943 if (!localResourceOverride || localResourceOverride.disabled) { 944 target.NetworkAgent.interceptContinue.invoke({ 945 requestId, 946 stage: InspectorBackend.Enum.Network.NetworkStage.Request, 947 }); 948 return; 949 } 950 951 console.assert(localResourceOverride.type === WI.LocalResourceOverride.InterceptType.ResponseSkippingNetwork, localResourceOverride); 952 953 let localResource = localResourceOverride.localResource; 954 let revision = localResource.currentRevision; 955 956 console.assert(revision.mimeType === localResource.mimeType); 957 958 target.NetworkAgent.interceptRequestWithResponse.invoke({ 952 for (let localResourceOverride of this.localResourceOverridesForURL(url)) { 953 if (localResourceOverride.disabled) 954 continue; 955 956 let localResource = localResourceOverride.localResource; 957 let revision = localResource.currentRevision; 958 959 switch (localResourceOverride.type) { 960 case WI.LocalResourceOverride.InterceptType.Request: { 961 target.NetworkAgent.interceptWithRequest.invoke({ 962 requestId, 963 url: localResource.url || undefined, 964 method: localResource.requestMethod ?? undefined, 965 headers: localResource.requestHeaders, 966 postData: (WI.HTTPUtilities.RequestMethodsWithBody.has(localResource.requestMethod) && localResource.requestData) ? btoa(localResource.requestData) : undefined, 967 }); 968 return; 969 } 970 971 case WI.LocalResourceOverride.InterceptType.ResponseSkippingNetwork: 972 console.assert(revision.mimeType === localResource.mimeType); 973 target.NetworkAgent.interceptRequestWithResponse.invoke({ 974 requestId, 975 content: revision.content, 976 base64Encoded: !!revision.base64Encoded, 977 mimeType: revision.mimeType ?? undefined, 978 status: !isNaN(localResource.statusCode) ? localResource.statusCode : 200, 979 statusText: !isNaN(localResource.statusCode) ? (localResource.statusText ?? "") : WI.HTTPUtilities.statusTextForStatusCode(200), 980 headers: localResource.responseHeaders, 981 }); 982 return; 983 } 984 } 985 986 // It's possible for a response regex override to overlap a request regex override, in 987 // which case we should silently continue the request if the response regex override was 988 // used instead (e.g. it was added first). 989 target.NetworkAgent.interceptContinue.invoke({ 959 990 requestId, 960 content: revision.content, 961 base64Encoded: !!revision.base64Encoded, 962 mimeType: revision.mimeType, 963 status: !isNaN(localResource.statusCode) ? localResource.statusCode : 200, 964 statusText: localResource.statusText ?? WI.HTTPUtilities.statusTextForStatusCode(200), 965 headers: localResource.responseHeaders ?? {}, 991 stage: InspectorBackend.Enum.Network.NetworkStage.Request, 966 992 }); 967 993 } … … 970 996 { 971 997 let url = WI.urlWithoutFragment(response.url); 972 let localResourceOverride = this.localResourceOverrideForURL(url);973 if (!localResourceOverride || localResourceOverride.disabled) {974 target.NetworkAgent.interceptContinue.invoke({975 requestId, 976 stage: InspectorBackend.Enum.Network.NetworkStage.Response,977 });978 return; 979 }980 981 console.assert(localResourceOverride.type === WI.LocalResourceOverride.InterceptType.Response, localResourceOverride);982 983 let localResource = localResourceOverride.localResource;984 let revision = localResource.currentRevision;985 986 let content = revision.content;987 let base64Encoded = revision.base64Encoded;988 let mimeType = revision.mimeType;989 let statusCode = localResource.statusCode;990 let statusText = localResource.statusText;991 let responseHeaders = localResource.responseHeaders;992 console.assert(revision.mimeType === localResource.mimeType);993 994 if (isNaN(statusCode)) 995 statusCode = undefined;996 if (!statusText)997 statusText = undefined;998 if (!responseHeaders)999 re sponseHeaders = undefined;1000 1001 target.NetworkAgent.interceptWithResponse(requestId, content, base64Encoded, mimeType, statusCode, statusText, responseHeaders);998 for (let localResourceOverride of this.localResourceOverridesForURL(url)) { 999 if (localResourceOverride.disabled) 1000 continue; 1001 1002 let localResource = localResourceOverride.localResource; 1003 let revision = localResource.currentRevision; 1004 1005 switch (localResourceOverride.type) { 1006 case WI.LocalResourceOverride.InterceptType.Response: 1007 console.assert(revision.mimeType === localResource.mimeType); 1008 target.NetworkAgent.interceptWithResponse.invoke({ 1009 requestId, 1010 content: revision.content, 1011 base64Encoded: !!revision.base64Encoded, 1012 mimeType: revision.mimeType ?? undefined, 1013 status: !isNaN(localResource.statusCode) ? localResource.statusCode : undefined, 1014 statusText: !isNaN(localResource.statusCode) ? (localResource.statusText ?? "") : undefined, 1015 headers: localResource.responseHeaders, 1016 }); 1017 return; 1018 } 1019 } 1020 1021 // It's possible for a request regex override to overlap a response regex override, in 1022 // which case we should silently continue the response if the request regex override was 1023 // used instead (e.g. it was added first). 1024 target.NetworkAgent.interceptContinue.invoke({ 1025 requestId, 1026 stage: InspectorBackend.Enum.Network.NetworkStage.Response, 1027 }); 1002 1028 } 1003 1029 … … 1442 1468 } 1443 1469 1444 _handleResourceContentDidChange(event) 1445 { 1446 let resource = event.target; 1447 if (!(resource instanceof WI.Resource)) 1448 return; 1449 1450 if (!resource.isLocalResourceOverride) 1451 return; 1452 1453 let localResourceOverride = this.localResourceOverrideForURL(resource.url); 1454 console.assert(localResourceOverride); 1470 _handleResourceContentChangedForLocalResourceOverride(event) 1471 { 1472 let localResourceOverride = event.target.localResourceOverride; 1455 1473 if (!localResourceOverride) 1456 1474 return; … … 1527 1545 LocalResourceOverrideAdded: "network-manager-local-resource-override-added", 1528 1546 LocalResourceOverrideRemoved: "network-manager-local-resource-override-removed", 1529 RequestIntercepted: "network-manager-request-intercepted"1530 1547 }; -
trunk/Source/WebInspectorUI/UserInterface/Images/DocumentIcons.svg
r259329 r270604 34 34 } 35 35 36 .generic.override.light { 37 --border: hsl(226, 70%, 75%); 38 --paper: hsl(0, 0%, 18%); 39 } 40 41 .generic.override.dark { 42 --border: hsl(226, 30%, 20%); 43 --paper: hsl(0, 0%, 90%); 44 } 45 36 46 .markup.override.light { 37 47 --border: hsl(226, 70%, 75%); … … 156 166 </symbol> 157 167 158 <g id="generic-light" class=" light"><use href="#doc"/></g>159 <g id="generic-light-override" class=" light override"><use href="#doc"/></g>160 <g id="generic-dark" class=" dark"><use href="#doc"/></g>161 <g id="generic-dark-override" class=" dark override"><use href="#doc"/></g>162 <g id="css-light" class=" light"><use href="#doc"/><use href="#css"/></g>168 <g id="generic-light" class="generic light"><use href="#doc"/></g> 169 <g id="generic-light-override" class="generic light override"><use href="#doc"/></g> 170 <g id="generic-dark" class="generic dark"><use href="#doc"/></g> 171 <g id="generic-dark-override" class="generic dark override"><use href="#doc"/></g> 172 <g id="css-light" class="css light"><use href="#doc"/><use href="#css"/></g> 163 173 <g id="css-light-override" class="css light override"><use href="#doc"/><use href="#css"/></g> 164 <g id="css-dark" class=" dark"><use href="#doc"/><use href="#css"/></g>174 <g id="css-dark" class="css dark"><use href="#doc"/><use href="#css"/></g> 165 175 <g id="css-dark-override" class="css dark override"><use href="#doc"/><use href="#css"/></g> 166 <g id="font-light" class=" light"><use href="#doc"/><use href="#font"/></g>176 <g id="font-light" class="font light"><use href="#doc"/><use href="#font"/></g> 167 177 <g id="font-light-override" class="font light override"><use href="#doc"/><use href="#font"/></g> 168 <g id="font-dark" class=" dark"><use href="#doc"/><use href="#font"/></g>178 <g id="font-dark" class="font dark"><use href="#doc"/><use href="#font"/></g> 169 179 <g id="font-dark-override" class="font dark override"><use href="#doc"/><use href="#font"/></g> 170 <g id="image-light" class=" light"><use href="#doc"/><use href="#image"/></g>180 <g id="image-light" class="image light"><use href="#doc"/><use href="#image"/></g> 171 181 <g id="image-light-override" class="image light override"><use href="#doc"/><use href="#image"/></g> 172 <g id="image-dark" class=" dark"><use href="#doc"/><use href="#image"/></g>182 <g id="image-dark" class="image dark"><use href="#doc"/><use href="#image"/></g> 173 183 <g id="image-dark-override" class="image dark override"><use href="#doc"/><use href="#image"/></g> 174 <g id="gl-light" class=" light"><use href="#doc"/><use href="#gl"/></g>184 <g id="gl-light" class="gl light"><use href="#doc"/><use href="#gl"/></g> 175 185 <g id="gl-light-override" class="gl light override"><use href="#doc"/><use href="#gl"/></g> 176 <g id="gl-dark" class=" dark"><use href="#doc"/><use href="#gl"/></g>186 <g id="gl-dark" class="gl dark"><use href="#doc"/><use href="#gl"/></g> 177 187 <g id="gl-dark-override" class="gl dark override"><use href="#doc"/><use href="#gl"/></g> 178 <g id="js-light" class=" light"><use href="#doc"/><use href="#js"/></g>188 <g id="js-light" class="js light"><use href="#doc"/><use href="#js"/></g> 179 189 <g id="js-light-override" class="js light override"><use href="#doc"/><use href="#js"/></g> 180 <g id="js-dark" class=" dark"><use href="#doc"/><use href="#js"/></g>190 <g id="js-dark" class="js dark"><use href="#doc"/><use href="#js"/></g> 181 191 <g id="js-dark-override" class="js dark override"><use href="#doc"/><use href="#js"/></g> 182 <g id="markup-light" class=" light"><use href="#doc"/><use href="#markup"/></g>192 <g id="markup-light" class="markup light"><use href="#doc"/><use href="#markup"/></g> 183 193 <g id="markup-light-override" class="markup light override"><use href="#doc"/><use href="#markup"/></g> 184 <g id="markup-dark" class=" dark"><use href="#doc"/><use href="#markup"/></g>194 <g id="markup-dark" class="markup dark"><use href="#doc"/><use href="#markup"/></g> 185 195 <g id="markup-dark-override" class="markup dark override"><use href="#doc"/><use href="#markup"/></g> 186 <g id="websocket-light" class=" light"><use href="#websocket"/></g>187 <g id="websocket-dark" class=" dark"><use href="#websocket"/></g>188 <g id="worker-light" class=" light"><use href="#doc"/><use href="#worker"/></g>196 <g id="websocket-light" class="websocket light"><use href="#websocket"/></g> 197 <g id="websocket-dark" class="websocket dark"><use href="#websocket"/></g> 198 <g id="worker-light" class="worker light"><use href="#doc"/><use href="#worker"/></g> 189 199 <g id="worker-light-override" class="worker light override"><use href="#doc"/><use href="#worker"/></g> 190 <g id="worker-dark" class=" dark"><use href="#doc"/><use href="#worker"/></g>200 <g id="worker-dark" class="worker dark"><use href="#doc"/><use href="#worker"/></g> 191 201 <g id="worker-dark-override" class="worker dark override"><use href="#doc"/><use href="#worker"/></g> 192 202 </svg> -
trunk/Source/WebInspectorUI/UserInterface/Main.html
r269701 r270604 139 139 <link rel="stylesheet" href="Views/LocalResourceOverrideLabelView.css"> 140 140 <link rel="stylesheet" href="Views/LocalResourceOverridePopover.css"> 141 <link rel="stylesheet" href="Views/LocalResourceOverrideRequestContentView.css"> 141 142 <link rel="stylesheet" href="Views/LocalResourceOverrideTreeElement.css"> 142 143 <link rel="stylesheet" href="Views/LocalResourceOverrideWarningView.css"> … … 548 549 <script src="Views/ResourceContentView.js"></script> 549 550 <script src="Views/TabContentView.js"></script> 551 <script src="Views/TextContentView.js"></script> 550 552 <script src="Views/TimelineDataGrid.js"></script> 551 553 <script src="Views/TimelineDataGridNode.js"></script> … … 738 740 <script src="Views/LocalResourceOverrideLabelView.js"></script> 739 741 <script src="Views/LocalResourceOverridePopover.js"></script> 742 <script src="Views/LocalResourceOverrideRequestContentView.js"></script> 740 743 <script src="Views/LocalResourceOverrideTreeElement.js"></script> 741 744 <script src="Views/LocalResourceOverrideWarningView.js"></script> … … 836 839 <script src="Views/StorageSidebarPanel.js"></script> 837 840 <script src="Views/SyntaxHighlightingSupport.js"></script> 838 <script src="Views/TextContentView.js"></script>839 841 <script src="Views/TextNavigationItem.js"></script> 840 842 <script src="Views/TextResourceContentView.js"></script> -
trunk/Source/WebInspectorUI/UserInterface/Models/LocalResource.js
r251024 r270604 30 30 // Construction values try to mimic protocol inputs to WI.Resource: 31 31 // 32 // request: { url, method, headers, timestamp, walltime, finishedTimestamp data }32 // request: { url, method, headers, timestamp, walltime, finishedTimestamp, data } 33 33 // response: { mimeType, headers, statusCode, statusText, failureReasonText, content, base64Encoded } 34 34 // metrics: { responseSource, protocol, priority, remoteAddress, connectionIdentifier, sizes } 35 35 // timing: { startTime, domainLookupStart, domainLookupEnd, connectStart, connectEnd, secureConnectionStart, requestStart, responseStart, responseEnd } 36 // isLocalResourceOverride: <boolean>37 36 38 37 WI.LocalResource = class LocalResource extends WI.Resource 39 38 { 40 constructor({request, response, metrics, timing , isLocalResourceOverride})39 constructor({request, response, metrics, timing}) 41 40 { 42 41 console.assert(request); … … 61 60 this._statusText = response.statusText || null; 62 61 this._responseHeaders = response.headers || {}; 63 this._failureReasonText = response.failureReasonText ;62 this._failureReasonText = response.failureReasonText || null; 64 63 this._timingData = new WI.ResourceTimingData(this, timing); 65 64 … … 75 74 this._responseBodySize = !isNaN(metrics.responseBodyDecodedSize) ? metrics.responseBodyDecodedSize : NaN; 76 75 77 // LocalResource specific.78 this._ isLocalResourceOverride = isLocalResourceOverride || false;76 // Set by `WI.LocalResourceOverride`. 77 this._localResourceOverride = null; 79 78 80 79 // Finalize WI.Resource. … … 84 83 85 84 // Finalize WI.SourceCode. 86 let content = response.content ;87 let base64Encoded = response.base64Encoded ;85 let content = response.content || ""; 86 let base64Encoded = response.base64Encoded || false; 88 87 this._originalRevision = new WI.SourceCodeRevision(this, content, base64Encoded, this._mimeType); 89 88 this._currentRevision = this._originalRevision; … … 216 215 request: { 217 216 url: this.url, 217 method: this.requestMethod, 218 headers: this.requestHeaders, 219 data: this.requestData, 218 220 }, 219 221 response: { … … 225 227 base64Encoded: this.currentRevision.base64Encoded, 226 228 }, 227 isLocalResourceOverride: this._isLocalResourceOverride,228 229 }; 229 230 } … … 231 232 // Public 232 233 233 get isLocalResourceOverride() 234 { 235 return this._isLocalResourceOverride; 236 } 234 get localResourceOverride() { return this._localResourceOverride; } 237 235 238 236 // Protected -
trunk/Source/WebInspectorUI/UserInterface/Models/LocalResourceOverride.js
r267723 r270604 26 26 WI.LocalResourceOverride = class LocalResourceOverride extends WI.Object 27 27 { 28 constructor(type, localResource, {isCaseSensitive, isRegex, disabled} = {}) 29 { 28 constructor(url, type, localResource, {isCaseSensitive, isRegex, disabled} = {}) 29 { 30 console.assert(url && typeof url === "string", url); 30 31 console.assert(Object.values(WI.LocalResourceOverride.InterceptType).includes(type), type); 31 32 console.assert(localResource instanceof WI.LocalResource, localResource); 32 console.assert(localResource.isLocalResourceOverride, localResource); 33 console.assert(localResource.url, localResource); 33 console.assert(!localResource.localResourceOverride, localResource); 34 34 console.assert(isCaseSensitive === undefined || typeof isCaseSensitive === "boolean", isCaseSensitive); 35 35 console.assert(isRegex === undefined || typeof isRegex === "boolean", isRegex); … … 38 38 super(); 39 39 40 this._url = url; 41 this._urlComponents = null; 40 42 this._type = type; 41 43 this._localResource = localResource; … … 43 45 this._isRegex = isRegex !== undefined ? isRegex : false; 44 46 this._disabled = disabled !== undefined ? disabled : false; 47 48 this._localResource._localResourceOverride = this; 45 49 } 46 50 47 51 // Static 48 52 49 static create( type, {url, mimeType, content, base64Encoded, statusCode, statusText, headers, isCaseSensitive, isRegex, disabled})53 static create(url, type, {requestURL, requestMethod, requestHeaders, requestData, responseMIMEType, responseContent, responseBase64Encoded, responseStatusCode, responseStatusText, responseHeaders, isCaseSensitive, isRegex, disabled} = {}) 50 54 { 51 55 let localResource = new WI.LocalResource({ 52 56 request: { 53 url: isRegex ? url : WI.urlWithoutFragment(url), 57 url: requestURL || "", 58 method: requestMethod, 59 headers: requestHeaders, 60 data: requestData, 54 61 }, 55 62 response: { 56 headers ,57 mimeType ,58 statusCode ,59 statusText ,60 content ,61 base64Encoded ,63 headers: responseHeaders, 64 mimeType: responseMIMEType, 65 statusCode: responseStatusCode, 66 statusText: responseStatusText, 67 content: responseContent, 68 base64Encoded: responseBase64Encoded, 62 69 }, 63 isLocalResourceOverride: true,64 70 }); 65 66 return new WI.LocalResourceOverride(type, localResource, {isCaseSensitive, isRegex, disabled}); 71 return new WI.LocalResourceOverride(url, type, localResource, {isCaseSensitive, isRegex, disabled}); 72 } 73 74 static displayNameForType(type) 75 { 76 switch (type) { 77 case WI.LocalResourceOverride.InterceptType.Request: 78 return WI.UIString("Request", "Request @ Local Override Type", "Text indicating that the local override intercepts the request phase of network activity."); 79 case WI.LocalResourceOverride.InterceptType.Response: 80 return WI.UIString("Response", "Response @ Local Override Type", "Text indicating that the local override intercepts the response phase of network activity."); 81 case WI.LocalResourceOverride.InterceptType.ResponseSkippingNetwork: 82 return WI.UIString("Response (skip network)", "Response (skip network) @ Local Override Type", "Text indicating that the local override will skip all network activity and instead immediately serve the response."); 83 } 84 85 console.assert(false, "Unknown type: ", type); 86 return ""; 67 87 } 68 88 … … 71 91 static fromJSON(json) 72 92 { 73 let {type, localResource, isCaseSensitive, isRegex, disabled} = json; 93 let {url, type, localResource: localResourceJSON, isCaseSensitive, isRegex, disabled} = json; 94 95 let localResource = WI.LocalResource.fromJSON(localResourceJSON); 74 96 75 97 // COMPATIBILITY (iOS 13.4): Network.interceptWithRequest/Network.interceptRequestWithResponse did not exist yet. 98 url ??= localResource.url; 76 99 type ??= WI.LocalResourceOverride.InterceptType.Response; 77 100 78 return new WI.LocalResourceOverride( type, WI.LocalResource.fromJSON(localResource), {isCaseSensitive, isRegex, disabled});101 return new WI.LocalResourceOverride(url, type, localResource, {isCaseSensitive, isRegex, disabled}); 79 102 } 80 103 … … 82 105 { 83 106 let json = { 107 url: this._url, 84 108 type: this._type, 85 109 localResource: this._localResource.toJSON(key), … … 90 114 91 115 if (key === WI.ObjectStore.toJSONSymbol) 92 json[WI.objectStores.localResourceOverrides.keyPath] = this._ localResource.url;116 json[WI.objectStores.localResourceOverrides.keyPath] = this._url; 93 117 94 118 return json; … … 97 121 // Public 98 122 123 get url() { return this._url; } 99 124 get type() { return this._type; } 100 get url() { return this._localResource.url; }101 125 get localResource() { return this._localResource; } 102 126 get isCaseSensitive() { return this._isCaseSensitive; } 103 127 get isRegex() { return this._isRegex; } 104 128 129 get urlComponents() 130 { 131 if (!this._urlComponents) 132 this._urlComponents = parseURL(this._url); 133 return this._urlComponents; 134 } 135 105 136 get disabled() 106 137 { … … 118 149 } 119 150 151 get displayName() 152 { 153 return this.displayURL(); 154 } 155 156 displayURL({full} = {}) 157 { 158 if (this._isRegex) 159 return "/" + this._url + "/" + (!this._isCaseSensitive ? "i" : ""); 160 161 let displayName = full ? this._url : WI.displayNameForURL(this._url, this.urlComponents); 162 if (!this._isCaseSensitive) 163 displayName = WI.UIString("%s (Case Insensitive)", "%s (Case Insensitive) @ Local Override", "Label for case-insensitive URL match pattern of a local override.").format(displayName); 164 return displayName; 165 } 166 120 167 matches(url) 121 168 { 122 169 if (this._isRegex) { 123 let regex = new RegExp(this. url, !this._isCaseSensitive ? "i" : "");170 let regex = new RegExp(this._url, !this._isCaseSensitive ? "i" : ""); 124 171 return regex.test(url); 125 172 } 126 173 127 174 if (!this._isCaseSensitive) 128 return String(url).toLowerCase() === this.url.toLowerCase(); 129 130 return url === this.url; 175 return String(url).toLowerCase() === this._url.toLowerCase(); 176 177 return url === this._url; 178 } 179 180 equals(localResourceOverrideOrSerializedData) 181 { 182 console.assert(localResourceOverrideOrSerializedData instanceof WI.LocalResourceOverride || (localResourceOverrideOrSerializedData && typeof localResourceOverrideOrSerializedData === "object"), localResourceOverrideOrSerializedData); 183 184 return localResourceOverrideOrSerializedData.url === this._url 185 && localResourceOverrideOrSerializedData.isCaseSensitive === this._isCaseSensitive 186 && localResourceOverrideOrSerializedData.isRegex === this._isRegex; 131 187 } 132 188 … … 135 191 saveIdentityToCookie(cookie) 136 192 { 193 cookie["local-resource-override-url"] = this._url; 137 194 cookie["local-resource-override-type"] = this._type; 138 cookie["local-resource-override-url"] = this._localResource.url;139 195 cookie["local-resource-override-is-case-sensitive"] = this._isCaseSensitive; 140 196 cookie["local-resource-override-is-regex"] = this._isRegex; … … 146 202 147 203 WI.LocalResourceOverride.InterceptType = { 204 Request: "request", 148 205 Response: "response", 149 206 ResponseSkippingNetwork: "response-skipping-network", -
trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js
r269359 r270604 184 184 let classes = []; 185 185 186 let isOverride = resource.isLocalResourceOverride;186 let isOverride = !!resource.localResourceOverride; 187 187 let wasOverridden = resource.responseSource === WI.Resource.ResponseSource.InspectorOverride; 188 let shouldBeOverridden = resource.isLoading() && WI.networkManager.localResourceOverride ForURL(resource.url);188 let shouldBeOverridden = resource.isLoading() && WI.networkManager.localResourceOverridesForURL(resource.url).some((localResourceOverride) => !localResourceOverride.disabled); 189 189 if (isOverride || wasOverridden || shouldBeOverridden) 190 190 classes.push("override"); … … 364 364 get supportsScriptBlackboxing() 365 365 { 366 if (this. isLocalResourceOverride)366 if (this.localResourceOverride) 367 367 return false; 368 368 if (!this.finished || this.failed) … … 428 428 { 429 429 return this._parentFrame ? this._parentFrame.mainResource === this : false; 430 }431 432 get isLocalResourceOverride()433 {434 return false;435 430 } 436 431 … … 1063 1058 } 1064 1059 1065 async createLocalResourceOverride( {mimeType, base64Encoded, content} = {})1066 { 1067 console.assert(!this. isLocalResourceOverride);1060 async createLocalResourceOverride(type, {mimeType, base64Encoded, content} = {}) 1061 { 1062 console.assert(!this.localResourceOverride); 1068 1063 console.assert(WI.NetworkManager.supportsOverridingResponses()); 1069 1064 1070 mimeType ??= this.mimeType ?? WI.mimeTypeForFileExtension(WI.fileExtensionForFilename(this.urlComponents.lastPathComponent)); 1071 1072 if (base64Encoded === undefined || content === undefined) { 1073 try { 1074 let {rawContent, rawBase64Encoded} = await this.requestContent(); 1075 content ??= rawContent; 1076 base64Encoded ??= rawBase64Encoded; 1077 } catch { 1078 content ??= ""; 1079 base64Encoded ??= !WI.shouldTreatMIMETypeAsText(mimeType); 1065 let resourceData = { 1066 requestURL: this.url, 1067 }; 1068 1069 switch (type) { 1070 case WI.LocalResourceOverride.InterceptType.Request: 1071 resourceData.requestMethod = this.requestMethod ?? WI.HTTPUtilities.RequestMethod.GET; 1072 resourceData.requestHeaders = Object.shallowCopy(this.requestHeaders); 1073 resourceData.requestData = this.requestData ?? ""; 1074 break; 1075 1076 case WI.LocalResourceOverride.InterceptType.Response: 1077 case WI.LocalResourceOverride.InterceptType.ResponseSkippingNetwork: 1078 resourceData.responseMIMEType = this.mimeType ?? WI.mimeTypeForFileExtension(WI.fileExtensionForFilename(this.urlComponents.lastPathComponent)); 1079 resourceData.responseStatusCode = this.statusCode; 1080 resourceData.responseStatusText = this.statusText; 1081 if (!resourceData.responseStatusCode) { 1082 resourceData.responseStatusCode = 200; 1083 resourceData.responseStatusText = null; 1080 1084 } 1081 } 1082 1083 return WI.LocalResourceOverride.create(WI.LocalResourceOverride.InterceptType.Response, { 1084 url: this.url, 1085 mimeType, 1086 content, 1087 base64Encoded, 1088 statusCode: this.statusCode, 1089 statusText: this.statusText, 1090 headers: this.responseHeaders, 1091 }); 1085 resourceData.responseStatusText ||= WI.HTTPUtilities.statusTextForStatusCode(resourceData.responseStatusCode); 1086 1087 if (base64Encoded === undefined || content === undefined) { 1088 try { 1089 let {rawContent, rawBase64Encoded} = await this.requestContent(); 1090 content ??= rawContent; 1091 base64Encoded ??= rawBase64Encoded; 1092 } catch { 1093 content ??= ""; 1094 base64Encoded ??= !WI.shouldTreatMIMETypeAsText(resourceData.mimeType); 1095 } 1096 } 1097 resourceData.responseContent = content; 1098 resourceData.responseBase64Encoded = base64Encoded; 1099 resourceData.responseHeaders = Object.shallowCopy(this.responseHeaders); 1100 break; 1101 } 1102 1103 return WI.LocalResourceOverride.create(WI.urlWithoutFragment(this.url), type, resourceData); 1104 } 1105 1106 updateLocalResourceOverrideRequestData(data) 1107 { 1108 console.assert(this.localResourceOverride); 1109 1110 if (data === this._requestData) 1111 return; 1112 1113 this._requestData = data; 1114 1115 this.dispatchEventToListeners(WI.Resource.Event.RequestDataDidChange); 1092 1116 } 1093 1117 … … 1219 1243 TypeDidChange: "resource-type-did-change", 1220 1244 RequestHeadersDidChange: "resource-request-headers-did-change", 1245 RequestDataDidChange: "resource-request-data-did-change", 1221 1246 ResponseReceived: "resource-response-received", 1222 1247 LoadingDidFinish: "resource-loading-did-finish", -
trunk/Source/WebInspectorUI/UserInterface/Models/SourceCode.js
r264669 r270604 142 142 } 143 143 144 get localResourceOverride() 145 { 146 // Overridden by subclasses if needed. 147 return null; 148 } 149 144 150 get sourceMaps() 145 151 { -
trunk/Source/WebInspectorUI/UserInterface/Test.html
r269701 r270604 58 58 <script src="Base/DOMUtilities.js"></script> 59 59 <script src="Base/FileUtilities.js"></script> 60 <script src="Base/HTTPUtilities.js"></script> 60 61 <script src="Base/ImageUtilities.js"></script> 61 62 <script src="Base/MIMETypeUtilities.js"></script> -
trunk/Source/WebInspectorUI/UserInterface/Views/ContentView.js
r270134 r270604 99 99 } 100 100 101 if (representedObject instanceof WI.LocalResourceOverride) 101 if (representedObject instanceof WI.LocalResourceOverride) { 102 if (representedObject.type === WI.LocalResourceOverride.InterceptType.Request) 103 return new WI.LocalResourceOverrideRequestContentView(representedObject); 102 104 return WI.ContentView.createFromRepresentedObject(representedObject.localResource); 105 } 103 106 104 107 if (representedObject instanceof WI.DOMStorageObject) … … 238 241 if (representedObject.sourceCodeLocation) 239 242 return representedObject.sourceCodeLocation.displaySourceCode; 243 return representedObject; 240 244 } 241 245 … … 243 247 if (representedObject.domNode) 244 248 return WI.ContentView.resolvedRepresentedObjectForRepresentedObject(representedObject.domNode); 249 return representedObject; 245 250 } 246 251 … … 248 253 if (representedObject.frame) 249 254 return WI.ContentView.resolvedRepresentedObjectForRepresentedObject(representedObject.frame); 255 return representedObject; 250 256 } 251 257 … … 256 262 return representedObject.sourceCode; 257 263 258 if (representedObject instanceof WI.LocalResourceOverride) 259 return representedObject.localResource; 264 if (representedObject instanceof WI.LocalResourceOverride) { 265 if (representedObject.type !== WI.LocalResourceOverride.InterceptType.Request) 266 return representedObject.localResource; 267 return representedObject; 268 } 260 269 261 270 return representedObject; -
trunk/Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js
r269755 r270604 78 78 if (WI.networkManager.canBeOverridden(sourceCode)) { 79 79 contextMenu.appendSeparator(); 80 contextMenu.appendItem(WI.UIString("Create Local Override"), async () => { 81 let resource = sourceCode; 82 let localResourceOverride = await resource.createLocalResourceOverride(); 80 81 if (WI.NetworkManager.supportsOverridingRequests()) { 82 contextMenu.appendItem(WI.UIString("Create Request Local Override"), async () => { 83 let localResourceOverride = await sourceCode.createLocalResourceOverride(WI.LocalResourceOverride.InterceptType.Request); 84 WI.networkManager.addLocalResourceOverride(localResourceOverride); 85 WI.showLocalResourceOverride(localResourceOverride, { 86 initiatorHint: WI.TabBrowser.TabNavigationInitiator.ContextMenu, 87 }); 88 }); 89 } 90 91 contextMenu.appendItem(WI.UIString("Create Response Local Override"), async () => { 92 let localResourceOverride = await sourceCode.createLocalResourceOverride(WI.LocalResourceOverride.InterceptType.Response); 83 93 WI.networkManager.addLocalResourceOverride(localResourceOverride); 84 94 WI.showLocalResourceOverride(localResourceOverride, { … … 87 97 }); 88 98 } else { 89 let localResourceOverride = WI.networkManager.localResourceOverride ForURL(sourceCode.url);99 let localResourceOverride = WI.networkManager.localResourceOverridesForURL(sourceCode.url)[0]; 90 100 if (localResourceOverride) { 91 101 contextMenu.appendSeparator(); … … 110 120 contextMenu.appendSeparator(); 111 121 112 if (location && (sourceCode instanceof WI.Script || (sourceCode instanceof WI.Resource && sourceCode.type === WI.Resource.Type.Script && !sourceCode. isLocalResourceOverride))) {122 if (location && (sourceCode instanceof WI.Script || (sourceCode instanceof WI.Resource && sourceCode.type === WI.Resource.Type.Script && !sourceCode.localResourceOverride))) { 113 123 let existingBreakpoint = WI.debuggerManager.breakpointForSourceCodeLocation(location); 114 124 if (existingBreakpoint) { … … 143 153 WI.appendContextMenuItemsForURL(contextMenu, sourceCode.url, {sourceCode, location}); 144 154 145 if (sourceCode instanceof WI.Resource && !sourceCode. isLocalResourceOverride) {155 if (sourceCode instanceof WI.Resource && !sourceCode.localResourceOverride) { 146 156 if (sourceCode.urlComponents.scheme !== "data") { 147 157 contextMenu.appendItem(WI.UIString("Copy as cURL"), () => { -
trunk/Source/WebInspectorUI/UserInterface/Views/FontResourceContentView.js
r270134 r270604 71 71 this.addSubview(dropZoneView); 72 72 73 if (this. showingLocalResourceOverride)73 if (this.resource.localResourceOverride) 74 74 this.resource.addEventListener(WI.SourceCode.Event.ContentDidChange, this._handleLocalResourceContentDidChange, this); 75 75 } … … 117 117 dropZoneShouldAppearForDragEvent(dropZone, event) 118 118 { 119 let existingOverrides = WI.networkManager.localResourceOverridesForURL(this.resource.url); 120 if (existingOverrides.length > 1) 121 return false; 122 123 // Request overrides cannot be created/updated from a file as files don't have network info. 124 let localResourceOverride = this.resource.localResourceOverride || existingOverrides[0]; 125 if (localResourceOverride?.type === WI.LocalResourceOverride.InterceptType.Request) 126 return false; 127 119 128 return event.dataTransfer.types.includes("Files"); 120 129 } … … 122 131 dropZoneHandleDragEnter(dropZone, event) 123 132 { 124 if (this. showingLocalResourceOverride)133 if (this.resource.localResourceOverride) 125 134 dropZone.text = WI.UIString("Update Font"); 126 else if (WI.networkManager.localResourceOverride ForURL(this.resource.url))135 else if (WI.networkManager.localResourceOverridesForURL(this.resource.url).length) 127 136 dropZone.text = WI.UIString("Update Local Override"); 128 137 else … … 139 148 140 149 WI.FileUtilities.readData(files, async ({dataURL, mimeType, base64Encoded, content}) => { 141 let localResourceOverride = WI.networkManager.localResourceOverrideForURL(this.resource.url);142 if (!localResourceOverride && !this.showingLocalResourceOverride) {143 localResourceOverride = await this.resource.createLocalResourceOverride( );150 let localResourceOverride = this.resource.localResourceOverride || WI.networkManager.localResourceOverridesForURL(this.resource.url)[0]; 151 if (!localResourceOverride) { 152 localResourceOverride = await this.resource.createLocalResourceOverride(WI.LocalResourceOverride.InterceptType.Response); 144 153 WI.networkManager.addLocalResourceOverride(localResourceOverride); 145 154 } 146 147 155 console.assert(localResourceOverride); 148 156 … … 150 158 revision.updateRevisionContent(content, {base64Encoded, mimeType}); 151 159 152 if (!this. showingLocalResourceOverride)160 if (!this.resource.localResourceOverride) 153 161 WI.showLocalResourceOverride(localResourceOverride); 154 162 }); -
trunk/Source/WebInspectorUI/UserInterface/Views/ImageResourceContentView.js
r270134 r270604 93 93 this.addSubview(dropZoneView); 94 94 95 if (this. showingLocalResourceOverride)95 if (this.resource.localResourceOverride) 96 96 this.resource.addEventListener(WI.SourceCode.Event.ContentDidChange, this._handleLocalResourceContentDidChange, this); 97 97 } … … 124 124 return false; 125 125 126 let existingOverrides = WI.networkManager.localResourceOverridesForURL(this.resource.url); 127 if (existingOverrides.length > 1) 128 return false; 129 130 // Request overrides cannot be created/updated from a file as files don't have network info. 131 let localResourceOverride = this.resource.localResourceOverride || existingOverrides[0]; 132 if (localResourceOverride?.type === WI.LocalResourceOverride.InterceptType.Request) 133 return false; 134 126 135 // Appear if the drop contains a file. 127 136 return event.dataTransfer.types.includes("Files"); … … 130 139 dropZoneHandleDragEnter(dropZone, event) 131 140 { 132 if (this. showingLocalResourceOverride)141 if (this.resource.localResourceOverride) 133 142 dropZone.text = WI.UIString("Update Image"); 134 else if (WI.networkManager.localResourceOverride ForURL(this.resource.url))143 else if (WI.networkManager.localResourceOverridesForURL(this.resource.url).length) 135 144 dropZone.text = WI.UIString("Update Local Override"); 136 145 else … … 147 156 148 157 WI.FileUtilities.readData(files, async ({dataURL, mimeType, base64Encoded, content}) => { 149 let localResourceOverride = WI.networkManager.localResourceOverrideForURL(this.resource.url);150 if (!localResourceOverride && !this.showingLocalResourceOverride) {151 localResourceOverride = await this.resource.createLocalResourceOverride( );158 let localResourceOverride = this.resource.localResourceOverride || WI.networkManager.localResourceOverridesForURL(this.resource.url)[0]; 159 if (!localResourceOverride) { 160 localResourceOverride = await this.resource.createLocalResourceOverride(WI.LocalResourceOverride.InterceptType.Response); 152 161 WI.networkManager.addLocalResourceOverride(localResourceOverride); 153 162 } 154 155 163 console.assert(localResourceOverride); 156 164 … … 158 166 revision.updateRevisionContent(content, {base64Encoded, mimeType}); 159 167 160 if (!this. showingLocalResourceOverride)168 if (!this.resource.localResourceOverride) 161 169 WI.showLocalResourceOverride(localResourceOverride); 162 170 }); -
trunk/Source/WebInspectorUI/UserInterface/Views/LocalResourceOverrideLabelView.js
r249504 r270604 26 26 WI.LocalResourceOverrideLabelView = class LocalResourceOverrideLabelView extends WI.View 27 27 { 28 constructor(localResource )28 constructor(localResourceOverride) 29 29 { 30 console.assert(localResource .isLocalResourceOverride);30 console.assert(localResourceOverride instanceof WI.LocalResourceOverride, localResourceOverride); 31 31 32 32 super(); 33 33 34 this._localResource = localResource;34 this._localResourceOverride = localResourceOverride; 35 35 36 36 this.element.classList.add("local-resource-override-label-view"); … … 41 41 initialLayout() 42 42 { 43 this._labelElement = document.createElement("span"); 44 this._labelElement.className = "label"; 45 this._labelElement.textContent = WI.UIString("Override"); 43 let labelElement = document.createElement("span"); 44 labelElement.className = "label"; 45 if (this._localResourceOverride.type === WI.LocalResourceOverride.InterceptType.Request) 46 labelElement.textContent = WI.UIString("Request Override", "Request Override @ Local Override Content View", "Label indicating that the shown content is from a request local override."); 47 else 48 labelElement.textContent = WI.UIString("Response Override", "Response Override @ Local Override Content View", "Label indicating that the shown content is from a response local override."); 46 49 47 this._urlElement = document.createElement("span");48 this._urlElement.textContent = this._localResource.url;49 this._urlElement.className = "url";50 let urlElement = document.createElement("span"); 51 urlElement.textContent = this._localResourceOverride.displayURL({full: true}); 52 urlElement.className = "url"; 50 53 51 54 let container = this.element.appendChild(document.createElement("div")); 52 container.append( this._labelElement, " ", this._urlElement);55 container.append(labelElement, " ", urlElement); 53 56 } 54 57 }; -
trunk/Source/WebInspectorUI/UserInterface/Views/LocalResourceOverridePopover.css
r269166 r270604 66 66 } 67 67 68 .popover .local-resource-override-popover-content .editor.url { 69 width: 324px; 68 .popover .local-resource-override-popover-content.request .editor:is(.url, .redirect) { 69 width: 344px; 70 } 71 72 .popover .local-resource-override-popover-content.response .editor.url { 73 width: 330px; 70 74 } 71 75 … … 91 95 } 92 96 97 .popover .local-resource-override-popover-content .data-grid { 98 margin-bottom: 6px; 99 } 100 93 101 .popover .local-resource-override-popover-content .data-grid tr.header-content-type > :matches(.name-column, .value-column) { 94 102 opacity: 0.5; 95 }96 97 .popover .local-resource-override-popover-content .add-header {98 margin-top: 8px;99 }100 101 .popover .local-resource-override-popover-content .add-header + .reference-page-link-container {102 margin-top: 6px;103 103 } 104 104 … … 107 107 } 108 108 109 body[dir=ltr] .popover .local-resource-override-popover-content .reference-page-link-container { 110 float: right; 111 } 112 113 body[dir=rtl] .popover .local-resource-override-popover-content .reference-page-link-container { 114 float: left; 109 .popover .local-resource-override-popover-content .reference-page-link-container { 110 position: absolute; 111 inset-inline-end: 1.5em; 112 bottom: 1.25em; 115 113 } 116 114 -
trunk/Source/WebInspectorUI/UserInterface/Views/LocalResourceOverridePopover.js
r267723 r270604 30 30 super(delegate); 31 31 32 this._typeSelectElement = null; 32 33 this._urlCodeMirror = null; 33 34 this._isCaseSensitiveCheckbox = null; 34 35 this._isRegexCheckbox = null; 36 this._requestURLCodeMirror = null; 37 this._methodSelectElement = null; 35 38 this._mimeTypeCodeMirror = null; 36 39 this._statusCodeCodeMirror = null; 37 40 this._statusTextCodeMirror = null; 38 41 this._headersDataGrid = null; 39 42 this._skipNetworkCheckbox = null; 43 44 this._originalRequestURL = null; 40 45 this._serializedDataWhenShown = null; 41 46 … … 50 55 return null; 51 56 52 let url = this._urlCodeMirror.getValue(); 53 if (!url) 57 // COMPATIBILITY (iOS 13.4): `Network.addInterception` did not exist yet. 58 let data = { 59 type: this._skipNetworkCheckbox?.checked ? WI.LocalResourceOverride.InterceptType.ResponseSkippingNetwork : this._typeSelectElement.value, 60 url: WI.urlWithoutFragment(this._urlCodeMirror.getValue()), 61 isCaseSensitive: !this._isCaseSensitiveCheckbox || this._isCaseSensitiveCheckbox.checked, 62 isRegex: !!this._isRegexCheckbox?.checked, 63 }; 64 65 if (!data.url) 54 66 return null; 55 67 56 let isRegex = this._isRegexCheckbox && this._isRegexCheckbox.checked; 57 if (!isRegex) { 68 if (!data.isRegex) { 58 69 const schemes = ["http:", "https:", "file:"]; 59 if (!schemes.some((scheme) => url.toLowerCase().startsWith(scheme)))70 if (!schemes.some((scheme) => data.url.toLowerCase().startsWith(scheme))) 60 71 return null; 61 72 } 62 63 // NOTE: We can allow an empty mimeType / statusCode / statusText to pass64 // network values through, but lets require them for overrides so that65 // the popover doesn't have to have an additional state for "pass through".66 67 let mimeType = this._mimeTypeCodeMirror.getValue() || this._mimeTypeCodeMirror.getOption("placeholder");68 if (!mimeType)69 return null;70 71 let statusCode = parseInt(this._statusCodeCodeMirror.getValue());72 if (isNaN(statusCode))73 statusCode = parseInt(this._statusCodeCodeMirror.getOption("placeholder"));74 if (isNaN(statusCode) || statusCode < 0)75 return null;76 77 let statusText = this._statusTextCodeMirror.getValue() || this._statusTextCodeMirror.getOption("placeholder");78 if (!statusText)79 return null;80 73 81 74 let headers = {}; … … 84 77 if (!name || !value) 85 78 continue; 86 if (name.toLowerCase() === "content-type") 87 continue; 88 if (name.toLowerCase() === "set-cookie") 89 continue; 79 if (data.type !== WI.LocalResourceOverride.InterceptType.Request) { 80 if (name.toLowerCase() === "content-type") 81 continue; 82 if (name.toLowerCase() === "set-cookie") 83 continue; 84 } 90 85 headers[name] = value; 91 86 } 92 87 93 let data = { 94 type: this._skipNetworkCheckbox?.checked ? WI.LocalResourceOverride.InterceptType.ResponseSkippingNetwork : WI.LocalResourceOverride.InterceptType.Response, 95 url, 96 mimeType, 97 statusCode, 98 statusText, 99 headers, 100 }; 101 102 if (this._isCaseSensitiveCheckbox) 103 data.isCaseSensitive = this._isCaseSensitiveCheckbox.checked; 104 105 if (this._isRegexCheckbox) 106 data.isRegex = this._isRegexCheckbox.checked; 88 switch (data.type) { 89 case WI.LocalResourceOverride.InterceptType.Request: 90 data.requestURL = this._requestURLCodeMirror.getValue(); 91 data.requestMethod = this._methodSelectElement.value; 92 data.requestHeaders = headers; 93 break; 94 95 case WI.LocalResourceOverride.InterceptType.Response: 96 case WI.LocalResourceOverride.InterceptType.ResponseSkippingNetwork: 97 // NOTE: We can allow an empty mimeType / statusCode / statusText to pass 98 // network values through, but lets require them for overrides so that 99 // the popover doesn't have to have an additional state for "pass through". 100 101 data.responseMIMEType = this._mimeTypeCodeMirror.getValue() || this._mimeTypeCodeMirror.getOption("placeholder"); 102 if (!data.responseMIMEType) 103 return null; 104 105 data.responseStatusCode = parseInt(this._statusCodeCodeMirror.getValue()); 106 if (isNaN(data.responseStatusCode)) 107 data.responseStatusCode = parseInt(this._statusCodeCodeMirror.getOption("placeholder")); 108 if (isNaN(data.responseStatusCode) || data.responseStatusCode < 0) 109 return null; 110 111 data.responseStatusText = this._statusTextCodeMirror.getValue() || this._statusTextCodeMirror.getOption("placeholder"); 112 if (!data.responseStatusText) 113 return null; 114 115 data.responseHeaders = headers; 116 break; 117 } 118 119 if (!data.requestURL) { 120 if (data.isCaseSensitive && !data.isRegex) 121 data.requestURL = data.url; 122 else if (this._originalRequestURL) 123 data.requestURL = this._originalRequestURL; 124 } 125 126 if (!data.responseMIMEType && data.requestURL) { 127 data.responseMIMEType = WI.mimeTypeForFileExtension(WI.fileExtensionForURL(data.requestURL)); 128 if (data.type !== WI.LocalResourceOverride.InterceptType.Request) 129 headers["Content-Type"] = data.responseMIMEType; 130 } 107 131 108 132 // No change. … … 122 146 let localResource = localResourceOverride ? localResourceOverride.localResource : null; 123 147 124 let data = {};125 let resourceData = {};148 let placeholderData = {}; 149 let valueData = {}; 126 150 if (localResource) { 127 data.url = resourceData.url = localResource.url; 128 data.mimeType = resourceData.mimeType = localResource.mimeType; 129 data.statusCode = resourceData.statusCode = String(localResource.statusCode); 130 data.statusText = resourceData.statusText = localResource.statusText; 131 } 132 133 if (!data.url) 134 data.url = this._defaultURL(); 135 136 if (!data.mimeType) 137 data.mimeType = "text/javascript"; 138 139 if (!data.statusCode || data.statusCode === "NaN") { 140 data.statusCode = "200"; 141 resourceData.statusCode = undefined; 142 } 143 144 if (!data.statusText) { 145 data.statusText = WI.HTTPUtilities.statusTextForStatusCode(parseInt(data.statusCode)); 146 resourceData.statusText = undefined; 147 } 148 149 let responseHeaders = localResource ? localResource.responseHeaders : {}; 151 placeholderData.url = valueData.url = localResourceOverride.url; 152 placeholderData.requestURL = valueData.requestURL = localResource.url; 153 placeholderData.method = valueData.method = localResource.requestMethod; 154 placeholderData.mimeType = valueData.mimeType = localResource.mimeType; 155 placeholderData.statusCode = valueData.statusCode = String(localResource.statusCode); 156 placeholderData.statusText = valueData.statusText = localResource.statusText; 157 } 158 159 placeholderData.url ||= this._defaultURL(); 160 placeholderData.requestURL ||= placeholderData.url; 161 placeholderData.method ||= "GET"; 162 placeholderData.mimeType ||= "text/javascript"; 163 if (!placeholderData.statusCode || placeholderData.statusCode === "NaN") { 164 placeholderData.statusCode = "200"; 165 placeholderData.statusText = undefined; 166 valueData.statusCode = undefined; 167 valueData.statusText = undefined; 168 } 169 if (!placeholderData.statusText) { 170 placeholderData.statusText = WI.HTTPUtilities.statusTextForStatusCode(parseInt(placeholderData.statusCode)); 171 valueData.statusText = undefined; 172 } 173 174 let requestHeaders = localResource?.requestHeaders ?? {}; 175 let responseHeaders = localResource?.responseHeaders ?? {}; 150 176 151 177 let popoverContentElement = document.createElement("div"); … … 170 196 labelElement.setAttribute("for", inputField.id); 171 197 172 return {codeMirror, dataElement}; 173 }; 174 175 let urlRow = createRow(WI.UIString("URL"), "url", resourceData.url || "", data.url); 198 return {element: row, dataElement, codeMirror}; 199 }; 200 201 this._typeSelectElement = document.createElement("select"); 202 for (let type of [WI.LocalResourceOverride.InterceptType.Request, WI.LocalResourceOverride.InterceptType.Response]) { 203 let optionElement = this._typeSelectElement.appendChild(document.createElement("option")); 204 optionElement.textContent = WI.LocalResourceOverride.displayNameForType(type); 205 optionElement.value = type; 206 } 207 this._typeSelectElement.value = localResourceOverride?.type ?? WI.LocalResourceOverride.InterceptType.Request; 208 209 if (!localResourceOverride && WI.NetworkManager.supportsOverridingRequests()) { 210 let typeRowElement = table.appendChild(document.createElement("tr")); 211 212 let typeHeaderElement = typeRowElement.appendChild(document.createElement("th")); 213 214 let typeLabelElement = typeHeaderElement.appendChild(document.createElement("label")); 215 typeLabelElement.textContent = WI.UIString("Type"); 216 217 let typeDataElement = typeRowElement.appendChild(document.createElement("td")); 218 typeDataElement.appendChild(this._typeSelectElement); 219 220 this._typeSelectElement.addEventListener("change", (event) => { 221 toggleInputsForType(); 222 this.update(); 223 }); 224 225 this._typeSelectElement.id = "local-resource-override-popover-type-input-field"; 226 typeLabelElement.setAttribute("for", this._typeSelectElement.id); 227 } 228 229 let urlRow = createRow(WI.UIString("URL"), "url", valueData.url || "", placeholderData.url); 176 230 this._urlCodeMirror = urlRow.codeMirror; 177 231 … … 191 245 }; 192 246 247 // COMPATIBILITY (iOS 13.4): `Network.addInterception` did not exist yet. 193 248 if (InspectorBackend.hasCommand("Network.addInterception", "caseSensitive")) { 194 249 let isCaseSensitiveLabel = urlRow.dataElement.appendChild(document.createElement("label")); … … 202 257 } 203 258 259 // COMPATIBILITY (iOS 13.4): `Network.addInterception` did not exist yet. 204 260 if (InspectorBackend.hasCommand("Network.addInterception", "isRegex")) { 205 261 let isRegexLabel = urlRow.dataElement.appendChild(document.createElement("label")); … … 216 272 } 217 273 218 let mimeTypeRow = createRow(WI.UIString("MIME Type"), "mime", resourceData.mimeType || "", data.mimeType); 274 let requestURLRow = null; 275 let methodRowElement = null; 276 if (WI.NetworkManager.supportsOverridingRequests()) { 277 requestURLRow = createRow(WI.UIString("Redirect"), "redirect", valueData.requestURL || "", placeholderData.requestURL); 278 this._requestURLCodeMirror = requestURLRow.codeMirror; 279 280 methodRowElement = table.appendChild(document.createElement("tr")); 281 282 let methodHeaderElement = methodRowElement.appendChild(document.createElement("th")); 283 284 let methodLabelElement = methodHeaderElement.appendChild(document.createElement("label")); 285 methodLabelElement.textContent = WI.UIString("Method"); 286 287 let methodDataElement = methodRowElement.appendChild(document.createElement("td")); 288 289 this._methodSelectElement = methodDataElement.appendChild(document.createElement("select")); 290 291 [ 292 WI.HTTPUtilities.RequestMethod.GET, 293 WI.HTTPUtilities.RequestMethod.POST, 294 null, // divider 295 WI.HTTPUtilities.RequestMethod.HEAD, 296 WI.HTTPUtilities.RequestMethod.PATCH, 297 WI.HTTPUtilities.RequestMethod.PUT, 298 WI.HTTPUtilities.RequestMethod.DELETE, 299 null, // divider 300 WI.HTTPUtilities.RequestMethod.OPTIONS, 301 WI.HTTPUtilities.RequestMethod.CONNECT, 302 WI.HTTPUtilities.RequestMethod.TRACE, 303 ].forEach((method) => { 304 if (!method) { 305 this._methodSelectElement.appendChild(document.createElement("hr")); 306 return; 307 } 308 309 let optionElement = this._methodSelectElement.appendChild(document.createElement("option")); 310 optionElement.textContent = method; 311 }); 312 313 this._methodSelectElement.value = valueData.method || placeholderData.method; 314 315 this._methodSelectElement.id = "local-resource-override-popover-method-input-field"; 316 methodLabelElement.setAttribute("for", this._methodSelectElement.id); 317 } 318 319 let mimeTypeRow = createRow(WI.UIString("MIME Type", "MIME Type @ Local Override Popover", "Label for MIME type input for the local override currently being edited."), "mime", valueData.mimeType || "", placeholderData.mimeType); 219 320 this._mimeTypeCodeMirror = mimeTypeRow.codeMirror; 220 321 221 let statusCodeRow = createRow(WI.UIString("Status" ), "status", resourceData.statusCode || "", data.statusCode);322 let statusCodeRow = createRow(WI.UIString("Status", "Status @ Local Override Popover", "Label for the HTTP status code input for the local override currently being edited."), "status", valueData.statusCode || "", placeholderData.statusCode); 222 323 this._statusCodeCodeMirror = statusCodeRow.codeMirror; 223 324 224 325 let statusTextEditorElement = statusCodeRow.dataElement.appendChild(document.createElement("div")); 225 326 statusTextEditorElement.className = "editor status-text"; 226 this._statusTextCodeMirror = this._createEditor(statusTextEditorElement, {value: resourceData.statusText || "", placeholder: data.statusText});327 this._statusTextCodeMirror = this._createEditor(statusTextEditorElement, {value: valueData.statusText || "", placeholder: placeholderData.statusText}); 227 328 228 329 let editCallback = () => {}; … … 236 337 siblingToSelect.select(); 237 338 238 t his._headersDataGrid.updateLayoutIfNeeded();339 toggleHeadersDataGridVisibility(); 239 340 this.update(); 240 341 }; … … 261 362 }; 262 363 263 let contentTypeDataGridNode = addDataGridNodeForHeader("Content-Type", data.mimeType, {selectable: false, editable: false, classNames: ["header-content-type"]}); 264 265 for (let name in responseHeaders) { 266 if (name.toLowerCase() === "content-type") 267 continue; 268 if (name.toLowerCase() === "set-cookie") 269 continue; 270 addDataGridNodeForHeader(name, responseHeaders[name]); 271 } 364 let toggleHeadersDataGridVisibility = (force) => { 365 this._headersDataGrid.element.hidden = force !== undefined ? force : !this._headersDataGrid.hasChildren; 366 this._headersDataGrid.updateLayoutIfNeeded(); 367 }; 368 369 let contentTypeDataGridNode = addDataGridNodeForHeader(WI.unlocalizedString("Content-Type"), valueData.mimeType || placeholderData.mimeType, {selectable: false, editable: false, classNames: ["header-content-type"]}); 272 370 273 371 let headersRow = table.appendChild(document.createElement("tr")); … … 277 375 headersLabel.textContent = WI.UIString("Headers"); 278 376 headersData.appendChild(this._headersDataGrid.element); 279 this._headersDataGrid.updateLayoutIfNeeded();280 377 281 378 let addHeaderButton = headersData.appendChild(document.createElement("button")); … … 288 385 }); 289 386 this._headersDataGrid.appendChild(newNode); 290 t his._headersDataGrid.updateLayoutIfNeeded();387 toggleHeadersDataGridVisibility(false); 291 388 this.update(); 292 389 this._headersDataGrid.startEditingNode(newNode); 293 390 }); 294 391 392 let optionsRowElement = null; 295 393 if (WI.NetworkManager.supportsOverridingRequestsWithResponses()) { 296 let optionsRow= table.appendChild(document.createElement("tr"));297 optionsRow .className = "options";298 299 let optionsHeader = optionsRow .appendChild(document.createElement("th"));394 optionsRowElement = table.appendChild(document.createElement("tr")); 395 optionsRowElement.className = "options"; 396 397 let optionsHeader = optionsRowElement.appendChild(document.createElement("th")); 300 398 301 399 let optionsLabel = optionsHeader.appendChild(document.createElement("label")); 302 400 optionsLabel.textContent = WI.UIString("Options"); 303 401 304 let optionsData = optionsRow .appendChild(document.createElement("td"));402 let optionsData = optionsRowElement.appendChild(document.createElement("td")); 305 403 306 404 let skipNetworkLabel = optionsData.appendChild(document.createElement("label")); … … 312 410 313 411 skipNetworkLabel.appendChild(document.createTextNode(WI.UIString("Skip Network", "Skip Network @ Local Override Popover Options", "Label for checkbox that controls whether the local override will actually perform a network request or skip it to immediately serve the response."))); 314 315 optionsData.appendChild(WI.createReferencePageLink("local-overrides", "configuring-local-overrides")); 316 } else 317 headersData.appendChild(WI.createReferencePageLink("local-overrides", "configuring-local-overrides")); 412 } 413 414 popoverContentElement.appendChild(WI.createReferencePageLink(WI.ReferencePage.LocalOverrides, "configuring-local-overrides")); 318 415 319 416 let incrementStatusCode = () => { … … 404 501 updateURLCodeMirrorMode(); 405 502 503 let toggleInputsForType = (initializeHeaders) => { 504 let isRequest = this._typeSelectElement.value === WI.LocalResourceOverride.InterceptType.Request; 505 popoverContentElement.classList.toggle("request", isRequest); 506 popoverContentElement.classList.toggle("response", !isRequest); 507 508 if (initializeHeaders) { 509 let headers = isRequest ? requestHeaders : responseHeaders; 510 for (let name in headers) { 511 if (!isRequest) { 512 if (name.toLowerCase() === "content-type") 513 continue; 514 if (name.toLowerCase() === "set-cookie") 515 continue; 516 } 517 addDataGridNodeForHeader(name, headers[name]); 518 } 519 } 520 521 if (requestURLRow) 522 requestURLRow.element.hidden = !isRequest; 523 if (methodRowElement) 524 methodRowElement.hidden = !isRequest; 525 526 mimeTypeRow.element.hidden = isRequest; 527 statusCodeRow.element.hidden = isRequest; 528 if (optionsRowElement) 529 optionsRowElement.hidden = isRequest; 530 531 if (isRequest) { 532 this._requestURLCodeMirror.refresh(); 533 534 if (contentTypeDataGridNode.parent) 535 this._headersDataGrid.removeChild(contentTypeDataGridNode); 536 } else { 537 this._mimeTypeCodeMirror.refresh(); 538 this._statusCodeCodeMirror.refresh(); 539 this._statusTextCodeMirror.refresh(); 540 541 if (!contentTypeDataGridNode.parent) 542 this._headersDataGrid.insertChild(contentTypeDataGridNode, 0); 543 } 544 toggleHeadersDataGridVisibility(); 545 }; 546 toggleInputsForType(true); 547 548 this._originalRequestURL = localResource?.url ?? null; 406 549 this._serializedDataWhenShown = this.serializedData; 407 550 … … 412 555 setTimeout(() => { 413 556 this._urlCodeMirror.refresh(); 557 this._requestURLCodeMirror?.refresh(); 414 558 this._mimeTypeCodeMirror.refresh(); 415 559 this._statusCodeCodeMirror.refresh(); -
trunk/Source/WebInspectorUI/UserInterface/Views/LocalResourceOverrideRequestContentView.css
r270601 r270604 24 24 */ 25 25 26 WI.ReferencePage = { 27 DOMBreakpoints: "dom-breakpoints", 28 EventBreakpoints: "event-breakpoints", 29 JavaScriptBreakpoints: "javascript-breakpoints", 30 URLBreakpoints: "url-breakpoints", 31 }; 26 .content-view.text.local-resource-override-request { 27 display: flex; 28 flex-direction: column; 29 } 30 31 .content-view.text.local-resource-override-request > .text-editor { 32 position: relative; 33 width: 100%; 34 height: 100%; 35 } 36 37 .content-view.text.local-resource-override-request > .message-text-view { 38 top: var(--navigation-bar-height); 39 } -
trunk/Source/WebInspectorUI/UserInterface/Views/LocalResourceOverrideTreeElement.js
r267723 r270604 26 26 WI.LocalResourceOverrideTreeElement = class LocalResourceOverrideTreeElement extends WI.ResourceTreeElement 27 27 { 28 constructor(localResource , representedObject, options)28 constructor(localResourceOverride, options) 29 29 { 30 console.assert(localResource instanceof WI.LocalResource); 31 console.assert(localResource.isLocalResourceOverride); 32 console.assert(representedObject instanceof WI.LocalResourceOverride); 30 console.assert(localResourceOverride instanceof WI.LocalResourceOverride, localResourceOverride); 33 31 34 super(localResource , representedObject, options);32 super(localResourceOverride.localResource, localResourceOverride, options); 35 33 36 this._localResourceOverride = representedObject;34 this._localResourceOverride = localResourceOverride; 37 35 38 36 this._popover = null; … … 43 41 get mainTitleText() 44 42 { 45 let text; 46 if (this.representedObject.isRegex) { 47 text = "/" + this.resource.url + "/"; 48 if (!this.representedObject.isCaseSensitive) 49 text += "i"; 50 } else { 51 text = super.mainTitleText; 52 if (!this.representedObject.isCaseSensitive) 53 text = WI.UIString("%s (Case Insensitive)").format(text); 54 } 55 return text; 43 return this.representedObject.displayName; 56 44 } 57 45 … … 132 120 return; 133 121 134 let {type, url, isCaseSensitive, isRegex, mimeType, statusCode, statusText, headers} = serializedData;135 136 122 // Do not conflict with an existing override unless we are modifying ourselves. 137 let existingOverride = WI.networkManager.localResourceOverrideForURL(url); 138 if (existingOverride && existingOverride !== this._localResourceOverride) { 123 if (WI.networkManager.localResourceOverrides.some((existingOverride) => existingOverride !== this._localResourceOverride && existingOverride.equals(this._localResourceOverride))) { 139 124 InspectorFrontendHost.beep(); 140 125 return; … … 143 128 let wasSelected = this.selected; 144 129 145 let revision = this._localResourceOverride.localResource.currentRevision; 146 let newLocalResourceOverride = WI.LocalResourceOverride.create(type, { 147 url, 148 isCaseSensitive, 149 isRegex, 150 mimeType, 151 statusCode, 152 statusText, 153 headers, 154 content: revision.content, 155 base64Encoded: revision.base64Encoded, 156 }); 130 if (serializedData.type !== WI.LocalResourceOverride.InterceptType.Request) { 131 let revision = this._localResourceOverride.localResource.currentRevision; 132 serializedData.responseContent = revision.content; 133 serializedData.responseBase64Encoded = revision.base64Encoded; 134 } 157 135 136 let newLocalResourceOverride = WI.LocalResourceOverride.create(serializedData.url, serializedData.type, serializedData); 158 137 WI.networkManager.removeLocalResourceOverride(this._localResourceOverride); 159 138 WI.networkManager.addLocalResourceOverride(newLocalResourceOverride); -
trunk/Source/WebInspectorUI/UserInterface/Views/LocalResourceOverrideWarningView.js
r269359 r270604 28 28 constructor(resource) 29 29 { 30 console.assert(!resource.isLocalResourceOverride); 30 console.assert(resource instanceof WI.Resource, resource); 31 console.assert(!resource.localResourceOverride, resource); 31 32 32 33 super(); … … 64 65 const cookie = null; 65 66 const options = {ignoreNetworkTab: true, ignoreSearchTab: true}; 66 let overrideResource = WI.networkManager.localResourceOverrideForURL(this._resource.url);67 WI.showRepresentedObject( overrideResource, cookie, options);67 let localResourceOverride = WI.networkManager.localResourceOverridesForURL(this._resource.url)[0]; 68 WI.showRepresentedObject(localResourceOverride, cookie, options); 68 69 }); 69 70 … … 81 82 return; 82 83 83 let hasLocalResourceOverride = !!WI.networkManager.localResourceOverrideForURL(this._resource.url); 84 this._revealButton.hidden = !hasLocalResourceOverride; 84 this._revealButton.hidden = !WI.networkManager.localResourceOverridesForURL(this._resource.url).length; 85 85 86 86 let resourceShowingOverrideContent = this._resource.responseSource === WI.Resource.ResponseSource.InspectorOverride; … … 90 90 _handleLocalResourceOverrideAddedOrRemoved(event) 91 91 { 92 if (this._resource.url !== event.data.localResourceOverride.url) 92 let {localResourceOverride} = event.data; 93 if (!localResourceOverride.matches(this._resource.url)) 93 94 return; 94 95 -
trunk/Source/WebInspectorUI/UserInterface/Views/NavigationSidebarPanel.js
r270134 r270604 502 502 // Local Overrides are never stale resources. 503 503 let resource = treeElement.resource; 504 if (resource. isLocalResourceOverride)504 if (resource.localResourceOverride) 505 505 continue; 506 506 -
trunk/Source/WebInspectorUI/UserInterface/Views/OpenResourceDialog.js
r267723 r270604 125 125 treeElement.mainTitle = createHighlightedTitleFragment(resource.displayName, result.matchingTextRanges); 126 126 127 if (resource instanceof WI.LocalResource && resource. isLocalResourceOverride)127 if (resource instanceof WI.LocalResource && resource.localResourceOverride) 128 128 treeElement.subtitle = WI.UIString("Local Override"); 129 129 -
trunk/Source/WebInspectorUI/UserInterface/Views/ResourceContentView.js
r269359 r270604 59 59 } 60 60 61 this._showingLocalResourceOverride = false;62 63 61 if (WI.NetworkManager.supportsOverridingResponses()) { 64 if (resource.isLocalResourceOverride) { 65 this._showingLocalResourceOverride = true; 66 67 this._localResourceOverrideBannerView = new WI.LocalResourceOverrideLabelView(resource); 62 if (resource.localResourceOverride) { 63 this._localResourceOverrideBannerView = new WI.LocalResourceOverrideLabelView(resource.localResourceOverride); 68 64 69 65 this._importLocalResourceOverrideButtonNavigationItem = new WI.ButtonNavigationItem("import-local-resource-override", WI.UIString("Import"), "Images/Import.svg", 15, 15); … … 79 75 80 76 this._createLocalResourceOverrideButtonNavigationItem = new WI.ButtonNavigationItem("create-local-resource-override", this.createLocalResourceOverrideTooltip, "Images/NavigationItemNetworkOverride.svg", 13, 14); 81 this._createLocalResourceOverrideButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleCreateLocalResourceOverride, this);82 77 this._createLocalResourceOverrideButtonNavigationItem.enabled = false; // Enabled when the content is available. 83 78 this._createLocalResourceOverrideButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low; 79 if (WI.NetworkManager.supportsOverridingRequests()) 80 WI.addMouseDownContextMenuHandlers(this._createLocalResourceOverrideButtonNavigationItem.element, this._populateCreateLocalResourceOverrideContextMenu.bind(this)); 81 else 82 this._createLocalResourceOverrideButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleCreateLocalResourceOverride, this); 84 83 } 85 84 … … 92 91 93 92 get resource() { return this._resource; } 94 get showingLocalResourceOverride() { return this._showingLocalResourceOverride; }95 93 96 94 get navigationItems() … … 139 137 } 140 138 141 requestLocalResourceOverrideInitialContent( callback)139 requestLocalResourceOverrideInitialContent() 142 140 { 143 141 // Overridden by subclasses if needed. 144 142 145 WI.FileUtilities.import(async (fileList) => { 146 console.assert(fileList.length === 1); 147 148 this._getContentForLocalResourceOverrideFromFile(fileList[0], ({mimeType, base64Encoded, content}) => { 149 callback({mimeType, base64Encoded, content}); 143 return new Promise((resolve, reject) => { 144 WI.FileUtilities.import(async (fileList) => { 145 console.assert(fileList.length === 1); 146 147 this._getContentForLocalResourceOverrideFromFile(fileList[0], ({mimeType, base64Encoded, content}) => { 148 resolve({mimeType, base64Encoded, content}); 149 }); 150 150 }); 151 151 }); … … 296 296 } 297 297 298 async _createAndShowLocalResourceOverride(type, {requestInitialContent} = {}) 299 { 300 let initialContent = requestInitialContent ? await this.requestLocalResourceOverrideInitialContent() : {}; 301 let localResourceOverride = await this._resource.createLocalResourceOverride(type, initialContent); 302 WI.networkManager.addLocalResourceOverride(localResourceOverride); 303 WI.showLocalResourceOverride(localResourceOverride); 304 } 305 306 _populateCreateLocalResourceOverrideContextMenu(contextMenu, event) 307 { 308 contextMenu.appendItem(WI.UIString("Create Request Local Override"), () => { 309 // Request overrides cannot be created from a file as files don't have network info. 310 this._createAndShowLocalResourceOverride(WI.LocalResourceOverride.InterceptType.Request); 311 }); 312 313 contextMenu.appendItem(WI.UIString("Create Response Local Override"), () => { 314 this._createAndShowLocalResourceOverride(WI.LocalResourceOverride.InterceptType.Response, { 315 requestInitialContent: !event.shiftKey, 316 }); 317 }); 318 } 319 298 320 _handleCreateLocalResourceOverride(event) 299 321 { 300 322 let {nativeEvent} = event.data; 301 323 302 let createLocalResourceOverride = async (initialContent) => { 303 let localResourceOverride = await this._resource.createLocalResourceOverride(initialContent); 304 WI.networkManager.addLocalResourceOverride(localResourceOverride); 305 WI.showLocalResourceOverride(localResourceOverride); 306 }; 307 308 if (nativeEvent.shiftKey) 309 createLocalResourceOverride({}); 310 else 311 this.requestLocalResourceOverrideInitialContent(createLocalResourceOverride); 324 this._createAndShowLocalResourceOverride(WI.LocalResourceOverride.InterceptType.Response, { 325 requestInitialContent: !nativeEvent.shiftKey, 326 }); 312 327 } 313 328 314 329 _handleImportLocalResourceOverride(event) 315 330 { 316 console.assert(this._showingLocalResourceOverride); 331 let localResourceOverride = this.resource.localResourceOverride || WI.networkManager.localResourceOverridesForURL(this.resource.url)[0]; 332 console.assert(localResourceOverride); 317 333 318 334 WI.FileUtilities.import(async (fileList) => { 319 335 console.assert(fileList.length === 1); 320 321 let localResourceOverride = WI.networkManager.localResourceOverrideForURL(this.resource.url);322 console.assert(localResourceOverride);323 336 324 337 await this._getContentForLocalResourceOverrideFromFile(fileList[0], ({mimeType, base64Encoded, content}) => { … … 327 340 }); 328 341 329 if (!this. showingLocalResourceOverride)342 if (!this._resource.localResourceOverride) 330 343 WI.showLocalResourceOverride(localResourceOverride); 331 344 }); … … 334 347 _handleRemoveLocalResourceOverride(event) 335 348 { 336 console.assert(this._showingLocalResourceOverride); 337 338 let localResourceOverride = WI.networkManager.localResourceOverrideForURL(this._resource.url); 349 let localResourceOverride = this.resource.localResourceOverride || WI.networkManager.localResourceOverridesForURL(this._resource.url)[0]; 350 console.assert(localResourceOverride); 339 351 WI.networkManager.removeLocalResourceOverride(localResourceOverride); 340 352 } … … 342 354 _handleLocalResourceOverrideChanged(event) 343 355 { 344 if (this._resource.url !== event.data.localResourceOverride.url) 356 let {localResourceOverride} = event.data; 357 if (!localResourceOverride.matches(this._resource.url)) 345 358 return; 346 359 -
trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTreeElement.js
r267411 r270604 164 164 get mainTitleText() 165 165 { 166 // Overridden by subclasses if needed. 166 167 return WI.displayNameForURL(this._resource.url, this._resource.urlComponents, { 167 168 allowDirectoryAsName: this._allowDirectoryAsName, … … 190 191 191 192 if (!this._hideOrigin) { 192 if (this._resource.isLocalResourceOverride) { 193 // Show the host for a local resource override if it is different from the main frame. 194 let localResourceOverrideHost = urlComponents.host; 195 let mainFrameHost = (WI.networkManager.mainFrame && WI.networkManager.mainFrame.mainResource) ? WI.networkManager.mainFrame.mainResource.urlComponents.host : null; 196 let subtitle = localResourceOverrideHost !== mainFrameHost ? localResourceOverrideHost : null; 197 this.subtitle = this.mainTitle !== subtitle ? subtitle : null; 193 if (this._resource.localResourceOverride) { 194 if (WI.NetworkManager.supportsOverridingRequests()) 195 this.subtitle = WI.LocalResourceOverride.displayNameForType(this._resource.localResourceOverride.type); 196 else { 197 // Show the host for a local resource override if it is different from the main frame. 198 let localResourceOverrideHost = urlComponents.host; 199 let mainFrameHost = (WI.networkManager.mainFrame && WI.networkManager.mainFrame.mainResource) ? WI.networkManager.mainFrame.mainResource.urlComponents.host : null; 200 let subtitle = localResourceOverrideHost !== mainFrameHost ? localResourceOverrideHost : null; 201 this.subtitle = this.mainTitle !== subtitle ? subtitle : null; 202 } 198 203 } else { 199 204 // Show the host as the subtitle if it is different from the main resource or if this is the main frame's main resource. … … 256 261 _updateIcon() 257 262 { 258 let isOverride = this._resource.isLocalResourceOverride;263 let isOverride = !!this._resource.localResourceOverride; 259 264 let wasOverridden = this._resource.responseSource === WI.Resource.ResponseSource.InspectorOverride; 260 261 265 if (isOverride || wasOverridden) 262 266 this.addClassName("override"); -
trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js
r270134 r270604 1215 1215 { 1216 1216 if (this._sourceCode instanceof WI.Resource) { 1217 if (this._sourceCode. isLocalResourceOverride)1217 if (this._sourceCode.localResourceOverride) 1218 1218 return false; 1219 1219 return this._sourceCode.type === WI.Resource.Type.Document || this._sourceCode.type === WI.Resource.Type.Script; -
trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js
r269754 r270604 542 542 543 543 if (representedObject instanceof WI.LocalResource) { 544 let localResourceOverride = WI.networkManager.localResourceOverrideForURL(representedObject.url);544 let localResourceOverride = representedObject.localResourceOverride || WI.networkManager.localResourceOverridesForURL(representedObject.url)[0]; 545 545 return this._localOverridesTreeOutline.findTreeElement(localResourceOverride); 546 546 } … … 852 852 } 853 853 854 let {type, url, isCaseSensitive, isRegex, mimeType, statusCode, statusText, headers} = serializedData;855 856 854 // Do not conflict with an existing override. 857 let existingOverride = WI.networkManager.localResourceOverrideForURL(url); 858 if (existingOverride) { 855 if (WI.networkManager.localResourceOverrides.some((existingOverride) => existingOverride.equals(serializedData))) { 859 856 InspectorFrontendHost.beep(); 860 857 return; 861 858 } 862 859 863 let localResourceOverride = WI.LocalResourceOverride.create(type, { 864 url, 865 isCaseSensitive, 866 isRegex, 867 mimeType, 868 statusCode, 869 statusText, 870 headers, 871 content: "", 872 base64Encoded: false, 873 }); 874 860 let localResourceOverride = WI.LocalResourceOverride.create(serializedData.url, serializedData.type, serializedData); 875 861 WI.networkManager.addLocalResourceOverride(localResourceOverride); 876 862 WI.showLocalResourceOverride(localResourceOverride); … … 956 942 { 957 943 // Local Resource Override content views do not need to be closed across page navigations. 958 if (contentView.representedObject instanceof WI.LocalResource && contentView.representedObject. isLocalResourceOverride)944 if (contentView.representedObject instanceof WI.LocalResource && contentView.representedObject.localResourceOverride) 959 945 return false; 960 946 … … 1489 1475 localOverrideTreeElement = new WI.BootstrapScriptTreeElement(localOverride); 1490 1476 else if (localOverride instanceof WI.LocalResourceOverride) 1491 localOverrideTreeElement = new WI.LocalResourceOverrideTreeElement(localOverride .localResource, localOverride);1477 localOverrideTreeElement = new WI.LocalResourceOverrideTreeElement(localOverride); 1492 1478 console.assert(localOverrideTreeElement); 1493 1479 … … 1939 1925 1940 1926 if (treeElement instanceof WI.LocalResourceOverrideTreeElement) { 1941 WI.showRepresentedObject(treeElement.representedObject .localResource);1927 WI.showRepresentedObject(treeElement.representedObject); 1942 1928 return; 1943 1929 } -
trunk/Source/WebInspectorUI/UserInterface/Views/TextResourceContentView.js
r270134 r270604 79 79 items.push(this._prettyPrintButtonNavigationItem); 80 80 81 if (!this. showingLocalResourceOverride)81 if (!this.resource.localResourceOverride) 82 82 items.push(this._showTypesButtonNavigationItem, this._codeCoverageButtonNavigationItem); 83 83 … … 136 136 } 137 137 138 requestLocalResourceOverrideInitialContent( callback)139 { 140 callback({138 requestLocalResourceOverrideInitialContent() 139 { 140 return Promise.resolve({ 141 141 mimeType: this.resource.mimeType, 142 142 base64Encoded: this.resource.base64Encoded, … … 327 327 return true; 328 328 329 if (this. showingLocalResourceOverride)329 if (this.resource.localResourceOverride) 330 330 return true; 331 331
Note: See TracChangeset
for help on using the changeset viewer.