Changeset 251024 in webkit
- Timestamp:
- Oct 11, 2019, 1:44:05 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 27 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r251023 r251024 1 2019-10-10 Joseph Pecoraro <pecoraro@apple.com> 2 3 Web Inspector: Local Resource Overrides: UI for overriding image and font resource content 4 https://bugs.webkit.org/show_bug.cgi?id=202016 5 <rdar://problem/55541475> 6 7 Reviewed by Devin Rousso. 8 9 * inspector/unit-tests/mimetype-utilities-expected.txt: 10 * inspector/unit-tests/mimetype-utilities.html: 11 Test new utilities. 12 13 * http/tests/inspector/network/fetch-response-body.html: 14 * http/tests/inspector/network/xhr-response-body.html: 15 Renamed utilities. 16 1 17 2019-10-11 Dean Jackson <dino@apple.com> 2 18 -
trunk/LayoutTests/http/tests/inspector/network/fetch-response-body.html
r225546 r251024 43 43 return; 44 44 } 45 blobAsText(content, (text) => {45 WI.BlobUtilities.blobAsText(content, (text) => { 46 46 resolve(text); 47 47 }); -
trunk/LayoutTests/http/tests/inspector/network/xhr-response-body.html
r234702 r251024 57 57 return; 58 58 } 59 blobAsText(content, (text) => {59 WI.BlobUtilities.blobAsText(content, (text) => { 60 60 resolve(text); 61 61 }); -
trunk/LayoutTests/inspector/unit-tests/mimetype-utilities-expected.txt
r247533 r251024 1 1 2 2 == Running test suite: MIMETypeUtilities 3 -- Running test case: fileExtensionForFilename 4 PASS: File extension for null filename should be null. 5 PASS: File extension for filename without a period should be null. 6 PASS: File extension for filename ending in a period should be null. 7 PASS: File extension for "foo.xyz" should be "xyz". 8 PASS: File extension for "image.png" should be "png". 9 PASS: File extension for "image.png" should be "gif". 10 PASS: File extension for "script.js" should be "js". 11 PASS: File extension for "script.min.js" should be "js". 12 3 13 -- Running test case: fileExtensionForURL 4 14 PASS: File extension for null URL should be null. -
trunk/LayoutTests/inspector/unit-tests/mimetype-utilities.html
r247533 r251024 9 9 10 10 suite.addTestCase({ 11 name: "fileExtensionForFilename", 12 test() { 13 InspectorTest.expectNull(WI.fileExtensionForFilename(null), `File extension for null filename should be null.`); 14 InspectorTest.expectEqual(WI.fileExtensionForURL("test"), null, `File extension for filename without a period should be null.`); 15 InspectorTest.expectEqual(WI.fileExtensionForURL("test."), null, `File extension for filename ending in a period should be null.`); 16 17 InspectorTest.expectEqual(WI.fileExtensionForFilename("foo.xyz"), "xyz", `File extension for "foo.xyz" should be "xyz".`); 18 InspectorTest.expectEqual(WI.fileExtensionForFilename("image.png"), "png", `File extension for "image.png" should be "png".`); 19 InspectorTest.expectEqual(WI.fileExtensionForFilename("image.gif"), "gif", `File extension for "image.png" should be "gif".`); 20 InspectorTest.expectEqual(WI.fileExtensionForFilename("script.js"), "js", `File extension for "script.js" should be "js".`); 21 InspectorTest.expectEqual(WI.fileExtensionForFilename("script.min.js"), "js", `File extension for "script.min.js" should be "js".`); 22 23 return true; 24 } 25 }); 26 27 suite.addTestCase({ 11 28 name: "fileExtensionForURL", 12 29 test() { 13 InspectorTest.expect Equal(WI.fileExtensionForURL(null), null, `File extension for null URL should be null.`);30 InspectorTest.expectNull(WI.fileExtensionForURL(null), `File extension for null URL should be null.`); 14 31 InspectorTest.expectEqual(WI.fileExtensionForURL("invalid-url"), null, `File extension for invalid URL should be null.`); 15 32 InspectorTest.expectEqual(WI.fileExtensionForURL("https://example.com"), null, `File extension for URL without last path component should be null.`); -
trunk/Source/WebInspectorUI/.eslintrc
r248537 r251024 112 112 "appendWebInspectorConsoleEvaluationSourceURL": true, 113 113 "appendWebInspectorSourceURL": true, 114 "blobAsText": true,115 114 "clamp": true, 116 115 "doubleQuotedString": true, … … 133 132 "resolveDotsInPath": true, 134 133 "simpleGlobStringToRegExp": true, 135 "textToBlob": true,136 134 "timestamp": true, 137 135 "zeroWidthSpace": true, … … 142 140 // URL Utilities 143 141 "absoluteURL": true, 144 "decodeBase64ToBlob": true,145 142 "parseDataURL": true, 146 143 "parseLocationQueryParameters": true, -
trunk/Source/WebInspectorUI/ChangeLog
r250991 r251024 1 2019-10-10 Joseph Pecoraro <pecoraro@apple.com> 2 3 Web Inspector: Local Resource Overrides: UI for overriding image and font resource content 4 https://bugs.webkit.org/show_bug.cgi?id=202016 5 <rdar://problem/55541475> 6 7 Reviewed by Devin Rousso. 8 9 Extend SourceCodeRevision to be a (content, base64Encoded, mimeType) tuple and 10 make clients update the revision content more explicitly (`updateRevisionContent`). 11 This also includes `blobContent` as a more explicit way to get the content as 12 a Blob, which may not always be desired. 13 14 Switch LocalResource use the originalRevision / currentRevision instead of 15 keeping its own localContent / localContentIsBase64Encoded properties. 16 17 Introduce a `DropZoneView` to simplify handling of presenting a drop zone 18 over a specific element. And use it for the ImageResourceContentView for local 19 resource overrides to accept new content. 20 21 * Localizations/en.lproj/localizedStrings.js: 22 * UserInterface/Main.html: 23 New strings and resources. 24 25 * .eslintrc: 26 * UserInterface/Base/BlobUtilities.js: Added. 27 (WI.BlobUtilities.blobForContent): 28 (WI.BlobUtilities.decodeBase64ToBlob): 29 (WI.BlobUtilities.textToBlob): 30 (WI.BlobUtilities.blobAsText): 31 (WI.BlobUtilities): 32 * UserInterface/Base/FileUtilities.js: 33 (WI.FileUtilities.async.readDataURL): 34 (WI.FileUtilities): 35 * UserInterface/Base/MIMETypeUtilities.js: 36 (WI.fileExtensionForFilename): 37 (WI.fileExtensionForURL): 38 * UserInterface/Base/Utilities.js: 39 Move around or introduce some minor utilities. 40 41 * UserInterface/Models/SourceCodeRevision.js: 42 (WI.SourceCodeRevision): 43 (WI.SourceCodeRevision.prototype.get sourceCode): 44 (WI.SourceCodeRevision.prototype.get content): 45 (WI.SourceCodeRevision.prototype.get base64Encoded): 46 (WI.SourceCodeRevision.prototype.get mimeType): 47 (WI.SourceCodeRevision.prototype.get blobContent): 48 (WI.SourceCodeRevision.prototype.updateRevisionContent): 49 (WI.SourceCodeRevision.prototype.copy): 50 (WI.SourceCodeRevision.prototype.set content): Deleted. 51 Data is now a (content, base64Encoded, mimeType) tuple. 52 53 * UserInterface/Controllers/NetworkManager.js: 54 (WI.NetworkManager.prototype.responseIntercepted): 55 (WI.NetworkManager.prototype._handleResourceContentDidChange): 56 (WI.NetworkManager.prototype._persistLocalResourceOverrideSoonAfterContentChange): Deleted. 57 This is now a unified resource content change path without anything special for 58 local resource overrides. 59 60 * UserInterface/Models/LocalResource.js: 61 (WI.LocalResource.prototype.toJSON): 62 (WI.LocalResource.prototype.requestContentFromBackend): 63 (WI.LocalResource.prototype.handleCurrentRevisionContentChange): 64 (WI.LocalResource): 65 (WI.LocalResource.prototype.get localContent): Deleted. 66 (WI.LocalResource.prototype.get localContentIsBase64Encoded): Deleted. 67 (WI.LocalResource.prototype.hasContent): Deleted. 68 (WI.LocalResource.prototype.setContent): Deleted. 69 (WI.LocalResource.prototype.updateOverrideContent): Deleted. 70 Use originalRevision / currentRevision as appropriate. 71 72 * UserInterface/Views/DropZoneView.css: Added. 73 (.drop-zone): 74 (.drop-zone.visible): 75 (@media (prefers-color-scheme: dark)): 76 * UserInterface/Views/DropZoneView.js: Added. 77 (WI.DropZoneView): 78 (WI.DropZoneView.prototype.get delegate): 79 (WI.DropZoneView.prototype.get targetElement): 80 (WI.DropZoneView.prototype.set targetElement): 81 (WI.DropZoneView.prototype.initialLayout): 82 (WI.DropZoneView.prototype._startActiveDrag): 83 (WI.DropZoneView.prototype._stopActiveDrag): 84 (WI.DropZoneView.prototype._handleDragEnter): 85 (WI.DropZoneView.prototype._handleDragLeave): 86 (WI.DropZoneView.prototype._handleDragOver): 87 (WI.DropZoneView.prototype._handleDrop): 88 Simplified handling of a drop zone. 89 90 * UserInterface/Views/ResourceContentView.js: 91 (WI.ResourceContentView.prototype.removeLoadingIndicator): 92 More safely remove children and subviews. 93 94 (WI.ResourceContentView): 95 (WI.ResourceContentView.prototype.get resource): 96 (WI.ResourceContentView.prototype.get navigationItems): 97 (WI.ResourceContentView.prototype.localResourceOverrideInitialContent): 98 (WI.ResourceContentView.prototype.closed): 99 (WI.ResourceContentView.prototype.removeLoadingIndicator): 100 (WI.ResourceContentView.prototype._contentAvailable): 101 (WI.ResourceContentView.prototype._issueWasAdded): 102 (WI.ResourceContentView.prototype.async._handleCreateLocalResourceOverride): 103 (WI.ResourceContentView.prototype._handleRemoveLocalResourceOverride): 104 (WI.ResourceContentView.prototype._handleLocalResourceOverrideChanged): 105 (WI.ResourceContentView.prototype._mouseWasClicked): 106 * UserInterface/Views/TextResourceContentView.js: 107 (WI.TextResourceContentView): 108 (WI.TextResourceContentView.prototype.get navigationItems): 109 (WI.TextResourceContentView.prototype.localResourceOverrideInitialContent): 110 (WI.TextResourceContentView.prototype._contentWillPopulate): 111 (WI.TextResourceContentView.prototype._contentDidPopulate): 112 (WI.TextResourceContentView.prototype._textEditorContentDidChange): 113 (WI.TextResourceContentView.prototype._shouldBeEditable): 114 (WI.TextResourceContentView.prototype.async._handleCreateLocalResourceOverride): Deleted. 115 (WI.TextResourceContentView.prototype._handleRemoveLocalResourceOverride): Deleted. 116 (WI.TextResourceContentView.prototype._handleLocalResourceOverrideChanged): Deleted. 117 Extract generalized local resource override properties into the ResourceContentView base class. 118 119 * UserInterface/Views/FontResourceContentView.css: 120 (.content-view.resource.font): 121 (.content-view.resource.font > .drop-zone): 122 (.content-view.resource.font > .preview-container): 123 (.content-view.resource.font .preview): 124 * UserInterface/Views/FontResourceContentView.js: 125 (WI.FontResourceContentView): 126 (WI.FontResourceContentView.prototype.contentAvailable): 127 (WI.FontResourceContentView.prototype.shown): 128 (WI.FontResourceContentView.prototype.hidden): 129 (WI.FontResourceContentView.prototype.closed): 130 (WI.FontResourceContentView.prototype.layout): 131 (WI.FontResourceContentView.prototype._updatePreviewElement.createMetricElement): 132 (WI.FontResourceContentView.prototype._updatePreviewElement): 133 (WI.FontResourceContentView.prototype.dropZoneShouldAppearForDragEvent): 134 (WI.FontResourceContentView.prototype.dropZoneHandleDrop): 135 Create a drop zone that will update the font local resource override content. 136 137 * UserInterface/Views/ImageResourceContentView.css: 138 (.content-view.resource.image): 139 (.content-view.resource.image > .drop-zone): 140 (.content-view.resource.image > .img-container): 141 (.content-view.resource.image img): 142 * UserInterface/Views/ImageResourceContentView.js: 143 (WI.ImageResourceContentView): 144 (WI.ImageResourceContentView.prototype.get navigationItems): 145 (WI.ImageResourceContentView.prototype.contentAvailable): 146 (WI.ImageResourceContentView.prototype.closed): 147 (WI.ImageResourceContentView.prototype.dropZoneShouldAppearForDragEvent): 148 (WI.ImageResourceContentView.prototype.dropZoneHandleDrop): 149 Create a drop zone that will update the image local resource override content. 150 151 * UserInterface/Models/Script.js: 152 (WI.Script.prototype.get mimeType): 153 Seems like this should have a default value given there may not be a resource. 154 155 * UserInterface/Views/LocalResourceOverridePopover.js: 156 (WI.LocalResourceOverridePopover.prototype.show): 157 Better handling here, since the utilities expects a number not a string. 158 159 * UserInterface/Models/Resource.js: 160 (WI.Resource.prototype.createObjectURL): 161 * UserInterface/Views/LocalResourceOverrideTreeElement.js: 162 (WI.LocalResourceOverrideTreeElement.prototype.willDismissPopover): 163 Use currentRevision more appropriately. 164 165 * UserInterface/Models/SourceCode.js: 166 (WI.SourceCode.prototype._processContent): 167 * UserInterface/Views/TextResourceContentView.js: 168 (WI.TextResourceContentView.prototype._textEditorContentDidChange): 169 * UserInterface/Controllers/CSSManager.js: 170 (WI.CSSManager.prototype._resourceContentDidChange.applyStyleSheetChanges.styleSheetFound): 171 (WI.CSSManager.prototype._resourceContentDidChange.applyStyleSheetChanges): 172 (WI.CSSManager.prototype._resourceContentDidChange): 173 (WI.CSSManager.prototype._updateResourceContent.fetchedStyleSheetContent): 174 Update revision content more explicitly. 175 1 176 2019-10-10 Devin Rousso <drousso@apple.com> 2 177 -
trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
r250991 r251024 380 380 localizedStrings["Download"] = "Download"; 381 381 localizedStrings["Download Web Archive"] = "Download Web Archive"; 382 localizedStrings["Drop Font"] = "Drop Font"; 383 localizedStrings["Drop Image"] = "Drop Image"; 382 384 localizedStrings["Dropped Element"] = "Dropped Element"; 383 385 localizedStrings["Dropped Node"] = "Dropped Node"; -
trunk/Source/WebInspectorUI/UserInterface/Base/MIMETypeUtilities.js
r247533 r251024 24 24 */ 25 25 26 WI.fileExtensionForURL = function(url) 27 { 28 let lastPathComponent = parseURL(url).lastPathComponent; 29 if (!lastPathComponent) 26 WI.fileExtensionForFilename = function(filename) 27 { 28 if (!filename) 30 29 return null; 31 30 32 let index = lastPathComponent.lastIndexOf(".");31 let index = filename.lastIndexOf("."); 33 32 if (index === -1) 34 33 return null; 35 34 36 if (index === lastPathComponent.length - 1)35 if (index === filename.length - 1) 37 36 return null; 38 37 39 return lastPathComponent.substr(index + 1); 38 return filename.substr(index + 1); 39 }; 40 41 WI.fileExtensionForURL = function(url) 42 { 43 let lastPathComponent = parseURL(url).lastPathComponent; 44 return WI.fileExtensionForFilename(lastPathComponent); 40 45 }; 41 46 -
trunk/Source/WebInspectorUI/UserInterface/Base/Utilities.js
r249301 r251024 1675 1675 array.splice(insertionIndexForObjectInListSortedByFunction(object, array, comparator), 0, object); 1676 1676 } 1677 1678 function decodeBase64ToBlob(base64Data, mimeType)1679 {1680 mimeType = mimeType || "";1681 1682 const sliceSize = 1024;1683 var byteCharacters = atob(base64Data);1684 var bytesLength = byteCharacters.length;1685 var slicesCount = Math.ceil(bytesLength / sliceSize);1686 var byteArrays = new Array(slicesCount);1687 1688 for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {1689 var begin = sliceIndex * sliceSize;1690 var end = Math.min(begin + sliceSize, bytesLength);1691 1692 var bytes = new Array(end - begin);1693 for (var offset = begin, i = 0; offset < end; ++i, ++offset)1694 bytes[i] = byteCharacters[offset].charCodeAt(0);1695 1696 byteArrays[sliceIndex] = new Uint8Array(bytes);1697 }1698 1699 return new Blob(byteArrays, {type: mimeType});1700 }1701 1702 function textToBlob(text, mimeType)1703 {1704 return new Blob([text], {type: mimeType});1705 }1706 1707 function blobAsText(blob, callback)1708 {1709 console.assert(blob instanceof Blob);1710 let fileReader = new FileReader;1711 fileReader.addEventListener("loadend", () => { callback(fileReader.result); });1712 fileReader.readAsText(blob);1713 } -
trunk/Source/WebInspectorUI/UserInterface/Controllers/CSSManager.js
r250149 r251024 657 657 658 658 let revision = styleSheet.currentRevision; 659 revision. content = resource.content;659 revision.updateRevisionContent(resource.content); 660 660 } 661 661 … … 702 702 let revision = representedObject.currentRevision; 703 703 if (styleSheet.isInspectorStyleSheet()) { 704 revision. content = representedObject.content;704 revision.updateRevisionContent(representedObject.content); 705 705 styleSheet.dispatchEventToListeners(WI.SourceCode.Event.ContentDidChange); 706 706 } else 707 revision. content = parameters.content;707 revision.updateRevisionContent(parameters.content); 708 708 709 709 this._ignoreResourceContentDidChangeEventForResource = null; -
trunk/Source/WebInspectorUI/UserInterface/Controllers/NetworkManager.js
r250991 r251024 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013-2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 817 817 818 818 let localResource = localResourceOverride.localResource; 819 let content = localResource.localContent; 820 let base64Encoded = localResource.localContentIsBase64Encoded; 821 let {mimeType, statusCode, statusText, responseHeaders} = localResource; 819 let revision = localResource.currentRevision; 820 821 let content = revision.content; 822 let base64Encoded = revision.base64Encoded; 823 let mimeType = revision.mimeType; 824 let statusCode = localResource.statusCode; 825 let statusText = localResource.statusText; 826 let responseHeaders = localResource.responseHeaders; 827 console.assert(revision.mimeType === localResource.mimeType); 822 828 823 829 if (isNaN(statusCode)) … … 1245 1251 return; 1246 1252 1247 let localResource = localResourceOverride.localResource;1248 let content = localResource.content;1249 let base64Encoded = localResource.localContentIsBase64Encoded;1250 let mimeType = localResource.mimeType;1251 localResource.updateOverrideContent(content, base64Encoded, mimeType, {suppressEvent: true});1252 1253 this._persistLocalResourceOverrideSoonAfterContentChange(localResourceOverride);1254 }1255 1256 _persistLocalResourceOverrideSoonAfterContentChange(localResourceOverride)1257 {1258 1253 if (!this._saveLocalResourceOverridesDebouncer) { 1259 1254 this._pendingLocalResourceOverrideSaves = new Set; -
trunk/Source/WebInspectorUI/UserInterface/Main.html
r250991 r251024 95 95 <link rel="stylesheet" href="Views/DetailsSection.css"> 96 96 <link rel="stylesheet" href="Views/DividerNavigationItem.css"> 97 <link rel="stylesheet" href="Views/DropZoneView.css"> 97 98 <link rel="stylesheet" href="Views/Editing.css"> 98 99 <link rel="stylesheet" href="Views/ErrorObjectView.css"> … … 291 292 <script src="Base/Throttler.js"></script> 292 293 294 <script src="Base/BlobUtilities.js"></script> 293 295 <script src="Base/DOMUtilities.js"></script> 294 296 <script src="Base/EventListener.js"></script> … … 661 663 <script src="Views/DefaultDashboardView.js"></script> 662 664 <script src="Views/DividerNavigationItem.js"></script> 665 <script src="Views/DropZoneView.js"></script> 663 666 <script src="Views/EditableDataGridNode.js"></script> 664 667 <script src="Views/EditingSupport.js"></script> -
trunk/Source/WebInspectorUI/UserInterface/Models/LocalResource.js
r249504 r251024 75 75 this._responseBodySize = !isNaN(metrics.responseBodyDecodedSize) ? metrics.responseBodyDecodedSize : NaN; 76 76 77 // Access to the content.78 this._localContent = response.content;79 this._localContentIsBase64Encoded = response.base64Encoded;80 81 77 // LocalResource specific. 82 78 this._isLocalResourceOverride = isLocalResourceOverride || false; … … 88 84 89 85 // Finalize WI.SourceCode. 90 this._originalRevision = new WI.SourceCodeRevision(this, this._localContent); 86 let content = response.content; 87 let base64Encoded = response.base64Encoded; 88 this._originalRevision = new WI.SourceCodeRevision(this, content, base64Encoded, this._mimeType); 91 89 this._currentRevision = this._originalRevision; 92 90 } … … 224 222 statusCode: this.statusCode, 225 223 statusText: this.statusText, 226 content: this. _localContent,227 base64Encoded: this. _localContentIsBase64Encoded,224 content: this.currentRevision.content, 225 base64Encoded: this.currentRevision.base64Encoded, 228 226 }, 229 227 isLocalResourceOverride: this._isLocalResourceOverride, … … 233 231 // Public 234 232 235 get localContent() { return this._localContent; }236 get localContentIsBase64Encoded() { return this._localContentIsBase64Encoded; }237 238 233 get isLocalResourceOverride() 239 234 { … … 241 236 } 242 237 243 hasContent() 244 { 245 return !!this._localContent; 246 } 247 248 setContent(content, base64Encoded) 249 { 250 console.assert(!this._localContent); 251 252 // The backend may send base64 encoded data for text resources. 253 // If that is the case decode them here and treat as text. 254 if (base64Encoded && WI.shouldTreatMIMETypeAsText(this._mimeType)) { 255 content = atob(content); 256 base64Encoded = false; 257 } 258 259 this._localContent = content; 260 this._localContentIsBase64Encoded = base64Encoded; 261 } 262 263 updateOverrideContent(content, base64Encoded, mimeType, options = {}) 264 { 265 console.assert(this._isLocalResourceOverride); 266 267 if (content !== undefined && this._localContent !== content) 268 this._localContent = content; 269 270 if (base64Encoded !== undefined && this._localContentIsBase64Encoded !== base64Encoded) 271 this._localContentIsBase64Encoded = base64Encoded; 272 273 if (mimeType !== undefined && mimeType !== this._mimeType) { 238 // Protected 239 240 requestContentFromBackend() 241 { 242 return Promise.resolve({ 243 content: this._originalRevision.content, 244 base64Encoded: this._originalRevision.base64Encoded, 245 }); 246 } 247 248 handleCurrentRevisionContentChange() 249 { 250 if (this._mimeType !== this.currentRevision.mimeType) { 274 251 let oldMIMEType = this._mimeType; 275 this._mimeType = mimeType;252 this._mimeType = this.currentRevision.mimeType; 276 253 this.dispatchEventToListeners(WI.Resource.Event.MIMETypeDidChange, {oldMIMEType}); 277 254 } 278 255 } 279 280 // Protected281 282 requestContentFromBackend()283 {284 return Promise.resolve({285 content: this._localContent,286 base64Encoded: this._localContentIsBase64Encoded,287 });288 }289 256 }; -
trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js
r250813 r251024 423 423 createObjectURL() 424 424 { 425 let revision = this.currentRevision; 426 let blobContent = revision.blobContent; 427 if (blobContent) 428 return URL.createObjectURL(blobContent) 429 425 430 // If content is not available, fallback to using original URL. 426 431 // The client may try to revoke it, but nothing will happen. 427 let content = this.content; 428 if (!content) 429 return this._url; 430 431 if (content instanceof Blob) 432 return URL.createObjectURL(content); 433 434 if (typeof content === "string") { 435 let blob = textToBlob(content, this._mimeType); 436 return URL.createObjectURL(blob); 437 } 438 439 return null; 432 return this._url; 440 433 } 441 434 … … 1066 1059 } 1067 1060 1068 async createLocalResourceOverride( initialContent)1061 async createLocalResourceOverride({initialContent} = {}) 1069 1062 { 1070 1063 console.assert(!this.isLocalResourceOverride); -
trunk/Source/WebInspectorUI/UserInterface/Models/Script.js
r249450 r251024 118 118 get mimeType() 119 119 { 120 return this._resource .mimeType;120 return this._resource ? this._resource.mimeType : "text/javascript"; 121 121 } 122 122 -
trunk/Source/WebInspectorUI/UserInterface/Models/SourceCode.js
r250618 r251024 30 30 super(); 31 31 32 this._originalRevision = new WI.SourceCodeRevision(this , null, false);32 this._originalRevision = new WI.SourceCodeRevision(this); 33 33 this._currentRevision = this._originalRevision; 34 34 … … 232 232 // Different backend APIs return one of `content, `body`, `text`, or `scriptSource`. 233 233 let rawContent = parameters.content || parameters.body || parameters.text || parameters.scriptSource; 234 let rawBase64Encoded = !!parameters.base64Encoded; 234 235 let content = rawContent; 235 236 let error = parameters.error; … … 237 238 238 239 if (parameters.base64Encoded) 239 content = content ? decodeBase64ToBlob(content, this.mimeType) : "";240 content = content ? WI.BlobUtilities.decodeBase64ToBlob(content, this.mimeType) : ""; 240 241 241 242 let revision = this.revisionForRequestedContent; 242 243 243 244 this._ignoreRevisionContentDidChangeEvent = true; 244 revision.content = content || null; 245 revision.updateRevisionContent(rawContent, { 246 base64Encoded: rawBase64Encoded, 247 mimeType: this.mimeType, 248 blobContent: content instanceof Blob ? content : null, 249 }); 245 250 this._ignoreRevisionContentDidChangeEvent = false; 246 251 … … 250 255 // now, and it may become out-dated later on. We should drop content from this promise 251 256 // and require clients to ask for the current contents from the sourceCode in the result. 257 // That would also avoid confusion around `content` being a Blob and eliminate the work 258 // of creating the Blob if it is not used. 252 259 253 260 return Promise.resolve({ … … 257 264 content, 258 265 rawContent, 259 rawBase64Encoded : parameters.base64Encoded,266 rawBase64Encoded, 260 267 }); 261 268 } -
trunk/Source/WebInspectorUI/UserInterface/Models/SourceCodeRevision.js
r220119 r251024 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013-2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 WI.SourceCodeRevision = class SourceCodeRevision extends WI.Revision 27 27 { 28 constructor(sourceCode, content )28 constructor(sourceCode, content, base64Encoded, mimeType) 29 29 { 30 30 super(); 31 31 32 32 console.assert(sourceCode instanceof WI.SourceCode); 33 console.assert(content === undefined || typeof content === "string"); 34 console.assert(base64Encoded === undefined || typeof base64Encoded === "boolean"); 35 console.assert(mimeType === undefined || typeof mimeType === "string"); 33 36 34 37 this._sourceCode = sourceCode; 38 35 39 this._content = content || ""; 40 this._base64Encoded = !!base64Encoded; 41 this._mimeType = mimeType; 42 this._blobContent = null; 36 43 } 37 44 38 45 // Public 39 46 40 get sourceCode() 47 get sourceCode() { return this._sourceCode; } 48 get content() { return this._content; } 49 get base64Encoded() { return this._base64Encoded; } 50 get mimeType() { return this._mimeType; } 51 52 get blobContent() 41 53 { 42 return this._sourceCode; 54 if (!this._blobContent && this._content) 55 this._blobContent = WI.BlobUtilities.blobForContent(this._content, this._base64Encoded, this._mimeType); 56 57 console.assert(!this._blobContent || this._blobContent instanceof Blob); 58 return this._blobContent; 43 59 } 44 60 45 get content()61 updateRevisionContent(content, {base64Encoded, mimeType, blobContent} = {}) 46 62 { 47 return this._content;48 }63 console.assert(content === undefined || typeof content === "string"); 64 this._content = content || ""; 49 65 50 set content(content) 51 { 52 content = content || ""; 66 if (base64Encoded !== undefined) { 67 console.assert(typeof base64Encoded === "boolean"); 68 this._base64Encoded = !!base64Encoded; 69 } 53 70 54 if (this._content === content) 55 return; 71 if (mimeType !== undefined) { 72 console.assert(typeof mimeType === "string"); 73 this._mimeType = mimeType; 74 } 56 75 57 this._content = content; 76 console.assert(!blobContent || blobContent instanceof Blob); 77 this._blobContent = blobContent !== undefined ? blobContent : null; 58 78 59 79 this._sourceCode.revisionContentDidChange(this); … … 72 92 copy() 73 93 { 74 return new WI.SourceCodeRevision(this._sourceCode, this._content );94 return new WI.SourceCodeRevision(this._sourceCode, this._content, this._base64Encoded, this._mimeType); 75 95 } 76 96 }; -
trunk/Source/WebInspectorUI/UserInterface/Test.html
r249831 r251024 55 55 <script src="Test/TestUtilities.js"></script> 56 56 57 <script src="Base/BlobUtilities.js"></script> 57 58 <script src="Base/DOMUtilities.js"></script> 58 59 <script src="Base/EventListener.js"></script> -
trunk/Source/WebInspectorUI/UserInterface/Views/DropZoneView.css
r251023 r251024 1 1 /* 2 * Copyright (C) 201 3Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 24 24 */ 25 25 26 .content-view.resource.image { 27 background-color: hsl(0, 0%, 90%); 26 .drop-zone { 27 display: none; 28 position: absolute; 29 top: 0; 30 left: 0; 31 right: 0; 32 bottom: 0; 33 z-index: var(--z-index-glass-pane-for-drag); 34 } 28 35 29 overflow-x: hidden; 30 overflow-y: auto; 31 36 .drop-zone.visible { 32 37 display: flex; 33 34 38 justify-content: center; 35 39 align-items: center; 36 37 padding: 15px; 38 } 39 40 .content-view.resource.image img { 41 max-width: 100%; 42 43 -webkit-user-select: text; 44 -webkit-user-drag: auto; 45 46 margin: auto 0; 40 font-size: 60px; 41 text-align: center; 42 color: white; 43 text-shadow: 0 1px black; 44 background-color: hsla(0, 0%, 50%, 0.50); 45 border: 3px dashed hsla(0, 0%, 100%, 0.9); 46 -webkit-backdrop-filter: blur(10px); 47 47 } 48 48 49 49 @media (prefers-color-scheme: dark) { 50 .content-view.resource.image { 51 background: var(--background-color-content); 50 .drop-zone.visible { 51 color: hsl(0, 0%, 80%); 52 text-shadow: 0 1px hsl(0, 0%, 20%); 53 background-color: hsla(0, 0%, 30%, 0.5); 54 border: 3px dashed hsla(0, 0%, 65%, 0.9); 52 55 } 53 56 } -
trunk/Source/WebInspectorUI/UserInterface/Views/FontResourceContentView.css
r242768 r251024 26 26 .content-view.resource.font { 27 27 display: flex; 28 28 flex-direction: column; 29 29 justify-content: center; 30 30 align-items: center; 31 31 overflow-x: hidden; 32 32 overflow-y: auto; 33 } 34 35 .content-view.resource.font > .drop-zone { 36 top: calc(var(--navigation-bar-height) - 2px); /* borders */ 37 } 38 39 .content-view.resource.font > .preview-container { 40 display: flex; 41 justify-content: center; 42 align-items: center; 43 width: 100%; 44 height: 100%; 33 45 } 34 46 … … 43 55 for the padding/margin in FontResourceContentView.siteToFit. */ 44 56 border: 15px solid transparent; 45 46 margin: auto 0;47 57 } 48 58 -
trunk/Source/WebInspectorUI/UserInterface/Views/FontResourceContentView.js
r220119 r251024 32 32 this._styleElement = null; 33 33 this._previewElement = null; 34 this._previewContainer = null; 35 36 if (this.showingLocalResourceOverride) 37 this._dropZoneView = new WI.DropZoneView(this, {text: WI.UIString("Drop Font")}); 34 38 } 35 39 36 40 // Public 37 38 get previewElement()39 {40 return this._previewElement;41 }42 41 43 42 sizeToFit() … … 57 56 { 58 57 this._fontObjectURL = this.resource.createObjectURL(); 58 59 59 if (!this._fontObjectURL) { 60 60 this.showGenericErrorMessage(); … … 62 62 } 63 63 64 const uniqueFontName = "WebInspectorFontPreview" + (++WI.FontResourceContentView._uniqueFontIdentifier);65 66 var format = "";67 68 // We need to specify a format when loading SVG fonts to make them work.69 if (this.resource.mimeTypeComponents.type === "image/svg+xml")70 format = " format(\"svg\")";71 72 if (this._styleElement && this._styleElement.parentNode)73 this._styleElement.parentNode.removeChild(this._styleElement);74 75 64 this.removeLoadingIndicator(); 76 65 77 this._styleElement = document.createElement("style"); 78 this._styleElement.textContent = "@font-face { font-family: \"" + uniqueFontName + "\"; src: url(" + this._fontObjectURL + ")" + format + "; }"; 79 80 // The style element will be added when shown later if we are not visible now. 81 if (this.visible) 82 document.head.appendChild(this._styleElement); 83 84 this._previewElement = document.createElement("div"); 85 this._previewElement.className = "preview"; 86 this._previewElement.style.fontFamily = uniqueFontName; 87 88 function createMetricElement(className) 89 { 90 var metricElement = document.createElement("div"); 91 metricElement.className = "metric " + className; 92 return metricElement; 93 } 94 95 var lines = WI.FontResourceContentView.PreviewLines; 96 for (var i = 0; i < lines.length; ++i) { 97 var lineElement = document.createElement("div"); 98 lineElement.className = "line"; 99 100 lineElement.appendChild(createMetricElement("top")); 101 lineElement.appendChild(createMetricElement("xheight")); 102 lineElement.appendChild(createMetricElement("middle")); 103 lineElement.appendChild(createMetricElement("baseline")); 104 lineElement.appendChild(createMetricElement("bottom")); 105 106 var contentElement = document.createElement("div"); 107 contentElement.className = "content"; 108 contentElement.textContent = lines[i]; 109 lineElement.appendChild(contentElement); 110 111 this._previewElement.appendChild(lineElement); 112 } 113 114 this.element.appendChild(this._previewElement); 115 116 this.sizeToFit(); 66 this._previewContainer = this.element.appendChild(document.createElement("div")); 67 this._previewContainer.className = "preview-container"; 68 69 this._updatePreviewElement(); 70 71 if (this._dropZoneView) { 72 this._dropZoneView.targetElement = this._previewContainer; 73 this.addSubview(this._dropZoneView); 74 } 117 75 } 118 76 119 77 shown() 120 78 { 79 super.shown(); 80 121 81 // Add the style element since it is removed when hidden. 122 82 if (this._styleElement) … … 127 87 { 128 88 // Remove the style element so it will not stick around when this content view is destroyed. 129 if (this._styleElement && this._styleElement.parentNode) 130 this._styleElement.parentNode.removeChild(this._styleElement); 89 if (this._styleElement) 90 this._styleElement.remove(); 91 92 super.hidden(); 131 93 } 132 94 … … 139 101 if (this._fontObjectURL) 140 102 URL.revokeObjectURL(this._fontObjectURL); 103 104 super.closed(); 141 105 } 142 106 … … 145 109 layout() 146 110 { 111 this.sizeToFit(); 112 } 113 114 // DropZoneView delegate 115 116 dropZoneShouldAppearForDragEvent(dropZone, event) 117 { 118 return event.dataTransfer.types.includes("Files"); 119 } 120 121 dropZoneHandleDrop(dropZone, event) 122 { 123 let files = event.dataTransfer.files; 124 let file = files.length === 1 ? files[0] : null; 125 if (!file) { 126 InspectorFrontendHost.beep(); 127 return; 128 } 129 130 let fileReader = new FileReader; 131 fileReader.addEventListener("loadend", (event) => { 132 let localResourceOverride = WI.networkManager.localResourceOverrideForURL(this.resource.url); 133 if (!localResourceOverride) 134 return; 135 136 let dataURL = fileReader.result; 137 let {base64, data, mimeType} = parseDataURL(dataURL); 138 139 // In case no mime type was determined, try to derive one from the file extension. 140 if (!mimeType || mimeType === "text/plain") { 141 let extension = WI.fileExtensionForFilename(file.name); 142 if (extension) 143 mimeType = WI.mimeTypeForFileExtension(extension); 144 } 145 146 let revision = localResourceOverride.localResource.currentRevision; 147 revision.updateRevisionContent(data, {base64Encoded: base64, mimeType}); 148 149 this._fontObjectURL = this.resource.createObjectURL(); 150 this._updatePreviewElement(); 151 }); 152 fileReader.readAsDataURL(file); 153 } 154 155 // Private 156 157 _updatePreviewElement() 158 { 159 if (this._styleElement) 160 this._styleElement.remove(); 161 if (this._previewElement) 162 this._previewElement.remove(); 163 164 const uniqueFontName = "WebInspectorFontPreview" + (++WI.FontResourceContentView._uniqueFontIdentifier); 165 166 let format = ""; 167 168 // We need to specify a format when loading SVG fonts to make them work. 169 if (this.resource.mimeTypeComponents.type === "image/svg+xml") 170 format = " format(\"svg\")"; 171 172 this._styleElement = document.createElement("style"); 173 this._styleElement.textContent = `@font-face { font-family: "${uniqueFontName}"; src: url(${this._fontObjectURL}) ${format}; }`; 174 175 // The style element will be added when shown later if we are not visible now. 176 if (this.visible) 177 document.head.appendChild(this._styleElement); 178 179 this._previewElement = document.createElement("div"); 180 this._previewElement.className = "preview"; 181 this._previewElement.style.fontFamily = uniqueFontName; 182 183 function createMetricElement(className) { 184 let metricElement = document.createElement("div"); 185 metricElement.className = "metric " + className; 186 return metricElement; 187 } 188 189 for (let line of WI.FontResourceContentView.PreviewLines) { 190 let lineElement = document.createElement("div"); 191 lineElement.className = "line"; 192 193 lineElement.appendChild(createMetricElement("top")); 194 lineElement.appendChild(createMetricElement("xheight")); 195 lineElement.appendChild(createMetricElement("middle")); 196 lineElement.appendChild(createMetricElement("baseline")); 197 lineElement.appendChild(createMetricElement("bottom")); 198 199 let contentElement = document.createElement("div"); 200 contentElement.className = "content"; 201 contentElement.textContent = line; 202 lineElement.appendChild(contentElement); 203 204 this._previewElement.appendChild(lineElement); 205 } 206 207 this._previewContainer.appendChild(this._previewElement); 208 147 209 this.sizeToFit(); 148 210 } -
trunk/Source/WebInspectorUI/UserInterface/Views/ImageResourceContentView.css
r239760 r251024 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013-2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 25 25 26 26 .content-view.resource.image { 27 display: flex; 28 flex-direction: column; 29 justify-content: center; 30 align-items: center; 27 31 background-color: hsl(0, 0%, 90%); 28 29 32 overflow-x: hidden; 30 33 overflow-y: auto; 34 } 31 35 36 .content-view.resource.image > .drop-zone { 37 top: calc(var(--navigation-bar-height) - 2px); /* borders */ 38 } 39 40 .content-view.resource.image > .img-container { 32 41 display: flex; 33 34 42 justify-content: center; 35 43 align-items: center; 36 44 width: 100%; 45 height: 100%; 37 46 padding: 15px; 38 47 } … … 40 49 .content-view.resource.image img { 41 50 max-width: 100%; 42 51 max-height: 100%; 43 52 -webkit-user-select: text; 44 53 -webkit-user-drag: auto; 45 46 margin: auto 0;47 54 } 48 55 -
trunk/Source/WebInspectorUI/UserInterface/Views/ImageResourceContentView.js
r250814 r251024 1 1 /* 2 * Copyright (C) 2013-201 5Apple Inc. All rights reserved.2 * Copyright (C) 2013-2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 constructor(resource) 29 29 { 30 console.assert(resource instanceof WI.Resource); 31 30 32 super(resource, "image"); 31 33 32 34 this._imageElement = null; 35 this._draggingInternalImageElement = false; 33 36 34 37 const toolTip = WI.UIString("Show transparency grid"); … … 38 41 this._showGridButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._showGridButtonClicked, this); 39 42 this._showGridButtonNavigationItem.activated = !!WI.settings.showImageGrid.value; 43 44 if (this.showingLocalResourceOverride) 45 this._dropZoneView = new WI.DropZoneView(this, {text: WI.UIString("Drop Image")}); 40 46 } 41 47 … … 44 50 get navigationItems() 45 51 { 46 return [this._showGridButtonNavigationItem]; 52 let items = super.navigationItems; 53 54 items.push(this._showGridButtonNavigationItem); 55 56 return items; 47 57 } 48 58 … … 62 72 } 63 73 64 this._imageElement = document.createElement("img"); 74 let imageContainer = this.element.appendChild(document.createElement("div")); 75 imageContainer.className = "img-container"; 76 77 this._imageElement = imageContainer.appendChild(document.createElement("img")); 65 78 this._imageElement.addEventListener("load", function() { URL.revokeObjectURL(objectURL); }); 66 79 this._imageElement.src = objectURL; … … 68 81 this._updateImageGrid(); 69 82 70 this.element.appendChild(this._imageElement); 83 this._imageElement.addEventListener("dragstart", (event) => { 84 console.assert(!this._draggingInternalImageElement); 85 this._draggingInternalImageElement = true; 86 }); 87 this._imageElement.addEventListener("dragend", (event) => { 88 console.assert(this._draggingInternalImageElement); 89 this._draggingInternalImageElement = false; 90 }); 91 92 if (this._dropZoneView) { 93 this._dropZoneView.targetElement = imageContainer; 94 this.addSubview(this._dropZoneView); 95 } 71 96 } 72 97 … … 87 112 88 113 super.hidden(); 114 } 115 116 closed() 117 { 118 WI.networkManager.removeEventListener(null, null, this); 119 120 super.closed(); 121 } 122 123 // DropZoneView delegate 124 125 dropZoneShouldAppearForDragEvent(dropZone, event) 126 { 127 // Do not appear if the drag is the current image inside this view. 128 if (this._draggingInternalImageElement) 129 return false; 130 131 // Appear if the drop contains a file. 132 return event.dataTransfer.types.includes("Files"); 133 } 134 135 dropZoneHandleDrop(dropZone, event) 136 { 137 let files = event.dataTransfer.files; 138 let file = files.length === 1 ? files[0] : null; 139 if (!file) { 140 InspectorFrontendHost.beep(); 141 return; 142 } 143 144 let fileReader = new FileReader; 145 fileReader.addEventListener("loadend", (event) => { 146 let localResourceOverride = WI.networkManager.localResourceOverrideForURL(this.resource.url); 147 if (!localResourceOverride) 148 return; 149 150 let dataURL = fileReader.result; 151 this._imageElement.src = dataURL; 152 153 let {base64, data, mimeType} = parseDataURL(dataURL); 154 155 // In case no mime type was determined, try to derive one from the file extension. 156 if (!mimeType || mimeType === "text/plain") { 157 let extension = WI.fileExtensionForFilename(file.name); 158 if (extension) 159 mimeType = WI.mimeTypeForFileExtension(extension); 160 } 161 162 let revision = localResourceOverride.localResource.currentRevision; 163 revision.updateRevisionContent(data, {base64Encoded: base64, mimeType}); 164 }); 165 fileReader.readAsDataURL(file); 89 166 } 90 167 -
trunk/Source/WebInspectorUI/UserInterface/Views/LocalResourceOverridePopover.js
r249831 r251024 119 119 statusCode = "200"; 120 120 if (!statusText) 121 statusText = WI.HTTPUtilities.statusTextForStatusCode( statusCode);121 statusText = WI.HTTPUtilities.statusTextForStatusCode(parseInt(statusCode)); 122 122 123 123 let popoverContentElement = document.createElement("div"); -
trunk/Source/WebInspectorUI/UserInterface/Views/LocalResourceOverrideTreeElement.js
r249831 r251024 126 126 let wasSelected = this.selected; 127 127 128 let revision = this._localResourceOverride.localResource.currentRevision; 128 129 let newLocalResourceOverride = WI.LocalResourceOverride.create({ 129 130 url, … … 132 133 statusText, 133 134 headers, 134 content: this._localResourceOverride.localResource.localContent,135 base64Encoded: this._localResourceOverride.localResource.localContentIsBase64Encoded,135 content: revision.content, 136 base64Encoded: revision.base64Encoded, 136 137 }); 137 138 -
trunk/Source/WebInspectorUI/UserInterface/Views/ResourceContentView.js
r247747 r251024 1 1 /* 2 * Copyright (C) 2013 , 2015Apple Inc. All rights reserved.2 * Copyright (C) 2013-2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 58 58 this.addIssue(issues[i]); 59 59 } 60 61 this._showingLocalResourceOverride = false; 62 63 if (WI.NetworkManager.supportsLocalResourceOverrides()) { 64 if (resource.isLocalResourceOverride) { 65 this._showingLocalResourceOverride = true; 66 67 this._localResourceOverrideBannerView = new WI.LocalResourceOverrideLabelView(resource); 68 69 this._removeLocalResourceOverrideButtonNavigationItem = new WI.ButtonNavigationItem("remove-local-resource-override", WI.UIString("Remove Local Override"), "Images/NavigationItemTrash.svg", 15, 15); 70 this._removeLocalResourceOverrideButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleRemoveLocalResourceOverride, this); 71 this._removeLocalResourceOverrideButtonNavigationItem.enabled = true; 72 this._removeLocalResourceOverrideButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low; 73 } else { 74 this._localResourceOverrideBannerView = new WI.LocalResourceOverrideWarningView(resource); 75 76 this._createLocalResourceOverrideButtonNavigationItem = new WI.ButtonNavigationItem("create-local-resource-override", WI.UIString("Create Local Override"), "Images/NavigationItemNetworkOverride.svg", 13, 14); 77 this._createLocalResourceOverrideButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleCreateLocalResourceOverride, this); 78 this._createLocalResourceOverrideButtonNavigationItem.enabled = false; // Enabled when the content is available. 79 this._createLocalResourceOverrideButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low; 80 } 81 82 WI.networkManager.addEventListener(WI.NetworkManager.Event.LocalResourceOverrideAdded, this._handleLocalResourceOverrideChanged, this); 83 WI.networkManager.addEventListener(WI.NetworkManager.Event.LocalResourceOverrideRemoved, this._handleLocalResourceOverrideChanged, this); 84 } 60 85 } 61 86 62 87 // Public 63 88 64 get resource() 65 { 66 return this._resource; 89 get resource() { return this._resource; } 90 get showingLocalResourceOverride() { return this._showingLocalResourceOverride; } 91 92 get navigationItems() 93 { 94 let items = []; 95 96 if (this._removeLocalResourceOverrideButtonNavigationItem) 97 items.push(this._removeLocalResourceOverrideButtonNavigationItem); 98 if (this._createLocalResourceOverrideButtonNavigationItem) 99 items.push(this._createLocalResourceOverrideButtonNavigationItem); 100 101 return items; 67 102 } 68 103 … … 80 115 { 81 116 throw WI.NotImplementedError.subclassMustOverride(); 117 } 118 119 localResourceOverrideInitialContent() 120 { 121 // Implemented by subclasses if needed. 122 return {}; 82 123 } 83 124 … … 111 152 super.closed(); 112 153 154 if (WI.NetworkManager.supportsLocalResourceOverrides()) 155 WI.networkManager.removeEventListener(null, null, this); 156 113 157 if (!this.managesOwnIssues) 114 158 WI.consoleManager.removeEventListener(null, null, this); … … 124 168 } 125 169 126 this.element.removeChildren(); 170 this.removeAllSubviews(); 171 172 if (this._localResourceOverrideBannerView) 173 this.addSubview(this._localResourceOverrideBannerView); 127 174 } 128 175 … … 145 192 console.assert(parameters.sourceCode === this._resource); 146 193 this.contentAvailable(parameters.sourceCode.content, parameters.base64Encoded); 194 195 if (this._createLocalResourceOverrideButtonNavigationItem) 196 this._createLocalResourceOverrideButtonNavigationItem.enabled = WI.networkManager.canBeOverridden(this._resource); 147 197 } 148 198 … … 169 219 170 220 var issue = event.data.issue; 171 if (!WI.ConsoleManager.issueMatchSourceCode(issue, this. resource))221 if (!WI.ConsoleManager.issueMatchSourceCode(issue, this._resource)) 172 222 return; 173 223 … … 175 225 } 176 226 227 async _handleCreateLocalResourceOverride(event) 228 { 229 let initialContent = this.localResourceOverrideInitialContent(); 230 let localResourceOverride = await this._resource.createLocalResourceOverride(initialContent); 231 WI.networkManager.addLocalResourceOverride(localResourceOverride); 232 WI.showLocalResourceOverride(localResourceOverride); 233 } 234 235 _handleRemoveLocalResourceOverride(event) 236 { 237 console.assert(this._showingLocalResourceOverride); 238 239 let localResourceOverride = WI.networkManager.localResourceOverrideForURL(this._resource.url); 240 WI.networkManager.removeLocalResourceOverride(localResourceOverride); 241 } 242 243 _handleLocalResourceOverrideChanged(event) 244 { 245 if (this._resource.url !== event.data.localResourceOverride.url) 246 return; 247 248 if (this._createLocalResourceOverrideButtonNavigationItem) 249 this._createLocalResourceOverrideButtonNavigationItem.enabled = WI.networkManager.canBeOverridden(this._resource); 250 } 251 177 252 _mouseWasClicked(event) 178 253 { 179 WI.handlePossibleLinkClick(event, this. resource.parentFrame);254 WI.handlePossibleLinkClick(event, this._resource.parentFrame); 180 255 } 181 256 }; -
trunk/Source/WebInspectorUI/UserInterface/Views/TextResourceContentView.js
r250149 r251024 57 57 WI.settings.enableControlFlowProfiler.addEventListener(WI.Setting.Event.Changed, this._enableControlFlowProfilerSettingChanged, this); 58 58 59 this._showingLocalResourceOverride = false;60 61 if (WI.NetworkManager.supportsLocalResourceOverrides()) {62 if (resource instanceof WI.Resource && resource.isLocalResourceOverride) {63 this._showingLocalResourceOverride = true;64 this._localResourceOverrideBannerView = new WI.LocalResourceOverrideLabelView(resource);65 66 this._removeLocalResourceOverrideButtonNavigationItem = new WI.ButtonNavigationItem("remove-local-resource-override", WI.UIString("Remove Local Override"), "Images/NavigationItemTrash.svg", 15, 15);67 this._removeLocalResourceOverrideButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleRemoveLocalResourceOverride, this);68 this._removeLocalResourceOverrideButtonNavigationItem.enabled = true;69 this._removeLocalResourceOverrideButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;70 } else {71 this._localResourceOverrideBannerView = new WI.LocalResourceOverrideWarningView(resource);72 73 this._createLocalResourceOverrideButtonNavigationItem = new WI.ButtonNavigationItem("create-local-resource-override", WI.UIString("Create Local Override"), "Images/NavigationItemNetworkOverride.svg", 13, 14);74 this._createLocalResourceOverrideButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleCreateLocalResourceOverride, this);75 this._createLocalResourceOverrideButtonNavigationItem.enabled = false; // Enabled when the text editor is populated with content.76 this._createLocalResourceOverrideButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;77 }78 }79 80 59 this._textEditor = new WI.SourceCodeTextEditor(resource); 81 60 this._textEditor.addEventListener(WI.TextEditor.Event.ExecutionLineNumberDidChange, this._executionLineNumberDidChange, this); … … 90 69 WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ProbeSetAdded, this._probeSetsChanged, this); 91 70 WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ProbeSetRemoved, this._probeSetsChanged, this); 92 93 if (WI.NetworkManager.supportsLocalResourceOverrides()) {94 WI.networkManager.addEventListener(WI.NetworkManager.Event.LocalResourceOverrideAdded, this._handleLocalResourceOverrideChanged, this);95 WI.networkManager.addEventListener(WI.NetworkManager.Event.LocalResourceOverrideRemoved, this._handleLocalResourceOverrideChanged, this);96 }97 71 } 98 72 … … 101 75 get navigationItems() 102 76 { 103 let items = []; 104 105 if (this._removeLocalResourceOverrideButtonNavigationItem) 106 items.push(this._removeLocalResourceOverrideButtonNavigationItem); 107 if (this._createLocalResourceOverrideButtonNavigationItem) 108 items.push(this._createLocalResourceOverrideButtonNavigationItem); 77 let items = super.navigationItems; 109 78 110 79 items.push(this._prettyPrintButtonNavigationItem); 111 80 112 if (!this. _showingLocalResourceOverride)81 if (!this.showingLocalResourceOverride) 113 82 items.push(this._showTypesButtonNavigationItem, this._codeCoverageButtonNavigationItem); 114 83 … … 176 145 } 177 146 147 localResourceOverrideInitialContent() 148 { 149 return {initialContent: this._textEditor.string}; 150 } 151 178 152 get supportsSave() 179 153 { … … 244 218 this.removeLoadingIndicator(); 245 219 246 if (this._localResourceOverrideBannerView)247 this.addSubview(this._localResourceOverrideBannerView);248 249 220 this.addSubview(this._textEditor); 250 221 } … … 252 223 _contentDidPopulate(event) 253 224 { 254 if (this._createLocalResourceOverrideButtonNavigationItem)255 this._createLocalResourceOverrideButtonNavigationItem.enabled = WI.networkManager.canBeOverridden(this.resource);256 257 225 this._prettyPrintButtonNavigationItem.enabled = this._textEditor.canBeFormatted(); 258 226 … … 262 230 this._codeCoverageButtonNavigationItem.enabled = this._textEditor.canShowCoverageHints(); 263 231 this._codeCoverageButtonNavigationItem.activated = WI.settings.enableControlFlowProfiler.value; 264 }265 266 async _handleCreateLocalResourceOverride(event)267 {268 let localResourceOverride = await this.resource.createLocalResourceOverride(this._textEditor.string);269 WI.networkManager.addLocalResourceOverride(localResourceOverride);270 WI.showLocalResourceOverride(localResourceOverride);271 }272 273 _handleRemoveLocalResourceOverride(event)274 {275 console.assert(this._showingLocalResourceOverride);276 277 let localResourceOverride = WI.networkManager.localResourceOverrideForURL(this.resource.url);278 WI.networkManager.removeLocalResourceOverride(localResourceOverride);279 232 } 280 233 … … 321 274 } 322 275 323 _handleLocalResourceOverrideChanged(event)324 {325 if (this.resource.url !== event.data.localResourceOverride.url)326 return;327 328 if (this._createLocalResourceOverrideButtonNavigationItem)329 this._createLocalResourceOverrideButtonNavigationItem.enabled = WI.networkManager.canBeOverridden(this.resource);330 }331 332 276 _sourceCodeContentDidChange(event) 333 277 { … … 341 285 { 342 286 this._ignoreSourceCodeContentDidChangeEvent = true; 343 this.resource.currentRevision. content = this._textEditor.string;287 this.resource.currentRevision.updateRevisionContent(this._textEditor.string); 344 288 this._ignoreSourceCodeContentDidChangeEvent = false; 345 289 } … … 375 319 return true; 376 320 377 if (this. _showingLocalResourceOverride)321 if (this.showingLocalResourceOverride) 378 322 return true; 379 323
Note:
See TracChangeset
for help on using the changeset viewer.