diff --git a/ui/component.js b/ui/component.js index 519b904d87..56748eb75f 100644 --- a/ui/component.js +++ b/ui/component.js @@ -1350,19 +1350,28 @@ var Component = exports.Component = Target.specialize(/** @lends Component.proto get: function () { if (this._element) { return Array.prototype.slice.call(this._element.childNodes, 0); - } else { - return null; } + + return null; }, set: function (value) { - var components, + var components = this.childComponents, componentsToAdd = [], - i, - component; + component, + i; if (!this._elementsToAppend) { this._elementsToAppend = []; + } else if (this._elementsToAppend.length) { + this._elementsToAppend.clear(); + } + + if (!this._componentsPendingBuildOut) { + this._componentsPendingBuildOut = []; + } else if (this._componentsPendingBuildOut.length) { + this._componentsPendingBuildOut.clear(); } + this._newDomContent = value; this.needsDraw = true; @@ -1370,37 +1379,32 @@ var Component = exports.Component = Target.specialize(/** @lends Component.proto this._shouldClearDomContentOnNextDraw = true; } + //@benoit this method should be probably before we really change the content. if (typeof this.contentWillChange === "function") { this.contentWillChange(value); } - // cleanup current content - components = this.childComponents; if (value) { - if (!this._componentsPendingBuildOut) { - this._componentsPendingBuildOut = []; - } for (i = components.length - 1; i >= 0; i--) { - if (this._componentsPendingBuildOut.indexOf(components[i]) === -1) { - this._componentsPendingBuildOut.push(components[i]); - } + this._componentsPendingBuildOut.push(components[i]); } } else { - this._componentsPendingBuildOut = []; for (i = components.length - 1; i >= 0; i--) { components[i]._shouldBuildOut = true; } } + if (value instanceof Element) { this._elementsToAppend.push(value); this._findAndDetachComponents(value, componentsToAdd); + } else if (value && value[0]) { for (i = 0; i < value.length; i++) { this._elementsToAppend.push(value[i]); this._findAndDetachComponents(value[i], componentsToAdd); } } - + // not sure if I can rely on _parentComponent to detach the nodes instead of doing one loop for dettach and another to attach... for (i = 0; (component = componentsToAdd[i]); i++) { this.addChildComponent(component); @@ -2076,6 +2080,8 @@ var Component = exports.Component = Target.specialize(/** @lends Component.proto } } this._disposeArray(oldDrawList); + } else if (this._componentsPendingBuildOut) { + this._releaseChildComponentsPendingBuildOut(); } } }, @@ -3125,8 +3131,6 @@ var Component = exports.Component = Target.specialize(/** @lends Component.proto _buildOut: { value: function () { - var self = this; - if (this._currentBuildAnimation) { this._currentBuildAnimation.cancel(); this._currentBuildAnimation = this.buildOutSwitchAnimation; @@ -3134,8 +3138,11 @@ var Component = exports.Component = Target.specialize(/** @lends Component.proto this._updateActiveBuildAnimations(); this._currentBuildAnimation = this.buildOutInitialAnimation; } - if (this._element && this._element.parentNode && this._element.parentNode.component) { + + if ((this.parentComponent) || (this._element && this._element.parentNode && this._element.parentNode.component)) { if (this._currentBuildAnimation) { + var self = this; + this._currentBuildAnimation.play(); this._currentBuildAnimation.finished.then(function () { var parent = self.parentComponent; @@ -3144,16 +3151,21 @@ var Component = exports.Component = Target.specialize(/** @lends Component.proto self.detachFromParentComponent(); self.buildInAnimationOverride = null; self.buildOutAnimationOverride = null; + if (self._element.parentNode.component) { self._element.parentNode.removeChild(self._element); } + self._isElementAttachedToParent = false; parent.dispatchEventNamed("buildOutEnd", true, true); - }, function () {}); + + }, Function.noop); + } else { this.detachFromParentComponent(); this.buildInAnimationOverride = null; this.buildOutAnimationOverride = null; + if (this._isElementAttachedToParent) { if (this._element.parentNode && this._element.parentNode.component) { this._element.parentNode.removeChild(this._element); @@ -3178,7 +3190,7 @@ var Component = exports.Component = Target.specialize(/** @lends Component.proto this.dispatchEvent(event); this._inDocument = true; if (this.parentComponent) { - this.parentComponent._childWillEnterDocument(); + this.parentComponent._releaseChildComponentsPendingBuildOut(); } if (this.__shouldBuildIn) { this._buildIn(); @@ -3190,7 +3202,7 @@ var Component = exports.Component = Target.specialize(/** @lends Component.proto } }, - _childWillEnterDocument: { + _releaseChildComponentsPendingBuildOut: { value: function () { if (this._componentsPendingBuildOut) { while (this._componentsPendingBuildOut.length) { diff --git a/ui/substitution.reel/substitution.js b/ui/substitution.reel/substitution.js index 2fa9f40428..9f9fb2de2c 100644 --- a/ui/substitution.reel/substitution.js +++ b/ui/substitution.reel/substitution.js @@ -157,19 +157,20 @@ exports.Substitution = Slot.specialize( /** @lends Substitution.prototype # */ { return this._switchValue; }, set: function (value) { - - if (this._switchValue === value || this._isSwitchingContent) { - return; + if (typeof value === "number") { + value = value.toString(); } - - this._switchValue = value; - - // switchElements is only ready after the first draw - // At first draw the substitution automatically draws what is in - // the switchValue so we defer any content loading until the first - // draw. - if (!this._firstDraw && !this.isDeserializing) { - this._loadContent(value); + + if (this._switchValue !== value) { + this._switchValue = value; + + // switchElements is only ready after the first draw + // At first draw the substitution automatically draws what is in + // the switchValue so we defer any content loading until the first + // draw. + if (!this._firstDraw && !this.isDeserializing) { + this._loadContent(value); + } } } }, @@ -200,6 +201,16 @@ exports.Substitution = Slot.specialize( /** @lends Substitution.prototype # */ { _loadContent: { value: function (value) { var typeOfValue = typeof value; + + // Fixme: [workaround] we need a better logic here. + // the method extractDomArgument(name) (used in enterDocument) + // keeps a pointer to the original element and not the "new" one (_templateElement). + if (this._switchComponents[value] && + this._switchComponents[value].element !== this._switchElements[value]) { + + this._switchElements[value] = this._switchComponents[value].element; + } + this.content = this._switchElements[value] || null; if ((typeOfValue === "string" || typeOfValue === "number") && !this._switchComponentTreeLoaded[value]) { @@ -209,14 +220,13 @@ exports.Substitution = Slot.specialize( /** @lends Substitution.prototype # */ { }, contentDidChange: { - value: function (newContent, oldContent) { - Slot.prototype.contentDidChange.call(this, newContent, oldContent); + value: function () { + Slot.prototype.contentDidChange.call(this); - if (this._drawnSwitchValue) { - if (this._switchComponents[this._drawnSwitchValue]) { - this._switchElements[this._drawnSwitchValue] = this._switchComponents[this._drawnSwitchValue].element; - } + if (this._drawnSwitchValue && this._switchComponents[this._drawnSwitchValue]) { + this._switchElements[this._drawnSwitchValue] = this._switchComponents[this._drawnSwitchValue].element; } + this._drawnSwitchValue = this._switchValue; } },