Index: third_party/WebKit/Source/devtools/front_end/elements/StylesSectionModel.js |
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/StylesSectionModel.js b/third_party/WebKit/Source/devtools/front_end/elements/StylesSectionModel.js |
index 3389f7158824375376414651a1b7f38514ded87a..186fcff1a5b34373f4851b6f924b4708a76cc844 100644 |
--- a/third_party/WebKit/Source/devtools/front_end/elements/StylesSectionModel.js |
+++ b/third_party/WebKit/Source/devtools/front_end/elements/StylesSectionModel.js |
@@ -4,45 +4,56 @@ |
/** |
* @constructor |
- * @param {!WebInspector.SectionCascade} cascade |
- * @param {?WebInspector.CSSRule} rule |
- * @param {!WebInspector.CSSStyleDeclaration} style |
- * @param {string} customSelectorText |
- * @param {?WebInspector.DOMNode=} inheritedFromNode |
+ * @param {!WebInspector.CSSStyleModel.MatchedStyleResult} matchedStyles |
+ * @param {!Array<!WebInspector.CSSStyleDeclaration>} styles |
*/ |
-WebInspector.StylesSectionModel = function(cascade, rule, style, customSelectorText, inheritedFromNode) |
+WebInspector.SectionCascade = function(matchedStyles, styles) |
{ |
- this._cascade = cascade; |
- this._rule = rule; |
- this._style = style; |
- this._customSelectorText = customSelectorText; |
- this._editable = !!(this._style && this._style.styleSheetId); |
- this._inheritedFromNode = inheritedFromNode || null; |
+ this._matchedStyles = matchedStyles; |
+ this._styles = styles; |
+ this.resetActiveProperties(); |
} |
-WebInspector.StylesSectionModel.prototype = { |
- /** |
- * @return {!WebInspector.SectionCascade} |
- */ |
- cascade: function() |
- { |
- return this._cascade; |
- }, |
+/** |
+ * @param {!WebInspector.CSSStyleModel.MatchedStyleResult} matchedStyles |
+ * @return {!{matched: !WebInspector.SectionCascade, pseudo: !Map.<number, !WebInspector.SectionCascade>}} |
+ */ |
+WebInspector.SectionCascade.fromMatchedStyles = function(matchedStyles) |
+{ |
+ var matched = new WebInspector.SectionCascade(matchedStyles, matchedStyles.nodeStyles()); |
+ var pseudo = new Map(); |
+ |
+ var pseudoStyles = matchedStyles.pseudoStyles(); |
+ var pseudoElements = pseudoStyles.keysArray(); |
+ for (var i = 0; i < pseudoElements.length; ++i) { |
+ var pseudoElement = pseudoElements[i]; |
+ var pseudoCascade = new WebInspector.SectionCascade(matchedStyles, /** @type {!Array<!WebInspector.CSSStyleDeclaration>} */(pseudoStyles.get(pseudoElement))); |
+ pseudo.set(pseudoElement, pseudoCascade); |
+ } |
+ |
+ return { |
+ matched: matched, |
+ pseudo: pseudo |
+ }; |
+} |
+WebInspector.SectionCascade.prototype = { |
/** |
+ * @param {!WebInspector.CSSStyleDeclaration} style |
* @return {boolean} |
*/ |
- hasMatchingSelectors: function() |
+ hasMatchingSelectors: function(style) |
{ |
- return this.rule() ? this.rule().matchingSelectors.length > 0 && this.mediaMatches() : true; |
+ return style.parentRule ? style.parentRule.matchingSelectors && style.parentRule.matchingSelectors.length > 0 && this.mediaMatches(style) : true; |
}, |
/** |
+ * @param {!WebInspector.CSSStyleDeclaration} style |
* @return {boolean} |
*/ |
- mediaMatches: function() |
+ mediaMatches: function(style) |
{ |
- var media = this.media(); |
+ var media = style.parentRule ? style.parentRule.media : []; |
for (var i = 0; media && i < media.length; ++i) { |
if (!media[i].active()) |
return false; |
@@ -51,132 +62,45 @@ WebInspector.StylesSectionModel.prototype = { |
}, |
/** |
- * @return {boolean} |
- */ |
- inherited: function() |
- { |
- return !!this._inheritedFromNode; |
- }, |
- |
- /** |
+ * @param {!WebInspector.CSSStyleDeclaration} style |
* @return {?WebInspector.DOMNode} |
*/ |
- parentNode: function() |
+ nodeForStyle: function(style) |
{ |
- return this._inheritedFromNode; |
- }, |
- |
- /** |
- * @return {string} |
- */ |
- selectorText: function() |
- { |
- if (this._customSelectorText) |
- return this._customSelectorText; |
- return this.rule() ? this.rule().selectorText() : ""; |
+ return this._matchedStyles.nodeForStyle(style); |
}, |
/** |
+ * @param {!WebInspector.CSSStyleDeclaration} style |
* @return {boolean} |
*/ |
- editable: function() |
+ isInherited: function(style) |
{ |
- return this._editable; |
+ return this._matchedStyles.isInherited(style); |
}, |
/** |
- * @param {boolean} editable |
+ * @return {!Array.<!WebInspector.CSSStyleDeclaration>} |
*/ |
- setEditable: function(editable) |
+ styles: function() |
{ |
- this._editable = editable; |
- }, |
- |
- /** |
- * @return {!WebInspector.CSSStyleDeclaration} |
- */ |
- style: function() |
- { |
- return this._style; |
- }, |
- |
- /** |
- * @return {?WebInspector.CSSRule} |
- */ |
- rule: function() |
- { |
- return this._rule; |
- }, |
- |
- /** |
- * @return {?Array.<!WebInspector.CSSMedia>} |
- */ |
- media: function() |
- { |
- return this.rule() ? this.rule().media : null; |
- }, |
- |
- resetCachedData: function() |
- { |
- this._cascade._resetUsedProperties(); |
- } |
-} |
- |
-/** |
- * @constructor |
- */ |
-WebInspector.SectionCascade = function() |
-{ |
- this._models = []; |
- this._resetUsedProperties(); |
-} |
- |
-WebInspector.SectionCascade.prototype = { |
- /** |
- * @return {!Array.<!WebInspector.StylesSectionModel>} |
- */ |
- sectionModels: function() |
- { |
- return this._models; |
- }, |
- |
- /** |
- * @param {!WebInspector.CSSRule} rule |
- * @param {!WebInspector.StylesSectionModel} insertAfterStyleRule |
- * @return {!WebInspector.StylesSectionModel} |
- */ |
- insertModelFromRule: function(rule, insertAfterStyleRule) |
- { |
- return this._insertModel(new WebInspector.StylesSectionModel(this, rule, rule.style, "", null), insertAfterStyleRule); |
+ return this._styles; |
}, |
/** |
* @param {!WebInspector.CSSStyleDeclaration} style |
- * @param {string} selectorText |
- * @param {?WebInspector.DOMNode=} inheritedFromNode |
- * @return {!WebInspector.StylesSectionModel} |
- */ |
- appendModelFromStyle: function(style, selectorText, inheritedFromNode) |
- { |
- return this._insertModel(new WebInspector.StylesSectionModel(this, style.parentRule, style, selectorText, inheritedFromNode)); |
- }, |
- |
- /** |
- * @param {!WebInspector.StylesSectionModel} model |
- * @param {!WebInspector.StylesSectionModel=} insertAfter |
- * @return {!WebInspector.StylesSectionModel} |
+ * @param {!WebInspector.CSSStyleDeclaration=} insertAfter |
*/ |
- _insertModel: function(model, insertAfter) |
+ insertStyle: function(style, insertAfter) |
{ |
if (insertAfter) { |
- var index = this._models.indexOf(insertAfter); |
+ var index = this._styles.indexOf(insertAfter); |
console.assert(index !== -1, "The insertAfter anchor could not be found in cascade"); |
- this._models.splice(index + 1, 0, model); |
+ this._styles.splice(index + 1, 0, style); |
} else { |
- this._models.push(model); |
+ this._styles.push(style); |
} |
- this._resetUsedProperties(); |
- return model; |
+ this.resetActiveProperties(); |
}, |
/** |
@@ -186,110 +110,109 @@ WebInspector.SectionCascade.prototype = { |
propertyState: function(property) |
{ |
if (this._propertiesState.size === 0) |
- this._propertiesState = WebInspector.SectionCascade._computeUsedProperties(this._models); |
+ this._propertiesState = this._computeActiveProperties(); |
return this._propertiesState.get(property) || null; |
}, |
- _resetUsedProperties: function() |
+ resetActiveProperties: function() |
{ |
/** @type {!Map<!WebInspector.CSSProperty, !WebInspector.SectionCascade.PropertyState>} */ |
this._propertiesState = new Map(); |
- } |
-} |
- |
-/** |
- * @param {!Array.<!WebInspector.StylesSectionModel>} styleRules |
- * @return {!Map<!WebInspector.CSSProperty, !WebInspector.SectionCascade.PropertyState>} |
- */ |
-WebInspector.SectionCascade._computeUsedProperties = function(styleRules) |
-{ |
- /** @type {!Set.<string>} */ |
- var foundImportantProperties = new Set(); |
- /** @type {!Map.<string, !Map<string, !WebInspector.CSSProperty>>} */ |
- var propertyToEffectiveRule = new Map(); |
- /** @type {!Map.<string, !WebInspector.DOMNode>} */ |
- var inheritedPropertyToNode = new Map(); |
- /** @type {!Set<string>} */ |
- var allUsedProperties = new Set(); |
- var result = new Map(); |
- for (var i = 0; i < styleRules.length; ++i) { |
- var styleRule = styleRules[i]; |
- if (!styleRule.hasMatchingSelectors()) |
- continue; |
- |
- /** @type {!Map<string, !WebInspector.CSSProperty>} */ |
- var styleActiveProperties = new Map(); |
- var style = styleRule.style(); |
- var allProperties = style.allProperties; |
- for (var j = 0; j < allProperties.length; ++j) { |
- var property = allProperties[j]; |
+ }, |
- // Do not pick non-inherited properties from inherited styles. |
- if (styleRule.inherited() && !WebInspector.CSSMetadata.isPropertyInherited(property.name)) |
+ /** |
+ * @return {!Map<!WebInspector.CSSProperty, !WebInspector.SectionCascade.PropertyState>} |
+ */ |
+ _computeActiveProperties: function() |
+ { |
+ /** @type {!Set.<string>} */ |
+ var foundImportantProperties = new Set(); |
+ /** @type {!Map.<string, !Map<string, !WebInspector.CSSProperty>>} */ |
+ var propertyToEffectiveRule = new Map(); |
+ /** @type {!Map.<string, !WebInspector.DOMNode>} */ |
+ var inheritedPropertyToNode = new Map(); |
+ /** @type {!Set<string>} */ |
+ var allUsedProperties = new Set(); |
+ var result = new Map(); |
+ for (var i = 0; i < this._styles.length; ++i) { |
+ var style = this._styles[i]; |
+ if (!this.hasMatchingSelectors(style)) |
continue; |
- if (!property.activeInStyle()) { |
- result.set(property, WebInspector.SectionCascade.PropertyState.Overloaded); |
- continue; |
- } |
+ /** @type {!Map<string, !WebInspector.CSSProperty>} */ |
+ var styleActiveProperties = new Map(); |
+ var allProperties = style.allProperties; |
+ for (var j = 0; j < allProperties.length; ++j) { |
+ var property = allProperties[j]; |
- var canonicalName = WebInspector.CSSMetadata.canonicalPropertyName(property.name); |
- if (foundImportantProperties.has(canonicalName)) { |
- result.set(property, WebInspector.SectionCascade.PropertyState.Overloaded); |
- continue; |
- } |
+ // Do not pick non-inherited properties from inherited styles. |
+ var inherited = this._matchedStyles.isInherited(style); |
+ if (inherited && !WebInspector.CSSMetadata.isPropertyInherited(property.name)) |
+ continue; |
- if (!property.important && allUsedProperties.has(canonicalName)) { |
- result.set(property, WebInspector.SectionCascade.PropertyState.Overloaded); |
- continue; |
- } |
+ if (!property.activeInStyle()) { |
+ result.set(property, WebInspector.SectionCascade.PropertyState.Overloaded); |
+ continue; |
+ } |
- var isKnownProperty = propertyToEffectiveRule.has(canonicalName); |
- var parentNode = styleRule.parentNode(); |
- if (!isKnownProperty && parentNode && !inheritedPropertyToNode.has(canonicalName)) |
- inheritedPropertyToNode.set(canonicalName, parentNode); |
+ var canonicalName = WebInspector.CSSMetadata.canonicalPropertyName(property.name); |
+ if (foundImportantProperties.has(canonicalName)) { |
+ result.set(property, WebInspector.SectionCascade.PropertyState.Overloaded); |
+ continue; |
+ } |
- if (property.important) { |
- if (styleRule.inherited() && isKnownProperty && styleRule.parentNode() !== inheritedPropertyToNode.get(canonicalName)) { |
+ if (!property.important && allUsedProperties.has(canonicalName)) { |
result.set(property, WebInspector.SectionCascade.PropertyState.Overloaded); |
continue; |
} |
- foundImportantProperties.add(canonicalName); |
- if (isKnownProperty) { |
- var overloaded = propertyToEffectiveRule.get(canonicalName).get(canonicalName); |
- result.set(overloaded, WebInspector.SectionCascade.PropertyState.Overloaded); |
- propertyToEffectiveRule.get(canonicalName).delete(canonicalName); |
+ var isKnownProperty = propertyToEffectiveRule.has(canonicalName); |
+ var inheritedFromNode = inherited ? this._matchedStyles.nodeForStyle(style) : null; |
+ if (!isKnownProperty && inheritedFromNode && !inheritedPropertyToNode.has(canonicalName)) |
+ inheritedPropertyToNode.set(canonicalName, inheritedFromNode); |
+ |
+ if (property.important) { |
+ if (inherited && isKnownProperty && inheritedFromNode !== inheritedPropertyToNode.get(canonicalName)) { |
+ result.set(property, WebInspector.SectionCascade.PropertyState.Overloaded); |
+ continue; |
+ } |
+ |
+ foundImportantProperties.add(canonicalName); |
+ if (isKnownProperty) { |
+ var overloaded = propertyToEffectiveRule.get(canonicalName).get(canonicalName); |
+ result.set(overloaded, WebInspector.SectionCascade.PropertyState.Overloaded); |
+ propertyToEffectiveRule.get(canonicalName).delete(canonicalName); |
+ } |
} |
- } |
- styleActiveProperties.set(canonicalName, property); |
- allUsedProperties.add(canonicalName); |
- propertyToEffectiveRule.set(canonicalName, styleActiveProperties); |
- result.set(property, WebInspector.SectionCascade.PropertyState.Active); |
- } |
+ styleActiveProperties.set(canonicalName, property); |
+ allUsedProperties.add(canonicalName); |
+ propertyToEffectiveRule.set(canonicalName, styleActiveProperties); |
+ result.set(property, WebInspector.SectionCascade.PropertyState.Active); |
+ } |
- // If every longhand of the shorthand is not active, then the shorthand is not active too. |
- for (var property of style.leadingProperties()) { |
- var canonicalName = WebInspector.CSSMetadata.canonicalPropertyName(property.name); |
- if (!styleActiveProperties.has(canonicalName)) |
- continue; |
- var longhands = style.longhandProperties(property.name); |
- if (!longhands.length) |
- continue; |
- var notUsed = true; |
- for (var longhand of longhands) { |
- var longhandCanonicalName = WebInspector.CSSMetadata.canonicalPropertyName(longhand.name); |
- notUsed = notUsed && !styleActiveProperties.has(longhandCanonicalName); |
+ // If every longhand of the shorthand is not active, then the shorthand is not active too. |
+ for (var property of style.leadingProperties()) { |
+ var canonicalName = WebInspector.CSSMetadata.canonicalPropertyName(property.name); |
+ if (!styleActiveProperties.has(canonicalName)) |
+ continue; |
+ var longhands = style.longhandProperties(property.name); |
+ if (!longhands.length) |
+ continue; |
+ var notUsed = true; |
+ for (var longhand of longhands) { |
+ var longhandCanonicalName = WebInspector.CSSMetadata.canonicalPropertyName(longhand.name); |
+ notUsed = notUsed && !styleActiveProperties.has(longhandCanonicalName); |
+ } |
+ if (!notUsed) |
+ continue; |
+ styleActiveProperties.delete(canonicalName); |
+ allUsedProperties.delete(canonicalName); |
+ result.set(property, WebInspector.SectionCascade.PropertyState.Overloaded); |
} |
- if (!notUsed) |
- continue; |
- styleActiveProperties.delete(canonicalName); |
- allUsedProperties.delete(canonicalName); |
- result.set(property, WebInspector.SectionCascade.PropertyState.Overloaded); |
} |
+ return result; |
} |
- return result; |
} |
/** @enum {string} */ |