From 13ae16997d4bbca14e255d5989d1c44a76eac72c Mon Sep 17 00:00:00 2001 From: Valerio Virgillito Date: Wed, 16 May 2012 15:23:48 -0700 Subject: montage v.0.10 integration Signed-off-by: Valerio Virgillito --- node_modules/montage/ui/component.js | 163 +++++++++++++++++++++++------------ 1 file changed, 108 insertions(+), 55 deletions(-) (limited to 'node_modules/montage/ui/component.js') diff --git a/node_modules/montage/ui/component.js b/node_modules/montage/ui/component.js index 9d963ada..8a8f5739 100755 --- a/node_modules/montage/ui/component.js +++ b/node_modules/montage/ui/component.js @@ -270,7 +270,7 @@ var Component = exports.Component = Montage.create(Montage,/** @lends module:mon aParentNode, eventManager = this.eventManager; if (anElement) { - while ((aParentNode = anElement.parentNode) !== null && eventManager.eventHandlerForElement(aParentNode) == null) { + while ((aParentNode = anElement.parentNode) != null && eventManager.eventHandlerForElement(aParentNode) == null) { anElement = aParentNode; } return aParentNode ? eventManager.eventHandlerForElement(aParentNode) : this._alternateParentComponent; @@ -539,6 +539,7 @@ var Component = exports.Component = Montage.create(Montage,/** @lends module:mon */ cleanupDeletedComponentTree: { value: function() { + Object.deleteBindings(this); this.needsDraw = false; this.traverseComponentTree(function(component) { Object.deleteBindings(component); @@ -551,12 +552,12 @@ var Component = exports.Component = Montage.create(Montage,/** @lends module:mon value: null }, - _newContent: { + _newDomContent: { enumerable: false, value: null }, - content: { + domContent: { get: function() { if (this._element) { return Array.prototype.slice.call(this._element.childNodes, 0); @@ -565,12 +566,16 @@ var Component = exports.Component = Montage.create(Montage,/** @lends module:mon } }, set: function(value) { - var components = [], - childNodes; + var components, + componentsToAdd = []; - this._newContent = value; + this._newDomContent = value; this.needsDraw = true; + if (this._newDomContent === null) { + this._shouldClearDomContentOnNextDraw = true; + } + if (typeof this.contentWillChange === "function") { this.contentWillChange(value); } @@ -584,7 +589,7 @@ var Component = exports.Component = Montage.create(Montage,/** @lends module:mon if (value instanceof Element) { findAndDetachComponents(value); - } else { + } else if (value) { for (var i = 0; i < value.length; i++) { findAndDetachComponents(value[i]); } @@ -596,7 +601,7 @@ var Component = exports.Component = Montage.create(Montage,/** @lends module:mon if (component) { component.detachFromParentComponent(); - components.push(component); + componentsToAdd.push(component); } else { var childNodes = node.childNodes; for (var i = 0, childNode; (childNode = childNodes[i]); i++) { @@ -606,12 +611,16 @@ var Component = exports.Component = Montage.create(Montage,/** @lends module:mon } // not sure if I can rely on _cachedParentComponent to detach the nodes instead of doing one loop for dettach and another to attach... - for (var i = 0, component; (component = components[i]); i++) { + for (var i = 0, component; (component = componentsToAdd[i]); i++) { this._addChildComponent(component); } } }, + _shouldClearDomContentOnNextDraw: { + value: false + }, + /** Description TODO @function @@ -988,7 +997,7 @@ var Component = exports.Component = Montage.create(Montage,/** @lends module:mon enumerable: false, value: function _drawIfNeeded(level) { var childComponent, - oldDrawList; + oldDrawList, i, childComponentListLength; this._treeLevel = level; if (this.needsDraw && !this._addedToDrawCycle) { rootComponent.addToDrawCycle(this); @@ -999,7 +1008,9 @@ var Component = exports.Component = Montage.create(Montage,/** @lends module:mon if (this._drawList !== null && this._drawList.length > 0) { oldDrawList = this._drawList; this._drawList = []; - while ((childComponent = oldDrawList.shift())) { + childComponentListLength = oldDrawList.length; + for (i = 0; i < childComponentListLength; i++) { + childComponent = oldDrawList[i]; if (drawLogger.isDebug) { drawLogger.debug("Parent Component " + (this.element != null ? this.element.id : "") + " drawList length: " + oldDrawList.length); } @@ -1014,6 +1025,44 @@ var Component = exports.Component = Montage.create(Montage,/** @lends module:mon } } }, + + _updateComponentDom: { + value: function() { + var component, composer, length, i; + if (this._firstDraw) { + + if (this.parentComponent && typeof this.parentComponent.childComponentWillPrepareForDraw === "function") { + this.parentComponent.childComponentWillPrepareForDraw(this); + } + + this._prepareForDraw(); + + if (this.prepareForDraw) { + this.prepareForDraw(); + } + + // Load any non lazyLoad composers that have been added + length = this.composerList.length; + for (i = 0; i < length; i++) { + composer = this.composerList[i]; + if (!composer.lazyLoad) { + composer._load(); + } + } + + // Will we expose a different property, firstDraw, for components to check + this._firstDraw = false; + } + + if (this._newDomContent !== null || this._shouldClearDomContentOnNextDraw) { + if (drawLogger.isDebug) { + logger.debug("Component content changed: component ", this._montage_metadata.objectName, this.identifier, " newDomContent", this._newDomContent); + } + this._performDomContentChanges(); + } + } + }, + /** Description TODO @private @@ -1042,7 +1091,11 @@ var Component = exports.Component = Montage.create(Montage,/** @lends module:mon template.setAttribute(attributeName, value); } - element.parentNode.replaceChild(template, element); + if (element.parentNode) { + element.parentNode.replaceChild(template, element); + } else { + console.warn("Warning: Trying to replace element ", element," which has no parentNode"); + } this.eventManager.unregisterEventHandlerForElement(element); this.eventManager.registerEventHandlerForElement(this, template); @@ -1108,31 +1161,30 @@ var Component = exports.Component = Montage.create(Montage,/** @lends module:mon Description TODO @private */ - _draw: { + _performDomContentChanges: { value: function() { - var contents = this._newContent, + var contents = this._newDomContent, + oldContent = this._element.childNodes[0], element; - this._canDrawTable = {}; - this._canDrawCount = 0; - - if (contents) { + if (contents || this._shouldClearDomContentOnNextDraw) { element = this._element; element.innerHTML = ""; if (contents instanceof Element) { element.appendChild(contents); - } else { + } else if(contents !== null) { for (var i = 0, content; (content = contents[i]); i++) { element.appendChild(content); } } - this._newContent = null; + this._newDomContent = null; if (typeof this.contentDidChange === "function") { - this.contentDidChange(); + this.contentDidChange(this._element.childNodes[0], oldContent); } + this._shouldClearDomContentOnNextDraw = false; } } }, @@ -1189,6 +1241,9 @@ var Component = exports.Component = Montage.create(Montage,/** @lends module:mon } else { parentComponent._addToDrawList(this); } + if (drawLogger.isDebug) { + drawLogger.debug("drawList -- childComponent",this._montage_metadata.objectName," added to ",parentComponent._montage_metadata.objectName); + } } } }, @@ -1390,10 +1445,12 @@ var Component = exports.Component = Montage.create(Montage,/** @lends module:mon */ clearAllComposers: { value: function() { - var composer; - while (composer = this.composerList.shift()) { - composer.unload(); + var i, length, composerList = this.composerList; + length = composerList.length; + for (i = 0; i < length; i++) { + composerList[i].unload(); } + composerList.splice(0, length); } } @@ -1515,13 +1572,16 @@ var rootComponent = Montage.create(Component, /** @lends module:montage/ui/compo */ _clearNeedsDrawList: { value: function() { - var component; - while ((component = this._needsDrawList.shift())) { + var component, i, length, needsDrawList = this._needsDrawList; + length = needsDrawList.length; + for (i = 0; i < length; i++) { + component = needsDrawList[i]; if (component.needsDraw) { component._addToParentsDrawList(); } } this._clearNeedsDrawTimeOut = null; + needsDrawList.splice(0, length); } }, /** @@ -1708,6 +1768,11 @@ var rootComponent = Montage.create(Component, /** @lends module:montage/ui/compo Description TODO @function */ + _previousDrawDate: { + enumerable: false, + value: 0 + }, + drawTree: { value: function drawTree() { if (this.requestedAnimationFrame === null) { // 0 is a valid requestedAnimationFrame value @@ -1757,8 +1822,16 @@ var rootComponent = Montage.create(Component, /** @lends module:montage/ui/compo if (requestAnimationFrame) { this.requestedAnimationFrame = requestAnimationFrame.call(window, _drawTree); } else { - //1000/17 = 60fps - this.requestedAnimationFrame = setTimeout(_drawTree, 16); + // Shim based in Erik Möller's code at + // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating + var currentDate = Date.now(), + miliseconds = 17 - currentDate + this._previousDrawDate; + + if (miliseconds < 0) { + miliseconds = 0; + } + this.requestedAnimationFrame = setTimeout(_drawTree, miliseconds); + this._previousDrawDate = currentDate + miliseconds; } this._scheduleComposerRequest = false; } @@ -1801,29 +1874,7 @@ var rootComponent = Montage.create(Component, /** @lends module:montage/ui/compo this._readyToDrawList.push(component); this._readyToDrawListIndex[component.uuid] = true; - if (component._firstDraw) { - - if (component.parentComponent && typeof component.parentComponent.childComponentWillPrepareForDraw === "function") { - component.parentComponent.childComponentWillPrepareForDraw(component); - } - - component._prepareForDraw(); - if (component.prepareForDraw) { - component.prepareForDraw(); - } - - // Load any non lazyLoad composers that have been added - length = component.composerList.length; - for (i = 0; i < length; i++) { - composer = component.composerList[i]; - if (!composer.lazyLoad) { - composer._load(); - } - } - - // Will we expose a different property, firstDraw, for components to check - component._firstDraw = false; - } + component._updateComponentDom(); } }, @@ -1835,18 +1886,21 @@ var rootComponent = Montage.create(Component, /** @lends module:montage/ui/compo drawIfNeeded:{ value: function drawIfNeeded() { var needsDrawList = this._readyToDrawList, component, i, j, start = 0, firstDrawEvent, - composerList = this.composerList, composer; + composerList = this.composerList, composer, composerListLength; needsDrawList.length = 0; + composerListLength = composerList.length; this._readyToDrawListIndex = {}; // Process the composers first so that any components that need to be newly drawn due to composer changes // get added in this cycle - if (composerList.length > 0) { + if (composerListLength > 0) { this.composerList = this.composerListSwap; // Swap between two arrays instead of creating a new array each draw cycle - while (composer = composerList.shift()) { + for (i = 0; i < composerListLength; i++) { + composer = composerList[i]; composer.needsFrame = false; composer.frame(this._frameTime); } + composerList.splice(0, composerListLength); this.composerListSwap = composerList; } @@ -1882,7 +1936,6 @@ var rootComponent = Montage.create(Component, /** @lends module:montage/ui/compo // TODO: add the possibility to display = "none" the body during development (IKXARIA-3631). for (i = j-1; i >= 0; i--) { component = needsDrawList[i]; - component._draw(); component.draw(this._frameTime); if (drawLogger.isDebug) { drawLogger.debug(component._montage_metadata.objectName, " draw treeLevel ",component._treeLevel); -- cgit v1.2.3