@ibyar/core 0.5.6 → 0.6.1

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 (80) hide show
  1. package/annotation/decorators.d.ts +121 -0
  2. package/annotation/decorators.js.map +1 -1
  3. package/binding/binding.expressions.d.ts +9 -4
  4. package/binding/binding.expressions.js +10 -15
  5. package/binding/binding.expressions.js.map +1 -1
  6. package/component/component.d.ts +3 -0
  7. package/component/component.js +1 -0
  8. package/component/component.js.map +1 -1
  9. package/component/custom-element.d.ts +48 -4
  10. package/component/custom-element.js.map +1 -1
  11. package/component/events.js +2 -6
  12. package/component/events.js.map +1 -1
  13. package/context/stack.js +4 -0
  14. package/context/stack.js.map +1 -1
  15. package/directive/directive.d.ts +9 -0
  16. package/directive/directive.js +9 -0
  17. package/directive/directive.js.map +1 -1
  18. package/directive/parser.d.ts +4 -0
  19. package/directive/parser.js +19 -0
  20. package/directive/parser.js.map +1 -1
  21. package/directive/providers.js +3 -3
  22. package/directive/providers.js.map +1 -1
  23. package/html/expression.d.ts +5 -0
  24. package/html/expression.js +13 -1
  25. package/html/expression.js.map +1 -1
  26. package/index.d.ts +4 -0
  27. package/index.js +4 -0
  28. package/index.js.map +1 -1
  29. package/linker/change-detector-ref.d.ts +25 -2
  30. package/linker/change-detector-ref.js +30 -18
  31. package/linker/change-detector-ref.js.map +1 -1
  32. package/linker/template-ref.d.ts +17 -5
  33. package/linker/template-ref.js +23 -20
  34. package/linker/template-ref.js.map +1 -1
  35. package/linker/view-container-ref.d.ts +140 -8
  36. package/linker/view-container-ref.js +82 -31
  37. package/linker/view-container-ref.js.map +1 -1
  38. package/linker/view-ref.d.ts +49 -5
  39. package/linker/view-ref.js +23 -9
  40. package/linker/view-ref.js.map +1 -1
  41. package/package.json +9 -5
  42. package/pipe/pipe.d.ts +7 -0
  43. package/pipe/pipe.js +4 -4
  44. package/pipe/pipe.js.map +1 -1
  45. package/providers/injector.js +1 -0
  46. package/providers/injector.js.map +1 -1
  47. package/render/host-listener.handler.d.ts +17 -0
  48. package/render/host-listener.handler.js +20 -3
  49. package/render/host-listener.handler.js.map +1 -1
  50. package/render/render-handler.d.ts +6 -0
  51. package/utils/typeof.d.ts +3 -0
  52. package/utils/utils.js +1 -0
  53. package/utils/utils.js.map +1 -1
  54. package/view/base-view.js +56 -19
  55. package/view/base-view.js.map +1 -1
  56. package/view/form-view.js +21 -0
  57. package/view/form-view.js.map +1 -1
  58. package/view/mutation.js +1 -0
  59. package/view/mutation.js.map +1 -1
  60. package/view/render.d.ts +9 -9
  61. package/view/render.js +38 -29
  62. package/view/render.js.map +1 -1
  63. package/view/view.d.ts +5 -0
  64. package/view/view.js +7 -0
  65. package/view/view.js.map +1 -1
  66. package/zone/bootstrap.d.ts +21 -0
  67. package/zone/bootstrap.js +35 -0
  68. package/zone/bootstrap.js.map +1 -0
  69. package/zone/proxy.d.ts +15 -0
  70. package/zone/proxy.js +41 -0
  71. package/zone/proxy.js.map +1 -0
  72. package/zone/task.d.ts +61 -0
  73. package/zone/task.js +109 -0
  74. package/zone/task.js.map +1 -0
  75. package/zone/zone.d.ts +51 -0
  76. package/zone/zone.js +193 -0
  77. package/zone/zone.js.map +1 -0
  78. package/component/provider.d.ts +0 -10
  79. package/component/provider.js +0 -17
  80. package/component/provider.js.map +0 -1
@@ -1,27 +1,67 @@
1
- import { ScopeContext, ScopeSubscription } from '@ibyar/expressions';
2
- export declare abstract class ViewRef {
1
+ import { ReactiveScopeControl, Context, ScopeSubscription } from '@ibyar/expressions';
2
+ import { ChangeDetectorRef } from './change-detector-ref.js';
3
+ export declare abstract class ViewRef extends ChangeDetectorRef {
4
+ /**
5
+ * Destroys this view and all of the data structures associated with it.
6
+ */
3
7
  abstract destroy(): void;
8
+ /**
9
+ * Reports whether this view has been destroyed.
10
+ * @returns True after the `destroy()` method has been called, false otherwise.
11
+ */
4
12
  abstract get destroyed(): boolean;
13
+ /**
14
+ * A lifecycle hook that provides additional developer-defined cleanup
15
+ * functionality for views.
16
+ * @param callback A handler function that cleans up developer-defined data
17
+ * associated with a view. Called when the `destroy()` method is invoked.
18
+ */
5
19
  abstract onDestroy(callback: Function): {
6
20
  unsubscribe(): void;
7
21
  };
8
22
  }
9
23
  export declare abstract class EmbeddedViewRef<C extends object> extends ViewRef {
24
+ /**
25
+ * The context for this view, inherited from the anchor element.
26
+ */
10
27
  abstract get context(): C;
28
+ /**
29
+ * The root nodes for this embedded view.
30
+ */
11
31
  abstract get rootNodes(): Node[];
32
+ /**
33
+ * the first node for this embedded view.
34
+ */
12
35
  abstract get first(): ChildNode;
36
+ /**
37
+ * the last node for this embedded view.
38
+ */
13
39
  abstract get last(): ChildNode;
40
+ /**
41
+ * insert view after the node.
42
+ * @param node
43
+ */
14
44
  abstract after(node: ChildNode): void;
45
+ /**
46
+ * insert view before the node.
47
+ * @param node
48
+ */
15
49
  abstract before(node: ChildNode): void;
50
+ /**
51
+ * remove the root nodes from the view, but keep reference to them.
52
+ *
53
+ * Detaches a view from this container without destroying it.
54
+ * Use along with after()/before() to move a view within the current container.
55
+ */
16
56
  abstract detach(): void;
17
57
  }
18
58
  export declare class EmbeddedViewRefImpl<C extends object> extends EmbeddedViewRef<C> {
19
- private _context;
59
+ private _scope;
20
60
  private _rootNodes;
21
61
  private _subscriptions?;
22
62
  private _destroyed;
23
- private onDestroySubscribes;
24
- constructor(_context: C, _rootNodes: Node[], _subscriptions?: ScopeSubscription<ScopeContext>[] | undefined);
63
+ private _onDestroySubscribes;
64
+ constructor(_scope: ReactiveScopeControl<C>, _rootNodes: Node[], _subscriptions?: ScopeSubscription<Context>[] | undefined);
25
65
  get context(): C;
26
66
  get rootNodes(): Node[];
27
67
  get first(): Element;
@@ -32,6 +72,10 @@ export declare class EmbeddedViewRefImpl<C extends object> extends EmbeddedViewR
32
72
  after(node: ChildNode): void;
33
73
  before(node: ChildNode): void;
34
74
  detach(): void;
75
+ reattach(): void;
76
+ markForCheck(): void;
77
+ detectChanges(): void;
78
+ checkNoChanges(): void;
35
79
  onDestroy(callback: () => void): {
36
80
  unsubscribe(): void;
37
81
  };
@@ -1,18 +1,19 @@
1
- export class ViewRef {
1
+ import { ChangeDetectorRef } from './change-detector-ref.js';
2
+ export class ViewRef extends ChangeDetectorRef {
2
3
  }
3
4
  export class EmbeddedViewRef extends ViewRef {
4
5
  }
5
6
  export class EmbeddedViewRefImpl extends EmbeddedViewRef {
6
- constructor(_context, _rootNodes, _subscriptions) {
7
+ constructor(_scope, _rootNodes, _subscriptions) {
7
8
  super();
8
- this._context = _context;
9
+ this._scope = _scope;
9
10
  this._rootNodes = _rootNodes;
10
11
  this._subscriptions = _subscriptions;
11
12
  this._destroyed = false;
12
- this.onDestroySubscribes = [];
13
+ this._onDestroySubscribes = [];
13
14
  }
14
15
  get context() {
15
- return this._context;
16
+ return this._scope.getContext();
16
17
  }
17
18
  get rootNodes() {
18
19
  return this._rootNodes;
@@ -33,7 +34,7 @@ export class EmbeddedViewRefImpl extends EmbeddedViewRef {
33
34
  for (const node of this._rootNodes) {
34
35
  node.remove();
35
36
  }
36
- this.onDestroySubscribes.forEach(callback => {
37
+ this._onDestroySubscribes.forEach(callback => {
37
38
  try {
38
39
  callback();
39
40
  }
@@ -62,14 +63,27 @@ export class EmbeddedViewRefImpl extends EmbeddedViewRef {
62
63
  for (const node of this._rootNodes) {
63
64
  node.remove();
64
65
  }
66
+ this._scope.detach();
67
+ }
68
+ reattach() {
69
+ this._scope.emitChanges();
70
+ }
71
+ markForCheck() {
72
+ this._scope.emitChanges();
73
+ }
74
+ detectChanges() {
75
+ this._scope.detectChanges();
76
+ }
77
+ checkNoChanges() {
78
+ this._scope.checkNoChanges();
65
79
  }
66
80
  onDestroy(callback) {
67
- this.onDestroySubscribes.push(callback);
81
+ this._onDestroySubscribes.push(callback);
68
82
  return {
69
83
  unsubscribe: () => {
70
- const index = this.onDestroySubscribes.indexOf(callback);
84
+ const index = this._onDestroySubscribes.indexOf(callback);
71
85
  if (index > -1) {
72
- this.onDestroySubscribes.splice(index, 1);
86
+ this._onDestroySubscribes.splice(index, 1);
73
87
  }
74
88
  }
75
89
  };
@@ -1 +1 @@
1
- {"version":3,"file":"view-ref.js","sourceRoot":"","sources":["../../../src/core/linker/view-ref.ts"],"names":[],"mappings":"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","sourcesContent":["import { ScopeContext, ScopeSubscription } from '@ibyar/expressions';\n\nexport abstract class ViewRef {\n\t/**\n\t * Destroys this view and all of the data structures associated with it.\n\t */\n\tabstract destroy(): void;\n\n\t/**\n\t * Reports whether this view has been destroyed.\n\t * @returns True after the `destroy()` method has been called, false otherwise.\n\t */\n\tabstract get destroyed(): boolean;\n\n\t/**\n\t * A lifecycle hook that provides additional developer-defined cleanup\n\t * functionality for views.\n\t * @param callback A handler function that cleans up developer-defined data\n\t * associated with a view. Called when the `destroy()` method is invoked.\n\t */\n\tabstract onDestroy(callback: Function): { unsubscribe(): void };\n}\n\n\nexport abstract class EmbeddedViewRef<C extends object> extends ViewRef {\n\t/**\n\t * The context for this view, inherited from the anchor element.\n\t */\n\tabstract get context(): C;\n\n\t/**\n\t * The root nodes for this embedded view.\n\t */\n\tabstract get rootNodes(): Node[];\n\n\t/**\n\t * the first node for this embedded view.\n\t */\n\tabstract get first(): ChildNode;\n\n\t/**\n\t * the last node for this embedded view.\n\t */\n\tabstract get last(): ChildNode;\n\n\t/**\n\t * insert view after the node.\n\t * @param node \n\t */\n\tabstract after(node: ChildNode): void;\n\n\t/**\n\t * insert view before the node.\n\t * @param node \n\t */\n\tabstract before(node: ChildNode): void;\n\n\t/**\n\t * remove the root nodes from the view, but keep reference to them.\n\t * \n\t * Detaches a view from this container without destroying it.\n\t * Use along with after()/before() to move a view within the current container.\n\t */\n\tabstract detach(): void;\n}\n\nexport class EmbeddedViewRefImpl<C extends object> extends EmbeddedViewRef<C> {\n\n\tprivate _destroyed: boolean = false;\n\tprivate onDestroySubscribes: (() => void)[] = [];\n\n\tconstructor(\n\t\tprivate _context: C,\n\t\tprivate _rootNodes: Node[],\n\t\tprivate _subscriptions?: ScopeSubscription<ScopeContext>[]) {\n\t\tsuper();\n\t}\n\n\tget context(): C {\n\t\treturn this._context;\n\t}\n\n\tget rootNodes(): Node[] {\n\t\treturn this._rootNodes;\n\t}\n\tget first(): Element {\n\t\treturn this._rootNodes[0] as Element;\n\t}\n\tget last(): Element {\n\t\treturn this._rootNodes[this._rootNodes.length - 1] as Element;\n\t}\n\tget destroyed(): boolean {\n\t\treturn this._destroyed;\n\t}\n\tdestroy(): void {\n\t\tif (!this._destroyed) {\n\t\t\tthis._subscriptions?.forEach(sub => sub.unsubscribe());\n\t\t\tthis._subscriptions?.splice(0, this._subscriptions.length);\n\t\t\tfor (const node of this._rootNodes) {\n\t\t\t\t(<Element>node).remove();\n\t\t\t}\n\t\t\tthis.onDestroySubscribes.forEach(callback => {\n\t\t\t\ttry {\n\t\t\t\t\tcallback();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(error);\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis._destroyed = true;\n\t\t}\n\t}\n\tprivate getAsANode() {\n\t\tif (this._rootNodes.length == 1) {\n\t\t\treturn this._rootNodes[0];\n\t\t}\n\t\tconst fragment = document.createDocumentFragment();\n\t\tthis._rootNodes.forEach(node => fragment.append(node));\n\t\treturn fragment;\n\t}\n\tafter(node: ChildNode): void {\n\t\tnode.after(this.getAsANode());\n\t}\n\tbefore(node: ChildNode): void {\n\t\tnode.before(this.getAsANode());\n\t}\n\tdetach(): void {\n\t\tfor (const node of this._rootNodes) {\n\t\t\t(<Element>node).remove();\n\t\t}\n\t}\n\tonDestroy(callback: () => void): { unsubscribe(): void; } {\n\t\tthis.onDestroySubscribes.push(callback);\n\t\treturn {\n\t\t\tunsubscribe: () => {\n\t\t\t\tconst index = this.onDestroySubscribes.indexOf(callback);\n\t\t\t\tif (index > -1) {\n\t\t\t\t\tthis.onDestroySubscribes.splice(index, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n}\n"]}
1
+ {"version":3,"file":"view-ref.js","sourceRoot":"","sources":["../../../src/core/linker/view-ref.ts"],"names":[],"mappings":"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","sourcesContent":["import { ReactiveScopeControl, Context, ScopeSubscription } from '@ibyar/expressions';\nimport { ChangeDetectorRef } from './change-detector-ref.js';\n\nexport abstract class ViewRef extends ChangeDetectorRef {\n\t/**\n\t * Destroys this view and all of the data structures associated with it.\n\t */\n\tabstract destroy(): void;\n\n\t/**\n\t * Reports whether this view has been destroyed.\n\t * @returns True after the `destroy()` method has been called, false otherwise.\n\t */\n\tabstract get destroyed(): boolean;\n\n\t/**\n\t * A lifecycle hook that provides additional developer-defined cleanup\n\t * functionality for views.\n\t * @param callback A handler function that cleans up developer-defined data\n\t * associated with a view. Called when the `destroy()` method is invoked.\n\t */\n\tabstract onDestroy(callback: Function): { unsubscribe(): void };\n}\n\n\nexport abstract class EmbeddedViewRef<C extends object> extends ViewRef {\n\t/**\n\t * The context for this view, inherited from the anchor element.\n\t */\n\tabstract get context(): C;\n\n\t/**\n\t * The root nodes for this embedded view.\n\t */\n\tabstract get rootNodes(): Node[];\n\n\t/**\n\t * the first node for this embedded view.\n\t */\n\tabstract get first(): ChildNode;\n\n\t/**\n\t * the last node for this embedded view.\n\t */\n\tabstract get last(): ChildNode;\n\n\t/**\n\t * insert view after the node.\n\t * @param node \n\t */\n\tabstract after(node: ChildNode): void;\n\n\t/**\n\t * insert view before the node.\n\t * @param node \n\t */\n\tabstract before(node: ChildNode): void;\n\n\t/**\n\t * remove the root nodes from the view, but keep reference to them.\n\t * \n\t * Detaches a view from this container without destroying it.\n\t * Use along with after()/before() to move a view within the current container.\n\t */\n\tabstract detach(): void;\n}\n\nexport class EmbeddedViewRefImpl<C extends object> extends EmbeddedViewRef<C> {\n\n\tprivate _destroyed: boolean = false;\n\tprivate _onDestroySubscribes: (() => void)[] = [];\n\n\tconstructor(\n\t\tprivate _scope: ReactiveScopeControl<C>,\n\t\tprivate _rootNodes: Node[],\n\t\tprivate _subscriptions?: ScopeSubscription<Context>[]) {\n\t\tsuper();\n\t}\n\n\tget context(): C {\n\t\treturn this._scope.getContext();\n\t}\n\n\tget rootNodes(): Node[] {\n\t\treturn this._rootNodes;\n\t}\n\tget first(): Element {\n\t\treturn this._rootNodes[0] as Element;\n\t}\n\tget last(): Element {\n\t\treturn this._rootNodes[this._rootNodes.length - 1] as Element;\n\t}\n\tget destroyed(): boolean {\n\t\treturn this._destroyed;\n\t}\n\tdestroy(): void {\n\t\tif (!this._destroyed) {\n\t\t\tthis._subscriptions?.forEach(sub => sub.unsubscribe());\n\t\t\tthis._subscriptions?.splice(0, this._subscriptions.length);\n\t\t\tfor (const node of this._rootNodes) {\n\t\t\t\t(<Element>node).remove();\n\t\t\t}\n\t\t\tthis._onDestroySubscribes.forEach(callback => {\n\t\t\t\ttry {\n\t\t\t\t\tcallback();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(error);\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis._destroyed = true;\n\t\t}\n\t}\n\tprivate getAsANode() {\n\t\tif (this._rootNodes.length == 1) {\n\t\t\treturn this._rootNodes[0];\n\t\t}\n\t\tconst fragment = document.createDocumentFragment();\n\t\tthis._rootNodes.forEach(node => fragment.append(node));\n\t\treturn fragment;\n\t}\n\tafter(node: ChildNode): void {\n\t\tnode.after(this.getAsANode());\n\t}\n\tbefore(node: ChildNode): void {\n\t\tnode.before(this.getAsANode());\n\t}\n\tdetach(): void {\n\t\tfor (const node of this._rootNodes) {\n\t\t\t(<Element>node).remove();\n\t\t}\n\t\tthis._scope.detach();\n\t}\n\treattach(): void {\n\t\tthis._scope.emitChanges();\n\t}\n\tmarkForCheck(): void {\n\t\tthis._scope.emitChanges();\n\t}\n\tdetectChanges(): void {\n\t\tthis._scope.detectChanges();\n\t}\n\tcheckNoChanges(): void {\n\t\tthis._scope.checkNoChanges();\n\t}\n\tonDestroy(callback: () => void): { unsubscribe(): void; } {\n\t\tthis._onDestroySubscribes.push(callback);\n\t\treturn {\n\t\t\tunsubscribe: () => {\n\t\t\t\tconst index = this._onDestroySubscribes.indexOf(callback);\n\t\t\t\tif (index > -1) {\n\t\t\t\t\tthis._onDestroySubscribes.splice(index, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ibyar/core",
3
- "version": "0.5.6",
3
+ "version": "0.6.1",
4
4
  "description": "Implements Aurora's core functionality, low-level services, and utilities",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/ibyar/aurora/tree/dev/packages/core",
@@ -23,11 +23,14 @@
23
23
  "access": "public"
24
24
  },
25
25
  "dependencies": {
26
- "@ibyar/elements": "^0.5.6",
27
- "@ibyar/expressions": "^0.5.6",
26
+ "@ibyar/elements": "^0.6.1",
27
+ "@ibyar/expressions": "^0.6.1",
28
28
  "reflect-metadata": "^0.1.13",
29
29
  "tslib": "^2.4.0"
30
30
  },
31
+ "peerDependencies": {
32
+ "zone.js": "^0.11.6"
33
+ },
31
34
  "devDependencies": {
32
35
  "typescript": "^4.7.4"
33
36
  },
@@ -60,7 +63,8 @@
60
63
  "elements-info",
61
64
  "element",
62
65
  "interceptor",
63
- "typescript"
66
+ "typescript",
67
+ "front-end"
64
68
  ],
65
- "gitHead": "1e724c041319c2cfab7f9b21f6246cd658b8c3c3"
69
+ "gitHead": "b2375dc0a3d6fea0231a3d91eb65f38a457e2a1e"
66
70
  }
package/pipe/pipe.d.ts CHANGED
@@ -2,6 +2,13 @@ import { ReactiveScopeControl, ReadOnlyScope, ScopeSubscription } from '@ibyar/e
2
2
  import { OnDestroy } from '../component/lifecycle.js';
3
3
  import { ChangeDetectorRef } from '../linker/change-detector-ref.js';
4
4
  import { TypeOf } from '../utils/typeof.js';
5
+ /**
6
+ * Pipes are used as singleton
7
+ * it will be created if it needed, had no life cycle
8
+ *
9
+ * * no dependency injection applied on filters for now,
10
+ * TODO: add support of dependency injection
11
+ */
5
12
  export interface PipeTransform<T, U> {
6
13
  transform(value: T, ...args: any[]): U;
7
14
  }
package/pipe/pipe.js CHANGED
@@ -14,7 +14,7 @@ export class PipeProvider extends ReadOnlyScope {
14
14
  super({});
15
15
  }
16
16
  has(pipeName) {
17
- if (pipeName in this.context) {
17
+ if (pipeName in this._ctx) {
18
18
  return true;
19
19
  }
20
20
  const pipeRef = ClassRegistryProvider.getPipe(pipeName);
@@ -22,14 +22,14 @@ export class PipeProvider extends ReadOnlyScope {
22
22
  }
23
23
  get(pipeName) {
24
24
  let transformFunc;
25
- if (transformFunc = this.context[pipeName]) {
25
+ if (transformFunc = this._ctx[pipeName]) {
26
26
  return transformFunc;
27
27
  }
28
28
  const pipeRef = ClassRegistryProvider.getPipe(pipeName);
29
29
  if (pipeRef !== undefined && !pipeRef.asynchronous) {
30
30
  const pipe = new pipeRef.modelClass();
31
31
  transformFunc = (value, ...args) => pipe.transform(value, ...args);
32
- this.context[pipeRef.name] = transformFunc;
32
+ this._ctx[pipeRef.name] = transformFunc;
33
33
  return transformFunc;
34
34
  }
35
35
  return void 0;
@@ -81,7 +81,7 @@ export class AsyncPipeScope extends ReactiveScopeControl {
81
81
  }
82
82
  unsubscribe(propertyKey, subscription) {
83
83
  super.unsubscribe(propertyKey, subscription);
84
- const pipe = this.context[propertyKey];
84
+ const pipe = this._ctx[propertyKey];
85
85
  pipe.onDestroy();
86
86
  }
87
87
  getClass() {
package/pipe/pipe.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"pipe.js","sourceRoot":"","sources":["../../../src/core/pipe/pipe.ts"],"names":[],"mappings":"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","sourcesContent":["import { ReactiveScopeControl, ReadOnlyScope, ScopeSubscription } from '@ibyar/expressions';\nimport { OnDestroy } from '../component/lifecycle.js';\nimport { ChangeDetectorRef, createChangeDetectorRef } from '../linker/change-detector-ref.js';\nimport { ClassRegistryProvider } from '../providers/provider.js';\nimport { TypeOf } from '../utils/typeof.js';\n\n/**\n * Pipes are used as singleton\n * it will be created if it needed, had no life cycle\n * \n * * no dependency injection applied on filters for now,\n * TODO: add support of dependency injection\n */\nexport interface PipeTransform<T, U> {\n\ttransform(value: T, ...args: any[]): U;\n}\n\nexport abstract class AsyncPipeTransform<T, U> implements PipeTransform<T, U>, OnDestroy {\n\tconstructor(protected changeDetectorRef: ChangeDetectorRef) { }\n\tabstract transform(value: T, ...args: any[]): U;\n\tabstract onDestroy(): void;\n}\n\nexport function isPipeTransform<T extends any, U extends any>(pipe: any): pipe is PipeTransform<T, U> {\n\treturn Reflect.has(Object.getPrototypeOf(pipe), 'transform');\n}\n\nexport class PipeProvider extends ReadOnlyScope<{ [pipeName: string]: Function }> {\n\tconstructor() {\n\t\tsuper({});\n\t}\n\thas(pipeName: string): boolean {\n\t\tif (pipeName in this.context) {\n\t\t\treturn true;\n\t\t}\n\t\tconst pipeRef = ClassRegistryProvider.getPipe<PipeTransform<any, any>>(pipeName);\n\t\treturn pipeRef !== undefined && !pipeRef.asynchronous;\n\t}\n\tget(pipeName: string): any {\n\t\tlet transformFunc: Function | undefined;\n\t\tif (transformFunc = this.context[pipeName]) {\n\t\t\treturn transformFunc;\n\t\t}\n\t\tconst pipeRef = ClassRegistryProvider.getPipe<PipeTransform<any, any>>(pipeName);\n\t\tif (pipeRef !== undefined && !pipeRef.asynchronous) {\n\t\t\tconst pipe = new pipeRef.modelClass();\n\t\t\ttransformFunc = (value: any, ...args: any[]) => pipe.transform(value, ...args);\n\t\t\tthis.context[pipeRef.name] = transformFunc;\n\t\t\treturn transformFunc;\n\t\t}\n\t\treturn void 0;\n\t}\n\tgetClass(): TypeOf<PipeProvider> {\n\t\treturn PipeProvider;\n\t}\n}\n\nexport class AsyncPipeProvider extends ReadOnlyScope<object> {\n\tconstructor() {\n\t\tsuper({});\n\t}\n\thas(pipeName: string): boolean {\n\t\tconst pipeRef = ClassRegistryProvider.getPipe<AsyncPipeTransform<any, any>>(pipeName);\n\t\treturn pipeRef?.asynchronous ? true : false;\n\t}\n\tget(pipeName: string): TypeOf<AsyncPipeTransform<any, any>> | undefined {\n\t\tconst pipeRef = ClassRegistryProvider.getPipe<AsyncPipeTransform<any, any>>(pipeName);\n\t\tif (pipeRef?.asynchronous) {\n\t\t\treturn pipeRef.modelClass;\n\t\t}\n\t\treturn;\n\t}\n\tgetClass(): TypeOf<AsyncPipeProvider> {\n\t\treturn AsyncPipeProvider;\n\t}\n}\n\nexport class AsyncPipeScope<T extends { [key: string]: AsyncPipeTransform<any, any> }> extends ReactiveScopeControl<T> {\n\tstatic blockScope<P extends { [key: string]: AsyncPipeTransform<any, any> }>(): AsyncPipeScope<P> {\n\t\treturn new AsyncPipeScope();\n\t}\n\tprivate wrapper: { [key: string]: Function } = {};\n\tconstructor() {\n\t\tsuper({} as T);\n\t}\n\toverride set(propertyKey: keyof T, pipeClass: TypeOf<AsyncPipeTransform<any, any>>, receiver?: any): boolean {\n\t\tconst detector = createChangeDetectorRef(this, propertyKey);\n\t\tconst pipe = new pipeClass(detector);\n\t\tconst result = super.set(propertyKey, pipe, receiver);\n\t\tif (result) {\n\t\t\tthis.wrapper[propertyKey as string] = (value: any, ...args: any[]) => {\n\t\t\t\treturn pipe.transform(value, ...args)\n\t\t\t};\n\t\t}\n\t\treturn result;\n\t}\n\toverride get(propertyKey: keyof T): any {\n\t\treturn Reflect.get(this.wrapper, propertyKey);\n\t}\n\toverride unsubscribe(propertyKey: keyof T, subscription?: ScopeSubscription<T>) {\n\t\tsuper.unsubscribe(propertyKey, subscription);\n\t\tconst pipe = this.context[propertyKey];\n\t\tpipe.onDestroy();\n\t}\n\tgetClass(): TypeOf<AsyncPipeScope<T>> {\n\t\treturn AsyncPipeScope;\n\t}\n}\n"]}
1
+ {"version":3,"file":"pipe.js","sourceRoot":"","sources":["../../../src/core/pipe/pipe.ts"],"names":[],"mappings":"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","sourcesContent":["import { ReactiveScopeControl, ReadOnlyScope, ScopeSubscription } from '@ibyar/expressions';\nimport { OnDestroy } from '../component/lifecycle.js';\nimport { ChangeDetectorRef, createChangeDetectorRef } from '../linker/change-detector-ref.js';\nimport { ClassRegistryProvider } from '../providers/provider.js';\nimport { TypeOf } from '../utils/typeof.js';\n\n/**\n * Pipes are used as singleton\n * it will be created if it needed, had no life cycle\n * \n * * no dependency injection applied on filters for now,\n * TODO: add support of dependency injection\n */\nexport interface PipeTransform<T, U> {\n\ttransform(value: T, ...args: any[]): U;\n}\n\nexport abstract class AsyncPipeTransform<T, U> implements PipeTransform<T, U>, OnDestroy {\n\tconstructor(protected changeDetectorRef: ChangeDetectorRef) { }\n\tabstract transform(value: T, ...args: any[]): U;\n\tabstract onDestroy(): void;\n}\n\nexport function isPipeTransform<T extends any, U extends any>(pipe: any): pipe is PipeTransform<T, U> {\n\treturn Reflect.has(Object.getPrototypeOf(pipe), 'transform');\n}\n\nexport class PipeProvider extends ReadOnlyScope<{ [pipeName: string]: Function }> {\n\tconstructor() {\n\t\tsuper({});\n\t}\n\thas(pipeName: string): boolean {\n\t\tif (pipeName in this._ctx) {\n\t\t\treturn true;\n\t\t}\n\t\tconst pipeRef = ClassRegistryProvider.getPipe<PipeTransform<any, any>>(pipeName);\n\t\treturn pipeRef !== undefined && !pipeRef.asynchronous;\n\t}\n\tget(pipeName: string): any {\n\t\tlet transformFunc: Function | undefined;\n\t\tif (transformFunc = this._ctx[pipeName]) {\n\t\t\treturn transformFunc;\n\t\t}\n\t\tconst pipeRef = ClassRegistryProvider.getPipe<PipeTransform<any, any>>(pipeName);\n\t\tif (pipeRef !== undefined && !pipeRef.asynchronous) {\n\t\t\tconst pipe = new pipeRef.modelClass();\n\t\t\ttransformFunc = (value: any, ...args: any[]) => pipe.transform(value, ...args);\n\t\t\tthis._ctx[pipeRef.name] = transformFunc;\n\t\t\treturn transformFunc;\n\t\t}\n\t\treturn void 0;\n\t}\n\tgetClass(): TypeOf<PipeProvider> {\n\t\treturn PipeProvider;\n\t}\n}\n\nexport class AsyncPipeProvider extends ReadOnlyScope<object> {\n\tconstructor() {\n\t\tsuper({});\n\t}\n\thas(pipeName: string): boolean {\n\t\tconst pipeRef = ClassRegistryProvider.getPipe<AsyncPipeTransform<any, any>>(pipeName);\n\t\treturn pipeRef?.asynchronous ? true : false;\n\t}\n\tget(pipeName: string): TypeOf<AsyncPipeTransform<any, any>> | undefined {\n\t\tconst pipeRef = ClassRegistryProvider.getPipe<AsyncPipeTransform<any, any>>(pipeName);\n\t\tif (pipeRef?.asynchronous) {\n\t\t\treturn pipeRef.modelClass;\n\t\t}\n\t\treturn;\n\t}\n\tgetClass(): TypeOf<AsyncPipeProvider> {\n\t\treturn AsyncPipeProvider;\n\t}\n}\n\nexport class AsyncPipeScope<T extends { [key: string]: AsyncPipeTransform<any, any> }> extends ReactiveScopeControl<T> {\n\tstatic blockScope<P extends { [key: string]: AsyncPipeTransform<any, any> }>(): AsyncPipeScope<P> {\n\t\treturn new AsyncPipeScope();\n\t}\n\tprivate wrapper: { [key: string]: Function } = {};\n\tconstructor() {\n\t\tsuper({} as T);\n\t}\n\toverride set(propertyKey: keyof T, pipeClass: TypeOf<AsyncPipeTransform<any, any>>, receiver?: any): boolean {\n\t\tconst detector = createChangeDetectorRef(this, propertyKey);\n\t\tconst pipe = new pipeClass(detector);\n\t\tconst result = super.set(propertyKey, pipe, receiver);\n\t\tif (result) {\n\t\t\tthis.wrapper[propertyKey as string] = (value: any, ...args: any[]) => {\n\t\t\t\treturn pipe.transform(value, ...args)\n\t\t\t};\n\t\t}\n\t\treturn result;\n\t}\n\toverride get(propertyKey: keyof T): any {\n\t\treturn Reflect.get(this.wrapper, propertyKey);\n\t}\n\toverride unsubscribe(propertyKey: keyof T, subscription?: ScopeSubscription<T>) {\n\t\tsuper.unsubscribe(propertyKey, subscription);\n\t\tconst pipe = this._ctx[propertyKey];\n\t\tpipe.onDestroy();\n\t}\n\tgetClass(): TypeOf<AsyncPipeScope<T>> {\n\t\treturn AsyncPipeScope;\n\t}\n}\n"]}
@@ -11,6 +11,7 @@ export class Injector {
11
11
  if (currentInstance)
12
12
  return currentInstance;
13
13
  const params = Reflect.getMetadata('design:paramtypes', constructor);
14
+ // We need to init each constructor function into it's instance
14
15
  if (params) {
15
16
  const argumentsInstances = params.map((paramter) => this.constructObject(paramter));
16
17
  currentInstance = new constructor(...argumentsInstances);
@@ -1 +1 @@
1
- {"version":3,"file":"injector.js","sourceRoot":"","sources":["../../../src/core/providers/injector.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,QAAQ;IAIpB;QAFQ,2BAAsB,GAAG,IAAI,GAAG,EAAE,CAAC;IAE3B,CAAC;IAEjB,WAAW,CAAI,KAAuB;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7C,OAAO,QAAQ,CAAC;IACjB,CAAC;IAEO,eAAe,CAAC,WAA0B;QACjD,IAAI,eAAe,GAAG,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACnE,IAAI,eAAe;YAAE,OAAO,eAAe,CAAC;QAE5C,MAAM,MAAM,GACX,OAAO,CAAC,WAAW,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;QAEvD,IAAI,MAAM,EAAE;YACX,MAAM,kBAAkB,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAClD,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAC9B,CAAC;YACF,eAAe,GAAG,IAAI,WAAW,CAAC,GAAG,kBAAkB,CAAC,CAAC;SACzD;aAAM;YACN,eAAe,GAAG,IAAI,WAAW,EAAE,CAAC;SACpC;QACD,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;QAC9D,OAAO,eAAe,CAAC;IACxB,CAAC;CACD;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAa,IAAI,QAAQ,EAAE,CAAC","sourcesContent":["\nexport interface Constructable<T = any> {\n\tnew(...params: any[]): T;\n}\n\nexport class Injector {\n\n\tprivate dependencyInjectionMap = new Map();\n\n\tconstructor() { }\n\n\tgetInstance<T>(contr: Constructable<T>): T {\n\t\tconst instance = this.constructObject(contr);\n\t\treturn instance;\n\t}\n\n\tprivate constructObject(constructor: Constructable) {\n\t\tlet currentInstance = this.dependencyInjectionMap.get(constructor);\n\t\tif (currentInstance) return currentInstance;\n\n\t\tconst params: Constructable[] =\n\t\t\tReflect.getMetadata('design:paramtypes', constructor);\n\t\t// We need to init each constructor function into it's instance\n\t\tif (params) {\n\t\t\tconst argumentsInstances = params.map((paramter) =>\n\t\t\t\tthis.constructObject(paramter)\n\t\t\t);\n\t\t\tcurrentInstance = new constructor(...argumentsInstances);\n\t\t} else {\n\t\t\tcurrentInstance = new constructor();\n\t\t}\n\t\tthis.dependencyInjectionMap.set(constructor, currentInstance);\n\t\treturn currentInstance;\n\t}\n}\n\nexport const dependencyInjector: Injector = new Injector();\n"]}
1
+ {"version":3,"file":"injector.js","sourceRoot":"","sources":["../../../src/core/providers/injector.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,QAAQ;IAIpB;QAFQ,2BAAsB,GAAG,IAAI,GAAG,EAAE,CAAC;IAE3B,CAAC;IAEjB,WAAW,CAAI,KAAuB;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7C,OAAO,QAAQ,CAAC;IACjB,CAAC;IAEO,eAAe,CAAC,WAA0B;QACjD,IAAI,eAAe,GAAG,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACnE,IAAI,eAAe;YAAE,OAAO,eAAe,CAAC;QAE5C,MAAM,MAAM,GACX,OAAO,CAAC,WAAW,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;QACvD,+DAA+D;QAC/D,IAAI,MAAM,EAAE;YACX,MAAM,kBAAkB,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAClD,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAC9B,CAAC;YACF,eAAe,GAAG,IAAI,WAAW,CAAC,GAAG,kBAAkB,CAAC,CAAC;SACzD;aAAM;YACN,eAAe,GAAG,IAAI,WAAW,EAAE,CAAC;SACpC;QACD,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;QAC9D,OAAO,eAAe,CAAC;IACxB,CAAC;CACD;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAa,IAAI,QAAQ,EAAE,CAAC","sourcesContent":["\nexport interface Constructable<T = any> {\n\tnew(...params: any[]): T;\n}\n\nexport class Injector {\n\n\tprivate dependencyInjectionMap = new Map();\n\n\tconstructor() { }\n\n\tgetInstance<T>(contr: Constructable<T>): T {\n\t\tconst instance = this.constructObject(contr);\n\t\treturn instance;\n\t}\n\n\tprivate constructObject(constructor: Constructable) {\n\t\tlet currentInstance = this.dependencyInjectionMap.get(constructor);\n\t\tif (currentInstance) return currentInstance;\n\n\t\tconst params: Constructable[] =\n\t\t\tReflect.getMetadata('design:paramtypes', constructor);\n\t\t// We need to init each constructor function into it's instance\n\t\tif (params) {\n\t\t\tconst argumentsInstances = params.map((paramter) =>\n\t\t\t\tthis.constructObject(paramter)\n\t\t\t);\n\t\t\tcurrentInstance = new constructor(...argumentsInstances);\n\t\t} else {\n\t\t\tcurrentInstance = new constructor();\n\t\t}\n\t\tthis.dependencyInjectionMap.set(constructor, currentInstance);\n\t\treturn currentInstance;\n\t}\n}\n\nexport const dependencyInjector: Injector = new Injector();\n"]}
@@ -5,6 +5,23 @@ import { RenderHandler } from './render-handler.js';
5
5
  declare type ElementScope = {
6
6
  [element: string]: HTMLElement;
7
7
  };
8
+ /**
9
+ * ```ts
10
+ * class View {
11
+ *
12
+ * @HostListener('window:load', ['$event.target', '"load"'])
13
+ * @HostListener('click', ['$event.target', '"click"'])
14
+ * public onClick(target: any, type: string){
15
+ * console.log(target, type);
16
+ * }
17
+ * }
18
+ * ```
19
+ *
20
+ * window.addEventListener('load', $event => listener($event.target, 'load'));
21
+ *
22
+ * view.addEventListener('click', $event => listener($event.target, 'click'));
23
+ *
24
+ */
8
25
  export declare class HostListenerHandler implements RenderHandler {
9
26
  private listenerRef;
10
27
  private element;
@@ -1,16 +1,33 @@
1
1
  import { JavaScriptParser, Stack } from '@ibyar/expressions';
2
+ /**
3
+ * ```ts
4
+ * class View {
5
+ *
6
+ * @HostListener('window:load', ['$event.target', '"load"'])
7
+ * @HostListener('click', ['$event.target', '"click"'])
8
+ * public onClick(target: any, type: string){
9
+ * console.log(target, type);
10
+ * }
11
+ * }
12
+ * ```
13
+ *
14
+ * window.addEventListener('load', $event => listener($event.target, 'load'));
15
+ *
16
+ * view.addEventListener('click', $event => listener($event.target, 'click'));
17
+ *
18
+ */
2
19
  export class HostListenerHandler {
3
20
  constructor(listenerRef, element, elementScope) {
4
21
  this.listenerRef = listenerRef;
5
22
  this.element = element;
6
23
  this.elementScope = elementScope;
7
24
  this.listener = (event) => {
8
- const method = this.element._proxyModel[this.listenerRef.modelCallbackName];
9
- if (typeof method === 'function') {
25
+ const callback = this.element._model[this.listenerRef.modelCallbackName];
26
+ if (typeof callback === 'function') {
10
27
  const eventScope = this.stack.pushBlockScopeFor({ $event: event });
11
28
  const params = this.argumentsExpression.get(this.stack);
12
29
  this.stack.clearTo(eventScope);
13
- method.apply(this.element._proxyModel, params);
30
+ this.element._zone.run(callback, this.element._model, params);
14
31
  typeof event.preventDefault === 'function' && event.preventDefault();
15
32
  }
16
33
  };
@@ -1 +1 @@
1
- {"version":3,"file":"host-listener.handler.js","sourceRoot":"","sources":["../../../src/core/render/host-listener.handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { ArrayExpression, JavaScriptParser, ReactiveScope, ScopeSubscription, Stack } from '@ibyar/expressions';\nimport { ListenerRef } from '../component/component.js';\nimport { HTMLComponent } from '../component/custom-element.js';\nimport { RenderHandler } from './render-handler.js';\n\ntype ElementScope = { [element: string]: HTMLElement };\n\n/**\n * ```ts\n * class View {\n * \n *\t@HostListener('window:load', ['$event.target', '\"load\"'])\n * \t@HostListener('click', ['$event.target', '\"click\"'])\n * \tpublic onClick(target: any, type: string){\n * \t\tconsole.log(target, type);\n * \t}\n * }\n * ```\n * \n * window.addEventListener('load', $event => listener($event.target, 'load'));\n * \n * view.addEventListener('click', $event => listener($event.target, 'click'));\n * \n */\nexport class HostListenerHandler implements RenderHandler {\n\n\tprivate source: HTMLElement | Window;\n\tprivate eventName: string;\n\n\tprivate argumentsExpression: ArrayExpression;\n\tprivate stack: Stack;\n\n\tprivate scopeSubscription?: ScopeSubscription<ElementScope>;\n\n\n\tprivate listener = (event: Event) => {\n\t\tconst method: Function | undefined = this.element._proxyModel[this.listenerRef.modelCallbackName];\n\t\tif (typeof method === 'function') {\n\t\t\tconst eventScope = this.stack.pushBlockScopeFor({ $event: event });\n\t\t\tconst params = this.argumentsExpression.get(this.stack);\n\t\t\tthis.stack.clearTo(eventScope);\n\t\t\tmethod.apply(this.element._proxyModel, params);\n\t\t\ttypeof event.preventDefault === 'function' && event.preventDefault();\n\t\t}\n\t};\n\n\tconstructor(private listenerRef: ListenerRef, private element: HTMLComponent<any>, private elementScope: ReactiveScope<ElementScope>) {\n\t\tthis.stack = new Stack(elementScope);\n\t}\n\tonInit(): void {\n\t\tconst args = this.listenerRef.args ?? [];\n\t\tconst array = `[${args.join(', ')}]`;\n\t\tthis.argumentsExpression = JavaScriptParser.parseScript(array) as ArrayExpression;\n\t\tif (this.listenerRef.eventName.includes(':')) {\n\t\t\tconst [eventSource, eventName] = this.listenerRef.eventName.split(':', 2);\n\t\t\tthis.eventName = eventName;\n\t\t\tif ('window' === eventSource.toLowerCase()) {\n\t\t\t\tthis.source = window;\n\t\t\t} else {\n\t\t\t\tlet source = this.elementScope.get(eventSource) as HTMLElement;\n\t\t\t\tthis.scopeSubscription = this.elementScope.subscribe(eventSource, (newValue: HTMLElement) => {\n\t\t\t\t\tif (source !== newValue) {\n\t\t\t\t\t\tif (source) {\n\t\t\t\t\t\t\tthis.removeEventListener();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (!newValue) {\n\t\t\t\t\t\tthis.removeEventListener();\n\t\t\t\t\t}\n\t\t\t\t\tsource = newValue;\n\t\t\t\t\tthis.addEventListener();\n\t\t\t\t});\n\t\t\t\tthis.source = source;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.eventName = this.listenerRef.eventName;\n\t\t\tthis.source = this.element;\n\t\t}\n\t\tthis.addEventListener();\n\t}\n\n\tprivate addEventListener() {\n\t\tthis.source?.addEventListener(this.eventName, this.listener);\n\t}\n\n\tprivate removeEventListener() {\n\t\tthis.source?.removeEventListener(this.eventName, this.listener);\n\t}\n\n\tonConnect() {\n\t\tthis.scopeSubscription?.resume();\n\t}\n\n\tonDisconnect() {\n\t\tthis.scopeSubscription?.pause();\n\t}\n\n\tonDestroy(): void {\n\t\tthis.scopeSubscription?.unsubscribe();\n\t\tthis.removeEventListener();\n\t}\n\n}\n"]}
1
+ {"version":3,"file":"host-listener.handler.js","sourceRoot":"","sources":["../../../src/core/render/host-listener.handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { ArrayExpression, JavaScriptParser, ReactiveScope, ScopeSubscription, Stack } from '@ibyar/expressions';\nimport { ListenerRef } from '../component/component.js';\nimport { HTMLComponent } from '../component/custom-element.js';\nimport { RenderHandler } from './render-handler.js';\n\ntype ElementScope = { [element: string]: HTMLElement };\n\n/**\n * ```ts\n * class View {\n * \n *\t@HostListener('window:load', ['$event.target', '\"load\"'])\n * \t@HostListener('click', ['$event.target', '\"click\"'])\n * \tpublic onClick(target: any, type: string){\n * \t\tconsole.log(target, type);\n * \t}\n * }\n * ```\n * \n * window.addEventListener('load', $event => listener($event.target, 'load'));\n * \n * view.addEventListener('click', $event => listener($event.target, 'click'));\n * \n */\nexport class HostListenerHandler implements RenderHandler {\n\n\tprivate source: HTMLElement | Window;\n\tprivate eventName: string;\n\n\tprivate argumentsExpression: ArrayExpression;\n\tprivate stack: Stack;\n\n\tprivate scopeSubscription?: ScopeSubscription<ElementScope>;\n\n\n\tprivate listener = (event: Event) => {\n\t\tconst callback: Function | undefined = this.element._model[this.listenerRef.modelCallbackName];\n\t\tif (typeof callback === 'function') {\n\t\t\tconst eventScope = this.stack.pushBlockScopeFor({ $event: event });\n\t\t\tconst params = this.argumentsExpression.get(this.stack);\n\t\t\tthis.stack.clearTo(eventScope);\n\t\t\tthis.element._zone.run(\n\t\t\t\tcallback as () => void,\n\t\t\t\tthis.element._model,\n\t\t\t\tparams\n\t\t\t);\n\t\t\ttypeof event.preventDefault === 'function' && event.preventDefault();\n\t\t}\n\t};\n\n\tconstructor(private listenerRef: ListenerRef, private element: HTMLComponent<any>, private elementScope: ReactiveScope<ElementScope>) {\n\t\tthis.stack = new Stack(elementScope);\n\t}\n\tonInit(): void {\n\t\tconst args = this.listenerRef.args ?? [];\n\t\tconst array = `[${args.join(', ')}]`;\n\t\tthis.argumentsExpression = JavaScriptParser.parseScript(array) as ArrayExpression;\n\t\tif (this.listenerRef.eventName.includes(':')) {\n\t\t\tconst [eventSource, eventName] = this.listenerRef.eventName.split(':', 2);\n\t\t\tthis.eventName = eventName;\n\t\t\tif ('window' === eventSource.toLowerCase()) {\n\t\t\t\tthis.source = window;\n\t\t\t} else {\n\t\t\t\tlet source = this.elementScope.get(eventSource) as HTMLElement;\n\t\t\t\tthis.scopeSubscription = this.elementScope.subscribe(eventSource, (newValue: HTMLElement) => {\n\t\t\t\t\tif (source !== newValue) {\n\t\t\t\t\t\tif (source) {\n\t\t\t\t\t\t\tthis.removeEventListener();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (!newValue) {\n\t\t\t\t\t\tthis.removeEventListener();\n\t\t\t\t\t}\n\t\t\t\t\tsource = newValue;\n\t\t\t\t\tthis.addEventListener();\n\t\t\t\t});\n\t\t\t\tthis.source = source;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.eventName = this.listenerRef.eventName;\n\t\t\tthis.source = this.element;\n\t\t}\n\t\tthis.addEventListener();\n\t}\n\n\tprivate addEventListener() {\n\t\tthis.source?.addEventListener(this.eventName, this.listener);\n\t}\n\n\tprivate removeEventListener() {\n\t\tthis.source?.removeEventListener(this.eventName, this.listener);\n\t}\n\n\tonConnect() {\n\t\tthis.scopeSubscription?.resume();\n\t}\n\n\tonDisconnect() {\n\t\tthis.scopeSubscription?.pause();\n\t}\n\n\tonDestroy(): void {\n\t\tthis.scopeSubscription?.unsubscribe();\n\t\tthis.removeEventListener();\n\t}\n\n}\n"]}
@@ -1,5 +1,11 @@
1
1
  import { OnDestroy, OnInit } from '../component/lifecycle.js';
2
2
  export interface RenderHandler extends Partial<OnInit>, Partial<OnDestroy> {
3
+ /**
4
+ * execute when element attached to parent from ui
5
+ */
3
6
  onConnect?(): void;
7
+ /**
8
+ * execute when element disconnected from ui
9
+ */
4
10
  onDisconnect?(): void;
5
11
  }
package/utils/typeof.d.ts CHANGED
@@ -1,3 +1,6 @@
1
+ /**
2
+ * send the class itself, not instance
3
+ */
1
4
  export interface TypeOf<T> extends Function {
2
5
  new (...values: any): T;
3
6
  }
package/utils/utils.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export function ToCamelCase(str) {
2
2
  return str.replace(/([A-Z])/g, ' $1')
3
+ // uppercase the first character
3
4
  .replace(/^./, function (str) { return str.toUpperCase(); })
4
5
  .replace(/ /g, '');
5
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/core/utils/utils.ts"],"names":[],"mappings":"AACA,MAAM,UAAU,WAAW,CAAC,GAAW;IACtC,OAAO,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC;SAEnC,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;SAC3D,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AACrB,CAAC","sourcesContent":["\nexport function ToCamelCase(str: string) {\n\treturn str.replace(/([A-Z])/g, ' $1')\n\t\t// uppercase the first character\n\t\t.replace(/^./, function (str) { return str.toUpperCase(); })\n\t\t.replace(/ /g, '');\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/core/utils/utils.ts"],"names":[],"mappings":"AACA,MAAM,UAAU,WAAW,CAAC,GAAW;IACtC,OAAO,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC;QACpC,gCAAgC;SAC/B,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;SAC3D,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AACrB,CAAC","sourcesContent":["\nexport function ToCamelCase(str: string) {\n\treturn str.replace(/([A-Z])/g, ' $1')\n\t\t// uppercase the first character\n\t\t.replace(/^./, function (str) { return str.toUpperCase(); })\n\t\t.replace(/ /g, '');\n}\n"]}
package/view/base-view.js CHANGED
@@ -1,7 +1,10 @@
1
- import { ReactiveScope } from '@ibyar/expressions';
1
+ import { ReactiveScope, ReactiveScopeControl } from '@ibyar/expressions';
2
2
  import { isAfterContentChecked, isAfterContentInit, isAfterViewChecked, isAfterViewInit, isDoCheck, isOnChanges, isOnDestroy, isOnInit } from '../component/lifecycle.js';
3
3
  import { ComponentRender } from './render.js';
4
- import { ElementModelReactiveScope } from '../component/provider.js';
4
+ import { getCurrentZone } from '../zone/bootstrap.js';
5
+ import { ProxyAuroraZone } from '../zone/zone.js';
6
+ import { createModelChangeDetectorRef } from '../linker/change-detector-ref.js';
7
+ import { createZoneProxyHandler } from '../zone/proxy.js';
5
8
  const FACTORY_CACHE = new WeakMap();
6
9
  export function baseFactoryView(htmlElementType) {
7
10
  if (FACTORY_CACHE.has(htmlElementType)) {
@@ -11,9 +14,10 @@ export function baseFactoryView(htmlElementType) {
11
14
  constructor(componentRef, modelClass) {
12
15
  super();
13
16
  this.subscriptions = [];
17
+ this.onDestroyCalls = [];
14
18
  this.doBlockCallback = () => {
15
19
  if (isDoCheck(this._model)) {
16
- this._model.doCheck.call(this._proxyModel);
20
+ this._zone.run(this._model.doCheck, this._modelScope.getContextProxy());
17
21
  }
18
22
  };
19
23
  this._componentRef = componentRef;
@@ -23,13 +27,21 @@ export function baseFactoryView(htmlElementType) {
23
27
  delegatesFocus: componentRef.shadowDomDelegatesFocus
24
28
  });
25
29
  }
26
- const model = new modelClass();
30
+ const args = []; /* resolve dependency injection*/
31
+ const detector = createModelChangeDetectorRef(() => this._modelScope);
32
+ args.push(detector);
33
+ this._zone = getCurrentZone(componentRef.zone).fork();
34
+ args.push(this._zone);
35
+ const model = new modelClass(...args);
27
36
  this._model = model;
28
- const modelScope = ElementModelReactiveScope.for(model);
29
- this._proxyModel = modelScope.getContextProxy();
37
+ const modelScope = ReactiveScopeControl.for(model);
38
+ const modelProxyRef = this._zone instanceof ProxyAuroraZone
39
+ ? createZoneProxyHandler(model, this._zone)
40
+ : model;
41
+ modelScope.getContextProxy = () => modelProxyRef;
30
42
  this._modelScope = modelScope;
31
43
  this._viewScope = ReactiveScope.for({ 'this': this });
32
- const elementScope = this._viewScope.getScopeOrCreat('this');
44
+ const elementScope = this._viewScope.getInnerScope('this');
33
45
  componentRef.inputs.forEach(input => {
34
46
  elementScope.subscribe(input.viewAttribute, (newValue, oldValue) => {
35
47
  if (newValue === oldValue) {
@@ -44,6 +56,7 @@ export function baseFactoryView(htmlElementType) {
44
56
  elementScope.emit(input.viewAttribute, newValue, oldValue);
45
57
  });
46
58
  });
59
+ // if property of the model has view decorator
47
60
  if (this._componentRef.view) {
48
61
  Reflect.set(this._model, this._componentRef.view, this);
49
62
  }
@@ -141,7 +154,7 @@ export function baseFactoryView(htmlElementType) {
141
154
  return;
142
155
  }
143
156
  if (isOnChanges(this._model)) {
144
- this._model.onChanges.call(this._proxyModel);
157
+ this._zone.run(this._model.onChanges, this._modelScope.getContextProxy());
145
158
  }
146
159
  this.doBlockCallback();
147
160
  }
@@ -150,6 +163,8 @@ export function baseFactoryView(htmlElementType) {
150
163
  this.subscriptions.forEach(sub => sub.unsubscribe());
151
164
  }
152
165
  this.subscriptions.splice(0, this.subscriptions.length);
166
+ const cds = this._zone.onEmpty.subscribe(() => this._modelScope.detectChanges());
167
+ this.onDestroy(() => cds.unsubscribe());
153
168
  this._componentRef.inputs.forEach(input => {
154
169
  const inputDefaultValue = this._model[input.modelProperty];
155
170
  if (inputDefaultValue !== null && inputDefaultValue !== undefined) {
@@ -161,43 +176,47 @@ export function baseFactoryView(htmlElementType) {
161
176
  attrs.forEach(attr => this.initOuterAttribute(attr));
162
177
  }
163
178
  if (isOnChanges(this._model)) {
164
- this._model.onChanges.call(this._proxyModel);
179
+ this._zone.run(this._model.onChanges, this._modelScope.getContextProxy());
165
180
  }
166
181
  if (isOnInit(this._model)) {
167
- this._model.onInit.call(this._proxyModel);
182
+ this._zone.run(this._model.onInit, this._modelScope.getContextProxy());
168
183
  }
169
184
  if (isDoCheck(this._model)) {
170
- this._model.doCheck.call(this._proxyModel);
185
+ this._zone.run(this._model.doCheck, this._modelScope.getContextProxy());
171
186
  }
172
187
  if (isAfterContentInit(this._model)) {
173
- this._model.afterContentInit.call(this._proxyModel);
188
+ this._zone.run(this._model.afterContentInit, this._modelScope.getContextProxy());
174
189
  }
175
190
  if (isAfterContentChecked(this._model)) {
176
- this._model.afterContentChecked.call(this._proxyModel);
191
+ this._zone.run(this._model.afterContentChecked, this._modelScope.getContextProxy());
177
192
  }
193
+ // do once
178
194
  if (this.childNodes.length === 0) {
195
+ // setup ui view
179
196
  this._render.initView();
197
+ // init Host Listener events
180
198
  this._render.initHostListener();
181
199
  }
182
200
  if (isAfterViewInit(this._model)) {
183
- this._model.afterViewInit.call(this._proxyModel);
201
+ this._zone.run(this._model.afterViewInit, this._modelScope.getContextProxy());
184
202
  }
185
203
  if (isAfterViewChecked(this._model)) {
186
- this._model.afterViewChecked.call(this._proxyModel);
204
+ this._zone.run(this._model.afterViewChecked, this._modelScope.getContextProxy());
187
205
  }
188
206
  this.doBlockCallback = () => {
189
207
  if (isDoCheck(this._model)) {
190
- this._model.doCheck.call(this._proxyModel);
208
+ this._zone.run(this._model.doCheck, this._modelScope.getContextProxy());
191
209
  }
192
210
  if (isAfterContentChecked(this._model)) {
193
- this._model.afterContentChecked.call(this._proxyModel);
211
+ this._zone.run(this._model.afterContentChecked, this._modelScope.getContextProxy());
194
212
  }
195
213
  if (isAfterViewChecked(this._model)) {
196
- this._model.afterViewChecked.call(this._proxyModel);
214
+ this._zone.run(this._model.afterViewChecked, this._modelScope.getContextProxy());
197
215
  }
198
216
  };
199
217
  }
200
218
  initOuterAttribute(attr) {
219
+ // [window, this] scop
201
220
  let elementAttr = attr.name;
202
221
  let modelProperty = attr.value;
203
222
  if (elementAttr.startsWith('[')) {
@@ -207,7 +226,9 @@ export function baseFactoryView(htmlElementType) {
207
226
  }
208
227
  }
209
228
  else if (elementAttr.startsWith('(')) {
229
+ // (elementAttr)="modelProperty()"
210
230
  elementAttr = elementAttr.substring(1, elementAttr.length - 1);
231
+ // this.handleEvent(element, elementAttr, viewProperty);
211
232
  modelProperty = modelProperty.endsWith('()') ?
212
233
  modelProperty.substring(0, modelProperty.length - 2) : modelProperty;
213
234
  let callback = Reflect.get(window, modelProperty);
@@ -218,6 +239,7 @@ export function baseFactoryView(htmlElementType) {
218
239
  else if (elementAttr.startsWith('on')) {
219
240
  const modelEvent = this.getEventEmitter(elementAttr.substring(2));
220
241
  if (modelEvent) {
242
+ // modelEvent.subscribe(listener);
221
243
  modelProperty = modelProperty.endsWith('()') ?
222
244
  modelProperty.substring(0, modelProperty.length - 2) : modelProperty;
223
245
  let listener = Reflect.get(window, modelProperty);
@@ -230,17 +252,32 @@ export function baseFactoryView(htmlElementType) {
230
252
  this.setInputValue(attr.name, attr.value);
231
253
  }
232
254
  }
255
+ onDestroy(callback) {
256
+ this.onDestroyCalls.push(callback);
257
+ }
233
258
  adoptedCallback() {
259
+ // restart the process
234
260
  this.innerHTML = '';
235
261
  this.connectedCallback();
236
262
  }
237
263
  disconnectedCallback() {
264
+ // notify first, then call model.onDestroy func
238
265
  if (isOnDestroy(this._model)) {
239
- this._model.onDestroy.call(this._proxyModel);
266
+ this._zone.run(this._model.onDestroy, this._modelScope.getContextProxy());
240
267
  }
241
268
  this.subscriptions.forEach(sub => sub.unsubscribe());
242
269
  this.subscriptions.splice(0, this.subscriptions.length);
270
+ this.onDestroyCalls.forEach(callback => {
271
+ try {
272
+ callback();
273
+ }
274
+ catch (error) {
275
+ console.error(error);
276
+ }
277
+ });
278
+ this.onDestroyCalls.splice(0, this.onDestroyCalls.length);
243
279
  }
280
+ // events api
244
281
  addEventListener(eventName, listener, options) {
245
282
  if ('on' + eventName in this) {
246
283
  super.addEventListener(eventName, (event) => {