vsn 0.1.93 → 0.1.96
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/demo/demo.html +1 -1
- package/demo/vsn.js +2 -2
- package/dist/AST/ClassNode.js +4 -0
- package/dist/AST/ClassNode.js.map +1 -1
- package/dist/DOM.d.ts +3 -0
- package/dist/DOM.js +150 -105
- package/dist/DOM.js.map +1 -1
- package/dist/attributes/List.d.ts +1 -0
- package/dist/attributes/List.js +37 -14
- package/dist/attributes/List.js.map +1 -1
- package/dist/attributes/ListItem.d.ts +1 -3
- package/dist/attributes/ListItem.js +7 -25
- package/dist/attributes/ListItem.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/src/AST/ClassNode.ts +5 -0
- package/src/DOM.ts +42 -27
- package/src/attributes/List.ts +28 -11
- package/src/attributes/ListItem.ts +3 -20
- package/src/version.ts +1 -1
- package/test/attributes/ListItem.spec.ts +7 -9
package/dist/version.js
CHANGED
package/package.json
CHANGED
package/src/AST/ClassNode.ts
CHANGED
|
@@ -226,6 +226,11 @@ export class ClassNode extends Node implements TreeNode {
|
|
|
226
226
|
tag = await dom.getTagForElement(element, true);
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
+
if (!tag) {
|
|
230
|
+
console.error('no tag found for element', element);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
|
|
229
234
|
const classNode: ClassNode = Registry.instance.classes.getSynchronous(selector);
|
|
230
235
|
if (classNode) {
|
|
231
236
|
await classNode.constructTag(tag, dom);
|
package/src/DOM.ts
CHANGED
|
@@ -189,16 +189,8 @@ export class DOM extends EventDispatcher {
|
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
async
|
|
193
|
-
|
|
194
|
-
document.body.setAttribute('vsn-root', '');
|
|
195
|
-
document.ondragover = (e) => e.cancelable && e.preventDefault(); // Allow dragging over document
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// Create tags for each html element with a v-attribute
|
|
199
|
-
const newTags: Tag[] = [];
|
|
200
|
-
const toBuild: HTMLElement[] = [];
|
|
201
|
-
|
|
192
|
+
async discover(ele: HTMLElement, forComponent: boolean = false): Promise<HTMLElement[]> {
|
|
193
|
+
const discovered: HTMLElement[] = [];
|
|
202
194
|
const checkElement = (e: HTMLElement): boolean => {
|
|
203
195
|
if (ElementHelper.hasVisionAttribute(e)) {
|
|
204
196
|
if (
|
|
@@ -206,7 +198,7 @@ export class DOM extends EventDispatcher {
|
|
|
206
198
|
) return false;
|
|
207
199
|
if (this.queued.indexOf(e) > -1) return false;
|
|
208
200
|
this.queued.push(e);
|
|
209
|
-
|
|
201
|
+
discovered.push(e);
|
|
210
202
|
}
|
|
211
203
|
|
|
212
204
|
return true;
|
|
@@ -221,38 +213,39 @@ export class DOM extends EventDispatcher {
|
|
|
221
213
|
checkElement(ele);
|
|
222
214
|
scanChildren(ele);
|
|
223
215
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
const tag: Tag = new Tag(element, this);
|
|
227
|
-
this.tags.push(tag);
|
|
228
|
-
newTags.push(tag);
|
|
229
|
-
}
|
|
216
|
+
return discovered;
|
|
217
|
+
}
|
|
230
218
|
|
|
231
|
-
|
|
232
|
-
|
|
219
|
+
async buildTag(element: HTMLElement, returnExisting: boolean = false): Promise<Tag> {
|
|
220
|
+
if (element[Tag.TaggedVariable]) return returnExisting ? element[Tag.TaggedVariable] : null;
|
|
221
|
+
const tag: Tag = new Tag(element, this);
|
|
222
|
+
this.tags.push(tag);
|
|
223
|
+
return tag;
|
|
224
|
+
}
|
|
233
225
|
|
|
234
|
-
|
|
235
|
-
|
|
226
|
+
async setupTags(tags: Tag[]) {
|
|
227
|
+
// Configure, setup & execute attributes
|
|
228
|
+
for (const tag of tags)
|
|
236
229
|
await tag.buildAttributes();
|
|
237
230
|
|
|
238
|
-
for (const tag of
|
|
231
|
+
for (const tag of tags)
|
|
239
232
|
await tag.compileAttributes();
|
|
240
233
|
|
|
241
|
-
for (const tag of
|
|
234
|
+
for (const tag of tags)
|
|
242
235
|
await tag.setupAttributes();
|
|
243
236
|
|
|
244
|
-
for (const tag of
|
|
237
|
+
for (const tag of tags)
|
|
245
238
|
await tag.extractAttributes();
|
|
246
239
|
|
|
247
|
-
for (const tag of
|
|
240
|
+
for (const tag of tags)
|
|
248
241
|
await tag.connectAttributes();
|
|
249
242
|
|
|
250
|
-
for (const tag of
|
|
243
|
+
for (const tag of tags) {
|
|
251
244
|
await tag.finalize();
|
|
252
245
|
this.queued.splice(this.queued.indexOf(tag.element), 1);
|
|
253
246
|
}
|
|
254
247
|
|
|
255
|
-
for (const tag of
|
|
248
|
+
for (const tag of tags) {
|
|
256
249
|
this.observer.observe(tag.element, {
|
|
257
250
|
attributes: true,
|
|
258
251
|
characterData: true,
|
|
@@ -260,6 +253,28 @@ export class DOM extends EventDispatcher {
|
|
|
260
253
|
subtree: true
|
|
261
254
|
});
|
|
262
255
|
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
async buildFrom(ele: any, isRoot: boolean = false, forComponent: boolean = false) {
|
|
259
|
+
if (isRoot) {
|
|
260
|
+
document.body.setAttribute('vsn-root', '');
|
|
261
|
+
document.ondragover = (e) => e.cancelable && e.preventDefault(); // Allow dragging over document
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Create tags for each html element with a vsn-attribute
|
|
265
|
+
const newTags: Tag[] = [];
|
|
266
|
+
const toBuild: HTMLElement[] = await this.discover(ele, forComponent);
|
|
267
|
+
|
|
268
|
+
for (const element of toBuild) {
|
|
269
|
+
const tag = await this.buildTag(element);
|
|
270
|
+
if (tag)
|
|
271
|
+
newTags.push(tag);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (isRoot)
|
|
275
|
+
this._root = await this.getTagForElement(document.body);
|
|
276
|
+
|
|
277
|
+
await this.setupTags(newTags);
|
|
263
278
|
|
|
264
279
|
if (isRoot) {
|
|
265
280
|
this._built = true;
|
package/src/attributes/List.ts
CHANGED
|
@@ -113,11 +113,11 @@ export class List extends Attribute {
|
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
public get listItemName(): string {
|
|
116
|
-
return this.tag.getRawAttributeValue('
|
|
116
|
+
return this.tag.getRawAttributeValue('list-item-name', 'item');
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
public get listItemModel(): string {
|
|
120
|
-
return this.tag.getRawAttributeValue('
|
|
120
|
+
return this.tag.getRawAttributeValue('list-item-model');
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
public remove(item: any) {
|
|
@@ -135,6 +135,7 @@ export class List extends Attribute {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
protected async add(obj) {
|
|
138
|
+
// Setup new HTML element
|
|
138
139
|
const clone = this.template.cloneNode(true);
|
|
139
140
|
let element: HTMLElement;
|
|
140
141
|
if (clone instanceof DocumentFragment) {
|
|
@@ -144,20 +145,36 @@ export class List extends Attribute {
|
|
|
144
145
|
}
|
|
145
146
|
delete element[Tag.TaggedVariable];
|
|
146
147
|
|
|
147
|
-
|
|
148
|
+
// Setup new tag
|
|
149
|
+
const tag = await this.tag.dom.buildTag(element, true);
|
|
150
|
+
|
|
151
|
+
await this.setupTag(tag, obj);
|
|
148
152
|
|
|
153
|
+
// Add to DOM & build
|
|
154
|
+
this.tag.element.appendChild(element);
|
|
149
155
|
await this.tag.dom.buildFrom(this.tag.element);
|
|
150
|
-
const tag: Tag = await this.tag.dom.getTagForElement(element);
|
|
151
156
|
this.tags.push(tag);
|
|
157
|
+
this.tag.dispatch('add', obj);
|
|
158
|
+
}
|
|
152
159
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
160
|
+
async setupTag(tag: Tag, obj: any) {
|
|
161
|
+
tag.createScope(true);
|
|
162
|
+
|
|
163
|
+
// Setup new scope & class, if defined
|
|
164
|
+
const modelName: string = this.listItemModel;
|
|
165
|
+
let cls;
|
|
166
|
+
if (modelName)
|
|
167
|
+
cls = await Registry.instance.models.get(modelName);
|
|
168
|
+
|
|
169
|
+
if (cls) {
|
|
170
|
+
if (!obj || !(obj instanceof cls))
|
|
171
|
+
obj = new cls(obj);
|
|
159
172
|
}
|
|
160
173
|
|
|
161
|
-
|
|
174
|
+
// Check if the class is set up already
|
|
175
|
+
if (!cls || (!(tag.scope.data instanceof cls) && !(tag.scope.wrapped instanceof cls)))
|
|
176
|
+
tag.wrap(obj);
|
|
177
|
+
|
|
178
|
+
tag.scope.set(this.listItemName, tag.scope);
|
|
162
179
|
}
|
|
163
180
|
}
|
|
@@ -18,30 +18,13 @@ export class ListItem extends Attribute {
|
|
|
18
18
|
this._list = this.tag.findAncestorByAttribute('vsn-list');
|
|
19
19
|
if (!this._list)
|
|
20
20
|
throw Error(ListItem.ERROR_NO_PARENT);
|
|
21
|
-
const modelName: string = (await this.getList()).listItemModel;
|
|
22
|
-
if (modelName) {
|
|
23
|
-
const cls = await Registry.instance.models.get(modelName);
|
|
24
|
-
if (
|
|
25
|
-
!(this.tag.scope.data instanceof cls) &&
|
|
26
|
-
!(this.tag.scope.wrapped instanceof cls)
|
|
27
|
-
) {
|
|
28
|
-
this.instantiateModel(cls);
|
|
29
|
-
}
|
|
30
21
|
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
const listAttr = await this.getListAttribute();
|
|
23
|
+
await listAttr.setupTag(this.tag, {});
|
|
33
24
|
await super.setup();
|
|
34
25
|
}
|
|
35
26
|
|
|
36
|
-
public
|
|
37
|
-
return this.getAttributeBinding('item');
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
public async getList(): Promise<List> {
|
|
27
|
+
public async getListAttribute(): Promise<List> {
|
|
41
28
|
return await this._list.getAttribute<List>('vsn-list');
|
|
42
29
|
}
|
|
43
|
-
|
|
44
|
-
private instantiateModel(model: any) {
|
|
45
|
-
this.tag.wrap(model, false, true);
|
|
46
|
-
}
|
|
47
30
|
}
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '0.1.
|
|
1
|
+
export const VERSION = '0.1.96';
|
|
2
2
|
|
|
@@ -41,7 +41,7 @@ describe('ListItem', () => {
|
|
|
41
41
|
|
|
42
42
|
it("vsn-list-item should find it's parent list", (done) => {
|
|
43
43
|
document.body.innerHTML = `
|
|
44
|
-
<ul vsn-list:list
|
|
44
|
+
<ul vsn-list:list list-item-model="ListItemSpecTestItem" id="test"><li vsn-list-item id="test-item"></li></ul>
|
|
45
45
|
`;
|
|
46
46
|
|
|
47
47
|
const dom = new DOM(document);
|
|
@@ -58,7 +58,7 @@ describe('ListItem', () => {
|
|
|
58
58
|
it("should properly wrap list item class", (done) => {
|
|
59
59
|
document.body.innerHTML = `
|
|
60
60
|
<div vsn-controller:controller="ListItemController">
|
|
61
|
-
<ul vsn-list:controller.items
|
|
61
|
+
<ul vsn-list:controller.items list-item-model="ListItemSpecTestItem" id="test">
|
|
62
62
|
<li vsn-template vsn-list-item:item></li>
|
|
63
63
|
</ul>
|
|
64
64
|
</div>
|
|
@@ -89,15 +89,12 @@ describe('ListItem', () => {
|
|
|
89
89
|
|
|
90
90
|
it("vsn-list-item should work with vsn-set", (done) => {
|
|
91
91
|
document.body.innerHTML = `
|
|
92
|
-
<ul vsn-list:list
|
|
92
|
+
<ul vsn-list:list list-item-model="ListItemSpecTestItem" id="test"><li vsn-list-item id="test-item" vsn-set:item.testing|integer="1"></li></ul>
|
|
93
93
|
`;
|
|
94
94
|
|
|
95
95
|
const dom = new DOM(document);
|
|
96
96
|
dom.once('built', async () => {
|
|
97
|
-
const list = await dom.getTagForElement(document.getElementById('test'));
|
|
98
97
|
const listItem = await dom.getTagForElement(document.getElementById('test-item'));
|
|
99
|
-
const listItemAttr: ListItem = await listItem.getAttribute('vsn-list-item') as ListItem;
|
|
100
|
-
|
|
101
98
|
expect(listItem.scope.get('testing')).toBe(1);
|
|
102
99
|
done();
|
|
103
100
|
});
|
|
@@ -105,14 +102,15 @@ describe('ListItem', () => {
|
|
|
105
102
|
|
|
106
103
|
it("vsn-list-item should work with vsn-exec", (done) => {
|
|
107
104
|
document.body.innerHTML = `
|
|
108
|
-
<ul vsn-list:list
|
|
105
|
+
<ul vsn-list:list list-item-model="ListItemSpecTestItem" id="test">
|
|
106
|
+
<li vsn-list-item id="test-item" vsn-exec="item.test = 1"></li>
|
|
107
|
+
</ul>
|
|
109
108
|
`;
|
|
110
109
|
|
|
110
|
+
console.log('################# building dom');
|
|
111
111
|
const dom = new DOM(document);
|
|
112
112
|
dom.once('built', async () => {
|
|
113
|
-
const list = await dom.getTagForElement(document.getElementById('test'));
|
|
114
113
|
const listItem = await dom.getTagForElement(document.getElementById('test-item'));
|
|
115
|
-
const listItemAttr: ListItem = await listItem.getAttribute('vsn-list-item') as ListItem;
|
|
116
114
|
console.log('test keys', listItem.scope.keys);
|
|
117
115
|
expect(listItem.scope.get('test')).toBe(1);
|
|
118
116
|
done();
|