diff --git a/src/blockdom/block_compiler.ts b/src/blockdom/block_compiler.ts index 728fe6b5..76f7df31 100644 --- a/src/blockdom/block_compiler.ts +++ b/src/blockdom/block_compiler.ts @@ -113,7 +113,7 @@ interface IntermediateTree { nextSibling: IntermediateTree | null; el: Node; info: DynamicInfo[]; - forceRef?: boolean; + isRef?: boolean; refIdx?: number; refN: number; currentNS: string | null; @@ -127,7 +127,6 @@ function buildTree( switch (node.nodeType) { case Node.ELEMENT_NODE: { // HTMLElement - let isActive = false; let currentNS = parent && parent.currentNS; const tagName = (node as Element).tagName; let el: Node | undefined = undefined; @@ -136,14 +135,14 @@ function buildTree( const index = parseInt(tagName.slice(11), 10); info.push({ type: "text", idx: index }); el = document.createTextNode(""); - isActive = true; } if (tagName.startsWith("block-child-")) { - domParentTree!.forceRef = true; + if (!domParentTree!.isRef) { + addRef(domParentTree!); + } const index = parseInt(tagName.slice(12), 10); info.push({ type: "child", idx: index }); el = document.createTextNode(""); - isActive = true; } const attrs = (node as Element).attributes; const ns = attrs.getNamedItem("block-ns"); @@ -161,7 +160,6 @@ function buildTree( const attrName = attrs[i].name; const attrValue = attrs[i].value; if (attrName.startsWith("block-handler-")) { - isActive = true; const idx = parseInt(attrName.slice(14), 10); info.push({ type: "handler", @@ -169,7 +167,6 @@ function buildTree( event: attrValue, }); } else if (attrName.startsWith("block-attribute-")) { - isActive = true; const idx = parseInt(attrName.slice(16), 10); info.push({ type: "attribute", @@ -178,13 +175,11 @@ function buildTree( tag: tagName, }); } else if (attrName === "block-attributes") { - isActive = true; info.push({ type: "attributes", idx: parseInt(attrValue, 10), }); } else if (attrName === "block-ref") { - isActive = true; info.push({ type: "ref", idx: parseInt(attrValue, 10), @@ -201,7 +196,7 @@ function buildTree( nextSibling: null, el, info, - refN: isActive ? 1 : 0, + refN: 0, currentNS, }; @@ -215,8 +210,6 @@ function buildTree( const tagName = (childNode as Element).tagName; const index = parseInt(tagName.slice(12), 10); info.push({ idx: index, type: "child", isOnlyChild: true }); - isActive = true; - tree.refN = 1; } else { tree.firstChild = buildTree(node.firstChild, tree, tree); el.appendChild(tree.firstChild.el); @@ -229,11 +222,8 @@ function buildTree( } } } - if (isActive) { - let cur: IntermediateTree | null = tree; - while ((cur = cur.parent)) { - cur.refN++; - } + if (tree.info.length) { + addRef(tree); } return tree; } @@ -258,6 +248,13 @@ function buildTree( throw new Error("boom"); } +function addRef(tree: IntermediateTree) { + tree.isRef = true; + do { + tree.refN++; + } while ((tree = tree.parent as any)); +} + function parentTree(tree: IntermediateTree): IntermediateTree | null { let parent = tree.parent; while (parent && parent.nextSibling === tree) { @@ -304,21 +301,15 @@ interface BlockCtx { cbRefs: number[]; } -function buildContext( - tree: IntermediateTree, - ctx?: BlockCtx, - fromIdx?: number, - toIdx?: number -): BlockCtx { +function buildContext(tree: IntermediateTree, ctx?: BlockCtx, fromIdx?: number): BlockCtx { if (!ctx) { const children = new Array(tree.info.filter((v) => v.type === "child").length); ctx = { collectors: [], locations: [], children, cbRefs: [], refN: tree.refN }; fromIdx = 0; - toIdx = tree.refN - 1; } if (tree.refN) { const initialIdx = fromIdx!; - const isRef = tree.forceRef || tree.info.length > 0; + const isRef = tree.isRef; const firstChild = tree.firstChild ? tree.firstChild.refN : 0; const nextSibling = tree.nextSibling ? tree.nextSibling.refN : 0; @@ -336,13 +327,13 @@ function buildContext( if (nextSibling) { const idx = fromIdx! + firstChild; ctx.collectors.push({ idx, prevIdx: initialIdx, getVal: nodeGetNextSibling }); - buildContext(tree.nextSibling!, ctx, idx, toIdx); + buildContext(tree.nextSibling!, ctx, idx); } // left if (firstChild) { ctx.collectors.push({ idx: fromIdx!, prevIdx: initialIdx, getVal: nodeGetFirstChild }); - buildContext(tree.firstChild!, ctx, fromIdx!, toIdx! - nextSibling); + buildContext(tree.firstChild!, ctx, fromIdx!); } } diff --git a/tests/blockdom/block.test.ts b/tests/blockdom/block.test.ts index ec69d729..98c80df7 100644 --- a/tests/blockdom/block.test.ts +++ b/tests/blockdom/block.test.ts @@ -227,6 +227,22 @@ describe("misc", () => { expect(fixture.innerHTML).toBe("
() => 3tostring
"); }); + test("block with 2 subblocks: variation", async () => { + const block = createBlock("