vsn 0.1.62 → 0.1.65

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 (56) hide show
  1. package/demo/demo.html +4 -0
  2. package/demo/vsn.js +2 -2
  3. package/demo/xhr.html +22 -4
  4. package/dist/AST/ClassNode.d.ts +4 -1
  5. package/dist/AST/ClassNode.js +72 -27
  6. package/dist/AST/ClassNode.js.map +1 -1
  7. package/dist/AST/ElementAttributeNode.d.ts +1 -1
  8. package/dist/AST/ElementAttributeNode.js +3 -2
  9. package/dist/AST/ElementAttributeNode.js.map +1 -1
  10. package/dist/AST/ElementQueryNode.d.ts +4 -4
  11. package/dist/AST/ElementQueryNode.js +17 -6
  12. package/dist/AST/ElementQueryNode.js.map +1 -1
  13. package/dist/AST/ElementStyleNode.d.ts +1 -1
  14. package/dist/AST/ElementStyleNode.js +3 -2
  15. package/dist/AST/ElementStyleNode.js.map +1 -1
  16. package/dist/AST/FunctionNode.d.ts +1 -1
  17. package/dist/AST/FunctionNode.js +4 -3
  18. package/dist/AST/FunctionNode.js.map +1 -1
  19. package/dist/AST/Node.d.ts +1 -1
  20. package/dist/AST/Node.js +3 -2
  21. package/dist/AST/Node.js.map +1 -1
  22. package/dist/AST/OnNode.d.ts +1 -1
  23. package/dist/AST/OnNode.js +5 -4
  24. package/dist/AST/OnNode.js.map +1 -1
  25. package/dist/AST.d.ts +1 -1
  26. package/dist/AST.js +1 -1
  27. package/dist/AST.js.map +1 -1
  28. package/dist/DOM.d.ts +7 -1
  29. package/dist/DOM.js +94 -112
  30. package/dist/DOM.js.map +1 -1
  31. package/dist/Registry.d.ts +3 -0
  32. package/dist/Registry.js +13 -0
  33. package/dist/Registry.js.map +1 -1
  34. package/dist/attributes/RootAttribute.d.ts +1 -0
  35. package/dist/attributes/RootAttribute.js +18 -6
  36. package/dist/attributes/RootAttribute.js.map +1 -1
  37. package/dist/helpers/ElementHelper.js +6 -0
  38. package/dist/helpers/ElementHelper.js.map +1 -1
  39. package/dist/vsn.js +4 -0
  40. package/dist/vsn.js.map +1 -1
  41. package/package.json +1 -1
  42. package/src/AST/ClassNode.ts +42 -12
  43. package/src/AST/ElementAttributeNode.ts +2 -2
  44. package/src/AST/ElementQueryNode.ts +13 -5
  45. package/src/AST/ElementStyleNode.ts +2 -2
  46. package/src/AST/FunctionNode.ts +4 -3
  47. package/src/AST/Node.ts +2 -2
  48. package/src/AST/OnNode.ts +4 -4
  49. package/src/AST.ts +2 -3
  50. package/src/DOM.ts +25 -28
  51. package/src/Registry.ts +10 -0
  52. package/src/attributes/RootAttribute.ts +11 -3
  53. package/src/helpers/ElementHelper.ts +6 -0
  54. package/src/vsn.ts +4 -0
  55. package/test/DOM.spec.ts +27 -0
  56. package/dist/vsn.min.js +0 -2
@@ -1 +1 @@
1
- {"version":3,"file":"RootAttribute.js","sourceRoot":"","sources":["../../src/attributes/RootAttribute.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,0CAAuC;AACvC,wDAAqD;AACrD,wCAAqC;AACrC,kCAA+B;AAG/B;IAAmC,iCAAS;IAA5C;;IAUA,CAAC;IANgB,6BAAK,GAAlB;;;;;wBACI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,2BAAY,CAAC,QAAQ,EAAE,CAAC,CAAC;wBACvD,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;4BACzC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,aAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;wBAC7D,qBAAM,iBAAM,KAAK,WAAE,EAAA;;wBAAnB,SAAmB,CAAC;;;;;KACvB;IARsB,sBAAQ,GAAY,KAAK,CAAC;IAC1B,oBAAM,GAAY,IAAI,CAAC;IAFrC,aAAa;QADzB,mBAAQ,CAAC,SAAS,CAAC,UAAU,CAAC;OAClB,aAAa,CAUzB;IAAD,oBAAC;CAAA,AAVD,CAAmC,qBAAS,GAU3C;AAVY,sCAAa"}
1
+ {"version":3,"file":"RootAttribute.js","sourceRoot":"","sources":["../../src/attributes/RootAttribute.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,0CAAuC;AACvC,wDAAqD;AACrD,wCAAqC;AAGrC;IAAmC,iCAAS;IAA5C;;IAmBA,CAAC;IAfgB,6BAAK,GAAlB;;;;;;wBACI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,2BAAY,CAAC,QAAQ,EAAE,CAAC,CAAC;wBAEvD,WAAkD,EAAhC,KAAA,mBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;4BAAzC,GAAG;4BACJ,EAAE,GAAG,mBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;4BAChD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;yBAC/B;wBAED,mBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;wBACxE,qBAAM,iBAAM,KAAK,WAAE,EAAA;;wBAAnB,SAAmB,CAAC;;;;;KACvB;IAEY,wCAAgB,GAA7B,UAA8B,IAAY,EAAE,EAAY;;;gBACpD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;;;;KAChC;IAjBsB,sBAAQ,GAAY,KAAK,CAAC;IAC1B,oBAAM,GAAY,IAAI,CAAC;IAFrC,aAAa;QADzB,mBAAQ,CAAC,SAAS,CAAC,UAAU,CAAC;OAClB,aAAa,CAmBzB;IAAD,oBAAC;CAAA,AAnBD,CAAmC,qBAAS,GAmB3C;AAnBY,sCAAa"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ElementHelper = void 0;
4
+ var ClassNode_1 = require("../AST/ClassNode");
4
5
  var ElementHelper = /** @class */ (function () {
5
6
  function ElementHelper() {
6
7
  }
@@ -14,6 +15,11 @@ var ElementHelper = /** @class */ (function () {
14
15
  return true;
15
16
  }
16
17
  }
18
+ for (var _i = 0, _a = Array.from(element.classList); _i < _a.length; _i++) {
19
+ var cls = _a[_i];
20
+ if (ClassNode_1.ClassNode.isClass(cls))
21
+ return true;
22
+ }
17
23
  return false;
18
24
  };
19
25
  ElementHelper.normalizeElementID = function (id) {
@@ -1 +1 @@
1
- {"version":3,"file":"ElementHelper.js","sourceRoot":"","sources":["../../src/helpers/ElementHelper.ts"],"names":[],"mappings":";;;AACA;IAAA;IAiBA,CAAC;IAhBiB,gCAAkB,GAAhC,UAAiC,OAA8B,EAAE,QAAyB;QAAzB,yBAAA,EAAA,iBAAyB;QACtF,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACxE,KAAK,IAAI,CAAC,GAAW,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACxD,IAAM,IAAI,GAAS,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACzC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAClC;gBACI,OAAO,IAAI,CAAC;aACf;SACJ;QAED,OAAO,KAAK,CAAC;IACjB,CAAC;IAEa,gCAAkB,GAAhC,UAAiC,EAAU;QACvC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,iBAAiB,EAAE,UAAU,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClG,CAAC;IACL,oBAAC;AAAD,CAAC,AAjBD,IAiBC;AAjBY,sCAAa"}
1
+ {"version":3,"file":"ElementHelper.js","sourceRoot":"","sources":["../../src/helpers/ElementHelper.ts"],"names":[],"mappings":";;;AAAA,8CAA2C;AAE3C;IAAA;IAsBA,CAAC;IArBiB,gCAAkB,GAAhC,UAAiC,OAA8B,EAAE,QAAyB;QAAzB,yBAAA,EAAA,iBAAyB;QACtF,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACxE,KAAK,IAAI,CAAC,GAAW,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACxD,IAAM,IAAI,GAAS,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACzC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAClC;gBACI,OAAO,IAAI,CAAC;aACf;SACJ;QAED,KAAkB,UAA6B,EAA7B,KAAA,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAA7B,cAA6B,EAA7B,IAA6B,EAAE;YAA5C,IAAM,GAAG,SAAA;YACV,IAAI,qBAAS,CAAC,OAAO,CAAC,GAAG,CAAC;gBACtB,OAAO,IAAI,CAAC;SACnB;QAED,OAAO,KAAK,CAAC;IACjB,CAAC;IAEa,gCAAkB,GAAhC,UAAiC,EAAU;QACvC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,iBAAiB,EAAE,UAAU,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClG,CAAC;IACL,oBAAC;AAAD,CAAC,AAtBD,IAsBC;AAtBY,sCAAa"}
package/dist/vsn.js CHANGED
@@ -83,6 +83,10 @@ var Vision = /** @class */ (function (_super) {
83
83
  else {
84
84
  console.warn('No dom, running in CLI mode.');
85
85
  }
86
+ _this.registry.functions.register('log', console.log);
87
+ _this.registry.functions.register('warn', console.warn);
88
+ _this.registry.functions.register('error', console.error);
89
+ _this.registry.functions.register('info', console.info);
86
90
  _this.registry.controllers.register('Object', Object);
87
91
  _this.registry.controllers.register('WrappedArray', WrappedArray_1.WrappedArray);
88
92
  _this.registry.controllers.register('Data', DynamicScopeData_1.DynamicScopeData);
package/dist/vsn.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vsn.js","sourceRoot":"","sources":["../src/vsn.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vsn.js","sourceRoot":"","sources":["../src/vsn.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vsn",
3
- "version": "0.1.62",
3
+ "version": "0.1.65",
4
4
  "description": "SEO Friendly Javascript/Typescript Framework",
5
5
  "keywords": [
6
6
  "framework",
@@ -19,19 +19,19 @@ export class ClassNode extends Node implements TreeNode {
19
19
  super();
20
20
  }
21
21
 
22
- public async prepare(scope: Scope, dom: DOM, tag: Tag = null): Promise<void> {
22
+ public updateMeta(meta?: any) {
23
+ meta = meta || {};
24
+ meta['ClassNode'] = this;
25
+ return meta;
26
+ }
27
+
28
+ public async prepare(scope: Scope, dom: DOM, tag: Tag = null, meta?: any): Promise<void> {
29
+ meta = meta || {};
30
+ meta['ClassNodePrepare'] = true;
23
31
  if (ClassNode.classes[this.name]) return; // Don't re-prepare same classes
24
32
  ClassNode.classes[this.name] = this;
25
- await this.block.prepare(this.classScope, dom, tag);
33
+ await this.block.prepare(this.classScope, dom, tag, meta);
26
34
  Registry.class(this);
27
- const hasConstructor = this.classScope.has('construct');
28
-
29
- for (const element of Array.from(dom.querySelectorAll(`.${this.name}`))) {
30
- const tag: Tag = await dom.getTagForElement(element as HTMLElement, true);
31
- if (tag) {
32
- await this.prepareTag(tag, dom, hasConstructor);
33
- }
34
- }
35
35
  }
36
36
 
37
37
  public async prepareTag(tag: Tag, dom: DOM, hasConstructor: boolean | null = null) {
@@ -39,7 +39,8 @@ export class ClassNode extends Node implements TreeNode {
39
39
  hasConstructor = this.classScope.has('construct');
40
40
 
41
41
  tag.createScope(true);
42
- await this.block.prepare(tag.scope, dom, tag);
42
+ const meta = this.updateMeta();
43
+ await this.block.prepare(tag.scope, dom, tag, meta);
43
44
  if (hasConstructor) {
44
45
  const fnc = this.classScope.get('construct');
45
46
  (await fnc.evaluate(tag.scope, dom, tag))();
@@ -83,9 +84,38 @@ export class ClassNode extends Node implements TreeNode {
83
84
  if (t.type === TokenType.L_BRACE) break;
84
85
  nameParts.push(t.value);
85
86
  }
86
- const name = nameParts.join('');
87
+ const name = nameParts.join('').trim();
87
88
  tokens.splice(0, nameParts.length);
88
89
  const block = Tree.processTokens(Tree.getNextStatementTokens(tokens, true, true));
89
90
  return new ClassNode(name, block);
90
91
  }
92
+
93
+ public static async checkForClassChanges(element: HTMLElement, dom: DOM, tag: Tag = null) {
94
+ const classes: string[] = Array.from(element.classList);
95
+ let addedClasses: string[] = classes.filter(c => Registry.instance.classes.has(c));
96
+ let removedClasses: string[] = [];
97
+ if (!tag) {
98
+ tag = await dom.getTagForElement(element, true);
99
+ }
100
+ addedClasses = addedClasses.filter(c => !tag.preppedClasses.includes(c));
101
+ removedClasses = tag.preppedClasses.filter(c => !classes.includes(c));
102
+
103
+ for (const addedClass of addedClasses) {
104
+ const classNode: ClassNode = Registry.instance.classes.getSynchronous(addedClass);
105
+ if (classNode) {
106
+ await classNode.prepareTag(tag, dom);
107
+ }
108
+ }
109
+
110
+ for (const removedClass of removedClasses) {
111
+ const classNode: ClassNode = Registry.instance.classes.getSynchronous(removedClass);
112
+ if (classNode) {
113
+ await classNode.tearDownTag(tag, dom);
114
+ }
115
+ }
116
+ }
117
+
118
+ public static isClass(cls: string): boolean {
119
+ return this.classes[cls] instanceof ClassNode;
120
+ }
91
121
  }
@@ -50,9 +50,9 @@ export class ElementAttributeNode extends Node implements TreeNode {
50
50
  return tags.map((tag) => tag.scope.get(`@${this.attributeName}`));
51
51
  }
52
52
 
53
- async prepare(scope: Scope, dom: DOM, tag: Tag = null) {
53
+ async prepare(scope: Scope, dom: DOM, tag: Tag = null, meta: any = null) {
54
54
  if (this.elementRef) {
55
- await this.elementRef.prepare(scope, dom, tag);
55
+ await this.elementRef.prepare(scope, dom, tag, meta);
56
56
  const tags: TagList = await this.elementRef.evaluate(scope, dom, tag, true);
57
57
  for (const t of tags)
58
58
  await t.watchAttribute(this.attributeName);
@@ -1,5 +1,5 @@
1
1
  import {Scope} from "../Scope";
2
- import {DOM} from "../DOM";
2
+ import {DOM, EQuerySelectDirection} from "../DOM";
3
3
  import {Tag} from "../Tag";
4
4
  import {Token, TreeNode} from "../AST";
5
5
  import {Node} from "./Node";
@@ -10,24 +10,32 @@ export class ElementQueryNode extends Node implements TreeNode {
10
10
  constructor(
11
11
  public readonly query: string,
12
12
  public readonly first: boolean = false,
13
- public readonly global: boolean = false,
13
+ public readonly direction: EQuerySelectDirection = EQuerySelectDirection.ALL,
14
14
  ) {
15
15
  super();
16
16
  }
17
17
 
18
18
  async evaluate(scope: Scope, dom: DOM, tag: Tag = null, forceList: boolean = false): Promise<any> {
19
19
  tag = tag || await dom.getTagForScope(scope);
20
- const elements = await dom.get(this.query, true, this.global ? null : tag);
20
+ const elements = await dom.get(this.query, true, tag, this.direction);
21
21
  return this.first && !forceList ? elements[0] : elements;
22
22
  }
23
23
 
24
- async prepare(scope: Scope, dom: DOM, tag: Tag = null) {
24
+ async prepare(scope: Scope, dom: DOM, tag: Tag = null, meta: any = null): Promise<any> {
25
25
  tag = tag || await dom.getTagForScope(scope);
26
26
  await dom.get(this.query, true, tag);
27
27
  }
28
28
 
29
29
  public static parse(lastNode, token, tokens: Token[]): ElementQueryNode {
30
30
  tokens.shift();
31
- return new ElementQueryNode(token.value, false, !token.full.startsWith('?>'));
31
+ let first = false;
32
+ let direction = EQuerySelectDirection.ALL;
33
+ if (token.full.startsWith('?>')) {
34
+ direction = EQuerySelectDirection.DOWN;
35
+ } else if (token.full.startsWith('?<')) {
36
+ direction = EQuerySelectDirection.UP;
37
+ first = true;
38
+ }
39
+ return new ElementQueryNode(token.value, first, direction);
32
40
  }
33
41
  }
@@ -50,9 +50,9 @@ export class ElementStyleNode extends Node implements TreeNode {
50
50
  return tags.map((tag) => tag.scope.get(`$${this.attributeName}`));
51
51
  }
52
52
 
53
- async prepare(scope: Scope, dom: DOM, tag: Tag = null) {
53
+ async prepare(scope: Scope, dom: DOM, tag: Tag = null, meta: any = null) {
54
54
  if (this.elementRef) {
55
- await this.elementRef.prepare(scope, dom, tag);
55
+ await this.elementRef.prepare(scope, dom, tag, meta);
56
56
  const tags: TagList = await this.elementRef.evaluate(scope, dom, tag, true);
57
57
  for (const t of tags)
58
58
  await t.watchStyle(this.attributeName);
@@ -22,9 +22,10 @@ export class FunctionNode extends Node implements TreeNode {
22
22
  ];
23
23
  }
24
24
 
25
- public async prepare(scope: Scope, dom: DOM, tag: Tag = null): Promise<void> {
26
- scope.set(this.name, this);
27
- await super.prepare(scope, dom, tag);
25
+ public async prepare(scope: Scope, dom: DOM, tag: Tag = null, meta?: any): Promise<void> {
26
+ if (!meta?.ClassNode) // Don't muddle up tag scope if we're in a class
27
+ scope.set(this.name, this);
28
+ await super.prepare(scope, dom, tag, meta);
28
29
  }
29
30
 
30
31
  public async evaluate(scope: Scope, dom: DOM, tag: Tag = null) {
package/src/AST/Node.ts CHANGED
@@ -27,9 +27,9 @@ export abstract class Node implements TreeNode {
27
27
  return false;
28
28
  }
29
29
 
30
- async prepare(scope: Scope, dom: DOM, tag: Tag = null) {
30
+ async prepare(scope: Scope, dom: DOM, tag: Tag = null, meta: any = null): Promise<void> {
31
31
  for (const node of this.getChildNodes()) {
32
- await node.prepare(scope, dom, tag);
32
+ await node.prepare(scope, dom, tag, meta);
33
33
  }
34
34
  }
35
35
 
package/src/AST/OnNode.ts CHANGED
@@ -5,11 +5,11 @@ import {DOM} from "../DOM";
5
5
  import {Tag} from "../Tag";
6
6
 
7
7
  export class OnNode extends FunctionNode implements TreeNode {
8
- public async prepare(scope: Scope, dom: DOM, tag: Tag = null): Promise<void> {
9
- if (tag) {
8
+ public async prepare(scope: Scope, dom: DOM, tag: Tag = null, meta): Promise<void> {
9
+ const classPrep = meta?.ClassNodePrepare; // Don't add event handler if we're in class prep
10
+ if (tag && !classPrep)
10
11
  tag.addEventHandler(this.name, [], await this.getFunction(scope, dom, tag), this);
11
- }
12
- await super.prepare(scope, dom, tag);
12
+ await super.prepare(scope, dom, tag, meta);
13
13
  }
14
14
 
15
15
  public static parse(lastNode, token, tokens: Token[]): OnNode {
package/src/AST.ts CHANGED
@@ -226,7 +226,7 @@ const TOKEN_PATTERNS: TokenPattern[] = [
226
226
  },
227
227
  {
228
228
  type: TokenType.ELEMENT_QUERY,
229
- pattern: /^\?>?\(([#.\[\]:,=\-_a-zA-Z0-9*\s]*[\]_a-zA-Z0-9*])\)/
229
+ pattern: /^\?[>|<]?\(([#.\[\]:,=\-_a-zA-Z0-9*\s]*[\]_a-zA-Z0-9*])\)/
230
230
  },
231
231
  {
232
232
  type: TokenType.NAME,
@@ -368,8 +368,7 @@ const TOKEN_PATTERNS: TokenPattern[] = [
368
368
 
369
369
  export interface TreeNode<T = any> {
370
370
  evaluate(scope: Scope, dom: DOM, tag?: Tag);
371
-
372
- prepare(scope: Scope, dom: DOM, tag?: Tag);
371
+ prepare(scope: Scope, dom: DOM, tag?: Tag, meta?: any);
373
372
  }
374
373
 
375
374
  export interface IBlockInfo {
package/src/DOM.ts CHANGED
@@ -7,9 +7,14 @@ import {WrappedWindow} from "./DOM/WrappedWindow";
7
7
  import {WrappedDocument} from "./DOM/WrappedDocument";
8
8
  import {Scope} from "./Scope";
9
9
  import {EventDispatcher} from "./EventDispatcher";
10
- import {Registry} from "./Registry";
11
10
  import {ClassNode} from "./AST/ClassNode";
12
11
 
12
+ export enum EQuerySelectDirection {
13
+ ALL,
14
+ UP,
15
+ DOWN
16
+ }
17
+
13
18
  export class DOM extends EventDispatcher {
14
19
  protected static _instance: DOM;
15
20
  protected _root: Tag;
@@ -44,7 +49,7 @@ export class DOM extends EventDispatcher {
44
49
  return this._root;
45
50
  }
46
51
 
47
- public async get(selector: string, create: boolean = false, tag: Tag = null) {
52
+ public async get(selector: string, create: boolean = false, tag: Tag = null, direction: EQuerySelectDirection = EQuerySelectDirection.DOWN): Promise<TagList> {
48
53
  switch (selector) {
49
54
  case 'window':
50
55
  return new TagList(this.window);
@@ -53,7 +58,14 @@ export class DOM extends EventDispatcher {
53
58
  case 'body':
54
59
  return new TagList(this.root);
55
60
  default:
56
- const nodes = this.querySelectorAll(selector, tag);
61
+ let nodes;
62
+ if (direction === EQuerySelectDirection.DOWN) {
63
+ nodes = this.querySelectorAll(selector, tag);
64
+ } else if (direction === EQuerySelectDirection.UP) {
65
+ nodes = [this.querySelectorClosest(selector, tag)];
66
+ } else {
67
+ nodes = this.querySelectorAll(selector);
68
+ }
57
69
  return await this.getTagsForElements(Array.from(nodes) as Element[], create);
58
70
  }
59
71
  }
@@ -69,6 +81,10 @@ export class DOM extends EventDispatcher {
69
81
  this.root.scope.set(`#${id}`, tag.scope);
70
82
  }
71
83
 
84
+ public querySelectorClosest(q: string, tag: Tag = null): HTMLElement {
85
+ return tag.element.closest(q);
86
+ }
87
+
72
88
  public querySelectorAll(q: string, tag: Tag = null): NodeList | HTMLElement[] {
73
89
  const element: HTMLElement | Document = tag && !q.startsWith('#') ? tag.element : this.rootElement;
74
90
  return this.querySelectorElement(element, q);
@@ -124,29 +140,7 @@ export class DOM extends EventDispatcher {
124
140
 
125
141
  // Check for class changes
126
142
  if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
127
- const classes: string[] = Array.from((mutation.target as HTMLElement).classList);
128
- let addedClasses: string[] = classes.filter(c => Registry.instance.classes.has(c));
129
- let removedClasses: string[] = [];
130
- if (tag) {
131
- addedClasses = addedClasses.filter(c => !tag.preppedClasses.includes(c));
132
- removedClasses = tag.preppedClasses.filter(c => !classes.includes(c));
133
- } else {
134
- tag = await this.getTagForElement(mutation.target as HTMLElement, true);
135
- }
136
-
137
- for (const addedClass of addedClasses) {
138
- const classNode: ClassNode = Registry.instance.classes.getSynchronous(addedClass);
139
- if (classNode) {
140
- await classNode.prepareTag(tag, this);
141
- }
142
- }
143
-
144
- for (const removedClass of removedClasses) {
145
- const classNode: ClassNode = Registry.instance.classes.getSynchronous(removedClass);
146
- if (classNode) {
147
- await classNode.tearDownTag(tag, this);
148
- }
149
- }
143
+ await ClassNode.checkForClassChanges(mutation.target as HTMLElement, this, tag);
150
144
  }
151
145
 
152
146
  for (const ele of Array.from(mutation.removedNodes)) {
@@ -220,12 +214,15 @@ export class DOM extends EventDispatcher {
220
214
  this.queued.splice(this.queued.indexOf(tag.element), 1);
221
215
  }
222
216
 
223
- newTags.forEach(tag => this.observer.observe(tag.element, {
217
+ for (const tag of newTags) {
218
+ this.observer.observe(tag.element, {
224
219
  attributes: true,
225
220
  characterData: true,
226
221
  childList: true,
227
222
  subtree: true
228
- }));
223
+ });
224
+ await ClassNode.checkForClassChanges(tag.element, this, tag);
225
+ }
229
226
 
230
227
  this.dispatch('built');
231
228
  }
package/src/Registry.ts CHANGED
@@ -54,10 +54,15 @@ export class RegistryStore extends EventDispatcher {
54
54
  has(key: string) {
55
55
  return !!this.store[key];
56
56
  }
57
+
58
+ get keys(): string[] {
59
+ return Object.keys(this.store);
60
+ }
57
61
  }
58
62
 
59
63
  export class Registry extends EventDispatcher {
60
64
  protected static _instance: Registry;
65
+ public readonly functions: RegistryStore;
61
66
  public readonly controllers: RegistryStore;
62
67
  public readonly classes: RegistryStore;
63
68
  public readonly models: RegistryStore;
@@ -69,6 +74,7 @@ export class Registry extends EventDispatcher {
69
74
 
70
75
  constructor() {
71
76
  super();
77
+ this.functions = new RegistryStore();
72
78
  this.controllers = new RegistryStore();
73
79
  this.classes = new RegistryStore();
74
80
  this.models = new RegistryStore();
@@ -79,6 +85,10 @@ export class Registry extends EventDispatcher {
79
85
  this.attributes = new RegistryStore();
80
86
  }
81
87
 
88
+ public static function(key: string = null, setup = null) {
89
+ return register('functions', key, setup);
90
+ }
91
+
82
92
  public static class(cls: ClassNode) {
83
93
  Registry.instance.classes.register(cls.name, cls);
84
94
  }
@@ -1,7 +1,6 @@
1
1
  import {Attribute} from "../Attribute";
2
2
  import {VisionHelper} from "../helpers/VisionHelper";
3
3
  import {Registry} from "../Registry";
4
- import {Scope} from "../Scope";
5
4
 
6
5
  @Registry.attribute('vsn-root')
7
6
  export class RootAttribute extends Attribute {
@@ -10,8 +9,17 @@ export class RootAttribute extends Attribute {
10
9
 
11
10
  public async setup() {
12
11
  this.tag.scope.set('$mobile', VisionHelper.isMobile());
13
- if (console && !this.tag.scope.get('console'))
14
- this.tag.scope.set('console', Scope.fromObject(console));
12
+
13
+ for (const key of Registry.instance.functions.keys) {
14
+ const fn = Registry.instance.functions.get(key);
15
+ this.tag.scope.set(key, fn);
16
+ }
17
+
18
+ Registry.instance.functions.on('register', this.registerFunction, this);
15
19
  await super.setup();
16
20
  }
21
+
22
+ public async registerFunction(name: string, fn: Function) {
23
+ this.tag.scope.set(name, fn);
24
+ }
17
25
  }
@@ -1,3 +1,4 @@
1
+ import {ClassNode} from "../AST/ClassNode";
1
2
 
2
3
  export class ElementHelper {
3
4
  public static hasVisionAttribute(element: HTMLElement | Element, testAttr: string = 'vsn-'): boolean {
@@ -10,6 +11,11 @@ export class ElementHelper {
10
11
  }
11
12
  }
12
13
 
14
+ for (const cls of Array.from(element.classList)) {
15
+ if (ClassNode.isClass(cls))
16
+ return true;
17
+ }
18
+
13
19
  return false;
14
20
  }
15
21
 
package/src/vsn.ts CHANGED
@@ -25,6 +25,10 @@ export class Vision extends EventDispatcher {
25
25
  } else {
26
26
  console.warn('No dom, running in CLI mode.');
27
27
  }
28
+ this.registry.functions.register('log', console.log);
29
+ this.registry.functions.register('warn', console.warn);
30
+ this.registry.functions.register('error', console.error);
31
+ this.registry.functions.register('info', console.info);
28
32
  this.registry.controllers.register('Object', Object);
29
33
  this.registry.controllers.register('WrappedArray', WrappedArray);
30
34
  this.registry.controllers.register('Data', DynamicScopeData);
package/test/DOM.spec.ts CHANGED
@@ -33,4 +33,31 @@ describe('DOM', () => {
33
33
  done();
34
34
  });
35
35
  });
36
+
37
+ it("should be able to query elements in all directions", (done) => {
38
+ document.body.innerHTML = `
39
+ <div id="root" vsn-set:asd|integer="1">
40
+ <main id="parent" vsn-set:asd|integer="123">
41
+ <div id="testing" vsn-controller:test="TestController" vsn-set:asd="234|integer">
42
+ <div id="child" vsn-set:asd|integer="345">
43
+ <ul>
44
+ <li vsn-set:asd|integer="456"></li>
45
+ <li id="grandchild" vsn-set:asd|integer="567"></li>
46
+ </ul>
47
+ </div>
48
+ </div>
49
+ </main>
50
+ </div>
51
+ `;
52
+ const dom = new DOM(document);
53
+ dom.once('built', async () => {
54
+ const root = await dom.exec('#root');
55
+ const child = await dom.exec('#child');
56
+ const grandchild = await dom.exec('#grandchild');
57
+ expect(await child.exec('?<(main).asd')).toBe(123);
58
+ expect(await child.exec('?>(li)[0].asd')).toBe(456);
59
+ expect(await dom.exec('?(#grandchild)[0]')).toBe(grandchild);
60
+ done();
61
+ });
62
+ });
36
63
  });