aboutsummaryrefslogtreecommitdiff
path: root/js/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'js/controllers')
-rwxr-xr-xjs/controllers/styles-controller.js80
1 files changed, 64 insertions, 16 deletions
diff --git a/js/controllers/styles-controller.js b/js/controllers/styles-controller.js
index ae504f0e..f6977a00 100755
--- a/js/controllers/styles-controller.js
+++ b/js/controllers/styles-controller.js
@@ -82,6 +82,11 @@ var stylesController = exports.StylesController = Montage.create(Component, {
82 ///// If the document is null set default stylesheets to null 82 ///// If the document is null set default stylesheets to null
83 83
84 if(!document) { 84 if(!document) {
85 this._activeDocument = null;
86 this._stageStylesheet = null;
87 this.defaultStylesheet = null;
88 this.userStyleSheets = [];
89 this.clearDirtyStyleSheets();
85 return false; 90 return false;
86 } 91 }
87 92
@@ -93,11 +98,18 @@ var stylesController = exports.StylesController = Montage.create(Component, {
93 // Returns null if sheet not found (as in non-ninja projects) 98 // Returns null if sheet not found (as in non-ninja projects)
94 // Setter will handle null case 99 // Setter will handle null case
95 this.defaultStylesheet = this.getSheetFromElement(this.CONST.DEFAULT_SHEET_ID); 100 this.defaultStylesheet = this.getSheetFromElement(this.CONST.DEFAULT_SHEET_ID);
96 101
97 //debugger; 102 this.userStyleSheets = nj.toArray(document._document.styleSheets).filter(function(sheet) {
103 return sheet !== this._stageStylesheet;
104 }, this);
105
106 NJevent('styleSheetsReady', this);
98 }, 107 },
99 enumerable : false 108 enumerable : false
100 }, 109 },
110 userStyleSheets : {
111 value : null
112 },
101 _stageStylesheet : { 113 _stageStylesheet : {
102 value : null 114 value : null
103 }, 115 },
@@ -112,7 +124,10 @@ var stylesController = exports.StylesController = Montage.create(Component, {
112 if(sheet) { 124 if(sheet) {
113 this._defaultStylesheet = sheet; 125 this._defaultStylesheet = sheet;
114 } else { 126 } else {
115 127 if(sheet === null) {
128 this._defaultStylesheet = null;
129 return false;
130 }
116 ///// Use the last stylesheet in the document as the default 131 ///// Use the last stylesheet in the document as the default
117 132
118 var sheets = this._activeDocument._document.styleSheets, 133 var sheets = this._activeDocument._document.styleSheets,
@@ -182,6 +197,7 @@ var stylesController = exports.StylesController = Montage.create(Component, {
182 ///// attach specificity to rule object 197 ///// attach specificity to rule object
183 ///// if rule is css keyframes, return rule and don't attach specificity 198 ///// if rule is css keyframes, return rule and don't attach specificity
184 if (rule instanceof WebKitCSSKeyframesRule) { 199 if (rule instanceof WebKitCSSKeyframesRule) {
200
185 return rule; 201 return rule;
186 } 202 }
187 rule[this.CONST.SPECIFICITY_KEY] = this.getSpecificity(rule.selectorText); 203 rule[this.CONST.SPECIFICITY_KEY] = this.getSpecificity(rule.selectorText);
@@ -208,10 +224,12 @@ var stylesController = exports.StylesController = Montage.create(Component, {
208 } 224 }
209 225
210 var selectorToOverride = getSelector.bind(this)(element, ruleToOverride), 226 var selectorToOverride = getSelector.bind(this)(element, ruleToOverride),
211 overrideData, rule; 227 overrideData, rule, isRuleLocked;
228
229 isRuleLocked = this.isSheetLocked(ruleToOverride.parentStyleSheet);
212 230
213 ///// Get the overriding selector and className 231 ///// Get the overriding selector and className
214 overrideData = this.createOverrideSelector(selectorToOverride, element.nodeName); 232 overrideData = this.createOverrideSelector(selectorToOverride, element.nodeName, isRuleLocked);
215 233
216 ///// Create new rule with selector and insert it after the rule we're overriding 234 ///// Create new rule with selector and insert it after the rule we're overriding
217 rule = this.addRule(overrideData.selector + ' { }', this.getRuleIndex(ruleToOverride)+1); 235 rule = this.addRule(overrideData.selector + ' { }', this.getRuleIndex(ruleToOverride)+1);
@@ -225,7 +243,7 @@ var stylesController = exports.StylesController = Montage.create(Component, {
225 }, 243 },
226 244
227 createOverrideSelector : { 245 createOverrideSelector : {
228 value: function(selectorToOverride, classPrefix, className) { 246 value: function(selectorToOverride, classPrefix, increaseSpecificity, className) {
229 var tokens = selectorToOverride.split(/\s/), 247 var tokens = selectorToOverride.split(/\s/),
230 newClass = className || this.generateClassName(classPrefix, true), 248 newClass = className || this.generateClassName(classPrefix, true),
231 lastToken, pseudoSplit, base, pseudo, newToken, newSelector; 249 lastToken, pseudoSplit, base, pseudo, newToken, newSelector;
@@ -246,10 +264,19 @@ var stylesController = exports.StylesController = Montage.create(Component, {
246 if(base.indexOf('#') !== -1) { 264 if(base.indexOf('#') !== -1) {
247 newToken = base + '.' + newClass + pseudo; 265 newToken = base + '.' + newClass + pseudo;
248 } else { 266 } else {
249 ///// Replace last class or attribute selector 267 if(increaseSpecificity) {
250 ///// Get everything right before the last class or attribute selector 268 ///// Increases specificity by one class selector
251 ///// to support compound selector values: (i.e. .firstClass.secondClass) 269 ///// We'll do a direct append to the base class
252 newToken = base.substring(0, Math.max(base.lastIndexOf('.'), base.lastIndexOf('['))); 270 ///// if we want to increase the specificity
271 newToken = base;
272 } else {
273 ///// Maintains original specificity
274 ///// Replace last class or attribute selector
275 ///// Get everything right before the last class or attribute selector
276 ///// to support compound selector values: (i.e. .firstClass.secondClass)
277 newToken = base.substring(0, Math.max(base.lastIndexOf('.'), base.lastIndexOf('[')));
278 }
279
253 ///// Append the generated class 280 ///// Append the generated class
254 newToken += '.' + newClass + pseudo; 281 newToken += '.' + newClass + pseudo;
255 } 282 }
@@ -970,12 +997,13 @@ var stylesController = exports.StylesController = Montage.create(Component, {
970 var doc = element.ownerDocument, 997 var doc = element.ownerDocument,
971 useImportant = false, 998 useImportant = false,
972 cache = this._getCachedRuleForProperty(element, property), 999 cache = this._getCachedRuleForProperty(element, property),
973 dominantRule, override, className, browserValue; 1000 dominantRule, override, className, browserValue, cacheMatchesMany;
974 1001
975 if(cache) { 1002 if(cache) {
976 ///// We've cached the rule for this property! 1003 ///// We've cached the rule for this property!
977 //console.log('Styles Controller :: setElementStyle - We found the cached rule!'); 1004 //console.log('Styles Controller :: setElementStyle - We found the cached rule!');
978 dominantRule = cache; 1005 dominantRule = cache;
1006 cacheMatchesMany = this.matchesMultipleElements(dominantRule, doc);
979 } else { 1007 } else {
980 ///// Use Dominant Rule logic to find the right place to add the style 1008 ///// Use Dominant Rule logic to find the right place to add the style
981 ///// Pass "true" to method to return an override object, which 1009 ///// Pass "true" to method to return an override object, which
@@ -983,7 +1011,7 @@ var stylesController = exports.StylesController = Montage.create(Component, {
983 dominantRule = this.getDominantRuleForElement(element, property, true, isStageElement); 1011 dominantRule = this.getDominantRuleForElement(element, property, true, isStageElement);
984 1012
985 } 1013 }
986 1014
987 ///// Did we find a dominant rule? 1015 ///// Did we find a dominant rule?
988 if(!dominantRule) { 1016 if(!dominantRule) {
989 ///// No. This means there was no rule with this property, and no 1017 ///// No. This means there was no rule with this property, and no
@@ -1001,6 +1029,13 @@ var stylesController = exports.StylesController = Montage.create(Component, {
1001 useImportant = dominantRule.useImportant; 1029 useImportant = dominantRule.useImportant;
1002 dominantRule = override.rule; 1030 dominantRule = override.rule;
1003 this.addClass(element, override.className); 1031 this.addClass(element, override.className);
1032 } else if(cacheMatchesMany) {
1033 ///// Only happens when the cached rule applies to multiple
1034 ///// elements - we must create override
1035 override = this.createOverrideRule(dominantRule, element);
1036 useImportant = !!dominantRule.style.getPropertyPriority(property);
1037 dominantRule = override.rule;
1038 this.addClass(element, override.className);
1004 } 1039 }
1005 1040
1006 1041
@@ -1008,7 +1043,7 @@ var stylesController = exports.StylesController = Montage.create(Component, {
1008 browserValue = this.setStyle(dominantRule, property, value, useImportant); 1043 browserValue = this.setStyle(dominantRule, property, value, useImportant);
1009 1044
1010 ///// Only cache the dominant rule if the style value was valid, and not already cached 1045 ///// Only cache the dominant rule if the style value was valid, and not already cached
1011 if(browserValue && !cache) { 1046 if(browserValue && (!cache || cacheMatchesMany)) {
1012 this._setCachedRuleForProperty(element, property, dominantRule); 1047 this._setCachedRuleForProperty(element, property, dominantRule);
1013 } 1048 }
1014 1049
@@ -1245,8 +1280,12 @@ var stylesController = exports.StylesController = Montage.create(Component, {
1245 doc.head.appendChild(sheetElement); 1280 doc.head.appendChild(sheetElement);
1246 sheet = this.getSheetFromElement(sheetElement, doc); 1281 sheet = this.getSheetFromElement(sheetElement, doc);
1247 1282
1283 this.userStyleSheets.push(sheet);
1284
1248 this.styleSheetModified(sheet); 1285 this.styleSheetModified(sheet);
1249 1286
1287 NJevent('newStyleSheet', sheet);
1288
1250 return sheet; 1289 return sheet;
1251 } 1290 }
1252 }, 1291 },
@@ -1269,6 +1308,12 @@ var stylesController = exports.StylesController = Montage.create(Component, {
1269 } 1308 }
1270 }, 1309 },
1271 1310
1311 isSheetLocked : {
1312 value: function(sheet) {
1313 return !!sheet.ownerNode.dataset['ninjaFileReadOnly'];
1314 }
1315 },
1316
1272 ///// Style Sheet Modified 1317 ///// Style Sheet Modified
1273 ///// Method to call whenever a stylesheet change is made 1318 ///// Method to call whenever a stylesheet change is made
1274 ///// Dispatches an event, and keeps list of dirty style sheets 1319 ///// Dispatches an event, and keeps list of dirty style sheets
@@ -1279,6 +1324,9 @@ var stylesController = exports.StylesController = Montage.create(Component, {
1279 return sheetObj.stylesheet === sheet; 1324 return sheetObj.stylesheet === sheet;
1280 }); 1325 });
1281 1326
1327 ///// Dispatch modified event
1328 NJevent('styleSheetModified', eventData);
1329
1282 ///// If the sheet doesn't already exist in the list of modified 1330 ///// If the sheet doesn't already exist in the list of modified
1283 ///// sheets, dispatch dirty event and add the sheet to the list