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

Unified Diff: third_party/WebKit/Source/devtools/front_end/css_tracker/CSSTrackerView.js

Issue 2705433003: DevTools: decouple model logic from presentation within CSSTrackerView (Closed)
Patch Set: Review comments addressed Created 3 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/LayoutTests/inspector/css_tracker/highlight-in-source.html ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/devtools/front_end/css_tracker/CSSTrackerView.js
diff --git a/third_party/WebKit/Source/devtools/front_end/css_tracker/CSSTrackerView.js b/third_party/WebKit/Source/devtools/front_end/css_tracker/CSSTrackerView.js
index 38318b0f0469f6a8c30c606a7a8f4e1aa53630c6..354ed14157a3bd2316f65531dada472244e3c6b3 100644
--- a/third_party/WebKit/Source/devtools/front_end/css_tracker/CSSTrackerView.js
+++ b/third_party/WebKit/Source/devtools/front_end/css_tracker/CSSTrackerView.js
@@ -84,130 +84,138 @@ CSSTracker.CSSTrackerView = class extends UI.VBox {
var cssModel = mainTarget.model(SDK.CSSModel);
dgozman 2017/02/18 06:21:09 While you are working on this, could you make it w
if (!cssModel)
return;
- cssModel.ruleListPromise().then(ruleListReceived.bind(this, cssModel));
+
+ cssModel.ruleListPromise().then(processRuleList.bind(this)).then(updateViews.bind(this));
/**
- * @param {!SDK.CSSModel} cssModel
- * @param {!Array<!CSSTracker.RuleUsage>} ruleUsageList
+ * @param {!Array<!SDK.CSSModel.RuleUsage>} ruleUsageList
* @this {!CSSTracker.CSSTrackerView}
+ * @return {!Promise<!Array<!CSSTracker.StyleSheetUsage>>}
*/
- function ruleListReceived(cssModel, ruleUsageList) {
- var unusedRulesCount = 0;
+ function processRuleList(ruleUsageList) {
+ /** @type {!Map<?SDK.CSSStyleSheetHeader, !CSSTracker.StyleSheetUsage>} */
+ var rulesByStyleSheet = new Map();
for (var rule of ruleUsageList) {
- if (!rule.wasUsed)
- unusedRulesCount++;
-
- var url = this._urlForStyleSheetId(cssModel, rule.styleSheetId);
- if (!url)
- continue;
- var uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url);
- if (!uiSourceCode)
- continue;
-
- var gutterRange = Common.TextRange.fromObject(rule.range);
- if (gutterRange.startColumn)
- gutterRange.startColumn--;
- uiSourceCode.addDecoration(gutterRange, CSSTracker.CSSTrackerView.LineDecorator.type, rule.wasUsed);
- }
- var percentUnused = Math.round(100 * unusedRulesCount / ruleUsageList.length);
- if (unusedRulesCount === 1) {
- this._statusMessageElement.textContent =
- Common.UIString('%d CSS rule is not used. (%d%%)', unusedRulesCount, percentUnused);
- } else {
- this._statusMessageElement.textContent =
- Common.UIString('%d CSS rules are not used. (%d%%)', unusedRulesCount, percentUnused);
+ var styleSheetHeader = cssModel.styleSheetHeaderForId(rule.styleSheetId);
+ var entry = rulesByStyleSheet.get(styleSheetHeader);
+ if (!entry) {
+ entry = {styleSheetHeader: styleSheetHeader, rules: []};
+ rulesByStyleSheet.set(styleSheetHeader, entry);
+ }
+ entry.rules.push(rule);
}
+ return Promise.all(Array.from(
+ rulesByStyleSheet.values(),
+ entry => this._populateSourceInfo(/** @type {!CSSTracker.StyleSheetUsage} */ (entry))));
+ }
- this._renderRuleUsage(cssModel, ruleUsageList);
+ /**
+ * @param {!Array<!CSSTracker.StyleSheetUsage>} styleSheetUsages
+ * @this {!CSSTracker.CSSTrackerView}
+ */
+ function updateViews(styleSheetUsages) {
+ this._updateStats(styleSheetUsages);
+ this._updateGutter(styleSheetUsages);
+ this._updateTree(styleSheetUsages);
}
}
/**
- * @param {!Array<!SDK.CSSStyleSheetHeader>} styleSheetHeaders
- * @return {!Promise<!Array<!CSSTracker.ParsedStyleSheet>>}
+ * @param {!CSSTracker.StyleSheetUsage} styleSheetUsage
+ * @return {!Promise<!CSSTracker.StyleSheetUsage>}
*/
- _parseStyleSheets(styleSheetHeaders) {
- var promises = styleSheetHeaders.map(header => parseStyleSheet(header));
- return Promise.all(promises);
-
- /**
- * @param {!SDK.CSSStyleSheetHeader} styleSheet
- * @return {!Promise<!CSSTracker.ParsedStyleSheet>}
- */
- function parseStyleSheet(styleSheet) {
- return new Promise(fulfill => {
- /** @type {!Array<!Common.FormatterWorkerPool.CSSStyleRule>} */
- var allRules = [];
- styleSheet.requestContent().then(content => Common.formatterWorkerPool.parseCSS(content || '', onRules));
-
- /**
- * @param {boolean} isLastChunk
- * @param {!Array<!Common.FormatterWorkerPool.CSSStyleRule>} rules
- */
- function onRules(isLastChunk, rules) {
- allRules.pushAll(rules);
- if (isLastChunk)
- fulfill({sourceURL: styleSheet.sourceURL, rules: allRules});
+ _populateSourceInfo(styleSheetUsage) {
+ if (!styleSheetUsage.styleSheetHeader)
+ return Promise.resolve(styleSheetUsage);
+ var ruleIndex =
+ new Map(styleSheetUsage.rules.map(rule => [`${rule.range.startLine}.${rule.range.startColumn}`, rule]));
+
+ return new Promise(fulfill => {
+ styleSheetUsage.styleSheetHeader.requestContent().then(
+ content => Common.formatterWorkerPool.parseCSS(content || '', onRules));
+
+ /**
+ * @param {boolean} isLastChunk
+ * @param {!Array<!Common.FormatterWorkerPool.CSSStyleRule>} rules
+ */
+ function onRules(isLastChunk, rules) {
+ for (var rule of rules) {
+ if (!rule.styleRange)
+ continue;
+ var entry = ruleIndex.get(`${rule.styleRange.startLine}.${rule.styleRange.startColumn}`);
+ if (entry)
+ entry.selector = rule.selectorText;
}
- });
- }
+ if (isLastChunk)
+ fulfill(styleSheetUsage);
+ }
+ });
}
/**
- * @param {!SDK.CSSModel} cssModel
- * @param {!Array<!CSSTracker.RuleUsage>} ruleList
+ * @param {!Array<!CSSTracker.StyleSheetUsage>} styleSheetUsage
*/
- _renderRuleUsage(cssModel, ruleList) {
- var headers = cssModel.allStyleSheets();
- if (!headers.length)
- return;
-
- this._parseStyleSheets(headers).then(this._onGotStyleSheets.bind(this, cssModel, ruleList));
+ _updateStats(styleSheetUsage) {
+ var total = 0;
+ var unused = 0;
+ for (var styleSheet of styleSheetUsage) {
+ total += styleSheet.rules.length;
+ unused += styleSheet.rules.reduce((count, rule) => rule.wasUsed ? count : count + 1, 0);
+ }
+ var percentUnused = total ? Math.round(100 * unused / total) : 0;
+ if (unused === 1) {
+ this._statusMessageElement.textContent =
+ Common.UIString('%d CSS rule is not used. (%d%%)', unused, percentUnused);
+ } else {
+ this._statusMessageElement.textContent =
+ Common.UIString('%d CSS rules are not used. (%d%%)', unused, percentUnused);
+ }
}
/**
- * @param {!SDK.CSSModel} cssModel
- * @param {!Array<!CSSTracker.RuleUsage>} ruleList
- * @param {!Array<!CSSTracker.ParsedStyleSheet>} styleSheets
- * @this {CSSTracker.CSSTrackerView}
+ * @param {!Array<!CSSTracker.StyleSheetUsage>} styleSheetUsages
*/
- _onGotStyleSheets(cssModel, ruleList, styleSheets) {
- /** @type {!Map<string, string>} */
- var rangeToSelector = new Map();
-
- for (var styleSheet of styleSheets) {
+ _updateGutter(styleSheetUsages) {
+ for (var styleSheet of styleSheetUsages) {
+ if (!styleSheet.styleSheetHeader)
+ continue;
+ var url = styleSheet.styleSheetHeader.sourceURL;
+ var uiSourceCode = url && Workspace.workspace.uiSourceCodeForURL(url);
+ if (!uiSourceCode)
+ continue;
for (var rule of styleSheet.rules) {
- if (!rule.styleRange)
- continue;
-
- rangeToSelector.set(
- rule.styleRange.startLine + ',' + rule.styleRange.startColumn + ',' + styleSheet.sourceURL,
- rule.selectorText);
+ var gutterRange = Common.TextRange.fromObject(rule.range);
+ if (gutterRange.startColumn)
+ gutterRange.startColumn--;
+ uiSourceCode.addDecoration(gutterRange, CSSTracker.CSSTrackerView.LineDecorator.type, rule.wasUsed);
}
}
+ }
- var unattributedRulesCount = 0;
-
- for (var rule of ruleList) {
- var url = this._urlForStyleSheetId(cssModel, rule.styleSheetId);
- if (url === '')
- continue;
- var range = rule.range.startLine + ',' + rule.range.startColumn + ',' + url;
- rule.selector = rangeToSelector.get(range);
- if (!rule.selector && !rule.wasUsed)
- ++unattributedRulesCount;
- }
- ruleList = ruleList.filter(rule => rule.selector);
-
+ /**
+ * @param {!Array<!CSSTracker.StyleSheetUsage>} styleSheetUsages
+ */
+ _updateTree(styleSheetUsages) {
this._cssResultsElement.removeChildren();
+ this._cssResultsElement.appendChild(this._treeOutline.element);
+
+ for (var sheet of styleSheetUsages) {
+ var unusedRuleCount = sheet.rules.reduce((count, rule) => rule.wasUsed ? count : count + 1, 0);
+ if (sheet.styleSheetHeader) {
+ var url = sheet.styleSheetHeader.sourceURL;
+ if (!url)
+ continue;
- if (unattributedRulesCount) {
- if (unattributedRulesCount === 1) {
- var removedStyleSheetStats = Common.UIString('1 unused rule in a removed style sheet.');
- } else {
- var removedStyleSheetStats =
- Common.UIString('%d unused rules in removed style sheets.', unattributedRulesCount);
+ var styleSheetTreeElement = new CSSTracker.CSSTrackerView.StyleSheetTreeElement(url, sheet.rules);
+ this._treeOutline.appendChild(styleSheetTreeElement);
+ continue;
}
+ if (!unusedRuleCount)
+ continue;
+ var removedStyleSheetStats = unusedRuleCount === 1 ?
+ Common.UIString('1 unused rule in a removed style sheet.') :
+ Common.UIString('%d unused rules in removed style sheets.', unusedRuleCount);
+
var treeElement = new UI.TreeElement(Common.UIString('Unknown style sheets'), true);
treeElement.toggleOnClick = true;
treeElement.selectable = false;
@@ -217,51 +225,17 @@ CSSTracker.CSSTrackerView = class extends UI.VBox {
treeElement.appendChild(stats);
this._treeOutline.appendChild(treeElement);
}
-
- if (!ruleList.length)
- return;
-
- this._cssResultsElement.appendChild(this._treeOutline.element);
-
- var startPosition = 0;
- for (var i = 1; i < ruleList.length; ++i) {
- if (ruleList[i].styleSheetId === ruleList[i - 1].styleSheetId)
- continue;
-
- var url = this._urlForStyleSheetId(cssModel, ruleList[startPosition].styleSheetId);
- var styleSheetTreeElement =
- new CSSTracker.CSSTrackerView.StyleSheetTreeElement(url, ruleList.slice(startPosition, i));
- this._treeOutline.appendChild(styleSheetTreeElement);
-
- startPosition = i;
- }
- var url = this._urlForStyleSheetId(cssModel, ruleList[startPosition].styleSheetId);
- var styleSheetTreeElement = new CSSTracker.CSSTrackerView.StyleSheetTreeElement(url, ruleList.slice(startPosition));
- this._treeOutline.appendChild(styleSheetTreeElement);
- }
-
- /**
- * @param {string} styleSheetId
- * @param {!SDK.CSSModel} cssModel
- * @return {string}
- */
- _urlForStyleSheetId(cssModel, styleSheetId) {
- var styleSheetHeader = cssModel.styleSheetHeaderForId(styleSheetId);
- if (!styleSheetHeader)
- return '';
- return styleSheetHeader.sourceURL;
}
};
/** @typedef {{range: !Protocol.CSS.SourceRange,
* selector: (string|undefined),
- * styleSheetId: !Protocol.CSS.StyleSheetId,
* wasUsed: boolean}}
*/
CSSTracker.RuleUsage;
-/** @typedef {{sourceURL: string, rules: !Array<!Common.FormatterWorkerPool.CSSStyleRule>}} */
-CSSTracker.ParsedStyleSheet;
+/** @typedef {{styleSheetHeader: ?SDK.CSSStyleSheetHeader, rules: !Array<!CSSTracker.RuleUsage>}} */
+CSSTracker.StyleSheetUsage;
CSSTracker.CSSTrackerView._rulesShownAtOnce = 20;
« no previous file with comments | « third_party/WebKit/LayoutTests/inspector/css_tracker/highlight-in-source.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698