UNPKG

raptor

Version:

RaptorJS provides an AMD module loader that works in Node, Rhino and the web browser. It also includes various sub-modules to support building optimized web applications.

190 lines (163 loc) 6.67 kB
define('raptor/renderer/RenderResult', function(require) { "use strict"; var dom = require('raptor/dom'); var RenderResult = function(html, context) { this.html = html; this.context = context; this._node = undefined; }; RenderResult.prototype = { getWidget : function() { if (!this.widgetDefs) { throw new Error('Cannot call getWidget() until after HTML fragment is added to DOM.'); } return this.widgetDefs.length ? this.widgetDefs[0].widget : undefined; }, /** * This method used to retrieve all or some of the widgets that were instantiated as a result of rendering. * * @param {Function} selector an optional function that should accept a widget argument * and return true if the widget should be selected * @return {raptor/widgets/Widget[]} the array of widgets that matched the selector or * all widgets if no selector was given */ getWidgets: function(selector) { if (!this.widgetDefs) { throw new Error('Cannot call getWidgets() until after HTML fragment is added to DOM.'); } var widgets, i; if (selector) { // use the selector to find the widgets that the caller wants widgets = []; for (i = 0; i < this.widgetDefs.length; i++) { var widget = this.widgetDefs[i].widget; if (selector(widget)) { widgets.push(widget); } } } else { // return all widgets widgets = new Array(this.widgetDefs.length); for (i = 0; i < this.widgetDefs.length; i++) { widgets[i] = this.widgetDefs[i].widget; } } return widgets; }, /** * Invoked after the rendered document fragment is inserted into the DOM. * * @return {void} * @private */ _afterInsert: function() { var widgets = require.find('raptor/widgets'); if (widgets) { var widgetsContext = widgets.getWidgetsContext(this.context); this.widgetDefs = widgetsContext.widgets; } var pubsub = require.find('raptor/pubsub'); if (pubsub) { pubsub.publish('raptor/renderer/renderedToDOM', { node: this.getNode(), context: this.context }); // NOTE: This will trigger widgets to be initialized if there were any } return this; }, /** * Appends the rendered document fragment as a child of the reference element. * * @param {DOMElement|String} referenceEl The reference element * @return {void} */ appendTo: function(referenceEl) { dom.appendTo(this.getNode(), referenceEl); return this._afterInsert(); }, /** * Replaces the reference element with the rendered document fragment. * * @param {DOMElement|String} referenceEl The reference element * @return {void} */ replace: function(referenceEl) { dom.replace(this.getNode(), referenceEl); return this._afterInsert(); }, /** * Replaces the children of reference element with the rendered document fragment. * * @param {DOMElement|String} referenceEl The reference element * @return {void} */ replaceChildrenOf: function(referenceEl) { dom.replaceChildrenOf(this.getNode(), referenceEl); return this._afterInsert(); }, /** * Inserts the rendered document fragment before the reference element (as a sibling). * * @param {DOMElement|String} referenceEl The reference element * @return {void} */ insertBefore: function(referenceEl) { dom.insertBefore(this.getNode(), referenceEl); return this._afterInsert(); }, /** * Inserts the rendered document fragment after the reference element (as a sibling). * * @param {DOMElement|String} referenceEl The reference element * @return {void} */ insertAfter: function(referenceEl) { dom.insertAfter(this.getNode(), referenceEl); return this._afterInsert(); }, /** * Prepends the rendered document fragment as a child of the reference element. * * @param {DOMElement|String} referenceEl The reference element * @return {void} */ prependTo: function(referenceEl) { dom.prependTo(this.getNode(), referenceEl); return this._afterInsert(); }, /** * Returns the DOM node for the rendered HTML. If the rendered HTML resulted * in multiple top-level DOM nodes then the top-level DOM nodes are wrapped * in a single DocumentFragment node. * * @return {Node|DocumentFragment} The DOM node that can be used to insert the rendered HTML into the DOM. */ getNode: function() { var node = this._node, curEl, newBodyEl; if (node === undefined) { if (this.html) { newBodyEl = document.createElement('body'); newBodyEl.innerHTML = this.html; if (newBodyEl.childNodes.length == 1) { // If the rendered component resulted in a single node then just use that node node = newBodyEl.childNodes[0]; } else { // Otherwise, wrap the nodes in a document fragment node node = document.createDocumentFragment(); while((curEl=newBodyEl.firstChild)) { node.appendChild(curEl); } } } else { // empty HTML so use empty document fragment (so that we're returning a valid DOM node) node = document.createDocumentFragment(); } this._node = node; } return node; } }; return RenderResult; });