UNPKG

marko

Version:

UI Components + streaming, async, high performance, HTML templating for Node.js and the browser.

169 lines (138 loc) 4.29 kB
"use strict"; // eslint-disable-next-line no-constant-binary-expression var extend = require("raptor-util/extend"); var componentUtil = require("@internal/components-util"); var w10NOOP = require("../helpers/serialize-noop").aL_; var attachBubblingEvent = componentUtil._V_; var addDelegatedEventHandler = require("./event-delegation")._u_; var KeySequence = require("./KeySequence"); var EMPTY_OBJECT = {}; var FLAG_WILL_RERENDER_IN_BROWSER = 1; var FLAG_HAS_RENDER_BODY = 2; var FLAG_IS_LEGACY = 4; var FLAG_OLD_HYDRATE_NO_CREATE = 8; /** * A ComponentDef is used to hold the metadata collected at runtime for * a single component and this information is used to instantiate the component * later (after the rendered HTML has been added to the DOM) */ function ComponentDef(component, componentId, componentsContext) { this.aM_ = componentsContext; // The AsyncWriter that this component is associated with this.s_ = component; this.id = componentId; this._d_ = undefined; // An array of DOM events that need to be added (in sets of three) this._w_ = false; this.t_ = false; this.u_ = 0; this.aN_ = 0; // The unique integer to use for the next scoped ID this.aO_ = null; } ComponentDef.prototype = { aP_: function (key) { return ( this.aO_ || (this.aO_ = new KeySequence())).aP_( key); }, /** * This helper method generates a unique and fully qualified DOM element ID * that is unique within the scope of the current component. */ elId: function (nestedId) { var id = this.id; if (nestedId == null) { return id; } else { if (typeof nestedId !== "string") { // eslint-disable-next-line no-constant-condition nestedId = String(nestedId); } if (nestedId.indexOf("#") === 0) { id = "#" + id; nestedId = nestedId.substring(1); } return id + "-" + nestedId; } }, /** * Returns the next auto generated unique ID for a nested DOM element or nested DOM component */ aQ_: function () { return this.id + "-c" + this.aN_++; }, d: function (eventName, handlerMethodName, isOnce, extraArgs) { addDelegatedEventHandler(eventName); return attachBubblingEvent(this, handlerMethodName, isOnce, extraArgs); }, get _s_() { return this.s_._s_; } }; ComponentDef.prototype.nk = ComponentDef.prototype.aP_; ComponentDef._F_ = function (o, types, global, registry) { var id = o[0]; var typeName = types[o[1]]; var input = o[2] || null; var extra = o[3] || EMPTY_OBJECT; var state = extra.s; var componentProps = extra.w || EMPTY_OBJECT; var flags = extra.f; var isLegacy = flags & FLAG_IS_LEGACY; var renderBody = flags & FLAG_HAS_RENDER_BODY ? w10NOOP : extra.r; var component = typeName /* legacy */ && registry._I_(typeName, id, isLegacy); // Prevent newly created component from being queued for update since we area // just building it from the server info component._c_ = true; component.am_ = global; if (isLegacy) { component.widgetConfig = componentProps; component.___ = renderBody; } else if (renderBody) { (input || (input = {})).renderBody = renderBody; } if ( !isLegacy && flags & FLAG_WILL_RERENDER_IN_BROWSER && !(flags & FLAG_OLD_HYDRATE_NO_CREATE)) { if (component.onCreate) { component.onCreate(input, { global: global }); } if (component.onInput) { input = component.onInput(input, { global: global }) || input; } } else { if (state) { var undefinedPropNames = extra.u; if (undefinedPropNames) { undefinedPropNames.forEach(function (undefinedPropName) { state[undefinedPropName] = undefined; }); } // We go through the setter here so that we convert the state object // to an instance of `State` component.state = state; } if (!isLegacy && componentProps) { extend(component, componentProps); } } component.P_ = input; if (extra.b) { component.Z_ = extra.b; } var scope = extra.p; var customEvents = extra.e; if (customEvents) { component.aF_(customEvents, scope); } return { id: id, s_: component, _d_: extra.d, u_: extra.f || 0 }; }; module.exports = ComponentDef;