From 9d1c9d10436c0e0b38115b0025b40b1e838b1350 Mon Sep 17 00:00:00 2001
From: Eric Guzman
Date: Wed, 1 Feb 2012 16:50:59 -0800
Subject: Styles Controller - First stab at group styling
Split "createOverrideRule" into two methods --> now has createOverrideSelector. Also took first stab at creating a group style.
---
js/controllers/styles-controller.js | 102 ++++++++++++++++++++++++++++++------
1 file changed, 86 insertions(+), 16 deletions(-)
(limited to 'js/controllers')
diff --git a/js/controllers/styles-controller.js b/js/controllers/styles-controller.js
index afd298c9..8fc90e7d 100644
--- a/js/controllers/styles-controller.js
+++ b/js/controllers/styles-controller.js
@@ -171,7 +171,7 @@ var stylesController = exports.StylesController = Montage.create(Component, {
if(argType === 'string') {
ruleText += '{' + declaration + '}';
} else if(argType === 'object') {
- ruleText += '{' + nj.cssFromObject(declaration) + '}';
+ ruleText += '{' + this.cssFromObject(declaration) + '}';
}
stylesheet.insertRule(ruleText, index);
@@ -199,25 +199,42 @@ var stylesController = exports.StylesController = Montage.create(Component, {
///// Locally-scoped function to de-clutter variable declarations
function getSelector(el, rule) {
-
return this._getMostSpecificSelectorForElement(el, rule[this.CONST.SPECIFICITY_KEY]).selector;
}
var selectorToOverride = getSelector.bind(this)(element, ruleToOverride),
- tokens = selectorToOverride.split(/\s/),
- newClass = this.generateClassName(element.nodeName),
- lastToken, pseudoSplit, base, pseudo, newToken, newSelector, rule;
+ overrideData, rule;
+
+ ///// Get the overriding selector and className
+ overrideData = this.createOverrideSelector(selectorToOverride, element.nodeName);
+
+ ///// Create new rule with selector and insert it after the rule we're overriding
+ rule = this.addRule(overrideData.selector + ' { }', this.getRuleIndex(ruleToOverride)+1);
+
+ return {
+ className : overrideData.className,
+ rule : rule
+ };
+
+ }
+ },
+
+ createOverrideSelector : {
+ value: function(selectorToOverride, classPrefix, className) {
+ var tokens = selectorToOverride.split(/\s/),
+ newClass = className || this.generateClassName(classPrefix, true),
+ lastToken, pseudoSplit, base, pseudo, newToken, newSelector;
///// Creating an overriding selector by replacing the last
///// class, attribute or type selector in passed-in rule's selector
-
+
///// Grab the last token
lastToken = tokens[tokens.length-1];
pseudoSplit = lastToken.split(':');
///// The last token can have pseudo class. Let's preserve it
base = pseudoSplit[0];
pseudo = (pseudoSplit[1]) ? ':'+pseudoSplit[1] : '';
-
+
///// Now, all we want to do is replace the last token with a
///// generated class name, except if the last token is an ID selector,
///// in which case we append the generated class name to the ID selector
@@ -231,18 +248,15 @@ var stylesController = exports.StylesController = Montage.create(Component, {
///// Append the generated class
newToken += '.' + newClass + pseudo;
}
-
+
///// Now we can build the new selector by replacing the last token
tokens[tokens.length-1] = newToken;
newSelector = tokens.join(' ');
-
- rule = this.addRule(newSelector + ' { }', this.getRuleIndex(ruleToOverride)+1);
-
+
return {
className : newClass,
- rule : rule
+ selector : newSelector
};
-
}
},
@@ -370,7 +384,7 @@ var stylesController = exports.StylesController = Montage.create(Component, {
///// from which an overriding rule can be created.
getDominantRuleForGroup : {
- value : function(elements, property) {
+ value : function(elements, property, forceOverride) {
var selectorsToOverride = [],
commonRules, dominantRules, useImportant;
@@ -639,7 +653,7 @@ var stylesController = exports.StylesController = Montage.create(Component, {
},
///// Get Most Specific Selector For Element
- ///// Given a selector+specificty array, find the most specific
+ ///// Given a selector+specificity array, find the most specific
///// selector for the passed-in element
_getMostSpecificSelectorForElement : {
@@ -721,7 +735,11 @@ var stylesController = exports.StylesController = Montage.create(Component, {
///// Calculate specificity
///// Returns the specificity value of passed-in selector
///// WARNING: Do not pass in grouped selectors!
- ///// Helpful for determining precedence of style rules
+ ///// Helpful for determining precedence of style rules
+ ///// Calculation javascript code courtesy of David Owens:
+ ///// http://gbradley.com/2009/10/02/css-specificity-in-javascript
+ ///// Used with author's permission
+
calculateSpecificity : {
value : function(selector) {
var s = selector.replace(/\([^\)]+\)/,''),
@@ -922,6 +940,43 @@ var stylesController = exports.StylesController = Montage.create(Component, {
}
}
},
+
+ setGroupStyles : {
+ value : function(elements, styles) {
+ var properties = Object.keys(styles),
+ newClass = this.generateClassName(null, true),
+ selectors;
+
+ ///// TODO: move this: Locally-scoped function to de-clutter variable declarations
+ function getSelector(el, rule) {
+ return this._getMostSpecificSelectorForElement(el, rule[this.CONST.SPECIFICITY_KEY]).selector;
+ }
+
+ selectors = elements.map(function(el) {
+ ///// for each element, we want to find the most specific selector
+ var matchingRules = this.getMatchingRules(el, true);
+
+ this.addClass(el, newClass);
+
+ if(matchingRules.length === 0) {
+ return null;
+ }
+
+ var mostSpecificRule = matchingRules[0], // TODO: iterate over properties to find most specific
+ selectorToOverride = getSelector.bind(this)(el, mostSpecificRule),
+ override = this.createOverrideSelector(selectorToOverride, null, newClass);
+
+ return override.selector;
+
+ }, this);
+
+ selectors.filter(function(item) {
+ return item !== null;
+ });
+
+ this.addRule(selectors.join(', '), styles);
+ }
+ },
///// Get Element Style
///// Gets the style value that is currently applied to the element
@@ -1058,6 +1113,21 @@ var stylesController = exports.StylesController = Montage.create(Component, {
}
},
+ ///// CSS From Object
+ ///// Returns css text from object with key/value pairs
+ ///// representing css styles
+
+ cssFromObject : {
+ value : function(obj) {
+ var cssText = '';
+ ///// For each key/value pair, create css text
+ for(var prop in obj) {
+ cssText += prop + ':' + obj[prop] + ';';
+ }
+ return cssText;
+ }
+ },
+
/* ----------------- Element model (rule cache) related methods ----------------- */
///// Get Cached Rule For Property
--
cgit v1.2.3
From 9dc2f9d72364bb3a8ddaef56eaf7d5c22b134e59 Mon Sep 17 00:00:00 2001
From: Eric Guzman
Date: Mon, 6 Feb 2012 16:55:34 -0800
Subject: Styles Controller - Add code to remove cache items from history (not
just nullifying them)
---
js/controllers/styles-controller.js | 29 ++++++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)
(limited to 'js/controllers')
diff --git a/js/controllers/styles-controller.js b/js/controllers/styles-controller.js
index 8fc90e7d..6ba24aa6 100644
--- a/js/controllers/styles-controller.js
+++ b/js/controllers/styles-controller.js
@@ -736,7 +736,6 @@ var stylesController = exports.StylesController = Montage.create(Component, {
///// Returns the specificity value of passed-in selector
///// WARNING: Do not pass in grouped selectors!
///// Helpful for determining precedence of style rules
- ///// Calculation javascript code courtesy of David Owens:
///// http://gbradley.com/2009/10/02/css-specificity-in-javascript
///// Used with author's permission
@@ -1177,15 +1176,24 @@ var stylesController = exports.StylesController = Montage.create(Component, {
_clearCache: {
value: function(element) {
- var itemsToClear = this._cacheHistory;
+ var itemsToNullify = this._cacheHistory,
+ itemsToRemove = [],
+ i;
+
+ ///// If clearing the cache for an element, filter by element
+ ///// and keep track of indices to remove from cache
if(element) {
- itemsToClear = itemsToClear.filter(function(item) {
- return item.element === element;
+ itemsToNullify = itemsToNullify.filter(function(item, index) {
+ if(item.element === element) {
+ itemsToRemove.push(index);
+ return true;
+ }
+ return false;
});
}
- itemsToClear.forEach(function(item) {
+ itemsToNullify.forEach(function(item) {
//var identifier = item.element.nodeName;
//identifier += '#'+item.element.id || '.'+item.element.className;
//console.log("clearing cache for \"" + item.property +"\" and element \"" + identifier+ "");
@@ -1194,6 +1202,17 @@ var stylesController = exports.StylesController = Montage.create(Component, {
}
});
+ ///// Remove the nullified items from the cache
+ ///// Start at the end to not mess up index references
+ for(i = itemsToRemove.length-1; i >= 0; i--) {
+ this._cacheHistory.splice(itemsToRemove[i], 1);
+ }
+
+ if(!element) {
+ this._cacheHistory = null;
+ this._cacheHistory = [];
+ }
+
}
},
_removeCachedRuleForProperty : {
--
cgit v1.2.3
From bb8e0289ff170fd1a5256b99259c6ee5d3fdea17 Mon Sep 17 00:00:00 2001
From: Eric Guzman
Date: Mon, 6 Feb 2012 16:56:57 -0800
Subject: Styles Controller - Correct author attribution for specificity
calculation
---
js/controllers/styles-controller.js | 1 +
1 file changed, 1 insertion(+)
(limited to 'js/controllers')
diff --git a/js/controllers/styles-controller.js b/js/controllers/styles-controller.js
index 6ba24aa6..1dd91c8d 100644
--- a/js/controllers/styles-controller.js
+++ b/js/controllers/styles-controller.js
@@ -736,6 +736,7 @@ var stylesController = exports.StylesController = Montage.create(Component, {
///// Returns the specificity value of passed-in selector
///// WARNING: Do not pass in grouped selectors!
///// Helpful for determining precedence of style rules
+ ///// Calculation javascript code courtesy of Graham Bradley:
///// http://gbradley.com/2009/10/02/css-specificity-in-javascript
///// Used with author's permission
--
cgit v1.2.3
From b89ede5ba6e2389e623c9e15d4cb4329044eefb6 Mon Sep 17 00:00:00 2001
From: Eric Guzman
Date: Mon, 6 Feb 2012 16:57:33 -0800
Subject: Styles Controller - Add some methods for modifying css keyframe rules
---
js/controllers/styles-controller.js | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
(limited to 'js/controllers')
diff --git a/js/controllers/styles-controller.js b/js/controllers/styles-controller.js
index 1dd91c8d..21024125 100644
--- a/js/controllers/styles-controller.js
+++ b/js/controllers/styles-controller.js
@@ -804,7 +804,34 @@ var stylesController = exports.StylesController = Montage.create(Component, {
return browserValues;
}
},
-
+
+ ///// Set Keyframe Style
+ ///// For a given CSSKeyframesRule, we may add a style to the keyframe at
+ ///// given index.
+
+ setKeyframeStyle : {
+ value : function(rule, keyframeIndex, property, value, useImportant) {
+ return this.setStyle(rule.cssRules[keyframeIndex], property, value, useImportant);
+ }
+ },
+
+ ///// Set Keyframe Styles
+ ///// For a given CSSKeyframesRule, we may add styles to the keyframe at
+ ///// given index.
+
+ setKeyframeStyle : {
+ value : function(rule, keyframeIndex, property, value, useImportant) {
+ return this.setStyles(rule.cssRules[keyframeIndex], property, value, useImportant);
+ }
+ },
+
+ insertKeyframe : {
+ value : function() {
+
+ }
+ },
+
+
///// Delete style
///// Removes the property from the style declaration/rule
///// Returns the rule
--
cgit v1.2.3
From 0df27aef631bd797b14c84b04c6f20b15966eabb Mon Sep 17 00:00:00 2001
From: Eric Guzman
Date: Thu, 2 Feb 2012 10:36:05 -0800
Subject: Tree Controller - Initial add
---
js/controllers/tree-controller.js | 219 ++++++++++++++++++++++++++++++++++++++
1 file changed, 219 insertions(+)
create mode 100644 js/controllers/tree-controller.js
(limited to 'js/controllers')
diff --git a/js/controllers/tree-controller.js b/js/controllers/tree-controller.js
new file mode 100644
index 00000000..45e4c4ba
--- /dev/null
+++ b/js/controllers/tree-controller.js
@@ -0,0 +1,219 @@
+/*
+ This file contains proprietary software owned by Motorola Mobility, Inc.
+ No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
+ (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved.
+ */
+/**
+ @module montage/ui/controller/tree-controller
+ @requires montage/core/core
+ @requires montage/ui/controller/object-controller
+ @requires montage/core/event/mutable-event
+ */
+var Montage = require("montage").Montage,
+ ObjectController = require("montage/ui/controller/object-controller").ObjectController,
+ ArrayController = require("montage/ui/controller/array-controller").ArrayController,
+ MutableEvent = require("montage/core/event/mutable-event").MutableEvent;
+/**
+ TODO: Write description like the array controllers: The ArrayController helps with organizing a hierarchical
+ collection of objects, and managing user selection within that collection.
+ You can assign a TreeController instance as the contentProvider
property for a TreeView object.
+ @class module:montage/ui/controller/tree-controller.TreeController
+ @classdesc
+ @extends module:montage/ui/controller/object-controller.ObjectController
+*/
+var TreeController = exports.TreeController = Montage.create(ObjectController, /** @lends module:montage/ui/controller/tree-controller.TreeController# */ {
+
+ rootKey : {
+ value: null
+ },
+
+ branchKey : {
+ value: 'children'
+ },
+
+ _root : {
+ value : null
+ },
+ root : {
+ get: function() {
+ return this._root;
+ },
+ set: function(value) {
+ this._root = value;
+
+ this.initArrayControllers();
+ }
+ },
+
+ rootController: {
+ value: null
+ },
+
+ initArrayControllers : {
+ value: function() {
+ var self = this;
+
+ ///// Declare function to initialize controller for each node
+ ///// that is a branch
+
+ function initController(array, depth) {
+ var controller = Montage.create(ArrayController, {
+ content : { value: array },
+ delegate : { value: self },
+ isSelectionEnabled : { value: true }});
+
+ if(depth === 0) {
+ self.rootController = controller;
+ }
+
+ self.branchControllers.push({
+ depth : depth,
+ controller : controller
+
+ });
+ }
+
+ ///// Recursive function that finds all branch nodes and initializes
+ ///// an array controller
+
+ function walk(node, init, depth) {
+ var children = node[self.branchKey];
+
+ if(children) {
+ //init(children, depth);
+
+ children.forEach(function(child) {
+ walk(child, init, ++depth);
+ });
+
+ node['treeNodeType'] = 'branch';
+ } else {
+ node['treeNodeType'] = 'leaf';
+ }
+ }
+
+ walk(this._root, initController, 0);
+
+ }
+ },
+
+ /**
+ @private
+ */
+ _selectedIndexes: {
+ value: null,
+ enumerable: false
+ },
+
+ /**
+ Description TODO
+ @type {Function}
+ @default null
+ */
+ selectedIndexes: {
+ get: function() {
+
+ },
+ set: function(value) {
+
+ }
+ },
+
+ lazyLoad : {
+ value: false
+ },
+
+ branchControllers: {
+ value: []
+ },
+
+ addBranchController : {
+ value: function(controller) {
+ if(this.delegate) {
+ controller.delegate = this.delegate;
+ }
+
+ this.branchControllers.push(controller);
+ }
+ },
+
+ /**
+ @private
+ */
+ _content: {
+ enumerable: false,
+ value: null
+ },
+ /**
+ The content managed by the TreeController.
+ @type {Function}
+ @default {String} null
+ */
+ content: {
+ get: function() {
+ return this._content;
+ },
+ set: function(value) {
+ if (this._content === value) {
+ return;
+ }
+
+ this._content = value;
+
+ //TODO for right now assume that any content change invalidates the selection completely; we'll need to address this of course
+ this.selectedObjects = null;
+
+ if (this.rootKey) {
+ if (value[this.rootKey]) {
+ this.root = value[this.rootKey];
+ } else {
+ console.log('No root key found in content data');
+ }
+ } else {
+ this.root = value;
+ }
+
+
+ }
+ },
+
+ addObjects : {
+ value: function() {
+
+ var objects = Array.prototype.slice.call(arguments),
+ i,
+ objectCount = objects.length,
+ selectedContentIndexes, firstIndex;
+
+ for (i = 0; i < objectCount; i++) {
+ this.content.push(objects[i]);
+ }
+
+ if (this.selectObjectsOnAddition) {
+ selectedContentIndexes = [];
+ firstIndex = this.content.length-objectCount;
+ for (i = 0; i < objectCount; i++) {
+ selectedContentIndexes[i] = firstIndex++;
+ }
+ this.selectedContentIndexes = selectedContentIndexes;
+ this.selectedObjects = objects;
+ }
+
+ if (this.clearFilterFunctionOnAddition) {
+ this.filterFunction = null;
+ }
+
+ if (this.automaticallyOrganizeObjects) {
+ this.organizeObjects();
+ }
+
+ }
+ },
+
+ insertChildBefore : { value : function() {} },
+
+ insertChildAfter : { value : function() {} }
+
+
+
+});
--
cgit v1.2.3
From 57562aace901f12215895133dc1e7a6fd4daf2a2 Mon Sep 17 00:00:00 2001
From: Eric Guzman
Date: Thu, 2 Feb 2012 14:58:21 -0800
Subject: Tree Controller - Clean out unused code
---
js/controllers/tree-controller.js | 48 ++++++---------------------------------
1 file changed, 7 insertions(+), 41 deletions(-)
(limited to 'js/controllers')
diff --git a/js/controllers/tree-controller.js b/js/controllers/tree-controller.js
index 45e4c4ba..2b2e910c 100644
--- a/js/controllers/tree-controller.js
+++ b/js/controllers/tree-controller.js
@@ -53,37 +53,15 @@ var TreeController = exports.TreeController = Montage.create(ObjectController, /
value: function() {
var self = this;
- ///// Declare function to initialize controller for each node
- ///// that is a branch
-
- function initController(array, depth) {
- var controller = Montage.create(ArrayController, {
- content : { value: array },
- delegate : { value: self },
- isSelectionEnabled : { value: true }});
-
- if(depth === 0) {
- self.rootController = controller;
- }
-
- self.branchControllers.push({
- depth : depth,
- controller : controller
-
- });
- }
-
///// Recursive function that finds all branch nodes and initializes
- ///// an array controller
+ ///// sets the tree node type to "branch" or "leaf"
function walk(node, init, depth) {
- var children = node[self.branchKey];
-
- if(children) {
- //init(children, depth);
+ var branch = node[self.branchKey];
- children.forEach(function(child) {
- walk(child, init, ++depth);
+ if(branch) {
+ branch.forEach(function(node) {
+ walk(node, init, ++depth);
});
node['treeNodeType'] = 'branch';
@@ -92,7 +70,7 @@ var TreeController = exports.TreeController = Montage.create(ObjectController, /
}
}
- walk(this._root, initController, 0);
+ walk(this._root, 0);
}
},
@@ -119,10 +97,6 @@ var TreeController = exports.TreeController = Montage.create(ObjectController, /
}
},
- lazyLoad : {
- value: false
- },
-
branchControllers: {
value: []
},
@@ -160,7 +134,6 @@ var TreeController = exports.TreeController = Montage.create(ObjectController, /
this._content = value;
- //TODO for right now assume that any content change invalidates the selection completely; we'll need to address this of course
this.selectedObjects = null;
if (this.rootKey) {
@@ -173,7 +146,6 @@ var TreeController = exports.TreeController = Montage.create(ObjectController, /
this.root = value;
}
-
}
},
@@ -208,12 +180,6 @@ var TreeController = exports.TreeController = Montage.create(ObjectController, /
}
}
- },
-
- insertChildBefore : { value : function() {} },
-
- insertChildAfter : { value : function() {} }
-
-
+ }
});
--
cgit v1.2.3