vsn 0.1.26 → 0.1.29

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 (303) hide show
  1. package/demo/vsn.js +1 -1
  2. package/dist/AST/ArithmeticAssignmentNode.d.ts +23 -0
  3. package/dist/AST/ArithmeticAssignmentNode.js +313 -0
  4. package/dist/AST/ArithmeticAssignmentNode.js.map +1 -0
  5. package/dist/AST/ArithmeticNode.d.ts +15 -0
  6. package/dist/AST/ArithmeticNode.js +114 -0
  7. package/dist/AST/ArithmeticNode.js.map +1 -0
  8. package/dist/AST/ArrayNode.d.ts +14 -0
  9. package/dist/AST/ArrayNode.js +114 -0
  10. package/dist/AST/ArrayNode.js.map +1 -0
  11. package/dist/AST/BlockNode.d.ts +11 -0
  12. package/dist/AST/BlockNode.js +98 -0
  13. package/dist/AST/BlockNode.js.map +1 -0
  14. package/dist/AST/BooleanLiteralNode.d.ts +5 -0
  15. package/dist/AST/BooleanLiteralNode.js +31 -0
  16. package/dist/AST/BooleanLiteralNode.js.map +1 -0
  17. package/dist/AST/ComparisonNode.d.ts +15 -0
  18. package/dist/AST/ComparisonNode.js +120 -0
  19. package/dist/AST/ComparisonNode.js.map +1 -0
  20. package/dist/AST/ConditionalNode.d.ts +13 -0
  21. package/dist/AST/ConditionalNode.js +95 -0
  22. package/dist/AST/ConditionalNode.js.map +1 -0
  23. package/dist/AST/ElementAttributeNode.d.ts +18 -0
  24. package/dist/AST/ElementAttributeNode.js +159 -0
  25. package/dist/AST/ElementAttributeNode.js.map +1 -0
  26. package/dist/AST/ElementQueryNode.d.ts +12 -0
  27. package/dist/AST/ElementQueryNode.js +111 -0
  28. package/dist/AST/ElementQueryNode.js.map +1 -0
  29. package/dist/AST/ElementStyleNode.d.ts +18 -0
  30. package/dist/AST/ElementStyleNode.js +159 -0
  31. package/dist/AST/ElementStyleNode.js.map +1 -0
  32. package/dist/AST/ForStatementNode.d.ts +17 -0
  33. package/dist/AST/ForStatementNode.js +121 -0
  34. package/dist/AST/ForStatementNode.js.map +1 -0
  35. package/dist/AST/FunctionArgumentNode.d.ts +11 -0
  36. package/dist/AST/FunctionArgumentNode.js +100 -0
  37. package/dist/AST/FunctionArgumentNode.js.map +1 -0
  38. package/dist/AST/FunctionCallNode.d.ts +13 -0
  39. package/dist/AST/FunctionCallNode.js +102 -0
  40. package/dist/AST/FunctionCallNode.js.map +1 -0
  41. package/dist/AST/IfStatementNode.d.ts +14 -0
  42. package/dist/AST/IfStatementNode.js +128 -0
  43. package/dist/AST/IfStatementNode.js.map +1 -0
  44. package/dist/AST/InNode.d.ts +15 -0
  45. package/dist/AST/InNode.js +107 -0
  46. package/dist/AST/InNode.js.map +1 -0
  47. package/dist/AST/IndexNode.d.ts +16 -0
  48. package/dist/AST/IndexNode.js +126 -0
  49. package/dist/AST/IndexNode.js.map +1 -0
  50. package/dist/AST/LiteralNode.d.ts +10 -0
  51. package/dist/AST/LiteralNode.js +74 -0
  52. package/dist/AST/LiteralNode.js.map +1 -0
  53. package/dist/AST/Node.d.ts +19 -0
  54. package/dist/AST/Node.js +117 -0
  55. package/dist/AST/Node.js.map +1 -0
  56. package/dist/AST/NotNode.d.ts +12 -0
  57. package/dist/AST/NotNode.js +103 -0
  58. package/dist/AST/NotNode.js.map +1 -0
  59. package/dist/AST/NumberLiteralNode.d.ts +5 -0
  60. package/dist/AST/NumberLiteralNode.js +36 -0
  61. package/dist/AST/NumberLiteralNode.js.map +1 -0
  62. package/dist/AST/ObjectNode.d.ts +14 -0
  63. package/dist/AST/ObjectNode.js +131 -0
  64. package/dist/AST/ObjectNode.js.map +1 -0
  65. package/dist/AST/RootScopeMemberNode.d.ts +11 -0
  66. package/dist/AST/RootScopeMemberNode.js +87 -0
  67. package/dist/AST/RootScopeMemberNode.js.map +1 -0
  68. package/dist/AST/ScopeMemberNode.d.ts +12 -0
  69. package/dist/AST/ScopeMemberNode.js +128 -0
  70. package/dist/AST/ScopeMemberNode.js.map +1 -0
  71. package/dist/AST/UnitLiteralNode.d.ts +15 -0
  72. package/dist/AST/UnitLiteralNode.js +72 -0
  73. package/dist/AST/UnitLiteralNode.js.map +1 -0
  74. package/dist/AST.d.ts +7 -60
  75. package/dist/AST.js +778 -0
  76. package/dist/AST.js.map +1 -0
  77. package/dist/Attribute.d.ts +1 -1
  78. package/dist/Attribute.js +187 -0
  79. package/dist/Attribute.js.map +1 -0
  80. package/dist/Bencmark.js +179 -0
  81. package/dist/Bencmark.js.map +1 -0
  82. package/dist/Configuration.d.ts +1 -1
  83. package/dist/Configuration.js +64 -0
  84. package/dist/Configuration.js.map +1 -0
  85. package/dist/Controller.d.ts +4 -2
  86. package/dist/Controller.js +62 -0
  87. package/dist/Controller.js.map +1 -0
  88. package/dist/DOM/DOMObject.d.ts +1 -1
  89. package/dist/DOM/DOMObject.js +47 -0
  90. package/dist/DOM/DOMObject.js.map +1 -0
  91. package/dist/DOM/WrappedDocument.js +34 -0
  92. package/dist/DOM/WrappedDocument.js.map +1 -0
  93. package/dist/DOM/WrappedWindow.js +45 -0
  94. package/dist/DOM/WrappedWindow.js.map +1 -0
  95. package/dist/DOM.d.ts +1 -1
  96. package/dist/DOM.js +547 -0
  97. package/dist/DOM.js.map +1 -0
  98. package/dist/EventDispatcher.d.ts +29 -0
  99. package/dist/EventDispatcher.js +132 -0
  100. package/dist/EventDispatcher.js.map +1 -0
  101. package/dist/Formats.js +44 -0
  102. package/dist/Formats.js.map +1 -0
  103. package/dist/MessageList.d.ts +15 -0
  104. package/dist/MessageList.js +96 -0
  105. package/dist/MessageList.js.map +1 -0
  106. package/dist/Model/Field.d.ts +8 -0
  107. package/dist/Model/Field.js +38 -0
  108. package/dist/Model/Field.js.map +1 -0
  109. package/dist/Model.d.ts +12 -0
  110. package/dist/Model.js +61 -0
  111. package/dist/Model.js.map +1 -0
  112. package/dist/Query.js +66 -0
  113. package/dist/Query.js.map +1 -0
  114. package/dist/Registry.d.ts +5 -2
  115. package/dist/Registry.js +139 -0
  116. package/dist/Registry.js.map +1 -0
  117. package/dist/Scope/DynamicScopeData.d.ts +6 -0
  118. package/dist/Scope/DynamicScopeData.js +54 -0
  119. package/dist/Scope/DynamicScopeData.js.map +1 -0
  120. package/dist/Scope/QueryReference.d.ts +10 -0
  121. package/dist/Scope/QueryReference.js +103 -0
  122. package/dist/Scope/QueryReference.js.map +1 -0
  123. package/dist/Scope/ScopeData.d.ts +4 -0
  124. package/dist/Scope/ScopeData.js +40 -0
  125. package/dist/Scope/ScopeData.js.map +1 -0
  126. package/dist/Scope/ScopeDataAbstract.d.ts +22 -0
  127. package/dist/Scope/ScopeDataAbstract.js +137 -0
  128. package/dist/Scope/ScopeDataAbstract.js.map +1 -0
  129. package/dist/Scope/ScopeReference.d.ts +10 -0
  130. package/dist/Scope/ScopeReference.js +73 -0
  131. package/dist/Scope/ScopeReference.js.map +1 -0
  132. package/dist/Scope/ScopedVariableType.d.ts +6 -0
  133. package/dist/Scope/ScopedVariableType.js +14 -0
  134. package/dist/Scope/ScopedVariableType.js.map +1 -0
  135. package/dist/Scope/WrappedArray.d.ts +16 -0
  136. package/dist/Scope/WrappedArray.js +121 -0
  137. package/dist/Scope/WrappedArray.js.map +1 -0
  138. package/dist/Scope/properties/Property.d.ts +18 -0
  139. package/dist/Scope/properties/Property.js +93 -0
  140. package/dist/Scope/properties/Property.js.map +1 -0
  141. package/dist/Scope.d.ts +4 -48
  142. package/dist/Scope.js +227 -0
  143. package/dist/Scope.js.map +1 -0
  144. package/dist/SimplePromise.d.ts +42 -0
  145. package/dist/SimplePromise.js +217 -0
  146. package/dist/SimplePromise.js.map +1 -0
  147. package/dist/Tag/List.js +85 -0
  148. package/dist/Tag/List.js.map +1 -0
  149. package/dist/Tag.js +770 -0
  150. package/dist/Tag.js.map +1 -0
  151. package/dist/Types.d.ts +1 -0
  152. package/dist/Types.js +54 -0
  153. package/dist/Types.js.map +1 -0
  154. package/dist/Validators.d.ts +7 -0
  155. package/dist/Validators.js +54 -0
  156. package/dist/Validators.js.map +1 -0
  157. package/dist/attributes/AddClassIf.js +93 -0
  158. package/dist/attributes/AddClassIf.js.map +1 -0
  159. package/dist/attributes/Bind.js +272 -0
  160. package/dist/attributes/Bind.js.map +1 -0
  161. package/dist/attributes/ClassConstructor.d.ts +1 -0
  162. package/dist/attributes/ClassConstructor.js +104 -0
  163. package/dist/attributes/ClassConstructor.js.map +1 -0
  164. package/dist/attributes/ClickRemoveClass.js +114 -0
  165. package/dist/attributes/ClickRemoveClass.js.map +1 -0
  166. package/dist/attributes/ClickToggleClass.js +114 -0
  167. package/dist/attributes/ClickToggleClass.js.map +1 -0
  168. package/dist/attributes/ControllerAttribute.js +28 -0
  169. package/dist/attributes/ControllerAttribute.js.map +1 -0
  170. package/dist/attributes/DisableIf.js +94 -0
  171. package/dist/attributes/DisableIf.js.map +1 -0
  172. package/dist/attributes/Exec.js +108 -0
  173. package/dist/attributes/Exec.js.map +1 -0
  174. package/dist/attributes/Format.js +99 -0
  175. package/dist/attributes/Format.js.map +1 -0
  176. package/dist/attributes/If.js +159 -0
  177. package/dist/attributes/If.js.map +1 -0
  178. package/dist/attributes/JSONAttribute.js +118 -0
  179. package/dist/attributes/JSONAttribute.js.map +1 -0
  180. package/dist/attributes/KeyAbstract.js +117 -0
  181. package/dist/attributes/KeyAbstract.js.map +1 -0
  182. package/dist/attributes/KeyDown.js +88 -0
  183. package/dist/attributes/KeyDown.js.map +1 -0
  184. package/dist/attributes/KeyUp.js +88 -0
  185. package/dist/attributes/KeyUp.js.map +1 -0
  186. package/dist/attributes/List.js +282 -0
  187. package/dist/attributes/List.js.map +1 -0
  188. package/dist/attributes/ListItem.js +138 -0
  189. package/dist/attributes/ListItem.js.map +1 -0
  190. package/dist/attributes/ListItemModel.js +39 -0
  191. package/dist/attributes/ListItemModel.js.map +1 -0
  192. package/dist/attributes/ModelAttribute.js +29 -0
  193. package/dist/attributes/ModelAttribute.js.map +1 -0
  194. package/dist/attributes/Name.js +88 -0
  195. package/dist/attributes/Name.js.map +1 -0
  196. package/dist/attributes/On.js +135 -0
  197. package/dist/attributes/On.js.map +1 -0
  198. package/dist/attributes/Radio.js +174 -0
  199. package/dist/attributes/Radio.js.map +1 -0
  200. package/dist/attributes/Referenced.js +38 -0
  201. package/dist/attributes/Referenced.js.map +1 -0
  202. package/dist/attributes/RootAttribute.js +91 -0
  203. package/dist/attributes/RootAttribute.js.map +1 -0
  204. package/dist/attributes/ScopeAttribute.js +40 -0
  205. package/dist/attributes/ScopeAttribute.js.map +1 -0
  206. package/dist/attributes/ScopeChange.js +130 -0
  207. package/dist/attributes/ScopeChange.js.map +1 -0
  208. package/dist/attributes/SetAttribute.js +133 -0
  209. package/dist/attributes/SetAttribute.js.map +1 -0
  210. package/dist/attributes/StandardAttribute.js +186 -0
  211. package/dist/attributes/StandardAttribute.js.map +1 -0
  212. package/dist/attributes/StyleAttribute.js +183 -0
  213. package/dist/attributes/StyleAttribute.js.map +1 -0
  214. package/dist/attributes/Template.js +39 -0
  215. package/dist/attributes/Template.js.map +1 -0
  216. package/dist/attributes/TypeAttribute.js +104 -0
  217. package/dist/attributes/TypeAttribute.js.map +1 -0
  218. package/dist/attributes/_imports.js +60 -0
  219. package/dist/attributes/_imports.js.map +1 -0
  220. package/dist/helpers/DOMHelper.js +81 -0
  221. package/dist/helpers/DOMHelper.js.map +1 -0
  222. package/dist/helpers/ElementHelper.js +25 -0
  223. package/dist/helpers/ElementHelper.js.map +1 -0
  224. package/dist/helpers/VisionHelper.js +71 -0
  225. package/dist/helpers/VisionHelper.js.map +1 -0
  226. package/dist/helpers/decorators.js +38 -0
  227. package/dist/helpers/decorators.js.map +1 -0
  228. package/dist/vsn.d.ts +11 -2
  229. package/dist/vsn.js +181 -0
  230. package/dist/vsn.js.map +1 -0
  231. package/package.json +2 -6
  232. package/src/AST/ArithmeticAssignmentNode.ts +236 -0
  233. package/src/AST/ArithmeticNode.ts +52 -0
  234. package/src/AST/ArrayNode.ts +39 -0
  235. package/src/AST/BlockNode.ts +25 -0
  236. package/src/AST/BooleanLiteralNode.ts +10 -0
  237. package/src/AST/ComparisonNode.ts +57 -0
  238. package/src/AST/ConditionalNode.ts +36 -0
  239. package/src/AST/ElementAttributeNode.ts +63 -0
  240. package/src/AST/ElementQueryNode.ts +25 -0
  241. package/src/AST/ElementStyleNode.ts +63 -0
  242. package/src/AST/ForStatementNode.ts +59 -0
  243. package/src/AST/FunctionArgumentNode.ts +27 -0
  244. package/src/AST/FunctionCallNode.ts +32 -0
  245. package/src/AST/IfStatementNode.ts +67 -0
  246. package/src/AST/InNode.ts +46 -0
  247. package/src/AST/IndexNode.ts +61 -0
  248. package/src/AST/LiteralNode.ts +17 -0
  249. package/src/AST/Node.ts +71 -0
  250. package/src/AST/NotNode.ts +41 -0
  251. package/src/AST/NumberLiteralNode.ts +14 -0
  252. package/src/AST/ObjectNode.ts +55 -0
  253. package/src/AST/RootScopeMemberNode.ts +25 -0
  254. package/src/AST/ScopeMemberNode.ts +53 -0
  255. package/src/AST/UnitLiteralNode.ts +51 -0
  256. package/src/AST.ts +34 -1094
  257. package/src/Attribute.ts +2 -2
  258. package/src/Configuration.ts +3 -3
  259. package/src/Controller.ts +10 -2
  260. package/src/DOM/DOMObject.ts +1 -1
  261. package/src/DOM.ts +3 -3
  262. package/src/EventDispatcher.ts +134 -0
  263. package/src/Formats.ts +2 -2
  264. package/src/MessageList.ts +85 -0
  265. package/src/Model/Field.ts +20 -0
  266. package/src/Model.ts +43 -0
  267. package/src/Registry.ts +13 -3
  268. package/src/Scope/DynamicScopeData.ts +29 -0
  269. package/src/Scope/QueryReference.ts +29 -0
  270. package/src/Scope/ScopeData.ts +21 -0
  271. package/src/Scope/ScopeDataAbstract.ts +126 -0
  272. package/src/Scope/ScopeReference.ts +30 -0
  273. package/src/Scope/ScopedVariableType.ts +7 -0
  274. package/src/Scope/WrappedArray.ts +88 -0
  275. package/src/Scope/properties/Property.ts +79 -0
  276. package/src/Scope.ts +31 -252
  277. package/src/SimplePromise.ts +219 -0
  278. package/src/Tag.ts +3 -3
  279. package/src/Types.ts +6 -1
  280. package/src/Validators.ts +45 -0
  281. package/src/attributes/Bind.ts +4 -4
  282. package/src/attributes/ClassConstructor.ts +2 -1
  283. package/src/attributes/JSONAttribute.ts +2 -1
  284. package/src/attributes/List.ts +4 -4
  285. package/src/attributes/Radio.ts +3 -2
  286. package/src/attributes/ScopeChange.ts +2 -2
  287. package/src/attributes/SetAttribute.ts +2 -1
  288. package/src/attributes/StandardAttribute.ts +1 -1
  289. package/src/attributes/StyleAttribute.ts +3 -2
  290. package/src/attributes/TypeAttribute.ts +1 -1
  291. package/src/vsn.ts +16 -5
  292. package/test/AST/ArithmeticAssignmentNode.spec.ts +47 -0
  293. package/test/AST.spec.ts +3 -2
  294. package/test/Controller.spec.ts +44 -0
  295. package/test/MessageList.spec.ts +101 -0
  296. package/test/Model/DataModel.spec.ts +0 -0
  297. package/test/Scope/DynamicScopeData.spec.ts +141 -0
  298. package/test/Scope.spec.ts +15 -3
  299. package/test/SimplePromise.spec.ts +271 -0
  300. package/test/Tag/TagList.spec.ts +1 -1
  301. package/test/attributes/Bind.spec.ts +5 -5
  302. package/test/attributes/ListItem.spec.ts +1 -1
  303. package/dist/vsn.min.js +0 -1
@@ -0,0 +1,63 @@
1
+ import {Scope} from "../Scope";
2
+ import {DOM} from "../DOM";
3
+ import {Tag} from "../Tag";
4
+ import {TagList} from "../Tag/List";
5
+ import {TreeNode} from "../AST";
6
+ import {Node} from "./Node";
7
+ import {ElementQueryNode} from "./ElementQueryNode";
8
+ import {LiteralNode} from "./LiteralNode";
9
+
10
+ export class ElementAttributeNode extends Node implements TreeNode {
11
+ protected requiresPrep: boolean = true;
12
+
13
+ constructor(
14
+ public readonly elementRef: ElementQueryNode | null,
15
+ public readonly attr: string
16
+ ) {
17
+ super();
18
+ }
19
+
20
+ public get name(): LiteralNode<string> {
21
+ return new LiteralNode<string>(`@${this.attributeName}`);
22
+ }
23
+
24
+ protected _getChildNodes(): Node[] {
25
+ let nodes = [];
26
+ if (this.elementRef)
27
+ nodes.push(this.elementRef)
28
+ return nodes;
29
+ }
30
+
31
+ get attributeName(): string {
32
+ if (this.attr.startsWith('.'))
33
+ return this.attr.substring(2);
34
+ return this.attr.substring(1);
35
+ }
36
+
37
+ async evaluate(scope: Scope, dom: DOM, tag: Tag = null) {
38
+ let tags: TagList;
39
+ if (this.elementRef) {
40
+ tags = await this.elementRef.evaluate(scope, dom, tag);
41
+ } else if (tag) {
42
+ tags = new TagList(tag)
43
+ } else {
44
+ return;
45
+ }
46
+
47
+ if (tags.length === 1)
48
+ return tags[0].scope.get(`@${this.attributeName}`);
49
+
50
+ return tags.map((tag) => tag.scope.get(`@${this.attributeName}`));
51
+ }
52
+
53
+ async prepare(scope: Scope, dom: DOM, tag: Tag = null) {
54
+ if (this.elementRef) {
55
+ await this.elementRef.prepare(scope, dom, tag);
56
+ const tags: TagList = await this.elementRef.evaluate(scope, dom, tag);
57
+ for (const t of tags)
58
+ await t.watchAttribute(this.attributeName);
59
+ } else if(tag) {
60
+ await tag.watchAttribute(this.attributeName);
61
+ }
62
+ }
63
+ }
@@ -0,0 +1,25 @@
1
+ import {Scope} from "../Scope";
2
+ import {DOM} from "../DOM";
3
+ import {Tag} from "../Tag";
4
+ import {TreeNode} from "../AST";
5
+ import {Node} from "./Node";
6
+
7
+ export class ElementQueryNode extends Node implements TreeNode {
8
+ protected requiresPrep: boolean = true;
9
+
10
+ constructor(
11
+ public readonly query: string
12
+ ) {
13
+ super();
14
+ }
15
+
16
+ async evaluate(scope: Scope, dom: DOM, tag: Tag = null) {
17
+ tag = tag || await dom.getTagForScope(scope);
18
+ return await dom.get(this.query, true, tag);
19
+ }
20
+
21
+ async prepare(scope: Scope, dom: DOM, tag: Tag = null) {
22
+ tag = tag || await dom.getTagForScope(scope);
23
+ await dom.get(this.query, true, tag);
24
+ }
25
+ }
@@ -0,0 +1,63 @@
1
+ import {Scope} from "../Scope";
2
+ import {DOM} from "../DOM";
3
+ import {Tag} from "../Tag";
4
+ import {TagList} from "../Tag/List";
5
+ import {TreeNode} from "../AST";
6
+ import {Node} from "./Node";
7
+ import {ElementQueryNode} from "./ElementQueryNode";
8
+ import {LiteralNode} from "./LiteralNode";
9
+
10
+ export class ElementStyleNode extends Node implements TreeNode {
11
+ protected requiresPrep: boolean = true;
12
+
13
+ constructor(
14
+ public readonly elementRef: ElementQueryNode | null,
15
+ public readonly attr: string
16
+ ) {
17
+ super();
18
+ }
19
+
20
+ public get name(): LiteralNode<string> {
21
+ return new LiteralNode<string>(`$${this.attributeName}`);
22
+ }
23
+
24
+ protected _getChildNodes(): Node[] {
25
+ let nodes = [];
26
+ if (this.elementRef)
27
+ nodes.push(this.elementRef)
28
+ return nodes;
29
+ }
30
+
31
+ get attributeName(): string {
32
+ if (this.attr.startsWith('.'))
33
+ return this.attr.substring(2);
34
+ return this.attr.substring(1);
35
+ }
36
+
37
+ async evaluate(scope: Scope, dom: DOM, tag: Tag = null) {
38
+ let tags: TagList;
39
+ if (this.elementRef) {
40
+ tags = await this.elementRef.evaluate(scope, dom, tag);
41
+ } else if (tag) {
42
+ tags = new TagList(tag)
43
+ } else {
44
+ return;
45
+ }
46
+
47
+ if (tags.length === 1)
48
+ return tags[0].scope.get(`$${this.attributeName}`);
49
+
50
+ return tags.map((tag) => tag.scope.get(`$${this.attributeName}`));
51
+ }
52
+
53
+ async prepare(scope: Scope, dom: DOM, tag: Tag = null) {
54
+ if (this.elementRef) {
55
+ await this.elementRef.prepare(scope, dom, tag);
56
+ const tags: TagList = await this.elementRef.evaluate(scope, dom, tag);
57
+ for (const t of tags)
58
+ await t.watchStyle(this.attributeName);
59
+ } else if(tag) {
60
+ await tag.watchStyle(this.attributeName);
61
+ }
62
+ }
63
+ }
@@ -0,0 +1,59 @@
1
+ import {Scope} from "../Scope";
2
+ import {DOM} from "../DOM";
3
+ import {Tag} from "../Tag";
4
+ import {Token, TokenType, Tree, TreeNode} from "../AST";
5
+ import {Node} from "./Node";
6
+ import {LiteralNode} from "./LiteralNode";
7
+ import {RootScopeMemberNode} from "./RootScopeMemberNode";
8
+ import {ScopeMemberNode} from "./ScopeMemberNode";
9
+
10
+ export class ForStatementNode extends Node implements TreeNode {
11
+ constructor(
12
+ public readonly variable: LiteralNode<string>,
13
+ public readonly list: RootScopeMemberNode | ScopeMemberNode,
14
+ public readonly block: RootScopeMemberNode | ScopeMemberNode,
15
+ ) {
16
+ super();
17
+ }
18
+
19
+ protected _getChildNodes(): Node[] {
20
+ return [
21
+ this.variable,
22
+ this.list,
23
+ this.block
24
+ ];
25
+ }
26
+
27
+ public async evaluate(scope: Scope, dom: DOM, tag: Tag = null) {
28
+ const variable: string = await this.variable.evaluate(scope, dom, tag);
29
+ const list: any[] = await this.list.evaluate(scope, dom, tag);
30
+ for (let i = 0;i < list.length; i++) {
31
+ scope.set(variable, list[i]);
32
+ await this.block.evaluate(scope, dom, tag);
33
+ }
34
+
35
+ return null;
36
+ }
37
+
38
+ public static parse(lastNode, token, tokens: Token[]): ForStatementNode {
39
+ if (tokens[1].type !== TokenType.L_PAREN) {
40
+ throw SyntaxError('Syntax error: Missing (');
41
+ }
42
+ if (tokens[3].type !== TokenType.OF) {
43
+ throw SyntaxError('Syntax error: Missing of');
44
+ }
45
+
46
+ tokens.splice(0, 1); // consume for
47
+ const loopDef: Token[] = Tree.getNextStatementTokens(tokens);
48
+ const variableName: Token = loopDef.splice(0, 1)[0];
49
+ loopDef.splice(0, 1); // consume of
50
+ const list: TreeNode = Tree.processTokens(loopDef);
51
+ const block: TreeNode = Tree.processTokens(Tree.getBlockTokens(tokens, null)[0]);
52
+
53
+ return new ForStatementNode(
54
+ new LiteralNode<string>(variableName.value),
55
+ list as any,
56
+ block as any
57
+ );
58
+ }
59
+ }
@@ -0,0 +1,27 @@
1
+ import {Scope} from "../Scope";
2
+ import {DOM} from "../DOM";
3
+ import {Tag} from "../Tag";
4
+ import {TreeNode} from "../AST";
5
+ import {Node} from "./Node";
6
+
7
+ export class FunctionArgumentNode<T = any> extends Node implements TreeNode {
8
+ constructor(
9
+ protected args: Node[]
10
+ ) {
11
+ super();
12
+ }
13
+
14
+ protected _getChildNodes(): Node[] {
15
+ return [
16
+ ...(this.args as Node[])
17
+ ]
18
+ }
19
+
20
+ async evaluate(scope: Scope, dom: DOM, tag: Tag = null) {
21
+ const values: any[] = [];
22
+ for (const arg of this.args) {
23
+ values.push(await arg.evaluate(scope, dom, tag));
24
+ }
25
+ return values;
26
+ }
27
+ }
@@ -0,0 +1,32 @@
1
+ import {Scope} from "../Scope";
2
+ import {DOM} from "../DOM";
3
+ import {Tag} from "../Tag";
4
+ import {TreeNode} from "../AST";
5
+ import {Node} from "./Node";
6
+ import {FunctionArgumentNode} from "./FunctionArgumentNode";
7
+ import {ScopeMemberNode} from "./ScopeMemberNode";
8
+
9
+ export class FunctionCallNode<T = any> extends Node implements TreeNode {
10
+ constructor(
11
+ public readonly fnc: TreeNode<(...args: any[]) => any>,
12
+ public readonly args: FunctionArgumentNode<any[]>
13
+ ) {
14
+ super();
15
+ }
16
+
17
+ protected _getChildNodes(): Node[] {
18
+ return [
19
+ this.fnc as Node,
20
+ this.args as Node
21
+ ]
22
+ }
23
+
24
+ public async evaluate(scope: Scope, dom: DOM, tag: Tag = null) {
25
+ let functionScope: Scope = scope;
26
+ if (this.fnc instanceof ScopeMemberNode) {
27
+ functionScope = await this.fnc.scope.evaluate(scope, dom, tag);
28
+ }
29
+ const values = await this.args.evaluate(scope, dom, tag);
30
+ return (await this.fnc.evaluate(scope, dom, tag)).call(functionScope.wrapped || functionScope, ...values);
31
+ }
32
+ }
@@ -0,0 +1,67 @@
1
+ import {Scope} from "../Scope";
2
+ import {DOM} from "../DOM";
3
+ import {Tag} from "../Tag";
4
+ import {Token, TokenType, Tree, TreeNode} from "../AST";
5
+ import {Node} from "./Node";
6
+ import {ConditionalNode} from "./ConditionalNode";
7
+ import {LiteralNode} from "./LiteralNode";
8
+
9
+ export class IfStatementNode extends Node implements TreeNode {
10
+ constructor(
11
+ protected nodes: ConditionalNode[]
12
+ ) {
13
+ super();
14
+ }
15
+
16
+ protected _getChildNodes(): Node[] {
17
+ return [
18
+ ...(this.nodes as Node[])
19
+ ]
20
+ }
21
+
22
+ public async evaluate(scope: Scope, dom: DOM, tag: Tag = null) {
23
+ for (const condition of this.nodes) {
24
+ const uno: boolean = await condition.evaluate(scope, dom, tag);
25
+ if (uno) {
26
+ return await condition.block.evaluate(scope, dom, tag);
27
+ }
28
+ }
29
+ }
30
+
31
+ public static parseConditional(tokens: Token[]): ConditionalNode {
32
+ if ([
33
+ TokenType.IF,
34
+ TokenType.ELSE_IF
35
+ ].indexOf(tokens[0].type) === -1) {
36
+ throw SyntaxError('Invalid Syntax');
37
+ }
38
+
39
+ tokens.splice(0, 1); // consume if and else if
40
+ return new ConditionalNode(
41
+ Tree.processTokens(Tree.getBlockTokens(tokens, null)[0]),
42
+ Tree.processTokens(Tree.getBlockTokens(tokens, null)[0])
43
+ );
44
+ }
45
+
46
+ public static parse(lastNode, token, tokens: Token[]): IfStatementNode {
47
+ if (tokens[1].type !== TokenType.L_PAREN) {
48
+ throw SyntaxError('If statement needs to be followed by a condition encased in parenthesis.');
49
+ }
50
+ const nodes: ConditionalNode[] = [];
51
+ nodes.push(IfStatementNode.parseConditional(tokens));
52
+
53
+ while(tokens.length > 0 && TokenType.ELSE_IF === tokens[0].type) {
54
+ nodes.push(IfStatementNode.parseConditional(tokens));
55
+ }
56
+
57
+ if (tokens.length > 0 && TokenType.ELSE === tokens[0].type) {
58
+ tokens.splice(0, 1); // Consume else
59
+ nodes.push(new ConditionalNode(
60
+ new LiteralNode(true),
61
+ Tree.processTokens(Tree.getBlockTokens(tokens, null)[0])
62
+ ))
63
+ }
64
+
65
+ return new IfStatementNode(nodes);
66
+ }
67
+ }
@@ -0,0 +1,46 @@
1
+ import {Scope} from "../Scope";
2
+ import {DOM} from "../DOM";
3
+ import {Tag} from "../Tag";
4
+ import {Token, TokenType, Tree, TreeNode} from "../AST";
5
+ import {Node} from "./Node";
6
+
7
+ export class InNode extends Node implements TreeNode {
8
+ constructor(
9
+ public readonly left: TreeNode,
10
+ public readonly right: TreeNode,
11
+ public readonly flip: boolean = false
12
+ ) {
13
+ super();
14
+ }
15
+
16
+ public async evaluate(scope: Scope, dom: DOM, tag: Tag = null) {
17
+ const toCheck = await this.left.evaluate(scope, dom, tag);
18
+ const array = await this.right.evaluate(scope, dom, tag);
19
+
20
+ let inArray = array.indexOf(toCheck) > -1;
21
+ if (this.flip)
22
+ inArray = !inArray;
23
+ return inArray;
24
+ }
25
+
26
+ protected _getChildNodes(): Node[] {
27
+ return [
28
+ this.left as Node,
29
+ this.right as Node
30
+ ];
31
+ }
32
+
33
+ public static match(tokens: Token[]): boolean {
34
+ return tokens[0].type === TokenType.IN || (tokens[0].type === TokenType.NOT && tokens[1].type === TokenType.IN);
35
+ }
36
+
37
+ public static parse(lastNode, token, tokens: Token[]) {
38
+ const flip: boolean = tokens[0].type === TokenType.NOT;
39
+ if (flip)
40
+ tokens.splice(0, 1); // consume not
41
+ tokens.splice(0, 1); // consume in
42
+
43
+ const containedTokens = Tree.getNextStatementTokens(tokens, false, false, true);
44
+ return new InNode(lastNode, Tree.processTokens(containedTokens), flip);
45
+ }
46
+ }
@@ -0,0 +1,61 @@
1
+ import {Scope} from "../Scope";
2
+ import {DOM} from "../DOM";
3
+ import {Tag} from "../Tag";
4
+ import {Token, TokenType, Tree, TreeNode} from "../AST";
5
+ import {Node} from "./Node";
6
+
7
+ export class IndexNode extends Node implements TreeNode {
8
+ constructor(
9
+ public readonly object: Node,
10
+ public readonly index: Node,
11
+ public readonly indexTwo: Node = null
12
+ ) {
13
+ super();
14
+ }
15
+
16
+ protected _getChildNodes(): Node[] {
17
+ const children = [
18
+ this.object,
19
+ this.index
20
+ ];
21
+ if (this.indexTwo)
22
+ children.push(this.indexTwo);
23
+
24
+ return children;
25
+ }
26
+
27
+ public negativeIndex(obj: any[], index: number | string): number | string {
28
+ if (Number.isFinite(index) && index < 0)
29
+ return obj.length + (index as number);
30
+ return index;
31
+ }
32
+
33
+ async evaluate(scope: Scope, dom: DOM, tag: Tag = null) {
34
+ const obj = await this.object.evaluate(scope, dom, tag);
35
+ const index: string | number = this.negativeIndex(obj, await this.index.evaluate(scope, dom, tag));
36
+
37
+ if (Number.isFinite(index) && this.indexTwo) {
38
+ const indexTwo: number = this.negativeIndex(obj, await this.indexTwo.evaluate(scope, dom, tag)) as number;
39
+ const values = [];
40
+ for (let i: number = index as number; i <= indexTwo; i++) {
41
+ values.push(obj[i]);
42
+ }
43
+ return values;
44
+ } else {
45
+ return (obj)[index];
46
+ }
47
+ }
48
+
49
+ public static match(tokens: Token[]): boolean {
50
+ return tokens[0].type === TokenType.L_BRACKET;
51
+ }
52
+
53
+ public static parse(lastNode, token, tokens: Token[]): IndexNode {
54
+ const valueTokens: Token[][] = Tree.getBlockTokens(tokens, TokenType.COLON);
55
+ const values: Node[] = [];
56
+ for (const arg of valueTokens) {
57
+ values.push(Tree.processTokens(arg));
58
+ }
59
+ return new IndexNode(lastNode, values[0], values.length > 1 && values[1]);
60
+ }
61
+ }
@@ -0,0 +1,17 @@
1
+ import {Scope} from "../Scope";
2
+ import {DOM} from "../DOM";
3
+ import {Tag} from "../Tag";
4
+ import {TreeNode} from "../AST";
5
+ import {Node} from "./Node";
6
+
7
+ export class LiteralNode<T = any> extends Node implements TreeNode {
8
+ constructor(
9
+ public readonly value: T
10
+ ) {
11
+ super();
12
+ }
13
+
14
+ public async evaluate(scope: Scope, dom: DOM, tag: Tag = null) {
15
+ return this.value;
16
+ }
17
+ }
@@ -0,0 +1,71 @@
1
+ import {Scope} from "../Scope";
2
+ import {DOM} from "../DOM";
3
+ import {Tag} from "../Tag";
4
+ import {TreeNode} from "../AST";
5
+
6
+ export abstract class Node implements TreeNode {
7
+ protected requiresPrep: boolean = false;
8
+ protected _isPreparationRequired: boolean;
9
+ protected childNodes: Node[];
10
+ protected nodeCache: {[key: string]: Node[]} = {};
11
+ abstract evaluate(scope: Scope, dom: DOM, tag?: Tag);
12
+
13
+ isPreparationRequired(): boolean {
14
+ if (this.requiresPrep)
15
+ return true;
16
+
17
+ if (this._isPreparationRequired !== undefined)
18
+ return this._isPreparationRequired;
19
+
20
+ for (const node of this.getChildNodes()) {
21
+ if (node.isPreparationRequired()) {
22
+ this._isPreparationRequired = true;
23
+ return true;
24
+ }
25
+ }
26
+
27
+ return false;
28
+ }
29
+
30
+ async prepare(scope: Scope, dom: DOM, tag: Tag = null) {
31
+ for (const node of this.getChildNodes()) {
32
+ await node.prepare(scope, dom, tag);
33
+ }
34
+ }
35
+
36
+ protected _getChildNodes(): Node[] {
37
+ return [];
38
+ }
39
+
40
+ getChildNodes(): Node[] {
41
+ if (this.childNodes === undefined) {
42
+ this.childNodes = this._getChildNodes();
43
+ }
44
+ return this.childNodes;
45
+ }
46
+
47
+ findChildrenByType<T = Node>(t: any): T[] {
48
+ return this.findChildrenByTypes([t]);
49
+ }
50
+
51
+ findChildrenByTypes<T = Node>(types: any[], cacheKey: string = null): T[] {
52
+ if (cacheKey !== null && this.nodeCache[cacheKey])
53
+ return this.nodeCache[cacheKey] as any;
54
+
55
+ const nodes: T[] = [];
56
+ for (const child of this.getChildNodes()) {
57
+ for (const t of types) {
58
+ if (child instanceof t)
59
+ nodes.push(child as any as T);
60
+ const childNodes: T[] = child.findChildrenByType<T>(t);
61
+ nodes.push(...childNodes);
62
+ }
63
+ }
64
+
65
+ if (cacheKey !== null)
66
+ this.nodeCache[cacheKey] = nodes as any;
67
+
68
+ return nodes;
69
+ }
70
+ }
71
+
@@ -0,0 +1,41 @@
1
+ import {Scope} from "../Scope";
2
+ import {DOM} from "../DOM";
3
+ import {Tag} from "../Tag";
4
+ import {Token, TokenType, Tree, TreeNode} from "../AST";
5
+ import {Node} from "./Node";
6
+
7
+ export class NotNode extends Node implements TreeNode {
8
+ constructor(
9
+ public readonly toFlip: Node
10
+ ) {
11
+ super();
12
+ }
13
+
14
+ public async evaluate(scope: Scope, dom: DOM, tag: Tag = null) {
15
+ const flipping = await this.toFlip.evaluate(scope, dom, tag);
16
+ return !flipping;
17
+ }
18
+
19
+ protected _getChildNodes(): Node[] {
20
+ return [
21
+ this.toFlip
22
+ ];
23
+ }
24
+
25
+ public static parse(lastNode, token, tokens: Token[]) {
26
+ tokens.splice(0, 1); // Remove not operator
27
+ let containedTokens;
28
+ if (tokens[0].type === TokenType.L_PAREN) {
29
+ containedTokens = Tree.getNextStatementTokens(tokens);
30
+ } else {
31
+ containedTokens = Tree.consumeTypes(tokens, [
32
+ TokenType.BOOLEAN_LITERAL,
33
+ TokenType.NUMBER_LITERAL,
34
+ TokenType.STRING_LITERAL,
35
+ TokenType.NAME,
36
+ TokenType.PERIOD
37
+ ]);
38
+ }
39
+ return new NotNode(Tree.processTokens(containedTokens));
40
+ }
41
+ }
@@ -0,0 +1,14 @@
1
+ import {LiteralNode} from "./LiteralNode";
2
+
3
+ export class NumberLiteralNode extends LiteralNode<number> {
4
+ constructor(
5
+ public readonly value: any
6
+ ) {
7
+ super(value);
8
+ if (this.value.indexOf('.') > -1) {
9
+ this.value = parseFloat(this.value)
10
+ } else {
11
+ this.value = parseInt(this.value);
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,55 @@
1
+ import {Scope} from "../Scope";
2
+ import {DOM} from "../DOM";
3
+ import {Tag} from "../Tag";
4
+ import {BlockType, Token, TokenType, Tree, TreeNode} from "../AST";
5
+ import {Node} from "./Node";
6
+
7
+ export class ObjectNode extends Node implements TreeNode {
8
+ constructor(
9
+ public readonly keys: Node[],
10
+ public readonly values: Node[]
11
+ ) {
12
+ super();
13
+ }
14
+
15
+ protected _getChildNodes(): Node[] {
16
+ return new Array(...this.values);
17
+ }
18
+
19
+ async evaluate(scope: Scope, dom: DOM, tag: Tag = null) {
20
+ const obj: Scope = new Scope();
21
+ for (let i = 0; i < this.values.length; i++) {
22
+ const key = this.keys[i];
23
+ const val = this.values[i];
24
+ obj.set(await key.evaluate(scope, dom, tag), await val.evaluate(scope, dom, tag));
25
+ }
26
+ return obj;
27
+ }
28
+
29
+ public static match(tokens: Token[]): boolean {
30
+ return tokens[0].type === TokenType.L_BRACE;
31
+ }
32
+
33
+ public static parse(lastNode, token, tokens: Token[]): ObjectNode {
34
+ const valueTokens: Token[] = Tree.getNextStatementTokens(tokens);
35
+ const keys: Node[] = [];
36
+ const values: Node[] = [];
37
+
38
+ while (valueTokens.length > 0) {
39
+ const key: Token[] = Tree.getTokensUntil(valueTokens, TokenType.COLON, false);
40
+ if (valueTokens[0].type !== TokenType.COLON)
41
+ throw Error('Invalid object literal syntax. Expecting :');
42
+ valueTokens.splice(0, 1); // Consume :
43
+ const val: Token[] = Tree.getTokensUntil(valueTokens, TokenType.COMMA, true, false, true, {
44
+ type: BlockType.STATEMENT,
45
+ open: null,
46
+ close: null,
47
+ openCharacter: null,
48
+ closeCharacter: null
49
+ });
50
+ keys.push(Tree.processTokens(key));
51
+ values.push(Tree.processTokens(val));
52
+ }
53
+ return new ObjectNode(keys, values);
54
+ }
55
+ }
@@ -0,0 +1,25 @@
1
+ import {Scope} from "../Scope";
2
+ import {DOM} from "../DOM";
3
+ import {Tag} from "../Tag";
4
+ import {TreeNode} from "../AST";
5
+ import {Node} from "./Node";
6
+
7
+ export class RootScopeMemberNode<T = any> extends Node implements TreeNode {
8
+ constructor(
9
+ public readonly name: TreeNode<string>
10
+ ) {
11
+ super();
12
+ }
13
+
14
+ protected _getChildNodes(): Node[] {
15
+ return [
16
+ this.name as Node
17
+ ]
18
+ }
19
+
20
+ async evaluate(scope: Scope, dom: DOM, tag: Tag = null) {
21
+ const name = await this.name.evaluate(scope, dom, tag);
22
+ const value = scope.get(name);
23
+ return value instanceof Scope && value.wrapped || value;
24
+ }
25
+ }