Skip to content

Commit

Permalink
using always the same kind of abc object
Browse files Browse the repository at this point in the history
  • Loading branch information
WebReflection committed Jan 19, 2024
1 parent 8bdb589 commit f6ab1b5
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 56 deletions.
20 changes: 11 additions & 9 deletions esm/creator.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { PersistentFragment } from './persistent-fragment.js';
import { detail, resolved } from './literals.js';
import { abc, detail } from './literals.js';
import { array, hole } from './handler.js';
import { empty } from './utils.js';
import { cache } from './literals.js';
Expand All @@ -16,24 +16,26 @@ const childNodesIndex = (node, i) => node.childNodes[i];
export default parse => (
/** @param {(template: TemplateStringsArray, values: any[]) => import("./literals.js").Cache} parse */
(template, values) => {
const { f: fragment, e: entries, d: direct } = parse(template, values);
const { a: fragment, b: entries, c: direct } = parse(template, values);
const root = fragment.cloneNode(true);
let details = empty, stack = empty;
let details = empty;
if (entries !== empty) {
details = [];
stack = [];
for (let current, prev, i = 0; i < entries.length; i++) {
const { p: path, u: update, n: name } = entries[i];
const { a: path, b: update, c: name } = entries[i];
const node = path === prev ? current : (current = find(root, (prev = path)));
details[i] = detail(empty, update, node, name);
stack[i] = update === array ? [] : (update === hole ? cache() : null);
details[i] = detail(
update,
node,
name,
update === array ? [] : (update === hole ? cache() : null)
);
}
}
return resolved(
return abc(
template,
direct ? root.firstChild : new PersistentFragment(root),
details,
stack,
);
}
);
37 changes: 7 additions & 30 deletions esm/literals.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,32 @@ import { empty } from './utils.js';
/** @typedef {Node | Element | PersistentFragment} Target */
/** @typedef {null | undefined | string | number | boolean | Node | Element | PersistentFragment} DOMValue */

/**
* @param {DocumentFragment} f content retrieved from the template
* @param {Entry[]} e entries per each hole in the template
* @param {boolean} d direct node to handle
* @returns
*/
export const cel = (f, e, d) => ({ f, e, d });
export const abc = (a, b, c) => ({ a, b, c });

/**
* @typedef {Object} Detail
* @property {any} v the current value of the interpolation / hole
* @property {function} u the callback to update the value
* @property {Node} t the target comment node or element
* @property {string | null} n the attribute name, if any, or `null`
* @param {Cache | Hole[] | Node[] | null} c the cache value for this detail
*/

/**
* @param {any} v the current value of the interpolation / hole
* @param {function} u the callback to update the value
* @param {Node} t the target comment node or element
* @param {string | null} n the attribute name, if any, or `null`
* @param {Cache | null} c the cache value for this detail
* @returns {Detail}
*/
export const detail = (v, u, t, n, c) => ({ v, u, t, n, c });
export const detail = (u, t, n, c) => ({ v: empty, u, t, n, c });

/**
* @typedef {Object} Entry
* @property {number[]} p the path to retrieve the node
* @property {function} u the update function
* @property {string | null} n the attribute name, if any, or `null`
*/

/**
* @param {number[]} p the path to retrieve the node
* @param {function} u the update function
* @param {string | null} n the attribute name, if any, or `null`
* @returns {Entry}
* @property {number[]} a the path to retrieve the node
* @property {function} b the update function
* @property {string | null} c the attribute name, if any, or `null`
*/
export const entry = (p, u, n) => ({ p, u, n });

/**
* @typedef {Object} Cache
Expand All @@ -59,16 +45,7 @@ export const entry = (p, u, n) => ({ p, u, n });
/**
* @returns {Cache}
*/
export const cache = () => resolved(null, null, empty, empty);

/**
* @property {null | TemplateStringsArray} t the cached template
* @property {null | Node | PersistentFragment} n the node returned when parsing the template
* @property {Detail[]} d the list of updates to perform
* @property {Cache[]} s the stack of caches per each interpolation / hole
* @returns {Cache}
*/
export const resolved = (t, n, d, s) => ({ t, n, d, s });
export const cache = () => abc(null, null, empty);

/**
* @typedef {Object} Parsed
Expand Down
10 changes: 5 additions & 5 deletions esm/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { TEXT_ELEMENTS } from 'domconstants/re';
import parser from '@webreflection/uparser';

import { empty, isArray, set } from './utils.js';
import { cel, entry } from './literals.js';
import { abc } from './literals.js';

import { array, attribute, hole, text, removeAttribute } from './handler.js';
import createContent from './create-content.js';
Expand Down Expand Up @@ -55,7 +55,7 @@ const resolve = (template, values, xml) => {
// ⚠️ once array, always array!
const update = isArray(values[i - 1]) ? array : hole;
if (update === hole) replace.push(node);
entries.push(entry(createPath(node), update, null));
entries.push(abc(createPath(node), update, null));
search = `${prefix}${i++}`;
}
}
Expand All @@ -65,7 +65,7 @@ const resolve = (template, values, xml) => {
while (node.hasAttribute(search)) {
if (!path) path = createPath(node);
const name = node.getAttribute(search);
entries.push(entry(path, attribute(node, name, xml), name));
entries.push(abc(path, attribute(node, name, xml), name));
removeAttribute(node, search);
search = `${prefix}${i++}`;
}
Expand All @@ -75,7 +75,7 @@ const resolve = (template, values, xml) => {
TEXT_ELEMENTS.test(node.localName) &&
node.textContent.trim() === `<!--${search}-->`
) {
entries.push(entry(path || createPath(node), text, null));
entries.push(abc(path || createPath(node), text, null));
search = `${prefix}${i++}`;
}
}
Expand Down Expand Up @@ -107,7 +107,7 @@ const resolve = (template, values, xml) => {
len = 0;
}

return set(cache, template, cel(content, entries, len === 1));
return set(cache, template, abc(content, entries, len === 1));
};

/** @type {WeakMap<TemplateStringsArray, Resolved>} */
Expand Down
14 changes: 7 additions & 7 deletions esm/rabbit.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,24 @@ const parseSVG = create(parser(true));
* @returns {Node}
*/
const unroll = (info, { s, t, v }) => {
if (info.t !== t)
if (info.a !== t)
assign(info, (s ? parseSVG : parseHTML)(t, v));
for (let { d, s } = info, i = 0; i < d.length; i++) {
for (let { c } = info, i = 0; i < c.length; i++) {
const value = v[i];
const detail = d[i];
const detail = c[i];
const { v: previous, u: update, t: target, n: name } = detail;
switch (update) {
case array:
detail.v = array(
target,
unrollValues(s[i], value),
unrollValues(detail.c, value),
previous
);
break;
case hole:
const current = value instanceof Hole ?
unroll(s[i] || (s[i] = cache()), value) :
(s[i] = null, value)
unroll(detail.c || (detail.c = cache()), value) :
(detail.c = null, value)
;
if (current !== previous)
detail.v = hole.call(detail, target, current);
Expand All @@ -42,7 +42,7 @@ const unroll = (info, { s, t, v }) => {
break;
}
}
return info.n;
return info.b;
};

/**
Expand Down
5 changes: 3 additions & 2 deletions esm/render/hole.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ const known = new WeakMap;
*/
export default (where, what) => {
const info = known.get(where) || set(known, where, cache());
if (info.n !== (typeof what === 'function' ? what() : what).toDOM(info))
where.replaceChildren(info.n.valueOf());
const { b } = info;
if (b !== (typeof what === 'function' ? what() : what).toDOM(info))
where.replaceChildren(info.b.valueOf());
return where;
};
6 changes: 3 additions & 3 deletions esm/render/shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ const known = new WeakMap;
*/
export default (where, what, check) => {
const info = known.get(where) || set(known, where, cache());
const { b } = info;
const hole = (check && typeof what === 'function') ? what() : what;
const { n } = info;
const node = hole instanceof Hole ? hole.toDOM(info) : hole;
if (n !== node)
where.replaceChildren((info.n = node).valueOf());
if (b !== node)
where.replaceChildren((info.b = node).valueOf());
return where;
};

0 comments on commit f6ab1b5

Please sign in to comment.