OLD | NEW |
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 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 CSSTracker.CSSTrackerView = class extends UI.VBox { | 5 CSSTracker.CSSTrackerView = class extends UI.VBox { |
6 constructor() { | 6 constructor() { |
7 super(true); | 7 super(true); |
8 | 8 |
9 this.registerRequiredCSS('css_tracker/cssTrackerView.css'); | 9 this.registerRequiredCSS('css_tracker/cssTrackerView.css'); |
10 | 10 |
11 var toolbarContainer = this.contentElement.createChild('div', 'css-tracker-t
oolbar-container'); | 11 var toolbarContainer = this.contentElement.createChild('div', 'css-tracker-t
oolbar-container'); |
12 var topToolbar = new UI.Toolbar('css-tracker-toolbar', toolbarContainer); | 12 var topToolbar = new UI.Toolbar('css-tracker-toolbar', toolbarContainer); |
13 | 13 |
14 this._recordButton = new UI.ToolbarToggle(Common.UIString('Start recording')
, | 14 this._recordButton = |
15 'largeicon-resume', | 15 new UI.ToolbarToggle(Common.UIString('Start recording'), 'largeicon-resu
me', 'largeicon-pause'); |
16 'largeicon-pause'); | |
17 this._recordButton.addEventListener(UI.ToolbarButton.Events.Click, () => thi
s._toggleRecording(!this._isRecording)); | 16 this._recordButton.addEventListener(UI.ToolbarButton.Events.Click, () => thi
s._toggleRecording(!this._isRecording)); |
18 topToolbar.appendToolbarItem(this._recordButton); | 17 topToolbar.appendToolbarItem(this._recordButton); |
19 | 18 |
20 var clearButton = new UI.ToolbarButton(Common.UIString('Clear all'), 'largei
con-clear'); | 19 var clearButton = new UI.ToolbarButton(Common.UIString('Clear all'), 'largei
con-clear'); |
21 clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._reset.bind
(this)); | 20 clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._reset.bind
(this)); |
22 topToolbar.appendToolbarItem(clearButton); | 21 topToolbar.appendToolbarItem(clearButton); |
23 | 22 |
24 this._cssResultsElement = this.contentElement.createChild('div', 'css-result
s'); | 23 this._cssResultsElement = this.contentElement.createChild('div', 'css-result
s'); |
25 this._progressElement = this._cssResultsElement.createChild('div', 'progress
-view'); | 24 this._progressElement = this._cssResultsElement.createChild('div', 'progress
-view'); |
26 this._treeOutline = new TreeOutlineInShadow(); | 25 this._treeOutline = new UI.TreeOutlineInShadow(); |
27 this._treeOutline.registerRequiredCSS('css_tracker/unusedRulesTree.css'); | 26 this._treeOutline.registerRequiredCSS('css_tracker/unusedRulesTree.css'); |
28 | 27 |
29 this._statusToolbarElement = this.contentElement.createChild('div', 'css-too
lbar-summary'); | 28 this._statusToolbarElement = this.contentElement.createChild('div', 'css-too
lbar-summary'); |
30 this._statusMessageElement = this._statusToolbarElement.createChild('div', '
css-message'); | 29 this._statusMessageElement = this._statusToolbarElement.createChild('div', '
css-message'); |
31 | 30 |
32 this._isRecording = false; | 31 this._isRecording = false; |
33 } | 32 } |
34 | 33 |
35 _reset() { | 34 _reset() { |
36 Workspace.workspace.uiSourceCodes().forEach( | 35 Workspace.workspace.uiSourceCodes().forEach( |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 var url = this._urlForStyleSheetId(cssModel, rule.styleSheetId); | 97 var url = this._urlForStyleSheetId(cssModel, rule.styleSheetId); |
99 if (!url) | 98 if (!url) |
100 continue; | 99 continue; |
101 var uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url); | 100 var uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url); |
102 if (!uiSourceCode) | 101 if (!uiSourceCode) |
103 continue; | 102 continue; |
104 | 103 |
105 var gutterRange = Common.TextRange.fromObject(rule.range); | 104 var gutterRange = Common.TextRange.fromObject(rule.range); |
106 if (gutterRange.startColumn) | 105 if (gutterRange.startColumn) |
107 gutterRange.startColumn--; | 106 gutterRange.startColumn--; |
108 uiSourceCode.addDecoration(gutterRange, | 107 uiSourceCode.addDecoration(gutterRange, CSSTracker.CSSTrackerView.LineDe
corator.type, rule.wasUsed); |
109 CSSTracker.CSSTrackerView.LineDecorator.type, rule.wasUsed); | |
110 } | 108 } |
111 var percentUnused = Math.round(100 * unusedRulesCount / ruleUsageList.leng
th); | 109 var percentUnused = Math.round(100 * unusedRulesCount / ruleUsageList.leng
th); |
112 if (unusedRulesCount === 1) { | 110 if (unusedRulesCount === 1) { |
113 this._statusMessageElement.textContent = | 111 this._statusMessageElement.textContent = |
114 Common.UIString('%d CSS rule is not used. (%d%%)', unusedRulesCount
, percentUnused); | 112 Common.UIString('%d CSS rule is not used. (%d%%)', unusedRulesCount,
percentUnused); |
115 } else { | 113 } else { |
116 this._statusMessageElement.textContent = | 114 this._statusMessageElement.textContent = |
117 Common.UIString('%d CSS rules are not used. (%d%%)', unusedRulesCoun
t, percentUnused); | 115 Common.UIString('%d CSS rules are not used. (%d%%)', unusedRulesCoun
t, percentUnused); |
118 } | 116 } |
119 | 117 |
120 this._renderRuleUsage(cssModel, ruleUsageList); | 118 this._renderRuleUsage(cssModel, ruleUsageList); |
121 } | 119 } |
122 } | 120 } |
123 | 121 |
124 /** | 122 /** |
125 * @param {!Array<!SDK.CSSStyleSheetHeader>} styleSheetHeaders | 123 * @param {!Array<!SDK.CSSStyleSheetHeader>} styleSheetHeaders |
126 * @return {!Promise<!Array<!CSSTracker.ParsedStyleSheet>>} | 124 * @return {!Promise<!Array<!CSSTracker.ParsedStyleSheet>>} |
127 */ | 125 */ |
128 _parseStyleSheets(styleSheetHeaders) { | 126 _parseStyleSheets(styleSheetHeaders) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 if (!rule.selector && !rule.wasUsed) | 194 if (!rule.selector && !rule.wasUsed) |
197 ++unattributedRulesCount; | 195 ++unattributedRulesCount; |
198 } | 196 } |
199 ruleList = ruleList.filter(rule => rule.selector); | 197 ruleList = ruleList.filter(rule => rule.selector); |
200 | 198 |
201 this._cssResultsElement.removeChildren(); | 199 this._cssResultsElement.removeChildren(); |
202 | 200 |
203 if (unattributedRulesCount) { | 201 if (unattributedRulesCount) { |
204 if (unattributedRulesCount === 1) { | 202 if (unattributedRulesCount === 1) { |
205 var removedStyleSheetStats = Common.UIString('1 unused rule in a removed
style sheet.'); | 203 var removedStyleSheetStats = Common.UIString('1 unused rule in a removed
style sheet.'); |
206 } | 204 } else { |
207 else { | |
208 var removedStyleSheetStats = | 205 var removedStyleSheetStats = |
209 Common.UIString('%d unused rules in removed style sheets.', unattrib
utedRulesCount); | 206 Common.UIString('%d unused rules in removed style sheets.', unattrib
utedRulesCount); |
210 } | 207 } |
211 var treeElement = new TreeElement(Common.UIString('Unknown style sheets'),
true); | 208 var treeElement = new UI.TreeElement(Common.UIString('Unknown style sheets
'), true); |
212 treeElement.toggleOnClick = true; | 209 treeElement.toggleOnClick = true; |
213 treeElement.selectable = false; | 210 treeElement.selectable = false; |
214 | 211 |
215 var stats = new TreeElement(removedStyleSheetStats, false); | 212 var stats = new UI.TreeElement(removedStyleSheetStats, false); |
216 stats.selectable = false; | 213 stats.selectable = false; |
217 treeElement.appendChild(stats); | 214 treeElement.appendChild(stats); |
218 this._treeOutline.appendChild(treeElement); | 215 this._treeOutline.appendChild(treeElement); |
219 } | 216 } |
220 | 217 |
221 if (!ruleList.length) | 218 if (!ruleList.length) |
222 return; | 219 return; |
223 | 220 |
224 this._cssResultsElement.appendChild(this._treeOutline.element); | 221 this._cssResultsElement.appendChild(this._treeOutline.element); |
225 | 222 |
226 var startPosition = 0; | 223 var startPosition = 0; |
227 for (var i = 1; i < ruleList.length; ++i) { | 224 for (var i = 1; i < ruleList.length; ++i) { |
228 if (ruleList[i].styleSheetId === ruleList[i - 1].styleSheetId) | 225 if (ruleList[i].styleSheetId === ruleList[i - 1].styleSheetId) |
229 continue; | 226 continue; |
230 | 227 |
231 var url = this._urlForStyleSheetId(cssModel, ruleList[startPosition].style
SheetId); | 228 var url = this._urlForStyleSheetId(cssModel, ruleList[startPosition].style
SheetId); |
232 var styleSheetTreeElement = | 229 var styleSheetTreeElement = |
233 new CSSTracker.CSSTrackerView.StyleSheetTreeElement(url, ruleList.slic
e(startPosition, i)); | 230 new CSSTracker.CSSTrackerView.StyleSheetTreeElement(url, ruleList.slic
e(startPosition, i)); |
234 this._treeOutline.appendChild(styleSheetTreeElement); | 231 this._treeOutline.appendChild(styleSheetTreeElement); |
235 | 232 |
236 startPosition = i; | 233 startPosition = i; |
237 } | 234 } |
238 var url = this._urlForStyleSheetId(cssModel, ruleList[startPosition].styleSh
eetId); | 235 var url = this._urlForStyleSheetId(cssModel, ruleList[startPosition].styleSh
eetId); |
239 var styleSheetTreeElement = | 236 var styleSheetTreeElement = new CSSTracker.CSSTrackerView.StyleSheetTreeElem
ent(url, ruleList.slice(startPosition)); |
240 new CSSTracker.CSSTrackerView.StyleSheetTreeElement(url, ruleList.slice(
startPosition)); | |
241 this._treeOutline.appendChild(styleSheetTreeElement); | 237 this._treeOutline.appendChild(styleSheetTreeElement); |
242 } | 238 } |
243 | 239 |
244 /** | 240 /** |
245 * @param {string} styleSheetId | 241 * @param {string} styleSheetId |
246 * @param {!SDK.CSSModel} cssModel | 242 * @param {!SDK.CSSModel} cssModel |
247 * @return {string} | 243 * @return {string} |
248 */ | 244 */ |
249 _urlForStyleSheetId(cssModel, styleSheetId) { | 245 _urlForStyleSheetId(cssModel, styleSheetId) { |
250 var styleSheetHeader = cssModel.styleSheetHeaderForId(styleSheetId); | 246 var styleSheetHeader = cssModel.styleSheetHeaderForId(styleSheetId); |
251 if (!styleSheetHeader) | 247 if (!styleSheetHeader) |
252 return ''; | 248 return ''; |
253 return styleSheetHeader.sourceURL; | 249 return styleSheetHeader.sourceURL; |
254 } | 250 } |
255 }; | 251 }; |
256 | 252 |
257 /** @typedef {{range: !Protocol.CSS.SourceRange, | 253 /** @typedef {{range: !Protocol.CSS.SourceRange, |
258 * selector: (string|undefined), | 254 * selector: (string|undefined), |
259 * styleSheetId: !Protocol.CSS.StyleSheetId, | 255 * styleSheetId: !Protocol.CSS.StyleSheetId, |
260 * wasUsed: boolean}} | 256 * wasUsed: boolean}} |
261 */ | 257 */ |
262 CSSTracker.RuleUsage; | 258 CSSTracker.RuleUsage; |
263 | 259 |
264 /** @typedef {{sourceURL: string, rules: !Array<!Common.FormatterWorkerPool.CSSS
tyleRule>}} */ | 260 /** @typedef {{sourceURL: string, rules: !Array<!Common.FormatterWorkerPool.CSSS
tyleRule>}} */ |
265 CSSTracker.ParsedStyleSheet; | 261 CSSTracker.ParsedStyleSheet; |
266 | 262 |
267 CSSTracker.CSSTrackerView._rulesShownAtOnce = 20; | 263 CSSTracker.CSSTrackerView._rulesShownAtOnce = 20; |
268 | 264 |
269 CSSTracker.CSSTrackerView.StyleSheetTreeElement = class extends TreeElement { | 265 CSSTracker.CSSTrackerView.StyleSheetTreeElement = class extends UI.TreeElement { |
270 /** | 266 /** |
271 * @param {string} url | 267 * @param {string} url |
272 * @param {!Array<!CSSTracker.RuleUsage>} ruleList | 268 * @param {!Array<!CSSTracker.RuleUsage>} ruleList |
273 */ | 269 */ |
274 constructor(url, ruleList) { | 270 constructor(url, ruleList) { |
275 super('', true); | 271 super('', true); |
276 | 272 |
277 this._uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url); | 273 this._uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url); |
278 | 274 |
279 /** @type {!Array<!CSSTracker.RuleUsage>} */ | 275 /** @type {!Array<!CSSTracker.RuleUsage>} */ |
280 this._unusedRules = ruleList.filter(rule => !rule.wasUsed); | 276 this._unusedRules = ruleList.filter(rule => !rule.wasUsed); |
281 | 277 |
282 var lastLineNumber = 0; | 278 var lastLineNumber = 0; |
283 for (var i = this._unusedRules.length - 1; i >= 0; --i) { | 279 for (var i = this._unusedRules.length - 1; i >= 0; --i) { |
284 if (this._unusedRules[i].range) { | 280 if (this._unusedRules[i].range) { |
285 lastLineNumber = this._unusedRules[i].range.startLine; | 281 lastLineNumber = this._unusedRules[i].range.startLine; |
286 break; | 282 break; |
287 } | 283 } |
288 } | 284 } |
289 this._numberOfSpaces = lastLineNumber.toString().length + 1; | 285 this._numberOfSpaces = lastLineNumber.toString().length + 1; |
290 | 286 |
291 this._percentUnused = Math.round(100 * this._unusedRules.length / ruleList.l
ength); | 287 this._percentUnused = Math.round(100 * this._unusedRules.length / ruleList.l
ength); |
292 | 288 |
293 this.toggleOnClick = true; | 289 this.toggleOnClick = true; |
294 this.selectable = false; | 290 this.selectable = false; |
295 | 291 |
296 /** @type {?TreeElement} */ | 292 /** @type {?UI.TreeElement} */ |
297 this._showAllRulesTreeElement = null; | 293 this._showAllRulesTreeElement = null; |
298 | 294 |
299 var title = createElementWithClass('div', 'rule-result'); | 295 var title = createElementWithClass('div', 'rule-result'); |
300 var titleText; | 296 var titleText; |
301 if (this._uiSourceCode) | 297 if (this._uiSourceCode) |
302 titleText = this._uiSourceCode.fullDisplayName(); | 298 titleText = this._uiSourceCode.fullDisplayName(); |
303 else | 299 else |
304 titleText = Common.UIString('Style Sheet was removed'); | 300 titleText = Common.UIString('Style Sheet was removed'); |
305 title.createChild('span', 'rule-result-file-name').textContent = titleText; | 301 title.createChild('span', 'rule-result-file-name').textContent = titleText; |
306 | 302 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 var anchor = Components.Linkifier.linkifyRevealable(this._uiSourceCode.uiL
ocation(lineNumber, columnNumber), ''); | 343 var anchor = Components.Linkifier.linkifyRevealable(this._uiSourceCode.uiL
ocation(lineNumber, columnNumber), ''); |
348 | 344 |
349 var lineNumberSpan = createElement('span'); | 345 var lineNumberSpan = createElement('span'); |
350 lineNumberSpan.classList.add('rule-match-line-number'); | 346 lineNumberSpan.classList.add('rule-match-line-number'); |
351 lineNumberSpan.textContent = numberToStringWithSpacesPadding(lineNumber +
1, this._numberOfSpaces); | 347 lineNumberSpan.textContent = numberToStringWithSpacesPadding(lineNumber +
1, this._numberOfSpaces); |
352 anchor.appendChild(lineNumberSpan); | 348 anchor.appendChild(lineNumberSpan); |
353 | 349 |
354 var contentSpan = anchor.createChild('span', 'rule-match-content'); | 350 var contentSpan = anchor.createChild('span', 'rule-match-content'); |
355 contentSpan.textContent = rule.selector; | 351 contentSpan.textContent = rule.selector; |
356 | 352 |
357 var ruleElement = new TreeElement(); | 353 var ruleElement = new UI.TreeElement(); |
358 ruleElement.selectable = true; | 354 ruleElement.selectable = true; |
359 this.appendChild(ruleElement); | 355 this.appendChild(ruleElement); |
360 ruleElement.listItemElement.className = 'rule-match source-code'; | 356 ruleElement.listItemElement.className = 'rule-match source-code'; |
361 ruleElement.listItemElement.appendChild(anchor); | 357 ruleElement.listItemElement.appendChild(anchor); |
362 } | 358 } |
363 } | 359 } |
364 | 360 |
365 /** | 361 /** |
366 * @param {number} startMatchIndex | 362 * @param {number} startMatchIndex |
367 */ | 363 */ |
368 _appendShowAllRulesButton(startMatchIndex) { | 364 _appendShowAllRulesButton(startMatchIndex) { |
369 var rulesLeftCount = this._unusedRules.length - startMatchIndex; | 365 var rulesLeftCount = this._unusedRules.length - startMatchIndex; |
370 var button = createTextButton('', this._showMoreRulesElementSelected.bind(th
is, startMatchIndex)); | 366 var button = UI.createTextButton('', this._showMoreRulesElementSelected.bind
(this, startMatchIndex)); |
371 button.textContent = Common.UIString('Show all rules (%d more).', rulesLeftC
ount); | 367 button.textContent = Common.UIString('Show all rules (%d more).', rulesLeftC
ount); |
372 this._showAllRulesTreeElement = new TreeElement(button); | 368 this._showAllRulesTreeElement = new UI.TreeElement(button); |
373 this._showAllRulesTreeElement.selectable = false; | 369 this._showAllRulesTreeElement.selectable = false; |
374 this.appendChild(this._showAllRulesTreeElement); | 370 this.appendChild(this._showAllRulesTreeElement); |
375 } | 371 } |
376 | 372 |
377 /** | 373 /** |
378 * @param {number} startMatchIndex | 374 * @param {number} startMatchIndex |
379 */ | 375 */ |
380 _showMoreRulesElementSelected(startMatchIndex) { | 376 _showMoreRulesElementSelected(startMatchIndex) { |
381 if (!this._showAllRulesTreeElement) | 377 if (!this._showAllRulesTreeElement) |
382 return; | 378 return; |
(...skipping 29 matching lines...) Expand all Loading... |
412 else | 408 else |
413 element.className = 'text-editor-css-rule-unused-marker'; | 409 element.className = 'text-editor-css-rule-unused-marker'; |
414 | 410 |
415 textEditor.setGutterDecoration(line, gutterType, element); | 411 textEditor.setGutterDecoration(line, gutterType, element); |
416 } | 412 } |
417 } | 413 } |
418 } | 414 } |
419 }; | 415 }; |
420 | 416 |
421 CSSTracker.CSSTrackerView.LineDecorator.type = 'coverage'; | 417 CSSTracker.CSSTrackerView.LineDecorator.type = 'coverage'; |
OLD | NEW |