@ibyar/core 0.4.2 → 0.5.0

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 (58) hide show
  1. package/README.md +1 -0
  2. package/annotation/decorators.d.ts +2 -3
  3. package/annotation/decorators.js.map +1 -1
  4. package/binding/binding.expressions.d.ts +32 -0
  5. package/binding/binding.expressions.js +99 -0
  6. package/binding/binding.expressions.js.map +1 -0
  7. package/component/component.d.ts +2 -2
  8. package/component/component.js +4 -10
  9. package/component/component.js.map +1 -1
  10. package/component/custom-element.d.ts +10 -14
  11. package/component/custom-element.js.map +1 -1
  12. package/component/provider.js +1 -1
  13. package/component/provider.js.map +1 -1
  14. package/directive/directive.d.ts +5 -10
  15. package/directive/directive.js +3 -9
  16. package/directive/directive.js.map +1 -1
  17. package/directive/parser.d.ts +30 -0
  18. package/directive/parser.js +174 -0
  19. package/directive/parser.js.map +1 -0
  20. package/html/expression.d.ts +13 -10
  21. package/html/expression.js +75 -20
  22. package/html/expression.js.map +1 -1
  23. package/index.d.ts +3 -1
  24. package/index.js +3 -1
  25. package/index.js.map +1 -1
  26. package/linker/template-ref.d.ts +18 -0
  27. package/linker/template-ref.js +59 -0
  28. package/linker/template-ref.js.map +1 -0
  29. package/linker/view-container-ref.d.ts +39 -0
  30. package/linker/view-container-ref.js +82 -0
  31. package/linker/view-container-ref.js.map +1 -0
  32. package/linker/view-ref.d.ts +36 -0
  33. package/linker/view-ref.js +75 -0
  34. package/linker/view-ref.js.map +1 -0
  35. package/package.json +5 -5
  36. package/pipe/pipe.d.ts +14 -1
  37. package/pipe/pipe.js +28 -1
  38. package/pipe/pipe.js.map +1 -1
  39. package/utils/elements-util.js +4 -1
  40. package/utils/elements-util.js.map +1 -1
  41. package/view/base-view.d.ts +1 -1
  42. package/view/base-view.js +26 -49
  43. package/view/base-view.js.map +1 -1
  44. package/view/render.d.ts +21 -19
  45. package/view/render.js +124 -161
  46. package/view/render.js.map +1 -1
  47. package/view/view.d.ts +1 -1
  48. package/view/view.js +7 -10
  49. package/view/view.js.map +1 -1
  50. package/html/update.d.ts +0 -12
  51. package/html/update.js +0 -24
  52. package/html/update.js.map +0 -1
  53. package/model/change-detection.d.ts +0 -13
  54. package/model/change-detection.js +0 -100
  55. package/model/change-detection.js.map +0 -1
  56. package/view/events.d.ts +0 -2
  57. package/view/events.js +0 -25
  58. package/view/events.js.map +0 -1
package/view/render.d.ts CHANGED
@@ -1,36 +1,38 @@
1
- import { ExpressionEventMap, ExpressionNode, Stack } from '@ibyar/expressions';
2
- import { CommentNode, DOMDirectiveNode, DOMElementNode, DOMFragmentNode, DOMNode, LiveAttribute, LiveTextContent, TextContent } from '@ibyar/elements';
1
+ import { ReactiveScope, ScopeContext, ScopeSubscription, Stack } from '@ibyar/expressions';
2
+ import { CommentNode, DomStructuralDirectiveNode, DomElementNode, DomFragmentNode, DomNode, LiveTextContent, TextContent, DomAttributeDirectiveNode } from '@ibyar/elements';
3
3
  import { ComponentRef, ListenerRef } from '../component/component.js';
4
4
  import { ElementMutation } from './mutation.js';
5
5
  import { HTMLComponent } from '../component/custom-element.js';
6
- import { SourceFollowerCallback } from '../model/change-detection.js';
7
- import { StructuralDirective } from '../directive/directive.js';
8
- export declare class ComponentRender<T> {
6
+ import { AttributeDirective, StructuralDirective } from '../directive/directive.js';
7
+ import { TemplateRef } from '../linker/template-ref.js';
8
+ export declare class ComponentRender<T extends object> {
9
9
  view: HTMLComponent<T>;
10
10
  componentRef: ComponentRef<T>;
11
- template: DOMNode;
11
+ template: DomNode;
12
12
  nativeElementMutation: ElementMutation;
13
13
  contextStack: Stack;
14
- templateRefMap: Map<string, DOMElementNode>;
14
+ templateNameScope: ReactiveScope<{
15
+ [templateName: string]: TemplateRef;
16
+ }>;
15
17
  constructor(view: HTMLComponent<T>);
16
18
  initView(): void;
17
- isTemplateRefName(template: DOMNode): template is DOMElementNode;
18
- initTemplateRefMap(domNode: DOMNode): void;
19
+ isTemplateRefName(template: DomNode): template is DomElementNode;
20
+ initTemplateRefMap(domNode: DomNode): void;
19
21
  initHostListener(): void;
20
22
  handelHostListener(listener: ListenerRef): void;
21
23
  addNativeEventListener(source: HTMLElement | Window, eventName: string, funcCallback: Function): void;
22
24
  getElementByName(name: string): any;
23
- createStructuralDirective(directive: DOMDirectiveNode, comment: Comment, directiveStack: Stack, parentNode: Node): void;
25
+ createStructuralDirective(directive: DomStructuralDirectiveNode, comment: Comment, directiveStack: Stack, parentNode: Node): void;
24
26
  createComment(node: CommentNode): Comment;
25
27
  createText(node: TextContent): Text;
26
28
  createLiveText(textNode: LiveTextContent, contextStack: Stack, parentNode: Node): Text;
27
- createDocumentFragment(node: DOMFragmentNode, contextStack: Stack, parentNode: Node): DocumentFragment;
28
- appendChildToParent(fragmentParent: HTMLElement | DocumentFragment, child: DOMNode, contextStack: Stack, parentNode: Node): void;
29
- createElementByTagName(node: DOMElementNode): HTMLElement;
30
- createElement(node: DOMElementNode, contextStack: Stack, parentNode: Node): HTMLElement;
31
- initAttribute(element: HTMLElement, node: DOMElementNode, contextStack: Stack): void;
32
- initDirectiveAttributes(directive: StructuralDirective, node: DOMDirectiveNode, contextStack: Stack): void;
33
- bind1Way(element: HTMLElement | StructuralDirective | Text, attr: LiveAttribute | LiveTextContent, contextStack: Stack): void;
34
- subscribeExpressionNode(node: ExpressionNode, contextStack: Stack, callback: SourceFollowerCallback, object?: object, attrName?: string, events?: ExpressionEventMap): void;
35
- bind2Way(element: HTMLElement | StructuralDirective, attr: LiveAttribute, contextStack: Stack): void;
29
+ createDocumentFragment(node: DomFragmentNode, contextStack: Stack, parentNode: Node): DocumentFragment;
30
+ appendChildToParent(fragmentParent: HTMLElement | DocumentFragment, child: DomNode, contextStack: Stack, parentNode: Node): void;
31
+ createElementByTagName(node: {
32
+ tagName: string;
33
+ is?: string;
34
+ }): HTMLElement;
35
+ createElement(node: DomElementNode, contextStack: Stack, parentNode: Node): HTMLElement;
36
+ initAttribute(element: HTMLElement, node: DomElementNode, contextStack: Stack): ScopeSubscription<ScopeContext>[];
37
+ initDirectiveAttributes(directive: StructuralDirective | AttributeDirective, node: DomStructuralDirectiveNode | DomAttributeDirectiveNode, contextStack: Stack): ScopeSubscription<ScopeContext>[];
36
38
  }
package/view/render.js CHANGED
@@ -1,40 +1,32 @@
1
- import { CommentNode, DOMDirectiveNode, DOMElementNode, DOMFragmentNode, isLiveTextContent, isTagNameNative, isValidCustomElementName, TextContent } from '@ibyar/elements';
1
+ import { CommentNode, DomStructuralDirectiveNode, DomElementNode, DomFragmentNode, isLiveTextContent, isTagNameNative, isValidCustomElementName, TextContent } from '@ibyar/elements';
2
2
  import { ElementMutation } from './mutation.js';
3
3
  import { isHTMLComponent } from '../component/custom-element.js';
4
4
  import { documentStack } from '../context/stack.js';
5
5
  import { ClassRegistryProvider } from '../providers/provider.js';
6
6
  import { isOnDestroy, isOnInit } from '../component/lifecycle.js';
7
7
  import { hasAttr } from '../utils/elements-util.js';
8
- import { addChangeListener, isModel, subscribe1way, subscribe2way } from '../model/change-detection.js';
9
- import { AsyncPipeProvider, PipeProvider } from '../pipe/pipe.js';
10
- import { StructuralDirective } from '../directive/directive.js';
11
- import { ElementReactiveScope } from '../directive/providers.js';
12
- import { findScopeMap } from './events.js';
13
- function getChangeEventName(element, elementAttr) {
14
- if (elementAttr === 'value') {
15
- if (element instanceof HTMLInputElement) {
8
+ import { AttributeDirective } from '../directive/directive.js';
9
+ import { TemplateRefImpl } from '../linker/template-ref.js';
10
+ import { ViewContainerRefImpl } from '../linker/view-container-ref.js';
11
+ function getInputEventName(element) {
12
+ switch (true) {
13
+ case element instanceof HTMLInputElement:
16
14
  return 'input';
17
- }
18
- else if (element instanceof HTMLSelectElement
19
- || element instanceof HTMLTextAreaElement) {
15
+ case element instanceof HTMLTextAreaElement:
16
+ case element instanceof HTMLSelectElement:
20
17
  return 'change';
21
- }
18
+ default:
19
+ return undefined;
22
20
  }
23
- return elementAttr;
24
21
  }
25
22
  export class ComponentRender {
26
23
  constructor(view) {
27
24
  this.view = view;
28
- this.templateRefMap = new Map();
29
25
  this.componentRef = this.view.getComponentRef();
30
26
  this.contextStack = documentStack.copyStack();
31
- this.contextStack.pushFunctionScope();
32
- this.contextStack.pushScope(this.view._viewScope);
33
27
  this.contextStack.pushScope(this.view._modelScope);
28
+ this.templateNameScope = this.contextStack.pushBlockReactiveScope();
34
29
  this.nativeElementMutation = new ElementMutation();
35
- this.view._model.subscribeModel('destroy', () => {
36
- this.nativeElementMutation.disconnect();
37
- });
38
30
  }
39
31
  initView() {
40
32
  if (this.componentRef.template) {
@@ -58,13 +50,19 @@ export class ComponentRender {
58
50
  rootRef = this.view;
59
51
  }
60
52
  this.initTemplateRefMap(this.template);
61
- const rootFragment = document.createDocumentFragment();
62
- this.appendChildToParent(rootFragment, this.template, this.contextStack, rootRef);
53
+ let rootFragment;
54
+ if (this.template instanceof DomFragmentNode) {
55
+ rootFragment = this.createDocumentFragment(this.template, this.contextStack, rootRef);
56
+ }
57
+ else {
58
+ rootFragment = document.createDocumentFragment();
59
+ this.appendChildToParent(rootFragment, this.template, this.contextStack, rootRef);
60
+ }
63
61
  rootRef.append(rootFragment);
64
62
  }
65
63
  }
66
64
  isTemplateRefName(template) {
67
- if (template instanceof DOMElementNode) {
65
+ if (template instanceof DomElementNode) {
68
66
  if (template.tagName === 'template' && template.templateRefName) {
69
67
  return true;
70
68
  }
@@ -72,22 +70,17 @@ export class ComponentRender {
72
70
  return false;
73
71
  }
74
72
  initTemplateRefMap(domNode) {
75
- if (domNode instanceof DOMElementNode || domNode instanceof DOMFragmentNode) {
73
+ if (domNode instanceof DomElementNode || domNode instanceof DomFragmentNode) {
76
74
  if (domNode.children) {
77
- const toRemove = [];
78
75
  for (let index = 0; index < domNode.children.length; index++) {
79
76
  const child = domNode.children[index];
80
77
  if (this.isTemplateRefName(child)) {
81
- toRemove.unshift({ index, template: child });
78
+ this.templateNameScope.set(child.templateRefName.name, undefined);
82
79
  }
83
80
  else {
84
81
  this.initTemplateRefMap(child);
85
82
  }
86
83
  }
87
- toRemove.forEach(info => {
88
- this.templateRefMap.set(info.template.templateRefName.name, info.template);
89
- domNode.children.splice(info.index, 1);
90
- });
91
84
  }
92
85
  }
93
86
  }
@@ -135,7 +128,6 @@ export class ComponentRender {
135
128
  });
136
129
  }
137
130
  else {
138
- addChangeListener(sourceModel, eventName, () => this.view._model[listener.modelCallbackName].call(this.view._proxyModel));
139
131
  }
140
132
  }
141
133
  addNativeEventListener(source, eventName, funcCallback) {
@@ -150,20 +142,19 @@ export class ComponentRender {
150
142
  const directiveRef = ClassRegistryProvider.getDirectiveRef(directive.name);
151
143
  if (directiveRef) {
152
144
  const StructuralDirectiveClass = directiveRef.modelClass;
153
- const structural = new StructuralDirectiveClass(this, directiveStack.copyStack(), comment, parentNode, directive.node);
154
- if (isOnDestroy(structural)) {
155
- const removeSubscription = this.nativeElementMutation.subscribeOnRemoveNode(parentNode, comment, () => {
156
- console.log('destroy structural directive', directive.name, removeSubscription);
157
- removeSubscription.unsubscribe();
145
+ const stack = directiveStack.copyStack();
146
+ const templateRef = new TemplateRefImpl(this, directive.node, stack, directive.templateExpressions ?? []);
147
+ const viewContainerRef = new ViewContainerRefImpl(parentNode, comment);
148
+ const structural = new StructuralDirectiveClass(templateRef, viewContainerRef);
149
+ stack.pushBlockReactiveScopeFor({ 'this': structural });
150
+ const subscriptions = this.initDirectiveAttributes(structural, directive, stack);
151
+ const removeSubscription = this.nativeElementMutation.subscribeOnRemoveNode(parentNode, comment, () => {
152
+ removeSubscription.unsubscribe();
153
+ subscriptions.forEach(subscription => subscription.unsubscribe());
154
+ if (isOnDestroy(structural)) {
158
155
  structural.onDestroy();
159
- });
160
- }
161
- const directiveInputName = directive.name.substring(1);
162
- const directiveInput = directiveRef.inputs?.find(input => input.viewAttribute === directiveInputName);
163
- if (directiveInput) {
164
- Reflect.set(structural, directiveInput.modelProperty, String(directive.value));
165
- }
166
- this.initDirectiveAttributes(structural, directive, directiveStack);
156
+ }
157
+ });
167
158
  if (isOnInit(structural)) {
168
159
  structural.onInit();
169
160
  }
@@ -181,22 +172,34 @@ export class ComponentRender {
181
172
  const liveText = new Text('');
182
173
  contextStack = contextStack.copyStack();
183
174
  contextStack.pushBlockScopeFor({ this: liveText });
184
- this.bind1Way(liveText, textNode, contextStack);
175
+ const subscriptions = textNode.expression.subscribe(contextStack, textNode.pipelineNames);
176
+ textNode.expression.get(contextStack);
177
+ const removeSubscription = this.nativeElementMutation.subscribeOnRemoveNode(parentNode, liveText, () => {
178
+ removeSubscription.unsubscribe();
179
+ subscriptions.forEach(subscription => subscription.unsubscribe());
180
+ });
185
181
  return liveText;
186
182
  }
187
183
  createDocumentFragment(node, contextStack, parentNode) {
188
184
  const fragment = document.createDocumentFragment();
189
- node.children.forEach(child => this.appendChildToParent(fragment, child, contextStack, parentNode));
185
+ node.children?.forEach(child => this.appendChildToParent(fragment, child, contextStack, parentNode));
190
186
  return fragment;
191
187
  }
192
188
  appendChildToParent(fragmentParent, child, contextStack, parentNode) {
193
- if (child instanceof DOMElementNode) {
189
+ if (child instanceof DomElementNode) {
190
+ if (this.isTemplateRefName(child)) {
191
+ const templateRefName = child.templateRefName;
192
+ const templateRef = new TemplateRefImpl(this, new DomFragmentNode(child.children), contextStack.copyStack(), []);
193
+ this.templateNameScope.set(templateRefName.name, templateRef);
194
+ return;
195
+ }
194
196
  fragmentParent.append(this.createElement(child, contextStack, parentNode));
195
197
  }
196
- else if (child instanceof DOMDirectiveNode) {
197
- const comment = document.createComment(`start ${child.name} = ${child.value}`);
198
+ else if (child instanceof DomStructuralDirectiveNode) {
199
+ const commentText = child.name + (typeof child.value == 'string' ? (' = ' + child.value) : '');
200
+ const comment = document.createComment(`start ${commentText}`);
198
201
  fragmentParent.append(comment);
199
- const lastComment = document.createComment(`end ${child.name} = ${child.value}`);
202
+ const lastComment = document.createComment(`end ${commentText}`);
200
203
  comment.after(lastComment);
201
204
  this.createStructuralDirective(child, comment, contextStack, parentNode);
202
205
  }
@@ -209,7 +212,7 @@ export class ComponentRender {
209
212
  else if (child instanceof CommentNode) {
210
213
  fragmentParent.append(this.createComment(child));
211
214
  }
212
- else if (child instanceof DOMFragmentNode) {
215
+ else if (child instanceof DomFragmentNode) {
213
216
  fragmentParent.append(this.createDocumentFragment(child, contextStack, parentNode));
214
217
  }
215
218
  }
@@ -240,26 +243,57 @@ export class ComponentRender {
240
243
  }
241
244
  createElement(node, contextStack, parentNode) {
242
245
  const element = this.createElementByTagName(node);
243
- const elContext = isHTMLComponent(element) ? element._viewScope : new ElementReactiveScope(element);
244
- contextStack = contextStack.copyStack();
245
- contextStack.pushScope(elContext);
246
- this.initAttribute(element, node, contextStack);
247
- if (node.templateRefName) {
248
- Reflect.set(this.view, node.templateRefName.name, element);
249
- const view = this.componentRef.viewChild.find(child => child.selector === node.templateRefName.name);
246
+ const elementStack = contextStack.copyStack();
247
+ const elementScope = isHTMLComponent(element) ? element._viewScope : elementStack.pushBlockReactiveScopeFor({ 'this': element });
248
+ elementStack.pushScope(elementScope);
249
+ const subscriptions = [];
250
+ if (node.attributeDirectives?.length) {
251
+ node.attributeDirectives.forEach(directiveNode => {
252
+ const directiveRef = ClassRegistryProvider.getDirectiveRef(directiveNode.name);
253
+ if (directiveRef && directiveRef.modelClass.prototype instanceof AttributeDirective) {
254
+ const directive = new directiveRef.modelClass(element);
255
+ const stack = contextStack.copyStack();
256
+ stack.pushBlockReactiveScopeFor({ 'this': directive });
257
+ const directiveSubscriptions = this.initDirectiveAttributes(directive, directiveNode, stack);
258
+ subscriptions.push(...directiveSubscriptions);
259
+ if (isOnInit(directive)) {
260
+ directive.onInit();
261
+ }
262
+ }
263
+ });
264
+ }
265
+ const attributesSubscriptions = this.initAttribute(element, node, elementStack);
266
+ subscriptions.push(...attributesSubscriptions);
267
+ const eventName = getInputEventName(element);
268
+ let listener;
269
+ if (eventName) {
270
+ const inputScope = elementScope.getScopeOrCreat('this');
271
+ listener = (event) => inputScope.emit('value', element.value);
272
+ element.addEventListener(eventName, listener);
273
+ }
274
+ const removeSubscription = this.nativeElementMutation.subscribeOnRemoveNode(parentNode, element, () => {
275
+ removeSubscription.unsubscribe();
276
+ listener && element.removeEventListener(eventName, listener);
277
+ subscriptions.forEach(subscription => subscription.unsubscribe());
278
+ });
279
+ const templateRefName = node.templateRefName;
280
+ if (templateRefName) {
281
+ Reflect.set(this.view, templateRefName.name, element);
282
+ const view = this.componentRef.viewChild.find(child => child.selector === templateRefName.name);
250
283
  if (view) {
251
284
  Reflect.set(this.view._model, view.modelName, element);
252
285
  }
253
286
  }
254
287
  if (node.children) {
255
288
  for (const child of node.children) {
256
- this.appendChildToParent(element, child, contextStack, element);
289
+ this.appendChildToParent(element, child, elementStack, element);
257
290
  }
258
291
  }
259
292
  return element;
260
293
  }
261
294
  initAttribute(element, node, contextStack) {
262
- if (node.attributes) {
295
+ const subscriptions = [];
296
+ if (node.attributes?.length) {
263
297
  node.attributes.forEach(attr => {
264
298
  const isAttr = hasAttr(element, attr.name);
265
299
  if (isAttr) {
@@ -278,17 +312,21 @@ export class ComponentRender {
278
312
  }
279
313
  });
280
314
  }
281
- if (node.twoWayBinding) {
315
+ if (node.twoWayBinding?.length) {
282
316
  node.twoWayBinding.forEach(attr => {
283
- this.bind2Way(element, attr, contextStack);
317
+ const sub = attr.expression.subscribe(contextStack);
318
+ subscriptions.push(...sub);
319
+ attr.expression.get(contextStack);
284
320
  });
285
321
  }
286
- if (node.inputs) {
322
+ if (node.inputs?.length) {
287
323
  node.inputs.forEach(attr => {
288
- this.bind1Way(element, attr, contextStack);
324
+ const sub = attr.expression.subscribe(contextStack, attr.pipelineNames);
325
+ subscriptions.push(...sub);
326
+ attr.expression.get(contextStack);
289
327
  });
290
328
  }
291
- if (node.outputs) {
329
+ if (node.outputs?.length) {
292
330
  node.outputs.forEach(event => {
293
331
  let listener;
294
332
  if (typeof event.value === 'string') {
@@ -304,27 +342,35 @@ export class ComponentRender {
304
342
  element.addEventListener(event.name, listener);
305
343
  });
306
344
  }
307
- if (node.templateAttrs) {
345
+ if (node.templateAttrs?.length) {
308
346
  node.templateAttrs.forEach(attr => {
309
- this.bind1Way(element, attr, contextStack);
347
+ const sub = attr.expression.subscribe(contextStack);
348
+ subscriptions.push(...sub);
349
+ attr.expression.get(contextStack);
310
350
  });
311
351
  }
352
+ return subscriptions;
312
353
  }
313
354
  initDirectiveAttributes(directive, node, contextStack) {
314
- if (node.attributes) {
355
+ const subscriptions = [];
356
+ if (node.attributes?.length) {
315
357
  node.attributes.forEach(attr => Reflect.set(directive, attr.name, attr.value));
316
358
  }
317
- if (node.twoWayBinding) {
359
+ if (node.twoWayBinding?.length) {
318
360
  node.twoWayBinding.forEach(attr => {
319
- this.bind2Way(directive, attr, contextStack);
361
+ const sub = attr.expression.subscribe(contextStack);
362
+ subscriptions.push(...sub);
363
+ attr.expression.get(contextStack);
320
364
  });
321
365
  }
322
- if (node.inputs) {
366
+ if (node.inputs?.length) {
323
367
  node.inputs.forEach(attr => {
324
- this.bind1Way(directive, attr, contextStack);
368
+ const sub = attr.expression.subscribe(contextStack, attr.pipelineNames);
369
+ subscriptions.push(...sub);
370
+ attr.expression.get(contextStack);
325
371
  });
326
372
  }
327
- if (node.outputs) {
373
+ if (node.outputs?.length) {
328
374
  node.outputs.forEach(event => {
329
375
  const listener = ($event) => {
330
376
  const stack = contextStack.copyStack();
@@ -334,97 +380,14 @@ export class ComponentRender {
334
380
  directive[event.name].subscribe(listener);
335
381
  });
336
382
  }
337
- if (node.templateAttrs) {
383
+ if (node.templateAttrs?.length) {
338
384
  node.templateAttrs.forEach(attr => {
339
- this.bind1Way(directive, attr, contextStack);
340
- });
341
- }
342
- }
343
- bind1Way(element, attr, contextStack) {
344
- const callback = () => {
345
- attr.expression.get(contextStack);
346
- };
347
- this.subscribeExpressionNode(attr.expression, contextStack, callback, element, attr.name, attr.expressionEvent);
348
- callback();
349
- }
350
- subscribeExpressionNode(node, contextStack, callback, object, attrName, events) {
351
- events ??= node.events();
352
- const scopeMap = findScopeMap(events, contextStack);
353
- scopeMap.forEach((scope, eventName) => {
354
- const context = scope.getContext();
355
- if (context) {
356
- if (scope instanceof AsyncPipeProvider) {
357
- const pipe = contextStack.get(eventName);
358
- subscribe1way(pipe, eventName, callback, object, attrName);
359
- if (isOnDestroy(pipe)) {
360
- this.view._model.subscribeModel('destroy', () => {
361
- if (isModel(pipe)) {
362
- pipe.emitChangeModel('destroy');
363
- }
364
- pipe.onDestroy();
365
- });
366
- }
367
- const pipeContext = {};
368
- pipeContext[eventName] = (value, ...args) => pipe.transform(value, ...args);
369
- contextStack.pushBlockScopeFor(pipeContext);
370
- }
371
- else if (!(scope instanceof PipeProvider)) {
372
- subscribe1way(context, eventName, callback, object, attrName);
373
- }
374
- }
375
- });
376
- }
377
- bind2Way(element, attr, contextStack) {
378
- const callback1 = () => {
379
- attr.expression.get(contextStack);
380
- };
381
- const callback2 = () => {
382
- attr.callbackExpression.get(contextStack);
383
- };
384
- const scopeMap = findScopeMap(attr.expressionEvent, contextStack);
385
- scopeMap.forEach((scope, eventName) => {
386
- const context = scope.getContext();
387
- if (context) {
388
- if (scope instanceof AsyncPipeProvider) {
389
- const pipe = contextStack.get(eventName);
390
- subscribe2way(pipe, eventName, callback1, element, attr.name, callback2);
391
- if (isOnDestroy(pipe)) {
392
- this.view._model.subscribeModel('destroy', () => {
393
- if (isModel(pipe)) {
394
- pipe.emitChangeModel('destroy');
395
- }
396
- pipe.onDestroy();
397
- });
398
- }
399
- const pipeContext = {};
400
- pipeContext[eventName] = (value, ...args) => pipe.transform(value, ...args);
401
- contextStack.pushBlockScopeFor(pipeContext);
402
- }
403
- else if (!(scope instanceof PipeProvider)) {
404
- subscribe2way(context, eventName, callback1, element, attr.name, callback2);
405
- }
406
- }
407
- });
408
- callback1();
409
- if (element instanceof StructuralDirective) {
410
- return;
411
- }
412
- const changeEventName = getChangeEventName(element, attr.name);
413
- if ((changeEventName === 'input' || changeEventName === 'change')
414
- && isModel(element)) {
415
- element.addEventListener(changeEventName, () => {
416
- element.emitChangeModel(attr.name);
417
- });
418
- }
419
- else if (isHTMLComponent(element)) {
420
- }
421
- else {
422
- this.nativeElementMutation.subscribe(element, attr.name, () => {
423
- if (isModel(element)) {
424
- element.emitChangeModel(attr.name);
425
- }
385
+ const sub = attr.expression.subscribe(contextStack);
386
+ subscriptions.push(...sub);
387
+ attr.expression.get(contextStack);
426
388
  });
427
389
  }
390
+ return subscriptions;
428
391
  }
429
392
  }
430
393
  //# sourceMappingURL=render.js.map