@typed/template 0.1.4 → 0.3.0
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/Directive/package.json +6 -0
- package/ElementRef/package.json +6 -0
- package/ElementSource/package.json +6 -0
- package/Entry/package.json +6 -0
- package/EventHandler/package.json +6 -0
- package/Html/package.json +6 -0
- package/HtmlChunk/package.json +6 -0
- package/Hydrate/package.json +6 -0
- package/Many/package.json +6 -0
- package/Meta/package.json +6 -0
- package/Parser/package.json +6 -0
- package/Part/package.json +6 -0
- package/Placeholder/package.json +6 -0
- package/Platform/package.json +6 -0
- package/Render/package.json +6 -0
- package/RenderContext/package.json +6 -0
- package/RenderEvent/package.json +6 -0
- package/RenderTemplate/package.json +6 -0
- package/Renderable/package.json +6 -0
- package/Template/package.json +6 -0
- package/TemplateInstance/package.json +6 -0
- package/Test/package.json +6 -0
- package/Vitest/package.json +6 -0
- package/dist/cjs/Directive.js +1 -1
- package/dist/cjs/Directive.js.map +1 -1
- package/dist/cjs/ElementRef.js +23 -13
- package/dist/cjs/ElementRef.js.map +1 -1
- package/dist/cjs/ElementSource.js +16 -18
- package/dist/cjs/ElementSource.js.map +1 -1
- package/dist/cjs/EventHandler.js +1 -1
- package/dist/cjs/EventHandler.js.map +1 -1
- package/dist/cjs/Html.js +31 -32
- package/dist/cjs/Html.js.map +1 -1
- package/dist/cjs/HtmlChunk.js +4 -1
- package/dist/cjs/HtmlChunk.js.map +1 -1
- package/dist/cjs/Hydrate.js +1 -1
- package/dist/cjs/Hydrate.js.map +1 -1
- package/dist/cjs/Many.js +14 -13
- package/dist/cjs/Many.js.map +1 -1
- package/dist/cjs/Parser.js +11 -323
- package/dist/cjs/Parser.js.map +1 -1
- package/dist/cjs/Placeholder.js +3 -3
- package/dist/cjs/Placeholder.js.map +1 -1
- package/dist/cjs/Platform.js +4 -4
- package/dist/cjs/Platform.js.map +1 -1
- package/dist/cjs/Render.js +1 -1
- package/dist/cjs/Render.js.map +1 -1
- package/dist/cjs/RenderContext.js +48 -27
- package/dist/cjs/RenderContext.js.map +1 -1
- package/dist/cjs/RenderTemplate.js +2 -17
- package/dist/cjs/RenderTemplate.js.map +1 -1
- package/dist/cjs/Template.js +27 -1
- package/dist/cjs/Template.js.map +1 -1
- package/dist/cjs/TemplateInstance.js +2 -2
- package/dist/cjs/TemplateInstance.js.map +1 -1
- package/dist/cjs/Test.js +20 -7
- package/dist/cjs/Test.js.map +1 -1
- package/dist/cjs/index.js +0 -12
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internal/EventSource.js +95 -0
- package/dist/cjs/internal/EventSource.js.map +1 -0
- package/dist/cjs/internal/browser.js +11 -11
- package/dist/cjs/internal/browser.js.map +1 -1
- package/dist/cjs/internal/hydrate.js +49 -50
- package/dist/cjs/internal/hydrate.js.map +1 -1
- package/dist/cjs/internal/indexRefCounter.js +49 -2
- package/dist/cjs/internal/indexRefCounter.js.map +1 -1
- package/dist/cjs/internal/parser.js +60 -17
- package/dist/cjs/internal/parser.js.map +1 -1
- package/dist/cjs/internal/parts.js +128 -28
- package/dist/cjs/internal/parts.js.map +1 -1
- package/dist/cjs/internal/render.js +486 -53
- package/dist/cjs/internal/render.js.map +1 -1
- package/dist/cjs/internal/server.js +5 -2
- package/dist/cjs/internal/server.js.map +1 -1
- package/dist/dts/Directive.d.ts.map +1 -1
- package/dist/dts/ElementRef.d.ts +4 -2
- package/dist/dts/ElementRef.d.ts.map +1 -1
- package/dist/dts/ElementSource.d.ts +10 -5
- package/dist/dts/ElementSource.d.ts.map +1 -1
- package/dist/dts/EventHandler.d.ts.map +1 -1
- package/dist/dts/Html.d.ts +1 -1
- package/dist/dts/Html.d.ts.map +1 -1
- package/dist/dts/HtmlChunk.d.ts.map +1 -1
- package/dist/dts/Many.d.ts +13 -11
- package/dist/dts/Many.d.ts.map +1 -1
- package/dist/dts/Parser.d.ts +3 -6
- package/dist/dts/Parser.d.ts.map +1 -1
- package/dist/dts/Part.d.ts +13 -3
- package/dist/dts/Part.d.ts.map +1 -1
- package/dist/dts/Placeholder.d.ts +2 -2
- package/dist/dts/Placeholder.d.ts.map +1 -1
- package/dist/dts/Render.d.ts +2 -1
- package/dist/dts/Render.d.ts.map +1 -1
- package/dist/dts/RenderContext.d.ts +5 -4
- package/dist/dts/RenderContext.d.ts.map +1 -1
- package/dist/dts/RenderTemplate.d.ts +2 -16
- package/dist/dts/RenderTemplate.d.ts.map +1 -1
- package/dist/dts/Renderable.d.ts +2 -2
- package/dist/dts/Renderable.d.ts.map +1 -1
- package/dist/dts/Template.d.ts +21 -3
- package/dist/dts/Template.d.ts.map +1 -1
- package/dist/dts/TemplateInstance.d.ts +3 -2
- package/dist/dts/TemplateInstance.d.ts.map +1 -1
- package/dist/dts/Test.d.ts +4 -6
- package/dist/dts/Test.d.ts.map +1 -1
- package/dist/dts/index.d.ts +0 -4
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/EventSource.d.ts +12 -0
- package/dist/dts/internal/EventSource.d.ts.map +1 -0
- package/dist/dts/internal/browser.d.ts.map +1 -1
- package/dist/dts/internal/hydrate.d.ts +5 -5
- package/dist/dts/internal/hydrate.d.ts.map +1 -1
- package/dist/dts/internal/indexRefCounter.d.ts +5 -0
- package/dist/dts/internal/indexRefCounter.d.ts.map +1 -1
- package/dist/dts/internal/module-augmentation.d.ts +0 -4
- package/dist/dts/internal/module-augmentation.d.ts.map +1 -1
- package/dist/dts/internal/parser.d.ts +8 -0
- package/dist/dts/internal/parser.d.ts.map +1 -1
- package/dist/dts/internal/parts.d.ts +66 -56
- package/dist/dts/internal/parts.d.ts.map +1 -1
- package/dist/dts/internal/render.d.ts +7 -7
- package/dist/dts/internal/render.d.ts.map +1 -1
- package/dist/dts/internal/server.d.ts.map +1 -1
- package/dist/esm/Directive.js +1 -1
- package/dist/esm/Directive.js.map +1 -1
- package/dist/esm/ElementRef.js +12 -7
- package/dist/esm/ElementRef.js.map +1 -1
- package/dist/esm/ElementSource.js +16 -13
- package/dist/esm/ElementSource.js.map +1 -1
- package/dist/esm/EventHandler.js +1 -1
- package/dist/esm/EventHandler.js.map +1 -1
- package/dist/esm/Html.js +29 -24
- package/dist/esm/Html.js.map +1 -1
- package/dist/esm/HtmlChunk.js +6 -1
- package/dist/esm/HtmlChunk.js.map +1 -1
- package/dist/esm/Hydrate.js +1 -1
- package/dist/esm/Hydrate.js.map +1 -1
- package/dist/esm/Many.js +14 -10
- package/dist/esm/Many.js.map +1 -1
- package/dist/esm/Parser.js +6 -335
- package/dist/esm/Parser.js.map +1 -1
- package/dist/esm/Placeholder.js +2 -2
- package/dist/esm/Placeholder.js.map +1 -1
- package/dist/esm/Platform.js +2 -2
- package/dist/esm/Platform.js.map +1 -1
- package/dist/esm/Render.js +1 -1
- package/dist/esm/Render.js.map +1 -1
- package/dist/esm/RenderContext.js +38 -17
- package/dist/esm/RenderContext.js.map +1 -1
- package/dist/esm/RenderTemplate.js +2 -12
- package/dist/esm/RenderTemplate.js.map +1 -1
- package/dist/esm/Template.js +24 -0
- package/dist/esm/Template.js.map +1 -1
- package/dist/esm/TemplateInstance.js +2 -2
- package/dist/esm/TemplateInstance.js.map +1 -1
- package/dist/esm/Test.js +20 -7
- package/dist/esm/Test.js.map +1 -1
- package/dist/esm/index.js +0 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/EventSource.js +91 -0
- package/dist/esm/internal/EventSource.js.map +1 -0
- package/dist/esm/internal/browser.js +12 -12
- package/dist/esm/internal/browser.js.map +1 -1
- package/dist/esm/internal/hydrate.js +45 -46
- package/dist/esm/internal/hydrate.js.map +1 -1
- package/dist/esm/internal/indexRefCounter.js +50 -2
- package/dist/esm/internal/indexRefCounter.js.map +1 -1
- package/dist/esm/internal/parser.js +84 -17
- package/dist/esm/internal/parser.js.map +1 -1
- package/dist/esm/internal/parts.js +110 -27
- package/dist/esm/internal/parts.js.map +1 -1
- package/dist/esm/internal/render.js +476 -58
- package/dist/esm/internal/render.js.map +1 -1
- package/dist/esm/internal/server.js +5 -4
- package/dist/esm/internal/server.js.map +1 -1
- package/package.json +10 -26
- package/src/Directive.ts +1 -1
- package/src/ElementRef.ts +18 -14
- package/src/ElementSource.ts +62 -47
- package/src/EventHandler.ts +1 -1
- package/src/Html.ts +58 -57
- package/src/HtmlChunk.ts +15 -1
- package/src/Hydrate.ts +1 -1
- package/src/Many.ts +53 -43
- package/src/Parser.ts +10 -453
- package/src/Part.ts +15 -3
- package/src/Placeholder.ts +4 -4
- package/src/Platform.ts +2 -2
- package/src/Render.ts +7 -2
- package/src/RenderContext.ts +49 -21
- package/src/RenderTemplate.ts +9 -54
- package/src/Renderable.ts +2 -1
- package/src/Template.ts +26 -0
- package/src/TemplateInstance.ts +9 -9
- package/src/Test.ts +40 -21
- package/src/index.ts +0 -4
- package/src/internal/EventSource.ts +153 -0
- package/src/internal/browser.ts +26 -25
- package/src/internal/hydrate.ts +68 -61
- package/src/internal/indexRefCounter.ts +63 -2
- package/src/internal/module-augmentation.ts +0 -4
- package/src/internal/parser.ts +92 -19
- package/src/internal/parts.ts +158 -73
- package/src/internal/render.ts +701 -89
- package/src/internal/server.ts +5 -3
- package/dist/cjs/Token.js +0 -270
- package/dist/cjs/Token.js.map +0 -1
- package/dist/cjs/Tokenizer.js +0 -18
- package/dist/cjs/Tokenizer.js.map +0 -1
- package/dist/cjs/internal/readAttribute.js +0 -34
- package/dist/cjs/internal/readAttribute.js.map +0 -1
- package/dist/cjs/internal/tokenizer.js +0 -264
- package/dist/cjs/internal/tokenizer.js.map +0 -1
- package/dist/dts/Token.d.ts +0 -202
- package/dist/dts/Token.d.ts.map +0 -1
- package/dist/dts/Tokenizer.d.ts +0 -6
- package/dist/dts/Tokenizer.d.ts.map +0 -1
- package/dist/dts/internal/readAttribute.d.ts +0 -9
- package/dist/dts/internal/readAttribute.d.ts.map +0 -1
- package/dist/dts/internal/tokenizer.d.ts +0 -3
- package/dist/dts/internal/tokenizer.d.ts.map +0 -1
- package/dist/esm/Token.js +0 -264
- package/dist/esm/Token.js.map +0 -1
- package/dist/esm/Tokenizer.js +0 -9
- package/dist/esm/Tokenizer.js.map +0 -1
- package/dist/esm/internal/readAttribute.js +0 -24
- package/dist/esm/internal/readAttribute.js.map +0 -1
- package/dist/esm/internal/tokenizer.js +0 -296
- package/dist/esm/internal/tokenizer.js.map +0 -1
- package/src/Token.ts +0 -269
- package/src/Tokenizer.ts +0 -10
- package/src/internal/readAttribute.ts +0 -28
- package/src/internal/tokenizer.ts +0 -338
|
@@ -1,45 +1,387 @@
|
|
|
1
1
|
import * as Fx from "@typed/fx/Fx";
|
|
2
|
-
import * as Subject from "@typed/fx/Subject";
|
|
3
2
|
import { TypeId } from "@typed/fx/TypeId";
|
|
4
3
|
import { persistent } from "@typed/wire";
|
|
5
4
|
import { Effect } from "effect";
|
|
5
|
+
import * as Context from "effect/Context";
|
|
6
6
|
import { replace } from "effect/ReadonlyArray";
|
|
7
|
+
import { Scope } from "effect/Scope";
|
|
7
8
|
import { isDirective } from "../Directive.js";
|
|
8
9
|
import * as ElementRef from "../ElementRef.js";
|
|
10
|
+
import * as ElementSource from "../ElementSource.js";
|
|
9
11
|
import * as EventHandler from "../EventHandler.js";
|
|
10
12
|
import { DomRenderEvent } from "../RenderEvent.js";
|
|
11
|
-
import { TemplateInstance } from "../TemplateInstance.js";
|
|
12
13
|
import { makeRenderNodePart } from "./browser.js";
|
|
14
|
+
import { makeEventSource } from "./EventSource.js";
|
|
13
15
|
import { HydrateContext } from "./HydrateContext.js";
|
|
14
|
-
import {
|
|
16
|
+
import { indexRefCounter2 } from "./indexRefCounter.js";
|
|
15
17
|
import { parse } from "./parser.js";
|
|
16
|
-
import { AttributePartImpl, BooleanPartImpl, ClassNamePartImpl, CommentPartImpl, DataPartImpl, EventPartImpl, PropertyPartImpl, RefPartImpl, SparseAttributePartImpl, SparseClassNamePartImpl, SparseCommentPartImpl, StaticTextImpl, TextPartImpl } from "./parts.js";
|
|
17
|
-
import { findPath } from "./utils.js";
|
|
18
|
+
import { AttributePartImpl, BooleanPartImpl, ClassNamePartImpl, CommentPartImpl, DataPartImpl, EventPartImpl, PropertiesPartImpl, PropertyPartImpl, RefPartImpl, SparseAttributePartImpl, SparseClassNamePartImpl, SparseCommentPartImpl, StaticTextImpl, TextPartImpl } from "./parts.js";
|
|
19
|
+
import { findHoleComment, findPath } from "./utils.js";
|
|
20
|
+
const RenderPartMap = {
|
|
21
|
+
"attr": (templatePart, node, ctx) => {
|
|
22
|
+
const { document, refCounter, renderContext, values } = ctx;
|
|
23
|
+
const element = node;
|
|
24
|
+
const attr = createAttribute(document, element, templatePart.name);
|
|
25
|
+
const renderable = values[templatePart.index];
|
|
26
|
+
let isSet = true;
|
|
27
|
+
const setValue = (value) => {
|
|
28
|
+
if (isNullOrUndefined(value)) {
|
|
29
|
+
element.removeAttribute(templatePart.name);
|
|
30
|
+
isSet = false;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
attr.value = String(value);
|
|
34
|
+
if (isSet === false) {
|
|
35
|
+
element.setAttributeNode(attr);
|
|
36
|
+
isSet = true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
return matchSettablePart(renderable, setValue, () => AttributePartImpl.browser(templatePart.index, element, templatePart.name, renderContext), (f) => Effect.zipRight(renderContext.queue.add(element, f), refCounter.release(templatePart.index)), () => ctx.expected++);
|
|
41
|
+
},
|
|
42
|
+
"boolean-part": (templatePart, node, ctx) => {
|
|
43
|
+
const { refCounter, renderContext, values } = ctx;
|
|
44
|
+
const element = node;
|
|
45
|
+
const renderable = values[templatePart.index];
|
|
46
|
+
const setValue = (value) => {
|
|
47
|
+
element.toggleAttribute(templatePart.name, isNullOrUndefined(value) ? false : Boolean(value));
|
|
48
|
+
};
|
|
49
|
+
return matchSettablePart(renderable, setValue, () => BooleanPartImpl.browser(templatePart.index, element, templatePart.name, renderContext), (f) => Effect.zipRight(renderContext.queue.add(element, f), refCounter.release(templatePart.index)), () => ctx.expected++);
|
|
50
|
+
},
|
|
51
|
+
"className-part": (templatePart, node, ctx) => {
|
|
52
|
+
const { refCounter, renderContext, values } = ctx;
|
|
53
|
+
const element = node;
|
|
54
|
+
const renderable = values[templatePart.index];
|
|
55
|
+
let classNames = new Set();
|
|
56
|
+
const setValue = (value) => {
|
|
57
|
+
if (isNullOrUndefined(value)) {
|
|
58
|
+
element.classList.remove(...classNames);
|
|
59
|
+
classNames.clear();
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
const newClassNames = new Set(Array.isArray(value) ? value : [String(value)]);
|
|
63
|
+
const { added, removed } = diffClassNames(classNames, newClassNames);
|
|
64
|
+
if (removed.length > 0) {
|
|
65
|
+
element.classList.remove(...removed);
|
|
66
|
+
}
|
|
67
|
+
if (added.length > 0)
|
|
68
|
+
element.classList.add(...added);
|
|
69
|
+
classNames = newClassNames;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
return matchSettablePart(renderable, setValue, () => ClassNamePartImpl.browser(templatePart.index, element, renderContext), (f) => Effect.zipRight(renderContext.queue.add(element, f), refCounter.release(templatePart.index)), () => ctx.expected++);
|
|
73
|
+
},
|
|
74
|
+
"comment-part": (templatePart, node, ctx) => {
|
|
75
|
+
const { refCounter, renderContext, values } = ctx;
|
|
76
|
+
const comment = findHoleComment(node, templatePart.index);
|
|
77
|
+
const renderable = values[templatePart.index];
|
|
78
|
+
const setValue = (value) => {
|
|
79
|
+
comment.textContent = isNullOrUndefined(value) ? "" : String(value);
|
|
80
|
+
};
|
|
81
|
+
return matchSettablePart(renderable, setValue, () => CommentPartImpl.browser(templatePart.index, comment, renderContext), (f) => Effect.zipRight(renderContext.queue.add(comment, f), refCounter.release(templatePart.index)), () => ctx.expected++);
|
|
82
|
+
},
|
|
83
|
+
"data": (templatePart, node, ctx) => {
|
|
84
|
+
const element = node;
|
|
85
|
+
const renderable = ctx.values[templatePart.index];
|
|
86
|
+
const previousKeys = new Set(Object.keys(element.dataset));
|
|
87
|
+
const setValue = (value) => {
|
|
88
|
+
if (isNullOrUndefined(value)) {
|
|
89
|
+
for (const key of previousKeys) {
|
|
90
|
+
delete element.dataset[key];
|
|
91
|
+
}
|
|
92
|
+
previousKeys.clear();
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
for (const key of previousKeys) {
|
|
96
|
+
if (!(key in value)) {
|
|
97
|
+
delete element.dataset[key];
|
|
98
|
+
previousKeys.delete(key);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
for (const key of Object.keys(value)) {
|
|
102
|
+
if (!previousKeys.has(key)) {
|
|
103
|
+
previousKeys.add(key);
|
|
104
|
+
}
|
|
105
|
+
element.dataset[key] = value[key] || "";
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
return matchSettablePart(renderable, setValue, () => DataPartImpl.browser(templatePart.index, element, ctx.renderContext), (f) => Effect.zipRight(ctx.renderContext.queue.add(element, f), ctx.refCounter.release(templatePart.index)), () => ctx.expected++);
|
|
110
|
+
},
|
|
111
|
+
"event": (templatePart, node, ctx) => {
|
|
112
|
+
const element = node;
|
|
113
|
+
const renderable = ctx.values[templatePart.index];
|
|
114
|
+
const handler = getEventHandler(renderable, ctx.context, ctx.onCause);
|
|
115
|
+
if (handler) {
|
|
116
|
+
ctx.eventSource.addEventListener(element, templatePart.name, handler);
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
},
|
|
120
|
+
"node": (templatePart, node, ctx) => {
|
|
121
|
+
const part = makeRenderNodePart(templatePart.index, node, ctx.renderContext, ctx.document, false);
|
|
122
|
+
ctx.expected++;
|
|
123
|
+
return handlePart(ctx.values[templatePart.index], (value) => Effect.zipRight(part.update(value), ctx.refCounter.release(templatePart.index)));
|
|
124
|
+
},
|
|
125
|
+
"property": (templatePart, node, ctx) => {
|
|
126
|
+
const element = node;
|
|
127
|
+
const renderable = ctx.values[templatePart.index];
|
|
128
|
+
const setValue = (value) => {
|
|
129
|
+
if (isNullOrUndefined(value)) {
|
|
130
|
+
delete element[templatePart.name];
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
;
|
|
134
|
+
element[templatePart.name] = value;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
return matchSettablePart(renderable, setValue, () => PropertyPartImpl.browser(templatePart.index, element, templatePart.name, ctx.renderContext), (f) => Effect.zipRight(ctx.renderContext.queue.add(element, f), ctx.refCounter.release(templatePart.index)), () => ctx.expected++);
|
|
138
|
+
},
|
|
139
|
+
"properties": (templatePart, node, ctx) => {
|
|
140
|
+
const renderable = ctx.values[templatePart.index];
|
|
141
|
+
if (isNullOrUndefined(renderable))
|
|
142
|
+
return null;
|
|
143
|
+
else if (Fx.isFx(renderable) || Effect.isEffect(renderable)) {
|
|
144
|
+
throw new Error(`Properties Part must utilize an Record of renderable values.`);
|
|
145
|
+
}
|
|
146
|
+
else if (typeof renderable === "object" && !Array.isArray(renderable)) {
|
|
147
|
+
const element = node;
|
|
148
|
+
const toggleBoolean = (key, value) => {
|
|
149
|
+
element.toggleAttribute(key, isNullOrUndefined(value) ? false : Boolean(value));
|
|
150
|
+
};
|
|
151
|
+
const setAttribute = (key, value) => {
|
|
152
|
+
if (isNullOrUndefined(value)) {
|
|
153
|
+
element.removeAttribute(key);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
element.setAttribute(key, String(value));
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
const setProperty = (key, value) => {
|
|
160
|
+
if (isNullOrUndefined(value)) {
|
|
161
|
+
delete element[key];
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
;
|
|
165
|
+
element[key] = value;
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
const effects = [];
|
|
169
|
+
// We need indexes to track async values that won't conflict
|
|
170
|
+
// with any other Parts, we can start end of the current values.length
|
|
171
|
+
// As there should only ever be exactly 1 properties part.
|
|
172
|
+
let i = ctx.values.length;
|
|
173
|
+
loop: for (const [key, value] of Object.entries(renderable)) {
|
|
174
|
+
const index = ++i;
|
|
175
|
+
switch (key[0]) {
|
|
176
|
+
case "?": {
|
|
177
|
+
const name = key.slice(1);
|
|
178
|
+
const eff = matchSettablePart(value, (value) => toggleBoolean(name, value), () => BooleanPartImpl.browser(index, element, name, ctx.renderContext), (f) => Effect.zipRight(ctx.renderContext.queue.add(element, f), ctx.refCounter.release(index)), () => ctx.expected++);
|
|
179
|
+
if (eff !== null) {
|
|
180
|
+
effects.push(eff);
|
|
181
|
+
}
|
|
182
|
+
continue loop;
|
|
183
|
+
}
|
|
184
|
+
case ".": {
|
|
185
|
+
const name = key.slice(1);
|
|
186
|
+
const eff = matchSettablePart(value, (value) => setProperty(name, value), () => PropertyPartImpl.browser(index, element, name, ctx.renderContext), (f) => Effect.zipRight(ctx.renderContext.queue.add(element, f), ctx.refCounter.release(index)), () => ctx.expected++);
|
|
187
|
+
if (eff !== null) {
|
|
188
|
+
effects.push(eff);
|
|
189
|
+
}
|
|
190
|
+
continue loop;
|
|
191
|
+
}
|
|
192
|
+
case "@": {
|
|
193
|
+
const name = key.slice(1);
|
|
194
|
+
const handler = getEventHandler(value, ctx.context, ctx.onCause);
|
|
195
|
+
if (handler) {
|
|
196
|
+
ctx.eventSource.addEventListener(element, name, handler);
|
|
197
|
+
}
|
|
198
|
+
continue loop;
|
|
199
|
+
}
|
|
200
|
+
case "o": {
|
|
201
|
+
if (key[1] === "n") {
|
|
202
|
+
const name = key.slice(2);
|
|
203
|
+
const handler = getEventHandler(value, ctx.context, ctx.onCause);
|
|
204
|
+
if (handler) {
|
|
205
|
+
ctx.eventSource.addEventListener(element, name, handler);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
continue loop;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const eff = matchSettablePart(value, (value) => setAttribute(key, value), () => AttributePartImpl.browser(index, element, key, ctx.renderContext), (f) => Effect.zipRight(ctx.renderContext.queue.add(element, f), ctx.refCounter.release(index)), () => ctx.expected++);
|
|
212
|
+
if (eff !== null) {
|
|
213
|
+
effects.push(eff);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return effects;
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
"ref": (templatePart, node, ctx) => {
|
|
223
|
+
const element = node;
|
|
224
|
+
const renderable = ctx.values[templatePart.index];
|
|
225
|
+
if (isDirective(renderable)) {
|
|
226
|
+
return renderable(new RefPartImpl(ElementSource.fromElement(element), templatePart.index));
|
|
227
|
+
}
|
|
228
|
+
else if (ElementRef.isElementRef(renderable)) {
|
|
229
|
+
return ElementRef.set(renderable, element);
|
|
230
|
+
}
|
|
231
|
+
return null;
|
|
232
|
+
},
|
|
233
|
+
"sparse-attr": (templatePart, node, ctx) => {
|
|
234
|
+
const values = Array.from({ length: templatePart.nodes.length }, () => "");
|
|
235
|
+
const element = node;
|
|
236
|
+
const attr = createAttribute(ctx.document, element, templatePart.name);
|
|
237
|
+
const setValue = (value, index) => Effect.suspend(() => {
|
|
238
|
+
values[index] = value || "";
|
|
239
|
+
return ctx.renderContext.queue.add(element, () => attr.value = values.join(""));
|
|
240
|
+
});
|
|
241
|
+
const effects = [];
|
|
242
|
+
for (let i = 0; i < templatePart.nodes.length; ++i) {
|
|
243
|
+
const node = templatePart.nodes[i];
|
|
244
|
+
if (node._tag === "text") {
|
|
245
|
+
values[i] = node.value;
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
const renderable = ctx.values[node.index];
|
|
249
|
+
const index = i;
|
|
250
|
+
const effect = matchSettablePart(renderable, (value) => setValue(value, index), () => new AttributePartImpl(templatePart.name, node.index, ({ value }) => setValue(value, index), null), (f) => Effect.zipRight(ctx.renderContext.queue.add(element, f), ctx.refCounter.release(node.index)), () => ctx.expected++);
|
|
251
|
+
if (effect !== null) {
|
|
252
|
+
effects.push(effect);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return effects;
|
|
257
|
+
},
|
|
258
|
+
"sparse-class-name": (templatePart, node, ctx) => {
|
|
259
|
+
const element = node;
|
|
260
|
+
const effects = templatePart.nodes.flatMap((node) => {
|
|
261
|
+
if (node._tag === "text") {
|
|
262
|
+
const split = splitClassNames(node.value);
|
|
263
|
+
if (split.length > 0)
|
|
264
|
+
element.classList.add(...split);
|
|
265
|
+
return [];
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
const eff = RenderPartMap[node._tag](node, element, ctx);
|
|
269
|
+
if (eff === null)
|
|
270
|
+
return [];
|
|
271
|
+
return Array.isArray(eff) ? eff : [eff];
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
return effects;
|
|
275
|
+
},
|
|
276
|
+
"sparse-comment": (templatePart, node, ctx) => {
|
|
277
|
+
const values = Array.from({ length: templatePart.nodes.length }, () => "");
|
|
278
|
+
const comment = node;
|
|
279
|
+
const setValue = (value, index) => Effect.suspend(() => {
|
|
280
|
+
values[index] = value || "";
|
|
281
|
+
return ctx.renderContext.queue.add(comment, () => comment.textContent = values.join(""));
|
|
282
|
+
});
|
|
283
|
+
const effects = [];
|
|
284
|
+
for (let i = 0; i < templatePart.nodes.length; ++i) {
|
|
285
|
+
const node = templatePart.nodes[i];
|
|
286
|
+
if (node._tag === "text") {
|
|
287
|
+
values[i] = node.value;
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
const renderable = ctx.values[node.index];
|
|
291
|
+
const index = i;
|
|
292
|
+
const effect = matchSettablePart(renderable, (value) => setValue(value, index), () => new CommentPartImpl(node.index, ({ value }) => setValue(value, index), null), (f) => Effect.zipRight(ctx.renderContext.queue.add(comment, f), ctx.refCounter.release(node.index)), () => ctx.expected++);
|
|
293
|
+
if (effect !== null) {
|
|
294
|
+
effects.push(effect);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return effects;
|
|
299
|
+
},
|
|
300
|
+
"text-part": (templatePart, node, ctx) => {
|
|
301
|
+
const part = TextPartImpl.browser(ctx.document, templatePart.index, node, ctx.renderContext);
|
|
302
|
+
ctx.expected++;
|
|
303
|
+
return handlePart(ctx.values[templatePart.index], (value) => Effect.zipRight(part.update(value), ctx.refCounter.release(templatePart.index)));
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
const SPACE_REGEXP = /\s+/g;
|
|
307
|
+
function splitClassNames(value) {
|
|
308
|
+
return value.split(SPACE_REGEXP).flatMap((a) => {
|
|
309
|
+
const trimmed = a.trim();
|
|
310
|
+
return trimmed.length > 0 ? [trimmed] : [];
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
function isNullOrUndefined(value) {
|
|
314
|
+
return value === null || value === undefined;
|
|
315
|
+
}
|
|
316
|
+
function diffClassNames(oldClassNames, newClassNames) {
|
|
317
|
+
const added = [];
|
|
318
|
+
const removed = [];
|
|
319
|
+
for (const className of oldClassNames) {
|
|
320
|
+
if (!newClassNames.has(className)) {
|
|
321
|
+
removed.push(className);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
for (const className of newClassNames) {
|
|
325
|
+
if (!oldClassNames.has(className) && className.trim()) {
|
|
326
|
+
added.push(className);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return { added, removed };
|
|
330
|
+
}
|
|
18
331
|
/**
|
|
19
332
|
* Here for "standard" browser rendering, a TemplateInstance is effectively a live
|
|
20
333
|
* view into the contents rendered by the Template.
|
|
21
334
|
*/
|
|
22
|
-
export const renderTemplate = (document,
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const entry = getBrowserEntry(document, ctx, templateStrings);
|
|
27
|
-
const content = document.importNode(entry.content, true); // Clone our template
|
|
28
|
-
const parts = yield* _(buildParts(document, ctx, entry.template, content, elementRef, errors.onFailure, false)); // Build runtime-variant of parts with our content.
|
|
29
|
-
// If there are parts we need to render them before constructing our Wire
|
|
30
|
-
if (parts.length > 0) {
|
|
31
|
-
const refCounter = yield* _(indexRefCounter(parts.length));
|
|
32
|
-
// Do the work
|
|
33
|
-
yield* _(renderValues(values, parts, refCounter, errors.onFailure));
|
|
34
|
-
// Wait for initial work to be completed
|
|
35
|
-
yield* _(refCounter.wait);
|
|
335
|
+
export const renderTemplate = (document, renderContext) => (templateStrings, values) => {
|
|
336
|
+
const entry = getBrowserEntry(document, renderContext, templateStrings);
|
|
337
|
+
if (values.length === 0) {
|
|
338
|
+
return Fx.sync(() => DomRenderEvent(persistent(document.importNode(entry.content, true))));
|
|
36
339
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
340
|
+
return Fx.make((sink) => {
|
|
341
|
+
return Effect.gen(function* (_) {
|
|
342
|
+
const content = document.importNode(entry.content, true);
|
|
343
|
+
const context = yield* _(Effect.context());
|
|
344
|
+
const refCounter = yield* _(indexRefCounter2());
|
|
345
|
+
const ctx = {
|
|
346
|
+
context,
|
|
347
|
+
document,
|
|
348
|
+
eventSource: makeEventSource(),
|
|
349
|
+
expected: 0,
|
|
350
|
+
refCounter,
|
|
351
|
+
renderContext,
|
|
352
|
+
onCause: sink.onFailure,
|
|
353
|
+
values
|
|
354
|
+
};
|
|
355
|
+
// Connect our interpolated values to our template parts
|
|
356
|
+
const effects = [];
|
|
357
|
+
for (const [part, path] of entry.template.parts) {
|
|
358
|
+
const eff = RenderPartMap[part._tag](part, findPath(content, path), ctx);
|
|
359
|
+
if (eff !== null) {
|
|
360
|
+
effects.push(...(Array.isArray(eff) ? eff : [eff]));
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
// Fork any effects necessary
|
|
364
|
+
if (effects.length > 0) {
|
|
365
|
+
yield* _(Effect.forkAll(effects));
|
|
366
|
+
}
|
|
367
|
+
// If there's anything to wait on and it's not already done, wait for an initial value
|
|
368
|
+
// for all asynchronous sources.
|
|
369
|
+
if (ctx.expected > 0 && (yield* _(refCounter.expect(ctx.expected)))) {
|
|
370
|
+
yield* _(refCounter.wait);
|
|
371
|
+
}
|
|
372
|
+
// Create a persistent wire from our content
|
|
373
|
+
const wire = persistent(content);
|
|
374
|
+
// Set the element when it is ready
|
|
375
|
+
yield* _(ctx.eventSource.setup(wire, Context.get(context, Scope)));
|
|
376
|
+
// Emity our DomRenderEvent
|
|
377
|
+
yield* _(sink.onSuccess(DomRenderEvent(wire)));
|
|
378
|
+
// Ensure our templates last forever in the DOM environment
|
|
379
|
+
// so event listeners are kept attached to the current Scope.
|
|
380
|
+
yield* _(Effect.never);
|
|
381
|
+
});
|
|
382
|
+
});
|
|
383
|
+
};
|
|
384
|
+
export function renderValues(values, parts, refCounter, ctx, makeHydrateContext) {
|
|
43
385
|
return Effect.all(parts.map((part, index) => {
|
|
44
386
|
switch (part._tag) {
|
|
45
387
|
case "sparse/attribute":
|
|
@@ -48,7 +390,7 @@ export function renderValues(values, parts, refCounter, onCause, makeHydrateCont
|
|
|
48
390
|
return renderSparsePart(values, part, refCounter);
|
|
49
391
|
}
|
|
50
392
|
default:
|
|
51
|
-
return renderPart(values, part, refCounter,
|
|
393
|
+
return renderPart(values, part, refCounter, ctx, makeHydrateContext ? () => makeHydrateContext(index) : undefined);
|
|
52
394
|
}
|
|
53
395
|
}));
|
|
54
396
|
}
|
|
@@ -56,37 +398,47 @@ export function renderSparsePart(values, part, refCounter) {
|
|
|
56
398
|
const indexes = part.parts.flatMap((p) => p._tag === "static/text" ? [] : [p.index]);
|
|
57
399
|
return Effect.forkScoped(Fx.observe(unwrapSparsePartRenderables(part.parts.map((p) => p._tag === "static/text" ? Fx.succeed(p.value) : values[p.index]), part), (value) => Effect.tap(part.update(value), () => Effect.forEach(indexes, (a) => refCounter.release(a)))));
|
|
58
400
|
}
|
|
59
|
-
export function renderPart(values, part, refCounter,
|
|
401
|
+
export function renderPart(values, part, refCounter, ctx, hydrateCtx) {
|
|
60
402
|
const partIndex = part.index;
|
|
61
403
|
const renderable = values[partIndex];
|
|
404
|
+
if (renderable === null || renderable === undefined)
|
|
405
|
+
return refCounter.release(partIndex);
|
|
62
406
|
if (isDirective(renderable)) {
|
|
63
|
-
return renderable(part).pipe(Effect.
|
|
407
|
+
return renderable(part).pipe(Effect.flatMap(() => refCounter.release(partIndex)), Effect.forkScoped);
|
|
64
408
|
}
|
|
65
409
|
else if (part._tag === "ref") {
|
|
66
410
|
return refCounter.release(partIndex);
|
|
67
411
|
}
|
|
68
412
|
else if (part._tag === "event") {
|
|
69
|
-
|
|
413
|
+
const handler = getEventHandler(renderable, ctx, part.onCause);
|
|
414
|
+
if (handler) {
|
|
415
|
+
part.addEventListener(handler);
|
|
416
|
+
}
|
|
417
|
+
return refCounter.release(partIndex);
|
|
70
418
|
}
|
|
71
419
|
else if (part._tag === "node" && hydrateCtx) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
420
|
+
return handlePart(renderable, (value) => Effect.flatMap(part.update(value), () => refCounter.release(partIndex))).pipe(HydrateContext.provide(hydrateCtx()), Effect.forkScoped);
|
|
421
|
+
}
|
|
422
|
+
else if (part._tag === "properties") {
|
|
423
|
+
return handlePropertiesPart(renderable, part, refCounter);
|
|
75
424
|
}
|
|
76
425
|
else {
|
|
77
|
-
|
|
78
|
-
if (renderable === null || renderable === undefined)
|
|
79
|
-
return refCounter.release(partIndex);
|
|
80
|
-
return handlePart(values[partIndex], (value) => Effect.tap(part.update(value), () => refCounter.release(partIndex)));
|
|
426
|
+
return handlePart(renderable, (value) => Effect.flatMap(part.update(value), () => refCounter.release(partIndex)));
|
|
81
427
|
}
|
|
82
428
|
}
|
|
83
|
-
function
|
|
429
|
+
function handlePropertiesPart(renderable, part, refCounter) {
|
|
430
|
+
if (renderable && typeof renderable === "object") {
|
|
431
|
+
return handlePart(Fx.struct(Object.fromEntries(Object.entries(renderable).map(([k, v]) => [k, unwrapRenderable(v)]))), (value) => Effect.tap(part.update(value), () => refCounter.release(part.index)));
|
|
432
|
+
}
|
|
433
|
+
return Effect.succeed(void 0);
|
|
434
|
+
}
|
|
435
|
+
function getEventHandler(renderable, ctx, onCause) {
|
|
84
436
|
if (renderable && typeof renderable === "object") {
|
|
85
437
|
if (EventHandler.EventHandlerTypeId in renderable) {
|
|
86
|
-
return EventHandler.make((ev) => Effect.catchAllCause(renderable.handler(ev), onCause), renderable.options);
|
|
438
|
+
return EventHandler.make((ev) => Effect.provide(Effect.catchAllCause(renderable.handler(ev), onCause), ctx), renderable.options);
|
|
87
439
|
}
|
|
88
440
|
else if (Effect.EffectTypeId in renderable) {
|
|
89
|
-
return EventHandler.make(() => Effect.catchAllCause(renderable, onCause));
|
|
441
|
+
return EventHandler.make(() => Effect.provide(Effect.catchAllCause(renderable, onCause), ctx));
|
|
90
442
|
}
|
|
91
443
|
}
|
|
92
444
|
return null;
|
|
@@ -100,7 +452,7 @@ function handlePart(renderable, update) {
|
|
|
100
452
|
else if (Array.isArray(renderable)) {
|
|
101
453
|
return renderable.length === 0
|
|
102
454
|
? update(null)
|
|
103
|
-
: Effect.forkScoped(Fx.observe(Fx.
|
|
455
|
+
: Effect.forkScoped(Fx.observe(Fx.tuple(renderable.map(unwrapRenderable)), update));
|
|
104
456
|
}
|
|
105
457
|
else if (TypeId in renderable) {
|
|
106
458
|
return Effect.forkScoped(Fx.observe(renderable, update));
|
|
@@ -122,7 +474,7 @@ function unwrapRenderable(renderable) {
|
|
|
122
474
|
if (renderable === null || renderable === undefined)
|
|
123
475
|
return Fx.succeed(null);
|
|
124
476
|
else if (Array.isArray(renderable)) {
|
|
125
|
-
return renderable.length === 0 ? Fx.succeed(null) : Fx.
|
|
477
|
+
return renderable.length === 0 ? Fx.succeed(null) : Fx.tuple(renderable.map(unwrapRenderable));
|
|
126
478
|
}
|
|
127
479
|
else if (TypeId in renderable) {
|
|
128
480
|
return renderable;
|
|
@@ -138,7 +490,7 @@ function unwrapRenderable(renderable) {
|
|
|
138
490
|
}
|
|
139
491
|
}
|
|
140
492
|
function unwrapSparsePartRenderables(renderables, part) {
|
|
141
|
-
return Fx.
|
|
493
|
+
return Fx.tuple(
|
|
142
494
|
// @ts-ignore type too deep
|
|
143
495
|
renderables.map((renderable, i) => {
|
|
144
496
|
const p = part.parts[i];
|
|
@@ -196,29 +548,31 @@ export function getBrowserEntry(document, ctx, templateStrings) {
|
|
|
196
548
|
return cached;
|
|
197
549
|
}
|
|
198
550
|
}
|
|
199
|
-
export function buildParts(document, ctx, template, content,
|
|
200
|
-
return
|
|
551
|
+
export function buildParts(document, ctx, template, content, eventSource, onCause, isHydrating) {
|
|
552
|
+
return template.parts.map(([part, path]) => buildPartWithNode(document, ctx, part, findPath(content, path), eventSource, onCause, isHydrating));
|
|
201
553
|
}
|
|
202
|
-
function buildPartWithNode(document, ctx, part, node,
|
|
554
|
+
function buildPartWithNode(document, ctx, part, node, eventSource, onCause, isHydrating) {
|
|
203
555
|
switch (part._tag) {
|
|
204
556
|
case "attr":
|
|
205
|
-
return
|
|
557
|
+
return AttributePartImpl.browser(part.index, node, part.name, ctx);
|
|
206
558
|
case "boolean-part":
|
|
207
|
-
return
|
|
559
|
+
return BooleanPartImpl.browser(part.index, node, part.name, ctx);
|
|
208
560
|
case "className-part":
|
|
209
|
-
return
|
|
561
|
+
return ClassNamePartImpl.browser(part.index, node, ctx);
|
|
210
562
|
case "comment-part":
|
|
211
|
-
return
|
|
563
|
+
return CommentPartImpl.browser(part.index, node, ctx);
|
|
212
564
|
case "data":
|
|
213
|
-
return
|
|
565
|
+
return DataPartImpl.browser(part.index, node, ctx);
|
|
214
566
|
case "event":
|
|
215
|
-
return EventPartImpl
|
|
567
|
+
return new EventPartImpl(part.name, part.index, ElementSource.fromElement(node), onCause, (handler) => eventSource.addEventListener(node, part.name, handler));
|
|
216
568
|
case "node":
|
|
217
|
-
return
|
|
569
|
+
return makeRenderNodePart(part.index, node, ctx, document, isHydrating);
|
|
218
570
|
case "property":
|
|
219
|
-
return
|
|
571
|
+
return PropertyPartImpl.browser(part.index, node, part.name, ctx);
|
|
572
|
+
case "properties":
|
|
573
|
+
return PropertiesPartImpl.browser(part.index, node, ctx);
|
|
220
574
|
case "ref":
|
|
221
|
-
return
|
|
575
|
+
return new RefPartImpl(ElementSource.fromElement(node), part.index);
|
|
222
576
|
case "sparse-attr": {
|
|
223
577
|
const parts = Array(part.nodes.length);
|
|
224
578
|
const sparse = SparseAttributePartImpl.browser(part.name, parts, node, ctx);
|
|
@@ -232,7 +586,7 @@ function buildPartWithNode(document, ctx, part, node, ref, onCause, isHydrating)
|
|
|
232
586
|
parts.push(new AttributePartImpl(node.name, node.index, ({ value }) => sparse.update(replace(sparse.value, i, value || "")), sparse.value[i]));
|
|
233
587
|
}
|
|
234
588
|
}
|
|
235
|
-
return
|
|
589
|
+
return sparse;
|
|
236
590
|
}
|
|
237
591
|
case "sparse-class-name": {
|
|
238
592
|
const parts = [];
|
|
@@ -249,7 +603,7 @@ function buildPartWithNode(document, ctx, part, node, ref, onCause, isHydrating)
|
|
|
249
603
|
parts.push(new ClassNamePartImpl(node.index, ({ value }) => sparse.update(replace(sparse.value, i, value || "")), []));
|
|
250
604
|
}
|
|
251
605
|
}
|
|
252
|
-
return
|
|
606
|
+
return sparse;
|
|
253
607
|
}
|
|
254
608
|
case "sparse-comment": {
|
|
255
609
|
const parts = Array(part.nodes.length);
|
|
@@ -264,10 +618,10 @@ function buildPartWithNode(document, ctx, part, node, ref, onCause, isHydrating)
|
|
|
264
618
|
parts.push(new CommentPartImpl(node.index, ({ value }) => sparse.update(replace(sparse.value, i, value || "")), sparse.value[i]));
|
|
265
619
|
}
|
|
266
620
|
}
|
|
267
|
-
return
|
|
621
|
+
return sparse;
|
|
268
622
|
}
|
|
269
623
|
case "text-part":
|
|
270
|
-
return
|
|
624
|
+
return TextPartImpl.browser(document, part.index, node, ctx);
|
|
271
625
|
}
|
|
272
626
|
}
|
|
273
627
|
export function buildTemplate(document, { nodes }) {
|
|
@@ -293,6 +647,33 @@ function buildNode(document, node, isSvgContext) {
|
|
|
293
647
|
case "comment-part":
|
|
294
648
|
case "node":
|
|
295
649
|
return document.createComment(`hole${node.index}`);
|
|
650
|
+
case "doctype":
|
|
651
|
+
return document.implementation.createDocumentType(node.name, docTypeNameToPublicId(node.name), docTypeNameToSystemId(node.name));
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
function docTypeNameToPublicId(name) {
|
|
655
|
+
switch (name) {
|
|
656
|
+
case "html":
|
|
657
|
+
return "-//W3C//DTD HTML 4.01//EN";
|
|
658
|
+
case "svg":
|
|
659
|
+
return "-//W3C//DTD SVG 1.1//EN";
|
|
660
|
+
case "math":
|
|
661
|
+
return "-//W3C//DTD MathML 2.0//EN";
|
|
662
|
+
default:
|
|
663
|
+
return "";
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
function docTypeNameToSystemId(name) {
|
|
667
|
+
switch (name) {
|
|
668
|
+
// HTML5
|
|
669
|
+
case "html":
|
|
670
|
+
return "http://www.w3.org/TR/html4/strict.dtd";
|
|
671
|
+
case "svg":
|
|
672
|
+
return "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";
|
|
673
|
+
case "math":
|
|
674
|
+
return "http://www.w3.org/Math/DTD/mathml2/mathml2.dtd";
|
|
675
|
+
default:
|
|
676
|
+
return "";
|
|
296
677
|
}
|
|
297
678
|
}
|
|
298
679
|
const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
@@ -326,4 +707,41 @@ function buildTextChild(document, node) {
|
|
|
326
707
|
}
|
|
327
708
|
return document.createComment(`hole${node.index}`);
|
|
328
709
|
}
|
|
710
|
+
function createAttribute(document, element, name) {
|
|
711
|
+
return element.getAttributeNode(name) ?? document.createAttribute(name);
|
|
712
|
+
}
|
|
713
|
+
function matchSettablePart(renderable, setValue, makePart, schedule, expect) {
|
|
714
|
+
return matchRenderable(renderable, {
|
|
715
|
+
Fx: (fx) => {
|
|
716
|
+
expect();
|
|
717
|
+
return Fx.observe(fx, (a) => schedule(() => setValue(a)));
|
|
718
|
+
},
|
|
719
|
+
Effect: (effect) => {
|
|
720
|
+
expect();
|
|
721
|
+
return Effect.flatMap(effect, (a) => schedule(() => setValue(a)));
|
|
722
|
+
},
|
|
723
|
+
Directive: (directive) => {
|
|
724
|
+
expect();
|
|
725
|
+
return directive(makePart());
|
|
726
|
+
},
|
|
727
|
+
Otherwise: (otherwise) => {
|
|
728
|
+
setValue(otherwise);
|
|
729
|
+
return null;
|
|
730
|
+
}
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
function matchRenderable(renderable, matches) {
|
|
734
|
+
if (Fx.isFx(renderable)) {
|
|
735
|
+
return matches.Fx(renderable);
|
|
736
|
+
}
|
|
737
|
+
else if (Effect.isEffect(renderable)) {
|
|
738
|
+
return matches.Effect(renderable);
|
|
739
|
+
}
|
|
740
|
+
else if (isDirective(renderable)) {
|
|
741
|
+
return matches.Directive(renderable);
|
|
742
|
+
}
|
|
743
|
+
else {
|
|
744
|
+
return matches.Otherwise(renderable);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
329
747
|
//# sourceMappingURL=render.js.map
|