diff options
Diffstat (limited to 'js/controllers')
-rw-r--r-- | js/controllers/objects-controller.js | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/js/controllers/objects-controller.js b/js/controllers/objects-controller.js new file mode 100644 index 00000000..6557c14e --- /dev/null +++ b/js/controllers/objects-controller.js | |||
@@ -0,0 +1,246 @@ | |||
1 | /* <copyright> | ||
2 | This file contains proprietary software owned by Motorola Mobility, Inc.<br/> | ||
3 | No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/> | ||
4 | (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. | ||
5 | </copyright> */ | ||
6 | |||
7 | var Montage = require("montage/core/core").Montage; | ||
8 | |||
9 | var CATEGORIES = { | ||
10 | |||
11 | }; | ||
12 | |||
13 | var objectsController = exports.ObjectsController = Montage.create(Montage, { | ||
14 | |||
15 | _currentDocument : { | ||
16 | value : null, | ||
17 | enumerable : false | ||
18 | }, | ||
19 | currentDocument : { | ||
20 | get : function() { | ||
21 | return this._currentDocument; | ||
22 | }, | ||
23 | set : function(doc) { | ||
24 | if(!doc) { return false; } | ||
25 | |||
26 | // TODO: remove setTimeout when timing of montage initialization is done | ||
27 | setTimeout(function() { | ||
28 | this.bindToModelObjects(); | ||
29 | }.bind(this), 1000); | ||
30 | |||
31 | this._currentDocument = doc; | ||
32 | }, | ||
33 | enumerable : false | ||
34 | }, | ||
35 | |||
36 | objects : { | ||
37 | value: [] | ||
38 | }, | ||
39 | |||
40 | _isBoundToModelObjects : { | ||
41 | value: null | ||
42 | }, | ||
43 | bindToModelObjects : { | ||
44 | value: function() { | ||
45 | //// Remove any previous bindings if previously bound | ||
46 | if(!this._isBoundToModelObjects) { | ||
47 | Object.deleteBinding(this, 'objects'); | ||
48 | this._isBoundToModelObjects = true; | ||
49 | } | ||
50 | } | ||
51 | }, | ||
52 | |||
53 | /* -------------------------- | ||
54 | Binding Methods | ||
55 | ----------------------------- */ | ||
56 | |||
57 | addBinding : { | ||
58 | value: function(bindingArgs) { | ||
59 | if(!bindingArgs.sourceObject || !bindingArgs.sourceObjectPropertyPath || !bindingArgs) { return; } | ||
60 | |||
61 | var sourceObject = bindingArgs.sourceObject, | ||
62 | sourcePath = bindingArgs.sourceObjectPropertyPath, | ||
63 | sourceDescriptor = sourceObject._bindingDescriptors; | ||
64 | |||
65 | if(sourceDescriptor && sourceDescriptor[sourcePath]) { | ||
66 | this.removeBinding(bindingArgs); | ||
67 | } | ||
68 | |||
69 | Object.defineBinding(sourceObject, sourcePath, bindingArgs); | ||
70 | this.currentObjectBindings = this.getObjectBindings(bindingArgs.sourceObject); | ||
71 | } | ||
72 | }, | ||
73 | |||
74 | removeBinding : { | ||
75 | value: function(bindingArgs) { | ||
76 | if(!bindingArgs) { return; } | ||
77 | |||
78 | |||
79 | |||
80 | Object.deleteBinding(bindingArgs.sourceObject, bindingArgs.sourceObjectPropertyPath); | ||
81 | this.currentObjectBindings = this.getObjectBindings(bindingArgs.sourceObject); | ||
82 | } | ||
83 | }, | ||
84 | |||
85 | editBinding : { | ||
86 | value: function(bindingArgs, newProperties) { | ||
87 | var property; | ||
88 | |||
89 | this.removeBinding(bindingArgs); | ||
90 | |||
91 | if(newProperties) { | ||
92 | for(property in newProperties) { | ||
93 | bindingArgs[property] = newProperties[property]; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | this.addBinding(bindingArgs); | ||
98 | |||
99 | } | ||
100 | }, | ||
101 | |||
102 | getObjectBindings : { | ||
103 | value: function(object) { | ||
104 | var descriptors = object._bindingDescriptors, | ||
105 | bindingsArray = [], | ||
106 | property, descriptor, bindingArgsObject; | ||
107 | |||
108 | if(descriptors) { | ||
109 | for(property in descriptors) { | ||
110 | if(descriptors.hasOwnProperty(property)) { | ||
111 | descriptor = descriptors[property]; | ||
112 | |||
113 | bindingArgsObject = { | ||
114 | sourceObject : object, | ||
115 | sourceObjectPropertyPath : property, | ||
116 | boundObject : descriptor.boundObject, | ||
117 | boundObjectPropertyPath : descriptor.boundObjectPropertyPath, | ||
118 | oneway : descriptor.oneway | ||
119 | }; | ||
120 | |||
121 | bindingsArray.push(bindingArgsObject); | ||
122 | } | ||
123 | } | ||
124 | } | ||
125 | |||
126 | return bindingsArray; | ||
127 | } | ||
128 | }, | ||
129 | |||
130 | /* ---- Get Bindable Properties ---- */ | ||
131 | |||
132 | getPropertyList : { | ||
133 | value: function(object, excludeUnderscoreProperties) { | ||
134 | return this.getPrototypes(object).map(function(proto) { | ||
135 | |||
136 | var metadata = proto._montage_metadata, | ||
137 | objectName = (metadata) ? metadata.objectName : "Object"; | ||
138 | |||
139 | return { | ||
140 | category : objectName, | ||
141 | properties : this.getPropertiesFromObject(proto) | ||
142 | }; | ||
143 | }, this); | ||
144 | |||
145 | } | ||
146 | }, | ||
147 | |||
148 | getPropertiesFromObject : { | ||
149 | value: function (object, excludeUnderscoreProperties) { | ||
150 | var properties = []; | ||
151 | |||
152 | for(var key in object) { | ||
153 | if(object.hasOwnProperty(key)) { | ||
154 | properties.push(key); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | if(excludeUnderscoreProperties) { | ||
159 | properties = properties.filter(function(property) { | ||
160 | return property[0] !== '_'; | ||
161 | }, this); | ||
162 | } | ||
163 | |||
164 | return properties.sort(); | ||
165 | } | ||
166 | }, | ||
167 | |||
168 | getPrototypes : { | ||
169 | value: function(object) { | ||
170 | var object_i = object, | ||
171 | prototypes = [object_i]; | ||
172 | |||
173 | ///// Collect prototypes | ||
174 | while(Object.getPrototypeOf(object_i)) { | ||
175 | object_i = Object.getPrototypeOf(object_i); | ||
176 | prototypes.push(object_i); | ||
177 | } | ||
178 | |||
179 | return prototypes; | ||
180 | } | ||
181 | }, | ||
182 | |||
183 | /* ----- Category properties ----- */ | ||
184 | |||
185 | getObjectCategory : { | ||
186 | value: function(object) { | ||
187 | if(this._hasPrototype(object, 'Component')) { | ||
188 | return 'Component'; | ||
189 | } | ||
190 | |||
191 | return null; | ||
192 | } | ||
193 | }, | ||
194 | |||
195 | /* ----- Utils ----- */ | ||
196 | |||
197 | _hasPrototype : { | ||
198 | value: function(object, prototypeName) { | ||
199 | var prototypes = this.getPrototypes(object).map(function(proto) { | ||
200 | var metadata = proto._montage_metadata; | ||
201 | return (metadata) ? metadata.objectName : "Object"; | ||
202 | }); | ||
203 | |||
204 | return prototypes.indexOf(prototypeName) !== -1; | ||
205 | } | ||
206 | }, | ||
207 | |||
208 | ///// Returns true if the element is "non-visual", i.e. is not a component, | ||
209 | ///// and has not element property | ||
210 | |||
211 | isOffStageObject : { | ||
212 | value: function(object) { | ||
213 | var isComponent = this._hasPrototype(object, "Component"), | ||
214 | hasValidElement = object.element && object.element.parentNode; | ||
215 | |||
216 | return !isComponent || !hasValidElement; | ||
217 | } | ||
218 | }, | ||
219 | |||
220 | /* ---- Bindable controller properties ---- */ | ||
221 | |||
222 | currentObjectBindings : { | ||
223 | value: null | ||
224 | }, | ||
225 | _currentObject : { | ||
226 | value: null | ||
227 | }, | ||
228 | currentObject : { | ||
229 | get: function() { | ||
230 | return this._currentObject; | ||
231 | }, | ||
232 | set: function(value) { | ||
233 | //if(value === this._currentObject) { return; } | ||
234 | |||
235 | if(value) { | ||
236 | this.currentObjectBindings = this.getObjectBindings(value); | ||
237 | //console.log("Property list", this.getPropertyList(value, true)); | ||
238 | } else { | ||
239 | this.currentObjectBindings = []; | ||