@vertexvis/html-templates 0.24.5-canary.5 → 1.0.0-testing.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/dist/binding.d.ts +36 -36
- package/dist/bundle.cjs.js +230 -230
- package/dist/bundle.cjs.js.map +1 -1
- package/dist/bundle.esm.js +230 -230
- package/dist/bundle.esm.js.map +1 -1
- package/dist/element-pool.d.ts +18 -18
- package/dist/index.d.ts +3 -3
- package/dist/templates.d.ts +7 -7
- package/package.json +13 -12
package/dist/binding.d.ts
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
export
|
|
2
|
-
export interface Binding {
|
|
3
|
-
bind<T extends BindingDataMap>(data: T): void;
|
|
4
|
-
}
|
|
5
|
-
export declare class CollectionBinding implements Binding {
|
|
6
|
-
private bindings;
|
|
7
|
-
constructor(bindings: Binding[]);
|
|
8
|
-
bind<T extends BindingDataMap>(data: T): void;
|
|
9
|
-
}
|
|
10
|
-
export declare abstract class NodeBinding<N extends Node> implements Binding {
|
|
11
|
-
protected node: N;
|
|
12
|
-
protected expr: string;
|
|
13
|
-
protected constructor(node: N, expr: string);
|
|
14
|
-
abstract bind<T extends BindingDataMap>(data: T): void;
|
|
15
|
-
}
|
|
16
|
-
export declare class TextNodeBinding extends NodeBinding<Node> {
|
|
17
|
-
constructor(node: Node, expr: string);
|
|
18
|
-
bind<T extends BindingDataMap>(data: T): void;
|
|
19
|
-
}
|
|
20
|
-
export declare class AttributeBinding extends NodeBinding<Element> {
|
|
21
|
-
private attr;
|
|
22
|
-
constructor(node: Element, expr: string, attr: string);
|
|
23
|
-
bind<T extends BindingDataMap>(data: T): void;
|
|
24
|
-
}
|
|
25
|
-
export declare class PropertyBinding extends NodeBinding<Element> {
|
|
26
|
-
private prop;
|
|
27
|
-
constructor(node: Element, expr: string, prop: string);
|
|
28
|
-
bind<T extends BindingDataMap>(data: T): void;
|
|
29
|
-
}
|
|
30
|
-
export declare class EventHandlerBinding extends NodeBinding<Element> {
|
|
31
|
-
private eventName;
|
|
32
|
-
private disposable?;
|
|
33
|
-
constructor(node: Element, expr: string, eventName: string);
|
|
34
|
-
bind<T extends BindingDataMap>(data: T): void;
|
|
35
|
-
}
|
|
36
|
-
export declare function generateBindings(node: Node): Binding[];
|
|
1
|
+
export type BindingDataMap = Record<string, any>;
|
|
2
|
+
export interface Binding {
|
|
3
|
+
bind<T extends BindingDataMap>(data: T): void;
|
|
4
|
+
}
|
|
5
|
+
export declare class CollectionBinding implements Binding {
|
|
6
|
+
private bindings;
|
|
7
|
+
constructor(bindings: Binding[]);
|
|
8
|
+
bind<T extends BindingDataMap>(data: T): void;
|
|
9
|
+
}
|
|
10
|
+
export declare abstract class NodeBinding<N extends Node> implements Binding {
|
|
11
|
+
protected node: N;
|
|
12
|
+
protected expr: string;
|
|
13
|
+
protected constructor(node: N, expr: string);
|
|
14
|
+
abstract bind<T extends BindingDataMap>(data: T): void;
|
|
15
|
+
}
|
|
16
|
+
export declare class TextNodeBinding extends NodeBinding<Node> {
|
|
17
|
+
constructor(node: Node, expr: string);
|
|
18
|
+
bind<T extends BindingDataMap>(data: T): void;
|
|
19
|
+
}
|
|
20
|
+
export declare class AttributeBinding extends NodeBinding<Element> {
|
|
21
|
+
private readonly attr;
|
|
22
|
+
constructor(node: Element, expr: string, attr: string);
|
|
23
|
+
bind<T extends BindingDataMap>(data: T): void;
|
|
24
|
+
}
|
|
25
|
+
export declare class PropertyBinding extends NodeBinding<Element> {
|
|
26
|
+
private prop;
|
|
27
|
+
constructor(node: Element, expr: string, prop: string);
|
|
28
|
+
bind<T extends BindingDataMap>(data: T): void;
|
|
29
|
+
}
|
|
30
|
+
export declare class EventHandlerBinding extends NodeBinding<Element> {
|
|
31
|
+
private eventName;
|
|
32
|
+
private disposable?;
|
|
33
|
+
constructor(node: Element, expr: string, eventName: string);
|
|
34
|
+
bind<T extends BindingDataMap>(data: T): void;
|
|
35
|
+
}
|
|
36
|
+
export declare function generateBindings(node: Node): Binding[];
|
package/dist/bundle.cjs.js
CHANGED
|
@@ -67,240 +67,240 @@ function camelCase(input, options) {
|
|
|
67
67
|
return pascalCase(input, tslib.__assign({ transform: camelCaseTransform }, options));
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
const bindingRegEx = /{{(.+)}}/;
|
|
71
|
-
class CollectionBinding {
|
|
72
|
-
constructor(bindings) {
|
|
73
|
-
this.bindings = bindings;
|
|
74
|
-
}
|
|
75
|
-
bind(data) {
|
|
76
|
-
this.bindings.forEach((binding) => binding.bind(data));
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
class NodeBinding {
|
|
80
|
-
constructor(node, expr) {
|
|
81
|
-
this.node = node;
|
|
82
|
-
this.expr = expr;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
class TextNodeBinding extends NodeBinding {
|
|
86
|
-
constructor(node, expr) {
|
|
87
|
-
super(node, expr);
|
|
88
|
-
}
|
|
89
|
-
bind(data) {
|
|
90
|
-
const newContent = replaceBindingString(data, this.expr);
|
|
91
|
-
if (newContent !== this.node.textContent) {
|
|
92
|
-
this.node.textContent = newContent;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
class AttributeBinding extends NodeBinding {
|
|
97
|
-
constructor(node, expr, attr) {
|
|
98
|
-
super(node, expr);
|
|
99
|
-
this.attr = attr;
|
|
100
|
-
}
|
|
101
|
-
bind(data) {
|
|
102
|
-
const newValue = replaceBindingString(data, this.expr);
|
|
103
|
-
const oldValue = this.node.getAttribute(this.attr);
|
|
104
|
-
if (oldValue !== newValue) {
|
|
105
|
-
this.node.setAttribute(this.attr, newValue);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
class PropertyBinding extends NodeBinding {
|
|
110
|
-
constructor(node, expr, prop) {
|
|
111
|
-
super(node, expr);
|
|
112
|
-
this.prop = prop;
|
|
113
|
-
}
|
|
114
|
-
bind(data) {
|
|
115
|
-
const newValue = replaceBinding(data, this.expr);
|
|
116
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
117
|
-
const oldValue = this.node[this.prop];
|
|
118
|
-
if (oldValue !== newValue) {
|
|
119
|
-
this.node[this.prop] = newValue;
|
|
120
|
-
}
|
|
121
|
-
/* eslint-enable @typescript-eslint/no-explicit-any */
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
class EventHandlerBinding extends NodeBinding {
|
|
125
|
-
constructor(node, expr, eventName) {
|
|
126
|
-
super(node, expr);
|
|
127
|
-
this.eventName = eventName;
|
|
128
|
-
}
|
|
129
|
-
bind(data) {
|
|
130
|
-
var _a;
|
|
131
|
-
const path = extractBindingPath(this.expr);
|
|
132
|
-
if (path != null) {
|
|
133
|
-
(_a = this.disposable) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
134
|
-
const listener = getBindableValue(data, path, true);
|
|
135
|
-
this.node.addEventListener(this.eventName, listener);
|
|
136
|
-
this.disposable = {
|
|
137
|
-
dispose: () => {
|
|
138
|
-
this.node.removeEventListener(this.eventName, listener);
|
|
139
|
-
},
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
function generateBindings(node) {
|
|
145
|
-
const bindings = [];
|
|
146
|
-
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
147
|
-
const el = node;
|
|
148
|
-
const bindableAttributes = getBindableAttributes(el);
|
|
149
|
-
bindableAttributes.forEach((attr) => {
|
|
150
|
-
if (attr.name.startsWith('event:')) {
|
|
151
|
-
const eventName = camelCase(attr.name.replace('event:', ''));
|
|
152
|
-
bindings.push(new EventHandlerBinding(el, attr.value, eventName));
|
|
153
|
-
}
|
|
154
|
-
else if (attr.name.startsWith('attr:')) {
|
|
155
|
-
bindings.push(new AttributeBinding(el, attr.value, attr.name.replace('attr:', '')));
|
|
156
|
-
}
|
|
157
|
-
else if (attr.name.startsWith('prop:')) {
|
|
158
|
-
const propName = camelCase(attr.name.replace('prop:', ''));
|
|
159
|
-
bindings.push(new PropertyBinding(el, attr.value, propName));
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
else if (node.nodeType === Node.TEXT_NODE &&
|
|
164
|
-
node.textContent != null &&
|
|
165
|
-
bindingRegEx.test(node.textContent)) {
|
|
166
|
-
bindings.push(new TextNodeBinding(node, node.textContent));
|
|
167
|
-
}
|
|
168
|
-
for (let i = 0; i < node.childNodes.length; i++) {
|
|
169
|
-
bindings.push(...generateBindings(node.childNodes[i]));
|
|
170
|
-
}
|
|
171
|
-
return bindings;
|
|
172
|
-
}
|
|
173
|
-
function getBindableAttributes(element) {
|
|
174
|
-
return Array.from(element.attributes).filter((attr) => bindingRegEx.test(attr.value));
|
|
175
|
-
}
|
|
176
|
-
function extractBindingPath(expr) {
|
|
177
|
-
const result = bindingRegEx.exec(expr);
|
|
178
|
-
return result != null ? result[1] : undefined;
|
|
179
|
-
}
|
|
180
|
-
function replaceBindingString(data, expr) {
|
|
181
|
-
const path = extractBindingPath(expr);
|
|
182
|
-
if (path != null) {
|
|
183
|
-
const value = getBindableValue(data, path, true);
|
|
184
|
-
return expr.replace(`{{${path}}}`, value === null || value === void 0 ? void 0 : value.toString());
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
return expr;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
191
|
-
function replaceBinding(data, expr) {
|
|
192
|
-
const path = extractBindingPath(expr);
|
|
193
|
-
if (path != null) {
|
|
194
|
-
const value = getBindableValue(data, path, true);
|
|
195
|
-
return value;
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
return expr;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
function getBindableValue(data, path, isHead = false
|
|
202
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
203
|
-
) {
|
|
204
|
-
const [head, ...tail] = path.split('.');
|
|
205
|
-
if (isHead && tail.length === 0) {
|
|
206
|
-
return data;
|
|
207
|
-
}
|
|
208
|
-
else if (isHead && tail.length > 0) {
|
|
209
|
-
return getBindableValue(data, tail.join('.'), false);
|
|
210
|
-
}
|
|
211
|
-
else {
|
|
212
|
-
const value = data[head];
|
|
213
|
-
if (tail.length > 0) {
|
|
214
|
-
return getBindableValue(value, tail.join('.'), false);
|
|
215
|
-
}
|
|
216
|
-
else {
|
|
217
|
-
return value;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
70
|
+
const bindingRegEx = /{{(.+)}}/;
|
|
71
|
+
class CollectionBinding {
|
|
72
|
+
constructor(bindings) {
|
|
73
|
+
this.bindings = bindings;
|
|
74
|
+
}
|
|
75
|
+
bind(data) {
|
|
76
|
+
this.bindings.forEach((binding) => binding.bind(data));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
class NodeBinding {
|
|
80
|
+
constructor(node, expr) {
|
|
81
|
+
this.node = node;
|
|
82
|
+
this.expr = expr;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
class TextNodeBinding extends NodeBinding {
|
|
86
|
+
constructor(node, expr) {
|
|
87
|
+
super(node, expr);
|
|
88
|
+
}
|
|
89
|
+
bind(data) {
|
|
90
|
+
const newContent = replaceBindingString(data, this.expr);
|
|
91
|
+
if (newContent !== this.node.textContent) {
|
|
92
|
+
this.node.textContent = newContent;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
class AttributeBinding extends NodeBinding {
|
|
97
|
+
constructor(node, expr, attr) {
|
|
98
|
+
super(node, expr);
|
|
99
|
+
this.attr = attr;
|
|
100
|
+
}
|
|
101
|
+
bind(data) {
|
|
102
|
+
const newValue = replaceBindingString(data, this.expr);
|
|
103
|
+
const oldValue = this.node.getAttribute(this.attr);
|
|
104
|
+
if (oldValue !== newValue) {
|
|
105
|
+
this.node.setAttribute(this.attr, newValue);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
class PropertyBinding extends NodeBinding {
|
|
110
|
+
constructor(node, expr, prop) {
|
|
111
|
+
super(node, expr);
|
|
112
|
+
this.prop = prop;
|
|
113
|
+
}
|
|
114
|
+
bind(data) {
|
|
115
|
+
const newValue = replaceBinding(data, this.expr);
|
|
116
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
117
|
+
const oldValue = this.node[this.prop];
|
|
118
|
+
if (oldValue !== newValue) {
|
|
119
|
+
this.node[this.prop] = newValue;
|
|
120
|
+
}
|
|
121
|
+
/* eslint-enable @typescript-eslint/no-explicit-any */
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
class EventHandlerBinding extends NodeBinding {
|
|
125
|
+
constructor(node, expr, eventName) {
|
|
126
|
+
super(node, expr);
|
|
127
|
+
this.eventName = eventName;
|
|
128
|
+
}
|
|
129
|
+
bind(data) {
|
|
130
|
+
var _a;
|
|
131
|
+
const path = extractBindingPath(this.expr);
|
|
132
|
+
if (path != null) {
|
|
133
|
+
(_a = this.disposable) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
134
|
+
const listener = getBindableValue(data, path, true);
|
|
135
|
+
this.node.addEventListener(this.eventName, listener);
|
|
136
|
+
this.disposable = {
|
|
137
|
+
dispose: () => {
|
|
138
|
+
this.node.removeEventListener(this.eventName, listener);
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function generateBindings(node) {
|
|
145
|
+
const bindings = [];
|
|
146
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
147
|
+
const el = node;
|
|
148
|
+
const bindableAttributes = getBindableAttributes(el);
|
|
149
|
+
bindableAttributes.forEach((attr) => {
|
|
150
|
+
if (attr.name.startsWith('event:')) {
|
|
151
|
+
const eventName = camelCase(attr.name.replace('event:', ''));
|
|
152
|
+
bindings.push(new EventHandlerBinding(el, attr.value, eventName));
|
|
153
|
+
}
|
|
154
|
+
else if (attr.name.startsWith('attr:')) {
|
|
155
|
+
bindings.push(new AttributeBinding(el, attr.value, attr.name.replace('attr:', '')));
|
|
156
|
+
}
|
|
157
|
+
else if (attr.name.startsWith('prop:')) {
|
|
158
|
+
const propName = camelCase(attr.name.replace('prop:', ''));
|
|
159
|
+
bindings.push(new PropertyBinding(el, attr.value, propName));
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
else if (node.nodeType === Node.TEXT_NODE &&
|
|
164
|
+
node.textContent != null &&
|
|
165
|
+
bindingRegEx.test(node.textContent)) {
|
|
166
|
+
bindings.push(new TextNodeBinding(node, node.textContent));
|
|
167
|
+
}
|
|
168
|
+
for (let i = 0; i < node.childNodes.length; i++) {
|
|
169
|
+
bindings.push(...generateBindings(node.childNodes[i]));
|
|
170
|
+
}
|
|
171
|
+
return bindings;
|
|
172
|
+
}
|
|
173
|
+
function getBindableAttributes(element) {
|
|
174
|
+
return Array.from(element.attributes).filter((attr) => bindingRegEx.test(attr.value));
|
|
175
|
+
}
|
|
176
|
+
function extractBindingPath(expr) {
|
|
177
|
+
const result = bindingRegEx.exec(expr);
|
|
178
|
+
return result != null ? result[1] : undefined;
|
|
179
|
+
}
|
|
180
|
+
function replaceBindingString(data, expr) {
|
|
181
|
+
const path = extractBindingPath(expr);
|
|
182
|
+
if (path != null) {
|
|
183
|
+
const value = getBindableValue(data, path, true);
|
|
184
|
+
return expr.replace(`{{${path}}}`, value === null || value === void 0 ? void 0 : value.toString());
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
return expr;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
191
|
+
function replaceBinding(data, expr) {
|
|
192
|
+
const path = extractBindingPath(expr);
|
|
193
|
+
if (path != null) {
|
|
194
|
+
const value = getBindableValue(data, path, true);
|
|
195
|
+
return value;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
return expr;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function getBindableValue(data, path, isHead = false
|
|
202
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
203
|
+
) {
|
|
204
|
+
const [head, ...tail] = path.split('.');
|
|
205
|
+
if (isHead && tail.length === 0) {
|
|
206
|
+
return data;
|
|
207
|
+
}
|
|
208
|
+
else if (isHead && tail.length > 0) {
|
|
209
|
+
return getBindableValue(data, tail.join('.'), false);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
const value = data[head];
|
|
213
|
+
if (tail.length > 0) {
|
|
214
|
+
return getBindableValue(value, tail.join('.'), false);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
return value;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
-
class ElementPool {
|
|
223
|
-
constructor(container, elementFactory) {
|
|
224
|
-
this.container = container;
|
|
225
|
-
this.elementFactory = elementFactory;
|
|
226
|
-
this.instanceMap = new Map();
|
|
227
|
-
this.elements = [];
|
|
228
|
-
}
|
|
229
|
-
swapHeadToTail(count) {
|
|
230
|
-
const sliced = this.elements.splice(0, count);
|
|
231
|
-
this.elements.splice(this.elements.length, 0, ...sliced);
|
|
232
|
-
return this.elements.concat();
|
|
233
|
-
}
|
|
234
|
-
swapTailToHead(count) {
|
|
235
|
-
const sliced = this.elements.splice(-count, count);
|
|
236
|
-
this.elements.splice(0, 0, ...sliced);
|
|
237
|
-
return this.elements.concat();
|
|
238
|
-
}
|
|
239
|
-
updateElements(count) {
|
|
240
|
-
const diff = count - this.elements.length;
|
|
241
|
-
if (diff > 0) {
|
|
242
|
-
for (let i = 0; i < diff; i++) {
|
|
243
|
-
this.createElement();
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
else {
|
|
247
|
-
for (let i = 0; i < -diff; i++) {
|
|
248
|
-
this.deleteElement();
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
return this.elements.concat();
|
|
252
|
-
}
|
|
253
|
-
updateData(f) {
|
|
254
|
-
this.elements.forEach((el, i) => {
|
|
255
|
-
const instance = this.instanceMap.get(el);
|
|
256
|
-
const data = f(i);
|
|
257
|
-
instance === null || instance === void 0 ? void 0 : instance.bindings.bind(data);
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
updateElementFactory(elementFactory) {
|
|
261
|
-
this.elementFactory = elementFactory;
|
|
262
|
-
this.updateElements(0);
|
|
263
|
-
}
|
|
264
|
-
iterateElements(f) {
|
|
265
|
-
this.elements.forEach((el, i) => {
|
|
266
|
-
const instance = this.instanceMap.get(el);
|
|
267
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
268
|
-
f(el, instance.bindings, i);
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
createElement() {
|
|
272
|
-
const instance = this.elementFactory();
|
|
273
|
-
this.elements.push(instance.element);
|
|
274
|
-
this.instanceMap.set(instance.element, instance);
|
|
275
|
-
this.container.append(instance.element);
|
|
276
|
-
return instance;
|
|
277
|
-
}
|
|
278
|
-
deleteElement() {
|
|
279
|
-
const element = this.elements.pop();
|
|
280
|
-
if (element != null) {
|
|
281
|
-
this.instanceMap.delete(element);
|
|
282
|
-
element.remove();
|
|
283
|
-
}
|
|
284
|
-
}
|
|
222
|
+
class ElementPool {
|
|
223
|
+
constructor(container, elementFactory) {
|
|
224
|
+
this.container = container;
|
|
225
|
+
this.elementFactory = elementFactory;
|
|
226
|
+
this.instanceMap = new Map();
|
|
227
|
+
this.elements = [];
|
|
228
|
+
}
|
|
229
|
+
swapHeadToTail(count) {
|
|
230
|
+
const sliced = this.elements.splice(0, count);
|
|
231
|
+
this.elements.splice(this.elements.length, 0, ...sliced);
|
|
232
|
+
return this.elements.concat();
|
|
233
|
+
}
|
|
234
|
+
swapTailToHead(count) {
|
|
235
|
+
const sliced = this.elements.splice(-count, count);
|
|
236
|
+
this.elements.splice(0, 0, ...sliced);
|
|
237
|
+
return this.elements.concat();
|
|
238
|
+
}
|
|
239
|
+
updateElements(count) {
|
|
240
|
+
const diff = count - this.elements.length;
|
|
241
|
+
if (diff > 0) {
|
|
242
|
+
for (let i = 0; i < diff; i++) {
|
|
243
|
+
this.createElement();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
for (let i = 0; i < -diff; i++) {
|
|
248
|
+
this.deleteElement();
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return this.elements.concat();
|
|
252
|
+
}
|
|
253
|
+
updateData(f) {
|
|
254
|
+
this.elements.forEach((el, i) => {
|
|
255
|
+
const instance = this.instanceMap.get(el);
|
|
256
|
+
const data = f(i);
|
|
257
|
+
instance === null || instance === void 0 ? void 0 : instance.bindings.bind(data);
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
updateElementFactory(elementFactory) {
|
|
261
|
+
this.elementFactory = elementFactory;
|
|
262
|
+
this.updateElements(0);
|
|
263
|
+
}
|
|
264
|
+
iterateElements(f) {
|
|
265
|
+
this.elements.forEach((el, i) => {
|
|
266
|
+
const instance = this.instanceMap.get(el);
|
|
267
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
268
|
+
f(el, instance.bindings, i);
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
createElement() {
|
|
272
|
+
const instance = this.elementFactory();
|
|
273
|
+
this.elements.push(instance.element);
|
|
274
|
+
this.instanceMap.set(instance.element, instance);
|
|
275
|
+
this.container.append(instance.element);
|
|
276
|
+
return instance;
|
|
277
|
+
}
|
|
278
|
+
deleteElement() {
|
|
279
|
+
const element = this.elements.pop();
|
|
280
|
+
if (element != null) {
|
|
281
|
+
this.instanceMap.delete(element);
|
|
282
|
+
element.remove();
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
285
|
}
|
|
286
286
|
|
|
287
|
-
function append(container, element, data) {
|
|
288
|
-
const bindings = new CollectionBinding(generateBindings(element));
|
|
289
|
-
bindings.bind(data);
|
|
290
|
-
container.appendChild(element);
|
|
291
|
-
const created = container.lastElementChild;
|
|
292
|
-
if (created != null) {
|
|
293
|
-
return { element: created, bindings };
|
|
294
|
-
}
|
|
295
|
-
else {
|
|
296
|
-
throw new Error('Failed to append element');
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
function generateInstanceFromTemplate(template) {
|
|
300
|
-
const fragment = template.content.cloneNode(true);
|
|
301
|
-
const element = fragment.firstElementChild;
|
|
302
|
-
const bindings = new CollectionBinding(generateBindings(fragment));
|
|
303
|
-
return { element, bindings };
|
|
287
|
+
function append(container, element, data) {
|
|
288
|
+
const bindings = new CollectionBinding(generateBindings(element));
|
|
289
|
+
bindings.bind(data);
|
|
290
|
+
container.appendChild(element);
|
|
291
|
+
const created = container.lastElementChild;
|
|
292
|
+
if (created != null) {
|
|
293
|
+
return { element: created, bindings };
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
throw new Error('Failed to append element');
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
function generateInstanceFromTemplate(template) {
|
|
300
|
+
const fragment = template.content.cloneNode(true);
|
|
301
|
+
const element = fragment.firstElementChild;
|
|
302
|
+
const bindings = new CollectionBinding(generateBindings(fragment));
|
|
303
|
+
return { element, bindings };
|
|
304
304
|
}
|
|
305
305
|
|
|
306
306
|
exports.AttributeBinding = AttributeBinding;
|