Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/sources/SourceFormatter.js

Issue 2888843002: DevTools: fix race when revealing formatted source code (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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<string, !Promise<!Sources.SourceFormatData>>} */
40 this._formattedPaths = new Map(); 40 this._formattedPaths = 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 formatDataPromise = this._formattedPaths.get(uiSourceCode.project().id() + ':' + uiSourceCode.url());
53 if (formattedUISourceCode) 53 if (formatDataPromise)
54 this.discardFormattedUISourceCode(formattedUISourceCode); 54 formatDataPromise.then(formatData => this.discardFormattedUISourceCode(for matData.formattedSourceCode));
lushnikov 2017/05/17 23:39:08 Since you're caching per projectId + uiSourceCodeU
lushnikov 2017/05/17 23:57:32 this._formattedPath.delete(path);
55 } 55 }
56 56
57 /** 57 /**
58 * @param {!Workspace.UISourceCode} formattedUISourceCode 58 * @param {!Workspace.UISourceCode} formattedUISourceCode
59 * @return {?Workspace.UISourceCode} 59 * @return {?Workspace.UISourceCode}
60 */ 60 */
61 discardFormattedUISourceCode(formattedUISourceCode) { 61 discardFormattedUISourceCode(formattedUISourceCode) {
62 var formatData = Sources.SourceFormatData._for(formattedUISourceCode); 62 var formatData = Sources.SourceFormatData._for(formattedUISourceCode);
63 if (!formatData) 63 if (!formatData)
64 return null; 64 return null;
65 65
66 delete formattedUISourceCode[Sources.SourceFormatData._formatDataSymbol]; 66 delete formattedUISourceCode[Sources.SourceFormatData._formatDataSymbol];
67 this._scriptMapping._setSourceMappingEnabled(formatData, false); 67 this._scriptMapping._setSourceMappingEnabled(formatData, false);
68 this._styleMapping._setSourceMappingEnabled(formatData, false); 68 this._styleMapping._setSourceMappingEnabled(formatData, false);
69 this._project.removeFile(formattedUISourceCode.url()); 69 this._project.removeFile(formattedUISourceCode.url());
70 this._formattedPaths.remove(formatData.originalPath()); 70 var originalSourceCode = formatData.originalSourceCode;
71 return formatData.originalSourceCode; 71 this._formattedPaths.remove(originalSourceCode.project().id() + ':' + origin alSourceCode.url());
72 return originalSourceCode;
72 } 73 }
73 74
74 /** 75 /**
75 * @param {!Workspace.UISourceCode} uiSourceCode 76 * @param {!Workspace.UISourceCode} uiSourceCode
76 * @return {boolean} 77 * @return {boolean}
77 */ 78 */
78 hasFormatted(uiSourceCode) { 79 hasFormatted(uiSourceCode) {
79 return this._formattedPaths.has(uiSourceCode.project().id() + ':' + uiSource Code.url()); 80 return this._formattedPaths.has(uiSourceCode.project().id() + ':' + uiSource Code.url());
80 } 81 }
81 82
82 /** 83 /**
83 * @param {!Workspace.UISourceCode} uiSourceCode 84 * @param {!Workspace.UISourceCode} uiSourceCode
84 * @return {!Promise<!Sources.SourceFormatData>} 85 * @return {!Promise<!Sources.SourceFormatData>}
85 */ 86 */
86 async format(uiSourceCode) { 87 async format(uiSourceCode) {
87 var formattedUISourceCode = this._formattedPaths.get(uiSourceCode.project(). id() + ':' + uiSourceCode.url()); 88 var path = uiSourceCode.project().id() + ':' + uiSourceCode.url();
88 if (formattedUISourceCode) 89 var resultPromise = this._formattedPaths.get(path);
89 return Sources.SourceFormatData._for(formattedUISourceCode); 90 if (resultPromise)
91 return resultPromise;
90 92
93 var fulfillFormatPromise;
94 resultPromise = new Promise(fulfill => {
95 fulfillFormatPromise = fulfill;
96 });
97 this._formattedPaths.set(path, resultPromise);
91 var content = await uiSourceCode.requestContent(); 98 var content = await uiSourceCode.requestContent();
92 var highlighterType = Bindings.NetworkProject.uiSourceCodeMimeType(uiSourceC ode); 99 var highlighterType = Bindings.NetworkProject.uiSourceCodeMimeType(uiSourceC ode);
93 var fulfillFormatPromise;
94 var resultPromise = new Promise(fulfill => {
95 fulfillFormatPromise = fulfill;
96 });
97 Sources.Formatter.format(uiSourceCode.contentType(), highlighterType, conten t || '', innerCallback.bind(this)); 100 Sources.Formatter.format(uiSourceCode.contentType(), highlighterType, conten t || '', innerCallback.bind(this));
98 return resultPromise; 101 return resultPromise;
99 102
100 /** 103 /**
101 * @this Sources.SourceFormatter 104 * @this Sources.SourceFormatter
102 * @param {string} formattedContent 105 * @param {string} formattedContent
103 * @param {!Sources.FormatterSourceMapping} formatterMapping 106 * @param {!Sources.FormatterSourceMapping} formatterMapping
104 */ 107 */
105 function innerCallback(formattedContent, formatterMapping) { 108 function innerCallback(formattedContent, formatterMapping) {
106 var formattedURL = uiSourceCode.url() + ':formatted'; 109 var formattedURL = uiSourceCode.url() + ':formatted';
lushnikov 2017/05/17 23:57:32 if (this._formattedPaths.get(path) !== resultPromi
caseq 2017/05/18 02:04:37 Done.
107 var contentProvider = 110 var contentProvider =
108 Common.StaticContentProvider.fromString(formattedURL, uiSourceCode.con tentType(), formattedContent); 111 Common.StaticContentProvider.fromString(formattedURL, uiSourceCode.con tentType(), formattedContent);
109 var formattedUISourceCode = this._project.addContentProvider(formattedURL, contentProvider); 112 var formattedUISourceCode = this._project.addContentProvider(formattedURL, contentProvider);
110 var formatData = new Sources.SourceFormatData(uiSourceCode, formattedUISou rceCode, formatterMapping); 113 var formatData = new Sources.SourceFormatData(uiSourceCode, formattedUISou rceCode, formatterMapping);
111 formattedUISourceCode[Sources.SourceFormatData._formatDataSymbol] = format Data; 114 formattedUISourceCode[Sources.SourceFormatData._formatDataSymbol] = format Data;
112 this._scriptMapping._setSourceMappingEnabled(formatData, true); 115 this._scriptMapping._setSourceMappingEnabled(formatData, true);
113 this._styleMapping._setSourceMappingEnabled(formatData, true); 116 this._styleMapping._setSourceMappingEnabled(formatData, true);
114 117
115 var path = formatData.originalPath();
116 this._formattedPaths.set(path, formattedUISourceCode);
117
118 for (var decoration of uiSourceCode.allDecorations()) { 118 for (var decoration of uiSourceCode.allDecorations()) {
119 var range = decoration.range(); 119 var range = decoration.range();
120 var startLocation = formatterMapping.originalToFormatted(range.startLine , range.startColumn); 120 var startLocation = formatterMapping.originalToFormatted(range.startLine , range.startColumn);
121 var endLocation = formatterMapping.originalToFormatted(range.endLine, ra nge.endColumn); 121 var endLocation = formatterMapping.originalToFormatted(range.endLine, ra nge.endColumn);
122 122
123 formattedUISourceCode.addDecoration( 123 formattedUISourceCode.addDecoration(
124 new TextUtils.TextRange(startLocation[0], startLocation[1], endLocat ion[0], endLocation[1]), 124 new TextUtils.TextRange(startLocation[0], startLocation[1], endLocat ion[0], endLocation[1]),
125 /** @type {string} */ (decoration.type()), decoration.data()); 125 /** @type {string} */ (decoration.type()), decoration.data());
126 } 126 }
127 127
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 return; 283 return;
284 if (enable) 284 if (enable)
285 styleHeader[Sources.SourceFormatData._formatDataSymbol] = formatData; 285 styleHeader[Sources.SourceFormatData._formatDataSymbol] = formatData;
286 else 286 else
287 delete styleHeader[Sources.SourceFormatData._formatDataSymbol]; 287 delete styleHeader[Sources.SourceFormatData._formatDataSymbol];
288 Bindings.cssWorkspaceBinding.updateLocations(styleHeader); 288 Bindings.cssWorkspaceBinding.updateLocations(styleHeader);
289 } 289 }
290 }; 290 };
291 291
292 Sources.sourceFormatter = new Sources.SourceFormatter(); 292 Sources.sourceFormatter = new Sources.SourceFormatter();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698