| 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} */
|
|
|