UNPKG

marko

Version:

Optimized runtime for Marko templates.

410 lines (409 loc) • 17.8 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const require_control_flow = require("./dom-CiFITSPN.js"); //#region src/common/attr-tag.ts const empty = []; const rest = Symbol("Attribute Tag"); function attrTag(attrs) { attrs[Symbol.iterator] = attrTagIterator; attrs[rest] = empty; return attrs; } function attrTags(first, attrs) { if (first) { if (first[rest] === empty) first[rest] = [attrs]; else first[rest].push(attrs); return first; } return attrTag(attrs); } function* attrTagIterator() { yield this; yield* this[rest]; } //#endregion //#region src/common/constants/load-signal-value.debug.ts const Value = "value"; const Signal = "signal"; //#endregion //#region src/common/compat-meta.ts const SET_SCOPE_REGISTER_ID = "$compat_setScope"; const RENDER_BODY_ID = "$compat_renderBody"; //#endregion //#region src/dom/compat.ts const classIdToBranch = /* @__PURE__ */ new Map(); let classEventResolver; const scopesByRender = /* @__PURE__ */ new WeakMap(); const getRenderScopes = ($global) => { const render = self[$global.runtimeId]?.[$global.renderId]; let scopes = render && scopesByRender.get(render); if (render && !scopes) scopesByRender.set(render, scopes = {}); return scopes; }; const compat = { patchDynamicTag: require_control_flow.patchDynamicTag, queueEffect: require_control_flow.queueEffect, init(warp10Noop) { require_control_flow._resume(SET_SCOPE_REGISTER_ID, (scope) => { getRenderScopes(scope[require_control_flow.Global])[scope["#Id"]] = scope; if (scope.m5c) classIdToBranch.set(scope.m5c, scope); if (classEventResolver) for (const key in scope) { const resolved = classEventResolver(scope[key], scope); if (resolved !== scope[key]) scope[key] = resolved; } }); require_control_flow._resume(RENDER_BODY_ID, warp10Noop); }, setClassEventResolver(fn) { classEventResolver = fn; }, getScope($global, scopeId) { return getRenderScopes($global)?.[scopeId]; }, setRendererId(renderer, id) { renderer["id"] = id; }, isRenderer(renderer) { return renderer[require_control_flow.Clone]; }, getStartNode(branch) { return branch[require_control_flow.StartNode]; }, getEndNode(branch) { return branch[require_control_flow.EndNode]; }, setScopeNodes(branch, startNode, endNode) { branch[require_control_flow.StartNode] = startNode; branch[require_control_flow.EndNode] = endNode; }, runComponentEffects() { if (this.effects) require_control_flow.runEffects(this.effects); }, runComponentDestroy() { if (this.scope) require_control_flow.destroyBranch(this.scope); }, resolveRegistered(value, $global) { if (Array.isArray(value) && typeof value[0] === "string") return require_control_flow.getRegisteredWithScope(value[0], getRenderScopes($global)?.[value[1]]); return value; }, createRenderer(params, clone) { const renderer = require_control_flow._content("", 0, 0, 0, params)(); renderer[require_control_flow.Clone] = (branch) => { const cloned = clone(); branch[require_control_flow.StartNode] = cloned.startNode; branch[require_control_flow.EndNode] = cloned.endNode; }; return renderer; }, render(out, component, renderer, args) { let branch = component.scope; let created = 0; if (!branch && (branch = classIdToBranch.get(component.id))) { component.scope = branch; classIdToBranch.delete(component.id); } if (args[0] && typeof args[0] === "object" && "renderBody" in args[0]) { const input = args[0]; const normalizedInput = args[0] = {}; for (const key in input) normalizedInput[key === "renderBody" ? "content" : key] = input[key]; } component.effects = require_control_flow.prepareEffects(() => { if (!branch) { created = 1; branch = component.scope = require_control_flow.createAndSetupBranch(out.global, renderer, renderer[require_control_flow.Owner], document.body); } renderer[require_control_flow.Params]?.(branch, renderer._ ? args[0] : args); }); if (created) return require_control_flow.toInsertNode(branch[require_control_flow.StartNode], branch[require_control_flow.EndNode]); } }; //#endregion //#region src/dom/template.ts const _template = (id, template, walks, setup, inputSignal) => { const renderer = require_control_flow._content(id, template, walks, setup, inputSignal)(); renderer.mount = mount; renderer._ = renderer; renderer.render = () => { throw new Error(`render() is not implemented for the DOM compilation of a Marko template`); }; return require_control_flow._resume(id, renderer); }; function mount(input = {}, reference, position) { let branch; let parentNode = reference; let nextSibling = null; let { $global } = input; if ($global) { ({$global, ...input} = input); $global = { runtimeId: "M", renderId: "_", ...$global }; if (!String($global.runtimeId).match(/^[_a-z][_a-z0-9]*$/i)) throw new Error(`Invalid runtimeId: "${$global.runtimeId}". The runtimeId must start with a letter or underscore and only contain letters, numbers, and underscores.`); if (!String($global.renderId).match(/^[_a-z][_a-z0-9]*$/i)) throw new Error(`Invalid renderId: "${$global.renderId}". The renderId must start with a letter or underscore and only contain letters, numbers, and underscores.`); } else $global = { runtimeId: "M", renderId: "_" }; switch (position) { case "beforebegin": parentNode = reference.parentNode; nextSibling = reference; break; case "afterbegin": nextSibling = reference.firstChild; break; case "afterend": parentNode = reference.parentNode; nextSibling = reference.nextSibling; break; } let curValue; const args = this[require_control_flow.Params]; const effects = require_control_flow.prepareEffects(() => { branch = require_control_flow.createBranch($global, this, void 0, parentNode); branch[require_control_flow.TagVariable] = (newValue) => { curValue = newValue; }; this[require_control_flow.Setup]?.(branch); args?.(branch, input); }); require_control_flow.insertChildNodes(parentNode, nextSibling, branch[require_control_flow.StartNode], branch[require_control_flow.EndNode]); require_control_flow.runEffects(effects); return { get value() { return curValue; }, set value(newValue) { require_control_flow._var_change(branch, newValue); }, update(newInput = {}) { if (args) { if (newInput.$global) ({$global, ...newInput} = newInput); require_control_flow.runEffects(require_control_flow.prepareEffects(() => { args(branch, newInput); })); } }, destroy() { require_control_flow.removeAndDestroyBranch(branch); } }; } //#endregion //#region src/dom/load.ts function _load_template(id, load) { let pending; const lazyTemplate = _template(id, 0, 0, (branch) => { const awaitCounter = require_control_flow.addAwaitCounter(branch); branch[require_control_flow.Load] ||= /* @__PURE__ */ new Map(); (pending ||= load()).then((renderer) => { Object.assign(lazyTemplate, renderer); require_control_flow.queueAsyncRender(branch, (branch) => insertLoaded(renderer, branch, branch[require_control_flow.StartNode], awaitCounter)); }, loadFailed(branch, awaitCounter)); }, _load_signal(() => (pending ||= load()).then((r) => ({ _: r[require_control_flow.Params] })))); return lazyTemplate; } function _load_setup(nodeAccessor, childScopeAccessor, load) { let pending; let renderer; return (owner) => { const child = owner[childScopeAccessor]; if (renderer) insertLoaded(renderer, child, owner[nodeAccessor]); else { const awaitCounter = require_control_flow.addAwaitCounter(owner); child[require_control_flow.Load] ||= /* @__PURE__ */ new Map(); (pending ||= load()).then((mod) => { renderer = require_control_flow._content("", ...mod._)(); require_control_flow.queueAsyncRender(child, (child) => insertLoaded(renderer, child, owner[nodeAccessor], awaitCounter)); }, loadFailed(child, awaitCounter)); } }; } function insertLoaded(renderer, branch, marker, awaitCounter) { const parent = marker.parentNode, values = branch[require_control_flow.Load], insert = () => { require_control_flow.insertBranchBefore(branch, parent, marker); marker.remove(); awaitCounter?.c(); }; let remaining; require_control_flow.syncGen(branch); renderer[require_control_flow.Clone](branch, parent.namespaceURI); branch[require_control_flow.Load] = 0; if (remaining = values?.size) { const fail = loadFailed(branch, awaitCounter); for (const [promise, entry] of values) promise.then((signal) => { entry[Signal] = signal; if (!--remaining) require_control_flow.queueAsyncRender(branch, (branch) => { require_control_flow.syncGen(branch); renderer[require_control_flow.Setup]?.(branch); values.forEach((e) => e[Signal]._(branch, e[Value])); insert(); }); }, (error) => remaining > 0 && (remaining = 0, fail(error))); } else { require_control_flow.setupBranch(renderer, branch); insert(); } } function loadFailed(scope, awaitCounter) { return (error) => { if (awaitCounter) if (awaitCounter.m) awaitCounter.i = 0; else awaitCounter.c(); require_control_flow.queueAsyncRender(scope, require_control_flow.renderCatch, error); }; } function _load_signal(load) { let pending; let signal; return (scope, value) => { pending ||= load(); if (scope["#Load"] || !("#Load" in scope) && scope["#Gen"] === require_control_flow.runId) (scope[require_control_flow.Load] ||= /* @__PURE__ */ new Map()).set(pending, { [Value]: value }); else if (signal) signal(scope, value); else pending.then((mod) => require_control_flow.queueAsyncRender(scope, signal = mod._, value), () => 0); }; } function _load_visible_trigger(selector, options) { let pending; let el; return (load) => () => (pending ||= new Promise((resolve) => (el = getSelectorOrResolve(selector, resolve)) && new IntersectionObserver((entries, io) => entries.some((entry) => entry.isIntersecting) && resolve(io.disconnect()), options).observe(el))).then(load); } function _load_idle_trigger(options) { let pending; return (load) => () => (pending ||= new Promise((resolve) => (self.requestIdleCallback || resolve)(resolve, options))).then(load); } function _load_event_trigger(event, selector) { let pending; return (load) => () => (pending ||= new Promise((resolve) => getSelectorOrResolve(selector, resolve)?.addEventListener(event, resolve, { once: true }))).then(load); } function _load_media_trigger(query) { let pending; let mql; return (load) => () => (pending ||= new Promise((resolve) => (mql = matchMedia(query)).matches ? resolve() : mql.addEventListener("change", resolve, { once: true }))).then(load); } function _load_race_trigger(...triggers) { const noop = () => Promise.resolve(); let pending; return (load) => () => (pending ||= Promise.race(triggers.map((t) => t(noop)()))).then(load); } function getSelectorOrResolve(selector, resolve) { return document.querySelector(selector) || (console.warn(`A lazy load trigger could not find an element matching "${selector}". The module was loaded immediately.`), resolve()); } //#endregion exports.$signal = require_control_flow.$signal; exports.$signalReset = require_control_flow.$signalReset; exports._assert_hoist = require_control_flow._assert_hoist; exports._assert_init = require_control_flow._assert_init; exports._attr = require_control_flow._attr; exports._attr_class = require_control_flow._attr_class; exports._attr_class_item = require_control_flow._attr_class_item; exports._attr_class_items = require_control_flow._attr_class_items; exports._attr_content = require_control_flow._attr_content; exports._attr_details_open = require_control_flow._attr_details_or_dialog_open; exports._attr_details_open_default = require_control_flow._attr_details_or_dialog_open_default; exports._attr_details_open_script = require_control_flow._attr_details_or_dialog_open_script; exports._attr_dialog_open = require_control_flow._attr_details_or_dialog_open; exports._attr_dialog_open_default = require_control_flow._attr_details_or_dialog_open_default; exports._attr_dialog_open_script = require_control_flow._attr_details_or_dialog_open_script; exports._attr_input_checked = require_control_flow._attr_input_checked; exports._attr_input_checkedValue = require_control_flow._attr_input_checkedValue; exports._attr_input_checkedValue_default = require_control_flow._attr_input_checkedValue_default; exports._attr_input_checkedValue_script = require_control_flow._attr_input_checkedValue_script; exports._attr_input_checked_default = require_control_flow._attr_input_checked_default; exports._attr_input_checked_script = require_control_flow._attr_input_checked_script; exports._attr_input_value = require_control_flow._attr_input_value; exports._attr_input_value_attribute_default = require_control_flow._attr_input_value_attribute_default; exports._attr_input_value_default = require_control_flow._attr_input_value_default; exports._attr_input_value_dynamic_default = require_control_flow._attr_input_value_dynamic_default; exports._attr_input_value_script = require_control_flow._attr_input_value_script; exports._attr_nonce = require_control_flow._attr_nonce; exports._attr_select_value = require_control_flow._attr_select_value; exports._attr_select_value_default = require_control_flow._attr_select_value_default; exports._attr_select_value_script = require_control_flow._attr_select_value_script; exports._attr_style = require_control_flow._attr_style; exports._attr_style_item = require_control_flow._attr_style_item; exports._attr_style_items = require_control_flow._attr_style_items; exports._attr_textarea_value = require_control_flow._attr_input_value; exports._attr_textarea_value_default = require_control_flow._attr_input_value_default; exports._attr_textarea_value_script = require_control_flow._attr_input_value_script; exports._attrs = require_control_flow._attrs; exports._attrs_content = require_control_flow._attrs_content; exports._attrs_partial = require_control_flow._attrs_partial; exports._attrs_partial_content = require_control_flow._attrs_partial_content; exports._attrs_script = require_control_flow._attrs_script; exports._await_content = require_control_flow._await_content; exports._await_promise = require_control_flow._await_promise; exports._call = require_control_flow._call; exports._child_setup = require_control_flow._child_setup; exports._closure = require_control_flow._closure; exports._closure_get = require_control_flow._closure_get; exports._const = require_control_flow._const; exports._content = require_control_flow._content; exports._content_closures = require_control_flow._content_closures; exports._content_resume = require_control_flow._content_resume; exports._controllable_input = require_control_flow._controllable_input; exports._controllable_open = require_control_flow._controllable_open; exports._controllable_select = require_control_flow._controllable_select; exports._controllable_textarea = require_control_flow._controllable_textarea; Object.defineProperty(exports, "_dynamic_tag", { enumerable: true, get: function() { return require_control_flow._dynamic_tag; } }); exports._dynamic_tag_content = require_control_flow._dynamic_tag_content; exports._el = require_control_flow._el; exports._el_read = require_control_flow._el_read; exports._for_closure = require_control_flow._for_closure; exports._for_in = require_control_flow._for_in; exports._for_of = require_control_flow._for_of; exports._for_selector = require_control_flow._for_selector; exports._for_to = require_control_flow._for_to; exports._for_until = require_control_flow._for_until; exports._hoist = require_control_flow._hoist; exports._hoist_resume = require_control_flow._hoist_resume; exports._html = require_control_flow._html; exports._id = require_control_flow._id; exports._if = require_control_flow._if; exports._if_closure = require_control_flow._if_closure; exports._let = require_control_flow._let; exports._let_change = require_control_flow._let_change; exports._lifecycle = require_control_flow._lifecycle; exports._load_event_trigger = _load_event_trigger; exports._load_idle_trigger = _load_idle_trigger; exports._load_media_trigger = _load_media_trigger; exports._load_race_trigger = _load_race_trigger; exports._load_setup = _load_setup; exports._load_signal = _load_signal; exports._load_template = _load_template; exports._load_visible_trigger = _load_visible_trigger; exports._on = require_control_flow._on; exports._or = require_control_flow._or; exports._resume = require_control_flow._resume; exports._resume_dynamic_tag = require_control_flow._resume_dynamic_tag; exports._return = require_control_flow._return; exports._return_change = require_control_flow._return_change; exports._script = require_control_flow._script; exports._show = require_control_flow._show; exports._style_rule_item = require_control_flow._style_rule_item; exports._style_shell = require_control_flow._style_shell; exports._template = _template; exports._text = require_control_flow._text; exports._text_content = require_control_flow._text_content; exports._to_text = require_control_flow._to_text; exports._try = require_control_flow._try; exports._var = require_control_flow._var; exports._var_change = require_control_flow._var_change; exports._var_resume = require_control_flow._var_resume; exports.attrTag = attrTag; exports.attrTags = attrTags; exports.compat = compat; exports.forIn = require_control_flow.forIn; exports.forOf = require_control_flow.forOf; exports.forTo = require_control_flow.forTo; exports.forUntil = require_control_flow.forUntil; exports.init = require_control_flow.init; exports.initEmbedded = require_control_flow.initEmbedded; exports.ready = require_control_flow.ready; exports.run = require_control_flow.run;