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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/coverage/CoverageDecorationManager.js

Issue 2865573003: DevTools: support live coverage (Closed)
Patch Set: fixed accidentally creating too many promises for one resource 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
(Empty)
1 // Copyright (c) 2017 The Chromium Authors. All rights reserved.
dgozman 2017/05/05 19:21:19 no (c)
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 Coverage.CoverageDecorationManager = class {
6 /**
7 * @param {!Coverage.CoverageModel} coverageModel
8 */
9 constructor(coverageModel) {
10 this._coverageModel = coverageModel;
11 /** @type !Map<!Common.ContentProvider, ?TextUtils.Text> */
12 this._textByProvider = new Map();
13 /** @type !Multimap<!Common.ContentProvider, !Workspace.UISourceCode> */
14 this._uiSourceCodeByContentProvider = new Multimap();
15
16 for (var project of Workspace.workspace.projects()) {
dgozman 2017/05/05 19:21:19 Use Workspace.uiSourceCodes().
17 for (var uiSourceCode of project.uiSourceCodes())
18 uiSourceCode.addLineDecoration(0, Coverage.CoverageDecorationManager._de coratorType, this);
19 }
20 Workspace.workspace.addEventListener(Workspace.Workspace.Events.UISourceCode Added, this._onUISourceCodeAdded, this);
21 }
22
23 dispose() {
24 for (var project of Workspace.workspace.projects()) {
25 for (var uiSourceCode of project.uiSourceCodes())
dgozman 2017/05/05 19:21:19 ditto
26 uiSourceCode.removeDecorationsForType(Coverage.CoverageDecorationManager ._decoratorType);
27 }
28 Workspace.workspace.removeEventListener(
29 Workspace.Workspace.Events.UISourceCodeAdded, this._onUISourceCodeAdded, this);
30 }
31
32 /**
33 * @param {!Array<!Coverage.CoverageInfo>} updatedEntries
34 */
35 update(updatedEntries) {
36 for (var entry of updatedEntries) {
37 for (var uiSourceCode of this._uiSourceCodeByContentProvider.get(entry.con tentProvider())) {
38 uiSourceCode.removeDecorationsForType(Coverage.CoverageDecorationManager ._decoratorType);
39 uiSourceCode.addLineDecoration(0, Coverage.CoverageDecorationManager._de coratorType, this);
40 }
41 }
42 }
43
44 /**
45 * @param {!Workspace.UISourceCode} uiSourceCode
46 * @return {!Promise<!Array<boolean>>}
47 */
48 async usageByLine(uiSourceCode) {
49 var result = [];
50 var sourceText = new TextUtils.Text(uiSourceCode.content() || '');
51 await this._updateTexts(uiSourceCode, sourceText);
52 var lineEndings = sourceText.lineEndings();
53 for (var line = 0; line < sourceText.lineCount(); ++line) {
54 var lineLength = lineEndings[line] - (line ? lineEndings[line - 1] : 0);
55 var startLocations = this._rawLocationsForSourceLocation(uiSourceCode, lin e, 0);
56 var endLocations = this._rawLocationsForSourceLocation(uiSourceCode, line, lineLength - 1);
57 var startLocationsByProvider = new Map(startLocations.map(location => [loc ation.contentProvider, location]));
alph 2017/05/05 19:18:08 can it have several locations with he same provide
58 var used = false;
59 for (var end of endLocations) {
alph 2017/05/05 19:18:08 nit: var used = endLocations.some(...); ;-)
60 var start = startLocationsByProvider.get(end.contentProvider);
61 var text = this._textByProvider.get(end.contentProvider);
62 if (!start || !text)
63 continue;
64 var textValue = text.value();
65 var startOffset = text.offsetFromPosition(start.line, start.column);
66 var endOffset = text.offsetFromPosition(end.line, end.column);
67 while (startOffset < endOffset && /\s/.test(textValue[startOffset]))
alph 2017/05/05 19:18:08 Have you considered using substr and match with /^
alph 2017/05/05 19:18:08 <=
68 ++startOffset;
69 while (startOffset < endOffset && /\s/.test(textValue[endOffset]))
alph 2017/05/05 19:18:08 ditto
70 --endOffset;
71 used = this._coverageModel.usageForRange(end.contentProvider, startOffse t, endOffset);
72 if (used)
73 break;
74 }
75 result.push(used);
76 }
77 return result;
78 }
79
80 /**
81 * @param {!Workspace.UISourceCode} uiSourceCode
82 * @param {!TextUtils.Text} text
83 * @return !Promise
alph 2017/05/05 19:18:08 I'm ok with using the clean syntax, but I know cou
84 */
85 _updateTexts(uiSourceCode, text) {
86 var promises = [];
87 for (var line = 0; line < text.lineCount(); ++line) {
88 for (var entry of this._rawLocationsForSourceLocation(uiSourceCode, line, 0)) {
89 if (!this._textByProvider.has(entry.contentProvider)) {
alph 2017/05/05 19:18:08 if (...) continue;
90 this._textByProvider.set(entry.contentProvider, null);
91 this._uiSourceCodeByContentProvider.set(entry.contentProvider, uiSourc eCode);
92 promises.push(this._updateTextForProvider(entry.contentProvider));
93 }
94 }
95 }
96 return Promise.all(promises);
97 }
98
99 /**
100 * @param {!Common.ContentProvider} contentProvider
alph 2017/05/05 19:18:08 @return
101 */
102 async _updateTextForProvider(contentProvider) {
103 var content = await contentProvider.requestContent();
104 this._textByProvider.set(contentProvider, new TextUtils.Text(content));
105 }
106
107 /**
108 * @param {!Workspace.UISourceCode} uiSourceCode
109 * @param {number} line
110 * @param {number} column
111 * @return {!Array<!{contentProvider: !Common.ContentProvider, line: number, c olumn: number}>}
112 */
113 _rawLocationsForSourceLocation(uiSourceCode, line, column) {
114 if (uiSourceCode.contentType().hasScripts()) {
115 var location = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(u iSourceCode, line, column);
116 return location && location.script() ?
dgozman 2017/05/05 19:21:19 html file could have both css and js locations.
117 [{contentProvider: location.script(), line: location.lineNumber, colum n: location.columnNumber}] :
118 [];
119 }
120 var rawStyleLocations =
121 Bindings.cssWorkspaceBinding.uiLocationToRawLocations(new Workspace.UILo cation(uiSourceCode, line, 0));
122 var result = [];
123 for (var location of rawStyleLocations) {
124 if (!location.header())
125 continue;
126 result.push({contentProvider: location.header(), line: location.lineNumber , column: location.columnNumber});
127 }
128 return result;
129 }
130
131 /**
132 * @param {!Common.Event} event
133 */
134 _onUISourceCodeAdded(event) {
135 var uiSourceCode = /** @type !Workspace.UISourceCode */ (event.data);
136 uiSourceCode.addLineDecoration(0, Coverage.CoverageDecorationManager._decora torType, this);
137 }
138 };
139
140 Coverage.CoverageDecorationManager._decoratorType = 'coverage';
141
142 /**
143 * @implements {SourceFrame.UISourceCodeFrame.LineDecorator}
144 */
145 Coverage.CoverageView.LineDecorator = class {
146 /**
147 * @override
148 * @param {!Workspace.UISourceCode} uiSourceCode
149 * @param {!TextEditor.CodeMirrorTextEditor} textEditor
150 */
151 decorate(uiSourceCode, textEditor) {
152 var decorations = uiSourceCode.decorationsForType(Coverage.CoverageDecoratio nManager._decoratorType);
153 if (!decorations.size) {
154 textEditor.uninstallGutter(Coverage.CoverageView.LineDecorator._gutterType );
155 return;
156 }
157 var decorationManager =
158 /** @type {!Coverage.CoverageDecorationManager} */ (decorations.values() .next().value.data());
159 decorationManager.usageByLine(uiSourceCode).then(lineUsage => {
160 textEditor.operation(() => this._innerDecorate(textEditor, lineUsage));
161 });
162 }
163
164 /**
165 * @param {!TextEditor.CodeMirrorTextEditor} textEditor
166 * @param {!Array<boolean>} lineUsage
167 */
168 _innerDecorate(textEditor, lineUsage) {
169 var gutterType = Coverage.CoverageView.LineDecorator._gutterType;
170 textEditor.uninstallGutter(gutterType);
171 textEditor.installGutter(gutterType, false);
172 for (var line = 0; line < lineUsage.length; ++line) {
173 var className = lineUsage[line] ? 'text-editor-coverage-used-marker' : 'te xt-editor-coverage-unused-marker';
174 textEditor.setGutterDecoration(line, gutterType, createElementWithClass('d iv', className));
175 }
176 }
177 };
178
179 Coverage.CoverageView.LineDecorator._gutterType = 'CodeMirror-gutter-coverage';
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698