pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/WebReflection/uhtml/commit/176aa4f08cb23375c8c963ebddefdd3cdbe1477c

sets/repository-6534fbc3f5e83ac0.css" /> working on JSON variant · WebReflection/uhtml@176aa4f · GitHub
Skip to content

Commit 176aa4f

Browse files
committed
working on JSON variant
1 parent c830d27 commit 176aa4f

19 files changed

Lines changed: 241 additions & 117 deletions

src/constants.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export const ARRAY = 1 << 0;
2+
export const ARIA = 1 << 1;
3+
export const ATTRIBUTE = 1 << 2;
4+
export const COMMENT = 1 << 3;
5+
export const COMPONENT = 1 << 4;
6+
export const DATA = 1 << 5;
7+
export const DIRECT = 1 << 6;
8+
export const DOTS = 1 << 7;
9+
export const EVENT = 1 << 8;
10+
export const KEY = 1 << 9;
11+
export const PROP = 1 << 10;
12+
export const TEXT = 1 << 11;
13+
export const TOGGLE = 1 << 12;
14+
export const UNSAFE = 1 << 13;
15+
export const REF = 1 << 14;
16+
17+
// COMPONENT flags
18+
export const COMPONENT_DIRECT = COMPONENT | DIRECT;
19+
export const COMPONENT_DOTS = COMPONENT | DOTS;
20+
export const COMPONENT_PROP = COMPONENT | PROP;
21+
22+
// ARRAY flags
23+
export const EVENT_ARRAY = EVENT | ARRAY;
24+
export const COMMENT_ARRAY = COMMENT | ARRAY;

src/dom/ish.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,22 @@ export const prop = (node, name, value) => {
5454
node.props[name] = value;
5555
};
5656

57+
export const replaceWith = (source, target) => {
58+
const { children } = source.parent;
59+
children[children.indexOf(source)] = target;
60+
target.parent = source.parent;
61+
source.parent = null;
62+
};
63+
64+
export const remove = node => {
65+
const { parent } = node;
66+
if (parent) {
67+
const { children } = parent;
68+
children.splice(children.indexOf(node), 1);
69+
node.parent = null;
70+
}
71+
};
72+
5773
const addJSON = (value, comp, json) => {
5874
if (value !== comp) json.push(value);
5975
};

src/dom/node.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,14 @@ import props from './props.js';
88
// import { isArray } from '../utils.js';
99
import { children } from './ish.js';
1010
import { set as setRefs } from './ref.js';
11-
import { ARRAY, COMMENT, COMPONENT, KEY, REF } from './update.js';
11+
12+
import {
13+
ARRAY,
14+
COMMENT,
15+
COMPONENT,
16+
KEY,
17+
REF,
18+
} from '../constants.js';
1219

1320
/** @typedef {globalThis.Element | globalThis.HTMLElement | globalThis.SVGSVGElement | globalThis.DocumentFragment} Container */
1421

src/dom/process.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import {
1111

1212
import parser from '../parser/index.js';
1313
import templates from './templates.js';
14-
import { isKeyed, fragment, update, pdt } from './update.js';
14+
import { isKeyed, fragment, update } from './update.js';
15+
import { pdt } from '../utils.js';
1516

1617
const parse = parser({
1718
Comment,

src/dom/rabbit.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import resolve from './resolve.js';
77
import { children } from './ish.js';
88
import { isArray } from '../utils.js';
99
import { PersistentFragment, diffFragment, nodes } from './persistent-fragment.js';
10-
import { ARRAY, COMMENT, COMPONENT, EVENT, KEY, REF } from './update.js';
10+
import { ARRAY, COMMENT, COMPONENT, EVENT, KEY, REF } from '../constants.js';
1111

1212
import { _get as getDirect, _set as setDirect } from './direct.js';
1313

src/dom/resolve.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import DEBUG from '../debug.js';
22

33
const tree = DEBUG ?
4-
((node, i) => i < 0 ? node?.content : node?.childNodes?.[i]) :
5-
((node, i) => i < 0 ? node.content : node.childNodes[i])
4+
((node, i) => node?.childNodes?.[i]) :
5+
((node, i) => node.childNodes[i])
66
;
77

88
export default (root, path) => path.reduceRight(tree, root);

src/dom/update.js

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,47 +9,35 @@ import {
99
TEXT as TEMPLATE_TEXT,
1010
} from './ish.js';
1111

12-
import { Unsafe, assign, entries, reduce, isArray } from '../utils.js';
12+
import { Unsafe, assign, entries, pdt, reduce, isArray } from '../utils.js';
1313
import { PersistentFragment, diffFragment } from './persistent-fragment.js';
1414
import { ref } from './ref.js';
1515
import creator from './creator.js';
1616
import diff from './diff.js';
1717

18-
export const ARRAY = 1 << 0;
19-
export const ARIA = 1 << 1;
20-
export const ATTRIBUTE = 1 << 2;
21-
export const COMMENT = 1 << 3;
22-
export const COMPONENT = 1 << 4;
23-
export const DATA = 1 << 5;
24-
export const DIRECT = 1 << 6;
25-
export const DOTS = 1 << 7;
26-
export const EVENT = 1 << 8;
27-
export const KEY = 1 << 9;
28-
export const PROP = 1 << 10;
29-
export const TEXT = 1 << 11;
30-
export const TOGGLE = 1 << 12;
31-
export const UNSAFE = 1 << 13;
32-
export const REF = 1 << 14;
33-
34-
// COMPONENT flags
35-
const COMPONENT_DIRECT = COMPONENT | DIRECT;
36-
const COMPONENT_DOTS = COMPONENT | DOTS;
37-
const COMPONENT_PROP = COMPONENT | PROP;
38-
39-
// ARRAY flags
40-
const EVENT_ARRAY = EVENT | ARRAY;
41-
const COMMENT_ARRAY = COMMENT | ARRAY;
18+
import {
19+
ARIA,
20+
ATTRIBUTE,
21+
COMMENT,
22+
COMPONENT,
23+
DATA,
24+
DIRECT,
25+
DOTS,
26+
EVENT,
27+
KEY,
28+
TEXT,
29+
TOGGLE,
30+
UNSAFE,
31+
REF,
32+
COMPONENT_DIRECT,
33+
COMPONENT_DOTS,
34+
COMPONENT_PROP,
35+
EVENT_ARRAY,
36+
COMMENT_ARRAY,
37+
} from '../constants.js';
4238

4339
export const fragment = creator(document);
4440

45-
// /**
46-
// * @param {number[]} path
47-
// * @param {unknown} detail
48-
// * @param {typeof COMPONENT | typeof COMMENT_ARRAY | typeof UNSAFE | typeof COMMENT | typeof TEXT | typeof EVENT_ARRAY | typeof EVENT | typeof TOGGLE | typeof COMPONENT_DOTS | typeof DOTS | typeof COMPONENT_DIRECT | typeof DIRECT | typeof COMPONENT_PROP | typeof ARIA | typeof DATA | typeof KEY | typeof REF | typeof ATTRIBUTE} type
49-
// * @returns
50-
// */
51-
export const pdt = (path, detail, type) => ({ p: path, d: detail, t: type });
52-
5341
const aria = (node, curr, prev) => {
5442
if (prev !== curr) {
5543
for (const [key, value] of entries(curr))
@@ -185,9 +173,9 @@ function attribute(node, curr) {
185173
return curr;
186174
}
187175

188-
function direct(node, curr) {
176+
function direct(ref, curr) {
189177
'use strict';
190-
node[this] = curr;
178+
ref[this] = curr;
191179
return curr;
192180
}
193181

src/json/index.js

Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,68 +3,80 @@
33
import DEBUG from '../debug.js';
44
import errors from '../errors.js';
55
import { assign } from '../utils.js';
6+
import set from './process.js';
7+
import props from '../dom/props.js';
8+
import { set as setRefs } from '../dom/ref.js';
69

710
import {
8-
Comment,
9-
DocumentType,
10-
Text,
11-
Fragment,
12-
Element,
13-
Component,
1411
fromJSON,
12+
replaceWith,
13+
remove,
14+
children,
1515
} from '../dom/ish.js';
1616

17-
import parser from '../parser/index.js';
1817
import resolve from './resolve.js';
19-
import { COMPONENT, KEY, comment, update } from './update.js';
18+
import { ARRAY, COMMENT, COMPONENT, KEY, REF } from '../constants.js';
2019

21-
const textParser = parser({
22-
Comment,
23-
DocumentType,
24-
Text,
25-
Fragment,
26-
Element,
27-
Component,
28-
update,
29-
});
30-
31-
const { parse, stringify } = JSON;
20+
const create = ({ p: json, d: updates }, values) => {
21+
if (DEBUG && values.length) console.time(`mapping ${values.length} updates`);
22+
const root = fromJSON(json);
23+
let length = values.length;
24+
let node, prev, refs;
25+
// if (DEBUG && length !== updates.length) throw errors.invalid_interpolation(templates.get(fragment), values);
26+
while (length--) {
27+
const { p: path, d: update, t: type } = updates[length];
28+
const value = values[length];
29+
if (prev !== path) {
30+
node = resolve(root, path);
31+
prev = path;
32+
// if (DEBUG && !node) throw errors.invalid_path(templates.get(fragment), path);
33+
}
3234

33-
const create = xml => {
34-
const twm = new WeakMap;
35-
const cache = (template, values) => {
36-
const parsed = textParser(template, values, xml);
37-
parsed[0] = parse(stringify(parsed[0]));
38-
twm.set(template, parsed);
39-
return parsed;
40-
};
41-
return (template, ...values) => {
42-
const [json, updates] = twm.get(template) || cache(template, values);
43-
const root = fromJSON(json);
44-
const length = values.length;
45-
if (length === updates.length) {
46-
const components = [];
47-
for (let node, prev, i = 0; i < length; i++) {
48-
const [path, update, type] = updates[i];
49-
const value = values[i];
50-
if (prev !== path) {
51-
node = resolve(root, path);
52-
prev = path;
53-
if (DEBUG && !node) throw errors.invalid_path(path);
54-
}
55-
if (type === KEY) continue;
56-
if (type === COMPONENT) components.push(update(node, value));
57-
else update(node, value);
58-
}
59-
for (const [node, Component] of components) {
60-
const props = assign({ children: node.children }, node.props);
61-
comment(node, Component(props));
35+
if (type & COMPONENT) {
36+
const obj = props(node);
37+
if (type === COMPONENT) {
38+
if (DEBUG && typeof value !== 'function') throw errors.invalid_component(value);
39+
const result = value(assign({}, node.props, { children: node.children }, obj), {});
40+
if (result) replaceWith(node, result);
41+
else remove(node);
6242
}
43+
else update(obj, value);
6344
}
64-
else if (DEBUG) throw errors.invalid_template();
65-
return root;
66-
};
45+
else if (type !== KEY) {
46+
// if (DEBUG && (type & ARRAY) && !isArray(value)) throw errors.invalid_interpolation(templates.get(fragment), value);
47+
if (type === REF) (refs ??= []).push(node);
48+
const prev = type === COMMENT ? node : (type & ARRAY ? children : null);
49+
update(node, value, prev);
50+
}
51+
if (type & COMMENT) remove(node);
52+
}
53+
54+
if (refs) setRefs(refs);
55+
56+
if (DEBUG && values.length) console.timeEnd(`mapping ${values.length} updates`);
57+
return root.children.length === 1 ? root.children[0] : root;
58+
};
59+
60+
const tag = (xml, cache = new WeakMap) =>
61+
/**
62+
* @param {TemplateStringsArray | string[]} template
63+
* @param {unknown[]} values
64+
* @returns {import("../dom/ish.js").Node}
65+
*/
66+
(template, ...values) => create(
67+
cache.get(template) ?? set(xml, cache, template, values),
68+
values,
69+
);
70+
;
71+
72+
export const html = tag(false);
73+
export const svg = tag(true);
74+
75+
export const render = (where, what) => {
76+
const content = (typeof what === 'function' ? what() : what).toString();
77+
if (!where.write) return where(content);
78+
where.write(content);
79+
return where;
6780
};
6881

69-
export const html = create(false);
70-
export const svg = create(true);
82+
export { unsafe } from '../utils.js';

src/json/process.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import DEBUG from '../debug.js';
2+
3+
import {
4+
Comment,
5+
DocumentType,
6+
Text,
7+
Fragment,
8+
Element,
9+
Component,
10+
} from '../dom/ish.js';
11+
12+
import parser from '../parser/index.js';
13+
import templates from '../dom/templates.js';
14+
import { isKeyed, update } from './update.js';
15+
import { pdt } from '../utils.js';
16+
17+
const parse = parser({
18+
Comment,
19+
DocumentType,
20+
Text,
21+
Fragment,
22+
Element,
23+
Component,
24+
update,
25+
});
26+
27+
export default (xml, cache, template, values) => {
28+
if (DEBUG) console.time(`parsing ${values.length} holes`);
29+
const [domish, updates] = parse(template, values, xml);
30+
if (DEBUG) {
31+
console.timeEnd(`parsing ${values.length} holes`);
32+
console.time('creating fragment');
33+
}
34+
const parsed = pdt(domish.toJSON(), updates, isKeyed());
35+
if (DEBUG) {
36+
console.timeEnd('creating fragment');
37+
templates.set(parsed.p, template);
38+
}
39+
cache.set(template, parsed);
40+
return parsed;
41+
};

src/json/resolve.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import DEBUG from '../debug.js';
22

33
const tree = DEBUG ?
4-
((node, i) => i < 0 ? node : node?.children?.[i]) :
5-
((node, i) => i < 0 ? node : node.children[i])
4+
((node, i) => node?.children?.[i]) :
5+
((node, i) => node.children[i])
66
;
77

88
export default (root, path) => path.reduceRight(tree, root);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy