| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 Sources.SourceFormatData = class { | 5 Sources.SourceFormatData = class { |
| 6 /** | 6 /** |
| 7 * @param {!Workspace.UISourceCode} originalSourceCode | 7 * @param {!Workspace.UISourceCode} originalSourceCode |
| 8 * @param {!Workspace.UISourceCode} formattedSourceCode | 8 * @param {!Workspace.UISourceCode} formattedSourceCode |
| 9 * @param {!Sources.FormatterSourceMapping} mapping | 9 * @param {!Sources.FormatterSourceMapping} mapping |
| 10 */ | 10 */ |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 | 29 |
| 30 Sources.SourceFormatData._formatDataSymbol = Symbol('formatData'); | 30 Sources.SourceFormatData._formatDataSymbol = Symbol('formatData'); |
| 31 | 31 |
| 32 Sources.SourceFormatter = class { | 32 Sources.SourceFormatter = class { |
| 33 constructor() { | 33 constructor() { |
| 34 this._projectId = 'formatter:'; | 34 this._projectId = 'formatter:'; |
| 35 this._project = new Bindings.ContentProviderBasedProject( | 35 this._project = new Bindings.ContentProviderBasedProject( |
| 36 Workspace.workspace, this._projectId, Workspace.projectTypes.Formatter,
'formatter', | 36 Workspace.workspace, this._projectId, Workspace.projectTypes.Formatter,
'formatter', |
| 37 true /* isServiceProject */); | 37 true /* isServiceProject */); |
| 38 | 38 |
| 39 /** @type {!Map<string, !Workspace.UISourceCode>} */ | 39 /** @type {!Map<!Workspace.UISourceCode, !{promise: !Promise<!Sources.Source
FormatData>, formatData: ?Sources.SourceFormatData}>} */ |
| 40 this._formattedPaths = new Map(); | 40 this._formattedSourceCodes = new Map(); |
| 41 this._scriptMapping = new Sources.SourceFormatter.ScriptMapping(); | 41 this._scriptMapping = new Sources.SourceFormatter.ScriptMapping(); |
| 42 this._styleMapping = new Sources.SourceFormatter.StyleMapping(); | 42 this._styleMapping = new Sources.SourceFormatter.StyleMapping(); |
| 43 Workspace.workspace.addEventListener( | 43 Workspace.workspace.addEventListener( |
| 44 Workspace.Workspace.Events.UISourceCodeRemoved, this._onUISourceCodeRemo
ved, this); | 44 Workspace.Workspace.Events.UISourceCodeRemoved, this._onUISourceCodeRemo
ved, this); |
| 45 } | 45 } |
| 46 | 46 |
| 47 /** | 47 /** |
| 48 * @param {!Common.Event} event | 48 * @param {!Common.Event} event |
| 49 */ | 49 */ |
| 50 _onUISourceCodeRemoved(event) { | 50 _onUISourceCodeRemoved(event) { |
| 51 var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data); | 51 var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data); |
| 52 var formattedUISourceCode = this._formattedPaths.get(uiSourceCode.project().
id() + ':' + uiSourceCode.url()); | 52 var cacheEntry = this._formattedSourceCodes.get(uiSourceCode); |
| 53 if (formattedUISourceCode) | 53 if (cacheEntry && cacheEntry.formatData) |
| 54 this.discardFormattedUISourceCode(formattedUISourceCode); | 54 this._discardFormatData(cacheEntry.formatData); |
| 55 this._formattedSourceCodes.remove(uiSourceCode); |
| 55 } | 56 } |
| 56 | 57 |
| 57 /** | 58 /** |
| 58 * @param {!Workspace.UISourceCode} formattedUISourceCode | 59 * @param {!Workspace.UISourceCode} formattedUISourceCode |
| 59 * @return {?Workspace.UISourceCode} | 60 * @return {?Workspace.UISourceCode} |
| 60 */ | 61 */ |
| 61 discardFormattedUISourceCode(formattedUISourceCode) { | 62 discardFormattedUISourceCode(formattedUISourceCode) { |
| 62 var formatData = Sources.SourceFormatData._for(formattedUISourceCode); | 63 var formatData = Sources.SourceFormatData._for(formattedUISourceCode); |
| 63 if (!formatData) | 64 if (!formatData) |
| 64 return null; | 65 return null; |
| 65 | 66 this._discardFormatData(formatData); |
| 66 delete formattedUISourceCode[Sources.SourceFormatData._formatDataSymbol]; | 67 this._formattedSourceCodes.remove(formatData.originalSourceCode); |
| 67 this._scriptMapping._setSourceMappingEnabled(formatData, false); | |
| 68 this._styleMapping._setSourceMappingEnabled(formatData, false); | |
| 69 this._project.removeFile(formattedUISourceCode.url()); | |
| 70 this._formattedPaths.remove(formatData.originalPath()); | |
| 71 return formatData.originalSourceCode; | 68 return formatData.originalSourceCode; |
| 72 } | 69 } |
| 73 | 70 |
| 74 /** | 71 /** |
| 72 * @param {!Sources.SourceFormatData} formatData |
| 73 */ |
| 74 _discardFormatData(formatData) { |
| 75 delete formatData.formattedSourceCode[Sources.SourceFormatData._formatDataSy
mbol]; |
| 76 this._scriptMapping._setSourceMappingEnabled(formatData, false); |
| 77 this._styleMapping._setSourceMappingEnabled(formatData, false); |
| 78 this._project.removeFile(formatData.formattedSourceCode.url()); |
| 79 } |
| 80 |
| 81 /** |
| 75 * @param {!Workspace.UISourceCode} uiSourceCode | 82 * @param {!Workspace.UISourceCode} uiSourceCode |
| 76 * @return {boolean} | 83 * @return {boolean} |
| 77 */ | 84 */ |
| 78 hasFormatted(uiSourceCode) { | 85 hasFormatted(uiSourceCode) { |
| 79 return this._formattedPaths.has(uiSourceCode.project().id() + ':' + uiSource
Code.url()); | 86 return this._formattedSourceCodes.has(uiSourceCode); |
| 80 } | 87 } |
| 81 | 88 |
| 82 /** | 89 /** |
| 83 * @param {!Workspace.UISourceCode} uiSourceCode | 90 * @param {!Workspace.UISourceCode} uiSourceCode |
| 84 * @return {!Promise<!Sources.SourceFormatData>} | 91 * @return {!Promise<!Sources.SourceFormatData>} |
| 85 */ | 92 */ |
| 86 async format(uiSourceCode) { | 93 async format(uiSourceCode) { |
| 87 var formattedUISourceCode = this._formattedPaths.get(uiSourceCode.project().
id() + ':' + uiSourceCode.url()); | 94 var cacheEntry = this._formattedSourceCodes.get(uiSourceCode); |
| 88 if (formattedUISourceCode) | 95 if (cacheEntry) |
| 89 return Sources.SourceFormatData._for(formattedUISourceCode); | 96 return cacheEntry.promise; |
| 90 | 97 |
| 91 var content = await uiSourceCode.requestContent(); | |
| 92 var fulfillFormatPromise; | 98 var fulfillFormatPromise; |
| 93 var resultPromise = new Promise(fulfill => { | 99 var resultPromise = new Promise(fulfill => { |
| 94 fulfillFormatPromise = fulfill; | 100 fulfillFormatPromise = fulfill; |
| 95 }); | 101 }); |
| 96 Sources.Formatter.format( | 102 this._formattedSourceCodes.set(uiSourceCode, {promise: resultPromise, format
Data: null}); |
| 97 uiSourceCode.contentType(), uiSourceCode.mimeType(), content || '', inne
rCallback.bind(this)); | 103 var content = await uiSourceCode.requestContent(); |
| 104 // ------------ ASYNC ------------ |
| 105 Sources.Formatter.format(uiSourceCode.contentType(), uiSourceCode.mimeType()
, content || '', formatDone.bind(this)); |
| 98 return resultPromise; | 106 return resultPromise; |
| 99 | 107 |
| 100 /** | 108 /** |
| 101 * @this Sources.SourceFormatter | 109 * @this Sources.SourceFormatter |
| 102 * @param {string} formattedContent | 110 * @param {string} formattedContent |
| 103 * @param {!Sources.FormatterSourceMapping} formatterMapping | 111 * @param {!Sources.FormatterSourceMapping} formatterMapping |
| 104 */ | 112 */ |
| 105 function innerCallback(formattedContent, formatterMapping) { | 113 function formatDone(formattedContent, formatterMapping) { |
| 106 var formattedURL = uiSourceCode.url() + ':formatted'; | 114 var cacheEntry = this._formattedSourceCodes.get(uiSourceCode); |
| 115 if (!cacheEntry || cacheEntry.promise !== resultPromise) |
| 116 return; |
| 117 var formattedURL; |
| 118 var count = 0; |
| 119 var suffix = ''; |
| 120 do { |
| 121 formattedURL = `${uiSourceCode.url()}:formatted${suffix}`; |
| 122 suffix = `:${count++}`; |
| 123 } while (this._project.uiSourceCodeForURL(formattedURL)); |
| 107 var contentProvider = | 124 var contentProvider = |
| 108 Common.StaticContentProvider.fromString(formattedURL, uiSourceCode.con
tentType(), formattedContent); | 125 Common.StaticContentProvider.fromString(formattedURL, uiSourceCode.con
tentType(), formattedContent); |
| 109 var formattedUISourceCode = | 126 var formattedUISourceCode = |
| 110 this._project.addContentProvider(formattedURL, contentProvider, uiSour
ceCode.mimeType()); | 127 this._project.addContentProvider(formattedURL, contentProvider, uiSour
ceCode.mimeType()); |
| 111 var formatData = new Sources.SourceFormatData(uiSourceCode, formattedUISou
rceCode, formatterMapping); | 128 var formatData = new Sources.SourceFormatData(uiSourceCode, formattedUISou
rceCode, formatterMapping); |
| 112 formattedUISourceCode[Sources.SourceFormatData._formatDataSymbol] = format
Data; | 129 formattedUISourceCode[Sources.SourceFormatData._formatDataSymbol] = format
Data; |
| 113 this._scriptMapping._setSourceMappingEnabled(formatData, true); | 130 this._scriptMapping._setSourceMappingEnabled(formatData, true); |
| 114 this._styleMapping._setSourceMappingEnabled(formatData, true); | 131 this._styleMapping._setSourceMappingEnabled(formatData, true); |
| 115 | 132 cacheEntry.formatData = formatData; |
| 116 var path = formatData.originalPath(); | |
| 117 this._formattedPaths.set(path, formattedUISourceCode); | |
| 118 | 133 |
| 119 for (var decoration of uiSourceCode.allDecorations()) { | 134 for (var decoration of uiSourceCode.allDecorations()) { |
| 120 var range = decoration.range(); | 135 var range = decoration.range(); |
| 121 var startLocation = formatterMapping.originalToFormatted(range.startLine
, range.startColumn); | 136 var startLocation = formatterMapping.originalToFormatted(range.startLine
, range.startColumn); |
| 122 var endLocation = formatterMapping.originalToFormatted(range.endLine, ra
nge.endColumn); | 137 var endLocation = formatterMapping.originalToFormatted(range.endLine, ra
nge.endColumn); |
| 123 | 138 |
| 124 formattedUISourceCode.addDecoration( | 139 formattedUISourceCode.addDecoration( |
| 125 new TextUtils.TextRange(startLocation[0], startLocation[1], endLocat
ion[0], endLocation[1]), | 140 new TextUtils.TextRange(startLocation[0], startLocation[1], endLocat
ion[0], endLocation[1]), |
| 126 /** @type {string} */ (decoration.type()), decoration.data()); | 141 /** @type {string} */ (decoration.type()), decoration.data()); |
| 127 } | 142 } |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 headers.forEach(header => header[Sources.SourceFormatData._formatDataSymbo
l] = formatData); | 302 headers.forEach(header => header[Sources.SourceFormatData._formatDataSymbo
l] = formatData); |
| 288 } else { | 303 } else { |
| 289 original[this._headersSymbol] = null; | 304 original[this._headersSymbol] = null; |
| 290 headers.forEach(header => delete header[Sources.SourceFormatData._formatDa
taSymbol]); | 305 headers.forEach(header => delete header[Sources.SourceFormatData._formatDa
taSymbol]); |
| 291 } | 306 } |
| 292 headers.forEach(header => Bindings.cssWorkspaceBinding.updateLocations(heade
r)); | 307 headers.forEach(header => Bindings.cssWorkspaceBinding.updateLocations(heade
r)); |
| 293 } | 308 } |
| 294 }; | 309 }; |
| 295 | 310 |
| 296 Sources.sourceFormatter = new Sources.SourceFormatter(); | 311 Sources.sourceFormatter = new Sources.SourceFormatter(); |
| OLD | NEW |