vsn 0.1.18 → 0.1.21

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 (124) hide show
  1. package/demo/demo.html +9 -2
  2. package/demo/vision.js +1 -1
  3. package/dist/AST.d.ts +2 -1
  4. package/dist/AST.js +2107 -0
  5. package/dist/AST.js.map +1 -0
  6. package/dist/Attribute.js +187 -0
  7. package/dist/Attribute.js.map +1 -0
  8. package/dist/Bencmark.js +179 -0
  9. package/dist/Bencmark.js.map +1 -0
  10. package/dist/Configuration.js +64 -0
  11. package/dist/Configuration.js.map +1 -0
  12. package/dist/Controller.js +39 -0
  13. package/dist/Controller.js.map +1 -0
  14. package/dist/DOM/DOMObject.d.ts +1 -0
  15. package/dist/DOM/DOMObject.js +47 -0
  16. package/dist/DOM/DOMObject.js.map +1 -0
  17. package/dist/DOM/WrappedDocument.js +34 -0
  18. package/dist/DOM/WrappedDocument.js.map +1 -0
  19. package/dist/DOM/WrappedWindow.js +45 -0
  20. package/dist/DOM/WrappedWindow.js.map +1 -0
  21. package/dist/DOM.js +547 -0
  22. package/dist/DOM.js.map +1 -0
  23. package/dist/Formats.js +44 -0
  24. package/dist/Formats.js.map +1 -0
  25. package/dist/Query.js +66 -0
  26. package/dist/Query.js.map +1 -0
  27. package/dist/Registry.js +138 -0
  28. package/dist/Registry.js.map +1 -0
  29. package/dist/Scope.d.ts +2 -1
  30. package/dist/Scope.js +512 -0
  31. package/dist/Scope.js.map +1 -0
  32. package/dist/Tag/List.js +85 -0
  33. package/dist/Tag/List.js.map +1 -0
  34. package/dist/Tag.d.ts +3 -0
  35. package/dist/Tag.js +764 -0
  36. package/dist/Tag.js.map +1 -0
  37. package/dist/Types.js +48 -0
  38. package/dist/Types.js.map +1 -0
  39. package/dist/Vision.d.ts +1 -1
  40. package/dist/Vision.js +162 -0
  41. package/dist/Vision.js.map +1 -0
  42. package/dist/attributes/AddClassIf.js +93 -0
  43. package/dist/attributes/AddClassIf.js.map +1 -0
  44. package/dist/attributes/Bind.js +272 -0
  45. package/dist/attributes/Bind.js.map +1 -0
  46. package/dist/attributes/ClassConstructor.js +104 -0
  47. package/dist/attributes/ClassConstructor.js.map +1 -0
  48. package/dist/attributes/ClickRemoveClass.js +102 -0
  49. package/dist/attributes/ClickRemoveClass.js.map +1 -0
  50. package/dist/attributes/ClickToggleClass.js +102 -0
  51. package/dist/attributes/ClickToggleClass.js.map +1 -0
  52. package/dist/attributes/ControllerAttribute.js +28 -0
  53. package/dist/attributes/ControllerAttribute.js.map +1 -0
  54. package/dist/attributes/DisableIf.js +94 -0
  55. package/dist/attributes/DisableIf.js.map +1 -0
  56. package/dist/attributes/Exec.js +102 -0
  57. package/dist/attributes/Exec.js.map +1 -0
  58. package/dist/attributes/Format.js +96 -0
  59. package/dist/attributes/Format.js.map +1 -0
  60. package/dist/attributes/If.js +147 -0
  61. package/dist/attributes/If.js.map +1 -0
  62. package/dist/attributes/JSONAttribute.js +115 -0
  63. package/dist/attributes/JSONAttribute.js.map +1 -0
  64. package/dist/attributes/KeyAbstract.js +110 -0
  65. package/dist/attributes/KeyAbstract.js.map +1 -0
  66. package/dist/attributes/KeyDown.js +82 -0
  67. package/dist/attributes/KeyDown.js.map +1 -0
  68. package/dist/attributes/KeyUp.js +82 -0
  69. package/dist/attributes/KeyUp.js.map +1 -0
  70. package/dist/attributes/List.js +273 -0
  71. package/dist/attributes/List.js.map +1 -0
  72. package/dist/attributes/ListItem.js +135 -0
  73. package/dist/attributes/ListItem.js.map +1 -0
  74. package/dist/attributes/ListItemModel.js +39 -0
  75. package/dist/attributes/ListItemModel.js.map +1 -0
  76. package/dist/attributes/ModelAttribute.js +29 -0
  77. package/dist/attributes/ModelAttribute.js.map +1 -0
  78. package/dist/attributes/Name.js +88 -0
  79. package/dist/attributes/Name.js.map +1 -0
  80. package/dist/attributes/On.js +123 -0
  81. package/dist/attributes/On.js.map +1 -0
  82. package/dist/attributes/Radio.js +127 -0
  83. package/dist/attributes/Radio.js.map +1 -0
  84. package/dist/attributes/Referenced.js +38 -0
  85. package/dist/attributes/Referenced.js.map +1 -0
  86. package/dist/attributes/RootAttribute.js +85 -0
  87. package/dist/attributes/RootAttribute.js.map +1 -0
  88. package/dist/attributes/ScopeAttribute.js +40 -0
  89. package/dist/attributes/ScopeAttribute.js.map +1 -0
  90. package/dist/attributes/ScopeChange.js +124 -0
  91. package/dist/attributes/ScopeChange.js.map +1 -0
  92. package/dist/attributes/SetAttribute.js +130 -0
  93. package/dist/attributes/SetAttribute.js.map +1 -0
  94. package/dist/attributes/StandardAttribute.js +168 -0
  95. package/dist/attributes/StandardAttribute.js.map +1 -0
  96. package/dist/attributes/StyleAttribute.d.ts +12 -0
  97. package/dist/attributes/StyleAttribute.js +182 -0
  98. package/dist/attributes/StyleAttribute.js.map +1 -0
  99. package/dist/attributes/Template.js +39 -0
  100. package/dist/attributes/Template.js.map +1 -0
  101. package/dist/attributes/TypeAttribute.js +101 -0
  102. package/dist/attributes/TypeAttribute.js.map +1 -0
  103. package/dist/attributes/_imports.d.ts +1 -0
  104. package/dist/attributes/_imports.js +60 -0
  105. package/dist/attributes/_imports.js.map +1 -0
  106. package/dist/helpers/DOMHelper.js +81 -0
  107. package/dist/helpers/DOMHelper.js.map +1 -0
  108. package/dist/helpers/ElementHelper.js +25 -0
  109. package/dist/helpers/ElementHelper.js.map +1 -0
  110. package/dist/helpers/VisionHelper.js +71 -0
  111. package/dist/helpers/VisionHelper.js.map +1 -0
  112. package/dist/helpers/decorators.js +38 -0
  113. package/dist/helpers/decorators.js.map +1 -0
  114. package/main.py +16 -0
  115. package/package.json +2 -2
  116. package/src/AST.ts +70 -7
  117. package/src/DOM/DOMObject.ts +4 -0
  118. package/src/Scope.ts +11 -8
  119. package/src/Tag.ts +33 -0
  120. package/src/Vision.ts +1 -1
  121. package/src/attributes/StyleAttribute.ts +83 -0
  122. package/src/attributes/_imports.ts +1 -0
  123. package/test/attributes/Styles.spec.ts +43 -0
  124. package/dist/vision.min.js +0 -1
package/src/Scope.ts CHANGED
@@ -207,13 +207,12 @@ export class WrappedArray<T> extends Array<T> {
207
207
  }
208
208
  }
209
209
 
210
-
211
210
  export class Scope extends EventDispatcher {
212
211
  public wrapped: any;
213
212
  protected data: DataModel;
214
213
  protected types: {[key: string]: string;} = {};
215
214
  protected children: Scope[];
216
- protected keys: string[];
215
+ protected _keys: string[];
217
216
  protected _parentScope: Scope;
218
217
 
219
218
  constructor(
@@ -224,7 +223,7 @@ export class Scope extends EventDispatcher {
224
223
  this.parentScope = parent;
225
224
  this.children = [];
226
225
  this.data = new DataModel({});
227
- this.keys = [];
226
+ this._keys = [];
228
227
  }
229
228
 
230
229
  public get parentScope(): Scope {
@@ -277,7 +276,7 @@ export class Scope extends EventDispatcher {
277
276
  if (searchParents && this.parentScope)
278
277
  return this.parentScope.get(key, searchParents);
279
278
 
280
- return '';
279
+ return this._keys.indexOf(key) > -1 ? '' : undefined;
281
280
  }
282
281
 
283
282
  return value;
@@ -312,12 +311,16 @@ export class Scope extends EventDispatcher {
312
311
  this.trigger('change', key, event);
313
312
  }
314
313
 
315
- if (this.keys.indexOf(key) === -1)
316
- this.keys.push(key);
314
+ if (this._keys.indexOf(key) === -1)
315
+ this._keys.push(key);
316
+ }
317
+
318
+ get keys(): string[] {
319
+ return [...this._keys];
317
320
  }
318
321
 
319
322
  has(key: string): boolean {
320
- return this.keys.indexOf(key) > -1;
323
+ return this._keys.indexOf(key) > -1;
321
324
  }
322
325
 
323
326
  setType(key: string, type: string) {
@@ -337,7 +340,7 @@ export class Scope extends EventDispatcher {
337
340
  }
338
341
 
339
342
  clear() {
340
- for (const key of this.keys) {
343
+ for (const key of this._keys) {
341
344
  if (['function', 'object'].indexOf(typeof this.get(key)) > -1) continue;
342
345
  this.set(key, null);
343
346
  }
package/src/Tag.ts CHANGED
@@ -8,6 +8,8 @@ import {On} from "./attributes/On";
8
8
  import {Registry} from "./Registry";
9
9
  import {benchmarkEnd, benchmarkStart} from "./Bencmark";
10
10
  import {DOMObject} from "./DOM/DOMObject";
11
+ import { Tree } from "./AST";
12
+ import {StyleAttribute} from "./attributes/StyleAttribute";
11
13
 
12
14
  export enum TagState {
13
15
  Instantiated,
@@ -104,6 +106,12 @@ export class Tag extends DOMObject {
104
106
  }
105
107
  }
106
108
 
109
+ public async eval(code: string) {
110
+ const tree = new Tree(code);
111
+ await tree.prepare(this.scope, this.dom, this);
112
+ return await tree.evaluate(this.scope, this.dom, this);
113
+ }
114
+
107
115
  public async evaluate() {
108
116
  for (const attr of this.nonDeferredAttributes) {
109
117
  await attr.evaluate();
@@ -480,6 +488,31 @@ export class Tag extends DOMObject {
480
488
  return standardAttribute;
481
489
  }
482
490
 
491
+ async watchStyle(styleName: string) {
492
+ for (const attribute of this.attributes) {
493
+ if (attribute instanceof StyleAttribute) {
494
+ return attribute;
495
+ }
496
+ }
497
+
498
+ // Standard attribute requires a unique scope
499
+ // @todo: Does this cause any issues with attribute bindings on the parent scope prior to having its own scope? hmm...
500
+ if (!this.uniqueScope) {
501
+ this._uniqueScope = true;
502
+ this._scope = new Scope();
503
+
504
+ if (this.parentTag) {
505
+ this.scope.parentScope = this.parentTag.scope;
506
+ }
507
+ }
508
+
509
+ const styleAttribute = new StyleAttribute(this, 'style');
510
+ this.attributes.push(styleAttribute);
511
+ await this.setupAttribute(styleAttribute);
512
+
513
+ return styleAttribute;
514
+ }
515
+
483
516
  private async setupAttribute(attribute: Attribute) {
484
517
  await attribute.compile();
485
518
  await attribute.setup();
package/src/Vision.ts CHANGED
@@ -72,5 +72,5 @@ export * from './Registry';
72
72
  export * from './Attribute';
73
73
  export * from './AST';
74
74
  export {DOM} from './DOM';
75
- export {WrappedArray, Scope} from './Scope';
75
+ export {WrappedArray, Scope, ScopeReference} from './Scope';
76
76
  export const vision: Vision = Vision.instance;
@@ -0,0 +1,83 @@
1
+ import {Registry} from "../Registry";
2
+ import {Attribute} from "../Attribute";
3
+ import {Scope, ScopeReference} from "../Scope";
4
+
5
+
6
+ @Registry.attribute('vsn-styles')
7
+ export class StyleAttribute extends Attribute {
8
+ private scopeRef: ScopeReference;
9
+ private styleScope: Scope;
10
+
11
+ public async setup() {
12
+ const key = this.getAttributeValue() || null;
13
+ if (key) {
14
+ this.scopeRef = this.tag.scope.getReference(key, true);
15
+ const parentScope = await this.scopeRef.getScope();
16
+ const styleKey = await this.scopeRef.getKey();
17
+ this.styleScope = parentScope.get(styleKey);
18
+ if (!this.styleScope) {
19
+ this.styleScope = new Scope(parentScope);
20
+ parentScope.set(styleKey, this.styleScope);
21
+ }
22
+ } else {
23
+ this.styleScope = this.tag.scope;
24
+ }
25
+
26
+ await super.setup();
27
+ }
28
+
29
+ public async connect() {
30
+ this.styleScope.bind(`change`, this.handleEvent.bind(this));
31
+ await super.connect();
32
+ }
33
+
34
+ public async extract() {
35
+ this.updateFrom();
36
+ this.updateTo();
37
+ await super.extract();
38
+ }
39
+
40
+ updateFrom() {
41
+ const toSkip = [
42
+ 'cssText',
43
+ 'getPropertyPriority',
44
+ 'getPropertyValue',
45
+ 'removeProperty',
46
+ 'setProperty',
47
+ 'length'
48
+ ];
49
+ for (const k in this.tag.style) {
50
+ if (toSkip.indexOf(k) > -1 || isFinite(k as any))
51
+ continue;
52
+ const value = this.tag.style[k];
53
+ const key = `$${k}`;
54
+ if (value && value !== this.styleScope.get(key))
55
+ this.styleScope.set(key, value);
56
+ }
57
+ }
58
+
59
+ public updateTo() {
60
+ for (const k of this.styleScope.keys) {
61
+ const v = this.styleScope.get(k);
62
+ if (k.startsWith('$')) {
63
+ const key = k.substr(1);
64
+ this.tag.element.style[key] = v.value;
65
+ }
66
+ }
67
+ }
68
+
69
+ public mutate(mutation: MutationRecord) {
70
+ super.mutate(mutation);
71
+ this.updateFrom();
72
+ }
73
+
74
+ public async handleEvent(k, v) {
75
+ if (k.startsWith('$')) {
76
+ const key = k.substr(1);
77
+
78
+ if (v.value !== v.previousValue) {
79
+ this.tag.element.style[key] = v.value;
80
+ }
81
+ }
82
+ }
83
+ }
@@ -23,5 +23,6 @@ export {ScopeAttribute} from "./ScopeAttribute";
23
23
  export {ScopeChange} from "./ScopeChange";
24
24
  export {SetAttribute} from "./SetAttribute";
25
25
  export {StandardAttribute} from "./StandardAttribute";
26
+ export {StyleAttribute} from "./StyleAttribute";
26
27
  export {Template} from "./Template";
27
28
  export {TypeAttribute} from "./TypeAttribute";
@@ -0,0 +1,43 @@
1
+ import {DOM} from "../../src/DOM";
2
+ import "../../src/Types";
3
+ import "../../src/attributes/_imports";
4
+
5
+
6
+ describe('Styles', () => {
7
+ it("vsn-styles to just work", (done) => {
8
+ document.body.innerHTML = `
9
+ <div vsn-name="testing">
10
+ <span id="styling" vsn-styles="testing.styles" style="margin-top: 50px;">testing</span>
11
+ <span id="styling-dupe" vsn-styles="testing.styles" style="margin-top: 50px;">testing 2</span>
12
+ </div>
13
+ `;
14
+ const dom = new DOM(document);
15
+ dom.once('built', async () => {
16
+ const ele1 = (await dom.get('#styling'))[0];
17
+ const ele2 = (await dom.get('#styling-dupe'))[0];
18
+ const scope = ele1.scope;
19
+ const container = scope.get('testing');
20
+ const styles = container.get('styles');
21
+ expect(container).toBeTruthy();
22
+ expect(styles).toBeTruthy();
23
+ expect(ele1.element.style.marginTop).toBe('50px');
24
+ expect(ele2.element.style.marginTop).toBe('50px');
25
+ styles.set('$marginTop', '-50px');
26
+ expect(ele1.element.style.marginTop).toBe('-50px');
27
+ expect(ele2.element.style.marginTop).toBe('-50px');
28
+ done();
29
+ });
30
+ });
31
+
32
+ it("$ operator should work", (done) => {
33
+ document.body.innerHTML = `
34
+ <span id="styling">testing</span>
35
+ `;
36
+ const dom = new DOM(document);
37
+ dom.once('built', async () => {
38
+ await dom.eval('?(#styling).$marginTop = "50px"');
39
+ expect((await dom.get('#styling'))[0].element.style.marginTop).toBe('50px');
40
+ done();
41
+ });
42
+ });
43
+ });