UNPKG

marko

Version:

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

181 lines (147 loc) 4.02 kB
"use strict"; // eslint-disable-next-line no-constant-binary-expression var ComponentDef = require("../components/ComponentDef"); var ComponentsContext = require("../components/ComponentsContext"); var serializeNOOP = require("../helpers/serialize-noop"); var w10NOOP = serializeNOOP.aL_; var w10ToJSON = serializeNOOP.W_; var changeCase = require("./_change-case"); var getComponentsContext = ComponentsContext.T_; 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.bm_( tag, attrs, key, componentDef, addEvents(componentDef, customEvents, props) ); renderBody(out); out.bn_(); } else { out.bo_( 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.bp_) { renderer = dynamicTag.bp_( renderer, render, args, out.global ); } if (renderer) { out.c(componentDef, key, customEvents); renderer(attrs, out); out.ab_ = 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.aP_(key), globalContext ); render.toJSON = w10ToJSON; 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.bl_(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; }