prim().start(function () { // If an update to the endNode is requested before doing the transition, // load up module responsible for endNode and ask for an update. var d, moduleId = updateData && updateData.target; if (moduleId && endNode && endNode.getAttribute('data-moduleid') === moduleId) { d = prim(); require([moduleId], function (mod) { if (mod.update) { prim().start(function () { return mod.update({ card: this.card.bind(this) }, endNode, updateData.data); }.bind(this)).then(function (cardHtml) { if (cardHtml) { //Replace the node var node = this.toCardNode(cardHtml, updateData.href, moduleId); node.className = endNode.className; this.node.insertBefore(node, endNode); endNode.parentNode.removeChild(endNode); endNode = this.cards[cardIndex] = node; } }.bind(this)).then(d.resolve, d.reject); } else { d.resolve(); } }.bind(this), d.reject); return d.promise; } }.bind(this)).then(function () {
require([moduleId], function (init) { prim().start(function () { return init(deck.makeLocalDeck('', moduleId)); }).then(function () { deck._preloadModules(); }).end(); });
require([modData.id], function (mod) { if (mod[fn]) { prim().start(function () { return mod[fn](modData.node, this.makeLocalDeck(target.href, modData.id), data, evt); }.bind(this)).then(d.resolve, d.reject); } else { d.resolve(); } }.bind(this), d.reject);
require([moduleId], function (mod) { if (mod.update) { prim().start(function () { return mod.update({ card: this.card.bind(this) }, endNode, updateData.data); }.bind(this)).then(function (cardHtml) { if (cardHtml) { //Replace the node var node = this.toCardNode(cardHtml, updateData.href, moduleId); node.className = endNode.className; this.node.insertBefore(node, endNode); endNode.parentNode.removeChild(endNode); endNode = this.cards[cardIndex] = node; } }.bind(this)).then(d.resolve, d.reject); } else { d.resolve(); } }.bind(this), d.reject);
callFn: function (fn, target, data, evt) { var d = prim(), modData = walkUpForCardModule(target); if (modData) { require([modData.id], function (mod) { if (mod[fn]) { prim().start(function () { return mod[fn](modData.node, this.makeLocalDeck(target.href, modData.id), data, evt); }.bind(this)).then(d.resolve, d.reject); } else { d.resolve(); } }.bind(this), d.reject); } else { d.resolve(); } return d.promise; },
dialog: function (href, moduleId, data) { var html, d = prim(); data = Object.create(data || {}); data.moduleId = moduleId; if (data.cancel === true) { data.cancel = 'Cancel'; } if (data.ok === true) { data.ok = 'Accept'; } data.dialogId = 'id' + (dialogIdCounter += 1); this.dialogs[data.dialogId] = d; html = dialogTmpl(data || {}); this.node.appendChild(this.toNode(html)); return d.promise; },
nav: function (cardIndex, options) { options = options || {}; // Do not do anything if this is a show card for the current card. if (cardIndex === this.index) { // Could be an immediate injection, first card in the stack. Still do // post transition processing, like preloading next actions. this._handleAfterTransition(); // The state of the HTML could have still changed, so write it out here. this.saveState(); return; } var temp, updateData = options.update, finalIndex = cardIndex, beginNode = this.cards[this.index], endNode = this.cards[cardIndex], isForward = options.direction === 'forward'; prim().start(function () { // If an update to the endNode is requested before doing the transition, // load up module responsible for endNode and ask for an update. var d, moduleId = updateData && updateData.target; if (moduleId && endNode && endNode.getAttribute('data-moduleid') === moduleId) { d = prim(); require([moduleId], function (mod) { if (mod.update) { prim().start(function () { return mod.update({ card: this.card.bind(this) }, endNode, updateData.data); }.bind(this)).then(function (cardHtml) { if (cardHtml) { //Replace the node var node = this.toCardNode(cardHtml, updateData.href, moduleId); node.className = endNode.className; this.node.insertBefore(node, endNode); endNode.parentNode.removeChild(endNode); endNode = this.cards[cardIndex] = node; } }.bind(this)).then(d.resolve, d.reject); } else { d.resolve(); } }.bind(this), d.reject); return d.promise; } }.bind(this)).then(function () { // If going forward and it is an overlay node, then do not animate the // beginning node, it will just sit under the overlay. if (isForward && hasClass(endNode, 'anim-overlay')) { beginNode = null; } // Trim out dead nodes, ones that are considered "forward" in the // navigation, even though that could happen from either the left // or right side of the current card. if (!isForward) { if (cardIndex < this.index) { // Trim nodes from the "right" this._deadNodes = this.cards.splice(cardIndex + 1, this.cards.length - cardIndex); } else { // Trim nodes from the "left" this._deadNodes = this.cards.splice(0, cardIndex); finalIndex = 0; } } // If going back and the beginning node was an overlay, do not animate // the end node, since it should just be hidden under the overlay. if (beginNode && hasClass(beginNode, 'anim-overlay')) { if (isForward) { // If a forward animation and overlay had a vertical transition, // disable it, use normal horizontal transition. if (!options.immediate && hasClass(beginNode, 'anim-vertical')) { removeClass(beginNode, 'anim-vertical'); addClass(beginNode, 'disabled-anim-vertical'); } } else { endNode = null; } } if (options.immediate) { addClass(beginNode, 'no-anim'); addClass(endNode, 'no-anim'); } this._transitionCount = (beginNode && endNode && !options.immediate) ? 2 : 1; this._animating = true; // make sure the reflow sees the correct transition state, whether // it is on or off. Otherwise, forward navigation in Firefox // did not seem to know animation was involved. temp = this.node.clientWidth; if (this.index === cardIndex) { // same node, no transition, just bootstrapping UI. removeClass(beginNode, 'before'); removeClass(beginNode, 'after'); addClass(beginNode, 'center'); } else if (this.index > cardIndex) { // back removeClass(beginNode, 'center'); addClass(beginNode, 'after'); removeClass(endNode, 'before'); addClass(endNode, 'center'); } else { // forward removeClass(beginNode, 'center'); addClass(beginNode, 'before'); removeClass(endNode, 'after'); addClass(endNode, 'center'); } this._beginNode = beginNode; this._endNode = endNode; this._endNodeEvent = isForward ? null : 'onShow'; this.index = finalIndex; if (options.immediate) { // make sure the instantaneous transition is seen before we turn // transitions back on. temp = this.node.clientWidth; removeClass(beginNode, 'no-anim'); removeClass(endNode, 'no-anim'); // Manually call transition end to finish up any common work. this._onTransitionEnd(); } }.bind(this)).end(); },