1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, '__esModule', { value: true });
|
4 |
|
5 | var helpers = require('./helpers.js');
|
6 |
|
7 | function parseEach(node) {
|
8 | let each = node.getAttribute("each");
|
9 | let m = each?.match(/(.+)\s+in\s+(.+)/);
|
10 | if (!m) {
|
11 | if (!each) return m
|
12 | return {
|
13 | path: each.trim(),
|
14 | key: node.getAttribute("key"),
|
15 | }
|
16 | }
|
17 | let [_, left, right] = m;
|
18 | let parts = left.match(/\(([^\)]+)\)/);
|
19 | let [a, b] = (parts ? parts[1].split(",") : [left]).map((v) => v.trim());
|
20 |
|
21 | return {
|
22 | path: right.trim(),
|
23 | identifier: b ? b : a,
|
24 | index: b ? a : b,
|
25 | key: node.getAttribute("key"),
|
26 | }
|
27 | }
|
28 |
|
29 | const getBlockSize = (template) => {
|
30 | let i = 0;
|
31 | helpers.walk(template.content?.firstChild || template.firstChild, () => i++, false);
|
32 | return i
|
33 | };
|
34 |
|
35 | const nextNonWhitespaceSibling = (node) => {
|
36 | return helpers.isWhitespace(node.nextSibling)
|
37 | ? nextNonWhitespaceSibling(node.nextSibling)
|
38 | : node.nextSibling
|
39 | };
|
40 |
|
41 | const getBlockFragments = (template, numBlocks) => {
|
42 | let blockSize = getBlockSize(template);
|
43 |
|
44 | let r = [];
|
45 | if (numBlocks) {
|
46 | while (numBlocks--) {
|
47 | let f = document.createDocumentFragment();
|
48 | let n = blockSize;
|
49 | while (n--) {
|
50 | f.appendChild(nextNonWhitespaceSibling(template));
|
51 | }
|
52 | r.push(f);
|
53 | }
|
54 | }
|
55 | return r
|
56 | };
|
57 |
|
58 | const getBlocks = (template) => {
|
59 | let numBlocks = template.getAttribute("length");
|
60 | let blockSize = getBlockSize(template);
|
61 | let r = [];
|
62 | let node = template;
|
63 | if (numBlocks) {
|
64 | while (numBlocks--) {
|
65 | let f = [];
|
66 | let n = blockSize;
|
67 | while (n--) {
|
68 | node = nextNonWhitespaceSibling(node);
|
69 | f.push(node);
|
70 | }
|
71 | r.push(f);
|
72 | }
|
73 | }
|
74 | return r
|
75 | };
|
76 |
|
77 | const compareKeyedLists = (key, a = [], b = []) => {
|
78 | let delta = b.map(([k, item]) =>
|
79 | !key ? (k in a ? k : -1) : a.findIndex(([_, v]) => v[key] === item[key])
|
80 | );
|
81 | if (a.length !== b.length || !delta.every((a, b) => a === b)) return delta
|
82 | };
|
83 |
|
84 | function lastChild(v) {
|
85 | return (v.nodeType === v.DOCUMENT_FRAGMENT_NODE && v.lastChild) || v
|
86 | }
|
87 |
|
88 | const updateList = (template, delta, entries, createListItem) => {
|
89 | let n = template.getAttribute("length") || 0;
|
90 | let blocks = getBlockFragments(template, n);
|
91 | let t = template;
|
92 |
|
93 | delta.forEach((i, newIndex) => {
|
94 | let frag =
|
95 | i === -1
|
96 | ? createListItem(entries[newIndex][1], entries[newIndex][0])
|
97 | : blocks[i];
|
98 | let x = lastChild(frag);
|
99 | t.after(frag);
|
100 | t = x;
|
101 | });
|
102 |
|
103 | template.setAttribute("length", delta.length);
|
104 | };
|
105 |
|
106 | exports.compareKeyedLists = compareKeyedLists;
|
107 | exports.getBlocks = getBlocks;
|
108 | exports.parseEach = parseEach;
|
109 | exports.updateList = updateList;
|