From 2e04af953463643791f6362bd8ef4c6ba190abfa Mon Sep 17 00:00:00 2001 From: Valerio Virgillito Date: Wed, 18 Apr 2012 13:48:51 -0700 Subject: Squashed commit of the following: commit 2054551bfb01a0f4ca2e138b9d724835462d45cd Merge: 765c2da 616a853 Author: Valerio Virgillito Date: Wed Apr 18 13:48:21 2012 -0700 Merge branch 'refs/heads/master' into integration commit 765c2da8e1aa03550caf42b2bd5f367555ad2843 Author: Valerio Virgillito Date: Tue Apr 17 15:29:41 2012 -0700 updating the picasa carousel Signed-off-by: Valerio Virgillito commit 9484f1c82b81e27edf2dc0a1bcc1fa3b12077406 Merge: d27f2df cacb4a2 Author: Valerio Virgillito Date: Tue Apr 17 15:03:50 2012 -0700 Merge branch 'refs/heads/master' into integration commit d27f2df4d846064444263d7832d213535962abe7 Author: Valerio Virgillito Date: Wed Apr 11 10:39:36 2012 -0700 integrating new picasa carousel component Signed-off-by: Valerio Virgillito commit 6f98384c9ecbc8abe55ccfe1fc25a0c7ce22c493 Author: Valerio Virgillito Date: Tue Apr 10 14:33:00 2012 -0700 fixed the text area case issue Text area was renamed from TextArea to Textarea Signed-off-by: Valerio Virgillito commit 1e83e26652266136802bc7af930379c1ecd631a6 Author: Valerio Virgillito Date: Mon Apr 9 22:10:45 2012 -0700 integrating montage v0.8 into ninja. Signed-off-by: Valerio Virgillito Signed-off-by: Valerio Virgillito --- node_modules/montage/ui/template.js | 313 +++++++++++++++++++++++++++++------- 1 file changed, 251 insertions(+), 62 deletions(-) (limited to 'node_modules/montage/ui/template.js') diff --git a/node_modules/montage/ui/template.js b/node_modules/montage/ui/template.js index 210d8cb7..ee2cc1be 100755 --- a/node_modules/montage/ui/template.js +++ b/node_modules/montage/ui/template.js @@ -37,7 +37,16 @@ var Template = exports.Template = Montage.create(Montage, /** @lends module:mont /** @private */ - _document: {value: null}, + _document: { + enumerable: false, + value: null + }, + + document: { + get: function() { + return this._document; + } + }, /** @private */ @@ -134,6 +143,17 @@ var Template = exports.Template = Montage.create(Montage, /** @lends module:mont } }, + initWithHtmlString: { + value: function(htmlString) { + var doc = this.createHtmlDocumentFromString(htmlString); + + this._isLoaded = true; + this.initWithDocument(doc); + + return this; + } + }, + /** Initializes the Template object with a specific module id that represents an HTML page. @function @@ -234,62 +254,61 @@ var Template = exports.Template = Montage.create(Montage, /** @lends module:mont } }, - /** - Instantiates the Template by specifying an object as the owner and a document where the elements referenced in the serialization should be found. - @function - @param {Object} rootObject The owner object of the template. - @param {HTMLDocument} document The HTML document to be used to find elements referenced from the serialization. - @param {Function} callback The callback function to invoke when the template is instantiated. - */ - instantiateWithOwnerAndDocument: { - value: function(owner, document, callback) { + _deserialize: { + value: function(instances, targetDocument, callback) { var self = this, defaultApplication = applicationExports.application; - this.getDeserializer(function(deserializer) { - function invokeTemplateDidLoad(objects) { - owner = objects.owner; - self._invokeTemplateDidLoadWithOwner(deserializer, owner); - self.waitForStyles(function() { - callback(owner); - }); - } - var externalObjects, - targetDocument, - instances; + this.getDeserializer(function(deserializer) { + var externalObjects; if (deserializer) { externalObjects = self._externalObjects; if (externalObjects) { - instances = Object.create(externalObjects); - instances.owner = owner; - instances.application = defaultApplication; - } else { - instances = {owner: owner, application: defaultApplication}; + for (var label in externalObjects) { + if (!(label in instances)) { + instances[label] = externalObjects[label]; + } + } } - if (owner && owner._element) { - targetDocument = owner._element.ownerDocument; - } + instances.application = defaultApplication; + instances.template = self; if (self._document === window.document) { - deserializer.deserializeWithInstancesAndDocument(instances, self._document, invokeTemplateDidLoad); + deserializer.deserializeWithInstancesAndDocument(instances, self._document, callback); } else { - self.setupDocument(window.document); - deserializer.deserializeWithInstancesAndElementForDocument(instances, self._document.body, targetDocument, invokeTemplateDidLoad); + deserializer.deserializeWithInstancesAndElementForDocument(instances, self._document.body, targetDocument, callback); } } else { - if (self._document !== window.document) { - self.setupDocument(window.document); - } - self.waitForStyles(function() { - callback(); - }); + callback(); } }); } }, + /** + Instantiates the Template by specifying an object as the owner and a document where the elements referenced in the serialization should be found. + @function + @param {Object} rootObject The owner object of the template. + @param {HTMLDocument} document The HTML document to be used to find elements referenced from the serialization. + @param {Function} callback The callback function to invoke when the template is instantiated. + */ + instantiateWithOwnerAndDocument: { + value: function(owner, targetDocument, callback) { + var self = this; + + this._partiallyInstantiateWithInstancesForDocument({owner: owner}, targetDocument, function(objects) { + if (objects) { + self._invokeTemplateDidLoad(objects); + } + self.waitForStyles(function() { + callback(objects ? objects.owner : null); + }); + }); + } + }, + /** Instantiates the Template by using a component as the owner. All elements refereced in the serialization will be found on the document the component is attached to. @@ -303,32 +322,86 @@ var Template = exports.Template = Montage.create(Montage, /** @lends module:mont this.instantiateWithOwnerAndDocument(component, document, callback); }}, + instantiateWithDocument: { + value: function(document, callback) { + return this.instantiateWithOwnerAndDocument(null, document, callback); + } + }, + + _partiallyInstantiateWithInstancesForDocument: { + value: function(instances, targetDocument, callback) { + var self = this, + owner = instances.owner; + + if (!targetDocument && owner && owner._element) { + targetDocument = owner._element.ownerDocument; + } + + function importHeaders(objects) { + if (self._document !== targetDocument) { + self.exportHeaders(targetDocument); + } + callback(objects); + } + + this._deserialize(instances, targetDocument, function(objects, element) { + if (self._extends && !self._isExpanded) { + var _extends = self._extends, + element = _extends.element, + instances = _extends.instances, + instancesMapping = _extends.instancesMapping, + elementId = _extends.elementId; + + if (!element && elementId) { + element = element.querySelector("*[data-montage-id='" + elementId + "']"); + } + + if (!instances) { + if (instancesMapping) { + instances = {}; + for (var label in instancesMapping) { + instances[label] = objects[instancesMapping[label]]; + } + instances.owner = objects.owner; + } else { + instances = {owner: objects.owner}; + } + } + self._extendsTemplateWithInstances(_extends.templateModuleId, element, instances, function(extendsObjects) { + var labels = Object.keys(extendsObjects); + + for (var i =0, label; (label = labels[i]); i++) { + objects[label] = extendsObjects[label]; + } + importHeaders(objects); + }); + } else { + importHeaders(objects); + } + }); + } + }, + /** Instantiates the Template with no elements references. @function */ - instantiate: {value: function() { - var self = this; - var deserializer = Deserializer.create(); - - function invokeTemplateDidLoad(owner) { - self._invokeTemplateDidLoadWithOwner(deserializer, owner); - callback(component); + instantiate: { + value: function(callback) { + return this.instantiateWithOwnerAndDocument(null, null, callback); } - deserializer.deserializeRootObjectWithElement(this._document, invokeTemplateDidLoad); - }}, + }, /** @private */ - _invokeTemplateDidLoadWithOwner: { - value: function(deserializer, owner) { - var objects = deserializer.getObjectsFromLastDeserialization(), - hasTemplateDidDeserializeObject = owner && typeof owner.templateDidDeserializeObject === "function", - i, - object; - - for (i = 0; (object = objects[i]); i++) { + _invokeTemplateDidLoad: { + value: function(objects) { + var owner = objects.owner, + labels = Object.keys(objects), + hasTemplateDidDeserializeObject = owner && typeof owner.templateDidDeserializeObject === "function"; + + for (var i = 0, object; (object = objects[labels[i]]); i++) { if (owner !== object) { if (typeof object._deserializedFromTemplate === "function") { object._deserializedFromTemplate(owner); @@ -353,12 +426,102 @@ var Template = exports.Template = Montage.create(Montage, /** @lends module:mont } }, + defineExtension: { + value: function(templateModuleId, elementId, instances) { + this._extends = { + templateModuleId: templateModuleId, + element: elementId, + instancesMapping: instances + } + } + }, + + _extendsTemplateWithInstances: { + value: function(templateModuleId, element, instances, callback) { + var self = this, + owner = instances.owner, + ownerTemplateElement, + ownerTemplateDocument; + + // replace destination with the nodes inside source, merge the attributes from source with attributesElement + function importNodes(source, destination, attributesElement) { + var nextSibling = destination.nextSibling, + parentNode = destination.parentNode, + nodes = source.childNodes, + attributes = source.attributes; + + parentNode.removeChild(destination); + if (nextSibling) { + for (var i = 0, l = nodes.length; i < l; i++) { + parentNode.insertBefore(nodes[0], nextSibling); + } + } else { + for (var i = 0, l = nodes.length; i < l; i++) { + parentNode.appendChild(nodes[0]); + } + } + + for (var i = 0, attribute; (attribute = attributes[i]); i++) { + var attributeName = attribute.nodeName; + if (attributeName === "id" || attributeName === "data-montage-id") { + continue; + } else { + var value = (attributesElement.getAttribute(attributeName) || "") + " " + attribute.nodeValue; + } + + attributesElement.setAttribute(attributeName, value); + } + } + + ownerTemplateElement = owner._templateElement; + ownerTemplateDocument = ownerTemplateElement.ownerDocument; + + // reset this property in order to use it at the extended template + owner._templateElement = null; + + Template.templateWithModuleId(window.require, templateModuleId, function(template) { + template._partiallyInstantiateWithInstancesForDocument({owner: owner}, ownerTemplateDocument, function(objects) { + importNodes(owner._templateElement, element, ownerTemplateElement); + if (!self._isExpanded) { + var elementId = self.getMontageIdByElement(element), + ownerTemplateElementId = self.getMontageIdByElement(ownerTemplateElement), + templateElementId = self.getMontageIdByElement(owner._templateElement); + + importNodes( + self._document.importNode(template.getMontageElementById(templateElementId), true), + self.getMontageElementById(elementId), + self.getMontageElementById(ownerTemplateElementId) + ); + template.exportHeaders(self._document); + self._isExpanded = true; + } + self._deserializer.chainDeserializer(template._deserializer); + owner._templateElement = ownerTemplateElement; + callback(objects); + }); + }); + } + }, + + getMontageIdByElement: { + value: function(element) { + return element.getAttribute("data-montage-id") || element.id; + } + }, + + getMontageElementById: { + value: function(id) { + return this._document.querySelector("*[data-montage-id='" + id + "']") || + this._document.getElementById(id); + } + }, + /** Inserts all styles and scripts found in the Template object into the document given. @function @param {HTMLDocument} doc The document to insert the styles and scripts. */ - setupDocument: {value: function(doc) { + exportHeaders: {value: function(doc) { this.insertStylesInDocumentIfNeeded(doc); this.insertScriptsInDocumentIfNeeded(doc); }}, @@ -561,7 +724,7 @@ var Template = exports.Template = Montage.create(Montage, /** @lends module:mont }}, /** - This function is meant to work with insertScriptsInDocumentIfNeeded, insertStylesInDocumentIfNeeded and setupDocument. + This function is meant to work with insertScriptsInDocumentIfNeeded, insertStylesInDocumentIfNeeded and exportHeaders. This function informs the caller when the Template styles have been loaded into the document. @function @param {Function} callback The function to invoke when all linked CSS files have been loaded. @@ -728,10 +891,13 @@ var Template = exports.Template = Montage.create(Montage, /** @lends module:mont self = this; if (serialization) { + // no need to be always duplicating this on instantiation + this._removeSerialization(); callback(this._createDeserializer(serialization)); } else { this.getExternalSerialization(this._document, function(serialization) { if (serialization) { + self._removeSerialization(); callback(self._createDeserializer(serialization)); } else { callback(self._deserializer = false); @@ -767,6 +933,16 @@ var Template = exports.Template = Montage.create(Montage, /** @lends module:mont script.textContent = this._ownerSerialization = serialization; }}, + _removeSerialization: { + value: function() { + var script = this._document.querySelector("script[type='" + this._SCRIPT_TYPE + "']"); + + if (script) { + script.parentNode.removeChild(script); + } + } + }, + /** Converts the reel's HTML document into text. @function @@ -787,7 +963,7 @@ var Template = exports.Template = Montage.create(Montage, /** @lends module:mont /** @private */ - serializeSelf: {value: function(serializer) { + serializeProperties: {value: function(serializer) { serializer.set("owner", this._ownerSerialization); serializer.set("markup", this._document.body.innerHTML); }}, @@ -795,9 +971,22 @@ var Template = exports.Template = Montage.create(Montage, /** @lends module:mont /** @private */ - deserializeSelf: {value: function(deserializer) { - this._document = document.implementation.createHTMLDocument(""); - this._document.body.innerHTML = deserializer.get("markup"); - this._ownerSerialization = deserializer.get("owner"); + deserializeProperties: {value: function(deserializer) { + var markup = deserializer.get("markup"), + owner = deserializer.get("owner"), + _extends = deserializer.get("extends"); + + if (markup) { + this._document = document.implementation.createHTMLDocument(""); + this._document.body.innerHTML = markup; + } + + if (owner) { + this._ownerSerialization = owner; + } + + if (_extends) { + this._extends = _extends; + } }} }); -- cgit v1.2.3