@angular/core 15.0.0-next.1 → 15.0.0-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/esm2020/src/debug/debug_node.mjs +1 -1
  2. package/esm2020/src/render3/component_ref.mjs +16 -18
  3. package/esm2020/src/render3/context_discovery.mjs +12 -9
  4. package/esm2020/src/render3/definition.mjs +3 -2
  5. package/esm2020/src/render3/di.mjs +3 -3
  6. package/esm2020/src/render3/features/host_directives_feature.mjs +36 -13
  7. package/esm2020/src/render3/i18n/i18n_parse.mjs +3 -6
  8. package/esm2020/src/render3/instructions/element.mjs +1 -1
  9. package/esm2020/src/render3/instructions/element_validation.mjs +2 -2
  10. package/esm2020/src/render3/instructions/listener.mjs +2 -4
  11. package/esm2020/src/render3/instructions/lview_debug.mjs +9 -9
  12. package/esm2020/src/render3/instructions/projection.mjs +1 -1
  13. package/esm2020/src/render3/instructions/shared.mjs +75 -93
  14. package/esm2020/src/render3/instructions/styling.mjs +2 -2
  15. package/esm2020/src/render3/interfaces/definition.mjs +1 -1
  16. package/esm2020/src/render3/interfaces/injector.mjs +1 -1
  17. package/esm2020/src/render3/interfaces/node.mjs +3 -3
  18. package/esm2020/src/render3/interfaces/type_checks.mjs +3 -3
  19. package/esm2020/src/render3/interfaces/view.mjs +1 -1
  20. package/esm2020/src/render3/jit/directive.mjs +7 -2
  21. package/esm2020/src/render3/node_manipulation.mjs +6 -5
  22. package/esm2020/src/render3/node_manipulation_i18n.mjs +2 -2
  23. package/esm2020/src/render3/util/discovery_utils.mjs +2 -2
  24. package/esm2020/src/render3/util/view_traversal_utils.mjs +5 -5
  25. package/esm2020/src/render3/view_ref.mjs +10 -4
  26. package/esm2020/src/sanitization/html_sanitizer.mjs +4 -8
  27. package/esm2020/src/sanitization/url_sanitizer.mjs +1 -5
  28. package/esm2020/src/version.mjs +1 -1
  29. package/esm2020/testing/src/logger.mjs +3 -3
  30. package/esm2020/testing/src/ng_zone_mock.mjs +3 -3
  31. package/fesm2015/core.mjs +178 -174
  32. package/fesm2015/core.mjs.map +1 -1
  33. package/fesm2015/testing.mjs +170 -172
  34. package/fesm2015/testing.mjs.map +1 -1
  35. package/fesm2020/core.mjs +177 -173
  36. package/fesm2020/core.mjs.map +1 -1
  37. package/fesm2020/testing.mjs +170 -171
  38. package/fesm2020/testing.mjs.map +1 -1
  39. package/index.d.ts +44 -32
  40. package/package.json +1 -1
  41. package/testing/index.d.ts +1 -1
package/fesm2020/core.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v15.0.0-next.1
2
+ * @license Angular v15.0.0-next.3
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -931,7 +931,8 @@ function ɵɵdefineComponent(componentDefinition) {
931
931
  setInput: null,
932
932
  schemas: componentDefinition.schemas || null,
933
933
  tView: null,
934
- applyHostDirectives: null,
934
+ findHostDirectiveDefs: null,
935
+ hostDirectives: null,
935
936
  };
936
937
  const dependencies = componentDefinition.dependencies;
937
938
  const feature = componentDefinition.features;
@@ -1272,10 +1273,10 @@ function isLContainer(value) {
1272
1273
  return Array.isArray(value) && value[TYPE] === true;
1273
1274
  }
1274
1275
  function isContentQueryHost(tNode) {
1275
- return (tNode.flags & 8 /* TNodeFlags.hasContentQuery */) !== 0;
1276
+ return (tNode.flags & 4 /* TNodeFlags.hasContentQuery */) !== 0;
1276
1277
  }
1277
1278
  function isComponentHost(tNode) {
1278
- return (tNode.flags & 2 /* TNodeFlags.isComponentHost */) === 2 /* TNodeFlags.isComponentHost */;
1279
+ return tNode.componentOffset > -1;
1279
1280
  }
1280
1281
  function isDirectiveHost(tNode) {
1281
1282
  return (tNode.flags & 1 /* TNodeFlags.isDirectiveHost */) === 1 /* TNodeFlags.isDirectiveHost */;
@@ -2685,7 +2686,7 @@ const unusedValueExportToPlacateAjd$5 = 1;
2685
2686
  * @param tNode
2686
2687
  */
2687
2688
  function hasClassInput(tNode) {
2688
- return (tNode.flags & 16 /* TNodeFlags.hasClassInput */) !== 0;
2689
+ return (tNode.flags & 8 /* TNodeFlags.hasClassInput */) !== 0;
2689
2690
  }
2690
2691
  /**
2691
2692
  * Returns `true` if the `TNode` has a directive which has `@Input()` for `style` binding.
@@ -2709,7 +2710,7 @@ function hasClassInput(tNode) {
2709
2710
  * @param tNode
2710
2711
  */
2711
2712
  function hasStyleInput(tNode) {
2712
- return (tNode.flags & 32 /* TNodeFlags.hasStyleInput */) !== 0;
2713
+ return (tNode.flags & 16 /* TNodeFlags.hasStyleInput */) !== 0;
2713
2714
  }
2714
2715
 
2715
2716
  /**
@@ -3262,7 +3263,7 @@ function injectAttributeImpl(tNode, attrNameToInject) {
3262
3263
  return null;
3263
3264
  }
3264
3265
  function notFoundValueOrThrow(notFoundValue, token, flags) {
3265
- if (flags & InjectFlags.Optional) {
3266
+ if ((flags & InjectFlags.Optional) || notFoundValue !== undefined) {
3266
3267
  return notFoundValue;
3267
3268
  }
3268
3269
  else {
@@ -3279,7 +3280,7 @@ function notFoundValueOrThrow(notFoundValue, token, flags) {
3279
3280
  * @returns the value from the injector or throws an exception
3280
3281
  */
3281
3282
  function lookupTokenUsingModuleInjector(lView, token, flags, notFoundValue) {
3282
- if (flags & InjectFlags.Optional && notFoundValue === undefined) {
3283
+ if ((flags & InjectFlags.Optional) && notFoundValue === undefined) {
3283
3284
  // This must be set or the NullInjector will throw for optional deps
3284
3285
  notFoundValue = null;
3285
3286
  }
@@ -5802,10 +5803,6 @@ function _sanitizeUrl(url) {
5802
5803
  }
5803
5804
  return 'unsafe:' + url;
5804
5805
  }
5805
- function sanitizeSrcset(srcset) {
5806
- srcset = String(srcset);
5807
- return srcset.split(',').map((srcset) => _sanitizeUrl(srcset.trim())).join(', ');
5808
- }
5809
5806
 
5810
5807
  /**
5811
5808
  * @license
@@ -5852,12 +5849,10 @@ const INLINE_ELEMENTS = merge(OPTIONAL_END_TAG_INLINE_ELEMENTS, tagSet('a,abbr,a
5852
5849
  const VALID_ELEMENTS = merge(VOID_ELEMENTS, BLOCK_ELEMENTS, INLINE_ELEMENTS, OPTIONAL_END_TAG_ELEMENTS);
5853
5850
  // Attributes that have href and hence need to be sanitized
5854
5851
  const URI_ATTRS = tagSet('background,cite,href,itemtype,longdesc,poster,src,xlink:href');
5855
- // Attributes that have special href set hence need to be sanitized
5856
- const SRCSET_ATTRS = tagSet('srcset');
5857
5852
  const HTML_ATTRS = tagSet('abbr,accesskey,align,alt,autoplay,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,' +
5858
5853
  'compact,controls,coords,datetime,default,dir,download,face,headers,height,hidden,hreflang,hspace,' +
5859
5854
  'ismap,itemscope,itemprop,kind,label,lang,language,loop,media,muted,nohref,nowrap,open,preload,rel,rev,role,rows,rowspan,rules,' +
5860
- 'scope,scrolling,shape,size,sizes,span,srclang,start,summary,tabindex,target,title,translate,type,usemap,' +
5855
+ 'scope,scrolling,shape,size,sizes,span,srclang,srcset,start,summary,tabindex,target,title,translate,type,usemap,' +
5861
5856
  'valign,value,vspace,width');
5862
5857
  // Accessibility attributes as per WAI-ARIA 1.1 (W3C Working Draft 14 December 2018)
5863
5858
  const ARIA_ATTRS = tagSet('aria-activedescendant,aria-atomic,aria-autocomplete,aria-busy,aria-checked,aria-colcount,aria-colindex,' +
@@ -5873,7 +5868,7 @@ const ARIA_ATTRS = tagSet('aria-activedescendant,aria-atomic,aria-autocomplete,a
5873
5868
  // NB: Sanitization does not allow <form> elements or other active elements (<button> etc). Those
5874
5869
  // can be sanitized, but they increase security surface area without a legitimate use case, so they
5875
5870
  // are left out here.
5876
- const VALID_ATTRS = merge(URI_ATTRS, SRCSET_ATTRS, HTML_ATTRS, ARIA_ATTRS);
5871
+ const VALID_ATTRS = merge(URI_ATTRS, HTML_ATTRS, ARIA_ATTRS);
5877
5872
  // Elements whose content should not be traversed/preserved, if the elements themselves are invalid.
5878
5873
  //
5879
5874
  // Typically, `<invalid>Some content</invalid>` would traverse (and in this case preserve)
@@ -5956,8 +5951,6 @@ class SanitizingHtmlSerializer {
5956
5951
  // TODO(martinprobst): Special case image URIs for data:image/...
5957
5952
  if (URI_ATTRS[lower])
5958
5953
  value = _sanitizeUrl(value);
5959
- if (SRCSET_ATTRS[lower])
5960
- value = sanitizeSrcset(value);
5961
5954
  this.buf.push(' ', attrName, '="', encodeEntities(value), '"');
5962
5955
  }
5963
5956
  this.buf.push('>');
@@ -7258,7 +7251,7 @@ class Version {
7258
7251
  /**
7259
7252
  * @publicApi
7260
7253
  */
7261
- const VERSION = new Version('15.0.0-next.1');
7254
+ const VERSION = new Version('15.0.0-next.3');
7262
7255
 
7263
7256
  /**
7264
7257
  * @license
@@ -7561,7 +7554,7 @@ function getTemplateLocationDetails(lView) {
7561
7554
  * that the `CommonModule` should also be included.
7562
7555
  */
7563
7556
  const KNOWN_CONTROL_FLOW_DIRECTIVES = new Map([
7564
- ['ngIf', 'NgIf'], ['ngFor', 'NgForOf'], ['ngSwitchCase', 'NgSwitchCase'],
7557
+ ['ngIf', 'NgIf'], ['ngFor', 'NgFor'], ['ngSwitchCase', 'NgSwitchCase'],
7565
7558
  ['ngSwitchDefault', 'NgSwitchDefault']
7566
7559
  ]);
7567
7560
  /**
@@ -8077,18 +8070,21 @@ function findViaDirective(lView, directiveInstance) {
8077
8070
  */
8078
8071
  function getDirectivesAtNodeIndex(nodeIndex, lView, includeComponents) {
8079
8072
  const tNode = lView[TVIEW].data[nodeIndex];
8080
- let directiveStartIndex = tNode.directiveStart;
8081
- if (directiveStartIndex == 0)
8073
+ if (tNode.directiveStart === 0)
8082
8074
  return EMPTY_ARRAY;
8083
- const directiveEndIndex = tNode.directiveEnd;
8084
- if (!includeComponents && tNode.flags & 2 /* TNodeFlags.isComponentHost */)
8085
- directiveStartIndex++;
8086
- return lView.slice(directiveStartIndex, directiveEndIndex);
8075
+ const results = [];
8076
+ for (let i = tNode.directiveStart; i < tNode.directiveEnd; i++) {
8077
+ const directiveInstance = lView[i];
8078
+ if (!isComponentInstance(directiveInstance) || includeComponents) {
8079
+ results.push(directiveInstance);
8080
+ }
8081
+ }
8082
+ return results;
8087
8083
  }
8088
8084
  function getComponentAtNodeIndex(nodeIndex, lView) {
8089
8085
  const tNode = lView[TVIEW].data[nodeIndex];
8090
- let directiveStartIndex = tNode.directiveStart;
8091
- return tNode.flags & 2 /* TNodeFlags.isComponentHost */ ? lView[directiveStartIndex] : null;
8086
+ const { directiveStart, componentOffset } = tNode;
8087
+ return componentOffset > -1 ? lView[directiveStart + componentOffset] : null;
8092
8088
  }
8093
8089
  /**
8094
8090
  * Returns a map of local references (local reference name => element or directive instance) that
@@ -8365,16 +8361,16 @@ function getRootView(componentOrLView) {
8365
8361
  return lView;
8366
8362
  }
8367
8363
  /**
8368
- * Returns the `RootContext` instance that is associated with
8369
- * the application where the target is situated. It does this by walking the parent views until it
8370
- * gets to the root view, then getting the context off of that.
8364
+ * Returns the context information associated with the application where the target is situated. It
8365
+ * does this by walking the parent views until it gets to the root view, then getting the context
8366
+ * off of that.
8371
8367
  *
8372
8368
  * @param viewOrComponent the `LView` or component to get the root context for.
8373
8369
  */
8374
8370
  function getRootContext(viewOrComponent) {
8375
8371
  const rootView = getRootView(viewOrComponent);
8376
8372
  ngDevMode &&
8377
- assertDefined(rootView[CONTEXT], 'RootView has no context. Perhaps it is disconnected?');
8373
+ assertDefined(rootView[CONTEXT], 'Root view has no context. Perhaps it is disconnected?');
8378
8374
  return rootView[CONTEXT];
8379
8375
  }
8380
8376
  /**
@@ -8891,9 +8887,10 @@ function getClosestRElement(tView, tNode, lView) {
8891
8887
  }
8892
8888
  else {
8893
8889
  ngDevMode && assertTNodeType(parentTNode, 3 /* TNodeType.AnyRNode */ | 4 /* TNodeType.Container */);
8894
- if (parentTNode.flags & 2 /* TNodeFlags.isComponentHost */) {
8890
+ const { componentOffset } = parentTNode;
8891
+ if (componentOffset > -1) {
8895
8892
  ngDevMode && assertTNodeForLView(parentTNode, lView);
8896
- const encapsulation = tView.data[parentTNode.directiveStart].encapsulation;
8893
+ const { encapsulation } = tView.data[parentTNode.directiveStart + componentOffset];
8897
8894
  // We've got a parent which is an element in the current view. We just need to verify if the
8898
8895
  // parent element is not a component. Component's content nodes are not inserted immediately
8899
8896
  // because they will be projected, and so doing insert at this point would be wasteful.
@@ -9126,10 +9123,10 @@ function applyNodes(renderer, action, tNode, lView, parentRElement, beforeNode,
9126
9123
  if (isProjection) {
9127
9124
  if (action === 0 /* WalkTNodeTreeAction.Create */) {
9128
9125
  rawSlotValue && attachPatchData(unwrapRNode(rawSlotValue), lView);
9129
- tNode.flags |= 4 /* TNodeFlags.isProjected */;
9126
+ tNode.flags |= 2 /* TNodeFlags.isProjected */;
9130
9127
  }
9131
9128
  }
9132
- if ((tNode.flags & 64 /* TNodeFlags.isDetached */) !== 64 /* TNodeFlags.isDetached */) {
9129
+ if ((tNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
9133
9130
  if (tNodeType & 8 /* TNodeType.ElementContainer */) {
9134
9131
  applyNodes(renderer, action, tNode.child, lView, parentRElement, beforeNode, false);
9135
9132
  applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
@@ -11183,6 +11180,7 @@ class TNode {
11183
11180
  index, //
11184
11181
  insertBeforeIndex, //
11185
11182
  injectorIndex, //
11183
+ componentOffset, //
11186
11184
  directiveStart, //
11187
11185
  directiveEnd, //
11188
11186
  directiveStylingLast, //
@@ -11215,6 +11213,7 @@ class TNode {
11215
11213
  this.index = index;
11216
11214
  this.insertBeforeIndex = insertBeforeIndex;
11217
11215
  this.injectorIndex = injectorIndex;
11216
+ this.componentOffset = componentOffset;
11218
11217
  this.directiveStart = directiveStart;
11219
11218
  this.directiveEnd = directiveEnd;
11220
11219
  this.directiveStylingLast = directiveStylingLast;
@@ -11292,21 +11291,19 @@ class TNode {
11292
11291
  }
11293
11292
  get flags_() {
11294
11293
  const flags = [];
11295
- if (this.flags & 16 /* TNodeFlags.hasClassInput */)
11294
+ if (this.flags & 8 /* TNodeFlags.hasClassInput */)
11296
11295
  flags.push('TNodeFlags.hasClassInput');
11297
- if (this.flags & 8 /* TNodeFlags.hasContentQuery */)
11296
+ if (this.flags & 4 /* TNodeFlags.hasContentQuery */)
11298
11297
  flags.push('TNodeFlags.hasContentQuery');
11299
- if (this.flags & 32 /* TNodeFlags.hasStyleInput */)
11298
+ if (this.flags & 16 /* TNodeFlags.hasStyleInput */)
11300
11299
  flags.push('TNodeFlags.hasStyleInput');
11301
- if (this.flags & 128 /* TNodeFlags.hasHostBindings */)
11300
+ if (this.flags & 64 /* TNodeFlags.hasHostBindings */)
11302
11301
  flags.push('TNodeFlags.hasHostBindings');
11303
- if (this.flags & 2 /* TNodeFlags.isComponentHost */)
11304
- flags.push('TNodeFlags.isComponentHost');
11305
11302
  if (this.flags & 1 /* TNodeFlags.isDirectiveHost */)
11306
11303
  flags.push('TNodeFlags.isDirectiveHost');
11307
- if (this.flags & 64 /* TNodeFlags.isDetached */)
11304
+ if (this.flags & 32 /* TNodeFlags.isDetached */)
11308
11305
  flags.push('TNodeFlags.isDetached');
11309
- if (this.flags & 4 /* TNodeFlags.isProjected */)
11306
+ if (this.flags & 2 /* TNodeFlags.isProjected */)
11310
11307
  flags.push('TNodeFlags.isProjected');
11311
11308
  return flags.join('|');
11312
11309
  }
@@ -11816,7 +11813,7 @@ function getOrCreateTNode(tView, index, type, name, attrs) {
11816
11813
  // See `TNodeType.Placeholder` and `LFrame.inI18n` for more context.
11817
11814
  // If the `TNode` was not pre-declared than it means it was not mentioned which means it was
11818
11815
  // removed, so we mark it as detached.
11819
- tNode.flags |= 64 /* TNodeFlags.isDetached */;
11816
+ tNode.flags |= 32 /* TNodeFlags.isDetached */;
11820
11817
  }
11821
11818
  }
11822
11819
  else if (tNode.type & 64 /* TNodeType.Placeholder */) {
@@ -12078,28 +12075,6 @@ function refreshView(tView, lView, templateFn, context) {
12078
12075
  leaveView();
12079
12076
  }
12080
12077
  }
12081
- function renderComponentOrTemplate(tView, lView, templateFn, context) {
12082
- const rendererFactory = lView[RENDERER_FACTORY];
12083
- // Check no changes mode is a dev only mode used to verify that bindings have not changed
12084
- // since they were assigned. We do not want to invoke renderer factory functions in that mode
12085
- // to avoid any possible side-effects.
12086
- const checkNoChangesMode = !!ngDevMode && isInCheckNoChangesMode();
12087
- const creationModeIsActive = isCreationMode(lView);
12088
- try {
12089
- if (!checkNoChangesMode && !creationModeIsActive && rendererFactory.begin) {
12090
- rendererFactory.begin();
12091
- }
12092
- if (creationModeIsActive) {
12093
- renderView(tView, lView, context);
12094
- }
12095
- refreshView(tView, lView, templateFn, context);
12096
- }
12097
- finally {
12098
- if (!checkNoChangesMode && !creationModeIsActive && rendererFactory.end) {
12099
- rendererFactory.end();
12100
- }
12101
- }
12102
- }
12103
12078
  function executeTemplate(tView, lView, templateFn, rf, context) {
12104
12079
  const prevSelectedIndex = getSelectedIndex();
12105
12080
  const isUpdatePhase = rf & 2 /* RenderFlags.Update */;
@@ -12142,7 +12117,7 @@ function createDirectivesInstances(tView, lView, tNode) {
12142
12117
  if (!getBindingsEnabled())
12143
12118
  return;
12144
12119
  instantiateAllDirectives(tView, lView, tNode, getNativeByTNode(tNode, lView));
12145
- if ((tNode.flags & 128 /* TNodeFlags.hasHostBindings */) === 128 /* TNodeFlags.hasHostBindings */) {
12120
+ if ((tNode.flags & 64 /* TNodeFlags.hasHostBindings */) === 64 /* TNodeFlags.hasHostBindings */) {
12146
12121
  invokeDirectivesHostBindings(tView, lView, tNode);
12147
12122
  }
12148
12123
  }
@@ -12170,7 +12145,7 @@ function saveResolvedLocalsInData(viewData, tNode, localRefExtractor = getNative
12170
12145
  * @param def ComponentDef
12171
12146
  * @returns TView
12172
12147
  */
12173
- function getOrCreateTComponentView(def) {
12148
+ function getOrCreateComponentTView(def) {
12174
12149
  const tView = def.tView;
12175
12150
  // Create a TView if there isn't one, or recreate it if the first create pass didn't
12176
12151
  // complete successfully since we can't know for sure whether it's in a usable shape.
@@ -12342,6 +12317,7 @@ function createTNode(tView, tParent, type, index, value, attrs) {
12342
12317
  index, // index: number
12343
12318
  null, // insertBeforeIndex: null|-1|number|number[]
12344
12319
  injectorIndex, // injectorIndex: number
12320
+ -1, // componentOffset: number
12345
12321
  -1, // directiveStart: number
12346
12322
  -1, // directiveEnd: number
12347
12323
  -1, // directiveStylingLast: number
@@ -12377,6 +12353,7 @@ function createTNode(tView, tParent, type, index, value, attrs) {
12377
12353
  directiveStart: -1,
12378
12354
  directiveEnd: -1,
12379
12355
  directiveStylingLast: -1,
12356
+ componentOffset: -1,
12380
12357
  propertyBindings: null,
12381
12358
  flags: 0,
12382
12359
  providerIndexes: 0,
@@ -12440,24 +12417,23 @@ function initializeInputAndOutputAliases(tView, tNode) {
12440
12417
  let outputsStore = null;
12441
12418
  for (let i = start; i < end; i++) {
12442
12419
  const directiveDef = tViewData[i];
12443
- const directiveInputs = directiveDef.inputs;
12420
+ inputsStore = generatePropertyAliases(directiveDef.inputs, i, inputsStore);
12421
+ outputsStore = generatePropertyAliases(directiveDef.outputs, i, outputsStore);
12444
12422
  // Do not use unbound attributes as inputs to structural directives, since structural
12445
12423
  // directive inputs can only be set using microsyntax (e.g. `<div *dir="exp">`).
12446
12424
  // TODO(FW-1930): microsyntax expressions may also contain unbound/static attributes, which
12447
12425
  // should be set for inline templates.
12448
- const initialInputs = (tNodeAttrs !== null && !isInlineTemplate(tNode)) ?
12449
- generateInitialInputs(directiveInputs, tNodeAttrs) :
12426
+ const initialInputs = (inputsStore !== null && tNodeAttrs !== null && !isInlineTemplate(tNode)) ?
12427
+ generateInitialInputs(inputsStore, i, tNodeAttrs) :
12450
12428
  null;
12451
12429
  inputsFromAttrs.push(initialInputs);
12452
- inputsStore = generatePropertyAliases(directiveInputs, i, inputsStore);
12453
- outputsStore = generatePropertyAliases(directiveDef.outputs, i, outputsStore);
12454
12430
  }
12455
12431
  if (inputsStore !== null) {
12456
12432
  if (inputsStore.hasOwnProperty('class')) {
12457
- tNode.flags |= 16 /* TNodeFlags.hasClassInput */;
12433
+ tNode.flags |= 8 /* TNodeFlags.hasClassInput */;
12458
12434
  }
12459
12435
  if (inputsStore.hasOwnProperty('style')) {
12460
- tNode.flags |= 32 /* TNodeFlags.hasStyleInput */;
12436
+ tNode.flags |= 16 /* TNodeFlags.hasStyleInput */;
12461
12437
  }
12462
12438
  }
12463
12439
  tNode.initialInputs = inputsFromAttrs;
@@ -12578,7 +12554,7 @@ function instantiateRootComponent(tView, lView, def) {
12578
12554
  configureViewWithDirective(tView, rootTNode, lView, directiveIndex, def);
12579
12555
  initializeInputAndOutputAliases(tView, rootTNode);
12580
12556
  }
12581
- const directive = getNodeInjectable(lView, tView, rootTNode.directiveStart, rootTNode);
12557
+ const directive = getNodeInjectable(lView, tView, rootTNode.directiveStart + rootTNode.componentOffset, rootTNode);
12582
12558
  attachPatchData(directive, lView);
12583
12559
  const native = getNativeByTNode(rootTNode, lView);
12584
12560
  if (native) {
@@ -12595,7 +12571,10 @@ function resolveDirectives(tView, lView, tNode, localRefs) {
12595
12571
  ngDevMode && assertFirstCreatePass(tView);
12596
12572
  let hasDirectives = false;
12597
12573
  if (getBindingsEnabled()) {
12598
- const directiveDefs = findDirectiveDefMatches(tView, lView, tNode);
12574
+ const directiveDefsMatchedBySelectors = findDirectiveDefMatches(tView, lView, tNode);
12575
+ const directiveDefs = directiveDefsMatchedBySelectors ?
12576
+ findHostDirectiveDefs$1(directiveDefsMatchedBySelectors, tView, lView, tNode) :
12577
+ null;
12599
12578
  const exportsMap = localRefs === null ? null : { '': -1 };
12600
12579
  if (directiveDefs !== null) {
12601
12580
  hasDirectives = true;
@@ -12624,9 +12603,9 @@ function resolveDirectives(tView, lView, tNode, localRefs) {
12624
12603
  configureViewWithDirective(tView, tNode, lView, directiveIdx, def);
12625
12604
  saveNameToExportMap(directiveIdx, def, exportsMap);
12626
12605
  if (def.contentQueries !== null)
12627
- tNode.flags |= 8 /* TNodeFlags.hasContentQuery */;
12606
+ tNode.flags |= 4 /* TNodeFlags.hasContentQuery */;
12628
12607
  if (def.hostBindings !== null || def.hostAttrs !== null || def.hostVars !== 0)
12629
- tNode.flags |= 128 /* TNodeFlags.hasHostBindings */;
12608
+ tNode.flags |= 64 /* TNodeFlags.hasHostBindings */;
12630
12609
  const lifeCycleHooks = def.type.prototype;
12631
12610
  // Only push a node index into the preOrderHooks array if this is the first
12632
12611
  // pre-order hook found on this node.
@@ -12779,20 +12758,19 @@ function findDirectiveDefMatches(tView, viewData, tNode) {
12779
12758
  if (ngDevMode) {
12780
12759
  assertTNodeType(tNode, 2 /* TNodeType.Element */, `"${tNode.value}" tags cannot be used as component hosts. ` +
12781
12760
  `Please use a different tag to activate the ${stringify(def.type)} component.`);
12782
- if (tNode.flags & 2 /* TNodeFlags.isComponentHost */) {
12761
+ if (isComponentHost(tNode)) {
12783
12762
  // If another component has been matched previously, it's the first element in the
12784
12763
  // `matches` array, see how we store components/directives in `matches` below.
12785
12764
  throwMultipleComponentError(tNode, matches[0].type, def.type);
12786
12765
  }
12787
12766
  }
12788
- markAsComponentHost(tView, tNode);
12767
+ markAsComponentHost(tView, tNode, 0);
12789
12768
  // The component is always stored first with directives after.
12790
12769
  matches.unshift(def);
12791
12770
  }
12792
12771
  else {
12793
12772
  matches.push(def);
12794
12773
  }
12795
- def.applyHostDirectives?.(tView, viewData, tNode, matches);
12796
12774
  }
12797
12775
  }
12798
12776
  }
@@ -12800,15 +12778,36 @@ function findDirectiveDefMatches(tView, viewData, tNode) {
12800
12778
  }
12801
12779
  /**
12802
12780
  * Marks a given TNode as a component's host. This consists of:
12803
- * - setting appropriate TNode flags;
12781
+ * - setting the component offset on the TNode.
12804
12782
  * - storing index of component's host element so it will be queued for view refresh during CD.
12805
12783
  */
12806
- function markAsComponentHost(tView, hostTNode) {
12784
+ function markAsComponentHost(tView, hostTNode, componentOffset) {
12807
12785
  ngDevMode && assertFirstCreatePass(tView);
12808
- hostTNode.flags |= 2 /* TNodeFlags.isComponentHost */;
12786
+ ngDevMode && assertGreaterThan(componentOffset, -1, 'componentOffset must be great than -1');
12787
+ hostTNode.componentOffset = componentOffset;
12809
12788
  (tView.components || (tView.components = ngDevMode ? new TViewComponents() : []))
12810
12789
  .push(hostTNode.index);
12811
12790
  }
12791
+ /**
12792
+ * Given an array of directives that were matched by their selectors, this function
12793
+ * produces a new array that also includes any host directives that have to be applied.
12794
+ * @param selectorMatches Directives matched in a template based on their selectors.
12795
+ * @param tView Current TView.
12796
+ * @param lView Current LView.
12797
+ * @param tNode Current TNode that is being matched.
12798
+ */
12799
+ function findHostDirectiveDefs$1(selectorMatches, tView, lView, tNode) {
12800
+ const matches = [];
12801
+ for (const def of selectorMatches) {
12802
+ if (def.findHostDirectiveDefs === null) {
12803
+ matches.push(def);
12804
+ }
12805
+ else {
12806
+ def.findHostDirectiveDefs(matches, def, tView, lView, tNode);
12807
+ }
12808
+ }
12809
+ return matches;
12810
+ }
12812
12811
  /** Caches local names and their matching directive indices for query and template lookups. */
12813
12812
  function cacheMatchingLocalNames(tNode, localRefs, exportsMap) {
12814
12813
  if (localRefs) {
@@ -12880,7 +12879,7 @@ function configureViewWithDirective(tView, tNode, lView, directiveIndex, def) {
12880
12879
  }
12881
12880
  function addComponentLogic(lView, hostTNode, def) {
12882
12881
  const native = getNativeByTNode(hostTNode, lView);
12883
- const tView = getOrCreateTComponentView(def);
12882
+ const tView = getOrCreateComponentTView(def);
12884
12883
  // Only component views should be added to the view tree directly. Embedded views are
12885
12884
  // accessed through their containers because they may be removed / re-added later.
12886
12885
  const rendererFactory = lView[RENDERER_FACTORY];
@@ -12951,10 +12950,11 @@ function setInputsFromAttrs(lView, directiveIndex, instance, def, tNode, initial
12951
12950
  *
12952
12951
  * <my-component name="Bess"></my-component>
12953
12952
  *
12954
- * @param inputs The list of inputs from the directive def
12955
- * @param attrs The static attrs on this node
12953
+ * @param inputs Input alias map that was generated from the directive def inputs.
12954
+ * @param directiveIndex Index of the directive that is currently being processed.
12955
+ * @param attrs Static attrs on this node.
12956
12956
  */
12957
- function generateInitialInputs(inputs, attrs) {
12957
+ function generateInitialInputs(inputs, directiveIndex, attrs) {
12958
12958
  let inputsToStore = null;
12959
12959
  let i = 0;
12960
12960
  while (i < attrs.length) {
@@ -12975,7 +12975,17 @@ function generateInitialInputs(inputs, attrs) {
12975
12975
  if (inputs.hasOwnProperty(attrName)) {
12976
12976
  if (inputsToStore === null)
12977
12977
  inputsToStore = [];
12978
- inputsToStore.push(attrName, inputs[attrName], attrs[i + 1]);
12978
+ // Find the input's public name from the input store. Note that we can be found easier
12979
+ // through the directive def, but we want to do it using the inputs store so that it can
12980
+ // account for host directive aliases.
12981
+ const inputConfig = inputs[attrName];
12982
+ for (let j = 0; j < inputConfig.length; j += 2) {
12983
+ if (inputConfig[j] === directiveIndex) {
12984
+ inputsToStore.push(attrName, inputConfig[j + 1], attrs[i + 1]);
12985
+ // A directive can't have multiple inputs with the same name so we can break here.
12986
+ break;
12987
+ }
12988
+ }
12979
12989
  }
12980
12990
  i += 2;
12981
12991
  }
@@ -13207,63 +13217,32 @@ function markViewDirty(lView) {
13207
13217
  }
13208
13218
  return null;
13209
13219
  }
13210
- function tickRootContext(rootContext) {
13211
- for (let i = 0; i < rootContext.components.length; i++) {
13212
- const rootComponent = rootContext.components[i];
13213
- const lView = readPatchedLView(rootComponent);
13214
- // We might not have an `LView` if the component was destroyed.
13215
- if (lView !== null) {
13216
- const tView = lView[TVIEW];
13217
- renderComponentOrTemplate(tView, lView, tView.template, rootComponent);
13218
- }
13219
- }
13220
- }
13221
- function detectChangesInternal(tView, lView, context) {
13220
+ function detectChangesInternal(tView, lView, context, notifyErrorHandler = true) {
13222
13221
  const rendererFactory = lView[RENDERER_FACTORY];
13223
- if (rendererFactory.begin)
13222
+ // Check no changes mode is a dev only mode used to verify that bindings have not changed
13223
+ // since they were assigned. We do not want to invoke renderer factory functions in that mode
13224
+ // to avoid any possible side-effects.
13225
+ const checkNoChangesMode = !!ngDevMode && isInCheckNoChangesMode();
13226
+ if (!checkNoChangesMode && rendererFactory.begin)
13224
13227
  rendererFactory.begin();
13225
13228
  try {
13226
13229
  refreshView(tView, lView, tView.template, context);
13227
13230
  }
13228
13231
  catch (error) {
13229
- handleError(lView, error);
13232
+ if (notifyErrorHandler) {
13233
+ handleError(lView, error);
13234
+ }
13230
13235
  throw error;
13231
13236
  }
13232
13237
  finally {
13233
- if (rendererFactory.end)
13238
+ if (!checkNoChangesMode && rendererFactory.end)
13234
13239
  rendererFactory.end();
13235
13240
  }
13236
13241
  }
13237
- /**
13238
- * Synchronously perform change detection on a root view and its components.
13239
- *
13240
- * @param lView The view which the change detection should be performed on.
13241
- */
13242
- function detectChangesInRootView(lView) {
13243
- tickRootContext(lView[CONTEXT]);
13244
- }
13245
- function checkNoChangesInternal(tView, view, context) {
13246
- setIsInCheckNoChangesMode(true);
13247
- try {
13248
- detectChangesInternal(tView, view, context);
13249
- }
13250
- finally {
13251
- setIsInCheckNoChangesMode(false);
13252
- }
13253
- }
13254
- /**
13255
- * Checks the change detector on a root view and its components, and throws if any changes are
13256
- * detected.
13257
- *
13258
- * This is used in development mode to verify that running change detection doesn't
13259
- * introduce other changes.
13260
- *
13261
- * @param lView The view which the change detection should be checked on.
13262
- */
13263
- function checkNoChangesInRootView(lView) {
13242
+ function checkNoChangesInternal(tView, lView, context, notifyErrorHandler = true) {
13264
13243
  setIsInCheckNoChangesMode(true);
13265
13244
  try {
13266
- detectChangesInRootView(lView);
13245
+ detectChangesInternal(tView, lView, context, notifyErrorHandler);
13267
13246
  }
13268
13247
  finally {
13269
13248
  setIsInCheckNoChangesMode(false);
@@ -13756,11 +13735,17 @@ class RootViewRef extends ViewRef$1 {
13756
13735
  this._view = _view;
13757
13736
  }
13758
13737
  detectChanges() {
13759
- detectChangesInRootView(this._view);
13738
+ const lView = this._view;
13739
+ const tView = lView[TVIEW];
13740
+ const context = lView[CONTEXT];
13741
+ detectChangesInternal(tView, lView, context, false);
13760
13742
  }
13761
13743
  checkNoChanges() {
13762
13744
  if (ngDevMode) {
13763
- checkNoChangesInRootView(this._view);
13745
+ const lView = this._view;
13746
+ const tView = lView[TVIEW];
13747
+ const context = lView[CONTEXT];
13748
+ checkNoChangesInternal(tView, lView, context, false);
13764
13749
  }
13765
13750
  }
13766
13751
  get context() {
@@ -13827,7 +13812,7 @@ class ChainedInjector {
13827
13812
  }
13828
13813
  }
13829
13814
  /**
13830
- * Render3 implementation of {@link viewEngine_ComponentFactory}.
13815
+ * ComponentFactory interface implementation.
13831
13816
  */
13832
13817
  class ComponentFactory extends ComponentFactory$1 {
13833
13818
  /**
@@ -13877,10 +13862,9 @@ class ComponentFactory extends ComponentFactory$1 {
13877
13862
  createElementNode(rendererFactory.createRenderer(null, this.componentDef), elementName, getNamespace(elementName));
13878
13863
  const rootFlags = this.componentDef.onPush ? 32 /* LViewFlags.Dirty */ | 256 /* LViewFlags.IsRoot */ :
13879
13864
  16 /* LViewFlags.CheckAlways */ | 256 /* LViewFlags.IsRoot */;
13880
- const rootContext = createRootContext();
13881
13865
  // Create the root view. Uses empty TView and ContentTemplate.
13882
13866
  const rootTView = createTView(0 /* TViewType.Root */, null, null, 1, 0, null, null, null, null, null);
13883
- const rootLView = createLView(null, rootTView, rootContext, rootFlags, null, null, rendererFactory, hostRenderer, sanitizer, rootViewInjector, null);
13867
+ const rootLView = createLView(null, rootTView, null, rootFlags, null, null, rendererFactory, hostRenderer, sanitizer, rootViewInjector, null);
13884
13868
  // rootView is the parent when bootstrapping
13885
13869
  // TODO(misko): it looks like we are entering view here but we don't really need to as
13886
13870
  // `renderView` does that. However as the code is written it is needed because
@@ -13924,7 +13908,8 @@ class ComponentFactory extends ComponentFactory$1 {
13924
13908
  // TODO: should LifecycleHooksFeature and other host features be generated by the compiler and
13925
13909
  // executed here?
13926
13910
  // Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref
13927
- component = createRootComponent(componentView, this.componentDef, rootLView, rootContext, [LifecycleHooksFeature]);
13911
+ component =
13912
+ createRootComponent(componentView, this.componentDef, rootLView, [LifecycleHooksFeature]);
13928
13913
  renderView(rootTView, rootLView, null);
13929
13914
  }
13930
13915
  finally {
@@ -14030,10 +14015,10 @@ function createRootComponentView(rNode, def, rootView, rendererFactory, hostRend
14030
14015
  }
14031
14016
  }
14032
14017
  const viewRenderer = rendererFactory.createRenderer(rNode, def);
14033
- const componentView = createLView(rootView, getOrCreateTComponentView(def), null, def.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, rootView[index], tNode, rendererFactory, viewRenderer, sanitizer || null, null, null);
14018
+ const componentView = createLView(rootView, getOrCreateComponentTView(def), null, def.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, rootView[index], tNode, rendererFactory, viewRenderer, sanitizer || null, null, null);
14034
14019
  if (tView.firstCreatePass) {
14035
14020
  diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, rootView), tView, def.type);
14036
- markAsComponentHost(tView, tNode);
14021
+ markAsComponentHost(tView, tNode, 0);
14037
14022
  initTNodeFlags(tNode, rootView.length, 1);
14038
14023
  }
14039
14024
  addToViewTree(rootView, componentView);
@@ -14044,12 +14029,13 @@ function createRootComponentView(rNode, def, rootView, rendererFactory, hostRend
14044
14029
  * Creates a root component and sets it up with features and host bindings.Shared by
14045
14030
  * renderComponent() and ViewContainerRef.createComponent().
14046
14031
  */
14047
- function createRootComponent(componentView, componentDef, rootLView, rootContext, hostFeatures) {
14032
+ function createRootComponent(componentView, componentDef, rootLView, hostFeatures) {
14048
14033
  const tView = rootLView[TVIEW];
14049
14034
  // Create directive instance with factory() and store at next index in viewData
14050
14035
  const component = instantiateRootComponent(tView, rootLView, componentDef);
14051
- rootContext.components.push(component);
14052
- componentView[CONTEXT] = component;
14036
+ // Root view only contains an instance of this component,
14037
+ // so we use a reference to that component instance as a context.
14038
+ componentView[CONTEXT] = rootLView[CONTEXT] = component;
14053
14039
  if (hostFeatures !== null) {
14054
14040
  for (const feature of hostFeatures) {
14055
14041
  feature(component, componentDef);
@@ -14073,9 +14059,6 @@ function createRootComponent(componentView, componentDef, rootLView, rootContext
14073
14059
  }
14074
14060
  return component;
14075
14061
  }
14076
- function createRootContext() {
14077
- return { components: [] };
14078
- }
14079
14062
  /**
14080
14063
  * Used to enable lifecycle hooks on the root component.
14081
14064
  *
@@ -14332,6 +14315,13 @@ function ɵɵCopyDefinitionFeature(definition) {
14332
14315
  }
14333
14316
  }
14334
14317
 
14318
+ /**
14319
+ * @license
14320
+ * Copyright Google LLC All Rights Reserved.
14321
+ *
14322
+ * Use of this source code is governed by an MIT-style license that can be
14323
+ * found in the LICENSE file at https://angular.io/license
14324
+ */
14335
14325
  /**
14336
14326
  * This feature add the host directives behavior to a directive definition by patching a
14337
14327
  * function onto it. The expectation is that the runtime will invoke the function during
@@ -14353,29 +14343,43 @@ function ɵɵCopyDefinitionFeature(definition) {
14353
14343
  * @codeGenApi
14354
14344
  */
14355
14345
  function ɵɵHostDirectivesFeature(rawHostDirectives) {
14356
- const unwrappedHostDirectives = Array.isArray(rawHostDirectives) ? rawHostDirectives : rawHostDirectives();
14357
- const hostDirectives = unwrappedHostDirectives.map(dir => typeof dir === 'function' ? { directive: dir, inputs: EMPTY_OBJ, outputs: EMPTY_OBJ } : {
14358
- directive: dir.directive,
14359
- inputs: bindingArrayToMap(dir.inputs),
14360
- outputs: bindingArrayToMap(dir.outputs)
14361
- });
14362
14346
  return (definition) => {
14363
- // TODO(crisbeto): implement host directive matching logic.
14364
- definition.applyHostDirectives =
14365
- (tView, viewData, tNode, matches) => { };
14347
+ definition.findHostDirectiveDefs = findHostDirectiveDefs;
14348
+ definition.hostDirectives =
14349
+ (Array.isArray(rawHostDirectives) ? rawHostDirectives : rawHostDirectives()).map(dir => {
14350
+ return typeof dir === 'function' ?
14351
+ { directive: resolveForwardRef(dir), inputs: EMPTY_OBJ, outputs: EMPTY_OBJ } :
14352
+ {
14353
+ directive: resolveForwardRef(dir.directive),
14354
+ inputs: bindingArrayToMap(dir.inputs),
14355
+ outputs: bindingArrayToMap(dir.outputs)
14356
+ };
14357
+ });
14366
14358
  };
14367
14359
  }
14360
+ function findHostDirectiveDefs(matches, def, tView, lView, tNode) {
14361
+ if (def.hostDirectives !== null) {
14362
+ for (const hostDirectiveConfig of def.hostDirectives) {
14363
+ const hostDirectiveDef = getDirectiveDef(hostDirectiveConfig.directive);
14364
+ // TODO(crisbeto): assert that the def exists.
14365
+ // Host directives execute before the host so that its host bindings can be overwritten.
14366
+ findHostDirectiveDefs(matches, hostDirectiveDef, tView, lView, tNode);
14367
+ }
14368
+ }
14369
+ // Push the def itself at the end since it needs to execute after the host directives.
14370
+ matches.push(def);
14371
+ }
14368
14372
  /**
14369
14373
  * Converts an array in the form of `['publicName', 'alias', 'otherPublicName', 'otherAlias']` into
14370
14374
  * a map in the form of `{publicName: 'alias', otherPublicName: 'otherAlias'}`.
14371
14375
  */
14372
14376
  function bindingArrayToMap(bindings) {
14373
- if (!bindings || bindings.length === 0) {
14377
+ if (bindings === undefined || bindings.length === 0) {
14374
14378
  return EMPTY_OBJ;
14375
14379
  }
14376
14380
  const result = {};
14377
- for (let i = 1; i < bindings.length; i += 2) {
14378
- result[bindings[i - 1]] = bindings[i];
14381
+ for (let i = 0; i < bindings.length; i += 2) {
14382
+ result[bindings[i]] = bindings[i + 1];
14379
14383
  }
14380
14384
  return result;
14381
14385
  }
@@ -15334,7 +15338,7 @@ function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
15334
15338
  if (styles !== null) {
15335
15339
  writeDirectStyle(renderer, native, styles);
15336
15340
  }
15337
- if ((tNode.flags & 64 /* TNodeFlags.isDetached */) !== 64 /* TNodeFlags.isDetached */) {
15341
+ if ((tNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
15338
15342
  // In the i18n case, the translation may have removed this element, so only add it if it is not
15339
15343
  // detached. See `TNodeType.Placeholder` and `LFrame.inI18n` for more context.
15340
15344
  appendChild(tView, lView, native, tNode);
@@ -15772,9 +15776,7 @@ function wrapListener(tNode, lView, context, listenerFn, wrapWithPreventDefault)
15772
15776
  }
15773
15777
  // In order to be backwards compatible with View Engine, events on component host nodes
15774
15778
  // must also mark the component view itself dirty (i.e. the view that it owns).
15775
- const startView = tNode.flags & 2 /* TNodeFlags.isComponentHost */ ?
15776
- getComponentLViewByIndex(tNode.index, lView) :
15777
- lView;
15779
+ const startView = tNode.componentOffset > -1 ? getComponentLViewByIndex(tNode.index, lView) : lView;
15778
15780
  markViewDirty(startView);
15779
15781
  let result = executeListenerWithErrorHandling(lView, context, listenerFn, e);
15780
15782
  // A just-invoked listener function might have coalesced listeners so we need to check for
@@ -15931,7 +15933,7 @@ function ɵɵprojection(nodeIndex, selectorIndex = 0, attrs) {
15931
15933
  tProjectionNode.projection = selectorIndex;
15932
15934
  // `<ng-content>` has no content
15933
15935
  setCurrentTNodeAsNotParent();
15934
- if ((tProjectionNode.flags & 64 /* TNodeFlags.isDetached */) !== 64 /* TNodeFlags.isDetached */) {
15936
+ if ((tProjectionNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
15935
15937
  // re-distribution of projectable nodes is stored on a component's view level
15936
15938
  applyProjection(tView, lView, tProjectionNode);
15937
15939
  }
@@ -17845,7 +17847,7 @@ function normalizeSuffix(value, suffix) {
17845
17847
  * @param isClassBased `true` if `class` (`false` if `style`)
17846
17848
  */
17847
17849
  function hasStylingInputShadow(tNode, isClassBased) {
17848
- return (tNode.flags & (isClassBased ? 16 /* TNodeFlags.hasClassInput */ : 32 /* TNodeFlags.hasStyleInput */)) !== 0;
17850
+ return (tNode.flags & (isClassBased ? 8 /* TNodeFlags.hasClassInput */ : 16 /* TNodeFlags.hasStyleInput */)) !== 0;
17849
17851
  }
17850
17852
 
17851
17853
  /**
@@ -19537,7 +19539,7 @@ function processI18nInsertBefore(renderer, childTNode, lView, childRNode, parent
19537
19539
  anchorRNode = i18nParent;
19538
19540
  i18nParent = parentRElement;
19539
19541
  }
19540
- if (i18nParent !== null && (childTNode.flags & 2 /* TNodeFlags.isComponentHost */) === 0) {
19542
+ if (i18nParent !== null && childTNode.componentOffset === -1) {
19541
19543
  for (let i = 1; i < tNodeInsertBeforeIndex.length; i++) {
19542
19544
  // No need to `unwrapRNode` because all of the indexes point to i18n text nodes.
19543
19545
  // see `assertDomNode` below.
@@ -20968,9 +20970,6 @@ function walkIcuTree(tView, tIcu, lView, sharedUpdateOpCodes, create, remove, up
20968
20970
  if (URI_ATTRS[lowerAttrName]) {
20969
20971
  generateBindingUpdateOpCodes(update, attr.value, newIndex, attr.name, 0, _sanitizeUrl);
20970
20972
  }
20971
- else if (SRCSET_ATTRS[lowerAttrName]) {
20972
- generateBindingUpdateOpCodes(update, attr.value, newIndex, attr.name, 0, sanitizeSrcset);
20973
- }
20974
20973
  else {
20975
20974
  generateBindingUpdateOpCodes(update, attr.value, newIndex, attr.name, 0, null);
20976
20975
  }
@@ -21939,7 +21938,7 @@ function getOwningComponent(elementOrDir) {
21939
21938
  */
21940
21939
  function getRootComponents(elementOrDir) {
21941
21940
  const lView = readPatchedLView(elementOrDir);
21942
- return lView !== null ? [...getRootContext(lView).components] : [];
21941
+ return lView !== null ? [getRootContext(lView)] : [];
21943
21942
  }
21944
21943
  /**
21945
21944
  * Retrieves an `Injector` associated with an element, component or directive instance.
@@ -25041,7 +25040,12 @@ function directiveMetadata(type, metadata) {
25041
25040
  providers: metadata.providers || null,
25042
25041
  viewQueries: extractQueriesMetadata(type, propMetadata, isViewQuery),
25043
25042
  isStandalone: !!metadata.standalone,
25044
- hostDirectives: null,
25043
+ hostDirectives:
25044
+ // TODO(crisbeto): remove the `as any` usage here and down in the `map` call once
25045
+ // host directives are exposed in the public API.
25046
+ metadata
25047
+ .hostDirectives?.map((directive) => typeof directive === 'function' ? { directive } : directive) ||
25048
+ null
25045
25049
  };
25046
25050
  }
25047
25051
  /**
@@ -28295,7 +28299,7 @@ function _queryNodeChildren(tNode, lView, predicate, matches, elementsOnly, root
28295
28299
  if (rootNativeNode !== nativeNode) {
28296
28300
  // To determine the next node to be processed, we need to use the next or the projectionNext
28297
28301
  // link, depending on whether the current node has been projected.
28298
- const nextTNode = (tNode.flags & 4 /* TNodeFlags.isProjected */) ? tNode.projectionNext : tNode.next;
28302
+ const nextTNode = (tNode.flags & 2 /* TNodeFlags.isProjected */) ? tNode.projectionNext : tNode.next;
28299
28303
  if (nextTNode) {
28300
28304
  _queryNodeChildren(nextTNode, lView, predicate, matches, elementsOnly, rootNativeNode);
28301
28305
  }