Changeset 225546 in webkit
- Timestamp:
- Dec 5, 2017 2:09:36 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r225537 r225546 1 2017-12-05 Joseph Pecoraro <pecoraro@apple.com> 2 3 Web Inspector: content views for resources loaded through XHR do not reflect declared mime-type 4 https://bugs.webkit.org/show_bug.cgi?id=141389 5 <rdar://problem/19767070> 6 7 Reviewed by Brian Burg. 8 9 * http/tests/inspector/network/fetch-response-body-expected.txt: 10 * http/tests/inspector/network/fetch-response-body.html: 11 * http/tests/inspector/network/xhr-response-body-expected.txt: 12 * http/tests/inspector/network/xhr-response-body.html: 13 Update tests for new expectations now that binary data shows as binary. 14 1 15 2017-12-05 Youenn Fablet <youenn@apple.com> 2 16 -
trunk/LayoutTests/http/tests/inspector/network/fetch-response-body-expected.txt
r209629 r225546 6 6 PASS: Resource should be Fetch type. 7 7 PASS: MIMEType should be 'text/plain'. 8 PASS: Content should not be base64Encoded. 8 9 PASS: Text content should match data.txt. 9 10 … … 11 12 PASS: Resource should be Fetch type. 12 13 PASS: MIMEType should be 'text/html'. 14 PASS: Content should not be base64Encoded. 13 15 PASS: Text content should match data.html. 14 16 … … 16 18 PASS: Resource should be Fetch type. 17 19 PASS: MIMEType should be 'application/octet-stream'. 20 PASS: Content should be base64Encoded. 18 21 PASS: JSON content should match data.json. 19 22 … … 21 24 PASS: Resource should be Fetch type. 22 25 PASS: MIMEType should be 'application/json'. 26 PASS: Content should not be base64Encoded. 23 27 PASS: JSON content should match specified content. 24 28 … … 26 30 PASS: Resource should be Fetch type. 27 31 PASS: MIMEType should be 'application/vnd.api+json'. 32 PASS: Content should not be base64Encoded. 28 33 PASS: JSON content should match specified content. 29 34 … … 31 36 PASS: Resource should be Fetch type. 32 37 PASS: MIMEType should be 'image/svg+xml'. 38 PASS: Content should not be base64Encoded. 33 39 PASS: SVG content should be text. 34 40 … … 36 42 PASS: Resource should be Fetch type. 37 43 PASS: MIMEType should be 'image/png'. 38 PASS: Image content should be text. 44 PASS: Content should be base64Encoded. 45 PASS: Image content should be a Blob. 39 46 -
trunk/LayoutTests/http/tests/inspector/network/fetch-response-body.html
r220119 r225546 37 37 let suite = InspectorTest.createAsyncSuite("Network.getResponseBody.Fetch"); 38 38 39 function contentAsText(content) { 40 return new Promise((resolve) => { 41 if (typeof content === "string") { 42 resolve(content) 43 return; 44 } 45 blobAsText(content, (text) => { 46 resolve(text); 47 }); 48 }); 49 } 50 39 51 function addTestCase({name, description, expression, contentHandler}) { 40 52 suite.addTestCase({ … … 58 70 description: "Get text/plain content as text.", 59 71 expression: "createFetchForText()", 60 contentHandler({error, sourceCode, content }) {72 contentHandler({error, sourceCode, content, rawBase64Encoded}) { 61 73 InspectorTest.expectEqual(sourceCode.mimeType, "text/plain", "MIMEType should be 'text/plain'."); 74 InspectorTest.expectEqual(rawBase64Encoded, false, "Content should not be base64Encoded."); 62 75 InspectorTest.expectEqual(content, "Plain text resource.\n", "Text content should match data.txt."); 63 76 } … … 68 81 description: "Get text/html content as text.", 69 82 expression: "createFetchForHTML()", 70 contentHandler({error, sourceCode, content }) {83 contentHandler({error, sourceCode, content, rawBase64Encoded}) { 71 84 InspectorTest.expectEqual(sourceCode.mimeType, "text/html", "MIMEType should be 'text/html'."); 85 InspectorTest.expectEqual(rawBase64Encoded, false, "Content should not be base64Encoded."); 72 86 InspectorTest.expectEqual(content, "<span>Hello World</span>\n", "Text content should match data.html."); 73 87 } … … 76 90 addTestCase({ 77 91 name: "Network.getResponseBody.Fetch.JSON", 78 description: "Get application/octet-stream content as text.",92 description: "Get application/octet-stream content as base64Encoded text.", 79 93 expression: "createFetchForJSON()", 80 contentHandler({error, sourceCode, content }) {94 contentHandler({error, sourceCode, content, rawBase64Encoded}) { 81 95 InspectorTest.expectEqual(sourceCode.mimeType, "application/octet-stream", "MIMEType should be 'application/octet-stream'."); 82 InspectorTest.expectEqual(content, `{"json": true, "value": 42}\n`, "JSON content should match data.json."); 96 InspectorTest.expectEqual(rawBase64Encoded, true, "Content should be base64Encoded."); 97 return contentAsText(content).then((text) => { 98 InspectorTest.expectEqual(text, `{"json": true, "value": 42}\n`, "JSON content should match data.json."); 99 }); 83 100 } 84 101 }); … … 88 105 description: "Get application/json content as text.", 89 106 expression: "createFetchForJSON2()", 90 contentHandler({error, sourceCode, content }) {107 contentHandler({error, sourceCode, content, rawBase64Encoded}) { 91 108 InspectorTest.expectEqual(sourceCode.mimeType, "application/json", "MIMEType should be 'application/json'."); 109 InspectorTest.expectEqual(rawBase64Encoded, false, "Content should not be base64Encoded."); 92 110 InspectorTest.expectEqual(content, `{"json":true,"value":42}`, "JSON content should match specified content."); 93 111 } … … 98 116 description: "Get arbitrary +json content as text.", 99 117 expression: "createFetchForJSON3()", 100 contentHandler({error, sourceCode, content }) {118 contentHandler({error, sourceCode, content, rawBase64Encoded}) { 101 119 InspectorTest.expectEqual(sourceCode.mimeType, "application/vnd.api+json", "MIMEType should be 'application/vnd.api+json'."); 120 InspectorTest.expectEqual(rawBase64Encoded, false, "Content should not be base64Encoded."); 102 121 InspectorTest.expectEqual(content, `{"json":true,"value":999}`, "JSON content should match specified content."); 103 122 } … … 108 127 description: "Get image/svg+xml content as text.", 109 128 expression: "createFetchForSVG()", 110 contentHandler({error, sourceCode, content }) {129 contentHandler({error, sourceCode, content, rawBase64Encoded}) { 111 130 InspectorTest.expectEqual(sourceCode.mimeType, "image/svg+xml", "MIMEType should be 'image/svg+xml'."); 131 InspectorTest.expectEqual(rawBase64Encoded, false, "Content should not be base64Encoded."); 112 132 InspectorTest.expectEqual(content, 113 133 `<?xml version="1.0" encoding="UTF-8"?> … … 123 143 description: "Get image/png content.", 124 144 expression: "createFetchForPNG()", 125 contentHandler({error, sourceCode, content}) { 126 // FIXME: <https://webkit.org/b/165495> Web Inspector: XHR / Fetch for non-text content should not show garbled text 145 contentHandler({error, sourceCode, content, rawBase64Encoded}) { 127 146 InspectorTest.expectEqual(sourceCode.mimeType, "image/png", "MIMEType should be 'image/png'."); 128 InspectorTest.expectEqual(typeof content, "string", "Image content should be text."); 147 InspectorTest.expectEqual(rawBase64Encoded, true, "Content should be base64Encoded."); 148 InspectorTest.expectThat(content instanceof Blob, "Image content should be a Blob."); 129 149 } 130 150 }); -
trunk/LayoutTests/http/tests/inspector/network/xhr-response-body-expected.txt
r209629 r225546 6 6 PASS: Resource should be XHR type. 7 7 PASS: MIMEType should be 'text/plain'. 8 PASS: Content should not be base64Encoded. 8 9 PASS: Text content should match data.txt. 9 10 … … 11 12 PASS: Resource should be XHR type. 12 13 PASS: MIMEType should be 'text/html'. 14 PASS: Content should not be base64Encoded. 13 15 PASS: Text content should match data.html. 14 16 … … 16 18 PASS: Resource should be XHR type. 17 19 PASS: MIMEType should be 'application/octet-stream'. 20 PASS: Content should be base64Encoded. 18 21 PASS: JSON content should match data.json. 19 22 … … 21 24 PASS: Resource should be XHR type. 22 25 PASS: MIMEType should be 'application/json'. 26 PASS: Content should not be base64Encoded. 23 27 PASS: JSON content should match specified content. 24 28 … … 26 30 PASS: Resource should be XHR type. 27 31 PASS: MIMEType should be 'application/vnd.api+json'. 32 PASS: Content should not be base64Encoded. 28 33 PASS: JSON content should match specified content. 29 34 … … 31 36 PASS: Resource should be XHR type. 32 37 PASS: MIMEType should be 'image/svg+xml'. 38 PASS: Content should not be base64Encoded. 33 39 PASS: SVG content should be text. 34 40 … … 36 42 PASS: Resource should be XHR type. 37 43 PASS: MIMEType should be 'image/png'. 38 PASS: Image content should be text. 44 PASS: Content should be base64Encoded. 45 PASS: Image content should be a Blob. 39 46 -
trunk/LayoutTests/http/tests/inspector/network/xhr-response-body.html
r220119 r225546 43 43 let suite = InspectorTest.createAsyncSuite("Network.getResponseBody.XHR"); 44 44 45 function contentAsText(content) { 46 return new Promise((resolve) => { 47 if (typeof content === "string") { 48 resolve(content) 49 return; 50 } 51 blobAsText(content, (text) => { 52 resolve(text); 53 }); 54 }); 55 } 56 45 57 function addTestCase({name, description, expression, contentHandler}) { 46 58 suite.addTestCase({ … … 64 76 description: "Get text/plain content as text.", 65 77 expression: "createXHRForText()", 66 contentHandler({error, sourceCode, content }) {78 contentHandler({error, sourceCode, content, rawBase64Encoded}) { 67 79 InspectorTest.expectEqual(sourceCode.mimeType, "text/plain", "MIMEType should be 'text/plain'."); 80 InspectorTest.expectEqual(rawBase64Encoded, false, "Content should not be base64Encoded."); 68 81 InspectorTest.expectEqual(content, "Plain text resource.\n", "Text content should match data.txt."); 69 82 } … … 74 87 description: "Get text/html content as text.", 75 88 expression: "createXHRForHTML()", 76 contentHandler({error, sourceCode, content }) {89 contentHandler({error, sourceCode, content, rawBase64Encoded}) { 77 90 InspectorTest.expectEqual(sourceCode.mimeType, "text/html", "MIMEType should be 'text/html'."); 91 InspectorTest.expectEqual(rawBase64Encoded, false, "Content should not be base64Encoded."); 78 92 InspectorTest.expectEqual(content, "<span>Hello World</span>\n", "Text content should match data.html."); 79 93 } … … 82 96 addTestCase({ 83 97 name: "Network.getResponseBody.XHR.JSON", 84 description: "Get application/octet-stream content as text.",98 description: "Get application/octet-stream content as base64Encoded text.", 85 99 expression: "createXHRForJSON()", 86 contentHandler({error, sourceCode, content }) {100 contentHandler({error, sourceCode, content, rawBase64Encoded}) { 87 101 InspectorTest.expectEqual(sourceCode.mimeType, "application/octet-stream", "MIMEType should be 'application/octet-stream'."); 88 InspectorTest.expectEqual(content, `{"json": true, "value": 42}\n`, "JSON content should match data.json."); 102 InspectorTest.expectEqual(rawBase64Encoded, true, "Content should be base64Encoded."); 103 return contentAsText(content).then((text) => { 104 InspectorTest.expectEqual(text, `{"json": true, "value": 42}\n`, "JSON content should match data.json."); 105 }); 89 106 } 90 107 }); … … 94 111 description: "Get application/json content as text.", 95 112 expression: "createXHRForJSON2()", 96 contentHandler({error, sourceCode, content }) {113 contentHandler({error, sourceCode, content, rawBase64Encoded}) { 97 114 InspectorTest.expectEqual(sourceCode.mimeType, "application/json", "MIMEType should be 'application/json'."); 115 InspectorTest.expectEqual(rawBase64Encoded, false, "Content should not be base64Encoded."); 98 116 InspectorTest.expectEqual(content, `{"json":true,"value":42}`, "JSON content should match specified content."); 99 117 } … … 104 122 description: "Get arbitrary +json content as text.", 105 123 expression: "createXHRForJSON3()", 106 contentHandler({error, sourceCode, content }) {124 contentHandler({error, sourceCode, content, rawBase64Encoded}) { 107 125 InspectorTest.expectEqual(sourceCode.mimeType, "application/vnd.api+json", "MIMEType should be 'application/vnd.api+json'."); 126 InspectorTest.expectEqual(rawBase64Encoded, false, "Content should not be base64Encoded."); 108 127 InspectorTest.expectEqual(content, `{"json":true,"value":999}`, "JSON content should match specified content."); 109 128 } … … 114 133 description: "Get image/svg+xml content as text.", 115 134 expression: "createXHRForSVG()", 116 contentHandler({error, sourceCode, content }) {135 contentHandler({error, sourceCode, content, rawBase64Encoded}) { 117 136 InspectorTest.expectEqual(sourceCode.mimeType, "image/svg+xml", "MIMEType should be 'image/svg+xml'."); 137 InspectorTest.expectEqual(rawBase64Encoded, false, "Content should not be base64Encoded."); 118 138 InspectorTest.expectEqual(content, 119 139 `<?xml version="1.0" encoding="UTF-8"?> … … 129 149 description: "Get image/png content.", 130 150 expression: "createXHRForPNG()", 131 contentHandler({error, sourceCode, content}) { 132 // FIXME: <https://webkit.org/b/165495> Web Inspector: XHR / Fetch for non-text content should not show garbled text 151 contentHandler({error, sourceCode, content, rawBase64Encoded}) { 133 152 InspectorTest.expectEqual(sourceCode.mimeType, "image/png", "MIMEType should be 'image/png'."); 134 InspectorTest.expectEqual(typeof content, "string", "Image content should be text."); 153 InspectorTest.expectEqual(rawBase64Encoded, true, "Content should be base64Encoded."); 154 InspectorTest.expectThat(content instanceof Blob, "Image content should be a Blob."); 135 155 } 136 156 }); -
trunk/Source/WebCore/ChangeLog
r225537 r225546 1 2017-12-05 Joseph Pecoraro <pecoraro@apple.com> 2 3 Web Inspector: content views for resources loaded through XHR do not reflect declared mime-type 4 https://bugs.webkit.org/show_bug.cgi?id=141389 5 <rdar://problem/19767070> 6 7 Reviewed by Brian Burg. 8 9 Updated: http/tests/inspector/network/xhr-response-body.html: 10 http/tests/inspector/network/fetch-response-body.html: 11 12 * xml/XMLHttpRequest.cpp: 13 (WebCore::XMLHttpRequest::didFinishLoading): 14 * inspector/InspectorInstrumentation.cpp: 15 (WebCore::InspectorInstrumentation::didFinishXHRLoadingImpl): Deleted. 16 * inspector/InspectorInstrumentation.h: 17 (WebCore::InspectorInstrumentation::didFinishXHRLoading): Deleted. 18 Remove special handling of XHR content that decoded output as text. 19 20 * inspector/NetworkResourcesData.h: 21 (WebCore::NetworkResourcesData::ResourceData::requestId const): 22 (WebCore::NetworkResourcesData::ResourceData::loaderId const): 23 (WebCore::NetworkResourcesData::ResourceData::frameId const): 24 (WebCore::NetworkResourcesData::ResourceData::url const): 25 (WebCore::NetworkResourcesData::ResourceData::content const): 26 (WebCore::NetworkResourcesData::ResourceData::isContentEvicted const): 27 (WebCore::NetworkResourcesData::ResourceData::textEncodingName const): 28 * inspector/NetworkResourcesData.cpp: 29 (WebCore::NetworkResourcesData::ResourceData::ResourceData): 30 (WebCore::NetworkResourcesData::ResourceData::decodeDataToContent): 31 (WebCore::NetworkResourcesData::responseReceived): 32 (WebCore::NetworkResourcesData::setResourceContent): 33 (WebCore::shouldBufferResourceData): 34 (WebCore::NetworkResourcesData::maybeAddResourceData): 35 (WebCore::NetworkResourcesData::maybeDecodeDataToContent): 36 37 Make NetworkResourcesData only create a text decoder for resources we 38 really think are text, and buffer resource data if it is text data 39 or if it is a resource that would otherwise not be buffered by WebCore 40 (such as XHRs with a DoNotBufferData policy). This ensures that the 41 Inspector will have data to show for resources that won't be cached. 42 43 * inspector/agents/InspectorPageAgent.cpp: 44 (WebCore::InspectorPageAgent::resourceContent): 45 (WebCore::InspectorPageAgent::sourceMapURLForResource): 46 (WebCore::InspectorPageAgent::searchInResource): 47 (WebCore::InspectorPageAgent::searchInResources): 48 (WebCore::hasTextContent): Deleted. 49 (WebCore::InspectorPageAgent::cachedResourceContent): Deleted. 50 (WebCore::InspectorPageAgent::createTextDecoder): Deleted. 51 (WebCore::textContentForCachedResource): Deleted. 52 * inspector/agents/InspectorPageAgent.h: 53 * inspector/agents/InspectorNetworkAgent.cpp: 54 (WebCore::InspectorNetworkAgent::didReceiveData): 55 (WebCore::InspectorNetworkAgent::willDestroyCachedResource): 56 (WebCore::InspectorNetworkAgent::getResponseBody): 57 (WebCore::InspectorNetworkAgent::shouldTreatAsText): 58 (WebCore::InspectorNetworkAgent::createTextDecoder): 59 (WebCore::InspectorNetworkAgent::textContentForCachedResource): 60 (WebCore::InspectorNetworkAgent::cachedResourceContent): 61 (WebCore::textContentForResourceData): 62 (WebCore::InspectorNetworkAgent::searchOtherRequests): 63 (WebCore::isErrorStatusCode): Deleted. 64 (WebCore::InspectorNetworkAgent::didFinishXHRLoading): Deleted. 65 * inspector/agents/InspectorNetworkAgent.h: 66 Move static PageAgent functions related to the generic data tuple 67 (content, base64Encoded) to NetworkAgent. Also generalize it to 68 not rely on the CachedResourceType, but instead rely on the MIME type. 69 This has a few changes in behavior: 70 71 - Images, may now be text if they have a text mime type (image/svg+xml). 72 - XHR / Fetch / Other may be sent as text if they have a text mime type. 73 - XHR / Fetch / Other are not assumed to be text, and may be sent as base64 encoded. 74 75 For this to be useful the frontend should also check the mime type and 76 display an appropriate ContentView. 77 1 78 2017-12-05 Youenn Fablet <youenn@apple.com> 2 79 -
trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp
r225488 r225546 618 618 } 619 619 620 void InspectorInstrumentation::didFinishXHRLoadingImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, std::optional<String> decodedText)621 {622 if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) {623 if (decodedText)624 networkAgent->didFinishXHRLoading(identifier, *decodedText);625 }626 }627 628 620 void InspectorInstrumentation::willLoadXHRSynchronouslyImpl(InstrumentingAgents& instrumentingAgents) 629 621 { -
trunk/Source/WebCore/inspector/InspectorInstrumentation.h
r225488 r225546 196 196 static void continueWithPolicyDownload(Frame&, unsigned long identifier, DocumentLoader&, const ResourceResponse&); 197 197 static void continueWithPolicyIgnore(Frame&, unsigned long identifier, DocumentLoader&, const ResourceResponse&); 198 static void didFinishXHRLoading(ScriptExecutionContext*, unsigned long identifier, std::optional<String> decodedText);199 198 static void willLoadXHRSynchronously(ScriptExecutionContext*); 200 199 static void didLoadXHRSynchronously(ScriptExecutionContext*); … … 367 366 static void didFinishLoadingImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, const NetworkLoadMetrics&, ResourceLoader*); 368 367 static void didFailLoadingImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, const ResourceError&); 369 static void didFinishXHRLoadingImpl(InstrumentingAgents&, unsigned long identifier, std::optional<String> decodedText);370 368 static void willLoadXHRSynchronouslyImpl(InstrumentingAgents&); 371 369 static void didLoadXHRSynchronouslyImpl(InstrumentingAgents&); … … 1012 1010 } 1013 1011 1014 inline void InspectorInstrumentation::didFinishXHRLoading(ScriptExecutionContext* context, unsigned long identifier, std::optional<String> decodedText)1015 {1016 FAST_RETURN_IF_NO_FRONTENDS(void());1017 if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context))1018 didFinishXHRLoadingImpl(*instrumentingAgents, identifier, decodedText);1019 }1020 1021 1012 inline void InspectorInstrumentation::willLoadXHRSynchronously(ScriptExecutionContext* context) 1022 1013 { -
trunk/Source/WebCore/inspector/NetworkResourcesData.cpp
r224596 r225546 1 1 /* 2 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * Copyright (C) 2017 Apple Inc. All rights reserved. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 31 32 32 33 #include "CachedResource.h" 34 #include "InspectorNetworkAgent.h" 33 35 #include "ResourceResponse.h" 34 36 #include "SharedBuffer.h" 35 37 #include "TextResourceDecoder.h" 38 #include <wtf/text/Base64.h> 36 39 37 40 namespace WebCore { … … 45 48 : m_requestId(requestId) 46 49 , m_loaderId(loaderId) 47 , m_base64Encoded(false)48 , m_isContentEvicted(false)49 , m_type(InspectorPageAgent::OtherResource)50 , m_cachedResource(nullptr)51 50 { 52 51 } … … 105 104 { 106 105 ASSERT(!hasContent()); 106 107 107 size_t dataLength = m_dataBuffer->size(); 108 m_content = m_decoder->decodeAndFlush(m_dataBuffer->data(), m_dataBuffer->size()); 108 109 if (m_decoder) { 110 m_base64Encoded = false; 111 m_content = m_decoder->decodeAndFlush(m_dataBuffer->data(), dataLength); 112 } else { 113 m_base64Encoded = true; 114 m_content = base64Encode(m_dataBuffer->data(), dataLength); 115 } 116 109 117 m_dataBuffer = nullptr; 110 return contentSizeInBytes(m_content) - dataLength; 118 119 size_t decodedLength = contentSizeInBytes(m_content); 120 ASSERT(decodedLength >= dataLength); 121 return decodedLength - dataLength; 111 122 } 112 123 … … 145 156 if (!resourceData) 146 157 return; 158 147 159 resourceData->setFrameId(frameId); 148 160 resourceData->setURL(response.url()); 149 resourceData->setDecoder(InspectorPageAgent::createTextDecoder(response.mimeType(), response.textEncodingName()));150 161 resourceData->setHTTPStatusCode(response.httpStatusCode()); 151 162 resourceData->setType(type); 163 164 if (InspectorNetworkAgent::shouldTreatAsText(response.mimeType())) 165 resourceData->setDecoder(InspectorNetworkAgent::createTextDecoder(response.mimeType(), response.textEncodingName())); 152 166 } 153 167 … … 173 187 if (!resourceData) 174 188 return; 189 175 190 size_t dataLength = contentSizeInBytes(content); 176 191 if (dataLength > m_maximumSingleResourceContentSize) … … 178 193 if (resourceData->isContentEvicted()) 179 194 return; 195 180 196 if (ensureFreeSpace(dataLength) && !resourceData->isContentEvicted()) { 181 197 // We can not be sure that we didn't try to save this request data while it was loading, so remove it, if any. … … 188 204 } 189 205 206 static bool shouldBufferResourceData(const NetworkResourcesData::ResourceData& resourceData) 207 { 208 if (resourceData.decoder()) 209 return true; 210 211 // Buffer data for Web Inspector when the rest of the system would not normally buffer. 212 if (resourceData.cachedResource() && resourceData.cachedResource()->dataBufferingPolicy() == DoNotBufferData) 213 return true; 214 215 return false; 216 } 217 190 218 void NetworkResourcesData::maybeAddResourceData(const String& requestId, const char* data, size_t dataLength) 191 219 { … … 193 221 if (!resourceData) 194 222 return; 195 if (!resourceData->decoder()) 196 return; 223 224 if (!shouldBufferResourceData(*resourceData)) 225 return; 226 197 227 if (resourceData->dataLength() + dataLength > m_maximumSingleResourceContentSize) 198 228 m_contentSize -= resourceData->evictContent(); 199 229 if (resourceData->isContentEvicted()) 200 230 return; 231 201 232 if (ensureFreeSpace(dataLength) && !resourceData->isContentEvicted()) { 202 233 m_requestIdsDeque.append(requestId); … … 211 242 if (!resourceData) 212 243 return; 244 213 245 if (!resourceData->hasData()) 214 246 return; 247 215 248 m_contentSize += resourceData->decodeDataToContent(); 216 249 size_t dataLength = contentSizeInBytes(resourceData->content()); -
trunk/Source/WebCore/inspector/NetworkResourcesData.h
r224596 r225546 1 1 /* 2 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * Copyright (C) 2017 Apple Inc. All rights reserved. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 30 31 31 32 #include "InspectorPageAgent.h" 32 #include "TextResourceDecoder.h"33 33 #include <wtf/Deque.h> 34 34 #include <wtf/HashMap.h> … … 39 39 class CachedResource; 40 40 class ResourceResponse; 41 class TextResourceDecoder; 41 42 class SharedBuffer; 42 43 … … 50 51 ResourceData(const String& requestId, const String& loaderId); 51 52 52 StringrequestId() const { return m_requestId; }53 StringloaderId() const { return m_loaderId; }53 const String& requestId() const { return m_requestId; } 54 const String& loaderId() const { return m_loaderId; } 54 55 55 StringframeId() const { return m_frameId; }56 const String& frameId() const { return m_frameId; } 56 57 void setFrameId(const String& frameId) { m_frameId = frameId; } 57 58 58 Stringurl() const { return m_url; }59 const String& url() const { return m_url; } 59 60 void setURL(const String& url) { m_url = url; } 60 61 61 62 bool hasContent() const { return !m_content.isNull(); } 62 Stringcontent() const { return m_content; }63 const String& content() const { return m_content; } 63 64 void setContent(const String&, bool base64Encoded); 64 65 … … 66 67 67 68 unsigned removeContent(); 69 unsigned evictContent(); 68 70 bool isContentEvicted() const { return m_isContentEvicted; } 69 unsigned evictContent();70 71 71 72 InspectorPageAgent::ResourceType type() const { return m_type; } … … 75 76 void setHTTPStatusCode(int httpStatusCode) { m_httpStatusCode = httpStatusCode; } 76 77 77 StringtextEncodingName() const { return m_textEncodingName; }78 const String& textEncodingName() const { return m_textEncodingName; } 78 79 void setTextEncodingName(const String& textEncodingName) { m_textEncodingName = textEncodingName; } 79 80 … … 98 99 String m_url; 99 100 String m_content; 100 bool m_base64Encoded;101 RefPtr<SharedBuffer> m_dataBuffer;102 bool m_isContentEvicted;103 InspectorPageAgent::ResourceType m_type;104 int m_httpStatusCode;105 106 101 String m_textEncodingName; 107 102 RefPtr<TextResourceDecoder> m_decoder; 108 103 RefPtr<SharedBuffer> m_dataBuffer; 109 104 RefPtr<SharedBuffer> m_buffer; 110 CachedResource* m_cachedResource; 105 CachedResource* m_cachedResource { nullptr }; 106 InspectorPageAgent::ResourceType m_type { InspectorPageAgent::OtherResource }; 107 int m_httpStatusCode { 0 }; 108 bool m_isContentEvicted { false }; 109 bool m_base64Encoded { false }; 111 110 }; 112 111 -
trunk/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
r225425 r225546 33 33 #include "InspectorNetworkAgent.h" 34 34 35 #include "CachedCSSStyleSheet.h" 35 36 #include "CachedRawResource.h" 36 37 #include "CachedResource.h" 37 38 #include "CachedResourceLoader.h" 38 39 #include "CachedResourceRequestInitiators.h" 40 #include "CachedScript.h" 39 41 #include "Document.h" 40 42 #include "DocumentLoader.h" … … 48 50 #include "JSMainThreadExecState.h" 49 51 #include "JSWebSocket.h" 52 #include "MIMETypeRegistry.h" 50 53 #include "MemoryCache.h" 51 54 #include "NetworkResourcesData.h" … … 59 62 #include "ScriptableDocumentParser.h" 60 63 #include "SubresourceLoader.h" 64 #include "TextResourceDecoder.h" 61 65 #include "ThreadableLoaderClient.h" 62 66 #include "URL.h" … … 68 72 #include <inspector/InjectedScript.h> 69 73 #include <inspector/InjectedScriptManager.h> 70 #include <inspector/InspectorFrontendRouter.h>71 74 #include <inspector/ScriptCallStack.h> 72 75 #include <inspector/ScriptCallStackFactory.h> … … 76 79 #include <wtf/RefPtr.h> 77 80 #include <wtf/Stopwatch.h> 81 #include <wtf/text/Base64.h> 78 82 #include <wtf/text/StringBuilder.h> 79 83 … … 457 461 } 458 462 459 static bool isErrorStatusCode(int statusCode)460 {461 return statusCode >= 400;462 }463 464 463 void InspectorNetworkAgent::didReceiveData(unsigned long identifier, const char* data, int dataLength, int encodedDataLength) 465 464 { … … 471 470 if (data) { 472 471 NetworkResourcesData::ResourceData const* resourceData = m_resourcesData->data(requestId); 473 if (resourceData && !m_loadingXHRSynchronously && (!resourceData->cachedResource() || resourceData->cachedResource()->dataBufferingPolicy() == DoNotBufferData || isErrorStatusCode(resourceData->httpStatusCode())))472 if (resourceData && !m_loadingXHRSynchronously) 474 473 m_resourcesData->maybeAddResourceData(requestId, data, dataLength); 475 474 } … … 568 567 } 569 568 570 void InspectorNetworkAgent::didFinishXHRLoading(unsigned long identifier, const String& decodedText)571 {572 m_resourcesData->setResourceContent(IdentifiersFactory::requestId(identifier), decodedText);573 }574 575 569 void InspectorNetworkAgent::willLoadXHRSynchronously() 576 570 { … … 591 585 String content; 592 586 bool base64Encoded; 593 if (!InspectorPageAgent::cachedResourceContent(&cachedResource, &content, &base64Encoded)) 594 return; 587 if (!InspectorNetworkAgent::cachedResourceContent(cachedResource, &content, &base64Encoded)) 588 return; 589 595 590 for (auto& id : requestIds) 596 591 m_resourcesData->setResourceContent(id, content, base64Encoded); … … 779 774 780 775 if (resourceData->cachedResource()) { 781 if (Inspector PageAgent::cachedResourceContent(resourceData->cachedResource(), content, base64Encoded))776 if (InspectorNetworkAgent::cachedResourceContent(*resourceData->cachedResource(), content, base64Encoded)) 782 777 return; 783 778 } … … 867 862 String objectGroupName = objectGroup ? *objectGroup : String(); 868 863 result = injectedScript.wrapObject(webSocketAsScriptValue(state, webSocket), objectGroupName); 864 } 865 866 bool InspectorNetworkAgent::shouldTreatAsText(const String& mimeType) 867 { 868 return startsWithLettersIgnoringASCIICase(mimeType, "text/") 869 || MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType) 870 || MIMETypeRegistry::isSupportedJSONMIMEType(mimeType) 871 || MIMETypeRegistry::isXMLMIMEType(mimeType); 872 } 873 874 Ref<TextResourceDecoder> InspectorNetworkAgent::createTextDecoder(const String& mimeType, const String& textEncodingName) 875 { 876 if (!textEncodingName.isEmpty()) 877 return TextResourceDecoder::create(ASCIILiteral("text/plain"), textEncodingName); 878 879 if (MIMETypeRegistry::isTextMIMEType(mimeType)) 880 return TextResourceDecoder::create(mimeType, "UTF-8"); 881 if (MIMETypeRegistry::isXMLMIMEType(mimeType)) { 882 auto decoder = TextResourceDecoder::create(ASCIILiteral("application/xml")); 883 decoder->useLenientXMLDecoding(); 884 return decoder; 885 } 886 887 return TextResourceDecoder::create(ASCIILiteral("text/plain"), "UTF-8"); 888 } 889 890 std::optional<String> InspectorNetworkAgent::textContentForCachedResource(CachedResource& cachedResource) 891 { 892 if (!InspectorNetworkAgent::shouldTreatAsText(cachedResource.mimeType())) 893 return std::nullopt; 894 895 String result; 896 bool base64Encoded; 897 if (InspectorNetworkAgent::cachedResourceContent(cachedResource, &result, &base64Encoded)) { 898 ASSERT(!base64Encoded); 899 return result; 900 } 901 902 return std::nullopt; 903 } 904 905 bool InspectorNetworkAgent::cachedResourceContent(CachedResource& resource, String* result, bool* base64Encoded) 906 { 907 ASSERT(result); 908 ASSERT(base64Encoded); 909 910 if (!resource.encodedSize()) { 911 *base64Encoded = false; 912 *result = String(); 913 return true; 914 } 915 916 switch (resource.type()) { 917 case CachedResource::CSSStyleSheet: 918 *base64Encoded = false; 919 *result = downcast<CachedCSSStyleSheet>(resource).sheetText(); 920 // The above can return a null String if the MIME type is invalid. 921 return !result->isNull(); 922 case CachedResource::Script: 923 *base64Encoded = false; 924 *result = downcast<CachedScript>(resource).script().toString(); 925 return true; 926 default: 927 auto* buffer = resource.resourceBuffer(); 928 if (!buffer) 929 return false; 930 931 if (InspectorNetworkAgent::shouldTreatAsText(resource.mimeType())) { 932 auto decoder = InspectorNetworkAgent::createTextDecoder(resource.mimeType(), resource.response().textEncodingName()); 933 *base64Encoded = false; 934 *result = decoder->decodeAndFlush(buffer->data(), buffer->size()); 935 return true; 936 } 937 938 *base64Encoded = true; 939 *result = base64Encode(buffer->data(), buffer->size()); 940 return true; 941 } 869 942 } 870 943 … … 880 953 } 881 954 955 static std::optional<String> textContentForResourceData(const NetworkResourcesData::ResourceData& resourceData) 956 { 957 if (resourceData.hasContent() && !resourceData.base64Encoded()) 958 return resourceData.content(); 959 960 if (resourceData.cachedResource()) 961 return InspectorNetworkAgent::textContentForCachedResource(*resourceData.cachedResource()); 962 963 return std::nullopt; 964 } 965 882 966 void InspectorNetworkAgent::searchOtherRequests(const JSC::Yarr::RegularExpression& regex, RefPtr<JSON::ArrayOf<Inspector::Protocol::Page::SearchResult>>& result) 883 967 { 884 968 Vector<NetworkResourcesData::ResourceData*> resources = m_resourcesData->resources(); 885 969 for (auto* resourceData : resources) { 886 if ( resourceData->hasContent()) {970 if (auto textContent = textContentForResourceData(*resourceData)) { 887 971 int matchesCount = ContentSearchUtilities::countRegularExpressionMatches(regex, resourceData->content()); 888 972 if (matchesCount) -
trunk/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
r225425 r225546 58 58 class ResourceRequest; 59 59 class ResourceResponse; 60 class TextResourceDecoder; 60 61 class URL; 61 62 class WebSocket; … … 71 72 explicit InspectorNetworkAgent(WebAgentContext&); 72 73 virtual ~InspectorNetworkAgent(); 74 75 static bool shouldTreatAsText(const String& mimeType); 76 static Ref<TextResourceDecoder> createTextDecoder(const String& mimeType, const String& textEncodingName); 77 static std::optional<String> textContentForCachedResource(CachedResource&); 78 static bool cachedResourceContent(CachedResource&, String* result, bool* base64Encoded); 73 79 74 80 void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; … … 86 92 void didLoadResourceFromMemoryCache(DocumentLoader*, CachedResource&); 87 93 void didReceiveThreadableLoaderResponse(unsigned long identifier, DocumentThreadableLoader&); 88 void didFinishXHRLoading(unsigned long identifier, const String& decodedText);89 94 void willLoadXHRSynchronously(); 90 95 void didLoadXHRSynchronously(); … … 104 109 void searchOtherRequests(const JSC::Yarr::RegularExpression&, RefPtr<JSON::ArrayOf<Inspector::Protocol::Page::SearchResult>>&); 105 110 void searchInRequest(ErrorString&, const String& requestId, const String& query, bool caseSensitive, bool isRegex, RefPtr<JSON::ArrayOf<Inspector::Protocol::GenericTypes::SearchMatch>>&); 106 107 RefPtr<Inspector::Protocol::Network::Initiator> buildInitiatorObject(Document*);108 111 109 112 // Called from frontend. … … 129 132 WebSocket* webSocketForRequestId(const String& requestId); 130 133 134 RefPtr<Inspector::Protocol::Network::Initiator> buildInitiatorObject(Document*); 131 135 Ref<Inspector::Protocol::Network::ResourceTiming> buildObjectForTiming(const NetworkLoadMetrics&, ResourceLoader&); 132 136 Ref<Inspector::Protocol::Network::Metrics> buildObjectForMetrics(const NetworkLoadMetrics&); -
trunk/Source/WebCore/inspector/agents/InspectorPageAgent.cpp
r225425 r225546 33 33 #include "InspectorPageAgent.h" 34 34 35 #include "CachedCSSStyleSheet.h"36 #include "CachedFont.h"37 #include "CachedImage.h"38 35 #include "CachedResource.h" 39 36 #include "CachedResourceLoader.h" 40 #include "CachedScript.h"41 37 #include "Cookie.h" 42 38 #include "CookieJar.h" … … 66 62 #include "StyleScope.h" 67 63 #include "TextEncoding.h" 68 #include "TextResourceDecoder.h"69 64 #include "UserGestureIndicator.h" 70 65 #include <inspector/ContentSearchUtilities.h> … … 97 92 } 98 93 99 static bool hasTextContent(CachedResource* cachedResource)100 {101 // FIXME: <https://webkit.org/b/165495> Web Inspector: XHR / Fetch for non-text content should not show garbled text102 // We should not assume XHR / Fetch have text content.103 104 InspectorPageAgent::ResourceType type = InspectorPageAgent::inspectorResourceType(*cachedResource);105 return type == InspectorPageAgent::DocumentResource106 || type == InspectorPageAgent::StylesheetResource107 || type == InspectorPageAgent::ScriptResource108 || type == InspectorPageAgent::XHRResource109 || type == InspectorPageAgent::FetchResource;110 }111 112 bool InspectorPageAgent::cachedResourceContent(CachedResource* cachedResource, String* result, bool* base64Encoded)113 {114 if (!cachedResource)115 return false;116 117 *base64Encoded = !hasTextContent(cachedResource);118 119 if (!cachedResource->encodedSize()) {120 *result = emptyString();121 return true;122 }123 124 if (*base64Encoded) {125 if (auto* buffer = cachedResource->resourceBuffer()) {126 *result = base64Encode(buffer->data(), buffer->size());127 return true;128 }129 return false;130 }131 132 if (cachedResource) {133 switch (cachedResource->type()) {134 case CachedResource::CSSStyleSheet:135 // This can return a null String if the MIME type is invalid.136 *result = downcast<CachedCSSStyleSheet>(*cachedResource).sheetText();137 return !result->isNull();138 case CachedResource::Script:139 *result = downcast<CachedScript>(*cachedResource).script().toString();140 return true;141 case CachedResource::MediaResource:142 case CachedResource::Icon:143 case CachedResource::RawResource: {144 auto* buffer = cachedResource->resourceBuffer();145 if (!buffer)146 return false;147 RefPtr<TextResourceDecoder> decoder = InspectorPageAgent::createTextDecoder(cachedResource->response().mimeType(), cachedResource->response().textEncodingName());148 // We show content for raw resources only for certain mime types (text, html and xml). Otherwise decoder will be null.149 if (!decoder)150 return false;151 *result = decoder->decodeAndFlush(buffer->data(), buffer->size());152 return true;153 }154 default:155 auto* buffer = cachedResource->resourceBuffer();156 return decodeBuffer(buffer ? buffer->data() : nullptr, buffer ? buffer->size() : 0, cachedResource->encoding(), result);157 }158 }159 return false;160 }161 162 94 bool InspectorPageAgent::mainResourceContent(Frame* frame, bool withBase64Encode, String* result) 163 95 { … … 196 128 } 197 129 198 if (!success) 199 success = cachedResourceContent(cachedResource(frame, url), result, base64Encoded); 130 if (!success) { 131 if (auto* resource = cachedResource(frame, url)) 132 success = InspectorNetworkAgent::cachedResourceContent(*resource, result, base64Encoded); 133 } 200 134 201 135 if (!success) … … 203 137 } 204 138 205 //static206 139 String InspectorPageAgent::sourceMapURLForResource(CachedResource* cachedResource) 207 140 { … … 226 159 String content; 227 160 bool base64Encoded; 228 if (Inspector PageAgent::cachedResourceContent(cachedResource, &content, &base64Encoded) && !base64Encoded)161 if (InspectorNetworkAgent::cachedResourceContent(*cachedResource, &content, &base64Encoded) && !base64Encoded) 229 162 return ContentSearchUtilities::findStylesheetSourceMapURL(content); 230 163 … … 326 259 } 327 260 328 RefPtr<TextResourceDecoder> InspectorPageAgent::createTextDecoder(const String& mimeType, const String& textEncodingName)329 {330 if (!textEncodingName.isEmpty())331 return TextResourceDecoder::create(ASCIILiteral("text/plain"), textEncodingName);332 333 if (MIMETypeRegistry::isTextMIMEType(mimeType))334 return TextResourceDecoder::create(mimeType, "UTF-8");335 336 if (MIMETypeRegistry::isXMLMIMEType(mimeType)) {337 RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create(ASCIILiteral("application/xml"));338 decoder->useLenientXMLDecoding();339 return decoder;340 }341 342 return TextResourceDecoder::create(ASCIILiteral("text/plain"), "UTF-8");343 }344 345 261 InspectorPageAgent::InspectorPageAgent(PageAgentContext& context, InspectorClient* client, InspectorOverlay* overlay) 346 262 : InspectorAgentBase(ASCIILiteral("Page"), context) … … 544 460 } 545 461 546 static bool textContentForCachedResource(CachedResource* cachedResource, String* result)547 {548 if (hasTextContent(cachedResource)) {549 bool base64Encoded;550 if (InspectorPageAgent::cachedResourceContent(cachedResource, result, &base64Encoded)) {551 ASSERT(!base64Encoded);552 return true;553 }554 }555 return false;556 }557 558 462 void InspectorPageAgent::searchInResource(ErrorString& errorString, const String& frameId, const String& url, const String& query, const bool* const optionalCaseSensitive, const bool* const optionalIsRegex, const String* optionalRequestId, RefPtr<JSON::ArrayOf<Inspector::Protocol::GenericTypes::SearchMatch>>& results) 559 463 { … … 586 490 587 491 if (!success) { 588 CachedResource* resource = cachedResource(frame, kurl); 589 if (resource) 590 success = textContentForCachedResource(resource, &content); 492 if (auto* resource = cachedResource(frame, kurl)) { 493 if (auto textContent = InspectorNetworkAgent::textContentForCachedResource(*resource)) { 494 content = *textContent; 495 success = true; 496 } 497 } 591 498 } 592 499 … … 615 522 616 523 for (Frame* frame = &m_page.mainFrame(); frame; frame = frame->tree().traverseNext()) { 617 String content;618 619 524 for (auto* cachedResource : cachedResourcesForFrame(frame)) { 620 if ( textContentForCachedResource(cachedResource, &content)) {621 int matchesCount = ContentSearchUtilities::countRegularExpressionMatches(regex, content);525 if (auto textContent = InspectorNetworkAgent::textContentForCachedResource(*cachedResource)) { 526 int matchesCount = ContentSearchUtilities::countRegularExpressionMatches(regex, *textContent); 622 527 if (matchesCount) 623 528 result->addItem(buildObjectForSearchResult(frameId(frame), cachedResource->url(), matchesCount)); 624 529 } 625 }626 627 if (mainResourceContent(frame, false, &content)) {628 int matchesCount = ContentSearchUtilities::countRegularExpressionMatches(regex, content);629 if (matchesCount)630 result->addItem(buildObjectForSearchResult(frameId(frame), frame->document()->url(), matchesCount));631 530 } 632 531 } -
trunk/Source/WebCore/inspector/agents/InspectorPageAgent.h
r225425 r225546 51 51 class RenderObject; 52 52 class SharedBuffer; 53 class TextResourceDecoder;54 53 class URL; 55 54 … … 76 75 }; 77 76 78 static bool cachedResourceContent(CachedResource*, String* result, bool* base64Encoded);79 77 static bool sharedBufferContent(RefPtr<SharedBuffer>&&, const String& textEncodingName, bool withBase64Encode, String* result); 80 78 static void resourceContent(ErrorString&, Frame*, const URL&, String* result, bool* base64Encoded); … … 86 84 static ResourceType inspectorResourceType(const CachedResource&); 87 85 static Inspector::Protocol::Page::ResourceType cachedResourceTypeJSON(const CachedResource&); 88 static RefPtr<TextResourceDecoder> createTextDecoder(const String& mimeType, const String& textEncodingName);89 86 90 87 // Page API for InspectorFrontend -
trunk/Source/WebCore/xml/XMLHttpRequest.cpp
r224299 r225546 926 926 } 927 927 928 void XMLHttpRequest::didFinishLoading(unsigned long identifier)928 void XMLHttpRequest::didFinishLoading(unsigned long) 929 929 { 930 930 if (m_error) … … 938 938 939 939 m_responseBuilder.shrinkToFit(); 940 941 std::optional<String> decodedText;942 if (!m_binaryResponseBuilder)943 decodedText = m_responseBuilder.toStringPreserveCapacity();944 InspectorInstrumentation::didFinishXHRLoading(scriptExecutionContext(), identifier, decodedText);945 940 946 941 bool hadLoader = m_loader; -
trunk/Source/WebInspectorUI/ChangeLog
r225527 r225546 1 2017-12-05 Joseph Pecoraro <pecoraro@apple.com> 2 3 Web Inspector: content views for resources loaded through XHR do not reflect declared mime-type 4 https://bugs.webkit.org/show_bug.cgi?id=141389 5 <rdar://problem/19767070> 6 7 Reviewed by Brian Burg. 8 9 * UserInterface/Base/Utilities.js: 10 Blob <-> Text conversion helpers. 11 12 * UserInterface/Models/Resource.js: 13 (WI.Resource.prototype.createObjectURL): 14 Previously all Image resources were assumed to have base64Encoded data 15 which we automatically convert to a Blob. Now that some image data 16 can be transfered as text, convert that to a Blob here since the output 17 is expected to be a Blob. 18 19 * UserInterface/Views/ResourceContentView.js: 20 (WI.ResourceContentView.prototype.showGenericNoContentMessage): 21 * UserInterface/Views/TextResourceContentView.js: 22 (WI.TextResourceContentView.prototype.contentAvailable): 23 (WI.TextResourceContentView.prototype._contentDidPopulate): 24 * UserInterface/Views/ImageResourceContentView.js: 25 (WI.ImageResourceContentView.prototype.contentAvailable): 26 Better handle no content cases. 27 28 * UserInterface/Views/ResourceClusterContentView.js: 29 (WI.ResourceClusterContentView.prototype.get responseContentView): 30 (WI.ResourceClusterContentView.prototype._contentViewForResourceType): 31 Make a best effort to find a good ContentView to show the resource data. 32 This is done by looking at the ResourceType and MIME Type. 33 34 * UserInterface/Views/SVGImageResourceClusterContentView.js: 35 (WI.SVGImageResourceClusterContentView.prototype._showContentViewForIdentifier): 36 Handle if image data is now text (the image/svg+xml case). 37 1 38 2017-12-05 Simon Fraser <simon.fraser@apple.com> 2 39 -
trunk/Source/WebInspectorUI/UserInterface/Base/Utilities.js
r223308 r225546 1595 1595 } 1596 1596 1597 function textToBlob(text, mimeType) 1598 { 1599 return new Blob([text], {type: mimeType}); 1600 } 1601 1602 function blobAsText(blob, callback) 1603 { 1604 console.assert(blob instanceof Blob); 1605 let fileReader = new FileReader; 1606 fileReader.addEventListener("loadend", () => { callback(fileReader.result); }); 1607 fileReader.readAsText(blob); 1608 } 1609 1597 1610 if (!window.handlePromiseException) { 1598 1611 window.handlePromiseException = function handlePromiseException(error) -
trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js
r225244 r225546 381 381 return URL.createObjectURL(content); 382 382 383 if (typeof content === "string") { 384 let blob = textToBlob(content, this._mimeType); 385 return URL.createObjectURL(blob); 386 } 387 383 388 return null; 384 389 } … … 1130 1135 "text/plain": WI.Resource.Type.Document, 1131 1136 "application/xhtml+xml": WI.Resource.Type.Document, 1132 "image/svg+xml": WI.Resource.Type.Document,1133 1137 1134 1138 "text/css": WI.Resource.Type.Stylesheet, … … 1139 1143 1140 1144 "application/pdf": WI.Resource.Type.Image, 1145 "image/svg+xml": WI.Resource.Type.Image, 1141 1146 1142 1147 "application/x-font-type1": WI.Resource.Type.Font, -
trunk/Source/WebInspectorUI/UserInterface/Views/ImageResourceContentView.js
r221338 r225546 49 49 contentAvailable(content, base64Encoded) 50 50 { 51 this.removeLoadingIndicator(); 52 53 if (!content) { 54 this.showGenericNoContentMessage(); 55 return; 56 } 57 51 58 let objectURL = this.resource.createObjectURL(); 52 59 if (!objectURL) { … … 54 61 return; 55 62 } 56 57 this.removeLoadingIndicator();58 63 59 64 this._imageElement = document.createElement("img"); -
trunk/Source/WebInspectorUI/UserInterface/Views/ResourceClusterContentView.js
r224767 r225546 77 77 return this._responseContentView; 78 78 79 switch (this._resource.type) { 80 case WI.Resource.Type.Document: 81 case WI.Resource.Type.Script: 82 case WI.Resource.Type.Stylesheet: 79 this._responseContentView = this._contentViewForResourceType(this._resource.type); 80 if (this._responseContentView) 81 return this._responseContentView; 82 83 let typeFromMIMEType = WI.Resource.typeFromMIMEType(this._resource.mimeType); 84 this._responseContentView = this._contentViewForResourceType(typeFromMIMEType); 85 if (this._responseContentView) 86 return this._responseContentView; 87 88 if (WI.shouldTreatMIMETypeAsText(this._resource.mimeType)) { 83 89 this._responseContentView = new WI.TextResourceContentView(this._resource); 84 break; 85 86 case WI.Resource.Type.XHR: 87 case WI.Resource.Type.Fetch: 88 case WI.Resource.Type.Ping: 89 case WI.Resource.Type.Beacon: 90 // FIXME: <https://webkit.org/b/165495> Web Inspector: XHR / Fetch for non-text content should not show garbled text 91 // The response content for these requests may not always be text. 92 this._responseContentView = new WI.TextResourceContentView(this._resource); 93 break; 94 95 case WI.Resource.Type.Image: 96 if (this._resource.mimeTypeComponents.type === "image/svg+xml") 97 this._responseContentView = new WI.SVGImageResourceClusterContentView(this._resource); 98 else 99 this._responseContentView = new WI.ImageResourceContentView(this._resource); 100 break; 101 102 case WI.Resource.Type.Font: 103 this._responseContentView = new WI.FontResourceContentView(this._resource); 104 break; 105 106 case WI.Resource.Type.WebSocket: 107 this._responseContentView = new WI.WebSocketContentView(this._resource); 108 break; 109 110 default: 111 this._responseContentView = new WI.GenericResourceContentView(this._resource); 112 break; 113 } 114 90 return this._responseContentView; 91 } 92 93 this._responseContentView = new WI.GenericResourceContentView(this._resource); 115 94 return this._responseContentView; 116 95 } … … 223 202 { 224 203 return !!this._customResponseContentViewConstructor; 204 } 205 206 _contentViewForResourceType(type) 207 { 208 switch (type) { 209 case WI.Resource.Type.Document: 210 case WI.Resource.Type.Script: 211 case WI.Resource.Type.Stylesheet: 212 return new WI.TextResourceContentView(this._resource); 213 214 case WI.Resource.Type.Image: 215 if (this._resource.mimeTypeComponents.type === "image/svg+xml") 216 return new WI.SVGImageResourceClusterContentView(this._resource); 217 return new WI.ImageResourceContentView(this._resource); 218 219 case WI.Resource.Type.Font: 220 return new WI.FontResourceContentView(this._resource); 221 222 case WI.Resource.Type.WebSocket: 223 return new WI.WebSocketContentView(this._resource); 224 225 default: 226 return null; 227 } 225 228 } 226 229 -
trunk/Source/WebInspectorUI/UserInterface/Views/ResourceContentView.js
r225244 r225546 80 80 { 81 81 throw WI.NotImplementedError.subclassMustOverride(); 82 } 83 84 showGenericNoContentMessage() 85 { 86 this.showMessage(WI.UIString("Resource has no content")); 82 87 } 83 88 -
trunk/Source/WebInspectorUI/UserInterface/Views/SVGImageResourceClusterContentView.js
r220119 r225546 137 137 138 138 this._resource.requestContent().then((result) => { 139 let fileReader = new FileReader; 140 fileReader.addEventListener("loadend", () => { 141 contentViewToShow.textEditor.string = fileReader.result; 139 if (typeof result.content === "string") { 140 contentViewToShow.textEditor.string = result.content; 141 return; 142 } 143 144 blobAsText(result.content, (text) => { 145 contentViewToShow.textEditor.string = text; 142 146 }); 143 fileReader.readAsText(result.content);144 147 }); 145 148 break; -
trunk/Source/WebInspectorUI/UserInterface/Views/TextResourceContentView.js
r222739 r225546 131 131 } 132 132 133 contentAvailable(content, base64Encoded) 134 { 135 // Do nothing. 136 } 137 133 138 get supportsSave() 134 139 { … … 211 216 212 217 if (!this._textEditor.string) 213 this.show Message(WI.UIString("Resource has no content"));218 this.showGenericNoContentMessage(); 214 219 } 215 220
Note: See TracChangeset
for help on using the changeset viewer.