| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * @constructor | |
| 7 * @param {!WebInspector.CSSStyleModel.MatchedStyleResult} matchedStyles | |
| 8 * @param {!Array<!WebInspector.CSSStyleDeclaration>} styles | |
| 9 */ | |
| 10 WebInspector.SectionCascade = function(matchedStyles, styles) | |
| 11 { | |
| 12 this._matchedStyles = matchedStyles; | |
| 13 this._styles = styles; | |
| 14 this.resetActiveProperties(); | |
| 15 } | |
| 16 | |
| 17 /** | |
| 18 * @param {!WebInspector.CSSStyleModel.MatchedStyleResult} matchedStyles | |
| 19 * @return {!{matched: !WebInspector.SectionCascade, pseudo: !Map.<number, !WebI
nspector.SectionCascade>}} | |
| 20 */ | |
| 21 WebInspector.SectionCascade.fromMatchedStyles = function(matchedStyles) | |
| 22 { | |
| 23 var matched = new WebInspector.SectionCascade(matchedStyles, matchedStyles.n
odeStyles()); | |
| 24 var pseudo = new Map(); | |
| 25 | |
| 26 var pseudoStyles = matchedStyles.pseudoStyles(); | |
| 27 var pseudoElements = pseudoStyles.keysArray(); | |
| 28 for (var i = 0; i < pseudoElements.length; ++i) { | |
| 29 var pseudoElement = pseudoElements[i]; | |
| 30 var pseudoCascade = new WebInspector.SectionCascade(matchedStyles, /** @
type {!Array<!WebInspector.CSSStyleDeclaration>} */(pseudoStyles.get(pseudoEleme
nt))); | |
| 31 pseudo.set(pseudoElement, pseudoCascade); | |
| 32 } | |
| 33 | |
| 34 return { | |
| 35 matched: matched, | |
| 36 pseudo: pseudo | |
| 37 }; | |
| 38 } | |
| 39 | |
| 40 WebInspector.SectionCascade.prototype = { | |
| 41 /** | |
| 42 * @param {!WebInspector.CSSStyleDeclaration} style | |
| 43 * @return {boolean} | |
| 44 */ | |
| 45 hasMatchingSelectors: function(style) | |
| 46 { | |
| 47 return style.parentRule ? style.parentRule.matchingSelectors && style.pa
rentRule.matchingSelectors.length > 0 && this.mediaMatches(style) : true; | |
| 48 }, | |
| 49 | |
| 50 /** | |
| 51 * @param {!WebInspector.CSSStyleDeclaration} style | |
| 52 * @return {boolean} | |
| 53 */ | |
| 54 mediaMatches: function(style) | |
| 55 { | |
| 56 var media = style.parentRule ? style.parentRule.media : []; | |
| 57 for (var i = 0; media && i < media.length; ++i) { | |
| 58 if (!media[i].active()) | |
| 59 return false; | |
| 60 } | |
| 61 return true; | |
| 62 }, | |
| 63 | |
| 64 /** | |
| 65 * @param {!WebInspector.CSSStyleDeclaration} style | |
| 66 * @return {?WebInspector.DOMNode} | |
| 67 */ | |
| 68 nodeForStyle: function(style) | |
| 69 { | |
| 70 return this._matchedStyles.nodeForStyle(style); | |
| 71 }, | |
| 72 | |
| 73 /** | |
| 74 * @param {!WebInspector.CSSStyleDeclaration} style | |
| 75 * @return {boolean} | |
| 76 */ | |
| 77 isInherited: function(style) | |
| 78 { | |
| 79 return this._matchedStyles.isInherited(style); | |
| 80 }, | |
| 81 | |
| 82 /** | |
| 83 * @return {!Array.<!WebInspector.CSSStyleDeclaration>} | |
| 84 */ | |
| 85 styles: function() | |
| 86 { | |
| 87 return this._styles; | |
| 88 }, | |
| 89 | |
| 90 /** | |
| 91 * @param {!WebInspector.CSSProperty} property | |
| 92 * @return {?WebInspector.SectionCascade.PropertyState} | |
| 93 */ | |
| 94 propertyState: function(property) | |
| 95 { | |
| 96 if (this._propertiesState.size === 0) | |
| 97 this._propertiesState = this._computeActiveProperties(); | |
| 98 return this._propertiesState.get(property) || null; | |
| 99 }, | |
| 100 | |
| 101 resetActiveProperties: function() | |
| 102 { | |
| 103 /** @type {!Map<!WebInspector.CSSProperty, !WebInspector.SectionCascade.
PropertyState>} */ | |
| 104 this._propertiesState = new Map(); | |
| 105 }, | |
| 106 | |
| 107 /** | |
| 108 * @return {!Map<!WebInspector.CSSProperty, !WebInspector.SectionCascade.Pro
pertyState>} | |
| 109 */ | |
| 110 _computeActiveProperties: function() | |
| 111 { | |
| 112 /** @type {!Set.<string>} */ | |
| 113 var foundImportantProperties = new Set(); | |
| 114 /** @type {!Map.<string, !Map<string, !WebInspector.CSSProperty>>} */ | |
| 115 var propertyToEffectiveRule = new Map(); | |
| 116 /** @type {!Map.<string, !WebInspector.DOMNode>} */ | |
| 117 var inheritedPropertyToNode = new Map(); | |
| 118 /** @type {!Set<string>} */ | |
| 119 var allUsedProperties = new Set(); | |
| 120 var result = new Map(); | |
| 121 for (var i = 0; i < this._styles.length; ++i) { | |
| 122 var style = this._styles[i]; | |
| 123 if (!this.hasMatchingSelectors(style)) | |
| 124 continue; | |
| 125 | |
| 126 /** @type {!Map<string, !WebInspector.CSSProperty>} */ | |
| 127 var styleActiveProperties = new Map(); | |
| 128 var allProperties = style.allProperties; | |
| 129 for (var j = 0; j < allProperties.length; ++j) { | |
| 130 var property = allProperties[j]; | |
| 131 | |
| 132 // Do not pick non-inherited properties from inherited styles. | |
| 133 var inherited = this._matchedStyles.isInherited(style); | |
| 134 if (inherited && !WebInspector.CSSMetadata.isPropertyInherited(p
roperty.name)) | |
| 135 continue; | |
| 136 | |
| 137 if (!property.activeInStyle()) { | |
| 138 result.set(property, WebInspector.SectionCascade.PropertySta
te.Overloaded); | |
| 139 continue; | |
| 140 } | |
| 141 | |
| 142 var canonicalName = WebInspector.CSSMetadata.canonicalPropertyNa
me(property.name); | |
| 143 if (foundImportantProperties.has(canonicalName)) { | |
| 144 result.set(property, WebInspector.SectionCascade.PropertySta
te.Overloaded); | |
| 145 continue; | |
| 146 } | |
| 147 | |
| 148 if (!property.important && allUsedProperties.has(canonicalName))
{ | |
| 149 result.set(property, WebInspector.SectionCascade.PropertySta
te.Overloaded); | |
| 150 continue; | |
| 151 } | |
| 152 | |
| 153 var isKnownProperty = propertyToEffectiveRule.has(canonicalName)
; | |
| 154 var inheritedFromNode = inherited ? this._matchedStyles.nodeForS
tyle(style) : null; | |
| 155 if (!isKnownProperty && inheritedFromNode && !inheritedPropertyT
oNode.has(canonicalName)) | |
| 156 inheritedPropertyToNode.set(canonicalName, inheritedFromNode
); | |
| 157 | |
| 158 if (property.important) { | |
| 159 if (inherited && isKnownProperty && inheritedFromNode !== in
heritedPropertyToNode.get(canonicalName)) { | |
| 160 result.set(property, WebInspector.SectionCascade.Propert
yState.Overloaded); | |
| 161 continue; | |
| 162 } | |
| 163 | |
| 164 foundImportantProperties.add(canonicalName); | |
| 165 if (isKnownProperty) { | |
| 166 var overloaded = propertyToEffectiveRule.get(canonicalNa
me).get(canonicalName); | |
| 167 result.set(overloaded, WebInspector.SectionCascade.Prope
rtyState.Overloaded); | |
| 168 propertyToEffectiveRule.get(canonicalName).delete(canoni
calName); | |
| 169 } | |
| 170 } | |
| 171 | |
| 172 styleActiveProperties.set(canonicalName, property); | |
| 173 allUsedProperties.add(canonicalName); | |
| 174 propertyToEffectiveRule.set(canonicalName, styleActiveProperties
); | |
| 175 result.set(property, WebInspector.SectionCascade.PropertyState.A
ctive); | |
| 176 } | |
| 177 | |
| 178 // If every longhand of the shorthand is not active, then the shorth
and is not active too. | |
| 179 for (var property of style.leadingProperties()) { | |
| 180 var canonicalName = WebInspector.CSSMetadata.canonicalPropertyNa
me(property.name); | |
| 181 if (!styleActiveProperties.has(canonicalName)) | |
| 182 continue; | |
| 183 var longhands = style.longhandProperties(property.name); | |
| 184 if (!longhands.length) | |
| 185 continue; | |
| 186 var notUsed = true; | |
| 187 for (var longhand of longhands) { | |
| 188 var longhandCanonicalName = WebInspector.CSSMetadata.canonic
alPropertyName(longhand.name); | |
| 189 notUsed = notUsed && !styleActiveProperties.has(longhandCano
nicalName); | |
| 190 } | |
| 191 if (!notUsed) | |
| 192 continue; | |
| 193 styleActiveProperties.delete(canonicalName); | |
| 194 allUsedProperties.delete(canonicalName); | |
| 195 result.set(property, WebInspector.SectionCascade.PropertyState.O
verloaded); | |
| 196 } | |
| 197 } | |
| 198 return result; | |
| 199 } | |
| 200 } | |
| 201 | |
| 202 /** @enum {string} */ | |
| 203 WebInspector.SectionCascade.PropertyState = { | |
| 204 Active: "Active", | |
| 205 Overloaded: "Overloaded" | |
| 206 } | |
| OLD | NEW |