From 622d328858bc857e8622d0b14105726641ab66d5 Mon Sep 17 00:00:00 2001 From: dpiercey Date: Fri, 31 Jan 2025 10:00:06 -0700 Subject: [PATCH] chore: minor refactoring and type fixes --- .changeset/loud-llamas-warn.md | 6 + .sizes.json | 36 +-- .sizes/dom.js | 216 +++++++++--------- .sizes/name-cache.json | 2 +- packages/runtime-tags/index.d.ts | 2 +- packages/runtime-tags/src/common/types.ts | 6 +- packages/runtime-tags/src/dom/compat.ts | 46 ++-- packages/runtime-tags/src/dom/control-flow.ts | 2 +- packages/runtime-tags/src/dom/dom.ts | 38 +-- packages/runtime-tags/src/dom/parse-html.ts | 3 +- packages/runtime-tags/src/dom/reconcile.ts | 2 +- packages/runtime-tags/src/dom/resume.ts | 2 +- packages/runtime-tags/src/dom/scope.ts | 13 +- packages/runtime-tags/src/dom/template.ts | 2 +- packages/runtime-tags/src/dom/walker.ts | 16 +- 15 files changed, 197 insertions(+), 195 deletions(-) create mode 100644 .changeset/loud-llamas-warn.md diff --git a/.changeset/loud-llamas-warn.md b/.changeset/loud-llamas-warn.md new file mode 100644 index 0000000000..857b868bd3 --- /dev/null +++ b/.changeset/loud-llamas-warn.md @@ -0,0 +1,6 @@ +--- +"@marko/translator-interop-class-tags": patch +"@marko/runtime-tags": patch +--- + +Minor refactoring and cleanup. diff --git a/.sizes.json b/.sizes.json index b0cafdd0cf..6dd9f8f2a7 100644 --- a/.sizes.json +++ b/.sizes.json @@ -7,8 +7,8 @@ { "name": "*", "total": { - "min": 18067, - "brotli": 6621 + "min": 17998, + "brotli": 6598 } }, { @@ -18,12 +18,12 @@ "brotli": 144 }, "runtime": { - "min": 4178, - "brotli": 1805 + "min": 4174, + "brotli": 1799 }, "total": { - "min": 4367, - "brotli": 1949 + "min": 4363, + "brotli": 1943 } }, { @@ -33,12 +33,12 @@ "brotli": 100 }, "runtime": { - "min": 3622, - "brotli": 1625 + "min": 3626, + "brotli": 1631 }, "total": { - "min": 3733, - "brotli": 1725 + "min": 3737, + "brotli": 1731 } }, { @@ -48,12 +48,12 @@ "brotli": 541 }, "runtime": { - "min": 7868, - "brotli": 3241 + "min": 7863, + "brotli": 3245 }, "total": { - "min": 9008, - "brotli": 3782 + "min": 9003, + "brotli": 3786 } }, { @@ -63,12 +63,12 @@ "brotli": 478 }, "runtime": { - "min": 8903, - "brotli": 3618 + "min": 8898, + "brotli": 3619 }, "total": { - "min": 9851, - "brotli": 4096 + "min": 9846, + "brotli": 4097 } } ] diff --git a/.sizes/dom.js b/.sizes/dom.js index f18a94d8a4..f436d03366 100644 --- a/.sizes/dom.js +++ b/.sizes/dom.js @@ -1,4 +1,4 @@ -// size: 18067 (min) 6621 (brotli) +// size: 17998 (min) 6598 (brotli) var empty = [], rest = Symbol(); function attrTag(attrs2) { @@ -48,42 +48,6 @@ function flushAndWaitFrame() { function triggerMacroTask() { port2.postMessage(0); } -var pendingScopes = []; -function createScope($global) { - let scope = { f: 1, $global: $global }; - return pendingScopes.push(scope), scope; -} -var emptyBranch = createScope({}); -function getEmptyBranch(marker) { - return (emptyBranch.a = emptyBranch.c = marker), emptyBranch; -} -function destroyBranch(branch) { - branch.n?.k?.delete(branch), destroyNestedBranches(branch); -} -function destroyNestedBranches(branch) { - (branch.z = 1), - branch.k?.forEach(destroyNestedBranches), - branch.A?.forEach((scope) => { - for (let id in scope.g) scope.g[id]?.abort(); - }); -} -function removeAndDestroyBranch(branch) { - destroyBranch(branch); - let current = branch.a, - stop = branch.c.nextSibling; - for (; current !== stop; ) { - let next = current.nextSibling; - current.remove(), (current = next); - } -} -function insertBranchBefore(branch, parent, nextSibling) { - let current = branch.a, - stop = branch.c.nextSibling; - for (; current !== stop; ) { - let next = current.nextSibling; - parent.insertBefore(current, nextSibling), (current = next); - } -} function stringifyClassObject(name, value2) { return value2 ? name : ""; } @@ -162,23 +126,23 @@ function stripSpacesAndPunctuation(str) { } var registeredValues = {}, Render = class { - o = []; - p = {}; - B = { _: registeredValues }; + n = []; + o = {}; + z = { _: registeredValues }; constructor(renders, runtimeId, renderId) { - (this.C = renders), - (this.D = runtimeId), - (this.q = renderId), - (this.s = renders[renderId]), - this.t(); + (this.A = renders), + (this.B = runtimeId), + (this.p = renderId), + (this.q = renders[renderId]), + this.s(); } w() { - this.s.w(), this.t(); + this.q.w(), this.s(); } - t() { - let data2 = this.s, - serializeContext = this.B, - scopeLookup = this.p, + s() { + let data2 = this.q, + serializeContext = this.z, + scopeLookup = this.o, visits = data2.v, branchIds = new Set(), parentBranchIds = new Map(); @@ -217,7 +181,7 @@ var registeredValues = {}, else if ("[" === token) this.e && (dataIndex && branchEnd(this.e, visit, visit), - this.o.push(this.e)), + this.n.push(this.e)), (this.e = scopeId), (scope.a = visit); else if ("]" === token) { @@ -225,7 +189,7 @@ var registeredValues = {}, let curParent = visit.parentNode, startNode = branchEnd(this.e, visit, visit).a; curParent !== startNode.parentNode && curParent.prepend(startNode), - (this.e = this.o.pop()); + (this.e = this.n.pop()); } else if ("|" === token) { let next = data3.indexOf(" "), curNode = (scope[~next ? data3.slice(0, next) : data3] = visit); @@ -254,8 +218,8 @@ var registeredValues = {}, { $global: $global } = scopeLookup; $global || ((scopeLookup.$global = $global = scopes.$ || {}), - ($global.runtimeId = this.D), - ($global.renderId = this.q)); + ($global.runtimeId = this.B), + ($global.renderId = this.p)); for (let scopeId in scopes) if ("$" !== scopeId) { let scope = scopes[scopeId], @@ -270,16 +234,16 @@ var registeredValues = {}, ) { let branch = scope, parentBranch = branch.b; - (branch.h = +scopeId), + (branch.f = +scopeId), (scope.b = branch), parentBranch && - ((branch.n = parentBranch), + ((branch.t = parentBranch), (parentBranch.k ||= new Set()).add(branch)); } } } else i === len || "string" != typeof resumes[i] - ? delete this.C[this.q] + ? delete this.A[this.p] : registeredValues[resumes[i++]]( scopeLookup[resumeData], scopeLookup[resumeData], @@ -322,7 +286,7 @@ function init(runtimeId = "M") { }); } function registerSubscriber(id, signal) { - return register(id, signal.E), signal; + return register(id, signal.C), signal; } function nodeRef(id, key) { return register(id, (scope) => () => scope[key]); @@ -582,8 +546,7 @@ function normalizeBoolProp(value2) { function toValueProp(it) { return it.value; } -var fallback = new Text(), - parser = document.createElement("template"); +var parser = document.createElement("template"); function parseHTML(html2) { return (parser.innerHTML = html2), parser.content; } @@ -754,20 +717,14 @@ function attrsEvents(scope, nodeAccessor) { } for (let name in events) on(el, name, events[name]); } -function html(scope, value2, index) { - let firstChild = scope[index], - lastChild = scope[index + "-"] || firstChild, - parentNode = firstChild.parentNode, - afterReference = lastChild.nextSibling, +function html(scope, value2, accessor) { + let firstChild = scope[accessor], + lastChild = scope[accessor + "-"] || firstChild, newContent = parseHTML(value2 || 0 === value2 ? value2 + "" : ""); - (scope[index] = newContent.firstChild), - (scope[index + "-"] = newContent.lastChild), - parentNode.insertBefore(newContent, firstChild); - let current = firstChild; - for (; current !== afterReference; ) { - let next = current.nextSibling; - current.remove(), (current = next); - } + (scope[accessor] = newContent.firstChild), + (scope[accessor + "-"] = newContent.lastChild), + firstChild.parentNode.insertBefore(newContent, firstChild), + removeChildNodes(firstChild, lastChild); } function props(scope, nodeIndex, index) { let nextProps = scope[index], @@ -793,15 +750,53 @@ function lifecycle(scope, index, thisObj) { (getAbortSignal(scope, "-" + index).onabort = () => thisObj.onDestroy?.())); } +function removeChildNodes(startNode, endNode) { + let stop = endNode.nextSibling, + current = startNode; + for (; current !== stop; ) { + let next = current.nextSibling; + current.remove(), (current = next); + } +} +var pendingScopes = []; +function createScope($global) { + let scope = { g: 1, $global: $global }; + return pendingScopes.push(scope), scope; +} +var emptyBranch = createScope({}); +function getEmptyBranch(marker) { + return (emptyBranch.a = emptyBranch.c = marker), emptyBranch; +} +function destroyBranch(branch) { + branch.t?.k?.delete(branch), destroyNestedBranches(branch); +} +function destroyNestedBranches(branch) { + (branch.D = 1), + branch.k?.forEach(destroyNestedBranches), + branch.E?.forEach((scope) => { + for (let id in scope.h) scope.h[id]?.abort(); + }); +} +function removeAndDestroyBranch(branch) { + destroyBranch(branch), removeChildNodes(branch.a, branch.c); +} +function insertBranchBefore(branch, parentNode, nextSibling) { + let current = branch.a, + stop = branch.c.nextSibling; + for (; current !== stop; ) { + let next = current.nextSibling; + parentNode.insertBefore(current, nextSibling), (current = next); + } +} var walker = document.createTreeWalker(document); function trimWalkString(walkString) { let end = walkString.length; for (; walkString.charCodeAt(--end) > 47; ); return walkString.slice(0, end + 1); } -function walk(startNode, walkCodes, scope) { +function walk(startNode, walkCodes, branch) { (walker.currentNode = startNode), - walkInternal(walkCodes, scope, 0), + walkInternal(walkCodes, branch, 0), (walker.currentNode = document); } function walkInternal(walkCodes, scope, currentWalkIndex) { @@ -830,8 +825,7 @@ function walkInternal(walkCodes, scope, currentWalkIndex) { let childScope = (scope[currentScopeIndex++] = createScope( scope.$global, )); - (childScope.a = walker.currentNode), - (childScope.b = scope.b), + (childScope.b = scope.b), (currentWalkIndex = walkInternal( walkCodes, childScope, @@ -880,10 +874,10 @@ function createBranch($global, ownerScope, parentScope) { (branch._ = ownerScope), (branch.b = branch), parentBranch - ? ((branch.h = parentBranch.h + 1), - (branch.n = parentBranch), + ? ((branch.f = parentBranch.f + 1), + (branch.t = parentBranch), (parentBranch.k ||= new Set()).add(branch)) - : (branch.h = 1), + : (branch.f = 1), branch ); } @@ -951,7 +945,7 @@ function _clone() { let fragment = new DocumentFragment(); return fragment.appendChild(content), fragment; } - return fallback; + return new Text(); })(this.G)).cloneNode(!0); } var conditional = function (nodeAccessor, fn, getIntersection) { @@ -1334,7 +1328,7 @@ function loopClosure(ownerLoopNodeAccessor, fn, getIntersection) { []; if (loopScopes !== emptyMarkerArray) for (let scope of loopScopes) - scope.f || queueSource(scope, signal, value2); + scope.g || queueSource(scope, signal, value2); }; return (helperSignal._ = signal), helperSignal; } @@ -1350,7 +1344,7 @@ function conditionalClosure( helperSignal = (scope, value2) => { let conditionalScope = scope[scopeAccessor]; conditionalScope && - !conditionalScope.f && + !conditionalScope.g && scope[rendererAccessor]?.j === getRenderer().j && queueSource(conditionalScope, signal, value2); }; @@ -1368,7 +1362,7 @@ function dynamicClosure( let subscribers = ownerScope[ownerSubscribersAccessor]; if (subscribers) for (let subscriber of subscribers) - subscriber.f || queueSource(subscriber, _signal, value2); + subscriber.g || queueSource(subscriber, _signal, value2); }, subscribe = (scope) => { (getOwnerScope(scope)[ownerSubscribersAccessor] ||= new Set()).add(scope), @@ -1380,7 +1374,7 @@ function dynamicClosure( (helperSignal._ = (scope, value2) => { _signal(scope, value2), subscribe(scope); }), - (helperSignal.E = subscribe), + (helperSignal.C = subscribe), helperSignal ); } @@ -1500,10 +1494,10 @@ function runRenders() { } pendingRenders[i] = item; } - render.m.b?.z || render.I(render.m, render.J); + render.m.b?.D || render.I(render.m, render.J); } !(function () { - for (let scope of pendingScopes) scope.f = 0; + for (let scope of pendingScopes) scope.g = 0; pendingScopes = []; })(); } @@ -1511,22 +1505,22 @@ function comparePendingRenders(a, b) { return getBranchDepth(a) - getBranchDepth(b) || a.y - b.y; } function getBranchDepth(render) { - return render.m.b?.h || 0; + return render.m.b?.f || 0; } function resetAbortSignal(scope, id) { - let ctrl = scope.g?.[id]; - ctrl && (queueEffect(ctrl, abort), (scope.g[id] = void 0)); + let ctrl = scope.h?.[id]; + ctrl && (queueEffect(ctrl, abort), (scope.h[id] = void 0)); } function getAbortSignal(scope, id) { return ( - scope.b && (scope.b.A ||= new Set()).add(scope), - ((scope.g ||= {})[id] ||= new AbortController()).signal + scope.b && (scope.b.E ||= new Set()).add(scope), + ((scope.h ||= {})[id] ||= new AbortController()).signal ); } function abort(ctrl) { ctrl.abort(); } -var classIdToScope = new Map(), +var classIdToBranch = new Map(), compat = { patchConditionals: function (fn) { (conditional = fn(conditional)), @@ -1534,8 +1528,8 @@ var classIdToScope = new Map(), }, queueEffect: queueEffect, init() { - register("$C_s", (scope) => { - classIdToScope.set(scope.m5c, scope); + register("$C_s", (branch) => { + classIdToBranch.set(branch.m5c, branch); }); }, registerRenderer(fn) { @@ -1543,9 +1537,9 @@ var classIdToScope = new Map(), }, isOp: (value2) => value2 === MARK || value2 === CLEAN || value2 === DIRTY, isRenderer: (renderer) => void 0 !== renderer.l, - getStartNode: (scope) => scope.a, - setScopeNodes(scope, startNode, endNode) { - (scope.a = startNode), (scope.c = endNode); + getStartNode: (branch) => branch.a, + setScopeNodes(branch, startNode, endNode) { + (branch.a = startNode), (branch.c = endNode); }, runComponentEffects() { runEffects(this.effects); @@ -1566,7 +1560,7 @@ var classIdToScope = new Map(), 2 === value2.length && window[runtimeId]?.[ "s" === componentIdPrefix ? "_" : componentIdPrefix - ]?.p[value2[1]], + ]?.o[value2[1]], ) : value2, createRenderer(setup, clone, args) { @@ -1574,11 +1568,11 @@ var classIdToScope = new Map(), return (renderer.l = clone), renderer; }, render(out, component, renderer, args) { - let scope = component.scope; - scope || - ((scope = classIdToScope.get(component.id)), - scope && - ((component.scope = scope), classIdToScope.delete(component.id))); + let branch = component.scope; + branch || + ((branch = classIdToBranch.get(component.id)), + branch && + ((component.scope = branch), classIdToBranch.delete(component.id))); let applyArgs = renderer.d || noop, existing = !1; if ("object" == typeof args[0] && "renderBody" in args[0]) { @@ -1589,16 +1583,16 @@ var classIdToScope = new Map(), } if ( ((component.effects = prepareEffects(() => { - scope - ? (applyArgs(scope, MARK), (existing = !0)) - : ((scope = component.scope = createScope(out.global)), - (scope._ = renderer.u), - initBranch(renderer, scope)), - applyArgs(scope, args); + branch + ? (applyArgs(branch, MARK), (existing = !0)) + : ((branch = component.scope = createScope(out.global)), + (branch._ = renderer.u), + initBranch(renderer, branch)), + applyArgs(branch, args); })), !existing) ) - return scope.a === scope.c ? scope.a : scope.a.parentNode; + return branch.a === branch.c ? branch.a : branch.a.parentNode; }, }; function noop() {} diff --git a/.sizes/name-cache.json b/.sizes/name-cache.json index 8416272f3e..051e6cddbf 100644 --- a/.sizes/name-cache.json +++ b/.sizes/name-cache.json @@ -1 +1 @@ -{"vars":{"props":{"$empty":"e","$rest":"t","$attrTag":"n","$attrTags":"r","$attrTagIterator":"i","$forIn":"l","$forOf":"o","$forTo":"f","$isScheduled":"u","$port2":"a","$flushAndWaitFrame":"c","$triggerMacroTask":"s","$createScope":"d","$emptyScope":"h","$getEmptyScope":"g","$destroyScope":"p","$_destroyScope":"v","$onDestroy":"b","$removeAndDestroyScope":"m","$insertBefore":"y","$registeredValues":"k","$Render":"w","$isResuming":"C","$register":"A","$registerBoundSignal":"S","$init":"N","$registerSubscriber":"x","$nodeRef":"$","$MARK":"M","$CLEAN":"E","$DIRTY":"I","$state":"T","$value":"_","$accessorId":"O","$intersection":"B","$defaultGetOwnerScope":"V","$closure":"j","$dynamicClosure":"R","$childClosures":"q","$dynamicSubscribers":"D","$setTagVar":"P","$tagVarSignal":"W","$setTagVarChange":"L","$tagVarSignalChange":"z","$renderBodyClosures":"F","$tagIdsByGlobal":"U","$nextTagId":"G","$inChild":"J","$intersections":"X","$effect":"Z","$pendingSignals":"H","$pendingEffects":"K","$rendering":"Q","$queueEffect":"Y","$run":"ee","$prepareEffects":"te","$runEffects":"ne","$runSignals":"re","$resetAbortSignal":"ie","$getAbortSignal":"le","$stringifyClassObject":"oe","$NON_DIMENSIONAL":"fe","$stringifyStyleObject":"ue","$toDelimitedString":"ae","$isEventHandler":"ce","$getEventHandlerName":"se","$normalizeDynamicRenderer":"de","$elementHandlersByEvent":"he","$defaultDelegator":"ge","$on":"pe","$createDelegator":"ve","$handleDelegated":"be","$stripSpacesAndPunctuation":"me","$controllable_input_checked":"ye","$controllable_input_checked_effect":"ke","$controllable_input_checkedValue":"we","$controllable_input_checkedValue_effect":"Ce","$controllable_input_value":"Ae","$controllable_input_value_effect":"Se","$controllable_select_value":"Ne","$controllable_select_value_effect":"xe","$setSelectOptions":"$e","$controllable_detailsOrDialog_open":"Me","$controllable_detailsOrDialog_open_effect":"Ee","$inputType":"Ie","$setValueAndUpdateSelection":"Te","$setCheckboxValue":"_e","$delegateFormControl":"Oe","$formChangeHandlers":"Be","$syncControllable":"Ve","$onFormChange":"je","$onFormReset":"Re","$hasValueChanged":"qe","$hasCheckboxChanged":"De","$hasSelectChanged":"Pe","$hasFormElementChanged":"We","$normalizeStrProp":"Le","$normalizeBoolProp":"ze","$toValueProp":"Fe","$fallback":"Ue","$parser":"Ge","$parseHTML":"Je","$attr":"Xe","$setAttribute":"Ze","$classAttr":"He","$styleAttr":"Ke","$data":"Qe","$attrs":"Ye","$hasAttrAlias":"et","$partialAttrs":"tt","$attrsInternal":"nt","$attrsEvents":"rt","$html":"it","$props":"lt","$normalizeAttrValue":"ot","$lifecycle":"ft","$walker":"ut","$trimWalkString":"at","$walk":"ct","$walkInternal":"st","$createScopeWithRenderer":"dt","$createScopeWithTagNameOrRenderer":"ht","$initRenderer":"gt","$dynamicTagAttrs":"pt","$createRendererWithOwner":"vt","$createRenderer":"bt","$_clone":"mt","$conditional":"yt","$inConditionalScope":"kt","$conditionalOnlyChild":"wt","$setConditionalRendererOnlyChild":"Ct","$emptyMarkerMap":"At","$emptyMarkerArray":"St","$emptyMap":"Nt","$emptyArray":"xt","$loopOf":"$t","$loopIn":"Mt","$loopTo":"Et","$loop":"It","$inLoopScope":"Tt","$bySecondArg":"_t","$byFirstArg":"Ot","$isDifferentRenderer":"Bt","$classIdToScope":"Vt","$compat":"jt","$noop":"Rt","$createTemplate":"qt","$mount":"Dt","$parseHTMLOrSingleNode":"Wt","$marker":"Ft","$_clickCount_effect":"Qt","$_clickCount":"Yt","$_setup_":"zt","$_expr_comment_comments_id$ifBody":"ss","$_id$ifBody":"as","$_comment_comments$ifBody":"ts","$_ifBody":"ns","$_expr_input_path_i$forBody":"os","$_if$forBody":"cs","$_open$forBody_effect":"is","$_open$forBody":"ms","$_id$forBody":"ls","$_i$forBody":"us","$_comment_comments$forBody":"es","$_comment_text$forBody":"ds","$_comment$forBody":"rs","$_params_2$forBody":"bs","$_input_path$forBody":"ps","$_for":"hs","$_input_path_":"vs","$_input_comments_":"fs","$_input_$1":"js","$_input_":"ks","$_params__":"Ss","$noop2":"Pt","$textContent":"Lt","$normalizeString":"Ut","$contentClosures":"Gt","$_expr_comment_comments_id$if_content":"Zs","$_id$if_content":"$s","$_comment_comments$if_content":"_s","$_if_content":"gs","$_expr_input_path_i$for_content":"ws","$_if$for_content":"xs","$_open$for_content_effect":"Bs","$_open$for_content":"Ds","$_id$for_content":"Es","$_i$for_content":"Hs","$_comment_comments$for_content":"Xs","$_comment_text$for_content":"qs","$_comment$for_content":"ys","$_params_2$for_content":"zs","$_input_path$for_content":"As","$pendingSignal":"Ht","$scopeIsConnected":"Jt","$sortScopeByDOMPosition":"Xt","$ownerStartNode":"Zt","$queueSource":"Kt","$pendingScopes":"en","$loopClosure":"tn","$conditionalClosure":"nn","$queueRender":"rn","$abort":"on","$destroyBranch":"ln","$removeAndDestroyBranch":"un","$createBranchScopeWithRenderer":"fn","$createBranchScopeWithTagNameOrRenderer":"an","$createBranch":"cn","$pendingRender":"sn","$runRenders":"dn","$comparePendingRenders":"hn","$doc":"gn","$pendingRenders":"pn","$getBranchId":"bn","$getBranchDepth":"vn","$initBranch":"yn","$emptyBranch":"mn","$getEmptyBranch":"kn","$insertBranchBefore":"Cn","$destroyNestedBranches":"wn"}}} \ No newline at end of file +{"vars":{"props":{"$empty":"e","$rest":"t","$attrTag":"n","$attrTags":"r","$attrTagIterator":"i","$forIn":"l","$forOf":"o","$forTo":"f","$isScheduled":"u","$port2":"a","$flushAndWaitFrame":"c","$triggerMacroTask":"s","$createScope":"d","$emptyScope":"h","$getEmptyScope":"g","$destroyScope":"p","$_destroyScope":"v","$onDestroy":"b","$removeAndDestroyScope":"m","$insertBefore":"y","$registeredValues":"k","$Render":"w","$isResuming":"C","$register":"A","$registerBoundSignal":"S","$init":"N","$registerSubscriber":"x","$nodeRef":"$","$MARK":"M","$CLEAN":"E","$DIRTY":"I","$state":"T","$value":"_","$accessorId":"O","$intersection":"B","$defaultGetOwnerScope":"V","$closure":"j","$dynamicClosure":"R","$childClosures":"q","$dynamicSubscribers":"D","$setTagVar":"P","$tagVarSignal":"W","$setTagVarChange":"L","$tagVarSignalChange":"z","$renderBodyClosures":"F","$tagIdsByGlobal":"U","$nextTagId":"G","$inChild":"J","$intersections":"X","$effect":"Z","$pendingSignals":"H","$pendingEffects":"K","$rendering":"Q","$queueEffect":"Y","$run":"ee","$prepareEffects":"te","$runEffects":"ne","$runSignals":"re","$resetAbortSignal":"ie","$getAbortSignal":"le","$stringifyClassObject":"oe","$NON_DIMENSIONAL":"fe","$stringifyStyleObject":"ue","$toDelimitedString":"ae","$isEventHandler":"ce","$getEventHandlerName":"se","$normalizeDynamicRenderer":"de","$elementHandlersByEvent":"he","$defaultDelegator":"ge","$on":"pe","$createDelegator":"ve","$handleDelegated":"be","$stripSpacesAndPunctuation":"me","$controllable_input_checked":"ye","$controllable_input_checked_effect":"ke","$controllable_input_checkedValue":"we","$controllable_input_checkedValue_effect":"Ce","$controllable_input_value":"Ae","$controllable_input_value_effect":"Se","$controllable_select_value":"Ne","$controllable_select_value_effect":"xe","$setSelectOptions":"$e","$controllable_detailsOrDialog_open":"Me","$controllable_detailsOrDialog_open_effect":"Ee","$inputType":"Ie","$setValueAndUpdateSelection":"Te","$setCheckboxValue":"_e","$delegateFormControl":"Oe","$formChangeHandlers":"Be","$syncControllable":"Ve","$onFormChange":"je","$onFormReset":"Re","$hasValueChanged":"qe","$hasCheckboxChanged":"De","$hasSelectChanged":"Pe","$hasFormElementChanged":"We","$normalizeStrProp":"Le","$normalizeBoolProp":"ze","$toValueProp":"Fe","$fallback":"Ue","$parser":"Ge","$parseHTML":"Je","$attr":"Xe","$setAttribute":"Ze","$classAttr":"He","$styleAttr":"Ke","$data":"Qe","$attrs":"Ye","$hasAttrAlias":"et","$partialAttrs":"tt","$attrsInternal":"nt","$attrsEvents":"rt","$html":"it","$props":"lt","$normalizeAttrValue":"ot","$lifecycle":"ft","$walker":"ut","$trimWalkString":"at","$walk":"ct","$walkInternal":"st","$createScopeWithRenderer":"dt","$createScopeWithTagNameOrRenderer":"ht","$initRenderer":"gt","$dynamicTagAttrs":"pt","$createRendererWithOwner":"vt","$createRenderer":"bt","$_clone":"mt","$conditional":"yt","$inConditionalScope":"kt","$conditionalOnlyChild":"wt","$setConditionalRendererOnlyChild":"Ct","$emptyMarkerMap":"At","$emptyMarkerArray":"St","$emptyMap":"Nt","$emptyArray":"xt","$loopOf":"$t","$loopIn":"Mt","$loopTo":"Et","$loop":"It","$inLoopScope":"Tt","$bySecondArg":"_t","$byFirstArg":"Ot","$isDifferentRenderer":"Bt","$classIdToScope":"Vt","$compat":"jt","$noop":"Rt","$createTemplate":"qt","$mount":"Dt","$parseHTMLOrSingleNode":"Wt","$marker":"Ft","$_clickCount_effect":"Qt","$_clickCount":"Yt","$_setup_":"zt","$_expr_comment_comments_id$ifBody":"ss","$_id$ifBody":"as","$_comment_comments$ifBody":"ts","$_ifBody":"ns","$_expr_input_path_i$forBody":"os","$_if$forBody":"cs","$_open$forBody_effect":"is","$_open$forBody":"ms","$_id$forBody":"ls","$_i$forBody":"us","$_comment_comments$forBody":"es","$_comment_text$forBody":"ds","$_comment$forBody":"rs","$_params_2$forBody":"bs","$_input_path$forBody":"ps","$_for":"hs","$_input_path_":"vs","$_input_comments_":"fs","$_input_$1":"js","$_input_":"ks","$_params__":"Ss","$noop2":"Pt","$textContent":"Lt","$normalizeString":"Ut","$contentClosures":"Gt","$_expr_comment_comments_id$if_content":"Zs","$_id$if_content":"$s","$_comment_comments$if_content":"_s","$_if_content":"gs","$_expr_input_path_i$for_content":"ws","$_if$for_content":"xs","$_open$for_content_effect":"Bs","$_open$for_content":"Ds","$_id$for_content":"Es","$_i$for_content":"Hs","$_comment_comments$for_content":"Xs","$_comment_text$for_content":"qs","$_comment$for_content":"ys","$_params_2$for_content":"zs","$_input_path$for_content":"As","$pendingSignal":"Ht","$scopeIsConnected":"Jt","$sortScopeByDOMPosition":"Xt","$ownerStartNode":"Zt","$queueSource":"Kt","$pendingScopes":"en","$loopClosure":"tn","$conditionalClosure":"nn","$queueRender":"rn","$abort":"on","$destroyBranch":"ln","$removeAndDestroyBranch":"un","$createBranchScopeWithRenderer":"fn","$createBranchScopeWithTagNameOrRenderer":"an","$createBranch":"cn","$pendingRender":"sn","$runRenders":"dn","$comparePendingRenders":"hn","$doc":"gn","$pendingRenders":"pn","$getBranchId":"bn","$getBranchDepth":"vn","$initBranch":"yn","$emptyBranch":"mn","$getEmptyBranch":"kn","$insertBranchBefore":"Cn","$destroyNestedBranches":"wn","$removeChildNodes":"An","$classIdToBranch":"Sn"}}} \ No newline at end of file diff --git a/packages/runtime-tags/index.d.ts b/packages/runtime-tags/index.d.ts index c1ce982678..b7eb136698 100644 --- a/packages/runtime-tags/index.d.ts +++ b/packages/runtime-tags/index.d.ts @@ -82,7 +82,7 @@ declare global { /** Render and attach the template to a DOM node. */ abstract mount( input: Marko.TemplateInput, - reference: ParentNode & Node, + reference: Node, position?: "afterbegin" | "afterend" | "beforebegin" | "beforeend", ): { update(input: Marko.TemplateInput): void; diff --git a/packages/runtime-tags/src/common/types.ts b/packages/runtime-tags/src/common/types.ts index f7204a0de4..139087ab6b 100644 --- a/packages/runtime-tags/src/common/types.ts +++ b/packages/runtime-tags/src/common/types.ts @@ -2,6 +2,8 @@ import type { Renderer as ClientRenderer } from "../dom/renderer"; export type Falsy = undefined | null | false | 0 | ""; export type CommentWalker = TreeWalker & Record; export interface BranchScope extends Scope { + ___startNode: ChildNode; + ___endNode: ChildNode; ___parentBranch: BranchScope | undefined; ___branchDepth: number; ___destroyed: 1 | undefined; @@ -12,8 +14,6 @@ export interface Scope { $global: Record; _: Scope | undefined; ___args: unknown; - ___startNode: Node & ChildNode; - ___endNode: Node & ChildNode; ___pending: 1 | 0 | undefined; ___renderer: ClientRenderer | undefined; ___abortControllers: @@ -111,7 +111,7 @@ export interface TemplateInput extends Input { export interface Template { mount( input: Input, - reference: ParentNode & Node, + reference: Node, position?: InsertPosition, ): TemplateInstance; render(input?: Input): RenderResult; diff --git a/packages/runtime-tags/src/dom/compat.ts b/packages/runtime-tags/src/dom/compat.ts index a03f19b2c6..ecf6cb37f5 100644 --- a/packages/runtime-tags/src/dom/compat.ts +++ b/packages/runtime-tags/src/dom/compat.ts @@ -10,14 +10,14 @@ import { createRenderer, initBranch, type Renderer } from "./renderer"; import { getRegisteredWithScope, register } from "./resume"; import { destroyBranch } from "./scope"; import { CLEAN, DIRTY, MARK } from "./signals"; -const classIdToScope = new Map(); +const classIdToBranch = new Map(); export const compat = { patchConditionals, queueEffect, init() { - register(SET_SCOPE_REGISTER_ID, (scope: BranchScope & { m5c: string }) => { - classIdToScope.set(scope.m5c, scope); + register(SET_SCOPE_REGISTER_ID, (branch: BranchScope & { m5c: string }) => { + classIdToBranch.set(branch.m5c, branch); }); }, registerRenderer(fn: any) { @@ -29,12 +29,12 @@ export const compat = { isRenderer(renderer: any) { return renderer.___clone !== undefined; }, - getStartNode(scope: any) { - return scope.___startNode; + getStartNode(branch: any) { + return branch.___startNode; }, - setScopeNodes(scope: any, startNode: Node, endNode: Node) { - scope.___startNode = startNode; - scope.___endNode = endNode; + setScopeNodes(branch: any, startNode: Node, endNode: Node) { + branch.___startNode = startNode; + branch.___endNode = endNode; }, runComponentEffects(this: any) { runEffects(this.effects); @@ -73,13 +73,13 @@ export const compat = { return renderer; }, render(out: any, component: any, renderer: Renderer, args: any) { - let scope: BranchScope = component.scope; + let branch: BranchScope = component.scope; - if (!scope) { - scope = classIdToScope.get(component.id)!; - if (scope) { - component.scope = scope; - classIdToScope.delete(component.id); + if (!branch) { + branch = classIdToBranch.get(component.id)!; + if (branch) { + component.scope = branch; + classIdToBranch.delete(component.id); } } @@ -94,22 +94,22 @@ export const compat = { } component.effects = prepareEffects(() => { - if (!scope) { + if (!branch) { // TODO: this should be createBranch - scope = component.scope = createScope(out.global) as BranchScope; - scope._ = renderer.___owner; - initBranch(renderer, scope); + branch = component.scope = createScope(out.global) as BranchScope; + branch._ = renderer.___owner; + initBranch(renderer, branch); } else { - applyArgs(scope, MARK); + applyArgs(branch, MARK); existing = true; } - applyArgs(scope, args); + applyArgs(branch, args); }); if (!existing) { - return scope.___startNode === scope.___endNode - ? scope.___startNode - : scope.___startNode.parentNode; + return branch.___startNode === branch.___endNode + ? branch.___startNode + : branch.___startNode.parentNode; } }, }; diff --git a/packages/runtime-tags/src/dom/control-flow.ts b/packages/runtime-tags/src/dom/control-flow.ts index 8bdf974129..0e95feca5b 100644 --- a/packages/runtime-tags/src/dom/control-flow.ts +++ b/packages/runtime-tags/src/dom/control-flow.ts @@ -230,7 +230,7 @@ function loop( let newMap!: Map; let newArray!: BranchScope[]; let afterReference: Node | null; - let parentNode: Node & ParentNode; + let parentNode: ParentNode; let needsReconciliation = true; forEach(valueOrOp, (key, args) => { let branch = oldMap.get(key); diff --git a/packages/runtime-tags/src/dom/dom.ts b/packages/runtime-tags/src/dom/dom.ts index af09b578b1..f6c9df15e2 100644 --- a/packages/runtime-tags/src/dom/dom.ts +++ b/packages/runtime-tags/src/dom/dom.ts @@ -259,24 +259,20 @@ export function attrsEvents(scope: Scope, nodeAccessor: Accessor) { } } -export function html(scope: Scope, value: unknown, index: Accessor) { - const firstChild = scope[index] as Node & ChildNode; - const lastChild = (scope[index + "-"] || firstChild) as Node & ChildNode; - const parentNode = firstChild.parentNode!; - const afterReference = lastChild.nextSibling; - const newContent = parseHTML(value || value === 0 ? value + "" : ""); +export function html(scope: Scope, value: unknown, accessor: Accessor) { + const firstChild = scope[accessor] as ChildNode; + const lastChild = (scope[ + accessor + AccessorChar.DynamicPlaceholderLastChild + ] || firstChild) as ChildNode; + const newContent = parseHTML( + value || value === 0 ? value + "" : "", // TODO: is the comment needed + ); - scope[index] = newContent.firstChild; - scope[index + AccessorChar.DynamicPlaceholderLastChild] = + scope[accessor] = newContent.firstChild; + scope[accessor + AccessorChar.DynamicPlaceholderLastChild] = newContent.lastChild; - parentNode.insertBefore(newContent, firstChild); - - let current = firstChild; - while (current !== afterReference) { - const next = current.nextSibling; - current.remove(); - current = next!; - } + firstChild.parentNode!.insertBefore(newContent, firstChild); + removeChildNodes(firstChild, lastChild); } export function props(scope: Scope, nodeIndex: number, index: number) { @@ -330,3 +326,13 @@ export function lifecycle( ).onabort = () => thisObj.onDestroy?.(); } } + +export function removeChildNodes(startNode: ChildNode, endNode: ChildNode) { + const stop = endNode.nextSibling; + let current = startNode; + while (current !== stop) { + const next = current.nextSibling; + current.remove(); + current = next!; + } +} diff --git a/packages/runtime-tags/src/dom/parse-html.ts b/packages/runtime-tags/src/dom/parse-html.ts index ff69f37766..7a22621be4 100644 --- a/packages/runtime-tags/src/dom/parse-html.ts +++ b/packages/runtime-tags/src/dom/parse-html.ts @@ -1,4 +1,3 @@ -const fallback = /* @__PURE__ */ new Text(); const parser = /* @__PURE__ */ document.createElement("template"); export function parseHTML(html: string) { @@ -24,5 +23,5 @@ export function parseHTMLOrSingleNode(html: string) { return fragment; } - return fallback; + return new Text(); } diff --git a/packages/runtime-tags/src/dom/reconcile.ts b/packages/runtime-tags/src/dom/reconcile.ts index f52a0cb384..2d35780ffd 100644 --- a/packages/runtime-tags/src/dom/reconcile.ts +++ b/packages/runtime-tags/src/dom/reconcile.ts @@ -4,7 +4,7 @@ import { insertBranchBefore, removeAndDestroyBranch } from "./scope"; const WRONG_POS = 2147483647; export function reconcile( - parent: Node & ParentNode, + parent: ParentNode, oldBranches: BranchScope[], newBranches: BranchScope[], afterReference: Node | null, diff --git a/packages/runtime-tags/src/dom/resume.ts b/packages/runtime-tags/src/dom/resume.ts index d1067b12d6..06c5cc782a 100644 --- a/packages/runtime-tags/src/dom/resume.ts +++ b/packages/runtime-tags/src/dom/resume.ts @@ -114,7 +114,7 @@ class Render implements RenderData { this.___scopeStack.push(this.___currentScopeId); } this.___currentScopeId = scopeId; - scope.___startNode = visit; + (scope as BranchScope).___startNode = visit; } else if (token === ResumeSymbol.BranchEnd) { scope[data] = visit; const curParent = visit.parentNode!; diff --git a/packages/runtime-tags/src/dom/scope.ts b/packages/runtime-tags/src/dom/scope.ts index 57ffe2456b..767891f9cc 100644 --- a/packages/runtime-tags/src/dom/scope.ts +++ b/packages/runtime-tags/src/dom/scope.ts @@ -1,4 +1,5 @@ import type { BranchScope, Scope } from "../common/types"; +import { removeChildNodes } from "./dom"; let pendingScopes: Scope[] = []; let debugID = 0; @@ -49,25 +50,19 @@ function destroyNestedBranches(branch: BranchScope) { export function removeAndDestroyBranch(branch: BranchScope) { destroyBranch(branch); - let current = branch.___startNode; - const stop = branch.___endNode.nextSibling; - while (current !== stop) { - const next = current.nextSibling; - current.remove(); - current = next!; - } + removeChildNodes(branch.___startNode, branch.___endNode); } export function insertBranchBefore( branch: BranchScope, - parent: Node & ParentNode, + parentNode: ParentNode, nextSibling: Node | null, ) { let current = branch.___startNode as Node; const stop = branch.___endNode.nextSibling; while (current !== stop) { const next = current.nextSibling; - parent.insertBefore(current, nextSibling); + parentNode.insertBefore(current, nextSibling); current = next!; } } diff --git a/packages/runtime-tags/src/dom/template.ts b/packages/runtime-tags/src/dom/template.ts index f7779ed6b6..598b50e733 100644 --- a/packages/runtime-tags/src/dom/template.ts +++ b/packages/runtime-tags/src/dom/template.ts @@ -32,7 +32,7 @@ export const createTemplate = ( function mount( this: Template & Renderer, input: TemplateInput = {}, - reference: ParentNode & Node, + reference: Node, position?: InsertPosition, ): TemplateInstance { let branch!: BranchScope, dom!: Node; diff --git a/packages/runtime-tags/src/dom/walker.ts b/packages/runtime-tags/src/dom/walker.ts index a48ec0ac65..a331338a8c 100644 --- a/packages/runtime-tags/src/dom/walker.ts +++ b/packages/runtime-tags/src/dom/walker.ts @@ -1,4 +1,10 @@ -import { NodeType, type Scope, WalkCode, WalkRangeSize } from "../common/types"; +import { + type BranchScope, + NodeType, + type Scope, + WalkCode, + WalkRangeSize, +} from "../common/types"; import { createScope } from "./scope"; export const walker = /* @__PURE__ */ document.createTreeWalker(document); @@ -23,9 +29,9 @@ export function trimWalkString(walkString: string): string { return walkString.slice(0, end + 1); } -export function walk(startNode: Node, walkCodes: string, scope: Scope) { +export function walk(startNode: Node, walkCodes: string, branch: BranchScope) { walker.currentNode = startNode; - walkInternal(walkCodes, scope, 0); + walkInternal(walkCodes, branch, 0); walker.currentNode = document; } @@ -69,10 +75,6 @@ function walkInternal( ? getDebugKey(currentScopeIndex++, "#childScope") : currentScopeIndex++ ] = createScope(scope.$global)); - // TODO: shouldn't need startNode here only for direct children of controlflow. - // We need this currently because the scope in which the controlflow owner resides is returned - // we should change it to return the scope _controlled_ by the controlflow - childScope.___startNode = walker.currentNode as ChildNode; childScope.___closestBranch = scope.___closestBranch; currentWalkIndex = walkInternal(walkCodes, childScope, currentWalkIndex)!; } else if (value === WalkCode.EndChild) {