vsn 0.1.97 → 0.1.100

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.
Files changed (78) hide show
  1. package/demo/examples/component-slots.html +26 -0
  2. package/demo/vsn.js +2 -2
  3. package/dist/AST/ElementAttributeNode.js +5 -5
  4. package/dist/AST/ElementAttributeNode.js.map +1 -1
  5. package/dist/AST/ElementStyleNode.js +2 -2
  6. package/dist/AST/ElementStyleNode.js.map +1 -1
  7. package/dist/AST/FunctionCallNode.js +1 -1
  8. package/dist/AST/FunctionCallNode.js.map +1 -1
  9. package/dist/AST/ObjectNode.js +1 -1
  10. package/dist/AST/ObjectNode.js.map +1 -1
  11. package/dist/AST/ScopeMemberNode.js +2 -2
  12. package/dist/AST/ScopeMemberNode.js.map +1 -1
  13. package/dist/Component.d.ts +1 -0
  14. package/dist/Component.js +69 -24
  15. package/dist/Component.js.map +1 -1
  16. package/dist/DOM/DOMObject.d.ts +1 -0
  17. package/dist/DOM/DOMObject.js +7 -0
  18. package/dist/DOM/DOMObject.js.map +1 -1
  19. package/dist/DOM.d.ts +5 -4
  20. package/dist/DOM.js +114 -32
  21. package/dist/DOM.js.map +1 -1
  22. package/dist/Formats.js +4 -1
  23. package/dist/Formats.js.map +1 -1
  24. package/dist/Query.d.ts +1 -1
  25. package/dist/Query.js +2 -2
  26. package/dist/Query.js.map +1 -1
  27. package/dist/Scope.d.ts +1 -1
  28. package/dist/Scope.js +19 -1
  29. package/dist/Scope.js.map +1 -1
  30. package/dist/Tag/ShadowRootTag.d.ts +3 -0
  31. package/dist/Tag/ShadowRootTag.js +28 -0
  32. package/dist/Tag/ShadowRootTag.js.map +1 -0
  33. package/dist/Tag/SlotTag.d.ts +3 -0
  34. package/dist/Tag/SlotTag.js +28 -0
  35. package/dist/Tag/SlotTag.js.map +1 -0
  36. package/dist/Tag/SlottedTag.d.ts +7 -0
  37. package/dist/Tag/SlottedTag.js +87 -0
  38. package/dist/Tag/SlottedTag.js.map +1 -0
  39. package/dist/Tag/{List.d.ts → TagList.d.ts} +0 -0
  40. package/dist/Tag/{List.js → TagList.js} +1 -1
  41. package/dist/Tag/TagList.js.map +1 -0
  42. package/dist/Tag.d.ts +12 -2
  43. package/dist/Tag.js +45 -43
  44. package/dist/Tag.js.map +1 -1
  45. package/dist/attributes/List.d.ts +1 -0
  46. package/dist/attributes/List.js +27 -9
  47. package/dist/attributes/List.js.map +1 -1
  48. package/dist/attributes/ScopeAttribute.js +14 -12
  49. package/dist/attributes/ScopeAttribute.js.map +1 -1
  50. package/dist/version.d.ts +1 -1
  51. package/dist/version.js +1 -1
  52. package/dist/version.js.map +1 -1
  53. package/package.json +7 -2
  54. package/src/AST/ElementAttributeNode.ts +1 -1
  55. package/src/AST/ElementStyleNode.ts +1 -1
  56. package/src/AST/FunctionCallNode.ts +1 -1
  57. package/src/AST/ObjectNode.ts +1 -1
  58. package/src/AST/ScopeMemberNode.ts +1 -1
  59. package/src/Component.ts +26 -9
  60. package/src/DOM/DOMObject.ts +4 -0
  61. package/src/DOM.ts +59 -7
  62. package/src/Formats.ts +4 -1
  63. package/src/Query.ts +1 -1
  64. package/src/Scope.ts +17 -1
  65. package/src/Tag/ShadowRootTag.ts +5 -0
  66. package/src/Tag/SlotTag.ts +5 -0
  67. package/src/Tag/SlottedTag.ts +19 -0
  68. package/src/Tag/{List.ts → TagList.ts} +0 -0
  69. package/src/Tag.ts +49 -43
  70. package/src/attributes/List.ts +29 -7
  71. package/src/attributes/ScopeAttribute.ts +12 -8
  72. package/src/version.ts +1 -1
  73. package/test/AST/ClassNode.spec.ts +1 -1
  74. package/test/Tag/TagList.spec.ts +1 -1
  75. package/test/attributes/ListItem.spec.ts +2 -2
  76. package/dist/Tag/List.js.map +0 -1
  77. package/dist/vsn.min.js +0 -3
  78. package/dist/vsn.min.js.LICENSE.txt +0 -9
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);
@@ -94,7 +97,20 @@ export class Scope extends EventDispatcher {
94
97
  return value;
95
98
  }
96
99
 
97
- set(key: string, value: any) {
100
+ set(key: string, value: any, detectType: boolean = false): void {
101
+ if (detectType) {
102
+ const type = typeof value;
103
+ if (type === 'number') {
104
+ if (value % 1 === 0)
105
+ this.setType(key, 'integer');
106
+ else
107
+ this.setType(key, 'float');
108
+ } else if (type === 'string') {
109
+ this.setType(key, 'string');
110
+ } else if (type === 'boolean') {
111
+ this.setType(key, 'boolean');
112
+ }
113
+ }
98
114
  if (!this._data.hasProperty(key))
99
115
  this._data.createProperty(key);
100
116
  this._data[key] = value;
@@ -0,0 +1,5 @@
1
+ import {Tag} from "../Tag";
2
+
3
+ export class ShadowRootTag extends Tag {
4
+
5
+ }
@@ -0,0 +1,5 @@
1
+ import {Tag} from "../Tag";
2
+
3
+
4
+ export class SlotTag extends Tag {
5
+ }
@@ -0,0 +1,19 @@
1
+ import {Tag} from "../Tag";
2
+ import {SlotTag} from "./SlotTag";
3
+
4
+ export class SlottedTag extends Tag {
5
+ protected slotTag: SlotTag;
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
+ }
19
+ }
File without changes
package/src/Tag.ts CHANGED
@@ -26,7 +26,9 @@ export class Tag extends DOMObject {
26
26
  public readonly parsedAttributes: { [key: string]: string[]; };
27
27
  public readonly deferredAttributes: Attribute[] = [];
28
28
  protected _state: TagState;
29
+ protected _meta: { [key: string]: any; };
29
30
  protected attributes: Attribute[];
31
+ protected attributeMap: { [key: string]: Attribute; };
30
32
  protected _nonDeferredAttributes: Attribute[] = [];
31
33
  protected _parentTag: Tag;
32
34
  protected _children: Tag[] = [];
@@ -59,19 +61,16 @@ export class Tag extends DOMObject {
59
61
  this.rawAttributes = {};
60
62
  this.parsedAttributes = {};
61
63
  this.attributes = [];
64
+ this.attributeMap = {};
62
65
  this.onEventHandlers = {};
63
66
  this.analyzeElementAttributes();
64
67
  this._state = TagState.Instantiated;
65
- if (this.hasAttribute('slot')) {
66
- this.addEventHandler('slotted',[], (e) => {
67
- console.log('slot change', e, this.element.assignedSlot);
68
- })
69
- }
70
68
  }
71
69
 
72
- public slotted(slot: HTMLSlotElement) {
73
- this.slot = slot;
74
- console.log('i am slotted', slot);
70
+ public get meta() {
71
+ if (!this._meta)
72
+ this._meta = {};
73
+ return this._meta;
75
74
  }
76
75
 
77
76
  protected onAttributeStateChange(event) {
@@ -235,33 +234,33 @@ export class Tag extends DOMObject {
235
234
  this._children.push(tag);
236
235
  }
237
236
 
237
+ public removeChild(tag: Tag) {
238
+ this._children.splice(this._children.indexOf(tag), 1);
239
+ }
240
+
238
241
  public get children(): Tag[] {
239
242
  return [...this._children];
240
243
  }
241
244
 
242
- public get parentTag(): Tag {
243
- if (!this._parentTag) {
244
- let parentElement: HTMLElement = this.element.parentElement as HTMLElement;
245
- let foundParent = false;
246
- while (parentElement) {
247
- if (parentElement[Tag.TaggedVariable]) {
248
- foundParent = true;
249
- this.parentTag = parentElement[Tag.TaggedVariable];
250
- break;
251
- }
252
-
253
- if (parentElement.parentElement) {
254
- parentElement = parentElement.parentElement as HTMLElement;
255
- } else if (parentElement.assignedSlot) {
256
- parentElement = parentElement.assignedSlot.parentElement as HTMLElement;
257
- } else {
258
- parentElement = null;
259
- }
260
-
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;
261
253
  }
254
+ parentElement = DOM.getParentElement(parentElement);
255
+ }
262
256
 
263
- if (!foundParent && DOM.instance.root !== this)
264
- 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();
265
264
  }
266
265
 
267
266
  return this._parentTag;
@@ -271,11 +270,19 @@ export class Tag extends DOMObject {
271
270
  if (this.element === document.body)
272
271
  return;
273
272
 
273
+ if (this._parentTag && this._parentTag !== tag) {
274
+ this._parentTag.removeChild(this);
275
+ this.scope.parentScope = null;
276
+ }
277
+
274
278
  this._parentTag = tag;
275
- tag.addChild(this);
279
+ if (tag) {
280
+ tag.addChild(this);
276
281
 
277
- if (this.scope !== tag.scope)
278
- this.scope.parentScope = tag.scope;
282
+ if (this.scope !== tag.scope) {
283
+ this.scope.parentScope = tag.scope;
284
+ }
285
+ }
279
286
  }
280
287
 
281
288
  public get scope(): Scope {
@@ -432,7 +439,6 @@ export class Tag extends DOMObject {
432
439
  public async buildAttributes() {
433
440
  let requiresScope = false;
434
441
  let defer: boolean = false;
435
- this.attributes.length = 0;
436
442
  const isMobile: boolean = VisionHelper.isMobile();
437
443
  if (this.element.offsetParent === null ||
438
444
  this.hasAttribute('hidden') ||
@@ -445,17 +451,15 @@ export class Tag extends DOMObject {
445
451
  const slot: Tag = this.isSlot ? this : null;
446
452
  for (const tag of tags) {
447
453
  for (let attr in this.rawAttributes) {
448
- if (this.hasModifier(attr, 'mobile')) {
449
- if (!isMobile) {
450
- continue;
451
- }
452
- }
454
+ if (tag.attributeMap[attr])
455
+ continue;
453
456
 
454
- if (this.hasModifier(attr, 'desktop')) {
455
- if (isMobile) {
456
- continue;
457
- }
458
- }
457
+ if (this.hasModifier(attr, 'mobile') && !isMobile)
458
+ continue;
459
+
460
+
461
+ if (this.hasModifier(attr, 'desktop') && isMobile)
462
+ continue;
459
463
 
460
464
  const attrClass = await this.getAttributeClass(attr);
461
465
  if (attrClass) {
@@ -463,7 +467,9 @@ export class Tag extends DOMObject {
463
467
  requiresScope = true;
464
468
 
465
469
  const attrObj = attrClass.create(tag, attr, attrClass, slot);
470
+
466
471
  tag.attributes.push(attrObj);
472
+ tag.attributeMap[attr] = attrObj;
467
473
  if (defer && attrClass.canDefer) {
468
474
  await attrObj.defer();
469
475
  tag.deferredAttributes.push(attrObj);
@@ -5,9 +5,11 @@ import {ElementHelper} from "../helpers/ElementHelper";
5
5
  import {Registry} from "../Registry";
6
6
  import {DOM} from "../DOM";
7
7
  import {Scope} from "../Scope";
8
+ import {ScopeData} from "../Scope/ScopeData";
8
9
 
9
10
  @Registry.attribute('vsn-list')
10
11
  export class List extends Attribute {
12
+ public static readonly MetaItemSetupFlag = 'vsn-list-item-setup';
11
13
  public static readonly canDefer: boolean = false;
12
14
  public static readonly scoped: boolean = true;
13
15
 
@@ -145,6 +147,13 @@ export class List extends Attribute {
145
147
  }
146
148
  delete element[Tag.TaggedVariable];
147
149
 
150
+ // Collect raw data
151
+ let data;
152
+ if (obj instanceof ScopeData)
153
+ data = obj.getData();
154
+ else
155
+ data = Object.assign({}, obj);
156
+
148
157
  // Setup new tag
149
158
  const tag = await this.tag.dom.buildTag(element, true);
150
159
  await this.setupTagScope(tag, obj);
@@ -153,31 +162,44 @@ export class List extends Attribute {
153
162
  this.tag.element.appendChild(element);
154
163
  await this.tag.dom.setupTags([tag]);
155
164
  await this.tag.dom.buildFrom(this.tag.element);
165
+
166
+ // Make sure we're using the correct data (Template may have vsn-bind values that are not desired)
167
+ const itemScope = tag.scope.get(this.listItemName);
168
+ if (itemScope instanceof Scope && data) {
169
+ itemScope.data.setData(data);
170
+ }
171
+
156
172
  this.tags.push(tag);
157
173
  this.tag.dispatch('add', obj);
158
174
  }
159
175
 
160
176
  async setupTagScope(tag: Tag, obj: any) {
177
+ if (tag.meta[List.MetaItemSetupFlag])
178
+ return;
179
+
161
180
  tag.createScope(true);
181
+ const itemScope = new Scope(tag.scope);
162
182
 
163
- // Setup new scope & class, if defined
183
+ // Setup new scope & model class, if defined
164
184
  const modelName: string = this.listItemModel;
165
185
  let cls;
166
186
  if (modelName)
167
187
  cls = await Registry.instance.models.get(modelName);
168
188
 
169
189
  if (cls) {
170
- if (!obj || !(obj instanceof cls))
190
+ if (!obj || !(obj instanceof cls)) {
171
191
  obj = new cls(obj);
192
+ }
172
193
  }
173
194
 
174
195
  // Check if the class is set up already
175
- if (!cls || (!(tag.scope.data instanceof cls) && !(tag.scope.wrapped instanceof cls))) {
176
- if (tag.scope.wrapped)
177
- tag.scope.unwrap();
178
- tag.wrap(obj);
196
+ if (!cls || (!(itemScope.data instanceof cls) && !(itemScope.wrapped instanceof cls))) {
197
+ if (itemScope.wrapped)
198
+ itemScope.unwrap();
199
+ itemScope.wrap(obj, true, true);
179
200
  }
180
201
 
181
- tag.scope.set(this.listItemName, tag.scope);
202
+ tag.scope.set(this.listItemName, itemScope);
203
+ tag.meta[List.MetaItemSetupFlag] = true;
182
204
  }
183
205
  }
@@ -20,17 +20,21 @@ export class ScopeAttribute extends Attribute {
20
20
 
21
21
  public async extract() {
22
22
  if (this.tree) {
23
- const value = await this.tree.evaluate(this.tag.scope, this.tag.dom, this.tag);
24
- if (!(value instanceof Scope)) {
25
- throw new Error(`vsn-scope value must be an object, got ${typeof value}`);
23
+ const binding = this.getAttributeBinding();
24
+
25
+ const scope = await this.tree.evaluate(this.tag.scope, this.tag.dom, this.tag);
26
+ if (!(scope instanceof Scope)) {
27
+ throw new Error(`vsn-scope value must be an object, got ${typeof scope}`);
26
28
  }
27
- for (const key of value.data.keys) {
28
- this.tag.scope.set(key, value.data[key]);
29
+
30
+ if (binding) {
31
+ this.tag.scope.set(binding, scope);
32
+ } else {
33
+ for (const key of scope.data.keys) {
34
+ this.tag.scope.set(key, scope.data[key]);
35
+ }
29
36
  }
30
37
  }
31
- const binding = this.getAttributeBinding();
32
- if (binding)
33
- this.tag.scope.parentScope.set(binding, this.tag.scope);
34
38
  await super.extract();
35
39
  }
36
40
  }
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const VERSION = '0.1.97';
1
+ export const VERSION = '0.1.100';
2
2
 
@@ -1,7 +1,7 @@
1
1
  import {DOM} from "../../src/DOM";
2
2
  import {ClassNode} from "../../src/AST/ClassNode";
3
3
  import {Registry} from "../../src/Registry";
4
- import {TagList} from "../../src/Tag/List";
4
+ import {TagList} from "../../src/Tag/TagList";
5
5
 
6
6
 
7
7
  describe('ClassNode', () => {
@@ -1,6 +1,6 @@
1
1
  import {DOM} from "../../src/DOM";
2
2
  import {Query} from "../../src/Query";
3
- import {TagList} from "../../src/Tag/List";
3
+ import {TagList} from "../../src/Tag/TagList";
4
4
  import {DOMObject} from "../../src/DOM/DOMObject";
5
5
 
6
6
  describe('TagList', () => {
@@ -72,7 +72,7 @@ describe('ListItem', () => {
72
72
  list.on('add', () => {
73
73
  const listItem = listAttr.tags[0];
74
74
 
75
- expect(listItem.scope.data instanceof ListItemSpecTestItem).toBeTrue();
75
+ expect(listItem.scope.get('item').data instanceof ListItemSpecTestItem).toBeTrue();
76
76
  expect(controller.items.length).toBe(1);
77
77
  expect(controller.items[0] instanceof ListItemSpecTestItem).toBeTrue();
78
78
 
@@ -95,7 +95,7 @@ describe('ListItem', () => {
95
95
  const dom = new DOM(document);
96
96
  dom.once('built', async () => {
97
97
  const listItem = await dom.getTagForElement(document.getElementById('test-item'));
98
- expect(listItem.scope.get('testing')).toBe(1);
98
+ expect(listItem.scope.get('item').get('testing')).toBe(1);
99
99
  done();
100
100
  });
101
101
  });
@@ -1 +0,0 @@
1
- {"version":3,"file":"List.js","sourceRoot":"","sources":["../../src/Tag/List.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,wDAAqD;AAIrD;IAA6B,2BAAgB;IACzC;QAAY,eAAqB;aAArB,UAAqB,EAArB,qBAAqB,EAArB,IAAqB;YAArB,0BAAqB;;QAAjC,+BACa,KAAK,UAEjB;QADG,MAAM,CAAC,cAAc,CAAC,KAAI,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;;IACnD,CAAC;IAED,sBAAI,0BAAK;aAAT;YACI,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;QACxB,CAAC;;;OAAA;IAED,sBAAI,6BAAQ;aAAZ;YACI,OAAO,IAAI,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,OAAO,EAAT,CAAS,CAAC,CAAC;QACpC,CAAC;;;OAAA;IAED,sBAAI,0BAAK;aAAT;YACI,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;QACnB,CAAC;;;OAAA;IAED,sBAAI,yBAAI;aAAR;YACI,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjC,CAAC;;;OAAA;IAED,qBAAG,GAAH,UAAI,KAAa;QACb,IAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAhB,CAAgB,CAAC,CAAC;QACjD,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;IAED,6BAAW,GAAX,UAAY,SAAS;QACjB,IAAI,CAAC,OAAO,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,EAArC,CAAqC,CAAC,CAAA;QACxD,OAAO,IAAI,CAAA;IACf,CAAC;IAED,0BAAQ,GAAR,UAAS,SAAS;QACd,IAAI,CAAC,OAAO,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,EAAlC,CAAkC,CAAC,CAAA;QACrD,OAAO,IAAI,CAAA;IACf,CAAC;IAED,qBAAG,GAAH,UAAI,QAAQ,EAAE,KAAK;QACf,IAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,UAAA,CAAC;YAC5C,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;QAC3C,CAAC,CAAC,CAAA;QACF,IAAI,CAAC,OAAO,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,EAApC,CAAoC,CAAC,CAAA;QACvD,OAAO,IAAI,CAAA;IACf,CAAC;IACL,cAAC;AAAD,CAAC,AA5CD,CAA6B,KAAK,GA4CjC;AA5CY,0BAAO;AA8CpB,IAAI,2BAAY,CAAC,aAAa,IAAI,2BAAY,CAAC,MAAM;IACjD,MAAM,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC"}