aboutsummaryrefslogtreecommitdiff
path: root/js/controllers/styles-controller.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/controllers/styles-controller.js')
-rw-r--r--js/controllers/styles-controller.js232
1 files changed, 205 insertions, 27 deletions
diff --git a/js/controllers/styles-controller.js b/js/controllers/styles-controller.js
index afd298c9..011caec5 100644
--- 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 }, 856 },
@@ -922,6 +979,43 @@ var stylesController = exports.StylesController = Montage.create(Component, {