@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.
- package/esm2020/src/debug/debug_node.mjs +1 -1
- package/esm2020/src/render3/component_ref.mjs +16 -18
- package/esm2020/src/render3/context_discovery.mjs +12 -9
- package/esm2020/src/render3/definition.mjs +3 -2
- package/esm2020/src/render3/di.mjs +3 -3
- package/esm2020/src/render3/features/host_directives_feature.mjs +36 -13
- package/esm2020/src/render3/i18n/i18n_parse.mjs +3 -6
- package/esm2020/src/render3/instructions/element.mjs +1 -1
- package/esm2020/src/render3/instructions/element_validation.mjs +2 -2
- package/esm2020/src/render3/instructions/listener.mjs +2 -4
- package/esm2020/src/render3/instructions/lview_debug.mjs +9 -9
- package/esm2020/src/render3/instructions/projection.mjs +1 -1
- package/esm2020/src/render3/instructions/shared.mjs +75 -93
- package/esm2020/src/render3/instructions/styling.mjs +2 -2
- package/esm2020/src/render3/interfaces/definition.mjs +1 -1
- package/esm2020/src/render3/interfaces/injector.mjs +1 -1
- package/esm2020/src/render3/interfaces/node.mjs +3 -3
- package/esm2020/src/render3/interfaces/type_checks.mjs +3 -3
- package/esm2020/src/render3/interfaces/view.mjs +1 -1
- package/esm2020/src/render3/jit/directive.mjs +7 -2
- package/esm2020/src/render3/node_manipulation.mjs +6 -5
- package/esm2020/src/render3/node_manipulation_i18n.mjs +2 -2
- package/esm2020/src/render3/util/discovery_utils.mjs +2 -2
- package/esm2020/src/render3/util/view_traversal_utils.mjs +5 -5
- package/esm2020/src/render3/view_ref.mjs +10 -4
- package/esm2020/src/sanitization/html_sanitizer.mjs +4 -8
- package/esm2020/src/sanitization/url_sanitizer.mjs +1 -5
- package/esm2020/src/version.mjs +1 -1
- package/esm2020/testing/src/logger.mjs +3 -3
- package/esm2020/testing/src/ng_zone_mock.mjs +3 -3
- package/fesm2015/core.mjs +178 -174
- package/fesm2015/core.mjs.map +1 -1
- package/fesm2015/testing.mjs +170 -172
- package/fesm2015/testing.mjs.map +1 -1
- package/fesm2020/core.mjs +177 -173
- package/fesm2020/core.mjs.map +1 -1
- package/fesm2020/testing.mjs +170 -171
- package/fesm2020/testing.mjs.map +1 -1
- package/index.d.ts +44 -32
- package/package.json +1 -1
- 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.
|
|
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
|
-
|
|
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 &
|
|
1276
|
+
return (tNode.flags & 4 /* TNodeFlags.hasContentQuery */) !== 0;
|
|
1276
1277
|
}
|
|
1277
1278
|
function isComponentHost(tNode) {
|
|
1278
|
-
return
|
|
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 &
|
|
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 &
|
|
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,
|
|
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.
|
|
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', '
|
|
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
|
-
|
|
8081
|
-
if (directiveStartIndex == 0)
|
|
8073
|
+
if (tNode.directiveStart === 0)
|
|
8082
8074
|
return EMPTY_ARRAY;
|
|
8083
|
-
const
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
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
|
-
|
|
8091
|
-
return
|
|
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
|
|
8369
|
-
*
|
|
8370
|
-
*
|
|
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], '
|
|
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
|
-
|
|
8890
|
+
const { componentOffset } = parentTNode;
|
|
8891
|
+
if (componentOffset > -1) {
|
|
8895
8892
|
ngDevMode && assertTNodeForLView(parentTNode, lView);
|
|
8896
|
-
const encapsulation = tView.data[parentTNode.directiveStart]
|
|
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 |=
|
|
9126
|
+
tNode.flags |= 2 /* TNodeFlags.isProjected */;
|
|
9130
9127
|
}
|
|
9131
9128
|
}
|
|
9132
|
-
if ((tNode.flags &
|
|
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 &
|
|
11294
|
+
if (this.flags & 8 /* TNodeFlags.hasClassInput */)
|
|
11296
11295
|
flags.push('TNodeFlags.hasClassInput');
|
|
11297
|
-
if (this.flags &
|
|
11296
|
+
if (this.flags & 4 /* TNodeFlags.hasContentQuery */)
|
|
11298
11297
|
flags.push('TNodeFlags.hasContentQuery');
|
|
11299
|
-
if (this.flags &
|
|
11298
|
+
if (this.flags & 16 /* TNodeFlags.hasStyleInput */)
|
|
11300
11299
|
flags.push('TNodeFlags.hasStyleInput');
|
|
11301
|
-
if (this.flags &
|
|
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 &
|
|
11304
|
+
if (this.flags & 32 /* TNodeFlags.isDetached */)
|
|
11308
11305
|
flags.push('TNodeFlags.isDetached');
|
|
11309
|
-
if (this.flags &
|
|
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 |=
|
|
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 &
|
|
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
|
|
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
|
-
|
|
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(
|
|
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 |=
|
|
12433
|
+
tNode.flags |= 8 /* TNodeFlags.hasClassInput */;
|
|
12458
12434
|
}
|
|
12459
12435
|
if (inputsStore.hasOwnProperty('style')) {
|
|
12460
|
-
tNode.flags |=
|
|
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
|
|
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 |=
|
|
12606
|
+
tNode.flags |= 4 /* TNodeFlags.hasContentQuery */;
|
|
12628
12607
|
if (def.hostBindings !== null || def.hostAttrs !== null || def.hostVars !== 0)
|
|
12629
|
-
tNode.flags |=
|
|
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
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
|
12955
|
-
* @param
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
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,
|
|
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 =
|
|
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,
|
|
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,
|
|
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
|
-
|
|
14052
|
-
|
|
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
|
-
|
|
14364
|
-
definition.
|
|
14365
|
-
(
|
|
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 (
|
|
14377
|
+
if (bindings === undefined || bindings.length === 0) {
|
|
14374
14378
|
return EMPTY_OBJ;
|
|
14375
14379
|
}
|
|
14376
14380
|
const result = {};
|
|
14377
|
-
for (let i =
|
|
14378
|
-
result[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 &
|
|
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.
|
|
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 &
|
|
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 ?
|
|
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 &&
|
|
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 ? [
|
|
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:
|
|
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 &
|
|
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
|
}
|