vsn 0.1.99 → 0.1.102
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/examples/component-slots.html +4 -1
- package/demo/vsn.js +2 -2
- package/dist/AST.js +8 -8
- package/dist/AST.js.map +1 -1
- package/dist/Component.d.ts +1 -0
- package/dist/Component.js +66 -30
- package/dist/Component.js.map +1 -1
- package/dist/DOM.d.ts +4 -2
- package/dist/DOM.js +46 -1
- package/dist/DOM.js.map +1 -1
- package/dist/Scope.js +2 -0
- package/dist/Scope.js.map +1 -1
- package/dist/Tag/SlottedTag.d.ts +4 -0
- package/dist/Tag/SlottedTag.js +59 -0
- package/dist/Tag/SlottedTag.js.map +1 -1
- package/dist/Tag.d.ts +2 -1
- package/dist/Tag.js +28 -45
- package/dist/Tag.js.map +1 -1
- package/dist/attributes/If.js +3 -0
- package/dist/attributes/If.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/vsn.js +8 -1
- package/dist/vsn.js.map +1 -1
- package/dist/vsn.min.js +2 -2
- package/package.json +7 -2
- package/src/AST.ts +8 -8
- package/src/Component.ts +20 -10
- package/src/DOM.ts +33 -4
- package/src/Scope.ts +3 -0
- package/src/Tag/SlottedTag.ts +14 -0
- package/src/Tag.ts +32 -31
- package/src/attributes/If.ts +3 -0
- package/src/version.ts +1 -1
- package/src/vsn.ts +7 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vsn",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.102",
|
|
4
4
|
"description": "SEO Friendly Javascript/Typescript Framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -9,7 +9,12 @@
|
|
|
9
9
|
"ajax",
|
|
10
10
|
"hateoas",
|
|
11
11
|
"rest",
|
|
12
|
-
"seo"
|
|
12
|
+
"seo",
|
|
13
|
+
"reactive",
|
|
14
|
+
"component",
|
|
15
|
+
"web component",
|
|
16
|
+
"web components",
|
|
17
|
+
"web component framework"
|
|
13
18
|
],
|
|
14
19
|
"main": "./dist/vsn.js",
|
|
15
20
|
"scripts": {
|
package/src/AST.ts
CHANGED
|
@@ -282,14 +282,6 @@ const TOKEN_PATTERNS: TokenPattern[] = [
|
|
|
282
282
|
type: TokenType.NOT_EQUALS,
|
|
283
283
|
pattern: /^!=/
|
|
284
284
|
},
|
|
285
|
-
{
|
|
286
|
-
type: TokenType.GREATER_THAN,
|
|
287
|
-
pattern: /^>/
|
|
288
|
-
},
|
|
289
|
-
{
|
|
290
|
-
type: TokenType.LESS_THAN,
|
|
291
|
-
pattern: /^</
|
|
292
|
-
},
|
|
293
285
|
{
|
|
294
286
|
type: TokenType.GREATER_THAN_EQUAL,
|
|
295
287
|
pattern: /^>=/
|
|
@@ -298,6 +290,14 @@ const TOKEN_PATTERNS: TokenPattern[] = [
|
|
|
298
290
|
type: TokenType.LESS_THAN_EQUAL,
|
|
299
291
|
pattern: /^<=/
|
|
300
292
|
},
|
|
293
|
+
{
|
|
294
|
+
type: TokenType.GREATER_THAN,
|
|
295
|
+
pattern: /^>/
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
type: TokenType.LESS_THAN,
|
|
299
|
+
pattern: /^</
|
|
300
|
+
},
|
|
301
301
|
{
|
|
302
302
|
type: TokenType.COLON,
|
|
303
303
|
pattern: /^:/
|
package/src/Component.ts
CHANGED
|
@@ -20,22 +20,32 @@ export class Component extends HTMLElement {
|
|
|
20
20
|
template = Registry.instance.templates.getSynchronous(this.tagName.toLowerCase());
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
this.setAttribute('vsn-
|
|
24
|
-
|
|
23
|
+
this.setAttribute('vsn-scope', '');
|
|
25
24
|
this.shadow.appendChild(template.content.cloneNode(true));
|
|
25
|
+
for (const child of Array.from(this.shadow.children)) {
|
|
26
|
+
child['shadowParent'] = this;
|
|
27
|
+
}
|
|
26
28
|
this.shadow.querySelectorAll('slot').forEach((slot) => {
|
|
27
29
|
const slotTagPromise = DOM.instance.buildTag(slot,false, SlotTag);
|
|
28
|
-
slot.addEventListener('slotchange',
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
slot.addEventListener('slotchange', (e) => {
|
|
31
|
+
slotTagPromise.then(async (slotTag) => {
|
|
32
|
+
for (const child of slot.assignedNodes()) {
|
|
33
|
+
const t = await DOM.instance.buildTag<SlottedTag>(child as HTMLElement, false, SlottedTag);
|
|
34
|
+
await t?.slotted(slotTag);
|
|
35
|
+
}
|
|
36
|
+
await DOM.instance.setupTags([slotTag]);
|
|
35
37
|
});
|
|
36
38
|
});
|
|
37
39
|
});
|
|
40
|
+
}
|
|
38
41
|
|
|
39
|
-
|
|
42
|
+
async connectedCallback() {
|
|
43
|
+
const tag = await DOM.instance.buildTag(this, true);
|
|
44
|
+
tag.createScope(true);
|
|
45
|
+
const componentTags = await DOM.instance.buildFrom(this.shadow);
|
|
46
|
+
await DOM.instance.resetBranch(tag);
|
|
47
|
+
for (const componentTag of componentTags) {
|
|
48
|
+
await DOM.instance.resetBranch(componentTag);
|
|
49
|
+
}
|
|
40
50
|
}
|
|
41
51
|
}
|
package/src/DOM.ts
CHANGED
|
@@ -221,15 +221,15 @@ export class DOM extends EventDispatcher {
|
|
|
221
221
|
return discovered;
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
async buildTag(element: HTMLElement, returnExisting: boolean = false, cls: any = Tag): Promise<
|
|
224
|
+
async buildTag<T = Tag>(element: HTMLElement, returnExisting: boolean = false, cls: any = Tag): Promise<T> {
|
|
225
225
|
if (element[Tag.TaggedVariable]) return returnExisting ? element[Tag.TaggedVariable] : null;
|
|
226
226
|
if (element.tagName.toLowerCase() === 'slot')
|
|
227
227
|
cls = SlotTag;
|
|
228
228
|
else if (element.hasAttribute('slot'))
|
|
229
229
|
cls = SlottedTag;
|
|
230
230
|
|
|
231
|
-
const tag:
|
|
232
|
-
this.tags.push(tag);
|
|
231
|
+
const tag: T = new cls(element, this);
|
|
232
|
+
this.tags.push(tag as any);
|
|
233
233
|
return tag;
|
|
234
234
|
}
|
|
235
235
|
|
|
@@ -265,7 +265,7 @@ export class DOM extends EventDispatcher {
|
|
|
265
265
|
}
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
-
async buildFrom(ele: any, isRoot: boolean = false, forComponent: boolean = false) {
|
|
268
|
+
async buildFrom(ele: any, isRoot: boolean = false, forComponent: boolean = false): Promise<Tag[]> {
|
|
269
269
|
if (isRoot) {
|
|
270
270
|
document.body.setAttribute('vsn-root', '');
|
|
271
271
|
document.ondragover = (e) => e.cancelable && e.preventDefault(); // Allow dragging over document
|
|
@@ -304,6 +304,7 @@ export class DOM extends EventDispatcher {
|
|
|
304
304
|
this.dispatch('builtRoot')
|
|
305
305
|
}
|
|
306
306
|
this.dispatch('built', newTags);
|
|
307
|
+
return newTags;
|
|
307
308
|
}
|
|
308
309
|
|
|
309
310
|
async getTagsForElements(elements: Element[], create: boolean = false) {
|
|
@@ -357,10 +358,38 @@ export class DOM extends EventDispatcher {
|
|
|
357
358
|
return null;
|
|
358
359
|
}
|
|
359
360
|
|
|
361
|
+
public async resetBranch(e: Tag | HTMLElement) {
|
|
362
|
+
if (e instanceof Tag)
|
|
363
|
+
e = e.element;
|
|
364
|
+
const tag = e[Tag.TaggedVariable];
|
|
365
|
+
if (tag)
|
|
366
|
+
tag.parentTag = null;
|
|
367
|
+
|
|
368
|
+
const children = Array.from(e.children) as HTMLElement[]
|
|
369
|
+
for (const t of children) {
|
|
370
|
+
await this.resetBranch(t);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
if (tag && tag.uniqueScope && tag.parentTag) {
|
|
374
|
+
tag.scope.parentScope = tag.parentTag.scope;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
360
378
|
public static get instance(): DOM {
|
|
361
379
|
if (!DOM._instance)
|
|
362
380
|
DOM._instance = new DOM(document ,false, false);
|
|
363
381
|
|
|
364
382
|
return DOM._instance;
|
|
365
383
|
}
|
|
384
|
+
|
|
385
|
+
public static getParentElement(element: HTMLElement): HTMLElement {
|
|
386
|
+
if (element.parentElement) {
|
|
387
|
+
return element.parentElement as HTMLElement;
|
|
388
|
+
} else if (element.assignedSlot) {
|
|
389
|
+
return element.assignedSlot.parentElement as HTMLElement;
|
|
390
|
+
} else if (element['shadowParent']) {
|
|
391
|
+
return element['shadowParent'];
|
|
392
|
+
}
|
|
393
|
+
return null;
|
|
394
|
+
}
|
|
366
395
|
}
|
package/src/Scope.ts
CHANGED
|
@@ -32,6 +32,9 @@ export class Scope extends EventDispatcher {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
public set parentScope(scope: Scope) {
|
|
35
|
+
if (this._parentScope && this._parentScope !== scope)
|
|
36
|
+
this._parentScope.removeChild(this);
|
|
37
|
+
|
|
35
38
|
if (scope) {
|
|
36
39
|
this._parentScope = scope;
|
|
37
40
|
scope.addChild(this);
|
package/src/Tag/SlottedTag.ts
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
import {Tag} from "../Tag";
|
|
2
|
+
import {SlotTag} from "./SlotTag";
|
|
2
3
|
|
|
3
4
|
export class SlottedTag extends Tag {
|
|
5
|
+
protected slotTag: SlotTag;
|
|
4
6
|
|
|
7
|
+
public async slotted(slot: SlotTag) {
|
|
8
|
+
this.slotTag = slot;
|
|
9
|
+
this.slot = slot.element as HTMLSlotElement;
|
|
10
|
+
this.parentTag = slot;
|
|
11
|
+
await this.dom.setupTags([this]);
|
|
12
|
+
await this.dom.buildFrom(this.element, false, true);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
findParentTag(): Tag {
|
|
16
|
+
this.parentTag = this.slotTag;
|
|
17
|
+
return this._parentTag;
|
|
18
|
+
}
|
|
5
19
|
}
|
package/src/Tag.ts
CHANGED
|
@@ -73,13 +73,6 @@ export class Tag extends DOMObject {
|
|
|
73
73
|
return this._meta;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
public async slotted(slot: HTMLSlotElement) {
|
|
77
|
-
this.slot = slot;
|
|
78
|
-
this.parentTag = await this.dom.getTagForElement(slot);
|
|
79
|
-
await this.dom.setupTags([this]);
|
|
80
|
-
await this.dom.buildFrom(this.element, false, true);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
76
|
protected onAttributeStateChange(event) {
|
|
84
77
|
if (event.previouseState === AttributeState.Deferred) // @todo: what is this?
|
|
85
78
|
this._nonDeferredAttributes.length = 0;
|
|
@@ -241,33 +234,33 @@ export class Tag extends DOMObject {
|
|
|
241
234
|
this._children.push(tag);
|
|
242
235
|
}
|
|
243
236
|
|
|
237
|
+
public removeChild(tag: Tag) {
|
|
238
|
+
this._children.splice(this._children.indexOf(tag), 1);
|
|
239
|
+
}
|
|
240
|
+
|
|
244
241
|
public get children(): Tag[] {
|
|
245
242
|
return [...this._children];
|
|
246
243
|
}
|
|
247
244
|
|
|
248
|
-
public
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
break;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
if (parentElement.parentElement) {
|
|
260
|
-
parentElement = parentElement.parentElement as HTMLElement;
|
|
261
|
-
} else if (parentElement.assignedSlot) {
|
|
262
|
-
parentElement = parentElement.assignedSlot.parentElement as HTMLElement;
|
|
263
|
-
} else {
|
|
264
|
-
parentElement = null;
|
|
265
|
-
}
|
|
266
|
-
|
|
245
|
+
public findParentTag() {
|
|
246
|
+
let parentElement: HTMLElement = DOM.getParentElement(this.element);
|
|
247
|
+
let foundParent = false;
|
|
248
|
+
while (parentElement) {
|
|
249
|
+
if (parentElement[Tag.TaggedVariable]) {
|
|
250
|
+
foundParent = true;
|
|
251
|
+
this.parentTag = parentElement[Tag.TaggedVariable];
|
|
252
|
+
break;
|
|
267
253
|
}
|
|
254
|
+
parentElement = DOM.getParentElement(parentElement);
|
|
255
|
+
}
|
|
268
256
|
|
|
269
|
-
|
|
270
|
-
|
|
257
|
+
if (!foundParent && DOM.instance.root !== this)
|
|
258
|
+
return DOM.instance.root;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
public get parentTag(): Tag {
|
|
262
|
+
if (!this._parentTag) {
|
|
263
|
+
this.findParentTag();
|
|
271
264
|
}
|
|
272
265
|
|
|
273
266
|
return this._parentTag;
|
|
@@ -277,11 +270,19 @@ export class Tag extends DOMObject {
|
|
|
277
270
|
if (this.element === document.body)
|
|
278
271
|
return;
|
|
279
272
|
|
|
273
|
+
if (this._parentTag && this._parentTag !== tag) {
|
|
274
|
+
this._parentTag.removeChild(this);
|
|
275
|
+
this.scope.parentScope = null;
|
|
276
|
+
}
|
|
277
|
+
|
|
280
278
|
this._parentTag = tag;
|
|
281
|
-
tag
|
|
279
|
+
if (tag) {
|
|
280
|
+
tag.addChild(this);
|
|
282
281
|
|
|
283
|
-
|
|
284
|
-
|
|
282
|
+
if (this.scope !== tag.scope) {
|
|
283
|
+
this.scope.parentScope = tag.scope;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
285
286
|
}
|
|
286
287
|
|
|
287
288
|
public get scope(): Scope {
|
package/src/attributes/If.ts
CHANGED
|
@@ -9,6 +9,7 @@ export class If extends Attribute {
|
|
|
9
9
|
|
|
10
10
|
public async compile() {
|
|
11
11
|
const statement: string = this.getAttributeValue();
|
|
12
|
+
console.log('if statement for', this.tag.element, statement);
|
|
12
13
|
this.tree = new Tree(statement);
|
|
13
14
|
await this.tree.prepare(this.tag.scope, this.tag.dom, this.tag);
|
|
14
15
|
await super.compile();
|
|
@@ -33,8 +34,10 @@ export class If extends Attribute {
|
|
|
33
34
|
const result: boolean = await this.tree.evaluate(this.tag.scope, this.tag.dom, this.tag);
|
|
34
35
|
if (result) {
|
|
35
36
|
this.tag.show();
|
|
37
|
+
console.log('show', this.tag.element);
|
|
36
38
|
} else {
|
|
37
39
|
this.tag.hide();
|
|
40
|
+
console.log('hide', this.tag.element);
|
|
38
41
|
}
|
|
39
42
|
}
|
|
40
43
|
}
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '0.1.
|
|
1
|
+
export const VERSION = '0.1.102';
|
|
2
2
|
|
package/src/vsn.ts
CHANGED
|
@@ -47,7 +47,13 @@ export class Vision extends EventDispatcher {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
protected defineComponent(name, cls) {
|
|
50
|
-
|
|
50
|
+
if (this.dom.built) {
|
|
51
|
+
customElements.define(name, cls);
|
|
52
|
+
} else {
|
|
53
|
+
this.dom.once('built', () => {
|
|
54
|
+
customElements.define(name, cls);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
51
57
|
}
|
|
52
58
|
|
|
53
59
|
public get dom(): DOM {
|