UNPKG

2.64 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5var helpers = require('./helpers.js');
6
7function 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
29const getBlockSize = (template) => {
30 let i = 0;
31 helpers.walk(template.content?.firstChild || template.firstChild, () => i++, false);
32 return i
33};
34
35const nextNonWhitespaceSibling = (node) => {
36 return helpers.isWhitespace(node.nextSibling)
37 ? nextNonWhitespaceSibling(node.nextSibling)
38 : node.nextSibling
39};
40
41const 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
58const 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
77const 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
84function lastChild(v) {
85 return (v.nodeType === v.DOCUMENT_FRAGMENT_NODE && v.lastChild) || v
86}
87
88const 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
106exports.compareKeyedLists = compareKeyedLists;
107exports.getBlocks = getBlocks;
108exports.parseEach = parseEach;
109exports.updateList = updateList;