diff options
Diffstat (limited to 'js/controllers/styles-controller.js')
-rwxr-xr-x | js/controllers/styles-controller.js | 151 |
1 files changed, 116 insertions, 35 deletions
diff --git a/js/controllers/styles-controller.js b/js/controllers/styles-controller.js index 3a942364..dcbe0eaf 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 | }, |
@@ -111,23 +123,28 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
111 | set : function(sheet) { | 123 | set : function(sheet) { |
112 | if(sheet) { | 124 | if(sheet) { |
113 | this._defaultStylesheet = sheet; | 125 | this._defaultStylesheet = sheet; |
114 | } else if(this._activeDocument.model && this._activeDocument.model.views && this._activeDocument.model.views.design){//check that the document has a design view | 126 | } else { |
115 | 127 | if(sheet === null) { | |
116 | ///// Use the last stylesheet in the document as the default | 128 | this._defaultStylesheet = null; |
117 | 129 | return false; | |
118 | var sheets = this._activeDocument._document.styleSheets, | ||
119 | lastIndex = sheets.length-1; | ||
120 | |||
121 | ///// If the only sheet is the stage stylesheet, this will be true | ||
122 | ///// in which case, we want to create a stylesheet to hold the | ||
123 | ///// user's style rules | ||
124 | |||
125 | if(sheets[lastIndex] === this._stageStyleSheet) { | ||
126 | this._defaultStylesheet = this.createStylesheet('nj-default'); | ||
127 | } else { | ||
128 | this._defaultStylesheet = sheets[lastIndex]; | ||
129 | } | 130 | } |
131 | //check that the document has a design view | ||
132 | else if(this._activeDocument.model && this._activeDocument.model.views && this._activeDocument.model.views.design){ | ||
133 | ///// Use the last stylesheet in the document as the default | ||
134 | |||
135 | var sheets = this._activeDocument._document.styleSheets, | ||
136 | lastIndex = sheets.length-1; | ||
130 | 137 | ||
138 | ///// If the only sheet is the stage stylesheet, this will be true | ||
139 | ///// in which case, we want to create a stylesheet to hold the | ||
140 | ///// user's style rules | ||
141 | |||
142 | if(sheets[lastIndex] === this._stageStyleSheet) { | ||
143 | this._defaultStylesheet = this.createStylesheet('nj-default'); | ||
144 | } else { | ||
145 | this._defaultStylesheet = sheets[lastIndex]; | ||
146 | } | ||
147 | } | ||
131 | } | 148 | } |
132 | } | 149 | } |
133 | }, | 150 | }, |
@@ -158,13 +175,17 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
158 | 175 | ||
159 | addRule : { | 176 | addRule : { |
160 | value : function(selector, declaration, stylesheet, index) { | 177 | value : function(selector, declaration, stylesheet, index) { |
161 | //console.log("Add rule"); | 178 | stylesheet = stylesheet || this._defaultStylesheet; |
179 | |||
180 | if(stylesheet === null) { | ||
181 | stylesheet = this.defaultStylesheet = this.createStylesheet(); | ||
182 | } | ||
183 | |||
162 | var rulesLength = this._defaultStylesheet.rules.length, | 184 | var rulesLength = this._defaultStylesheet.rules.length, |
163 | argType = (typeof declaration), | 185 | argType = (typeof declaration), |
164 | ruleText = selector, | 186 | ruleText = selector, |
165 | stylesheet = stylesheet || this._defaultStylesheet, | 187 | rule; |
166 | property, rule; | 188 | |
167 | |||
168 | index = index || (argType === 'number') ? declaration : rulesLength; | 189 | index = index || (argType === 'number') ? declaration : rulesLength; |
169 | 190 | ||
170 | if(argType === 'string') { | 191 | if(argType === 'string') { |
@@ -182,6 +203,7 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
182 | ///// attach specificity to rule object | 203 | ///// attach specificity to rule object |
183 | ///// if rule is css keyframes, return rule and don't attach specificity | 204 | ///// if rule is css keyframes, return rule and don't attach specificity |
184 | if (rule instanceof WebKitCSSKeyframesRule) { | 205 | if (rule instanceof WebKitCSSKeyframesRule) { |
206 | |||
185 | return rule; | 207 | return rule; |
186 | } | 208 | } |
187 | rule[this.CONST.SPECIFICITY_KEY] = this.getSpecificity(rule.selectorText); | 209 | rule[this.CONST.SPECIFICITY_KEY] = this.getSpecificity(rule.selectorText); |
@@ -208,10 +230,12 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
208 | } | 230 | } |
209 | 231 | ||
210 | var selectorToOverride = getSelector.bind(this)(element, ruleToOverride), | 232 | var selectorToOverride = getSelector.bind(this)(element, ruleToOverride), |
211 | overrideData, rule; | 233 | overrideData, rule, isRuleLocked; |
234 | |||
235 | isRuleLocked = this.isSheetLocked(ruleToOverride.parentStyleSheet); | ||
212 | 236 | ||
213 | ///// Get the overriding selector and className | 237 | ///// Get the overriding selector and className |
214 | overrideData = this.createOverrideSelector(selectorToOverride, element.nodeName); | 238 | overrideData = this.createOverrideSelector(selectorToOverride, element.nodeName, isRuleLocked); |
215 | 239 | ||
216 | ///// Create new rule with selector and insert it after the rule we're overriding | 240 | ///// Create new rule with selector and insert it after the rule we're overriding |
217 | rule = this.addRule(overrideData.selector + ' { }', this.getRuleIndex(ruleToOverride)+1); | 241 | rule = this.addRule(overrideData.selector + ' { }', this.getRuleIndex(ruleToOverride)+1); |
@@ -225,7 +249,7 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
225 | }, | 249 | }, |
226 | 250 | ||
227 | createOverrideSelector : { | 251 | createOverrideSelector : { |
228 | value: function(selectorToOverride, classPrefix, className) { | 252 | value: function(selectorToOverride, classPrefix, increaseSpecificity, className) { |
229 | var tokens = selectorToOverride.split(/\s/), | 253 | var tokens = selectorToOverride.split(/\s/), |
230 | newClass = className || this.generateClassName(classPrefix, true), | 254 | newClass = className || this.generateClassName(classPrefix, true), |
231 | lastToken, pseudoSplit, base, pseudo, newToken, newSelector; | 255 | lastToken, pseudoSplit, base, pseudo, newToken, newSelector; |
@@ -246,10 +270,19 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
246 | if(base.indexOf('#') !== -1) { | 270 | if(base.indexOf('#') !== -1) { |
247 | newToken = base + '.' + newClass + pseudo; | 271 | newToken = base + '.' + newClass + pseudo; |
248 | } else { | 272 | } else { |
249 | ///// Replace last class or attribute selector | 273 | if(increaseSpecificity) { |
250 | ///// Get everything right before the last class or attribute selector | 274 | ///// Increases specificity by one class selector |
251 | ///// to support compound selector values: (i.e. .firstClass.secondClass) | 275 | ///// We'll do a direct append to the base class |
252 | newToken = base.substring(0, Math.max(base.lastIndexOf('.'), base.lastIndexOf('['))); | 276 | ///// if we want to increase the specificity |
277 | newToken = base; | ||
278 | } else { | ||
279 | ///// Maintains original specificity | ||
280 | ///// Replace last class or attribute selector | ||
281 | ///// Get everything right before the last class or attribute selector | ||
282 | ///// to support compound selector values: (i.e. .firstClass.secondClass) | ||
283 | newToken = base.substring(0, Math.max(base.lastIndexOf('.'), base.lastIndexOf('['))); | ||
284 | } | ||
285 | |||
253 | ///// Append the generated class | 286 | ///// Append the generated class |
254 | newToken += '.' + newClass + pseudo; | 287 | newToken += '.' + newClass + pseudo; |
255 | } | 288 | } |
@@ -794,7 +827,7 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
794 | ///// method to apply/test the new value | 827 | ///// method to apply/test the new value |
795 | dec.setProperty(property, value, priority); | 828 | dec.setProperty(property, value, priority); |
796 | 829 | ||
797 | if(rule.parentStyleSheet) { | 830 | if(rule.type !== 'inline' && rule.parentStyleSheet) { |
798 | this.styleSheetModified(rule.parentStyleSheet); | 831 | this.styleSheetModified(rule.parentStyleSheet); |
799 | } | 832 | } |
800 | 833 | ||
@@ -970,12 +1003,13 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
970 | var doc = element.ownerDocument, | 1003 | var doc = element.ownerDocument, |
971 | useImportant = false, | 1004 | useImportant = false, |
972 | cache = this._getCachedRuleForProperty(element, property), | 1005 | cache = this._getCachedRuleForProperty(element, property), |
973 | dominantRule, override, className, browserValue; | 1006 | dominantRule, override, className, browserValue, cacheMatchesMany; |
974 | 1007 | ||
975 | if(cache) { | 1008 | if(cache) { |
976 | ///// We've cached the rule for this property! | 1009 | ///// We've cached the rule for this property! |
977 | //console.log('Styles Controller :: setElementStyle - We found the cached rule!'); | 1010 | //console.log('Styles Controller :: setElementStyle - We found the cached rule!'); |
978 | dominantRule = cache; | 1011 | dominantRule = cache; |
1012 | cacheMatchesMany = this.matchesMultipleElements(dominantRule, doc); | ||
979 | } else { | 1013 | } else { |
980 | ///// Use Dominant Rule logic to find the right place to add the style | 1014 | ///// Use Dominant Rule logic to find the right place to add the style |
981 | ///// Pass "true" to method to return an override object, which | 1015 | ///// Pass "true" to method to return an override object, which |
@@ -983,7 +1017,7 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
983 | dominantRule = this.getDominantRuleForElement(element, property, true, isStageElement); | 1017 | dominantRule = this.getDominantRuleForElement(element, property, true, isStageElement); |
984 | 1018 | ||
985 | } | 1019 | } |
986 | 1020 | ||
987 | ///// Did we find a dominant rule? | 1021 | ///// Did we find a dominant rule? |
988 | if(!dominantRule) { | 1022 | if(!dominantRule) { |
989 | ///// No. This means there was no rule with this property, and no | 1023 | ///// No. This means there was no rule with this property, and no |
@@ -1001,6 +1035,13 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||