UNPKG

marko

Version:

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

176 lines (142 loc) 3.9 kB
"use strict"; var w10NOOP = require("warp10/constants").NOOP; var ComponentDef = require("../components/ComponentDef"); var ComponentsContext = require("../components/ComponentsContext"); var changeCase = require("./_change-case"); var getComponentsContext = ComponentsContext.S_; var RENDER_BODY_TO_JSON = function () { return w10NOOP; }; var FLAG_WILL_RERENDER_IN_BROWSER = 1; // var FLAG_HAS_RENDER_BODY = 2; var IS_SERVER = typeof document === "undefined"; /** * Helper to render a dynamic tag */ module.exports = function dynamicTag( out, tag, getAttrs, renderBody, args, props, componentDef, key, customEvents) { if (tag) { if (tag.default) { tag = tag.default; } var attrs = getAttrs && getAttrs(); var component = componentDef && componentDef.s_; if (typeof tag === "string") { if (renderBody) { out.bi_( tag, attrs, key, componentDef, addEvents(componentDef, customEvents, props) ); renderBody(out); out.bj_(); } else { out.bk_( tag, attrs, key, componentDef, addEvents(componentDef, customEvents, props) ); } } else { if (attrs == null) { attrs = { renderBody: renderBody }; } else if (typeof attrs === "object") { attrs = attrsToCamelCase(attrs); if (renderBody) { attrs.renderBody = renderBody; } } var renderer = tag._ || ( tag.renderer ? tag.renderer.renderer || tag.renderer : tag.render); var render = tag && tag.renderBody || tag; // eslint-disable-next-line no-constant-condition if (dynamicTag.bl_) { renderer = dynamicTag.bl_(renderer, render, args); } if (renderer) { out.c(componentDef, key, customEvents); renderer(attrs, out); out._Z_ = null; } else { var isFn = typeof render === "function"; // eslint-disable-next-line no-constant-condition if (isFn) { var flags = componentDef ? componentDef.u_ : 0; var willRerender = flags & FLAG_WILL_RERENDER_IN_BROWSER; var isW10NOOP = render === w10NOOP; var preserve = IS_SERVER ? willRerender : isW10NOOP; out.bf(key, component, preserve); if (!isW10NOOP && isFn) { var componentsContext = getComponentsContext(out); var parentComponentDef = componentsContext.o_; var globalContext = componentsContext.p_; componentsContext.o_ = new ComponentDef( component, parentComponentDef.id + "-" + parentComponentDef.aL_(key), globalContext ); render.toJSON = RENDER_BODY_TO_JSON; if (args) { render.apply(null, [out].concat(args, attrs)); } else { render(out, attrs); } componentsContext.o_ = parentComponentDef; } out.ef(); } else { out.error("Invalid dynamic tag value"); } } } } else if (renderBody) { out.bf( key, component, IS_SERVER && componentDef && componentDef.u_ & FLAG_WILL_RERENDER_IN_BROWSER ); renderBody(out); out.ef(); } }; function attrsToCamelCase(attrs) { var result = {}; for (var key in attrs) { result[changeCase.bh_(key)] = attrs[key]; } return result; } function addEvents(componentDef, customEvents, props) { var len = customEvents ? customEvents.length : 0; if (len === 0) { return props; } var result = props || {}; var event; for (var i = len; i--;) { event = customEvents[i]; result["on" + event[0]] = componentDef.d( event[0], event[1], event[2], event[3] ); } return result; }