@angular/core 14.0.4 → 14.0.7

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 (36) hide show
  1. package/esm2020/src/application_ref.mjs +2 -2
  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/r3_injector.mjs +7 -1
  6. package/esm2020/src/errors.mjs +1 -1
  7. package/esm2020/src/render/api.mjs +2 -11
  8. package/esm2020/src/render3/component.mjs +3 -58
  9. package/esm2020/src/render3/component_ref.mjs +9 -3
  10. package/esm2020/src/render3/index.mjs +4 -4
  11. package/esm2020/src/render3/instructions/change_detection.mjs +2 -20
  12. package/esm2020/src/render3/instructions/listener.mjs +34 -44
  13. package/esm2020/src/render3/instructions/lview_debug.mjs +1 -1
  14. package/esm2020/src/render3/instructions/shared.mjs +19 -57
  15. package/esm2020/src/render3/instructions/styling.mjs +2 -2
  16. package/esm2020/src/render3/interfaces/renderer.mjs +1 -26
  17. package/esm2020/src/render3/interfaces/view.mjs +1 -1
  18. package/esm2020/src/render3/node_manipulation.mjs +24 -87
  19. package/esm2020/src/render3/node_manipulation_i18n.mjs +1 -1
  20. package/esm2020/src/render3/util/attrs_utils.mjs +4 -12
  21. package/esm2020/src/render3/util/view_utils.mjs +3 -6
  22. package/esm2020/src/version.mjs +1 -1
  23. package/esm2020/testing/src/logger.mjs +3 -3
  24. package/esm2020/testing/src/ng_zone_mock.mjs +3 -3
  25. package/esm2020/testing/src/test_bed_common.mjs +1 -1
  26. package/fesm2015/core.mjs +1671 -1877
  27. package/fesm2015/core.mjs.map +1 -1
  28. package/fesm2015/testing.mjs +1702 -2000
  29. package/fesm2015/testing.mjs.map +1 -1
  30. package/fesm2020/core.mjs +1671 -1877
  31. package/fesm2020/core.mjs.map +1 -1
  32. package/fesm2020/testing.mjs +1702 -2000
  33. package/fesm2020/testing.mjs.map +1 -1
  34. package/index.d.ts +57 -129
  35. package/package.json +1 -1
  36. package/testing/index.d.ts +2 -2
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v14.0.4
2
+ * @license Angular v14.0.7
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -365,7 +365,7 @@ function fakeAsync(fn) {
365
365
  *
366
366
  * @publicApi
367
367
  */
368
- function tick$1(millis = 0, tickOptions = {
368
+ function tick(millis = 0, tickOptions = {
369
369
  processNewMacroTasksSynchronously: true
370
370
  }) {
371
371
  if (fakeAsyncTestModule) {
@@ -3189,96 +3189,6 @@ function getNamespaceUri(namespace) {
3189
3189
  (name === MATH_ML_NAMESPACE ? MATH_ML_NAMESPACE_URI : null);
3190
3190
  }
3191
3191
 
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
3192
  /**
3283
3193
  * @license
3284
3194
  * Copyright Google LLC All Rights Reserved.
@@ -3361,7 +3271,6 @@ function getNativeByTNode(tNode, lView) {
3361
3271
  ngDevMode && assertTNodeForLView(tNode, lView);
3362
3272
  ngDevMode && assertIndexInRange(lView, tNode.index);
3363
3273
  const node = unwrapRNode(lView[tNode.index]);
3364
- ngDevMode && !isProceduralRenderer(lView[RENDERER]) && assertDomNode(node);
3365
3274
  return node;
3366
3275
  }
3367
3276
  /**
@@ -3377,7 +3286,6 @@ function getNativeByTNodeOrNull(tNode, lView) {
3377
3286
  if (index !== -1) {
3378
3287
  ngDevMode && assertTNodeForLView(tNode, lView);
3379
3288
  const node = unwrapRNode(lView[index]);
3380
- ngDevMode && node !== null && !isProceduralRenderer(lView[RENDERER]) && assertDomNode(node);
3381
3289
  return node;
3382
3290
  }
3383
3291
  return null;
@@ -4326,7 +4234,7 @@ function isFactory(obj) {
4326
4234
  }
4327
4235
  // Note: This hack is necessary so we don't erroneously get a circular dependency
4328
4236
  // failure based on types.
4329
- const unusedValueExportToPlacateAjd$5 = 1;
4237
+ const unusedValueExportToPlacateAjd$6 = 1;
4330
4238
 
4331
4239
  /**
4332
4240
  * Converts `TNodeType` into human readable text.
@@ -4345,7 +4253,7 @@ function toTNodeTypeAsString(tNodeType) {
4345
4253
  }
4346
4254
  // Note: This hack is necessary so we don't erroneously get a circular dependency
4347
4255
  // failure based on types.
4348
- const unusedValueExportToPlacateAjd$4 = 1;
4256
+ const unusedValueExportToPlacateAjd$5 = 1;
4349
4257
  /**
4350
4258
  * Returns `true` if the `TNode` has a directive which has `@Input()` for `class` binding.
4351
4259
  *
@@ -4449,7 +4357,6 @@ function assertPureTNodeType(type) {
4449
4357
  * @returns the index value that was last accessed in the attributes array
4450
4358
  */
4451
4359
  function setUpAttributes(renderer, native, attrs) {
4452
- const isProc = isProceduralRenderer(renderer);
4453
4360
  let i = 0;
4454
4361
  while (i < attrs.length) {
4455
4362
  const value = attrs[i];
@@ -4466,9 +4373,7 @@ function setUpAttributes(renderer, native, attrs) {
4466
4373
  const attrName = attrs[i++];
4467
4374
  const attrVal = attrs[i++];
4468
4375
  ngDevMode && ngDevMode.rendererSetAttribute++;
4469
- isProc ?
4470
- renderer.setAttribute(native, attrName, attrVal, namespaceURI) :
4471
- native.setAttributeNS(namespaceURI, attrName, attrVal);
4376
+ renderer.setAttribute(native, attrName, attrVal, namespaceURI);
4472
4377
  }
4473
4378
  else {
4474
4379
  // attrName is string;
@@ -4477,14 +4382,10 @@ function setUpAttributes(renderer, native, attrs) {
4477
4382
  // Standard attributes
4478
4383
  ngDevMode && ngDevMode.rendererSetAttribute++;
4479
4384
  if (isAnimationProp(attrName)) {
4480
- if (isProc) {
4481
- renderer.setProperty(native, attrName, attrVal);
4482
- }
4385
+ renderer.setProperty(native, attrName, attrVal);
4483
4386
  }
4484
4387
  else {
4485
- isProc ?
4486
- renderer.setAttribute(native, attrName, attrVal) :
4487
- native.setAttribute(attrName, attrVal);
4388
+ renderer.setAttribute(native, attrName, attrVal);
4488
4389
  }
4489
4390
  i++;
4490
4391
  }
@@ -5618,6 +5519,61 @@ function maybeUnwrapFn$1(value) {
5618
5519
  }
5619
5520
  }
5620
5521
 
5522
+ /**
5523
+ * @license
5524
+ * Copyright Google LLC All Rights Reserved.
5525
+ *
5526
+ * Use of this source code is governed by an MIT-style license that can be
5527
+ * found in the LICENSE file at https://angular.io/license
5528
+ */
5529
+ /**
5530
+ * Most of the use of `document` in Angular is from within the DI system so it is possible to simply
5531
+ * inject the `DOCUMENT` token and are done.
5532
+ *
5533
+ * Ivy is special because it does not rely upon the DI and must get hold of the document some other
5534
+ * way.
5535
+ *
5536
+ * The solution is to define `getDocument()` and `setDocument()` top-level functions for ivy.
5537
+ * Wherever ivy needs the global document, it calls `getDocument()` instead.
5538
+ *
5539
+ * When running ivy outside of a browser environment, it is necessary to call `setDocument()` to
5540
+ * tell ivy what the global `document` is.
5541
+ *
5542
+ * Angular does this for us in each of the standard platforms (`Browser`, `Server`, and `WebWorker`)
5543
+ * by calling `setDocument()` when providing the `DOCUMENT` token.
5544
+ */
5545
+ let DOCUMENT = undefined;
5546
+ /**
5547
+ * Tell ivy what the `document` is for this platform.
5548
+ *
5549
+ * It is only necessary to call this if the current platform is not a browser.
5550
+ *
5551
+ * @param document The object representing the global `document` in this environment.
5552
+ */
5553
+ function setDocument(document) {
5554
+ DOCUMENT = document;
5555
+ }
5556
+ /**
5557
+ * Access the object that represents the `document` for this platform.
5558
+ *
5559
+ * Ivy calls this whenever it needs to access the `document` object.
5560
+ * For example to create the renderer or to do sanitization.
5561
+ */
5562
+ function getDocument() {
5563
+ if (DOCUMENT !== undefined) {
5564
+ return DOCUMENT;
5565
+ }
5566
+ else if (typeof document !== 'undefined') {
5567
+ return document;
5568
+ }
5569
+ // No "document" can be found. This should only happen if we are running ivy outside Angular and
5570
+ // the current platform is not a browser. Since this is not a supported scenario at the moment
5571
+ // this should not happen in Angular apps.
5572
+ // Once we support running ivy outside of Angular we will need to publish `setDocument()` as a
5573
+ // public API. Meanwhile we just return `undefined` and let the application fail.
5574
+ return undefined;
5575
+ }
5576
+
5621
5577
  /**
5622
5578
  * @license
5623
5579
  * Copyright Google LLC All Rights Reserved.
@@ -7287,6 +7243,17 @@ function ensureIcuContainerVisitorLoaded(loader) {
7287
7243
  }
7288
7244
  }
7289
7245
 
7246
+ /**
7247
+ * @license
7248
+ * Copyright Google LLC All Rights Reserved.
7249
+ *
7250
+ * Use of this source code is governed by an MIT-style license that can be
7251
+ * found in the LICENSE file at https://angular.io/license
7252
+ */
7253
+ // Note: This hack is necessary so we don't erroneously get a circular dependency
7254
+ // failure based on types.
7255
+ const unusedValueExportToPlacateAjd$4 = 1;
7256
+
7290
7257
  /**
7291
7258
  * @license
7292
7259
  * Copyright Google LLC All Rights Reserved.
@@ -7369,7 +7336,7 @@ function getNearestLContainer(viewOrContainer) {
7369
7336
  * Use of this source code is governed by an MIT-style license that can be
7370
7337
  * found in the LICENSE file at https://angular.io/license
7371
7338
  */
7372
- const unusedValueToPlacateAjd$2 = unusedValueExportToPlacateAjd$7 + unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd$3 + unusedValueExportToPlacateAjd$6 + unusedValueExportToPlacateAjd$8;
7339
+ const unusedValueToPlacateAjd$2 = unusedValueExportToPlacateAjd$7 + unusedValueExportToPlacateAjd$5 + unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd$3 + unusedValueExportToPlacateAjd$8;
7373
7340
  /**
7374
7341
  * NOTE: for performance reasons, the possible actions are inlined within the function instead of
7375
7342
  * being passed as an argument.
@@ -7394,7 +7361,6 @@ function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, befo
7394
7361
  lNodeToHandle = lNodeToHandle[HOST];
7395
7362
  }
7396
7363
  const rNode = unwrapRNode(lNodeToHandle);
7397
- ngDevMode && !isProceduralRenderer(renderer) && assertDomNode(rNode);
7398
7364
  if (action === 0 /* WalkTNodeTreeAction.Create */ && parent !== null) {
7399
7365
  if (beforeNode == null) {
7400
7366
  nativeAppendChild(renderer, parent, rNode);
@@ -7421,17 +7387,14 @@ function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, befo
7421
7387
  function createTextNode(renderer, value) {
7422
7388
  ngDevMode && ngDevMode.rendererCreateTextNode++;
7423
7389
  ngDevMode && ngDevMode.rendererSetText++;
7424
- return isProceduralRenderer(renderer) ? renderer.createText(value) :
7425
- renderer.createTextNode(value);
7390
+ return renderer.createText(value);
7426
7391
  }
7427
7392
  function updateTextNode(renderer, rNode, value) {
7428
7393
  ngDevMode && ngDevMode.rendererSetText++;
7429
- isProceduralRenderer(renderer) ? renderer.setValue(rNode, value) : rNode.textContent = value;
7394
+ renderer.setValue(rNode, value);
7430
7395
  }
7431
7396
  function createCommentNode(renderer, value) {
7432
7397
  ngDevMode && ngDevMode.rendererCreateComment++;
7433
- // isProceduralRenderer check is not needed because both `Renderer2` and `Renderer3` have the same
7434
- // method name.
7435
7398
  return renderer.createComment(escapeCommentText(value));
7436
7399
  }
7437
7400
  /**
@@ -7443,14 +7406,7 @@ function createCommentNode(renderer, value) {
7443
7406
  */
7444
7407
  function createElementNode(renderer, name, namespace) {
7445
7408
  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
- }
7409
+ return renderer.createElement(name, namespace);
7454
7410
  }
7455
7411
  /**
7456
7412
  * Removes all DOM elements associated with a view.
@@ -7682,7 +7638,7 @@ function detachView(lContainer, removeIndex) {
7682
7638
  function destroyLView(tView, lView) {
7683
7639
  if (!(lView[FLAGS] & 128 /* LViewFlags.Destroyed */)) {
7684
7640
  const renderer = lView[RENDERER];
7685
- if (isProceduralRenderer(renderer) && renderer.destroyNode) {
7641
+ if (renderer.destroyNode) {
7686
7642
  applyView(tView, lView, renderer, 3 /* WalkTNodeTreeAction.Destroy */, null, null);
7687
7643
  }
7688
7644
  destroyViewTree(lView);
@@ -7710,7 +7666,7 @@ function cleanUpView(tView, lView) {
7710
7666
  executeOnDestroys(tView, lView);
7711
7667
  processCleanups(tView, lView);
7712
7668
  // For component views only, the local renderer is destroyed at clean up time.
7713
- if (lView[TVIEW].type === 1 /* TViewType.Component */ && isProceduralRenderer(lView[RENDERER])) {
7669
+ if (lView[TVIEW].type === 1 /* TViewType.Component */) {
7714
7670
  ngDevMode && ngDevMode.rendererDestroy++;
7715
7671
  lView[RENDERER].destroy();
7716
7672
  }
@@ -7886,30 +7842,17 @@ function getClosestRElement(tView, tNode, lView) {
7886
7842
  }
7887
7843
  }
7888
7844
  /**
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.
7845
+ * Inserts a native node before another native node for a given parent.
7846
+ * This is a utility function that can be used when native nodes were determined.
7892
7847
  */
7893
7848
  function nativeInsertBefore(renderer, parent, child, beforeNode, isMove) {
7894
7849
  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
- }
7850
+ renderer.insertBefore(parent, child, beforeNode, isMove);
7902
7851
  }
7903
7852
  function nativeAppendChild(renderer, parent, child) {
7904
7853
  ngDevMode && ngDevMode.rendererAppendChild++;
7905
7854
  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
- }
7855
+ renderer.appendChild(parent, child);
7913
7856
  }
7914
7857
  function nativeAppendOrInsertBefore(renderer, parent, child, beforeNode, isMove) {
7915
7858
  if (beforeNode !== null) {
@@ -7921,12 +7864,7 @@ function nativeAppendOrInsertBefore(renderer, parent, child, beforeNode, isMove)
7921
7864
  }
7922
7865
  /** Removes a node from the DOM given its native parent. */
7923
7866
  function nativeRemoveChild(renderer, parent, child, isHostElement) {
7924
- if (isProceduralRenderer(renderer)) {
7925
- renderer.removeChild(parent, child, isHostElement);
7926
- }
7927
- else {
7928
- parent.removeChild(child);
7929
- }
7867
+ renderer.removeChild(parent, child, isHostElement);
7930
7868
  }
7931
7869
  /** Checks if an element is a `<template>` node. */
7932
7870
  function isTemplateNode(node) {
@@ -7936,13 +7874,13 @@ function isTemplateNode(node) {
7936
7874
  * Returns a native parent of a given native node.
7937
7875
  */
7938
7876
  function nativeParentNode(renderer, node) {
7939
- return (isProceduralRenderer(renderer) ? renderer.parentNode(node) : node.parentNode);
7877
+ return renderer.parentNode(node);
7940
7878
  }
7941
7879
  /**
7942
7880
  * Returns a native sibling of a given native node.
7943
7881
  */
7944
7882
  function nativeNextSibling(renderer, node) {
7945
- return isProceduralRenderer(renderer) ? renderer.nextSibling(node) : node.nextSibling;
7883
+ return renderer.nextSibling(node);
7946
7884
  }
7947
7885
  /**
7948
7886
  * Find a node in front of which `currentTNode` should be inserted.
@@ -8251,39 +8189,22 @@ function applyContainer(renderer, action, lContainer, parentRElement, beforeNode
8251
8189
  * otherwise).
8252
8190
  */
8253
8191
  function applyStyling(renderer, isClassBased, rNode, prop, value) {
8254
- const isProcedural = isProceduralRenderer(renderer);
8255
8192
  if (isClassBased) {
8256
8193
  // We actually want JS true/false here because any truthy value should add the class
8257
8194
  if (!value) {
8258
8195
  ngDevMode && ngDevMode.rendererRemoveClass++;
8259
- if (isProcedural) {
8260
- renderer.removeClass(rNode, prop);
8261
- }
8262
- else {
8263
- rNode.classList.remove(prop);
8264
- }
8196
+ renderer.removeClass(rNode, prop);
8265
8197
  }
8266
8198
  else {
8267
8199
  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
- }
8200
+ renderer.addClass(rNode, prop);
8275
8201
  }
8276
8202
  }
8277
8203
  else {
8278
8204
  let flags = prop.indexOf('-') === -1 ? undefined : RendererStyleFlags2.DashCase;
8279
8205
  if (value == null /** || value === undefined */) {
8280
8206
  ngDevMode && ngDevMode.rendererRemoveStyle++;
8281
- if (isProcedural) {
8282
- renderer.removeStyle(rNode, prop, flags);
8283
- }
8284
- else {
8285
- rNode.style.removeProperty(prop);
8286
- }
8207
+ renderer.removeStyle(rNode, prop, flags);
8287
8208
  }
8288
8209
  else {
8289
8210
  // A value is important if it ends with `!important`. The style
@@ -8295,13 +8216,7 @@ function applyStyling(renderer, isClassBased, rNode, prop, value) {
8295
8216
  flags |= RendererStyleFlags2.Important;
8296
8217
  }
8297
8218
  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
- }
8219
+ renderer.setStyle(rNode, prop, value, flags);
8305
8220
  }
8306
8221
  }
8307
8222
  }
@@ -8317,12 +8232,7 @@ function applyStyling(renderer, isClassBased, rNode, prop, value) {
8317
8232
  */
8318
8233
  function writeDirectStyle(renderer, element, newValue) {
8319
8234
  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
- }
8235
+ renderer.setAttribute(element, 'style', newValue);
8326
8236
  ngDevMode && ngDevMode.rendererSetStyle++;
8327
8237
  }
8328
8238
  /**
@@ -8337,17 +8247,12 @@ function writeDirectStyle(renderer, element, newValue) {
8337
8247
  */
8338
8248
  function writeDirectClass(renderer, element, newValue) {
8339
8249
  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
- }
8250
+ if (newValue === '') {
8251
+ // There are tests in `google3` which expect `element.getAttribute('class')` to be `null`.
8252
+ renderer.removeAttribute(element, 'class');
8348
8253
  }
8349
8254
  else {
8350
- element.className = newValue;
8255
+ renderer.setAttribute(element, 'class', newValue);
8351
8256
  }
8352
8257
  ngDevMode && ngDevMode.rendererSetClassName++;
8353
8258
  }
@@ -8397,7 +8302,7 @@ function classIndexOf(className, classToSearch, startingIndex) {
8397
8302
  * Use of this source code is governed by an MIT-style license that can be
8398
8303
  * found in the LICENSE file at https://angular.io/license
8399
8304
  */
8400
- const unusedValueToPlacateAjd$1 = unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd$3;
8305
+ const unusedValueToPlacateAjd$1 = unusedValueExportToPlacateAjd$5 + unusedValueExportToPlacateAjd$4;
8401
8306
  const NG_TEMPLATE_SELECTOR = 'ng-template';
8402
8307
  /**
8403
8308
  * Search the `TAttributes` to see if it contains `cssClassToMatch` (case insensitive)
@@ -9580,6 +9485,12 @@ class R3Injector extends EnvironmentInjector {
9580
9485
  const previousInjectImplementation = setInjectImplementation(undefined);
9581
9486
  try {
9582
9487
  const initializers = this.get(ENVIRONMENT_INITIALIZER.multi, EMPTY_ARRAY, InjectFlags.Self);
9488
+ if (ngDevMode && !Array.isArray(initializers)) {
9489
+ throw new RuntimeError(209 /* RuntimeErrorCode.INVALID_MULTI_PROVIDER */, 'Unexpected type of the `ENVIRONMENT_INITIALIZER` token value ' +
9490
+ `(expected an array, but got ${typeof initializers}). ` +
9491
+ 'Please check that the `ENVIRONMENT_INITIALIZER` token is configured as a ' +
9492
+ '`multi: true` provider.');
9493
+ }
9583
9494
  for (const initializer of initializers) {
9584
9495
  initializer();
9585
9496
  }
@@ -11812,6 +11723,13 @@ class LContainerDebug {
11812
11723
  }
11813
11724
  }
11814
11725
 
11726
+ /**
11727
+ * @license
11728
+ * Copyright Google LLC All Rights Reserved.
11729
+ *
11730
+ * Use of this source code is governed by an MIT-style license that can be
11731
+ * found in the LICENSE file at https://angular.io/license
11732
+ */
11815
11733
  /**
11816
11734
  * A permanent marker promise which signifies that the current CD tree is
11817
11735
  * clean.
@@ -11879,7 +11797,7 @@ function refreshChildComponents(hostLView, components) {
11879
11797
  /** Renders child components in the current view (creation mode). */
11880
11798
  function renderChildComponents(hostLView, components) {
11881
11799
  for (let i = 0; i < components.length; i++) {
11882
- renderComponent$1(hostLView, components[i]);
11800
+ renderComponent(hostLView, components[i]);
11883
11801
  }
11884
11802
  }
11885
11803
  function createLView(parentLView, tView, context, flags, host, tHostNode, rendererFactory, renderer, sanitizer, injector, embeddedViewInjector) {
@@ -12397,16 +12315,6 @@ function createViewBlueprint(bindingStartIndex, initialViewLength) {
12397
12315
  function createError(text, token) {
12398
12316
  return new Error(`Renderer: ${text} [${stringifyForError(token)}]`);
12399
12317
  }
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
12318
  /**
12411
12319
  * Locates the host native element, used for bootstrapping existing nodes into rendering pipeline.
12412
12320
  *
@@ -12415,21 +12323,9 @@ function assertHostNodeExists(rElement, elementOrSelector) {
12415
12323
  * @param encapsulation View Encapsulation defined for component that requests host element.
12416
12324
  */
12417
12325
  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;
12326
+ // When using native Shadow DOM, do not clear host element to allow native slot projection
12327
+ const preserveContent = encapsulation === ViewEncapsulation.ShadowDom;
12328
+ return renderer.selectRootElement(elementOrSelector, preserveContent);
12433
12329
  }
12434
12330
  /**
12435
12331
  * Saves context for this cleanup function in LView.cleanupInstances.
@@ -12644,13 +12540,7 @@ function elementPropertyInternal(tView, tNode, lView, propName, value, renderer,
12644
12540
  // It is assumed that the sanitizer is only added when the compiler determines that the
12645
12541
  // property is risky, so sanitization can be done without further checks.
12646
12542
  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
- }
12543
+ renderer.setProperty(element, propName, value);
12654
12544
  }
12655
12545
  else if (tNode.type & 12 /* TNodeType.AnyContainer */) {
12656
12546
  // If the node is a container and the property didn't
@@ -12674,23 +12564,15 @@ function setNgReflectProperty(lView, element, type, attrName, value) {
12674
12564
  const debugValue = normalizeDebugBindingValue(value);
12675
12565
  if (type & 3 /* TNodeType.AnyRNode */) {
12676
12566
  if (value == null) {
12677
- isProceduralRenderer(renderer) ? renderer.removeAttribute(element, attrName) :
12678
- element.removeAttribute(attrName);
12567
+ renderer.removeAttribute(element, attrName);
12679
12568
  }
12680
12569
  else {
12681
- isProceduralRenderer(renderer) ?
12682
- renderer.setAttribute(element, attrName, debugValue) :
12683
- element.setAttribute(attrName, debugValue);
12570
+ renderer.setAttribute(element, attrName, debugValue);
12684
12571
  }
12685
12572
  }
12686
12573
  else {
12687
12574
  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
- }
12575
+ renderer.setValue(element, textContent);
12694
12576
  }
12695
12577
  }
12696
12578
  function setNgReflectProperties(lView, element, type, dataValue, value) {
@@ -13044,19 +12926,12 @@ function elementAttributeInternal(tNode, lView, name, value, sanitizer, namespac
13044
12926
  function setElementAttribute(renderer, element, namespace, tagName, name, value, sanitizer) {
13045
12927
  if (value == null) {
13046
12928
  ngDevMode && ngDevMode.rendererRemoveAttribute++;
13047
- isProceduralRenderer(renderer) ? renderer.removeAttribute(element, name, namespace) :
13048
- element.removeAttribute(name);
12929
+ renderer.removeAttribute(element, name, namespace);
13049
12930
  }
13050
12931
  else {
13051
12932
  ngDevMode && ngDevMode.rendererSetAttribute++;
13052
12933
  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
- }
12934
+ renderer.setAttribute(element, name, strValue, namespace);
13060
12935
  }
13061
12936
  }
13062
12937
  /**
@@ -13148,7 +13023,6 @@ const LContainerArray = class LContainer extends Array {
13148
13023
  */
13149
13024
  function createLContainer(hostNative, currentView, native, tNode) {
13150
13025
  ngDevMode && assertLView(currentView);
13151
- ngDevMode && !isProceduralRenderer(currentView[RENDERER]) && assertDomNode(native);
13152
13026
  // https://jsperf.com/array-literal-vs-new-array-really
13153
13027
  const lContainer = new (ngDevMode ? LContainerArray : Array)(hostNative, // host native
13154
13028
  true, // Boolean `true` in this position signifies that this is an `LContainer`
@@ -13264,7 +13138,7 @@ function refreshContainsDirtyView(lView) {
13264
13138
  }
13265
13139
  }
13266
13140
  }
13267
- function renderComponent$1(hostLView, componentHostIdx) {
13141
+ function renderComponent(hostLView, componentHostIdx) {
13268
13142
  ngDevMode && assertEqual(isCreationMode(hostLView), true, 'Should be run in creation mode');
13269
13143
  const componentView = getComponentLViewByIndex(componentHostIdx, hostLView);
13270
13144
  const componentTView = componentView[TVIEW];
@@ -13616,458 +13490,450 @@ function computeStaticStyling(tNode, attrs, writeToHost) {
13616
13490
  * Use of this source code is governed by an MIT-style license that can be
13617
13491
  * found in the LICENSE file at https://angular.io/license
13618
13492
  */
13493
+ // TODO: A hack to not pull in the NullInjector from @angular/core.
13494
+ const NULL_INJECTOR = {
13495
+ get: (token, notFoundValue) => {
13496
+ throwProviderNotFoundError(token, 'NullInjector');
13497
+ }
13498
+ };
13619
13499
  /**
13620
- * Synchronously perform change detection on a component (and possibly its sub-components).
13500
+ * Creates the root component view and the root component node.
13621
13501
  *
13622
- * This function triggers change detection in a synchronous way on a component.
13502
+ * @param rNode Render host element.
13503
+ * @param def ComponentDef
13504
+ * @param rootView The parent view where the host node is stored
13505
+ * @param rendererFactory Factory to be used for creating child renderers.
13506
+ * @param hostRenderer The current renderer
13507
+ * @param sanitizer The sanitizer, if provided
13623
13508
  *
13624
- * @param component The component which the change detection should be performed on.
13509
+ * @returns Component view created
13625
13510
  */
13626
- function detectChanges(component) {
13627
- const view = getComponentViewByInstance(component);
13628
- detectChangesInternal(view[TVIEW], view, component);
13511
+ function createRootComponentView(rNode, def, rootView, rendererFactory, hostRenderer, sanitizer) {
13512
+ const tView = rootView[TVIEW];
13513
+ const index = HEADER_OFFSET;
13514
+ ngDevMode && assertIndexInRange(rootView, index);
13515
+ rootView[index] = rNode;
13516
+ // '#host' is added here as we don't know the real host DOM name (we don't want to read it) and at
13517
+ // the same time we want to communicate the debug `TNode` that this is a special `TNode`
13518
+ // representing a host element.
13519
+ const tNode = getOrCreateTNode(tView, index, 2 /* TNodeType.Element */, '#host', null);
13520
+ const mergedAttrs = tNode.mergedAttrs = def.hostAttrs;
13521
+ if (mergedAttrs !== null) {
13522
+ computeStaticStyling(tNode, mergedAttrs, true);
13523
+ if (rNode !== null) {
13524
+ setUpAttributes(hostRenderer, rNode, mergedAttrs);
13525
+ if (tNode.classes !== null) {
13526
+ writeDirectClass(hostRenderer, rNode, tNode.classes);
13527
+ }
13528
+ if (tNode.styles !== null) {
13529
+ writeDirectStyle(hostRenderer, rNode, tNode.styles);
13530
+ }
13531
+ }
13532
+ }
13533
+ const viewRenderer = rendererFactory.createRenderer(rNode, def);
13534
+ const componentView = createLView(rootView, getOrCreateTComponentView(def), null, def.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, rootView[index], tNode, rendererFactory, viewRenderer, sanitizer || null, null, null);
13535
+ if (tView.firstCreatePass) {
13536
+ diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, rootView), tView, def.type);
13537
+ markAsComponentHost(tView, tNode);
13538
+ initTNodeFlags(tNode, rootView.length, 1);
13539
+ }
13540
+ addToViewTree(rootView, componentView);
13541
+ // Store component view at node index, with node as the HOST
13542
+ return rootView[index] = componentView;
13629
13543
  }
13630
13544
  /**
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.
13636
- *
13637
- * @param component Component to mark as dirty.
13545
+ * Creates a root component and sets it up with features and host bindings. Shared by
13546
+ * renderComponent() and ViewContainerRef.createComponent().
13638
13547
  */
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 */);
13548
+ function createRootComponent(componentView, componentDef, rootLView, rootContext, hostFeatures) {
13549
+ const tView = rootLView[TVIEW];
13550
+ // Create directive instance with factory() and store at next index in viewData
13551
+ const component = instantiateRootComponent(tView, rootLView, componentDef);
13552
+ rootContext.components.push(component);
13553
+ componentView[CONTEXT] = component;
13554
+ if (hostFeatures !== null) {
13555
+ for (const feature of hostFeatures) {
13556
+ feature(component, componentDef);
13557
+ }
13558
+ }
13559
+ // We want to generate an empty QueryList for root content queries for backwards
13560
+ // compatibility with ViewEngine.
13561
+ if (componentDef.contentQueries) {
13562
+ const tNode = getCurrentTNode();
13563
+ ngDevMode && assertDefined(tNode, 'TNode expected');
13564
+ componentDef.contentQueries(1 /* RenderFlags.Create */, component, tNode.directiveStart);
13565
+ }
13566
+ const rootTNode = getCurrentTNode();
13567
+ ngDevMode && assertDefined(rootTNode, 'tNode should have been already created');
13568
+ if (tView.firstCreatePass &&
13569
+ (componentDef.hostBindings !== null || componentDef.hostAttrs !== null)) {
13570
+ setSelectedIndex(rootTNode.index);
13571
+ const rootTView = rootLView[TVIEW];
13572
+ registerHostBindingOpCodes(rootTView, rootTNode, rootLView, rootTNode.directiveStart, rootTNode.directiveEnd, componentDef);
13573
+ invokeHostBindingsInCreationMode(componentDef, component);
13574
+ }
13575
+ return component;
13644
13576
  }
13645
- /**
13646
- * Used to perform change detection on the whole application.
13647
- *
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.
13651
- *
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.
13656
- */
13657
- function tick(component) {
13658
- const rootView = getRootView(component);
13659
- const rootContext = rootView[CONTEXT];
13660
- tickRootContext(rootContext);
13577
+ function createRootContext(scheduler, playerHandler) {
13578
+ return {
13579
+ components: [],
13580
+ scheduler: scheduler || defaultScheduler,
13581
+ clean: CLEAN_PROMISE,
13582
+ playerHandler: playerHandler || null,
13583
+ flags: 0 /* RootContextFlags.Empty */
13584
+ };
13661
13585
  }
13662
-
13663
13586
  /**
13664
- * @license
13665
- * Copyright Google LLC All Rights Reserved.
13587
+ * Used to enable lifecycle hooks on the root component.
13666
13588
  *
13667
- * Use of this source code is governed by an MIT-style license that can be
13668
- * found in the LICENSE file at https://angular.io/license
13669
- */
13670
- /**
13671
- * Retrieves the component instance associated with a given DOM element.
13589
+ * Include this feature when calling `renderComponent` if the root component
13590
+ * you are rendering has lifecycle hooks defined. Otherwise, the hooks won't
13591
+ * be called properly.
13672
13592
  *
13673
- * @usageNotes
13674
- * Given the following DOM structure:
13593
+ * Example:
13675
13594
  *
13676
- * ```html
13677
- * <app-root>
13678
- * <div>
13679
- * <child-comp></child-comp>
13680
- * </div>
13681
- * </app-root>
13682
13595
  * ```
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.
13693
- *
13694
- * @publicApi
13695
- * @globalApi ng
13696
- */
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;
13706
- }
13707
- context.component = getComponentAtNodeIndex(context.nodeIndex, lView);
13708
- }
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
13596
+ * renderComponent(AppComponent, {hostFeatures: [LifecycleHooksFeature]});
13597
+ * ```
13722
13598
  */
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];
13599
+ function LifecycleHooksFeature() {
13600
+ const tNode = getCurrentTNode();
13601
+ ngDevMode && assertDefined(tNode, 'TNode is required');
13602
+ registerPostOrderHooks(getLView()[TVIEW], tNode);
13728
13603
  }
13729
13604
  /**
13730
- * Retrieves the component instance whose view contains the DOM element.
13605
+ * Wait on component until it is rendered.
13731
13606
  *
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>`.
13607
+ * This function returns a `Promise` which is resolved when the component's
13608
+ * change detection is executed. This is determined by finding the scheduler
13609
+ * associated with the `component`'s render tree and waiting until the scheduler
13610
+ * flushes. If nothing is scheduled, the function returns a resolved promise.
13735
13611
  *
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.
13612
+ * Example:
13613
+ * ```
13614
+ * await whenRendered(myComponent);
13615
+ * ```
13740
13616
  *
13741
- * @publicApi
13742
- * @globalApi ng
13617
+ * @param component Component to wait upon
13618
+ * @returns Promise which resolves when the component is rendered.
13743
13619
  */
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;
13752
- }
13753
- return lView[FLAGS] & 256 /* LViewFlags.IsRoot */ ? null : lView[CONTEXT];
13620
+ function whenRendered(component) {
13621
+ return getRootContext(component).clean;
13754
13622
  }
13623
+
13755
13624
  /**
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.
13625
+ * @license
13626
+ * Copyright Google LLC All Rights Reserved.
13762
13627
  *
13763
- * @publicApi
13764
- * @globalApi ng
13628
+ * Use of this source code is governed by an MIT-style license that can be
13629
+ * found in the LICENSE file at https://angular.io/license
13765
13630
  */
13766
- function getRootComponents(elementOrDir) {
13767
- const lView = readPatchedLView(elementOrDir);
13768
- return lView !== null ? [...getRootContext(lView).components] : [];
13631
+ function getSuperType(type) {
13632
+ return Object.getPrototypeOf(type.prototype).constructor;
13769
13633
  }
13770
13634
  /**
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.
13635
+ * Merges the definition from a super class to a sub class.
13636
+ * @param definition The definition that is a SubClass of another directive of component
13776
13637
  *
13777
- * @publicApi
13778
- * @globalApi ng
13638
+ * @codeGenApi
13779
13639
  */
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);
13640
+ function ɵɵInheritDefinitionFeature(definition) {
13641
+ let superType = getSuperType(definition.type);
13642
+ let shouldInheritFields = true;
13643
+ const inheritanceChain = [definition];
13644
+ while (superType) {
13645
+ let superDef = undefined;
13646
+ if (isComponentDef(definition)) {
13647
+ // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
13648
+ superDef = superType.ɵcmp || superType.ɵdir;
13649
+ }
13650
+ else {
13651
+ if (superType.ɵcmp) {
13652
+ throw new RuntimeError(903 /* RuntimeErrorCode.INVALID_INHERITANCE */, ngDevMode &&
13653
+ `Directives cannot inherit Components. Directive ${stringifyForError(definition.type)} is attempting to extend component ${stringifyForError(superType)}`);
13654
+ }
13655
+ // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
13656
+ superDef = superType.ɵdir;
13657
+ }
13658
+ if (superDef) {
13659
+ if (shouldInheritFields) {
13660
+ inheritanceChain.push(superDef);
13661
+ // Some fields in the definition may be empty, if there were no values to put in them that
13662
+ // would've justified object creation. Unwrap them if necessary.
13663
+ const writeableDef = definition;
13664
+ writeableDef.inputs = maybeUnwrapEmpty(definition.inputs);
13665
+ writeableDef.declaredInputs = maybeUnwrapEmpty(definition.declaredInputs);
13666
+ writeableDef.outputs = maybeUnwrapEmpty(definition.outputs);
13667
+ // Merge hostBindings
13668
+ const superHostBindings = superDef.hostBindings;
13669
+ superHostBindings && inheritHostBindings(definition, superHostBindings);
13670
+ // Merge queries
13671
+ const superViewQuery = superDef.viewQuery;
13672
+ const superContentQueries = superDef.contentQueries;
13673
+ superViewQuery && inheritViewQuery(definition, superViewQuery);
13674
+ superContentQueries && inheritContentQueries(definition, superContentQueries);
13675
+ // Merge inputs and outputs
13676
+ fillProperties(definition.inputs, superDef.inputs);
13677
+ fillProperties(definition.declaredInputs, superDef.declaredInputs);
13678
+ fillProperties(definition.outputs, superDef.outputs);
13679
+ // Merge animations metadata.
13680
+ // If `superDef` is a Component, the `data` field is present (defaults to an empty object).
13681
+ if (isComponentDef(superDef) && superDef.data.animation) {
13682
+ // If super def is a Component, the `definition` is also a Component, since Directives can
13683
+ // not inherit Components (we throw an error above and cannot reach this code).
13684
+ const defData = definition.data;
13685
+ defData.animation = (defData.animation || []).concat(superDef.data.animation);
13686
+ }
13687
+ }
13688
+ // Run parent features
13689
+ const features = superDef.features;
13690
+ if (features) {
13691
+ for (let i = 0; i < features.length; i++) {
13692
+ const feature = features[i];
13693
+ if (feature && feature.ngInherit) {
13694
+ feature(definition);
13695
+ }
13696
+ // If `InheritDefinitionFeature` is a part of the current `superDef`, it means that this
13697
+ // def already has all the necessary information inherited from its super class(es), so we
13698
+ // can stop merging fields from super classes. However we need to iterate through the
13699
+ // prototype chain to look for classes that might contain other "features" (like
13700
+ // NgOnChanges), which we should invoke for the original `definition`. We set the
13701
+ // `shouldInheritFields` flag to indicate that, essentially skipping fields inheritance
13702
+ // logic and only invoking functions from the "features" list.
13703
+ if (feature === ɵɵInheritDefinitionFeature) {
13704
+ shouldInheritFields = false;
13705
+ }
13706
+ }
13707
+ }
13708
+ }
13709
+ superType = Object.getPrototypeOf(superType);
13710
+ }
13711
+ mergeHostAttrsAcrossInheritance(inheritanceChain);
13787
13712
  }
13788
13713
  /**
13789
- * Retrieve a set of injection tokens at a given DOM node.
13714
+ * Merge the `hostAttrs` and `hostVars` from the inherited parent to the base class.
13790
13715
  *
13791
- * @param element Element for which the injection tokens should be retrieved.
13716
+ * @param inheritanceChain A list of `WritableDefs` starting at the top most type and listing
13717
+ * sub-types in order. For each type take the `hostAttrs` and `hostVars` and merge it with the child
13718
+ * type.
13792
13719
  */
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);
13720
+ function mergeHostAttrsAcrossInheritance(inheritanceChain) {
13721
+ let hostVars = 0;
13722
+ let hostAttrs = null;
13723
+ // We process the inheritance order from the base to the leaves here.
13724
+ for (let i = inheritanceChain.length - 1; i >= 0; i--) {
13725
+ const def = inheritanceChain[i];
13726
+ // For each `hostVars`, we need to add the superclass amount.
13727
+ def.hostVars = (hostVars += def.hostVars);
13728
+ // for each `hostAttrs` we need to merge it with superclass.
13729
+ def.hostAttrs =
13730
+ mergeHostAttrs(def.hostAttrs, hostAttrs = mergeHostAttrs(hostAttrs, def.hostAttrs));
13813
13731
  }
13814
- return providerTokens;
13815
13732
  }
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) {
13844
- return [];
13733
+ function maybeUnwrapEmpty(value) {
13734
+ if (value === EMPTY_OBJ) {
13735
+ return {};
13845
13736
  }
13846
- const context = getLContext(node);
13847
- const lView = context ? context.lView : null;
13848
- if (lView === null) {
13737
+ else if (value === EMPTY_ARRAY) {
13849
13738
  return [];
13850
13739
  }
13851
- const tView = lView[TVIEW];
13852
- const nodeIndex = context.nodeIndex;
13853
- if (!tView?.data[nodeIndex]) {
13854
- return [];
13740
+ else {
13741
+ return value;
13855
13742
  }
13856
- if (context.directives === undefined) {
13857
- context.directives = getDirectivesAtNodeIndex(nodeIndex, lView, false);
13743
+ }
13744
+ function inheritViewQuery(definition, superViewQuery) {
13745
+ const prevViewQuery = definition.viewQuery;
13746
+ if (prevViewQuery) {
13747
+ definition.viewQuery = (rf, ctx) => {
13748
+ superViewQuery(rf, ctx);
13749
+ prevViewQuery(rf, ctx);
13750
+ };
13751
+ }
13752
+ else {
13753
+ definition.viewQuery = superViewQuery;
13858
13754
  }
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
13755
  }
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');
13756
+ function inheritContentQueries(definition, superContentQueries) {
13757
+ const prevContentQueries = definition.contentQueries;
13758
+ if (prevContentQueries) {
13759
+ definition.contentQueries = (rf, ctx, directiveIndex) => {
13760
+ superContentQueries(rf, ctx, directiveIndex);
13761
+ prevContentQueries(rf, ctx, directiveIndex);
13762
+ };
13878
13763
  }
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
13764
+ else {
13765
+ definition.contentQueries = superContentQueries;
13766
+ }
13767
+ }
13768
+ function inheritHostBindings(definition, superHostBindings) {
13769
+ const prevHostBindings = definition.hostBindings;
13770
+ if (prevHostBindings) {
13771
+ definition.hostBindings = (rf, ctx) => {
13772
+ superHostBindings(rf, ctx);
13773
+ prevHostBindings(rf, ctx);
13889
13774
  };
13890
13775
  }
13891
- const directiveDef = getDirectiveDef(constructor);
13892
- if (directiveDef) {
13893
- return { inputs: directiveDef.inputs, outputs: directiveDef.outputs };
13776
+ else {
13777
+ definition.hostBindings = superHostBindings;
13894
13778
  }
13895
- return null;
13896
13779
  }
13780
+
13897
13781
  /**
13898
- * Retrieve map of local references.
13899
- *
13900
- * The references are retrieved as a map of local reference name to element or directive instance.
13782
+ * @license
13783
+ * Copyright Google LLC All Rights Reserved.
13901
13784
  *
13902
- * @param target DOM element, component or directive instance for which to retrieve
13903
- * the local references.
13785
+ * Use of this source code is governed by an MIT-style license that can be
13786
+ * found in the LICENSE file at https://angular.io/license
13904
13787
  */
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
13788
  /**
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
13789
+ * Fields which exist on either directive or component definitions, and need to be copied from
13790
+ * parent to child classes by the `ɵɵCopyDefinitionFeature`.
13928
13791
  */
13929
- function getHostElement(componentOrDirective) {
13930
- return getLContext(componentOrDirective).native;
13931
- }
13792
+ const COPY_DIRECTIVE_FIELDS = [
13793
+ // The child class should use the providers of its parent.
13794
+ 'providersResolver',
13795
+ // Not listed here are any fields which are handled by the `ɵɵInheritDefinitionFeature`, such
13796
+ // as inputs, outputs, and host binding functions.
13797
+ ];
13932
13798
  /**
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.
13799
+ * Fields which exist only on component definitions, and need to be copied from parent to child
13800
+ * classes by the `ɵɵCopyDefinitionFeature`.
13939
13801
  *
13940
- * @param component The component to return the content text for.
13802
+ * The type here allows any field of `ComponentDef` which is not also a property of `DirectiveDef`,
13803
+ * since those should go in `COPY_DIRECTIVE_FIELDS` above.
13941
13804
  */
13942
- function getRenderedText(component) {
13943
- const hostElement = getHostElement(component);
13944
- return hostElement.textContent || '';
13945
- }
13805
+ const COPY_COMPONENT_FIELDS = [
13806
+ // The child class should use the template function of its parent, including all template
13807
+ // semantics.
13808
+ 'template',
13809
+ 'decls',
13810
+ 'consts',
13811
+ 'vars',
13812
+ 'onPush',
13813
+ 'ngContentSelectors',
13814
+ // The child class should use the CSS styles of its parent, including all styling semantics.
13815
+ 'styles',
13816
+ 'encapsulation',
13817
+ // The child class should be checked by the runtime in the same way as its parent.
13818
+ 'schemas',
13819
+ ];
13946
13820
  /**
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`).
13950
- *
13951
- * @usageNotes
13952
- * Given the following DOM structure:
13953
- *
13954
- * ```html
13955
- * <app-root>
13956
- * <div (click)="doSomething()"></div>
13957
- * </app-root>
13958
- * ```
13821
+ * Copies the fields not handled by the `ɵɵInheritDefinitionFeature` from the supertype of a
13822
+ * definition.
13959
13823
  *
13960
- * Calling `getListeners` on `<div>` will return an object that looks as follows:
13824
+ * This exists primarily to support ngcc migration of an existing View Engine pattern, where an
13825
+ * entire decorator is inherited from a parent to a child class. When ngcc detects this case, it
13826
+ * generates a skeleton definition on the child class, and applies this feature.
13961
13827
  *
13962
- * ```ts
13963
- * {
13964
- * name: 'click',
13965
- * element: <div>,
13966
- * callback: () => doSomething(),
13967
- * useCapture: false
13968
- * }
13969
- * ```
13828
+ * The `ɵɵCopyDefinitionFeature` then copies any needed fields from the parent class' definition,
13829
+ * including things like the component template function.
13970
13830
  *
13971
- * @param element Element for which the DOM listeners should be retrieved.
13972
- * @returns Array of event listeners on the DOM element.
13831
+ * @param definition The definition of a child class which inherits from a parent class with its
13832
+ * own definition.
13973
13833
  *
13974
- * @publicApi
13975
- * @globalApi ng
13834
+ * @codeGenApi
13976
13835
  */
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
- }
13836
+ function ɵɵCopyDefinitionFeature(definition) {
13837
+ let superType = getSuperType(definition.type);
13838
+ let superDef = undefined;
13839
+ if (isComponentDef(definition)) {
13840
+ // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
13841
+ superDef = superType.ɵcmp;
13842
+ }
13843
+ else {
13844
+ // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
13845
+ superDef = superType.ɵdir;
13846
+ }
13847
+ // Needed because `definition` fields are readonly.
13848
+ const defAny = definition;
13849
+ // Copy over any fields that apply to either directives or components.
13850
+ for (const field of COPY_DIRECTIVE_FIELDS) {
13851
+ defAny[field] = superDef[field];
13852
+ }
13853
+ if (isComponentDef(superDef)) {
13854
+ // Copy over any component-specific fields.
13855
+ for (const field of COPY_COMPONENT_FIELDS) {
13856
+ defAny[field] = superDef[field];
14005
13857
  }
14006
13858
  }
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
13859
  }
13860
+
14015
13861
  /**
14016
- * This function should not exist because it is megamorphic and only mostly correct.
13862
+ * @license
13863
+ * Copyright Google LLC All Rights Reserved.
14017
13864
  *
14018
- * See call site for more info.
13865
+ * Use of this source code is governed by an MIT-style license that can be
13866
+ * found in the LICENSE file at https://angular.io/license
14019
13867
  */
14020
- function isDirectiveDefHack(obj) {
14021
- return obj.type !== undefined && obj.template !== undefined && obj.declaredInputs !== undefined;
13868
+ let _symbolIterator = null;
13869
+ function getSymbolIterator() {
13870
+ if (!_symbolIterator) {
13871
+ const Symbol = _global$1['Symbol'];
13872
+ if (Symbol && Symbol.iterator) {
13873
+ _symbolIterator = Symbol.iterator;
13874
+ }
13875
+ else {
13876
+ // es6-shim specific logic
13877
+ const keys = Object.getOwnPropertyNames(Map.prototype);
13878
+ for (let i = 0; i < keys.length; ++i) {
13879
+ const key = keys[i];
13880
+ if (key !== 'entries' && key !== 'size' &&
13881
+ Map.prototype[key] === Map.prototype['entries']) {
13882
+ _symbolIterator = key;
13883
+ }
13884
+ }
13885
+ }
13886
+ }
13887
+ return _symbolIterator;
14022
13888
  }
13889
+
14023
13890
  /**
14024
- * Returns the attached `DebugNode` instance for an element in the DOM.
13891
+ * @license
13892
+ * Copyright Google LLC All Rights Reserved.
14025
13893
  *
14026
- * @param element DOM element which is owned by an existing component's view.
13894
+ * Use of this source code is governed by an MIT-style license that can be
13895
+ * found in the LICENSE file at https://angular.io/license
14027
13896
  */
14028
- function getDebugNode(element) {
14029
- if (ngDevMode && !(element instanceof Node)) {
14030
- throw new Error('Expecting instance of DOM Element');
13897
+ function isIterable(obj) {
13898
+ return obj !== null && typeof obj === 'object' && obj[getSymbolIterator()] !== undefined;
13899
+ }
13900
+ function isListLikeIterable(obj) {
13901
+ if (!isJsObject(obj))
13902
+ return false;
13903
+ return Array.isArray(obj) ||
13904
+ (!(obj instanceof Map) && // JS Map are iterables but return entries as [k, v]
13905
+ getSymbolIterator() in obj); // JS Iterable have a Symbol.iterator prop
13906
+ }
13907
+ function areIterablesEqual(a, b, comparator) {
13908
+ const iterator1 = a[getSymbolIterator()]();
13909
+ const iterator2 = b[getSymbolIterator()]();
13910
+ while (true) {
13911
+ const item1 = iterator1.next();
13912
+ const item2 = iterator2.next();
13913
+ if (item1.done && item2.done)
13914
+ return true;
13915
+ if (item1.done || item2.done)
13916
+ return false;
13917
+ if (!comparator(item1.value, item2.value))
13918
+ return false;
14031
13919
  }
14032
- const lContext = getLContext(element);
14033
- const lView = lContext ? lContext.lView : null;
14034
- if (lView === null) {
14035
- return null;
13920
+ }
13921
+ function iterateListLike(obj, fn) {
13922
+ if (Array.isArray(obj)) {
13923
+ for (let i = 0; i < obj.length; i++) {
13924
+ fn(obj[i]);
13925
+ }
14036
13926
  }
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);
13927
+ else {
13928
+ const iterator = obj[getSymbolIterator()]();
13929
+ let item;
13930
+ while (!((item = iterator.next()).done)) {
13931
+ fn(item.value);
13932
+ }
14046
13933
  }
14047
- return null;
14048
- }
14049
- /**
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.
14054
- *
14055
- * @param target DOM element or component instance for which to retrieve the LView.
14056
- */
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
13934
  }
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');
14070
- }
13935
+ function isJsObject(o) {
13936
+ return o !== null && (typeof o === 'function' || typeof o === 'object');
14071
13937
  }
14072
13938
 
14073
13939
  /**
@@ -14077,18 +13943,22 @@ function assertDomElement(value) {
14077
13943
  * Use of this source code is governed by an MIT-style license that can be
14078
13944
  * found in the LICENSE file at https://angular.io/license
14079
13945
  */
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));
13946
+ function devModeEqual(a, b) {
13947
+ const isListLikeIterableA = isListLikeIterable(a);
13948
+ const isListLikeIterableB = isListLikeIterable(b);
13949
+ if (isListLikeIterableA && isListLikeIterableB) {
13950
+ return areIterablesEqual(a, b, devModeEqual);
13951
+ }
13952
+ else {
13953
+ const isAObject = a && (typeof a === 'object' || typeof a === 'function');
13954
+ const isBObject = b && (typeof b === 'object' || typeof b === 'function');
13955
+ if (!isListLikeIterableA && isAObject && !isListLikeIterableB && isBObject) {
13956
+ return true;
13957
+ }
13958
+ else {
13959
+ return Object.is(a, b);
13960
+ }
13961
+ }
14092
13962
  }
14093
13963
 
14094
13964
  /**
@@ -14098,70 +13968,73 @@ function applyChanges(component) {
14098
13968
  * Use of this source code is governed by an MIT-style license that can be
14099
13969
  * found in the LICENSE file at https://angular.io/license
14100
13970
  */
13971
+ // TODO(misko): consider inlining
13972
+ /** Updates binding and returns the value. */
13973
+ function updateBinding(lView, bindingIndex, value) {
13974
+ return lView[bindingIndex] = value;
13975
+ }
13976
+ /** Gets the current binding value. */
13977
+ function getBinding(lView, bindingIndex) {
13978
+ ngDevMode && assertIndexInRange(lView, bindingIndex);
13979
+ ngDevMode &&
13980
+ assertNotSame(lView[bindingIndex], NO_CHANGE, 'Stored value should never be NO_CHANGE.');
13981
+ return lView[bindingIndex];
13982
+ }
14101
13983
  /**
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
13984
+ * Updates binding if changed, then returns whether it was updated.
14108
13985
  *
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`.
13986
+ * This function also checks the `CheckNoChangesMode` and throws if changes are made.
13987
+ * Some changes (Objects/iterables) during `CheckNoChangesMode` are exempt to comply with VE
13988
+ * behavior.
14119
13989
  *
14120
- * These functions are available globally when Angular is in development
14121
- * mode and are automatically stripped away from prod mode is on.
13990
+ * @param lView current `LView`
13991
+ * @param bindingIndex The binding in the `LView` to check
13992
+ * @param value New value to check against `lView[bindingIndex]`
13993
+ * @returns `true` if the bindings has changed. (Throws if binding has changed during
13994
+ * `CheckNoChangesMode`)
14122
13995
  */
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);
13996
+ function bindingUpdated(lView, bindingIndex, value) {
13997
+ ngDevMode && assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
13998
+ ngDevMode &&
13999
+ assertLessThan(bindingIndex, lView.length, `Slot should have been initialized to NO_CHANGE`);
14000
+ const oldValue = lView[bindingIndex];
14001
+ if (Object.is(oldValue, value)) {
14002
+ return false;
14142
14003
  }
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] = {};
14004
+ else {
14005
+ if (ngDevMode && isInCheckNoChangesMode()) {
14006
+ // View engine didn't report undefined values as changed on the first checkNoChanges pass
14007
+ // (before the change detection was run).
14008
+ const oldValueToCompare = oldValue !== NO_CHANGE ? oldValue : undefined;
14009
+ if (!devModeEqual(oldValueToCompare, value)) {
14010
+ const details = getExpressionChangedErrorDetails(lView, bindingIndex, oldValueToCompare, value);
14011
+ throwErrorIfNoChangesMode(oldValue === NO_CHANGE, details.oldValue, details.newValue, details.propName);
14160
14012
  }
14161
- container[name] = fn;
14013
+ // There was a change, but the `devModeEqual` decided that the change is exempt from an error.
14014
+ // For this reason we exit as if no change. The early exit is needed to prevent the changed
14015
+ // value to be written into `LView` (If we would write the new value that we would not see it
14016
+ // as change on next CD.)
14017
+ return false;
14162
14018
  }
14019
+ lView[bindingIndex] = value;
14020
+ return true;
14163
14021
  }
14164
14022
  }
14023
+ /** Updates 2 bindings if changed, then returns whether either was updated. */
14024
+ function bindingUpdated2(lView, bindingIndex, exp1, exp2) {
14025
+ const different = bindingUpdated(lView, bindingIndex, exp1);
14026
+ return bindingUpdated(lView, bindingIndex + 1, exp2) || different;
14027
+ }
14028
+ /** Updates 3 bindings if changed, then returns whether any was updated. */
14029
+ function bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) {
14030
+ const different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
14031
+ return bindingUpdated(lView, bindingIndex + 2, exp3) || different;
14032
+ }
14033
+ /** Updates 4 bindings if changed, then returns whether any was updated. */
14034
+ function bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) {
14035
+ const different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
14036
+ return bindingUpdated2(lView, bindingIndex + 2, exp3, exp4) || different;
14037
+ }
14165
14038
 
14166
14039
  /**
14167
14040
  * @license
@@ -14170,817 +14043,377 @@ function publishGlobalUtil(name, fn) {
14170
14043
  * Use of this source code is governed by an MIT-style license that can be
14171
14044
  * found in the LICENSE file at https://angular.io/license
14172
14045
  */
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
14046
  /**
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();
14047
+ * Updates the value of or removes a bound attribute on an Element.
14048
+ *
14049
+ * Used in the case of `[attr.title]="value"`
14050
+ *
14051
+ * @param name name The name of the attribute.
14052
+ * @param value value The attribute is removed when value is `null` or `undefined`.
14053
+ * Otherwise the attribute value is set to the stringified value.
14054
+ * @param sanitizer An optional function used to sanitize the value.
14055
+ * @param namespace Optional namespace to use when setting the attribute.
14056
+ *
14057
+ * @codeGenApi
14058
+ */
14059
+ function ɵɵattribute(name, value, sanitizer, namespace) {
14060
+ const lView = getLView();
14061
+ const bindingIndex = nextBindingIndex();
14062
+ if (bindingUpdated(lView, bindingIndex, value)) {
14063
+ const tView = getTView();
14064
+ const tNode = getSelectedTNode();
14065
+ elementAttributeInternal(tNode, lView, name, value, sanitizer, namespace);
14066
+ ngDevMode && storePropertyBindingMetadata(tView.data, tNode, 'attr.' + name, bindingIndex);
14227
14067
  }
14228
- return component;
14068
+ return ɵɵattribute;
14229
14069
  }
14070
+
14230
14071
  /**
14231
- * Creates the root component view and the root component node.
14072
+ * @license
14073
+ * Copyright Google LLC All Rights Reserved.
14232
14074
  *
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
14075
+ * Use of this source code is governed by an MIT-style license that can be
14076
+ * found in the LICENSE file at https://angular.io/license
14077
+ */
14078
+ /**
14079
+ * Create interpolation bindings with a variable number of expressions.
14239
14080
  *
14240
- * @returns Component view created
14081
+ * If there are 1 to 8 expressions `interpolation1()` to `interpolation8()` should be used instead.
14082
+ * Those are faster because there is no need to create an array of expressions and iterate over it.
14083
+ *
14084
+ * `values`:
14085
+ * - has static text at even indexes,
14086
+ * - has evaluated expressions at odd indexes.
14087
+ *
14088
+ * Returns the concatenated string when any of the arguments changes, `NO_CHANGE` otherwise.
14241
14089
  */
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);
14261
- }
14262
- }
14090
+ function interpolationV(lView, values) {
14091
+ ngDevMode && assertLessThan(2, values.length, 'should have at least 3 values');
14092
+ ngDevMode && assertEqual(values.length % 2, 1, 'should have an odd number of values');
14093
+ let isBindingUpdated = false;
14094
+ let bindingIndex = getBindingIndex();
14095
+ for (let i = 1; i < values.length; i += 2) {
14096
+ // Check if bindings (odd indexes) have changed
14097
+ isBindingUpdated = bindingUpdated(lView, bindingIndex++, values[i]) || isBindingUpdated;
14263
14098
  }
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);
14099
+ setBindingIndex(bindingIndex);
14100
+ if (!isBindingUpdated) {
14101
+ return NO_CHANGE;
14270
14102
  }
14271
- addToViewTree(rootView, componentView);
14272
- // Store component view at node index, with node as the HOST
14273
- return rootView[index] = componentView;
14103
+ // Build the updated content
14104
+ let content = values[0];
14105
+ for (let i = 1; i < values.length; i += 2) {
14106
+ content += renderStringify(values[i]) + values[i + 1];
14107
+ }
14108
+ return content;
14274
14109
  }
14275
14110
  /**
14276
- * Creates a root component and sets it up with features and host bindings. Shared by
14277
- * renderComponent() and ViewContainerRef.createComponent().
14111
+ * Creates an interpolation binding with 1 expression.
14112
+ *
14113
+ * @param prefix static value used for concatenation only.
14114
+ * @param v0 value checked for change.
14115
+ * @param suffix static value used for concatenation only.
14278
14116
  */
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;
14117
+ function interpolation1(lView, prefix, v0, suffix) {
14118
+ const different = bindingUpdated(lView, nextBindingIndex(), v0);
14119
+ return different ? prefix + renderStringify(v0) + suffix : NO_CHANGE;
14307
14120
  }
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
- };
14121
+ /**
14122
+ * Creates an interpolation binding with 2 expressions.
14123
+ */
14124
+ function interpolation2(lView, prefix, v0, i0, v1, suffix) {
14125
+ const bindingIndex = getBindingIndex();
14126
+ const different = bindingUpdated2(lView, bindingIndex, v0, v1);
14127
+ incrementBindingIndex(2);
14128
+ return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + suffix : NO_CHANGE;
14316
14129
  }
14317
14130
  /**
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:
14325
- *
14326
- * ```
14327
- * renderComponent(AppComponent, {hostFeatures: [LifecycleHooksFeature]});
14328
- * ```
14131
+ * Creates an interpolation binding with 3 expressions.
14329
14132
  */
14330
- function LifecycleHooksFeature() {
14331
- const tNode = getCurrentTNode();
14332
- ngDevMode && assertDefined(tNode, 'TNode is required');
14333
- registerPostOrderHooks(getLView()[TVIEW], tNode);
14133
+ function interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix) {
14134
+ const bindingIndex = getBindingIndex();
14135
+ const different = bindingUpdated3(lView, bindingIndex, v0, v1, v2);
14136
+ incrementBindingIndex(3);
14137
+ return different ?
14138
+ prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + suffix :
14139
+ NO_CHANGE;
14334
14140
  }
14335
14141
  /**
14336
- * Wait on component until it is rendered.
14337
- *
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.
14342
- *
14343
- * Example:
14344
- * ```
14345
- * await whenRendered(myComponent);
14346
- * ```
14347
- *
14348
- * @param component Component to wait upon
14349
- * @returns Promise which resolves when the component is rendered.
14142
+ * Create an interpolation binding with 4 expressions.
14350
14143
  */
14351
- function whenRendered(component) {
14352
- return getRootContext(component).clean;
14144
+ function interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
14145
+ const bindingIndex = getBindingIndex();
14146
+ const different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14147
+ incrementBindingIndex(4);
14148
+ return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14149
+ renderStringify(v2) + i2 + renderStringify(v3) + suffix :
14150
+ NO_CHANGE;
14353
14151
  }
14354
-
14355
14152
  /**
14356
- * @license
14357
- * Copyright Google LLC All Rights Reserved.
14358
- *
14359
- * Use of this source code is governed by an MIT-style license that can be
14360
- * found in the LICENSE file at https://angular.io/license
14153
+ * Creates an interpolation binding with 5 expressions.
14361
14154
  */
14362
- function getSuperType(type) {
14363
- return Object.getPrototypeOf(type.prototype).constructor;
14155
+ function interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
14156
+ const bindingIndex = getBindingIndex();
14157
+ let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14158
+ different = bindingUpdated(lView, bindingIndex + 4, v4) || different;
14159
+ incrementBindingIndex(5);
14160
+ return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14161
+ renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + suffix :
14162
+ NO_CHANGE;
14364
14163
  }
14365
14164
  /**
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
14368
- *
14369
- * @codeGenApi
14165
+ * Creates an interpolation binding with 6 expressions.
14370
14166
  */
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);
14167
+ function interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
14168
+ const bindingIndex = getBindingIndex();
14169
+ let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14170
+ different = bindingUpdated2(lView, bindingIndex + 4, v4, v5) || different;
14171
+ incrementBindingIndex(6);
14172
+ return different ?
14173
+ prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 +
14174
+ renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + suffix :
14175
+ NO_CHANGE;
14443
14176
  }
14444
14177
  /**
14445
- * Merge the `hostAttrs` and `hostVars` from the inherited parent to the base class.
14446
- *
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.
14178
+ * Creates an interpolation binding with 7 expressions.
14450
14179
  */
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 {};
14467
- }
14468
- else if (value === EMPTY_ARRAY) {
14469
- return [];
14470
- }
14471
- else {
14472
- return value;
14473
- }
14474
- }
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
- }
14486
- }
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
- }
14180
+ function interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
14181
+ const bindingIndex = getBindingIndex();
14182
+ let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14183
+ different = bindingUpdated3(lView, bindingIndex + 4, v4, v5, v6) || different;
14184
+ incrementBindingIndex(7);
14185
+ return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14186
+ renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 +
14187
+ renderStringify(v5) + i5 + renderStringify(v6) + suffix :
14188
+ NO_CHANGE;
14498
14189
  }
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
- }
14190
+ /**
14191
+ * Creates an interpolation binding with 8 expressions.
14192
+ */
14193
+ function interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
14194
+ const bindingIndex = getBindingIndex();
14195
+ let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14196
+ different = bindingUpdated4(lView, bindingIndex + 4, v4, v5, v6, v7) || different;
14197
+ incrementBindingIndex(8);
14198
+ return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14199
+ renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 +
14200
+ renderStringify(v5) + i5 + renderStringify(v6) + i6 + renderStringify(v7) + suffix :
14201
+ NO_CHANGE;
14510
14202
  }
14511
14203
 
14512
14204
  /**
14513
- * @license
14514
- * Copyright Google LLC All Rights Reserved.
14515
14205
  *
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
14518
- */
14519
- /**
14520
- * Fields which exist on either directive or component definitions, and need to be copied from
14521
- * parent to child classes by the `ɵɵCopyDefinitionFeature`.
14522
- */
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
- ];
14529
- /**
14530
- * Fields which exist only on component definitions, and need to be copied from parent to child
14531
- * classes by the `ɵɵCopyDefinitionFeature`.
14206
+ * Update an interpolated attribute on an element with single bound value surrounded by text.
14532
14207
  *
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.
14535
- */
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
- ];
14551
- /**
14552
- * Copies the fields not handled by the `ɵɵInheritDefinitionFeature` from the supertype of a
14553
- * definition.
14208
+ * Used when the value passed to a property has 1 interpolated value in it:
14554
14209
  *
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.
14210
+ * ```html
14211
+ * <div attr.title="prefix{{v0}}suffix"></div>
14212
+ * ```
14558
14213
  *
14559
- * The `ɵɵCopyDefinitionFeature` then copies any needed fields from the parent class' definition,
14560
- * including things like the component template function.
14214
+ * Its compiled representation is::
14561
14215
  *
14562
- * @param definition The definition of a child class which inherits from a parent class with its
14563
- * own definition.
14216
+ * ```ts
14217
+ * ɵɵattributeInterpolate1('title', 'prefix', v0, 'suffix');
14218
+ * ```
14564
14219
  *
14220
+ * @param attrName The name of the attribute to update
14221
+ * @param prefix Static value used for concatenation only.
14222
+ * @param v0 Value checked for change.
14223
+ * @param suffix Static value used for concatenation only.
14224
+ * @param sanitizer An optional sanitizer function
14225
+ * @returns itself, so that it may be chained.
14565
14226
  * @codeGenApi
14566
14227
  */
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
- }
14228
+ function ɵɵattributeInterpolate1(attrName, prefix, v0, suffix, sanitizer, namespace) {
14229
+ const lView = getLView();
14230
+ const interpolatedValue = interpolation1(lView, prefix, v0, suffix);
14231
+ if (interpolatedValue !== NO_CHANGE) {
14232
+ const tNode = getSelectedTNode();
14233
+ elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
14234
+ ngDevMode &&
14235
+ storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 1, prefix, suffix);
14589
14236
  }
14237
+ return ɵɵattributeInterpolate1;
14590
14238
  }
14591
-
14592
14239
  /**
14593
- * @license
14594
- * Copyright Google LLC All Rights Reserved.
14595
14240
  *
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.
14241
+ * Update an interpolated attribute on an element with 2 bound values surrounded by text.
14624
14242
  *
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.
14243
+ * Used when the value passed to a property has 2 interpolated values in it:
14673
14244
  *
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
14245
+ * ```html
14246
+ * <div attr.title="prefix{{v0}}-{{v1}}suffix"></div>
14247
+ * ```
14248
+ *
14249
+ * Its compiled representation is::
14250
+ *
14251
+ * ```ts
14252
+ * ɵɵattributeInterpolate2('title', 'prefix', v0, '-', v1, 'suffix');
14253
+ * ```
14254
+ *
14255
+ * @param attrName The name of the attribute to update
14256
+ * @param prefix Static value used for concatenation only.
14257
+ * @param v0 Value checked for change.
14258
+ * @param i0 Static value used for concatenation only.
14259
+ * @param v1 Value checked for change.
14260
+ * @param suffix Static value used for concatenation only.
14261
+ * @param sanitizer An optional sanitizer function
14262
+ * @returns itself, so that it may be chained.
14263
+ * @codeGenApi
14676
14264
  */
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
- }
14265
+ function ɵɵattributeInterpolate2(attrName, prefix, v0, i0, v1, suffix, sanitizer, namespace) {
14266
+ const lView = getLView();
14267
+ const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
14268
+ if (interpolatedValue !== NO_CHANGE) {
14269
+ const tNode = getSelectedTNode();
14270
+ elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
14271
+ ngDevMode &&
14272
+ storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 2, prefix, i0, suffix);
14692
14273
  }
14274
+ return ɵɵattributeInterpolate2;
14693
14275
  }
14694
-
14695
14276
  /**
14696
- * @license
14697
- * Copyright Google LLC All Rights Reserved.
14698
14277
  *
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.
14278
+ * Update an interpolated attribute on an element with 3 bound values surrounded by text.
14716
14279
  *
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.
14280
+ * Used when the value passed to a property has 3 interpolated values in it:
14720
14281
  *
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`)
14282
+ * ```html
14283
+ * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
14284
+ * ```
14285
+ *
14286
+ * Its compiled representation is::
14287
+ *
14288
+ * ```ts
14289
+ * ɵɵattributeInterpolate3(
14290
+ * 'title', 'prefix', v0, '-', v1, '-', v2, 'suffix');
14291
+ * ```
14292
+ *
14293
+ * @param attrName The name of the attribute to update
14294
+ * @param prefix Static value used for concatenation only.
14295
+ * @param v0 Value checked for change.
14296
+ * @param i0 Static value used for concatenation only.
14297
+ * @param v1 Value checked for change.
14298
+ * @param i1 Static value used for concatenation only.
14299
+ * @param v2 Value checked for change.
14300
+ * @param suffix Static value used for concatenation only.
14301
+ * @param sanitizer An optional sanitizer function
14302
+ * @returns itself, so that it may be chained.
14303
+ * @codeGenApi
14726
14304
  */
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;
14305
+ function ɵɵattributeInterpolate3(attrName, prefix, v0, i0, v1, i1, v2, suffix, sanitizer, namespace) {
14306
+ const lView = getLView();
14307
+ const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
14308
+ if (interpolatedValue !== NO_CHANGE) {
14309
+ const tNode = getSelectedTNode();
14310
+ elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
14311
+ ngDevMode &&
14312
+ storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 3, prefix, i0, i1, suffix);
14752
14313
  }
14314
+ return ɵɵattributeInterpolate3;
14753
14315
  }
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
14316
  /**
14771
- * @license
14772
- * Copyright Google LLC All Rights Reserved.
14773
14317
  *
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.
14318
+ * Update an interpolated attribute on an element with 4 bound values surrounded by text.
14779
14319
  *
14780
- * Used in the case of `[attr.title]="value"`
14320
+ * Used when the value passed to a property has 4 interpolated values in it:
14781
14321
  *
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.
14322
+ * ```html
14323
+ * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
14324
+ * ```
14325
+ *
14326
+ * Its compiled representation is::
14327
+ *
14328
+ * ```ts
14329
+ * ɵɵattributeInterpolate4(
14330
+ * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
14331
+ * ```
14787
14332
  *
14333
+ * @param attrName The name of the attribute to update
14334
+ * @param prefix Static value used for concatenation only.
14335
+ * @param v0 Value checked for change.
14336
+ * @param i0 Static value used for concatenation only.
14337
+ * @param v1 Value checked for change.
14338
+ * @param i1 Static value used for concatenation only.
14339
+ * @param v2 Value checked for change.
14340
+ * @param i2 Static value used for concatenation only.
14341
+ * @param v3 Value checked for change.
14342
+ * @param suffix Static value used for concatenation only.
14343
+ * @param sanitizer An optional sanitizer function
14344
+ * @returns itself, so that it may be chained.
14788
14345
  * @codeGenApi
14789
14346
  */
14790
- function ɵɵattribute(name, value, sanitizer, namespace) {
14347
+ function ɵɵattributeInterpolate4(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, suffix, sanitizer, namespace) {
14791
14348
  const lView = getLView();
14792
- const bindingIndex = nextBindingIndex();
14793
- if (bindingUpdated(lView, bindingIndex, value)) {
14794
- const tView = getTView();
14349
+ const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
14350
+ if (interpolatedValue !== NO_CHANGE) {
14795
14351
  const tNode = getSelectedTNode();
14796
- elementAttributeInternal(tNode, lView, name, value, sanitizer, namespace);
14797
- ngDevMode && storePropertyBindingMetadata(tView.data, tNode, 'attr.' + name, bindingIndex);
14352
+ elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
14353
+ ngDevMode &&
14354
+ storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 4, prefix, i0, i1, i2, suffix);
14798
14355
  }
14799
- return ɵɵattribute;
14356
+ return ɵɵattributeInterpolate4;
14800
14357
  }
14801
-
14802
14358
  /**
14803
- * @license
14804
- * Copyright Google LLC All Rights Reserved.
14805
14359
  *
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.
14360
+ * Update an interpolated attribute on an element with 5 bound values surrounded by text.
14811
14361
  *
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.
14814
- *
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:
14362
+ * Used when the value passed to a property has 5 interpolated values in it:
14940
14363
  *
14941
14364
  * ```html
14942
- * <div attr.title="prefix{{v0}}suffix"></div>
14365
+ * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
14943
14366
  * ```
14944
14367
  *
14945
14368
  * Its compiled representation is::
14946
14369
  *
14947
14370
  * ```ts
14948
- * ɵɵattributeInterpolate1('title', 'prefix', v0, 'suffix');
14371
+ * ɵɵattributeInterpolate5(
14372
+ * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
14949
14373
  * ```
14950
14374
  *
14951
14375
  * @param attrName The name of the attribute to update
14952
14376
  * @param prefix Static value used for concatenation only.
14953
14377
  * @param v0 Value checked for change.
14378
+ * @param i0 Static value used for concatenation only.
14379
+ * @param v1 Value checked for change.
14380
+ * @param i1 Static value used for concatenation only.
14381
+ * @param v2 Value checked for change.
14382
+ * @param i2 Static value used for concatenation only.
14383
+ * @param v3 Value checked for change.
14384
+ * @param i3 Static value used for concatenation only.
14385
+ * @param v4 Value checked for change.
14954
14386
  * @param suffix Static value used for concatenation only.
14955
14387
  * @param sanitizer An optional sanitizer function
14956
14388
  * @returns itself, so that it may be chained.
14957
14389
  * @codeGenApi
14958
14390
  */
14959
- function ɵɵattributeInterpolate1(attrName, prefix, v0, suffix, sanitizer, namespace) {
14391
+ function ɵɵattributeInterpolate5(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix, sanitizer, namespace) {
14960
14392
  const lView = getLView();
14961
- const interpolatedValue = interpolation1(lView, prefix, v0, suffix);
14393
+ const interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
14962
14394
  if (interpolatedValue !== NO_CHANGE) {
14963
14395
  const tNode = getSelectedTNode();
14964
14396
  elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
14965
14397
  ngDevMode &&
14966
- storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 1, prefix, suffix);
14398
+ storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 5, prefix, i0, i1, i2, i3, suffix);
14967
14399
  }
14968
- return ɵɵattributeInterpolate1;
14400
+ return ɵɵattributeInterpolate5;
14969
14401
  }
14970
14402
  /**
14971
14403
  *
14972
- * Update an interpolated attribute on an element with 2 bound values surrounded by text.
14404
+ * Update an interpolated attribute on an element with 6 bound values surrounded by text.
14973
14405
  *
14974
- * Used when the value passed to a property has 2 interpolated values in it:
14406
+ * Used when the value passed to a property has 6 interpolated values in it:
14975
14407
  *
14976
14408
  * ```html
14977
- * <div attr.title="prefix{{v0}}-{{v1}}suffix"></div>
14409
+ * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
14978
14410
  * ```
14979
14411
  *
14980
14412
  * Its compiled representation is::
14981
14413
  *
14982
14414
  * ```ts
14983
- * ɵɵattributeInterpolate2('title', 'prefix', v0, '-', v1, 'suffix');
14415
+ * ɵɵattributeInterpolate6(
14416
+ * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
14984
14417
  * ```
14985
14418
  *
14986
14419
  * @param attrName The name of the attribute to update
@@ -14988,37 +14421,45 @@ function ɵɵattributeInterpolate1(attrName, prefix, v0, suffix, sanitizer, name
14988
14421
  * @param v0 Value checked for change.
14989
14422
  * @param i0 Static value used for concatenation only.
14990
14423
  * @param v1 Value checked for change.
14424
+ * @param i1 Static value used for concatenation only.
14425
+ * @param v2 Value checked for change.
14426
+ * @param i2 Static value used for concatenation only.
14427
+ * @param v3 Value checked for change.
14428
+ * @param i3 Static value used for concatenation only.
14429
+ * @param v4 Value checked for change.
14430
+ * @param i4 Static value used for concatenation only.
14431
+ * @param v5 Value checked for change.
14991
14432
  * @param suffix Static value used for concatenation only.
14992
14433
  * @param sanitizer An optional sanitizer function
14993
14434
  * @returns itself, so that it may be chained.
14994
14435
  * @codeGenApi
14995
14436
  */
14996
- function ɵɵattributeInterpolate2(attrName, prefix, v0, i0, v1, suffix, sanitizer, namespace) {
14437
+ function ɵɵattributeInterpolate6(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix, sanitizer, namespace) {
14997
14438
  const lView = getLView();
14998
- const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
14439
+ const interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
14999
14440
  if (interpolatedValue !== NO_CHANGE) {
15000
14441
  const tNode = getSelectedTNode();
15001
14442
  elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
15002
14443
  ngDevMode &&
15003
- storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 2, prefix, i0, suffix);
14444
+ storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 6, prefix, i0, i1, i2, i3, i4, suffix);
15004
14445
  }
15005
- return ɵɵattributeInterpolate2;
14446
+ return ɵɵattributeInterpolate6;
15006
14447
  }
15007
14448
  /**
15008
14449
  *
15009
- * Update an interpolated attribute on an element with 3 bound values surrounded by text.
14450
+ * Update an interpolated attribute on an element with 7 bound values surrounded by text.
15010
14451
  *
15011
- * Used when the value passed to a property has 3 interpolated values in it:
14452
+ * Used when the value passed to a property has 7 interpolated values in it:
15012
14453
  *
15013
14454
  * ```html
15014
- * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
14455
+ * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
15015
14456
  * ```
15016
14457
  *
15017
14458
  * Its compiled representation is::
15018
14459
  *
15019
14460
  * ```ts
15020
- * ɵɵattributeInterpolate3(
15021
- * 'title', 'prefix', v0, '-', v1, '-', v2, 'suffix');
14461
+ * ɵɵattributeInterpolate7(
14462
+ * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
15022
14463
  * ```
15023
14464
  *
15024
14465
  * @param attrName The name of the attribute to update
@@ -15028,37 +14469,45 @@ function ɵɵattributeInterpolate2(attrName, prefix, v0, i0, v1, suffix, sanitiz
15028
14469
  * @param v1 Value checked for change.
15029
14470
  * @param i1 Static value used for concatenation only.
15030
14471
  * @param v2 Value checked for change.
14472
+ * @param i2 Static value used for concatenation only.
14473
+ * @param v3 Value checked for change.
14474
+ * @param i3 Static value used for concatenation only.
14475
+ * @param v4 Value checked for change.
14476
+ * @param i4 Static value used for concatenation only.
14477
+ * @param v5 Value checked for change.
14478
+ * @param i5 Static value used for concatenation only.
14479
+ * @param v6 Value checked for change.
15031
14480
  * @param suffix Static value used for concatenation only.
15032
14481
  * @param sanitizer An optional sanitizer function
15033
14482
  * @returns itself, so that it may be chained.
15034
14483
  * @codeGenApi
15035
14484
  */
15036
- function ɵɵattributeInterpolate3(attrName, prefix, v0, i0, v1, i1, v2, suffix, sanitizer, namespace) {
14485
+ function ɵɵattributeInterpolate7(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix, sanitizer, namespace) {
15037
14486
  const lView = getLView();
15038
- const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
14487
+ const interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
15039
14488
  if (interpolatedValue !== NO_CHANGE) {
15040
14489
  const tNode = getSelectedTNode();
15041
14490
  elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
15042
14491
  ngDevMode &&
15043
- storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 3, prefix, i0, i1, suffix);
14492
+ storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 7, prefix, i0, i1, i2, i3, i4, i5, suffix);
15044
14493
  }
15045
- return ɵɵattributeInterpolate3;
14494
+ return ɵɵattributeInterpolate7;
15046
14495
  }
15047
14496
  /**
15048
14497
  *
15049
- * Update an interpolated attribute on an element with 4 bound values surrounded by text.
14498
+ * Update an interpolated attribute on an element with 8 bound values surrounded by text.
15050
14499
  *
15051
- * Used when the value passed to a property has 4 interpolated values in it:
14500
+ * Used when the value passed to a property has 8 interpolated values in it:
15052
14501
  *
15053
14502
  * ```html
15054
- * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
14503
+ * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
15055
14504
  * ```
15056
14505
  *
15057
14506
  * Its compiled representation is::
15058
14507
  *
15059
14508
  * ```ts
15060
- * ɵɵattributeInterpolate4(
15061
- * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
14509
+ * ɵɵattributeInterpolate8(
14510
+ * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
15062
14511
  * ```
15063
14512
  *
15064
14513
  * @param attrName The name of the attribute to update
@@ -15070,251 +14519,105 @@ function ɵɵattributeInterpolate3(attrName, prefix, v0, i0, v1, i1, v2, suffix,
15070
14519
  * @param v2 Value checked for change.
15071
14520
  * @param i2 Static value used for concatenation only.
15072
14521
  * @param v3 Value checked for change.
14522
+ * @param i3 Static value used for concatenation only.
14523
+ * @param v4 Value checked for change.
14524
+ * @param i4 Static value used for concatenation only.
14525
+ * @param v5 Value checked for change.
14526
+ * @param i5 Static value used for concatenation only.
14527
+ * @param v6 Value checked for change.
14528
+ * @param i6 Static value used for concatenation only.
14529
+ * @param v7 Value checked for change.
15073
14530
  * @param suffix Static value used for concatenation only.
15074
14531
  * @param sanitizer An optional sanitizer function
15075
14532
  * @returns itself, so that it may be chained.
15076
14533
  * @codeGenApi
15077
14534
  */
15078
- function ɵɵattributeInterpolate4(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, suffix, sanitizer, namespace) {
14535
+ function ɵɵattributeInterpolate8(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix, sanitizer, namespace) {
15079
14536
  const lView = getLView();
15080
- const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
14537
+ const interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
15081
14538
  if (interpolatedValue !== NO_CHANGE) {
15082
14539
  const tNode = getSelectedTNode();
15083
14540
  elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
15084
14541
  ngDevMode &&
15085
- storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 4, prefix, i0, i1, i2, suffix);
14542
+ storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 8, prefix, i0, i1, i2, i3, i4, i5, i6, suffix);
15086
14543
  }
15087
- return ɵɵattributeInterpolate4;
14544
+ return ɵɵattributeInterpolate8;
15088
14545
  }
15089
14546
  /**
14547
+ * Update an interpolated attribute on an element with 9 or more bound values surrounded by text.
15090
14548
  *
15091
- * Update an interpolated attribute on an element with 5 bound values surrounded by text.
15092
- *
15093
- * Used when the value passed to a property has 5 interpolated values in it:
14549
+ * Used when the number of interpolated values exceeds 8.
15094
14550
  *
15095
14551
  * ```html
15096
- * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
14552
+ * <div
14553
+ * title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix"></div>
15097
14554
  * ```
15098
14555
  *
15099
14556
  * Its compiled representation is::
15100
14557
  *
15101
14558
  * ```ts
15102
- * ɵɵattributeInterpolate5(
15103
- * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
14559
+ * ɵɵattributeInterpolateV(
14560
+ * 'title', ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
14561
+ * 'suffix']);
15104
14562
  * ```
15105
14563
  *
15106
- * @param attrName The name of the attribute to update
15107
- * @param prefix Static value used for concatenation only.
15108
- * @param v0 Value checked for change.
15109
- * @param i0 Static value used for concatenation only.
15110
- * @param v1 Value checked for change.
15111
- * @param i1 Static value used for concatenation only.
15112
- * @param v2 Value checked for change.
15113
- * @param i2 Static value used for concatenation only.
15114
- * @param v3 Value checked for change.
15115
- * @param i3 Static value used for concatenation only.
15116
- * @param v4 Value checked for change.
15117
- * @param suffix Static value used for concatenation only.
14564
+ * @param attrName The name of the attribute to update.
14565
+ * @param values The collection of values and the strings in-between those values, beginning with
14566
+ * a string prefix and ending with a string suffix.
14567
+ * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
15118
14568
  * @param sanitizer An optional sanitizer function
15119
14569
  * @returns itself, so that it may be chained.
15120
14570
  * @codeGenApi
15121
14571
  */
15122
- function ɵɵattributeInterpolate5(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix, sanitizer, namespace) {
15123
- const lView = getLView();
15124
- const interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
15125
- if (interpolatedValue !== NO_CHANGE) {
15126
- const tNode = getSelectedTNode();
15127
- elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
15128
- ngDevMode &&
15129
- storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 5, prefix, i0, i1, i2, i3, suffix);
15130
- }
15131
- return ɵɵattributeInterpolate5;
15132
- }
15133
- /**
15134
- *
15135
- * Update an interpolated attribute on an element with 6 bound values surrounded by text.
15136
- *
15137
- * Used when the value passed to a property has 6 interpolated values in it:
15138
- *
15139
- * ```html
15140
- * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
15141
- * ```
15142
- *
15143
- * Its compiled representation is::
15144
- *
15145
- * ```ts
15146
- * ɵɵattributeInterpolate6(
15147
- * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
15148
- * ```
15149
- *
15150
- * @param attrName The name of the attribute to update
15151
- * @param prefix Static value used for concatenation only.
15152
- * @param v0 Value checked for change.
15153
- * @param i0 Static value used for concatenation only.
15154
- * @param v1 Value checked for change.
15155
- * @param i1 Static value used for concatenation only.
15156
- * @param v2 Value checked for change.
15157
- * @param i2 Static value used for concatenation only.
15158
- * @param v3 Value checked for change.
15159
- * @param i3 Static value used for concatenation only.
15160
- * @param v4 Value checked for change.
15161
- * @param i4 Static value used for concatenation only.
15162
- * @param v5 Value checked for change.
15163
- * @param suffix Static value used for concatenation only.
15164
- * @param sanitizer An optional sanitizer function
15165
- * @returns itself, so that it may be chained.
15166
- * @codeGenApi
15167
- */
15168
- function ɵɵattributeInterpolate6(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix, sanitizer, namespace) {
14572
+ function ɵɵattributeInterpolateV(attrName, values, sanitizer, namespace) {
15169
14573
  const lView = getLView();
15170
- const interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
15171
- if (interpolatedValue !== NO_CHANGE) {
14574
+ const interpolated = interpolationV(lView, values);
14575
+ if (interpolated !== NO_CHANGE) {
15172
14576
  const tNode = getSelectedTNode();
15173
- elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
15174
- ngDevMode &&
15175
- storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 6, prefix, i0, i1, i2, i3, i4, suffix);
14577
+ elementAttributeInternal(tNode, lView, attrName, interpolated, sanitizer, namespace);
14578
+ if (ngDevMode) {
14579
+ const interpolationInBetween = [values[0]]; // prefix
14580
+ for (let i = 2; i < values.length; i += 2) {
14581
+ interpolationInBetween.push(values[i]);
14582
+ }
14583
+ storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - interpolationInBetween.length + 1, ...interpolationInBetween);
14584
+ }
15176
14585
  }
15177
- return ɵɵattributeInterpolate6;
14586
+ return ɵɵattributeInterpolateV;
15178
14587
  }
14588
+
15179
14589
  /**
14590
+ * @license
14591
+ * Copyright Google LLC All Rights Reserved.
15180
14592
  *
15181
- * Update an interpolated attribute on an element with 7 bound values surrounded by text.
15182
- *
15183
- * Used when the value passed to a property has 7 interpolated values in it:
15184
- *
15185
- * ```html
15186
- * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
15187
- * ```
15188
- *
15189
- * Its compiled representation is::
15190
- *
15191
- * ```ts
15192
- * ɵɵattributeInterpolate7(
15193
- * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
15194
- * ```
15195
- *
15196
- * @param attrName The name of the attribute to update
15197
- * @param prefix Static value used for concatenation only.
15198
- * @param v0 Value checked for change.
15199
- * @param i0 Static value used for concatenation only.
15200
- * @param v1 Value checked for change.
15201
- * @param i1 Static value used for concatenation only.
15202
- * @param v2 Value checked for change.
15203
- * @param i2 Static value used for concatenation only.
15204
- * @param v3 Value checked for change.
15205
- * @param i3 Static value used for concatenation only.
15206
- * @param v4 Value checked for change.
15207
- * @param i4 Static value used for concatenation only.
15208
- * @param v5 Value checked for change.
15209
- * @param i5 Static value used for concatenation only.
15210
- * @param v6 Value checked for change.
15211
- * @param suffix Static value used for concatenation only.
15212
- * @param sanitizer An optional sanitizer function
15213
- * @returns itself, so that it may be chained.
15214
- * @codeGenApi
14593
+ * Use of this source code is governed by an MIT-style license that can be
14594
+ * found in the LICENSE file at https://angular.io/license
15215
14595
  */
15216
- function ɵɵattributeInterpolate7(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix, sanitizer, namespace) {
15217
- const lView = getLView();
15218
- const interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
15219
- if (interpolatedValue !== NO_CHANGE) {
15220
- const tNode = getSelectedTNode();
15221
- elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
15222
- ngDevMode &&
15223
- storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 7, prefix, i0, i1, i2, i3, i4, i5, suffix);
15224
- }
15225
- return ɵɵattributeInterpolate7;
15226
- }
15227
14596
  /**
14597
+ * Synchronously perform change detection on a component (and possibly its sub-components).
15228
14598
  *
15229
- * Update an interpolated attribute on an element with 8 bound values surrounded by text.
15230
- *
15231
- * Used when the value passed to a property has 8 interpolated values in it:
15232
- *
15233
- * ```html
15234
- * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
15235
- * ```
15236
- *
15237
- * Its compiled representation is::
15238
- *
15239
- * ```ts
15240
- * ɵɵattributeInterpolate8(
15241
- * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
15242
- * ```
14599
+ * This function triggers change detection in a synchronous way on a component.
15243
14600
  *
15244
- * @param attrName The name of the attribute to update
15245
- * @param prefix Static value used for concatenation only.
15246
- * @param v0 Value checked for change.
15247
- * @param i0 Static value used for concatenation only.
15248
- * @param v1 Value checked for change.
15249
- * @param i1 Static value used for concatenation only.
15250
- * @param v2 Value checked for change.
15251
- * @param i2 Static value used for concatenation only.
15252
- * @param v3 Value checked for change.
15253
- * @param i3 Static value used for concatenation only.
15254
- * @param v4 Value checked for change.
15255
- * @param i4 Static value used for concatenation only.
15256
- * @param v5 Value checked for change.
15257
- * @param i5 Static value used for concatenation only.
15258
- * @param v6 Value checked for change.
15259
- * @param i6 Static value used for concatenation only.
15260
- * @param v7 Value checked for change.
15261
- * @param suffix Static value used for concatenation only.
15262
- * @param sanitizer An optional sanitizer function
15263
- * @returns itself, so that it may be chained.
15264
- * @codeGenApi
14601
+ * @param component The component which the change detection should be performed on.
15265
14602
  */
15266
- function ɵɵattributeInterpolate8(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix, sanitizer, namespace) {
15267
- const lView = getLView();
15268
- const interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
15269
- if (interpolatedValue !== NO_CHANGE) {
15270
- const tNode = getSelectedTNode();
15271
- elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
15272
- ngDevMode &&
15273
- storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 8, prefix, i0, i1, i2, i3, i4, i5, i6, suffix);
15274
- }
15275
- return ɵɵattributeInterpolate8;
14603
+ function detectChanges(component) {
14604
+ const view = getComponentViewByInstance(component);
14605
+ detectChangesInternal(view[TVIEW], view, component);
15276
14606
  }
15277
14607
  /**
15278
- * Update an interpolated attribute on an element with 9 or more bound values surrounded by text.
15279
- *
15280
- * Used when the number of interpolated values exceeds 8.
15281
- *
15282
- * ```html
15283
- * <div
15284
- * title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix"></div>
15285
- * ```
15286
- *
15287
- * Its compiled representation is::
14608
+ * Marks the component as dirty (needing change detection). Marking a component dirty will
14609
+ * schedule a change detection on it at some point in the future.
15288
14610
  *
15289
- * ```ts
15290
- * ɵɵattributeInterpolateV(
15291
- * 'title', ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
15292
- * 'suffix']);
15293
- * ```
14611
+ * Marking an already dirty component as dirty won't do anything. Only one outstanding change
14612
+ * detection can be scheduled per component tree.
15294
14613
  *
15295
- * @param attrName The name of the attribute to update.
15296
- * @param values The collection of values and the strings in-between those values, beginning with
15297
- * a string prefix and ending with a string suffix.
15298
- * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
15299
- * @param sanitizer An optional sanitizer function
15300
- * @returns itself, so that it may be chained.
15301
- * @codeGenApi
14614
+ * @param component Component to mark as dirty.
15302
14615
  */
15303
- function ɵɵattributeInterpolateV(attrName, values, sanitizer, namespace) {
15304
- const lView = getLView();
15305
- const interpolated = interpolationV(lView, values);
15306
- if (interpolated !== NO_CHANGE) {
15307
- const tNode = getSelectedTNode();
15308
- elementAttributeInternal(tNode, lView, attrName, interpolated, sanitizer, namespace);
15309
- if (ngDevMode) {
15310
- const interpolationInBetween = [values[0]]; // prefix
15311
- for (let i = 2; i < values.length; i += 2) {
15312
- interpolationInBetween.push(values[i]);
15313
- }
15314
- storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - interpolationInBetween.length + 1, ...interpolationInBetween);
15315
- }
15316
- }
15317
- return ɵɵattributeInterpolateV;
14616
+ function markDirty(component) {
14617
+ ngDevMode && assertDefined(component, 'component');
14618
+ const rootView = markViewDirty(getComponentViewByInstance(component));
14619
+ ngDevMode && assertDefined(rootView[CONTEXT], 'rootContext should be defined');
14620
+ scheduleTick(rootView[CONTEXT], 1 /* RootContextFlags.DetectChanges */);
15318
14621
  }
15319
14622
 
15320
14623
  /**
@@ -15861,51 +15164,42 @@ function listenerInternal(tView, lView, renderer, tNode, eventName, listenerFn,
15861
15164
  tNode.index;
15862
15165
  // In order to match current behavior, native DOM event listeners must be added for all
15863
15166
  // 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
- }
15167
+ // There might be cases where multiple directives on the same element try to register an event
15168
+ // handler function for the same event. In this situation we want to avoid registration of
15169
+ // several native listeners as each registration would be intercepted by NgZone and
15170
+ // trigger change detection. This would mean that a single user action would result in several
15171
+ // change detections being invoked. To avoid this situation we want to have only one call to
15172
+ // native handler registration (for the same element and same type of event).
15173
+ //
15174
+ // In order to have just one native event handler in presence of multiple handler functions,
15175
+ // we just register a first handler function as a native event listener and then chain
15176
+ // (coalesce) other handler functions on top of the first native handler function.
15177
+ let existingListener = null;
15178
+ // Please note that the coalescing described here doesn't happen for events specifying an
15179
+ // alternative target (ex. (document:click)) - this is to keep backward compatibility with the
15180
+ // view engine.
15181
+ // Also, we don't have to search for existing listeners is there are no directives
15182
+ // matching on a given node as we can't register multiple event handlers for the same event in
15183
+ // a template (this would mean having duplicate attributes).
15184
+ if (!eventTargetResolver && isTNodeDirectiveHost) {
15185
+ existingListener = findExistingListener(tView, lView, eventName, tNode.index);
15186
+ }
15187
+ if (existingListener !== null) {
15188
+ // Attach a new listener to coalesced listeners list, maintaining the order in which
15189
+ // listeners are registered. For performance reasons, we keep a reference to the last
15190
+ // listener in that list (in `__ngLastListenerFn__` field), so we can avoid going through
15191
+ // the entire set each time we need to add a new listener.
15192
+ const lastListenerFn = existingListener.__ngLastListenerFn__ || existingListener;
15193
+ lastListenerFn.__ngNextListenerFn__ = listenerFn;
15194
+ existingListener.__ngLastListenerFn__ = listenerFn;
15195
+ processOutputs = false;
15902
15196
  }
15903
15197
  else {
15904
- listenerFn = wrapListener(tNode, lView, context, listenerFn, true /** preventDefault */);
15905
- target.addEventListener(eventName, listenerFn, useCapture);
15198
+ listenerFn = wrapListener(tNode, lView, context, listenerFn, false /** preventDefault */);
15199
+ const cleanupFn = renderer.listen(target, eventName, listenerFn);
15906
15200
  ngDevMode && ngDevMode.rendererAddEventListener++;
15907
- lCleanup.push(listenerFn);
15908
- tCleanup && tCleanup.push(eventName, idxOrTargetGetter, lCleanupIndex, useCapture);
15201
+ lCleanup.push(listenerFn, cleanupFn);
15202
+ tCleanup && tCleanup.push(eventName, idxOrTargetGetter, lCleanupIndex, lCleanupIndex + 1);
15909
15203
  }
15910
15204
  }
15911
15205
  else {
@@ -17979,7 +17273,7 @@ function findStylingValue(tData, tNode, lView, prop, index, isClassBased) {
17979
17273
  valueAtLViewIndex = isStylingMap ? EMPTY_ARRAY : undefined;
17980
17274
  }
17981
17275
  let currentValue = isStylingMap ? keyValueArrayGet(valueAtLViewIndex, prop) :
17982
- key === prop ? valueAtLViewIndex : undefined;
17276
+ (key === prop ? valueAtLViewIndex : undefined);
17983
17277
  if (containsStatics && !isStylingValuePresent(currentValue)) {
17984
17278
  currentValue = keyValueArrayGet(rawKey, prop);
17985
17279
  }
@@ -21832,7 +21126,7 @@ function noComponentFactoryError(component) {
21832
21126
  return error;
21833
21127
  }
21834
21128
  const ERROR_COMPONENT = 'ngComponent';
21835
- function getComponent(error) {
21129
+ function getComponent$1(error) {
21836
21130
  return error[ERROR_COMPONENT];
21837
21131
  }
21838
21132
  class _NullComponentFactoryResolver {
@@ -22016,14 +21310,6 @@ class Renderer2 {
22016
21310
  * @nocollapse
22017
21311
  */
22018
21312
  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
21313
  /** Injects a Renderer2 for the current component. */
22028
21314
  function injectRenderer2() {
22029
21315
  // We need the Renderer to be based on the component that it's being injected into, however since
@@ -22031,7 +21317,7 @@ function injectRenderer2() {
22031
21317
  const lView = getLView();
22032
21318
  const tNode = getCurrentTNode();
22033
21319
  const nodeAtIndex = getComponentLViewByIndex(tNode.index, lView);
22034
- return getOrCreateRenderer2(isLView(nodeAtIndex) ? nodeAtIndex : lView);
21320
+ return (isLView(nodeAtIndex) ? nodeAtIndex : lView)[RENDERER];
22035
21321
  }
22036
21322
 
22037
21323
  /**
@@ -22078,7 +21364,7 @@ class Version {
22078
21364
  /**
22079
21365
  * @publicApi
22080
21366
  */
22081
- const VERSION = new Version('14.0.4');
21367
+ const VERSION = new Version('14.0.7');
22082
21368
 
22083
21369
  /**
22084
21370
  * @license
@@ -22424,31 +21710,407 @@ class ViewRef {
22424
21710
  this._appRef = null;
22425
21711
  renderDetachView(this._lView[TVIEW], this._lView);
22426
21712
  }
22427
- attachToAppRef(appRef) {
22428
- if (this._attachedToViewContainer) {
22429
- throw new RuntimeError(902 /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */, ngDevMode && 'This view is already attached to a ViewContainer!');
22430
- }
22431
- this._appRef = appRef;
21713
+ attachToAppRef(appRef) {
21714
+ if (this._attachedToViewContainer) {
21715
+ throw new RuntimeError(902 /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */, ngDevMode && 'This view is already attached to a ViewContainer!');
21716
+ }
21717
+ this._appRef = appRef;
21718
+ }
21719
+ }
21720
+ /** @internal */
21721
+ class RootViewRef extends ViewRef {
21722
+ constructor(_view) {
21723
+ super(_view);
21724
+ this._view = _view;
21725
+ }
21726
+ detectChanges() {
21727
+ detectChangesInRootView(this._view);
21728
+ }
21729
+ checkNoChanges() {
21730
+ if (ngDevMode) {
21731
+ checkNoChangesInRootView(this._view);
21732
+ }
21733
+ }
21734
+ get context() {
21735
+ return null;
21736
+ }
21737
+ }
21738
+
21739
+ /**
21740
+ * @license
21741
+ * Copyright Google LLC All Rights Reserved.
21742
+ *
21743
+ * Use of this source code is governed by an MIT-style license that can be
21744
+ * found in the LICENSE file at https://angular.io/license
21745
+ */
21746
+ class ComponentFactoryResolver extends ComponentFactoryResolver$1 {
21747
+ /**
21748
+ * @param ngModule The NgModuleRef to which all resolved factories are bound.
21749
+ */
21750
+ constructor(ngModule) {
21751
+ super();
21752
+ this.ngModule = ngModule;
21753
+ }
21754
+ resolveComponentFactory(component) {
21755
+ ngDevMode && assertComponentType(component);
21756
+ const componentDef = getComponentDef$1(component);
21757
+ return new ComponentFactory(componentDef, this.ngModule);
21758
+ }
21759
+ }
21760
+ function toRefArray(map) {
21761
+ const array = [];
21762
+ for (let nonMinified in map) {
21763
+ if (map.hasOwnProperty(nonMinified)) {
21764
+ const minified = map[nonMinified];
21765
+ array.push({ propName: minified, templateName: nonMinified });
21766
+ }
21767
+ }
21768
+ return array;
21769
+ }
21770
+ function getNamespace(elementName) {
21771
+ const name = elementName.toLowerCase();
21772
+ return name === 'svg' ? SVG_NAMESPACE : (name === 'math' ? MATH_ML_NAMESPACE : null);
21773
+ }
21774
+ /**
21775
+ * Injector that looks up a value using a specific injector, before falling back to the module
21776
+ * injector. Used primarily when creating components or embedded views dynamically.
21777
+ */
21778
+ class ChainedInjector {
21779
+ constructor(injector, parentInjector) {
21780
+ this.injector = injector;
21781
+ this.parentInjector = parentInjector;
21782
+ }
21783
+ get(token, notFoundValue, flags) {
21784
+ const value = this.injector.get(token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, flags);
21785
+ if (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR ||
21786
+ notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) {
21787
+ // Return the value from the root element injector when
21788
+ // - it provides it
21789
+ // (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
21790
+ // - the module injector should not be checked
21791
+ // (notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
21792
+ return value;
21793
+ }
21794
+ return this.parentInjector.get(token, notFoundValue, flags);
21795
+ }
21796
+ }
21797
+ /**
21798
+ * Render3 implementation of {@link viewEngine_ComponentFactory}.
21799
+ */
21800
+ class ComponentFactory extends ComponentFactory$1 {
21801
+ /**
21802
+ * @param componentDef The component definition.
21803
+ * @param ngModule The NgModuleRef to which the factory is bound.
21804
+ */
21805
+ constructor(componentDef, ngModule) {
21806
+ super();
21807
+ this.componentDef = componentDef;
21808
+ this.ngModule = ngModule;
21809
+ this.componentType = componentDef.type;
21810
+ this.selector = stringifyCSSSelectorList(componentDef.selectors);
21811
+ this.ngContentSelectors =
21812
+ componentDef.ngContentSelectors ? componentDef.ngContentSelectors : [];
21813
+ this.isBoundToModule = !!ngModule;
21814
+ }
21815
+ get inputs() {
21816
+ return toRefArray(this.componentDef.inputs);
21817
+ }
21818
+ get outputs() {
21819
+ return toRefArray(this.componentDef.outputs);
21820
+ }
21821
+ create(injector, projectableNodes, rootSelectorOrNode, environmentInjector) {
21822
+ environmentInjector = environmentInjector || this.ngModule;
21823
+ let realEnvironmentInjector = environmentInjector instanceof EnvironmentInjector ?
21824
+ environmentInjector :
21825
+ environmentInjector?.injector;
21826
+ if (realEnvironmentInjector && this.componentDef.getStandaloneInjector !== null) {
21827
+ realEnvironmentInjector = this.componentDef.getStandaloneInjector(realEnvironmentInjector) ||
21828
+ realEnvironmentInjector;
21829
+ }
21830
+ const rootViewInjector = realEnvironmentInjector ? new ChainedInjector(injector, realEnvironmentInjector) : injector;
21831
+ const rendererFactory = rootViewInjector.get(RendererFactory2, null);
21832
+ if (rendererFactory === null) {
21833
+ throw new RuntimeError(407 /* RuntimeErrorCode.RENDERER_NOT_FOUND */, ngDevMode &&
21834
+ 'Angular was not able to inject a renderer (RendererFactory2). ' +
21835
+ 'Likely this is due to a broken DI hierarchy. ' +
21836
+ 'Make sure that any injector used to create this component has a correct parent.');
21837
+ }
21838
+ const sanitizer = rootViewInjector.get(Sanitizer, null);
21839
+ const hostRenderer = rendererFactory.createRenderer(null, this.componentDef);
21840
+ // Determine a tag name used for creating host elements when this component is created
21841
+ // dynamically. Default to 'div' if this component did not specify any tag name in its selector.
21842
+ const elementName = this.componentDef.selectors[0][0] || 'div';
21843
+ const hostRNode = rootSelectorOrNode ?
21844
+ locateHostElement(hostRenderer, rootSelectorOrNode, this.componentDef.encapsulation) :
21845
+ createElementNode(rendererFactory.createRenderer(null, this.componentDef), elementName, getNamespace(elementName));
21846
+ const rootFlags = this.componentDef.onPush ? 32 /* LViewFlags.Dirty */ | 256 /* LViewFlags.IsRoot */ :
21847
+ 16 /* LViewFlags.CheckAlways */ | 256 /* LViewFlags.IsRoot */;
21848
+ const rootContext = createRootContext();
21849
+ // Create the root view. Uses empty TView and ContentTemplate.
21850
+ const rootTView = createTView(0 /* TViewType.Root */, null, null, 1, 0, null, null, null, null, null);
21851
+ const rootLView = createLView(null, rootTView, rootContext, rootFlags, null, null, rendererFactory, hostRenderer, sanitizer, rootViewInjector, null);
21852
+ // rootView is the parent when bootstrapping
21853
+ // TODO(misko): it looks like we are entering view here but we don't really need to as
21854
+ // `renderView` does that. However as the code is written it is needed because
21855
+ // `createRootComponentView` and `createRootComponent` both read global state. Fixing those
21856
+ // issues would allow us to drop this.
21857
+ enterView(rootLView);
21858
+ let component;
21859
+ let tElementNode;
21860
+ try {
21861
+ const componentView = createRootComponentView(hostRNode, this.componentDef, rootLView, rendererFactory, hostRenderer);
21862
+ if (hostRNode) {
21863
+ if (rootSelectorOrNode) {
21864
+ setUpAttributes(hostRenderer, hostRNode, ['ng-version', VERSION.full]);
21865
+ }
21866
+ else {
21867
+ // If host element is created as a part of this function call (i.e. `rootSelectorOrNode`
21868
+ // is not defined), also apply attributes and classes extracted from component selector.
21869
+ // Extract attributes and classes from the first selector only to match VE behavior.
21870
+ const { attrs, classes } = extractAttrsAndClassesFromSelector(this.componentDef.selectors[0]);
21871
+ if (attrs) {
21872
+ setUpAttributes(hostRenderer, hostRNode, attrs);
21873
+ }
21874
+ if (classes && classes.length > 0) {
21875
+ writeDirectClass(hostRenderer, hostRNode, classes.join(' '));
21876
+ }
21877
+ }
21878
+ }
21879
+ tElementNode = getTNode(rootTView, HEADER_OFFSET);
21880
+ if (projectableNodes !== undefined) {
21881
+ const projection = tElementNode.projection = [];
21882
+ for (let i = 0; i < this.ngContentSelectors.length; i++) {
21883
+ const nodesforSlot = projectableNodes[i];
21884
+ // Projectable nodes can be passed as array of arrays or an array of iterables (ngUpgrade
21885
+ // case). Here we do normalize passed data structure to be an array of arrays to avoid
21886
+ // complex checks down the line.
21887
+ // We also normalize the length of the passed in projectable nodes (to match the number of
21888
+ // <ng-container> slots defined by a component).
21889
+ projection.push(nodesforSlot != null ? Array.from(nodesforSlot) : null);
21890
+ }
21891
+ }
21892
+ // TODO: should LifecycleHooksFeature and other host features be generated by the compiler and
21893
+ // executed here?
21894
+ // Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref
21895
+ component = createRootComponent(componentView, this.componentDef, rootLView, rootContext, [LifecycleHooksFeature]);
21896
+ renderView(rootTView, rootLView, null);
21897
+ }
21898
+ finally {
21899
+ leaveView();
21900
+ }
21901
+ return new ComponentRef(this.componentType, component, createElementRef(tElementNode, rootLView), rootLView, tElementNode);
21902
+ }
21903
+ }
21904
+ const componentFactoryResolver = new ComponentFactoryResolver();
21905
+ /**
21906
+ * Creates a ComponentFactoryResolver and stores it on the injector. Or, if the
21907
+ * ComponentFactoryResolver
21908
+ * already exists, retrieves the existing ComponentFactoryResolver.
21909
+ *
21910
+ * @returns The ComponentFactoryResolver instance to use
21911
+ */
21912
+ function injectComponentFactoryResolver() {
21913
+ return componentFactoryResolver;
21914
+ }
21915
+ /**
21916
+ * Represents an instance of a Component created via a {@link ComponentFactory}.
21917
+ *
21918
+ * `ComponentRef` provides access to the Component Instance as well other objects related to this
21919
+ * Component Instance and allows you to destroy the Component Instance via the {@link #destroy}
21920
+ * method.
21921
+ *
21922
+ */
21923
+ class ComponentRef extends ComponentRef$1 {
21924
+ constructor(componentType, instance, location, _rootLView, _tNode) {
21925
+ super();
21926
+ this.location = location;
21927
+ this._rootLView = _rootLView;
21928
+ this._tNode = _tNode;
21929
+ this.instance = instance;
21930
+ this.hostView = this.changeDetectorRef = new RootViewRef(_rootLView);
21931
+ this.componentType = componentType;
21932
+ }
21933
+ get injector() {
21934
+ return new NodeInjector(this._tNode, this._rootLView);
21935
+ }
21936
+ destroy() {
21937
+ this.hostView.destroy();
21938
+ }
21939
+ onDestroy(callback) {
21940
+ this.hostView.onDestroy(callback);
21941
+ }
21942
+ }
21943
+
21944
+ /**
21945
+ * @license
21946
+ * Copyright Google LLC All Rights Reserved.
21947
+ *
21948
+ * Use of this source code is governed by an MIT-style license that can be
21949
+ * found in the LICENSE file at https://angular.io/license
21950
+ */
21951
+ /**
21952
+ * Returns a new NgModuleRef instance based on the NgModule class and parent injector provided.
21953
+ * @param ngModule NgModule class.
21954
+ * @param parentInjector Optional injector instance to use as a parent for the module injector. If
21955
+ * not provided, `NullInjector` will be used instead.
21956
+ * @publicApi
21957
+ */
21958
+ function createNgModuleRef(ngModule, parentInjector) {
21959
+ return new NgModuleRef(ngModule, parentInjector ?? null);
21960
+ }
21961
+ class NgModuleRef extends NgModuleRef$1 {
21962
+ constructor(ngModuleType, _parent) {
21963
+ super();
21964
+ this._parent = _parent;
21965
+ // tslint:disable-next-line:require-internal-with-underscore
21966
+ this._bootstrapComponents = [];
21967
+ this.injector = this;
21968
+ this.destroyCbs = [];
21969
+ // When bootstrapping a module we have a dependency graph that looks like this:
21970
+ // ApplicationRef -> ComponentFactoryResolver -> NgModuleRef. The problem is that if the
21971
+ // module being resolved tries to inject the ComponentFactoryResolver, it'll create a
21972
+ // circular dependency which will result in a runtime error, because the injector doesn't
21973
+ // exist yet. We work around the issue by creating the ComponentFactoryResolver ourselves
21974
+ // and providing it, rather than letting the injector resolve it.
21975
+ this.componentFactoryResolver = new ComponentFactoryResolver(this);
21976
+ const ngModuleDef = getNgModuleDef(ngModuleType);
21977
+ ngDevMode &&
21978
+ assertDefined(ngModuleDef, `NgModule '${stringify(ngModuleType)}' is not a subtype of 'NgModuleType'.`);
21979
+ this._bootstrapComponents = maybeUnwrapFn$1(ngModuleDef.bootstrap);
21980
+ this._r3Injector = createInjectorWithoutInjectorInstances(ngModuleType, _parent, [
21981
+ { provide: NgModuleRef$1, useValue: this }, {
21982
+ provide: ComponentFactoryResolver$1,
21983
+ useValue: this.componentFactoryResolver
21984
+ }
21985
+ ], stringify(ngModuleType), new Set(['environment']));
21986
+ // We need to resolve the injector types separately from the injector creation, because
21987
+ // the module might be trying to use this ref in its constructor for DI which will cause a
21988
+ // circular error that will eventually error out, because the injector isn't created yet.
21989
+ this._r3Injector.resolveInjectorInitializers();
21990
+ this.instance = this.get(ngModuleType);
21991
+ }
21992
+ get(token, notFoundValue = Injector.THROW_IF_NOT_FOUND, injectFlags = InjectFlags.Default) {
21993
+ if (token === Injector || token === NgModuleRef$1 || token === INJECTOR) {
21994
+ return this;
21995
+ }
21996
+ return this._r3Injector.get(token, notFoundValue, injectFlags);
21997
+ }
21998
+ destroy() {
21999
+ ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
22000
+ const injector = this._r3Injector;
22001
+ !injector.destroyed && injector.destroy();
22002
+ this.destroyCbs.forEach(fn => fn());
22003
+ this.destroyCbs = null;
22004
+ }
22005
+ onDestroy(callback) {
22006
+ ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
22007
+ this.destroyCbs.push(callback);
22008
+ }
22009
+ }
22010
+ class NgModuleFactory extends NgModuleFactory$1 {
22011
+ constructor(moduleType) {
22012
+ super();
22013
+ this.moduleType = moduleType;
22014
+ }
22015
+ create(parentInjector) {
22016
+ return new NgModuleRef(this.moduleType, parentInjector);
22432
22017
  }
22433
22018
  }
22434
- /** @internal */
22435
- class RootViewRef extends ViewRef {
22436
- constructor(_view) {
22437
- super(_view);
22438
- this._view = _view;
22019
+ class EnvironmentNgModuleRefAdapter extends NgModuleRef$1 {
22020
+ constructor(providers, parent, source) {
22021
+ super();
22022
+ this.componentFactoryResolver = new ComponentFactoryResolver(this);
22023
+ this.instance = null;
22024
+ const injector = new R3Injector([
22025
+ ...providers,
22026
+ { provide: NgModuleRef$1, useValue: this },
22027
+ { provide: ComponentFactoryResolver$1, useValue: this.componentFactoryResolver },
22028
+ ], parent || getNullInjector(), source, new Set(['environment']));
22029
+ this.injector = injector;
22030
+ injector.resolveInjectorInitializers();
22439
22031
  }
22440
- detectChanges() {
22441
- detectChangesInRootView(this._view);
22032
+ destroy() {
22033
+ this.injector.destroy();
22442
22034
  }
22443
- checkNoChanges() {
22444
- if (ngDevMode) {
22445
- checkNoChangesInRootView(this._view);
22035
+ onDestroy(callback) {
22036
+ this.injector.onDestroy(callback);
22037
+ }
22038
+ }
22039
+ /**
22040
+ * Create a new environment injector.
22041
+ *
22042
+ * @publicApi
22043
+ * @developerPreview
22044
+ */
22045
+ function createEnvironmentInjector(providers, parent = null, debugName = null) {
22046
+ const adapter = new EnvironmentNgModuleRefAdapter(providers, parent, debugName);
22047
+ return adapter.injector;
22048
+ }
22049
+
22050
+ /**
22051
+ * @license
22052
+ * Copyright Google LLC All Rights Reserved.
22053
+ *
22054
+ * Use of this source code is governed by an MIT-style license that can be
22055
+ * found in the LICENSE file at https://angular.io/license
22056
+ */
22057
+ /**
22058
+ * A service used by the framework to create instances of standalone injectors. Those injectors are
22059
+ * created on demand in case of dynamic component instantiation and contain ambient providers
22060
+ * collected from the imports graph rooted at a given standalone component.
22061
+ */
22062
+ class StandaloneService {
22063
+ constructor(_injector) {
22064
+ this._injector = _injector;
22065
+ this.cachedInjectors = new Map();
22066
+ }
22067
+ getOrCreateStandaloneInjector(componentDef) {
22068
+ if (!componentDef.standalone) {
22069
+ return null;
22070
+ }
22071
+ if (!this.cachedInjectors.has(componentDef.id)) {
22072
+ const providers = internalImportProvidersFrom(false, componentDef.type);
22073
+ const standaloneInjector = providers.length > 0 ?
22074
+ createEnvironmentInjector([providers], this._injector, `Standalone[${componentDef.type.name}]`) :
22075
+ null;
22076
+ this.cachedInjectors.set(componentDef.id, standaloneInjector);
22446
22077
  }
22078
+ return this.cachedInjectors.get(componentDef.id);
22447
22079
  }
22448
- get context() {
22449
- return null;
22080
+ ngOnDestroy() {
22081
+ try {
22082
+ for (const injector of this.cachedInjectors.values()) {
22083
+ if (injector !== null) {
22084
+ injector.destroy();
22085
+ }
22086
+ }
22087
+ }
22088
+ finally {
22089
+ this.cachedInjectors.clear();
22090
+ }
22450
22091
  }
22451
22092
  }
22093
+ /** @nocollapse */
22094
+ StandaloneService.ɵprov = ɵɵdefineInjectable({
22095
+ token: StandaloneService,
22096
+ providedIn: 'environment',
22097
+ factory: () => new StandaloneService(ɵɵinject(EnvironmentInjector)),
22098
+ });
22099
+ /**
22100
+ * A feature that acts as a setup code for the {@link StandaloneService}.
22101
+ *
22102
+ * The most important responsaibility of this feature is to expose the "getStandaloneInjector"
22103
+ * function (an entry points to a standalone injector creation) on a component definition object. We
22104
+ * go through the features infrastructure to make sure that the standalone injector creation logic
22105
+ * is tree-shakable and not included in applications that don't use standalone components.
22106
+ *
22107
+ * @codeGenApi
22108
+ */
22109
+ function ɵɵStandaloneFeature(definition) {
22110
+ definition.getStandaloneInjector = (parentInjector) => {
22111
+ return parentInjector.get(StandaloneService).getOrCreateStandaloneInjector(definition);
22112
+ };
22113
+ }
22452
22114
 
22453
22115
  /**
22454
22116
  * @license
@@ -22457,367 +22119,407 @@ class RootViewRef extends ViewRef {
22457
22119
  * Use of this source code is governed by an MIT-style license that can be
22458
22120
  * found in the LICENSE file at https://angular.io/license
22459
22121
  */
22460
- class ComponentFactoryResolver extends ComponentFactoryResolver$1 {
22461
- /**
22462
- * @param ngModule The NgModuleRef to which all resolved factories are bound.
22463
- */
22464
- constructor(ngModule) {
22465
- super();
22466
- this.ngModule = ngModule;
22122
+ /**
22123
+ * Retrieves the component instance associated with a given DOM element.
22124
+ *
22125
+ * @usageNotes
22126
+ * Given the following DOM structure:
22127
+ *
22128
+ * ```html
22129
+ * <app-root>
22130
+ * <div>
22131
+ * <child-comp></child-comp>
22132
+ * </div>
22133
+ * </app-root>
22134
+ * ```
22135
+ *
22136
+ * Calling `getComponent` on `<child-comp>` will return the instance of `ChildComponent`
22137
+ * associated with this DOM element.
22138
+ *
22139
+ * Calling the function on `<app-root>` will return the `MyApp` instance.
22140
+ *
22141
+ *
22142
+ * @param element DOM element from which the component should be retrieved.
22143
+ * @returns Component instance associated with the element or `null` if there
22144
+ * is no component associated with it.
22145
+ *
22146
+ * @publicApi
22147
+ * @globalApi ng
22148
+ */
22149
+ function getComponent(element) {
22150
+ ngDevMode && assertDomElement(element);
22151
+ const context = getLContext(element);
22152
+ if (context === null)
22153
+ return null;
22154
+ if (context.component === undefined) {
22155
+ const lView = context.lView;
22156
+ if (lView === null) {
22157
+ return null;
22158
+ }
22159
+ context.component = getComponentAtNodeIndex(context.nodeIndex, lView);
22467
22160
  }
22468
- resolveComponentFactory(component) {
22469
- ngDevMode && assertComponentType(component);
22470
- const componentDef = getComponentDef$1(component);
22471
- return new ComponentFactory(componentDef, this.ngModule);
22161
+ return context.component;
22162
+ }
22163
+ /**
22164
+ * If inside an embedded view (e.g. `*ngIf` or `*ngFor`), retrieves the context of the embedded
22165
+ * view that the element is part of. Otherwise retrieves the instance of the component whose view
22166
+ * owns the element (in this case, the result is the same as calling `getOwningComponent`).
22167
+ *
22168
+ * @param element Element for which to get the surrounding component instance.
22169
+ * @returns Instance of the component that is around the element or null if the element isn't
22170
+ * inside any component.
22171
+ *
22172
+ * @publicApi
22173
+ * @globalApi ng
22174
+ */
22175
+ function getContext(element) {
22176
+ assertDomElement(element);
22177
+ const context = getLContext(element);
22178
+ const lView = context ? context.lView : null;
22179
+ return lView === null ? null : lView[CONTEXT];
22180
+ }
22181
+ /**
22182
+ * Retrieves the component instance whose view contains the DOM element.
22183
+ *
22184
+ * For example, if `<child-comp>` is used in the template of `<app-comp>`
22185
+ * (i.e. a `ViewChild` of `<app-comp>`), calling `getOwningComponent` on `<child-comp>`
22186
+ * would return `<app-comp>`.
22187
+ *
22188
+ * @param elementOrDir DOM element, component or directive instance
22189
+ * for which to retrieve the root components.
22190
+ * @returns Component instance whose view owns the DOM element or null if the element is not
22191
+ * part of a component view.
22192
+ *
22193
+ * @publicApi
22194
+ * @globalApi ng
22195
+ */
22196
+ function getOwningComponent(elementOrDir) {
22197
+ const context = getLContext(elementOrDir);
22198
+ let lView = context ? context.lView : null;
22199
+ if (lView === null)
22200
+ return null;
22201
+ let parent;
22202
+ while (lView[TVIEW].type === 2 /* TViewType.Embedded */ && (parent = getLViewParent(lView))) {
22203
+ lView = parent;
22472
22204
  }
22205
+ return lView[FLAGS] & 256 /* LViewFlags.IsRoot */ ? null : lView[CONTEXT];
22473
22206
  }
22474
- function toRefArray(map) {
22475
- const array = [];
22476
- for (let nonMinified in map) {
22477
- if (map.hasOwnProperty(nonMinified)) {
22478
- const minified = map[nonMinified];
22479
- array.push({ propName: minified, templateName: nonMinified });
22207
+ /**
22208
+ * Retrieves all root components associated with a DOM element, directive or component instance.
22209
+ * Root components are those which have been bootstrapped by Angular.
22210
+ *
22211
+ * @param elementOrDir DOM element, component or directive instance
22212
+ * for which to retrieve the root components.
22213
+ * @returns Root components associated with the target object.
22214
+ *
22215
+ * @publicApi
22216
+ * @globalApi ng
22217
+ */
22218
+ function getRootComponents(elementOrDir) {
22219
+ const lView = readPatchedLView(elementOrDir);
22220
+ return lView !== null ? [...getRootContext(lView).components] : [];
22221
+ }
22222
+ /**
22223
+ * Retrieves an `Injector` associated with an element, component or directive instance.
22224
+ *
22225
+ * @param elementOrDir DOM element, component or directive instance for which to
22226
+ * retrieve the injector.
22227
+ * @returns Injector associated with the element, component or directive instance.
22228
+ *
22229
+ * @publicApi
22230
+ * @globalApi ng
22231
+ */
22232
+ function getInjector(elementOrDir) {
22233
+ const context = getLContext(elementOrDir);
22234
+ const lView = context ? context.lView : null;
22235
+ if (lView === null)
22236
+ return Injector.NULL;
22237
+ const tNode = lView[TVIEW].data[context.nodeIndex];
22238
+ return new NodeInjector(tNode, lView);
22239
+ }
22240
+ /**
22241
+ * Retrieve a set of injection tokens at a given DOM node.
22242
+ *
22243
+ * @param element Element for which the injection tokens should be retrieved.
22244
+ */
22245
+ function getInjectionTokens(element) {
22246
+ const context = getLContext(element);
22247
+ const lView = context ? context.lView : null;
22248
+ if (lView === null)
22249
+ return [];
22250
+ const tView = lView[TVIEW];
22251
+ const tNode = tView.data[context.nodeIndex];
22252
+ const providerTokens = [];
22253
+ const startIndex = tNode.providerIndexes & 1048575 /* TNodeProviderIndexes.ProvidersStartIndexMask */;
22254
+ const endIndex = tNode.directiveEnd;
22255
+ for (let i = startIndex; i < endIndex; i++) {
22256
+ let value = tView.data[i];
22257
+ if (isDirectiveDefHack(value)) {
22258
+ // The fact that we sometimes store Type and sometimes DirectiveDef in this location is a
22259
+ // design flaw. We should always store same type so that we can be monomorphic. The issue
22260
+ // is that for Components/Directives we store the def instead the type. The correct behavior
22261
+ // is that we should always be storing injectable type in this location.
22262
+ value = value.type;
22480
22263
  }
22264
+ providerTokens.push(value);
22481
22265
  }
22482
- return array;
22483
- }
22484
- function getNamespace(elementName) {
22485
- const name = elementName.toLowerCase();
22486
- return name === 'svg' ? SVG_NAMESPACE : (name === 'math' ? MATH_ML_NAMESPACE : null);
22266
+ return providerTokens;
22487
22267
  }
22488
22268
  /**
22489
- * Injector that looks up a value using a specific injector, before falling back to the module
22490
- * injector. Used primarily when creating components or embedded views dynamically.
22269
+ * Retrieves directive instances associated with a given DOM node. Does not include
22270
+ * component instances.
22271
+ *
22272
+ * @usageNotes
22273
+ * Given the following DOM structure:
22274
+ *
22275
+ * ```html
22276
+ * <app-root>
22277
+ * <button my-button></button>
22278
+ * <my-comp></my-comp>
22279
+ * </app-root>
22280
+ * ```
22281
+ *
22282
+ * Calling `getDirectives` on `<button>` will return an array with an instance of the `MyButton`
22283
+ * directive that is associated with the DOM node.
22284
+ *
22285
+ * Calling `getDirectives` on `<my-comp>` will return an empty array.
22286
+ *
22287
+ * @param node DOM node for which to get the directives.
22288
+ * @returns Array of directives associated with the node.
22289
+ *
22290
+ * @publicApi
22291
+ * @globalApi ng
22491
22292
  */
22492
- class ChainedInjector {
22493
- constructor(injector, parentInjector) {
22494
- this.injector = injector;
22495
- this.parentInjector = parentInjector;
22293
+ function getDirectives(node) {
22294
+ // Skip text nodes because we can't have directives associated with them.
22295
+ if (node instanceof Text) {
22296
+ return [];
22496
22297
  }
22497
- get(token, notFoundValue, flags) {
22498
- const value = this.injector.get(token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, flags);
22499
- if (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR ||
22500
- notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) {
22501
- // Return the value from the root element injector when
22502
- // - it provides it
22503
- // (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
22504
- // - the module injector should not be checked
22505
- // (notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
22506
- return value;
22507
- }
22508
- return this.parentInjector.get(token, notFoundValue, flags);
22298
+ const context = getLContext(node);
22299
+ const lView = context ? context.lView : null;
22300
+ if (lView === null) {
22301
+ return [];
22302
+ }
22303
+ const tView = lView[TVIEW];
22304
+ const nodeIndex = context.nodeIndex;
22305
+ if (!tView?.data[nodeIndex]) {
22306
+ return [];
22307
+ }
22308
+ if (context.directives === undefined) {
22309
+ context.directives = getDirectivesAtNodeIndex(nodeIndex, lView, false);
22509
22310
  }
22311
+ // The `directives` in this case are a named array called `LComponentView`. Clone the
22312
+ // result so we don't expose an internal data structure in the user's console.
22313
+ return context.directives === null ? [] : [...context.directives];
22510
22314
  }
22511
22315
  /**
22512
- * Render3 implementation of {@link viewEngine_ComponentFactory}.
22316
+ * Returns the debug (partial) metadata for a particular directive or component instance.
22317
+ * The function accepts an instance of a directive or component and returns the corresponding
22318
+ * metadata.
22319
+ *
22320
+ * @param directiveOrComponentInstance Instance of a directive or component
22321
+ * @returns metadata of the passed directive or component
22322
+ *
22323
+ * @publicApi
22324
+ * @globalApi ng
22513
22325
  */
22514
- class ComponentFactory extends ComponentFactory$1 {
22515
- /**
22516
- * @param componentDef The component definition.
22517
- * @param ngModule The NgModuleRef to which the factory is bound.
22518
- */
22519
- constructor(componentDef, ngModule) {
22520
- super();
22521
- this.componentDef = componentDef;
22522
- this.ngModule = ngModule;
22523
- this.componentType = componentDef.type;
22524
- this.selector = stringifyCSSSelectorList(componentDef.selectors);
22525
- this.ngContentSelectors =
22526
- componentDef.ngContentSelectors ? componentDef.ngContentSelectors : [];
22527
- this.isBoundToModule = !!ngModule;
22528
- }
22529
- get inputs() {
22530
- return toRefArray(this.componentDef.inputs);
22326
+ function getDirectiveMetadata(directiveOrComponentInstance) {
22327
+ const { constructor } = directiveOrComponentInstance;
22328
+ if (!constructor) {
22329
+ throw new Error('Unable to find the instance constructor');
22531
22330
  }
22532
- get outputs() {
22533
- return toRefArray(this.componentDef.outputs);
22331
+ // In case a component inherits from a directive, we may have component and directive metadata
22332
+ // To ensure we don't get the metadata of the directive, we want to call `getComponentDef` first.
22333
+ const componentDef = getComponentDef$1(constructor);
22334
+ if (componentDef) {
22335
+ return {
22336
+ inputs: componentDef.inputs,
22337
+ outputs: componentDef.outputs,
22338
+ encapsulation: componentDef.encapsulation,
22339
+ changeDetection: componentDef.onPush ? ChangeDetectionStrategy.OnPush :
22340
+ ChangeDetectionStrategy.Default
22341
+ };
22534
22342
  }
22535
- create(injector, projectableNodes, rootSelectorOrNode, environmentInjector) {
22536
- environmentInjector = environmentInjector || this.ngModule;
22537
- let realEnvironmentInjector = environmentInjector instanceof EnvironmentInjector ?
22538
- environmentInjector :
22539
- environmentInjector?.injector;
22540
- if (realEnvironmentInjector && this.componentDef.getStandaloneInjector !== null) {
22541
- realEnvironmentInjector = this.componentDef.getStandaloneInjector(realEnvironmentInjector) ||
22542
- realEnvironmentInjector;
22543
- }
22544
- const rootViewInjector = realEnvironmentInjector ? new ChainedInjector(injector, realEnvironmentInjector) : injector;
22545
- const rendererFactory = rootViewInjector.get(RendererFactory2, domRendererFactory3);
22546
- const sanitizer = rootViewInjector.get(Sanitizer, null);
22547
- const hostRenderer = rendererFactory.createRenderer(null, this.componentDef);
22548
- // Determine a tag name used for creating host elements when this component is created
22549
- // dynamically. Default to 'div' if this component did not specify any tag name in its selector.
22550
- const elementName = this.componentDef.selectors[0][0] || 'div';
22551
- const hostRNode = rootSelectorOrNode ?
22552
- locateHostElement(hostRenderer, rootSelectorOrNode, this.componentDef.encapsulation) :
22553
- createElementNode(rendererFactory.createRenderer(null, this.componentDef), elementName, getNamespace(elementName));
22554
- const rootFlags = this.componentDef.onPush ? 32 /* LViewFlags.Dirty */ | 256 /* LViewFlags.IsRoot */ :
22555
- 16 /* LViewFlags.CheckAlways */ | 256 /* LViewFlags.IsRoot */;
22556
- const rootContext = createRootContext();
22557
- // Create the root view. Uses empty TView and ContentTemplate.
22558
- const rootTView = createTView(0 /* TViewType.Root */, null, null, 1, 0, null, null, null, null, null);
22559
- const rootLView = createLView(null, rootTView, rootContext, rootFlags, null, null, rendererFactory, hostRenderer, sanitizer, rootViewInjector, null);
22560
- // rootView is the parent when bootstrapping
22561
- // TODO(misko): it looks like we are entering view here but we don't really need to as
22562
- // `renderView` does that. However as the code is written it is needed because
22563
- // `createRootComponentView` and `createRootComponent` both read global state. Fixing those
22564
- // issues would allow us to drop this.
22565
- enterView(rootLView);
22566
- let component;
22567
- let tElementNode;
22568
- try {
22569
- const componentView = createRootComponentView(hostRNode, this.componentDef, rootLView, rendererFactory, hostRenderer);
22570
- if (hostRNode) {
22571
- if (rootSelectorOrNode) {
22572
- setUpAttributes(hostRenderer, hostRNode, ['ng-version', VERSION.full]);
22573
- }
22574
- else {
22575
- // If host element is created as a part of this function call (i.e. `rootSelectorOrNode`
22576
- // is not defined), also apply attributes and classes extracted from component selector.
22577
- // Extract attributes and classes from the first selector only to match VE behavior.
22578
- const { attrs, classes } = extractAttrsAndClassesFromSelector(this.componentDef.selectors[0]);
22579
- if (attrs) {
22580
- setUpAttributes(hostRenderer, hostRNode, attrs);
22581
- }
22582
- if (classes && classes.length > 0) {
22583
- writeDirectClass(hostRenderer, hostRNode, classes.join(' '));
22584
- }
22585
- }
22586
- }
22587
- tElementNode = getTNode(rootTView, HEADER_OFFSET);
22588
- if (projectableNodes !== undefined) {
22589
- const projection = tElementNode.projection = [];
22590
- for (let i = 0; i < this.ngContentSelectors.length; i++) {
22591
- const nodesforSlot = projectableNodes[i];
22592
- // Projectable nodes can be passed as array of arrays or an array of iterables (ngUpgrade
22593
- // case). Here we do normalize passed data structure to be an array of arrays to avoid
22594
- // complex checks down the line.
22595
- // We also normalize the length of the passed in projectable nodes (to match the number of
22596
- // <ng-container> slots defined by a component).
22597
- projection.push(nodesforSlot != null ? Array.from(nodesforSlot) : null);
22598
- }
22599
- }
22600
- // TODO: should LifecycleHooksFeature and other host features be generated by the compiler and
22601
- // executed here?
22602
- // Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref
22603
- component = createRootComponent(componentView, this.componentDef, rootLView, rootContext, [LifecycleHooksFeature]);
22604
- renderView(rootTView, rootLView, null);
22605
- }
22606
- finally {
22607
- leaveView();
22608
- }
22609
- return new ComponentRef(this.componentType, component, createElementRef(tElementNode, rootLView), rootLView, tElementNode);
22343
+ const directiveDef = getDirectiveDef(constructor);
22344
+ if (directiveDef) {
22345
+ return { inputs: directiveDef.inputs, outputs: directiveDef.outputs };
22610
22346
  }
22347
+ return null;
22611
22348
  }
22612
- const componentFactoryResolver = new ComponentFactoryResolver();
22613
22349
  /**
22614
- * Creates a ComponentFactoryResolver and stores it on the injector. Or, if the
22615
- * ComponentFactoryResolver
22616
- * already exists, retrieves the existing ComponentFactoryResolver.
22350
+ * Retrieve map of local references.
22617
22351
  *
22618
- * @returns The ComponentFactoryResolver instance to use
22352
+ * The references are retrieved as a map of local reference name to element or directive instance.
22353
+ *
22354
+ * @param target DOM element, component or directive instance for which to retrieve
22355
+ * the local references.
22619
22356
  */
22620
- function injectComponentFactoryResolver() {
22621
- return componentFactoryResolver;
22357
+ function getLocalRefs(target) {
22358
+ const context = getLContext(target);
22359
+ if (context === null)
22360
+ return {};
22361
+ if (context.localRefs === undefined) {
22362
+ const lView = context.lView;
22363
+ if (lView === null) {
22364
+ return {};
22365
+ }
22366
+ context.localRefs = discoverLocalRefs(lView, context.nodeIndex);
22367
+ }
22368
+ return context.localRefs || {};
22622
22369
  }
22623
22370
  /**
22624
- * Represents an instance of a Component created via a {@link ComponentFactory}.
22371
+ * Retrieves the host element of a component or directive instance.
22372
+ * The host element is the DOM element that matched the selector of the directive.
22625
22373
  *
22626
- * `ComponentRef` provides access to the Component Instance as well other objects related to this
22627
- * Component Instance and allows you to destroy the Component Instance via the {@link #destroy}
22628
- * method.
22374
+ * @param componentOrDirective Component or directive instance for which the host
22375
+ * element should be retrieved.
22376
+ * @returns Host element of the target.
22629
22377
  *
22378
+ * @publicApi
22379
+ * @globalApi ng
22630
22380
  */
22631
- class ComponentRef extends ComponentRef$1 {
22632
- constructor(componentType, instance, location, _rootLView, _tNode) {
22633
- super();
22634
- this.location = location;
22635
- this._rootLView = _rootLView;
22636
- this._tNode = _tNode;
22637
- this.instance = instance;
22638
- this.hostView = this.changeDetectorRef = new RootViewRef(_rootLView);
22639
- this.componentType = componentType;
22640
- }
22641
- get injector() {
22642
- return new NodeInjector(this._tNode, this._rootLView);
22643
- }
22644
- destroy() {
22645
- this.hostView.destroy();
22646
- }
22647
- onDestroy(callback) {
22648
- this.hostView.onDestroy(callback);
22649
- }
22381
+ function getHostElement(componentOrDirective) {
22382
+ return getLContext(componentOrDirective).native;
22650
22383
  }
22651
-
22652
22384
  /**
22653
- * @license
22654
- * Copyright Google LLC All Rights Reserved.
22385
+ * Retrieves the rendered text for a given component.
22655
22386
  *
22656
- * Use of this source code is governed by an MIT-style license that can be
22657
- * found in the LICENSE file at https://angular.io/license
22387
+ * This function retrieves the host element of a component and
22388
+ * and then returns the `textContent` for that element. This implies
22389
+ * that the text returned will include re-projected content of
22390
+ * the component as well.
22391
+ *
22392
+ * @param component The component to return the content text for.
22658
22393
  */
22394
+ function getRenderedText(component) {
22395
+ const hostElement = getHostElement(component);
22396
+ return hostElement.textContent || '';
22397
+ }
22659
22398
  /**
22660
- * Returns a new NgModuleRef instance based on the NgModule class and parent injector provided.
22661
- * @param ngModule NgModule class.
22662
- * @param parentInjector Optional injector instance to use as a parent for the module injector. If
22663
- * not provided, `NullInjector` will be used instead.
22399
+ * Retrieves a list of event listeners associated with a DOM element. The list does include host
22400
+ * listeners, but it does not include event listeners defined outside of the Angular context
22401
+ * (e.g. through `addEventListener`).
22402
+ *
22403
+ * @usageNotes
22404
+ * Given the following DOM structure:
22405
+ *
22406
+ * ```html
22407
+ * <app-root>
22408
+ * <div (click)="doSomething()"></div>
22409
+ * </app-root>
22410
+ * ```
22411
+ *
22412
+ * Calling `getListeners` on `<div>` will return an object that looks as follows:
22413
+ *
22414
+ * ```ts
22415
+ * {
22416
+ * name: 'click',
22417
+ * element: <div>,
22418
+ * callback: () => doSomething(),
22419
+ * useCapture: false
22420
+ * }
22421
+ * ```
22422
+ *
22423
+ * @param element Element for which the DOM listeners should be retrieved.
22424
+ * @returns Array of event listeners on the DOM element.
22425
+ *
22664
22426
  * @publicApi
22427
+ * @globalApi ng
22665
22428
  */
22666
- function createNgModuleRef(ngModule, parentInjector) {
22667
- return new NgModuleRef(ngModule, parentInjector ?? null);
22668
- }
22669
- class NgModuleRef extends NgModuleRef$1 {
22670
- constructor(ngModuleType, _parent) {
22671
- super();
22672
- this._parent = _parent;
22673
- // tslint:disable-next-line:require-internal-with-underscore
22674
- this._bootstrapComponents = [];
22675
- this.injector = this;
22676
- this.destroyCbs = [];
22677
- // When bootstrapping a module we have a dependency graph that looks like this:
22678
- // ApplicationRef -> ComponentFactoryResolver -> NgModuleRef. The problem is that if the
22679
- // module being resolved tries to inject the ComponentFactoryResolver, it'll create a
22680
- // circular dependency which will result in a runtime error, because the injector doesn't
22681
- // exist yet. We work around the issue by creating the ComponentFactoryResolver ourselves
22682
- // and providing it, rather than letting the injector resolve it.
22683
- this.componentFactoryResolver = new ComponentFactoryResolver(this);
22684
- const ngModuleDef = getNgModuleDef(ngModuleType);
22685
- ngDevMode &&
22686
- assertDefined(ngModuleDef, `NgModule '${stringify(ngModuleType)}' is not a subtype of 'NgModuleType'.`);
22687
- this._bootstrapComponents = maybeUnwrapFn$1(ngModuleDef.bootstrap);
22688
- this._r3Injector = createInjectorWithoutInjectorInstances(ngModuleType, _parent, [
22689
- { provide: NgModuleRef$1, useValue: this }, {
22690
- provide: ComponentFactoryResolver$1,
22691
- useValue: this.componentFactoryResolver
22429
+ function getListeners(element) {
22430
+ ngDevMode && assertDomElement(element);
22431
+ const lContext = getLContext(element);
22432
+ const lView = lContext === null ? null : lContext.lView;
22433
+ if (lView === null)
22434
+ return [];
22435
+ const tView = lView[TVIEW];
22436
+ const lCleanup = lView[CLEANUP];
22437
+ const tCleanup = tView.cleanup;
22438
+ const listeners = [];
22439
+ if (tCleanup && lCleanup) {
22440
+ for (let i = 0; i < tCleanup.length;) {
22441
+ const firstParam = tCleanup[i++];
22442
+ const secondParam = tCleanup[i++];
22443
+ if (typeof firstParam === 'string') {
22444
+ const name = firstParam;
22445
+ const listenerElement = unwrapRNode(lView[secondParam]);
22446
+ const callback = lCleanup[tCleanup[i++]];
22447
+ const useCaptureOrIndx = tCleanup[i++];
22448
+ // if useCaptureOrIndx is boolean then report it as is.
22449
+ // if useCaptureOrIndx is positive number then it in unsubscribe method
22450
+ // if useCaptureOrIndx is negative number then it is a Subscription
22451
+ const type = (typeof useCaptureOrIndx === 'boolean' || useCaptureOrIndx >= 0) ? 'dom' : 'output';
22452
+ const useCapture = typeof useCaptureOrIndx === 'boolean' ? useCaptureOrIndx : false;
22453
+ if (element == listenerElement) {
22454
+ listeners.push({ element, name, callback, useCapture, type });
22455
+ }
22692
22456
  }
22693
- ], stringify(ngModuleType), new Set(['environment']));
22694
- // We need to resolve the injector types separately from the injector creation, because
22695
- // the module might be trying to use this ref in its constructor for DI which will cause a
22696
- // circular error that will eventually error out, because the injector isn't created yet.
22697
- this._r3Injector.resolveInjectorInitializers();
22698
- this.instance = this.get(ngModuleType);
22699
- }
22700
- get(token, notFoundValue = Injector.THROW_IF_NOT_FOUND, injectFlags = InjectFlags.Default) {
22701
- if (token === Injector || token === NgModuleRef$1 || token === INJECTOR) {
22702
- return this;
22703
22457
  }
22704
- return this._r3Injector.get(token, notFoundValue, injectFlags);
22705
- }
22706
- destroy() {
22707
- ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
22708
- const injector = this._r3Injector;
22709
- !injector.destroyed && injector.destroy();
22710
- this.destroyCbs.forEach(fn => fn());
22711
- this.destroyCbs = null;
22712
- }
22713
- onDestroy(callback) {
22714
- ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
22715
- this.destroyCbs.push(callback);
22716
- }
22717
- }
22718
- class NgModuleFactory extends NgModuleFactory$1 {
22719
- constructor(moduleType) {
22720
- super();
22721
- this.moduleType = moduleType;
22722
- }
22723
- create(parentInjector) {
22724
- return new NgModuleRef(this.moduleType, parentInjector);
22725
22458
  }
22459
+ listeners.sort(sortListeners);
22460
+ return listeners;
22726
22461
  }
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);
22745
- }
22462
+ function sortListeners(a, b) {
22463
+ if (a.name == b.name)
22464
+ return 0;
22465
+ return a.name < b.name ? -1 : 1;
22746
22466
  }
22747
22467
  /**
22748
- * Create a new environment injector.
22468
+ * This function should not exist because it is megamorphic and only mostly correct.
22749
22469
  *
22750
- * @publicApi
22751
- * @developerPreview
22470
+ * See call site for more info.
22752
22471
  */
22753
- function createEnvironmentInjector(providers, parent = null, debugName = null) {
22754
- const adapter = new EnvironmentNgModuleRefAdapter(providers, parent, debugName);
22755
- return adapter.injector;
22472
+ function isDirectiveDefHack(obj) {
22473
+ return obj.type !== undefined && obj.template !== undefined && obj.declaredInputs !== undefined;
22756
22474
  }
22757
-
22758
22475
  /**
22759
- * @license
22760
- * Copyright Google LLC All Rights Reserved.
22476
+ * Returns the attached `DebugNode` instance for an element in the DOM.
22761
22477
  *
22762
- * Use of this source code is governed by an MIT-style license that can be
22763
- * found in the LICENSE file at https://angular.io/license
22764
- */
22765
- /**
22766
- * A service used by the framework to create instances of standalone injectors. Those injectors are
22767
- * created on demand in case of dynamic component instantiation and contain ambient providers
22768
- * collected from the imports graph rooted at a given standalone component.
22478
+ * @param element DOM element which is owned by an existing component's view.
22769
22479
  */
22770
- class StandaloneService {
22771
- constructor(_injector) {
22772
- this._injector = _injector;
22773
- this.cachedInjectors = new Map();
22480
+ function getDebugNode(element) {
22481
+ if (ngDevMode && !(element instanceof Node)) {
22482
+ throw new Error('Expecting instance of DOM Element');
22774
22483
  }
22775
- getOrCreateStandaloneInjector(componentDef) {
22776
- if (!componentDef.standalone) {
22777
- return null;
22778
- }
22779
- if (!this.cachedInjectors.has(componentDef.id)) {
22780
- const providers = internalImportProvidersFrom(false, componentDef.type);
22781
- const standaloneInjector = providers.length > 0 ?
22782
- createEnvironmentInjector([providers], this._injector, `Standalone[${componentDef.type.name}]`) :
22783
- null;
22784
- this.cachedInjectors.set(componentDef.id, standaloneInjector);
22785
- }
22786
- return this.cachedInjectors.get(componentDef.id);
22484
+ const lContext = getLContext(element);
22485
+ const lView = lContext ? lContext.lView : null;
22486
+ if (lView === null) {
22487
+ return null;
22787
22488
  }
22788
- ngOnDestroy() {
22789
- try {
22790
- for (const injector of this.cachedInjectors.values()) {
22791
- if (injector !== null) {
22792
- injector.destroy();
22793
- }
22794
- }
22795
- }
22796
- finally {
22797
- this.cachedInjectors.clear();
22798
- }
22489
+ const nodeIndex = lContext.nodeIndex;
22490
+ if (nodeIndex !== -1) {
22491
+ const valueInLView = lView[nodeIndex];
22492
+ // this means that value in the lView is a component with its own
22493
+ // data. In this situation the TNode is not accessed at the same spot.
22494
+ const tNode = isLView(valueInLView) ? valueInLView[T_HOST] : getTNode(lView[TVIEW], nodeIndex);
22495
+ ngDevMode &&
22496
+ assertEqual(tNode.index, nodeIndex, 'Expecting that TNode at index is same as index');
22497
+ return buildDebugNode(tNode, lView);
22799
22498
  }
22499
+ return null;
22800
22500
  }
22801
- /** @nocollapse */
22802
- StandaloneService.ɵprov = ɵɵdefineInjectable({
22803
- token: StandaloneService,
22804
- providedIn: 'environment',
22805
- factory: () => new StandaloneService(ɵɵinject(EnvironmentInjector)),
22806
- });
22807
22501
  /**
22808
- * A feature that acts as a setup code for the {@link StandaloneService}.
22502
+ * Retrieve the component `LView` from component/element.
22809
22503
  *
22810
- * The most important responsaibility of this feature is to expose the "getStandaloneInjector"
22811
- * function (an entry points to a standalone injector creation) on a component definition object. We
22812
- * go through the features infrastructure to make sure that the standalone injector creation logic
22813
- * is tree-shakable and not included in applications that don't use standalone components.
22504
+ * NOTE: `LView` is a private and should not be leaked outside.
22505
+ * Don't export this method to `ng.*` on window.
22814
22506
  *
22815
- * @codeGenApi
22507
+ * @param target DOM element or component instance for which to retrieve the LView.
22816
22508
  */
22817
- function ɵɵStandaloneFeature(definition) {
22818
- definition.getStandaloneInjector = (parentInjector) => {
22819
- return parentInjector.get(StandaloneService).getOrCreateStandaloneInjector(definition);
22820
- };
22509
+ function getComponentLView(target) {
22510
+ const lContext = getLContext(target);
22511
+ const nodeIndx = lContext.nodeIndex;
22512
+ const lView = lContext.lView;
22513
+ ngDevMode && assertLView(lView);
22514
+ const componentLView = lView[nodeIndx];
22515
+ ngDevMode && assertLView(componentLView);
22516
+ return componentLView;
22517
+ }
22518
+ /** Asserts that a value is a DOM Element. */
22519
+ function assertDomElement(value) {
22520
+ if (typeof Element !== 'undefined' && !(value instanceof Element)) {
22521
+ throw new Error('Expecting instance of DOM Element');
22522
+ }
22821
22523
  }
22822
22524
 
22823
22525
  /**
@@ -24037,7 +23739,7 @@ const unusedValueExportToPlacateAjd = 1;
24037
23739
  * Use of this source code is governed by an MIT-style license that can be
24038
23740
  * found in the LICENSE file at https://angular.io/license
24039
23741
  */
24040
- const unusedValueToPlacateAjd = unusedValueExportToPlacateAjd$1 + unusedValueExportToPlacateAjd$5 + unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd;
23742
+ const unusedValueToPlacateAjd = unusedValueExportToPlacateAjd$1 + unusedValueExportToPlacateAjd$6 + unusedValueExportToPlacateAjd$5 + unusedValueExportToPlacateAjd;
24041
23743
  class LQuery_ {
24042
23744
  constructor(queryList) {
24043
23745
  this.queryList = queryList;
@@ -26894,5 +26596,5 @@ const __core_private_testing_placeholder__ = '';
26894
26596
  * Generated bundle index. Do not edit.
26895
26597
  */
26896
26598
 
26897
- export { ComponentFixture, ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, InjectSetupWrapper, TestBed, TestComponentRenderer, __core_private_testing_placeholder__, async, discardPeriodicTasks, fakeAsync, flush, flushMicrotasks, getTestBed, inject, resetFakeAsyncZone, tick$1 as tick, waitForAsync, withModule, MetadataOverrider as ɵMetadataOverrider };
26599
+ export { ComponentFixture, ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, InjectSetupWrapper, TestBed, TestComponentRenderer, __core_private_testing_placeholder__, async, discardPeriodicTasks, fakeAsync, flush, flushMicrotasks, getTestBed, inject, resetFakeAsyncZone, tick, waitForAsync, withModule, MetadataOverrider as ɵMetadataOverrider };
26898
26600
  //# sourceMappingURL=testing.mjs.map