From 9e1ee9114e5364199acf1abb54798c81c14b9cbe Mon Sep 17 00:00:00 2001 From: Ananya Sen Date: Wed, 16 May 2012 11:01:20 -0700 Subject: single selection copy/paste canvas 2d shapes [rectangle and circle] Signed-off-by: Ananya Sen --- js/controllers/styles-controller.js | 70 ++++++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 16 deletions(-) (limited to 'js/controllers/styles-controller.js') diff --git a/js/controllers/styles-controller.js b/js/controllers/styles-controller.js index 647c0870..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, { // Returns null if sheet not found (as in non-ninja projects) // Setter will handle null case this.defaultStylesheet = this.getSheetFromElement(this.CONST.DEFAULT_SHEET_ID); - - //debugger; + + this.userStyleSheets = nj.toArray(document._document.styleSheets).filter(function(sheet) { + return sheet !== this._stageStylesheet; + }, this); + + NJevent('styleSheetsReady', this); }, enumerable : false }, + userStyleSheets : { + value : null + }, _stageStylesheet : { value : null }, @@ -183,6 +190,7 @@ var stylesController = exports.StylesController = Montage.create(Component, { ///// attach specificity to rule object ///// if rule is css keyframes, return rule and don't attach specificity if (rule instanceof WebKitCSSKeyframesRule) { + return rule; } rule[this.CONST.SPECIFICITY_KEY] = this.getSpecificity(rule.selectorText); @@ -209,10 +217,12 @@ var stylesController = exports.StylesController = Montage.create(Component, { } var selectorToOverride = getSelector.bind(this)(element, ruleToOverride), - overrideData, rule; + overrideData, rule, isRuleLocked; + + isRuleLocked = this.isSheetLocked(ruleToOverride.parentStyleSheet); ///// Get the overriding selector and className - overrideData = this.createOverrideSelector(selectorToOverride, element.nodeName); + overrideData = this.createOverrideSelector(selectorToOverride, element.nodeName, isRuleLocked); ///// Create new rule with selector and insert it after the rule we're overriding rule = this.addRule(overrideData.selector + ' { }', this.getRuleIndex(ruleToOverride)+1); @@ -226,7 +236,7 @@ var stylesController = exports.StylesController = Montage.create(Component, { }, createOverrideSelector : { - value: function(selectorToOverride, classPrefix, className) { + value: function(selectorToOverride, classPrefix, increaseSpecificity, className) { var tokens = selectorToOverride.split(/\s/), newClass = className || this.generateClassName(classPrefix, true), lastToken, pseudoSplit, base, pseudo, newToken, newSelector; @@ -247,10 +257,19 @@ var stylesController = exports.StylesController = Montage.create(Component, { if(base.indexOf('#') !== -1) { newToken = base + '.' + newClass + pseudo; } else { - ///// Replace last class or attribute selector - ///// Get everything right before the last class or attribute selector - ///// to support compound selector values: (i.e. .firstClass.secondClass) - newToken = base.substring(0, Math.max(base.lastIndexOf('.'), base.lastIndexOf('['))); + if(increaseSpecificity) { + ///// Increases specificity by one class selector + ///// We'll do a direct append to the base class + ///// if we want to increase the specificity + newToken = base; + } else { + ///// Maintains original specificity + ///// Replace last class or attribute selector + ///// Get everything right before the last class or attribute selector + ///// to support compound selector values: (i.e. .firstClass.secondClass) + newToken = base.substring(0, Math.max(base.lastIndexOf('.'), base.lastIndexOf('['))); + } + ///// Append the generated class newToken += '.' + newClass + pseudo; } @@ -795,7 +814,9 @@ var stylesController = exports.StylesController = Montage.create(Component, { ///// method to apply/test the new value dec.setProperty(property, value, priority); - this.styleSheetModified(rule.parentStyleSheet); + if(rule.parentStyleSheet) { + this.styleSheetModified(rule.parentStyleSheet); + } ///// Return browser value for value we just set return dec.getPropertyValue(property); @@ -969,12 +990,13 @@ var stylesController = exports.StylesController = Montage.create(Component, { var doc = element.ownerDocument, useImportant = false, cache = this._getCachedRuleForProperty(element, property), - dominantRule, override, className, browserValue; + dominantRule, override, className, browserValue, cacheMatchesMany; if(cache) { ///// We've cached the rule for this property! //console.log('Styles Controller :: setElementStyle - We found the cached rule!'); dominantRule = cache; + cacheMatchesMany = this.matchesMultipleElements(dominantRule, doc); } else { ///// Use Dominant Rule logic to find the right place to add the style ///// Pass "true" to method to return an override object, which @@ -982,7 +1004,7 @@ var stylesController = exports.StylesController = Montage.create(Component, { dominantRule = this.getDominantRuleForElement(element, property, true, isStageElement); } - + ///// Did we find a dominant rule? if(!dominantRule) { ///// No. This means there was no rule with this property, and no @@ -1000,6 +1022,13 @@ var stylesController = exports.StylesController = Montage.create(Component, { useImportant = dominantRule.useImportant; dominantRule = override.rule; this.addClass(element, override.className); + } else if(cacheMatchesMany) { + ///// Only happens when the cached rule applies to multiple + ///// elements - we must create override + override = this.createOverrideRule(dominantRule, element); + useImportant = !!dominantRule.style.getPropertyPriority(property); + dominantRule = override.rule; + this.addClass(element, override.className); } @@ -1007,7 +1036,7 @@ var stylesController = exports.StylesController = Montage.create(Component, { browserValue = this.setStyle(dominantRule, property, value, useImportant); ///// Only cache the dominant rule if the style value was valid, and not already cached - if(browserValue && !cache) { + if(browserValue && (!cache || cacheMatchesMany)) { this._setCachedRuleForProperty(element, property, dominantRule); } @@ -1242,8 +1271,12 @@ var stylesController = exports.StylesController = Montage.create(Component, { doc.head.appendChild(sheetElement); sheet = this.getSheetFromElement(sheetElement, doc); + this.userStyleSheets.push(sheet); + this.styleSheetModified(sheet); + NJevent('newStyleSheet', sheet); + return sheet; } }, @@ -1266,6 +1299,12 @@ var stylesController = exports.StylesController = Montage.create(Component, { } }, + isSheetLocked : { + value: function(sheet) { + return !!sheet.ownerNode.dataset['ninjaFileReadOnly']; + } + }, + ///// Style Sheet Modified ///// Method to call whenever a stylesheet change is made ///// Dispatches an event, and keeps list of dirty style sheets @@ -1306,11 +1345,10 @@ var stylesController = exports.StylesController = Montage.create(Component, { this.dirtyStyleSheets.length = 0; if(doc) { - var stillDirty = this.dirtyStyleSheets.filter(function(sheet) { + this.dirtyStyleSheets = null; + this.dirtyStyleSheets = this.dirtyStyleSheets.filter(function(sheet) { return sheet.document !== doc; }); - this.dirtyStyleSheets = null; - this.dirtyStyleSheets = stillDirty; } -- cgit v1.2.3 From 41cd3496b403962179c2f497199b5ffa97061c80 Mon Sep 17 00:00:00 2001 From: Ananya Sen Date: Wed, 13 Jun 2012 12:25:40 -0700 Subject: - eric gunman's fix for styles-controller - select the appropriate override rule to apply the override style Signed-off-by: Ananya Sen --- js/controllers/styles-controller.js | 68 +++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 14 deletions(-) (limited to 'js/controllers/styles-controller.js') diff --git a/js/controllers/styles-controller.js b/js/controllers/styles-controller.js index a25a05df..8ab07b20 100755 --- a/js/controllers/styles-controller.js +++ b/js/controllers/styles-controller.js @@ -426,7 +426,8 @@ var stylesController = exports.StylesController = Montage.create(Component, { ///// rule to the calling method return { useImportant : useImportant, - ruleToOverride : dominantRule + ruleToOverride : dominantRule, + singleTargetBackup : this._getFirstSingleTargetRule(matchedRules.slice(1), doc) }; } @@ -674,6 +675,8 @@ var stylesController = exports.StylesController = Montage.create(Component, { if(sheetAIndex === sheetBIndex) { ruleAIndex = this.getRuleIndex(ruleA); ruleBIndex = this.getRuleIndex(ruleB); return ruleAIndex < ruleBIndex ? 1 : (ruleAIndex > ruleBIndex) ? -1 : 0; + } else { + return sheetAIndex < sheetBIndex ? 1 : (sheetAIndex > sheetBIndex) ? -1 : 0; } } @@ -737,6 +740,40 @@ var stylesController = exports.StylesController = Montage.create(Component, { console.error('StylesController::_getMostSpecificSelectorForElement - no matching selectors in specificity array.'); } }, + + + ///// Has Greater Specificity + ///// A method that returns true if the first argument has higher + ///// specificity than the second argument + ///// An element has to be supplied to determine which selector + ///// to evaluate within grouped selectors + hasGreaterSpecificity : { + value: function(rule1, rule2, element) { + var a = this._getMostSpecificSelectorForElement(element, rule1[this.CONST.SPECIFICITY_KEY]), + b = this._getMostSpecificSelectorForElement(element, rule2[this.CONST.SPECIFICITY_KEY]), + win = element.ownerDocument.defaultView, + order; + + order = this.compareSpecificity(a.specificity, b.specificity); + + if(order === 0) { + /// Tie. Sway one way or other based on stylesheet/rule order + sheetAIndex = nj.toArray(win.document.styleSheets).indexOf(rule1.parentStyleSheet); + sheetBIndex = nj.toArray(win.document.styleSheets).indexOf(rule2.parentStyleSheet); + /// If tied again (same sheet), determine which is further down in the sheet + if(sheetAIndex === sheetBIndex) { + ruleAIndex = this.getRuleIndex(rule1); ruleBIndex = this.getRuleIndex(rule2); + return ruleAIndex < ruleBIndex ? 1 : (ruleAIndex > ruleBIndex) ? -1 : 0; + } else { + return sheetAIndex < sheetBIndex ? 1 : (sheetAIndex > sheetBIndex) ? -1 : 0; + } + } + + return (order < 0); + + } + }, + ///// Get First Single Target Rule ///// Loops through the array of rules sequentially, returning the first @@ -1035,8 +1072,12 @@ var stylesController = exports.StylesController = Montage.create(Component, { } + if(cacheMatchesMany) { + dominantRule = this.getDominantRuleForElement(element, property, true, isStageElement); + } + ///// Did we find a dominant rule? - if(!dominantRule) { + else if(!dominantRule) { ///// No. This means there was no rule with this property, and no ///// single-target rule we can use to add the style to. ///// There's is no chance of colliding with another rule, so we @@ -1047,18 +1088,17 @@ var stylesController = exports.StylesController = Montage.create(Component, { } else if(dominantRule.ruleToOverride) { ///// Do we have to override a rule? - ////// Yes. The override object has the rule we need to override - override = this.createOverrideRule(dominantRule.ruleToOverride, element); - useImportant = dominantRule.useImportant; - dominantRule = override.rule; - this.addClass(element, override.className); - } else if(cacheMatchesMany) { - ///// Only happens when the cached rule applies to multiple - ///// elements - we must create override - override = this.createOverrideRule(dominantRule, element); - useImportant = !!dominantRule.style.getPropertyPriority(property); - dominantRule = override.rule; - this.addClass(element, override.className); + ///// Well, let's first see if a higher-specificity, single-target + ///// rule exists + if(dominantRule.singleTargetBackup && this.hasGreaterSpecificity(dominantRule.singleTargetBackup, dominantRule.ruleToOverride, element)) { + dominantRule = dominantRule.singleTargetBackup; + } else { + ///// No. The override object has the rule we need to override + override = this.createOverrideRule(dominantRule.ruleToOverride, element); + useImportant = dominantRule.useImportant; + dominantRule = override.rule; + this.addClass(element, override.className); + } } -- cgit v1.2.3 From 8e5cfac34edc9772ba89e0206890c23afa0a6fcc Mon Sep 17 00:00:00 2001 From: Ananya Sen Date: Wed, 13 Jun 2012 16:36:39 -0700 Subject: - Eric Guzman's styles-controller fix for relatively positioned Signed-off-by: Ananya Sen --- js/controllers/styles-controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/controllers/styles-controller.js') diff --git a/js/controllers/styles-controller.js b/js/controllers/styles-controller.js index 8ab07b20..1c1e75ed 100755 --- a/js/controllers/styles-controller.js +++ b/js/controllers/styles-controller.js @@ -1077,7 +1077,7 @@ var stylesController = exports.StylesController = Montage.create(Component, { } ///// Did we find a dominant rule? - else if(!dominantRule) { + if(!dominantRule) { ///// No. This means there was no rule with this property, and no ///// single-target rule we can use to add the style to. ///// There's is no chance of colliding with another rule, so we -- cgit v1.2.3