diff options
Diffstat (limited to 'js/controllers/objects-controller.js')
-rw-r--r-- | js/controllers/objects-controller.js | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/js/controllers/objects-controller.js b/js/controllers/objects-controller.js new file mode 100644 index 00000000..54ff14ba --- /dev/null +++ b/js/controllers/objects-controller.js | |||
@@ -0,0 +1,244 @@ | |||
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 | // Object.defineBinding(this, 'objects', { | ||
52 | // boundObject: this.currentDocument.model, | ||
53 | // boundObjectPropertyPath: 'mObjects', | ||
54 | // oneway: false | ||
55 | // }); | ||
56 | } | ||
57 | }, | ||
58 | |||
59 | /* -------------------------- | ||
60 | Binding Methods | ||
61 | ----------------------------- */ | ||
62 | |||
63 | addBinding : { | ||
64 | value: function(bindingArgs) { | ||
65 | if(!bindingArgs.sourceObject || !bindingArgs.sourceObjectPropertyPath || !bindingArgs) { return; } | ||
66 | |||
67 | Object.defineBinding(bindingArgs.sourceObject, bindingArgs.sourceObjectPropertyPath, bindingArgs); | ||
68 | this.currentObjectBindings = this.getObjectBindings(bindingArgs.sourceObject); | ||
69 | } | ||
70 | }, | ||
71 | |||
72 | removeBinding : { | ||
73 | value: function(bindingArgs) { | ||
74 | if(!bindingArgs) { return; } | ||
75 | |||
76 | |||
77 | |||
78 | Object.deleteBinding(bindingArgs.sourceObject, bindingArgs.sourceObjectPropertyPath); | ||
79 | this.currentObjectBindings = this.getObjectBindings(bindingArgs.sourceObject); | ||
80 | } | ||
81 | }, | ||
82 | |||
83 | editBinding : { | ||
84 | value: function(bindingArgs, newProperties) { | ||
85 | var property; | ||
86 | |||
87 | this.removeBinding(bindingArgs); | ||
88 | |||
89 | if(newProperties) { | ||
90 | for(property in newProperties) { | ||
91 | bindingArgs[property] = newProperties[property]; | ||
92 | } | ||
93 | } | ||
94 | |||
95 | this.addBinding(bindingArgs); | ||
96 | |||
97 | } | ||
98 | }, | ||
99 | |||
100 | getObjectBindings : { | ||
101 | value: function(object) { | ||
102 | var descriptors = object._bindingDescriptors, | ||
103 | bindingsArray = [], | ||
104 | property, descriptor, bindingArgsObject; | ||
105 | |||
106 | if(descriptors) { | ||
107 | for(property in descriptors) { | ||
108 | if(descriptors.hasOwnProperty(property)) { | ||
109 | descriptor = descriptors[property]; | ||
110 | |||
111 | bindingArgsObject = { | ||
112 | sourceObject : object, | ||
113 | sourceObjectPropertyPath : property, | ||
114 | boundObject : descriptor.boundObject, | ||
115 | boundObjectPropertyPath : descriptor.boundObjectPropertyPath, | ||
116 | oneway : descriptor.oneway | ||
117 | }; | ||
118 | |||
119 | bindingsArray.push(bindingArgsObject); | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | |||
124 | return bindingsArray; | ||
125 | } | ||
126 | }, | ||
127 | |||
128 | /* ---- Get Bindable Properties ---- */ | ||
129 | |||
130 | getPropertyList : { | ||
131 | value: function(object, excludeUnderscoreProperties) { | ||
132 | return this.getPrototypes(object).map(function(proto) { | ||
133 | |||
134 | var metadata = proto._montage_metadata, | ||
135 | objectName = (metadata) ? metadata.objectName : "Object"; | ||
136 | |||
137 | return { | ||
138 | category : objectName, | ||
139 | properties : this.getPropertiesFromObject(proto) | ||
140 | }; | ||
141 | }, this); | ||
142 | |||
143 | } | ||
144 | }, | ||
145 | |||
146 | getPropertiesFromObject : { | ||
147 | value: function (object, excludeUnderscoreProperties) { | ||
148 | var properties = []; | ||
149 | |||
150 | for(var key in object) { | ||
151 | if(object.hasOwnProperty(key)) { | ||
152 | properties.push(key); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | if(excludeUnderscoreProperties) { | ||
157 | properties = properties.filter(function(property) { | ||
158 | return property[0] !== '_'; | ||
159 | }, this); | ||
160 | } | ||
161 | |||
162 | return properties.sort(); | ||
163 | } | ||
164 | }, | ||
165 | |||
166 | getPrototypes : { | ||
167 | value: function(object) { | ||
168 | var object_i = object, | ||
169 | prototypes = [object_i]; | ||
170 | |||
171 | ///// Collect prototypes | ||
172 | while(Object.getPrototypeOf(object_i)) { | ||
173 | object_i = Object.getPrototypeOf(object_i); | ||
174 | prototypes.push(object_i); | ||
175 | } | ||
176 | |||
177 | return prototypes; | ||
178 | } | ||
179 | }, | ||
180 | |||
181 | /* ----- Category properties ----- */ | ||
182 | |||
183 | getObjectCategory : { | ||
184 | value: function(object) { | ||
185 | if(this._hasPrototype(object, 'Component')) { | ||
186 | return 'Component'; | ||
187 | } | ||
188 | |||
189 | return null; | ||
190 | } | ||
191 | }, | ||
192 | |||
193 | /* ----- Utils ----- */ | ||
194 | |||
195 | _hasPrototype : { | ||
196 | value: function(object, prototypeName) { | ||
197 | var prototypes = this.getPrototypes(object).map(function(proto) { | ||
198 | var metadata = proto._montage_metadata; | ||
199 | return (metadata) ? metadata.objectName : "Object"; | ||
200 | }); | ||
201 | |||
202 | return prototypes.indexOf(prototypeName) !== -1; | ||
203 | } | ||
204 | }, | ||
205 | |||
206 | ///// Returns true if the element is "non-visual", i.e. is not a component, | ||
207 | ///// and has not element property | ||
208 | |||
209 | isOffStageObject : { | ||
210 | value: function(object) { | ||
211 | var isComponent = this._hasPrototype(object, "Component"), | ||
212 | hasValidElement = object.element && object.element.parentNode; | ||
213 | |||
214 | return !isComponent || !hasValidElement; | ||
215 | } | ||
216 | }, | ||
217 | |||
218 | /* ---- Bindable controller properties ---- */ | ||
219 | |||
220 | currentObjectBindings : { | ||
221 | value: null | ||
222 | }, | ||
223 | _currentObject : { | ||
224 | value: null | ||
225 | }, | ||
226 | currentObject : { | ||
227 | get: function() { | ||
228 | return this._currentObject; | ||
229 | }, | ||
230 | set: function(value) { | ||
231 | //if(value === this._currentObject) { return; } | ||
232 | |||
233 | if(value) { | ||
234 | this.currentObjectBindings = this.getObjectBindings(value); | ||
235 | //console.log("Property list", this.getPropertyList(value, true)); | ||
236 | } else { | ||
237 | this.currentObjectBindings = []; | ||