@thomas-siegfried/tapout 0.0.1 → 0.0.2
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/LICENSE +21 -21
- package/README.md +1205 -1205
- package/package.json +55 -55
- package/src/applyBindings.ts +372 -372
- package/src/arrayToDomMapping.ts +300 -300
- package/src/attributeInterpolationMarkup.ts +91 -91
- package/src/bindingContext.ts +207 -207
- package/src/bindingEvent.ts +198 -198
- package/src/bindingProvider.ts +260 -260
- package/src/bindings.ts +963 -963
- package/src/compareArrays.ts +122 -122
- package/src/componentBinding.ts +318 -318
- package/src/componentDecorator.ts +62 -62
- package/src/components.ts +367 -367
- package/src/computed.ts +439 -439
- package/src/configure.ts +52 -52
- package/src/controlFlowBindings.ts +206 -206
- package/src/core.ts +60 -60
- package/src/decorators.ts +407 -407
- package/src/dependencyDetection.ts +76 -76
- package/src/disposable.ts +36 -36
- package/src/domData.ts +42 -42
- package/src/domNodeDisposal.ts +94 -94
- package/src/effects.ts +29 -29
- package/src/event.ts +173 -173
- package/src/expressionRewriting.ts +219 -219
- package/src/extenders.ts +102 -102
- package/src/filters.ts +91 -91
- package/src/index.ts +150 -150
- package/src/interpolationMarkup.ts +130 -130
- package/src/memoization.ts +71 -71
- package/src/namespacedBindings.ts +132 -132
- package/src/observable.ts +48 -48
- package/src/observableArray.ts +397 -397
- package/src/options.ts +25 -25
- package/src/selectExtensions.ts +68 -68
- package/src/slotBinding.ts +84 -84
- package/src/subscribable.ts +266 -266
- package/src/tasks.ts +79 -79
- package/src/templateEngine.ts +108 -108
- package/src/templateRendering.ts +399 -399
- package/src/templateRewriting.ts +94 -94
- package/src/templateSources.ts +134 -134
- package/src/utils.ts +123 -123
- package/src/utilsDom.ts +87 -87
- package/src/virtualElements.ts +153 -153
- package/src/wireParams.ts +49 -49
package/src/virtualElements.ts
CHANGED
|
@@ -1,153 +1,153 @@
|
|
|
1
|
-
import { domDataGet, domDataSet } from './domData.js';
|
|
2
|
-
import { removeNode } from './domNodeDisposal.js';
|
|
3
|
-
|
|
4
|
-
const startCommentRegex = /^\s*tap(?:\s+([\s\S]+))?\s*$/;
|
|
5
|
-
const endCommentRegex = /^\s*\/tap\s*$/;
|
|
6
|
-
const matchedEndCommentDataKey = '__tap_matchedEndComment__';
|
|
7
|
-
|
|
8
|
-
export const allowedVirtualElementBindings: Record<string, boolean> = {};
|
|
9
|
-
|
|
10
|
-
export function isStartComment(node: Node): boolean {
|
|
11
|
-
return node.nodeType === 8 && startCommentRegex.test(node.nodeValue || '');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function isEndComment(node: Node): boolean {
|
|
15
|
-
return node.nodeType === 8 && endCommentRegex.test(node.nodeValue || '');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function isUnmatchedEndComment(node: Node): boolean {
|
|
19
|
-
return isEndComment(node) && !domDataGet(node, matchedEndCommentDataKey);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function getVirtualChildren(startComment: Node, allowUnbalanced?: boolean): Node[] | null {
|
|
23
|
-
let currentNode = startComment.nextSibling;
|
|
24
|
-
let depth = 1;
|
|
25
|
-
const children: Node[] = [];
|
|
26
|
-
while (currentNode) {
|
|
27
|
-
if (isEndComment(currentNode)) {
|
|
28
|
-
domDataSet(currentNode, matchedEndCommentDataKey, true);
|
|
29
|
-
depth--;
|
|
30
|
-
if (depth === 0) return children;
|
|
31
|
-
}
|
|
32
|
-
children.push(currentNode);
|
|
33
|
-
if (isStartComment(currentNode)) depth++;
|
|
34
|
-
currentNode = currentNode.nextSibling;
|
|
35
|
-
}
|
|
36
|
-
if (!allowUnbalanced) {
|
|
37
|
-
throw new Error('Cannot find closing comment tag to match: ' + startComment.nodeValue);
|
|
38
|
-
}
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function getMatchingEndComment(startComment: Node, allowUnbalanced?: boolean): Node | null {
|
|
43
|
-
const allVirtualChildren = getVirtualChildren(startComment, allowUnbalanced);
|
|
44
|
-
if (allVirtualChildren) {
|
|
45
|
-
if (allVirtualChildren.length > 0) {
|
|
46
|
-
return allVirtualChildren[allVirtualChildren.length - 1].nextSibling;
|
|
47
|
-
}
|
|
48
|
-
return startComment.nextSibling;
|
|
49
|
-
}
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function virtualChildNodes(node: Node): Node[] | NodeListOf<ChildNode> {
|
|
54
|
-
return isStartComment(node) ? getVirtualChildren(node)! : node.childNodes;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function virtualEmptyNode(node: Node): void {
|
|
58
|
-
if (!isStartComment(node)) {
|
|
59
|
-
while (node.firstChild) {
|
|
60
|
-
removeNode(node.firstChild);
|
|
61
|
-
}
|
|
62
|
-
} else {
|
|
63
|
-
const children = getVirtualChildren(node)!;
|
|
64
|
-
for (let i = 0; i < children.length; i++) {
|
|
65
|
-
removeNode(children[i]);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export function virtualSetChildren(node: Node, childNodes: Node[]): void {
|
|
71
|
-
if (!isStartComment(node)) {
|
|
72
|
-
while (node.firstChild) {
|
|
73
|
-
removeNode(node.firstChild);
|
|
74
|
-
}
|
|
75
|
-
for (let i = 0; i < childNodes.length; i++) {
|
|
76
|
-
node.appendChild(childNodes[i]);
|
|
77
|
-
}
|
|
78
|
-
} else {
|
|
79
|
-
virtualEmptyNode(node);
|
|
80
|
-
const endCommentNode = node.nextSibling!;
|
|
81
|
-
for (let i = 0; i < childNodes.length; i++) {
|
|
82
|
-
endCommentNode.parentNode!.insertBefore(childNodes[i], endCommentNode);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export function virtualPrepend(containerNode: Node, nodeToPrepend: Node): void {
|
|
88
|
-
let insertBeforeNode: Node | null;
|
|
89
|
-
let parent: Node;
|
|
90
|
-
|
|
91
|
-
if (isStartComment(containerNode)) {
|
|
92
|
-
insertBeforeNode = containerNode.nextSibling;
|
|
93
|
-
parent = containerNode.parentNode!;
|
|
94
|
-
} else {
|
|
95
|
-
insertBeforeNode = containerNode.firstChild;
|
|
96
|
-
parent = containerNode;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (!insertBeforeNode) {
|
|
100
|
-
parent.appendChild(nodeToPrepend);
|
|
101
|
-
} else {
|
|
102
|
-
parent.insertBefore(nodeToPrepend, insertBeforeNode);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export function virtualInsertAfter(containerNode: Node, nodeToInsert: Node, insertAfterNode: Node | null): void {
|
|
107
|
-
if (!insertAfterNode) {
|
|
108
|
-
virtualPrepend(containerNode, nodeToInsert);
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const insertBeforeNode = insertAfterNode.nextSibling;
|
|
113
|
-
const parent = isStartComment(containerNode) ? containerNode.parentNode! : containerNode;
|
|
114
|
-
|
|
115
|
-
if (!insertBeforeNode) {
|
|
116
|
-
parent.appendChild(nodeToInsert);
|
|
117
|
-
} else {
|
|
118
|
-
parent.insertBefore(nodeToInsert, insertBeforeNode);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export function virtualFirstChild(node: Node): Node | null {
|
|
123
|
-
if (!isStartComment(node)) {
|
|
124
|
-
const first = node.firstChild;
|
|
125
|
-
if (first && isEndComment(first)) {
|
|
126
|
-
return first.nextSibling;
|
|
127
|
-
}
|
|
128
|
-
return first;
|
|
129
|
-
}
|
|
130
|
-
if (!node.nextSibling || isEndComment(node.nextSibling)) {
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
return node.nextSibling;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export function virtualNextSibling(node: Node): Node | null {
|
|
137
|
-
if (isStartComment(node)) {
|
|
138
|
-
node = getMatchingEndComment(node)!;
|
|
139
|
-
}
|
|
140
|
-
if (node.nextSibling && isEndComment(node.nextSibling)) {
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
return node.nextSibling;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
export function hasBindingValue(node: Node): boolean {
|
|
147
|
-
return isStartComment(node);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export function virtualNodeBindingValue(node: Node): string | null {
|
|
151
|
-
const match = (node.nodeValue || '').match(startCommentRegex);
|
|
152
|
-
return match ? match[1]?.trim() ?? null : null;
|
|
153
|
-
}
|
|
1
|
+
import { domDataGet, domDataSet } from './domData.js';
|
|
2
|
+
import { removeNode } from './domNodeDisposal.js';
|
|
3
|
+
|
|
4
|
+
const startCommentRegex = /^\s*tap(?:\s+([\s\S]+))?\s*$/;
|
|
5
|
+
const endCommentRegex = /^\s*\/tap\s*$/;
|
|
6
|
+
const matchedEndCommentDataKey = '__tap_matchedEndComment__';
|
|
7
|
+
|
|
8
|
+
export const allowedVirtualElementBindings: Record<string, boolean> = {};
|
|
9
|
+
|
|
10
|
+
export function isStartComment(node: Node): boolean {
|
|
11
|
+
return node.nodeType === 8 && startCommentRegex.test(node.nodeValue || '');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function isEndComment(node: Node): boolean {
|
|
15
|
+
return node.nodeType === 8 && endCommentRegex.test(node.nodeValue || '');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function isUnmatchedEndComment(node: Node): boolean {
|
|
19
|
+
return isEndComment(node) && !domDataGet(node, matchedEndCommentDataKey);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function getVirtualChildren(startComment: Node, allowUnbalanced?: boolean): Node[] | null {
|
|
23
|
+
let currentNode = startComment.nextSibling;
|
|
24
|
+
let depth = 1;
|
|
25
|
+
const children: Node[] = [];
|
|
26
|
+
while (currentNode) {
|
|
27
|
+
if (isEndComment(currentNode)) {
|
|
28
|
+
domDataSet(currentNode, matchedEndCommentDataKey, true);
|
|
29
|
+
depth--;
|
|
30
|
+
if (depth === 0) return children;
|
|
31
|
+
}
|
|
32
|
+
children.push(currentNode);
|
|
33
|
+
if (isStartComment(currentNode)) depth++;
|
|
34
|
+
currentNode = currentNode.nextSibling;
|
|
35
|
+
}
|
|
36
|
+
if (!allowUnbalanced) {
|
|
37
|
+
throw new Error('Cannot find closing comment tag to match: ' + startComment.nodeValue);
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function getMatchingEndComment(startComment: Node, allowUnbalanced?: boolean): Node | null {
|
|
43
|
+
const allVirtualChildren = getVirtualChildren(startComment, allowUnbalanced);
|
|
44
|
+
if (allVirtualChildren) {
|
|
45
|
+
if (allVirtualChildren.length > 0) {
|
|
46
|
+
return allVirtualChildren[allVirtualChildren.length - 1].nextSibling;
|
|
47
|
+
}
|
|
48
|
+
return startComment.nextSibling;
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function virtualChildNodes(node: Node): Node[] | NodeListOf<ChildNode> {
|
|
54
|
+
return isStartComment(node) ? getVirtualChildren(node)! : node.childNodes;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function virtualEmptyNode(node: Node): void {
|
|
58
|
+
if (!isStartComment(node)) {
|
|
59
|
+
while (node.firstChild) {
|
|
60
|
+
removeNode(node.firstChild);
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
const children = getVirtualChildren(node)!;
|
|
64
|
+
for (let i = 0; i < children.length; i++) {
|
|
65
|
+
removeNode(children[i]);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function virtualSetChildren(node: Node, childNodes: Node[]): void {
|
|
71
|
+
if (!isStartComment(node)) {
|
|
72
|
+
while (node.firstChild) {
|
|
73
|
+
removeNode(node.firstChild);
|
|
74
|
+
}
|
|
75
|
+
for (let i = 0; i < childNodes.length; i++) {
|
|
76
|
+
node.appendChild(childNodes[i]);
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
virtualEmptyNode(node);
|
|
80
|
+
const endCommentNode = node.nextSibling!;
|
|
81
|
+
for (let i = 0; i < childNodes.length; i++) {
|
|
82
|
+
endCommentNode.parentNode!.insertBefore(childNodes[i], endCommentNode);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function virtualPrepend(containerNode: Node, nodeToPrepend: Node): void {
|
|
88
|
+
let insertBeforeNode: Node | null;
|
|
89
|
+
let parent: Node;
|
|
90
|
+
|
|
91
|
+
if (isStartComment(containerNode)) {
|
|
92
|
+
insertBeforeNode = containerNode.nextSibling;
|
|
93
|
+
parent = containerNode.parentNode!;
|
|
94
|
+
} else {
|
|
95
|
+
insertBeforeNode = containerNode.firstChild;
|
|
96
|
+
parent = containerNode;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (!insertBeforeNode) {
|
|
100
|
+
parent.appendChild(nodeToPrepend);
|
|
101
|
+
} else {
|
|
102
|
+
parent.insertBefore(nodeToPrepend, insertBeforeNode);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function virtualInsertAfter(containerNode: Node, nodeToInsert: Node, insertAfterNode: Node | null): void {
|
|
107
|
+
if (!insertAfterNode) {
|
|
108
|
+
virtualPrepend(containerNode, nodeToInsert);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const insertBeforeNode = insertAfterNode.nextSibling;
|
|
113
|
+
const parent = isStartComment(containerNode) ? containerNode.parentNode! : containerNode;
|
|
114
|
+
|
|
115
|
+
if (!insertBeforeNode) {
|
|
116
|
+
parent.appendChild(nodeToInsert);
|
|
117
|
+
} else {
|
|
118
|
+
parent.insertBefore(nodeToInsert, insertBeforeNode);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function virtualFirstChild(node: Node): Node | null {
|
|
123
|
+
if (!isStartComment(node)) {
|
|
124
|
+
const first = node.firstChild;
|
|
125
|
+
if (first && isEndComment(first)) {
|
|
126
|
+
return first.nextSibling;
|
|
127
|
+
}
|
|
128
|
+
return first;
|
|
129
|
+
}
|
|
130
|
+
if (!node.nextSibling || isEndComment(node.nextSibling)) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
return node.nextSibling;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function virtualNextSibling(node: Node): Node | null {
|
|
137
|
+
if (isStartComment(node)) {
|
|
138
|
+
node = getMatchingEndComment(node)!;
|
|
139
|
+
}
|
|
140
|
+
if (node.nextSibling && isEndComment(node.nextSibling)) {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
return node.nextSibling;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function hasBindingValue(node: Node): boolean {
|
|
147
|
+
return isStartComment(node);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function virtualNodeBindingValue(node: Node): string | null {
|
|
151
|
+
const match = (node.nodeValue || '').match(startCommentRegex);
|
|
152
|
+
return match ? match[1]?.trim() ?? null : null;
|
|
153
|
+
}
|
package/src/wireParams.ts
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
import { Observable } from './observable.js';
|
|
2
|
-
import { Computed } from './computed.js';
|
|
3
|
-
import { isSubscribable } from './subscribable.js';
|
|
4
|
-
import type { Subscription } from './subscribable.js';
|
|
5
|
-
import { getObservable, replaceObservable } from './decorators.js';
|
|
6
|
-
import { addDisposeCallback } from './domNodeDisposal.js';
|
|
7
|
-
|
|
8
|
-
const SKIP_KEYS = new Set(['$raw']);
|
|
9
|
-
|
|
10
|
-
export interface WireParamsResult {
|
|
11
|
-
subscriptions: Subscription<unknown>[];
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function wireParams(
|
|
15
|
-
instance: object,
|
|
16
|
-
params: Record<string, unknown>,
|
|
17
|
-
element?: Node,
|
|
18
|
-
): WireParamsResult {
|
|
19
|
-
const subscriptions: Subscription<unknown>[] = [];
|
|
20
|
-
|
|
21
|
-
for (const key of Object.keys(params)) {
|
|
22
|
-
if (SKIP_KEYS.has(key)) continue;
|
|
23
|
-
|
|
24
|
-
const paramValue = params[key];
|
|
25
|
-
const childObs = getObservable(instance, key);
|
|
26
|
-
const childIsReactive = childObs !== undefined && isSubscribable(childObs);
|
|
27
|
-
|
|
28
|
-
if (paramValue instanceof Observable) {
|
|
29
|
-
if (childIsReactive) {
|
|
30
|
-
replaceObservable(instance, key, paramValue);
|
|
31
|
-
} else {
|
|
32
|
-
(instance as Record<string, unknown>)[key] = paramValue.get();
|
|
33
|
-
}
|
|
34
|
-
} else if (paramValue instanceof Computed) {
|
|
35
|
-
(instance as Record<string, unknown>)[key] = paramValue.get();
|
|
36
|
-
const sub = paramValue.subscribe((newValue: unknown) => {
|
|
37
|
-
(instance as Record<string, unknown>)[key] = newValue;
|
|
38
|
-
});
|
|
39
|
-
subscriptions.push(sub);
|
|
40
|
-
if (element) {
|
|
41
|
-
addDisposeCallback(element, () => sub.dispose());
|
|
42
|
-
}
|
|
43
|
-
} else {
|
|
44
|
-
(instance as Record<string, unknown>)[key] = paramValue;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return { subscriptions };
|
|
49
|
-
}
|
|
1
|
+
import { Observable } from './observable.js';
|
|
2
|
+
import { Computed } from './computed.js';
|
|
3
|
+
import { isSubscribable } from './subscribable.js';
|
|
4
|
+
import type { Subscription } from './subscribable.js';
|
|
5
|
+
import { getObservable, replaceObservable } from './decorators.js';
|
|
6
|
+
import { addDisposeCallback } from './domNodeDisposal.js';
|
|
7
|
+
|
|
8
|
+
const SKIP_KEYS = new Set(['$raw']);
|
|
9
|
+
|
|
10
|
+
export interface WireParamsResult {
|
|
11
|
+
subscriptions: Subscription<unknown>[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function wireParams(
|
|
15
|
+
instance: object,
|
|
16
|
+
params: Record<string, unknown>,
|
|
17
|
+
element?: Node,
|
|
18
|
+
): WireParamsResult {
|
|
19
|
+
const subscriptions: Subscription<unknown>[] = [];
|
|
20
|
+
|
|
21
|
+
for (const key of Object.keys(params)) {
|
|
22
|
+
if (SKIP_KEYS.has(key)) continue;
|
|
23
|
+
|
|
24
|
+
const paramValue = params[key];
|
|
25
|
+
const childObs = getObservable(instance, key);
|
|
26
|
+
const childIsReactive = childObs !== undefined && isSubscribable(childObs);
|
|
27
|
+
|
|
28
|
+
if (paramValue instanceof Observable) {
|
|
29
|
+
if (childIsReactive) {
|
|
30
|
+
replaceObservable(instance, key, paramValue);
|
|
31
|
+
} else {
|
|
32
|
+
(instance as Record<string, unknown>)[key] = paramValue.get();
|
|
33
|
+
}
|
|
34
|
+
} else if (paramValue instanceof Computed) {
|
|
35
|
+
(instance as Record<string, unknown>)[key] = paramValue.get();
|
|
36
|
+
const sub = paramValue.subscribe((newValue: unknown) => {
|
|
37
|
+
(instance as Record<string, unknown>)[key] = newValue;
|
|
38
|
+
});
|
|
39
|
+
subscriptions.push(sub);
|
|
40
|
+
if (element) {
|
|
41
|
+
addDisposeCallback(element, () => sub.dispose());
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
(instance as Record<string, unknown>)[key] = paramValue;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return { subscriptions };
|
|
49
|
+
}
|