marko
Version:
UI Components + streaming, async, high performance, HTML templating for Node.js and the browser.
181 lines (147 loc) • 4.02 kB
JavaScript
"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;
}