diff options
-rwxr-xr-x | js/controllers/styles-controller.js | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/js/controllers/styles-controller.js b/js/controllers/styles-controller.js index dfe7c69a..02c3dad9 100755 --- a/js/controllers/styles-controller.js +++ b/js/controllers/styles-controller.js | |||
@@ -217,10 +217,12 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
217 | } | 217 | } |
218 | 218 | ||
219 | var selectorToOverride = getSelector.bind(this)(element, ruleToOverride), | 219 | var selectorToOverride = getSelector.bind(this)(element, ruleToOverride), |
220 | overrideData, rule; | 220 | overrideData, rule, isRuleLocked; |
221 | |||
222 | isRuleLocked = this.isSheetLocked(ruleToOverride.parentStyleSheet); | ||
221 | 223 | ||
222 | ///// Get the overriding selector and className | 224 | ///// Get the overriding selector and className |
223 | overrideData = this.createOverrideSelector(selectorToOverride, element.nodeName); | 225 | overrideData = this.createOverrideSelector(selectorToOverride, element.nodeName, isRuleLocked); |
224 | 226 | ||
225 | ///// Create new rule with selector and insert it after the rule we're overriding | 227 | ///// Create new rule with selector and insert it after the rule we're overriding |
226 | rule = this.addRule(overrideData.selector + ' { }', this.getRuleIndex(ruleToOverride)+1); | 228 | rule = this.addRule(overrideData.selector + ' { }', this.getRuleIndex(ruleToOverride)+1); |
@@ -234,7 +236,7 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
234 | }, | 236 | }, |
235 | 237 | ||
236 | createOverrideSelector : { | 238 | createOverrideSelector : { |
237 | value: function(selectorToOverride, classPrefix, className) { | 239 | value: function(selectorToOverride, classPrefix, increaseSpecificity, className) { |
238 | var tokens = selectorToOverride.split(/\s/), | 240 | var tokens = selectorToOverride.split(/\s/), |
239 | newClass = className || this.generateClassName(classPrefix, true), | 241 | newClass = className || this.generateClassName(classPrefix, true), |
240 | lastToken, pseudoSplit, base, pseudo, newToken, newSelector; | 242 | lastToken, pseudoSplit, base, pseudo, newToken, newSelector; |
@@ -255,10 +257,19 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
255 | if(base.indexOf('#') !== -1) { | 257 | if(base.indexOf('#') !== -1) { |
256 | newToken = base + '.' + newClass + pseudo; | 258 | newToken = base + '.' + newClass + pseudo; |
257 | } else { | 259 | } else { |
258 | ///// Replace last class or attribute selector | 260 | if(increaseSpecificity) { |
259 | ///// Get everything right before the last class or attribute selector | 261 | ///// Increases specificity by one class selector |
260 | ///// to support compound selector values: (i.e. .firstClass.secondClass) | 262 | ///// We'll do a direct append to the base class |
261 | newToken = base.substring(0, Math.max(base.lastIndexOf('.'), base.lastIndexOf('['))); | 263 | ///// if we want to increase the specificity |
264 | newToken = base; | ||
265 | } else { | ||
266 | ///// Maintains original specificity | ||
267 | ///// Replace last class or attribute selector | ||
268 | ///// Get everything right before the last class or attribute selector | ||
269 | ///// to support compound selector values: (i.e. .firstClass.secondClass) | ||
270 | newToken = base.substring(0, Math.max(base.lastIndexOf('.'), base.lastIndexOf('['))); | ||
271 | } | ||
272 | |||
262 | ///// Append the generated class | 273 | ///// Append the generated class |
263 | newToken += '.' + newClass + pseudo; | 274 | newToken += '.' + newClass + pseudo; |
264 | } | 275 | } |
@@ -979,12 +990,13 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
979 | var doc = element.ownerDocument, | 990 | var doc = element.ownerDocument, |
980 | useImportant = false, | 991 | useImportant = false, |
981 | cache = this._getCachedRuleForProperty(element, property), | 992 | cache = this._getCachedRuleForProperty(element, property), |
982 | dominantRule, override, className, browserValue; | 993 | dominantRule, override, className, browserValue, cacheMatchesMany; |
983 | 994 | ||
984 | if(cache) { | 995 | if(cache) { |
985 | ///// We've cached the rule for this property! | 996 | ///// We've cached the rule for this property! |
986 | //console.log('Styles Controller :: setElementStyle - We found the cached rule!'); | 997 | //console.log('Styles Controller :: setElementStyle - We found the cached rule!'); |
987 | dominantRule = cache; | 998 | dominantRule = cache; |
999 | cacheMatchesMany = this.matchesMultipleElements(dominantRule, doc); | ||
988 | } else { | 1000 | } else { |
989 | ///// Use Dominant Rule logic to find the right place to add the style | 1001 | ///// Use Dominant Rule logic to find the right place to add the style |
990 | ///// Pass "true" to method to return an override object, which | 1002 | ///// Pass "true" to method to return an override object, which |
@@ -992,7 +1004,7 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
992 | dominantRule = this.getDominantRuleForElement(element, property, true, isStageElement); | 1004 | dominantRule = this.getDominantRuleForElement(element, property, true, isStageElement); |
993 | 1005 | ||
994 | } | 1006 | } |
995 | 1007 | ||
996 | ///// Did we find a dominant rule? | 1008 | ///// Did we find a dominant rule? |
997 | if(!dominantRule) { | 1009 | if(!dominantRule) { |
998 | ///// No. This means there was no rule with this property, and no | 1010 | ///// No. This means there was no rule with this property, and no |
@@ -1010,6 +1022,13 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
1010 | useImportant = dominantRule.useImportant; | 1022 | useImportant = dominantRule.useImportant; |
1011 | dominantRule = override.rule; | 1023 | dominantRule = override.rule; |
1012 | this.addClass(element, override.className); | 1024 | this.addClass(element, override.className); |
1025 | } else if(cacheMatchesMany) { | ||
1026 | ///// Only happens when the cached rule applies to multiple | ||
1027 | ///// elements - we must create override | ||
1028 | override = this.createOverrideRule(dominantRule, element); | ||
1029 | useImportant = !!dominantRule.style.getPropertyPriority(property); | ||
1030 | dominantRule = override.rule; | ||
1031 | this.addClass(element, override.className); | ||
1013 | } | 1032 | } |
1014 | 1033 | ||
1015 | 1034 | ||
@@ -1017,7 +1036,7 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
1017 | browserValue = this.setStyle(dominantRule, property, value, useImportant); | 1036 | browserValue = this.setStyle(dominantRule, property, value, useImportant); |
1018 | 1037 | ||
1019 | ///// Only cache the dominant rule if the style value was valid, and not already cached | 1038 | ///// Only cache the dominant rule if the style value was valid, and not already cached |
1020 | if(browserValue && !cache) { | 1039 | if(browserValue && (!cache || cacheMatchesMany)) { |
1021 | this._setCachedRuleForProperty(element, property, dominantRule); | 1040 | this._setCachedRuleForProperty(element, property, dominantRule); |
1022 | } | 1041 | } |
1023 | 1042 | ||
@@ -1280,6 +1299,12 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
1280 | } | 1299 | } |
1281 | }, | 1300 | }, |
1282 | 1301 | ||
1302 | isSheetLocked : { | ||
1303 | value: function(sheet) { | ||
1304 | return !!sheet.ownerNode.dataset['ninjaFileReadOnly']; | ||
1305 | } | ||
1306 | }, | ||
1307 | |||
1283 | ///// Style Sheet Modified | 1308 | ///// Style Sheet Modified |
1284 | ///// Method to call whenever a stylesheet change is made | 1309 | ///// Method to call whenever a stylesheet change is made |
1285 | ///// Dispatches an event, and keeps list of dirty style sheets | 1310 | ///// Dispatches an event, and keeps list of dirty style sheets |