@angular/core 14.1.0-next.3 → 14.1.0-next.4

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 (41) hide show
  1. package/esm2020/src/application_ref.mjs +1 -1
  2. package/esm2020/src/core.mjs +1 -1
  3. package/esm2020/src/core_render3_private_export.mjs +2 -2
  4. package/esm2020/src/debug/debug_node.mjs +2 -3
  5. package/esm2020/src/di/index.mjs +1 -1
  6. package/esm2020/src/di/injector_compatibility.mjs +11 -1
  7. package/esm2020/src/di/interface/injector.mjs +2 -1
  8. package/esm2020/src/di/r3_injector.mjs +13 -1
  9. package/esm2020/src/errors.mjs +1 -1
  10. package/esm2020/src/linker/component_factory.mjs +1 -1
  11. package/esm2020/src/metadata/di.mjs +1 -1
  12. package/esm2020/src/render/api.mjs +2 -11
  13. package/esm2020/src/render3/component.mjs +3 -58
  14. package/esm2020/src/render3/component_ref.mjs +30 -5
  15. package/esm2020/src/render3/index.mjs +3 -3
  16. package/esm2020/src/render3/instructions/element_validation.mjs +4 -1
  17. package/esm2020/src/render3/instructions/listener.mjs +34 -44
  18. package/esm2020/src/render3/instructions/lview_debug.mjs +1 -1
  19. package/esm2020/src/render3/instructions/shared.mjs +22 -59
  20. package/esm2020/src/render3/instructions/styling.mjs +2 -2
  21. package/esm2020/src/render3/interfaces/renderer.mjs +1 -26
  22. package/esm2020/src/render3/interfaces/view.mjs +1 -1
  23. package/esm2020/src/render3/ng_module_ref.mjs +4 -1
  24. package/esm2020/src/render3/node_manipulation.mjs +24 -87
  25. package/esm2020/src/render3/node_manipulation_i18n.mjs +1 -1
  26. package/esm2020/src/render3/util/attrs_utils.mjs +4 -12
  27. package/esm2020/src/render3/util/view_utils.mjs +3 -6
  28. package/esm2020/src/version.mjs +1 -1
  29. package/esm2020/testing/src/logger.mjs +3 -3
  30. package/esm2020/testing/src/ng_zone_mock.mjs +3 -3
  31. package/fesm2015/core.mjs +1798 -1946
  32. package/fesm2015/core.mjs.map +1 -1
  33. package/fesm2015/testing.mjs +1429 -1669
  34. package/fesm2015/testing.mjs.map +1 -1
  35. package/fesm2020/core.mjs +1798 -1946
  36. package/fesm2020/core.mjs.map +1 -1
  37. package/fesm2020/testing.mjs +1429 -1669
  38. package/fesm2020/testing.mjs.map +1 -1
  39. package/index.d.ts +138 -128
  40. package/package.json +1 -1
  41. package/testing/index.d.ts +1 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v14.1.0-next.3
2
+ * @license Angular v14.1.0-next.4
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -1932,6 +1932,7 @@ function throwProviderNotFoundError(token, injectorName) {
1932
1932
  * Injection flags for DI.
1933
1933
  *
1934
1934
  * @publicApi
1935
+ * @deprecated use an options object for `inject` instead.
1935
1936
  */
1936
1937
  var InjectFlags;
1937
1938
  (function (InjectFlags) {
@@ -2139,6 +2140,16 @@ Please check that 1) the type for the parameter at index ${index} is correct and
2139
2140
  * @publicApi
2140
2141
  */
2141
2142
  function inject$1(token, flags = InjectFlags.Default) {
2143
+ if (typeof flags !== 'number') {
2144
+ // While TypeScript doesn't accept it without a cast, bitwise OR with false-y values in
2145
+ // JavaScript is a no-op. We can use that for a very codesize-efficient conversion from
2146
+ // `InjectOptions` to `InjectFlags`.
2147
+ flags = (0 /* InternalInjectFlags.Default */ | // comment to force a line break in the formatter
2148
+ (flags.optional && 8 /* InternalInjectFlags.Optional */) |
2149
+ (flags.host && 1 /* InternalInjectFlags.Host */) |
2150
+ (flags.self && 2 /* InternalInjectFlags.Self */) |
2151
+ (flags.skipSelf && 4 /* InternalInjectFlags.SkipSelf */));
2152
+ }
2142
2153
  return ɵɵinject(token, flags);
2143
2154
  }
2144
2155
  function injectArgs(types) {
@@ -3189,96 +3200,6 @@ function getNamespaceUri(namespace) {
3189
3200
  (name === MATH_ML_NAMESPACE ? MATH_ML_NAMESPACE_URI : null);
3190
3201
  }
3191
3202
 
3192
- /**
3193
- * @license
3194
- * Copyright Google LLC All Rights Reserved.
3195
- *
3196
- * Use of this source code is governed by an MIT-style license that can be
3197
- * found in the LICENSE file at https://angular.io/license
3198
- */
3199
- /**
3200
- * Most of the use of `document` in Angular is from within the DI system so it is possible to simply
3201
- * inject the `DOCUMENT` token and are done.
3202
- *
3203
- * Ivy is special because it does not rely upon the DI and must get hold of the document some other
3204
- * way.
3205
- *
3206
- * The solution is to define `getDocument()` and `setDocument()` top-level functions for ivy.
3207
- * Wherever ivy needs the global document, it calls `getDocument()` instead.
3208
- *
3209
- * When running ivy outside of a browser environment, it is necessary to call `setDocument()` to
3210
- * tell ivy what the global `document` is.
3211
- *
3212
- * Angular does this for us in each of the standard platforms (`Browser`, `Server`, and `WebWorker`)
3213
- * by calling `setDocument()` when providing the `DOCUMENT` token.
3214
- */
3215
- let DOCUMENT = undefined;
3216
- /**
3217
- * Tell ivy what the `document` is for this platform.
3218
- *
3219
- * It is only necessary to call this if the current platform is not a browser.
3220
- *
3221
- * @param document The object representing the global `document` in this environment.
3222
- */
3223
- function setDocument(document) {
3224
- DOCUMENT = document;
3225
- }
3226
- /**
3227
- * Access the object that represents the `document` for this platform.
3228
- *
3229
- * Ivy calls this whenever it needs to access the `document` object.
3230
- * For example to create the renderer or to do sanitization.
3231
- */
3232
- function getDocument() {
3233
- if (DOCUMENT !== undefined) {
3234
- return DOCUMENT;
3235
- }
3236
- else if (typeof document !== 'undefined') {
3237
- return document;
3238
- }
3239
- // No "document" can be found. This should only happen if we are running ivy outside Angular and
3240
- // the current platform is not a browser. Since this is not a supported scenario at the moment
3241
- // this should not happen in Angular apps.
3242
- // Once we support running ivy outside of Angular we will need to publish `setDocument()` as a
3243
- // public API. Meanwhile we just return `undefined` and let the application fail.
3244
- return undefined;
3245
- }
3246
-
3247
- /**
3248
- * @license
3249
- * Copyright Google LLC All Rights Reserved.
3250
- *
3251
- * Use of this source code is governed by an MIT-style license that can be
3252
- * found in the LICENSE file at https://angular.io/license
3253
- */
3254
- // TODO: cleanup once the code is merged in angular/angular
3255
- var RendererStyleFlags3;
3256
- (function (RendererStyleFlags3) {
3257
- RendererStyleFlags3[RendererStyleFlags3["Important"] = 1] = "Important";
3258
- RendererStyleFlags3[RendererStyleFlags3["DashCase"] = 2] = "DashCase";
3259
- })(RendererStyleFlags3 || (RendererStyleFlags3 = {}));
3260
- /** Returns whether the `renderer` is a `ProceduralRenderer3` */
3261
- function isProceduralRenderer(renderer) {
3262
- return !!(renderer.listen);
3263
- }
3264
- let renderer3Enabled = false;
3265
- function enableRenderer3() {
3266
- renderer3Enabled = true;
3267
- }
3268
- const domRendererFactory3 = {
3269
- createRenderer: (hostElement, rendererType) => {
3270
- if (!renderer3Enabled) {
3271
- throw new Error(ngDevMode ?
3272
- `Renderer3 is not supported. This problem is likely caused by some component in the hierarchy was constructed without a correct parent injector.` :
3273
- 'Renderer3 disabled');
3274
- }
3275
- return getDocument();
3276
- }
3277
- };
3278
- // Note: This hack is necessary so we don't erroneously get a circular dependency
3279
- // failure based on types.
3280
- const unusedValueExportToPlacateAjd$6 = 1;
3281
-
3282
3203
  /**
3283
3204
  * @license
3284
3205
  * Copyright Google LLC All Rights Reserved.
@@ -3361,7 +3282,6 @@ function getNativeByTNode(tNode, lView) {
3361
3282
  ngDevMode && assertTNodeForLView(tNode, lView);
3362
3283
  ngDevMode && assertIndexInRange(lView, tNode.index);
3363
3284
  const node = unwrapRNode(lView[tNode.index]);
3364
- ngDevMode && !isProceduralRenderer(lView[RENDERER]) && assertDomNode(node);
3365
3285
  return node;
3366
3286
  }
3367
3287
  /**
@@ -3377,7 +3297,6 @@ function getNativeByTNodeOrNull(tNode, lView) {
3377
3297
  if (index !== -1) {
3378
3298
  ngDevMode && assertTNodeForLView(tNode, lView);
3379
3299
  const node = unwrapRNode(lView[index]);
3380
- ngDevMode && node !== null && !isProceduralRenderer(lView[RENDERER]) && assertDomNode(node);
3381
3300
  return node;
3382
3301
  }
3383
3302
  return null;
@@ -4326,7 +4245,7 @@ function isFactory(obj) {
4326
4245
  }
4327
4246
  // Note: This hack is necessary so we don't erroneously get a circular dependency
4328
4247
  // failure based on types.
4329
- const unusedValueExportToPlacateAjd$5 = 1;
4248
+ const unusedValueExportToPlacateAjd$6 = 1;
4330
4249
 
4331
4250
  /**
4332
4251
  * Converts `TNodeType` into human readable text.
@@ -4345,7 +4264,7 @@ function toTNodeTypeAsString(tNodeType) {
4345
4264
  }
4346
4265
  // Note: This hack is necessary so we don't erroneously get a circular dependency
4347
4266
  // failure based on types.
4348
- const unusedValueExportToPlacateAjd$4 = 1;
4267
+ const unusedValueExportToPlacateAjd$5 = 1;
4349
4268
  /**
4350
4269
  * Returns `true` if the `TNode` has a directive which has `@Input()` for `class` binding.
4351
4270
  *
@@ -4449,7 +4368,6 @@ function assertPureTNodeType(type) {
4449
4368
  * @returns the index value that was last accessed in the attributes array
4450
4369
  */
4451
4370
  function setUpAttributes(renderer, native, attrs) {
4452
- const isProc = isProceduralRenderer(renderer);
4453
4371
  let i = 0;
4454
4372
  while (i < attrs.length) {
4455
4373
  const value = attrs[i];
@@ -4466,9 +4384,7 @@ function setUpAttributes(renderer, native, attrs) {
4466
4384
  const attrName = attrs[i++];
4467
4385
  const attrVal = attrs[i++];
4468
4386
  ngDevMode && ngDevMode.rendererSetAttribute++;
4469
- isProc ?
4470
- renderer.setAttribute(native, attrName, attrVal, namespaceURI) :
4471
- native.setAttributeNS(namespaceURI, attrName, attrVal);
4387
+ renderer.setAttribute(native, attrName, attrVal, namespaceURI);
4472
4388
  }
4473
4389
  else {
4474
4390
  // attrName is string;
@@ -4477,14 +4393,10 @@ function setUpAttributes(renderer, native, attrs) {
4477
4393
  // Standard attributes
4478
4394
  ngDevMode && ngDevMode.rendererSetAttribute++;
4479
4395
  if (isAnimationProp(attrName)) {
4480
- if (isProc) {
4481
- renderer.setProperty(native, attrName, attrVal);
4482
- }
4396
+ renderer.setProperty(native, attrName, attrVal);
4483
4397
  }
4484
4398
  else {
4485
- isProc ?
4486
- renderer.setAttribute(native, attrName, attrVal) :
4487
- native.setAttribute(attrName, attrVal);
4399
+ renderer.setAttribute(native, attrName, attrVal);
4488
4400
  }
4489
4401
  i++;
4490
4402
  }
@@ -5618,6 +5530,61 @@ function maybeUnwrapFn$1(value) {
5618
5530
  }
5619
5531
  }
5620
5532
 
5533
+ /**
5534
+ * @license
5535
+ * Copyright Google LLC All Rights Reserved.
5536
+ *
5537
+ * Use of this source code is governed by an MIT-style license that can be
5538
+ * found in the LICENSE file at https://angular.io/license
5539
+ */
5540
+ /**
5541
+ * Most of the use of `document` in Angular is from within the DI system so it is possible to simply
5542
+ * inject the `DOCUMENT` token and are done.
5543
+ *
5544
+ * Ivy is special because it does not rely upon the DI and must get hold of the document some other
5545
+ * way.
5546
+ *
5547
+ * The solution is to define `getDocument()` and `setDocument()` top-level functions for ivy.
5548
+ * Wherever ivy needs the global document, it calls `getDocument()` instead.
5549
+ *
5550
+ * When running ivy outside of a browser environment, it is necessary to call `setDocument()` to
5551
+ * tell ivy what the global `document` is.
5552
+ *
5553
+ * Angular does this for us in each of the standard platforms (`Browser`, `Server`, and `WebWorker`)
5554
+ * by calling `setDocument()` when providing the `DOCUMENT` token.
5555
+ */
5556
+ let DOCUMENT = undefined;
5557
+ /**
5558
+ * Tell ivy what the `document` is for this platform.
5559
+ *
5560
+ * It is only necessary to call this if the current platform is not a browser.
5561
+ *
5562
+ * @param document The object representing the global `document` in this environment.
5563
+ */
5564
+ function setDocument(document) {
5565
+ DOCUMENT = document;
5566
+ }
5567
+ /**
5568
+ * Access the object that represents the `document` for this platform.
5569
+ *
5570
+ * Ivy calls this whenever it needs to access the `document` object.
5571
+ * For example to create the renderer or to do sanitization.
5572
+ */
5573
+ function getDocument() {
5574
+ if (DOCUMENT !== undefined) {
5575
+ return DOCUMENT;
5576
+ }
5577
+ else if (typeof document !== 'undefined') {
5578
+ return document;
5579
+ }
5580
+ // No "document" can be found. This should only happen if we are running ivy outside Angular and
5581
+ // the current platform is not a browser. Since this is not a supported scenario at the moment
5582
+ // this should not happen in Angular apps.
5583
+ // Once we support running ivy outside of Angular we will need to publish `setDocument()` as a
5584
+ // public API. Meanwhile we just return `undefined` and let the application fail.
5585
+ return undefined;
5586
+ }
5587
+
5621
5588
  /**
5622
5589
  * @license
5623
5590
  * Copyright Google LLC All Rights Reserved.
@@ -7287,6 +7254,17 @@ function ensureIcuContainerVisitorLoaded(loader) {
7287
7254
  }
7288
7255
  }
7289
7256
 
7257
+ /**
7258
+ * @license
7259
+ * Copyright Google LLC All Rights Reserved.
7260
+ *
7261
+ * Use of this source code is governed by an MIT-style license that can be
7262
+ * found in the LICENSE file at https://angular.io/license
7263
+ */
7264
+ // Note: This hack is necessary so we don't erroneously get a circular dependency
7265
+ // failure based on types.
7266
+ const unusedValueExportToPlacateAjd$4 = 1;
7267
+
7290
7268
  /**
7291
7269
  * @license
7292
7270
  * Copyright Google LLC All Rights Reserved.
@@ -7369,7 +7347,7 @@ function getNearestLContainer(viewOrContainer) {
7369
7347
  * Use of this source code is governed by an MIT-style license that can be
7370
7348
  * found in the LICENSE file at https://angular.io/license
7371
7349
  */
7372
- const unusedValueToPlacateAjd$2 = unusedValueExportToPlacateAjd$7 + unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd$3 + unusedValueExportToPlacateAjd$6 + unusedValueExportToPlacateAjd$8;
7350
+ const unusedValueToPlacateAjd$2 = unusedValueExportToPlacateAjd$7 + unusedValueExportToPlacateAjd$5 + unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd$3 + unusedValueExportToPlacateAjd$8;
7373
7351
  /**
7374
7352
  * NOTE: for performance reasons, the possible actions are inlined within the function instead of
7375
7353
  * being passed as an argument.
@@ -7394,7 +7372,6 @@ function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, befo
7394
7372
  lNodeToHandle = lNodeToHandle[HOST];
7395
7373
  }
7396
7374
  const rNode = unwrapRNode(lNodeToHandle);
7397
- ngDevMode && !isProceduralRenderer(renderer) && assertDomNode(rNode);
7398
7375
  if (action === 0 /* WalkTNodeTreeAction.Create */ && parent !== null) {
7399
7376
  if (beforeNode == null) {
7400
7377
  nativeAppendChild(renderer, parent, rNode);
@@ -7421,17 +7398,14 @@ function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, befo
7421
7398
  function createTextNode(renderer, value) {
7422
7399
  ngDevMode && ngDevMode.rendererCreateTextNode++;
7423
7400
  ngDevMode && ngDevMode.rendererSetText++;
7424
- return isProceduralRenderer(renderer) ? renderer.createText(value) :
7425
- renderer.createTextNode(value);
7401
+ return renderer.createText(value);
7426
7402
  }
7427
7403
  function updateTextNode(renderer, rNode, value) {
7428
7404
  ngDevMode && ngDevMode.rendererSetText++;
7429
- isProceduralRenderer(renderer) ? renderer.setValue(rNode, value) : rNode.textContent = value;
7405
+ renderer.setValue(rNode, value);
7430
7406
  }
7431
7407
  function createCommentNode(renderer, value) {
7432
7408
  ngDevMode && ngDevMode.rendererCreateComment++;
7433
- // isProceduralRenderer check is not needed because both `Renderer2` and `Renderer3` have the same
7434
- // method name.
7435
7409
  return renderer.createComment(escapeCommentText(value));
7436
7410
  }
7437
7411
  /**
@@ -7443,14 +7417,7 @@ function createCommentNode(renderer, value) {
7443
7417
  */
7444
7418
  function createElementNode(renderer, name, namespace) {
7445
7419
  ngDevMode && ngDevMode.rendererCreateElement++;
7446
- if (isProceduralRenderer(renderer)) {
7447
- return renderer.createElement(name, namespace);
7448
- }
7449
- else {
7450
- const namespaceUri = namespace !== null ? getNamespaceUri(namespace) : null;
7451
- return namespaceUri === null ? renderer.createElement(name) :
7452
- renderer.createElementNS(namespaceUri, name);
7453
- }
7420
+ return renderer.createElement(name, namespace);
7454
7421
  }
7455
7422
  /**
7456
7423
  * Removes all DOM elements associated with a view.
@@ -7682,7 +7649,7 @@ function detachView(lContainer, removeIndex) {
7682
7649
  function destroyLView(tView, lView) {
7683
7650
  if (!(lView[FLAGS] & 128 /* LViewFlags.Destroyed */)) {
7684
7651
  const renderer = lView[RENDERER];
7685
- if (isProceduralRenderer(renderer) && renderer.destroyNode) {
7652
+ if (renderer.destroyNode) {
7686
7653
  applyView(tView, lView, renderer, 3 /* WalkTNodeTreeAction.Destroy */, null, null);
7687
7654
  }
7688
7655
  destroyViewTree(lView);
@@ -7710,7 +7677,7 @@ function cleanUpView(tView, lView) {
7710
7677
  executeOnDestroys(tView, lView);
7711
7678
  processCleanups(tView, lView);
7712
7679
  // For component views only, the local renderer is destroyed at clean up time.
7713
- if (lView[TVIEW].type === 1 /* TViewType.Component */ && isProceduralRenderer(lView[RENDERER])) {
7680
+ if (lView[TVIEW].type === 1 /* TViewType.Component */) {
7714
7681
  ngDevMode && ngDevMode.rendererDestroy++;
7715
7682
  lView[RENDERER].destroy();
7716
7683
  }
@@ -7886,30 +7853,17 @@ function getClosestRElement(tView, tNode, lView) {
7886
7853
  }
7887
7854
  }
7888
7855
  /**
7889
- * Inserts a native node before another native node for a given parent using {@link Renderer3}.
7890
- * This is a utility function that can be used when native nodes were determined - it abstracts an
7891
- * actual renderer being used.
7856
+ * Inserts a native node before another native node for a given parent.
7857
+ * This is a utility function that can be used when native nodes were determined.
7892
7858
  */
7893
7859
  function nativeInsertBefore(renderer, parent, child, beforeNode, isMove) {
7894
7860
  ngDevMode && ngDevMode.rendererInsertBefore++;
7895
- if (isProceduralRenderer(renderer)) {
7896
- renderer.insertBefore(parent, child, beforeNode, isMove);
7897
- }
7898
- else {
7899
- const targetParent = isTemplateNode(parent) ? parent.content : parent;
7900
- targetParent.insertBefore(child, beforeNode, isMove);
7901
- }
7861
+ renderer.insertBefore(parent, child, beforeNode, isMove);
7902
7862
  }
7903
7863
  function nativeAppendChild(renderer, parent, child) {
7904
7864
  ngDevMode && ngDevMode.rendererAppendChild++;
7905
7865
  ngDevMode && assertDefined(parent, 'parent node must be defined');
7906
- if (isProceduralRenderer(renderer)) {
7907
- renderer.appendChild(parent, child);
7908
- }
7909
- else {
7910
- const targetParent = isTemplateNode(parent) ? parent.content : parent;
7911
- targetParent.appendChild(child);
7912
- }
7866
+ renderer.appendChild(parent, child);
7913
7867
  }
7914
7868
  function nativeAppendOrInsertBefore(renderer, parent, child, beforeNode, isMove) {
7915
7869
  if (beforeNode !== null) {
@@ -7921,12 +7875,7 @@ function nativeAppendOrInsertBefore(renderer, parent, child, beforeNode, isMove)
7921
7875
  }
7922
7876
  /** Removes a node from the DOM given its native parent. */
7923
7877
  function nativeRemoveChild(renderer, parent, child, isHostElement) {
7924
- if (isProceduralRenderer(renderer)) {
7925
- renderer.removeChild(parent, child, isHostElement);
7926
- }
7927
- else {
7928
- parent.removeChild(child);
7929
- }
7878
+ renderer.removeChild(parent, child, isHostElement);
7930
7879
  }
7931
7880
  /** Checks if an element is a `<template>` node. */
7932
7881
  function isTemplateNode(node) {
@@ -7936,13 +7885,13 @@ function isTemplateNode(node) {
7936
7885
  * Returns a native parent of a given native node.
7937
7886
  */
7938
7887
  function nativeParentNode(renderer, node) {
7939
- return (isProceduralRenderer(renderer) ? renderer.parentNode(node) : node.parentNode);
7888
+ return renderer.parentNode(node);
7940
7889
  }
7941
7890
  /**
7942
7891
  * Returns a native sibling of a given native node.
7943
7892
  */
7944
7893
  function nativeNextSibling(renderer, node) {
7945
- return isProceduralRenderer(renderer) ? renderer.nextSibling(node) : node.nextSibling;
7894
+ return renderer.nextSibling(node);
7946
7895
  }
7947
7896
  /**
7948
7897
  * Find a node in front of which `currentTNode` should be inserted.
@@ -8251,39 +8200,22 @@ function applyContainer(renderer, action, lContainer, parentRElement, beforeNode
8251
8200
  * otherwise).
8252
8201
  */
8253
8202
  function applyStyling(renderer, isClassBased, rNode, prop, value) {
8254
- const isProcedural = isProceduralRenderer(renderer);
8255
8203
  if (isClassBased) {
8256
8204
  // We actually want JS true/false here because any truthy value should add the class
8257
8205
  if (!value) {
8258
8206
  ngDevMode && ngDevMode.rendererRemoveClass++;
8259
- if (isProcedural) {
8260
- renderer.removeClass(rNode, prop);
8261
- }
8262
- else {
8263
- rNode.classList.remove(prop);
8264
- }
8207
+ renderer.removeClass(rNode, prop);
8265
8208
  }
8266
8209
  else {
8267
8210
  ngDevMode && ngDevMode.rendererAddClass++;
8268
- if (isProcedural) {
8269
- renderer.addClass(rNode, prop);
8270
- }
8271
- else {
8272
- ngDevMode && assertDefined(rNode.classList, 'HTMLElement expected');
8273
- rNode.classList.add(prop);
8274
- }
8211
+ renderer.addClass(rNode, prop);
8275
8212
  }
8276
8213
  }
8277
8214
  else {
8278
8215
  let flags = prop.indexOf('-') === -1 ? undefined : RendererStyleFlags2.DashCase;
8279
8216
  if (value == null /** || value === undefined */) {
8280
8217
  ngDevMode && ngDevMode.rendererRemoveStyle++;
8281
- if (isProcedural) {
8282
- renderer.removeStyle(rNode, prop, flags);
8283
- }
8284
- else {
8285
- rNode.style.removeProperty(prop);
8286
- }
8218
+ renderer.removeStyle(rNode, prop, flags);
8287
8219
  }
8288
8220
  else {
8289
8221
  // A value is important if it ends with `!important`. The style
@@ -8295,13 +8227,7 @@ function applyStyling(renderer, isClassBased, rNode, prop, value) {
8295
8227
  flags |= RendererStyleFlags2.Important;
8296
8228
  }
8297
8229
  ngDevMode && ngDevMode.rendererSetStyle++;
8298
- if (isProcedural) {
8299
- renderer.setStyle(rNode, prop, value, flags);
8300
- }
8301
- else {
8302
- ngDevMode && assertDefined(rNode.style, 'HTMLElement expected');
8303
- rNode.style.setProperty(prop, value, isImportant ? 'important' : '');
8304
- }
8230
+ renderer.setStyle(rNode, prop, value, flags);
8305
8231
  }
8306
8232
  }
8307
8233
  }
@@ -8317,12 +8243,7 @@ function applyStyling(renderer, isClassBased, rNode, prop, value) {
8317
8243
  */
8318
8244
  function writeDirectStyle(renderer, element, newValue) {
8319
8245
  ngDevMode && assertString(newValue, '\'newValue\' should be a string');
8320
- if (isProceduralRenderer(renderer)) {
8321
- renderer.setAttribute(element, 'style', newValue);
8322
- }
8323
- else {
8324
- element.style.cssText = newValue;
8325
- }
8246
+ renderer.setAttribute(element, 'style', newValue);
8326
8247
  ngDevMode && ngDevMode.rendererSetStyle++;
8327
8248
  }
8328
8249
  /**
@@ -8337,17 +8258,12 @@ function writeDirectStyle(renderer, element, newValue) {
8337
8258
  */
8338
8259
  function writeDirectClass(renderer, element, newValue) {
8339
8260
  ngDevMode && assertString(newValue, '\'newValue\' should be a string');
8340
- if (isProceduralRenderer(renderer)) {
8341
- if (newValue === '') {
8342
- // There are tests in `google3` which expect `element.getAttribute('class')` to be `null`.
8343
- renderer.removeAttribute(element, 'class');
8344
- }
8345
- else {
8346
- renderer.setAttribute(element, 'class', newValue);
8347
- }
8261
+ if (newValue === '') {
8262
+ // There are tests in `google3` which expect `element.getAttribute('class')` to be `null`.
8263
+ renderer.removeAttribute(element, 'class');
8348
8264
  }
8349
8265
  else {
8350
- element.className = newValue;
8266
+ renderer.setAttribute(element, 'class', newValue);
8351
8267
  }
8352
8268
  ngDevMode && ngDevMode.rendererSetClassName++;
8353
8269
  }
@@ -8397,7 +8313,7 @@ function classIndexOf(className, classToSearch, startingIndex) {
8397
8313
  * Use of this source code is governed by an MIT-style license that can be
8398
8314
  * found in the LICENSE file at https://angular.io/license
8399
8315
  */
8400
- const unusedValueToPlacateAjd$1 = unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd$3;
8316
+ const unusedValueToPlacateAjd$1 = unusedValueExportToPlacateAjd$5 + unusedValueExportToPlacateAjd$4;
8401
8317
  const NG_TEMPLATE_SELECTOR = 'ng-template';
8402
8318
  /**
8403
8319
  * Search the `TAttributes` to see if it contains `cssClassToMatch` (case insensitive)
@@ -9512,6 +9428,18 @@ class R3Injector extends EnvironmentInjector {
9512
9428
  onDestroy(callback) {
9513
9429
  this._onDestroyHooks.push(callback);
9514
9430
  }
9431
+ runInContext(fn) {
9432
+ this.assertNotDestroyed();
9433
+ const previousInjector = setCurrentInjector(this);
9434
+ const previousInjectImplementation = setInjectImplementation(undefined);
9435
+ try {
9436
+ return fn();
9437
+ }
9438
+ finally {
9439
+ setCurrentInjector(previousInjector);
9440
+ setInjectImplementation(previousInjectImplementation);
9441
+ }
9442
+ }
9515
9443
  get(token, notFoundValue = THROW_IF_NOT_FOUND, flags = InjectFlags.Default) {
9516
9444
  this.assertNotDestroyed();
9517
9445
  // Set the injection context.
@@ -10926,6 +10854,9 @@ function handleUnknownPropertyError(propName, tagName, nodeType, lView) {
10926
10854
  `the ${schemas} of this component.`;
10927
10855
  }
10928
10856
  }
10857
+ reportUnknownPropertyError(message);
10858
+ }
10859
+ function reportUnknownPropertyError(message) {
10929
10860
  if (shouldThrowErrorOnUnknownProperty) {
10930
10861
  throw new RuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message);
10931
10862
  }
@@ -11812,6 +11743,13 @@ class LContainerDebug {
11812
11743
  }
11813
11744
  }
11814
11745
 
11746
+ /**
11747
+ * @license
11748
+ * Copyright Google LLC All Rights Reserved.
11749
+ *
11750
+ * Use of this source code is governed by an MIT-style license that can be
11751
+ * found in the LICENSE file at https://angular.io/license
11752
+ */
11815
11753
  /**
11816
11754
  * A permanent marker promise which signifies that the current CD tree is
11817
11755
  * clean.
@@ -11879,7 +11817,7 @@ function refreshChildComponents(hostLView, components) {
11879
11817
  /** Renders child components in the current view (creation mode). */
11880
11818
  function renderChildComponents(hostLView, components) {
11881
11819
  for (let i = 0; i < components.length; i++) {
11882
- renderComponent$1(hostLView, components[i]);
11820
+ renderComponent(hostLView, components[i]);
11883
11821
  }
11884
11822
  }
11885
11823
  function createLView(parentLView, tView, context, flags, host, tHostNode, rendererFactory, renderer, sanitizer, injector, embeddedViewInjector) {
@@ -12397,16 +12335,6 @@ function createViewBlueprint(bindingStartIndex, initialViewLength) {
12397
12335
  function createError(text, token) {
12398
12336
  return new Error(`Renderer: ${text} [${stringifyForError(token)}]`);
12399
12337
  }
12400
- function assertHostNodeExists(rElement, elementOrSelector) {
12401
- if (!rElement) {
12402
- if (typeof elementOrSelector === 'string') {
12403
- throw createError('Host node with selector not found:', elementOrSelector);
12404
- }
12405
- else {
12406
- throw createError('Host node is required:', elementOrSelector);
12407
- }
12408
- }
12409
- }
12410
12338
  /**
12411
12339
  * Locates the host native element, used for bootstrapping existing nodes into rendering pipeline.
12412
12340
  *
@@ -12415,21 +12343,9 @@ function assertHostNodeExists(rElement, elementOrSelector) {
12415
12343
  * @param encapsulation View Encapsulation defined for component that requests host element.
12416
12344
  */
12417
12345
  function locateHostElement(renderer, elementOrSelector, encapsulation) {
12418
- if (isProceduralRenderer(renderer)) {
12419
- // When using native Shadow DOM, do not clear host element to allow native slot projection
12420
- const preserveContent = encapsulation === ViewEncapsulation.ShadowDom;
12421
- return renderer.selectRootElement(elementOrSelector, preserveContent);
12422
- }
12423
- let rElement = typeof elementOrSelector === 'string' ?
12424
- renderer.querySelector(elementOrSelector) :
12425
- elementOrSelector;
12426
- ngDevMode && assertHostNodeExists(rElement, elementOrSelector);
12427
- // Always clear host element's content when Renderer3 is in use. For procedural renderer case we
12428
- // make it depend on whether ShadowDom encapsulation is used (in which case the content should be
12429
- // preserved to allow native slot projection). ShadowDom encapsulation requires procedural
12430
- // renderer, and procedural renderer case is handled above.
12431
- rElement.textContent = '';
12432
- return rElement;
12346
+ // When using native Shadow DOM, do not clear host element to allow native slot projection
12347
+ const preserveContent = encapsulation === ViewEncapsulation.ShadowDom;
12348
+ return renderer.selectRootElement(elementOrSelector, preserveContent);
12433
12349
  }
12434
12350
  /**
12435
12351
  * Saves context for this cleanup function in LView.cleanupInstances.
@@ -12644,13 +12560,7 @@ function elementPropertyInternal(tView, tNode, lView, propName, value, renderer,
12644
12560
  // It is assumed that the sanitizer is only added when the compiler determines that the
12645
12561
  // property is risky, so sanitization can be done without further checks.
12646
12562
  value = sanitizer != null ? sanitizer(value, tNode.value || '', propName) : value;
12647
- if (isProceduralRenderer(renderer)) {
12648
- renderer.setProperty(element, propName, value);
12649
- }
12650
- else if (!isAnimationProp(propName)) {
12651
- element.setProperty ? element.setProperty(propName, value) :
12652
- element[propName] = value;
12653
- }
12563
+ renderer.setProperty(element, propName, value);
12654
12564
  }
12655
12565
  else if (tNode.type & 12 /* TNodeType.AnyContainer */) {
12656
12566
  // If the node is a container and the property didn't
@@ -12674,23 +12584,15 @@ function setNgReflectProperty(lView, element, type, attrName, value) {
12674
12584
  const debugValue = normalizeDebugBindingValue(value);
12675
12585
  if (type & 3 /* TNodeType.AnyRNode */) {
12676
12586
  if (value == null) {
12677
- isProceduralRenderer(renderer) ? renderer.removeAttribute(element, attrName) :
12678
- element.removeAttribute(attrName);
12587
+ renderer.removeAttribute(element, attrName);
12679
12588
  }
12680
12589
  else {
12681
- isProceduralRenderer(renderer) ?
12682
- renderer.setAttribute(element, attrName, debugValue) :
12683
- element.setAttribute(attrName, debugValue);
12590
+ renderer.setAttribute(element, attrName, debugValue);
12684
12591
  }
12685
12592
  }
12686
12593
  else {
12687
12594
  const textContent = escapeCommentText(`bindings=${JSON.stringify({ [attrName]: debugValue }, null, 2)}`);
12688
- if (isProceduralRenderer(renderer)) {
12689
- renderer.setValue(element, textContent);
12690
- }
12691
- else {
12692
- element.textContent = textContent;
12693
- }
12595
+ renderer.setValue(element, textContent);
12694
12596
  }
12695
12597
  }
12696
12598
  function setNgReflectProperties(lView, element, type, dataValue, value) {
@@ -12720,6 +12622,7 @@ function instantiateRootComponent(tView, lView, def) {
12720
12622
  ngDevMode &&
12721
12623
  assertEqual(directiveIndex, rootTNode.directiveStart, 'Because this is a root component the allocated expando should match the TNode component.');
12722
12624
  configureViewWithDirective(tView, rootTNode, lView, directiveIndex, def);
12625
+ initializeInputAndOutputAliases(tView, rootTNode);
12723
12626
  }
12724
12627
  const directive = getNodeInjectable(lView, tView, rootTNode.directiveStart, rootTNode);
12725
12628
  attachPatchData(directive, lView);
@@ -13044,19 +12947,12 @@ function elementAttributeInternal(tNode, lView, name, value, sanitizer, namespac
13044
12947
  function setElementAttribute(renderer, element, namespace, tagName, name, value, sanitizer) {
13045
12948
  if (value == null) {
13046
12949
  ngDevMode && ngDevMode.rendererRemoveAttribute++;
13047
- isProceduralRenderer(renderer) ? renderer.removeAttribute(element, name, namespace) :
13048
- element.removeAttribute(name);
12950
+ renderer.removeAttribute(element, name, namespace);
13049
12951
  }
13050
12952
  else {
13051
12953
  ngDevMode && ngDevMode.rendererSetAttribute++;
13052
12954
  const strValue = sanitizer == null ? renderStringify(value) : sanitizer(value, tagName || '', name);
13053
- if (isProceduralRenderer(renderer)) {
13054
- renderer.setAttribute(element, name, strValue, namespace);
13055
- }
13056
- else {
13057
- namespace ? element.setAttributeNS(namespace, name, strValue) :
13058
- element.setAttribute(name, strValue);
13059
- }
12955
+ renderer.setAttribute(element, name, strValue, namespace);
13060
12956
  }
13061
12957
  }
13062
12958
  /**
@@ -13148,7 +13044,6 @@ const LContainerArray = class LContainer extends Array {
13148
13044
  */
13149
13045
  function createLContainer(hostNative, currentView, native, tNode) {
13150
13046
  ngDevMode && assertLView(currentView);
13151
- ngDevMode && !isProceduralRenderer(currentView[RENDERER]) && assertDomNode(native);
13152
13047
  // https://jsperf.com/array-literal-vs-new-array-really
13153
13048
  const lContainer = new (ngDevMode ? LContainerArray : Array)(hostNative, // host native
13154
13049
  true, // Boolean `true` in this position signifies that this is an `LContainer`
@@ -13264,7 +13159,7 @@ function refreshContainsDirtyView(lView) {
13264
13159
  }
13265
13160
  }
13266
13161
  }
13267
- function renderComponent$1(hostLView, componentHostIdx) {
13162
+ function renderComponent(hostLView, componentHostIdx) {
13268
13163
  ngDevMode && assertEqual(isCreationMode(hostLView), true, 'Should be run in creation mode');
13269
13164
  const componentView = getComponentLViewByIndex(componentHostIdx, hostLView);
13270
13165
  const componentTView = componentView[TVIEW];
@@ -13616,48 +13511,135 @@ function computeStaticStyling(tNode, attrs, writeToHost) {
13616
13511
  * Use of this source code is governed by an MIT-style license that can be
13617
13512
  * found in the LICENSE file at https://angular.io/license
13618
13513
  */
13514
+ // TODO: A hack to not pull in the NullInjector from @angular/core.
13515
+ const NULL_INJECTOR = {
13516
+ get: (token, notFoundValue) => {
13517
+ throwProviderNotFoundError(token, 'NullInjector');
13518
+ }
13519
+ };
13619
13520
  /**
13620
- * Synchronously perform change detection on a component (and possibly its sub-components).
13521
+ * Creates the root component view and the root component node.
13621
13522
  *
13622
- * This function triggers change detection in a synchronous way on a component.
13523
+ * @param rNode Render host element.
13524
+ * @param def ComponentDef
13525
+ * @param rootView The parent view where the host node is stored
13526
+ * @param rendererFactory Factory to be used for creating child renderers.
13527
+ * @param hostRenderer The current renderer
13528
+ * @param sanitizer The sanitizer, if provided
13623
13529
  *
13624
- * @param component The component which the change detection should be performed on.
13530
+ * @returns Component view created
13625
13531
  */
13626
- function detectChanges(component) {
13627
- const view = getComponentViewByInstance(component);
13628
- detectChangesInternal(view[TVIEW], view, component);
13532
+ function createRootComponentView(rNode, def, rootView, rendererFactory, hostRenderer, sanitizer) {
13533
+ const tView = rootView[TVIEW];
13534
+ const index = HEADER_OFFSET;
13535
+ ngDevMode && assertIndexInRange(rootView, index);
13536
+ rootView[index] = rNode;
13537
+ // '#host' is added here as we don't know the real host DOM name (we don't want to read it) and at
13538
+ // the same time we want to communicate the debug `TNode` that this is a special `TNode`
13539
+ // representing a host element.
13540
+ const tNode = getOrCreateTNode(tView, index, 2 /* TNodeType.Element */, '#host', null);
13541
+ const mergedAttrs = tNode.mergedAttrs = def.hostAttrs;
13542
+ if (mergedAttrs !== null) {
13543
+ computeStaticStyling(tNode, mergedAttrs, true);
13544
+ if (rNode !== null) {
13545
+ setUpAttributes(hostRenderer, rNode, mergedAttrs);
13546
+ if (tNode.classes !== null) {
13547
+ writeDirectClass(hostRenderer, rNode, tNode.classes);
13548
+ }
13549
+ if (tNode.styles !== null) {
13550
+ writeDirectStyle(hostRenderer, rNode, tNode.styles);
13551
+ }
13552
+ }
13553
+ }
13554
+ const viewRenderer = rendererFactory.createRenderer(rNode, def);
13555
+ const componentView = createLView(rootView, getOrCreateTComponentView(def), null, def.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, rootView[index], tNode, rendererFactory, viewRenderer, sanitizer || null, null, null);
13556
+ if (tView.firstCreatePass) {
13557
+ diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, rootView), tView, def.type);
13558
+ markAsComponentHost(tView, tNode);
13559
+ initTNodeFlags(tNode, rootView.length, 1);
13560
+ }
13561
+ addToViewTree(rootView, componentView);
13562
+ // Store component view at node index, with node as the HOST
13563
+ return rootView[index] = componentView;
13629
13564
  }
13630
13565
  /**
13631
- * Marks the component as dirty (needing change detection). Marking a component dirty will
13632
- * schedule a change detection on it at some point in the future.
13633
- *
13634
- * Marking an already dirty component as dirty won't do anything. Only one outstanding change
13635
- * detection can be scheduled per component tree.
13566
+ * Creates a root component and sets it up with features and host bindings. Shared by
13567
+ * renderComponent() and ViewContainerRef.createComponent().
13568
+ */
13569
+ function createRootComponent(componentView, componentDef, rootLView, rootContext, hostFeatures) {
13570
+ const tView = rootLView[TVIEW];
13571
+ // Create directive instance with factory() and store at next index in viewData
13572
+ const component = instantiateRootComponent(tView, rootLView, componentDef);
13573
+ rootContext.components.push(component);
13574
+ componentView[CONTEXT] = component;
13575
+ if (hostFeatures !== null) {
13576
+ for (const feature of hostFeatures) {
13577
+ feature(component, componentDef);
13578
+ }
13579
+ }
13580
+ // We want to generate an empty QueryList for root content queries for backwards
13581
+ // compatibility with ViewEngine.
13582
+ if (componentDef.contentQueries) {
13583
+ const tNode = getCurrentTNode();
13584
+ ngDevMode && assertDefined(tNode, 'TNode expected');
13585
+ componentDef.contentQueries(1 /* RenderFlags.Create */, component, tNode.directiveStart);
13586
+ }
13587
+ const rootTNode = getCurrentTNode();
13588
+ ngDevMode && assertDefined(rootTNode, 'tNode should have been already created');
13589
+ if (tView.firstCreatePass &&
13590
+ (componentDef.hostBindings !== null || componentDef.hostAttrs !== null)) {
13591
+ setSelectedIndex(rootTNode.index);
13592
+ const rootTView = rootLView[TVIEW];
13593
+ registerHostBindingOpCodes(rootTView, rootTNode, rootLView, rootTNode.directiveStart, rootTNode.directiveEnd, componentDef);
13594
+ invokeHostBindingsInCreationMode(componentDef, component);
13595
+ }
13596
+ return component;
13597
+ }
13598
+ function createRootContext(scheduler, playerHandler) {
13599
+ return {
13600
+ components: [],
13601
+ scheduler: scheduler || defaultScheduler,
13602
+ clean: CLEAN_PROMISE,
13603
+ playerHandler: playerHandler || null,
13604
+ flags: 0 /* RootContextFlags.Empty */
13605
+ };
13606
+ }
13607
+ /**
13608
+ * Used to enable lifecycle hooks on the root component.
13636
13609
  *
13637
- * @param component Component to mark as dirty.
13610
+ * Include this feature when calling `renderComponent` if the root component
13611
+ * you are rendering has lifecycle hooks defined. Otherwise, the hooks won't
13612
+ * be called properly.
13613
+ *
13614
+ * Example:
13615
+ *
13616
+ * ```
13617
+ * renderComponent(AppComponent, {hostFeatures: [LifecycleHooksFeature]});
13618
+ * ```
13638
13619
  */
13639
- function markDirty(component) {
13640
- ngDevMode && assertDefined(component, 'component');
13641
- const rootView = markViewDirty(getComponentViewByInstance(component));
13642
- ngDevMode && assertDefined(rootView[CONTEXT], 'rootContext should be defined');
13643
- scheduleTick(rootView[CONTEXT], 1 /* RootContextFlags.DetectChanges */);
13620
+ function LifecycleHooksFeature() {
13621
+ const tNode = getCurrentTNode();
13622
+ ngDevMode && assertDefined(tNode, 'TNode is required');
13623
+ registerPostOrderHooks(getLView()[TVIEW], tNode);
13644
13624
  }
13645
13625
  /**
13646
- * Used to perform change detection on the whole application.
13626
+ * Wait on component until it is rendered.
13647
13627
  *
13648
- * This is equivalent to `detectChanges`, but invoked on root component. Additionally, `tick`
13649
- * executes lifecycle hooks and conditionally checks components based on their
13650
- * `ChangeDetectionStrategy` and dirtiness.
13628
+ * This function returns a `Promise` which is resolved when the component's
13629
+ * change detection is executed. This is determined by finding the scheduler
13630
+ * associated with the `component`'s render tree and waiting until the scheduler
13631
+ * flushes. If nothing is scheduled, the function returns a resolved promise.
13651
13632
  *
13652
- * The preferred way to trigger change detection is to call `markDirty`. `markDirty` internally
13653
- * schedules `tick` using a scheduler in order to coalesce multiple `markDirty` calls into a
13654
- * single change detection run. By default, the scheduler is `requestAnimationFrame`, but can
13655
- * be changed when calling `renderComponent` and providing the `scheduler` option.
13633
+ * Example:
13634
+ * ```
13635
+ * await whenRendered(myComponent);
13636
+ * ```
13637
+ *
13638
+ * @param component Component to wait upon
13639
+ * @returns Promise which resolves when the component is rendered.
13656
13640
  */
13657
- function tick(component) {
13658
- const rootView = getRootView(component);
13659
- const rootContext = rootView[CONTEXT];
13660
- tickRootContext(rootContext);
13641
+ function whenRendered(component) {
13642
+ return getRootContext(component).clean;
13661
13643
  }
13662
13644
 
13663
13645
  /**
@@ -13667,407 +13649,263 @@ function tick(component) {
13667
13649
  * Use of this source code is governed by an MIT-style license that can be
13668
13650
  * found in the LICENSE file at https://angular.io/license
13669
13651
  */
13652
+ function getSuperType(type) {
13653
+ return Object.getPrototypeOf(type.prototype).constructor;
13654
+ }
13670
13655
  /**
13671
- * Retrieves the component instance associated with a given DOM element.
13672
- *
13673
- * @usageNotes
13674
- * Given the following DOM structure:
13675
- *
13676
- * ```html
13677
- * <app-root>
13678
- * <div>
13679
- * <child-comp></child-comp>
13680
- * </div>
13681
- * </app-root>
13682
- * ```
13683
- *
13684
- * Calling `getComponent` on `<child-comp>` will return the instance of `ChildComponent`
13685
- * associated with this DOM element.
13686
- *
13687
- * Calling the function on `<app-root>` will return the `MyApp` instance.
13688
- *
13689
- *
13690
- * @param element DOM element from which the component should be retrieved.
13691
- * @returns Component instance associated with the element or `null` if there
13692
- * is no component associated with it.
13656
+ * Merges the definition from a super class to a sub class.
13657
+ * @param definition The definition that is a SubClass of another directive of component
13693
13658
  *
13694
- * @publicApi
13695
- * @globalApi ng
13659
+ * @codeGenApi
13696
13660
  */
13697
- function getComponent$1(element) {
13698
- ngDevMode && assertDomElement(element);
13699
- const context = getLContext(element);
13700
- if (context === null)
13701
- return null;
13702
- if (context.component === undefined) {
13703
- const lView = context.lView;
13704
- if (lView === null) {
13705
- return null;
13661
+ function ɵɵInheritDefinitionFeature(definition) {
13662
+ let superType = getSuperType(definition.type);
13663
+ let shouldInheritFields = true;
13664
+ const inheritanceChain = [definition];
13665
+ while (superType) {
13666
+ let superDef = undefined;
13667
+ if (isComponentDef(definition)) {
13668
+ // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
13669
+ superDef = superType.ɵcmp || superType.ɵdir;
13706
13670
  }
13707
- context.component = getComponentAtNodeIndex(context.nodeIndex, lView);
13671
+ else {
13672
+ if (superType.ɵcmp) {
13673
+ throw new RuntimeError(903 /* RuntimeErrorCode.INVALID_INHERITANCE */, ngDevMode &&
13674
+ `Directives cannot inherit Components. Directive ${stringifyForError(definition.type)} is attempting to extend component ${stringifyForError(superType)}`);
13675
+ }
13676
+ // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
13677
+ superDef = superType.ɵdir;
13678
+ }
13679
+ if (superDef) {
13680
+ if (shouldInheritFields) {
13681
+ inheritanceChain.push(superDef);
13682
+ // Some fields in the definition may be empty, if there were no values to put in them that
13683
+ // would've justified object creation. Unwrap them if necessary.
13684
+ const writeableDef = definition;
13685
+ writeableDef.inputs = maybeUnwrapEmpty(definition.inputs);
13686
+ writeableDef.declaredInputs = maybeUnwrapEmpty(definition.declaredInputs);
13687
+ writeableDef.outputs = maybeUnwrapEmpty(definition.outputs);
13688
+ // Merge hostBindings
13689
+ const superHostBindings = superDef.hostBindings;
13690
+ superHostBindings && inheritHostBindings(definition, superHostBindings);
13691
+ // Merge queries
13692
+ const superViewQuery = superDef.viewQuery;
13693
+ const superContentQueries = superDef.contentQueries;
13694
+ superViewQuery && inheritViewQuery(definition, superViewQuery);
13695
+ superContentQueries && inheritContentQueries(definition, superContentQueries);
13696
+ // Merge inputs and outputs
13697
+ fillProperties(definition.inputs, superDef.inputs);
13698
+ fillProperties(definition.declaredInputs, superDef.declaredInputs);
13699
+ fillProperties(definition.outputs, superDef.outputs);
13700
+ // Merge animations metadata.
13701
+ // If `superDef` is a Component, the `data` field is present (defaults to an empty object).
13702
+ if (isComponentDef(superDef) && superDef.data.animation) {
13703
+ // If super def is a Component, the `definition` is also a Component, since Directives can
13704
+ // not inherit Components (we throw an error above and cannot reach this code).
13705
+ const defData = definition.data;
13706
+ defData.animation = (defData.animation || []).concat(superDef.data.animation);
13707
+ }
13708
+ }
13709
+ // Run parent features
13710
+ const features = superDef.features;
13711
+ if (features) {
13712
+ for (let i = 0; i < features.length; i++) {
13713
+ const feature = features[i];
13714
+ if (feature && feature.ngInherit) {
13715
+ feature(definition);
13716
+ }
13717
+ // If `InheritDefinitionFeature` is a part of the current `superDef`, it means that this
13718
+ // def already has all the necessary information inherited from its super class(es), so we
13719
+ // can stop merging fields from super classes. However we need to iterate through the
13720
+ // prototype chain to look for classes that might contain other "features" (like
13721
+ // NgOnChanges), which we should invoke for the original `definition`. We set the
13722
+ // `shouldInheritFields` flag to indicate that, essentially skipping fields inheritance
13723
+ // logic and only invoking functions from the "features" list.
13724
+ if (feature === ɵɵInheritDefinitionFeature) {
13725
+ shouldInheritFields = false;
13726
+ }
13727
+ }
13728
+ }
13729
+ }
13730
+ superType = Object.getPrototypeOf(superType);
13708
13731
  }
13709
- return context.component;
13710
- }
13711
- /**
13712
- * If inside an embedded view (e.g. `*ngIf` or `*ngFor`), retrieves the context of the embedded
13713
- * view that the element is part of. Otherwise retrieves the instance of the component whose view
13714
- * owns the element (in this case, the result is the same as calling `getOwningComponent`).
13715
- *
13716
- * @param element Element for which to get the surrounding component instance.
13717
- * @returns Instance of the component that is around the element or null if the element isn't
13718
- * inside any component.
13719
- *
13720
- * @publicApi
13721
- * @globalApi ng
13722
- */
13723
- function getContext(element) {
13724
- assertDomElement(element);
13725
- const context = getLContext(element);
13726
- const lView = context ? context.lView : null;
13727
- return lView === null ? null : lView[CONTEXT];
13732
+ mergeHostAttrsAcrossInheritance(inheritanceChain);
13728
13733
  }
13729
13734
  /**
13730
- * Retrieves the component instance whose view contains the DOM element.
13731
- *
13732
- * For example, if `<child-comp>` is used in the template of `<app-comp>`
13733
- * (i.e. a `ViewChild` of `<app-comp>`), calling `getOwningComponent` on `<child-comp>`
13734
- * would return `<app-comp>`.
13735
- *
13736
- * @param elementOrDir DOM element, component or directive instance
13737
- * for which to retrieve the root components.
13738
- * @returns Component instance whose view owns the DOM element or null if the element is not
13739
- * part of a component view.
13735
+ * Merge the `hostAttrs` and `hostVars` from the inherited parent to the base class.
13740
13736
  *
13741
- * @publicApi
13742
- * @globalApi ng
13737
+ * @param inheritanceChain A list of `WritableDefs` starting at the top most type and listing
13738
+ * sub-types in order. For each type take the `hostAttrs` and `hostVars` and merge it with the child
13739
+ * type.
13743
13740
  */
13744
- function getOwningComponent(elementOrDir) {
13745
- const context = getLContext(elementOrDir);
13746
- let lView = context ? context.lView : null;
13747
- if (lView === null)
13748
- return null;
13749
- let parent;
13750
- while (lView[TVIEW].type === 2 /* TViewType.Embedded */ && (parent = getLViewParent(lView))) {
13751
- lView = parent;
13741
+ function mergeHostAttrsAcrossInheritance(inheritanceChain) {
13742
+ let hostVars = 0;
13743
+ let hostAttrs = null;
13744
+ // We process the inheritance order from the base to the leaves here.
13745
+ for (let i = inheritanceChain.length - 1; i >= 0; i--) {
13746
+ const def = inheritanceChain[i];
13747
+ // For each `hostVars`, we need to add the superclass amount.
13748
+ def.hostVars = (hostVars += def.hostVars);
13749
+ // for each `hostAttrs` we need to merge it with superclass.
13750
+ def.hostAttrs =
13751
+ mergeHostAttrs(def.hostAttrs, hostAttrs = mergeHostAttrs(hostAttrs, def.hostAttrs));
13752
13752
  }
13753
- return lView[FLAGS] & 256 /* LViewFlags.IsRoot */ ? null : lView[CONTEXT];
13754
13753
  }
13755
- /**
13756
- * Retrieves all root components associated with a DOM element, directive or component instance.
13757
- * Root components are those which have been bootstrapped by Angular.
13758
- *
13759
- * @param elementOrDir DOM element, component or directive instance
13760
- * for which to retrieve the root components.
13761
- * @returns Root components associated with the target object.
13762
- *
13763
- * @publicApi
13764
- * @globalApi ng
13765
- */
13766
- function getRootComponents(elementOrDir) {
13767
- const lView = readPatchedLView(elementOrDir);
13768
- return lView !== null ? [...getRootContext(lView).components] : [];
13769
- }
13770
- /**
13771
- * Retrieves an `Injector` associated with an element, component or directive instance.
13772
- *
13773
- * @param elementOrDir DOM element, component or directive instance for which to
13774
- * retrieve the injector.
13775
- * @returns Injector associated with the element, component or directive instance.
13776
- *
13777
- * @publicApi
13778
- * @globalApi ng
13779
- */
13780
- function getInjector(elementOrDir) {
13781
- const context = getLContext(elementOrDir);
13782
- const lView = context ? context.lView : null;
13783
- if (lView === null)
13784
- return Injector.NULL;
13785
- const tNode = lView[TVIEW].data[context.nodeIndex];
13786
- return new NodeInjector(tNode, lView);
13787
- }
13788
- /**
13789
- * Retrieve a set of injection tokens at a given DOM node.
13790
- *
13791
- * @param element Element for which the injection tokens should be retrieved.
13792
- */
13793
- function getInjectionTokens(element) {
13794
- const context = getLContext(element);
13795
- const lView = context ? context.lView : null;
13796
- if (lView === null)
13797
- return [];
13798
- const tView = lView[TVIEW];
13799
- const tNode = tView.data[context.nodeIndex];
13800
- const providerTokens = [];
13801
- const startIndex = tNode.providerIndexes & 1048575 /* TNodeProviderIndexes.ProvidersStartIndexMask */;
13802
- const endIndex = tNode.directiveEnd;
13803
- for (let i = startIndex; i < endIndex; i++) {
13804
- let value = tView.data[i];
13805
- if (isDirectiveDefHack(value)) {
13806
- // The fact that we sometimes store Type and sometimes DirectiveDef in this location is a
13807
- // design flaw. We should always store same type so that we can be monomorphic. The issue
13808
- // is that for Components/Directives we store the def instead the type. The correct behavior
13809
- // is that we should always be storing injectable type in this location.
13810
- value = value.type;
13811
- }
13812
- providerTokens.push(value);
13754
+ function maybeUnwrapEmpty(value) {
13755
+ if (value === EMPTY_OBJ) {
13756
+ return {};
13813
13757
  }
13814
- return providerTokens;
13815
- }
13816
- /**
13817
- * Retrieves directive instances associated with a given DOM node. Does not include
13818
- * component instances.
13819
- *
13820
- * @usageNotes
13821
- * Given the following DOM structure:
13822
- *
13823
- * ```html
13824
- * <app-root>
13825
- * <button my-button></button>
13826
- * <my-comp></my-comp>
13827
- * </app-root>
13828
- * ```
13829
- *
13830
- * Calling `getDirectives` on `<button>` will return an array with an instance of the `MyButton`
13831
- * directive that is associated with the DOM node.
13832
- *
13833
- * Calling `getDirectives` on `<my-comp>` will return an empty array.
13834
- *
13835
- * @param node DOM node for which to get the directives.
13836
- * @returns Array of directives associated with the node.
13837
- *
13838
- * @publicApi
13839
- * @globalApi ng
13840
- */
13841
- function getDirectives(node) {
13842
- // Skip text nodes because we can't have directives associated with them.
13843
- if (node instanceof Text) {
13758
+ else if (value === EMPTY_ARRAY) {
13844
13759
  return [];
13845
13760
  }
13846
- const context = getLContext(node);
13847
- const lView = context ? context.lView : null;
13848
- if (lView === null) {
13849
- return [];
13761
+ else {
13762
+ return value;
13850
13763
  }
13851
- const tView = lView[TVIEW];
13852
- const nodeIndex = context.nodeIndex;
13853
- if (!tView?.data[nodeIndex]) {
13854
- return [];
13764
+ }
13765
+ function inheritViewQuery(definition, superViewQuery) {
13766
+ const prevViewQuery = definition.viewQuery;
13767
+ if (prevViewQuery) {
13768
+ definition.viewQuery = (rf, ctx) => {
13769
+ superViewQuery(rf, ctx);
13770
+ prevViewQuery(rf, ctx);
13771
+ };
13855
13772
  }
13856
- if (context.directives === undefined) {
13857
- context.directives = getDirectivesAtNodeIndex(nodeIndex, lView, false);
13773
+ else {
13774
+ definition.viewQuery = superViewQuery;
13858
13775
  }
13859
- // The `directives` in this case are a named array called `LComponentView`. Clone the
13860
- // result so we don't expose an internal data structure in the user's console.
13861
- return context.directives === null ? [] : [...context.directives];
13862
13776
  }
13863
- /**
13864
- * Returns the debug (partial) metadata for a particular directive or component instance.
13865
- * The function accepts an instance of a directive or component and returns the corresponding
13866
- * metadata.
13867
- *
13868
- * @param directiveOrComponentInstance Instance of a directive or component
13869
- * @returns metadata of the passed directive or component
13870
- *
13871
- * @publicApi
13872
- * @globalApi ng
13873
- */
13874
- function getDirectiveMetadata(directiveOrComponentInstance) {
13875
- const { constructor } = directiveOrComponentInstance;
13876
- if (!constructor) {
13877
- throw new Error('Unable to find the instance constructor');
13777
+ function inheritContentQueries(definition, superContentQueries) {
13778
+ const prevContentQueries = definition.contentQueries;
13779
+ if (prevContentQueries) {
13780
+ definition.contentQueries = (rf, ctx, directiveIndex) => {
13781
+ superContentQueries(rf, ctx, directiveIndex);
13782
+ prevContentQueries(rf, ctx, directiveIndex);
13783
+ };
13878
13784
  }
13879
- // In case a component inherits from a directive, we may have component and directive metadata
13880
- // To ensure we don't get the metadata of the directive, we want to call `getComponentDef` first.
13881
- const componentDef = getComponentDef$1(constructor);
13882
- if (componentDef) {
13883
- return {
13884
- inputs: componentDef.inputs,
13885
- outputs: componentDef.outputs,
13886
- encapsulation: componentDef.encapsulation,
13887
- changeDetection: componentDef.onPush ? ChangeDetectionStrategy.OnPush :
13888
- ChangeDetectionStrategy.Default
13785
+ else {
13786
+ definition.contentQueries = superContentQueries;
13787
+ }
13788
+ }
13789
+ function inheritHostBindings(definition, superHostBindings) {
13790
+ const prevHostBindings = definition.hostBindings;
13791
+ if (prevHostBindings) {
13792
+ definition.hostBindings = (rf, ctx) => {
13793
+ superHostBindings(rf, ctx);
13794
+ prevHostBindings(rf, ctx);
13889
13795
  };
13890
13796
  }
13891
- const directiveDef = getDirectiveDef(constructor);
13892
- if (directiveDef) {
13893
- return { inputs: directiveDef.inputs, outputs: directiveDef.outputs };
13797
+ else {
13798
+ definition.hostBindings = superHostBindings;
13894
13799
  }
13895
- return null;
13896
13800
  }
13801
+
13897
13802
  /**
13898
- * Retrieve map of local references.
13899
- *
13900
- * The references are retrieved as a map of local reference name to element or directive instance.
13803
+ * @license
13804
+ * Copyright Google LLC All Rights Reserved.
13901
13805
  *
13902
- * @param target DOM element, component or directive instance for which to retrieve
13903
- * the local references.
13806
+ * Use of this source code is governed by an MIT-style license that can be
13807
+ * found in the LICENSE file at https://angular.io/license
13904
13808
  */
13905
- function getLocalRefs(target) {
13906
- const context = getLContext(target);
13907
- if (context === null)
13908
- return {};
13909
- if (context.localRefs === undefined) {
13910
- const lView = context.lView;
13911
- if (lView === null) {
13912
- return {};
13913
- }
13914
- context.localRefs = discoverLocalRefs(lView, context.nodeIndex);
13915
- }
13916
- return context.localRefs || {};
13917
- }
13918
13809
  /**
13919
- * Retrieves the host element of a component or directive instance.
13920
- * The host element is the DOM element that matched the selector of the directive.
13921
- *
13922
- * @param componentOrDirective Component or directive instance for which the host
13923
- * element should be retrieved.
13924
- * @returns Host element of the target.
13925
- *
13926
- * @publicApi
13927
- * @globalApi ng
13810
+ * Fields which exist on either directive or component definitions, and need to be copied from
13811
+ * parent to child classes by the `ɵɵCopyDefinitionFeature`.
13928
13812
  */
13929
- function getHostElement(componentOrDirective) {
13930
- return getLContext(componentOrDirective).native;
13931
- }
13813
+ const COPY_DIRECTIVE_FIELDS = [
13814
+ // The child class should use the providers of its parent.
13815
+ 'providersResolver',
13816
+ // Not listed here are any fields which are handled by the `ɵɵInheritDefinitionFeature`, such
13817
+ // as inputs, outputs, and host binding functions.
13818
+ ];
13932
13819
  /**
13933
- * Retrieves the rendered text for a given component.
13934
- *
13935
- * This function retrieves the host element of a component and
13936
- * and then returns the `textContent` for that element. This implies
13937
- * that the text returned will include re-projected content of
13938
- * the component as well.
13820
+ * Fields which exist only on component definitions, and need to be copied from parent to child
13821
+ * classes by the `ɵɵCopyDefinitionFeature`.
13939
13822
  *
13940
- * @param component The component to return the content text for.
13823
+ * The type here allows any field of `ComponentDef` which is not also a property of `DirectiveDef`,
13824
+ * since those should go in `COPY_DIRECTIVE_FIELDS` above.
13941
13825
  */
13942
- function getRenderedText(component) {
13943
- const hostElement = getHostElement(component);
13944
- return hostElement.textContent || '';
13945
- }
13826
+ const COPY_COMPONENT_FIELDS = [
13827
+ // The child class should use the template function of its parent, including all template
13828
+ // semantics.
13829
+ 'template',
13830
+ 'decls',
13831
+ 'consts',
13832
+ 'vars',
13833
+ 'onPush',
13834
+ 'ngContentSelectors',
13835
+ // The child class should use the CSS styles of its parent, including all styling semantics.
13836
+ 'styles',
13837
+ 'encapsulation',
13838
+ // The child class should be checked by the runtime in the same way as its parent.
13839
+ 'schemas',
13840
+ ];
13946
13841
  /**
13947
- * Retrieves a list of event listeners associated with a DOM element. The list does include host
13948
- * listeners, but it does not include event listeners defined outside of the Angular context
13949
- * (e.g. through `addEventListener`).
13842
+ * Copies the fields not handled by the `ɵɵInheritDefinitionFeature` from the supertype of a
13843
+ * definition.
13950
13844
  *
13951
- * @usageNotes
13952
- * Given the following DOM structure:
13845
+ * This exists primarily to support ngcc migration of an existing View Engine pattern, where an
13846
+ * entire decorator is inherited from a parent to a child class. When ngcc detects this case, it
13847
+ * generates a skeleton definition on the child class, and applies this feature.
13953
13848
  *
13954
- * ```html
13955
- * <app-root>
13956
- * <div (click)="doSomething()"></div>
13957
- * </app-root>
13958
- * ```
13849
+ * The `ɵɵCopyDefinitionFeature` then copies any needed fields from the parent class' definition,
13850
+ * including things like the component template function.
13959
13851
  *
13960
- * Calling `getListeners` on `<div>` will return an object that looks as follows:
13852
+ * @param definition The definition of a child class which inherits from a parent class with its
13853
+ * own definition.
13961
13854
  *
13962
- * ```ts
13963
- * {
13964
- * name: 'click',
13965
- * element: <div>,
13966
- * callback: () => doSomething(),
13967
- * useCapture: false
13968
- * }
13969
- * ```
13970
- *
13971
- * @param element Element for which the DOM listeners should be retrieved.
13972
- * @returns Array of event listeners on the DOM element.
13973
- *
13974
- * @publicApi
13975
- * @globalApi ng
13855
+ * @codeGenApi
13976
13856
  */
13977
- function getListeners(element) {
13978
- ngDevMode && assertDomElement(element);
13979
- const lContext = getLContext(element);
13980
- const lView = lContext === null ? null : lContext.lView;
13981
- if (lView === null)
13982
- return [];
13983
- const tView = lView[TVIEW];
13984
- const lCleanup = lView[CLEANUP];
13985
- const tCleanup = tView.cleanup;
13986
- const listeners = [];
13987
- if (tCleanup && lCleanup) {
13988
- for (let i = 0; i < tCleanup.length;) {
13989
- const firstParam = tCleanup[i++];
13990
- const secondParam = tCleanup[i++];
13991
- if (typeof firstParam === 'string') {
13992
- const name = firstParam;
13993
- const listenerElement = unwrapRNode(lView[secondParam]);
13994
- const callback = lCleanup[tCleanup[i++]];
13995
- const useCaptureOrIndx = tCleanup[i++];
13996
- // if useCaptureOrIndx is boolean then report it as is.
13997
- // if useCaptureOrIndx is positive number then it in unsubscribe method
13998
- // if useCaptureOrIndx is negative number then it is a Subscription
13999
- const type = (typeof useCaptureOrIndx === 'boolean' || useCaptureOrIndx >= 0) ? 'dom' : 'output';
14000
- const useCapture = typeof useCaptureOrIndx === 'boolean' ? useCaptureOrIndx : false;
14001
- if (element == listenerElement) {
14002
- listeners.push({ element, name, callback, useCapture, type });
14003
- }
14004
- }
14005
- }
13857
+ function ɵɵCopyDefinitionFeature(definition) {
13858
+ let superType = getSuperType(definition.type);
13859
+ let superDef = undefined;
13860
+ if (isComponentDef(definition)) {
13861
+ // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
13862
+ superDef = superType.ɵcmp;
14006
13863
  }
14007
- listeners.sort(sortListeners);
14008
- return listeners;
14009
- }
14010
- function sortListeners(a, b) {
14011
- if (a.name == b.name)
14012
- return 0;
14013
- return a.name < b.name ? -1 : 1;
14014
- }
14015
- /**
14016
- * This function should not exist because it is megamorphic and only mostly correct.
14017
- *
14018
- * See call site for more info.
14019
- */
14020
- function isDirectiveDefHack(obj) {
14021
- return obj.type !== undefined && obj.template !== undefined && obj.declaredInputs !== undefined;
14022
- }
14023
- /**
14024
- * Returns the attached `DebugNode` instance for an element in the DOM.
14025
- *
14026
- * @param element DOM element which is owned by an existing component's view.
14027
- */
14028
- function getDebugNode(element) {
14029
- if (ngDevMode && !(element instanceof Node)) {
14030
- throw new Error('Expecting instance of DOM Element');
13864
+ else {
13865
+ // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
13866
+ superDef = superType.ɵdir;
14031
13867
  }
14032
- const lContext = getLContext(element);
14033
- const lView = lContext ? lContext.lView : null;
14034
- if (lView === null) {
14035
- return null;
13868
+ // Needed because `definition` fields are readonly.
13869
+ const defAny = definition;
13870
+ // Copy over any fields that apply to either directives or components.
13871
+ for (const field of COPY_DIRECTIVE_FIELDS) {
13872
+ defAny[field] = superDef[field];
14036
13873
  }
14037
- const nodeIndex = lContext.nodeIndex;
14038
- if (nodeIndex !== -1) {
14039
- const valueInLView = lView[nodeIndex];
14040
- // this means that value in the lView is a component with its own
14041
- // data. In this situation the TNode is not accessed at the same spot.
14042
- const tNode = isLView(valueInLView) ? valueInLView[T_HOST] : getTNode(lView[TVIEW], nodeIndex);
14043
- ngDevMode &&
14044
- assertEqual(tNode.index, nodeIndex, 'Expecting that TNode at index is same as index');
14045
- return buildDebugNode(tNode, lView);
13874
+ if (isComponentDef(superDef)) {
13875
+ // Copy over any component-specific fields.
13876
+ for (const field of COPY_COMPONENT_FIELDS) {
13877
+ defAny[field] = superDef[field];
13878
+ }
14046
13879
  }
14047
- return null;
14048
13880
  }
13881
+
14049
13882
  /**
14050
- * Retrieve the component `LView` from component/element.
14051
- *
14052
- * NOTE: `LView` is a private and should not be leaked outside.
14053
- * Don't export this method to `ng.*` on window.
13883
+ * @license
13884
+ * Copyright Google LLC All Rights Reserved.
14054
13885
  *
14055
- * @param target DOM element or component instance for which to retrieve the LView.
13886
+ * Use of this source code is governed by an MIT-style license that can be
13887
+ * found in the LICENSE file at https://angular.io/license
14056
13888
  */
14057
- function getComponentLView(target) {
14058
- const lContext = getLContext(target);
14059
- const nodeIndx = lContext.nodeIndex;
14060
- const lView = lContext.lView;
14061
- ngDevMode && assertLView(lView);
14062
- const componentLView = lView[nodeIndx];
14063
- ngDevMode && assertLView(componentLView);
14064
- return componentLView;
14065
- }
14066
- /** Asserts that a value is a DOM Element. */
14067
- function assertDomElement(value) {
14068
- if (typeof Element !== 'undefined' && !(value instanceof Element)) {
14069
- throw new Error('Expecting instance of DOM Element');
13889
+ let _symbolIterator = null;
13890
+ function getSymbolIterator() {
13891
+ if (!_symbolIterator) {
13892
+ const Symbol = _global$1['Symbol'];
13893
+ if (Symbol && Symbol.iterator) {
13894
+ _symbolIterator = Symbol.iterator;
13895
+ }
13896
+ else {
13897
+ // es6-shim specific logic
13898
+ const keys = Object.getOwnPropertyNames(Map.prototype);
13899
+ for (let i = 0; i < keys.length; ++i) {
13900
+ const key = keys[i];
13901
+ if (key !== 'entries' && key !== 'size' &&
13902
+ Map.prototype[key] === Map.prototype['entries']) {
13903
+ _symbolIterator = key;
13904
+ }
13905
+ }
13906
+ }
14070
13907
  }
13908
+ return _symbolIterator;
14071
13909
  }
14072
13910
 
14073
13911
  /**
@@ -14077,18 +13915,46 @@ function assertDomElement(value) {
14077
13915
  * Use of this source code is governed by an MIT-style license that can be
14078
13916
  * found in the LICENSE file at https://angular.io/license
14079
13917
  */
14080
- /**
14081
- * Marks a component for check (in case of OnPush components) and synchronously
14082
- * performs change detection on the application this component belongs to.
14083
- *
14084
- * @param component Component to {@link ChangeDetectorRef#markForCheck mark for check}.
14085
- *
14086
- * @publicApi
14087
- * @globalApi ng
14088
- */
14089
- function applyChanges(component) {
14090
- markDirty(component);
14091
- getRootComponents(component).forEach(rootComponent => detectChanges(rootComponent));
13918
+ function isIterable(obj) {
13919
+ return obj !== null && typeof obj === 'object' && obj[getSymbolIterator()] !== undefined;
13920
+ }
13921
+ function isListLikeIterable(obj) {
13922
+ if (!isJsObject(obj))
13923
+ return false;
13924
+ return Array.isArray(obj) ||
13925
+ (!(obj instanceof Map) && // JS Map are iterables but return entries as [k, v]
13926
+ getSymbolIterator() in obj); // JS Iterable have a Symbol.iterator prop
13927
+ }
13928
+ function areIterablesEqual(a, b, comparator) {
13929
+ const iterator1 = a[getSymbolIterator()]();
13930
+ const iterator2 = b[getSymbolIterator()]();
13931
+ while (true) {
13932
+ const item1 = iterator1.next();
13933
+ const item2 = iterator2.next();
13934
+ if (item1.done && item2.done)
13935
+ return true;
13936
+ if (item1.done || item2.done)
13937
+ return false;
13938
+ if (!comparator(item1.value, item2.value))
13939
+ return false;
13940
+ }
13941
+ }
13942
+ function iterateListLike(obj, fn) {
13943
+ if (Array.isArray(obj)) {
13944
+ for (let i = 0; i < obj.length; i++) {
13945
+ fn(obj[i]);
13946
+ }
13947
+ }
13948
+ else {
13949
+ const iterator = obj[getSymbolIterator()]();
13950
+ let item;
13951
+ while (!((item = iterator.next()).done)) {
13952
+ fn(item.value);
13953
+ }
13954
+ }
13955
+ }
13956
+ function isJsObject(o) {
13957
+ return o !== null && (typeof o === 'function' || typeof o === 'object');
14092
13958
  }
14093
13959
 
14094
13960
  /**
@@ -14098,67 +13964,20 @@ function applyChanges(component) {
14098
13964
  * Use of this source code is governed by an MIT-style license that can be
14099
13965
  * found in the LICENSE file at https://angular.io/license
14100
13966
  */
14101
- /**
14102
- * This file introduces series of globally accessible debug tools
14103
- * to allow for the Angular debugging story to function.
14104
- *
14105
- * To see this in action run the following command:
14106
- *
14107
- * bazel run //packages/core/test/bundling/todo:devserver
14108
- *
14109
- * Then load `localhost:5432` and start using the console tools.
14110
- */
14111
- /**
14112
- * This value reflects the property on the window where the dev
14113
- * tools are patched (window.ng).
14114
- * */
14115
- const GLOBAL_PUBLISH_EXPANDO_KEY = 'ng';
14116
- let _published = false;
14117
- /**
14118
- * Publishes a collection of default debug tools onto`window.ng`.
14119
- *
14120
- * These functions are available globally when Angular is in development
14121
- * mode and are automatically stripped away from prod mode is on.
14122
- */
14123
- function publishDefaultGlobalUtils() {
14124
- if (!_published) {
14125
- _published = true;
14126
- /**
14127
- * Warning: this function is *INTERNAL* and should not be relied upon in application's code.
14128
- * The contract of the function might be changed in any release and/or the function can be
14129
- * removed completely.
14130
- */
14131
- publishGlobalUtil('ɵsetProfiler', setProfiler);
14132
- publishGlobalUtil('getDirectiveMetadata', getDirectiveMetadata);
14133
- publishGlobalUtil('getComponent', getComponent$1);
14134
- publishGlobalUtil('getContext', getContext);
14135
- publishGlobalUtil('getListeners', getListeners);
14136
- publishGlobalUtil('getOwningComponent', getOwningComponent);
14137
- publishGlobalUtil('getHostElement', getHostElement);
14138
- publishGlobalUtil('getInjector', getInjector);
14139
- publishGlobalUtil('getRootComponents', getRootComponents);
14140
- publishGlobalUtil('getDirectives', getDirectives);
14141
- publishGlobalUtil('applyChanges', applyChanges);
13967
+ function devModeEqual(a, b) {
13968
+ const isListLikeIterableA = isListLikeIterable(a);
13969
+ const isListLikeIterableB = isListLikeIterable(b);
13970
+ if (isListLikeIterableA && isListLikeIterableB) {
13971
+ return areIterablesEqual(a, b, devModeEqual);
14142
13972
  }
14143
- }
14144
- /**
14145
- * Publishes the given function to `window.ng` so that it can be
14146
- * used from the browser console when an application is not in production.
14147
- */
14148
- function publishGlobalUtil(name, fn) {
14149
- if (typeof COMPILED === 'undefined' || !COMPILED) {
14150
- // Note: we can't export `ng` when using closure enhanced optimization as:
14151
- // - closure declares globals itself for minified names, which sometimes clobber our `ng` global
14152
- // - we can't declare a closure extern as the namespace `ng` is already used within Google
14153
- // for typings for AngularJS (via `goog.provide('ng....')`).
14154
- const w = _global$1;
14155
- ngDevMode && assertDefined(fn, 'function not defined');
14156
- if (w) {
14157
- let container = w[GLOBAL_PUBLISH_EXPANDO_KEY];
14158
- if (!container) {
14159
- container = w[GLOBAL_PUBLISH_EXPANDO_KEY] = {};
14160
- }
14161
- container[name] = fn;
13973
+ else {
13974
+ const isAObject = a && (typeof a === 'object' || typeof a === 'function');
13975
+ const isBObject = b && (typeof b === 'object' || typeof b === 'function');
13976
+ if (!isListLikeIterableA && isAObject && !isListLikeIterableB && isBObject) {
13977
+ return true;
13978
+ }
13979
+ else {
13980
+ return Object.is(a, b);
14162
13981
  }
14163
13982
  }
14164
13983
  }
@@ -14170,186 +13989,104 @@ function publishGlobalUtil(name, fn) {
14170
13989
  * Use of this source code is governed by an MIT-style license that can be
14171
13990
  * found in the LICENSE file at https://angular.io/license
14172
13991
  */
14173
- // TODO: A hack to not pull in the NullInjector from @angular/core.
14174
- const NULL_INJECTOR = {
14175
- get: (token, notFoundValue) => {
14176
- throwProviderNotFoundError(token, 'NullInjector');
14177
- }
14178
- };
14179
- /**
14180
- * Bootstraps a Component into an existing host element and returns an instance
14181
- * of the component.
14182
- *
14183
- * Use this function to bootstrap a component into the DOM tree. Each invocation
14184
- * of this function will create a separate tree of components, injectors and
14185
- * change detection cycles and lifetimes. To dynamically insert a new component
14186
- * into an existing tree such that it shares the same injection, change detection
14187
- * and object lifetime, use {@link ViewContainer#createComponent}.
14188
- *
14189
- * @param componentType Component to bootstrap
14190
- * @param options Optional parameters which control bootstrapping
14191
- */
14192
- function renderComponent(componentType /* Type as workaround for: Microsoft/TypeScript/issues/4881 */, opts = {}) {
14193
- ngDevMode && publishDefaultGlobalUtils();
14194
- ngDevMode && assertComponentType(componentType);
14195
- enableRenderer3();
14196
- const rendererFactory = opts.rendererFactory || domRendererFactory3;
14197
- const sanitizer = opts.sanitizer || null;
14198
- const componentDef = getComponentDef$1(componentType);
14199
- if (componentDef.type != componentType)
14200
- componentDef.type = componentType;
14201
- // The first index of the first selector is the tag name.
14202
- const componentTag = componentDef.selectors[0][0];
14203
- const hostRenderer = rendererFactory.createRenderer(null, null);
14204
- const hostRNode = locateHostElement(hostRenderer, opts.host || componentTag, componentDef.encapsulation);
14205
- const rootFlags = componentDef.onPush ? 32 /* LViewFlags.Dirty */ | 256 /* LViewFlags.IsRoot */ :
14206
- 16 /* LViewFlags.CheckAlways */ | 256 /* LViewFlags.IsRoot */;
14207
- const rootContext = createRootContext(opts.scheduler, opts.playerHandler);
14208
- const renderer = rendererFactory.createRenderer(hostRNode, componentDef);
14209
- const rootTView = createTView(0 /* TViewType.Root */, null, null, 1, 0, null, null, null, null, null);
14210
- const rootView = createLView(null, rootTView, rootContext, rootFlags, null, null, rendererFactory, renderer, null, opts.injector || null, null);
14211
- enterView(rootView);
14212
- let component;
14213
- try {
14214
- if (rendererFactory.begin)
14215
- rendererFactory.begin();
14216
- const componentView = createRootComponentView(hostRNode, componentDef, rootView, rendererFactory, renderer, sanitizer);
14217
- component = createRootComponent(componentView, componentDef, rootView, rootContext, opts.hostFeatures || null);
14218
- // create mode pass
14219
- renderView(rootTView, rootView, null);
14220
- // update mode pass
14221
- refreshView(rootTView, rootView, null, null);
14222
- }
14223
- finally {
14224
- leaveView();
14225
- if (rendererFactory.end)
14226
- rendererFactory.end();
14227
- }
14228
- return component;
13992
+ // TODO(misko): consider inlining
13993
+ /** Updates binding and returns the value. */
13994
+ function updateBinding(lView, bindingIndex, value) {
13995
+ return lView[bindingIndex] = value;
13996
+ }
13997
+ /** Gets the current binding value. */
13998
+ function getBinding(lView, bindingIndex) {
13999
+ ngDevMode && assertIndexInRange(lView, bindingIndex);
14000
+ ngDevMode &&
14001
+ assertNotSame(lView[bindingIndex], NO_CHANGE, 'Stored value should never be NO_CHANGE.');
14002
+ return lView[bindingIndex];
14229
14003
  }
14230
14004
  /**
14231
- * Creates the root component view and the root component node.
14005
+ * Updates binding if changed, then returns whether it was updated.
14232
14006
  *
14233
- * @param rNode Render host element.
14234
- * @param def ComponentDef
14235
- * @param rootView The parent view where the host node is stored
14236
- * @param rendererFactory Factory to be used for creating child renderers.
14237
- * @param hostRenderer The current renderer
14238
- * @param sanitizer The sanitizer, if provided
14007
+ * This function also checks the `CheckNoChangesMode` and throws if changes are made.
14008
+ * Some changes (Objects/iterables) during `CheckNoChangesMode` are exempt to comply with VE
14009
+ * behavior.
14239
14010
  *
14240
- * @returns Component view created
14011
+ * @param lView current `LView`
14012
+ * @param bindingIndex The binding in the `LView` to check
14013
+ * @param value New value to check against `lView[bindingIndex]`
14014
+ * @returns `true` if the bindings has changed. (Throws if binding has changed during
14015
+ * `CheckNoChangesMode`)
14241
14016
  */
14242
- function createRootComponentView(rNode, def, rootView, rendererFactory, hostRenderer, sanitizer) {
14243
- const tView = rootView[TVIEW];
14244
- const index = HEADER_OFFSET;
14245
- ngDevMode && assertIndexInRange(rootView, index);
14246
- rootView[index] = rNode;
14247
- // '#host' is added here as we don't know the real host DOM name (we don't want to read it) and at
14248
- // the same time we want to communicate the debug `TNode` that this is a special `TNode`
14249
- // representing a host element.
14250
- const tNode = getOrCreateTNode(tView, index, 2 /* TNodeType.Element */, '#host', null);
14251
- const mergedAttrs = tNode.mergedAttrs = def.hostAttrs;
14252
- if (mergedAttrs !== null) {
14253
- computeStaticStyling(tNode, mergedAttrs, true);
14254
- if (rNode !== null) {
14255
- setUpAttributes(hostRenderer, rNode, mergedAttrs);
14256
- if (tNode.classes !== null) {
14257
- writeDirectClass(hostRenderer, rNode, tNode.classes);
14258
- }
14259
- if (tNode.styles !== null) {
14260
- writeDirectStyle(hostRenderer, rNode, tNode.styles);
14017
+ function bindingUpdated(lView, bindingIndex, value) {
14018
+ ngDevMode && assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
14019
+ ngDevMode &&
14020
+ assertLessThan(bindingIndex, lView.length, `Slot should have been initialized to NO_CHANGE`);
14021
+ const oldValue = lView[bindingIndex];
14022
+ if (Object.is(oldValue, value)) {
14023
+ return false;
14024
+ }
14025
+ else {
14026
+ if (ngDevMode && isInCheckNoChangesMode()) {
14027
+ // View engine didn't report undefined values as changed on the first checkNoChanges pass
14028
+ // (before the change detection was run).
14029
+ const oldValueToCompare = oldValue !== NO_CHANGE ? oldValue : undefined;
14030
+ if (!devModeEqual(oldValueToCompare, value)) {
14031
+ const details = getExpressionChangedErrorDetails(lView, bindingIndex, oldValueToCompare, value);
14032
+ throwErrorIfNoChangesMode(oldValue === NO_CHANGE, details.oldValue, details.newValue, details.propName);
14261
14033
  }
14034
+ // There was a change, but the `devModeEqual` decided that the change is exempt from an error.
14035
+ // For this reason we exit as if no change. The early exit is needed to prevent the changed
14036
+ // value to be written into `LView` (If we would write the new value that we would not see it
14037
+ // as change on next CD.)
14038
+ return false;
14262
14039
  }
14040
+ lView[bindingIndex] = value;
14041
+ return true;
14263
14042
  }
14264
- const viewRenderer = rendererFactory.createRenderer(rNode, def);
14265
- const componentView = createLView(rootView, getOrCreateTComponentView(def), null, def.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, rootView[index], tNode, rendererFactory, viewRenderer, sanitizer || null, null, null);
14266
- if (tView.firstCreatePass) {
14267
- diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, rootView), tView, def.type);
14268
- markAsComponentHost(tView, tNode);
14269
- initTNodeFlags(tNode, rootView.length, 1);
14270
- }
14271
- addToViewTree(rootView, componentView);
14272
- // Store component view at node index, with node as the HOST
14273
- return rootView[index] = componentView;
14274
14043
  }
14275
- /**
14276
- * Creates a root component and sets it up with features and host bindings. Shared by
14277
- * renderComponent() and ViewContainerRef.createComponent().
14278
- */
14279
- function createRootComponent(componentView, componentDef, rootLView, rootContext, hostFeatures) {
14280
- const tView = rootLView[TVIEW];
14281
- // Create directive instance with factory() and store at next index in viewData
14282
- const component = instantiateRootComponent(tView, rootLView, componentDef);
14283
- rootContext.components.push(component);
14284
- componentView[CONTEXT] = component;
14285
- if (hostFeatures !== null) {
14286
- for (const feature of hostFeatures) {
14287
- feature(component, componentDef);
14288
- }
14289
- }
14290
- // We want to generate an empty QueryList for root content queries for backwards
14291
- // compatibility with ViewEngine.
14292
- if (componentDef.contentQueries) {
14293
- const tNode = getCurrentTNode();
14294
- ngDevMode && assertDefined(tNode, 'TNode expected');
14295
- componentDef.contentQueries(1 /* RenderFlags.Create */, component, tNode.directiveStart);
14296
- }
14297
- const rootTNode = getCurrentTNode();
14298
- ngDevMode && assertDefined(rootTNode, 'tNode should have been already created');
14299
- if (tView.firstCreatePass &&
14300
- (componentDef.hostBindings !== null || componentDef.hostAttrs !== null)) {
14301
- setSelectedIndex(rootTNode.index);
14302
- const rootTView = rootLView[TVIEW];
14303
- registerHostBindingOpCodes(rootTView, rootTNode, rootLView, rootTNode.directiveStart, rootTNode.directiveEnd, componentDef);
14304
- invokeHostBindingsInCreationMode(componentDef, component);
14305
- }
14306
- return component;
14044
+ /** Updates 2 bindings if changed, then returns whether either was updated. */
14045
+ function bindingUpdated2(lView, bindingIndex, exp1, exp2) {
14046
+ const different = bindingUpdated(lView, bindingIndex, exp1);
14047
+ return bindingUpdated(lView, bindingIndex + 1, exp2) || different;
14307
14048
  }
14308
- function createRootContext(scheduler, playerHandler) {
14309
- return {
14310
- components: [],
14311
- scheduler: scheduler || defaultScheduler,
14312
- clean: CLEAN_PROMISE,
14313
- playerHandler: playerHandler || null,
14314
- flags: 0 /* RootContextFlags.Empty */
14315
- };
14049
+ /** Updates 3 bindings if changed, then returns whether any was updated. */
14050
+ function bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) {
14051
+ const different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
14052
+ return bindingUpdated(lView, bindingIndex + 2, exp3) || different;
14053
+ }
14054
+ /** Updates 4 bindings if changed, then returns whether any was updated. */
14055
+ function bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) {
14056
+ const different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
14057
+ return bindingUpdated2(lView, bindingIndex + 2, exp3, exp4) || different;
14316
14058
  }
14059
+
14317
14060
  /**
14318
- * Used to enable lifecycle hooks on the root component.
14319
- *
14320
- * Include this feature when calling `renderComponent` if the root component
14321
- * you are rendering has lifecycle hooks defined. Otherwise, the hooks won't
14322
- * be called properly.
14323
- *
14324
- * Example:
14061
+ * @license
14062
+ * Copyright Google LLC All Rights Reserved.
14325
14063
  *
14326
- * ```
14327
- * renderComponent(AppComponent, {hostFeatures: [LifecycleHooksFeature]});
14328
- * ```
14064
+ * Use of this source code is governed by an MIT-style license that can be
14065
+ * found in the LICENSE file at https://angular.io/license
14329
14066
  */
14330
- function LifecycleHooksFeature() {
14331
- const tNode = getCurrentTNode();
14332
- ngDevMode && assertDefined(tNode, 'TNode is required');
14333
- registerPostOrderHooks(getLView()[TVIEW], tNode);
14334
- }
14335
14067
  /**
14336
- * Wait on component until it is rendered.
14068
+ * Updates the value of or removes a bound attribute on an Element.
14337
14069
  *
14338
- * This function returns a `Promise` which is resolved when the component's
14339
- * change detection is executed. This is determined by finding the scheduler
14340
- * associated with the `component`'s render tree and waiting until the scheduler
14341
- * flushes. If nothing is scheduled, the function returns a resolved promise.
14070
+ * Used in the case of `[attr.title]="value"`
14342
14071
  *
14343
- * Example:
14344
- * ```
14345
- * await whenRendered(myComponent);
14346
- * ```
14072
+ * @param name name The name of the attribute.
14073
+ * @param value value The attribute is removed when value is `null` or `undefined`.
14074
+ * Otherwise the attribute value is set to the stringified value.
14075
+ * @param sanitizer An optional function used to sanitize the value.
14076
+ * @param namespace Optional namespace to use when setting the attribute.
14347
14077
  *
14348
- * @param component Component to wait upon
14349
- * @returns Promise which resolves when the component is rendered.
14078
+ * @codeGenApi
14350
14079
  */
14351
- function whenRendered(component) {
14352
- return getRootContext(component).clean;
14080
+ function ɵɵattribute(name, value, sanitizer, namespace) {
14081
+ const lView = getLView();
14082
+ const bindingIndex = nextBindingIndex();
14083
+ if (bindingUpdated(lView, bindingIndex, value)) {
14084
+ const tView = getTView();
14085
+ const tNode = getSelectedTNode();
14086
+ elementAttributeInternal(tNode, lView, name, value, sanitizer, namespace);
14087
+ ngDevMode && storePropertyBindingMetadata(tView.data, tNode, 'attr.' + name, bindingIndex);
14088
+ }
14089
+ return ɵɵattribute;
14353
14090
  }
14354
14091
 
14355
14092
  /**
@@ -14359,700 +14096,253 @@ function whenRendered(component) {
14359
14096
  * Use of this source code is governed by an MIT-style license that can be
14360
14097
  * found in the LICENSE file at https://angular.io/license
14361
14098
  */
14362
- function getSuperType(type) {
14363
- return Object.getPrototypeOf(type.prototype).constructor;
14364
- }
14365
14099
  /**
14366
- * Merges the definition from a super class to a sub class.
14367
- * @param definition The definition that is a SubClass of another directive of component
14100
+ * Create interpolation bindings with a variable number of expressions.
14368
14101
  *
14369
- * @codeGenApi
14370
- */
14371
- function ɵɵInheritDefinitionFeature(definition) {
14372
- let superType = getSuperType(definition.type);
14373
- let shouldInheritFields = true;
14374
- const inheritanceChain = [definition];
14375
- while (superType) {
14376
- let superDef = undefined;
14377
- if (isComponentDef(definition)) {
14378
- // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
14379
- superDef = superType.ɵcmp || superType.ɵdir;
14380
- }
14381
- else {
14382
- if (superType.ɵcmp) {
14383
- throw new RuntimeError(903 /* RuntimeErrorCode.INVALID_INHERITANCE */, ngDevMode &&
14384
- `Directives cannot inherit Components. Directive ${stringifyForError(definition.type)} is attempting to extend component ${stringifyForError(superType)}`);
14385
- }
14386
- // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
14387
- superDef = superType.ɵdir;
14388
- }
14389
- if (superDef) {
14390
- if (shouldInheritFields) {
14391
- inheritanceChain.push(superDef);
14392
- // Some fields in the definition may be empty, if there were no values to put in them that
14393
- // would've justified object creation. Unwrap them if necessary.
14394
- const writeableDef = definition;
14395
- writeableDef.inputs = maybeUnwrapEmpty(definition.inputs);
14396
- writeableDef.declaredInputs = maybeUnwrapEmpty(definition.declaredInputs);
14397
- writeableDef.outputs = maybeUnwrapEmpty(definition.outputs);
14398
- // Merge hostBindings
14399
- const superHostBindings = superDef.hostBindings;
14400
- superHostBindings && inheritHostBindings(definition, superHostBindings);
14401
- // Merge queries
14402
- const superViewQuery = superDef.viewQuery;
14403
- const superContentQueries = superDef.contentQueries;
14404
- superViewQuery && inheritViewQuery(definition, superViewQuery);
14405
- superContentQueries && inheritContentQueries(definition, superContentQueries);
14406
- // Merge inputs and outputs
14407
- fillProperties(definition.inputs, superDef.inputs);
14408
- fillProperties(definition.declaredInputs, superDef.declaredInputs);
14409
- fillProperties(definition.outputs, superDef.outputs);
14410
- // Merge animations metadata.
14411
- // If `superDef` is a Component, the `data` field is present (defaults to an empty object).
14412
- if (isComponentDef(superDef) && superDef.data.animation) {
14413
- // If super def is a Component, the `definition` is also a Component, since Directives can
14414
- // not inherit Components (we throw an error above and cannot reach this code).
14415
- const defData = definition.data;
14416
- defData.animation = (defData.animation || []).concat(superDef.data.animation);
14417
- }
14418
- }
14419
- // Run parent features
14420
- const features = superDef.features;
14421
- if (features) {
14422
- for (let i = 0; i < features.length; i++) {
14423
- const feature = features[i];
14424
- if (feature && feature.ngInherit) {
14425
- feature(definition);
14426
- }
14427
- // If `InheritDefinitionFeature` is a part of the current `superDef`, it means that this
14428
- // def already has all the necessary information inherited from its super class(es), so we
14429
- // can stop merging fields from super classes. However we need to iterate through the
14430
- // prototype chain to look for classes that might contain other "features" (like
14431
- // NgOnChanges), which we should invoke for the original `definition`. We set the
14432
- // `shouldInheritFields` flag to indicate that, essentially skipping fields inheritance
14433
- // logic and only invoking functions from the "features" list.
14434
- if (feature === ɵɵInheritDefinitionFeature) {
14435
- shouldInheritFields = false;
14436
- }
14437
- }
14438
- }
14439
- }
14440
- superType = Object.getPrototypeOf(superType);
14441
- }
14442
- mergeHostAttrsAcrossInheritance(inheritanceChain);
14443
- }
14444
- /**
14445
- * Merge the `hostAttrs` and `hostVars` from the inherited parent to the base class.
14102
+ * If there are 1 to 8 expressions `interpolation1()` to `interpolation8()` should be used instead.
14103
+ * Those are faster because there is no need to create an array of expressions and iterate over it.
14446
14104
  *
14447
- * @param inheritanceChain A list of `WritableDefs` starting at the top most type and listing
14448
- * sub-types in order. For each type take the `hostAttrs` and `hostVars` and merge it with the child
14449
- * type.
14105
+ * `values`:
14106
+ * - has static text at even indexes,
14107
+ * - has evaluated expressions at odd indexes.
14108
+ *
14109
+ * Returns the concatenated string when any of the arguments changes, `NO_CHANGE` otherwise.
14450
14110
  */
14451
- function mergeHostAttrsAcrossInheritance(inheritanceChain) {
14452
- let hostVars = 0;
14453
- let hostAttrs = null;
14454
- // We process the inheritance order from the base to the leaves here.
14455
- for (let i = inheritanceChain.length - 1; i >= 0; i--) {
14456
- const def = inheritanceChain[i];
14457
- // For each `hostVars`, we need to add the superclass amount.
14458
- def.hostVars = (hostVars += def.hostVars);
14459
- // for each `hostAttrs` we need to merge it with superclass.
14460
- def.hostAttrs =
14461
- mergeHostAttrs(def.hostAttrs, hostAttrs = mergeHostAttrs(hostAttrs, def.hostAttrs));
14462
- }
14463
- }
14464
- function maybeUnwrapEmpty(value) {
14465
- if (value === EMPTY_OBJ) {
14466
- return {};
14111
+ function interpolationV(lView, values) {
14112
+ ngDevMode && assertLessThan(2, values.length, 'should have at least 3 values');
14113
+ ngDevMode && assertEqual(values.length % 2, 1, 'should have an odd number of values');
14114
+ let isBindingUpdated = false;
14115
+ let bindingIndex = getBindingIndex();
14116
+ for (let i = 1; i < values.length; i += 2) {
14117
+ // Check if bindings (odd indexes) have changed
14118
+ isBindingUpdated = bindingUpdated(lView, bindingIndex++, values[i]) || isBindingUpdated;
14467
14119
  }
14468
- else if (value === EMPTY_ARRAY) {
14469
- return [];
14120
+ setBindingIndex(bindingIndex);
14121
+ if (!isBindingUpdated) {
14122
+ return NO_CHANGE;
14470
14123
  }
14471
- else {
14472
- return value;
14124
+ // Build the updated content
14125
+ let content = values[0];
14126
+ for (let i = 1; i < values.length; i += 2) {
14127
+ content += renderStringify(values[i]) + values[i + 1];
14473
14128
  }
14129
+ return content;
14474
14130
  }
14475
- function inheritViewQuery(definition, superViewQuery) {
14476
- const prevViewQuery = definition.viewQuery;
14477
- if (prevViewQuery) {
14478
- definition.viewQuery = (rf, ctx) => {
14479
- superViewQuery(rf, ctx);
14480
- prevViewQuery(rf, ctx);
14481
- };
14482
- }
14483
- else {
14484
- definition.viewQuery = superViewQuery;
14485
- }
14131
+ /**
14132
+ * Creates an interpolation binding with 1 expression.
14133
+ *
14134
+ * @param prefix static value used for concatenation only.
14135
+ * @param v0 value checked for change.
14136
+ * @param suffix static value used for concatenation only.
14137
+ */
14138
+ function interpolation1(lView, prefix, v0, suffix) {
14139
+ const different = bindingUpdated(lView, nextBindingIndex(), v0);
14140
+ return different ? prefix + renderStringify(v0) + suffix : NO_CHANGE;
14486
14141
  }
14487
- function inheritContentQueries(definition, superContentQueries) {
14488
- const prevContentQueries = definition.contentQueries;
14489
- if (prevContentQueries) {
14490
- definition.contentQueries = (rf, ctx, directiveIndex) => {
14491
- superContentQueries(rf, ctx, directiveIndex);
14492
- prevContentQueries(rf, ctx, directiveIndex);
14493
- };
14494
- }
14495
- else {
14496
- definition.contentQueries = superContentQueries;
14497
- }
14142
+ /**
14143
+ * Creates an interpolation binding with 2 expressions.
14144
+ */
14145
+ function interpolation2(lView, prefix, v0, i0, v1, suffix) {
14146
+ const bindingIndex = getBindingIndex();
14147
+ const different = bindingUpdated2(lView, bindingIndex, v0, v1);
14148
+ incrementBindingIndex(2);
14149
+ return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + suffix : NO_CHANGE;
14498
14150
  }
14499
- function inheritHostBindings(definition, superHostBindings) {
14500
- const prevHostBindings = definition.hostBindings;
14501
- if (prevHostBindings) {
14502
- definition.hostBindings = (rf, ctx) => {
14503
- superHostBindings(rf, ctx);
14504
- prevHostBindings(rf, ctx);
14505
- };
14506
- }
14507
- else {
14508
- definition.hostBindings = superHostBindings;
14509
- }
14151
+ /**
14152
+ * Creates an interpolation binding with 3 expressions.
14153
+ */
14154
+ function interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix) {
14155
+ const bindingIndex = getBindingIndex();
14156
+ const different = bindingUpdated3(lView, bindingIndex, v0, v1, v2);
14157
+ incrementBindingIndex(3);
14158
+ return different ?
14159
+ prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + suffix :
14160
+ NO_CHANGE;
14510
14161
  }
14511
-
14512
14162
  /**
14513
- * @license
14514
- * Copyright Google LLC All Rights Reserved.
14515
- *
14516
- * Use of this source code is governed by an MIT-style license that can be
14517
- * found in the LICENSE file at https://angular.io/license
14163
+ * Create an interpolation binding with 4 expressions.
14518
14164
  */
14165
+ function interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
14166
+ const bindingIndex = getBindingIndex();
14167
+ const different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14168
+ incrementBindingIndex(4);
14169
+ return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14170
+ renderStringify(v2) + i2 + renderStringify(v3) + suffix :
14171
+ NO_CHANGE;
14172
+ }
14519
14173
  /**
14520
- * Fields which exist on either directive or component definitions, and need to be copied from
14521
- * parent to child classes by the `ɵɵCopyDefinitionFeature`.
14174
+ * Creates an interpolation binding with 5 expressions.
14522
14175
  */
14523
- const COPY_DIRECTIVE_FIELDS = [
14524
- // The child class should use the providers of its parent.
14525
- 'providersResolver',
14526
- // Not listed here are any fields which are handled by the `ɵɵInheritDefinitionFeature`, such
14527
- // as inputs, outputs, and host binding functions.
14528
- ];
14176
+ function interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
14177
+ const bindingIndex = getBindingIndex();
14178
+ let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14179
+ different = bindingUpdated(lView, bindingIndex + 4, v4) || different;
14180
+ incrementBindingIndex(5);
14181
+ return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14182
+ renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + suffix :
14183
+ NO_CHANGE;
14184
+ }
14529
14185
  /**
14530
- * Fields which exist only on component definitions, and need to be copied from parent to child
14531
- * classes by the `ɵɵCopyDefinitionFeature`.
14532
- *
14533
- * The type here allows any field of `ComponentDef` which is not also a property of `DirectiveDef`,
14534
- * since those should go in `COPY_DIRECTIVE_FIELDS` above.
14186
+ * Creates an interpolation binding with 6 expressions.
14535
14187
  */
14536
- const COPY_COMPONENT_FIELDS = [
14537
- // The child class should use the template function of its parent, including all template
14538
- // semantics.
14539
- 'template',
14540
- 'decls',
14541
- 'consts',
14542
- 'vars',
14543
- 'onPush',
14544
- 'ngContentSelectors',
14545
- // The child class should use the CSS styles of its parent, including all styling semantics.
14546
- 'styles',
14547
- 'encapsulation',
14548
- // The child class should be checked by the runtime in the same way as its parent.
14549
- 'schemas',
14550
- ];
14188
+ function interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
14189
+ const bindingIndex = getBindingIndex();
14190
+ let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14191
+ different = bindingUpdated2(lView, bindingIndex + 4, v4, v5) || different;
14192
+ incrementBindingIndex(6);
14193
+ return different ?
14194
+ prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 +
14195
+ renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + suffix :
14196
+ NO_CHANGE;
14197
+ }
14198
+ /**
14199
+ * Creates an interpolation binding with 7 expressions.
14200
+ */
14201
+ function interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
14202
+ const bindingIndex = getBindingIndex();
14203
+ let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14204
+ different = bindingUpdated3(lView, bindingIndex + 4, v4, v5, v6) || different;
14205
+ incrementBindingIndex(7);
14206
+ return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14207
+ renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 +
14208
+ renderStringify(v5) + i5 + renderStringify(v6) + suffix :
14209
+ NO_CHANGE;
14210
+ }
14211
+ /**
14212
+ * Creates an interpolation binding with 8 expressions.
14213
+ */
14214
+ function interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
14215
+ const bindingIndex = getBindingIndex();
14216
+ let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14217
+ different = bindingUpdated4(lView, bindingIndex + 4, v4, v5, v6, v7) || different;
14218
+ incrementBindingIndex(8);
14219
+ return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14220
+ renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 +
14221
+ renderStringify(v5) + i5 + renderStringify(v6) + i6 + renderStringify(v7) + suffix :
14222
+ NO_CHANGE;
14223
+ }
14224
+
14551
14225
  /**
14552
- * Copies the fields not handled by the `ɵɵInheritDefinitionFeature` from the supertype of a
14553
- * definition.
14554
14226
  *
14555
- * This exists primarily to support ngcc migration of an existing View Engine pattern, where an
14556
- * entire decorator is inherited from a parent to a child class. When ngcc detects this case, it
14557
- * generates a skeleton definition on the child class, and applies this feature.
14227
+ * Update an interpolated attribute on an element with single bound value surrounded by text.
14558
14228
  *
14559
- * The `ɵɵCopyDefinitionFeature` then copies any needed fields from the parent class' definition,
14560
- * including things like the component template function.
14229
+ * Used when the value passed to a property has 1 interpolated value in it:
14561
14230
  *
14562
- * @param definition The definition of a child class which inherits from a parent class with its
14563
- * own definition.
14231
+ * ```html
14232
+ * <div attr.title="prefix{{v0}}suffix"></div>
14233
+ * ```
14234
+ *
14235
+ * Its compiled representation is::
14236
+ *
14237
+ * ```ts
14238
+ * ɵɵattributeInterpolate1('title', 'prefix', v0, 'suffix');
14239
+ * ```
14564
14240
  *
14241
+ * @param attrName The name of the attribute to update
14242
+ * @param prefix Static value used for concatenation only.
14243
+ * @param v0 Value checked for change.
14244
+ * @param suffix Static value used for concatenation only.
14245
+ * @param sanitizer An optional sanitizer function
14246
+ * @returns itself, so that it may be chained.
14565
14247
  * @codeGenApi
14566
14248
  */
14567
- function ɵɵCopyDefinitionFeature(definition) {
14568
- let superType = getSuperType(definition.type);
14569
- let superDef = undefined;
14570
- if (isComponentDef(definition)) {
14571
- // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
14572
- superDef = superType.ɵcmp;
14573
- }
14574
- else {
14575
- // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
14576
- superDef = superType.ɵdir;
14577
- }
14578
- // Needed because `definition` fields are readonly.
14579
- const defAny = definition;
14580
- // Copy over any fields that apply to either directives or components.
14581
- for (const field of COPY_DIRECTIVE_FIELDS) {
14582
- defAny[field] = superDef[field];
14583
- }
14584
- if (isComponentDef(superDef)) {
14585
- // Copy over any component-specific fields.
14586
- for (const field of COPY_COMPONENT_FIELDS) {
14587
- defAny[field] = superDef[field];
14588
- }
14249
+ function ɵɵattributeInterpolate1(attrName, prefix, v0, suffix, sanitizer, namespace) {
14250
+ const lView = getLView();
14251
+ const interpolatedValue = interpolation1(lView, prefix, v0, suffix);
14252
+ if (interpolatedValue !== NO_CHANGE) {
14253
+ const tNode = getSelectedTNode();
14254
+ elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
14255
+ ngDevMode &&
14256
+ storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 1, prefix, suffix);
14589
14257
  }
14258
+ return ɵɵattributeInterpolate1;
14590
14259
  }
14591
-
14592
14260
  /**
14593
- * @license
14594
- * Copyright Google LLC All Rights Reserved.
14595
14261
  *
14596
- * Use of this source code is governed by an MIT-style license that can be
14597
- * found in the LICENSE file at https://angular.io/license
14598
- */
14599
- let _symbolIterator = null;
14600
- function getSymbolIterator() {
14601
- if (!_symbolIterator) {
14602
- const Symbol = _global$1['Symbol'];
14603
- if (Symbol && Symbol.iterator) {
14604
- _symbolIterator = Symbol.iterator;
14605
- }
14606
- else {
14607
- // es6-shim specific logic
14608
- const keys = Object.getOwnPropertyNames(Map.prototype);
14609
- for (let i = 0; i < keys.length; ++i) {
14610
- const key = keys[i];
14611
- if (key !== 'entries' && key !== 'size' &&
14612
- Map.prototype[key] === Map.prototype['entries']) {
14613
- _symbolIterator = key;
14614
- }
14615
- }
14616
- }
14617
- }
14618
- return _symbolIterator;
14619
- }
14620
-
14621
- /**
14622
- * @license
14623
- * Copyright Google LLC All Rights Reserved.
14262
+ * Update an interpolated attribute on an element with 2 bound values surrounded by text.
14624
14263
  *
14625
- * Use of this source code is governed by an MIT-style license that can be
14626
- * found in the LICENSE file at https://angular.io/license
14627
- */
14628
- function isIterable(obj) {
14629
- return obj !== null && typeof obj === 'object' && obj[getSymbolIterator()] !== undefined;
14630
- }
14631
- function isListLikeIterable(obj) {
14632
- if (!isJsObject(obj))
14633
- return false;
14634
- return Array.isArray(obj) ||
14635
- (!(obj instanceof Map) && // JS Map are iterables but return entries as [k, v]
14636
- getSymbolIterator() in obj); // JS Iterable have a Symbol.iterator prop
14637
- }
14638
- function areIterablesEqual(a, b, comparator) {
14639
- const iterator1 = a[getSymbolIterator()]();
14640
- const iterator2 = b[getSymbolIterator()]();
14641
- while (true) {
14642
- const item1 = iterator1.next();
14643
- const item2 = iterator2.next();
14644
- if (item1.done && item2.done)
14645
- return true;
14646
- if (item1.done || item2.done)
14647
- return false;
14648
- if (!comparator(item1.value, item2.value))
14649
- return false;
14650
- }
14651
- }
14652
- function iterateListLike(obj, fn) {
14653
- if (Array.isArray(obj)) {
14654
- for (let i = 0; i < obj.length; i++) {
14655
- fn(obj[i]);
14656
- }
14657
- }
14658
- else {
14659
- const iterator = obj[getSymbolIterator()]();
14660
- let item;
14661
- while (!((item = iterator.next()).done)) {
14662
- fn(item.value);
14663
- }
14664
- }
14665
- }
14666
- function isJsObject(o) {
14667
- return o !== null && (typeof o === 'function' || typeof o === 'object');
14668
- }
14669
-
14670
- /**
14671
- * @license
14672
- * Copyright Google LLC All Rights Reserved.
14264
+ * Used when the value passed to a property has 2 interpolated values in it:
14673
14265
  *
14674
- * Use of this source code is governed by an MIT-style license that can be
14675
- * found in the LICENSE file at https://angular.io/license
14676
- */
14677
- function devModeEqual(a, b) {
14678
- const isListLikeIterableA = isListLikeIterable(a);
14679
- const isListLikeIterableB = isListLikeIterable(b);
14680
- if (isListLikeIterableA && isListLikeIterableB) {
14681
- return areIterablesEqual(a, b, devModeEqual);
14682
- }
14683
- else {
14684
- const isAObject = a && (typeof a === 'object' || typeof a === 'function');
14685
- const isBObject = b && (typeof b === 'object' || typeof b === 'function');
14686
- if (!isListLikeIterableA && isAObject && !isListLikeIterableB && isBObject) {
14687
- return true;
14688
- }
14689
- else {
14690
- return Object.is(a, b);
14691
- }
14692
- }
14693
- }
14694
-
14695
- /**
14696
- * @license
14697
- * Copyright Google LLC All Rights Reserved.
14266
+ * ```html
14267
+ * <div attr.title="prefix{{v0}}-{{v1}}suffix"></div>
14268
+ * ```
14698
14269
  *
14699
- * Use of this source code is governed by an MIT-style license that can be
14700
- * found in the LICENSE file at https://angular.io/license
14701
- */
14702
- // TODO(misko): consider inlining
14703
- /** Updates binding and returns the value. */
14704
- function updateBinding(lView, bindingIndex, value) {
14705
- return lView[bindingIndex] = value;
14706
- }
14707
- /** Gets the current binding value. */
14708
- function getBinding(lView, bindingIndex) {
14709
- ngDevMode && assertIndexInRange(lView, bindingIndex);
14710
- ngDevMode &&
14711
- assertNotSame(lView[bindingIndex], NO_CHANGE, 'Stored value should never be NO_CHANGE.');
14712
- return lView[bindingIndex];
14713
- }
14714
- /**
14715
- * Updates binding if changed, then returns whether it was updated.
14270
+ * Its compiled representation is::
14716
14271
  *
14717
- * This function also checks the `CheckNoChangesMode` and throws if changes are made.
14718
- * Some changes (Objects/iterables) during `CheckNoChangesMode` are exempt to comply with VE
14719
- * behavior.
14272
+ * ```ts
14273
+ * ɵɵattributeInterpolate2('title', 'prefix', v0, '-', v1, 'suffix');
14274
+ * ```
14720
14275
  *
14721
- * @param lView current `LView`
14722
- * @param bindingIndex The binding in the `LView` to check
14723
- * @param value New value to check against `lView[bindingIndex]`
14724
- * @returns `true` if the bindings has changed. (Throws if binding has changed during
14725
- * `CheckNoChangesMode`)
14276
+ * @param attrName The name of the attribute to update
14277
+ * @param prefix Static value used for concatenation only.
14278
+ * @param v0 Value checked for change.
14279
+ * @param i0 Static value used for concatenation only.
14280
+ * @param v1 Value checked for change.
14281
+ * @param suffix Static value used for concatenation only.
14282
+ * @param sanitizer An optional sanitizer function
14283
+ * @returns itself, so that it may be chained.
14284
+ * @codeGenApi
14726
14285
  */
14727
- function bindingUpdated(lView, bindingIndex, value) {
14728
- ngDevMode && assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
14729
- ngDevMode &&
14730
- assertLessThan(bindingIndex, lView.length, `Slot should have been initialized to NO_CHANGE`);
14731
- const oldValue = lView[bindingIndex];
14732
- if (Object.is(oldValue, value)) {
14733
- return false;
14734
- }
14735
- else {
14736
- if (ngDevMode && isInCheckNoChangesMode()) {
14737
- // View engine didn't report undefined values as changed on the first checkNoChanges pass
14738
- // (before the change detection was run).
14739
- const oldValueToCompare = oldValue !== NO_CHANGE ? oldValue : undefined;
14740
- if (!devModeEqual(oldValueToCompare, value)) {
14741
- const details = getExpressionChangedErrorDetails(lView, bindingIndex, oldValueToCompare, value);
14742
- throwErrorIfNoChangesMode(oldValue === NO_CHANGE, details.oldValue, details.newValue, details.propName);
14743
- }
14744
- // There was a change, but the `devModeEqual` decided that the change is exempt from an error.
14745
- // For this reason we exit as if no change. The early exit is needed to prevent the changed
14746
- // value to be written into `LView` (If we would write the new value that we would not see it
14747
- // as change on next CD.)
14748
- return false;
14749
- }
14750
- lView[bindingIndex] = value;
14751
- return true;
14286
+ function ɵɵattributeInterpolate2(attrName, prefix, v0, i0, v1, suffix, sanitizer, namespace) {
14287
+ const lView = getLView();
14288
+ const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
14289
+ if (interpolatedValue !== NO_CHANGE) {
14290
+ const tNode = getSelectedTNode();
14291
+ elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
14292
+ ngDevMode &&
14293
+ storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 2, prefix, i0, suffix);
14752
14294
  }
14295
+ return ɵɵattributeInterpolate2;
14753
14296
  }
14754
- /** Updates 2 bindings if changed, then returns whether either was updated. */
14755
- function bindingUpdated2(lView, bindingIndex, exp1, exp2) {
14756
- const different = bindingUpdated(lView, bindingIndex, exp1);
14757
- return bindingUpdated(lView, bindingIndex + 1, exp2) || different;
14758
- }
14759
- /** Updates 3 bindings if changed, then returns whether any was updated. */
14760
- function bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) {
14761
- const different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
14762
- return bindingUpdated(lView, bindingIndex + 2, exp3) || different;
14763
- }
14764
- /** Updates 4 bindings if changed, then returns whether any was updated. */
14765
- function bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) {
14766
- const different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
14767
- return bindingUpdated2(lView, bindingIndex + 2, exp3, exp4) || different;
14768
- }
14769
-
14770
14297
  /**
14771
- * @license
14772
- * Copyright Google LLC All Rights Reserved.
14773
14298
  *
14774
- * Use of this source code is governed by an MIT-style license that can be
14775
- * found in the LICENSE file at https://angular.io/license
14776
- */
14777
- /**
14778
- * Updates the value of or removes a bound attribute on an Element.
14299
+ * Update an interpolated attribute on an element with 3 bound values surrounded by text.
14779
14300
  *
14780
- * Used in the case of `[attr.title]="value"`
14301
+ * Used when the value passed to a property has 3 interpolated values in it:
14781
14302
  *
14782
- * @param name name The name of the attribute.
14783
- * @param value value The attribute is removed when value is `null` or `undefined`.
14784
- * Otherwise the attribute value is set to the stringified value.
14785
- * @param sanitizer An optional function used to sanitize the value.
14786
- * @param namespace Optional namespace to use when setting the attribute.
14303
+ * ```html
14304
+ * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
14305
+ * ```
14306
+ *
14307
+ * Its compiled representation is::
14308
+ *
14309
+ * ```ts
14310
+ * ɵɵattributeInterpolate3(
14311
+ * 'title', 'prefix', v0, '-', v1, '-', v2, 'suffix');
14312
+ * ```
14787
14313
  *
14314
+ * @param attrName The name of the attribute to update
14315
+ * @param prefix Static value used for concatenation only.
14316
+ * @param v0 Value checked for change.
14317
+ * @param i0 Static value used for concatenation only.
14318
+ * @param v1 Value checked for change.
14319
+ * @param i1 Static value used for concatenation only.
14320
+ * @param v2 Value checked for change.
14321
+ * @param suffix Static value used for concatenation only.
14322
+ * @param sanitizer An optional sanitizer function
14323
+ * @returns itself, so that it may be chained.
14788
14324
  * @codeGenApi
14789
14325
  */
14790
- function ɵɵattribute(name, value, sanitizer, namespace) {
14326
+ function ɵɵattributeInterpolate3(attrName, prefix, v0, i0, v1, i1, v2, suffix, sanitizer, namespace) {
14791
14327
  const lView = getLView();
14792
- const bindingIndex = nextBindingIndex();
14793
- if (bindingUpdated(lView, bindingIndex, value)) {
14794
- const tView = getTView();
14328
+ const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
14329
+ if (interpolatedValue !== NO_CHANGE) {
14795
14330
  const tNode = getSelectedTNode();
14796
- elementAttributeInternal(tNode, lView, name, value, sanitizer, namespace);
14797
- ngDevMode && storePropertyBindingMetadata(tView.data, tNode, 'attr.' + name, bindingIndex);
14331
+ elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
14332
+ ngDevMode &&
14333
+ storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 3, prefix, i0, i1, suffix);
14798
14334
  }
14799
- return ɵɵattribute;
14335
+ return ɵɵattributeInterpolate3;
14800
14336
  }
14801
-
14802
14337
  /**
14803
- * @license
14804
- * Copyright Google LLC All Rights Reserved.
14805
14338
  *
14806
- * Use of this source code is governed by an MIT-style license that can be
14807
- * found in the LICENSE file at https://angular.io/license
14808
- */
14809
- /**
14810
- * Create interpolation bindings with a variable number of expressions.
14339
+ * Update an interpolated attribute on an element with 4 bound values surrounded by text.
14811
14340
  *
14812
- * If there are 1 to 8 expressions `interpolation1()` to `interpolation8()` should be used instead.
14813
- * Those are faster because there is no need to create an array of expressions and iterate over it.
14341
+ * Used when the value passed to a property has 4 interpolated values in it:
14814
14342
  *
14815
- * `values`:
14816
- * - has static text at even indexes,
14817
- * - has evaluated expressions at odd indexes.
14818
- *
14819
- * Returns the concatenated string when any of the arguments changes, `NO_CHANGE` otherwise.
14820
- */
14821
- function interpolationV(lView, values) {
14822
- ngDevMode && assertLessThan(2, values.length, 'should have at least 3 values');
14823
- ngDevMode && assertEqual(values.length % 2, 1, 'should have an odd number of values');
14824
- let isBindingUpdated = false;
14825
- let bindingIndex = getBindingIndex();
14826
- for (let i = 1; i < values.length; i += 2) {
14827
- // Check if bindings (odd indexes) have changed
14828
- isBindingUpdated = bindingUpdated(lView, bindingIndex++, values[i]) || isBindingUpdated;
14829
- }
14830
- setBindingIndex(bindingIndex);
14831
- if (!isBindingUpdated) {
14832
- return NO_CHANGE;
14833
- }
14834
- // Build the updated content
14835
- let content = values[0];
14836
- for (let i = 1; i < values.length; i += 2) {
14837
- content += renderStringify(values[i]) + values[i + 1];
14838
- }
14839
- return content;
14840
- }
14841
- /**
14842
- * Creates an interpolation binding with 1 expression.
14843
- *
14844
- * @param prefix static value used for concatenation only.
14845
- * @param v0 value checked for change.
14846
- * @param suffix static value used for concatenation only.
14847
- */
14848
- function interpolation1(lView, prefix, v0, suffix) {
14849
- const different = bindingUpdated(lView, nextBindingIndex(), v0);
14850
- return different ? prefix + renderStringify(v0) + suffix : NO_CHANGE;
14851
- }
14852
- /**
14853
- * Creates an interpolation binding with 2 expressions.
14854
- */
14855
- function interpolation2(lView, prefix, v0, i0, v1, suffix) {
14856
- const bindingIndex = getBindingIndex();
14857
- const different = bindingUpdated2(lView, bindingIndex, v0, v1);
14858
- incrementBindingIndex(2);
14859
- return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + suffix : NO_CHANGE;
14860
- }
14861
- /**
14862
- * Creates an interpolation binding with 3 expressions.
14863
- */
14864
- function interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix) {
14865
- const bindingIndex = getBindingIndex();
14866
- const different = bindingUpdated3(lView, bindingIndex, v0, v1, v2);
14867
- incrementBindingIndex(3);
14868
- return different ?
14869
- prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + suffix :
14870
- NO_CHANGE;
14871
- }
14872
- /**
14873
- * Create an interpolation binding with 4 expressions.
14874
- */
14875
- function interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
14876
- const bindingIndex = getBindingIndex();
14877
- const different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14878
- incrementBindingIndex(4);
14879
- return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14880
- renderStringify(v2) + i2 + renderStringify(v3) + suffix :
14881
- NO_CHANGE;
14882
- }
14883
- /**
14884
- * Creates an interpolation binding with 5 expressions.
14885
- */
14886
- function interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
14887
- const bindingIndex = getBindingIndex();
14888
- let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14889
- different = bindingUpdated(lView, bindingIndex + 4, v4) || different;
14890
- incrementBindingIndex(5);
14891
- return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14892
- renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + suffix :
14893
- NO_CHANGE;
14894
- }
14895
- /**
14896
- * Creates an interpolation binding with 6 expressions.
14897
- */
14898
- function interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
14899
- const bindingIndex = getBindingIndex();
14900
- let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14901
- different = bindingUpdated2(lView, bindingIndex + 4, v4, v5) || different;
14902
- incrementBindingIndex(6);
14903
- return different ?
14904
- prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 +
14905
- renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + suffix :
14906
- NO_CHANGE;
14907
- }
14908
- /**
14909
- * Creates an interpolation binding with 7 expressions.
14910
- */
14911
- function interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
14912
- const bindingIndex = getBindingIndex();
14913
- let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14914
- different = bindingUpdated3(lView, bindingIndex + 4, v4, v5, v6) || different;
14915
- incrementBindingIndex(7);
14916
- return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14917
- renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 +
14918
- renderStringify(v5) + i5 + renderStringify(v6) + suffix :
14919
- NO_CHANGE;
14920
- }
14921
- /**
14922
- * Creates an interpolation binding with 8 expressions.
14923
- */
14924
- function interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
14925
- const bindingIndex = getBindingIndex();
14926
- let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14927
- different = bindingUpdated4(lView, bindingIndex + 4, v4, v5, v6, v7) || different;
14928
- incrementBindingIndex(8);
14929
- return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14930
- renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 +
14931
- renderStringify(v5) + i5 + renderStringify(v6) + i6 + renderStringify(v7) + suffix :
14932
- NO_CHANGE;
14933
- }
14934
-
14935
- /**
14936
- *
14937
- * Update an interpolated attribute on an element with single bound value surrounded by text.
14938
- *
14939
- * Used when the value passed to a property has 1 interpolated value in it:
14940
- *
14941
- * ```html
14942
- * <div attr.title="prefix{{v0}}suffix"></div>
14943
- * ```
14944
- *
14945
- * Its compiled representation is::
14946
- *
14947
- * ```ts
14948
- * ɵɵattributeInterpolate1('title', 'prefix', v0, 'suffix');
14949
- * ```
14950
- *
14951
- * @param attrName The name of the attribute to update
14952
- * @param prefix Static value used for concatenation only.
14953
- * @param v0 Value checked for change.
14954
- * @param suffix Static value used for concatenation only.
14955
- * @param sanitizer An optional sanitizer function
14956
- * @returns itself, so that it may be chained.
14957
- * @codeGenApi
14958
- */
14959
- function ɵɵattributeInterpolate1(attrName, prefix, v0, suffix, sanitizer, namespace) {
14960
- const lView = getLView();
14961
- const interpolatedValue = interpolation1(lView, prefix, v0, suffix);
14962
- if (interpolatedValue !== NO_CHANGE) {
14963
- const tNode = getSelectedTNode();
14964
- elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
14965
- ngDevMode &&
14966
- storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 1, prefix, suffix);
14967
- }
14968
- return ɵɵattributeInterpolate1;
14969
- }
14970
- /**
14971
- *
14972
- * Update an interpolated attribute on an element with 2 bound values surrounded by text.
14973
- *
14974
- * Used when the value passed to a property has 2 interpolated values in it:
14975
- *
14976
- * ```html
14977
- * <div attr.title="prefix{{v0}}-{{v1}}suffix"></div>
14978
- * ```
14979
- *
14980
- * Its compiled representation is::
14981
- *
14982
- * ```ts
14983
- * ɵɵattributeInterpolate2('title', 'prefix', v0, '-', v1, 'suffix');
14984
- * ```
14985
- *
14986
- * @param attrName The name of the attribute to update
14987
- * @param prefix Static value used for concatenation only.
14988
- * @param v0 Value checked for change.
14989
- * @param i0 Static value used for concatenation only.
14990
- * @param v1 Value checked for change.
14991
- * @param suffix Static value used for concatenation only.
14992
- * @param sanitizer An optional sanitizer function
14993
- * @returns itself, so that it may be chained.
14994
- * @codeGenApi
14995
- */
14996
- function ɵɵattributeInterpolate2(attrName, prefix, v0, i0, v1, suffix, sanitizer, namespace) {
14997
- const lView = getLView();
14998
- const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
14999
- if (interpolatedValue !== NO_CHANGE) {
15000
- const tNode = getSelectedTNode();
15001
- elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
15002
- ngDevMode &&
15003
- storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 2, prefix, i0, suffix);
15004
- }
15005
- return ɵɵattributeInterpolate2;
15006
- }
15007
- /**
15008
- *
15009
- * Update an interpolated attribute on an element with 3 bound values surrounded by text.
15010
- *
15011
- * Used when the value passed to a property has 3 interpolated values in it:
15012
- *
15013
- * ```html
15014
- * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
15015
- * ```
15016
- *
15017
- * Its compiled representation is::
15018
- *
15019
- * ```ts
15020
- * ɵɵattributeInterpolate3(
15021
- * 'title', 'prefix', v0, '-', v1, '-', v2, 'suffix');
15022
- * ```
15023
- *
15024
- * @param attrName The name of the attribute to update
15025
- * @param prefix Static value used for concatenation only.
15026
- * @param v0 Value checked for change.
15027
- * @param i0 Static value used for concatenation only.
15028
- * @param v1 Value checked for change.
15029
- * @param i1 Static value used for concatenation only.
15030
- * @param v2 Value checked for change.
15031
- * @param suffix Static value used for concatenation only.
15032
- * @param sanitizer An optional sanitizer function
15033
- * @returns itself, so that it may be chained.
15034
- * @codeGenApi
15035
- */
15036
- function ɵɵattributeInterpolate3(attrName, prefix, v0, i0, v1, i1, v2, suffix, sanitizer, namespace) {
15037
- const lView = getLView();
15038
- const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
15039
- if (interpolatedValue !== NO_CHANGE) {
15040
- const tNode = getSelectedTNode();
15041
- elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
15042
- ngDevMode &&
15043
- storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 3, prefix, i0, i1, suffix);
15044
- }
15045
- return ɵɵattributeInterpolate3;
15046
- }
15047
- /**
15048
- *
15049
- * Update an interpolated attribute on an element with 4 bound values surrounded by text.
15050
- *
15051
- * Used when the value passed to a property has 4 interpolated values in it:
15052
- *
15053
- * ```html
15054
- * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
15055
- * ```
14343
+ * ```html
14344
+ * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
14345
+ * ```
15056
14346
  *
15057
14347
  * Its compiled representation is::
15058
14348
  *
@@ -15324,30 +14614,81 @@ function ɵɵattributeInterpolateV(attrName, values, sanitizer, namespace) {
15324
14614
  * Use of this source code is governed by an MIT-style license that can be
15325
14615
  * found in the LICENSE file at https://angular.io/license
15326
14616
  */
15327
- function templateFirstCreatePass(index, tView, lView, templateFn, decls, vars, tagName, attrsIndex, localRefsIndex) {
15328
- ngDevMode && assertFirstCreatePass(tView);
15329
- ngDevMode && ngDevMode.firstCreatePass++;
15330
- const tViewConsts = tView.consts;
15331
- // TODO(pk): refactor getOrCreateTNode to have the "create" only version
15332
- const tNode = getOrCreateTNode(tView, index, 4 /* TNodeType.Container */, tagName || null, getConstant(tViewConsts, attrsIndex));
15333
- resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex));
15334
- registerPostOrderHooks(tView, tNode);
15335
- const embeddedTView = tNode.tViews = createTView(2 /* TViewType.Embedded */, tNode, templateFn, decls, vars, tView.directiveRegistry, tView.pipeRegistry, null, tView.schemas, tViewConsts);
15336
- if (tView.queries !== null) {
15337
- tView.queries.template(tView, tNode);
15338
- embeddedTView.queries = tView.queries.embeddedTView(tNode);
15339
- }
15340
- return tNode;
15341
- }
15342
14617
  /**
15343
- * Creates an LContainer for an ng-template (dynamically-inserted view), e.g.
14618
+ * Synchronously perform change detection on a component (and possibly its sub-components).
15344
14619
  *
15345
- * <ng-template #foo>
15346
- * <div></div>
15347
- * </ng-template>
14620
+ * This function triggers change detection in a synchronous way on a component.
15348
14621
  *
15349
- * @param index The index of the container in the data array
15350
- * @param templateFn Inline template
14622
+ * @param component The component which the change detection should be performed on.
14623
+ */
14624
+ function detectChanges(component) {
14625
+ const view = getComponentViewByInstance(component);
14626
+ detectChangesInternal(view[TVIEW], view, component);
14627
+ }
14628
+ /**
14629
+ * Marks the component as dirty (needing change detection). Marking a component dirty will
14630
+ * schedule a change detection on it at some point in the future.
14631
+ *
14632
+ * Marking an already dirty component as dirty won't do anything. Only one outstanding change
14633
+ * detection can be scheduled per component tree.
14634
+ *
14635
+ * @param component Component to mark as dirty.
14636
+ */
14637
+ function markDirty(component) {
14638
+ ngDevMode && assertDefined(component, 'component');
14639
+ const rootView = markViewDirty(getComponentViewByInstance(component));
14640
+ ngDevMode && assertDefined(rootView[CONTEXT], 'rootContext should be defined');
14641
+ scheduleTick(rootView[CONTEXT], 1 /* RootContextFlags.DetectChanges */);
14642
+ }
14643
+ /**
14644
+ * Used to perform change detection on the whole application.
14645
+ *
14646
+ * This is equivalent to `detectChanges`, but invoked on root component. Additionally, `tick`
14647
+ * executes lifecycle hooks and conditionally checks components based on their
14648
+ * `ChangeDetectionStrategy` and dirtiness.
14649
+ *
14650
+ * The preferred way to trigger change detection is to call `markDirty`. `markDirty` internally
14651
+ * schedules `tick` using a scheduler in order to coalesce multiple `markDirty` calls into a
14652
+ * single change detection run. By default, the scheduler is `requestAnimationFrame`, but can
14653
+ * be changed when calling `renderComponent` and providing the `scheduler` option.
14654
+ */
14655
+ function tick(component) {
14656
+ const rootView = getRootView(component);
14657
+ const rootContext = rootView[CONTEXT];
14658
+ tickRootContext(rootContext);
14659
+ }
14660
+
14661
+ /**
14662
+ * @license
14663
+ * Copyright Google LLC All Rights Reserved.
14664
+ *
14665
+ * Use of this source code is governed by an MIT-style license that can be
14666
+ * found in the LICENSE file at https://angular.io/license
14667
+ */
14668
+ function templateFirstCreatePass(index, tView, lView, templateFn, decls, vars, tagName, attrsIndex, localRefsIndex) {
14669
+ ngDevMode && assertFirstCreatePass(tView);
14670
+ ngDevMode && ngDevMode.firstCreatePass++;
14671
+ const tViewConsts = tView.consts;
14672
+ // TODO(pk): refactor getOrCreateTNode to have the "create" only version
14673
+ const tNode = getOrCreateTNode(tView, index, 4 /* TNodeType.Container */, tagName || null, getConstant(tViewConsts, attrsIndex));
14674
+ resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex));
14675
+ registerPostOrderHooks(tView, tNode);
14676
+ const embeddedTView = tNode.tViews = createTView(2 /* TViewType.Embedded */, tNode, templateFn, decls, vars, tView.directiveRegistry, tView.pipeRegistry, null, tView.schemas, tViewConsts);
14677
+ if (tView.queries !== null) {
14678
+ tView.queries.template(tView, tNode);
14679
+ embeddedTView.queries = tView.queries.embeddedTView(tNode);
14680
+ }
14681
+ return tNode;
14682
+ }
14683
+ /**
14684
+ * Creates an LContainer for an ng-template (dynamically-inserted view), e.g.
14685
+ *
14686
+ * <ng-template #foo>
14687
+ * <div></div>
14688
+ * </ng-template>
14689
+ *
14690
+ * @param index The index of the container in the data array
14691
+ * @param templateFn Inline template
15351
14692
  * @param decls The number of nodes, local refs, and pipes for this template
15352
14693
  * @param vars The number of bindings for this template
15353
14694
  * @param tagName The name of the container element, if applicable
@@ -15861,51 +15202,42 @@ function listenerInternal(tView, lView, renderer, tNode, eventName, listenerFn,
15861
15202
  tNode.index;
15862
15203
  // In order to match current behavior, native DOM event listeners must be added for all
15863
15204
  // events (including outputs).
15864
- if (isProceduralRenderer(renderer)) {
15865
- // There might be cases where multiple directives on the same element try to register an event
15866
- // handler function for the same event. In this situation we want to avoid registration of
15867
- // several native listeners as each registration would be intercepted by NgZone and
15868
- // trigger change detection. This would mean that a single user action would result in several
15869
- // change detections being invoked. To avoid this situation we want to have only one call to
15870
- // native handler registration (for the same element and same type of event).
15871
- //
15872
- // In order to have just one native event handler in presence of multiple handler functions,
15873
- // we just register a first handler function as a native event listener and then chain
15874
- // (coalesce) other handler functions on top of the first native handler function.
15875
- let existingListener = null;
15876
- // Please note that the coalescing described here doesn't happen for events specifying an
15877
- // alternative target (ex. (document:click)) - this is to keep backward compatibility with the
15878
- // view engine.
15879
- // Also, we don't have to search for existing listeners is there are no directives
15880
- // matching on a given node as we can't register multiple event handlers for the same event in
15881
- // a template (this would mean having duplicate attributes).
15882
- if (!eventTargetResolver && isTNodeDirectiveHost) {
15883
- existingListener = findExistingListener(tView, lView, eventName, tNode.index);
15884
- }
15885
- if (existingListener !== null) {
15886
- // Attach a new listener to coalesced listeners list, maintaining the order in which
15887
- // listeners are registered. For performance reasons, we keep a reference to the last
15888
- // listener in that list (in `__ngLastListenerFn__` field), so we can avoid going through
15889
- // the entire set each time we need to add a new listener.
15890
- const lastListenerFn = existingListener.__ngLastListenerFn__ || existingListener;
15891
- lastListenerFn.__ngNextListenerFn__ = listenerFn;
15892
- existingListener.__ngLastListenerFn__ = listenerFn;
15893
- processOutputs = false;
15894
- }
15895
- else {
15896
- listenerFn = wrapListener(tNode, lView, context, listenerFn, false /** preventDefault */);
15897
- const cleanupFn = renderer.listen(target, eventName, listenerFn);
15898
- ngDevMode && ngDevMode.rendererAddEventListener++;
15899
- lCleanup.push(listenerFn, cleanupFn);
15900
- tCleanup && tCleanup.push(eventName, idxOrTargetGetter, lCleanupIndex, lCleanupIndex + 1);
15901
- }
15205
+ // There might be cases where multiple directives on the same element try to register an event
15206
+ // handler function for the same event. In this situation we want to avoid registration of
15207
+ // several native listeners as each registration would be intercepted by NgZone and
15208
+ // trigger change detection. This would mean that a single user action would result in several
15209
+ // change detections being invoked. To avoid this situation we want to have only one call to
15210
+ // native handler registration (for the same element and same type of event).
15211
+ //
15212
+ // In order to have just one native event handler in presence of multiple handler functions,
15213
+ // we just register a first handler function as a native event listener and then chain
15214
+ // (coalesce) other handler functions on top of the first native handler function.
15215
+ let existingListener = null;
15216
+ // Please note that the coalescing described here doesn't happen for events specifying an
15217
+ // alternative target (ex. (document:click)) - this is to keep backward compatibility with the
15218
+ // view engine.
15219
+ // Also, we don't have to search for existing listeners is there are no directives
15220
+ // matching on a given node as we can't register multiple event handlers for the same event in
15221
+ // a template (this would mean having duplicate attributes).
15222
+ if (!eventTargetResolver && isTNodeDirectiveHost) {
15223
+ existingListener = findExistingListener(tView, lView, eventName, tNode.index);
15224
+ }
15225
+ if (existingListener !== null) {
15226
+ // Attach a new listener to coalesced listeners list, maintaining the order in which
15227
+ // listeners are registered. For performance reasons, we keep a reference to the last
15228
+ // listener in that list (in `__ngLastListenerFn__` field), so we can avoid going through
15229
+ // the entire set each time we need to add a new listener.
15230
+ const lastListenerFn = existingListener.__ngLastListenerFn__ || existingListener;
15231
+ lastListenerFn.__ngNextListenerFn__ = listenerFn;
15232
+ existingListener.__ngLastListenerFn__ = listenerFn;
15233
+ processOutputs = false;
15902
15234
  }
15903
15235
  else {
15904
- listenerFn = wrapListener(tNode, lView, context, listenerFn, true /** preventDefault */);
15905
- target.addEventListener(eventName, listenerFn, useCapture);
15236
+ listenerFn = wrapListener(tNode, lView, context, listenerFn, false /** preventDefault */);
15237
+ const cleanupFn = renderer.listen(target, eventName, listenerFn);
15906
15238
  ngDevMode && ngDevMode.rendererAddEventListener++;
15907
- lCleanup.push(listenerFn);
15908
- tCleanup && tCleanup.push(eventName, idxOrTargetGetter, lCleanupIndex, useCapture);
15239
+ lCleanup.push(listenerFn, cleanupFn);
15240
+ tCleanup && tCleanup.push(eventName, idxOrTargetGetter, lCleanupIndex, lCleanupIndex + 1);
15909
15241
  }
15910
15242
  }
15911
15243
  else {
@@ -17979,7 +17311,7 @@ function findStylingValue(tData, tNode, lView, prop, index, isClassBased) {
17979
17311
  valueAtLViewIndex = isStylingMap ? EMPTY_ARRAY : undefined;
17980
17312
  }
17981
17313
  let currentValue = isStylingMap ? keyValueArrayGet(valueAtLViewIndex, prop) :
17982
- key === prop ? valueAtLViewIndex : undefined;
17314
+ (key === prop ? valueAtLViewIndex : undefined);
17983
17315
  if (containsStatics && !isStylingValuePresent(currentValue)) {
17984
17316
  currentValue = keyValueArrayGet(rawKey, prop);
17985
17317
  }
@@ -21832,7 +21164,7 @@ function noComponentFactoryError(component) {
21832
21164
  return error;
21833
21165
  }
21834
21166
  const ERROR_COMPONENT = 'ngComponent';
21835
- function getComponent(error) {
21167
+ function getComponent$1(error) {
21836
21168
  return error[ERROR_COMPONENT];
21837
21169
  }
21838
21170
  class _NullComponentFactoryResolver {
@@ -22016,14 +21348,6 @@ class Renderer2 {
22016
21348
  * @nocollapse
22017
21349
  */
22018
21350
  Renderer2.__NG_ELEMENT_ID__ = () => injectRenderer2();
22019
- /** Returns a Renderer2 (or throws when application was bootstrapped with Renderer3) */
22020
- function getOrCreateRenderer2(lView) {
22021
- const renderer = lView[RENDERER];
22022
- if (ngDevMode && !isProceduralRenderer(renderer)) {
22023
- throw new Error('Cannot inject Renderer2 when the application uses Renderer3!');
22024
- }
22025
- return renderer;
22026
- }
22027
21351
  /** Injects a Renderer2 for the current component. */
22028
21352
  function injectRenderer2() {
22029
21353
  // We need the Renderer to be based on the component that it's being injected into, however since
@@ -22031,7 +21355,7 @@ function injectRenderer2() {
22031
21355
  const lView = getLView();
22032
21356
  const tNode = getCurrentTNode();
22033
21357
  const nodeAtIndex = getComponentLViewByIndex(tNode.index, lView);
22034
- return getOrCreateRenderer2(isLView(nodeAtIndex) ? nodeAtIndex : lView);
21358
+ return (isLView(nodeAtIndex) ? nodeAtIndex : lView)[RENDERER];
22035
21359
  }
22036
21360
 
22037
21361
  /**
@@ -22078,7 +21402,7 @@ class Version {
22078
21402
  /**
22079
21403
  * @publicApi
22080
21404
  */
22081
- const VERSION = new Version('14.1.0-next.3');
21405
+ const VERSION = new Version('14.1.0-next.4');
22082
21406
 
22083
21407
  /**
22084
21408
  * @license
@@ -22542,7 +21866,13 @@ class ComponentFactory extends ComponentFactory$1 {
22542
21866
  realEnvironmentInjector;
22543
21867
  }
22544
21868
  const rootViewInjector = realEnvironmentInjector ? new ChainedInjector(injector, realEnvironmentInjector) : injector;
22545
- const rendererFactory = rootViewInjector.get(RendererFactory2, domRendererFactory3);
21869
+ const rendererFactory = rootViewInjector.get(RendererFactory2, null);
21870
+ if (rendererFactory === null) {
21871
+ throw new RuntimeError(407 /* RuntimeErrorCode.RENDERER_NOT_FOUND */, ngDevMode &&
21872
+ 'Angular was not able to inject a renderer (RendererFactory2). ' +
21873
+ 'Likely this is due to a broken DI hierarchy. ' +
21874
+ 'Make sure that any injector used to create this component has a correct parent.');
21875
+ }
22546
21876
  const sanitizer = rootViewInjector.get(Sanitizer, null);
22547
21877
  const hostRenderer = rendererFactory.createRenderer(null, this.componentDef);
22548
21878
  // Determine a tag name used for creating host elements when this component is created
@@ -22638,6 +21968,23 @@ class ComponentRef extends ComponentRef$1 {
22638
21968
  this.hostView = this.changeDetectorRef = new RootViewRef(_rootLView);
22639
21969
  this.componentType = componentType;
22640
21970
  }
21971
+ setInput(name, value) {
21972
+ const inputData = this._tNode.inputs;
21973
+ let dataValue;
21974
+ if (inputData !== null && (dataValue = inputData[name])) {
21975
+ const lView = this._rootLView;
21976
+ setInputsForProperty(lView[TVIEW], lView, dataValue, name, value);
21977
+ markDirtyIfOnPush(lView, this._tNode.index);
21978
+ }
21979
+ else {
21980
+ if (ngDevMode) {
21981
+ const cmpNameForError = stringifyForError(this.componentType);
21982
+ let message = `Can't set value of the '${name}' input on the '${cmpNameForError}' component. `;
21983
+ message += `Make sure that the '${name}' property is annotated with @Input() or a mapped @Input('${name}') exists.`;
21984
+ reportUnknownPropertyError(message);
21985
+ }
21986
+ }
21987
+ }
22641
21988
  get injector() {
22642
21989
  return new NodeInjector(this._tNode, this._rootLView);
22643
21990
  }
@@ -22703,6 +22050,9 @@ class NgModuleRef extends NgModuleRef$1 {
22703
22050
  }
22704
22051
  return this._r3Injector.get(token, notFoundValue, injectFlags);
22705
22052
  }
22053
+ runInContext(fn) {
22054
+ return this.injector.runInContext(fn);
22055
+ }
22706
22056
  destroy() {
22707
22057
  ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
22708
22058
  const injector = this._r3Injector;
@@ -22714,118 +22064,528 @@ class NgModuleRef extends NgModuleRef$1 {
22714
22064
  ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
22715
22065
  this.destroyCbs.push(callback);
22716
22066
  }
22717
- }
22718
- class NgModuleFactory extends NgModuleFactory$1 {
22719
- constructor(moduleType) {
22720
- super();
22721
- this.moduleType = moduleType;
22067
+ }
22068
+ class NgModuleFactory extends NgModuleFactory$1 {
22069
+ constructor(moduleType) {
22070
+ super();
22071
+ this.moduleType = moduleType;
22072
+ }
22073
+ create(parentInjector) {
22074
+ return new NgModuleRef(this.moduleType, parentInjector);
22075
+ }
22076
+ }
22077
+ class EnvironmentNgModuleRefAdapter extends NgModuleRef$1 {
22078
+ constructor(providers, parent, source) {
22079
+ super();
22080
+ this.componentFactoryResolver = new ComponentFactoryResolver(this);
22081
+ this.instance = null;
22082
+ const injector = new R3Injector([
22083
+ ...providers,
22084
+ { provide: NgModuleRef$1, useValue: this },
22085
+ { provide: ComponentFactoryResolver$1, useValue: this.componentFactoryResolver },
22086
+ ], parent || getNullInjector(), source, new Set(['environment']));
22087
+ this.injector = injector;
22088
+ injector.resolveInjectorInitializers();
22089
+ }
22090
+ destroy() {
22091
+ this.injector.destroy();
22092
+ }
22093
+ onDestroy(callback) {
22094
+ this.injector.onDestroy(callback);
22095
+ }
22096
+ }
22097
+ /**
22098
+ * Create a new environment injector.
22099
+ *
22100
+ * Learn more about environment injectors in
22101
+ * [this guide](guide/standalone-components#environment-injectors).
22102
+ *
22103
+ * @param providers An array of providers.
22104
+ * @param parent A parent environment injector.
22105
+ * @param debugName An optional name for this injector instance, which will be used in error
22106
+ * messages.
22107
+ *
22108
+ * @publicApi
22109
+ * @developerPreview
22110
+ */
22111
+ function createEnvironmentInjector(providers, parent, debugName = null) {
22112
+ const adapter = new EnvironmentNgModuleRefAdapter(providers, parent, debugName);
22113
+ return adapter.injector;
22114
+ }
22115
+
22116
+ /**
22117
+ * @license
22118
+ * Copyright Google LLC All Rights Reserved.
22119
+ *
22120
+ * Use of this source code is governed by an MIT-style license that can be
22121
+ * found in the LICENSE file at https://angular.io/license
22122
+ */
22123
+ /**
22124
+ * A service used by the framework to create instances of standalone injectors. Those injectors are
22125
+ * created on demand in case of dynamic component instantiation and contain ambient providers
22126
+ * collected from the imports graph rooted at a given standalone component.
22127
+ */
22128
+ class StandaloneService {
22129
+ constructor(_injector) {
22130
+ this._injector = _injector;
22131
+ this.cachedInjectors = new Map();
22132
+ }
22133
+ getOrCreateStandaloneInjector(componentDef) {
22134
+ if (!componentDef.standalone) {
22135
+ return null;
22136
+ }
22137
+ if (!this.cachedInjectors.has(componentDef.id)) {
22138
+ const providers = internalImportProvidersFrom(false, componentDef.type);
22139
+ const standaloneInjector = providers.length > 0 ?
22140
+ createEnvironmentInjector([providers], this._injector, `Standalone[${componentDef.type.name}]`) :
22141
+ null;
22142
+ this.cachedInjectors.set(componentDef.id, standaloneInjector);
22143
+ }
22144
+ return this.cachedInjectors.get(componentDef.id);
22145
+ }
22146
+ ngOnDestroy() {
22147
+ try {
22148
+ for (const injector of this.cachedInjectors.values()) {
22149
+ if (injector !== null) {
22150
+ injector.destroy();
22151
+ }
22152
+ }
22153
+ }
22154
+ finally {
22155
+ this.cachedInjectors.clear();
22156
+ }
22157
+ }
22158
+ }
22159
+ /** @nocollapse */
22160
+ StandaloneService.ɵprov = ɵɵdefineInjectable({
22161
+ token: StandaloneService,
22162
+ providedIn: 'environment',
22163
+ factory: () => new StandaloneService(ɵɵinject(EnvironmentInjector)),
22164
+ });
22165
+ /**
22166
+ * A feature that acts as a setup code for the {@link StandaloneService}.
22167
+ *
22168
+ * The most important responsaibility of this feature is to expose the "getStandaloneInjector"
22169
+ * function (an entry points to a standalone injector creation) on a component definition object. We
22170
+ * go through the features infrastructure to make sure that the standalone injector creation logic
22171
+ * is tree-shakable and not included in applications that don't use standalone components.
22172
+ *
22173
+ * @codeGenApi
22174
+ */
22175
+ function ɵɵStandaloneFeature(definition) {
22176
+ definition.getStandaloneInjector = (parentInjector) => {
22177
+ return parentInjector.get(StandaloneService).getOrCreateStandaloneInjector(definition);
22178
+ };
22179
+ }
22180
+
22181
+ /**
22182
+ * @license
22183
+ * Copyright Google LLC All Rights Reserved.
22184
+ *
22185
+ * Use of this source code is governed by an MIT-style license that can be
22186
+ * found in the LICENSE file at https://angular.io/license
22187
+ */
22188
+ /**
22189
+ * Retrieves the component instance associated with a given DOM element.
22190
+ *
22191
+ * @usageNotes
22192
+ * Given the following DOM structure:
22193
+ *
22194
+ * ```html
22195
+ * <app-root>
22196
+ * <div>
22197
+ * <child-comp></child-comp>
22198
+ * </div>
22199
+ * </app-root>
22200
+ * ```
22201
+ *
22202
+ * Calling `getComponent` on `<child-comp>` will return the instance of `ChildComponent`
22203
+ * associated with this DOM element.
22204
+ *
22205
+ * Calling the function on `<app-root>` will return the `MyApp` instance.
22206
+ *
22207
+ *
22208
+ * @param element DOM element from which the component should be retrieved.
22209
+ * @returns Component instance associated with the element or `null` if there
22210
+ * is no component associated with it.
22211
+ *
22212
+ * @publicApi
22213
+ * @globalApi ng
22214
+ */
22215
+ function getComponent(element) {
22216
+ ngDevMode && assertDomElement(element);
22217
+ const context = getLContext(element);
22218
+ if (context === null)
22219
+ return null;
22220
+ if (context.component === undefined) {
22221
+ const lView = context.lView;
22222
+ if (lView === null) {
22223
+ return null;
22224
+ }
22225
+ context.component = getComponentAtNodeIndex(context.nodeIndex, lView);
22226
+ }
22227
+ return context.component;
22228
+ }
22229
+ /**
22230
+ * If inside an embedded view (e.g. `*ngIf` or `*ngFor`), retrieves the context of the embedded
22231
+ * view that the element is part of. Otherwise retrieves the instance of the component whose view
22232
+ * owns the element (in this case, the result is the same as calling `getOwningComponent`).
22233
+ *
22234
+ * @param element Element for which to get the surrounding component instance.
22235
+ * @returns Instance of the component that is around the element or null if the element isn't
22236
+ * inside any component.
22237
+ *
22238
+ * @publicApi
22239
+ * @globalApi ng
22240
+ */
22241
+ function getContext(element) {
22242
+ assertDomElement(element);
22243
+ const context = getLContext(element);
22244
+ const lView = context ? context.lView : null;
22245
+ return lView === null ? null : lView[CONTEXT];
22246
+ }
22247
+ /**
22248
+ * Retrieves the component instance whose view contains the DOM element.
22249
+ *
22250
+ * For example, if `<child-comp>` is used in the template of `<app-comp>`
22251
+ * (i.e. a `ViewChild` of `<app-comp>`), calling `getOwningComponent` on `<child-comp>`
22252
+ * would return `<app-comp>`.
22253
+ *
22254
+ * @param elementOrDir DOM element, component or directive instance
22255
+ * for which to retrieve the root components.
22256
+ * @returns Component instance whose view owns the DOM element or null if the element is not
22257
+ * part of a component view.
22258
+ *
22259
+ * @publicApi
22260
+ * @globalApi ng
22261
+ */
22262
+ function getOwningComponent(elementOrDir) {
22263
+ const context = getLContext(elementOrDir);
22264
+ let lView = context ? context.lView : null;
22265
+ if (lView === null)
22266
+ return null;
22267
+ let parent;
22268
+ while (lView[TVIEW].type === 2 /* TViewType.Embedded */ && (parent = getLViewParent(lView))) {
22269
+ lView = parent;
22270
+ }
22271
+ return lView[FLAGS] & 256 /* LViewFlags.IsRoot */ ? null : lView[CONTEXT];
22272
+ }
22273
+ /**
22274
+ * Retrieves all root components associated with a DOM element, directive or component instance.
22275
+ * Root components are those which have been bootstrapped by Angular.
22276
+ *
22277
+ * @param elementOrDir DOM element, component or directive instance
22278
+ * for which to retrieve the root components.
22279
+ * @returns Root components associated with the target object.
22280
+ *
22281
+ * @publicApi
22282
+ * @globalApi ng
22283
+ */
22284
+ function getRootComponents(elementOrDir) {
22285
+ const lView = readPatchedLView(elementOrDir);
22286
+ return lView !== null ? [...getRootContext(lView).components] : [];
22287
+ }
22288
+ /**
22289
+ * Retrieves an `Injector` associated with an element, component or directive instance.
22290
+ *
22291
+ * @param elementOrDir DOM element, component or directive instance for which to
22292
+ * retrieve the injector.
22293
+ * @returns Injector associated with the element, component or directive instance.
22294
+ *
22295
+ * @publicApi
22296
+ * @globalApi ng
22297
+ */
22298
+ function getInjector(elementOrDir) {
22299
+ const context = getLContext(elementOrDir);
22300
+ const lView = context ? context.lView : null;
22301
+ if (lView === null)
22302
+ return Injector.NULL;
22303
+ const tNode = lView[TVIEW].data[context.nodeIndex];
22304
+ return new NodeInjector(tNode, lView);
22305
+ }
22306
+ /**
22307
+ * Retrieve a set of injection tokens at a given DOM node.
22308
+ *
22309
+ * @param element Element for which the injection tokens should be retrieved.
22310
+ */
22311
+ function getInjectionTokens(element) {
22312
+ const context = getLContext(element);
22313
+ const lView = context ? context.lView : null;
22314
+ if (lView === null)
22315
+ return [];
22316
+ const tView = lView[TVIEW];
22317
+ const tNode = tView.data[context.nodeIndex];
22318
+ const providerTokens = [];
22319
+ const startIndex = tNode.providerIndexes & 1048575 /* TNodeProviderIndexes.ProvidersStartIndexMask */;
22320
+ const endIndex = tNode.directiveEnd;
22321
+ for (let i = startIndex; i < endIndex; i++) {
22322
+ let value = tView.data[i];
22323
+ if (isDirectiveDefHack(value)) {
22324
+ // The fact that we sometimes store Type and sometimes DirectiveDef in this location is a
22325
+ // design flaw. We should always store same type so that we can be monomorphic. The issue
22326
+ // is that for Components/Directives we store the def instead the type. The correct behavior
22327
+ // is that we should always be storing injectable type in this location.
22328
+ value = value.type;
22329
+ }
22330
+ providerTokens.push(value);
22331
+ }
22332
+ return providerTokens;
22333
+ }
22334
+ /**
22335
+ * Retrieves directive instances associated with a given DOM node. Does not include
22336
+ * component instances.
22337
+ *
22338
+ * @usageNotes
22339
+ * Given the following DOM structure:
22340
+ *
22341
+ * ```html
22342
+ * <app-root>
22343
+ * <button my-button></button>
22344
+ * <my-comp></my-comp>
22345
+ * </app-root>
22346
+ * ```
22347
+ *
22348
+ * Calling `getDirectives` on `<button>` will return an array with an instance of the `MyButton`
22349
+ * directive that is associated with the DOM node.
22350
+ *
22351
+ * Calling `getDirectives` on `<my-comp>` will return an empty array.
22352
+ *
22353
+ * @param node DOM node for which to get the directives.
22354
+ * @returns Array of directives associated with the node.
22355
+ *
22356
+ * @publicApi
22357
+ * @globalApi ng
22358
+ */
22359
+ function getDirectives(node) {
22360
+ // Skip text nodes because we can't have directives associated with them.
22361
+ if (node instanceof Text) {
22362
+ return [];
22363
+ }
22364
+ const context = getLContext(node);
22365
+ const lView = context ? context.lView : null;
22366
+ if (lView === null) {
22367
+ return [];
22368
+ }
22369
+ const tView = lView[TVIEW];
22370
+ const nodeIndex = context.nodeIndex;
22371
+ if (!tView?.data[nodeIndex]) {
22372
+ return [];
22373
+ }
22374
+ if (context.directives === undefined) {
22375
+ context.directives = getDirectivesAtNodeIndex(nodeIndex, lView, false);
22376
+ }
22377
+ // The `directives` in this case are a named array called `LComponentView`. Clone the
22378
+ // result so we don't expose an internal data structure in the user's console.
22379
+ return context.directives === null ? [] : [...context.directives];
22380
+ }
22381
+ /**
22382
+ * Returns the debug (partial) metadata for a particular directive or component instance.
22383
+ * The function accepts an instance of a directive or component and returns the corresponding
22384
+ * metadata.
22385
+ *
22386
+ * @param directiveOrComponentInstance Instance of a directive or component
22387
+ * @returns metadata of the passed directive or component
22388
+ *
22389
+ * @publicApi
22390
+ * @globalApi ng
22391
+ */
22392
+ function getDirectiveMetadata(directiveOrComponentInstance) {
22393
+ const { constructor } = directiveOrComponentInstance;
22394
+ if (!constructor) {
22395
+ throw new Error('Unable to find the instance constructor');
22396
+ }
22397
+ // In case a component inherits from a directive, we may have component and directive metadata
22398
+ // To ensure we don't get the metadata of the directive, we want to call `getComponentDef` first.
22399
+ const componentDef = getComponentDef$1(constructor);
22400
+ if (componentDef) {
22401
+ return {
22402
+ inputs: componentDef.inputs,
22403
+ outputs: componentDef.outputs,
22404
+ encapsulation: componentDef.encapsulation,
22405
+ changeDetection: componentDef.onPush ? ChangeDetectionStrategy.OnPush :
22406
+ ChangeDetectionStrategy.Default
22407
+ };
22722
22408
  }
22723
- create(parentInjector) {
22724
- return new NgModuleRef(this.moduleType, parentInjector);
22409
+ const directiveDef = getDirectiveDef(constructor);
22410
+ if (directiveDef) {
22411
+ return { inputs: directiveDef.inputs, outputs: directiveDef.outputs };
22725
22412
  }
22413
+ return null;
22726
22414
  }
22727
- class EnvironmentNgModuleRefAdapter extends NgModuleRef$1 {
22728
- constructor(providers, parent, source) {
22729
- super();
22730
- this.componentFactoryResolver = new ComponentFactoryResolver(this);
22731
- this.instance = null;
22732
- const injector = new R3Injector([
22733
- ...providers,
22734
- { provide: NgModuleRef$1, useValue: this },
22735
- { provide: ComponentFactoryResolver$1, useValue: this.componentFactoryResolver },
22736
- ], parent || getNullInjector(), source, new Set(['environment']));
22737
- this.injector = injector;
22738
- injector.resolveInjectorInitializers();
22739
- }
22740
- destroy() {
22741
- this.injector.destroy();
22742
- }
22743
- onDestroy(callback) {
22744
- this.injector.onDestroy(callback);
22415
+ /**
22416
+ * Retrieve map of local references.
22417
+ *
22418
+ * The references are retrieved as a map of local reference name to element or directive instance.
22419
+ *
22420
+ * @param target DOM element, component or directive instance for which to retrieve
22421
+ * the local references.
22422
+ */
22423
+ function getLocalRefs(target) {
22424
+ const context = getLContext(target);
22425
+ if (context === null)
22426
+ return {};
22427
+ if (context.localRefs === undefined) {
22428
+ const lView = context.lView;
22429
+ if (lView === null) {
22430
+ return {};
22431
+ }
22432
+ context.localRefs = discoverLocalRefs(lView, context.nodeIndex);
22745
22433
  }
22434
+ return context.localRefs || {};
22746
22435
  }
22747
22436
  /**
22748
- * Create a new environment injector.
22749
- *
22750
- * Learn more about environment injectors in
22751
- * [this guide](guide/standalone-components#environment-injectors).
22437
+ * Retrieves the host element of a component or directive instance.
22438
+ * The host element is the DOM element that matched the selector of the directive.
22752
22439
  *
22753
- * @param providers An array of providers.
22754
- * @param parent A parent environment injector.
22755
- * @param debugName An optional name for this injector instance, which will be used in error
22756
- * messages.
22440
+ * @param componentOrDirective Component or directive instance for which the host
22441
+ * element should be retrieved.
22442
+ * @returns Host element of the target.
22757
22443
  *
22758
22444
  * @publicApi
22759
- * @developerPreview
22445
+ * @globalApi ng
22760
22446
  */
22761
- function createEnvironmentInjector(providers, parent, debugName = null) {
22762
- const adapter = new EnvironmentNgModuleRefAdapter(providers, parent, debugName);
22763
- return adapter.injector;
22447
+ function getHostElement(componentOrDirective) {
22448
+ return getLContext(componentOrDirective).native;
22764
22449
  }
22765
-
22766
22450
  /**
22767
- * @license
22768
- * Copyright Google LLC All Rights Reserved.
22451
+ * Retrieves the rendered text for a given component.
22769
22452
  *
22770
- * Use of this source code is governed by an MIT-style license that can be
22771
- * found in the LICENSE file at https://angular.io/license
22453
+ * This function retrieves the host element of a component and
22454
+ * and then returns the `textContent` for that element. This implies
22455
+ * that the text returned will include re-projected content of
22456
+ * the component as well.
22457
+ *
22458
+ * @param component The component to return the content text for.
22772
22459
  */
22460
+ function getRenderedText(component) {
22461
+ const hostElement = getHostElement(component);
22462
+ return hostElement.textContent || '';
22463
+ }
22773
22464
  /**
22774
- * A service used by the framework to create instances of standalone injectors. Those injectors are
22775
- * created on demand in case of dynamic component instantiation and contain ambient providers
22776
- * collected from the imports graph rooted at a given standalone component.
22465
+ * Retrieves a list of event listeners associated with a DOM element. The list does include host
22466
+ * listeners, but it does not include event listeners defined outside of the Angular context
22467
+ * (e.g. through `addEventListener`).
22468
+ *
22469
+ * @usageNotes
22470
+ * Given the following DOM structure:
22471
+ *
22472
+ * ```html
22473
+ * <app-root>
22474
+ * <div (click)="doSomething()"></div>
22475
+ * </app-root>
22476
+ * ```
22477
+ *
22478
+ * Calling `getListeners` on `<div>` will return an object that looks as follows:
22479
+ *
22480
+ * ```ts
22481
+ * {
22482
+ * name: 'click',
22483
+ * element: <div>,
22484
+ * callback: () => doSomething(),
22485
+ * useCapture: false
22486
+ * }
22487
+ * ```
22488
+ *
22489
+ * @param element Element for which the DOM listeners should be retrieved.
22490
+ * @returns Array of event listeners on the DOM element.
22491
+ *
22492
+ * @publicApi
22493
+ * @globalApi ng
22777
22494
  */
22778
- class StandaloneService {
22779
- constructor(_injector) {
22780
- this._injector = _injector;
22781
- this.cachedInjectors = new Map();
22782
- }
22783
- getOrCreateStandaloneInjector(componentDef) {
22784
- if (!componentDef.standalone) {
22785
- return null;
22786
- }
22787
- if (!this.cachedInjectors.has(componentDef.id)) {
22788
- const providers = internalImportProvidersFrom(false, componentDef.type);
22789
- const standaloneInjector = providers.length > 0 ?
22790
- createEnvironmentInjector([providers], this._injector, `Standalone[${componentDef.type.name}]`) :
22791
- null;
22792
- this.cachedInjectors.set(componentDef.id, standaloneInjector);
22793
- }
22794
- return this.cachedInjectors.get(componentDef.id);
22795
- }
22796
- ngOnDestroy() {
22797
- try {
22798
- for (const injector of this.cachedInjectors.values()) {
22799
- if (injector !== null) {
22800
- injector.destroy();
22495
+ function getListeners(element) {
22496
+ ngDevMode && assertDomElement(element);
22497
+ const lContext = getLContext(element);
22498
+ const lView = lContext === null ? null : lContext.lView;
22499
+ if (lView === null)
22500
+ return [];
22501
+ const tView = lView[TVIEW];
22502
+ const lCleanup = lView[CLEANUP];
22503
+ const tCleanup = tView.cleanup;
22504
+ const listeners = [];
22505
+ if (tCleanup && lCleanup) {
22506
+ for (let i = 0; i < tCleanup.length;) {
22507
+ const firstParam = tCleanup[i++];
22508
+ const secondParam = tCleanup[i++];
22509
+ if (typeof firstParam === 'string') {
22510
+ const name = firstParam;
22511
+ const listenerElement = unwrapRNode(lView[secondParam]);
22512
+ const callback = lCleanup[tCleanup[i++]];
22513
+ const useCaptureOrIndx = tCleanup[i++];
22514
+ // if useCaptureOrIndx is boolean then report it as is.
22515
+ // if useCaptureOrIndx is positive number then it in unsubscribe method
22516
+ // if useCaptureOrIndx is negative number then it is a Subscription
22517
+ const type = (typeof useCaptureOrIndx === 'boolean' || useCaptureOrIndx >= 0) ? 'dom' : 'output';
22518
+ const useCapture = typeof useCaptureOrIndx === 'boolean' ? useCaptureOrIndx : false;
22519
+ if (element == listenerElement) {
22520
+ listeners.push({ element, name, callback, useCapture, type });
22801
22521
  }
22802
22522
  }
22803
22523
  }
22804
- finally {
22805
- this.cachedInjectors.clear();
22806
- }
22807
22524
  }
22525
+ listeners.sort(sortListeners);
22526
+ return listeners;
22527
+ }
22528
+ function sortListeners(a, b) {
22529
+ if (a.name == b.name)
22530
+ return 0;
22531
+ return a.name < b.name ? -1 : 1;
22808
22532
  }
22809
- /** @nocollapse */
22810
- StandaloneService.ɵprov = ɵɵdefineInjectable({
22811
- token: StandaloneService,
22812
- providedIn: 'environment',
22813
- factory: () => new StandaloneService(ɵɵinject(EnvironmentInjector)),
22814
- });
22815
22533
  /**
22816
- * A feature that acts as a setup code for the {@link StandaloneService}.
22534
+ * This function should not exist because it is megamorphic and only mostly correct.
22817
22535
  *
22818
- * The most important responsaibility of this feature is to expose the "getStandaloneInjector"
22819
- * function (an entry points to a standalone injector creation) on a component definition object. We
22820
- * go through the features infrastructure to make sure that the standalone injector creation logic
22821
- * is tree-shakable and not included in applications that don't use standalone components.
22536
+ * See call site for more info.
22537
+ */
22538
+ function isDirectiveDefHack(obj) {
22539
+ return obj.type !== undefined && obj.template !== undefined && obj.declaredInputs !== undefined;
22540
+ }
22541
+ /**
22542
+ * Returns the attached `DebugNode` instance for an element in the DOM.
22822
22543
  *
22823
- * @codeGenApi
22544
+ * @param element DOM element which is owned by an existing component's view.
22824
22545
  */
22825
- function ɵɵStandaloneFeature(definition) {
22826
- definition.getStandaloneInjector = (parentInjector) => {
22827
- return parentInjector.get(StandaloneService).getOrCreateStandaloneInjector(definition);
22828
- };
22546
+ function getDebugNode(element) {
22547
+ if (ngDevMode && !(element instanceof Node)) {
22548
+ throw new Error('Expecting instance of DOM Element');
22549
+ }
22550
+ const lContext = getLContext(element);
22551
+ const lView = lContext ? lContext.lView : null;
22552
+ if (lView === null) {
22553
+ return null;
22554
+ }
22555
+ const nodeIndex = lContext.nodeIndex;
22556
+ if (nodeIndex !== -1) {
22557
+ const valueInLView = lView[nodeIndex];
22558
+ // this means that value in the lView is a component with its own
22559
+ // data. In this situation the TNode is not accessed at the same spot.
22560
+ const tNode = isLView(valueInLView) ? valueInLView[T_HOST] : getTNode(lView[TVIEW], nodeIndex);
22561
+ ngDevMode &&
22562
+ assertEqual(tNode.index, nodeIndex, 'Expecting that TNode at index is same as index');
22563
+ return buildDebugNode(tNode, lView);
22564
+ }
22565
+ return null;
22566
+ }
22567
+ /**
22568
+ * Retrieve the component `LView` from component/element.
22569
+ *
22570
+ * NOTE: `LView` is a private and should not be leaked outside.
22571
+ * Don't export this method to `ng.*` on window.
22572
+ *
22573
+ * @param target DOM element or component instance for which to retrieve the LView.
22574
+ */
22575
+ function getComponentLView(target) {
22576
+ const lContext = getLContext(target);
22577
+ const nodeIndx = lContext.nodeIndex;
22578
+ const lView = lContext.lView;
22579
+ ngDevMode && assertLView(lView);
22580
+ const componentLView = lView[nodeIndx];
22581
+ ngDevMode && assertLView(componentLView);
22582
+ return componentLView;
22583
+ }
22584
+ /** Asserts that a value is a DOM Element. */
22585
+ function assertDomElement(value) {
22586
+ if (typeof Element !== 'undefined' && !(value instanceof Element)) {
22587
+ throw new Error('Expecting instance of DOM Element');
22588
+ }
22829
22589
  }
22830
22590
 
22831
22591
  /**
@@ -24045,7 +23805,7 @@ const unusedValueExportToPlacateAjd = 1;
24045
23805
  * Use of this source code is governed by an MIT-style license that can be
24046
23806
  * found in the LICENSE file at https://angular.io/license
24047
23807
  */
24048
- const unusedValueToPlacateAjd = unusedValueExportToPlacateAjd$1 + unusedValueExportToPlacateAjd$5 + unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd;
23808
+ const unusedValueToPlacateAjd = unusedValueExportToPlacateAjd$1 + unusedValueExportToPlacateAjd$6 + unusedValueExportToPlacateAjd$5 + unusedValueExportToPlacateAjd;
24049
23809
  class LQuery_ {
24050
23810
  constructor(queryList) {
24051
23811
  this.queryList = queryList;