vsn 0.1.87 → 0.1.88
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 +17 -225
- package/demo/vsn.js +2 -2
- package/dist/AST/ClassNode.js +6 -1
- package/dist/AST/ClassNode.js.map +1 -1
- package/dist/Attribute.js +0 -3
- package/dist/Attribute.js.map +1 -1
- package/dist/Component.js +60 -0
- package/dist/Component.js.map +1 -1
- package/dist/DOM/DOMObject.js +2 -1
- package/dist/DOM/DOMObject.js.map +1 -1
- package/dist/DOM.d.ts +2 -2
- package/dist/DOM.js +78 -77
- package/dist/DOM.js.map +1 -1
- package/dist/Tag.d.ts +1 -0
- package/dist/Tag.js +8 -6
- package/dist/Tag.js.map +1 -1
- package/dist/attributes/JSONAttribute.js +4 -3
- package/dist/attributes/JSONAttribute.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/vsn.min.js +2 -2
- package/package.json +1 -1
- package/src/AST/ClassNode.ts +7 -3
- package/src/Attribute.ts +0 -1
- package/src/Component.ts +8 -0
- package/src/DOM/DOMObject.ts +2 -1
- package/src/DOM.ts +22 -23
- package/src/Tag.ts +9 -6
- package/src/attributes/JSONAttribute.ts +3 -3
- package/src/version.ts +1 -1
- package/test/attributes/JSONAttribute.spec.ts +31 -29
package/package.json
CHANGED
package/src/AST/ClassNode.ts
CHANGED
|
@@ -73,8 +73,8 @@ export class ClassNode extends Node implements TreeNode {
|
|
|
73
73
|
else
|
|
74
74
|
dom.once('builtRoot', () => this.findClassElements(dom));
|
|
75
75
|
}
|
|
76
|
-
} else {
|
|
77
|
-
await this.block.prepare(
|
|
76
|
+
} else if (meta['PrepForSelector'] === this.fullSelector) { // Only prepare top level class if we're prepping for tag
|
|
77
|
+
await this.block.prepare(tag.scope, dom, tag, meta);
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -83,6 +83,7 @@ export class ClassNode extends Node implements TreeNode {
|
|
|
83
83
|
for (const element of Array.from(dom.querySelectorAll(this.selector, tag))) {
|
|
84
84
|
tags.push(await ClassNode.addElementClass(this._fullSelector, element as HTMLElement, dom, element[Tag.TaggedVariable] || null));
|
|
85
85
|
}
|
|
86
|
+
|
|
86
87
|
for (const childSelector of ClassNode.classChildren[this._fullSelector]) {
|
|
87
88
|
const node = ClassNode.classes[`${this._fullSelector} ${childSelector}`];
|
|
88
89
|
if (!node) continue;
|
|
@@ -98,6 +99,7 @@ export class ClassNode extends Node implements TreeNode {
|
|
|
98
99
|
|
|
99
100
|
tag.createScope(true);
|
|
100
101
|
const meta = this.updateMeta();
|
|
102
|
+
meta['PrepForSelector'] = this.fullSelector;
|
|
101
103
|
await this.block.prepare(tag.scope, dom, tag, meta);
|
|
102
104
|
if (hasConstruct) {
|
|
103
105
|
const fncCls: FunctionNode = this.classScope.get('construct') as FunctionNode;
|
|
@@ -140,7 +142,9 @@ export class ClassNode extends Node implements TreeNode {
|
|
|
140
142
|
if (t.type === TokenType.L_BRACE) break;
|
|
141
143
|
nameParts.push(t.value);
|
|
142
144
|
}
|
|
143
|
-
|
|
145
|
+
let selector = nameParts.join('').trim();
|
|
146
|
+
if (selector.startsWith('>'))
|
|
147
|
+
selector = `:scope ${selector}`;
|
|
144
148
|
tokens.splice(0, nameParts.length);
|
|
145
149
|
const block = Tree.processTokens(Tree.getNextStatementTokens(tokens, true, true));
|
|
146
150
|
return new ClassNode(selector, block);
|
package/src/Attribute.ts
CHANGED
package/src/Component.ts
CHANGED
|
@@ -21,6 +21,14 @@ export class Component extends HTMLElement {
|
|
|
21
21
|
this.setAttribute('vsn-ref', '');
|
|
22
22
|
|
|
23
23
|
this.shadow.appendChild(template.content.cloneNode(true));
|
|
24
|
+
this.shadow.querySelectorAll('slot').forEach(slot => {
|
|
25
|
+
slot.addEventListener('slotchange', async (e) => {
|
|
26
|
+
for (const child of slot.assignedNodes()) {
|
|
27
|
+
const t = await DOM.instance.getTagForElement(child as HTMLElement, true, true);
|
|
28
|
+
t?.slotted(slot);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
});
|
|
24
32
|
DOM.instance.buildFrom(this.shadow);
|
|
25
33
|
}
|
|
26
34
|
}
|
package/src/DOM/DOMObject.ts
CHANGED
|
@@ -22,8 +22,9 @@ export abstract class DOMObject extends EventDispatcher {
|
|
|
22
22
|
if (this.isSlot) {
|
|
23
23
|
this.delegates.push(...(element as HTMLSlotElement).assignedNodes() as HTMLElement[]);
|
|
24
24
|
}
|
|
25
|
-
if (element.assignedSlot)
|
|
25
|
+
if (element.assignedSlot) {
|
|
26
26
|
this.slot = element.assignedSlot;
|
|
27
|
+
}
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
public get isSlot(): boolean {
|
package/src/DOM.ts
CHANGED
|
@@ -189,42 +189,41 @@ export class DOM extends EventDispatcher {
|
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
async buildFrom(ele: any, isRoot: boolean = false) {
|
|
193
|
-
// Assign parents to each tag
|
|
194
|
-
const allElements: HTMLElement[] = [];
|
|
195
|
-
|
|
192
|
+
async buildFrom(ele: any, isRoot: boolean = false, forComponent: boolean = false) {
|
|
196
193
|
if (isRoot) {
|
|
197
194
|
document.body.setAttribute('vsn-root', '');
|
|
198
195
|
document.ondragover = (e) => e.cancelable && e.preventDefault(); // Allow dragging over document
|
|
199
196
|
}
|
|
200
197
|
|
|
201
|
-
for (const tag of this.tags)
|
|
202
|
-
allElements.push(tag.element);
|
|
203
|
-
|
|
204
198
|
// Create tags for each html element with a v-attribute
|
|
205
199
|
const newTags: Tag[] = [];
|
|
206
200
|
const toBuild: HTMLElement[] = [];
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
201
|
+
|
|
202
|
+
const checkElement = (e: HTMLElement) => {
|
|
203
|
+
if (ElementHelper.hasVisionAttribute(e)) {
|
|
204
|
+
if (
|
|
205
|
+
(!forComponent && e.hasAttribute('slot'))
|
|
206
|
+
) return;
|
|
207
|
+
if (this.queued.indexOf(e) > -1) return;
|
|
208
|
+
this.queued.push(e);
|
|
209
|
+
toBuild.push(e);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
const scanChildren = (e: HTMLElement) => {
|
|
213
|
+
for (const element of Array.from(e.children) as HTMLElement[]) {
|
|
214
|
+
checkElement(element);
|
|
215
|
+
if (element.tagName.toLowerCase() !== 'template')
|
|
216
|
+
scanChildren(element);
|
|
219
217
|
}
|
|
220
218
|
}
|
|
219
|
+
checkElement(ele);
|
|
220
|
+
scanChildren(ele);
|
|
221
221
|
|
|
222
222
|
for (const element of toBuild) {
|
|
223
|
-
if (
|
|
223
|
+
if (element[Tag.TaggedVariable]) continue;
|
|
224
224
|
const tag: Tag = new Tag(element, this);
|
|
225
225
|
this.tags.push(tag);
|
|
226
226
|
newTags.push(tag);
|
|
227
|
-
allElements.push(element as HTMLElement);
|
|
228
227
|
}
|
|
229
228
|
|
|
230
229
|
if (isRoot)
|
|
@@ -295,14 +294,14 @@ export class DOM extends EventDispatcher {
|
|
|
295
294
|
return tags;
|
|
296
295
|
}
|
|
297
296
|
|
|
298
|
-
async getTagForElement(element: Element, create: boolean = false) {
|
|
297
|
+
async getTagForElement(element: Element, create: boolean = false, forComponent: boolean = false) {
|
|
299
298
|
if (element[Tag.TaggedVariable])
|
|
300
299
|
return element[Tag.TaggedVariable];
|
|
301
300
|
|
|
302
301
|
if (element && create) {
|
|
303
302
|
if (element instanceof HTMLElement)
|
|
304
303
|
element.setAttribute('vsn-ref', '');
|
|
305
|
-
await this.buildFrom(element.parentElement || element);
|
|
304
|
+
await this.buildFrom(element.parentElement || element, false, forComponent);
|
|
306
305
|
return await this.getTagForElement(element, false);
|
|
307
306
|
}
|
|
308
307
|
|
package/src/Tag.ts
CHANGED
|
@@ -62,15 +62,18 @@ export class Tag extends DOMObject {
|
|
|
62
62
|
this.onEventHandlers = {};
|
|
63
63
|
this.analyzeElementAttributes();
|
|
64
64
|
this._state = TagState.Instantiated;
|
|
65
|
-
if (
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
VisionHelper.window['Tags'].push(this);
|
|
65
|
+
if (this.hasAttribute('slot')) {
|
|
66
|
+
this.addEventHandler('slotted',[], (e) => {
|
|
67
|
+
console.log('slot change', e, this.element.assignedSlot);
|
|
68
|
+
})
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
71
|
|
|
72
|
+
public slotted(slot: HTMLSlotElement) {
|
|
73
|
+
this.slot = slot;
|
|
74
|
+
console.log('i am slotted', slot);
|
|
75
|
+
}
|
|
76
|
+
|
|
74
77
|
protected onAttributeStateChange(event) {
|
|
75
78
|
if (event.previouseState === AttributeState.Deferred) // @todo: what is this?
|
|
76
79
|
this._nonDeferredAttributes.length = 0;
|
|
@@ -26,15 +26,15 @@ export class JSONAttribute extends Attribute {
|
|
|
26
26
|
} else {
|
|
27
27
|
json = unescape(this.getAttributeValue());
|
|
28
28
|
}
|
|
29
|
-
const property = this.getAttributeBinding();
|
|
30
29
|
const data = JSON.parse(json);
|
|
30
|
+
|
|
31
31
|
if (data && typeof data === 'object' && data.constructor === Object) {
|
|
32
32
|
const newScope = new Scope(scope);
|
|
33
33
|
newScope.wrap(data);
|
|
34
34
|
scope.set(key, newScope);
|
|
35
|
+
} else {
|
|
36
|
+
scope.set(key, data);
|
|
35
37
|
}
|
|
36
|
-
|
|
37
|
-
scope.set(key, data);
|
|
38
38
|
await super.extract();
|
|
39
39
|
}
|
|
40
40
|
}
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '0.1.
|
|
1
|
+
export const VERSION = '0.1.88';
|
|
2
2
|
|
|
@@ -3,23 +3,23 @@ import {DOM} from "../../src/DOM";
|
|
|
3
3
|
describe('JSONAttribute', () => {
|
|
4
4
|
it("vsn-json should work with script/ld-json and an array", (done) => {
|
|
5
5
|
document.body.innerHTML = `
|
|
6
|
-
<script type="application/ld+json" vsn-json:
|
|
6
|
+
<script type="application/ld+json" vsn-json:t0>
|
|
7
7
|
[1,2,3,"four"]
|
|
8
8
|
</script>
|
|
9
9
|
`;
|
|
10
10
|
const dom = new DOM(document);
|
|
11
11
|
dom.once('built', async () => {
|
|
12
|
-
expect(dom.root.scope.get('
|
|
13
|
-
expect(dom.root.scope.get('
|
|
14
|
-
expect(dom.root.scope.get('
|
|
15
|
-
expect(dom.root.scope.get('
|
|
12
|
+
expect(dom.root.scope.get('t0')[0]).toBe(1);
|
|
13
|
+
expect(dom.root.scope.get('t0')[1]).toBe(2);
|
|
14
|
+
expect(dom.root.scope.get('t0')[2]).toBe(3);
|
|
15
|
+
expect(dom.root.scope.get('t0')[3]).toBe("four");
|
|
16
16
|
done();
|
|
17
17
|
});
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
it("vsn-json should work with script/ld-json and an object", (done) => {
|
|
21
21
|
document.body.innerHTML = `
|
|
22
|
-
<script type="application/ld+json" vsn-json:
|
|
22
|
+
<script type="application/ld+json" vsn-json:t1>
|
|
23
23
|
{
|
|
24
24
|
"testing": [1,2,3,"four"],
|
|
25
25
|
"test": ["one","two","three",4],
|
|
@@ -29,47 +29,49 @@ describe('JSONAttribute', () => {
|
|
|
29
29
|
`;
|
|
30
30
|
const dom = new DOM(document);
|
|
31
31
|
dom.once('built', async () => {
|
|
32
|
-
expect(dom.root.scope.get('
|
|
33
|
-
expect(dom.root.scope.get('
|
|
34
|
-
expect(dom.root.scope.get('
|
|
35
|
-
expect(dom.root.scope.get('
|
|
36
|
-
expect(dom.root.scope.get('
|
|
37
|
-
expect(dom.root.scope.get('
|
|
38
|
-
expect(dom.root.scope.get('
|
|
39
|
-
expect(dom.root.scope.get('
|
|
40
|
-
expect(dom.root.scope.get('
|
|
32
|
+
expect(dom.root.scope.get('t1').get("testing")[0]).toBe(1);
|
|
33
|
+
expect(dom.root.scope.get('t1').get("testing")[1]).toBe(2);
|
|
34
|
+
expect(dom.root.scope.get('t1').get("testing")[2]).toBe(3);
|
|
35
|
+
expect(dom.root.scope.get('t1').get("testing")[3]).toBe("four");
|
|
36
|
+
expect(dom.root.scope.get('t1').get("test")[0]).toBe("one");
|
|
37
|
+
expect(dom.root.scope.get('t1').get("test")[1]).toBe("two");
|
|
38
|
+
expect(dom.root.scope.get('t1').get("test")[2]).toBe("three");
|
|
39
|
+
expect(dom.root.scope.get('t1').get("test")[3]).toBe(4);
|
|
40
|
+
expect(dom.root.scope.get('t1').get("val")).toBe(111);
|
|
41
41
|
done();
|
|
42
42
|
});
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
it("vsn-json should work with div and an array", (done) => {
|
|
46
46
|
document.body.innerHTML = `
|
|
47
|
-
<div vsn-json:
|
|
47
|
+
<div vsn-json:t2="[1,2,3,"four"]"></div>
|
|
48
48
|
`;
|
|
49
|
+
|
|
49
50
|
const dom = new DOM(document);
|
|
50
51
|
dom.once('built', async () => {
|
|
51
|
-
|
|
52
|
-
expect(dom.root.scope.get('
|
|
53
|
-
expect(dom.root.scope.get('
|
|
54
|
-
expect(dom.root.scope.get('
|
|
52
|
+
console.log('scope keys', dom.root.scope.keys);
|
|
53
|
+
expect(dom.root.scope.get('t2')[0]).toBe(1);
|
|
54
|
+
expect(dom.root.scope.get('t2')[1]).toBe(2);
|
|
55
|
+
expect(dom.root.scope.get('t2')[2]).toBe(3);
|
|
56
|
+
expect(dom.root.scope.get('t2')[3]).toBe("four");
|
|
55
57
|
done();
|
|
56
58
|
});
|
|
57
59
|
});
|
|
58
60
|
|
|
59
61
|
it("vsn-json should work with div and an object", (done) => {
|
|
60
62
|
document.body.innerHTML = `
|
|
61
|
-
<div vsn-json:
|
|
63
|
+
<div vsn-json:t3="{"testing": [1,2,3,"four"],"test": ["one","two","three",4]}"></div>
|
|
62
64
|
`;
|
|
63
65
|
const dom = new DOM(document);
|
|
64
66
|
dom.once('built', async () => {
|
|
65
|
-
expect(dom.root.scope.get('
|
|
66
|
-
expect(dom.root.scope.get('
|
|
67
|
-
expect(dom.root.scope.get('
|
|
68
|
-
expect(dom.root.scope.get('
|
|
69
|
-
expect(dom.root.scope.get('
|
|
70
|
-
expect(dom.root.scope.get('
|
|
71
|
-
expect(dom.root.scope.get('
|
|
72
|
-
expect(dom.root.scope.get('
|
|
67
|
+
expect(dom.root.scope.get('t3').get("testing")[0]).toBe(1);
|
|
68
|
+
expect(dom.root.scope.get('t3').get("testing")[1]).toBe(2);
|
|
69
|
+
expect(dom.root.scope.get('t3').get("testing")[2]).toBe(3);
|
|
70
|
+
expect(dom.root.scope.get('t3').get("testing")[3]).toBe("four");
|
|
71
|
+
expect(dom.root.scope.get('t3').get("test")[0]).toBe("one");
|
|
72
|
+
expect(dom.root.scope.get('t3').get("test")[1]).toBe("two");
|
|
73
|
+
expect(dom.root.scope.get('t3').get("test")[2]).toBe("three");
|
|
74
|
+
expect(dom.root.scope.get('t3').get("test")[3]).toBe(4);
|
|
73
75
|
done();
|
|
74
76
|
});
|
|
75
77
|
});
|