diff options
Diffstat (limited to 'node_modules/montage/ui/template.js')
-rwxr-xr-x | node_modules/montage/ui/template.js | 792 |
1 files changed, 792 insertions, 0 deletions
diff --git a/node_modules/montage/ui/template.js b/node_modules/montage/ui/template.js new file mode 100755 index 00000000..219fbc5f --- /dev/null +++ b/node_modules/montage/ui/template.js | |||
@@ -0,0 +1,792 @@ | |||
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 | @module montage/ui/template | ||
8 | @requires montage/core | ||
9 | @requires montage/core/serializer | ||
10 | @requires montage/core/deserializer | ||
11 | @requires montage/core/logger | ||
12 | */ | ||
13 | |||
14 | exports = typeof exports !== "undefined" ? exports : {}; | ||
15 | |||
16 | var Montage = require("montage").Montage; | ||
17 | var Serializer = require("core/serializer").Serializer; | ||
18 | var Deserializer = require("core/deserializer").Deserializer; | ||
19 | var logger = require("core/logger").logger("template"); | ||
20 | var defaultEventManager = require("core/event/event-manager").defaultEventManager; | ||
21 | var defaultApplication = require("ui/application").application; | ||
22 | |||
23 | /** | ||
24 | @class module:montage/ui/template.Template | ||
25 | @extends module:montage/core/core.Montage | ||
26 | */ | ||
27 | var Template = exports.Template = Montage.create(Montage, /** @lends module:montage/ui/template.Template# */ { | ||
28 | |||
29 | /** | ||
30 | The value of the type assigned to a Montage script block. | ||
31 | @type {string} | ||
32 | @private | ||
33 | */ | ||
34 | _OLD_SCRIPT_TYPE: {value: "text/m-objects"}, | ||
35 | _SCRIPT_TYPE: {value: "text/montage-serialization"}, | ||
36 | |||
37 | /** | ||
38 | @private | ||
39 | */ | ||
40 | _document: {value: null}, | ||
41 | /** | ||
42 | @private | ||
43 | */ | ||
44 | _externalObjects: {value: null}, | ||
45 | _ownerSerialization: {value: null}, | ||
46 | _rootUrl: {value: null}, | ||
47 | /** | ||
48 | @private | ||
49 | */ | ||
50 | _isLoaded: {value: false}, | ||
51 | |||
52 | /** | ||
53 | Creates a new Template instance from an HTML document element. | ||
54 | @function | ||
55 | @return {module:montage/template.Template} | ||
56 | */ | ||
57 | initWithDocument: {value: function(doc) { | ||
58 | this._document = doc; | ||
59 | |||
60 | return this; | ||
61 | }}, | ||
62 | |||
63 | __templatesById: {value: {}}, | ||
64 | __templateCallbacksByModuleId: {value: {}}, | ||
65 | |||
66 | /** | ||
67 | Finds (or creates) the apropriate Template object to be used on a specific module id that represents an HTML page. | ||
68 | Any Template object can be used but this function guarantees that only one template object is used per module id reducing the number of objects needed. | ||
69 | @function | ||
70 | @param {Function} requireFunction The require function to load the template file. | ||
71 | @param {String} moduleId The module id. | ||
72 | @param {Function} callback The function to call when the template is ready, receives a Template object as a parameter. | ||
73 | */ | ||
74 | templateWithModuleId: {value: function(requireFunction, moduleId, callback) { | ||
75 | var template = this.__templatesById[moduleId]; | ||
76 | var templateCallback = function(template) { | ||
77 | template.__templateCallbacksByModuleId[moduleId].forEach(function(value) { | ||
78 | value.call(this,template); | ||
79 | }); | ||
80 | delete template.__templateCallbacksByModuleId[moduleId]; | ||
81 | }; | ||
82 | |||
83 | if(!template) { | ||
84 | this.__templateCallbacksByModuleId[moduleId] = [callback]; | ||
85 | this.__templatesById[moduleId] = (template = this.create().initWithModuleId(requireFunction, moduleId, templateCallback)); | ||
86 | } else if(!template._isLoaded) { | ||
87 | this.__templateCallbacksByModuleId[moduleId].push(callback); | ||
88 | } | ||
89 | else { | ||
90 | callback(template); | ||
91 | } | ||
92 | return template; | ||
93 | }}, | ||
94 | |||
95 | /** | ||
96 | Creates a (or uses a previously created one) Template object out of a fully instantiated component. | ||
97 | This means creating a markup from the Component object's element and a serialization with the Component object as the owner of the Template. | ||
98 | This function guarantees that only one Template object is used per type of component reducing the number of objects needed. | ||
99 | @function | ||
100 | @param {Function} requireFunction The require function to use to load the modules used in the serialization. | ||
101 | @param {String} moduleId The module id. | ||
102 | @param {Function} callback The function to call when the template is ready, receives a Template object as a parameter. | ||
103 | */ | ||
104 | templateWithComponent: {value: function(component) { | ||
105 | var componentId = component._templateId, | ||
106 | template = this.__templatesById[componentId], | ||
107 | externalObjects; | ||
108 | |||
109 | if (!template) { | ||
110 | template = this.create().initWithComponent(component); | ||
111 | externalObjects = template._externalObjects; | ||
112 | // don't store this template if it has external objects, the next component to use might have diferent objects for the same ids | ||
113 | if (!externalObjects || Object.keys(externalObjects).length === 0) { | ||
114 | this.__templatesById[componentId] = template; | ||
115 | } | ||
116 | } | ||
117 | |||
118 | return template; | ||
119 | }}, | ||
120 | |||
121 | /** | ||
122 | Private reference to template's deserializer. | ||
123 | @private | ||
124 | */ | ||
125 | _deserializer: {value:null}, | ||
126 | |||
127 | /** | ||
128 | The deserializer object used by the template. | ||
129 | @type {module:montage/core/deserializer.Deserializer} | ||
130 | */ | ||
131 | deserializer: { | ||
132 | get: function() { | ||
133 | return this._deserializer || (this._deserializer = Deserializer.create().initWithString(this._rootObjectSerialization)); | ||
134 | } | ||
135 | }, | ||
136 | |||
137 | /** | ||
138 | Initializes the Template object with a specific module id that represents an HTML page. | ||
139 | @function | ||
140 | @param {Function} requireFunction The require function to load the template file. | ||
141 | @param {String} moduleId The module id. | ||
142 | @param {Function} callback The function to call when the template is initialized, receives a Template object as a parameter. | ||
143 | @returns itself | ||
144 | */ | ||
145 | initWithModuleId: {value: function(requireFunction, moduleId, callback) { | ||
146 | var self = this; | ||
147 | |||
148 | this.createHtmlDocumentFromModuleId(requireFunction, moduleId, function(doc) { | ||
149 | if (!doc) { | ||
150 | throw "Template '" + url + "' not found."; | ||
151 | } | ||
152 | self._isLoaded = true; | ||
153 | self.initWithDocument(doc); | ||
154 | if (callback) { | ||
155 | callback(self); | ||
156 | } | ||
157 | }); | ||
158 | return this; | ||
159 | }}, | ||
160 | |||
161 | /** | ||
162 | @private | ||
163 | */ | ||
164 | _serializer: { | ||
165 | value: null | ||
166 | }, | ||
167 | |||
168 | /** | ||
169 | The serializer object used by the template. | ||
170 | @type {module:montage/core/serializer.Serializer} | ||
171 | */ | ||
172 | serializer: { | ||
173 | get: function() { | ||
174 | return this._serializer || (this._serializer = Serializer.create().initWithRequire(window.require)); | ||
175 | } | ||
176 | }, | ||
177 | |||
178 | /** | ||
179 | Initializes a Template object out of a fully instantiated component. | ||
180 | This means creating a markup from the Component object's element and a serialization with the Component object as the owner of the Template. | ||
181 | @function | ||
182 | @param {Object} component The component with which to initialize the template. | ||
183 | @returns itself | ||
184 | */ | ||
185 | initWithComponent: {value: function(component) { | ||
186 | var htmlDocument = document.implementation.createHTMLDocument(""), | ||
187 | serializer = this.serializer, | ||
188 | serialization, | ||
189 | elements, element, | ||
190 | elementsCount, e1, e2; | ||
191 | |||
192 | this._document = htmlDocument; | ||
193 | |||
194 | this._ownerSerialization = serializer.serialize({owner: component}); | ||
195 | this._externalObjects = serializer.getExternalObjects(); | ||
196 | elements = serializer.getExternalElements(); | ||
197 | |||
198 | var elementsCount = elements.length; | ||
199 | if (elementsCount > 1) { | ||
200 | // reduce elements to its top fringe O(n^2) ... could probably reduce this (in avg) by removing all children of the component's element first | ||
201 | for (var i = 0; i < elementsCount; i++) { | ||
202 | e1 = elements[i]; | ||
203 | for (var j = 0; j < elementsCount; j++) { | ||
204 | if (i !== j) { | ||
205 | var e2 = elements[j]; | ||
206 | // is e2 contained in e1? | ||
207 | while ((e2 = e2.parentNode) && e2 !== e1) { | ||
208 | }; | ||
209 | if (e2) { | ||
210 | elements.splice(j, 1); | ||
211 | elementsCount--; | ||
212 | j--; | ||
213 | if (i > j) { | ||
214 | i--; | ||
215 | } | ||
216 | } | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | } | ||
221 | |||
222 | for (var i = 0; element = elements[i]; i++) { | ||
223 | htmlDocument.body.appendChild(htmlDocument.importNode(element, true)) | ||
224 | } | ||
225 | // make sure we use the same require used to create this component to instantiate this reel | ||
226 | this._deserializer = this._createDeserializer(this._ownerSerialization); | ||
227 | |||
228 | return this; | ||
229 | }}, | ||
230 | |||
231< |