@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/testing.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
|
*/
|
|
@@ -2568,7 +2568,8 @@ function ɵɵdefineComponent(componentDefinition) {
|
|
|
2568
2568
|
setInput: null,
|
|
2569
2569
|
schemas: componentDefinition.schemas || null,
|
|
2570
2570
|
tView: null,
|
|
2571
|
-
|
|
2571
|
+
findHostDirectiveDefs: null,
|
|
2572
|
+
hostDirectives: null,
|
|
2572
2573
|
};
|
|
2573
2574
|
const dependencies = componentDefinition.dependencies;
|
|
2574
2575
|
const feature = componentDefinition.features;
|
|
@@ -2909,10 +2910,10 @@ function isLContainer(value) {
|
|
|
2909
2910
|
return Array.isArray(value) && value[TYPE] === true;
|
|
2910
2911
|
}
|
|
2911
2912
|
function isContentQueryHost(tNode) {
|
|
2912
|
-
return (tNode.flags &
|
|
2913
|
+
return (tNode.flags & 4 /* TNodeFlags.hasContentQuery */) !== 0;
|
|
2913
2914
|
}
|
|
2914
2915
|
function isComponentHost(tNode) {
|
|
2915
|
-
return
|
|
2916
|
+
return tNode.componentOffset > -1;
|
|
2916
2917
|
}
|
|
2917
2918
|
function isDirectiveHost(tNode) {
|
|
2918
2919
|
return (tNode.flags & 1 /* TNodeFlags.isDirectiveHost */) === 1 /* TNodeFlags.isDirectiveHost */;
|
|
@@ -4322,7 +4323,7 @@ const unusedValueExportToPlacateAjd$5 = 1;
|
|
|
4322
4323
|
* @param tNode
|
|
4323
4324
|
*/
|
|
4324
4325
|
function hasClassInput(tNode) {
|
|
4325
|
-
return (tNode.flags &
|
|
4326
|
+
return (tNode.flags & 8 /* TNodeFlags.hasClassInput */) !== 0;
|
|
4326
4327
|
}
|
|
4327
4328
|
/**
|
|
4328
4329
|
* Returns `true` if the `TNode` has a directive which has `@Input()` for `style` binding.
|
|
@@ -4346,7 +4347,7 @@ function hasClassInput(tNode) {
|
|
|
4346
4347
|
* @param tNode
|
|
4347
4348
|
*/
|
|
4348
4349
|
function hasStyleInput(tNode) {
|
|
4349
|
-
return (tNode.flags &
|
|
4350
|
+
return (tNode.flags & 16 /* TNodeFlags.hasStyleInput */) !== 0;
|
|
4350
4351
|
}
|
|
4351
4352
|
|
|
4352
4353
|
/**
|
|
@@ -4899,7 +4900,7 @@ function injectAttributeImpl(tNode, attrNameToInject) {
|
|
|
4899
4900
|
return null;
|
|
4900
4901
|
}
|
|
4901
4902
|
function notFoundValueOrThrow(notFoundValue, token, flags) {
|
|
4902
|
-
if (flags & InjectFlags.Optional) {
|
|
4903
|
+
if ((flags & InjectFlags.Optional) || notFoundValue !== undefined) {
|
|
4903
4904
|
return notFoundValue;
|
|
4904
4905
|
}
|
|
4905
4906
|
else {
|
|
@@ -4916,7 +4917,7 @@ function notFoundValueOrThrow(notFoundValue, token, flags) {
|
|
|
4916
4917
|
* @returns the value from the injector or throws an exception
|
|
4917
4918
|
*/
|
|
4918
4919
|
function lookupTokenUsingModuleInjector(lView, token, flags, notFoundValue) {
|
|
4919
|
-
if (flags & InjectFlags.Optional && notFoundValue === undefined) {
|
|
4920
|
+
if ((flags & InjectFlags.Optional) && notFoundValue === undefined) {
|
|
4920
4921
|
// This must be set or the NullInjector will throw for optional deps
|
|
4921
4922
|
notFoundValue = null;
|
|
4922
4923
|
}
|
|
@@ -6102,10 +6103,6 @@ function _sanitizeUrl(url) {
|
|
|
6102
6103
|
}
|
|
6103
6104
|
return 'unsafe:' + url;
|
|
6104
6105
|
}
|
|
6105
|
-
function sanitizeSrcset(srcset) {
|
|
6106
|
-
srcset = String(srcset);
|
|
6107
|
-
return srcset.split(',').map((srcset) => _sanitizeUrl(srcset.trim())).join(', ');
|
|
6108
|
-
}
|
|
6109
6106
|
|
|
6110
6107
|
/**
|
|
6111
6108
|
* @license
|
|
@@ -6152,12 +6149,10 @@ const INLINE_ELEMENTS = merge(OPTIONAL_END_TAG_INLINE_ELEMENTS, tagSet('a,abbr,a
|
|
|
6152
6149
|
const VALID_ELEMENTS = merge(VOID_ELEMENTS, BLOCK_ELEMENTS, INLINE_ELEMENTS, OPTIONAL_END_TAG_ELEMENTS);
|
|
6153
6150
|
// Attributes that have href and hence need to be sanitized
|
|
6154
6151
|
const URI_ATTRS = tagSet('background,cite,href,itemtype,longdesc,poster,src,xlink:href');
|
|
6155
|
-
// Attributes that have special href set hence need to be sanitized
|
|
6156
|
-
const SRCSET_ATTRS = tagSet('srcset');
|
|
6157
6152
|
const HTML_ATTRS = tagSet('abbr,accesskey,align,alt,autoplay,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,' +
|
|
6158
6153
|
'compact,controls,coords,datetime,default,dir,download,face,headers,height,hidden,hreflang,hspace,' +
|
|
6159
6154
|
'ismap,itemscope,itemprop,kind,label,lang,language,loop,media,muted,nohref,nowrap,open,preload,rel,rev,role,rows,rowspan,rules,' +
|
|
6160
|
-
'scope,scrolling,shape,size,sizes,span,srclang,start,summary,tabindex,target,title,translate,type,usemap,' +
|
|
6155
|
+
'scope,scrolling,shape,size,sizes,span,srclang,srcset,start,summary,tabindex,target,title,translate,type,usemap,' +
|
|
6161
6156
|
'valign,value,vspace,width');
|
|
6162
6157
|
// Accessibility attributes as per WAI-ARIA 1.1 (W3C Working Draft 14 December 2018)
|
|
6163
6158
|
const ARIA_ATTRS = tagSet('aria-activedescendant,aria-atomic,aria-autocomplete,aria-busy,aria-checked,aria-colcount,aria-colindex,' +
|
|
@@ -6173,7 +6168,7 @@ const ARIA_ATTRS = tagSet('aria-activedescendant,aria-atomic,aria-autocomplete,a
|
|
|
6173
6168
|
// NB: Sanitization does not allow <form> elements or other active elements (<button> etc). Those
|
|
6174
6169
|
// can be sanitized, but they increase security surface area without a legitimate use case, so they
|
|
6175
6170
|
// are left out here.
|
|
6176
|
-
const VALID_ATTRS = merge(URI_ATTRS,
|
|
6171
|
+
const VALID_ATTRS = merge(URI_ATTRS, HTML_ATTRS, ARIA_ATTRS);
|
|
6177
6172
|
// Elements whose content should not be traversed/preserved, if the elements themselves are invalid.
|
|
6178
6173
|
//
|
|
6179
6174
|
// Typically, `<invalid>Some content</invalid>` would traverse (and in this case preserve)
|
|
@@ -6256,8 +6251,6 @@ class SanitizingHtmlSerializer {
|
|
|
6256
6251
|
// TODO(martinprobst): Special case image URIs for data:image/...
|
|
6257
6252
|
if (URI_ATTRS[lower])
|
|
6258
6253
|
value = _sanitizeUrl(value);
|
|
6259
|
-
if (SRCSET_ATTRS[lower])
|
|
6260
|
-
value = sanitizeSrcset(value);
|
|
6261
6254
|
this.buf.push(' ', attrName, '="', encodeEntities(value), '"');
|
|
6262
6255
|
}
|
|
6263
6256
|
this.buf.push('>');
|
|
@@ -7644,7 +7637,7 @@ class Version {
|
|
|
7644
7637
|
/**
|
|
7645
7638
|
* @publicApi
|
|
7646
7639
|
*/
|
|
7647
|
-
const VERSION = new Version('15.0.0-next.
|
|
7640
|
+
const VERSION = new Version('15.0.0-next.3');
|
|
7648
7641
|
|
|
7649
7642
|
/**
|
|
7650
7643
|
* @license
|
|
@@ -7947,7 +7940,7 @@ function getTemplateLocationDetails(lView) {
|
|
|
7947
7940
|
* that the `CommonModule` should also be included.
|
|
7948
7941
|
*/
|
|
7949
7942
|
const KNOWN_CONTROL_FLOW_DIRECTIVES = new Map([
|
|
7950
|
-
['ngIf', 'NgIf'], ['ngFor', '
|
|
7943
|
+
['ngIf', 'NgIf'], ['ngFor', 'NgFor'], ['ngSwitchCase', 'NgSwitchCase'],
|
|
7951
7944
|
['ngSwitchDefault', 'NgSwitchDefault']
|
|
7952
7945
|
]);
|
|
7953
7946
|
/**
|
|
@@ -8463,18 +8456,21 @@ function findViaDirective(lView, directiveInstance) {
|
|
|
8463
8456
|
*/
|
|
8464
8457
|
function getDirectivesAtNodeIndex(nodeIndex, lView, includeComponents) {
|
|
8465
8458
|
const tNode = lView[TVIEW].data[nodeIndex];
|
|
8466
|
-
|
|
8467
|
-
if (directiveStartIndex == 0)
|
|
8459
|
+
if (tNode.directiveStart === 0)
|
|
8468
8460
|
return EMPTY_ARRAY;
|
|
8469
|
-
const
|
|
8470
|
-
|
|
8471
|
-
|
|
8472
|
-
|
|
8461
|
+
const results = [];
|
|
8462
|
+
for (let i = tNode.directiveStart; i < tNode.directiveEnd; i++) {
|
|
8463
|
+
const directiveInstance = lView[i];
|
|
8464
|
+
if (!isComponentInstance(directiveInstance) || includeComponents) {
|
|
8465
|
+
results.push(directiveInstance);
|
|
8466
|
+
}
|
|
8467
|
+
}
|
|
8468
|
+
return results;
|
|
8473
8469
|
}
|
|
8474
8470
|
function getComponentAtNodeIndex(nodeIndex, lView) {
|
|
8475
8471
|
const tNode = lView[TVIEW].data[nodeIndex];
|
|
8476
|
-
|
|
8477
|
-
return
|
|
8472
|
+
const { directiveStart, componentOffset } = tNode;
|
|
8473
|
+
return componentOffset > -1 ? lView[directiveStart + componentOffset] : null;
|
|
8478
8474
|
}
|
|
8479
8475
|
/**
|
|
8480
8476
|
* Returns a map of local references (local reference name => element or directive instance) that
|
|
@@ -8696,16 +8692,16 @@ function getRootView(componentOrLView) {
|
|
|
8696
8692
|
return lView;
|
|
8697
8693
|
}
|
|
8698
8694
|
/**
|
|
8699
|
-
* Returns the
|
|
8700
|
-
*
|
|
8701
|
-
*
|
|
8695
|
+
* Returns the context information associated with the application where the target is situated. It
|
|
8696
|
+
* does this by walking the parent views until it gets to the root view, then getting the context
|
|
8697
|
+
* off of that.
|
|
8702
8698
|
*
|
|
8703
8699
|
* @param viewOrComponent the `LView` or component to get the root context for.
|
|
8704
8700
|
*/
|
|
8705
8701
|
function getRootContext(viewOrComponent) {
|
|
8706
8702
|
const rootView = getRootView(viewOrComponent);
|
|
8707
8703
|
ngDevMode &&
|
|
8708
|
-
assertDefined(rootView[CONTEXT], '
|
|
8704
|
+
assertDefined(rootView[CONTEXT], 'Root view has no context. Perhaps it is disconnected?');
|
|
8709
8705
|
return rootView[CONTEXT];
|
|
8710
8706
|
}
|
|
8711
8707
|
/**
|
|
@@ -9222,9 +9218,10 @@ function getClosestRElement(tView, tNode, lView) {
|
|
|
9222
9218
|
}
|
|
9223
9219
|
else {
|
|
9224
9220
|
ngDevMode && assertTNodeType(parentTNode, 3 /* TNodeType.AnyRNode */ | 4 /* TNodeType.Container */);
|
|
9225
|
-
|
|
9221
|
+
const { componentOffset } = parentTNode;
|
|
9222
|
+
if (componentOffset > -1) {
|
|
9226
9223
|
ngDevMode && assertTNodeForLView(parentTNode, lView);
|
|
9227
|
-
const encapsulation = tView.data[parentTNode.directiveStart]
|
|
9224
|
+
const { encapsulation } = tView.data[parentTNode.directiveStart + componentOffset];
|
|
9228
9225
|
// We've got a parent which is an element in the current view. We just need to verify if the
|
|
9229
9226
|
// parent element is not a component. Component's content nodes are not inserted immediately
|
|
9230
9227
|
// because they will be projected, and so doing insert at this point would be wasteful.
|
|
@@ -9457,10 +9454,10 @@ function applyNodes(renderer, action, tNode, lView, parentRElement, beforeNode,
|
|
|
9457
9454
|
if (isProjection) {
|
|
9458
9455
|
if (action === 0 /* WalkTNodeTreeAction.Create */) {
|
|
9459
9456
|
rawSlotValue && attachPatchData(unwrapRNode(rawSlotValue), lView);
|
|
9460
|
-
tNode.flags |=
|
|
9457
|
+
tNode.flags |= 2 /* TNodeFlags.isProjected */;
|
|
9461
9458
|
}
|
|
9462
9459
|
}
|
|
9463
|
-
if ((tNode.flags &
|
|
9460
|
+
if ((tNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
|
|
9464
9461
|
if (tNodeType & 8 /* TNodeType.ElementContainer */) {
|
|
9465
9462
|
applyNodes(renderer, action, tNode.child, lView, parentRElement, beforeNode, false);
|
|
9466
9463
|
applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
|
|
@@ -11514,6 +11511,7 @@ class TNode {
|
|
|
11514
11511
|
index, //
|
|
11515
11512
|
insertBeforeIndex, //
|
|
11516
11513
|
injectorIndex, //
|
|
11514
|
+
componentOffset, //
|
|
11517
11515
|
directiveStart, //
|
|
11518
11516
|
directiveEnd, //
|
|
11519
11517
|
directiveStylingLast, //
|
|
@@ -11546,6 +11544,7 @@ class TNode {
|
|
|
11546
11544
|
this.index = index;
|
|
11547
11545
|
this.insertBeforeIndex = insertBeforeIndex;
|
|
11548
11546
|
this.injectorIndex = injectorIndex;
|
|
11547
|
+
this.componentOffset = componentOffset;
|
|
11549
11548
|
this.directiveStart = directiveStart;
|
|
11550
11549
|
this.directiveEnd = directiveEnd;
|
|
11551
11550
|
this.directiveStylingLast = directiveStylingLast;
|
|
@@ -11623,21 +11622,19 @@ class TNode {
|
|
|
11623
11622
|
}
|
|
11624
11623
|
get flags_() {
|
|
11625
11624
|
const flags = [];
|
|
11626
|
-
if (this.flags &
|
|
11625
|
+
if (this.flags & 8 /* TNodeFlags.hasClassInput */)
|
|
11627
11626
|
flags.push('TNodeFlags.hasClassInput');
|
|
11628
|
-
if (this.flags &
|
|
11627
|
+
if (this.flags & 4 /* TNodeFlags.hasContentQuery */)
|
|
11629
11628
|
flags.push('TNodeFlags.hasContentQuery');
|
|
11630
|
-
if (this.flags &
|
|
11629
|
+
if (this.flags & 16 /* TNodeFlags.hasStyleInput */)
|
|
11631
11630
|
flags.push('TNodeFlags.hasStyleInput');
|
|
11632
|
-
if (this.flags &
|
|
11631
|
+
if (this.flags & 64 /* TNodeFlags.hasHostBindings */)
|
|
11633
11632
|
flags.push('TNodeFlags.hasHostBindings');
|
|
11634
|
-
if (this.flags & 2 /* TNodeFlags.isComponentHost */)
|
|
11635
|
-
flags.push('TNodeFlags.isComponentHost');
|
|
11636
11633
|
if (this.flags & 1 /* TNodeFlags.isDirectiveHost */)
|
|
11637
11634
|
flags.push('TNodeFlags.isDirectiveHost');
|
|
11638
|
-
if (this.flags &
|
|
11635
|
+
if (this.flags & 32 /* TNodeFlags.isDetached */)
|
|
11639
11636
|
flags.push('TNodeFlags.isDetached');
|
|
11640
|
-
if (this.flags &
|
|
11637
|
+
if (this.flags & 2 /* TNodeFlags.isProjected */)
|
|
11641
11638
|
flags.push('TNodeFlags.isProjected');
|
|
11642
11639
|
return flags.join('|');
|
|
11643
11640
|
}
|
|
@@ -12147,7 +12144,7 @@ function getOrCreateTNode(tView, index, type, name, attrs) {
|
|
|
12147
12144
|
// See `TNodeType.Placeholder` and `LFrame.inI18n` for more context.
|
|
12148
12145
|
// If the `TNode` was not pre-declared than it means it was not mentioned which means it was
|
|
12149
12146
|
// removed, so we mark it as detached.
|
|
12150
|
-
tNode.flags |=
|
|
12147
|
+
tNode.flags |= 32 /* TNodeFlags.isDetached */;
|
|
12151
12148
|
}
|
|
12152
12149
|
}
|
|
12153
12150
|
else if (tNode.type & 64 /* TNodeType.Placeholder */) {
|
|
@@ -12409,28 +12406,6 @@ function refreshView(tView, lView, templateFn, context) {
|
|
|
12409
12406
|
leaveView();
|
|
12410
12407
|
}
|
|
12411
12408
|
}
|
|
12412
|
-
function renderComponentOrTemplate(tView, lView, templateFn, context) {
|
|
12413
|
-
const rendererFactory = lView[RENDERER_FACTORY];
|
|
12414
|
-
// Check no changes mode is a dev only mode used to verify that bindings have not changed
|
|
12415
|
-
// since they were assigned. We do not want to invoke renderer factory functions in that mode
|
|
12416
|
-
// to avoid any possible side-effects.
|
|
12417
|
-
const checkNoChangesMode = !!ngDevMode && isInCheckNoChangesMode();
|
|
12418
|
-
const creationModeIsActive = isCreationMode(lView);
|
|
12419
|
-
try {
|
|
12420
|
-
if (!checkNoChangesMode && !creationModeIsActive && rendererFactory.begin) {
|
|
12421
|
-
rendererFactory.begin();
|
|
12422
|
-
}
|
|
12423
|
-
if (creationModeIsActive) {
|
|
12424
|
-
renderView(tView, lView, context);
|
|
12425
|
-
}
|
|
12426
|
-
refreshView(tView, lView, templateFn, context);
|
|
12427
|
-
}
|
|
12428
|
-
finally {
|
|
12429
|
-
if (!checkNoChangesMode && !creationModeIsActive && rendererFactory.end) {
|
|
12430
|
-
rendererFactory.end();
|
|
12431
|
-
}
|
|
12432
|
-
}
|
|
12433
|
-
}
|
|
12434
12409
|
function executeTemplate(tView, lView, templateFn, rf, context) {
|
|
12435
12410
|
const prevSelectedIndex = getSelectedIndex();
|
|
12436
12411
|
const isUpdatePhase = rf & 2 /* RenderFlags.Update */;
|
|
@@ -12473,7 +12448,7 @@ function createDirectivesInstances(tView, lView, tNode) {
|
|
|
12473
12448
|
if (!getBindingsEnabled())
|
|
12474
12449
|
return;
|
|
12475
12450
|
instantiateAllDirectives(tView, lView, tNode, getNativeByTNode(tNode, lView));
|
|
12476
|
-
if ((tNode.flags &
|
|
12451
|
+
if ((tNode.flags & 64 /* TNodeFlags.hasHostBindings */) === 64 /* TNodeFlags.hasHostBindings */) {
|
|
12477
12452
|
invokeDirectivesHostBindings(tView, lView, tNode);
|
|
12478
12453
|
}
|
|
12479
12454
|
}
|
|
@@ -12501,7 +12476,7 @@ function saveResolvedLocalsInData(viewData, tNode, localRefExtractor = getNative
|
|
|
12501
12476
|
* @param def ComponentDef
|
|
12502
12477
|
* @returns TView
|
|
12503
12478
|
*/
|
|
12504
|
-
function
|
|
12479
|
+
function getOrCreateComponentTView(def) {
|
|
12505
12480
|
const tView = def.tView;
|
|
12506
12481
|
// Create a TView if there isn't one, or recreate it if the first create pass didn't
|
|
12507
12482
|
// complete successfully since we can't know for sure whether it's in a usable shape.
|
|
@@ -12673,6 +12648,7 @@ function createTNode(tView, tParent, type, index, value, attrs) {
|
|
|
12673
12648
|
index, // index: number
|
|
12674
12649
|
null, // insertBeforeIndex: null|-1|number|number[]
|
|
12675
12650
|
injectorIndex, // injectorIndex: number
|
|
12651
|
+
-1, // componentOffset: number
|
|
12676
12652
|
-1, // directiveStart: number
|
|
12677
12653
|
-1, // directiveEnd: number
|
|
12678
12654
|
-1, // directiveStylingLast: number
|
|
@@ -12708,6 +12684,7 @@ function createTNode(tView, tParent, type, index, value, attrs) {
|
|
|
12708
12684
|
directiveStart: -1,
|
|
12709
12685
|
directiveEnd: -1,
|
|
12710
12686
|
directiveStylingLast: -1,
|
|
12687
|
+
componentOffset: -1,
|
|
12711
12688
|
propertyBindings: null,
|
|
12712
12689
|
flags: 0,
|
|
12713
12690
|
providerIndexes: 0,
|
|
@@ -12771,24 +12748,23 @@ function initializeInputAndOutputAliases(tView, tNode) {
|
|
|
12771
12748
|
let outputsStore = null;
|
|
12772
12749
|
for (let i = start; i < end; i++) {
|
|
12773
12750
|
const directiveDef = tViewData[i];
|
|
12774
|
-
|
|
12751
|
+
inputsStore = generatePropertyAliases(directiveDef.inputs, i, inputsStore);
|
|
12752
|
+
outputsStore = generatePropertyAliases(directiveDef.outputs, i, outputsStore);
|
|
12775
12753
|
// Do not use unbound attributes as inputs to structural directives, since structural
|
|
12776
12754
|
// directive inputs can only be set using microsyntax (e.g. `<div *dir="exp">`).
|
|
12777
12755
|
// TODO(FW-1930): microsyntax expressions may also contain unbound/static attributes, which
|
|
12778
12756
|
// should be set for inline templates.
|
|
12779
|
-
const initialInputs = (tNodeAttrs !== null && !isInlineTemplate(tNode)) ?
|
|
12780
|
-
generateInitialInputs(
|
|
12757
|
+
const initialInputs = (inputsStore !== null && tNodeAttrs !== null && !isInlineTemplate(tNode)) ?
|
|
12758
|
+
generateInitialInputs(inputsStore, i, tNodeAttrs) :
|
|
12781
12759
|
null;
|
|
12782
12760
|
inputsFromAttrs.push(initialInputs);
|
|
12783
|
-
inputsStore = generatePropertyAliases(directiveInputs, i, inputsStore);
|
|
12784
|
-
outputsStore = generatePropertyAliases(directiveDef.outputs, i, outputsStore);
|
|
12785
12761
|
}
|
|
12786
12762
|
if (inputsStore !== null) {
|
|
12787
12763
|
if (inputsStore.hasOwnProperty('class')) {
|
|
12788
|
-
tNode.flags |=
|
|
12764
|
+
tNode.flags |= 8 /* TNodeFlags.hasClassInput */;
|
|
12789
12765
|
}
|
|
12790
12766
|
if (inputsStore.hasOwnProperty('style')) {
|
|
12791
|
-
tNode.flags |=
|
|
12767
|
+
tNode.flags |= 16 /* TNodeFlags.hasStyleInput */;
|
|
12792
12768
|
}
|
|
12793
12769
|
}
|
|
12794
12770
|
tNode.initialInputs = inputsFromAttrs;
|
|
@@ -12909,7 +12885,7 @@ function instantiateRootComponent(tView, lView, def) {
|
|
|
12909
12885
|
configureViewWithDirective(tView, rootTNode, lView, directiveIndex, def);
|
|
12910
12886
|
initializeInputAndOutputAliases(tView, rootTNode);
|
|
12911
12887
|
}
|
|
12912
|
-
const directive = getNodeInjectable(lView, tView, rootTNode.directiveStart, rootTNode);
|
|
12888
|
+
const directive = getNodeInjectable(lView, tView, rootTNode.directiveStart + rootTNode.componentOffset, rootTNode);
|
|
12913
12889
|
attachPatchData(directive, lView);
|
|
12914
12890
|
const native = getNativeByTNode(rootTNode, lView);
|
|
12915
12891
|
if (native) {
|
|
@@ -12926,7 +12902,10 @@ function resolveDirectives(tView, lView, tNode, localRefs) {
|
|
|
12926
12902
|
ngDevMode && assertFirstCreatePass(tView);
|
|
12927
12903
|
let hasDirectives = false;
|
|
12928
12904
|
if (getBindingsEnabled()) {
|
|
12929
|
-
const
|
|
12905
|
+
const directiveDefsMatchedBySelectors = findDirectiveDefMatches(tView, lView, tNode);
|
|
12906
|
+
const directiveDefs = directiveDefsMatchedBySelectors ?
|
|
12907
|
+
findHostDirectiveDefs$1(directiveDefsMatchedBySelectors, tView, lView, tNode) :
|
|
12908
|
+
null;
|
|
12930
12909
|
const exportsMap = localRefs === null ? null : { '': -1 };
|
|
12931
12910
|
if (directiveDefs !== null) {
|
|
12932
12911
|
hasDirectives = true;
|
|
@@ -12955,9 +12934,9 @@ function resolveDirectives(tView, lView, tNode, localRefs) {
|
|
|
12955
12934
|
configureViewWithDirective(tView, tNode, lView, directiveIdx, def);
|
|
12956
12935
|
saveNameToExportMap(directiveIdx, def, exportsMap);
|
|
12957
12936
|
if (def.contentQueries !== null)
|
|
12958
|
-
tNode.flags |=
|
|
12937
|
+
tNode.flags |= 4 /* TNodeFlags.hasContentQuery */;
|
|
12959
12938
|
if (def.hostBindings !== null || def.hostAttrs !== null || def.hostVars !== 0)
|
|
12960
|
-
tNode.flags |=
|
|
12939
|
+
tNode.flags |= 64 /* TNodeFlags.hasHostBindings */;
|
|
12961
12940
|
const lifeCycleHooks = def.type.prototype;
|
|
12962
12941
|
// Only push a node index into the preOrderHooks array if this is the first
|
|
12963
12942
|
// pre-order hook found on this node.
|
|
@@ -13110,20 +13089,19 @@ function findDirectiveDefMatches(tView, viewData, tNode) {
|
|
|
13110
13089
|
if (ngDevMode) {
|
|
13111
13090
|
assertTNodeType(tNode, 2 /* TNodeType.Element */, `"${tNode.value}" tags cannot be used as component hosts. ` +
|
|
13112
13091
|
`Please use a different tag to activate the ${stringify(def.type)} component.`);
|
|
13113
|
-
if (tNode
|
|
13092
|
+
if (isComponentHost(tNode)) {
|
|
13114
13093
|
// If another component has been matched previously, it's the first element in the
|
|
13115
13094
|
// `matches` array, see how we store components/directives in `matches` below.
|
|
13116
13095
|
throwMultipleComponentError(tNode, matches[0].type, def.type);
|
|
13117
13096
|
}
|
|
13118
13097
|
}
|
|
13119
|
-
markAsComponentHost(tView, tNode);
|
|
13098
|
+
markAsComponentHost(tView, tNode, 0);
|
|
13120
13099
|
// The component is always stored first with directives after.
|
|
13121
13100
|
matches.unshift(def);
|
|
13122
13101
|
}
|
|
13123
13102
|
else {
|
|
13124
13103
|
matches.push(def);
|
|
13125
13104
|
}
|
|
13126
|
-
def.applyHostDirectives?.(tView, viewData, tNode, matches);
|
|
13127
13105
|
}
|
|
13128
13106
|
}
|
|
13129
13107
|
}
|
|
@@ -13131,15 +13109,36 @@ function findDirectiveDefMatches(tView, viewData, tNode) {
|
|
|
13131
13109
|
}
|
|
13132
13110
|
/**
|
|
13133
13111
|
* Marks a given TNode as a component's host. This consists of:
|
|
13134
|
-
* - setting
|
|
13112
|
+
* - setting the component offset on the TNode.
|
|
13135
13113
|
* - storing index of component's host element so it will be queued for view refresh during CD.
|
|
13136
13114
|
*/
|
|
13137
|
-
function markAsComponentHost(tView, hostTNode) {
|
|
13115
|
+
function markAsComponentHost(tView, hostTNode, componentOffset) {
|
|
13138
13116
|
ngDevMode && assertFirstCreatePass(tView);
|
|
13139
|
-
|
|
13117
|
+
ngDevMode && assertGreaterThan(componentOffset, -1, 'componentOffset must be great than -1');
|
|
13118
|
+
hostTNode.componentOffset = componentOffset;
|
|
13140
13119
|
(tView.components || (tView.components = ngDevMode ? new TViewComponents() : []))
|
|
13141
13120
|
.push(hostTNode.index);
|
|
13142
13121
|
}
|
|
13122
|
+
/**
|
|
13123
|
+
* Given an array of directives that were matched by their selectors, this function
|
|
13124
|
+
* produces a new array that also includes any host directives that have to be applied.
|
|
13125
|
+
* @param selectorMatches Directives matched in a template based on their selectors.
|
|
13126
|
+
* @param tView Current TView.
|
|
13127
|
+
* @param lView Current LView.
|
|
13128
|
+
* @param tNode Current TNode that is being matched.
|
|
13129
|
+
*/
|
|
13130
|
+
function findHostDirectiveDefs$1(selectorMatches, tView, lView, tNode) {
|
|
13131
|
+
const matches = [];
|
|
13132
|
+
for (const def of selectorMatches) {
|
|
13133
|
+
if (def.findHostDirectiveDefs === null) {
|
|
13134
|
+
matches.push(def);
|
|
13135
|
+
}
|
|
13136
|
+
else {
|
|
13137
|
+
def.findHostDirectiveDefs(matches, def, tView, lView, tNode);
|
|
13138
|
+
}
|
|
13139
|
+
}
|
|
13140
|
+
return matches;
|
|
13141
|
+
}
|
|
13143
13142
|
/** Caches local names and their matching directive indices for query and template lookups. */
|
|
13144
13143
|
function cacheMatchingLocalNames(tNode, localRefs, exportsMap) {
|
|
13145
13144
|
if (localRefs) {
|
|
@@ -13211,7 +13210,7 @@ function configureViewWithDirective(tView, tNode, lView, directiveIndex, def) {
|
|
|
13211
13210
|
}
|
|
13212
13211
|
function addComponentLogic(lView, hostTNode, def) {
|
|
13213
13212
|
const native = getNativeByTNode(hostTNode, lView);
|
|
13214
|
-
const tView =
|
|
13213
|
+
const tView = getOrCreateComponentTView(def);
|
|
13215
13214
|
// Only component views should be added to the view tree directly. Embedded views are
|
|
13216
13215
|
// accessed through their containers because they may be removed / re-added later.
|
|
13217
13216
|
const rendererFactory = lView[RENDERER_FACTORY];
|
|
@@ -13282,10 +13281,11 @@ function setInputsFromAttrs(lView, directiveIndex, instance, def, tNode, initial
|
|
|
13282
13281
|
*
|
|
13283
13282
|
* <my-component name="Bess"></my-component>
|
|
13284
13283
|
*
|
|
13285
|
-
* @param inputs
|
|
13286
|
-
* @param
|
|
13284
|
+
* @param inputs Input alias map that was generated from the directive def inputs.
|
|
13285
|
+
* @param directiveIndex Index of the directive that is currently being processed.
|
|
13286
|
+
* @param attrs Static attrs on this node.
|
|
13287
13287
|
*/
|
|
13288
|
-
function generateInitialInputs(inputs, attrs) {
|
|
13288
|
+
function generateInitialInputs(inputs, directiveIndex, attrs) {
|
|
13289
13289
|
let inputsToStore = null;
|
|
13290
13290
|
let i = 0;
|
|
13291
13291
|
while (i < attrs.length) {
|
|
@@ -13306,7 +13306,17 @@ function generateInitialInputs(inputs, attrs) {
|
|
|
13306
13306
|
if (inputs.hasOwnProperty(attrName)) {
|
|
13307
13307
|
if (inputsToStore === null)
|
|
13308
13308
|
inputsToStore = [];
|
|
13309
|
-
|
|
13309
|
+
// Find the input's public name from the input store. Note that we can be found easier
|
|
13310
|
+
// through the directive def, but we want to do it using the inputs store so that it can
|
|
13311
|
+
// account for host directive aliases.
|
|
13312
|
+
const inputConfig = inputs[attrName];
|
|
13313
|
+
for (let j = 0; j < inputConfig.length; j += 2) {
|
|
13314
|
+
if (inputConfig[j] === directiveIndex) {
|
|
13315
|
+
inputsToStore.push(attrName, inputConfig[j + 1], attrs[i + 1]);
|
|
13316
|
+
// A directive can't have multiple inputs with the same name so we can break here.
|
|
13317
|
+
break;
|
|
13318
|
+
}
|
|
13319
|
+
}
|
|
13310
13320
|
}
|
|
13311
13321
|
i += 2;
|
|
13312
13322
|
}
|
|
@@ -13538,63 +13548,32 @@ function markViewDirty(lView) {
|
|
|
13538
13548
|
}
|
|
13539
13549
|
return null;
|
|
13540
13550
|
}
|
|
13541
|
-
function
|
|
13542
|
-
for (let i = 0; i < rootContext.components.length; i++) {
|
|
13543
|
-
const rootComponent = rootContext.components[i];
|
|
13544
|
-
const lView = readPatchedLView(rootComponent);
|
|
13545
|
-
// We might not have an `LView` if the component was destroyed.
|
|
13546
|
-
if (lView !== null) {
|
|
13547
|
-
const tView = lView[TVIEW];
|
|
13548
|
-
renderComponentOrTemplate(tView, lView, tView.template, rootComponent);
|
|
13549
|
-
}
|
|
13550
|
-
}
|
|
13551
|
-
}
|
|
13552
|
-
function detectChangesInternal(tView, lView, context) {
|
|
13551
|
+
function detectChangesInternal(tView, lView, context, notifyErrorHandler = true) {
|
|
13553
13552
|
const rendererFactory = lView[RENDERER_FACTORY];
|
|
13554
|
-
|
|
13553
|
+
// Check no changes mode is a dev only mode used to verify that bindings have not changed
|
|
13554
|
+
// since they were assigned. We do not want to invoke renderer factory functions in that mode
|
|
13555
|
+
// to avoid any possible side-effects.
|
|
13556
|
+
const checkNoChangesMode = !!ngDevMode && isInCheckNoChangesMode();
|
|
13557
|
+
if (!checkNoChangesMode && rendererFactory.begin)
|
|
13555
13558
|
rendererFactory.begin();
|
|
13556
13559
|
try {
|
|
13557
13560
|
refreshView(tView, lView, tView.template, context);
|
|
13558
13561
|
}
|
|
13559
13562
|
catch (error) {
|
|
13560
|
-
|
|
13563
|
+
if (notifyErrorHandler) {
|
|
13564
|
+
handleError(lView, error);
|
|
13565
|
+
}
|
|
13561
13566
|
throw error;
|
|
13562
13567
|
}
|
|
13563
13568
|
finally {
|
|
13564
|
-
if (rendererFactory.end)
|
|
13569
|
+
if (!checkNoChangesMode && rendererFactory.end)
|
|
13565
13570
|
rendererFactory.end();
|
|
13566
13571
|
}
|
|
13567
13572
|
}
|
|
13568
|
-
|
|
13569
|
-
* Synchronously perform change detection on a root view and its components.
|
|
13570
|
-
*
|
|
13571
|
-
* @param lView The view which the change detection should be performed on.
|
|
13572
|
-
*/
|
|
13573
|
-
function detectChangesInRootView(lView) {
|
|
13574
|
-
tickRootContext(lView[CONTEXT]);
|
|
13575
|
-
}
|
|
13576
|
-
function checkNoChangesInternal(tView, view, context) {
|
|
13573
|
+
function checkNoChangesInternal(tView, lView, context, notifyErrorHandler = true) {
|
|
13577
13574
|
setIsInCheckNoChangesMode(true);
|
|
13578
13575
|
try {
|
|
13579
|
-
detectChangesInternal(tView,
|
|
13580
|
-
}
|
|
13581
|
-
finally {
|
|
13582
|
-
setIsInCheckNoChangesMode(false);
|
|
13583
|
-
}
|
|
13584
|
-
}
|
|
13585
|
-
/**
|
|
13586
|
-
* Checks the change detector on a root view and its components, and throws if any changes are
|
|
13587
|
-
* detected.
|
|
13588
|
-
*
|
|
13589
|
-
* This is used in development mode to verify that running change detection doesn't
|
|
13590
|
-
* introduce other changes.
|
|
13591
|
-
*
|
|
13592
|
-
* @param lView The view which the change detection should be checked on.
|
|
13593
|
-
*/
|
|
13594
|
-
function checkNoChangesInRootView(lView) {
|
|
13595
|
-
setIsInCheckNoChangesMode(true);
|
|
13596
|
-
try {
|
|
13597
|
-
detectChangesInRootView(lView);
|
|
13576
|
+
detectChangesInternal(tView, lView, context, notifyErrorHandler);
|
|
13598
13577
|
}
|
|
13599
13578
|
finally {
|
|
13600
13579
|
setIsInCheckNoChangesMode(false);
|
|
@@ -14087,11 +14066,17 @@ class RootViewRef extends ViewRef {
|
|
|
14087
14066
|
this._view = _view;
|
|
14088
14067
|
}
|
|
14089
14068
|
detectChanges() {
|
|
14090
|
-
|
|
14069
|
+
const lView = this._view;
|
|
14070
|
+
const tView = lView[TVIEW];
|
|
14071
|
+
const context = lView[CONTEXT];
|
|
14072
|
+
detectChangesInternal(tView, lView, context, false);
|
|
14091
14073
|
}
|
|
14092
14074
|
checkNoChanges() {
|
|
14093
14075
|
if (ngDevMode) {
|
|
14094
|
-
|
|
14076
|
+
const lView = this._view;
|
|
14077
|
+
const tView = lView[TVIEW];
|
|
14078
|
+
const context = lView[CONTEXT];
|
|
14079
|
+
checkNoChangesInternal(tView, lView, context, false);
|
|
14095
14080
|
}
|
|
14096
14081
|
}
|
|
14097
14082
|
get context() {
|
|
@@ -14158,7 +14143,7 @@ class ChainedInjector {
|
|
|
14158
14143
|
}
|
|
14159
14144
|
}
|
|
14160
14145
|
/**
|
|
14161
|
-
*
|
|
14146
|
+
* ComponentFactory interface implementation.
|
|
14162
14147
|
*/
|
|
14163
14148
|
class ComponentFactory extends ComponentFactory$1 {
|
|
14164
14149
|
/**
|
|
@@ -14208,10 +14193,9 @@ class ComponentFactory extends ComponentFactory$1 {
|
|
|
14208
14193
|
createElementNode(rendererFactory.createRenderer(null, this.componentDef), elementName, getNamespace(elementName));
|
|
14209
14194
|
const rootFlags = this.componentDef.onPush ? 32 /* LViewFlags.Dirty */ | 256 /* LViewFlags.IsRoot */ :
|
|
14210
14195
|
16 /* LViewFlags.CheckAlways */ | 256 /* LViewFlags.IsRoot */;
|
|
14211
|
-
const rootContext = createRootContext();
|
|
14212
14196
|
// Create the root view. Uses empty TView and ContentTemplate.
|
|
14213
14197
|
const rootTView = createTView(0 /* TViewType.Root */, null, null, 1, 0, null, null, null, null, null);
|
|
14214
|
-
const rootLView = createLView(null, rootTView,
|
|
14198
|
+
const rootLView = createLView(null, rootTView, null, rootFlags, null, null, rendererFactory, hostRenderer, sanitizer, rootViewInjector, null);
|
|
14215
14199
|
// rootView is the parent when bootstrapping
|
|
14216
14200
|
// TODO(misko): it looks like we are entering view here but we don't really need to as
|
|
14217
14201
|
// `renderView` does that. However as the code is written it is needed because
|
|
@@ -14255,7 +14239,8 @@ class ComponentFactory extends ComponentFactory$1 {
|
|
|
14255
14239
|
// TODO: should LifecycleHooksFeature and other host features be generated by the compiler and
|
|
14256
14240
|
// executed here?
|
|
14257
14241
|
// Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref
|
|
14258
|
-
component =
|
|
14242
|
+
component =
|
|
14243
|
+
createRootComponent(componentView, this.componentDef, rootLView, [LifecycleHooksFeature]);
|
|
14259
14244
|
renderView(rootTView, rootLView, null);
|
|
14260
14245
|
}
|
|
14261
14246
|
finally {
|
|
@@ -14361,10 +14346,10 @@ function createRootComponentView(rNode, def, rootView, rendererFactory, hostRend
|
|
|
14361
14346
|
}
|
|
14362
14347
|
}
|
|
14363
14348
|
const viewRenderer = rendererFactory.createRenderer(rNode, def);
|
|
14364
|
-
const componentView = createLView(rootView,
|
|
14349
|
+
const componentView = createLView(rootView, getOrCreateComponentTView(def), null, def.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, rootView[index], tNode, rendererFactory, viewRenderer, sanitizer || null, null, null);
|
|
14365
14350
|
if (tView.firstCreatePass) {
|
|
14366
14351
|
diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, rootView), tView, def.type);
|
|
14367
|
-
markAsComponentHost(tView, tNode);
|
|
14352
|
+
markAsComponentHost(tView, tNode, 0);
|
|
14368
14353
|
initTNodeFlags(tNode, rootView.length, 1);
|
|
14369
14354
|
}
|
|
14370
14355
|
addToViewTree(rootView, componentView);
|
|
@@ -14375,12 +14360,13 @@ function createRootComponentView(rNode, def, rootView, rendererFactory, hostRend
|
|
|
14375
14360
|
* Creates a root component and sets it up with features and host bindings.Shared by
|
|
14376
14361
|
* renderComponent() and ViewContainerRef.createComponent().
|
|
14377
14362
|
*/
|
|
14378
|
-
function createRootComponent(componentView, componentDef, rootLView,
|
|
14363
|
+
function createRootComponent(componentView, componentDef, rootLView, hostFeatures) {
|
|
14379
14364
|
const tView = rootLView[TVIEW];
|
|
14380
14365
|
// Create directive instance with factory() and store at next index in viewData
|
|
14381
14366
|
const component = instantiateRootComponent(tView, rootLView, componentDef);
|
|
14382
|
-
|
|
14383
|
-
|
|
14367
|
+
// Root view only contains an instance of this component,
|
|
14368
|
+
// so we use a reference to that component instance as a context.
|
|
14369
|
+
componentView[CONTEXT] = rootLView[CONTEXT] = component;
|
|
14384
14370
|
if (hostFeatures !== null) {
|
|
14385
14371
|
for (const feature of hostFeatures) {
|
|
14386
14372
|
feature(component, componentDef);
|
|
@@ -14404,9 +14390,6 @@ function createRootComponent(componentView, componentDef, rootLView, rootContext
|
|
|
14404
14390
|
}
|
|
14405
14391
|
return component;
|
|
14406
14392
|
}
|
|
14407
|
-
function createRootContext() {
|
|
14408
|
-
return { components: [] };
|
|
14409
|
-
}
|
|
14410
14393
|
/**
|
|
14411
14394
|
* Used to enable lifecycle hooks on the root component.
|
|
14412
14395
|
*
|
|
@@ -14663,6 +14646,13 @@ function ɵɵCopyDefinitionFeature(definition) {
|
|
|
14663
14646
|
}
|
|
14664
14647
|
}
|
|
14665
14648
|
|
|
14649
|
+
/**
|
|
14650
|
+
* @license
|
|
14651
|
+
* Copyright Google LLC All Rights Reserved.
|
|
14652
|
+
*
|
|
14653
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
14654
|
+
* found in the LICENSE file at https://angular.io/license
|
|
14655
|
+
*/
|
|
14666
14656
|
/**
|
|
14667
14657
|
* This feature add the host directives behavior to a directive definition by patching a
|
|
14668
14658
|
* function onto it. The expectation is that the runtime will invoke the function during
|
|
@@ -14684,29 +14674,43 @@ function ɵɵCopyDefinitionFeature(definition) {
|
|
|
14684
14674
|
* @codeGenApi
|
|
14685
14675
|
*/
|
|
14686
14676
|
function ɵɵHostDirectivesFeature(rawHostDirectives) {
|
|
14687
|
-
const unwrappedHostDirectives = Array.isArray(rawHostDirectives) ? rawHostDirectives : rawHostDirectives();
|
|
14688
|
-
const hostDirectives = unwrappedHostDirectives.map(dir => typeof dir === 'function' ? { directive: dir, inputs: EMPTY_OBJ, outputs: EMPTY_OBJ } : {
|
|
14689
|
-
directive: dir.directive,
|
|
14690
|
-
inputs: bindingArrayToMap(dir.inputs),
|
|
14691
|
-
outputs: bindingArrayToMap(dir.outputs)
|
|
14692
|
-
});
|
|
14693
14677
|
return (definition) => {
|
|
14694
|
-
|
|
14695
|
-
definition.
|
|
14696
|
-
(
|
|
14678
|
+
definition.findHostDirectiveDefs = findHostDirectiveDefs;
|
|
14679
|
+
definition.hostDirectives =
|
|
14680
|
+
(Array.isArray(rawHostDirectives) ? rawHostDirectives : rawHostDirectives()).map(dir => {
|
|
14681
|
+
return typeof dir === 'function' ?
|
|
14682
|
+
{ directive: resolveForwardRef(dir), inputs: EMPTY_OBJ, outputs: EMPTY_OBJ } :
|
|
14683
|
+
{
|
|
14684
|
+
directive: resolveForwardRef(dir.directive),
|
|
14685
|
+
inputs: bindingArrayToMap(dir.inputs),
|
|
14686
|
+
outputs: bindingArrayToMap(dir.outputs)
|
|
14687
|
+
};
|
|
14688
|
+
});
|
|
14697
14689
|
};
|
|
14698
14690
|
}
|
|
14691
|
+
function findHostDirectiveDefs(matches, def, tView, lView, tNode) {
|
|
14692
|
+
if (def.hostDirectives !== null) {
|
|
14693
|
+
for (const hostDirectiveConfig of def.hostDirectives) {
|
|
14694
|
+
const hostDirectiveDef = getDirectiveDef(hostDirectiveConfig.directive);
|
|
14695
|
+
// TODO(crisbeto): assert that the def exists.
|
|
14696
|
+
// Host directives execute before the host so that its host bindings can be overwritten.
|
|
14697
|
+
findHostDirectiveDefs(matches, hostDirectiveDef, tView, lView, tNode);
|
|
14698
|
+
}
|
|
14699
|
+
}
|
|
14700
|
+
// Push the def itself at the end since it needs to execute after the host directives.
|
|
14701
|
+
matches.push(def);
|
|
14702
|
+
}
|
|
14699
14703
|
/**
|
|
14700
14704
|
* Converts an array in the form of `['publicName', 'alias', 'otherPublicName', 'otherAlias']` into
|
|
14701
14705
|
* a map in the form of `{publicName: 'alias', otherPublicName: 'otherAlias'}`.
|
|
14702
14706
|
*/
|
|
14703
14707
|
function bindingArrayToMap(bindings) {
|
|
14704
|
-
if (
|
|
14708
|
+
if (bindings === undefined || bindings.length === 0) {
|
|
14705
14709
|
return EMPTY_OBJ;
|
|
14706
14710
|
}
|
|
14707
14711
|
const result = {};
|
|
14708
|
-
for (let i =
|
|
14709
|
-
result[bindings[i
|
|
14712
|
+
for (let i = 0; i < bindings.length; i += 2) {
|
|
14713
|
+
result[bindings[i]] = bindings[i + 1];
|
|
14710
14714
|
}
|
|
14711
14715
|
return result;
|
|
14712
14716
|
}
|
|
@@ -15665,7 +15669,7 @@ function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
|
|
|
15665
15669
|
if (styles !== null) {
|
|
15666
15670
|
writeDirectStyle(renderer, native, styles);
|
|
15667
15671
|
}
|
|
15668
|
-
if ((tNode.flags &
|
|
15672
|
+
if ((tNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
|
|
15669
15673
|
// In the i18n case, the translation may have removed this element, so only add it if it is not
|
|
15670
15674
|
// detached. See `TNodeType.Placeholder` and `LFrame.inI18n` for more context.
|
|
15671
15675
|
appendChild(tView, lView, native, tNode);
|
|
@@ -16103,9 +16107,7 @@ function wrapListener(tNode, lView, context, listenerFn, wrapWithPreventDefault)
|
|
|
16103
16107
|
}
|
|
16104
16108
|
// In order to be backwards compatible with View Engine, events on component host nodes
|
|
16105
16109
|
// must also mark the component view itself dirty (i.e. the view that it owns).
|
|
16106
|
-
const startView = tNode.
|
|
16107
|
-
getComponentLViewByIndex(tNode.index, lView) :
|
|
16108
|
-
lView;
|
|
16110
|
+
const startView = tNode.componentOffset > -1 ? getComponentLViewByIndex(tNode.index, lView) : lView;
|
|
16109
16111
|
markViewDirty(startView);
|
|
16110
16112
|
let result = executeListenerWithErrorHandling(lView, context, listenerFn, e);
|
|
16111
16113
|
// A just-invoked listener function might have coalesced listeners so we need to check for
|
|
@@ -16262,7 +16264,7 @@ function ɵɵprojection(nodeIndex, selectorIndex = 0, attrs) {
|
|
|
16262
16264
|
tProjectionNode.projection = selectorIndex;
|
|
16263
16265
|
// `<ng-content>` has no content
|
|
16264
16266
|
setCurrentTNodeAsNotParent();
|
|
16265
|
-
if ((tProjectionNode.flags &
|
|
16267
|
+
if ((tProjectionNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
|
|
16266
16268
|
// re-distribution of projectable nodes is stored on a component's view level
|
|
16267
16269
|
applyProjection(tView, lView, tProjectionNode);
|
|
16268
16270
|
}
|
|
@@ -18176,7 +18178,7 @@ function normalizeSuffix(value, suffix) {
|
|
|
18176
18178
|
* @param isClassBased `true` if `class` (`false` if `style`)
|
|
18177
18179
|
*/
|
|
18178
18180
|
function hasStylingInputShadow(tNode, isClassBased) {
|
|
18179
|
-
return (tNode.flags & (isClassBased ?
|
|
18181
|
+
return (tNode.flags & (isClassBased ? 8 /* TNodeFlags.hasClassInput */ : 16 /* TNodeFlags.hasStyleInput */)) !== 0;
|
|
18180
18182
|
}
|
|
18181
18183
|
|
|
18182
18184
|
/**
|
|
@@ -19868,7 +19870,7 @@ function processI18nInsertBefore(renderer, childTNode, lView, childRNode, parent
|
|
|
19868
19870
|
anchorRNode = i18nParent;
|
|
19869
19871
|
i18nParent = parentRElement;
|
|
19870
19872
|
}
|
|
19871
|
-
if (i18nParent !== null &&
|
|
19873
|
+
if (i18nParent !== null && childTNode.componentOffset === -1) {
|
|
19872
19874
|
for (let i = 1; i < tNodeInsertBeforeIndex.length; i++) {
|
|
19873
19875
|
// No need to `unwrapRNode` because all of the indexes point to i18n text nodes.
|
|
19874
19876
|
// see `assertDomNode` below.
|
|
@@ -21299,9 +21301,6 @@ function walkIcuTree(tView, tIcu, lView, sharedUpdateOpCodes, create, remove, up
|
|
|
21299
21301
|
if (URI_ATTRS[lowerAttrName]) {
|
|
21300
21302
|
generateBindingUpdateOpCodes(update, attr.value, newIndex, attr.name, 0, _sanitizeUrl);
|
|
21301
21303
|
}
|
|
21302
|
-
else if (SRCSET_ATTRS[lowerAttrName]) {
|
|
21303
|
-
generateBindingUpdateOpCodes(update, attr.value, newIndex, attr.name, 0, sanitizeSrcset);
|
|
21304
|
-
}
|
|
21305
21304
|
else {
|
|
21306
21305
|
generateBindingUpdateOpCodes(update, attr.value, newIndex, attr.name, 0, null);
|
|
21307
21306
|
}
|
|
@@ -22270,7 +22269,7 @@ function getOwningComponent(elementOrDir) {
|
|
|
22270
22269
|
*/
|
|
22271
22270
|
function getRootComponents(elementOrDir) {
|
|
22272
22271
|
const lView = readPatchedLView(elementOrDir);
|
|
22273
|
-
return lView !== null ? [
|
|
22272
|
+
return lView !== null ? [getRootContext(lView)] : [];
|
|
22274
22273
|
}
|
|
22275
22274
|
/**
|
|
22276
22275
|
* Retrieves an `Injector` associated with an element, component or directive instance.
|