aboutsummaryrefslogtreecommitdiff
path: root/js/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'js/controllers')
-rwxr-xr-xjs/controllers/styles-controller.js66
1 files changed, 51 insertions, 15 deletions
diff --git a/js/controllers/styles-controller.js b/js/controllers/styles-controller.js
index 2ff3e235..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 }
@@ -971,12 +990,13 @@ var stylesController = exports.StylesController = Montage.create(Component, {
971 var doc = element.ownerDocument, 990 var doc = element.ownerDocument,
972 useImportant = false, 991 useImportant = false,
973 cache = this._getCachedRuleForProperty(element, property), 992 cache = this._getCachedRuleForProperty(element, property),
974 dominantRule, override, className, browserValue; 993 dominantRule, override, className, browserValue, cacheMatchesMany;
975 994
976 if(cache) { 995 if(cache) {
977 ///// We've cached the rule for this property! 996 ///// We've cached the rule for this property!
978 //console.log('Styles Controller :: setElementStyle - We found the cached rule!'); 997 //console.log('Styles Controller :: setElementStyle - We found the cached rule!');
979 dominantRule = cache; 998 dominantRule = cache;
999 cacheMatchesMany = this.matchesMultipleElements(dominantRule, doc);
980 } else { 1000 } else {
981 ///// 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
982 ///// Pass "true" to method to return an override object, which 1002 ///// Pass "true" to method to return an override object, which
@@ -984,7 +1004,7 @@ var stylesController = exports.StylesController = Montage.create(Component, {
984 dominantRule = this.getDominantRuleForElement(element, property, true, isStageElement); 1004 dominantRule = this.getDominantRuleForElement(element, property, true, isStageElement);
985 1005
986 } 1006 }
987 1007
988 ///// Did we find a dominant rule? 1008 ///// Did we find a dominant rule?
989 if(!dominantRule) { 1009 if(!dominantRule) {
990 ///// 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
@@ -1002,6 +1022,13 @@ var stylesController = exports.StylesController = Montage.create(Component, {
1002 useImportant = dominantRule.useImportant; 1022 useImportant = dominantRule.useImportant;
1003 dominantRule = override.rule; 1023 dominantRule = override.rule;
1004 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);
1005 } 1032 }
1006 1033
1007 1034
@@ -1009,7 +1036,7 @@ var stylesController = exports.StylesController = Montage.create(Component, {
1009 browserValue = this.setStyle(dominantRule, property, value, useImportant); 1036 browserValue = this.setStyle(dominantRule, property, value, useImportant);
1010 1037
1011 ///// 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
1012 if(browserValue && !cache) { 1039 if(browserValue && (!cache || cacheMatchesMany)) {
1013 this._setCachedRuleForProperty(element, property, dominantRule); 1040 this._setCachedRuleForProperty(element, property, dominantRule);
1014 } 1041 }
1015 1042
@@ -1244,8 +1271,12 @@ var stylesController = exports.StylesController = Montage.create(Component, {
1244 doc.head.appendChild(sheetElement); 1271 doc.head.appendChild(sheetElement);
1245 sheet = this.getSheetFromElement(sheetElement, doc); 1272 sheet = this.getSheetFromElement(sheetElement, doc);
1246 1273
1274 this.userStyleSheets.push(sheet);
1275
1247 this.styleSheetModified(sheet); 1276 this.styleSheetModified(sheet);
1248 1277
1278 NJevent('newStyleSheet', sheet);
1279
1249 return sheet; 1280 return sheet;
1250 } 1281 }
1251 }, 1282 },
@@ -1268,6 +1299,12 @@ var stylesController = exports.StylesController = Montage.create(Component, {
1268 } 1299 }
1269 }, 1300 },
1270 1301
1302 isSheetLocked : {
1303 value: function(sheet) {
1304 return !!sheet.ownerNode.dataset['ninjaFileReadOnly'];
1305 }
1306 },
1307
1271 ///// Style Sheet Modified 1308 ///// Style Sheet Modified
1272 ///// Method to call whenever a stylesheet change is made 1309 ///// Method to call whenever a stylesheet change is made
1273 ///// Dispatches an event, and keeps list of dirty style sheets 1310 ///// Dispatches an event, and keeps list of dirty style sheets
@@ -1308,11 +1345,10 @@ var stylesController = exports.StylesController = Montage.create(Component, {
1308 this.dirtyStyleSheets.length = 0; 1345 this.dirtyStyleSheets.length = 0;
1309 1346
1310 if(doc) { 1347 if(doc) {
1311 var stillDirty = this.dirtyStyleSheets.filter(function(sheet) { 1348 this.dirtyStyleSheets = null;
1349 this.dirtyStyleSheets = this.dirtyStyleSheets.filter(function(sheet) {
1312 return sheet.document !== doc; 1350 return sheet.document !== doc;
1313 }); 1351 });
1314 this.dirtyStyleSheets = null;
1315 this.dirtyStyleSheets = stillDirty;
1316 } 1352 }
1317 1353
1318 1354