@angular/core 15.0.0-next.2 → 15.0.0-next.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/esm2020/src/core_private_export.mjs +2 -2
  2. package/esm2020/src/debug/debug_node.mjs +1 -1
  3. package/esm2020/src/di/index.mjs +1 -1
  4. package/esm2020/src/di/injector.mjs +1 -1
  5. package/esm2020/src/di/injector_compatibility.mjs +15 -11
  6. package/esm2020/src/di/interface/injector.mjs +1 -1
  7. package/esm2020/src/di/r3_injector.mjs +3 -2
  8. package/esm2020/src/render3/component_ref.mjs +103 -84
  9. package/esm2020/src/render3/context_discovery.mjs +17 -14
  10. package/esm2020/src/render3/definition.mjs +3 -2
  11. package/esm2020/src/render3/di.mjs +3 -2
  12. package/esm2020/src/render3/features/host_directives_feature.mjs +35 -13
  13. package/esm2020/src/render3/instructions/element.mjs +4 -16
  14. package/esm2020/src/render3/instructions/listener.mjs +2 -4
  15. package/esm2020/src/render3/instructions/lview_debug.mjs +9 -9
  16. package/esm2020/src/render3/instructions/projection.mjs +1 -1
  17. package/esm2020/src/render3/instructions/shared.mjs +123 -101
  18. package/esm2020/src/render3/instructions/styling.mjs +2 -2
  19. package/esm2020/src/render3/interfaces/definition.mjs +1 -1
  20. package/esm2020/src/render3/interfaces/node.mjs +3 -3
  21. package/esm2020/src/render3/interfaces/type_checks.mjs +3 -3
  22. package/esm2020/src/render3/jit/directive.mjs +7 -2
  23. package/esm2020/src/render3/ng_module_ref.mjs +1 -1
  24. package/esm2020/src/render3/node_manipulation.mjs +20 -5
  25. package/esm2020/src/render3/node_manipulation_i18n.mjs +2 -2
  26. package/esm2020/src/render3/util/discovery_utils.mjs +2 -2
  27. package/esm2020/src/util/is_dev_mode.mjs +11 -19
  28. package/esm2020/src/version.mjs +1 -1
  29. package/esm2020/src/zone/async-stack-tagging.mjs +28 -0
  30. package/esm2020/src/zone/ng_zone.mjs +8 -3
  31. package/esm2020/testing/src/logger.mjs +3 -3
  32. package/esm2020/testing/src/ng_zone_mock.mjs +3 -3
  33. package/esm2020/testing/src/test_bed.mjs +4 -4
  34. package/fesm2015/core.mjs +1463 -1363
  35. package/fesm2015/core.mjs.map +1 -1
  36. package/fesm2015/testing.mjs +970 -901
  37. package/fesm2015/testing.mjs.map +1 -1
  38. package/fesm2020/core.mjs +1464 -1366
  39. package/fesm2020/core.mjs.map +1 -1
  40. package/fesm2020/testing.mjs +969 -900
  41. package/fesm2020/testing.mjs.map +1 -1
  42. package/index.d.ts +100 -33
  43. package/package.json +1 -1
  44. package/testing/index.d.ts +9 -1
package/fesm2020/core.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v15.0.0-next.2
2
+ * @license Angular v15.0.0-next.4
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -582,152 +582,6 @@ function assertInjectImplementationNotEqual(fn) {
582
582
  assertNotEqual(_injectImplementation, fn, 'Calling ɵɵinject would cause infinite recursion');
583
583
  }
584
584
 
585
- /**
586
- * @license
587
- * Copyright Google LLC All Rights Reserved.
588
- *
589
- * Use of this source code is governed by an MIT-style license that can be
590
- * found in the LICENSE file at https://angular.io/license
591
- */
592
- /**
593
- * Convince closure compiler that the wrapped function has no side-effects.
594
- *
595
- * Closure compiler always assumes that `toString` has no side-effects. We use this quirk to
596
- * allow us to execute a function but have closure compiler mark the call as no-side-effects.
597
- * It is important that the return value for the `noSideEffects` function be assigned
598
- * to something which is retained otherwise the call to `noSideEffects` will be removed by closure
599
- * compiler.
600
- */
601
- function noSideEffects(fn) {
602
- return { toString: fn }.toString();
603
- }
604
-
605
- /**
606
- * @license
607
- * Copyright Google LLC All Rights Reserved.
608
- *
609
- * Use of this source code is governed by an MIT-style license that can be
610
- * found in the LICENSE file at https://angular.io/license
611
- */
612
- /**
613
- * The strategy that the default change detector uses to detect changes.
614
- * When set, takes effect the next time change detection is triggered.
615
- *
616
- * @see {@link ChangeDetectorRef#usage-notes Change detection usage}
617
- *
618
- * @publicApi
619
- */
620
- var ChangeDetectionStrategy;
621
- (function (ChangeDetectionStrategy) {
622
- /**
623
- * Use the `CheckOnce` strategy, meaning that automatic change detection is deactivated
624
- * until reactivated by setting the strategy to `Default` (`CheckAlways`).
625
- * Change detection can still be explicitly invoked.
626
- * This strategy applies to all child directives and cannot be overridden.
627
- */
628
- ChangeDetectionStrategy[ChangeDetectionStrategy["OnPush"] = 0] = "OnPush";
629
- /**
630
- * Use the default `CheckAlways` strategy, in which change detection is automatic until
631
- * explicitly deactivated.
632
- */
633
- ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default";
634
- })(ChangeDetectionStrategy || (ChangeDetectionStrategy = {}));
635
- /**
636
- * Defines the possible states of the default change detector.
637
- * @see `ChangeDetectorRef`
638
- */
639
- var ChangeDetectorStatus;
640
- (function (ChangeDetectorStatus) {
641
- /**
642
- * A state in which, after calling `detectChanges()`, the change detector
643
- * state becomes `Checked`, and must be explicitly invoked or reactivated.
644
- */
645
- ChangeDetectorStatus[ChangeDetectorStatus["CheckOnce"] = 0] = "CheckOnce";
646
- /**
647
- * A state in which change detection is skipped until the change detector mode
648
- * becomes `CheckOnce`.
649
- */
650
- ChangeDetectorStatus[ChangeDetectorStatus["Checked"] = 1] = "Checked";
651
- /**
652
- * A state in which change detection continues automatically until explicitly
653
- * deactivated.
654
- */
655
- ChangeDetectorStatus[ChangeDetectorStatus["CheckAlways"] = 2] = "CheckAlways";
656
- /**
657
- * A state in which a change detector sub tree is not a part of the main tree and
658
- * should be skipped.
659
- */
660
- ChangeDetectorStatus[ChangeDetectorStatus["Detached"] = 3] = "Detached";
661
- /**
662
- * Indicates that the change detector encountered an error checking a binding
663
- * or calling a directive lifecycle method and is now in an inconsistent state. Change
664
- * detectors in this state do not detect changes.
665
- */
666
- ChangeDetectorStatus[ChangeDetectorStatus["Errored"] = 4] = "Errored";
667
- /**
668
- * Indicates that the change detector has been destroyed.
669
- */
670
- ChangeDetectorStatus[ChangeDetectorStatus["Destroyed"] = 5] = "Destroyed";
671
- })(ChangeDetectorStatus || (ChangeDetectorStatus = {}));
672
- /**
673
- * Reports whether a given strategy is currently the default for change detection.
674
- * @param changeDetectionStrategy The strategy to check.
675
- * @returns True if the given strategy is the current default, false otherwise.
676
- * @see `ChangeDetectorStatus`
677
- * @see `ChangeDetectorRef`
678
- */
679
- function isDefaultChangeDetectionStrategy(changeDetectionStrategy) {
680
- return changeDetectionStrategy == null ||
681
- changeDetectionStrategy === ChangeDetectionStrategy.Default;
682
- }
683
-
684
- /**
685
- * @license
686
- * Copyright Google LLC All Rights Reserved.
687
- *
688
- * Use of this source code is governed by an MIT-style license that can be
689
- * found in the LICENSE file at https://angular.io/license
690
- */
691
- /**
692
- * Defines the CSS styles encapsulation policies for the {@link Component} decorator's
693
- * `encapsulation` option.
694
- *
695
- * See {@link Component#encapsulation encapsulation}.
696
- *
697
- * @usageNotes
698
- * ### Example
699
- *
700
- * {@example core/ts/metadata/encapsulation.ts region='longform'}
701
- *
702
- * @publicApi
703
- */
704
- var ViewEncapsulation$1;
705
- (function (ViewEncapsulation) {
706
- // TODO: consider making `ViewEncapsulation` a `const enum` instead. See
707
- // https://github.com/angular/angular/issues/44119 for additional information.
708
- /**
709
- * Emulates a native Shadow DOM encapsulation behavior by adding a specific attribute to the
710
- * component's host element and applying the same attribute to all the CSS selectors provided
711
- * via {@link Component#styles styles} or {@link Component#styleUrls styleUrls}.
712
- *
713
- * This is the default option.
714
- */
715
- ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated";
716
- // Historically the 1 value was for `Native` encapsulation which has been removed as of v11.
717
- /**
718
- * Doesn't provide any sort of CSS style encapsulation, meaning that all the styles provided
719
- * via {@link Component#styles styles} or {@link Component#styleUrls styleUrls} are applicable
720
- * to any HTML element of the application regardless of their host Component.
721
- */
722
- ViewEncapsulation[ViewEncapsulation["None"] = 2] = "None";
723
- /**
724
- * Uses the browser's native Shadow DOM API to encapsulate CSS styles, meaning that it creates
725
- * a ShadowRoot for the component's host element which is then used to encapsulate
726
- * all the Component's styling.
727
- */
728
- ViewEncapsulation[ViewEncapsulation["ShadowDom"] = 3] = "ShadowDom";
729
- })(ViewEncapsulation$1 || (ViewEncapsulation$1 = {}));
730
-
731
585
  /**
732
586
  * @license
733
587
  * Copyright Google LLC All Rights Reserved.
@@ -826,61 +680,437 @@ function initNgDevMode() {
826
680
  * Use of this source code is governed by an MIT-style license that can be
827
681
  * found in the LICENSE file at https://angular.io/license
828
682
  */
683
+ const _THROW_IF_NOT_FOUND = {};
684
+ const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
685
+ /*
686
+ * Name of a property (that we patch onto DI decorator), which is used as an annotation of which
687
+ * InjectFlag this decorator represents. This allows to avoid direct references to the DI decorators
688
+ * in the code, thus making them tree-shakable.
689
+ */
690
+ const DI_DECORATOR_FLAG = '__NG_DI_FLAG__';
691
+ const NG_TEMP_TOKEN_PATH = 'ngTempTokenPath';
692
+ const NG_TOKEN_PATH = 'ngTokenPath';
693
+ const NEW_LINE = /\n/gm;
694
+ const NO_NEW_LINE = 'ɵ';
695
+ const SOURCE = '__source';
829
696
  /**
830
- * This file contains reuseable "empty" symbols that can be used as default return values
831
- * in different parts of the rendering code. Because the same symbols are returned, this
832
- * allows for identity checks against these values to be consistently used by the framework
833
- * code.
697
+ * Current injector value used by `inject`.
698
+ * - `undefined`: it is an error to call `inject`
699
+ * - `null`: `inject` can be called but there is no injector (limp-mode).
700
+ * - Injector instance: Use the injector for resolution.
834
701
  */
835
- const EMPTY_OBJ = {};
836
- const EMPTY_ARRAY = [];
837
- // freezing the values prevents any code from accidentally inserting new values in
838
- if ((typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode()) {
839
- // These property accesses can be ignored because ngDevMode will be set to false
840
- // when optimizing code and the whole if statement will be dropped.
841
- // tslint:disable-next-line:no-toplevel-property-access
842
- Object.freeze(EMPTY_OBJ);
843
- // tslint:disable-next-line:no-toplevel-property-access
844
- Object.freeze(EMPTY_ARRAY);
702
+ let _currentInjector = undefined;
703
+ function setCurrentInjector(injector) {
704
+ const former = _currentInjector;
705
+ _currentInjector = injector;
706
+ return former;
707
+ }
708
+ function injectInjectorOnly(token, flags = InjectFlags.Default) {
709
+ if (_currentInjector === undefined) {
710
+ throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, ngDevMode &&
711
+ `inject() must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with \`EnvironmentInjector#runInContext\`.`);
712
+ }
713
+ else if (_currentInjector === null) {
714
+ return injectRootLimpMode(token, undefined, flags);
715
+ }
716
+ else {
717
+ return _currentInjector.get(token, flags & InjectFlags.Optional ? null : undefined, flags);
718
+ }
719
+ }
720
+ function ɵɵinject(token, flags = InjectFlags.Default) {
721
+ return (getInjectImplementation() || injectInjectorOnly)(resolveForwardRef(token), flags);
845
722
  }
846
-
847
723
  /**
848
- * @license
849
- * Copyright Google LLC All Rights Reserved.
724
+ * Throws an error indicating that a factory function could not be generated by the compiler for a
725
+ * particular class.
850
726
  *
851
- * Use of this source code is governed by an MIT-style license that can be
852
- * found in the LICENSE file at https://angular.io/license
853
- */
854
- const NG_COMP_DEF = getClosureSafeProperty({ ɵcmp: getClosureSafeProperty });
855
- const NG_DIR_DEF = getClosureSafeProperty({ ɵdir: getClosureSafeProperty });
856
- const NG_PIPE_DEF = getClosureSafeProperty({ ɵpipe: getClosureSafeProperty });
857
- const NG_MOD_DEF = getClosureSafeProperty({ ɵmod: getClosureSafeProperty });
858
- const NG_FACTORY_DEF = getClosureSafeProperty({ ɵfac: getClosureSafeProperty });
859
- /**
860
- * If a directive is diPublic, bloomAdd sets a property on the type with this constant as
861
- * the key and the directive's unique ID as the value. This allows us to map directives to their
862
- * bloom filter bit for DI.
727
+ * The name of the class is not mentioned here, but will be in the generated factory function name
728
+ * and thus in the stack trace.
729
+ *
730
+ * @codeGenApi
863
731
  */
864
- // TODO(misko): This is wrong. The NG_ELEMENT_ID should never be minified.
865
- const NG_ELEMENT_ID = getClosureSafeProperty({ __NG_ELEMENT_ID__: getClosureSafeProperty });
732
+ function ɵɵinvalidFactoryDep(index) {
733
+ throw new RuntimeError(202 /* RuntimeErrorCode.INVALID_FACTORY_DEPENDENCY */, ngDevMode &&
734
+ `This constructor is not compatible with Angular Dependency Injection because its dependency at index ${index} of the parameter list is invalid.
735
+ This can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.
866
736
 
737
+ Please check that 1) the type for the parameter at index ${index} is correct and 2) the correct Angular decorators are defined for this class and its ancestors.`);
738
+ }
867
739
  /**
868
- * @license
869
- * Copyright Google LLC All Rights Reserved.
740
+ * Injects a token from the currently active injector.
741
+ * `inject` is only supported during instantiation of a dependency by the DI system. It can be used
742
+ * during:
743
+ * - Construction (via the `constructor`) of a class being instantiated by the DI system, such
744
+ * as an `@Injectable` or `@Component`.
745
+ * - In the initializer for fields of such classes.
746
+ * - In the factory function specified for `useFactory` of a `Provider` or an `@Injectable`.
747
+ * - In the `factory` function specified for an `InjectionToken`.
870
748
  *
871
- * Use of this source code is governed by an MIT-style license that can be
872
- * found in the LICENSE file at https://angular.io/license
873
- */
874
- /** Counter used to generate unique IDs for component definitions. */
875
- let componentDefCount = 0;
876
- /**
877
- * Create a component definition object.
749
+ * @param token A token that represents a dependency that should be injected.
750
+ * @param flags Optional flags that control how injection is executed.
751
+ * The flags correspond to injection strategies that can be specified with
752
+ * parameter decorators `@Host`, `@Self`, `@SkipSef`, and `@Optional`.
753
+ * @returns the injected value if operation is successful, `null` otherwise.
754
+ * @throws if called outside of a supported context.
878
755
  *
756
+ * @usageNotes
757
+ * In practice the `inject()` calls are allowed in a constructor, a constructor parameter and a
758
+ * field initializer:
879
759
  *
880
- * # Example
881
- * ```
882
- * class MyDirective {
883
- * // Generated by Angular Template Compiler
760
+ * ```typescript
761
+ * @Injectable({providedIn: 'root'})
762
+ * export class Car {
763
+ * radio: Radio|undefined;
764
+ * // OK: field initializer
765
+ * spareTyre = inject(Tyre);
766
+ *
767
+ * constructor() {
768
+ * // OK: constructor body
769
+ * this.radio = inject(Radio);
770
+ * }
771
+ * }
772
+ * ```
773
+ *
774
+ * It is also legal to call `inject` from a provider's factory:
775
+ *
776
+ * ```typescript
777
+ * providers: [
778
+ * {provide: Car, useFactory: () => {
779
+ * // OK: a class factory
780
+ * const engine = inject(Engine);
781
+ * return new Car(engine);
782
+ * }}
783
+ * ]
784
+ * ```
785
+ *
786
+ * Calls to the `inject()` function outside of the class creation context will result in error. Most
787
+ * notably, calls to `inject()` are disallowed after a class instance was created, in methods
788
+ * (including lifecycle hooks):
789
+ *
790
+ * ```typescript
791
+ * @Component({ ... })
792
+ * export class CarComponent {
793
+ * ngOnInit() {
794
+ * // ERROR: too late, the component instance was already created
795
+ * const engine = inject(Engine);
796
+ * engine.start();
797
+ * }
798
+ * }
799
+ * ```
800
+ *
801
+ * @publicApi
802
+ */
803
+ function inject(token, flags = InjectFlags.Default) {
804
+ return ɵɵinject(token, convertToBitFlags(flags));
805
+ }
806
+ // Converts object-based DI flags (`InjectOptions`) to bit flags (`InjectFlags`).
807
+ function convertToBitFlags(flags) {
808
+ if (typeof flags === 'undefined' || typeof flags === 'number') {
809
+ return flags;
810
+ }
811
+ // While TypeScript doesn't accept it without a cast, bitwise OR with false-y values in
812
+ // JavaScript is a no-op. We can use that for a very codesize-efficient conversion from
813
+ // `InjectOptions` to `InjectFlags`.
814
+ return (0 /* InternalInjectFlags.Default */ | // comment to force a line break in the formatter
815
+ (flags.optional && 8 /* InternalInjectFlags.Optional */) |
816
+ (flags.host && 1 /* InternalInjectFlags.Host */) |
817
+ (flags.self && 2 /* InternalInjectFlags.Self */) |
818
+ (flags.skipSelf && 4 /* InternalInjectFlags.SkipSelf */));
819
+ }
820
+ function injectArgs(types) {
821
+ const args = [];
822
+ for (let i = 0; i < types.length; i++) {
823
+ const arg = resolveForwardRef(types[i]);
824
+ if (Array.isArray(arg)) {
825
+ if (arg.length === 0) {
826
+ throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, ngDevMode && 'Arguments array must have arguments.');
827
+ }
828
+ let type = undefined;
829
+ let flags = InjectFlags.Default;
830
+ for (let j = 0; j < arg.length; j++) {
831
+ const meta = arg[j];
832
+ const flag = getInjectFlag(meta);
833
+ if (typeof flag === 'number') {
834
+ // Special case when we handle @Inject decorator.
835
+ if (flag === -1 /* DecoratorFlags.Inject */) {
836
+ type = meta.token;
837
+ }
838
+ else {
839
+ flags |= flag;
840
+ }
841
+ }
842
+ else {
843
+ type = meta;
844
+ }
845
+ }
846
+ args.push(ɵɵinject(type, flags));
847
+ }
848
+ else {
849
+ args.push(ɵɵinject(arg));
850
+ }
851
+ }
852
+ return args;
853
+ }
854
+ /**
855
+ * Attaches a given InjectFlag to a given decorator using monkey-patching.
856
+ * Since DI decorators can be used in providers `deps` array (when provider is configured using
857
+ * `useFactory`) without initialization (e.g. `Host`) and as an instance (e.g. `new Host()`), we
858
+ * attach the flag to make it available both as a static property and as a field on decorator
859
+ * instance.
860
+ *
861
+ * @param decorator Provided DI decorator.
862
+ * @param flag InjectFlag that should be applied.
863
+ */
864
+ function attachInjectFlag(decorator, flag) {
865
+ decorator[DI_DECORATOR_FLAG] = flag;
866
+ decorator.prototype[DI_DECORATOR_FLAG] = flag;
867
+ return decorator;
868
+ }
869
+ /**
870
+ * Reads monkey-patched property that contains InjectFlag attached to a decorator.
871
+ *
872
+ * @param token Token that may contain monkey-patched DI flags property.
873
+ */
874
+ function getInjectFlag(token) {
875
+ return token[DI_DECORATOR_FLAG];
876
+ }
877
+ function catchInjectorError(e, token, injectorErrorName, source) {
878
+ const tokenPath = e[NG_TEMP_TOKEN_PATH];
879
+ if (token[SOURCE]) {
880
+ tokenPath.unshift(token[SOURCE]);
881
+ }
882
+ e.message = formatError('\n' + e.message, tokenPath, injectorErrorName, source);
883
+ e[NG_TOKEN_PATH] = tokenPath;
884
+ e[NG_TEMP_TOKEN_PATH] = null;
885
+ throw e;
886
+ }
887
+ function formatError(text, obj, injectorErrorName, source = null) {
888
+ text = text && text.charAt(0) === '\n' && text.charAt(1) == NO_NEW_LINE ? text.slice(2) : text;
889
+ let context = stringify(obj);
890
+ if (Array.isArray(obj)) {
891
+ context = obj.map(stringify).join(' -> ');
892
+ }
893
+ else if (typeof obj === 'object') {
894
+ let parts = [];
895
+ for (let key in obj) {
896
+ if (obj.hasOwnProperty(key)) {
897
+ let value = obj[key];
898
+ parts.push(key + ':' + (typeof value === 'string' ? JSON.stringify(value) : stringify(value)));
899
+ }
900
+ }
901
+ context = `{${parts.join(', ')}}`;
902
+ }
903
+ return `${injectorErrorName}${source ? '(' + source + ')' : ''}[${context}]: ${text.replace(NEW_LINE, '\n ')}`;
904
+ }
905
+
906
+ /**
907
+ * @license
908
+ * Copyright Google LLC All Rights Reserved.
909
+ *
910
+ * Use of this source code is governed by an MIT-style license that can be
911
+ * found in the LICENSE file at https://angular.io/license
912
+ */
913
+ /**
914
+ * Convince closure compiler that the wrapped function has no side-effects.
915
+ *
916
+ * Closure compiler always assumes that `toString` has no side-effects. We use this quirk to
917
+ * allow us to execute a function but have closure compiler mark the call as no-side-effects.
918
+ * It is important that the return value for the `noSideEffects` function be assigned
919
+ * to something which is retained otherwise the call to `noSideEffects` will be removed by closure
920
+ * compiler.
921
+ */
922
+ function noSideEffects(fn) {
923
+ return { toString: fn }.toString();
924
+ }
925
+
926
+ /**
927
+ * @license
928
+ * Copyright Google LLC All Rights Reserved.
929
+ *
930
+ * Use of this source code is governed by an MIT-style license that can be
931
+ * found in the LICENSE file at https://angular.io/license
932
+ */
933
+ /**
934
+ * The strategy that the default change detector uses to detect changes.
935
+ * When set, takes effect the next time change detection is triggered.
936
+ *
937
+ * @see {@link ChangeDetectorRef#usage-notes Change detection usage}
938
+ *
939
+ * @publicApi
940
+ */
941
+ var ChangeDetectionStrategy;
942
+ (function (ChangeDetectionStrategy) {
943
+ /**
944
+ * Use the `CheckOnce` strategy, meaning that automatic change detection is deactivated
945
+ * until reactivated by setting the strategy to `Default` (`CheckAlways`).
946
+ * Change detection can still be explicitly invoked.
947
+ * This strategy applies to all child directives and cannot be overridden.
948
+ */
949
+ ChangeDetectionStrategy[ChangeDetectionStrategy["OnPush"] = 0] = "OnPush";
950
+ /**
951
+ * Use the default `CheckAlways` strategy, in which change detection is automatic until
952
+ * explicitly deactivated.
953
+ */
954
+ ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default";
955
+ })(ChangeDetectionStrategy || (ChangeDetectionStrategy = {}));
956
+ /**
957
+ * Defines the possible states of the default change detector.
958
+ * @see `ChangeDetectorRef`
959
+ */
960
+ var ChangeDetectorStatus;
961
+ (function (ChangeDetectorStatus) {
962
+ /**
963
+ * A state in which, after calling `detectChanges()`, the change detector
964
+ * state becomes `Checked`, and must be explicitly invoked or reactivated.
965
+ */
966
+ ChangeDetectorStatus[ChangeDetectorStatus["CheckOnce"] = 0] = "CheckOnce";
967
+ /**
968
+ * A state in which change detection is skipped until the change detector mode
969
+ * becomes `CheckOnce`.
970
+ */
971
+ ChangeDetectorStatus[ChangeDetectorStatus["Checked"] = 1] = "Checked";
972
+ /**
973
+ * A state in which change detection continues automatically until explicitly
974
+ * deactivated.
975
+ */
976
+ ChangeDetectorStatus[ChangeDetectorStatus["CheckAlways"] = 2] = "CheckAlways";
977
+ /**
978
+ * A state in which a change detector sub tree is not a part of the main tree and
979
+ * should be skipped.
980
+ */
981
+ ChangeDetectorStatus[ChangeDetectorStatus["Detached"] = 3] = "Detached";
982
+ /**
983
+ * Indicates that the change detector encountered an error checking a binding
984
+ * or calling a directive lifecycle method and is now in an inconsistent state. Change
985
+ * detectors in this state do not detect changes.
986
+ */
987
+ ChangeDetectorStatus[ChangeDetectorStatus["Errored"] = 4] = "Errored";
988
+ /**
989
+ * Indicates that the change detector has been destroyed.
990
+ */
991
+ ChangeDetectorStatus[ChangeDetectorStatus["Destroyed"] = 5] = "Destroyed";
992
+ })(ChangeDetectorStatus || (ChangeDetectorStatus = {}));
993
+ /**
994
+ * Reports whether a given strategy is currently the default for change detection.
995
+ * @param changeDetectionStrategy The strategy to check.
996
+ * @returns True if the given strategy is the current default, false otherwise.
997
+ * @see `ChangeDetectorStatus`
998
+ * @see `ChangeDetectorRef`
999
+ */
1000
+ function isDefaultChangeDetectionStrategy(changeDetectionStrategy) {
1001
+ return changeDetectionStrategy == null ||
1002
+ changeDetectionStrategy === ChangeDetectionStrategy.Default;
1003
+ }
1004
+
1005
+ /**
1006
+ * @license
1007
+ * Copyright Google LLC All Rights Reserved.
1008
+ *
1009
+ * Use of this source code is governed by an MIT-style license that can be
1010
+ * found in the LICENSE file at https://angular.io/license
1011
+ */
1012
+ /**
1013
+ * Defines the CSS styles encapsulation policies for the {@link Component} decorator's
1014
+ * `encapsulation` option.
1015
+ *
1016
+ * See {@link Component#encapsulation encapsulation}.
1017
+ *
1018
+ * @usageNotes
1019
+ * ### Example
1020
+ *
1021
+ * {@example core/ts/metadata/encapsulation.ts region='longform'}
1022
+ *
1023
+ * @publicApi
1024
+ */
1025
+ var ViewEncapsulation$1;
1026
+ (function (ViewEncapsulation) {
1027
+ // TODO: consider making `ViewEncapsulation` a `const enum` instead. See
1028
+ // https://github.com/angular/angular/issues/44119 for additional information.
1029
+ /**
1030
+ * Emulates a native Shadow DOM encapsulation behavior by adding a specific attribute to the
1031
+ * component's host element and applying the same attribute to all the CSS selectors provided
1032
+ * via {@link Component#styles styles} or {@link Component#styleUrls styleUrls}.
1033
+ *
1034
+ * This is the default option.
1035
+ */
1036
+ ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated";
1037
+ // Historically the 1 value was for `Native` encapsulation which has been removed as of v11.
1038
+ /**
1039
+ * Doesn't provide any sort of CSS style encapsulation, meaning that all the styles provided
1040
+ * via {@link Component#styles styles} or {@link Component#styleUrls styleUrls} are applicable
1041
+ * to any HTML element of the application regardless of their host Component.
1042
+ */
1043
+ ViewEncapsulation[ViewEncapsulation["None"] = 2] = "None";
1044
+ /**
1045
+ * Uses the browser's native Shadow DOM API to encapsulate CSS styles, meaning that it creates
1046
+ * a ShadowRoot for the component's host element which is then used to encapsulate
1047
+ * all the Component's styling.
1048
+ */
1049
+ ViewEncapsulation[ViewEncapsulation["ShadowDom"] = 3] = "ShadowDom";
1050
+ })(ViewEncapsulation$1 || (ViewEncapsulation$1 = {}));
1051
+
1052
+ /**
1053
+ * @license
1054
+ * Copyright Google LLC All Rights Reserved.
1055
+ *
1056
+ * Use of this source code is governed by an MIT-style license that can be
1057
+ * found in the LICENSE file at https://angular.io/license
1058
+ */
1059
+ /**
1060
+ * This file contains reuseable "empty" symbols that can be used as default return values
1061
+ * in different parts of the rendering code. Because the same symbols are returned, this
1062
+ * allows for identity checks against these values to be consistently used by the framework
1063
+ * code.
1064
+ */
1065
+ const EMPTY_OBJ = {};
1066
+ const EMPTY_ARRAY = [];
1067
+ // freezing the values prevents any code from accidentally inserting new values in
1068
+ if ((typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode()) {
1069
+ // These property accesses can be ignored because ngDevMode will be set to false
1070
+ // when optimizing code and the whole if statement will be dropped.
1071
+ // tslint:disable-next-line:no-toplevel-property-access
1072
+ Object.freeze(EMPTY_OBJ);
1073
+ // tslint:disable-next-line:no-toplevel-property-access
1074
+ Object.freeze(EMPTY_ARRAY);
1075
+ }
1076
+
1077
+ /**
1078
+ * @license
1079
+ * Copyright Google LLC All Rights Reserved.
1080
+ *
1081
+ * Use of this source code is governed by an MIT-style license that can be
1082
+ * found in the LICENSE file at https://angular.io/license
1083
+ */
1084
+ const NG_COMP_DEF = getClosureSafeProperty({ ɵcmp: getClosureSafeProperty });
1085
+ const NG_DIR_DEF = getClosureSafeProperty({ ɵdir: getClosureSafeProperty });
1086
+ const NG_PIPE_DEF = getClosureSafeProperty({ ɵpipe: getClosureSafeProperty });
1087
+ const NG_MOD_DEF = getClosureSafeProperty({ ɵmod: getClosureSafeProperty });
1088
+ const NG_FACTORY_DEF = getClosureSafeProperty({ ɵfac: getClosureSafeProperty });
1089
+ /**
1090
+ * If a directive is diPublic, bloomAdd sets a property on the type with this constant as
1091
+ * the key and the directive's unique ID as the value. This allows us to map directives to their
1092
+ * bloom filter bit for DI.
1093
+ */
1094
+ // TODO(misko): This is wrong. The NG_ELEMENT_ID should never be minified.
1095
+ const NG_ELEMENT_ID = getClosureSafeProperty({ __NG_ELEMENT_ID__: getClosureSafeProperty });
1096
+
1097
+ /**
1098
+ * @license
1099
+ * Copyright Google LLC All Rights Reserved.
1100
+ *
1101
+ * Use of this source code is governed by an MIT-style license that can be
1102
+ * found in the LICENSE file at https://angular.io/license
1103
+ */
1104
+ /** Counter used to generate unique IDs for component definitions. */
1105
+ let componentDefCount = 0;
1106
+ /**
1107
+ * Create a component definition object.
1108
+ *
1109
+ *
1110
+ * # Example
1111
+ * ```
1112
+ * class MyDirective {
1113
+ * // Generated by Angular Template Compiler
884
1114
  * // [Symbol] syntax will not be supported by TypeScript until v2.7
885
1115
  * static ɵcmp = defineComponent({
886
1116
  * ...
@@ -931,7 +1161,8 @@ function ɵɵdefineComponent(componentDefinition) {
931
1161
  setInput: null,
932
1162
  schemas: componentDefinition.schemas || null,
933
1163
  tView: null,
934
- applyHostDirectives: null,
1164
+ findHostDirectiveDefs: null,
1165
+ hostDirectives: null,
935
1166
  };
936
1167
  const dependencies = componentDefinition.dependencies;
937
1168
  const feature = componentDefinition.features;
@@ -1272,10 +1503,10 @@ function isLContainer(value) {
1272
1503
  return Array.isArray(value) && value[TYPE] === true;
1273
1504
  }
1274
1505
  function isContentQueryHost(tNode) {
1275
- return (tNode.flags & 8 /* TNodeFlags.hasContentQuery */) !== 0;
1506
+ return (tNode.flags & 4 /* TNodeFlags.hasContentQuery */) !== 0;
1276
1507
  }
1277
1508
  function isComponentHost(tNode) {
1278
- return (tNode.flags & 2 /* TNodeFlags.isComponentHost */) === 2 /* TNodeFlags.isComponentHost */;
1509
+ return tNode.componentOffset > -1;
1279
1510
  }
1280
1511
  function isDirectiveHost(tNode) {
1281
1512
  return (tNode.flags & 1 /* TNodeFlags.isDirectiveHost */) === 1 /* TNodeFlags.isDirectiveHost */;
@@ -2685,7 +2916,7 @@ const unusedValueExportToPlacateAjd$5 = 1;
2685
2916
  * @param tNode
2686
2917
  */
2687
2918
  function hasClassInput(tNode) {
2688
- return (tNode.flags & 16 /* TNodeFlags.hasClassInput */) !== 0;
2919
+ return (tNode.flags & 8 /* TNodeFlags.hasClassInput */) !== 0;
2689
2920
  }
2690
2921
  /**
2691
2922
  * Returns `true` if the `TNode` has a directive which has `@Input()` for `style` binding.
@@ -2709,7 +2940,7 @@ function hasClassInput(tNode) {
2709
2940
  * @param tNode
2710
2941
  */
2711
2942
  function hasStyleInput(tNode) {
2712
- return (tNode.flags & 32 /* TNodeFlags.hasStyleInput */) !== 0;
2943
+ return (tNode.flags & 16 /* TNodeFlags.hasStyleInput */) !== 0;
2713
2944
  }
2714
2945
 
2715
2946
  /**
@@ -3601,7 +3832,7 @@ class NodeInjector {
3601
3832
  this._lView = _lView;
3602
3833
  }
3603
3834
  get(token, notFoundValue, flags) {
3604
- return getOrCreateInjectable(this._tNode, this._lView, token, flags, notFoundValue);
3835
+ return getOrCreateInjectable(this._tNode, this._lView, token, convertToBitFlags(flags), notFoundValue);
3605
3836
  }
3606
3837
  }
3607
3838
  /** Creates a `NodeInjector` for the current node. */
@@ -4698,271 +4929,45 @@ class ReflectionCapabilities {
4698
4929
  });
4699
4930
  }
4700
4931
  const ownPropMetadata = this._ownPropMetadata(typeOrFunc, parentCtor);
4701
- if (ownPropMetadata) {
4702
- Object.keys(ownPropMetadata).forEach((propName) => {
4703
- const decorators = [];
4704
- if (propMetadata.hasOwnProperty(propName)) {
4705
- decorators.push(...propMetadata[propName]);
4706
- }
4707
- decorators.push(...ownPropMetadata[propName]);
4708
- propMetadata[propName] = decorators;
4709
- });
4710
- }
4711
- return propMetadata;
4712
- }
4713
- ownPropMetadata(typeOrFunc) {
4714
- if (!isType(typeOrFunc)) {
4715
- return {};
4716
- }
4717
- return this._ownPropMetadata(typeOrFunc, getParentCtor(typeOrFunc)) || {};
4718
- }
4719
- hasLifecycleHook(type, lcProperty) {
4720
- return type instanceof Type && lcProperty in type.prototype;
4721
- }
4722
- }
4723
- function convertTsickleDecoratorIntoMetadata(decoratorInvocations) {
4724
- if (!decoratorInvocations) {
4725
- return [];
4726
- }
4727
- return decoratorInvocations.map(decoratorInvocation => {
4728
- const decoratorType = decoratorInvocation.type;
4729
- const annotationCls = decoratorType.annotationCls;
4730
- const annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
4731
- return new annotationCls(...annotationArgs);
4732
- });
4733
- }
4734
- function getParentCtor(ctor) {
4735
- const parentProto = ctor.prototype ? Object.getPrototypeOf(ctor.prototype) : null;
4736
- const parentCtor = parentProto ? parentProto.constructor : null;
4737
- // Note: We always use `Object` as the null value
4738
- // to simplify checking later on.
4739
- return parentCtor || Object;
4740
- }
4741
-
4742
- /**
4743
- * @license
4744
- * Copyright Google LLC All Rights Reserved.
4745
- *
4746
- * Use of this source code is governed by an MIT-style license that can be
4747
- * found in the LICENSE file at https://angular.io/license
4748
- */
4749
- const _THROW_IF_NOT_FOUND = {};
4750
- const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
4751
- /*
4752
- * Name of a property (that we patch onto DI decorator), which is used as an annotation of which
4753
- * InjectFlag this decorator represents. This allows to avoid direct references to the DI decorators
4754
- * in the code, thus making them tree-shakable.
4755
- */
4756
- const DI_DECORATOR_FLAG = '__NG_DI_FLAG__';
4757
- const NG_TEMP_TOKEN_PATH = 'ngTempTokenPath';
4758
- const NG_TOKEN_PATH = 'ngTokenPath';
4759
- const NEW_LINE = /\n/gm;
4760
- const NO_NEW_LINE = 'ɵ';
4761
- const SOURCE = '__source';
4762
- /**
4763
- * Current injector value used by `inject`.
4764
- * - `undefined`: it is an error to call `inject`
4765
- * - `null`: `inject` can be called but there is no injector (limp-mode).
4766
- * - Injector instance: Use the injector for resolution.
4767
- */
4768
- let _currentInjector = undefined;
4769
- function setCurrentInjector(injector) {
4770
- const former = _currentInjector;
4771
- _currentInjector = injector;
4772
- return former;
4773
- }
4774
- function injectInjectorOnly(token, flags = InjectFlags.Default) {
4775
- if (_currentInjector === undefined) {
4776
- throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, ngDevMode &&
4777
- `inject() must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with \`EnvironmentInjector#runInContext\`.`);
4778
- }
4779
- else if (_currentInjector === null) {
4780
- return injectRootLimpMode(token, undefined, flags);
4781
- }
4782
- else {
4783
- return _currentInjector.get(token, flags & InjectFlags.Optional ? null : undefined, flags);
4784
- }
4785
- }
4786
- function ɵɵinject(token, flags = InjectFlags.Default) {
4787
- return (getInjectImplementation() || injectInjectorOnly)(resolveForwardRef(token), flags);
4788
- }
4789
- /**
4790
- * Throws an error indicating that a factory function could not be generated by the compiler for a
4791
- * particular class.
4792
- *
4793
- * The name of the class is not mentioned here, but will be in the generated factory function name
4794
- * and thus in the stack trace.
4795
- *
4796
- * @codeGenApi
4797
- */
4798
- function ɵɵinvalidFactoryDep(index) {
4799
- throw new RuntimeError(202 /* RuntimeErrorCode.INVALID_FACTORY_DEPENDENCY */, ngDevMode &&
4800
- `This constructor is not compatible with Angular Dependency Injection because its dependency at index ${index} of the parameter list is invalid.
4801
- This can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.
4802
-
4803
- Please check that 1) the type for the parameter at index ${index} is correct and 2) the correct Angular decorators are defined for this class and its ancestors.`);
4804
- }
4805
- /**
4806
- * Injects a token from the currently active injector.
4807
- * `inject` is only supported during instantiation of a dependency by the DI system. It can be used
4808
- * during:
4809
- * - Construction (via the `constructor`) of a class being instantiated by the DI system, such
4810
- * as an `@Injectable` or `@Component`.
4811
- * - In the initializer for fields of such classes.
4812
- * - In the factory function specified for `useFactory` of a `Provider` or an `@Injectable`.
4813
- * - In the `factory` function specified for an `InjectionToken`.
4814
- *
4815
- * @param token A token that represents a dependency that should be injected.
4816
- * @param flags Optional flags that control how injection is executed.
4817
- * The flags correspond to injection strategies that can be specified with
4818
- * parameter decorators `@Host`, `@Self`, `@SkipSef`, and `@Optional`.
4819
- * @returns the injected value if operation is successful, `null` otherwise.
4820
- * @throws if called outside of a supported context.
4821
- *
4822
- * @usageNotes
4823
- * In practice the `inject()` calls are allowed in a constructor, a constructor parameter and a
4824
- * field initializer:
4825
- *
4826
- * ```typescript
4827
- * @Injectable({providedIn: 'root'})
4828
- * export class Car {
4829
- * radio: Radio|undefined;
4830
- * // OK: field initializer
4831
- * spareTyre = inject(Tyre);
4832
- *
4833
- * constructor() {
4834
- * // OK: constructor body
4835
- * this.radio = inject(Radio);
4836
- * }
4837
- * }
4838
- * ```
4839
- *
4840
- * It is also legal to call `inject` from a provider's factory:
4841
- *
4842
- * ```typescript
4843
- * providers: [
4844
- * {provide: Car, useFactory: () => {
4845
- * // OK: a class factory
4846
- * const engine = inject(Engine);
4847
- * return new Car(engine);
4848
- * }}
4849
- * ]
4850
- * ```
4851
- *
4852
- * Calls to the `inject()` function outside of the class creation context will result in error. Most
4853
- * notably, calls to `inject()` are disallowed after a class instance was created, in methods
4854
- * (including lifecycle hooks):
4855
- *
4856
- * ```typescript
4857
- * @Component({ ... })
4858
- * export class CarComponent {
4859
- * ngOnInit() {
4860
- * // ERROR: too late, the component instance was already created
4861
- * const engine = inject(Engine);
4862
- * engine.start();
4863
- * }
4864
- * }
4865
- * ```
4866
- *
4867
- * @publicApi
4868
- */
4869
- function inject(token, flags = InjectFlags.Default) {
4870
- if (typeof flags !== 'number') {
4871
- // While TypeScript doesn't accept it without a cast, bitwise OR with false-y values in
4872
- // JavaScript is a no-op. We can use that for a very codesize-efficient conversion from
4873
- // `InjectOptions` to `InjectFlags`.
4874
- flags = (0 /* InternalInjectFlags.Default */ | // comment to force a line break in the formatter
4875
- (flags.optional && 8 /* InternalInjectFlags.Optional */) |
4876
- (flags.host && 1 /* InternalInjectFlags.Host */) |
4877
- (flags.self && 2 /* InternalInjectFlags.Self */) |
4878
- (flags.skipSelf && 4 /* InternalInjectFlags.SkipSelf */));
4879
- }
4880
- return ɵɵinject(token, flags);
4881
- }
4882
- function injectArgs(types) {
4883
- const args = [];
4884
- for (let i = 0; i < types.length; i++) {
4885
- const arg = resolveForwardRef(types[i]);
4886
- if (Array.isArray(arg)) {
4887
- if (arg.length === 0) {
4888
- throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, ngDevMode && 'Arguments array must have arguments.');
4889
- }
4890
- let type = undefined;
4891
- let flags = InjectFlags.Default;
4892
- for (let j = 0; j < arg.length; j++) {
4893
- const meta = arg[j];
4894
- const flag = getInjectFlag(meta);
4895
- if (typeof flag === 'number') {
4896
- // Special case when we handle @Inject decorator.
4897
- if (flag === -1 /* DecoratorFlags.Inject */) {
4898
- type = meta.token;
4899
- }
4900
- else {
4901
- flags |= flag;
4902
- }
4903
- }
4904
- else {
4905
- type = meta;
4932
+ if (ownPropMetadata) {
4933
+ Object.keys(ownPropMetadata).forEach((propName) => {
4934
+ const decorators = [];
4935
+ if (propMetadata.hasOwnProperty(propName)) {
4936
+ decorators.push(...propMetadata[propName]);
4906
4937
  }
4907
- }
4908
- args.push(ɵɵinject(type, flags));
4938
+ decorators.push(...ownPropMetadata[propName]);
4939
+ propMetadata[propName] = decorators;
4940
+ });
4909
4941
  }
4910
- else {
4911
- args.push(ɵɵinject(arg));
4942
+ return propMetadata;
4943
+ }
4944
+ ownPropMetadata(typeOrFunc) {
4945
+ if (!isType(typeOrFunc)) {
4946
+ return {};
4912
4947
  }
4948
+ return this._ownPropMetadata(typeOrFunc, getParentCtor(typeOrFunc)) || {};
4913
4949
  }
4914
- return args;
4915
- }
4916
- /**
4917
- * Attaches a given InjectFlag to a given decorator using monkey-patching.
4918
- * Since DI decorators can be used in providers `deps` array (when provider is configured using
4919
- * `useFactory`) without initialization (e.g. `Host`) and as an instance (e.g. `new Host()`), we
4920
- * attach the flag to make it available both as a static property and as a field on decorator
4921
- * instance.
4922
- *
4923
- * @param decorator Provided DI decorator.
4924
- * @param flag InjectFlag that should be applied.
4925
- */
4926
- function attachInjectFlag(decorator, flag) {
4927
- decorator[DI_DECORATOR_FLAG] = flag;
4928
- decorator.prototype[DI_DECORATOR_FLAG] = flag;
4929
- return decorator;
4930
- }
4931
- /**
4932
- * Reads monkey-patched property that contains InjectFlag attached to a decorator.
4933
- *
4934
- * @param token Token that may contain monkey-patched DI flags property.
4935
- */
4936
- function getInjectFlag(token) {
4937
- return token[DI_DECORATOR_FLAG];
4938
- }
4939
- function catchInjectorError(e, token, injectorErrorName, source) {
4940
- const tokenPath = e[NG_TEMP_TOKEN_PATH];
4941
- if (token[SOURCE]) {
4942
- tokenPath.unshift(token[SOURCE]);
4950
+ hasLifecycleHook(type, lcProperty) {
4951
+ return type instanceof Type && lcProperty in type.prototype;
4943
4952
  }
4944
- e.message = formatError('\n' + e.message, tokenPath, injectorErrorName, source);
4945
- e[NG_TOKEN_PATH] = tokenPath;
4946
- e[NG_TEMP_TOKEN_PATH] = null;
4947
- throw e;
4948
4953
  }
4949
- function formatError(text, obj, injectorErrorName, source = null) {
4950
- text = text && text.charAt(0) === '\n' && text.charAt(1) == NO_NEW_LINE ? text.slice(2) : text;
4951
- let context = stringify(obj);
4952
- if (Array.isArray(obj)) {
4953
- context = obj.map(stringify).join(' -> ');
4954
- }
4955
- else if (typeof obj === 'object') {
4956
- let parts = [];
4957
- for (let key in obj) {
4958
- if (obj.hasOwnProperty(key)) {
4959
- let value = obj[key];
4960
- parts.push(key + ':' + (typeof value === 'string' ? JSON.stringify(value) : stringify(value)));
4961
- }
4962
- }
4963
- context = `{${parts.join(', ')}}`;
4954
+ function convertTsickleDecoratorIntoMetadata(decoratorInvocations) {
4955
+ if (!decoratorInvocations) {
4956
+ return [];
4964
4957
  }
4965
- return `${injectorErrorName}${source ? '(' + source + ')' : ''}[${context}]: ${text.replace(NEW_LINE, '\n ')}`;
4958
+ return decoratorInvocations.map(decoratorInvocation => {
4959
+ const decoratorType = decoratorInvocation.type;
4960
+ const annotationCls = decoratorType.annotationCls;
4961
+ const annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
4962
+ return new annotationCls(...annotationArgs);
4963
+ });
4964
+ }
4965
+ function getParentCtor(ctor) {
4966
+ const parentProto = ctor.prototype ? Object.getPrototypeOf(ctor.prototype) : null;
4967
+ const parentCtor = parentProto ? parentProto.constructor : null;
4968
+ // Note: We always use `Object` as the null value
4969
+ // to simplify checking later on.
4970
+ return parentCtor || Object;
4966
4971
  }
4967
4972
 
4968
4973
  /**
@@ -6749,6 +6754,7 @@ class R3Injector extends EnvironmentInjector {
6749
6754
  }
6750
6755
  get(token, notFoundValue = THROW_IF_NOT_FOUND, flags = InjectFlags.Default) {
6751
6756
  this.assertNotDestroyed();
6757
+ flags = convertToBitFlags(flags);
6752
6758
  // Set the injection context.
6753
6759
  const previousInjector = setCurrentInjector(this);
6754
6760
  const previousInjectImplementation = setInjectImplementation(undefined);
@@ -7250,7 +7256,7 @@ class Version {
7250
7256
  /**
7251
7257
  * @publicApi
7252
7258
  */
7253
- const VERSION = new Version('15.0.0-next.2');
7259
+ const VERSION = new Version('15.0.0-next.4');
7254
7260
 
7255
7261
  /**
7256
7262
  * @license
@@ -7285,29 +7291,70 @@ const NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = {};
7285
7291
  * Use of this source code is governed by an MIT-style license that can be
7286
7292
  * found in the LICENSE file at https://angular.io/license
7287
7293
  */
7294
+ // Keeps track of the currently-active LViews.
7295
+ const TRACKED_LVIEWS = new Map();
7296
+ // Used for generating unique IDs for LViews.
7297
+ let uniqueIdCounter = 0;
7298
+ /** Gets a unique ID that can be assigned to an LView. */
7299
+ function getUniqueLViewId() {
7300
+ return uniqueIdCounter++;
7301
+ }
7302
+ /** Starts tracking an LView. */
7303
+ function registerLView(lView) {
7304
+ ngDevMode && assertNumber(lView[ID], 'LView must have an ID in order to be registered');
7305
+ TRACKED_LVIEWS.set(lView[ID], lView);
7306
+ }
7307
+ /** Gets an LView by its unique ID. */
7308
+ function getLViewById(id) {
7309
+ ngDevMode && assertNumber(id, 'ID used for LView lookup must be a number');
7310
+ return TRACKED_LVIEWS.get(id) || null;
7311
+ }
7312
+ /** Stops tracking an LView. */
7313
+ function unregisterLView(lView) {
7314
+ ngDevMode && assertNumber(lView[ID], 'Cannot stop tracking an LView that does not have an ID');
7315
+ TRACKED_LVIEWS.delete(lView[ID]);
7316
+ }
7317
+
7288
7318
  /**
7289
- * Defines a schema that allows an NgModule to contain the following:
7290
- * - Non-Angular elements named with dash case (`-`).
7291
- * - Element properties named with dash case (`-`).
7292
- * Dash case is the naming convention for custom elements.
7319
+ * @license
7320
+ * Copyright Google LLC All Rights Reserved.
7293
7321
  *
7294
- * @publicApi
7322
+ * Use of this source code is governed by an MIT-style license that can be
7323
+ * found in the LICENSE file at https://angular.io/license
7295
7324
  */
7296
- const CUSTOM_ELEMENTS_SCHEMA = {
7297
- name: 'custom-elements'
7298
- };
7299
7325
  /**
7300
- * Defines a schema that allows any property on any element.
7301
- *
7302
- * This schema allows you to ignore the errors related to any unknown elements or properties in a
7303
- * template. The usage of this schema is generally discouraged because it prevents useful validation
7304
- * and may hide real errors in your template. Consider using the `CUSTOM_ELEMENTS_SCHEMA` instead.
7326
+ * The internal view context which is specific to a given DOM element, directive or
7327
+ * component instance. Each value in here (besides the LView and element node details)
7328
+ * can be present, null or undefined. If undefined then it implies the value has not been
7329
+ * looked up yet, otherwise, if null, then a lookup was executed and nothing was found.
7305
7330
  *
7306
- * @publicApi
7331
+ * Each value will get filled when the respective value is examined within the getContext
7332
+ * function. The component, element and each directive instance will share the same instance
7333
+ * of the context.
7307
7334
  */
7308
- const NO_ERRORS_SCHEMA = {
7309
- name: 'no-errors-schema'
7310
- };
7335
+ class LContext {
7336
+ constructor(
7337
+ /**
7338
+ * ID of the component's parent view data.
7339
+ */
7340
+ lViewId,
7341
+ /**
7342
+ * The index instance of the node.
7343
+ */
7344
+ nodeIndex,
7345
+ /**
7346
+ * The instance of the DOM node that is attached to the lNode.
7347
+ */
7348
+ native) {
7349
+ this.lViewId = lViewId;
7350
+ this.nodeIndex = nodeIndex;
7351
+ this.native = native;
7352
+ }
7353
+ /** Component's parent view data. */
7354
+ get lView() {
7355
+ return getLViewById(this.lViewId);
7356
+ }
7357
+ }
7311
7358
 
7312
7359
  /**
7313
7360
  * @license
@@ -7316,442 +7363,305 @@ const NO_ERRORS_SCHEMA = {
7316
7363
  * Use of this source code is governed by an MIT-style license that can be
7317
7364
  * found in the LICENSE file at https://angular.io/license
7318
7365
  */
7319
- let shouldThrowErrorOnUnknownElement = false;
7320
- /**
7321
- * Sets a strict mode for JIT-compiled components to throw an error on unknown elements,
7322
- * instead of just logging the error.
7323
- * (for AOT-compiled ones this check happens at build time).
7324
- */
7325
- function ɵsetUnknownElementStrictMode(shouldThrow) {
7326
- shouldThrowErrorOnUnknownElement = shouldThrow;
7327
- }
7328
- /**
7329
- * Gets the current value of the strict mode.
7330
- */
7331
- function ɵgetUnknownElementStrictMode() {
7332
- return shouldThrowErrorOnUnknownElement;
7333
- }
7334
- let shouldThrowErrorOnUnknownProperty = false;
7335
7366
  /**
7336
- * Sets a strict mode for JIT-compiled components to throw an error on unknown properties,
7337
- * instead of just logging the error.
7338
- * (for AOT-compiled ones this check happens at build time).
7339
- */
7340
- function ɵsetUnknownPropertyStrictMode(shouldThrow) {
7341
- shouldThrowErrorOnUnknownProperty = shouldThrow;
7342
- }
7343
- /**
7344
- * Gets the current value of the strict mode.
7345
- */
7346
- function ɵgetUnknownPropertyStrictMode() {
7347
- return shouldThrowErrorOnUnknownProperty;
7348
- }
7349
- /**
7350
- * Validates that the element is known at runtime and produces
7351
- * an error if it's not the case.
7352
- * This check is relevant for JIT-compiled components (for AOT-compiled
7353
- * ones this check happens at build time).
7367
+ * Returns the matching `LContext` data for a given DOM node, directive or component instance.
7354
7368
  *
7355
- * The element is considered known if either:
7356
- * - it's a known HTML element
7357
- * - it's a known custom element
7358
- * - the element matches any directive
7359
- * - the element is allowed by one of the schemas
7369
+ * This function will examine the provided DOM element, component, or directive instance\'s
7370
+ * monkey-patched property to derive the `LContext` data. Once called then the monkey-patched
7371
+ * value will be that of the newly created `LContext`.
7360
7372
  *
7361
- * @param element Element to validate
7362
- * @param lView An `LView` that represents a current component that is being rendered
7363
- * @param tagName Name of the tag to check
7364
- * @param schemas Array of schemas
7365
- * @param hasDirectives Boolean indicating that the element matches any directive
7373
+ * If the monkey-patched value is the `LView` instance then the context value for that
7374
+ * target will be created and the monkey-patch reference will be updated. Therefore when this
7375
+ * function is called it may mutate the provided element\'s, component\'s or any of the associated
7376
+ * directive\'s monkey-patch values.
7377
+ *
7378
+ * If the monkey-patch value is not detected then the code will walk up the DOM until an element
7379
+ * is found which contains a monkey-patch reference. When that occurs then the provided element
7380
+ * will be updated with a new context (which is then returned). If the monkey-patch value is not
7381
+ * detected for a component/directive instance then it will throw an error (all components and
7382
+ * directives should be automatically monkey-patched by ivy).
7383
+ *
7384
+ * @param target Component, Directive or DOM Node.
7366
7385
  */
7367
- function validateElementIsKnown(element, lView, tagName, schemas, hasDirectives) {
7368
- // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
7369
- // mode where this check happens at compile time. In JIT mode, `schemas` is always present and
7370
- // defined as an array (as an empty array in case `schemas` field is not defined) and we should
7371
- // execute the check below.
7372
- if (schemas === null)
7373
- return;
7374
- // If the element matches any directive, it's considered as valid.
7375
- if (!hasDirectives && tagName !== null) {
7376
- // The element is unknown if it's an instance of HTMLUnknownElement, or it isn't registered
7377
- // as a custom element. Note that unknown elements with a dash in their name won't be instances
7378
- // of HTMLUnknownElement in browsers that support web components.
7379
- const isUnknown =
7380
- // Note that we can't check for `typeof HTMLUnknownElement === 'function'`,
7381
- // because while most browsers return 'function', IE returns 'object'.
7382
- (typeof HTMLUnknownElement !== 'undefined' && HTMLUnknownElement &&
7383
- element instanceof HTMLUnknownElement) ||
7384
- (typeof customElements !== 'undefined' && tagName.indexOf('-') > -1 &&
7385
- !customElements.get(tagName));
7386
- if (isUnknown && !matchingSchemas(schemas, tagName)) {
7387
- const isHostStandalone = isHostComponentStandalone(lView);
7388
- const templateLocation = getTemplateLocationDetails(lView);
7389
- const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
7390
- let message = `'${tagName}' is not a known element${templateLocation}:\n`;
7391
- message += `1. If '${tagName}' is an Angular component, then verify that it is ${isHostStandalone ? 'included in the \'@Component.imports\' of this component' :
7392
- 'a part of an @NgModule where this component is declared'}.\n`;
7393
- if (tagName && tagName.indexOf('-') > -1) {
7394
- message +=
7395
- `2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the ${schemas} of this component to suppress this message.`;
7386
+ function getLContext(target) {
7387
+ let mpValue = readPatchedData(target);
7388
+ if (mpValue) {
7389
+ // only when it's an array is it considered an LView instance
7390
+ // ... otherwise it's an already constructed LContext instance
7391
+ if (isLView(mpValue)) {
7392
+ const lView = mpValue;
7393
+ let nodeIndex;
7394
+ let component = undefined;
7395
+ let directives = undefined;
7396
+ if (isComponentInstance(target)) {
7397
+ nodeIndex = findViaComponent(lView, target);
7398
+ if (nodeIndex == -1) {
7399
+ throw new Error('The provided component was not found in the application');
7400
+ }
7401
+ component = target;
7402
+ }
7403
+ else if (isDirectiveInstance(target)) {
7404
+ nodeIndex = findViaDirective(lView, target);
7405
+ if (nodeIndex == -1) {
7406
+ throw new Error('The provided directive was not found in the application');
7407
+ }
7408
+ directives = getDirectivesAtNodeIndex(nodeIndex, lView);
7396
7409
  }
7397
7410
  else {
7398
- message +=
7399
- `2. To allow any element add 'NO_ERRORS_SCHEMA' to the ${schemas} of this component.`;
7411
+ nodeIndex = findViaNativeElement(lView, target);
7412
+ if (nodeIndex == -1) {
7413
+ return null;
7414
+ }
7400
7415
  }
7401
- if (shouldThrowErrorOnUnknownElement) {
7402
- throw new RuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message);
7416
+ // the goal is not to fill the entire context full of data because the lookups
7417
+ // are expensive. Instead, only the target data (the element, component, container, ICU
7418
+ // expression or directive details) are filled into the context. If called multiple times
7419
+ // with different target values then the missing target data will be filled in.
7420
+ const native = unwrapRNode(lView[nodeIndex]);
7421
+ const existingCtx = readPatchedData(native);
7422
+ const context = (existingCtx && !Array.isArray(existingCtx)) ?
7423
+ existingCtx :
7424
+ createLContext(lView, nodeIndex, native);
7425
+ // only when the component has been discovered then update the monkey-patch
7426
+ if (component && context.component === undefined) {
7427
+ context.component = component;
7428
+ attachPatchData(context.component, context);
7403
7429
  }
7404
- else {
7405
- console.error(formatRuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message));
7430
+ // only when the directives have been discovered then update the monkey-patch
7431
+ if (directives && context.directives === undefined) {
7432
+ context.directives = directives;
7433
+ for (let i = 0; i < directives.length; i++) {
7434
+ attachPatchData(directives[i], context);
7435
+ }
7406
7436
  }
7437
+ attachPatchData(context.native, context);
7438
+ mpValue = context;
7407
7439
  }
7408
7440
  }
7409
- }
7410
- /**
7411
- * Validates that the property of the element is known at runtime and returns
7412
- * false if it's not the case.
7413
- * This check is relevant for JIT-compiled components (for AOT-compiled
7414
- * ones this check happens at build time).
7415
- *
7416
- * The property is considered known if either:
7417
- * - it's a known property of the element
7418
- * - the element is allowed by one of the schemas
7419
- * - the property is used for animations
7420
- *
7421
- * @param element Element to validate
7422
- * @param propName Name of the property to check
7423
- * @param tagName Name of the tag hosting the property
7424
- * @param schemas Array of schemas
7425
- */
7426
- function isPropertyValid(element, propName, tagName, schemas) {
7427
- // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
7428
- // mode where this check happens at compile time. In JIT mode, `schemas` is always present and
7429
- // defined as an array (as an empty array in case `schemas` field is not defined) and we should
7430
- // execute the check below.
7431
- if (schemas === null)
7432
- return true;
7433
- // The property is considered valid if the element matches the schema, it exists on the element,
7434
- // or it is synthetic, and we are in a browser context (web worker nodes should be skipped).
7435
- if (matchingSchemas(schemas, tagName) || propName in element || isAnimationProp(propName)) {
7436
- return true;
7437
- }
7438
- // Note: `typeof Node` returns 'function' in most browsers, but on IE it is 'object' so we
7439
- // need to account for both here, while being careful with `typeof null` also returning 'object'.
7440
- return typeof Node === 'undefined' || Node === null || !(element instanceof Node);
7441
- }
7442
- /**
7443
- * Logs or throws an error that a property is not supported on an element.
7444
- *
7445
- * @param propName Name of the invalid property
7446
- * @param tagName Name of the tag hosting the property
7447
- * @param nodeType Type of the node hosting the property
7448
- * @param lView An `LView` that represents a current component
7449
- */
7450
- function handleUnknownPropertyError(propName, tagName, nodeType, lView) {
7451
- // Special-case a situation when a structural directive is applied to
7452
- // an `<ng-template>` element, for example: `<ng-template *ngIf="true">`.
7453
- // In this case the compiler generates the `ɵɵtemplate` instruction with
7454
- // the `null` as the tagName. The directive matching logic at runtime relies
7455
- // on this effect (see `isInlineTemplate`), thus using the 'ng-template' as
7456
- // a default value of the `tNode.value` is not feasible at this moment.
7457
- if (!tagName && nodeType === 4 /* TNodeType.Container */) {
7458
- tagName = 'ng-template';
7459
- }
7460
- const isHostStandalone = isHostComponentStandalone(lView);
7461
- const templateLocation = getTemplateLocationDetails(lView);
7462
- let message = `Can't bind to '${propName}' since it isn't a known property of '${tagName}'${templateLocation}.`;
7463
- const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
7464
- const importLocation = isHostStandalone ?
7465
- 'included in the \'@Component.imports\' of this component' :
7466
- 'a part of an @NgModule where this component is declared';
7467
- if (KNOWN_CONTROL_FLOW_DIRECTIVES.has(propName)) {
7468
- // Most likely this is a control flow directive (such as `*ngIf`) used in
7469
- // a template, but the directive or the `CommonModule` is not imported.
7470
- const correspondingImport = KNOWN_CONTROL_FLOW_DIRECTIVES.get(propName);
7471
- message += `\nIf the '${propName}' is an Angular control flow directive, ` +
7472
- `please make sure that either the '${correspondingImport}' directive or the 'CommonModule' is ${importLocation}.`;
7473
- }
7474
7441
  else {
7475
- // May be an Angular component, which is not imported/declared?
7476
- message += `\n1. If '${tagName}' is an Angular component and it has the ` +
7477
- `'${propName}' input, then verify that it is ${importLocation}.`;
7478
- // May be a Web Component?
7479
- if (tagName && tagName.indexOf('-') > -1) {
7480
- message += `\n2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' ` +
7481
- `to the ${schemas} of this component to suppress this message.`;
7482
- message += `\n3. To allow any property add 'NO_ERRORS_SCHEMA' to ` +
7483
- `the ${schemas} of this component.`;
7484
- }
7485
- else {
7486
- // If it's expected, the error can be suppressed by the `NO_ERRORS_SCHEMA` schema.
7487
- message += `\n2. To allow any property add 'NO_ERRORS_SCHEMA' to ` +
7488
- `the ${schemas} of this component.`;
7442
+ const rElement = target;
7443
+ ngDevMode && assertDomNode(rElement);
7444
+ // if the context is not found then we need to traverse upwards up the DOM
7445
+ // to find the nearest element that has already been monkey patched with data
7446
+ let parent = rElement;
7447
+ while (parent = parent.parentNode) {
7448
+ const parentContext = readPatchedData(parent);
7449
+ if (parentContext) {
7450
+ const lView = Array.isArray(parentContext) ? parentContext : parentContext.lView;
7451
+ // the edge of the app was also reached here through another means
7452
+ // (maybe because the DOM was changed manually).
7453
+ if (!lView) {
7454
+ return null;
7455
+ }
7456
+ const index = findViaNativeElement(lView, rElement);
7457
+ if (index >= 0) {
7458
+ const native = unwrapRNode(lView[index]);
7459
+ const context = createLContext(lView, index, native);
7460
+ attachPatchData(native, context);
7461
+ mpValue = context;
7462
+ break;
7463
+ }
7464
+ }
7489
7465
  }
7490
7466
  }
7491
- reportUnknownPropertyError(message);
7492
- }
7493
- function reportUnknownPropertyError(message) {
7494
- if (shouldThrowErrorOnUnknownProperty) {
7495
- throw new RuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message);
7496
- }
7497
- else {
7498
- console.error(formatRuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message));
7499
- }
7500
- }
7501
- /**
7502
- * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
7503
- * and must **not** be used in production bundles. The function makes megamorphic reads, which might
7504
- * be too slow for production mode and also it relies on the constructor function being available.
7505
- *
7506
- * Gets a reference to the host component def (where a current component is declared).
7507
- *
7508
- * @param lView An `LView` that represents a current component that is being rendered.
7509
- */
7510
- function getDeclarationComponentDef(lView) {
7511
- !ngDevMode && throwError('Must never be called in production mode');
7512
- const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
7513
- const context = declarationLView[CONTEXT];
7514
- // Unable to obtain a context.
7515
- if (!context)
7516
- return null;
7517
- return context.constructor ? getComponentDef(context.constructor) : null;
7467
+ return mpValue || null;
7518
7468
  }
7519
7469
  /**
7520
- * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
7521
- * and must **not** be used in production bundles. The function makes megamorphic reads, which might
7522
- * be too slow for production mode.
7523
- *
7524
- * Checks if the current component is declared inside of a standalone component template.
7525
- *
7526
- * @param lView An `LView` that represents a current component that is being rendered.
7470
+ * Creates an empty instance of a `LContext` context
7527
7471
  */
7528
- function isHostComponentStandalone(lView) {
7529
- !ngDevMode && throwError('Must never be called in production mode');
7530
- const componentDef = getDeclarationComponentDef(lView);
7531
- // Treat host component as non-standalone if we can't obtain the def.
7532
- return !!componentDef?.standalone;
7472
+ function createLContext(lView, nodeIndex, native) {
7473
+ return new LContext(lView[ID], nodeIndex, native);
7533
7474
  }
7534
7475
  /**
7535
- * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
7536
- * and must **not** be used in production bundles. The function makes megamorphic reads, which might
7537
- * be too slow for production mode.
7538
- *
7539
- * Constructs a string describing the location of the host component template. The function is used
7540
- * in dev mode to produce error messages.
7476
+ * Takes a component instance and returns the view for that component.
7541
7477
  *
7542
- * @param lView An `LView` that represents a current component that is being rendered.
7478
+ * @param componentInstance
7479
+ * @returns The component's view
7543
7480
  */
7544
- function getTemplateLocationDetails(lView) {
7545
- !ngDevMode && throwError('Must never be called in production mode');
7546
- const hostComponentDef = getDeclarationComponentDef(lView);
7547
- const componentClassName = hostComponentDef?.type?.name;
7548
- return componentClassName ? ` (used in the '${componentClassName}' component template)` : '';
7481
+ function getComponentViewByInstance(componentInstance) {
7482
+ let patchedData = readPatchedData(componentInstance);
7483
+ let lView;
7484
+ if (isLView(patchedData)) {
7485
+ const contextLView = patchedData;
7486
+ const nodeIndex = findViaComponent(contextLView, componentInstance);
7487
+ lView = getComponentLViewByIndex(nodeIndex, contextLView);
7488
+ const context = createLContext(contextLView, nodeIndex, lView[HOST]);
7489
+ context.component = componentInstance;
7490
+ attachPatchData(componentInstance, context);
7491
+ attachPatchData(context.native, context);
7492
+ }
7493
+ else {
7494
+ const context = patchedData;
7495
+ const contextLView = context.lView;
7496
+ ngDevMode && assertLView(contextLView);
7497
+ lView = getComponentLViewByIndex(context.nodeIndex, contextLView);
7498
+ }
7499
+ return lView;
7549
7500
  }
7550
7501
  /**
7551
- * The set of known control flow directives and their corresponding imports.
7552
- * We use this set to produce a more precises error message with a note
7553
- * that the `CommonModule` should also be included.
7502
+ * This property will be monkey-patched on elements, components and directives.
7554
7503
  */
7555
- const KNOWN_CONTROL_FLOW_DIRECTIVES = new Map([
7556
- ['ngIf', 'NgIf'], ['ngFor', 'NgFor'], ['ngSwitchCase', 'NgSwitchCase'],
7557
- ['ngSwitchDefault', 'NgSwitchDefault']
7558
- ]);
7504
+ const MONKEY_PATCH_KEY_NAME = '__ngContext__';
7559
7505
  /**
7560
- * Returns true if the tag name is allowed by specified schemas.
7561
- * @param schemas Array of schemas
7562
- * @param tagName Name of the tag
7506
+ * Assigns the given data to the given target (which could be a component,
7507
+ * directive or DOM node instance) using monkey-patching.
7563
7508
  */
7564
- function matchingSchemas(schemas, tagName) {
7565
- if (schemas !== null) {
7566
- for (let i = 0; i < schemas.length; i++) {
7567
- const schema = schemas[i];
7568
- if (schema === NO_ERRORS_SCHEMA ||
7569
- schema === CUSTOM_ELEMENTS_SCHEMA && tagName && tagName.indexOf('-') > -1) {
7570
- return true;
7571
- }
7572
- }
7509
+ function attachPatchData(target, data) {
7510
+ ngDevMode && assertDefined(target, 'Target expected');
7511
+ // Only attach the ID of the view in order to avoid memory leaks (see #41047). We only do this
7512
+ // for `LView`, because we have control over when an `LView` is created and destroyed, whereas
7513
+ // we can't know when to remove an `LContext`.
7514
+ if (isLView(data)) {
7515
+ target[MONKEY_PATCH_KEY_NAME] = data[ID];
7516
+ registerLView(data);
7517
+ }
7518
+ else {
7519
+ target[MONKEY_PATCH_KEY_NAME] = data;
7573
7520
  }
7574
- return false;
7575
7521
  }
7576
-
7577
7522
  /**
7578
- * @license
7579
- * Copyright Google LLC All Rights Reserved.
7580
- *
7581
- * Use of this source code is governed by an MIT-style license that can be
7582
- * found in the LICENSE file at https://angular.io/license
7523
+ * Returns the monkey-patch value data present on the target (which could be
7524
+ * a component, directive or a DOM node).
7583
7525
  */
7584
- const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
7585
- function wrappedError(message, originalError) {
7586
- const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
7587
- const error = Error(msg);
7588
- error[ERROR_ORIGINAL_ERROR] = originalError;
7589
- return error;
7526
+ function readPatchedData(target) {
7527
+ ngDevMode && assertDefined(target, 'Target expected');
7528
+ const data = target[MONKEY_PATCH_KEY_NAME];
7529
+ return (typeof data === 'number') ? getLViewById(data) : data || null;
7590
7530
  }
7591
- function getOriginalError(error) {
7592
- return error[ERROR_ORIGINAL_ERROR];
7531
+ function readPatchedLView(target) {
7532
+ const value = readPatchedData(target);
7533
+ if (value) {
7534
+ return (isLView(value) ? value : value.lView);
7535
+ }
7536
+ return null;
7537
+ }
7538
+ function isComponentInstance(instance) {
7539
+ return instance && instance.constructor && instance.constructor.ɵcmp;
7540
+ }
7541
+ function isDirectiveInstance(instance) {
7542
+ return instance && instance.constructor && instance.constructor.ɵdir;
7593
7543
  }
7594
-
7595
7544
  /**
7596
- * @license
7597
- * Copyright Google LLC All Rights Reserved.
7598
- *
7599
- * Use of this source code is governed by an MIT-style license that can be
7600
- * found in the LICENSE file at https://angular.io/license
7545
+ * Locates the element within the given LView and returns the matching index
7601
7546
  */
7547
+ function findViaNativeElement(lView, target) {
7548
+ const tView = lView[TVIEW];
7549
+ for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
7550
+ if (unwrapRNode(lView[i]) === target) {
7551
+ return i;
7552
+ }
7553
+ }
7554
+ return -1;
7555
+ }
7602
7556
  /**
7603
- * Provides a hook for centralized exception handling.
7604
- *
7605
- * The default implementation of `ErrorHandler` prints error messages to the `console`. To
7606
- * intercept error handling, write a custom exception handler that replaces this default as
7607
- * appropriate for your app.
7608
- *
7609
- * @usageNotes
7610
- * ### Example
7611
- *
7612
- * ```
7613
- * class MyErrorHandler implements ErrorHandler {
7614
- * handleError(error) {
7615
- * // do something with the exception
7616
- * }
7617
- * }
7618
- *
7619
- * @NgModule({
7620
- * providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
7621
- * })
7622
- * class MyModule {}
7623
- * ```
7624
- *
7625
- * @publicApi
7557
+ * Locates the next tNode (child, sibling or parent).
7626
7558
  */
7627
- class ErrorHandler {
7628
- constructor() {
7629
- /**
7630
- * @internal
7631
- */
7632
- this._console = console;
7559
+ function traverseNextElement(tNode) {
7560
+ if (tNode.child) {
7561
+ return tNode.child;
7633
7562
  }
7634
- handleError(error) {
7635
- const originalError = this._findOriginalError(error);
7636
- this._console.error('ERROR', error);
7637
- if (originalError) {
7638
- this._console.error('ORIGINAL ERROR', originalError);
7639
- }
7563
+ else if (tNode.next) {
7564
+ return tNode.next;
7640
7565
  }
7641
- /** @internal */
7642
- _findOriginalError(error) {
7643
- let e = error && getOriginalError(error);
7644
- while (e && getOriginalError(e)) {
7645
- e = getOriginalError(e);
7566
+ else {
7567
+ // Let's take the following template: <div><span>text</span></div><component/>
7568
+ // After checking the text node, we need to find the next parent that has a "next" TNode,
7569
+ // in this case the parent `div`, so that we can find the component.
7570
+ while (tNode.parent && !tNode.parent.next) {
7571
+ tNode = tNode.parent;
7646
7572
  }
7647
- return e || null;
7573
+ return tNode.parent && tNode.parent.next;
7648
7574
  }
7649
7575
  }
7650
-
7651
- /**
7652
- * @license
7653
- * Copyright Google LLC All Rights Reserved.
7654
- *
7655
- * Use of this source code is governed by an MIT-style license that can be
7656
- * found in the LICENSE file at https://angular.io/license
7657
- */
7658
- /**
7659
- * Disallowed strings in the comment.
7660
- *
7661
- * see: https://html.spec.whatwg.org/multipage/syntax.html#comments
7662
- */
7663
- const COMMENT_DISALLOWED = /^>|^->|<!--|-->|--!>|<!-$/g;
7664
7576
  /**
7665
- * Delimiter in the disallowed strings which needs to be wrapped with zero with character.
7666
- */
7667
- const COMMENT_DELIMITER = /(<|>)/;
7668
- const COMMENT_DELIMITER_ESCAPED = '\u200B$1\u200B';
7669
- /**
7670
- * Escape the content of comment strings so that it can be safely inserted into a comment node.
7671
- *
7672
- * The issue is that HTML does not specify any way to escape comment end text inside the comment.
7673
- * Consider: `<!-- The way you close a comment is with ">", and "->" at the beginning or by "-->" or
7674
- * "--!>" at the end. -->`. Above the `"-->"` is meant to be text not an end to the comment. This
7675
- * can be created programmatically through DOM APIs. (`<!--` are also disallowed.)
7676
- *
7677
- * see: https://html.spec.whatwg.org/multipage/syntax.html#comments
7678
- *
7679
- * ```
7680
- * div.innerHTML = div.innerHTML
7681
- * ```
7682
- *
7683
- * One would expect that the above code would be safe to do, but it turns out that because comment
7684
- * text is not escaped, the comment may contain text which will prematurely close the comment
7685
- * opening up the application for XSS attack. (In SSR we programmatically create comment nodes which
7686
- * may contain such text and expect them to be safe.)
7687
- *
7688
- * This function escapes the comment text by looking for comment delimiters (`<` and `>`) and
7689
- * surrounding them with `_>_` where the `_` is a zero width space `\u200B`. The result is that if a
7690
- * comment contains any of the comment start/end delimiters (such as `<!--`, `-->` or `--!>`) the
7691
- * text it will render normally but it will not cause the HTML parser to close/open the comment.
7692
- *
7693
- * @param value text to make safe for comment node by escaping the comment open/close character
7694
- * sequence.
7577
+ * Locates the component within the given LView and returns the matching index
7695
7578
  */
7696
- function escapeCommentText(value) {
7697
- return value.replace(COMMENT_DISALLOWED, (text) => text.replace(COMMENT_DELIMITER, COMMENT_DELIMITER_ESCAPED));
7579
+ function findViaComponent(lView, componentInstance) {
7580
+ const componentIndices = lView[TVIEW].components;
7581
+ if (componentIndices) {
7582
+ for (let i = 0; i < componentIndices.length; i++) {
7583
+ const elementComponentIndex = componentIndices[i];
7584
+ const componentView = getComponentLViewByIndex(elementComponentIndex, lView);
7585
+ if (componentView[CONTEXT] === componentInstance) {
7586
+ return elementComponentIndex;
7587
+ }
7588
+ }
7589
+ }
7590
+ else {
7591
+ const rootComponentView = getComponentLViewByIndex(HEADER_OFFSET, lView);
7592
+ const rootComponent = rootComponentView[CONTEXT];
7593
+ if (rootComponent === componentInstance) {
7594
+ // we are dealing with the root element here therefore we know that the
7595
+ // element is the very first element after the HEADER data in the lView
7596
+ return HEADER_OFFSET;
7597
+ }
7598
+ }
7599
+ return -1;
7698
7600
  }
7699
-
7700
7601
  /**
7701
- * @license
7702
- * Copyright Google LLC All Rights Reserved.
7703
- *
7704
- * Use of this source code is governed by an MIT-style license that can be
7705
- * found in the LICENSE file at https://angular.io/license
7602
+ * Locates the directive within the given LView and returns the matching index
7706
7603
  */
7707
- function normalizeDebugBindingName(name) {
7708
- // Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
7709
- name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
7710
- return `ng-reflect-${name}`;
7711
- }
7712
- const CAMEL_CASE_REGEXP = /([A-Z])/g;
7713
- function camelCaseToDashCase(input) {
7714
- return input.replace(CAMEL_CASE_REGEXP, (...m) => '-' + m[1].toLowerCase());
7715
- }
7716
- function normalizeDebugBindingValue(value) {
7717
- try {
7718
- // Limit the size of the value as otherwise the DOM just gets polluted.
7719
- return value != null ? value.toString().slice(0, 30) : value;
7720
- }
7721
- catch (e) {
7722
- return '[ERROR] Exception while trying to serialize the value';
7604
+ function findViaDirective(lView, directiveInstance) {
7605
+ // if a directive is monkey patched then it will (by default)
7606
+ // have a reference to the LView of the current view. The
7607
+ // element bound to the directive being search lives somewhere
7608
+ // in the view data. We loop through the nodes and check their
7609
+ // list of directives for the instance.
7610
+ let tNode = lView[TVIEW].firstChild;
7611
+ while (tNode) {
7612
+ const directiveIndexStart = tNode.directiveStart;
7613
+ const directiveIndexEnd = tNode.directiveEnd;
7614
+ for (let i = directiveIndexStart; i < directiveIndexEnd; i++) {
7615
+ if (lView[i] === directiveInstance) {
7616
+ return tNode.index;
7617
+ }
7618
+ }
7619
+ tNode = traverseNextElement(tNode);
7723
7620
  }
7621
+ return -1;
7724
7622
  }
7725
-
7726
7623
  /**
7727
- * @license
7728
- * Copyright Google LLC All Rights Reserved.
7624
+ * Returns a list of directives applied to a node at a specific index. The list includes
7625
+ * directives matched by selector and any host directives, but it excludes components.
7626
+ * Use `getComponentAtNodeIndex` to find the component applied to a node.
7729
7627
  *
7730
- * Use of this source code is governed by an MIT-style license that can be
7731
- * found in the LICENSE file at https://angular.io/license
7628
+ * @param nodeIndex The node index
7629
+ * @param lView The target view data
7732
7630
  */
7733
- // Keeps track of the currently-active LViews.
7734
- const TRACKED_LVIEWS = new Map();
7735
- // Used for generating unique IDs for LViews.
7736
- let uniqueIdCounter = 0;
7737
- /** Gets a unique ID that can be assigned to an LView. */
7738
- function getUniqueLViewId() {
7739
- return uniqueIdCounter++;
7740
- }
7741
- /** Starts tracking an LView. */
7742
- function registerLView(lView) {
7743
- ngDevMode && assertNumber(lView[ID], 'LView must have an ID in order to be registered');
7744
- TRACKED_LVIEWS.set(lView[ID], lView);
7631
+ function getDirectivesAtNodeIndex(nodeIndex, lView) {
7632
+ const tNode = lView[TVIEW].data[nodeIndex];
7633
+ if (tNode.directiveStart === 0)
7634
+ return EMPTY_ARRAY;
7635
+ const results = [];
7636
+ for (let i = tNode.directiveStart; i < tNode.directiveEnd; i++) {
7637
+ const directiveInstance = lView[i];
7638
+ if (!isComponentInstance(directiveInstance)) {
7639
+ results.push(directiveInstance);
7640
+ }
7641
+ }
7642
+ return results;
7745
7643
  }
7746
- /** Gets an LView by its unique ID. */
7747
- function getLViewById(id) {
7748
- ngDevMode && assertNumber(id, 'ID used for LView lookup must be a number');
7749
- return TRACKED_LVIEWS.get(id) || null;
7644
+ function getComponentAtNodeIndex(nodeIndex, lView) {
7645
+ const tNode = lView[TVIEW].data[nodeIndex];
7646
+ const { directiveStart, componentOffset } = tNode;
7647
+ return componentOffset > -1 ? lView[directiveStart + componentOffset] : null;
7750
7648
  }
7751
- /** Stops tracking an LView. */
7752
- function unregisterLView(lView) {
7753
- ngDevMode && assertNumber(lView[ID], 'Cannot stop tracking an LView that does not have an ID');
7754
- TRACKED_LVIEWS.delete(lView[ID]);
7649
+ /**
7650
+ * Returns a map of local references (local reference name => element or directive instance) that
7651
+ * exist on a given element.
7652
+ */
7653
+ function discoverLocalRefs(lView, nodeIndex) {
7654
+ const tNode = lView[TVIEW].data[nodeIndex];
7655
+ if (tNode && tNode.localNames) {
7656
+ const result = {};
7657
+ let localIndex = tNode.index + 1;
7658
+ for (let i = 0; i < tNode.localNames.length; i += 2) {
7659
+ result[tNode.localNames[i]] = lView[localIndex];
7660
+ localIndex++;
7661
+ }
7662
+ return result;
7663
+ }
7664
+ return null;
7755
7665
  }
7756
7666
 
7757
7667
  /**
@@ -7762,38 +7672,28 @@ function unregisterLView(lView) {
7762
7672
  * found in the LICENSE file at https://angular.io/license
7763
7673
  */
7764
7674
  /**
7765
- * The internal view context which is specific to a given DOM element, directive or
7766
- * component instance. Each value in here (besides the LView and element node details)
7767
- * can be present, null or undefined. If undefined then it implies the value has not been
7768
- * looked up yet, otherwise, if null, then a lookup was executed and nothing was found.
7675
+ * Defines a schema that allows an NgModule to contain the following:
7676
+ * - Non-Angular elements named with dash case (`-`).
7677
+ * - Element properties named with dash case (`-`).
7678
+ * Dash case is the naming convention for custom elements.
7769
7679
  *
7770
- * Each value will get filled when the respective value is examined within the getContext
7771
- * function. The component, element and each directive instance will share the same instance
7772
- * of the context.
7680
+ * @publicApi
7773
7681
  */
7774
- class LContext {
7775
- constructor(
7776
- /**
7777
- * ID of the component's parent view data.
7778
- */
7779
- lViewId,
7780
- /**
7781
- * The index instance of the node.
7782
- */
7783
- nodeIndex,
7784
- /**
7785
- * The instance of the DOM node that is attached to the lNode.
7786
- */
7787
- native) {
7788
- this.lViewId = lViewId;
7789
- this.nodeIndex = nodeIndex;
7790
- this.native = native;
7791
- }
7792
- /** Component's parent view data. */
7793
- get lView() {
7794
- return getLViewById(this.lViewId);
7795
- }
7796
- }
7682
+ const CUSTOM_ELEMENTS_SCHEMA = {
7683
+ name: 'custom-elements'
7684
+ };
7685
+ /**
7686
+ * Defines a schema that allows any property on any element.
7687
+ *
7688
+ * This schema allows you to ignore the errors related to any unknown elements or properties in a
7689
+ * template. The usage of this schema is generally discouraged because it prevents useful validation
7690
+ * and may hide real errors in your template. Consider using the `CUSTOM_ELEMENTS_SCHEMA` instead.
7691
+ *
7692
+ * @publicApi
7693
+ */
7694
+ const NO_ERRORS_SCHEMA = {
7695
+ name: 'no-errors-schema'
7696
+ };
7797
7697
 
7798
7698
  /**
7799
7699
  * @license
@@ -7802,302 +7702,411 @@ class LContext {
7802
7702
  * Use of this source code is governed by an MIT-style license that can be
7803
7703
  * found in the LICENSE file at https://angular.io/license
7804
7704
  */
7705
+ let shouldThrowErrorOnUnknownElement = false;
7805
7706
  /**
7806
- * Returns the matching `LContext` data for a given DOM node, directive or component instance.
7807
- *
7808
- * This function will examine the provided DOM element, component, or directive instance\'s
7809
- * monkey-patched property to derive the `LContext` data. Once called then the monkey-patched
7810
- * value will be that of the newly created `LContext`.
7811
- *
7812
- * If the monkey-patched value is the `LView` instance then the context value for that
7813
- * target will be created and the monkey-patch reference will be updated. Therefore when this
7814
- * function is called it may mutate the provided element\'s, component\'s or any of the associated
7815
- * directive\'s monkey-patch values.
7707
+ * Sets a strict mode for JIT-compiled components to throw an error on unknown elements,
7708
+ * instead of just logging the error.
7709
+ * (for AOT-compiled ones this check happens at build time).
7710
+ */
7711
+ function ɵsetUnknownElementStrictMode(shouldThrow) {
7712
+ shouldThrowErrorOnUnknownElement = shouldThrow;
7713
+ }
7714
+ /**
7715
+ * Gets the current value of the strict mode.
7716
+ */
7717
+ function ɵgetUnknownElementStrictMode() {
7718
+ return shouldThrowErrorOnUnknownElement;
7719
+ }
7720
+ let shouldThrowErrorOnUnknownProperty = false;
7721
+ /**
7722
+ * Sets a strict mode for JIT-compiled components to throw an error on unknown properties,
7723
+ * instead of just logging the error.
7724
+ * (for AOT-compiled ones this check happens at build time).
7725
+ */
7726
+ function ɵsetUnknownPropertyStrictMode(shouldThrow) {
7727
+ shouldThrowErrorOnUnknownProperty = shouldThrow;
7728
+ }
7729
+ /**
7730
+ * Gets the current value of the strict mode.
7731
+ */
7732
+ function ɵgetUnknownPropertyStrictMode() {
7733
+ return shouldThrowErrorOnUnknownProperty;
7734
+ }
7735
+ /**
7736
+ * Validates that the element is known at runtime and produces
7737
+ * an error if it's not the case.
7738
+ * This check is relevant for JIT-compiled components (for AOT-compiled
7739
+ * ones this check happens at build time).
7816
7740
  *
7817
- * If the monkey-patch value is not detected then the code will walk up the DOM until an element
7818
- * is found which contains a monkey-patch reference. When that occurs then the provided element
7819
- * will be updated with a new context (which is then returned). If the monkey-patch value is not
7820
- * detected for a component/directive instance then it will throw an error (all components and
7821
- * directives should be automatically monkey-patched by ivy).
7741
+ * The element is considered known if either:
7742
+ * - it's a known HTML element
7743
+ * - it's a known custom element
7744
+ * - the element matches any directive
7745
+ * - the element is allowed by one of the schemas
7822
7746
  *
7823
- * @param target Component, Directive or DOM Node.
7747
+ * @param element Element to validate
7748
+ * @param lView An `LView` that represents a current component that is being rendered
7749
+ * @param tagName Name of the tag to check
7750
+ * @param schemas Array of schemas
7751
+ * @param hasDirectives Boolean indicating that the element matches any directive
7824
7752
  */
7825
- function getLContext(target) {
7826
- let mpValue = readPatchedData(target);
7827
- if (mpValue) {
7828
- // only when it's an array is it considered an LView instance
7829
- // ... otherwise it's an already constructed LContext instance
7830
- if (isLView(mpValue)) {
7831
- const lView = mpValue;
7832
- let nodeIndex;
7833
- let component = undefined;
7834
- let directives = undefined;
7835
- if (isComponentInstance(target)) {
7836
- nodeIndex = findViaComponent(lView, target);
7837
- if (nodeIndex == -1) {
7838
- throw new Error('The provided component was not found in the application');
7839
- }
7840
- component = target;
7841
- }
7842
- else if (isDirectiveInstance(target)) {
7843
- nodeIndex = findViaDirective(lView, target);
7844
- if (nodeIndex == -1) {
7845
- throw new Error('The provided directive was not found in the application');
7846
- }
7847
- directives = getDirectivesAtNodeIndex(nodeIndex, lView, false);
7753
+ function validateElementIsKnown(element, lView, tagName, schemas, hasDirectives) {
7754
+ // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
7755
+ // mode where this check happens at compile time. In JIT mode, `schemas` is always present and
7756
+ // defined as an array (as an empty array in case `schemas` field is not defined) and we should
7757
+ // execute the check below.
7758
+ if (schemas === null)
7759
+ return;
7760
+ // If the element matches any directive, it's considered as valid.
7761
+ if (!hasDirectives && tagName !== null) {
7762
+ // The element is unknown if it's an instance of HTMLUnknownElement, or it isn't registered
7763
+ // as a custom element. Note that unknown elements with a dash in their name won't be instances
7764
+ // of HTMLUnknownElement in browsers that support web components.
7765
+ const isUnknown =
7766
+ // Note that we can't check for `typeof HTMLUnknownElement === 'function'`,
7767
+ // because while most browsers return 'function', IE returns 'object'.
7768
+ (typeof HTMLUnknownElement !== 'undefined' && HTMLUnknownElement &&
7769
+ element instanceof HTMLUnknownElement) ||
7770
+ (typeof customElements !== 'undefined' && tagName.indexOf('-') > -1 &&
7771
+ !customElements.get(tagName));
7772
+ if (isUnknown && !matchingSchemas(schemas, tagName)) {
7773
+ const isHostStandalone = isHostComponentStandalone(lView);
7774
+ const templateLocation = getTemplateLocationDetails(lView);
7775
+ const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
7776
+ let message = `'${tagName}' is not a known element${templateLocation}:\n`;
7777
+ message += `1. If '${tagName}' is an Angular component, then verify that it is ${isHostStandalone ? 'included in the \'@Component.imports\' of this component' :
7778
+ 'a part of an @NgModule where this component is declared'}.\n`;
7779
+ if (tagName && tagName.indexOf('-') > -1) {
7780
+ message +=
7781
+ `2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the ${schemas} of this component to suppress this message.`;
7848
7782
  }
7849
7783
  else {
7850
- nodeIndex = findViaNativeElement(lView, target);
7851
- if (nodeIndex == -1) {
7852
- return null;
7853
- }
7854
- }
7855
- // the goal is not to fill the entire context full of data because the lookups
7856
- // are expensive. Instead, only the target data (the element, component, container, ICU
7857
- // expression or directive details) are filled into the context. If called multiple times
7858
- // with different target values then the missing target data will be filled in.
7859
- const native = unwrapRNode(lView[nodeIndex]);
7860
- const existingCtx = readPatchedData(native);
7861
- const context = (existingCtx && !Array.isArray(existingCtx)) ?
7862
- existingCtx :
7863
- createLContext(lView, nodeIndex, native);
7864
- // only when the component has been discovered then update the monkey-patch
7865
- if (component && context.component === undefined) {
7866
- context.component = component;
7867
- attachPatchData(context.component, context);
7784
+ message +=
7785
+ `2. To allow any element add 'NO_ERRORS_SCHEMA' to the ${schemas} of this component.`;
7868
7786
  }
7869
- // only when the directives have been discovered then update the monkey-patch
7870
- if (directives && context.directives === undefined) {
7871
- context.directives = directives;
7872
- for (let i = 0; i < directives.length; i++) {
7873
- attachPatchData(directives[i], context);
7874
- }
7787
+ if (shouldThrowErrorOnUnknownElement) {
7788
+ throw new RuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message);
7875
7789
  }
7876
- attachPatchData(context.native, context);
7877
- mpValue = context;
7878
- }
7879
- }
7880
- else {
7881
- const rElement = target;
7882
- ngDevMode && assertDomNode(rElement);
7883
- // if the context is not found then we need to traverse upwards up the DOM
7884
- // to find the nearest element that has already been monkey patched with data
7885
- let parent = rElement;
7886
- while (parent = parent.parentNode) {
7887
- const parentContext = readPatchedData(parent);
7888
- if (parentContext) {
7889
- const lView = Array.isArray(parentContext) ? parentContext : parentContext.lView;
7890
- // the edge of the app was also reached here through another means
7891
- // (maybe because the DOM was changed manually).
7892
- if (!lView) {
7893
- return null;
7894
- }
7895
- const index = findViaNativeElement(lView, rElement);
7896
- if (index >= 0) {
7897
- const native = unwrapRNode(lView[index]);
7898
- const context = createLContext(lView, index, native);
7899
- attachPatchData(native, context);
7900
- mpValue = context;
7901
- break;
7902
- }
7790
+ else {
7791
+ console.error(formatRuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message));
7903
7792
  }
7904
7793
  }
7905
7794
  }
7906
- return mpValue || null;
7907
7795
  }
7908
7796
  /**
7909
- * Creates an empty instance of a `LContext` context
7797
+ * Validates that the property of the element is known at runtime and returns
7798
+ * false if it's not the case.
7799
+ * This check is relevant for JIT-compiled components (for AOT-compiled
7800
+ * ones this check happens at build time).
7801
+ *
7802
+ * The property is considered known if either:
7803
+ * - it's a known property of the element
7804
+ * - the element is allowed by one of the schemas
7805
+ * - the property is used for animations
7806
+ *
7807
+ * @param element Element to validate
7808
+ * @param propName Name of the property to check
7809
+ * @param tagName Name of the tag hosting the property
7810
+ * @param schemas Array of schemas
7910
7811
  */
7911
- function createLContext(lView, nodeIndex, native) {
7912
- return new LContext(lView[ID], nodeIndex, native);
7812
+ function isPropertyValid(element, propName, tagName, schemas) {
7813
+ // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
7814
+ // mode where this check happens at compile time. In JIT mode, `schemas` is always present and
7815
+ // defined as an array (as an empty array in case `schemas` field is not defined) and we should
7816
+ // execute the check below.
7817
+ if (schemas === null)
7818
+ return true;
7819
+ // The property is considered valid if the element matches the schema, it exists on the element,
7820
+ // or it is synthetic, and we are in a browser context (web worker nodes should be skipped).
7821
+ if (matchingSchemas(schemas, tagName) || propName in element || isAnimationProp(propName)) {
7822
+ return true;
7823
+ }
7824
+ // Note: `typeof Node` returns 'function' in most browsers, but on IE it is 'object' so we
7825
+ // need to account for both here, while being careful with `typeof null` also returning 'object'.
7826
+ return typeof Node === 'undefined' || Node === null || !(element instanceof Node);
7913
7827
  }
7914
7828
  /**
7915
- * Takes a component instance and returns the view for that component.
7829
+ * Logs or throws an error that a property is not supported on an element.
7916
7830
  *
7917
- * @param componentInstance
7918
- * @returns The component's view
7831
+ * @param propName Name of the invalid property
7832
+ * @param tagName Name of the tag hosting the property
7833
+ * @param nodeType Type of the node hosting the property
7834
+ * @param lView An `LView` that represents a current component
7919
7835
  */
7920
- function getComponentViewByInstance(componentInstance) {
7921
- let patchedData = readPatchedData(componentInstance);
7922
- let lView;
7923
- if (isLView(patchedData)) {
7924
- const contextLView = patchedData;
7925
- const nodeIndex = findViaComponent(contextLView, componentInstance);
7926
- lView = getComponentLViewByIndex(nodeIndex, contextLView);
7927
- const context = createLContext(contextLView, nodeIndex, lView[HOST]);
7928
- context.component = componentInstance;
7929
- attachPatchData(componentInstance, context);
7930
- attachPatchData(context.native, context);
7836
+ function handleUnknownPropertyError(propName, tagName, nodeType, lView) {
7837
+ // Special-case a situation when a structural directive is applied to
7838
+ // an `<ng-template>` element, for example: `<ng-template *ngIf="true">`.
7839
+ // In this case the compiler generates the `ɵɵtemplate` instruction with
7840
+ // the `null` as the tagName. The directive matching logic at runtime relies
7841
+ // on this effect (see `isInlineTemplate`), thus using the 'ng-template' as
7842
+ // a default value of the `tNode.value` is not feasible at this moment.
7843
+ if (!tagName && nodeType === 4 /* TNodeType.Container */) {
7844
+ tagName = 'ng-template';
7845
+ }
7846
+ const isHostStandalone = isHostComponentStandalone(lView);
7847
+ const templateLocation = getTemplateLocationDetails(lView);
7848
+ let message = `Can't bind to '${propName}' since it isn't a known property of '${tagName}'${templateLocation}.`;
7849
+ const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
7850
+ const importLocation = isHostStandalone ?
7851
+ 'included in the \'@Component.imports\' of this component' :
7852
+ 'a part of an @NgModule where this component is declared';
7853
+ if (KNOWN_CONTROL_FLOW_DIRECTIVES.has(propName)) {
7854
+ // Most likely this is a control flow directive (such as `*ngIf`) used in
7855
+ // a template, but the directive or the `CommonModule` is not imported.
7856
+ const correspondingImport = KNOWN_CONTROL_FLOW_DIRECTIVES.get(propName);
7857
+ message += `\nIf the '${propName}' is an Angular control flow directive, ` +
7858
+ `please make sure that either the '${correspondingImport}' directive or the 'CommonModule' is ${importLocation}.`;
7931
7859
  }
7932
7860
  else {
7933
- const context = patchedData;
7934
- const contextLView = context.lView;
7935
- ngDevMode && assertLView(contextLView);
7936
- lView = getComponentLViewByIndex(context.nodeIndex, contextLView);
7861
+ // May be an Angular component, which is not imported/declared?
7862
+ message += `\n1. If '${tagName}' is an Angular component and it has the ` +
7863
+ `'${propName}' input, then verify that it is ${importLocation}.`;
7864
+ // May be a Web Component?
7865
+ if (tagName && tagName.indexOf('-') > -1) {
7866
+ message += `\n2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' ` +
7867
+ `to the ${schemas} of this component to suppress this message.`;
7868
+ message += `\n3. To allow any property add 'NO_ERRORS_SCHEMA' to ` +
7869
+ `the ${schemas} of this component.`;
7870
+ }
7871
+ else {
7872
+ // If it's expected, the error can be suppressed by the `NO_ERRORS_SCHEMA` schema.
7873
+ message += `\n2. To allow any property add 'NO_ERRORS_SCHEMA' to ` +
7874
+ `the ${schemas} of this component.`;
7875
+ }
7937
7876
  }
7938
- return lView;
7877
+ reportUnknownPropertyError(message);
7939
7878
  }
7940
- /**
7941
- * This property will be monkey-patched on elements, components and directives.
7942
- */
7943
- const MONKEY_PATCH_KEY_NAME = '__ngContext__';
7944
- /**
7945
- * Assigns the given data to the given target (which could be a component,
7946
- * directive or DOM node instance) using monkey-patching.
7947
- */
7948
- function attachPatchData(target, data) {
7949
- ngDevMode && assertDefined(target, 'Target expected');
7950
- // Only attach the ID of the view in order to avoid memory leaks (see #41047). We only do this
7951
- // for `LView`, because we have control over when an `LView` is created and destroyed, whereas
7952
- // we can't know when to remove an `LContext`.
7953
- if (isLView(data)) {
7954
- target[MONKEY_PATCH_KEY_NAME] = data[ID];
7955
- registerLView(data);
7879
+ function reportUnknownPropertyError(message) {
7880
+ if (shouldThrowErrorOnUnknownProperty) {
7881
+ throw new RuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message);
7956
7882
  }
7957
7883
  else {
7958
- target[MONKEY_PATCH_KEY_NAME] = data;
7884
+ console.error(formatRuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message));
7959
7885
  }
7960
7886
  }
7961
7887
  /**
7962
- * Returns the monkey-patch value data present on the target (which could be
7963
- * a component, directive or a DOM node).
7888
+ * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
7889
+ * and must **not** be used in production bundles. The function makes megamorphic reads, which might
7890
+ * be too slow for production mode and also it relies on the constructor function being available.
7891
+ *
7892
+ * Gets a reference to the host component def (where a current component is declared).
7893
+ *
7894
+ * @param lView An `LView` that represents a current component that is being rendered.
7964
7895
  */
7965
- function readPatchedData(target) {
7966
- ngDevMode && assertDefined(target, 'Target expected');
7967
- const data = target[MONKEY_PATCH_KEY_NAME];
7968
- return (typeof data === 'number') ? getLViewById(data) : data || null;
7969
- }
7970
- function readPatchedLView(target) {
7971
- const value = readPatchedData(target);
7972
- if (value) {
7973
- return (isLView(value) ? value : value.lView);
7974
- }
7975
- return null;
7896
+ function getDeclarationComponentDef(lView) {
7897
+ !ngDevMode && throwError('Must never be called in production mode');
7898
+ const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
7899
+ const context = declarationLView[CONTEXT];
7900
+ // Unable to obtain a context.
7901
+ if (!context)
7902
+ return null;
7903
+ return context.constructor ? getComponentDef(context.constructor) : null;
7976
7904
  }
7977
- function isComponentInstance(instance) {
7978
- return instance && instance.constructor && instance.constructor.ɵcmp;
7905
+ /**
7906
+ * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
7907
+ * and must **not** be used in production bundles. The function makes megamorphic reads, which might
7908
+ * be too slow for production mode.
7909
+ *
7910
+ * Checks if the current component is declared inside of a standalone component template.
7911
+ *
7912
+ * @param lView An `LView` that represents a current component that is being rendered.
7913
+ */
7914
+ function isHostComponentStandalone(lView) {
7915
+ !ngDevMode && throwError('Must never be called in production mode');
7916
+ const componentDef = getDeclarationComponentDef(lView);
7917
+ // Treat host component as non-standalone if we can't obtain the def.
7918
+ return !!componentDef?.standalone;
7979
7919
  }
7980
- function isDirectiveInstance(instance) {
7981
- return instance && instance.constructor && instance.constructor.ɵdir;
7920
+ /**
7921
+ * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
7922
+ * and must **not** be used in production bundles. The function makes megamorphic reads, which might
7923
+ * be too slow for production mode.
7924
+ *
7925
+ * Constructs a string describing the location of the host component template. The function is used
7926
+ * in dev mode to produce error messages.
7927
+ *
7928
+ * @param lView An `LView` that represents a current component that is being rendered.
7929
+ */
7930
+ function getTemplateLocationDetails(lView) {
7931
+ !ngDevMode && throwError('Must never be called in production mode');
7932
+ const hostComponentDef = getDeclarationComponentDef(lView);
7933
+ const componentClassName = hostComponentDef?.type?.name;
7934
+ return componentClassName ? ` (used in the '${componentClassName}' component template)` : '';
7982
7935
  }
7983
7936
  /**
7984
- * Locates the element within the given LView and returns the matching index
7937
+ * The set of known control flow directives and their corresponding imports.
7938
+ * We use this set to produce a more precises error message with a note
7939
+ * that the `CommonModule` should also be included.
7985
7940
  */
7986
- function findViaNativeElement(lView, target) {
7987
- const tView = lView[TVIEW];
7988
- for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
7989
- if (unwrapRNode(lView[i]) === target) {
7990
- return i;
7941
+ const KNOWN_CONTROL_FLOW_DIRECTIVES = new Map([
7942
+ ['ngIf', 'NgIf'], ['ngFor', 'NgFor'], ['ngSwitchCase', 'NgSwitchCase'],
7943
+ ['ngSwitchDefault', 'NgSwitchDefault']
7944
+ ]);
7945
+ /**
7946
+ * Returns true if the tag name is allowed by specified schemas.
7947
+ * @param schemas Array of schemas
7948
+ * @param tagName Name of the tag
7949
+ */
7950
+ function matchingSchemas(schemas, tagName) {
7951
+ if (schemas !== null) {
7952
+ for (let i = 0; i < schemas.length; i++) {
7953
+ const schema = schemas[i];
7954
+ if (schema === NO_ERRORS_SCHEMA ||
7955
+ schema === CUSTOM_ELEMENTS_SCHEMA && tagName && tagName.indexOf('-') > -1) {
7956
+ return true;
7957
+ }
7991
7958
  }
7992
7959
  }
7993
- return -1;
7960
+ return false;
7994
7961
  }
7962
+
7995
7963
  /**
7996
- * Locates the next tNode (child, sibling or parent).
7964
+ * @license
7965
+ * Copyright Google LLC All Rights Reserved.
7966
+ *
7967
+ * Use of this source code is governed by an MIT-style license that can be
7968
+ * found in the LICENSE file at https://angular.io/license
7997
7969
  */
7998
- function traverseNextElement(tNode) {
7999
- if (tNode.child) {
8000
- return tNode.child;
8001
- }
8002
- else if (tNode.next) {
8003
- return tNode.next;
8004
- }
8005
- else {
8006
- // Let's take the following template: <div><span>text</span></div><component/>
8007
- // After checking the text node, we need to find the next parent that has a "next" TNode,
8008
- // in this case the parent `div`, so that we can find the component.
8009
- while (tNode.parent && !tNode.parent.next) {
8010
- tNode = tNode.parent;
8011
- }
8012
- return tNode.parent && tNode.parent.next;
8013
- }
7970
+ const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
7971
+ function wrappedError(message, originalError) {
7972
+ const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
7973
+ const error = Error(msg);
7974
+ error[ERROR_ORIGINAL_ERROR] = originalError;
7975
+ return error;
7976
+ }
7977
+ function getOriginalError(error) {
7978
+ return error[ERROR_ORIGINAL_ERROR];
8014
7979
  }
7980
+
8015
7981
  /**
8016
- * Locates the component within the given LView and returns the matching index
7982
+ * @license
7983
+ * Copyright Google LLC All Rights Reserved.
7984
+ *
7985
+ * Use of this source code is governed by an MIT-style license that can be
7986
+ * found in the LICENSE file at https://angular.io/license
8017
7987
  */
8018
- function findViaComponent(lView, componentInstance) {
8019
- const componentIndices = lView[TVIEW].components;
8020
- if (componentIndices) {
8021
- for (let i = 0; i < componentIndices.length; i++) {
8022
- const elementComponentIndex = componentIndices[i];
8023
- const componentView = getComponentLViewByIndex(elementComponentIndex, lView);
8024
- if (componentView[CONTEXT] === componentInstance) {
8025
- return elementComponentIndex;
8026
- }
7988
+ /**
7989
+ * Provides a hook for centralized exception handling.
7990
+ *
7991
+ * The default implementation of `ErrorHandler` prints error messages to the `console`. To
7992
+ * intercept error handling, write a custom exception handler that replaces this default as
7993
+ * appropriate for your app.
7994
+ *
7995
+ * @usageNotes
7996
+ * ### Example
7997
+ *
7998
+ * ```
7999
+ * class MyErrorHandler implements ErrorHandler {
8000
+ * handleError(error) {
8001
+ * // do something with the exception
8002
+ * }
8003
+ * }
8004
+ *
8005
+ * @NgModule({
8006
+ * providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
8007
+ * })
8008
+ * class MyModule {}
8009
+ * ```
8010
+ *
8011
+ * @publicApi
8012
+ */
8013
+ class ErrorHandler {
8014
+ constructor() {
8015
+ /**
8016
+ * @internal
8017
+ */
8018
+ this._console = console;
8019
+ }
8020
+ handleError(error) {
8021
+ const originalError = this._findOriginalError(error);
8022
+ this._console.error('ERROR', error);
8023
+ if (originalError) {
8024
+ this._console.error('ORIGINAL ERROR', originalError);
8027
8025
  }
8028
8026
  }
8029
- else {
8030
- const rootComponentView = getComponentLViewByIndex(HEADER_OFFSET, lView);
8031
- const rootComponent = rootComponentView[CONTEXT];
8032
- if (rootComponent === componentInstance) {
8033
- // we are dealing with the root element here therefore we know that the
8034
- // element is the very first element after the HEADER data in the lView
8035
- return HEADER_OFFSET;
8027
+ /** @internal */
8028
+ _findOriginalError(error) {
8029
+ let e = error && getOriginalError(error);
8030
+ while (e && getOriginalError(e)) {
8031
+ e = getOriginalError(e);
8036
8032
  }
8033
+ return e || null;
8037
8034
  }
8038
- return -1;
8039
8035
  }
8036
+
8040
8037
  /**
8041
- * Locates the directive within the given LView and returns the matching index
8038
+ * @license
8039
+ * Copyright Google LLC All Rights Reserved.
8040
+ *
8041
+ * Use of this source code is governed by an MIT-style license that can be
8042
+ * found in the LICENSE file at https://angular.io/license
8042
8043
  */
8043
- function findViaDirective(lView, directiveInstance) {
8044
- // if a directive is monkey patched then it will (by default)
8045
- // have a reference to the LView of the current view. The
8046
- // element bound to the directive being search lives somewhere
8047
- // in the view data. We loop through the nodes and check their
8048
- // list of directives for the instance.
8049
- let tNode = lView[TVIEW].firstChild;
8050
- while (tNode) {
8051
- const directiveIndexStart = tNode.directiveStart;
8052
- const directiveIndexEnd = tNode.directiveEnd;
8053
- for (let i = directiveIndexStart; i < directiveIndexEnd; i++) {
8054
- if (lView[i] === directiveInstance) {
8055
- return tNode.index;
8056
- }
8057
- }
8058
- tNode = traverseNextElement(tNode);
8059
- }
8060
- return -1;
8061
- }
8062
8044
  /**
8063
- * Returns a list of directives extracted from the given view based on the
8064
- * provided list of directive index values.
8045
+ * Disallowed strings in the comment.
8065
8046
  *
8066
- * @param nodeIndex The node index
8067
- * @param lView The target view data
8068
- * @param includeComponents Whether or not to include components in returned directives
8047
+ * see: https://html.spec.whatwg.org/multipage/syntax.html#comments
8069
8048
  */
8070
- function getDirectivesAtNodeIndex(nodeIndex, lView, includeComponents) {
8071
- const tNode = lView[TVIEW].data[nodeIndex];
8072
- let directiveStartIndex = tNode.directiveStart;
8073
- if (directiveStartIndex == 0)
8074
- return EMPTY_ARRAY;
8075
- const directiveEndIndex = tNode.directiveEnd;
8076
- if (!includeComponents && tNode.flags & 2 /* TNodeFlags.isComponentHost */)
8077
- directiveStartIndex++;
8078
- return lView.slice(directiveStartIndex, directiveEndIndex);
8079
- }
8080
- function getComponentAtNodeIndex(nodeIndex, lView) {
8081
- const tNode = lView[TVIEW].data[nodeIndex];
8082
- let directiveStartIndex = tNode.directiveStart;
8083
- return tNode.flags & 2 /* TNodeFlags.isComponentHost */ ? lView[directiveStartIndex] : null;
8049
+ const COMMENT_DISALLOWED = /^>|^->|<!--|-->|--!>|<!-$/g;
8050
+ /**
8051
+ * Delimiter in the disallowed strings which needs to be wrapped with zero with character.
8052
+ */
8053
+ const COMMENT_DELIMITER = /(<|>)/;
8054
+ const COMMENT_DELIMITER_ESCAPED = '\u200B$1\u200B';
8055
+ /**
8056
+ * Escape the content of comment strings so that it can be safely inserted into a comment node.
8057
+ *
8058
+ * The issue is that HTML does not specify any way to escape comment end text inside the comment.
8059
+ * Consider: `<!-- The way you close a comment is with ">", and "->" at the beginning or by "-->" or
8060
+ * "--!>" at the end. -->`. Above the `"-->"` is meant to be text not an end to the comment. This
8061
+ * can be created programmatically through DOM APIs. (`<!--` are also disallowed.)
8062
+ *
8063
+ * see: https://html.spec.whatwg.org/multipage/syntax.html#comments
8064
+ *
8065
+ * ```
8066
+ * div.innerHTML = div.innerHTML
8067
+ * ```
8068
+ *
8069
+ * One would expect that the above code would be safe to do, but it turns out that because comment
8070
+ * text is not escaped, the comment may contain text which will prematurely close the comment
8071
+ * opening up the application for XSS attack. (In SSR we programmatically create comment nodes which
8072
+ * may contain such text and expect them to be safe.)
8073
+ *
8074
+ * This function escapes the comment text by looking for comment delimiters (`<` and `>`) and
8075
+ * surrounding them with `_>_` where the `_` is a zero width space `\u200B`. The result is that if a
8076
+ * comment contains any of the comment start/end delimiters (such as `<!--`, `-->` or `--!>`) the
8077
+ * text it will render normally but it will not cause the HTML parser to close/open the comment.
8078
+ *
8079
+ * @param value text to make safe for comment node by escaping the comment open/close character
8080
+ * sequence.
8081
+ */
8082
+ function escapeCommentText(value) {
8083
+ return value.replace(COMMENT_DISALLOWED, (text) => text.replace(COMMENT_DELIMITER, COMMENT_DELIMITER_ESCAPED));
8084
8084
  }
8085
+
8085
8086
  /**
8086
- * Returns a map of local references (local reference name => element or directive instance) that
8087
- * exist on a given element.
8087
+ * @license
8088
+ * Copyright Google LLC All Rights Reserved.
8089
+ *
8090
+ * Use of this source code is governed by an MIT-style license that can be
8091
+ * found in the LICENSE file at https://angular.io/license
8088
8092
  */
8089
- function discoverLocalRefs(lView, nodeIndex) {
8090
- const tNode = lView[TVIEW].data[nodeIndex];
8091
- if (tNode && tNode.localNames) {
8092
- const result = {};
8093
- let localIndex = tNode.index + 1;
8094
- for (let i = 0; i < tNode.localNames.length; i += 2) {
8095
- result[tNode.localNames[i]] = lView[localIndex];
8096
- localIndex++;
8097
- }
8098
- return result;
8093
+ function normalizeDebugBindingName(name) {
8094
+ // Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
8095
+ name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
8096
+ return `ng-reflect-${name}`;
8097
+ }
8098
+ const CAMEL_CASE_REGEXP = /([A-Z])/g;
8099
+ function camelCaseToDashCase(input) {
8100
+ return input.replace(CAMEL_CASE_REGEXP, (...m) => '-' + m[1].toLowerCase());
8101
+ }
8102
+ function normalizeDebugBindingValue(value) {
8103
+ try {
8104
+ // Limit the size of the value as otherwise the DOM just gets polluted.
8105
+ return value != null ? value.toString().slice(0, 30) : value;
8106
+ }
8107
+ catch (e) {
8108
+ return '[ERROR] Exception while trying to serialize the value';
8099
8109
  }
8100
- return null;
8101
8110
  }
8102
8111
 
8103
8112
  /**
@@ -8883,9 +8892,10 @@ function getClosestRElement(tView, tNode, lView) {
8883
8892
  }
8884
8893
  else {
8885
8894
  ngDevMode && assertTNodeType(parentTNode, 3 /* TNodeType.AnyRNode */ | 4 /* TNodeType.Container */);
8886
- if (parentTNode.flags & 2 /* TNodeFlags.isComponentHost */) {
8895
+ const { componentOffset } = parentTNode;
8896
+ if (componentOffset > -1) {
8887
8897
  ngDevMode && assertTNodeForLView(parentTNode, lView);
8888
- const encapsulation = tView.data[parentTNode.directiveStart].encapsulation;
8898
+ const { encapsulation } = tView.data[parentTNode.directiveStart + componentOffset];
8889
8899
  // We've got a parent which is an element in the current view. We just need to verify if the
8890
8900
  // parent element is not a component. Component's content nodes are not inserted immediately
8891
8901
  // because they will be projected, and so doing insert at this point would be wasteful.
@@ -9118,10 +9128,10 @@ function applyNodes(renderer, action, tNode, lView, parentRElement, beforeNode,
9118
9128
  if (isProjection) {
9119
9129
  if (action === 0 /* WalkTNodeTreeAction.Create */) {
9120
9130
  rawSlotValue && attachPatchData(unwrapRNode(rawSlotValue), lView);
9121
- tNode.flags |= 4 /* TNodeFlags.isProjected */;
9131
+ tNode.flags |= 2 /* TNodeFlags.isProjected */;
9122
9132
  }
9123
9133
  }
9124
- if ((tNode.flags & 64 /* TNodeFlags.isDetached */) !== 64 /* TNodeFlags.isDetached */) {
9134
+ if ((tNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
9125
9135
  if (tNodeType & 8 /* TNodeType.ElementContainer */) {
9126
9136
  applyNodes(renderer, action, tNode.child, lView, parentRElement, beforeNode, false);
9127
9137
  applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
@@ -9315,6 +9325,19 @@ function writeDirectClass(renderer, element, newValue) {
9315
9325
  }
9316
9326
  ngDevMode && ngDevMode.rendererSetClassName++;
9317
9327
  }
9328
+ /** Sets up the static DOM attributes on an `RNode`. */
9329
+ function setupStaticAttributes(renderer, element, tNode) {
9330
+ const { mergedAttrs, classes, styles } = tNode;
9331
+ if (mergedAttrs !== null) {
9332
+ setUpAttributes(renderer, element, mergedAttrs);
9333
+ }
9334
+ if (classes !== null) {
9335
+ writeDirectClass(renderer, element, classes);
9336
+ }
9337
+ if (styles !== null) {
9338
+ writeDirectStyle(renderer, element, styles);
9339
+ }
9340
+ }
9318
9341
 
9319
9342
  /**
9320
9343
  * @license
@@ -11175,6 +11198,7 @@ class TNode {
11175
11198
  index, //
11176
11199
  insertBeforeIndex, //
11177
11200
  injectorIndex, //
11201
+ componentOffset, //
11178
11202
  directiveStart, //
11179
11203
  directiveEnd, //
11180
11204
  directiveStylingLast, //
@@ -11207,6 +11231,7 @@ class TNode {
11207
11231
  this.index = index;
11208
11232
  this.insertBeforeIndex = insertBeforeIndex;
11209
11233
  this.injectorIndex = injectorIndex;
11234
+ this.componentOffset = componentOffset;
11210
11235
  this.directiveStart = directiveStart;
11211
11236
  this.directiveEnd = directiveEnd;
11212
11237
  this.directiveStylingLast = directiveStylingLast;
@@ -11284,21 +11309,19 @@ class TNode {
11284
11309
  }
11285
11310
  get flags_() {
11286
11311
  const flags = [];
11287
- if (this.flags & 16 /* TNodeFlags.hasClassInput */)
11312
+ if (this.flags & 8 /* TNodeFlags.hasClassInput */)
11288
11313
  flags.push('TNodeFlags.hasClassInput');
11289
- if (this.flags & 8 /* TNodeFlags.hasContentQuery */)
11314
+ if (this.flags & 4 /* TNodeFlags.hasContentQuery */)
11290
11315
  flags.push('TNodeFlags.hasContentQuery');
11291
- if (this.flags & 32 /* TNodeFlags.hasStyleInput */)
11316
+ if (this.flags & 16 /* TNodeFlags.hasStyleInput */)
11292
11317
  flags.push('TNodeFlags.hasStyleInput');
11293
- if (this.flags & 128 /* TNodeFlags.hasHostBindings */)
11318
+ if (this.flags & 64 /* TNodeFlags.hasHostBindings */)
11294
11319
  flags.push('TNodeFlags.hasHostBindings');
11295
- if (this.flags & 2 /* TNodeFlags.isComponentHost */)
11296
- flags.push('TNodeFlags.isComponentHost');
11297
11320
  if (this.flags & 1 /* TNodeFlags.isDirectiveHost */)
11298
11321
  flags.push('TNodeFlags.isDirectiveHost');
11299
- if (this.flags & 64 /* TNodeFlags.isDetached */)
11322
+ if (this.flags & 32 /* TNodeFlags.isDetached */)
11300
11323
  flags.push('TNodeFlags.isDetached');
11301
- if (this.flags & 4 /* TNodeFlags.isProjected */)
11324
+ if (this.flags & 2 /* TNodeFlags.isProjected */)
11302
11325
  flags.push('TNodeFlags.isProjected');
11303
11326
  return flags.join('|');
11304
11327
  }
@@ -11808,7 +11831,7 @@ function getOrCreateTNode(tView, index, type, name, attrs) {
11808
11831
  // See `TNodeType.Placeholder` and `LFrame.inI18n` for more context.
11809
11832
  // If the `TNode` was not pre-declared than it means it was not mentioned which means it was
11810
11833
  // removed, so we mark it as detached.
11811
- tNode.flags |= 64 /* TNodeFlags.isDetached */;
11834
+ tNode.flags |= 32 /* TNodeFlags.isDetached */;
11812
11835
  }
11813
11836
  }
11814
11837
  else if (tNode.type & 64 /* TNodeType.Placeholder */) {
@@ -12112,7 +12135,7 @@ function createDirectivesInstances(tView, lView, tNode) {
12112
12135
  if (!getBindingsEnabled())
12113
12136
  return;
12114
12137
  instantiateAllDirectives(tView, lView, tNode, getNativeByTNode(tNode, lView));
12115
- if ((tNode.flags & 128 /* TNodeFlags.hasHostBindings */) === 128 /* TNodeFlags.hasHostBindings */) {
12138
+ if ((tNode.flags & 64 /* TNodeFlags.hasHostBindings */) === 64 /* TNodeFlags.hasHostBindings */) {
12116
12139
  invokeDirectivesHostBindings(tView, lView, tNode);
12117
12140
  }
12118
12141
  }
@@ -12312,6 +12335,7 @@ function createTNode(tView, tParent, type, index, value, attrs) {
12312
12335
  index, // index: number
12313
12336
  null, // insertBeforeIndex: null|-1|number|number[]
12314
12337
  injectorIndex, // injectorIndex: number
12338
+ -1, // componentOffset: number
12315
12339
  -1, // directiveStart: number
12316
12340
  -1, // directiveEnd: number
12317
12341
  -1, // directiveStylingLast: number
@@ -12347,6 +12371,7 @@ function createTNode(tView, tParent, type, index, value, attrs) {
12347
12371
  directiveStart: -1,
12348
12372
  directiveEnd: -1,
12349
12373
  directiveStylingLast: -1,
12374
+ componentOffset: -1,
12350
12375
  propertyBindings: null,
12351
12376
  flags: 0,
12352
12377
  providerIndexes: 0,
@@ -12410,24 +12435,23 @@ function initializeInputAndOutputAliases(tView, tNode) {
12410
12435
  let outputsStore = null;
12411
12436
  for (let i = start; i < end; i++) {
12412
12437
  const directiveDef = tViewData[i];
12413
- const directiveInputs = directiveDef.inputs;
12438
+ inputsStore = generatePropertyAliases(directiveDef.inputs, i, inputsStore);
12439
+ outputsStore = generatePropertyAliases(directiveDef.outputs, i, outputsStore);
12414
12440
  // Do not use unbound attributes as inputs to structural directives, since structural
12415
12441
  // directive inputs can only be set using microsyntax (e.g. `<div *dir="exp">`).
12416
12442
  // TODO(FW-1930): microsyntax expressions may also contain unbound/static attributes, which
12417
12443
  // should be set for inline templates.
12418
- const initialInputs = (tNodeAttrs !== null && !isInlineTemplate(tNode)) ?
12419
- generateInitialInputs(directiveInputs, tNodeAttrs) :
12444
+ const initialInputs = (inputsStore !== null && tNodeAttrs !== null && !isInlineTemplate(tNode)) ?
12445
+ generateInitialInputs(inputsStore, i, tNodeAttrs) :
12420
12446
  null;
12421
12447
  inputsFromAttrs.push(initialInputs);
12422
- inputsStore = generatePropertyAliases(directiveInputs, i, inputsStore);
12423
- outputsStore = generatePropertyAliases(directiveDef.outputs, i, outputsStore);
12424
12448
  }
12425
12449
  if (inputsStore !== null) {
12426
12450
  if (inputsStore.hasOwnProperty('class')) {
12427
- tNode.flags |= 16 /* TNodeFlags.hasClassInput */;
12451
+ tNode.flags |= 8 /* TNodeFlags.hasClassInput */;
12428
12452
  }
12429
12453
  if (inputsStore.hasOwnProperty('style')) {
12430
- tNode.flags |= 32 /* TNodeFlags.hasStyleInput */;
12454
+ tNode.flags |= 16 /* TNodeFlags.hasStyleInput */;
12431
12455
  }
12432
12456
  }
12433
12457
  tNode.initialInputs = inputsFromAttrs;
@@ -12534,28 +12558,6 @@ function setNgReflectProperties(lView, element, type, dataValue, value) {
12534
12558
  }
12535
12559
  }
12536
12560
  }
12537
- /**
12538
- * Instantiate a root component.
12539
- */
12540
- function instantiateRootComponent(tView, lView, def) {
12541
- const rootTNode = getCurrentTNode();
12542
- if (tView.firstCreatePass) {
12543
- if (def.providersResolver)
12544
- def.providersResolver(def);
12545
- const directiveIndex = allocExpando(tView, lView, 1, null);
12546
- ngDevMode &&
12547
- assertEqual(directiveIndex, rootTNode.directiveStart, 'Because this is a root component the allocated expando should match the TNode component.');
12548
- configureViewWithDirective(tView, rootTNode, lView, directiveIndex, def);
12549
- initializeInputAndOutputAliases(tView, rootTNode);
12550
- }
12551
- const directive = getNodeInjectable(lView, tView, rootTNode.directiveStart, rootTNode);
12552
- attachPatchData(directive, lView);
12553
- const native = getNativeByTNode(rootTNode, lView);
12554
- if (native) {
12555
- attachPatchData(native, lView);
12556
- }
12557
- return directive;
12558
- }
12559
12561
  /**
12560
12562
  * Resolve the matched directives on a node.
12561
12563
  */
@@ -12568,53 +12570,13 @@ function resolveDirectives(tView, lView, tNode, localRefs) {
12568
12570
  const directiveDefs = findDirectiveDefMatches(tView, lView, tNode);
12569
12571
  const exportsMap = localRefs === null ? null : { '': -1 };
12570
12572
  if (directiveDefs !== null) {
12571
- hasDirectives = true;
12572
- initTNodeFlags(tNode, tView.data.length, directiveDefs.length);
12573
- // When the same token is provided by several directives on the same node, some rules apply in
12574
- // the viewEngine:
12575
- // - viewProviders have priority over providers
12576
- // - the last directive in NgModule.declarations has priority over the previous one
12577
- // So to match these rules, the order in which providers are added in the arrays is very
12578
- // important.
12573
+ // Publishes the directive types to DI so they can be injected. Needs to
12574
+ // happen in a separate pass before the TNode flags have been initialized.
12579
12575
  for (let i = 0; i < directiveDefs.length; i++) {
12580
- const def = directiveDefs[i];
12581
- if (def.providersResolver)
12582
- def.providersResolver(def);
12583
- }
12584
- let preOrderHooksFound = false;
12585
- let preOrderCheckHooksFound = false;
12586
- let directiveIdx = allocExpando(tView, lView, directiveDefs.length, null);
12587
- ngDevMode &&
12588
- assertSame(directiveIdx, tNode.directiveStart, 'TNode.directiveStart should point to just allocated space');
12589
- for (let i = 0; i < directiveDefs.length; i++) {
12590
- const def = directiveDefs[i];
12591
- // Merge the attrs in the order of matches. This assumes that the first directive is the
12592
- // component itself, so that the component has the least priority.
12593
- tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, def.hostAttrs);
12594
- configureViewWithDirective(tView, tNode, lView, directiveIdx, def);
12595
- saveNameToExportMap(directiveIdx, def, exportsMap);
12596
- if (def.contentQueries !== null)
12597
- tNode.flags |= 8 /* TNodeFlags.hasContentQuery */;
12598
- if (def.hostBindings !== null || def.hostAttrs !== null || def.hostVars !== 0)
12599
- tNode.flags |= 128 /* TNodeFlags.hasHostBindings */;
12600
- const lifeCycleHooks = def.type.prototype;
12601
- // Only push a node index into the preOrderHooks array if this is the first
12602
- // pre-order hook found on this node.
12603
- if (!preOrderHooksFound &&
12604
- (lifeCycleHooks.ngOnChanges || lifeCycleHooks.ngOnInit || lifeCycleHooks.ngDoCheck)) {
12605
- // We will push the actual hook function into this array later during dir instantiation.
12606
- // We cannot do it now because we must ensure hooks are registered in the same
12607
- // order that directives are created (i.e. injection order).
12608
- (tView.preOrderHooks || (tView.preOrderHooks = [])).push(tNode.index);
12609
- preOrderHooksFound = true;
12610
- }
12611
- if (!preOrderCheckHooksFound && (lifeCycleHooks.ngOnChanges || lifeCycleHooks.ngDoCheck)) {
12612
- (tView.preOrderCheckHooks || (tView.preOrderCheckHooks = [])).push(tNode.index);
12613
- preOrderCheckHooksFound = true;
12614
- }
12615
- directiveIdx++;
12576
+ diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, lView), tView, directiveDefs[i].type);
12616
12577
  }
12617
- initializeInputAndOutputAliases(tView, tNode);
12578
+ hasDirectives = true;
12579
+ initializeDirectives(tView, lView, tNode, directiveDefs, exportsMap);
12618
12580
  }
12619
12581
  if (exportsMap)
12620
12582
  cacheMatchingLocalNames(tNode, localRefs, exportsMap);
@@ -12623,17 +12585,66 @@ function resolveDirectives(tView, lView, tNode, localRefs) {
12623
12585
  tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, tNode.attrs);
12624
12586
  return hasDirectives;
12625
12587
  }
12588
+ /** Initializes the data structures necessary for a list of directives to be instantiated. */
12589
+ function initializeDirectives(tView, lView, tNode, directives, exportsMap) {
12590
+ ngDevMode && assertFirstCreatePass(tView);
12591
+ initTNodeFlags(tNode, tView.data.length, directives.length);
12592
+ // When the same token is provided by several directives on the same node, some rules apply in
12593
+ // the viewEngine:
12594
+ // - viewProviders have priority over providers
12595
+ // - the last directive in NgModule.declarations has priority over the previous one
12596
+ // So to match these rules, the order in which providers are added in the arrays is very
12597
+ // important.
12598
+ for (let i = 0; i < directives.length; i++) {
12599
+ const def = directives[i];
12600
+ if (def.providersResolver)
12601
+ def.providersResolver(def);
12602
+ }
12603
+ let preOrderHooksFound = false;
12604
+ let preOrderCheckHooksFound = false;
12605
+ let directiveIdx = allocExpando(tView, lView, directives.length, null);
12606
+ ngDevMode &&
12607
+ assertSame(directiveIdx, tNode.directiveStart, 'TNode.directiveStart should point to just allocated space');
12608
+ for (let i = 0; i < directives.length; i++) {
12609
+ const def = directives[i];
12610
+ // Merge the attrs in the order of matches. This assumes that the first directive is the
12611
+ // component itself, so that the component has the least priority.
12612
+ tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, def.hostAttrs);
12613
+ configureViewWithDirective(tView, tNode, lView, directiveIdx, def);
12614
+ saveNameToExportMap(directiveIdx, def, exportsMap);
12615
+ if (def.contentQueries !== null)
12616
+ tNode.flags |= 4 /* TNodeFlags.hasContentQuery */;
12617
+ if (def.hostBindings !== null || def.hostAttrs !== null || def.hostVars !== 0)
12618
+ tNode.flags |= 64 /* TNodeFlags.hasHostBindings */;
12619
+ const lifeCycleHooks = def.type.prototype;
12620
+ // Only push a node index into the preOrderHooks array if this is the first
12621
+ // pre-order hook found on this node.
12622
+ if (!preOrderHooksFound &&
12623
+ (lifeCycleHooks.ngOnChanges || lifeCycleHooks.ngOnInit || lifeCycleHooks.ngDoCheck)) {
12624
+ // We will push the actual hook function into this array later during dir instantiation.
12625
+ // We cannot do it now because we must ensure hooks are registered in the same
12626
+ // order that directives are created (i.e. injection order).
12627
+ (tView.preOrderHooks || (tView.preOrderHooks = [])).push(tNode.index);
12628
+ preOrderHooksFound = true;
12629
+ }
12630
+ if (!preOrderCheckHooksFound && (lifeCycleHooks.ngOnChanges || lifeCycleHooks.ngDoCheck)) {
12631
+ (tView.preOrderCheckHooks || (tView.preOrderCheckHooks = [])).push(tNode.index);
12632
+ preOrderCheckHooksFound = true;
12633
+ }
12634
+ directiveIdx++;
12635
+ }
12636
+ initializeInputAndOutputAliases(tView, tNode);
12637
+ }
12626
12638
  /**
12627
12639
  * Add `hostBindings` to the `TView.hostBindingOpCodes`.
12628
12640
  *
12629
12641
  * @param tView `TView` to which the `hostBindings` should be added.
12630
12642
  * @param tNode `TNode` the element which contains the directive
12631
- * @param lView `LView` current `LView`
12632
12643
  * @param directiveIdx Directive index in view.
12633
12644
  * @param directiveVarsIdx Where will the directive's vars be stored
12634
12645
  * @param def `ComponentDef`/`DirectiveDef`, which contains the `hostVars`/`hostBindings` to add.
12635
12646
  */
12636
- function registerHostBindingOpCodes(tView, tNode, lView, directiveIdx, directiveVarsIdx, def) {
12647
+ function registerHostBindingOpCodes(tView, tNode, directiveIdx, directiveVarsIdx, def) {
12637
12648
  ngDevMode && assertFirstCreatePass(tView);
12638
12649
  const hostBindings = def.hostBindings;
12639
12650
  if (hostBindings) {
@@ -12734,7 +12745,7 @@ function invokeHostBindingsInCreationMode(def, directive) {
12734
12745
  * Matches the current node against all available selectors.
12735
12746
  * If a component is matched (at most one), it is returned in first position in the array.
12736
12747
  */
12737
- function findDirectiveDefMatches(tView, viewData, tNode) {
12748
+ function findDirectiveDefMatches(tView, lView, tNode) {
12738
12749
  ngDevMode && assertFirstCreatePass(tView);
12739
12750
  ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 12 /* TNodeType.AnyContainer */);
12740
12751
  const registry = tView.directiveRegistry;
@@ -12744,25 +12755,47 @@ function findDirectiveDefMatches(tView, viewData, tNode) {
12744
12755
  const def = registry[i];
12745
12756
  if (isNodeMatchingSelectorList(tNode, def.selectors, /* isProjectionMode */ false)) {
12746
12757
  matches || (matches = ngDevMode ? new MatchesArray() : []);
12747
- diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, viewData), tView, def.type);
12748
12758
  if (isComponentDef(def)) {
12749
12759
  if (ngDevMode) {
12750
12760
  assertTNodeType(tNode, 2 /* TNodeType.Element */, `"${tNode.value}" tags cannot be used as component hosts. ` +
12751
12761
  `Please use a different tag to activate the ${stringify(def.type)} component.`);
12752
- if (tNode.flags & 2 /* TNodeFlags.isComponentHost */) {
12753
- // If another component has been matched previously, it's the first element in the
12754
- // `matches` array, see how we store components/directives in `matches` below.
12755
- throwMultipleComponentError(tNode, matches[0].type, def.type);
12762
+ if (isComponentHost(tNode)) {
12763
+ throwMultipleComponentError(tNode, matches.find(isComponentDef).type, def.type);
12756
12764
  }
12757
12765
  }
12758
- markAsComponentHost(tView, tNode);
12759
- // The component is always stored first with directives after.
12760
- matches.unshift(def);
12766
+ // Components are inserted at the front of the matches array so that their lifecycle
12767
+ // hooks run before any directive lifecycle hooks. This appears to be for ViewEngine
12768
+ // compatibility. This logic doesn't make sense with host directives, because it
12769
+ // would allow the host directives to undo any overrides the host may have made.
12770
+ // To handle this case, the host directives of components are inserted at the beginning
12771
+ // of the array, followed by the component. As such, the insertion order is as follows:
12772
+ // 1. Host directives belonging to the selector-matched component.
12773
+ // 2. Selector-matched component.
12774
+ // 3. Host directives belonging to selector-matched directives.
12775
+ // 4. Selector-matched directives.
12776
+ if (def.findHostDirectiveDefs !== null) {
12777
+ const hostDirectiveMatches = [];
12778
+ def.findHostDirectiveDefs(hostDirectiveMatches, def, tView, lView, tNode);
12779
+ // Add all host directives declared on this component, followed by the component itself.
12780
+ // Host directives should execute first so the host has a chance to override changes
12781
+ // to the DOM made by them.
12782
+ matches.unshift(...hostDirectiveMatches, def);
12783
+ // Component is offset starting from the beginning of the host directives array.
12784
+ const componentOffset = hostDirectiveMatches.length;
12785
+ markAsComponentHost(tView, tNode, componentOffset);
12786
+ }
12787
+ else {
12788
+ // No host directives on this component, just add the
12789
+ // component def to the beginning of the matches.
12790
+ matches.unshift(def);
12791
+ markAsComponentHost(tView, tNode, 0);
12792
+ }
12761
12793
  }
12762
12794
  else {
12795
+ // Append any host directives to the matches first.
12796
+ def.findHostDirectiveDefs?.(matches, def, tView, lView, tNode);
12763
12797
  matches.push(def);
12764
12798
  }
12765
- def.applyHostDirectives?.(tView, viewData, tNode, matches);
12766
12799
  }
12767
12800
  }
12768
12801
  }
@@ -12770,12 +12803,13 @@ function findDirectiveDefMatches(tView, viewData, tNode) {
12770
12803
  }
12771
12804
  /**
12772
12805
  * Marks a given TNode as a component's host. This consists of:
12773
- * - setting appropriate TNode flags;
12806
+ * - setting the component offset on the TNode.
12774
12807
  * - storing index of component's host element so it will be queued for view refresh during CD.
12775
12808
  */
12776
- function markAsComponentHost(tView, hostTNode) {
12809
+ function markAsComponentHost(tView, hostTNode, componentOffset) {
12777
12810
  ngDevMode && assertFirstCreatePass(tView);
12778
- hostTNode.flags |= 2 /* TNodeFlags.isComponentHost */;
12811
+ ngDevMode && assertGreaterThan(componentOffset, -1, 'componentOffset must be great than -1');
12812
+ hostTNode.componentOffset = componentOffset;
12779
12813
  (tView.components || (tView.components = ngDevMode ? new TViewComponents() : []))
12780
12814
  .push(hostTNode.index);
12781
12815
  }
@@ -12846,7 +12880,7 @@ function configureViewWithDirective(tView, tNode, lView, directiveIndex, def) {
12846
12880
  const nodeInjectorFactory = new NodeInjectorFactory(directiveFactory, isComponentDef(def), ɵɵdirectiveInject);
12847
12881
  tView.blueprint[directiveIndex] = nodeInjectorFactory;
12848
12882
  lView[directiveIndex] = nodeInjectorFactory;
12849
- registerHostBindingOpCodes(tView, tNode, lView, directiveIndex, allocExpando(tView, lView, def.hostVars, NO_CHANGE), def);
12883
+ registerHostBindingOpCodes(tView, tNode, directiveIndex, allocExpando(tView, lView, def.hostVars, NO_CHANGE), def);
12850
12884
  }
12851
12885
  function addComponentLogic(lView, hostTNode, def) {
12852
12886
  const native = getNativeByTNode(hostTNode, lView);
@@ -12921,10 +12955,11 @@ function setInputsFromAttrs(lView, directiveIndex, instance, def, tNode, initial
12921
12955
  *
12922
12956
  * <my-component name="Bess"></my-component>
12923
12957
  *
12924
- * @param inputs The list of inputs from the directive def
12925
- * @param attrs The static attrs on this node
12958
+ * @param inputs Input alias map that was generated from the directive def inputs.
12959
+ * @param directiveIndex Index of the directive that is currently being processed.
12960
+ * @param attrs Static attrs on this node.
12926
12961
  */
12927
- function generateInitialInputs(inputs, attrs) {
12962
+ function generateInitialInputs(inputs, directiveIndex, attrs) {
12928
12963
  let inputsToStore = null;
12929
12964
  let i = 0;
12930
12965
  while (i < attrs.length) {
@@ -12945,7 +12980,17 @@ function generateInitialInputs(inputs, attrs) {
12945
12980
  if (inputs.hasOwnProperty(attrName)) {
12946
12981
  if (inputsToStore === null)
12947
12982
  inputsToStore = [];
12948
- inputsToStore.push(attrName, inputs[attrName], attrs[i + 1]);
12983
+ // Find the input's public name from the input store. Note that we can be found easier
12984
+ // through the directive def, but we want to do it using the inputs store so that it can
12985
+ // account for host directive aliases.
12986
+ const inputConfig = inputs[attrName];
12987
+ for (let j = 0; j < inputConfig.length; j += 2) {
12988
+ if (inputConfig[j] === directiveIndex) {
12989
+ inputsToStore.push(attrName, inputConfig[j + 1], attrs[i + 1]);
12990
+ // A directive can't have multiple inputs with the same name so we can break here.
12991
+ break;
12992
+ }
12993
+ }
12949
12994
  }
12950
12995
  i += 2;
12951
12996
  }
@@ -13758,6 +13803,7 @@ class ChainedInjector {
13758
13803
  this.parentInjector = parentInjector;
13759
13804
  }
13760
13805
  get(token, notFoundValue, flags) {
13806
+ flags = convertToBitFlags(flags);
13761
13807
  const value = this.injector.get(token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, flags);
13762
13808
  if (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR ||
13763
13809
  notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) {
@@ -13834,42 +13880,23 @@ class ComponentFactory extends ComponentFactory$1 {
13834
13880
  let component;
13835
13881
  let tElementNode;
13836
13882
  try {
13837
- const componentView = createRootComponentView(hostRNode, this.componentDef, rootLView, rendererFactory, hostRenderer);
13883
+ const rootDirectives = [this.componentDef];
13884
+ const hostTNode = createRootComponentTNode(rootLView, hostRNode);
13885
+ const componentView = createRootComponentView(hostTNode, hostRNode, this.componentDef, rootDirectives, rootLView, rendererFactory, hostRenderer);
13886
+ tElementNode = getTNode(rootTView, HEADER_OFFSET);
13887
+ // TODO(crisbeto): in practice `hostRNode` should always be defined, but there are some tests
13888
+ // where the renderer is mocked out and `undefined` is returned. We should update the tests so
13889
+ // that this check can be removed.
13838
13890
  if (hostRNode) {
13839
- if (rootSelectorOrNode) {
13840
- setUpAttributes(hostRenderer, hostRNode, ['ng-version', VERSION.full]);
13841
- }
13842
- else {
13843
- // If host element is created as a part of this function call (i.e. `rootSelectorOrNode`
13844
- // is not defined), also apply attributes and classes extracted from component selector.
13845
- // Extract attributes and classes from the first selector only to match VE behavior.
13846
- const { attrs, classes } = extractAttrsAndClassesFromSelector(this.componentDef.selectors[0]);
13847
- if (attrs) {
13848
- setUpAttributes(hostRenderer, hostRNode, attrs);
13849
- }
13850
- if (classes && classes.length > 0) {
13851
- writeDirectClass(hostRenderer, hostRNode, classes.join(' '));
13852
- }
13853
- }
13891
+ setRootNodeAttributes(hostRenderer, this.componentDef, hostRNode, rootSelectorOrNode);
13854
13892
  }
13855
- tElementNode = getTNode(rootTView, HEADER_OFFSET);
13856
13893
  if (projectableNodes !== undefined) {
13857
- const projection = tElementNode.projection = [];
13858
- for (let i = 0; i < this.ngContentSelectors.length; i++) {
13859
- const nodesforSlot = projectableNodes[i];
13860
- // Projectable nodes can be passed as array of arrays or an array of iterables (ngUpgrade
13861
- // case). Here we do normalize passed data structure to be an array of arrays to avoid
13862
- // complex checks down the line.
13863
- // We also normalize the length of the passed in projectable nodes (to match the number of
13864
- // <ng-container> slots defined by a component).
13865
- projection.push(nodesforSlot != null ? Array.from(nodesforSlot) : null);
13866
- }
13894
+ projectNodes(tElementNode, this.ngContentSelectors, projectableNodes);
13867
13895
  }
13868
13896
  // TODO: should LifecycleHooksFeature and other host features be generated by the compiler and
13869
13897
  // executed here?
13870
13898
  // Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref
13871
- component =
13872
- createRootComponent(componentView, this.componentDef, rootLView, [LifecycleHooksFeature]);
13899
+ component = createRootComponent(componentView, this.componentDef, rootDirectives, rootLView, [LifecycleHooksFeature]);
13873
13900
  renderView(rootTView, rootLView, null);
13874
13901
  }
13875
13902
  finally {
@@ -13940,11 +13967,22 @@ const NULL_INJECTOR = {
13940
13967
  throwProviderNotFoundError(token, 'NullInjector');
13941
13968
  }
13942
13969
  };
13970
+ /** Creates a TNode that can be used to instantiate a root component. */
13971
+ function createRootComponentTNode(lView, rNode) {
13972
+ const tView = lView[TVIEW];
13973
+ const index = HEADER_OFFSET;
13974
+ ngDevMode && assertIndexInRange(lView, index);
13975
+ lView[index] = rNode;
13976
+ // '#host' is added here as we don't know the real host DOM name (we don't want to read it) and at
13977
+ // the same time we want to communicate the debug `TNode` that this is a special `TNode`
13978
+ // representing a host element.
13979
+ return getOrCreateTNode(tView, index, 2 /* TNodeType.Element */, '#host', null);
13980
+ }
13943
13981
  /**
13944
13982
  * Creates the root component view and the root component node.
13945
13983
  *
13946
13984
  * @param rNode Render host element.
13947
- * @param def ComponentDef
13985
+ * @param rootComponentDef ComponentDef
13948
13986
  * @param rootView The parent view where the host node is stored
13949
13987
  * @param rendererFactory Factory to be used for creating child renderers.
13950
13988
  * @param hostRenderer The current renderer
@@ -13952,72 +13990,96 @@ const NULL_INJECTOR = {
13952
13990
  *
13953
13991
  * @returns Component view created
13954
13992
  */
13955
- function createRootComponentView(rNode, def, rootView, rendererFactory, hostRenderer, sanitizer) {
13993
+ function createRootComponentView(tNode, rNode, rootComponentDef, rootDirectives, rootView, rendererFactory, hostRenderer, sanitizer) {
13956
13994
  const tView = rootView[TVIEW];
13957
- const index = HEADER_OFFSET;
13958
- ngDevMode && assertIndexInRange(rootView, index);
13959
- rootView[index] = rNode;
13960
- // '#host' is added here as we don't know the real host DOM name (we don't want to read it) and at
13961
- // the same time we want to communicate the debug `TNode` that this is a special `TNode`
13962
- // representing a host element.
13963
- const tNode = getOrCreateTNode(tView, index, 2 /* TNodeType.Element */, '#host', null);
13964
- const mergedAttrs = tNode.mergedAttrs = def.hostAttrs;
13965
- if (mergedAttrs !== null) {
13966
- computeStaticStyling(tNode, mergedAttrs, true);
13967
- if (rNode !== null) {
13968
- setUpAttributes(hostRenderer, rNode, mergedAttrs);
13969
- if (tNode.classes !== null) {
13970
- writeDirectClass(hostRenderer, rNode, tNode.classes);
13971
- }
13972
- if (tNode.styles !== null) {
13973
- writeDirectStyle(hostRenderer, rNode, tNode.styles);
13974
- }
13975
- }
13976
- }
13977
- const viewRenderer = rendererFactory.createRenderer(rNode, def);
13978
- const componentView = createLView(rootView, getOrCreateComponentTView(def), null, def.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, rootView[index], tNode, rendererFactory, viewRenderer, sanitizer || null, null, null);
13995
+ applyRootComponentStyling(rootDirectives, tNode, rNode, hostRenderer);
13996
+ const viewRenderer = rendererFactory.createRenderer(rNode, rootComponentDef);
13997
+ const componentView = createLView(rootView, getOrCreateComponentTView(rootComponentDef), null, rootComponentDef.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, rootView[tNode.index], tNode, rendererFactory, viewRenderer, sanitizer || null, null, null);
13979
13998
  if (tView.firstCreatePass) {
13980
- diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, rootView), tView, def.type);
13981
- markAsComponentHost(tView, tNode);
13982
- initTNodeFlags(tNode, rootView.length, 1);
13999
+ diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, rootView), tView, rootComponentDef.type);
14000
+ markAsComponentHost(tView, tNode, 0);
13983
14001
  }
13984
14002
  addToViewTree(rootView, componentView);
13985
14003
  // Store component view at node index, with node as the HOST
13986
- return rootView[index] = componentView;
14004
+ return rootView[tNode.index] = componentView;
14005
+ }
14006
+ /** Sets up the styling information on a root component. */
14007
+ function applyRootComponentStyling(rootDirectives, tNode, rNode, hostRenderer) {
14008
+ for (const def of rootDirectives) {
14009
+ tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, def.hostAttrs);
14010
+ }
14011
+ if (tNode.mergedAttrs !== null) {
14012
+ computeStaticStyling(tNode, tNode.mergedAttrs, true);
14013
+ if (rNode !== null) {
14014
+ setupStaticAttributes(hostRenderer, rNode, tNode);
14015
+ }
14016
+ }
13987
14017
  }
13988
14018
  /**
13989
14019
  * Creates a root component and sets it up with features and host bindings.Shared by
13990
14020
  * renderComponent() and ViewContainerRef.createComponent().
13991
14021
  */
13992
- function createRootComponent(componentView, componentDef, rootLView, hostFeatures) {
14022
+ function createRootComponent(componentView, rootComponentDef, rootDirectives, rootLView, hostFeatures) {
14023
+ const rootTNode = getCurrentTNode();
14024
+ ngDevMode && assertDefined(rootTNode, 'tNode should have been already created');
13993
14025
  const tView = rootLView[TVIEW];
13994
- // Create directive instance with factory() and store at next index in viewData
13995
- const component = instantiateRootComponent(tView, rootLView, componentDef);
13996
- // Root view only contains an instance of this component,
13997
- // so we use a reference to that component instance as a context.
14026
+ const native = getNativeByTNode(rootTNode, rootLView);
14027
+ initializeDirectives(tView, rootLView, rootTNode, rootDirectives, null);
14028
+ for (let i = 0; i < rootDirectives.length; i++) {
14029
+ const directiveIndex = rootTNode.directiveStart + i;
14030
+ const directiveInstance = getNodeInjectable(rootLView, tView, directiveIndex, rootTNode);
14031
+ attachPatchData(directiveInstance, rootLView);
14032
+ }
14033
+ invokeDirectivesHostBindings(tView, rootLView, rootTNode);
14034
+ if (native) {
14035
+ attachPatchData(native, rootLView);
14036
+ }
14037
+ // We're guaranteed for the `componentOffset` to be positive here
14038
+ // since a root component always matches a component def.
14039
+ ngDevMode &&
14040
+ assertGreaterThan(rootTNode.componentOffset, -1, 'componentOffset must be great than -1');
14041
+ const component = getNodeInjectable(rootLView, tView, rootTNode.directiveStart + rootTNode.componentOffset, rootTNode);
13998
14042
  componentView[CONTEXT] = rootLView[CONTEXT] = component;
13999
14043
  if (hostFeatures !== null) {
14000
14044
  for (const feature of hostFeatures) {
14001
- feature(component, componentDef);
14045
+ feature(component, rootComponentDef);
14002
14046
  }
14003
14047
  }
14004
14048
  // We want to generate an empty QueryList for root content queries for backwards
14005
14049
  // compatibility with ViewEngine.
14006
- if (componentDef.contentQueries) {
14007
- const tNode = getCurrentTNode();
14008
- ngDevMode && assertDefined(tNode, 'TNode expected');
14009
- componentDef.contentQueries(1 /* RenderFlags.Create */, component, tNode.directiveStart);
14050
+ executeContentQueries(tView, rootTNode, componentView);
14051
+ return component;
14052
+ }
14053
+ /** Sets the static attributes on a root component. */
14054
+ function setRootNodeAttributes(hostRenderer, componentDef, hostRNode, rootSelectorOrNode) {
14055
+ if (rootSelectorOrNode) {
14056
+ setUpAttributes(hostRenderer, hostRNode, ['ng-version', VERSION.full]);
14010
14057
  }
14011
- const rootTNode = getCurrentTNode();
14012
- ngDevMode && assertDefined(rootTNode, 'tNode should have been already created');
14013
- if (tView.firstCreatePass &&
14014
- (componentDef.hostBindings !== null || componentDef.hostAttrs !== null)) {
14015
- setSelectedIndex(rootTNode.index);
14016
- const rootTView = rootLView[TVIEW];
14017
- registerHostBindingOpCodes(rootTView, rootTNode, rootLView, rootTNode.directiveStart, rootTNode.directiveEnd, componentDef);
14018
- invokeHostBindingsInCreationMode(componentDef, component);
14058
+ else {
14059
+ // If host element is created as a part of this function call (i.e. `rootSelectorOrNode`
14060
+ // is not defined), also apply attributes and classes extracted from component selector.
14061
+ // Extract attributes and classes from the first selector only to match VE behavior.
14062
+ const { attrs, classes } = extractAttrsAndClassesFromSelector(componentDef.selectors[0]);
14063
+ if (attrs) {
14064
+ setUpAttributes(hostRenderer, hostRNode, attrs);
14065
+ }
14066
+ if (classes && classes.length > 0) {
14067
+ writeDirectClass(hostRenderer, hostRNode, classes.join(' '));
14068
+ }
14069
+ }
14070
+ }
14071
+ /** Projects the `projectableNodes` that were specified when creating a root component. */
14072
+ function projectNodes(tNode, ngContentSelectors, projectableNodes) {
14073
+ const projection = tNode.projection = [];
14074
+ for (let i = 0; i < ngContentSelectors.length; i++) {
14075
+ const nodesforSlot = projectableNodes[i];
14076
+ // Projectable nodes can be passed as array of arrays or an array of iterables (ngUpgrade
14077
+ // case). Here we do normalize passed data structure to be an array of arrays to avoid
14078
+ // complex checks down the line.
14079
+ // We also normalize the length of the passed in projectable nodes (to match the number of
14080
+ // <ng-container> slots defined by a component).
14081
+ projection.push(nodesforSlot != null ? Array.from(nodesforSlot) : null);
14019
14082
  }
14020
- return component;
14021
14083
  }
14022
14084
  /**
14023
14085
  * Used to enable lifecycle hooks on the root component.
@@ -14275,6 +14337,13 @@ function ɵɵCopyDefinitionFeature(definition) {
14275
14337
  }
14276
14338
  }
14277
14339
 
14340
+ /**
14341
+ * @license
14342
+ * Copyright Google LLC All Rights Reserved.
14343
+ *
14344
+ * Use of this source code is governed by an MIT-style license that can be
14345
+ * found in the LICENSE file at https://angular.io/license
14346
+ */
14278
14347
  /**
14279
14348
  * This feature add the host directives behavior to a directive definition by patching a
14280
14349
  * function onto it. The expectation is that the runtime will invoke the function during
@@ -14296,29 +14365,42 @@ function ɵɵCopyDefinitionFeature(definition) {
14296
14365
  * @codeGenApi
14297
14366
  */
14298
14367
  function ɵɵHostDirectivesFeature(rawHostDirectives) {
14299
- const unwrappedHostDirectives = Array.isArray(rawHostDirectives) ? rawHostDirectives : rawHostDirectives();
14300
- const hostDirectives = unwrappedHostDirectives.map(dir => typeof dir === 'function' ? { directive: dir, inputs: EMPTY_OBJ, outputs: EMPTY_OBJ } : {
14301
- directive: dir.directive,
14302
- inputs: bindingArrayToMap(dir.inputs),
14303
- outputs: bindingArrayToMap(dir.outputs)
14304
- });
14305
14368
  return (definition) => {
14306
- // TODO(crisbeto): implement host directive matching logic.
14307
- definition.applyHostDirectives =
14308
- (tView, viewData, tNode, matches) => { };
14369
+ definition.findHostDirectiveDefs = findHostDirectiveDefs;
14370
+ definition.hostDirectives =
14371
+ (Array.isArray(rawHostDirectives) ? rawHostDirectives : rawHostDirectives()).map(dir => {
14372
+ return typeof dir === 'function' ?
14373
+ { directive: resolveForwardRef(dir), inputs: EMPTY_OBJ, outputs: EMPTY_OBJ } :
14374
+ {
14375
+ directive: resolveForwardRef(dir.directive),
14376
+ inputs: bindingArrayToMap(dir.inputs),
14377
+ outputs: bindingArrayToMap(dir.outputs)
14378
+ };
14379
+ });
14309
14380
  };
14310
14381
  }
14382
+ function findHostDirectiveDefs(matches, def, tView, lView, tNode) {
14383
+ if (def.hostDirectives !== null) {
14384
+ for (const hostDirectiveConfig of def.hostDirectives) {
14385
+ const hostDirectiveDef = getDirectiveDef(hostDirectiveConfig.directive);
14386
+ // TODO(crisbeto): assert that the def exists.
14387
+ // Host directives execute before the host so that its host bindings can be overwritten.
14388
+ findHostDirectiveDefs(matches, hostDirectiveDef, tView, lView, tNode);
14389
+ matches.push(hostDirectiveDef);
14390
+ }
14391
+ }
14392
+ }
14311
14393
  /**
14312
14394
  * Converts an array in the form of `['publicName', 'alias', 'otherPublicName', 'otherAlias']` into
14313
14395
  * a map in the form of `{publicName: 'alias', otherPublicName: 'otherAlias'}`.
14314
14396
  */
14315
14397
  function bindingArrayToMap(bindings) {
14316
- if (!bindings || bindings.length === 0) {
14398
+ if (bindings === undefined || bindings.length === 0) {
14317
14399
  return EMPTY_OBJ;
14318
14400
  }
14319
14401
  const result = {};
14320
- for (let i = 1; i < bindings.length; i += 2) {
14321
- result[bindings[i - 1]] = bindings[i];
14402
+ for (let i = 0; i < bindings.length; i += 2) {
14403
+ result[bindings[i]] = bindings[i + 1];
14322
14404
  }
14323
14405
  return result;
14324
14406
  }
@@ -15265,19 +15347,8 @@ function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
15265
15347
  elementStartFirstCreatePass(adjustedIndex, tView, lView, native, name, attrsIndex, localRefsIndex) :
15266
15348
  tView.data[adjustedIndex];
15267
15349
  setCurrentTNode(tNode, true);
15268
- const mergedAttrs = tNode.mergedAttrs;
15269
- if (mergedAttrs !== null) {
15270
- setUpAttributes(renderer, native, mergedAttrs);
15271
- }
15272
- const classes = tNode.classes;
15273
- if (classes !== null) {
15274
- writeDirectClass(renderer, native, classes);
15275
- }
15276
- const styles = tNode.styles;
15277
- if (styles !== null) {
15278
- writeDirectStyle(renderer, native, styles);
15279
- }
15280
- if ((tNode.flags & 64 /* TNodeFlags.isDetached */) !== 64 /* TNodeFlags.isDetached */) {
15350
+ setupStaticAttributes(renderer, native, tNode);
15351
+ if ((tNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
15281
15352
  // In the i18n case, the translation may have removed this element, so only add it if it is not
15282
15353
  // detached. See `TNodeType.Placeholder` and `LFrame.inI18n` for more context.
15283
15354
  appendChild(tView, lView, native, tNode);
@@ -15715,9 +15786,7 @@ function wrapListener(tNode, lView, context, listenerFn, wrapWithPreventDefault)
15715
15786
  }
15716
15787
  // In order to be backwards compatible with View Engine, events on component host nodes
15717
15788
  // must also mark the component view itself dirty (i.e. the view that it owns).
15718
- const startView = tNode.flags & 2 /* TNodeFlags.isComponentHost */ ?
15719
- getComponentLViewByIndex(tNode.index, lView) :
15720
- lView;
15789
+ const startView = tNode.componentOffset > -1 ? getComponentLViewByIndex(tNode.index, lView) : lView;
15721
15790
  markViewDirty(startView);
15722
15791
  let result = executeListenerWithErrorHandling(lView, context, listenerFn, e);
15723
15792
  // A just-invoked listener function might have coalesced listeners so we need to check for
@@ -15874,7 +15943,7 @@ function ɵɵprojection(nodeIndex, selectorIndex = 0, attrs) {
15874
15943
  tProjectionNode.projection = selectorIndex;
15875
15944
  // `<ng-content>` has no content
15876
15945
  setCurrentTNodeAsNotParent();
15877
- if ((tProjectionNode.flags & 64 /* TNodeFlags.isDetached */) !== 64 /* TNodeFlags.isDetached */) {
15946
+ if ((tProjectionNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
15878
15947
  // re-distribution of projectable nodes is stored on a component's view level
15879
15948
  applyProjection(tView, lView, tProjectionNode);
15880
15949
  }
@@ -17788,7 +17857,7 @@ function normalizeSuffix(value, suffix) {
17788
17857
  * @param isClassBased `true` if `class` (`false` if `style`)
17789
17858
  */
17790
17859
  function hasStylingInputShadow(tNode, isClassBased) {
17791
- return (tNode.flags & (isClassBased ? 16 /* TNodeFlags.hasClassInput */ : 32 /* TNodeFlags.hasStyleInput */)) !== 0;
17860
+ return (tNode.flags & (isClassBased ? 8 /* TNodeFlags.hasClassInput */ : 16 /* TNodeFlags.hasStyleInput */)) !== 0;
17792
17861
  }
17793
17862
 
17794
17863
  /**
@@ -19480,7 +19549,7 @@ function processI18nInsertBefore(renderer, childTNode, lView, childRNode, parent
19480
19549
  anchorRNode = i18nParent;
19481
19550
  i18nParent = parentRElement;
19482
19551
  }
19483
- if (i18nParent !== null && (childTNode.flags & 2 /* TNodeFlags.isComponentHost */) === 0) {
19552
+ if (i18nParent !== null && childTNode.componentOffset === -1) {
19484
19553
  for (let i = 1; i < tNodeInsertBeforeIndex.length; i++) {
19485
19554
  // No need to `unwrapRNode` because all of the indexes point to i18n text nodes.
19486
19555
  // see `assertDomNode` below.
@@ -21968,7 +22037,7 @@ function getDirectives(node) {
21968
22037
  return [];
21969
22038
  }
21970
22039
  if (context.directives === undefined) {
21971
- context.directives = getDirectivesAtNodeIndex(nodeIndex, lView, false);
22040
+ context.directives = getDirectivesAtNodeIndex(nodeIndex, lView);
21972
22041
  }
21973
22042
  // The `directives` in this case are a named array called `LComponentView`. Clone the
21974
22043
  // result so we don't expose an internal data structure in the user's console.
@@ -24981,7 +25050,12 @@ function directiveMetadata(type, metadata) {
24981
25050
  providers: metadata.providers || null,
24982
25051
  viewQueries: extractQueriesMetadata(type, propMetadata, isViewQuery),
24983
25052
  isStandalone: !!metadata.standalone,
24984
- hostDirectives: null,
25053
+ hostDirectives:
25054
+ // TODO(crisbeto): remove the `as any` usage here and down in the `map` call once
25055
+ // host directives are exposed in the public API.
25056
+ metadata
25057
+ .hostDirectives?.map((directive) => typeof directive === 'function' ? { directive } : directive) ||
25058
+ null
24985
25059
  };
24986
25060
  }
24987
25061
  /**
@@ -25972,6 +26046,34 @@ function getNativeRequestAnimationFrame() {
25972
26046
  return { nativeRequestAnimationFrame, nativeCancelAnimationFrame };
25973
26047
  }
25974
26048
 
26049
+ /**
26050
+ * @license
26051
+ * Copyright Google LLC All Rights Reserved.
26052
+ *
26053
+ * Use of this source code is governed by an MIT-style license that can be
26054
+ * found in the LICENSE file at https://angular.io/license
26055
+ */
26056
+ class AsyncStackTaggingZoneSpec {
26057
+ constructor(namePrefix, consoleAsyncStackTaggingImpl = console) {
26058
+ this.name = 'asyncStackTagging for ' + namePrefix;
26059
+ this.createTask = consoleAsyncStackTaggingImpl?.createTask ?? (() => null);
26060
+ }
26061
+ onScheduleTask(delegate, _current, target, task) {
26062
+ task.consoleTask = this.createTask(`Zone - ${task.source || task.type}`);
26063
+ return delegate.scheduleTask(target, task);
26064
+ }
26065
+ onInvokeTask(delegate, _currentZone, targetZone, task, applyThis, applyArgs) {
26066
+ let ret;
26067
+ if (task.consoleTask) {
26068
+ ret = task.consoleTask.run(() => delegate.invokeTask(targetZone, task, applyThis, applyArgs));
26069
+ }
26070
+ else {
26071
+ ret = delegate.invokeTask(targetZone, task, applyThis, applyArgs);
26072
+ }
26073
+ return ret;
26074
+ }
26075
+ }
26076
+
25975
26077
  /**
25976
26078
  * @license
25977
26079
  * Copyright Google LLC All Rights Reserved.
@@ -26088,8 +26190,12 @@ class NgZone {
26088
26190
  const self = this;
26089
26191
  self._nesting = 0;
26090
26192
  self._outer = self._inner = Zone.current;
26091
- if (Zone['AsyncStackTaggingZoneSpec']) {
26092
- const AsyncStackTaggingZoneSpec = Zone['AsyncStackTaggingZoneSpec'];
26193
+ // AsyncStackTaggingZoneSpec provides `linked stack traces` to show
26194
+ // where the async operation is scheduled. For more details, refer
26195
+ // to this article, https://developer.chrome.com/blog/devtools-better-angular-debugging/
26196
+ // And we only import this AsyncStackTaggingZoneSpec in development mode,
26197
+ // in the production mode, the AsyncStackTaggingZoneSpec will be tree shaken away.
26198
+ if (ngDevMode) {
26093
26199
  self._inner = self._inner.fork(new AsyncStackTaggingZoneSpec('Angular'));
26094
26200
  }
26095
26201
  if (Zone['TaskTrackingZoneSpec']) {
@@ -27523,24 +27629,16 @@ function _mergeArrays(parts) {
27523
27629
  * found in the LICENSE file at https://angular.io/license
27524
27630
  */
27525
27631
  /**
27526
- * This file is used to control if the default rendering pipeline should be `ViewEngine` or `Ivy`.
27527
- *
27528
- * For more information on how to run and debug tests with either Ivy or View Engine (legacy),
27529
- * please see [BAZEL.md](./docs/BAZEL.md).
27530
- */
27531
- let _devMode = true;
27532
- let _runModeLocked = false;
27533
- /**
27534
- * Returns whether Angular is in development mode. After called once,
27535
- * the value is locked and won't change any more.
27632
+ * Returns whether Angular is in development mode.
27536
27633
  *
27537
- * By default, this is true, unless a user calls `enableProdMode` before calling this.
27634
+ * By default, this is true, unless `enableProdMode` is invoked prior to calling this method or the
27635
+ * application is built using the Angular CLI with the `optimization` option.
27636
+ * @see {@link cli/build ng build}
27538
27637
  *
27539
27638
  * @publicApi
27540
27639
  */
27541
27640
  function isDevMode() {
27542
- _runModeLocked = true;
27543
- return _devMode;
27641
+ return typeof ngDevMode === 'undefined' || !!ngDevMode;
27544
27642
  }
27545
27643
  /**
27546
27644
  * Disable Angular's development mode, which turns off assertions and other
@@ -27550,18 +27648,18 @@ function isDevMode() {
27550
27648
  * does not result in additional changes to any bindings (also known as
27551
27649
  * unidirectional data flow).
27552
27650
  *
27651
+ * Using this method is discouraged as the Angular CLI will set production mode when using the
27652
+ * `optimization` option.
27653
+ * @see {@link cli/build ng build}
27654
+ *
27553
27655
  * @publicApi
27554
27656
  */
27555
27657
  function enableProdMode() {
27556
- if (_runModeLocked) {
27557
- throw new Error('Cannot enable prod mode after platform setup.');
27558
- }
27559
27658
  // The below check is there so when ngDevMode is set via terser
27560
27659
  // `global['ngDevMode'] = false;` is also dropped.
27561
- if (typeof ngDevMode === undefined || !!ngDevMode) {
27660
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
27562
27661
  _global['ngDevMode'] = false;
27563
27662
  }
27564
- _devMode = false;
27565
27663
  }
27566
27664
 
27567
27665
  /**
@@ -28235,7 +28333,7 @@ function _queryNodeChildren(tNode, lView, predicate, matches, elementsOnly, root
28235
28333
  if (rootNativeNode !== nativeNode) {
28236
28334
  // To determine the next node to be processed, we need to use the next or the projectionNext
28237
28335
  // link, depending on whether the current node has been projected.
28238
- const nextTNode = (tNode.flags & 4 /* TNodeFlags.isProjected */) ? tNode.projectionNext : tNode.next;
28336
+ const nextTNode = (tNode.flags & 2 /* TNodeFlags.isProjected */) ? tNode.projectionNext : tNode.next;
28239
28337
  if (nextTNode) {
28240
28338
  _queryNodeChildren(nextTNode, lView, predicate, matches, elementsOnly, rootNativeNode);
28241
28339
  }
@@ -29807,5 +29905,5 @@ if (typeof ngDevMode !== 'undefined' && ngDevMode) {
29807
29905
  * Generated bundle index. Do not edit.
29808
29906
  */
29809
29907
 
29810
- export { ANALYZE_FOR_ENTRY_COMPONENTS, ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, ApplicationInitStatus, ApplicationModule, ApplicationRef, Attribute, COMPILER_OPTIONS, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Compiler, CompilerFactory, Component, ComponentFactory$1 as ComponentFactory, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ContentChild, ContentChildren, DEFAULT_CURRENCY_CODE, DebugElement, DebugEventListener, DebugNode, DefaultIterableDiffer, Directive, ENVIRONMENT_INITIALIZER, ElementRef, EmbeddedViewRef, EnvironmentInjector, ErrorHandler, EventEmitter, Host, HostBinding, HostListener, INJECTOR, Inject, InjectFlags, Injectable, InjectionToken, Injector, Input, IterableDiffers, KeyValueDiffers, LOCALE_ID, MissingTranslationStrategy, ModuleWithComponentFactories, NO_ERRORS_SCHEMA, NgModule, NgModuleFactory$1 as NgModuleFactory, NgModuleRef$1 as NgModuleRef, NgProbeToken, NgZone, Optional, Output, PACKAGE_ROOT_URL, PLATFORM_ID, PLATFORM_INITIALIZER, Pipe, PlatformRef, Query, QueryList, ReflectiveInjector, ReflectiveKey, Renderer2, RendererFactory2, RendererStyleFlags2, ResolvedReflectiveFactory, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, Type, VERSION, Version, ViewChild, ViewChildren, ViewContainerRef, ViewEncapsulation$1 as ViewEncapsulation, ViewRef, asNativeElements, assertPlatform, createComponent, createEnvironmentInjector, createNgModule, createNgModuleRef, createPlatform, createPlatformFactory, defineInjectable, destroyPlatform, enableProdMode, forwardRef, getDebugNode, getModuleFactory, getNgModuleById, getPlatform, importProvidersFrom, inject, isDevMode, platformCore, reflectComponentType, resolveForwardRef, setTestabilityGetter, ALLOW_MULTIPLE_PLATFORMS as ɵALLOW_MULTIPLE_PLATFORMS, APP_ID_RANDOM_PROVIDER as ɵAPP_ID_RANDOM_PROVIDER, ChangeDetectorStatus as ɵChangeDetectorStatus, ComponentFactory$1 as ɵComponentFactory, Console as ɵConsole, DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID, INJECTOR_SCOPE as ɵINJECTOR_SCOPE, LContext as ɵLContext, LifecycleHooksFeature as ɵLifecycleHooksFeature, LocaleDataIndex as ɵLocaleDataIndex, NG_COMP_DEF as ɵNG_COMP_DEF, NG_DIR_DEF as ɵNG_DIR_DEF, NG_ELEMENT_ID as ɵNG_ELEMENT_ID, NG_INJ_DEF as ɵNG_INJ_DEF, NG_MOD_DEF as ɵNG_MOD_DEF, NG_PIPE_DEF as ɵNG_PIPE_DEF, NG_PROV_DEF as ɵNG_PROV_DEF, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE as ɵNO_CHANGE, NgModuleFactory as ɵNgModuleFactory, NoopNgZone as ɵNoopNgZone, ReflectionCapabilities as ɵReflectionCapabilities, ComponentFactory as ɵRender3ComponentFactory, ComponentRef as ɵRender3ComponentRef, NgModuleRef as ɵRender3NgModuleRef, RuntimeError as ɵRuntimeError, TESTABILITY as ɵTESTABILITY, TESTABILITY_GETTER as ɵTESTABILITY_GETTER, ViewRef$1 as ɵViewRef, _sanitizeHtml as ɵ_sanitizeHtml, _sanitizeUrl as ɵ_sanitizeUrl, allowSanitizationBypassAndThrow as ɵallowSanitizationBypassAndThrow, bypassSanitizationTrustHtml as ɵbypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl as ɵbypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript as ɵbypassSanitizationTrustScript, bypassSanitizationTrustStyle as ɵbypassSanitizationTrustStyle, bypassSanitizationTrustUrl as ɵbypassSanitizationTrustUrl, clearResolutionOfComponentResourcesQueue as ɵclearResolutionOfComponentResourcesQueue, coerceToBoolean as ɵcoerceToBoolean, compileComponent as ɵcompileComponent, compileDirective as ɵcompileDirective, compileNgModule as ɵcompileNgModule, compileNgModuleDefs as ɵcompileNgModuleDefs, compileNgModuleFactory as ɵcompileNgModuleFactory, compilePipe as ɵcompilePipe, createInjector as ɵcreateInjector, defaultIterableDiffers as ɵdefaultIterableDiffers, defaultKeyValueDiffers as ɵdefaultKeyValueDiffers, detectChanges as ɵdetectChanges, devModeEqual as ɵdevModeEqual, findLocaleData as ɵfindLocaleData, flushModuleScopingQueueAsMuchAsPossible as ɵflushModuleScopingQueueAsMuchAsPossible, formatRuntimeError as ɵformatRuntimeError, getDebugNode as ɵgetDebugNode, getDebugNodeR2 as ɵgetDebugNodeR2, getDirectives as ɵgetDirectives, getHostElement as ɵgetHostElement, getInjectableDef as ɵgetInjectableDef, getLContext as ɵgetLContext, getLocaleCurrencyCode as ɵgetLocaleCurrencyCode, getLocalePluralCase as ɵgetLocalePluralCase, getSanitizationBypassType as ɵgetSanitizationBypassType, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, _global as ɵglobal, injectChangeDetectorRef as ɵinjectChangeDetectorRef, internalCreateApplication as ɵinternalCreateApplication, isBoundToModule as ɵisBoundToModule, isDefaultChangeDetectionStrategy as ɵisDefaultChangeDetectionStrategy, isInjectable as ɵisInjectable, isListLikeIterable as ɵisListLikeIterable, isObservable as ɵisObservable, isPromise as ɵisPromise, isStandalone as ɵisStandalone, isSubscribable as ɵisSubscribable, ɵivyEnabled, makeDecorator as ɵmakeDecorator, noSideEffects as ɵnoSideEffects, patchComponentDefWithScope as ɵpatchComponentDefWithScope, publishDefaultGlobalUtils$1 as ɵpublishDefaultGlobalUtils, publishGlobalUtil as ɵpublishGlobalUtil, registerLocaleData as ɵregisterLocaleData, resetCompiledComponents as ɵresetCompiledComponents, resetJitOptions as ɵresetJitOptions, resolveComponentResources as ɵresolveComponentResources, setAllowDuplicateNgModuleIdsForTest as ɵsetAllowDuplicateNgModuleIdsForTest, setClassMetadata as ɵsetClassMetadata, setCurrentInjector as ɵsetCurrentInjector, setDocument as ɵsetDocument, setLocaleId as ɵsetLocaleId, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, store as ɵstore, stringify as ɵstringify, transitiveScopesFor as ɵtransitiveScopesFor, unregisterAllLocaleData as ɵunregisterLocaleData, unwrapSafeValue as ɵunwrapSafeValue, ɵɵCopyDefinitionFeature, FactoryTarget as ɵɵFactoryTarget, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵStandaloneFeature, ɵɵadvance, ɵɵattribute, ɵɵattributeInterpolate1, ɵɵattributeInterpolate2, ɵɵattributeInterpolate3, ɵɵattributeInterpolate4, ɵɵattributeInterpolate5, ɵɵattributeInterpolate6, ɵɵattributeInterpolate7, ɵɵattributeInterpolate8, ɵɵattributeInterpolateV, ɵɵclassMap, ɵɵclassMapInterpolate1, ɵɵclassMapInterpolate2, ɵɵclassMapInterpolate3, ɵɵclassMapInterpolate4, ɵɵclassMapInterpolate5, ɵɵclassMapInterpolate6, ɵɵclassMapInterpolate7, ɵɵclassMapInterpolate8, ɵɵclassMapInterpolateV, ɵɵclassProp, ɵɵcontentQuery, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineInjectable, ɵɵdefineInjector, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdisableBindings, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵenableBindings, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵhostProperty, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinject, ɵɵinjectAttribute, ɵɵinvalidFactory, ɵɵinvalidFactoryDep, ɵɵlistener, ɵɵloadQuery, ɵɵnamespaceHTML, ɵɵnamespaceMathML, ɵɵnamespaceSVG, ɵɵnextContext, ɵɵngDeclareClassMetadata, ɵɵngDeclareComponent, ɵɵngDeclareDirective, ɵɵngDeclareFactory, ɵɵngDeclareInjectable, ɵɵngDeclareInjector, ɵɵngDeclareNgModule, ɵɵngDeclarePipe, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpropertyInterpolate, ɵɵpropertyInterpolate1, ɵɵpropertyInterpolate2, ɵɵpropertyInterpolate3, ɵɵpropertyInterpolate4, ɵɵpropertyInterpolate5, ɵɵpropertyInterpolate6, ɵɵpropertyInterpolate7, ɵɵpropertyInterpolate8, ɵɵpropertyInterpolateV, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryRefresh, ɵɵreference, registerNgModuleType as ɵɵregisterNgModuleType, ɵɵresetView, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵrestoreView, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstyleMap, ɵɵstyleMapInterpolate1, ɵɵstyleMapInterpolate2, ɵɵstyleMapInterpolate3, ɵɵstyleMapInterpolate4, ɵɵstyleMapInterpolate5, ɵɵstyleMapInterpolate6, ɵɵstyleMapInterpolate7, ɵɵstyleMapInterpolate8, ɵɵstyleMapInterpolateV, ɵɵstyleProp, ɵɵstylePropInterpolate1, ɵɵstylePropInterpolate2, ɵɵstylePropInterpolate3, ɵɵstylePropInterpolate4, ɵɵstylePropInterpolate5, ɵɵstylePropInterpolate6, ɵɵstylePropInterpolate7, ɵɵstylePropInterpolate8, ɵɵstylePropInterpolateV, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵviewQuery };
29908
+ export { ANALYZE_FOR_ENTRY_COMPONENTS, ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, ApplicationInitStatus, ApplicationModule, ApplicationRef, Attribute, COMPILER_OPTIONS, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Compiler, CompilerFactory, Component, ComponentFactory$1 as ComponentFactory, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ContentChild, ContentChildren, DEFAULT_CURRENCY_CODE, DebugElement, DebugEventListener, DebugNode, DefaultIterableDiffer, Directive, ENVIRONMENT_INITIALIZER, ElementRef, EmbeddedViewRef, EnvironmentInjector, ErrorHandler, EventEmitter, Host, HostBinding, HostListener, INJECTOR, Inject, InjectFlags, Injectable, InjectionToken, Injector, Input, IterableDiffers, KeyValueDiffers, LOCALE_ID, MissingTranslationStrategy, ModuleWithComponentFactories, NO_ERRORS_SCHEMA, NgModule, NgModuleFactory$1 as NgModuleFactory, NgModuleRef$1 as NgModuleRef, NgProbeToken, NgZone, Optional, Output, PACKAGE_ROOT_URL, PLATFORM_ID, PLATFORM_INITIALIZER, Pipe, PlatformRef, Query, QueryList, ReflectiveInjector, ReflectiveKey, Renderer2, RendererFactory2, RendererStyleFlags2, ResolvedReflectiveFactory, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, Type, VERSION, Version, ViewChild, ViewChildren, ViewContainerRef, ViewEncapsulation$1 as ViewEncapsulation, ViewRef, asNativeElements, assertPlatform, createComponent, createEnvironmentInjector, createNgModule, createNgModuleRef, createPlatform, createPlatformFactory, defineInjectable, destroyPlatform, enableProdMode, forwardRef, getDebugNode, getModuleFactory, getNgModuleById, getPlatform, importProvidersFrom, inject, isDevMode, platformCore, reflectComponentType, resolveForwardRef, setTestabilityGetter, ALLOW_MULTIPLE_PLATFORMS as ɵALLOW_MULTIPLE_PLATFORMS, APP_ID_RANDOM_PROVIDER as ɵAPP_ID_RANDOM_PROVIDER, ChangeDetectorStatus as ɵChangeDetectorStatus, ComponentFactory$1 as ɵComponentFactory, Console as ɵConsole, DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID, INJECTOR_SCOPE as ɵINJECTOR_SCOPE, LContext as ɵLContext, LifecycleHooksFeature as ɵLifecycleHooksFeature, LocaleDataIndex as ɵLocaleDataIndex, NG_COMP_DEF as ɵNG_COMP_DEF, NG_DIR_DEF as ɵNG_DIR_DEF, NG_ELEMENT_ID as ɵNG_ELEMENT_ID, NG_INJ_DEF as ɵNG_INJ_DEF, NG_MOD_DEF as ɵNG_MOD_DEF, NG_PIPE_DEF as ɵNG_PIPE_DEF, NG_PROV_DEF as ɵNG_PROV_DEF, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE as ɵNO_CHANGE, NgModuleFactory as ɵNgModuleFactory, NoopNgZone as ɵNoopNgZone, ReflectionCapabilities as ɵReflectionCapabilities, ComponentFactory as ɵRender3ComponentFactory, ComponentRef as ɵRender3ComponentRef, NgModuleRef as ɵRender3NgModuleRef, RuntimeError as ɵRuntimeError, TESTABILITY as ɵTESTABILITY, TESTABILITY_GETTER as ɵTESTABILITY_GETTER, ViewRef$1 as ɵViewRef, _sanitizeHtml as ɵ_sanitizeHtml, _sanitizeUrl as ɵ_sanitizeUrl, allowSanitizationBypassAndThrow as ɵallowSanitizationBypassAndThrow, bypassSanitizationTrustHtml as ɵbypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl as ɵbypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript as ɵbypassSanitizationTrustScript, bypassSanitizationTrustStyle as ɵbypassSanitizationTrustStyle, bypassSanitizationTrustUrl as ɵbypassSanitizationTrustUrl, clearResolutionOfComponentResourcesQueue as ɵclearResolutionOfComponentResourcesQueue, coerceToBoolean as ɵcoerceToBoolean, compileComponent as ɵcompileComponent, compileDirective as ɵcompileDirective, compileNgModule as ɵcompileNgModule, compileNgModuleDefs as ɵcompileNgModuleDefs, compileNgModuleFactory as ɵcompileNgModuleFactory, compilePipe as ɵcompilePipe, convertToBitFlags as ɵconvertToBitFlags, createInjector as ɵcreateInjector, defaultIterableDiffers as ɵdefaultIterableDiffers, defaultKeyValueDiffers as ɵdefaultKeyValueDiffers, detectChanges as ɵdetectChanges, devModeEqual as ɵdevModeEqual, findLocaleData as ɵfindLocaleData, flushModuleScopingQueueAsMuchAsPossible as ɵflushModuleScopingQueueAsMuchAsPossible, formatRuntimeError as ɵformatRuntimeError, getDebugNode as ɵgetDebugNode, getDebugNodeR2 as ɵgetDebugNodeR2, getDirectives as ɵgetDirectives, getHostElement as ɵgetHostElement, getInjectableDef as ɵgetInjectableDef, getLContext as ɵgetLContext, getLocaleCurrencyCode as ɵgetLocaleCurrencyCode, getLocalePluralCase as ɵgetLocalePluralCase, getSanitizationBypassType as ɵgetSanitizationBypassType, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, _global as ɵglobal, injectChangeDetectorRef as ɵinjectChangeDetectorRef, internalCreateApplication as ɵinternalCreateApplication, isBoundToModule as ɵisBoundToModule, isDefaultChangeDetectionStrategy as ɵisDefaultChangeDetectionStrategy, isInjectable as ɵisInjectable, isListLikeIterable as ɵisListLikeIterable, isObservable as ɵisObservable, isPromise as ɵisPromise, isStandalone as ɵisStandalone, isSubscribable as ɵisSubscribable, ɵivyEnabled, makeDecorator as ɵmakeDecorator, noSideEffects as ɵnoSideEffects, patchComponentDefWithScope as ɵpatchComponentDefWithScope, publishDefaultGlobalUtils$1 as ɵpublishDefaultGlobalUtils, publishGlobalUtil as ɵpublishGlobalUtil, registerLocaleData as ɵregisterLocaleData, resetCompiledComponents as ɵresetCompiledComponents, resetJitOptions as ɵresetJitOptions, resolveComponentResources as ɵresolveComponentResources, setAllowDuplicateNgModuleIdsForTest as ɵsetAllowDuplicateNgModuleIdsForTest, setClassMetadata as ɵsetClassMetadata, setCurrentInjector as ɵsetCurrentInjector, setDocument as ɵsetDocument, setLocaleId as ɵsetLocaleId, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, store as ɵstore, stringify as ɵstringify, transitiveScopesFor as ɵtransitiveScopesFor, unregisterAllLocaleData as ɵunregisterLocaleData, unwrapSafeValue as ɵunwrapSafeValue, ɵɵCopyDefinitionFeature, FactoryTarget as ɵɵFactoryTarget, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵStandaloneFeature, ɵɵadvance, ɵɵattribute, ɵɵattributeInterpolate1, ɵɵattributeInterpolate2, ɵɵattributeInterpolate3, ɵɵattributeInterpolate4, ɵɵattributeInterpolate5, ɵɵattributeInterpolate6, ɵɵattributeInterpolate7, ɵɵattributeInterpolate8, ɵɵattributeInterpolateV, ɵɵclassMap, ɵɵclassMapInterpolate1, ɵɵclassMapInterpolate2, ɵɵclassMapInterpolate3, ɵɵclassMapInterpolate4, ɵɵclassMapInterpolate5, ɵɵclassMapInterpolate6, ɵɵclassMapInterpolate7, ɵɵclassMapInterpolate8, ɵɵclassMapInterpolateV, ɵɵclassProp, ɵɵcontentQuery, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineInjectable, ɵɵdefineInjector, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdisableBindings, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵenableBindings, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵhostProperty, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinject, ɵɵinjectAttribute, ɵɵinvalidFactory, ɵɵinvalidFactoryDep, ɵɵlistener, ɵɵloadQuery, ɵɵnamespaceHTML, ɵɵnamespaceMathML, ɵɵnamespaceSVG, ɵɵnextContext, ɵɵngDeclareClassMetadata, ɵɵngDeclareComponent, ɵɵngDeclareDirective, ɵɵngDeclareFactory, ɵɵngDeclareInjectable, ɵɵngDeclareInjector, ɵɵngDeclareNgModule, ɵɵngDeclarePipe, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpropertyInterpolate, ɵɵpropertyInterpolate1, ɵɵpropertyInterpolate2, ɵɵpropertyInterpolate3, ɵɵpropertyInterpolate4, ɵɵpropertyInterpolate5, ɵɵpropertyInterpolate6, ɵɵpropertyInterpolate7, ɵɵpropertyInterpolate8, ɵɵpropertyInterpolateV, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryRefresh, ɵɵreference, registerNgModuleType as ɵɵregisterNgModuleType, ɵɵresetView, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵrestoreView, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstyleMap, ɵɵstyleMapInterpolate1, ɵɵstyleMapInterpolate2, ɵɵstyleMapInterpolate3, ɵɵstyleMapInterpolate4, ɵɵstyleMapInterpolate5, ɵɵstyleMapInterpolate6, ɵɵstyleMapInterpolate7, ɵɵstyleMapInterpolate8, ɵɵstyleMapInterpolateV, ɵɵstyleProp, ɵɵstylePropInterpolate1, ɵɵstylePropInterpolate2, ɵɵstylePropInterpolate3, ɵɵstylePropInterpolate4, ɵɵstylePropInterpolate5, ɵɵstylePropInterpolate6, ɵɵstylePropInterpolate7, ɵɵstylePropInterpolate8, ɵɵstylePropInterpolateV, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵviewQuery };
29811
29909
  //# sourceMappingURL=core.mjs.map