jq79 0.3.24 → 0.3.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/jq79.cjs +7 -7
- package/dist/jq79.cjs.map +1 -1
- package/dist/jq79.global.js +7 -7
- package/dist/jq79.global.js.map +1 -1
- package/dist/jq79.js +8 -8
- package/dist/jq79.js.map +1 -1
- package/package.json +1 -1
- package/src/jq79.ts +30 -10
package/src/jq79.ts
CHANGED
|
@@ -24,12 +24,18 @@ type TagBlock = {
|
|
|
24
24
|
const elementAttrs = (el: Element): Record<string, string> =>
|
|
25
25
|
Object.fromEntries(Array.from(el.attributes).map(attr => [attr.name, attr.value]))
|
|
26
26
|
|
|
27
|
+
// text is kept verbatim - not trimmed, not dropped when it's only whitespace.
|
|
28
|
+
// A template is HTML, so the space in `<span>a</span>\n<span>b</span>` is the
|
|
29
|
+
// same space the browser would collapse-and-render between them, and CSS gets
|
|
30
|
+
// to decide what it's worth (nothing in a block or flex container, one space
|
|
31
|
+
// between inline elements). Trimming it here, as this used to, silently glued
|
|
32
|
+
// siblings together and ate the spaces in `hola <b>mundo</b> adios`
|
|
27
33
|
const elementToAST = (el: Element): TemplateNode => ({
|
|
28
34
|
tag: el.tagName.toLowerCase(),
|
|
29
35
|
attrs: elementAttrs(el),
|
|
30
36
|
children: Array.from(el.childNodes).flatMap((node): (TemplateNode | string)[] => {
|
|
31
37
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
32
|
-
const text = node.textContent
|
|
38
|
+
const text = node.textContent ?? ""
|
|
33
39
|
return text ? [text] : []
|
|
34
40
|
}
|
|
35
41
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
@@ -409,8 +415,10 @@ const renderNodes = (nodes: (TemplateNode | string)[], scope: Record<string, any
|
|
|
409
415
|
const node = nodes[i]
|
|
410
416
|
|
|
411
417
|
if (typeof node === "string") {
|
|
412
|
-
const textNode = document.createTextNode(
|
|
413
|
-
|
|
418
|
+
const textNode = document.createTextNode(node)
|
|
419
|
+
// static text is most of a template (all of its indentation, for a start):
|
|
420
|
+
// only text with a {{ expression }} in it needs an effect to stay in sync
|
|
421
|
+
if (node.includes("{{")) fx.effect(() => { textNode.textContent = interpolate(node, scope) })
|
|
414
422
|
fragment.appendChild(textNode)
|
|
415
423
|
i++
|
|
416
424
|
continue
|
|
@@ -425,15 +433,27 @@ const renderNodes = (nodes: (TemplateNode | string)[], scope: Record<string, any
|
|
|
425
433
|
if (":if" in node.attrs) {
|
|
426
434
|
const branches: ConditionalBranch[] = [{ expr: node.attrs[":if"], node }]
|
|
427
435
|
i++
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
436
|
+
|
|
437
|
+
// the branches of a chain are siblings in the AST, but the template writes
|
|
438
|
+
// them on their own lines - so the whitespace between them is indentation
|
|
439
|
+
// and nothing else, and it's dropped rather than rendered: only one branch
|
|
440
|
+
// is ever in the DOM, so there is nothing for it to be a space *between*
|
|
441
|
+
const nextBranch = (attr: string): TemplateNode | undefined => {
|
|
442
|
+
let next = i
|
|
443
|
+
while (next < nodes.length && typeof nodes[next] === "string" && !(nodes[next] as string).trim()) next++
|
|
444
|
+
const candidate = nodes[next]
|
|
445
|
+
if (typeof candidate === "object" && attr in candidate.attrs) {
|
|
446
|
+
i = next + 1
|
|
447
|
+
return candidate
|
|
448
|
+
}
|
|
449
|
+
return undefined
|
|
432
450
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
451
|
+
|
|
452
|
+
for (let elseif = nextBranch(":elseif"); elseif; elseif = nextBranch(":elseif")) {
|
|
453
|
+
branches.push({ expr: elseif.attrs[":elseif"], node: elseif })
|
|
436
454
|
}
|
|
455
|
+
const elseNode = nextBranch(":else")
|
|
456
|
+
if (elseNode) branches.push({ node: elseNode })
|
|
437
457
|
|
|
438
458
|
fragment.appendChild(renderConditional(branches, scope, fx))
|
|
439
459
|
continue
|