@b9g/crank 0.5.0-debug.0 → 0.5.1
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/README.md +6 -17
- package/crank.cjs +682 -392
- package/crank.cjs.map +1 -1
- package/crank.d.ts +57 -77
- package/crank.js +681 -391
- package/crank.js.map +1 -1
- package/dom.cjs +103 -27
- package/dom.cjs.map +1 -1
- package/dom.d.ts +1 -0
- package/dom.js +103 -25
- package/dom.js.map +1 -1
- package/html.cjs +1 -3
- package/html.cjs.map +1 -1
- package/html.d.ts +2 -1
- package/html.js +1 -1
- package/html.js.map +1 -1
- package/jsx-runtime.cjs +18 -0
- package/jsx-runtime.cjs.map +1 -0
- package/jsx-runtime.d.ts +5 -0
- package/jsx-runtime.js +15 -0
- package/jsx-runtime.js.map +1 -0
- package/{xm.cjs → jsx-tag.cjs} +8 -10
- package/jsx-tag.cjs.map +1 -0
- package/jsx-tag.d.ts +2 -0
- package/{xm.js → jsx-tag.js} +9 -9
- package/jsx-tag.js.map +1 -0
- package/package.json +41 -33
- package/{mod.cjs → standalone.cjs} +3 -5
- package/standalone.cjs.map +1 -0
- package/standalone.d.ts +2 -0
- package/{mod.js → standalone.js} +3 -3
- package/standalone.js.map +1 -0
- package/umd.js +787 -421
- package/umd.js.map +1 -1
- package/mod.cjs.map +0 -1
- package/mod.d.ts +0 -2
- package/mod.js.map +0 -1
- package/xm.cjs.map +0 -1
- package/xm.d.ts +0 -2
- package/xm.js.map +0 -1
package/dom.cjs
CHANGED
|
@@ -1,49 +1,61 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
3
|
var crank = require('./crank.cjs');
|
|
6
4
|
|
|
7
5
|
const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
8
6
|
const impl = {
|
|
9
|
-
|
|
10
|
-
if (typeof document.createRange === "function") {
|
|
11
|
-
const fragment = document.createRange().createContextualFragment(text);
|
|
12
|
-
return Array.from(fragment.childNodes);
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
const childNodes = new DOMParser().parseFromString(text, "text/html").body
|
|
16
|
-
.childNodes;
|
|
17
|
-
return Array.from(childNodes);
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
scope(scope, tag) {
|
|
7
|
+
scope(xmlns, tag) {
|
|
21
8
|
// TODO: Should we handle xmlns???
|
|
22
9
|
switch (tag) {
|
|
23
10
|
case crank.Portal:
|
|
24
11
|
case "foreignObject":
|
|
25
|
-
|
|
12
|
+
xmlns = undefined;
|
|
13
|
+
break;
|
|
26
14
|
case "svg":
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return scope;
|
|
15
|
+
xmlns = SVG_NAMESPACE;
|
|
16
|
+
break;
|
|
30
17
|
}
|
|
18
|
+
return xmlns;
|
|
31
19
|
},
|
|
32
|
-
create(tag, _props,
|
|
20
|
+
create(tag, _props, xmlns) {
|
|
33
21
|
if (typeof tag !== "string") {
|
|
34
22
|
throw new Error(`Unknown tag: ${tag.toString()}`);
|
|
35
23
|
}
|
|
36
24
|
else if (tag.toLowerCase() === "svg") {
|
|
37
|
-
|
|
25
|
+
xmlns = SVG_NAMESPACE;
|
|
38
26
|
}
|
|
39
|
-
return
|
|
27
|
+
return xmlns
|
|
28
|
+
? document.createElementNS(xmlns, tag)
|
|
29
|
+
: document.createElement(tag);
|
|
30
|
+
},
|
|
31
|
+
hydrate(tag, node, props) {
|
|
32
|
+
if (typeof tag !== "string" && tag !== crank.Portal) {
|
|
33
|
+
throw new Error(`Unknown tag: ${tag.toString()}`);
|
|
34
|
+
}
|
|
35
|
+
if (typeof tag === "string" &&
|
|
36
|
+
tag.toUpperCase() !== node.tagName) {
|
|
37
|
+
console.error(`Expected <${tag}> while hydrating but found:`, node);
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
const children = [];
|
|
41
|
+
for (let i = 0; i < node.childNodes.length; i++) {
|
|
42
|
+
const child = node.childNodes[i];
|
|
43
|
+
if (child.nodeType === Node.TEXT_NODE) {
|
|
44
|
+
children.push(child.data);
|
|
45
|
+
}
|
|
46
|
+
else if (child.nodeType === Node.ELEMENT_NODE) {
|
|
47
|
+
children.push(child);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// TODO: extract props from nodes
|
|
51
|
+
return { props, children };
|
|
40
52
|
},
|
|
41
53
|
patch(_tag,
|
|
42
54
|
// TODO: Why does this assignment work?
|
|
43
55
|
node, name,
|
|
44
56
|
// TODO: Stricter typings?
|
|
45
|
-
value, oldValue,
|
|
46
|
-
const isSVG =
|
|
57
|
+
value, oldValue, xmlns) {
|
|
58
|
+
const isSVG = xmlns === SVG_NAMESPACE;
|
|
47
59
|
switch (name) {
|
|
48
60
|
case "style": {
|
|
49
61
|
const style = node.style;
|
|
@@ -119,7 +131,9 @@ const impl = {
|
|
|
119
131
|
const descriptor = Object.getOwnPropertyDescriptor(obj, name);
|
|
120
132
|
if (descriptor != null &&
|
|
121
133
|
(descriptor.writable === true || descriptor.set !== undefined)) {
|
|
122
|
-
node[name]
|
|
134
|
+
if (node[name] !== value) {
|
|
135
|
+
node[name] = value;
|
|
136
|
+
}
|
|
123
137
|
return;
|
|
124
138
|
}
|
|
125
139
|
// if the property wasn't writable, fall through to the code below
|
|
@@ -206,17 +220,79 @@ const impl = {
|
|
|
206
220
|
}
|
|
207
221
|
}
|
|
208
222
|
},
|
|
223
|
+
text(text, _scope, hydrationData) {
|
|
224
|
+
if (hydrationData != null) {
|
|
225
|
+
let value = hydrationData.children.shift();
|
|
226
|
+
if (typeof value !== "string" || !value.startsWith(text)) {
|
|
227
|
+
console.error(`Expected "${text}" while hydrating but found:`, value);
|
|
228
|
+
}
|
|
229
|
+
else if (text.length < value.length) {
|
|
230
|
+
value = value.slice(text.length);
|
|
231
|
+
hydrationData.children.unshift(value);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return text;
|
|
235
|
+
},
|
|
236
|
+
raw(value, xmlns, hydrationData) {
|
|
237
|
+
let result;
|
|
238
|
+
if (typeof value === "string") {
|
|
239
|
+
const el = xmlns == null
|
|
240
|
+
? document.createElement("div")
|
|
241
|
+
: document.createElementNS(xmlns, "svg");
|
|
242
|
+
el.innerHTML = value;
|
|
243
|
+
if (el.childNodes.length === 0) {
|
|
244
|
+
result = undefined;
|
|
245
|
+
}
|
|
246
|
+
else if (el.childNodes.length === 1) {
|
|
247
|
+
result = el.childNodes[0];
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
result = Array.from(el.childNodes);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
result = value;
|
|
255
|
+
}
|
|
256
|
+
if (hydrationData != null) {
|
|
257
|
+
// TODO: maybe we should warn on incorrect values
|
|
258
|
+
if (Array.isArray(result)) {
|
|
259
|
+
for (let i = 0; i < result.length; i++) {
|
|
260
|
+
const node = result[i];
|
|
261
|
+
if (typeof node !== "string" &&
|
|
262
|
+
(node.nodeType === Node.ELEMENT_NODE ||
|
|
263
|
+
node.nodeType === Node.TEXT_NODE)) {
|
|
264
|
+
hydrationData.children.shift();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
else if (result != null && typeof result !== "string") {
|
|
269
|
+
if (result.nodeType === Node.ELEMENT_NODE ||
|
|
270
|
+
result.nodeType === Node.TEXT_NODE) {
|
|
271
|
+
hydrationData.children.shift();
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return result;
|
|
276
|
+
},
|
|
209
277
|
};
|
|
210
278
|
class DOMRenderer extends crank.Renderer {
|
|
211
279
|
constructor() {
|
|
212
280
|
super(impl);
|
|
213
281
|
}
|
|
214
282
|
render(children, root, ctx) {
|
|
215
|
-
|
|
216
|
-
throw new TypeError(`Render root is not a node. Received: ${JSON.stringify(root && root.toString())}`);
|
|
217
|
-
}
|
|
283
|
+
validateRoot(root);
|
|
218
284
|
return super.render(children, root, ctx);
|
|
219
285
|
}
|
|
286
|
+
hydrate(children, root, ctx) {
|
|
287
|
+
validateRoot(root);
|
|
288
|
+
return super.hydrate(children, root, ctx);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
function validateRoot(root) {
|
|
292
|
+
if (root === null ||
|
|
293
|
+
(typeof root === "object" && typeof root.nodeType !== "number")) {
|
|
294
|
+
throw new TypeError(`Render root is not a node. Received: ${JSON.stringify(root && root.toString())}`);
|
|
295
|
+
}
|
|
220
296
|
}
|
|
221
297
|
const renderer = new DOMRenderer();
|
|
222
298
|
|
package/dom.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom.cjs","sources":["../src/dom.ts"],"sourcesContent":["import {\n\tChildren,\n\tContext,\n\tElementValue,\n\tPortal,\n\tRenderer,\n\tRendererImpl,\n} from \"./crank.js\";\n\nconst SVG_NAMESPACE = \"http://www.w3.org/2000/svg\";\n\nexport const impl: Partial<RendererImpl<Node, string>> = {\n\tparse(text: string): ElementValue<Node> {\n\t\tif (typeof document.createRange === \"function\") {\n\t\t\tconst fragment = document.createRange().createContextualFragment(text);\n\t\t\treturn Array.from(fragment.childNodes);\n\t\t} else {\n\t\t\tconst childNodes = new DOMParser().parseFromString(text, \"text/html\").body\n\t\t\t\t.childNodes;\n\t\t\treturn Array.from(childNodes);\n\t\t}\n\t},\n\n\tscope(scope: string, tag: string | symbol): string | undefined {\n\t\t// TODO: Should we handle xmlns???\n\t\tswitch (tag) {\n\t\t\tcase Portal:\n\t\t\tcase \"foreignObject\":\n\t\t\t\treturn undefined;\n\t\t\tcase \"svg\":\n\t\t\t\treturn SVG_NAMESPACE;\n\t\t\tdefault:\n\t\t\t\treturn scope;\n\t\t}\n\t},\n\n\tcreate(tag: string | symbol, _props: unknown, ns: string | undefined): Node {\n\t\tif (typeof tag !== \"string\") {\n\t\t\tthrow new Error(`Unknown tag: ${tag.toString()}`);\n\t\t} else if (tag.toLowerCase() === \"svg\") {\n\t\t\tns = SVG_NAMESPACE;\n\t\t}\n\n\t\treturn ns ? document.createElementNS(ns, tag) : document.createElement(tag);\n\t},\n\n\tpatch(\n\t\t_tag: string | symbol,\n\t\t// TODO: Why does this assignment work?\n\t\tnode: HTMLElement | SVGElement,\n\t\tname: string,\n\t\t// TODO: Stricter typings?\n\t\tvalue: unknown,\n\t\toldValue: unknown,\n\t\tscope: string | undefined,\n\t): void {\n\t\tconst isSVG = scope === SVG_NAMESPACE;\n\t\tswitch (name) {\n\t\t\tcase \"style\": {\n\t\t\t\tconst style: CSSStyleDeclaration = node.style;\n\t\t\t\tif (style == null) {\n\t\t\t\t\tnode.setAttribute(\"style\", value as string);\n\t\t\t\t} else if (value == null || value === false) {\n\t\t\t\t\tnode.removeAttribute(\"style\");\n\t\t\t\t} else if (value === true) {\n\t\t\t\t\tnode.setAttribute(\"style\", \"\");\n\t\t\t\t} else if (typeof value === \"string\") {\n\t\t\t\t\tif (style.cssText !== value) {\n\t\t\t\t\t\tstyle.cssText = value;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (typeof oldValue === \"string\") {\n\t\t\t\t\t\tstyle.cssText = \"\";\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (const styleName in {...(oldValue as {}), ...(value as {})}) {\n\t\t\t\t\t\tconst styleValue = value && (value as any)[styleName];\n\t\t\t\t\t\tif (styleValue == null) {\n\t\t\t\t\t\t\tstyle.removeProperty(styleName);\n\t\t\t\t\t\t} else if (style.getPropertyValue(styleName) !== styleValue) {\n\t\t\t\t\t\t\tstyle.setProperty(styleName, styleValue);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"class\":\n\t\t\tcase \"className\":\n\t\t\t\tif (value === true) {\n\t\t\t\t\tnode.setAttribute(\"class\", \"\");\n\t\t\t\t} else if (value == null) {\n\t\t\t\t\tnode.removeAttribute(\"class\");\n\t\t\t\t} else if (!isSVG) {\n\t\t\t\t\tif (node.className !== value) {\n\t\t\t\t\t\t(node as any)[\"className\"] = value;\n\t\t\t\t\t}\n\t\t\t\t} else if (node.getAttribute(\"class\") !== value) {\n\t\t\t\t\tnode.setAttribute(\"class\", value as string);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"innerHTML\":\n\t\t\t\tif (value !== oldValue) {\n\t\t\t\t\tnode.innerHTML = value as any;\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\tdefault: {\n\t\t\t\tif (\n\t\t\t\t\tname in node &&\n\t\t\t\t\t// boolean properties will coerce strings, but sometimes they map to\n\t\t\t\t\t// enumerated attributes, where truthy strings (\"false\", \"no\") map to\n\t\t\t\t\t// falsy properties, so we use attributes in this case.\n\t\t\t\t\t!(\n\t\t\t\t\t\ttypeof value === \"string\" &&\n\t\t\t\t\t\ttypeof (node as any)[name] === \"boolean\"\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\t// walk up the object's prototype chain to find the owner of the\n\t\t\t\t\t// named property\n\t\t\t\t\tlet obj = node;\n\t\t\t\t\tdo {\n\t\t\t\t\t\tif (Object.prototype.hasOwnProperty.call(obj, name)) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} while ((obj = Object.getPrototypeOf(obj)));\n\n\t\t\t\t\t// get the descriptor for the named property and check whether it\n\t\t\t\t\t// implies that the property is writable\n\t\t\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(obj, name);\n\t\t\t\t\tif (\n\t\t\t\t\t\tdescriptor != null &&\n\t\t\t\t\t\t(descriptor.writable === true || descriptor.set !== undefined)\n\t\t\t\t\t) {\n\t\t\t\t\t\t(node as any)[name] = value;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// if the property wasn't writable, fall through to the code below\n\t\t\t\t\t// which uses setAttribute() instead of assigning directly.\n\t\t\t\t}\n\n\t\t\t\tif (value === true) {\n\t\t\t\t\tvalue = \"\";\n\t\t\t\t} else if (value == null || value === false) {\n\t\t\t\t\tnode.removeAttribute(name);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (node.getAttribute(name) !== value) {\n\t\t\t\t\tnode.setAttribute(name, value as any);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tarrange(\n\t\ttag: string | symbol,\n\t\tnode: Node,\n\t\tprops: Record<string, any>,\n\t\tchildren: Array<Element | string>,\n\t\t_oldProps: Record<string, any> | undefined,\n\t\toldChildren: Array<Element | string> | undefined,\n\t): void {\n\t\tif (tag === Portal && (node == null || typeof node.nodeType !== \"number\")) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`Portal root is not a node. Received: ${JSON.stringify(\n\t\t\t\t\tnode && node.toString(),\n\t\t\t\t)}`,\n\t\t\t);\n\t\t}\n\n\t\tif (\n\t\t\t!(\"innerHTML\" in props) &&\n\t\t\t// We don’t want to update elements without explicit children (<div/>),\n\t\t\t// because these elements sometimes have child nodes added via raw\n\t\t\t// DOM manipulations.\n\t\t\t// However, if an element has previously rendered children, we clear the\n\t\t\t// them because it would be surprising not to clear Crank managed\n\t\t\t// children, even if the new element does not have explicit children.\n\t\t\t(\"children\" in props || (oldChildren && oldChildren.length))\n\t\t) {\n\t\t\tif (children.length === 0) {\n\t\t\t\tnode.textContent = \"\";\n\t\t\t} else {\n\t\t\t\tlet oldChild = node.firstChild;\n\t\t\t\tlet i = 0;\n\t\t\t\twhile (oldChild !== null && i < children.length) {\n\t\t\t\t\tconst newChild = children[i];\n\t\t\t\t\tif (oldChild === newChild) {\n\t\t\t\t\t\toldChild = oldChild.nextSibling;\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (typeof newChild === \"string\") {\n\t\t\t\t\t\tif (oldChild.nodeType === Node.TEXT_NODE) {\n\t\t\t\t\t\t\tif ((oldChild as Text).data !== newChild) {\n\t\t\t\t\t\t\t\t(oldChild as Text).data = newChild;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\toldChild = oldChild.nextSibling;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnode.insertBefore(document.createTextNode(newChild), oldChild);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (oldChild.nodeType === Node.TEXT_NODE) {\n\t\t\t\t\t\tconst nextSibling = oldChild.nextSibling;\n\t\t\t\t\t\tnode.removeChild(oldChild);\n\t\t\t\t\t\toldChild = nextSibling;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnode.insertBefore(newChild, oldChild);\n\t\t\t\t\t\ti++;\n\t\t\t\t\t\t// TODO: This is an optimization but we need to think a little more about other cases like prepending.\n\t\t\t\t\t\tif (oldChild !== children[i]) {\n\t\t\t\t\t\t\tconst nextSibling = oldChild.nextSibling;\n\t\t\t\t\t\t\tnode.removeChild(oldChild);\n\t\t\t\t\t\t\toldChild = nextSibling;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// remove excess DOM nodes\n\t\t\t\twhile (oldChild !== null) {\n\t\t\t\t\tconst nextSibling = oldChild.nextSibling;\n\t\t\t\t\tnode.removeChild(oldChild);\n\t\t\t\t\toldChild = nextSibling;\n\t\t\t\t}\n\n\t\t\t\t// append excess children\n\t\t\t\tfor (; i < children.length; i++) {\n\t\t\t\t\tconst newChild = children[i];\n\t\t\t\t\tnode.appendChild(\n\t\t\t\t\t\ttypeof newChild === \"string\"\n\t\t\t\t\t\t\t? document.createTextNode(newChild)\n\t\t\t\t\t\t\t: newChild,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n};\n\nexport class DOMRenderer extends Renderer<Node, string> {\n\tconstructor() {\n\t\tsuper(impl);\n\t}\n\n\trender(\n\t\tchildren: Children,\n\t\troot: Node,\n\t\tctx?: Context,\n\t): Promise<ElementValue<Node>> | ElementValue<Node> {\n\t\tif (root == null || typeof root.nodeType !== \"number\") {\n\t\t\tthrow new TypeError(\n\t\t\t\t`Render root is not a node. Received: ${JSON.stringify(\n\t\t\t\t\troot && root.toString(),\n\t\t\t\t)}`,\n\t\t\t);\n\t\t}\n\n\t\treturn super.render(children, root, ctx);\n\t}\n}\n\nexport const renderer = new DOMRenderer();\n\ndeclare global {\n\tmodule Crank {\n\t\tinterface EventMap extends GlobalEventHandlersEventMap {}\n\t}\n}\n"],"names":["Portal","Renderer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dom.cjs","sources":["../src/dom.ts"],"sourcesContent":["import {\n\tChildren,\n\tContext,\n\tElementValue,\n\tHydrationData,\n\tPortal,\n\tRenderer,\n\tRendererImpl,\n} from \"./crank.js\";\n\nconst SVG_NAMESPACE = \"http://www.w3.org/2000/svg\";\n\nexport const impl: Partial<RendererImpl<Node, string>> = {\n\tscope(xmlns: string | undefined, tag: string | symbol): string | undefined {\n\t\t// TODO: Should we handle xmlns???\n\t\tswitch (tag) {\n\t\t\tcase Portal:\n\t\t\tcase \"foreignObject\":\n\t\t\t\txmlns = undefined;\n\t\t\t\tbreak;\n\t\t\tcase \"svg\":\n\t\t\t\txmlns = SVG_NAMESPACE;\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn xmlns;\n\t},\n\n\tcreate(\n\t\ttag: string | symbol,\n\t\t_props: unknown,\n\t\txmlns: string | undefined,\n\t): Node {\n\t\tif (typeof tag !== \"string\") {\n\t\t\tthrow new Error(`Unknown tag: ${tag.toString()}`);\n\t\t} else if (tag.toLowerCase() === \"svg\") {\n\t\t\txmlns = SVG_NAMESPACE;\n\t\t}\n\n\t\treturn xmlns\n\t\t\t? document.createElementNS(xmlns, tag)\n\t\t\t: document.createElement(tag);\n\t},\n\n\thydrate(\n\t\ttag: string | symbol,\n\t\tnode: Element,\n\t\tprops: Record<string, unknown>,\n\t): HydrationData<Element> | undefined {\n\t\tif (typeof tag !== \"string\" && tag !== Portal) {\n\t\t\tthrow new Error(`Unknown tag: ${tag.toString()}`);\n\t\t}\n\n\t\tif (\n\t\t\ttypeof tag === \"string\" &&\n\t\t\ttag.toUpperCase() !== (node as Element).tagName\n\t\t) {\n\t\t\tconsole.error(`Expected <${tag}> while hydrating but found:`, node);\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst children: Array<string | Element> = [];\n\t\tfor (let i = 0; i < node.childNodes.length; i++) {\n\t\t\tconst child = node.childNodes[i];\n\t\t\tif (child.nodeType === Node.TEXT_NODE) {\n\t\t\t\tchildren.push((child as Text).data);\n\t\t\t} else if (child.nodeType === Node.ELEMENT_NODE) {\n\t\t\t\tchildren.push(child as Element);\n\t\t\t}\n\t\t}\n\n\t\t// TODO: extract props from nodes\n\t\treturn {props, children};\n\t},\n\n\tpatch(\n\t\t_tag: string | symbol,\n\t\t// TODO: Why does this assignment work?\n\t\tnode: HTMLElement | SVGElement,\n\t\tname: string,\n\t\t// TODO: Stricter typings?\n\t\tvalue: unknown,\n\t\toldValue: unknown,\n\t\txmlns: string | undefined,\n\t): void {\n\t\tconst isSVG = xmlns === SVG_NAMESPACE;\n\t\tswitch (name) {\n\t\t\tcase \"style\": {\n\t\t\t\tconst style: CSSStyleDeclaration = node.style;\n\t\t\t\tif (style == null) {\n\t\t\t\t\tnode.setAttribute(\"style\", value as string);\n\t\t\t\t} else if (value == null || value === false) {\n\t\t\t\t\tnode.removeAttribute(\"style\");\n\t\t\t\t} else if (value === true) {\n\t\t\t\t\tnode.setAttribute(\"style\", \"\");\n\t\t\t\t} else if (typeof value === \"string\") {\n\t\t\t\t\tif (style.cssText !== value) {\n\t\t\t\t\t\tstyle.cssText = value;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (typeof oldValue === \"string\") {\n\t\t\t\t\t\tstyle.cssText = \"\";\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (const styleName in {...(oldValue as {}), ...(value as {})}) {\n\t\t\t\t\t\tconst styleValue = value && (value as any)[styleName];\n\t\t\t\t\t\tif (styleValue == null) {\n\t\t\t\t\t\t\tstyle.removeProperty(styleName);\n\t\t\t\t\t\t} else if (style.getPropertyValue(styleName) !== styleValue) {\n\t\t\t\t\t\t\tstyle.setProperty(styleName, styleValue);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"class\":\n\t\t\tcase \"className\":\n\t\t\t\tif (value === true) {\n\t\t\t\t\tnode.setAttribute(\"class\", \"\");\n\t\t\t\t} else if (value == null) {\n\t\t\t\t\tnode.removeAttribute(\"class\");\n\t\t\t\t} else if (!isSVG) {\n\t\t\t\t\tif (node.className !== value) {\n\t\t\t\t\t\t(node as any)[\"className\"] = value;\n\t\t\t\t\t}\n\t\t\t\t} else if (node.getAttribute(\"class\") !== value) {\n\t\t\t\t\tnode.setAttribute(\"class\", value as string);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"innerHTML\":\n\t\t\t\tif (value !== oldValue) {\n\t\t\t\t\tnode.innerHTML = value as any;\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\tdefault: {\n\t\t\t\tif (\n\t\t\t\t\tname in node &&\n\t\t\t\t\t// boolean properties will coerce strings, but sometimes they map to\n\t\t\t\t\t// enumerated attributes, where truthy strings (\"false\", \"no\") map to\n\t\t\t\t\t// falsy properties, so we use attributes in this case.\n\t\t\t\t\t!(\n\t\t\t\t\t\ttypeof value === \"string\" &&\n\t\t\t\t\t\ttypeof (node as any)[name] === \"boolean\"\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\t// walk up the object's prototype chain to find the owner of the\n\t\t\t\t\t// named property\n\t\t\t\t\tlet obj = node;\n\t\t\t\t\tdo {\n\t\t\t\t\t\tif (Object.prototype.hasOwnProperty.call(obj, name)) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} while ((obj = Object.getPrototypeOf(obj)));\n\n\t\t\t\t\t// get the descriptor for the named property and check whether it\n\t\t\t\t\t// implies that the property is writable\n\t\t\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(obj, name);\n\t\t\t\t\tif (\n\t\t\t\t\t\tdescriptor != null &&\n\t\t\t\t\t\t(descriptor.writable === true || descriptor.set !== undefined)\n\t\t\t\t\t) {\n\t\t\t\t\t\tif ((node as any)[name] !== value) {\n\t\t\t\t\t\t\t(node as any)[name] = value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// if the property wasn't writable, fall through to the code below\n\t\t\t\t\t// which uses setAttribute() instead of assigning directly.\n\t\t\t\t}\n\n\t\t\t\tif (value === true) {\n\t\t\t\t\tvalue = \"\";\n\t\t\t\t} else if (value == null || value === false) {\n\t\t\t\t\tnode.removeAttribute(name);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (node.getAttribute(name) !== value) {\n\t\t\t\t\tnode.setAttribute(name, value as any);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tarrange(\n\t\ttag: string | symbol,\n\t\tnode: Node,\n\t\tprops: Record<string, any>,\n\t\tchildren: Array<Element | string>,\n\t\t_oldProps: Record<string, any> | undefined,\n\t\toldChildren: Array<Element | string> | undefined,\n\t): void {\n\t\tif (tag === Portal && (node == null || typeof node.nodeType !== \"number\")) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`Portal root is not a node. Received: ${JSON.stringify(\n\t\t\t\t\tnode && node.toString(),\n\t\t\t\t)}`,\n\t\t\t);\n\t\t}\n\n\t\tif (\n\t\t\t!(\"innerHTML\" in props) &&\n\t\t\t// We don’t want to update elements without explicit children (<div/>),\n\t\t\t// because these elements sometimes have child nodes added via raw\n\t\t\t// DOM manipulations.\n\t\t\t// However, if an element has previously rendered children, we clear the\n\t\t\t// them because it would be surprising not to clear Crank managed\n\t\t\t// children, even if the new element does not have explicit children.\n\t\t\t(\"children\" in props || (oldChildren && oldChildren.length))\n\t\t) {\n\t\t\tif (children.length === 0) {\n\t\t\t\tnode.textContent = \"\";\n\t\t\t} else {\n\t\t\t\tlet oldChild = node.firstChild;\n\t\t\t\tlet i = 0;\n\t\t\t\twhile (oldChild !== null && i < children.length) {\n\t\t\t\t\tconst newChild = children[i];\n\t\t\t\t\tif (oldChild === newChild) {\n\t\t\t\t\t\toldChild = oldChild.nextSibling;\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (typeof newChild === \"string\") {\n\t\t\t\t\t\tif (oldChild.nodeType === Node.TEXT_NODE) {\n\t\t\t\t\t\t\tif ((oldChild as Text).data !== newChild) {\n\t\t\t\t\t\t\t\t(oldChild as Text).data = newChild;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\toldChild = oldChild.nextSibling;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnode.insertBefore(document.createTextNode(newChild), oldChild);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (oldChild.nodeType === Node.TEXT_NODE) {\n\t\t\t\t\t\tconst nextSibling = oldChild.nextSibling;\n\t\t\t\t\t\tnode.removeChild(oldChild);\n\t\t\t\t\t\toldChild = nextSibling;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnode.insertBefore(newChild, oldChild);\n\t\t\t\t\t\ti++;\n\t\t\t\t\t\t// TODO: This is an optimization but we need to think a little more about other cases like prepending.\n\t\t\t\t\t\tif (oldChild !== children[i]) {\n\t\t\t\t\t\t\tconst nextSibling = oldChild.nextSibling;\n\t\t\t\t\t\t\tnode.removeChild(oldChild);\n\t\t\t\t\t\t\toldChild = nextSibling;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// remove excess DOM nodes\n\t\t\t\twhile (oldChild !== null) {\n\t\t\t\t\tconst nextSibling = oldChild.nextSibling;\n\t\t\t\t\tnode.removeChild(oldChild);\n\t\t\t\t\toldChild = nextSibling;\n\t\t\t\t}\n\n\t\t\t\t// append excess children\n\t\t\t\tfor (; i < children.length; i++) {\n\t\t\t\t\tconst newChild = children[i];\n\t\t\t\t\tnode.appendChild(\n\t\t\t\t\t\ttypeof newChild === \"string\"\n\t\t\t\t\t\t\t? document.createTextNode(newChild)\n\t\t\t\t\t\t\t: newChild,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\ttext(\n\t\ttext: string,\n\t\t_scope: string | undefined,\n\t\thydrationData: HydrationData<Element> | undefined,\n\t): string {\n\t\tif (hydrationData != null) {\n\t\t\tlet value = hydrationData.children.shift();\n\t\t\tif (typeof value !== \"string\" || !value.startsWith(text)) {\n\t\t\t\tconsole.error(`Expected \"${text}\" while hydrating but found:`, value);\n\t\t\t} else if (text.length < value.length) {\n\t\t\t\tvalue = value.slice(text.length);\n\t\t\t\thydrationData.children.unshift(value);\n\t\t\t}\n\t\t}\n\n\t\treturn text;\n\t},\n\n\traw(\n\t\tvalue: string | Node,\n\t\txmlns: string | undefined,\n\t\thydrationData: HydrationData<Element> | undefined,\n\t): ElementValue<Node> {\n\t\tlet result: ElementValue<Node>;\n\t\tif (typeof value === \"string\") {\n\t\t\tconst el =\n\t\t\t\txmlns == null\n\t\t\t\t\t? document.createElement(\"div\")\n\t\t\t\t\t: document.createElementNS(xmlns, \"svg\");\n\t\t\tel.innerHTML = value;\n\t\t\tif (el.childNodes.length === 0) {\n\t\t\t\tresult = undefined;\n\t\t\t} else if (el.childNodes.length === 1) {\n\t\t\t\tresult = el.childNodes[0];\n\t\t\t} else {\n\t\t\t\tresult = Array.from(el.childNodes);\n\t\t\t}\n\t\t} else {\n\t\t\tresult = value;\n\t\t}\n\n\t\tif (hydrationData != null) {\n\t\t\t// TODO: maybe we should warn on incorrect values\n\t\t\tif (Array.isArray(result)) {\n\t\t\t\tfor (let i = 0; i < result.length; i++) {\n\t\t\t\t\tconst node = result[i];\n\t\t\t\t\tif (\n\t\t\t\t\t\ttypeof node !== \"string\" &&\n\t\t\t\t\t\t(node.nodeType === Node.ELEMENT_NODE ||\n\t\t\t\t\t\t\tnode.nodeType === Node.TEXT_NODE)\n\t\t\t\t\t) {\n\t\t\t\t\t\thydrationData.children.shift();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (result != null && typeof result !== \"string\") {\n\t\t\t\tif (\n\t\t\t\t\tresult.nodeType === Node.ELEMENT_NODE ||\n\t\t\t\t\tresult.nodeType === Node.TEXT_NODE\n\t\t\t\t) {\n\t\t\t\t\thydrationData.children.shift();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t},\n};\n\nexport class DOMRenderer extends Renderer<Node, string> {\n\tconstructor() {\n\t\tsuper(impl);\n\t}\n\n\trender(\n\t\tchildren: Children,\n\t\troot: Node,\n\t\tctx?: Context,\n\t): Promise<ElementValue<Node>> | ElementValue<Node> {\n\t\tvalidateRoot(root);\n\t\treturn super.render(children, root, ctx);\n\t}\n\n\thydrate(\n\t\tchildren: Children,\n\t\troot: Node,\n\t\tctx?: Context,\n\t): Promise<ElementValue<Node>> | ElementValue<Node> {\n\t\tvalidateRoot(root);\n\t\treturn super.hydrate(children, root, ctx);\n\t}\n}\n\nfunction validateRoot(root: unknown): asserts root is Node {\n\tif (\n\t\troot === null ||\n\t\t(typeof root === \"object\" && typeof (root as any).nodeType !== \"number\")\n\t) {\n\t\tthrow new TypeError(\n\t\t\t`Render root is not a node. Received: ${JSON.stringify(\n\t\t\t\troot && root.toString(),\n\t\t\t)}`,\n\t\t);\n\t}\n}\n\nexport const renderer = new DOMRenderer();\n\ndeclare global {\n\tmodule Crank {\n\t\tinterface EventMap extends GlobalEventHandlersEventMap {}\n\t}\n}\n"],"names":["Portal","Renderer"],"mappings":"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"}
|
package/dom.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export declare const impl: Partial<RendererImpl<Node, string>>;
|
|
|
3
3
|
export declare class DOMRenderer extends Renderer<Node, string> {
|
|
4
4
|
constructor();
|
|
5
5
|
render(children: Children, root: Node, ctx?: Context): Promise<ElementValue<Node>> | ElementValue<Node>;
|
|
6
|
+
hydrate(children: Children, root: Node, ctx?: Context): Promise<ElementValue<Node>> | ElementValue<Node>;
|
|
6
7
|
}
|
|
7
8
|
export declare const renderer: DOMRenderer;
|
|
8
9
|
declare global {
|
package/dom.js
CHANGED
|
@@ -3,44 +3,58 @@ import { Portal, Renderer } from './crank.js';
|
|
|
3
3
|
|
|
4
4
|
const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
5
5
|
const impl = {
|
|
6
|
-
|
|
7
|
-
if (typeof document.createRange === "function") {
|
|
8
|
-
const fragment = document.createRange().createContextualFragment(text);
|
|
9
|
-
return Array.from(fragment.childNodes);
|
|
10
|
-
}
|
|
11
|
-
else {
|
|
12
|
-
const childNodes = new DOMParser().parseFromString(text, "text/html").body
|
|
13
|
-
.childNodes;
|
|
14
|
-
return Array.from(childNodes);
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
scope(scope, tag) {
|
|
6
|
+
scope(xmlns, tag) {
|
|
18
7
|
// TODO: Should we handle xmlns???
|
|
19
8
|
switch (tag) {
|
|
20
9
|
case Portal:
|
|
21
10
|
case "foreignObject":
|
|
22
|
-
|
|
11
|
+
xmlns = undefined;
|
|
12
|
+
break;
|
|
23
13
|
case "svg":
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return scope;
|
|
14
|
+
xmlns = SVG_NAMESPACE;
|
|
15
|
+
break;
|
|
27
16
|
}
|
|
17
|
+
return xmlns;
|
|
28
18
|
},
|
|
29
|
-
create(tag, _props,
|
|
19
|
+
create(tag, _props, xmlns) {
|
|
30
20
|
if (typeof tag !== "string") {
|
|
31
21
|
throw new Error(`Unknown tag: ${tag.toString()}`);
|
|
32
22
|
}
|
|
33
23
|
else if (tag.toLowerCase() === "svg") {
|
|
34
|
-
|
|
24
|
+
xmlns = SVG_NAMESPACE;
|
|
25
|
+
}
|
|
26
|
+
return xmlns
|
|
27
|
+
? document.createElementNS(xmlns, tag)
|
|
28
|
+
: document.createElement(tag);
|
|
29
|
+
},
|
|
30
|
+
hydrate(tag, node, props) {
|
|
31
|
+
if (typeof tag !== "string" && tag !== Portal) {
|
|
32
|
+
throw new Error(`Unknown tag: ${tag.toString()}`);
|
|
35
33
|
}
|
|
36
|
-
|
|
34
|
+
if (typeof tag === "string" &&
|
|
35
|
+
tag.toUpperCase() !== node.tagName) {
|
|
36
|
+
console.error(`Expected <${tag}> while hydrating but found:`, node);
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
const children = [];
|
|
40
|
+
for (let i = 0; i < node.childNodes.length; i++) {
|
|
41
|
+
const child = node.childNodes[i];
|
|
42
|
+
if (child.nodeType === Node.TEXT_NODE) {
|
|
43
|
+
children.push(child.data);
|
|
44
|
+
}
|
|
45
|
+
else if (child.nodeType === Node.ELEMENT_NODE) {
|
|
46
|
+
children.push(child);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// TODO: extract props from nodes
|
|
50
|
+
return { props, children };
|
|
37
51
|
},
|
|
38
52
|
patch(_tag,
|
|
39
53
|
// TODO: Why does this assignment work?
|
|
40
54
|
node, name,
|
|
41
55
|
// TODO: Stricter typings?
|
|
42
|
-
value, oldValue,
|
|
43
|
-
const isSVG =
|
|
56
|
+
value, oldValue, xmlns) {
|
|
57
|
+
const isSVG = xmlns === SVG_NAMESPACE;
|
|
44
58
|
switch (name) {
|
|
45
59
|
case "style": {
|
|
46
60
|
const style = node.style;
|
|
@@ -116,7 +130,9 @@ const impl = {
|
|
|
116
130
|
const descriptor = Object.getOwnPropertyDescriptor(obj, name);
|
|
117
131
|
if (descriptor != null &&
|
|
118
132
|
(descriptor.writable === true || descriptor.set !== undefined)) {
|
|
119
|
-
node[name]
|
|
133
|
+
if (node[name] !== value) {
|
|
134
|
+
node[name] = value;
|
|
135
|
+
}
|
|
120
136
|
return;
|
|
121
137
|
}
|
|
122
138
|
// if the property wasn't writable, fall through to the code below
|
|
@@ -203,17 +219,79 @@ const impl = {
|
|
|
203
219
|
}
|
|
204
220
|
}
|
|
205
221
|
},
|
|
222
|
+
text(text, _scope, hydrationData) {
|
|
223
|
+
if (hydrationData != null) {
|
|
224
|
+
let value = hydrationData.children.shift();
|
|
225
|
+
if (typeof value !== "string" || !value.startsWith(text)) {
|
|
226
|
+
console.error(`Expected "${text}" while hydrating but found:`, value);
|
|
227
|
+
}
|
|
228
|
+
else if (text.length < value.length) {
|
|
229
|
+
value = value.slice(text.length);
|
|
230
|
+
hydrationData.children.unshift(value);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return text;
|
|
234
|
+
},
|
|
235
|
+
raw(value, xmlns, hydrationData) {
|
|
236
|
+
let result;
|
|
237
|
+
if (typeof value === "string") {
|
|
238
|
+
const el = xmlns == null
|
|
239
|
+
? document.createElement("div")
|
|
240
|
+
: document.createElementNS(xmlns, "svg");
|
|
241
|
+
el.innerHTML = value;
|
|
242
|
+
if (el.childNodes.length === 0) {
|
|
243
|
+
result = undefined;
|
|
244
|
+
}
|
|
245
|
+
else if (el.childNodes.length === 1) {
|
|
246
|
+
result = el.childNodes[0];
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
result = Array.from(el.childNodes);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
result = value;
|
|
254
|
+
}
|
|
255
|
+
if (hydrationData != null) {
|
|
256
|
+
// TODO: maybe we should warn on incorrect values
|
|
257
|
+
if (Array.isArray(result)) {
|
|
258
|
+
for (let i = 0; i < result.length; i++) {
|
|
259
|
+
const node = result[i];
|
|
260
|
+
if (typeof node !== "string" &&
|
|
261
|
+
(node.nodeType === Node.ELEMENT_NODE ||
|
|
262
|
+
node.nodeType === Node.TEXT_NODE)) {
|
|
263
|
+
hydrationData.children.shift();
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
else if (result != null && typeof result !== "string") {
|
|
268
|
+
if (result.nodeType === Node.ELEMENT_NODE ||
|
|
269
|
+
result.nodeType === Node.TEXT_NODE) {
|
|
270
|
+
hydrationData.children.shift();
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return result;
|
|
275
|
+
},
|
|
206
276
|
};
|
|
207
277
|
class DOMRenderer extends Renderer {
|
|
208
278
|
constructor() {
|
|
209
279
|
super(impl);
|
|
210
280
|
}
|
|
211
281
|
render(children, root, ctx) {
|
|
212
|
-
|
|
213
|
-
throw new TypeError(`Render root is not a node. Received: ${JSON.stringify(root && root.toString())}`);
|
|
214
|
-
}
|
|
282
|
+
validateRoot(root);
|
|
215
283
|
return super.render(children, root, ctx);
|
|
216
284
|
}
|
|
285
|
+
hydrate(children, root, ctx) {
|
|
286
|
+
validateRoot(root);
|
|
287
|
+
return super.hydrate(children, root, ctx);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
function validateRoot(root) {
|
|
291
|
+
if (root === null ||
|
|
292
|
+
(typeof root === "object" && typeof root.nodeType !== "number")) {
|
|
293
|
+
throw new TypeError(`Render root is not a node. Received: ${JSON.stringify(root && root.toString())}`);
|
|
294
|
+
}
|
|
217
295
|
}
|
|
218
296
|
const renderer = new DOMRenderer();
|
|
219
297
|
|