marko
Version:
UI Components + streaming, async, high performance, HTML templating for Node.js and the browser.
231 lines (194 loc) • 5.99 kB
JavaScript
"use strict";var beginComponent = require("@internal/components-beginComponent");
var endComponent = require("@internal/components-endComponent");
var registry = require("@internal/components-registry");
var componentsUtil = require("@internal/components-util");
var getComponentsContext =
require("../ComponentsContext").T_;
var componentLookup = componentsUtil._n_;
var modernRenderer = require("../renderer");
var resolveComponentKey = modernRenderer.aZ_;
var trackAsyncComponents = modernRenderer.bc_;
// eslint-disable-next-line no-constant-binary-expression
function createRendererFunc(templateRenderFunc, componentProps) {
var typeName = componentProps.t;
//var assignedId = componentProps.id;
var isSplit = componentProps.s === true;
var isImplicit = componentProps.i === true;
return function renderer(input, out, assignedId, renderingLogic) {
trackAsyncComponents(out);
var componentsContext = getComponentsContext(out);
var parentLegacyComponentDef = componentsContext.bd_;
if (isImplicit && parentLegacyComponentDef) {
templateRenderFunc(
input,
out,
parentLegacyComponentDef,
parentLegacyComponentDef.s_,
parentLegacyComponentDef.s_.aE_,
out.global
);
return;
}
var widgetBody = input.renderBody;
var widgetState = input.widgetState;
var widgetConfig = input.widgetConfig;
var globalComponentsContext = componentsContext.p_;
var component = globalComponentsContext.aB_;
var isRerender = component !== undefined;
var id = assignedId;
var isExisting;
var parentComponentDef = componentsContext.o_;
var ownerComponentDef = out.ab_;
var ownerComponentId = ownerComponentDef && ownerComponentDef.id;
var key = out.ac_;
var customEvents = out.be_;
out.ab_ = null;
if (component) {
id = component.id;
isExisting = true;
globalComponentsContext.aB_ = null;
} else {
if (key != null) {
id = id || resolveComponentKey(key.toString(), parentComponentDef);
} else if (parentComponentDef) {
id = parentComponentDef.aQ_();
} else {
id = globalComponentsContext.aQ_();
}
}
if (registry._L_ && typeName) {
if (renderingLogic) delete renderingLogic.onRender;
component = registry._I_(
renderingLogic,
id,
input,
out,
typeName,
customEvents,
ownerComponentId
);
if (isSplit || widgetState) {
component.input = null;
} else if (input.widgetProps) {
// eslint-disable-next-line no-constant-condition
component.input = input.widgetProps;
}
} else {
if (!component) {
if (isRerender) {
// Look in in the DOM to see if a component with the same ID and type already exists.
component = componentLookup[id];
if (component && component._s_ !== typeName) {
component = undefined;
}
}
if (component) {
isExisting = true;
} else {
isExisting = false;
// We need to create a new instance of the component
if (typeName) {
component = registry._I_(typeName, id);
}
}
}
}
var isFakeComponent = false;
if (!component) {
isFakeComponent = true;
component = {
id: id,
L_: {}
};
} else {
component._c_ = true;
if (widgetState) {
component.state = widgetState;
}
}
component.widgetConfig = widgetConfig;
component.___ = widgetBody || component.___;
var componentDef = beginComponent(
componentsContext,
component,
key,
ownerComponentDef,
isSplit,
isFakeComponent
);
componentsContext.bd_ = componentDef;
// This is a hack, but we have to swap out the component instance stored with this node
var vComponentNode = out.ad_;
componentDef.s_ = isFakeComponent ? null : component;
componentDef._w_ = isExisting;
componentDef.z_ = true;
componentDef.t = function (typeName) {
if (typeName) {
if (registry._L_) {
var oldComponent = component;
if (renderingLogic) delete renderingLogic.onRender;
component = registry._I_(
renderingLogic || {},
id,
input,
out,
typeName,
customEvents,
ownerComponentId
);
if (isSplit || widgetState) {
component.input = null;
} else if (input.widgetProps) {
// eslint-disable-next-line no-constant-condition
component.input = input.widgetProps;
}
Object.assign(component, oldComponent);
beginComponent(
componentsContext,
component,
key,
ownerComponentDef,
isSplit,
false,
this
);
} else {
vComponentNode.s_ = component = registry._I_(
typeName,
component.id
);
}
this.s_ = component;
}
return component;
};
if (!registry._L_) {
component.M_ && component.M_();
}
// Render the template associated with the component using the final template
// data that we constructed
templateRenderFunc(
input,
out,
componentDef,
component,
component.aE_,
out.global
);
if (customEvents && componentDef.s_) {
if (registry._L_) {
componentDef.X_ = customEvents;
componentDef.Y_ = ownerComponentId;
} else {
componentDef.s_.aF_(
customEvents,
ownerComponentId
);
}
}
endComponent(out, componentDef);
componentsContext.o_ = parentComponentDef;
componentsContext.bd_ = parentLegacyComponentDef;
};
}
module.exports = createRendererFunc;