marko
Version:
UI Components + streaming, async, high performance, HTML templating for Node.js and the browser.
115 lines (96 loc) • 2.89 kB
JavaScript
;var registry = require("@internal/components-registry");
var setImmediate = require("@internal/set-immediate")._l_;
var updateManager = require("../components/update-manager");
var runtime = require(".");
var createTemplate = runtime.t;
var createComponent = registry._I_;
var registered = {};
var instancesByType = {};
var queue;
exports.t = runtime.t = function (typeName) {
if (registered[typeName]) {
return registered[typeName];
}
var renderFn;
var template = registered[typeName] = createTemplate(typeName);
var instances = instancesByType[typeName] = new Set();
Object.defineProperty(template, "_", {
get: function () {
return renderFn && proxyRenderer;
},
set: function (v) {
renderFn = v;
if (instances.size) {
if (!queue) {
queue = [];
setImmediate(batchUpdate);
}
queue.push(function () {
var newProto = registry._J_(typeName).prototype;
instances.forEach(function (instance) {
if (hasLifecycleChanged(instance.__proto__, newProto)) {
var renderer = instance.R_;
instance.R_ = (input, out) => {
instance.aH_(input, out);
if (instance.onInput) {
input = instance.onInput(input, out) || input;
}
instance.R_ = renderer;
instance.R_(input, out);
};
instance.cr_ = true;
instance.aq_();
instance._z_ = false;
if (instance.ak_) {
instance.ak_.removeAllListeners();
instance.ak_ = null;
}
}
instance.__proto__ = newProto;
instance._H_(
instance.P_, false).
afterInsert(instance.C_);
});
});
}
}
});
return template;
function proxyRenderer() {
return renderFn.apply(this, arguments);
}
};
registry._I_ = function (typeName, id) {
var instances = instancesByType[typeName];
var instance = createComponent(typeName, id);
if (instances) {
instances.add(instance);
instance.once("destroy", function () {
if (!instance.cr_) {
instances.delete(instance);
}
});
}
return instance;
};
function hasLifecycleChanged(oldProto, newProto) {
return (
hasMethodChanged("onCreate") ||
hasMethodChanged("onInput") ||
hasMethodChanged("onRender") ||
hasMethodChanged("onMount"));
function hasMethodChanged(method) {
return (
(oldProto[method] && oldProto[method].toString()) !== (
newProto[method] && newProto[method].toString()));
}
}
function batchUpdate() {
updateManager.aA_(function () {
var pending = queue;
queue = undefined;
for (var i = 0; i < pending.length; i++) {
pending[i]();
}
});
}