diff options
Diffstat (limited to 'js/controllers/styles-controller.js')
-rwxr-xr-x | js/controllers/styles-controller.js | 232 |
1 files changed, 205 insertions, 27 deletions
diff --git a/js/controllers/styles-controller.js b/js/controllers/styles-controller.js index afd298c9..011caec5 100755 --- a/js/controllers/styles-controller.js +++ b/js/controllers/styles-controller.js | |||
@@ -171,10 +171,12 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
171 | if(argType === 'string') { | 171 | if(argType === 'string') { |
172 | ruleText += '{' + declaration + '}'; | 172 | ruleText += '{' + declaration + '}'; |
173 | } else if(argType === 'object') { | 173 | } else if(argType === 'object') { |
174 | ruleText += '{' + nj.cssFromObject(declaration) + '}'; | 174 | ruleText += '{' + this.cssFromObject(declaration) + '}'; |
175 | } | 175 | } |
176 | 176 | ||
177 | stylesheet.insertRule(ruleText, index); | 177 | stylesheet.insertRule(ruleText, index); |
178 | |||
179 | this.styleSheetModified(stylesheet); | ||
178 | 180 | ||
179 | rule = stylesheet.rules[index]; | 181 | rule = stylesheet.rules[index]; |
180 | 182 | ||
@@ -199,25 +201,42 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
199 | 201 | ||
200 | ///// Locally-scoped function to de-clutter variable declarations | 202 | ///// Locally-scoped function to de-clutter variable declarations |
201 | function getSelector(el, rule) { | 203 | function getSelector(el, rule) { |
202 | |||
203 | return this._getMostSpecificSelectorForElement(el, rule[this.CONST.SPECIFICITY_KEY]).selector; | 204 | return this._getMostSpecificSelectorForElement(el, rule[this.CONST.SPECIFICITY_KEY]).selector; |
204 | } | 205 | } |
205 | 206 | ||
206 | var selectorToOverride = getSelector.bind(this)(element, ruleToOverride), | 207 | var selectorToOverride = getSelector.bind(this)(element, ruleToOverride), |
207 | tokens = selectorToOverride.split(/\s/), | 208 | overrideData, rule; |
208 | newClass = this.generateClassName(element.nodeName), | 209 | |
209 | lastToken, pseudoSplit, base, pseudo, newToken, newSelector, rule; | 210 | ///// Get the overriding selector and className |
211 | overrideData = this.createOverrideSelector(selectorToOverride, element.nodeName); | ||
212 | |||
213 | ///// Create new rule with selector and insert it after the rule we're overriding | ||
214 | rule = this.addRule(overrideData.selector + ' { }', this.getRuleIndex(ruleToOverride)+1); | ||
215 | |||
216 | return { | ||
217 | className : overrideData.className, | ||
218 | rule : rule | ||
219 | }; | ||
220 | |||
221 | } | ||
222 | }, | ||
223 | |||
224 | createOverrideSelector : { | ||
225 | value: function(selectorToOverride, classPrefix, className) { | ||
226 | var tokens = selectorToOverride.split(/\s/), | ||
227 | newClass = className || this.generateClassName(classPrefix, true), | ||
228 | lastToken, pseudoSplit, base, pseudo, newToken, newSelector; | ||
210 | 229 | ||
211 | ///// Creating an overriding selector by replacing the last | 230 | ///// Creating an overriding selector by replacing the last |
212 | ///// class, attribute or type selector in passed-in rule's selector | 231 | ///// class, attribute or type selector in passed-in rule's selector |
213 | 232 | ||
214 | ///// Grab the last token | 233 | ///// Grab the last token |
215 | lastToken = tokens[tokens.length-1]; | 234 | lastToken = tokens[tokens.length-1]; |
216 | pseudoSplit = lastToken.split(':'); | 235 | pseudoSplit = lastToken.split(':'); |
217 | ///// The last token can have pseudo class. Let's preserve it | 236 | ///// The last token can have pseudo class. Let's preserve it |
218 | base = pseudoSplit[0]; | 237 | base = pseudoSplit[0]; |
219 | pseudo = (pseudoSplit[1]) ? ':'+pseudoSplit[1] : ''; | 238 | pseudo = (pseudoSplit[1]) ? ':'+pseudoSplit[1] : ''; |
220 | 239 | ||
221 | ///// Now, all we want to do is replace the last token with a | 240 | ///// Now, all we want to do is replace the last token with a |
222 | ///// generated class name, except if the last token is an ID selector, | 241 | ///// generated class name, except if the last token is an ID selector, |
223 | ///// in which case we append the generated class name to the ID selector | 242 | ///// in which case we append the generated class name to the ID selector |
@@ -231,18 +250,15 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
231 | ///// Append the generated class | 250 | ///// Append the generated class |
232 | newToken += '.' + newClass + pseudo; | 251 | newToken += '.' + newClass + pseudo; |
233 | } | 252 | } |
234 | 253 | ||
235 | ///// Now we can build the new selector by replacing the last token | 254 | ///// Now we can build the new selector by replacing the last token |
236 | tokens[tokens.length-1] = newToken; | 255 | tokens[tokens.length-1] = newToken; |
237 | newSelector = tokens.join(' '); | 256 | newSelector = tokens.join(' '); |
238 | 257 | ||
239 | rule = this.addRule(newSelector + ' { }', this.getRuleIndex(ruleToOverride)+1); | ||
240 | |||
241 | return { | 258 | return { |
242 | className : newClass, | 259 | className : newClass, |
243 | rule : rule | 260 | selector : newSelector |
244 | }; | 261 | }; |
245 | |||
246 | } | 262 | } |
247 | }, | 263 | }, |
248 | 264 | ||
@@ -269,6 +285,8 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
269 | sheet.deleteRule(index); | 285 | sheet.deleteRule(index); |
270 | } | 286 | } |
271 | 287 | ||
288 | this.styleSheetModified(sheet); | ||
289 | |||
272 | return index; | 290 | return index; |
273 | } | 291 | } |
274 | }, | 292 | }, |
@@ -370,7 +388,7 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
370 | ///// from which an overriding rule can be created. | 388 | ///// from which an overriding rule can be created. |
371 | 389 | ||
372 | getDominantRuleForGroup : { | 390 | getDominantRuleForGroup : { |
373 | value : function(elements, property) { | 391 | value : function(elements, property, forceOverride) { |
374 | var selectorsToOverride = [], | 392 | var selectorsToOverride = [], |
375 | commonRules, dominantRules, useImportant; | 393 | commonRules, dominantRules, useImportant; |
376 | 394 | ||
@@ -517,6 +535,9 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
517 | value : function(rule, selector) { | 535 | value : function(rule, selector) { |
518 | rule.selectorText = selector; | 536 | rule.selectorText = selector; |
519 | rule[this.CONST.SPECIFICITY_KEY] = this.getSpecificity(selector); | 537 | rule[this.CONST.SPECIFICITY_KEY] = this.getSpecificity(selector); |
538 | |||
539 | this.styleSheetModified(rule.parentStyleSheet); | ||
540 | |||
520 | return rule; | 541 | return rule; |
521 | } | 542 | } |
522 | }, | 543 | }, |
@@ -639,7 +660,7 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
639 | }, | 660 | }, |
640 | 661 | ||
641 | ///// Get Most Specific Selector For Element | 662 | ///// Get Most Specific Selector For Element |
642 | ///// Given a selector+specificty array, find the most specific | 663 | ///// Given a selector+specificity array, find the most specific |
643 | ///// selector for the passed-in element | 664 | ///// selector for the passed-in element |
644 | 665 | ||
645 | _getMostSpecificSelectorForElement : { | 666 | _getMostSpecificSelectorForElement : { |
@@ -721,7 +742,11 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
721 | ///// Calculate specificity | 742 | ///// Calculate specificity |
722 | ///// Returns the specificity value of passed-in selector | 743 | ///// Returns the specificity value of passed-in selector |
723 | ///// WARNING: Do not pass in grouped selectors! | 744 | ///// WARNING: Do not pass in grouped selectors! |
724 | ///// Helpful for determining precedence of style rules | 745 | ///// Helpful for determining precedence of style rules |
746 | ///// Calculation javascript code courtesy of Graham Bradley: | ||
747 | ///// http://gbradley.com/2009/10/02/css-specificity-in-javascript | ||
748 | ///// Used with author's permission | ||
749 | |||
725 | calculateSpecificity : { | 750 | calculateSpecificity : { |
726 | value : function(selector) { | 751 | value : function(selector) { |
727 | var s = selector.replace(/\([^\)]+\)/,''), | 752 | var s = selector.replace(/\([^\)]+\)/,''), |
@@ -762,6 +787,8 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
762 | ///// method to apply/test the new value | 787 | ///// method to apply/test the new value |
763 | dec.setProperty(property, value, priority); | 788 | dec.setProperty(property, value, priority); |
764 | 789 | ||
790 | this.styleSheetModified(rule.parentStyleSheet); | ||
791 | |||
765 | ///// Return browser value for value we just set | 792 | ///// Return browser value for value we just set |
766 | return dec.getPropertyValue(property); | 793 | return dec.getPropertyValue(property); |
767 | } | 794 | } |
@@ -786,14 +813,44 @@ var stylesController = exports.StylesController = Montage.create(Component, { | |||
786 | return browserValues; | 813 | return browserValues; |
787 | } | 814 | } |
788 | }, | 815 | }, |
789 | 816 | ||
817 | ///// Set Keyframe Style | ||
818 | ///// For a given CSSKeyframesRule, we may add a style to the keyframe at | ||
819 | ///// given index. | ||
820 | |||
821 | setKeyframeStyle : { | ||
822 | value : function(rule, keyframeIndex, property, value, useImportant) { | ||
823 | return this.setStyle(rule.cssRules[keyframeIndex], property, value, useImportant); | ||
824 | } | ||
825 | }, | ||
826 | |||
827 | ///// Set Keyframe Styles | ||
828 | ///// For a given CSSKeyframesRule, we may add styles to the keyframe at | ||
829 | ///// given index. | ||
830 | |||
831 | setKeyframeStyle : { | ||
832 | value : function(rule, keyframeIndex, property, value, useImportant) { | ||
833 | return this.setStyles(rule.cssRules[keyframeIndex], property, value, useImportant); | ||
834 | } | ||
835 | }, | ||
836 | |||
837 | insertKeyframe : { | ||
838 | value : function() { | ||
839 | |||
840 | } | ||
841 | }, | ||
842 | |||
843 | |||
790 | ///// Delete style | 844 | ///// Delete style |
791 | ///// Removes the property from the style declaration/rule | 845 | ///// Removes the property from the style declaration/rule |
792 | ///// Returns the rule | 846 | ///// Returns the rule |
793 | 847 | ||
794 | deleteStyle : { | 848 | deleteStyle : { |
795 | value : function(rule, property) { | 849 | value : function(rule, property) { |
850 | this.styleSheetModified(rule.parentStyleSheet); | ||
851 | |||
796 | rule.style.removeProperty(property); | 852 | rule.style.removeProperty(property); |
853 | |||
797 | return rule; | 854 | return rule; |
798 | } | 855 | } |
799 | }, |