aboutsummaryrefslogtreecommitdiff
path: root/js/controllers/styles-controller.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/controllers/styles-controller.js')
-rwxr-xr-xjs/controllers/styles-controller.js70
1 files changed, 54 insertions, 16 deletions
diff --git a/js/controllers/styles-controller.js b/js/controllers/styles-controller.js
index 647c0870..cbc00676 100755
--- a/js/controllers/styles-controller.js
+++ b/js/controllers/styles-controller.js
@@ -94,11 +94,18 @@ var stylesController = exports.StylesController = Montage.create(Component, {
94 // Returns null if sheet not found (as in non-ninja projects) 94 // Returns null if sheet not found (as in non-ninja projects)
95 // Setter will handle null case 95 // Setter will handle null case
96 this.defaultStylesheet = this.getSheetFromElement(this.CONST.DEFAULT_SHEET_ID); 96 this.defaultStylesheet = this.getSheetFromElement(this.CONST.DEFAULT_SHEET_ID);
97 97
98 //debugger; 98 this.userStyleSheets = nj.toArray(document._document.styleSheets).filter(function(sheet) {
99 return sheet !== this._stageStylesheet;
100 }, this);
101
102 NJevent('styleSheetsReady', this);
99 }, 103 },
100 enumerable : false 104 enumerable : false
101 }, 105 },
106 userStyleSheets : {
107 value : null
108 },
102 _stageStylesheet : { 109 _stageStylesheet : {
103 value : null 110 value : null
104 }, 111 },
@@ -183,6 +190,7 @@ var stylesController = exports.StylesController = Montage.create(Component, {
183 ///// attach specificity to rule object 190 ///// attach specificity to rule object
184 ///// if rule is css keyframes, return rule and don't attach specificity 191 ///// if rule is css keyframes, return rule and don't attach specificity
185 if (rule instanceof WebKitCSSKeyframesRule) { 192 if (rule instanceof WebKitCSSKeyframesRule) {
193
186 return rule; 194 return rule;
187 } 195 }
188 rule[this.CONST.SPECIFICITY_KEY] = this.getSpecificity(rule.selectorText); 196 rule[this.CONST.SPECIFICITY_KEY] = this.getSpecificity(rule.selectorText);
@@ -209,10 +217,12 @@ var stylesController = exports.StylesController = Montage.create(Component, {
209 } 217 }
210 218
211 var selectorToOverride = getSelector.bind(this)(element, ruleToOverride), 219 var selectorToOverride = getSelector.bind(this)(element, ruleToOverride),
212 overrideData, rule; 220 overrideData, rule, isRuleLocked;
221
222 isRuleLocked = this.isSheetLocked(ruleToOverride.parentStyleSheet);
213 223
214 ///// Get the overriding selector and className 224 ///// Get the overriding selector and className
215 overrideData = this.createOverrideSelector(selectorToOverride, element.nodeName); 225 overrideData = this.createOverrideSelector(selectorToOverride, element.nodeName, isRuleLocked);
216 226
217 ///// 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
218 rule = this.addRule(overrideData.selector + ' { }', this.getRuleIndex(ruleToOverride)+1); 228 rule = this.addRule(overrideData.selector + ' { }', this.getRuleIndex(ruleToOverride)+1);
@@ -226,7 +236,7 @@ var stylesController = exports.StylesController = Montage.create(Component, {
226 }, 236 },
227 237
228 createOverrideSelector : { 238 createOverrideSelector : {
229 value: function(selectorToOverride, classPrefix, className) { 239 value: function(selectorToOverride, classPrefix, increaseSpecificity, className) {
230 var tokens = selectorToOverride.split(/\s/), 240 var tokens = selectorToOverride.split(/\s/),
231 newClass = className || this.generateClassName(classPrefix, true), 241 newClass = className || this.generateClassName(classPrefix, true),
232 lastToken, pseudoSplit, base, pseudo, newToken, newSelector; 242 lastToken, pseudoSplit, base, pseudo, newToken, newSelector;
@@ -247,10 +257,19 @@ var stylesController = exports.StylesController = Montage.create(Component, {
247 if(base.indexOf('#') !== -1) { 257 if(base.indexOf('#') !== -1) {
248 newToken = base + '.' + newClass + pseudo; 258 newToken = base + '.' + newClass + pseudo;
249 } else { 259 } else {
250 ///// Replace last class or attribute selector 260 if(increaseSpecificity) {
251 ///// Get everything right before the last class or attribute selector 261 ///// Increases specificity by one class selector
252 ///// to support compound selector values: (i.e. .firstClass.secondClass) 262 ///// We'll do a direct append to the base class
253 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
254 ///// Append the generated class 273 ///// Append the generated class
255 newToken += '.' + newClass + pseudo; 274 newToken += '.' + newClass + pseudo;
256 } 275 }
@@ -795,7 +814,9 @@ var stylesController = exports.StylesController = Montage.create(Component, {
795 ///// method to apply/test the new value 814 ///// method to apply/test the new value
796 dec.setProperty(property, value, priority); 815 dec.setProperty(property, value, priority);
797 816
798 this.styleSheetModified(rule.parentStyleSheet); 817 if(rule.parentStyleSheet) {
818 this.styleSheetModified(rule.parentStyleSheet);
819 }
799 820
800 ///// Return browser value for value we just set 821 ///// Return browser value for value we just set
801 return dec.getPropertyValue(property); 822 return dec.getPropertyValue(property);
@@ -969,12 +990,13 @@ var stylesController = exports.StylesController = Montage.create(Component, {
969 var doc = element.ownerDocument, 990 var doc = element.ownerDocument,
970 useImportant = false, 991 useImportant = false,
971 cache = this._getCachedRuleForProperty(element, property), 992 cache = this._getCachedRuleForProperty(element, property),
972 dominantRule, override, className, browserValue; 993 dominantRule, override, className, browserValue, cacheMatchesMany;
973 994
974 if(cache) { 995 if(cache) {
975 ///// We've cached the rule for this property! 996 ///// We've cached the rule for this property!
976 //console.log('Styles Controller :: setElementStyle - We found the cached rule!'); 997 //console.log('Styles Controller :: setElementStyle - We found the cached rule!');
977 dominantRule = cache; 998 dominantRule = cache;
999 cacheMatchesMany = this.matchesMultipleElements(dominantRule, doc);
978 } else { 1000 } else {
979 ///// 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
980 ///// Pass "true" to method to return an override object, which 1002 ///// Pass "true" to method to return an override object, which
@@ -982,7 +1004,7 @@ var stylesController = exports.StylesController = Montage.create(Component, {
982 dominantRule = this.getDominantRuleForElement(element, property, true, isStageElement); 1004 dominantRule = this.getDominantRuleForElement(element, property, true, isStageElement);
983 1005
984 } 1006 }
985 1007
986 ///// Did we find a dominant rule? 1008 ///// Did we find a dominant rule?
987 if(!dominantRule) { 1009 if(!dominantRule) {
988 ///// 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
@@ -1000,6 +1022,13 @@ var stylesController = exports.StylesController = Montage.create(Component, {
1000 useImportant = dominantRule.useImportant; 1022 useImportant = dominantRule.useImportant;
1001 dominantRule = override.rule; 1023 dominantRule = override.rule;
1002 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);
1003 } 1032 }
1004 1033
1005 1034
@@ -1007,7 +1036,7 @@ var stylesController = exports.StylesController = Montage.create(Component, {
1007 browserValue = this.setStyle(dominantRule, property, value, useImportant); 1036 browserValue = this.setStyle(dominantRule, property, value, useImportant);
1008 1037
1009 ///// 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
1010 if(browserValue && !cache) { 1039 if(browserValue && (!cache || cacheMatchesMany)) {
1011 this._setCachedRuleForProperty(element, property, dominantRule); 1040 this._setCachedRuleForProperty(element, property, dominantRule);
1012 } 1041 }
1013 1042
@@ -1242,8 +1271,12 @@ var stylesController = exports.StylesController = Montage.create(Component, {
1242 doc.head.appendChild(sheetElement); 1271 doc.head.appendChild(sheetElement);
1243 sheet = this.getSheetFromElement(sheetElement, doc); 1272 sheet = this.getSheetFromElement(sheetElement, doc);
1244 1273
1274 this.userStyleSheets.push(sheet);
1275
1245 this.styleSheetModified(sheet); 1276 this.styleSheetModified(sheet);
1246 1277
1278 NJevent('newStyleSheet', sheet);
1279
1247 return sheet; 1280 return sheet;
1248 } 1281 }
1249 }, 1282 },
@@ -1266,6 +1299,12 @@ var stylesController = exports.StylesController = Montage.create(Component, {
1266 } 1299 }
1267 }, 1300 },
1268 1301
1302 isSheetLocked : {
1303 value: function(sheet) {
1304 return !!sheet.ownerNode.dataset['ninjaFileReadOnly'];
1305 }
1306 },
1307
1269 ///// Style Sheet Modified 1308 ///// Style Sheet Modified
1270 ///// Method to call whenever a stylesheet change is made 1309 ///// Method to call whenever a stylesheet change is made
1271 ///// Dispatches an event, and keeps list of dirty style sheets 1310 ///// Dispatches an event, and keeps list of dirty style sheets
@@ -1306,11 +1345,10 @@ var stylesController = exports.StylesController = Montage.create(Component, {
1306 this.dirtyStyleSheets.length = 0; 1345 this.dirtyStyleSheets.length = 0;
1307 1346
1308 if(doc) { 1347 if(doc) {
1309 var stillDirty = this.dirtyStyleSheets.filter(function(sheet) { 1348 this.dirtyStyleSheets = null;
1349 this.dirtyStyleSheets = this.dirtyStyleSheets.filter(function(sheet) {
1310 return sheet.document !== doc; 1350 return sheet.document !== doc;
1311 }); 1351 });
1312 this.dirtyStyleSheets = null;
1313 this.dirtyStyleSheets = stillDirty;
1314 } 1352 }
1315 1353
1316 1354