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
package/src/Attribute.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import {Tag} from "./Tag";
2
2
  import {VisionHelper} from "./helpers/VisionHelper";
3
- import {EventDispatcher} from "simple-ts-event-dispatcher";
3
+ import {EventDispatcher} from "./EventDispatcher";
4
4
 
5
5
  export enum AttributeState {
6
6
  Instantiated,
@@ -83,7 +83,7 @@ export abstract class Attribute extends EventDispatcher {
83
83
  private setState(state: AttributeState) {
84
84
  const previousState = this._state;
85
85
  this._state = state;
86
- this.trigger('state', {
86
+ this.dispatch('state', {
87
87
  state: state,
88
88
  previousState: previousState,
89
89
  attribute: this
@@ -1,5 +1,5 @@
1
- import {EventDispatcher} from "simple-ts-event-dispatcher";
2
1
  import {VisionHelper} from "./helpers/VisionHelper";
2
+ import {EventDispatcher} from "./EventDispatcher";
3
3
 
4
4
  export type ConfigurationValue = string | number | boolean | null | undefined;
5
5
 
@@ -19,11 +19,11 @@ export class Configuration extends EventDispatcher {
19
19
  public set(key: string, value: ConfigurationValue) {
20
20
  const prev: ConfigurationValue = this.data[key];
21
21
  this.data[key] = value;
22
- this.trigger(`change:${key}`, {
22
+ this.dispatch(`change:${key}`, {
23
23
  value: value,
24
24
  previous: prev
25
25
  });
26
- this.trigger('change', {
26
+ this.dispatch('change', {
27
27
  key: key,
28
28
  value: value,
29
29
  previous: prev
package/src/Controller.ts CHANGED
@@ -1,8 +1,8 @@
1
- import {EventDispatcher} from "simple-ts-event-dispatcher";
2
1
  import {Scope} from "./Scope";
3
2
  import {Tag} from "./Tag";
3
+ import {ScopeData} from "./Scope/ScopeData";
4
4
 
5
- export abstract class Controller extends EventDispatcher {
5
+ export abstract class Controller extends ScopeData {
6
6
  protected _scope: Scope;
7
7
  protected _tag: Tag;
8
8
  protected _element: HTMLElement;
@@ -24,4 +24,12 @@ export abstract class Controller extends EventDispatcher {
24
24
  this._tag = tag;
25
25
  this._element = element;
26
26
  }
27
+
28
+ public get(key: string): any {
29
+ return this._scope?.get(key);
30
+ }
31
+
32
+ public set(key: string, value: any): void {
33
+ this._scope?.set(key, value);
34
+ }
27
35
  }
@@ -1,5 +1,5 @@
1
- import {EventDispatcher} from "simple-ts-event-dispatcher";
2
1
  import {Scope} from "../Scope";
2
+ import {EventDispatcher} from "../EventDispatcher";
3
3
 
4
4
  export abstract class DOMObject extends EventDispatcher {
5
5
  protected _scope: Scope;
package/src/DOM.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import {Tag} from "./Tag";
2
2
  import {ElementHelper} from "./helpers/ElementHelper";
3
- import {EventDispatcher} from "simple-ts-event-dispatcher";
4
3
  import {Configuration} from "./Configuration";
5
4
  import {Tree} from "./AST";
6
5
  import {TagList} from "./Tag/List";
@@ -9,6 +8,7 @@ import {VisionHelper} from "./helpers/VisionHelper";
9
8
  import {WrappedWindow} from "./DOM/WrappedWindow";
10
9
  import {WrappedDocument} from "./DOM/WrappedDocument";
11
10
  import {Scope} from "./Scope";
11
+ import {EventDispatcher} from "./EventDispatcher";
12
12
 
13
13
  export class DOM extends EventDispatcher {
14
14
  protected static _instance: DOM;
@@ -37,7 +37,7 @@ export class DOM extends EventDispatcher {
37
37
  this.buildFrom(rootElement, true);
38
38
  }
39
39
  this.evaluate();
40
- Configuration.instance.bind('change', this.evaluate.bind(this));
40
+ Configuration.instance.on('change', this.evaluate.bind(this));
41
41
  }
42
42
 
43
43
  public get root(): Tag {
@@ -232,7 +232,7 @@ export class DOM extends EventDispatcher {
232
232
  });
233
233
  if (VisionHelper.doBenchmark) benchmarkEnd('DOM', 'observeTags');
234
234
 
235
- this.trigger('built');
235
+ this.dispatch('built');
236
236
  }
237
237
 
238
238
  async getTagsForElements(elements: Element[], create: boolean = false) {
@@ -0,0 +1,134 @@
1
+
2
+ export interface EventCallbackList {
3
+ [index: string]: EventCallback[];
4
+ }
5
+
6
+
7
+ export class EventCallback {
8
+ public calls: number;
9
+ constructor(
10
+ public readonly fnc: any,
11
+ public readonly key: number,
12
+ public readonly once: boolean,
13
+ public readonly context?: any,
14
+ ) {
15
+ this.calls = 0;
16
+ }
17
+
18
+ call(...args: any[]): boolean {
19
+ if(this.once && this.calls > 0)
20
+ return false;
21
+
22
+ this.fnc.apply(this.context, ...args);
23
+ this.calls += 1;
24
+ return true;
25
+ }
26
+ }
27
+
28
+ export type EventDispatcherCallback = (...args: any[]) => any;
29
+
30
+
31
+ export class EventDispatcher {
32
+ private static sources: EventDispatcher[] = [];
33
+ private readonly _listeners: EventCallbackList;
34
+ private readonly _relays: EventDispatcher[] = [];
35
+ private _lastKey: number;
36
+
37
+ constructor() {
38
+ this._lastKey = 0;
39
+ this._listeners = {};
40
+ EventDispatcher.sources.push(this);
41
+ }
42
+
43
+ deconstruct() {
44
+ this.dispatch('deconstruct', this);
45
+ EventDispatcher.sources.splice(EventDispatcher.sources.indexOf(this), 1);
46
+ for (const k in this._listeners) {
47
+ delete this._listeners[k];
48
+ }
49
+ }
50
+
51
+ addRelay(relay: EventDispatcher) {
52
+ this._relays.push(relay);
53
+ }
54
+
55
+ removeRelay(relay: EventDispatcher) {
56
+ if (this._relays.indexOf(relay) > -1)
57
+ this._relays.splice(this._relays.indexOf(relay), 1);
58
+ }
59
+
60
+ on(event: string, fct: EventDispatcherCallback, context?: any, once?: boolean): number {
61
+ once = once || false;
62
+ this._lastKey++;
63
+ this._listeners[event] = this._listeners[event] || [];
64
+ this._listeners[event].push(new EventCallback(fct, this._lastKey, once, context));
65
+ return this._lastKey;
66
+ }
67
+
68
+ once(event: string, fct: EventDispatcherCallback, context?: any): number {
69
+ return this.on(event, fct, context, true);
70
+ }
71
+
72
+ off(event: string, key?: number): boolean {
73
+ if(event in this._listeners === false) return false;
74
+ if(key) {
75
+ for(const cb of this._listeners[event]) {
76
+ if(key == cb.key) {
77
+ this._listeners[event].splice(this._listeners[event].indexOf(cb), 1);
78
+ return true;
79
+ }
80
+ }
81
+ } else {
82
+ this._listeners[event] = [];
83
+ return true;
84
+ }
85
+ return false;
86
+ }
87
+
88
+ offWithContext(event: string, context: any): number {
89
+ if(!(event in this._listeners)) return 0;
90
+ let toRemove: EventCallback[] = [],
91
+ cnt = 0;
92
+
93
+ for(const cb of this._listeners[event]) {
94
+ if(context == cb.context) {
95
+ toRemove.push(cb);
96
+ }
97
+ }
98
+
99
+ for(const cb of toRemove) {
100
+ this._listeners[event].splice(this._listeners[event].indexOf(cb), 1);
101
+ cnt++;
102
+ }
103
+ return cnt;
104
+ }
105
+
106
+ getListener(event: string, key: number): EventCallback | undefined {
107
+ for(const cb of this._listeners[event]) {
108
+ if(key == cb.key)
109
+ return cb;
110
+ }
111
+ }
112
+
113
+ dispatch(event: string, ...args: any[]): void {
114
+ if(event in this._listeners) {
115
+ for (let i = 0; i < this._listeners[event].length; i++) {
116
+ const cb: EventCallback = this._listeners[event][i];
117
+
118
+ // We need to unbind callbacks before they're called to prevent
119
+ // infinite loops if the event is somehow triggered within the
120
+ // callback
121
+ if (cb.once) {
122
+ this.off(event, cb.key);
123
+ i--;
124
+ }
125
+
126
+ cb.call(args);
127
+ }
128
+ }
129
+
130
+ for (const relay of this._relays) {
131
+ relay.dispatch(event, ...args);
132
+ }
133
+ }
134
+ }
package/src/Formats.ts CHANGED
@@ -15,8 +15,8 @@ export class Formats {
15
15
  currency: currency
16
16
  });
17
17
  };
18
- Configuration.instance.bind('change:locale', setup);
19
- Configuration.instance.bind('change:currency', setup);
18
+ Configuration.instance.on('change:locale', setup);
19
+ Configuration.instance.on('change:currency', setup);
20
20
  setup();
21
21
  }
22
22
  value = `${value}`.replace(/[^0-9.]+/, '');
@@ -0,0 +1,85 @@
1
+ export interface IMessageHash {
2
+ [key: string]: string[] | null | undefined;
3
+ }
4
+
5
+ export class MessageList {
6
+ [key: string]: any; // We're trying to mimic a basic object
7
+
8
+ private _cachedList: IMessageHash | undefined;
9
+
10
+ constructor(messages?: IMessageHash) {
11
+ this.reset();
12
+ if (messages)
13
+ this.merge(messages);
14
+ }
15
+
16
+ reset(): void {
17
+ // Reset the object
18
+ const keys: string[] = this.keys;
19
+
20
+ this._cachedList = undefined;
21
+
22
+ if (keys.length > 0) {
23
+ for (const field of keys) {
24
+ delete this[field];
25
+ }
26
+ }
27
+ }
28
+
29
+ add(field: string, errors: string[] | string, replace: boolean = false) {
30
+ this.merge({
31
+ [field]: typeof errors == 'string' ? [errors] : errors
32
+ }, replace);
33
+ }
34
+
35
+ merge(messages: IMessageHash | null | undefined, replace: boolean = false) {
36
+ if (!messages) return;
37
+
38
+ this._cachedList = undefined;
39
+
40
+ const keys: string[] = this.keys;
41
+ for (const field in messages) {
42
+ if (!messages.hasOwnProperty(field))
43
+ continue;
44
+ const message: string[] | null | undefined = messages[field];
45
+
46
+ if (message instanceof Array) {
47
+ if (!replace && keys.indexOf(field) > -1) {
48
+ message.map((x) => {
49
+ this[field].push(x);
50
+ });
51
+ } else if (message.length > 0) {
52
+ this[field] = message;
53
+ }
54
+ }
55
+ }
56
+ }
57
+
58
+ get list(): IMessageHash {
59
+ if (this._cachedList)
60
+ return this._cachedList;
61
+
62
+ const list: IMessageHash = {},
63
+ keys: string[] = this.keys;
64
+
65
+ for (const field of keys) {
66
+ list[field] = this[field];
67
+ }
68
+ this._cachedList = list;
69
+ return list;
70
+ }
71
+
72
+ get keys(): string[] {
73
+ const keys = Object.keys(this);
74
+ keys.splice(keys.indexOf('_cachedList'), 1);
75
+ return keys;
76
+ }
77
+
78
+ get length(): number {
79
+ return this.keys.length;
80
+ }
81
+
82
+ get isEmpty(): boolean {
83
+ return this.length === 0;
84
+ }
85
+ }
@@ -0,0 +1,20 @@
1
+ import {IPropertyConfig, Property} from "../Scope/properties/Property";
2
+ import {Registry} from "../Registry";
3
+
4
+ export interface IFieldConfig extends IPropertyConfig {
5
+ validators?: string[];
6
+ }
7
+
8
+ export class Field extends Property {
9
+ config: IFieldConfig;
10
+
11
+ validate() {
12
+ const errors = [];
13
+ for(const validatorName of this.config.validators || []) {
14
+ const validator = Registry.instance.validators.getSynchronous(validatorName);
15
+ errors.concat(validator(this.value));
16
+ }
17
+
18
+ return errors;
19
+ }
20
+ }
package/src/Model.ts CHANGED
@@ -0,0 +1,43 @@
1
+ import {MessageList} from "./MessageList";
2
+ import {ScopeData} from "./Scope/ScopeData";
3
+ import {IScopeData} from "./Scope/ScopeDataAbstract";
4
+
5
+
6
+ export class Model extends ScopeData {
7
+ _errors!: MessageList;
8
+ _hasErrors: boolean;
9
+
10
+ constructor(data: IScopeData | null | undefined = null) {
11
+ super();
12
+
13
+ this._hasErrors = false;
14
+ if (data)
15
+ this.setData(data);
16
+ this._lastData = this.getData();
17
+ this._constructor();
18
+ }
19
+
20
+ _constructor() {}
21
+
22
+ validate(): MessageList {
23
+ this._hasErrors = false;
24
+ this._errors = new MessageList;
25
+ for(const property of this.getProperties()) {
26
+ const errors = this['__'+property].validate();
27
+ if(errors.length > 0) {
28
+ this._errors.add(property, errors, true);
29
+ this._hasErrors = true;
30
+ }
31
+ }
32
+ return this._errors;
33
+ }
34
+
35
+ hasErrors(): boolean {
36
+ this.validate();
37
+ return this._hasErrors;
38
+ }
39
+
40
+ get errors(): MessageList {
41
+ return this._errors;
42
+ }
43
+ }
package/src/Registry.ts CHANGED
@@ -1,6 +1,6 @@
1
- import {EventDispatcher} from "simple-ts-event-dispatcher";
2
- import {IDeferred, IPromise, Promise as SimplePromise} from "simple-ts-promise";
3
1
  import {VisionHelper} from "./helpers/VisionHelper";
2
+ import {EventDispatcher} from "./EventDispatcher";
3
+ import {IDeferred, IPromise, SimplePromise} from "./SimplePromise";
4
4
 
5
5
  export function register(store: string, key: string = null, setup: () => void = null) {
6
6
  return function(target: any, _key: string = null) {
@@ -24,7 +24,7 @@ export class RegistryStore extends EventDispatcher {
24
24
 
25
25
  register(key: string, item: any) {
26
26
  this.store[key] = item;
27
- this.trigger(`registered:${key}`, item);
27
+ this.dispatch(`registered:${key}`, item);
28
28
  }
29
29
 
30
30
  get(key: string): IPromise<any> {
@@ -57,6 +57,7 @@ export class Registry extends EventDispatcher {
57
57
  public readonly models: RegistryStore;
58
58
  public readonly templates: RegistryStore;
59
59
  public readonly types: RegistryStore;
60
+ public readonly validators: RegistryStore;
60
61
  public readonly formats: RegistryStore;
61
62
  public readonly attributes: RegistryStore;
62
63
 
@@ -68,6 +69,7 @@ export class Registry extends EventDispatcher {
68
69
  this.models = new RegistryStore(w['$models'] || {});
69
70
  this.templates = new RegistryStore(w['$templates'] || {});
70
71
  this.types = new RegistryStore(w['$types'] || {});
72
+ this.validators = new RegistryStore(w['$validators'] || {});
71
73
  this.formats = new RegistryStore(w['$formats'] || {});
72
74
  this.attributes = new RegistryStore(w['$attributes'] || {});
73
75
  }
@@ -76,6 +78,10 @@ export class Registry extends EventDispatcher {
76
78
  return register('classes', key, setup);
77
79
  }
78
80
 
81
+ public static controller(key: string = null, setup = null) {
82
+ return register('classes', key, setup);
83
+ }
84
+
79
85
  public static model(key: string = null, setup = null) {
80
86
  return register('models', key, setup);
81
87
  }
@@ -88,6 +94,10 @@ export class Registry extends EventDispatcher {
88
94
  return register('types', key, setup);
89
95
  }
90
96
 
97
+ public static validator(key: string = null, setup = null) {
98
+ return register('validators', key, setup);
99
+ }
100
+
91
101
  public static format(key: string = null, setup = null) {
92
102
  return register('formats', key, setup);
93
103
  }
@@ -0,0 +1,29 @@
1
+ import {IScopeData, ScopeDataAbstract} from "./ScopeDataAbstract";
2
+
3
+ export class DynamicScopeData extends ScopeDataAbstract {
4
+ constructor(data: IScopeData | string[]) {
5
+ super();
6
+ if(data instanceof Array) {
7
+ this.__properties__ = data;
8
+ for (const field of data)
9
+ this.createProperty(field);
10
+ } else {
11
+ this.setData(data);
12
+ }
13
+ }
14
+
15
+ setData(data: IScopeData) {
16
+ for(const field of Object.keys(data))
17
+ if(this.__properties__.indexOf(field) == -1) {
18
+ this.__properties__.push(field);
19
+ this.createProperty(field);
20
+ }
21
+ super.setData(data);
22
+ }
23
+
24
+ on(event: string, fct: (...args: any[]) => any, context?: any, once?: boolean): number {
25
+ if(event.indexOf('change:') == 0)
26
+ this.createProperty(event.substr(7));
27
+ return super.on(event, fct, context, once);
28
+ }
29
+ }
@@ -0,0 +1,29 @@
1
+ import {DOM} from "../DOM";
2
+ import {Scope} from "../Scope";
3
+ import {ScopeReference} from "./ScopeReference";
4
+
5
+
6
+ export class QueryReference extends ScopeReference {
7
+ constructor(
8
+ public readonly path: string,
9
+ public readonly scope: Scope
10
+ ) {
11
+ super();
12
+ }
13
+
14
+ public async getScope() {
15
+ let parts: string[] = this.path.split('.');
16
+ parts = parts.splice(0, parts.length - 1);
17
+ const qResult = await DOM.instance.eval(parts.join('.'));
18
+ return qResult.length === 1 ? qResult[0].scope : qResult.map((dobj) => dobj.scope);
19
+ }
20
+
21
+ public async getKey() {
22
+ const parts: string[] = this.path.split('.');
23
+ return parts[parts.length - 1];
24
+ }
25
+
26
+ public async getValue() {
27
+ return await DOM.instance.eval(this.path);
28
+ }
29
+ }
@@ -0,0 +1,21 @@
1
+ import {ScopeDataAbstract} from "./ScopeDataAbstract";
2
+
3
+ export class ScopeData extends ScopeDataAbstract {
4
+ constructor() {
5
+ super();
6
+ const properties = this.__properties__.splice(0, this.__properties__.length);
7
+ for(const property of properties) {
8
+ (function(_self, name) {
9
+ if(!_self['__'+name+'__'])
10
+ return;
11
+
12
+ _self.__properties__.push(name);
13
+ const _property = _self['__'+name+'__'],
14
+ propertyType = _property[0],
15
+ config = _property[1] || {};
16
+
17
+ _self.createProperty(name, propertyType, config);
18
+ })(this, property);
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,126 @@
1
+ import {IPropertyConfig, Property} from "./properties/Property";
2
+ import {EventDispatcher} from "../EventDispatcher";
3
+
4
+ export interface IScopeData {
5
+ [key: string]: any;
6
+ }
7
+
8
+ export class ScopeDataAbstract extends EventDispatcher {
9
+ [key: string]: any;
10
+ __properties__: string[];
11
+ protected _lastData: any;
12
+
13
+ constructor() {
14
+ super();
15
+
16
+ // Objects may have __properties__ from prototype
17
+ if(!this['__properties__'])
18
+ this.__properties__ = [];
19
+ }
20
+
21
+ createProperty(name: string, propertyType = Property, config?: IPropertyConfig): Property {
22
+ config = config || {};
23
+ const instance = new propertyType(config.default, config),
24
+ propDesc = Object.getOwnPropertyDescriptor(this, name);
25
+ this['__'+name] = instance;
26
+
27
+ // property getter
28
+ const propertyGetter = function() {
29
+ return instance.value;
30
+ };
31
+ const getter = propDesc ? propDesc.get : propertyGetter,
32
+ propertySetter = function(newVal: any) {
33
+ instance.value = newVal;
34
+ },
35
+ setter = propDesc ? propDesc.set : propertySetter;
36
+
37
+ // Delete the original property
38
+ delete this[name];
39
+
40
+ // Create new property with getter and setter
41
+ Object.defineProperty(this, name, {
42
+ get: getter,
43
+ set: setter,
44
+ enumerable: true,
45
+ configurable: true
46
+ });
47
+
48
+ instance.on('change', (...args: any[]) => {
49
+ this.dispatch('change', name, ...args);
50
+ this.dispatch('change:' + name, ...args);
51
+ });
52
+ return instance;
53
+ }
54
+
55
+ hasProperty(name: string): boolean {
56
+ return this.__properties__.indexOf(name) !== -1;
57
+ }
58
+
59
+ get keys(): string[] {
60
+ return [...this.__properties__];
61
+ }
62
+
63
+ setData(data: IScopeData) {
64
+ const properties = this.getProperties();
65
+ for (const key in data) {
66
+ if (properties.indexOf(key) > -1) {
67
+ this[key] = data[key];
68
+ }
69
+ }
70
+ }
71
+
72
+ getData(): IScopeData {
73
+ const data: IScopeData = {};
74
+ for (const key of this.getProperties()) {
75
+ const property = this['__'+key];
76
+ if(this[key] == null || !property)
77
+ continue;
78
+
79
+ data[key] = property.getData();
80
+ }
81
+ return data;
82
+ }
83
+
84
+ getProperties(): string[] {
85
+ return this.__properties__;
86
+ }
87
+
88
+ getProperty(name: string, create: boolean = false): Property {
89
+ let property = this['__'+name];
90
+ if (create && !property) {
91
+ property = this.createProperty(name);
92
+ }
93
+ return property;
94
+ }
95
+
96
+ bindToProperties(event:string, properties:string[], callback: (...args: any[]) => any) {
97
+ for(const name of properties) {
98
+ const _property = this['__'+ name];
99
+ if(_property)
100
+ _property.on(event, callback);
101
+
102
+ }
103
+ }
104
+
105
+ setLastData() {
106
+ this._lastData = this.getData();
107
+ }
108
+
109
+ /*
110
+ * Revert data to the last setData() call. Useful for forms that edit a
111
+ * list of items and then hit cancel rather than saving the list.
112
+ */
113
+ revert() {
114
+ this.setData(this._lastData);
115
+ }
116
+
117
+ isModified() {
118
+ const oData = this._lastData,
119
+ nData = this.getData();
120
+ for(const key of this.getProperties()) {
121
+ if(nData[key] != oData[key])
122
+ return true;
123
+ }
124
+ return false;
125
+ }
126
+ }
@@ -0,0 +1,30 @@
1
+ import {Scope} from "../Scope";
2
+
3
+
4
+ export class ScopeReference {
5
+ private _scope: Scope;
6
+ private _key: string;
7
+ private _value: any;
8
+
9
+ constructor(
10
+ scope: Scope = null,
11
+ key: string = null,
12
+ value: any = null
13
+ ) {
14
+ this._scope = scope;
15
+ this._key = key;
16
+ this._value = value;
17
+ }
18
+
19
+ public async getScope() {
20
+ return this._scope;
21
+ }
22
+
23
+ public async getKey() {
24
+ return this._key;
25
+ }
26
+
27
+ public async getValue() {
28
+ return this._value;
29
+ }
30
+ }