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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vsn",
3
- "version": "0.1.99",
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-ref', '');
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', async (e) => {
29
- for (const child of slot.assignedNodes()) {
30
- const t = await DOM.instance.buildTag(child as HTMLElement, false, SlottedTag);
31
- await t?.slotted(slot);
32
- }
33
- slotTagPromise.then((slotTag) => {
34
- slotTag.buildAttributes();
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
- DOM.instance.buildFrom(this.shadow);
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<Tag> {
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: Tag = new cls(element, this);
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);
@@ -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 get parentTag(): Tag {
249
- if (!this._parentTag) {
250
- let parentElement: HTMLElement = this.element.parentElement as HTMLElement;
251
- let foundParent = false;
252
- while (parentElement) {
253
- if (parentElement[Tag.TaggedVariable]) {
254
- foundParent = true;
255
- this.parentTag = parentElement[Tag.TaggedVariable];
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
- if (!foundParent && DOM.instance.root !== this)
270
- return DOM.instance.root;
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.addChild(this);
279
+ if (tag) {
280
+ tag.addChild(this);
282
281
 
283
- if (this.scope !== tag.scope)
284
- this.scope.parentScope = tag.scope;
282
+ if (this.scope !== tag.scope) {
283
+ this.scope.parentScope = tag.scope;
284
+ }
285
+ }
285
286
  }
286
287
 
287
288
  public get scope(): Scope {
@@ -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.99';
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
- customElements.define(name, cls);
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 {