fix(ivy): objects like ElementRef should not use a special injection fn (#26064)
PR Close #26064
This commit is contained in:
parent
482e12c940
commit
6a62ed2245
|
@ -68,21 +68,9 @@ export function getConstructorDependencies(
|
|||
const importedSymbol = reflector.getImportOfIdentifier(tokenExpr);
|
||||
if (importedSymbol !== null && importedSymbol.from === '@angular/core') {
|
||||
switch (importedSymbol.name) {
|
||||
case 'ChangeDetectorRef':
|
||||
resolved = R3ResolvedDependencyType.ChangeDetectorRef;
|
||||
break;
|
||||
case 'ElementRef':
|
||||
resolved = R3ResolvedDependencyType.ElementRef;
|
||||
break;
|
||||
case 'Injector':
|
||||
resolved = R3ResolvedDependencyType.Injector;
|
||||
break;
|
||||
case 'TemplateRef':
|
||||
resolved = R3ResolvedDependencyType.TemplateRef;
|
||||
break;
|
||||
case 'ViewContainerRef':
|
||||
resolved = R3ResolvedDependencyType.ViewContainerRef;
|
||||
break;
|
||||
case 'Renderer2':
|
||||
resolved = R3ResolvedDependencyType.Renderer2;
|
||||
break;
|
||||
|
|
|
@ -648,6 +648,49 @@ describe('compiler compliance', () => {
|
|||
expectEmit(source, HostBindingCompDeclaration, 'Invalid host binding code');
|
||||
});
|
||||
|
||||
it('should not treat ElementRef, ViewContainerRef, or ChangeDetectorRef specially when injecting',
|
||||
() => {
|
||||
const files = {
|
||||
app: {
|
||||
'spec.ts': `
|
||||
import {Component, NgModule, ElementRef, ChangeDetectorRef, ViewContainerRef} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'my-component',
|
||||
template: ''
|
||||
})
|
||||
export class MyComponent {
|
||||
constructor(public el: ElementRef, public vcr: ViewContainerRef, public cdr: ChangeDetectorRef) {}
|
||||
}
|
||||
|
||||
@NgModule({declarations: [MyComponent]})
|
||||
export class MyModule {}
|
||||
`
|
||||
}
|
||||
};
|
||||
|
||||
const MyComponentDefinition = `
|
||||
…
|
||||
MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
|
||||
type: MyComponent,
|
||||
selectors: [["my-component"]],
|
||||
factory: function MyComponent_Factory(t) {
|
||||
return new (t || MyComponent)(
|
||||
$r3$.ɵdirectiveInject(ElementRef), $r3$.ɵdirectiveInject(ViewContainerRef),
|
||||
$r3$.ɵdirectiveInject(ChangeDetectorRef));
|
||||
},
|
||||
features: [$r3$.ɵPublicFeature],
|
||||
consts: 0,
|
||||
vars: 0,
|
||||
template: function MyComponent_Template(rf, ctx) {}
|
||||
});`;
|
||||
|
||||
const result = compile(files, angularFiles);
|
||||
const source = result.source;
|
||||
|
||||
expectEmit(source, MyComponentDefinition, 'Incorrect MyComponent.ngComponentDef');
|
||||
});
|
||||
|
||||
it('should support structural directives', () => {
|
||||
const files = {
|
||||
app: {
|
||||
|
@ -677,7 +720,7 @@ describe('compiler compliance', () => {
|
|||
IfDirective.ngDirectiveDef = $r3$.ɵdefineDirective({
|
||||
type: IfDirective,
|
||||
selectors: [["", "if", ""]],
|
||||
factory: function IfDirective_Factory(t) { return new (t || IfDirective)($r3$.ɵinjectTemplateRef()); },
|
||||
factory: function IfDirective_Factory(t) { return new (t || IfDirective)($r3$.ɵdirectiveInject(TemplateRef)); },
|
||||
features: [$r3$.ɵPublicFeature]
|
||||
});`;
|
||||
const MyComponentDefinition = `
|
||||
|
@ -1703,7 +1746,7 @@ describe('compiler compliance', () => {
|
|||
type: ForOfDirective,
|
||||
selectors: [["", "forOf", ""]],
|
||||
factory: function ForOfDirective_Factory(t) {
|
||||
return new (t || ForOfDirective)($r3$.ɵinjectViewContainerRef(), $r3$.ɵinjectTemplateRef());
|
||||
return new (t || ForOfDirective)($r3$.ɵdirectiveInject(ViewContainerRef), $r3$.ɵdirectiveInject(TemplateRef));
|
||||
},
|
||||
features: [$r3$.ɵPublicFeature, $r3$.ɵNgOnChangesFeature],
|
||||
inputs: {forOf: "forOf"}
|
||||
|
@ -1779,7 +1822,7 @@ describe('compiler compliance', () => {
|
|||
type: ForOfDirective,
|
||||
selectors: [["", "forOf", ""]],
|
||||
factory: function ForOfDirective_Factory(t) {
|
||||
return new (t || ForOfDirective)($r3$.ɵinjectViewContainerRef(), $r3$.ɵinjectTemplateRef());
|
||||
return new (t || ForOfDirective)($r3$.ɵdirectiveInject(ViewContainerRef), $r3$.ɵdirectiveInject(TemplateRef));
|
||||
},
|
||||
features: [$r3$.ɵPublicFeature, $r3$.ɵNgOnChangesFeature],
|
||||
inputs: {forOf: "forOf"}
|
||||
|
|
|
@ -480,7 +480,7 @@ describe('ngtsc behavioral tests', () => {
|
|||
const jsContents = getContents('test.js');
|
||||
expect(jsContents)
|
||||
.toContain(
|
||||
`factory: function FooCmp_Factory(t) { return new (t || FooCmp)(i0.ɵinjectAttribute("test"), i0.ɵinjectChangeDetectorRef(), i0.ɵinjectElementRef(), i0.ɵdirectiveInject(i0.INJECTOR), i0.ɵinjectRenderer2(), i0.ɵinjectTemplateRef(), i0.ɵinjectViewContainerRef()); }`);
|
||||
`factory: function FooCmp_Factory(t) { return new (t || FooCmp)(i0.ɵinjectAttribute("test"), i0.ɵdirectiveInject(ChangeDetectorRef), i0.ɵdirectiveInject(ElementRef), i0.ɵdirectiveInject(i0.INJECTOR), i0.ɵinjectRenderer2(), i0.ɵdirectiveInject(TemplateRef), i0.ɵdirectiveInject(ViewContainerRef)); }`);
|
||||
});
|
||||
|
||||
it('should generate queries for components', () => {
|
||||
|
|
|
@ -101,30 +101,10 @@ export enum R3ResolvedDependencyType {
|
|||
*/
|
||||
Injector = 2,
|
||||
|
||||
/**
|
||||
* The dependency is for `ElementRef`.
|
||||
*/
|
||||
ElementRef = 3,
|
||||
|
||||
/**
|
||||
* The dependency is for `TemplateRef`.
|
||||
*/
|
||||
TemplateRef = 4,
|
||||
|
||||
/**
|
||||
* The dependency is for `ViewContainerRef`.
|
||||
*/
|
||||
ViewContainerRef = 5,
|
||||
|
||||
/**
|
||||
* The dependency is for `ChangeDetectorRef`.
|
||||
*/
|
||||
ChangeDetectorRef = 6,
|
||||
|
||||
/**
|
||||
* The dependency is for `Renderer2`.
|
||||
*/
|
||||
Renderer2 = 7,
|
||||
Renderer2 = 3,
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -282,14 +262,6 @@ function compileInjectDependency(
|
|||
case R3ResolvedDependencyType.Attribute:
|
||||
// In the case of attributes, the attribute name in question is given as the token.
|
||||
return o.importExpr(R3.injectAttribute).callFn([dep.token]);
|
||||
case R3ResolvedDependencyType.ElementRef:
|
||||
return o.importExpr(R3.injectElementRef).callFn([]);
|
||||
case R3ResolvedDependencyType.TemplateRef:
|
||||
return o.importExpr(R3.injectTemplateRef).callFn([]);
|
||||
case R3ResolvedDependencyType.ViewContainerRef:
|
||||
return o.importExpr(R3.injectViewContainerRef).callFn([]);
|
||||
case R3ResolvedDependencyType.ChangeDetectorRef:
|
||||
return o.importExpr(R3.injectChangeDetectorRef).callFn([]);
|
||||
case R3ResolvedDependencyType.Renderer2:
|
||||
return o.importExpr(R3.injectRenderer2).callFn([]);
|
||||
default:
|
||||
|
@ -320,13 +292,7 @@ export function dependenciesFromGlobalMetadata(
|
|||
if (dependency.token) {
|
||||
const tokenRef = tokenReference(dependency.token);
|
||||
let resolved: R3ResolvedDependencyType = R3ResolvedDependencyType.Token;
|
||||
if (tokenRef === elementRef) {
|
||||
resolved = R3ResolvedDependencyType.ElementRef;
|
||||
} else if (tokenRef === templateRef) {
|
||||
resolved = R3ResolvedDependencyType.TemplateRef;
|
||||
} else if (tokenRef === viewContainerRef) {
|
||||
resolved = R3ResolvedDependencyType.ViewContainerRef;
|
||||
} else if (tokenRef === injectorRef) {
|
||||
if (tokenRef === injectorRef) {
|
||||
resolved = R3ResolvedDependencyType.Injector;
|
||||
} else if (tokenRef === renderer2) {
|
||||
resolved = R3ResolvedDependencyType.Renderer2;
|
||||
|
@ -363,4 +329,4 @@ function isDelegatedMetadata(meta: R3FactoryMetadata): meta is R3DelegatedFactor
|
|||
|
||||
function isExpressionFactoryMetadata(meta: R3FactoryMetadata): meta is R3ExpressionFactoryMetadata {
|
||||
return (meta as any).expression !== undefined;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,16 +106,6 @@ export class Identifiers {
|
|||
|
||||
static injectAttribute: o.ExternalReference = {name: 'ɵinjectAttribute', moduleName: CORE};
|
||||
|
||||
static injectElementRef: o.ExternalReference = {name: 'ɵinjectElementRef', moduleName: CORE};
|
||||
|
||||
static injectTemplateRef: o.ExternalReference = {name: 'ɵinjectTemplateRef', moduleName: CORE};
|
||||
|
||||
static injectViewContainerRef:
|
||||
o.ExternalReference = {name: 'ɵinjectViewContainerRef', moduleName: CORE};
|
||||
|
||||
static injectChangeDetectorRef:
|
||||
o.ExternalReference = {name: 'ɵinjectChangeDetectorRef', moduleName: CORE};
|
||||
|
||||
static injectRenderer2: o.ExternalReference = {name: 'ɵinjectRenderer2', moduleName: CORE};
|
||||
|
||||
static directiveInject: o.ExternalReference = {name: 'ɵdirectiveInject', moduleName: CORE};
|
||||
|
|
|
@ -43,7 +43,7 @@ function baseDirectiveFields(
|
|||
definitionMap.set('selectors', createDirectiveSelector(meta.selector !));
|
||||
|
||||
|
||||
// e.g. `factory: () => new MyApp(injectElementRef())`
|
||||
// e.g. `factory: () => new MyApp(directiveInject(ElementRef))`
|
||||
const result = compileFactoryFunction({
|
||||
name: meta.name,
|
||||
type: meta.type,
|
||||
|
|
|
@ -9,9 +9,13 @@ ng_module(
|
|||
"*.ts",
|
||||
"src/**/*.ts",
|
||||
],
|
||||
exclude = ["src/ivy_switch.ts"],
|
||||
exclude = [
|
||||
"src/ivy_switch/compiler/index.ts",
|
||||
"src/ivy_switch/runtime/index.ts",
|
||||
],
|
||||
) + [
|
||||
":ivy_switch",
|
||||
":ivy_switch_compiler",
|
||||
":ivy_switch_runtime",
|
||||
],
|
||||
module_name = "@angular/core",
|
||||
deps = [
|
||||
|
@ -42,19 +46,27 @@ ng_package(
|
|||
|
||||
## Controls if Ivy is enabled. (Temporary target until we permanently switch over to Ivy)
|
||||
##
|
||||
## This file generates `src/ivy_switch.ts` file which reexports symbols for `ViewEngine` or `Ivy.`
|
||||
## - append `--define=compile=legacy` (default) to `bazel` command to reexport `./ivy_switch_legacy`
|
||||
## and use `ViewEngine`
|
||||
## - append `--define=compile=jit` to `bazel` command to rexport `./ivy_switch_jit` and use `Ivy`
|
||||
## - append `--define=compile=local` to `bazel` command to rexport `./ivy_switch_jit` and use `Ivy`
|
||||
## This file generates the `src/ivy_switch/compiler/index.ts` and `src/ivy_switch/runtime/index.ts` files which
|
||||
## reexport symbols for `ViewEngine` or `Ivy.`
|
||||
## - append `--define=compile=legacy` (default) to `bazel` command to reexport `./legacy` from each folder
|
||||
## in the 'ivy_switch' directory and use `ViewEngine`
|
||||
## - append `--define=compile=jit` to `bazel` command to rexport `./jit` from each folder in the `ivy_switch`
|
||||
## directory and use `Ivy`
|
||||
## - append `--define=compile=local` to `bazel` command to rexport `./ivy_switch/compiler/jit` and use `Ivy`
|
||||
## in the local analysis mode. (run as part of `ngtsc`)
|
||||
##
|
||||
## NOTE: `--define=compile=jit` works with any `bazel` command or target across the repo.
|
||||
##
|
||||
## See: `//tools/bazel.rc` where `--define=ivy=false` is defined as default.
|
||||
## See: `./src/ivy_switch.ts` for more details.
|
||||
## See: `./src/ivy_switch/compiler/index.ts` for more details.
|
||||
genrule(
|
||||
name = "ivy_switch",
|
||||
outs = ["src/ivy_switch.ts"],
|
||||
cmd = "echo export '*' from \"'./ivy_switch_$(compile)';\" > $@",
|
||||
name = "ivy_switch_compiler",
|
||||
outs = ["src/ivy_switch/compiler/index.ts"],
|
||||
cmd = "echo export '*' from \"'./$(compile)';\" > $@",
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "ivy_switch_runtime",
|
||||
outs = ["src/ivy_switch/runtime/index.ts"],
|
||||
cmd = "echo export '*' from \"'./$(compile)';\" > $@",
|
||||
)
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {R3_CHANGE_DETECTOR_REF_FACTORY} from '../ivy_switch/runtime/index';
|
||||
|
||||
/**
|
||||
* Base class for Angular Views, provides change detection functionality.
|
||||
* A change-detection tree collects all views that are to be checked for changes.
|
||||
|
@ -103,4 +105,7 @@ export abstract class ChangeDetectorRef {
|
|||
*
|
||||
*/
|
||||
abstract reattach(): void;
|
||||
|
||||
/** @internal */
|
||||
static __NG_ELEMENT_ID__: () => ChangeDetectorRef = () => R3_CHANGE_DETECTOR_REF_FACTORY();
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ export {Console as ɵConsole} from './console';
|
|||
export {InjectableDef as ɵInjectableDef, InjectorDef as ɵInjectorDef, getInjectableDef as ɵgetInjectableDef} from './di/defs';
|
||||
export {inject as ɵinject, setCurrentInjector as ɵsetCurrentInjector} from './di/injector';
|
||||
export {APP_ROOT as ɵAPP_ROOT} from './di/scope';
|
||||
export {ivyEnabled as ɵivyEnabled} from './ivy_switch';
|
||||
export {ivyEnabled as ɵivyEnabled} from './ivy_switch/compiler/index';
|
||||
export {ComponentFactory as ɵComponentFactory} from './linker/component_factory';
|
||||
export {CodegenComponentFactoryResolver as ɵCodegenComponentFactoryResolver} from './linker/component_factory_resolver';
|
||||
export {resolveComponentResources as ɵresolveComponentResources} from './metadata/resource_loading';
|
||||
|
|
|
@ -21,10 +21,6 @@ export {
|
|||
DirectiveType as ɵDirectiveType,
|
||||
RenderFlags as ɵRenderFlags,
|
||||
directiveInject as ɵdirectiveInject,
|
||||
injectElementRef as ɵinjectElementRef,
|
||||
injectTemplateRef as ɵinjectTemplateRef,
|
||||
injectViewContainerRef as ɵinjectViewContainerRef,
|
||||
injectChangeDetectorRef as ɵinjectChangeDetectorRef,
|
||||
injectRenderer2 as ɵinjectRenderer2,
|
||||
injectAttribute as ɵinjectAttribute,
|
||||
getFactoryOf as ɵgetFactoryOf,
|
||||
|
@ -187,6 +183,15 @@ export {
|
|||
R3_COMPILE_INJECTABLE__POST_NGCC__ as ɵR3_COMPILE_INJECTABLE__POST_NGCC__,
|
||||
R3_COMPILE_NGMODULE__POST_NGCC__ as ɵR3_COMPILE_NGMODULE__POST_NGCC__,
|
||||
R3_COMPILE_PIPE__POST_NGCC__ as ɵR3_COMPILE_PIPE__POST_NGCC__,
|
||||
ivyEnable__POST_NGCC__ as ɵivyEnable__POST_NGCC__
|
||||
} from './ivy_switch_legacy';
|
||||
ivyEnable__POST_NGCC__ as ɵivyEnable__POST_NGCC__,
|
||||
} from './ivy_switch/compiler/legacy';
|
||||
|
||||
export {
|
||||
R3_ELEMENT_REF_FACTORY__POST_NGCC__ as ɵR3_ELEMENT_REF_FACTORY__POST_NGCC__,
|
||||
R3_TEMPLATE_REF_FACTORY__POST_NGCC__ as ɵR3_TEMPLATE_REF_FACTORY__POST_NGCC__,
|
||||
R3_CHANGE_DETECTOR_REF_FACTORY__POST_NGCC__ as ɵR3_CHANGE_DETECTOR_REF_FACTORY__POST_NGCC__,
|
||||
R3_VIEW_CONTAINER_REF_FACTORY__POST_NGCC__ as ɵR3_VIEW_CONTAINER_REF_FACTORY__POST_NGCC__,
|
||||
} from './ivy_switch/runtime/legacy';
|
||||
|
||||
|
||||
// clang-format on
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {R3_COMPILE_INJECTABLE} from '../ivy_switch';
|
||||
import {R3_COMPILE_INJECTABLE} from '../ivy_switch/compiler/index';
|
||||
import {Type} from '../type';
|
||||
import {makeDecorator} from '../util/decorators';
|
||||
|
||||
|
|
|
@ -12,6 +12,6 @@
|
|||
* For more information on how to run and debug tests with either Ivy or View Engine (legacy),
|
||||
* please see [BAZEL.md](./docs/BAZEL.md).
|
||||
*/
|
||||
export * from './ivy_switch_legacy';
|
||||
export * from './legacy';
|
||||
|
||||
// TODO(alxhub): debug why metadata doesn't properly propagate through this file.
|
|
@ -6,10 +6,10 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {compileComponent, compileDirective} from './render3/jit/directive';
|
||||
import {compileInjectable} from './render3/jit/injectable';
|
||||
import {compileNgModule} from './render3/jit/module';
|
||||
import {compilePipe} from './render3/jit/pipe';
|
||||
import {compileComponent, compileDirective} from '../../render3/jit/directive';
|
||||
import {compileInjectable} from '../../render3/jit/injectable';
|
||||
import {compileNgModule} from '../../render3/jit/module';
|
||||
import {compilePipe} from '../../render3/jit/pipe';
|
||||
|
||||
export const ivyEnabled = true;
|
||||
export const R3_COMPILE_COMPONENT = compileComponent;
|
|
@ -6,15 +6,16 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {InjectableType, InjectorType, defineInjectable, defineInjector, getInjectableDef} from './di/defs';
|
||||
import {InjectableProvider} from './di/injectable';
|
||||
import {inject, injectArgs} from './di/injector';
|
||||
import {ClassSansProvider, ConstructorSansProvider, ExistingSansProvider, FactorySansProvider, StaticClassSansProvider, ValueProvider, ValueSansProvider} from './di/provider';
|
||||
import {InjectableType, InjectorType, defineInjectable, defineInjector, getInjectableDef} from '../../di/defs';
|
||||
import {InjectableProvider} from '../../di/injectable';
|
||||
import {inject, injectArgs} from '../../di/injector';
|
||||
import {ClassSansProvider, ConstructorSansProvider, ExistingSansProvider, FactorySansProvider, StaticClassSansProvider, ValueProvider, ValueSansProvider} from '../../di/provider';
|
||||
import {NgModule} from '../../metadata';
|
||||
import {ReflectionCapabilities} from '../../reflection/reflection_capabilities';
|
||||
import {Type} from '../../type';
|
||||
import {getClosureSafeProperty} from '../../util/property';
|
||||
|
||||
import * as ivyOn from './ivy_switch_on';
|
||||
import {NgModule} from './metadata';
|
||||
import {ReflectionCapabilities} from './reflection/reflection_capabilities';
|
||||
import {Type} from './type';
|
||||
import {getClosureSafeProperty} from './util/property';
|
||||
|
||||
function noop() {}
|
||||
|
||||
|
@ -25,6 +26,7 @@ export const R3_COMPILE_DIRECTIVE__POST_NGCC__: DirectiveCompiler = ivyOn.R3_COM
|
|||
export const R3_COMPILE_INJECTABLE__POST_NGCC__: DirectiveCompiler = ivyOn.R3_COMPILE_INJECTABLE;
|
||||
export const R3_COMPILE_NGMODULE__POST_NGCC__: DirectiveCompiler = ivyOn.R3_COMPILE_NGMODULE;
|
||||
export const R3_COMPILE_PIPE__POST_NGCC__: DirectiveCompiler = ivyOn.R3_COMPILE_PIPE;
|
||||
|
||||
export const ivyEnable__POST_NGCC__: boolean = ivyOn.ivyEnabled;
|
||||
|
||||
const R3_COMPILE_COMPONENT__PRE_NGCC__: DirectiveCompiler = noop;
|
||||
|
@ -32,6 +34,7 @@ const R3_COMPILE_DIRECTIVE__PRE_NGCC__: DirectiveCompiler = noop;
|
|||
const R3_COMPILE_INJECTABLE__PRE_NGCC__: DirectiveCompiler = preR3InjectableCompile;
|
||||
const R3_COMPILE_NGMODULE__PRE_NGCC__: DirectiveCompiler = preR3NgModuleCompile;
|
||||
const R3_COMPILE_PIPE__PRE_NGCC__: DirectiveCompiler = noop;
|
||||
|
||||
const ivyEnable__PRE_NGCC__ = false;
|
||||
|
||||
export const ivyEnabled = ivyEnable__PRE_NGCC__;
|
||||
|
@ -111,4 +114,4 @@ function preR3InjectableCompile(
|
|||
factory: convertInjectableProviderToFactory(injectableType, options),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file is used to control if the default rendering pipeline should be `ViewEngine` or `Ivy`.
|
||||
*
|
||||
* For more information on how to run and debug tests with either Ivy or View Engine (legacy),
|
||||
* please see [BAZEL.md](./docs/BAZEL.md).
|
||||
*/
|
||||
export * from './legacy';
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {injectChangeDetectorRef, injectElementRef, injectTemplateRef, injectViewContainerRef} from '../../render3/view_engine_compatibility';
|
||||
|
||||
export const R3_ELEMENT_REF_FACTORY = injectElementRef;
|
||||
export const R3_TEMPLATE_REF_FACTORY = injectTemplateRef;
|
||||
export const R3_CHANGE_DETECTOR_REF_FACTORY = injectChangeDetectorRef;
|
||||
export const R3_VIEW_CONTAINER_REF_FACTORY = injectViewContainerRef;
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
export * from './ivy_switch_on';
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import * as ivyOn from './ivy_switch_on';
|
||||
|
||||
function noopFactory(...tokens: any[]): any {}
|
||||
|
||||
type FactoryFunction<T = any> = (...tokens: any[]) => T;
|
||||
|
||||
export const R3_ELEMENT_REF_FACTORY__POST_NGCC__: FactoryFunction = ivyOn.R3_ELEMENT_REF_FACTORY;
|
||||
export const R3_TEMPLATE_REF_FACTORY__POST_NGCC__: FactoryFunction = ivyOn.R3_TEMPLATE_REF_FACTORY;
|
||||
export const R3_CHANGE_DETECTOR_REF_FACTORY__POST_NGCC__: FactoryFunction =
|
||||
ivyOn.R3_CHANGE_DETECTOR_REF_FACTORY;
|
||||
export const R3_VIEW_CONTAINER_REF_FACTORY__POST_NGCC__: FactoryFunction =
|
||||
ivyOn.R3_VIEW_CONTAINER_REF_FACTORY;
|
||||
|
||||
|
||||
export const R3_ELEMENT_REF_FACTORY__PRE_NGCC__ = noopFactory;
|
||||
export const R3_TEMPLATE_REF_FACTORY__PRE_NGCC__ = noopFactory;
|
||||
export const R3_CHANGE_DETECTOR_REF_FACTORY__PRE_NGCC__ = noopFactory;
|
||||
export const R3_VIEW_CONTAINER_REF_FACTORY__PRE_NGCC__ = noopFactory;
|
||||
|
||||
export let R3_ELEMENT_REF_FACTORY = R3_ELEMENT_REF_FACTORY__PRE_NGCC__;
|
||||
export let R3_TEMPLATE_REF_FACTORY = R3_TEMPLATE_REF_FACTORY__PRE_NGCC__;
|
||||
export let R3_CHANGE_DETECTOR_REF_FACTORY = R3_CHANGE_DETECTOR_REF_FACTORY__PRE_NGCC__;
|
||||
export let R3_VIEW_CONTAINER_REF_FACTORY = R3_VIEW_CONTAINER_REF_FACTORY__PRE_NGCC__;
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
export * from './ivy_switch_on';
|
|
@ -6,6 +6,8 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {R3_ELEMENT_REF_FACTORY} from '../ivy_switch/runtime/index';
|
||||
|
||||
/**
|
||||
* A wrapper around a native element inside of a View.
|
||||
*
|
||||
|
@ -46,4 +48,7 @@ export class ElementRef<T = any> {
|
|||
public nativeElement: T;
|
||||
|
||||
constructor(nativeElement: T) { this.nativeElement = nativeElement; }
|
||||
|
||||
/** @internal */
|
||||
static __NG_ELEMENT_ID__: () => ElementRef = () => R3_ELEMENT_REF_FACTORY(ElementRef);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {R3_TEMPLATE_REF_FACTORY} from '../ivy_switch/runtime/index';
|
||||
|
||||
import {ElementRef} from './element_ref';
|
||||
import {EmbeddedViewRef} from './view_ref';
|
||||
|
||||
|
@ -14,12 +16,12 @@ import {EmbeddedViewRef} from './view_ref';
|
|||
* Represents an embedded template that can be used to instantiate embedded views.
|
||||
* To instantiate embedded views based on a template, use the `ViewContainerRef`
|
||||
* method `createEmbeddedView()`.
|
||||
*
|
||||
*
|
||||
* Access a `TemplateRef` instance by placing a directive on an `<ng-template>`
|
||||
* element (or directive prefixed with `*`). The `TemplateRef` for the embedded view
|
||||
* is injected into the constructor of the directive,
|
||||
* using the `TemplateRef` token.
|
||||
*
|
||||
*
|
||||
* You can also use a `Query` to find a `TemplateRef` associated with
|
||||
* a component or a directive.
|
||||
*
|
||||
|
@ -48,4 +50,8 @@ export abstract class TemplateRef<C> {
|
|||
* @returns The new view object.
|
||||
*/
|
||||
abstract createEmbeddedView(context: C): EmbeddedViewRef<C>;
|
||||
|
||||
/** @internal */
|
||||
static __NG_ELEMENT_ID__:
|
||||
() => TemplateRef<any> = () => R3_TEMPLATE_REF_FACTORY(TemplateRef, ElementRef)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
*/
|
||||
|
||||
import {Injector} from '../di/injector';
|
||||
import {R3_VIEW_CONTAINER_REF_FACTORY} from '../ivy_switch/runtime/index';
|
||||
|
||||
import {ComponentFactory, ComponentRef} from './component_factory';
|
||||
import {ElementRef} from './element_ref';
|
||||
import {NgModuleRef} from './ng_module_factory';
|
||||
|
@ -139,4 +141,8 @@ export abstract class ViewContainerRef {
|
|||
* If not specified, the last view in the container is detached.
|
||||
*/
|
||||
abstract detach(index?: number): ViewRef|null;
|
||||
|
||||
/** @internal */
|
||||
static __NG_ELEMENT_ID__:
|
||||
() => ViewContainerRef = () => R3_VIEW_CONTAINER_REF_FACTORY(ViewContainerRef, ElementRef)
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import {ChangeDetectionStrategy} from '../change_detection/constants';
|
||||
import {Provider} from '../di';
|
||||
import {R3_COMPILE_COMPONENT, R3_COMPILE_DIRECTIVE, R3_COMPILE_PIPE} from '../ivy_switch';
|
||||
import {R3_COMPILE_COMPONENT, R3_COMPILE_DIRECTIVE, R3_COMPILE_PIPE} from '../ivy_switch/compiler/index';
|
||||
import {NG_BASE_DEF} from '../render3/fields';
|
||||
import {Type} from '../type';
|
||||
import {TypeDecorator, makeDecorator, makePropDecorator} from '../util/decorators';
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import {ApplicationRef} from '../application_ref';
|
||||
import {Provider} from '../di/provider';
|
||||
import {R3_COMPILE_NGMODULE} from '../ivy_switch';
|
||||
import {R3_COMPILE_NGMODULE} from '../ivy_switch/compiler/index';
|
||||
import {Type} from '../type';
|
||||
import {TypeDecorator, makeDecorator} from '../util/decorators';
|
||||
|
||||
|
|
|
@ -382,17 +382,19 @@ NOTE:
|
|||
An interesting thing about these objects is that they are not memoized `injector.get(ElementRef) !== injector.get(ElementRef)`.
|
||||
This could be considered a bug, it means that we don't have to allocate storage space for them.
|
||||
|
||||
We should treat these special objects like any other token. `directiveInject()` already reads a special `NG_ELEMENT_ID`
|
||||
property set on directives to locate their bit in the bloom filter. We can set this same property on special objects,
|
||||
but point to a factory function rather than an element ID number. When we check that property in `directiveInject()`
|
||||
and see that it's a function, we know to invoke the factory function directly instead of searching the node tree.
|
||||
|
||||
```typescript
|
||||
@Injectable({
|
||||
provideIn: '__node__' as any // Special token not available to the developer
|
||||
useFactory: injectElementRef // existing function which generates ElementRef
|
||||
})
|
||||
class ElementRef {
|
||||
...
|
||||
static __NG_ELEMENT_ID__ = () => injectElementRef();
|
||||
}
|
||||
```
|
||||
|
||||
Consequence of the above is that `injector.get(ElementRef)` returns an instance of `ElementRef` without `Injector` having to know about `ElementRef` at compile time.
|
||||
Consequence of the above is that `directiveInject(ElementRef)` returns an instance of `ElementRef` without `Injector` having to know about `ElementRef` at compile time.
|
||||
|
||||
# `EXPANDO` and Injecting the `Injector`.
|
||||
|
||||
|
@ -421,10 +423,7 @@ function inject(token: any): any {
|
|||
let injectableDef;
|
||||
if (typeof token === 'function' && injectableDef = token.ngInjectableDef) {
|
||||
const provideIn = injectableDef.provideIn;
|
||||
if (provideIn === '__node__') {
|
||||
// if it is a special object just call its factory
|
||||
return injectableDef.useFactory();
|
||||
} else if (provideIn === '__node_injector__') {
|
||||
if (provideIn === '__node_injector__') {
|
||||
// if we are injecting `Injector` than create a wrapper object around the inject but which
|
||||
// is bound to the current node.
|
||||
return createInjector();
|
||||
|
|
|
@ -24,6 +24,7 @@ import {ComponentDefInternal, RenderFlags} from './interfaces/definition';
|
|||
import {LElementNode, TElementNode, TNode, TNodeType, TViewNode} from './interfaces/node';
|
||||
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
|
||||
import {FLAGS, INJECTOR, LViewData, LViewFlags, RootContext, TVIEW} from './interfaces/view';
|
||||
import {createElementRef} from './view_engine_compatibility';
|
||||
import {RootViewRef, ViewRef} from './view_ref';
|
||||
|
||||
export class ComponentFactoryResolver extends viewEngine_ComponentFactoryResolver {
|
||||
|
@ -176,8 +177,10 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
|
|||
if (rendererFactory.end) rendererFactory.end();
|
||||
}
|
||||
|
||||
const componentRef =
|
||||
new ComponentRef(this.componentType, component, rootView, injector, hostNode !);
|
||||
const componentRef = new ComponentRef(
|
||||
this.componentType, component, rootView, injector,
|
||||
createElementRef(viewEngine_ElementRef, tElementNode, rootView));
|
||||
|
||||
if (isInternalRootView) {
|
||||
// The host element of the internal root view is attached to the component's host view node
|
||||
componentRef.hostView._tViewNode !.child = tElementNode;
|
||||
|
@ -186,6 +189,19 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
|
|||
}
|
||||
}
|
||||
|
||||
const componentFactoryResolver: ComponentFactoryResolver = new ComponentFactoryResolver();
|
||||
|
||||
/**
|
||||
* Creates a ComponentFactoryResolver and stores it on the injector. Or, if the
|
||||
* ComponentFactoryResolver
|
||||
* already exists, retrieves the existing ComponentFactoryResolver.
|
||||
*
|
||||
* @returns The ComponentFactoryResolver instance to use
|
||||
*/
|
||||
export function injectComponentFactoryResolver(): viewEngine_ComponentFactoryResolver {
|
||||
return componentFactoryResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an instance of a Component created via a {@link ComponentFactory}.
|
||||
*
|
||||
|
@ -196,7 +212,6 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
|
|||
*/
|
||||
export class ComponentRef<T> extends viewEngine_ComponentRef<T> {
|
||||
destroyCbs: (() => void)[]|null = [];
|
||||
location: viewEngine_ElementRef<any>;
|
||||
injector: Injector;
|
||||
instance: T;
|
||||
hostView: ViewRef<T>;
|
||||
|
@ -205,13 +220,12 @@ export class ComponentRef<T> extends viewEngine_ComponentRef<T> {
|
|||
|
||||
constructor(
|
||||
componentType: Type<T>, instance: T, rootView: LViewData, injector: Injector,
|
||||
hostNode: RElement) {
|
||||
public location: viewEngine_ElementRef) {
|
||||
super();
|
||||
this.instance = instance;
|
||||
this.hostView = this.changeDetectorRef = new RootViewRef<T>(rootView);
|
||||
this.hostView._tViewNode = createNodeAtIndex(-1, TNodeType.View, null, null, null, rootView);
|
||||
this.injector = injector;
|
||||
this.location = new viewEngine_ElementRef(hostNode);
|
||||
this.componentType = componentType;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,44 +9,23 @@
|
|||
// We are temporarily importing the existing viewEngine_from core so we can be sure we are
|
||||
// correctly implementing its interfaces for backwards compatibility.
|
||||
|
||||
import {ChangeDetectorRef as viewEngine_ChangeDetectorRef} from '../change_detection/change_detector_ref';
|
||||
import {getInjectableDef, getInjectorDef} from '../di/defs';
|
||||
import {InjectionToken} from '../di/injection_token';
|
||||
import {InjectFlags, Injector, NullInjector, inject, setCurrentInjector} from '../di/injector';
|
||||
import {ComponentFactory as viewEngine_ComponentFactory, ComponentRef as viewEngine_ComponentRef} from '../linker/component_factory';
|
||||
import {ComponentFactoryResolver as viewEngine_ComponentFactoryResolver} from '../linker/component_factory_resolver';
|
||||
import {ElementRef as viewEngine_ElementRef} from '../linker/element_ref';
|
||||
import {NgModuleRef as viewEngine_NgModuleRef} from '../linker/ng_module_factory';
|
||||
import {TemplateRef as viewEngine_TemplateRef} from '../linker/template_ref';
|
||||
import {ViewContainerRef as viewEngine_ViewContainerRef} from '../linker/view_container_ref';
|
||||
import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, ViewRef as viewEngine_ViewRef} from '../linker/view_ref';
|
||||
import {Renderer2} from '../render';
|
||||
import {Type} from '../type';
|
||||
|
||||
import {assertDefined, assertGreaterThan, assertLessThan} from './assert';
|
||||
import {ComponentFactoryResolver} from './component_ref';
|
||||
import {getComponentDef, getDirectiveDef, getPipeDef} from './definition';
|
||||
import {_getViewData, addToViewTree, assertPreviousIsParent, createEmbeddedViewAndNode, createLContainer, createLNodeObject, createTNode, getPreviousOrParentNode, getPreviousOrParentTNode, getRenderer, loadElement, renderEmbeddedTemplate, resolveDirective} from './instructions';
|
||||
import {LContainer, RENDER_PARENT, VIEWS} from './interfaces/container';
|
||||
import {NG_ELEMENT_ID} from './fields';
|
||||
import {_getViewData, addToViewTree, assertPreviousIsParent, createEmbeddedViewAndNode, createLContainer, createLNodeObject, createTNode, getPreviousOrParentNode, getPreviousOrParentTNode, getRenderer, loadElement, renderEmbeddedTemplate, resolveDirective, setEnvironment} from './instructions';
|
||||
import {DirectiveDefInternal, RenderFlags} from './interfaces/definition';
|
||||
import {LInjector} from './interfaces/injector';
|
||||
import {AttributeMarker, LContainerNode, LElementContainerNode, LElementNode, LNode, TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeType, TViewNode} from './interfaces/node';
|
||||
import {LQueries, QueryReadType} from './interfaces/query';
|
||||
import {Renderer3, isProceduralRenderer} from './interfaces/renderer';
|
||||
import {CONTEXT, DIRECTIVES, HOST_NODE, INJECTOR, LViewData, QUERIES, RENDERER, TVIEW, TView} from './interfaces/view';
|
||||
import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert';
|
||||
import {addRemoveViewFromContainer, appendChild, detachView, findComponentView, getBeforeNodeForView, getHostElementNode, getParentLNode, getParentOrContainerNode, getRenderParent, insertView, removeView} from './node_manipulation';
|
||||
import {getLNode, isComponent} from './util';
|
||||
import {ViewRef} from './view_ref';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* If a directive is diPublic, bloomAdd sets a property on the type with this constant as
|
||||
* the key and the directive's unique ID as the value. This allows us to map directives to their
|
||||
* bloom filter bit for DI.
|
||||
*/
|
||||
const NG_ELEMENT_ID = '__NG_ELEMENT_ID__';
|
||||
|
||||
/**
|
||||
* The number of slots in each bloom filter (used by DI). The larger this number, the fewer
|
||||
|
@ -196,56 +175,6 @@ export function directiveInject<T>(
|
|||
return getOrCreateInjectable<T>(getOrCreateNodeInjector(), token, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ElementRef and stores it on the injector.
|
||||
* Or, if the ElementRef already exists, retrieves the existing ElementRef.
|
||||
*
|
||||
* @returns The ElementRef instance to use
|
||||
*/
|
||||
export function injectElementRef(): viewEngine_ElementRef {
|
||||
return createElementRef(getPreviousOrParentTNode(), _getViewData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a TemplateRef and stores it on the injector. Or, if the TemplateRef already
|
||||
* exists, retrieves the existing TemplateRef.
|
||||
*
|
||||
* @returns The TemplateRef instance to use
|
||||
*/
|
||||
export function injectTemplateRef<T>(): viewEngine_TemplateRef<T> {
|
||||
return createTemplateRef<T>(getPreviousOrParentTNode(), _getViewData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ViewContainerRef and stores it on the injector. Or, if the ViewContainerRef
|
||||
* already exists, retrieves the existing ViewContainerRef.
|
||||
*
|
||||
* @returns The ViewContainerRef instance to use
|
||||
*/
|
||||
export function injectViewContainerRef(): viewEngine_ViewContainerRef {
|
||||
const previousTNode =
|
||||
getPreviousOrParentTNode() as TElementNode | TElementContainerNode | TContainerNode;
|
||||
return createContainerRef(previousTNode, _getViewData());
|
||||
}
|
||||
|
||||
/** Returns a ChangeDetectorRef (a.k.a. a ViewRef) */
|
||||
export function injectChangeDetectorRef(): viewEngine_ChangeDetectorRef {
|
||||
return createViewRef(getPreviousOrParentTNode(), _getViewData(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ComponentFactoryResolver and stores it on the injector. Or, if the
|
||||
* ComponentFactoryResolver
|
||||
* already exists, retrieves the existing ComponentFactoryResolver.
|
||||
*
|
||||
* @returns The ComponentFactoryResolver instance to use
|
||||
*/
|
||||
export function injectComponentFactoryResolver(): viewEngine_ComponentFactoryResolver {
|
||||
return componentFactoryResolver;
|
||||
}
|
||||
const componentFactoryResolver: ComponentFactoryResolver = new ComponentFactoryResolver();
|
||||
|
||||
|
||||
export function injectRenderer2(): Renderer2 {
|
||||
return getOrCreateRenderer2(getOrCreateNodeInjector());
|
||||
}
|
||||
|
@ -298,27 +227,6 @@ export function injectAttribute(attrNameToInject: string): string|undefined {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ViewRef and stores it on the injector as ChangeDetectorRef (public alias).
|
||||
*
|
||||
* @param hostTNode The node that is requesting a ChangeDetectorRef
|
||||
* @param hostView The view to which the node belongs
|
||||
* @param context The context for this change detector ref
|
||||
* @returns The ChangeDetectorRef to use
|
||||
*/
|
||||
export function createViewRef(
|
||||
hostTNode: TNode, hostView: LViewData, context: any): viewEngine_ChangeDetectorRef {
|
||||
if (isComponent(hostTNode)) {
|
||||
const componentIndex = hostTNode.flags >> TNodeFlags.DirectiveStartingIndexShift;
|
||||
const componentView = getLNode(hostTNode, hostView).data as LViewData;
|
||||
return new ViewRef(componentView, context, componentIndex);
|
||||
} else if (hostTNode.type === TNodeType.Element) {
|
||||
const hostComponentView = findComponentView(hostView);
|
||||
return new ViewRef(hostComponentView, hostComponentView[CONTEXT], -1);
|
||||
}
|
||||
return null !;
|
||||
}
|
||||
|
||||
function getOrCreateRenderer2(di: LInjector): Renderer2 {
|
||||
const renderer = di.view[RENDERER];
|
||||
if (isProceduralRenderer(renderer)) {
|
||||
|
@ -342,11 +250,14 @@ function getOrCreateRenderer2(di: LInjector): Renderer2 {
|
|||
export function getOrCreateInjectable<T>(
|
||||
nodeInjector: LInjector, token: Type<T>| InjectionToken<T>,
|
||||
flags: InjectFlags = InjectFlags.Default): T|null {
|
||||
const bloomHash = bloomHashBit(token);
|
||||
const bloomHash = bloomHashBitOrFactory(token);
|
||||
// If the ID stored here is a function, this is a special object like ElementRef or TemplateRef
|
||||
// so just call the factory function to create it.
|
||||
if (typeof bloomHash === 'function') return bloomHash();
|
||||
|
||||
// If the token has a bloom hash, then it is a directive that is public to the injection system
|
||||
// (diPublic) otherwise fall back to the module injector.
|
||||
if (bloomHash !== null) {
|
||||
if (bloomHash != null) {
|
||||
let injector: LInjector|null = nodeInjector;
|
||||
|
||||
while (injector) {
|
||||
|
@ -433,9 +344,9 @@ function searchMatchesQueuedForCreation<T>(token: any, hostTView: TView): T|null
|
|||
* @param token the injection token
|
||||
* @returns the matching bit to check in the bloom filter or `null` if the token is not known.
|
||||
*/
|
||||
function bloomHashBit(token: Type<any>| InjectionToken<any>): number|null {
|
||||
let id: number|undefined = (token as any)[NG_ELEMENT_ID];
|
||||
return typeof id === 'number' ? id & BLOOM_MASK : null;
|
||||
function bloomHashBitOrFactory(token: Type<any>| InjectionToken<any>): number|Function|undefined {
|
||||
const tokenId: number|undefined = (token as any)[NG_ELEMENT_ID] || null;
|
||||
return typeof tokenId === 'number' ? tokenId & BLOOM_MASK : tokenId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -525,258 +436,18 @@ function sameHostView(injector: LInjector): boolean {
|
|||
return !!injector.parent && injector.parent.view === injector.view;
|
||||
}
|
||||
|
||||
export class ReadFromInjectorFn<T> {
|
||||
constructor(readonly read: (tNode: TNode, view: LViewData, directiveIndex?: number) => T) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ElementRef for a given node injector and stores it on the injector.
|
||||
*
|
||||
* @param di The node injector where we should store a created ElementRef
|
||||
* @returns The ElementRef instance to use
|
||||
*/
|
||||
export function createElementRef(tNode: TNode, view: LViewData): viewEngine_ElementRef {
|
||||
return new ElementRef(getLNode(tNode, view).native);
|
||||
}
|
||||
|
||||
export const QUERY_READ_TEMPLATE_REF = <QueryReadType<viewEngine_TemplateRef<any>>>(
|
||||
new ReadFromInjectorFn<viewEngine_TemplateRef<any>>(
|
||||
(tNode: TNode, view: LViewData) => { return createTemplateRef(tNode, view);}) as any);
|
||||
|
||||
export const QUERY_READ_CONTAINER_REF = <QueryReadType<viewEngine_ViewContainerRef>>(
|
||||
new ReadFromInjectorFn<viewEngine_ViewContainerRef>(
|
||||
(tNode: TNode, view: LViewData) => createContainerRef(
|
||||
tNode as TElementNode | TContainerNode | TElementContainerNode, view)) as any);
|
||||
|
||||
export const QUERY_READ_ELEMENT_REF =
|
||||
<QueryReadType<viewEngine_ElementRef>>(new ReadFromInjectorFn<viewEngine_ElementRef>(
|
||||
(tNode: TNode, view: LViewData) => createElementRef(tNode, view)) as any);
|
||||
|
||||
export const QUERY_READ_FROM_NODE =
|
||||
(new ReadFromInjectorFn<any>((tNode: TNode, view: LViewData, directiveIdx: number) => {
|
||||
ngDevMode && assertNodeOfPossibleTypes(
|
||||
tNode, TNodeType.Container, TNodeType.Element, TNodeType.ElementContainer);
|
||||
if (directiveIdx > -1) {
|
||||
return view[DIRECTIVES] ![directiveIdx];
|
||||
}
|
||||
if (tNode.type === TNodeType.Element || tNode.type === TNodeType.ElementContainer) {
|
||||
return createElementRef(tNode, view);
|
||||
}
|
||||
if (tNode.type === TNodeType.Container) {
|
||||
return createTemplateRef(tNode, view);
|
||||
}
|
||||
if (ngDevMode) {
|
||||
// should never happen
|
||||
throw new Error(`Unexpected node type: ${tNode.type}`);
|
||||
}
|
||||
}) as any as QueryReadType<any>);
|
||||
|
||||
/** A ref to a node's native element. */
|
||||
class ElementRef extends viewEngine_ElementRef {}
|
||||
|
||||
/**
|
||||
* Creates a ViewContainerRef and stores it on the injector.
|
||||
*
|
||||
* @param hostTNode The node that is requesting a ViewContainerRef
|
||||
* @param hostView The view to which the node belongs
|
||||
* @returns The ViewContainerRef instance to use
|
||||
*/
|
||||
export function createContainerRef(
|
||||
hostTNode: TElementNode | TContainerNode | TElementContainerNode,
|
||||
hostView: LViewData): viewEngine_ViewContainerRef {
|
||||
const hostLNode = getLNode(hostTNode, hostView);
|
||||
ngDevMode && assertNodeOfPossibleTypes(
|
||||
hostTNode, TNodeType.Container, TNodeType.Element, TNodeType.ElementContainer);
|
||||
|
||||
const lContainer = createLContainer(hostView, true);
|
||||
const comment = hostView[RENDERER].createComment(ngDevMode ? 'container' : '');
|
||||
const lContainerNode: LContainerNode =
|
||||
createLNodeObject(TNodeType.Container, hostLNode.nodeInjector, comment, lContainer);
|
||||
|
||||
lContainer[RENDER_PARENT] = getRenderParent(hostTNode, hostView);
|
||||
|
||||
appendChild(comment, hostTNode, hostView);
|
||||
|
||||
if (!hostTNode.dynamicContainerNode) {
|
||||
hostTNode.dynamicContainerNode =
|
||||
createTNode(TNodeType.Container, -1, null, null, hostTNode, null);
|
||||
}
|
||||
|
||||
hostLNode.dynamicLContainerNode = lContainerNode;
|
||||
addToViewTree(hostView, hostTNode.index as number, lContainer);
|
||||
|
||||
return new ViewContainerRef(
|
||||
lContainer, hostTNode.dynamicContainerNode as TContainerNode, hostTNode, hostView);
|
||||
}
|
||||
|
||||
export class NodeInjector implements Injector {
|
||||
constructor(private _lInjector: LInjector) {}
|
||||
|
||||
get(token: any): any {
|
||||
if (token === viewEngine_TemplateRef) {
|
||||
return createTemplateRef(this._lInjector.tNode, this._lInjector.view);
|
||||
}
|
||||
if (token === viewEngine_ViewContainerRef) {
|
||||
return createContainerRef(this._lInjector.tNode, this._lInjector.view);
|
||||
}
|
||||
if (token === viewEngine_ElementRef) {
|
||||
return createElementRef(this._lInjector.tNode, this._lInjector.view);
|
||||
}
|
||||
if (token === viewEngine_ChangeDetectorRef) {
|
||||
return createViewRef(this._lInjector.tNode, this._lInjector.view, null);
|
||||
}
|
||||
if (token === Renderer2) {
|
||||
return getOrCreateRenderer2(this._lInjector);
|
||||
}
|
||||
|
||||
setEnvironment(this._lInjector.tNode, this._lInjector.view);
|
||||
return getOrCreateInjectable(this._lInjector, token);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A ref to a container that enables adding and removing views from that container
|
||||
* imperatively.
|
||||
*/
|
||||
class ViewContainerRef extends viewEngine_ViewContainerRef {
|
||||
private _viewRefs: viewEngine_ViewRef[] = [];
|
||||
|
||||
constructor(
|
||||
private _lContainer: LContainer, private _tContainerNode: TContainerNode,
|
||||
private _hostTNode: TElementNode|TContainerNode|TElementContainerNode,
|
||||
private _hostView: LViewData) {
|
||||
super();
|
||||
}
|
||||
|
||||
get element(): ElementRef {
|
||||
// TODO: Remove LNode lookup when removing LNode.nodeInjector
|
||||
const injector =
|
||||
getOrCreateNodeInjectorForNode(this._getHostNode(), this._hostTNode, this._hostView);
|
||||
return createElementRef(injector.tNode, injector.view);
|
||||
}
|
||||
|
||||
get injector(): Injector {
|
||||
// TODO: Remove LNode lookup when removing LNode.nodeInjector
|
||||
const injector =
|
||||
getOrCreateNodeInjectorForNode(this._getHostNode(), this._hostTNode, this._hostView);
|
||||
return new NodeInjector(injector);
|
||||
}
|
||||
|
||||
/** @deprecated No replacement */
|
||||
get parentInjector(): Injector {
|
||||
const parentLInjector = getParentLNode(this._hostTNode, this._hostView) !.nodeInjector;
|
||||
return parentLInjector ? new NodeInjector(parentLInjector) : new NullInjector();
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
while (this._lContainer[VIEWS].length) {
|
||||
this.remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
get(index: number): viewEngine_ViewRef|null { return this._viewRefs[index] || null; }
|
||||
|
||||
get length(): number { return this._lContainer[VIEWS].length; }
|
||||
|
||||
createEmbeddedView<C>(templateRef: viewEngine_TemplateRef<C>, context?: C, index?: number):
|
||||
viewEngine_EmbeddedViewRef<C> {
|
||||
const adjustedIdx = this._adjustIndex(index);
|
||||
const viewRef = (templateRef as TemplateRef<C>)
|
||||
.createEmbeddedView(
|
||||
context || <any>{}, this._lContainer, this._tContainerNode,
|
||||
this._hostView, adjustedIdx);
|
||||
(viewRef as ViewRef<any>).attachToViewContainerRef(this);
|
||||
this._viewRefs.splice(adjustedIdx, 0, viewRef);
|
||||
return viewRef;
|
||||
}
|
||||
|
||||
createComponent<C>(
|
||||
componentFactory: viewEngine_ComponentFactory<C>, index?: number|undefined,
|
||||
injector?: Injector|undefined, projectableNodes?: any[][]|undefined,
|
||||
ngModuleRef?: viewEngine_NgModuleRef<any>|undefined): viewEngine_ComponentRef<C> {
|
||||
const contextInjector = injector || this.parentInjector;
|
||||
if (!ngModuleRef && contextInjector) {
|
||||
ngModuleRef = contextInjector.get(viewEngine_NgModuleRef, null);
|
||||
}
|
||||
|
||||
const componentRef =
|
||||
componentFactory.create(contextInjector, projectableNodes, undefined, ngModuleRef);
|
||||
this.insert(componentRef.hostView, index);
|
||||
return componentRef;
|
||||
}
|
||||
|
||||
insert(viewRef: viewEngine_ViewRef, index?: number): viewEngine_ViewRef {
|
||||
if (viewRef.destroyed) {
|
||||
throw new Error('Cannot insert a destroyed View in a ViewContainer!');
|
||||
}
|
||||
const lView = (viewRef as ViewRef<any>)._view !;
|
||||
const adjustedIdx = this._adjustIndex(index);
|
||||
|
||||
insertView(
|
||||
lView, this._lContainer, this._hostView, adjustedIdx, this._tContainerNode.parent !.index);
|
||||
|
||||
const container = this._getHostNode().dynamicLContainerNode !;
|
||||
const beforeNode = getBeforeNodeForView(adjustedIdx, this._lContainer[VIEWS], container);
|
||||
addRemoveViewFromContainer(lView, true, beforeNode);
|
||||
|
||||
(viewRef as ViewRef<any>).attachToViewContainerRef(this);
|
||||
this._viewRefs.splice(adjustedIdx, 0, viewRef);
|
||||
|
||||
return viewRef;
|
||||
}
|
||||
|
||||
move(viewRef: viewEngine_ViewRef, newIndex: number): viewEngine_ViewRef {
|
||||
const index = this.indexOf(viewRef);
|
||||
this.detach(index);
|
||||
this.insert(viewRef, this._adjustIndex(newIndex));
|
||||
return viewRef;
|
||||
}
|
||||
|
||||
indexOf(viewRef: viewEngine_ViewRef): number { return this._viewRefs.indexOf(viewRef); }
|
||||
|
||||
remove(index?: number): void {
|
||||
const adjustedIdx = this._adjustIndex(index, -1);
|
||||
removeView(this._lContainer, this._tContainerNode as TContainerNode, adjustedIdx);
|
||||
this._viewRefs.splice(adjustedIdx, 1);
|
||||
}
|
||||
|
||||
detach(index?: number): viewEngine_ViewRef|null {
|
||||
const adjustedIdx = this._adjustIndex(index, -1);
|
||||
detachView(this._lContainer, adjustedIdx, !!this._tContainerNode.detached);
|
||||
return this._viewRefs.splice(adjustedIdx, 1)[0] || null;
|
||||
}
|
||||
|
||||
private _adjustIndex(index?: number, shift: number = 0) {
|
||||
if (index == null) {
|
||||
return this._lContainer[VIEWS].length + shift;
|
||||
}
|
||||
if (ngDevMode) {
|
||||
assertGreaterThan(index, -1, 'index must be positive');
|
||||
// +1 because it's legal to insert at the end.
|
||||
assertLessThan(index, this._lContainer[VIEWS].length + 1 + shift, 'index');
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
private _getHostNode() { return getLNode(this._hostTNode, this._hostView); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a TemplateRef and stores it on the injector.
|
||||
*
|
||||
* @param hostTNode The node that is requesting a TemplateRef
|
||||
* @param hostView The view to which the node belongs
|
||||
* @returns The TemplateRef instance to use
|
||||
*/
|
||||
export function createTemplateRef<T>(
|
||||
hostTNode: TNode, hostView: LViewData): viewEngine_TemplateRef<T> {
|
||||
const hostNode = getLNode(hostTNode, hostView);
|
||||
ngDevMode && assertNodeType(hostTNode, TNodeType.Container);
|
||||
ngDevMode && assertDefined(hostTNode.tViews, 'TView must be allocated');
|
||||
return new TemplateRef<any>(
|
||||
hostView, createElementRef(hostTNode, hostView), hostTNode.tViews as TView, getRenderer(),
|
||||
hostNode.data ![QUERIES]);
|
||||
}
|
||||
|
||||
export function getFactoryOf<T>(type: Type<any>): ((type?: Type<T>) => T)|null {
|
||||
const typeAny = type as any;
|
||||
const def = getComponentDef<T>(typeAny) || getDirectiveDef<T>(typeAny) ||
|
||||
|
@ -800,33 +471,3 @@ export function getInheritedFactory<T>(type: Type<any>): (type: Type<T>) => T {
|
|||
return (t) => new t();
|
||||
}
|
||||
}
|
||||
|
||||
class TemplateRef<T> extends viewEngine_TemplateRef<T> {
|
||||
constructor(
|
||||
private _declarationParentView: LViewData, readonly elementRef: viewEngine_ElementRef,
|
||||
private _tView: TView, private _renderer: Renderer3, private _queries: LQueries|null) {
|
||||
super();
|
||||
}
|
||||
|
||||
createEmbeddedView(
|
||||
context: T, container?: LContainer, tContainerNode?: TContainerNode, hostView?: LViewData,
|
||||
index?: number): viewEngine_EmbeddedViewRef<T> {
|
||||
const lView = createEmbeddedViewAndNode(
|
||||
this._tView, context, this._declarationParentView, this._renderer, this._queries);
|
||||
if (container) {
|
||||
insertView(lView, container, hostView !, index !, tContainerNode !.parent !.index);
|
||||
}
|
||||
renderEmbeddedTemplate(lView, this._tView, context, RenderFlags.Create);
|
||||
const viewRef = new ViewRef(lView, context, -1);
|
||||
viewRef._tViewNode = lView[HOST_NODE] as TViewNode;
|
||||
return viewRef;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves `TemplateRef` instance from `Injector` when a local reference is placed on the
|
||||
* `<ng-template>` element.
|
||||
*/
|
||||
export function templateRefExtractor(tNode: TContainerNode, currentView: LViewData) {
|
||||
return createTemplateRef(tNode, currentView);
|
||||
}
|
||||
|
|
|
@ -15,3 +15,10 @@ export const NG_INJECTOR_DEF = getClosureSafeProperty({ngInjectorDef: getClosure
|
|||
export const NG_PIPE_DEF = getClosureSafeProperty({ngPipeDef: getClosureSafeProperty});
|
||||
export const NG_MODULE_DEF = getClosureSafeProperty({ngModuleDef: getClosureSafeProperty});
|
||||
export const NG_BASE_DEF = getClosureSafeProperty({ngBaseDef: getClosureSafeProperty});
|
||||
|
||||
/**
|
||||
* If a directive is diPublic, bloomAdd sets a property on the type with this constant as
|
||||
* the key and the directive's unique ID as the value. This allows us to map directives to their
|
||||
* bloom filter bit for DI.
|
||||
*/
|
||||
export const NG_ELEMENT_ID = getClosureSafeProperty({__NG_ELEMENT_ID__: getClosureSafeProperty});
|
||||
|
|
|
@ -13,8 +13,8 @@ import {NgOnChangesFeature} from './features/ng_onchanges_feature';
|
|||
import {PublicFeature} from './features/public_feature';
|
||||
import {BaseDef, ComponentDef, ComponentDefInternal, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, DirectiveDefInternal, DirectiveType, PipeDef} from './interfaces/definition';
|
||||
|
||||
export {ComponentFactory, ComponentFactoryResolver, ComponentRef, WRAP_RENDERER_FACTORY2} from './component_ref';
|
||||
export {QUERY_READ_CONTAINER_REF, QUERY_READ_ELEMENT_REF, QUERY_READ_FROM_NODE, QUERY_READ_TEMPLATE_REF, directiveInject, getFactoryOf, getInheritedFactory, injectAttribute, injectChangeDetectorRef, injectComponentFactoryResolver, injectElementRef, injectRenderer2, injectTemplateRef, injectViewContainerRef, templateRefExtractor} from './di';
|
||||
export {ComponentFactory, ComponentFactoryResolver, ComponentRef, WRAP_RENDERER_FACTORY2, injectComponentFactoryResolver} from './component_ref';
|
||||
export {directiveInject, getFactoryOf, getInheritedFactory, injectAttribute, injectRenderer2} from './di';
|
||||
export {RenderFlags} from './interfaces/definition';
|
||||
export {CssSelectorList} from './interfaces/projection';
|
||||
|
||||
|
@ -119,6 +119,7 @@ export {
|
|||
QueryList,
|
||||
query,
|
||||
queryRefresh,
|
||||
QUERY_READ_CONTAINER_REF, QUERY_READ_ELEMENT_REF, QUERY_READ_FROM_NODE, QUERY_READ_TEMPLATE_REF
|
||||
} from './query';
|
||||
export {
|
||||
registerContentQuery,
|
||||
|
@ -138,6 +139,8 @@ export {
|
|||
pureFunctionV,
|
||||
} from './pure_function';
|
||||
|
||||
export {templateRefExtractor} from './view_engine_compatibility';
|
||||
|
||||
|
||||
// clang-format on
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector
|
|||
import {StylingContext, allocStylingContext, createStylingContextTemplate, renderStyling as renderElementStyles, updateClassProp as updateElementClassProp, updateStyleProp as updateElementStyleProp, updateStylingMap} from './styling';
|
||||
import {assertDataInRangeInternal, getLNode, isContentQueryHost, isDifferent, loadElementInternal, loadInternal, stringify} from './util';
|
||||
|
||||
|
||||
/**
|
||||
* A permanent marker promise which signifies that the current CD tree is
|
||||
* clean.
|
||||
|
@ -138,6 +137,10 @@ export function getPreviousOrParentTNode(): TNode {
|
|||
return previousOrParentTNode;
|
||||
}
|
||||
|
||||
export function setEnvironment(tNode: TNode, view: LViewData) {
|
||||
previousOrParentTNode = tNode;
|
||||
viewData = view;
|
||||
}
|
||||
|
||||
/**
|
||||
* If `isParent` is:
|
||||
|
|
|
@ -30,10 +30,6 @@ export const angularCoreEnv: {[name: string]: Function} = {
|
|||
'ɵgetInheritedFactory': r3.getInheritedFactory,
|
||||
'inject': inject,
|
||||
'ɵinjectAttribute': r3.injectAttribute,
|
||||
'ɵinjectChangeDetectorRef': r3.injectChangeDetectorRef,
|
||||
'ɵinjectElementRef': r3.injectElementRef,
|
||||
'ɵinjectTemplateRef': r3.injectTemplateRef,
|
||||
'ɵinjectViewContainerRef': r3.injectViewContainerRef,
|
||||
'ɵtemplateRefExtractor': r3.templateRefExtractor,
|
||||
'ɵinjectRenderer2': r3.injectRenderer2,
|
||||
'ɵNgOnChangesFeature': r3.NgOnChangesFeature,
|
||||
|
|
|
@ -42,14 +42,8 @@ function reflectDependency(dep: any | any[]): R3DependencyMetadata {
|
|||
};
|
||||
|
||||
function setTokenAndResolvedType(token: any): void {
|
||||
if (token === ElementRef) {
|
||||
meta.resolved = R3ResolvedDependencyType.ElementRef;
|
||||
} else if (token === Injector) {
|
||||
if (token === Injector) {
|
||||
meta.resolved = R3ResolvedDependencyType.Injector;
|
||||
} else if (token === TemplateRef) {
|
||||
meta.resolved = R3ResolvedDependencyType.TemplateRef;
|
||||
} else if (token === ViewContainerRef) {
|
||||
meta.resolved = R3ResolvedDependencyType.ViewContainerRef;
|
||||
} else {
|
||||
meta.resolved = R3ResolvedDependencyType.Token;
|
||||
}
|
||||
|
|
|
@ -11,19 +11,23 @@
|
|||
import {Observable} from 'rxjs';
|
||||
|
||||
import {EventEmitter} from '../event_emitter';
|
||||
import {ElementRef as ViewEngine_ElementRef} from '../linker/element_ref';
|
||||
import {QueryList as viewEngine_QueryList} from '../linker/query_list';
|
||||
import {TemplateRef as ViewEngine_TemplateRef} from '../linker/template_ref';
|
||||
import {ViewContainerRef as ViewEngine_ViewContainerRef} from '../linker/view_container_ref';
|
||||
import {Type} from '../type';
|
||||
import {getSymbolIterator} from '../util';
|
||||
|
||||
import {assertDefined, assertEqual} from './assert';
|
||||
import {ReadFromInjectorFn, getOrCreateNodeInjectorForNode} from './di';
|
||||
import {_getViewData, assertPreviousIsParent, getOrCreateCurrentQueries, store, storeCleanupWithContext} from './instructions';
|
||||
import {DirectiveDefInternal, unusedValueExportToPlacateAjd as unused1} from './interfaces/definition';
|
||||
import {LInjector, unusedValueExportToPlacateAjd as unused2} from './interfaces/injector';
|
||||
import {LContainerNode, LElementNode, TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, unusedValueExportToPlacateAjd as unused3} from './interfaces/node';
|
||||
import {LContainerNode, LElementNode, TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeType, unusedValueExportToPlacateAjd as unused3} from './interfaces/node';
|
||||
import {LQueries, QueryReadType, unusedValueExportToPlacateAjd as unused4} from './interfaces/query';
|
||||
import {DIRECTIVES, LViewData, TVIEW} from './interfaces/view';
|
||||
import {assertNodeOfPossibleTypes} from './node_assert';
|
||||
import {flatten, getLNode, isContentQueryHost} from './util';
|
||||
import {createContainerRef, createElementRef, createTemplateRef} from './view_engine_compatibility';
|
||||
|
||||
const unusedValueToPlacateAjd = unused1 + unused2 + unused3 + unused4;
|
||||
|
||||
|
@ -467,3 +471,63 @@ export function queryRefresh(queryList: QueryList<any>): boolean {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export class ReadFromInjectorFn<T> {
|
||||
constructor(readonly read: (tNode: TNode, view: LViewData, directiveIndex?: number) => T) {}
|
||||
}
|
||||
|
||||
// TODO: Remove wrapper function with TemplateRef when we turn on Ivy
|
||||
// Necessary for now to avoid a circular dependency
|
||||
export const QUERY_READ_TEMPLATE_REF =
|
||||
(TemplateRefConstructor: typeof ViewEngine_TemplateRef,
|
||||
ElementRefConstructor: typeof ViewEngine_ElementRef) => {
|
||||
return new ReadFromInjectorFn<ViewEngine_TemplateRef<any>>(
|
||||
(tNode: TNode, view: LViewData) => {
|
||||
return createTemplateRef(TemplateRefConstructor, ElementRefConstructor, tNode, view);
|
||||
}) as any;
|
||||
};
|
||||
|
||||
// TODO: Remove wrapper function with ViewContainerRef when we turn on Ivy
|
||||
// Necessary for now to avoid a circular dependency
|
||||
export const QUERY_READ_CONTAINER_REF =
|
||||
(ViewContainerRefConstructor: typeof ViewEngine_ViewContainerRef,
|
||||
ElementRefConstructor: typeof ViewEngine_ElementRef) => {
|
||||
return <QueryReadType<ViewEngine_ViewContainerRef>>(
|
||||
new ReadFromInjectorFn<ViewEngine_ViewContainerRef>(
|
||||
(tNode: TNode, view: LViewData) => createContainerRef(
|
||||
ViewContainerRefConstructor, ElementRefConstructor,
|
||||
tNode as TElementNode | TContainerNode | TElementContainerNode, view)) as any);
|
||||
|
||||
};
|
||||
|
||||
// TODO: Remove wrapper function with ElementRef when we turn on Ivy
|
||||
// Necessary for now to avoid a circular dependency
|
||||
export const QUERY_READ_ELEMENT_REF = (ElementRefConstructor: typeof ViewEngine_ElementRef) => {
|
||||
return <QueryReadType<ViewEngine_ElementRef>>(
|
||||
new ReadFromInjectorFn<ViewEngine_ElementRef>((tNode: TNode, view: LViewData) => {
|
||||
return createElementRef(ElementRefConstructor, tNode, view);
|
||||
}) as any);
|
||||
};
|
||||
|
||||
// TODO: Remove wrapper function with TemplateRef when we turn on Ivy
|
||||
export const QUERY_READ_FROM_NODE =
|
||||
(TemplateRefConstructor: typeof ViewEngine_TemplateRef,
|
||||
ElementRefConstructor: typeof ViewEngine_ElementRef) => {
|
||||
return new ReadFromInjectorFn<any>((tNode: TNode, view: LViewData, directiveIdx: number) => {
|
||||
ngDevMode && assertNodeOfPossibleTypes(
|
||||
tNode, TNodeType.Container, TNodeType.Element, TNodeType.ElementContainer);
|
||||
if (directiveIdx > -1) {
|
||||
return view[DIRECTIVES] ![directiveIdx];
|
||||
}
|
||||
if (tNode.type === TNodeType.Element || tNode.type === TNodeType.ElementContainer) {
|
||||
return createElementRef(ElementRefConstructor, tNode, view);
|
||||
}
|
||||
if (tNode.type === TNodeType.Container) {
|
||||
return createTemplateRef(TemplateRefConstructor, ElementRefConstructor, tNode, view);
|
||||
}
|
||||
if (ngDevMode) {
|
||||
// should never happen
|
||||
throw new Error(`Unexpected node type: ${tNode.type}`);
|
||||
}
|
||||
}) as any as QueryReadType<any>;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,351 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ChangeDetectorRef as ViewEngine_ChangeDetectorRef} from '../change_detection/change_detector_ref';
|
||||
import {Injector, NullInjector} from '../di/injector';
|
||||
import {ComponentFactory as viewEngine_ComponentFactory, ComponentRef as viewEngine_ComponentRef} from '../linker/component_factory';
|
||||
import {ElementRef as ViewEngine_ElementRef} from '../linker/element_ref';
|
||||
import {NgModuleRef as viewEngine_NgModuleRef} from '../linker/ng_module_factory';
|
||||
import {TemplateRef as ViewEngine_TemplateRef} from '../linker/template_ref';
|
||||
import {ViewContainerRef as ViewEngine_ViewContainerRef} from '../linker/view_container_ref';
|
||||
import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, ViewRef as viewEngine_ViewRef} from '../linker/view_ref';
|
||||
|
||||
import {assertDefined, assertGreaterThan, assertLessThan} from './assert';
|
||||
import {NodeInjector, getOrCreateNodeInjectorForNode} from './di';
|
||||
import {_getViewData, addToViewTree, createEmbeddedViewAndNode, createLContainer, createLNodeObject, createTNode, getPreviousOrParentTNode, getRenderer, renderEmbeddedTemplate} from './instructions';
|
||||
import {LContainer, RENDER_PARENT, VIEWS} from './interfaces/container';
|
||||
import {RenderFlags} from './interfaces/definition';
|
||||
import {LContainerNode, TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeType, TViewNode} from './interfaces/node';
|
||||
import {LQueries} from './interfaces/query';
|
||||
import {RComment, RElement, Renderer3} from './interfaces/renderer';
|
||||
import {CONTEXT, HOST_NODE, LViewData, QUERIES, RENDERER, TView} from './interfaces/view';
|
||||
import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert';
|
||||
import {addRemoveViewFromContainer, appendChild, detachView, findComponentView, getBeforeNodeForView, getParentLNode, getRenderParent, insertView, removeView} from './node_manipulation';
|
||||
import {getLNode, isComponent} from './util';
|
||||
import {ViewRef} from './view_ref';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates an ElementRef from the most recent node.
|
||||
*
|
||||
* @returns The ElementRef instance to use
|
||||
*/
|
||||
export function injectElementRef(ElementRefToken: typeof ViewEngine_ElementRef):
|
||||
ViewEngine_ElementRef {
|
||||
return createElementRef(ElementRefToken, getPreviousOrParentTNode(), _getViewData());
|
||||
}
|
||||
|
||||
let R3ElementRef: {new (native: RElement | RComment): ViewEngine_ElementRef};
|
||||
|
||||
/**
|
||||
* Creates an ElementRef given a node.
|
||||
*
|
||||
* @param ElementRefToken The ElementRef type
|
||||
* @param tNode The node for which you'd like an ElementRef
|
||||
* @param view The view to which the node belongs
|
||||
* @returns The ElementRef instance to use
|
||||
*/
|
||||
export function createElementRef(
|
||||
ElementRefToken: typeof ViewEngine_ElementRef, tNode: TNode,
|
||||
view: LViewData): ViewEngine_ElementRef {
|
||||
if (!R3ElementRef) {
|
||||
// TODO: Fix class name, should be ElementRef, but there appears to be a rollup bug
|
||||
R3ElementRef = class ElementRef_ extends ElementRefToken {};
|
||||
}
|
||||
return new R3ElementRef(getLNode(tNode, view).native);
|
||||
}
|
||||
|
||||
let R3TemplateRef: {
|
||||
new (
|
||||
_declarationParentView: LViewData, elementRef: ViewEngine_ElementRef, _tView: TView,
|
||||
_renderer: Renderer3, _queries: LQueries | null): ViewEngine_TemplateRef<any>
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a TemplateRef given a node.
|
||||
*
|
||||
* @returns The TemplateRef instance to use
|
||||
*/
|
||||
export function injectTemplateRef<T>(
|
||||
TemplateRefToken: typeof ViewEngine_TemplateRef,
|
||||
ElementRefToken: typeof ViewEngine_ElementRef): ViewEngine_TemplateRef<T> {
|
||||
return createTemplateRef<T>(
|
||||
TemplateRefToken, ElementRefToken, getPreviousOrParentTNode(), _getViewData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a TemplateRef and stores it on the injector.
|
||||
*
|
||||
* @param TemplateRefToken The TemplateRef type
|
||||
* @param ElementRefToken The ElementRef type
|
||||
* @param hostTNode The node that is requesting a TemplateRef
|
||||
* @param hostView The view to which the node belongs
|
||||
* @returns The TemplateRef instance to use
|
||||
*/
|
||||
export function createTemplateRef<T>(
|
||||
TemplateRefToken: typeof ViewEngine_TemplateRef, ElementRefToken: typeof ViewEngine_ElementRef,
|
||||
hostTNode: TNode, hostView: LViewData): ViewEngine_TemplateRef<T> {
|
||||
if (!R3TemplateRef) {
|
||||
// TODO: Fix class name, should be TemplateRef, but there appears to be a rollup bug
|
||||
R3TemplateRef = class TemplateRef_<T> extends TemplateRefToken<T> {
|
||||
constructor(
|
||||
private _declarationParentView: LViewData, readonly elementRef: ViewEngine_ElementRef,
|
||||
private _tView: TView, private _renderer: Renderer3, private _queries: LQueries|null) {
|
||||
super();
|
||||
}
|
||||
|
||||
createEmbeddedView(
|
||||
context: T, container?: LContainer, tContainerNode?: TContainerNode, hostView?: LViewData,
|
||||
index?: number): viewEngine_EmbeddedViewRef<T> {
|
||||
const lView = createEmbeddedViewAndNode(
|
||||
this._tView, context, this._declarationParentView, this._renderer, this._queries);
|
||||
if (container) {
|
||||
insertView(lView, container, hostView !, index !, tContainerNode !.parent !.index);
|
||||
}
|
||||
renderEmbeddedTemplate(lView, this._tView, context, RenderFlags.Create);
|
||||
const viewRef = new ViewRef(lView, context, -1);
|
||||
viewRef._tViewNode = lView[HOST_NODE] as TViewNode;
|
||||
return viewRef;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
const hostNode = getLNode(hostTNode, hostView);
|
||||
ngDevMode && assertNodeType(hostTNode, TNodeType.Container);
|
||||
ngDevMode && assertDefined(hostTNode.tViews, 'TView must be allocated');
|
||||
return new R3TemplateRef(
|
||||
hostView, createElementRef(ElementRefToken, hostTNode, hostView), hostTNode.tViews as TView,
|
||||
getRenderer(), hostNode.data ![QUERIES]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves `TemplateRef` instance from `Injector` when a local reference is placed on the
|
||||
* `<ng-template>` element.
|
||||
*/
|
||||
export function templateRefExtractor(
|
||||
TemplateRefToken: typeof ViewEngine_TemplateRef,
|
||||
ElementRefToken: typeof ViewEngine_ElementRef) {
|
||||
return (tNode: TNode, currentView: LViewData) => {
|
||||
return createTemplateRef(TemplateRefToken, ElementRefToken, tNode, currentView);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
let R3ViewContainerRef: {
|
||||
new (
|
||||
lContainer: LContainer, tContainerNode: TContainerNode,
|
||||
hostTNode: TElementNode | TContainerNode | TElementContainerNode, hostView: LViewData):
|
||||
ViewEngine_ViewContainerRef
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a ViewContainerRef and stores it on the injector. Or, if the ViewContainerRef
|
||||
* already exists, retrieves the existing ViewContainerRef.
|
||||
*
|
||||
* @returns The ViewContainerRef instance to use
|
||||
*/
|
||||
export function injectViewContainerRef(
|
||||
ViewContainerRefToken: typeof ViewEngine_ViewContainerRef,
|
||||
ElementRefToken: typeof ViewEngine_ElementRef): ViewEngine_ViewContainerRef {
|
||||
const previousTNode =
|
||||
getPreviousOrParentTNode() as TElementNode | TElementContainerNode | TContainerNode;
|
||||
return createContainerRef(ViewContainerRefToken, ElementRefToken, previousTNode, _getViewData());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a ViewContainerRef and stores it on the injector.
|
||||
*
|
||||
* @param ViewContainerRefToken The ViewContainerRef type
|
||||
* @param ElementRefToken The ElementRef type
|
||||
* @param hostTNode The node that is requesting a ViewContainerRef
|
||||
* @param hostView The view to which the node belongs
|
||||
* @returns The ViewContainerRef instance to use
|
||||
*/
|
||||
export function createContainerRef(
|
||||
ViewContainerRefToken: typeof ViewEngine_ViewContainerRef,
|
||||
ElementRefToken: typeof ViewEngine_ElementRef,
|
||||
hostTNode: TElementNode|TContainerNode|TElementContainerNode,
|
||||
hostView: LViewData): ViewEngine_ViewContainerRef {
|
||||
if (!R3ViewContainerRef) {
|
||||
// TODO: Fix class name, should be ViewContainerRef, but there appears to be a rollup bug
|
||||
R3ViewContainerRef = class ViewContainerRef_ extends ViewContainerRefToken {
|
||||
private _viewRefs: viewEngine_ViewRef[] = [];
|
||||
|
||||
constructor(
|
||||
private _lContainer: LContainer, private _tContainerNode: TContainerNode,
|
||||
private _hostTNode: TElementNode|TContainerNode|TElementContainerNode,
|
||||
private _hostView: LViewData) {
|
||||
super();
|
||||
}
|
||||
|
||||
get element(): ViewEngine_ElementRef {
|
||||
return createElementRef(ElementRefToken, this._hostTNode, this._hostView);
|
||||
}
|
||||
|
||||
get injector(): Injector {
|
||||
// TODO: Remove LNode lookup when removing LNode.nodeInjector
|
||||
const injector =
|
||||
getOrCreateNodeInjectorForNode(this._getHostNode(), this._hostTNode, this._hostView);
|
||||
return new NodeInjector(injector);
|
||||
}
|
||||
|
||||
/** @deprecated No replacement */
|
||||
get parentInjector(): Injector {
|
||||
const parentLInjector = getParentLNode(this._hostTNode, this._hostView) !.nodeInjector;
|
||||
return parentLInjector ? new NodeInjector(parentLInjector) : new NullInjector();
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
while (this._lContainer[VIEWS].length) {
|
||||
this.remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
get(index: number): viewEngine_ViewRef|null { return this._viewRefs[index] || null; }
|
||||
|
||||
get length(): number { return this._lContainer[VIEWS].length; }
|
||||
|
||||
createEmbeddedView<C>(templateRef: ViewEngine_TemplateRef<C>, context?: C, index?: number):
|
||||
viewEngine_EmbeddedViewRef<C> {
|
||||
const adjustedIdx = this._adjustIndex(index);
|
||||
const viewRef = (templateRef as any)
|
||||
.createEmbeddedView(
|
||||
context || <any>{}, this._lContainer, this._tContainerNode,
|
||||
this._hostView, adjustedIdx);
|
||||
(viewRef as ViewRef<any>).attachToViewContainerRef(this);
|
||||
this._viewRefs.splice(adjustedIdx, 0, viewRef);
|
||||
return viewRef;
|
||||
}
|
||||
|
||||
createComponent<C>(
|
||||
componentFactory: viewEngine_ComponentFactory<C>, index?: number|undefined,
|
||||
injector?: Injector|undefined, projectableNodes?: any[][]|undefined,
|
||||
ngModuleRef?: viewEngine_NgModuleRef<any>|undefined): viewEngine_ComponentRef<C> {
|
||||
const contextInjector = injector || this.parentInjector;
|
||||
if (!ngModuleRef && contextInjector) {
|
||||
ngModuleRef = contextInjector.get(viewEngine_NgModuleRef, null);
|
||||
}
|
||||
|
||||
const componentRef =
|
||||
componentFactory.create(contextInjector, projectableNodes, undefined, ngModuleRef);
|
||||
this.insert(componentRef.hostView, index);
|
||||
return componentRef;
|
||||
}
|
||||
|
||||
insert(viewRef: viewEngine_ViewRef, index?: number): viewEngine_ViewRef {
|
||||
if (viewRef.destroyed) {
|
||||
throw new Error('Cannot insert a destroyed View in a ViewContainer!');
|
||||
}
|
||||
const lView = (viewRef as ViewRef<any>)._view !;
|
||||
const adjustedIdx = this._adjustIndex(index);
|
||||
|
||||
insertView(
|
||||
lView, this._lContainer, this._hostView, adjustedIdx,
|
||||
this._tContainerNode.parent !.index);
|
||||
|
||||
const container = this._getHostNode().dynamicLContainerNode !;
|
||||
const beforeNode = getBeforeNodeForView(adjustedIdx, this._lContainer[VIEWS], container);
|
||||
addRemoveViewFromContainer(lView, true, beforeNode);
|
||||
|
||||
(viewRef as ViewRef<any>).attachToViewContainerRef(this);
|
||||
this._viewRefs.splice(adjustedIdx, 0, viewRef);
|
||||
|
||||
return viewRef;
|
||||
}
|
||||
|
||||
move(viewRef: viewEngine_ViewRef, newIndex: number): viewEngine_ViewRef {
|
||||
const index = this.indexOf(viewRef);
|
||||
this.detach(index);
|
||||
this.insert(viewRef, this._adjustIndex(newIndex));
|
||||
return viewRef;
|
||||
}
|
||||
|
||||
indexOf(viewRef: viewEngine_ViewRef): number { return this._viewRefs.indexOf(viewRef); }
|
||||
|
||||
remove(index?: number): void {
|
||||
const adjustedIdx = this._adjustIndex(index, -1);
|
||||
removeView(this._lContainer, this._tContainerNode as TContainerNode, adjustedIdx);
|
||||
this._viewRefs.splice(adjustedIdx, 1);
|
||||
}
|
||||
|
||||
detach(index?: number): viewEngine_ViewRef|null {
|
||||
const adjustedIdx = this._adjustIndex(index, -1);
|
||||
detachView(this._lContainer, adjustedIdx, !!this._tContainerNode.detached);
|
||||
return this._viewRefs.splice(adjustedIdx, 1)[0] || null;
|
||||
}
|
||||
|
||||
private _adjustIndex(index?: number, shift: number = 0) {
|
||||
if (index == null) {
|
||||
return this._lContainer[VIEWS].length + shift;
|
||||
}
|
||||
if (ngDevMode) {
|
||||
assertGreaterThan(index, -1, 'index must be positive');
|
||||
// +1 because it's legal to insert at the end.
|
||||
assertLessThan(index, this._lContainer[VIEWS].length + 1 + shift, 'index');
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
private _getHostNode() { return getLNode(this._hostTNode, this._hostView); }
|
||||
};
|
||||
}
|
||||
|
||||
const hostLNode = getLNode(hostTNode, hostView);
|
||||
ngDevMode && assertNodeOfPossibleTypes(
|
||||
hostTNode, TNodeType.Container, TNodeType.Element, TNodeType.ElementContainer);
|
||||
|
||||
const lContainer = createLContainer(hostView, true);
|
||||
const comment = hostView[RENDERER].createComment(ngDevMode ? 'container' : '');
|
||||
const lContainerNode: LContainerNode =
|
||||
createLNodeObject(TNodeType.Container, hostLNode.nodeInjector, comment, lContainer);
|
||||
|
||||
lContainer[RENDER_PARENT] = getRenderParent(hostTNode, hostView);
|
||||
|
||||
appendChild(comment, hostTNode, hostView);
|
||||
|
||||
if (!hostTNode.dynamicContainerNode) {
|
||||
hostTNode.dynamicContainerNode =
|
||||
createTNode(TNodeType.Container, -1, null, null, hostTNode, null);
|
||||
}
|
||||
|
||||
hostLNode.dynamicLContainerNode = lContainerNode;
|
||||
addToViewTree(hostView, hostTNode.index as number, lContainer);
|
||||
|
||||
return new R3ViewContainerRef(
|
||||
lContainer, hostTNode.dynamicContainerNode as TContainerNode, hostTNode, hostView);
|
||||
}
|
||||
|
||||
|
||||
/** Returns a ChangeDetectorRef (a.k.a. a ViewRef) */
|
||||
export function injectChangeDetectorRef(): ViewEngine_ChangeDetectorRef {
|
||||
return createViewRef(getPreviousOrParentTNode(), _getViewData(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ViewRef and stores it on the injector as ChangeDetectorRef (public alias).
|
||||
*
|
||||
* @param hostTNode The node that is requesting a ChangeDetectorRef
|
||||
* @param hostView The view to which the node belongs
|
||||
* @param context The context for this change detector ref
|
||||
* @returns The ChangeDetectorRef to use
|
||||
*/
|
||||
export function createViewRef(
|
||||
hostTNode: TNode, hostView: LViewData, context: any): ViewEngine_ChangeDetectorRef {
|
||||
if (isComponent(hostTNode)) {
|
||||
const componentIndex = hostTNode.flags >> TNodeFlags.DirectiveStartingIndexShift;
|
||||
const componentView = getLNode(hostTNode, hostView).data as LViewData;
|
||||
return new ViewRef(componentView, context, componentIndex);
|
||||
} else if (hostTNode.type === TNodeType.Element) {
|
||||
const hostComponentView = findComponentView(hostView);
|
||||
return new ViewRef(hostComponentView, hostComponentView[CONTEXT], -1);
|
||||
}
|
||||
return null !;
|
||||
}
|
|
@ -32,9 +32,6 @@
|
|||
{
|
||||
"name": "ChangeDetectionStrategy"
|
||||
},
|
||||
{
|
||||
"name": "ChangeDetectorRef"
|
||||
},
|
||||
{
|
||||
"name": "CorePlayerHandler"
|
||||
},
|
||||
|
@ -65,9 +62,6 @@
|
|||
{
|
||||
"name": "ElementRef"
|
||||
},
|
||||
{
|
||||
"name": "ElementRef$1"
|
||||
},
|
||||
{
|
||||
"name": "FLAGS"
|
||||
},
|
||||
|
@ -146,6 +140,15 @@
|
|||
{
|
||||
"name": "QUERIES"
|
||||
},
|
||||
{
|
||||
"name": "R3_ELEMENT_REF_FACTORY"
|
||||
},
|
||||
{
|
||||
"name": "R3_TEMPLATE_REF_FACTORY"
|
||||
},
|
||||
{
|
||||
"name": "R3_VIEW_CONTAINER_REF_FACTORY"
|
||||
},
|
||||
{
|
||||
"name": "RENDERER"
|
||||
},
|
||||
|
@ -179,18 +182,12 @@
|
|||
{
|
||||
"name": "TemplateRef"
|
||||
},
|
||||
{
|
||||
"name": "TemplateRef$1"
|
||||
},
|
||||
{
|
||||
"name": "VIEWS"
|
||||
},
|
||||
{
|
||||
"name": "ViewContainerRef"
|
||||
},
|
||||
{
|
||||
"name": "ViewContainerRef$1"
|
||||
},
|
||||
{
|
||||
"name": "ViewEncapsulation$1"
|
||||
},
|
||||
|
@ -300,7 +297,7 @@
|
|||
"name": "bloomFindPossibleInjector"
|
||||
},
|
||||
{
|
||||
"name": "bloomHashBit"
|
||||
"name": "bloomHashBitOrFactory"
|
||||
},
|
||||
{
|
||||
"name": "buildAnimationPlayer"
|
||||
|
@ -401,9 +398,6 @@
|
|||
{
|
||||
"name": "createViewQuery"
|
||||
},
|
||||
{
|
||||
"name": "createViewRef"
|
||||
},
|
||||
{
|
||||
"name": "defineComponent"
|
||||
},
|
||||
|
@ -719,9 +713,6 @@
|
|||
{
|
||||
"name": "isClassBased"
|
||||
},
|
||||
{
|
||||
"name": "isComponent"
|
||||
},
|
||||
{
|
||||
"name": "isComponentInstance"
|
||||
},
|
||||
|
@ -926,6 +917,9 @@
|
|||
{
|
||||
"name": "setDirty"
|
||||
},
|
||||
{
|
||||
"name": "setEnvironment"
|
||||
},
|
||||
{
|
||||
"name": "setFlag"
|
||||
},
|
||||
|
|
|
@ -1238,9 +1238,21 @@
|
|||
{
|
||||
"name": "Quote"
|
||||
},
|
||||
{
|
||||
"name": "R3_CHANGE_DETECTOR_REF_FACTORY$1"
|
||||
},
|
||||
{
|
||||
"name": "R3_COMPILE_INJECTABLE$1"
|
||||
},
|
||||
{
|
||||
"name": "R3_ELEMENT_REF_FACTORY$1"
|
||||
},
|
||||
{
|
||||
"name": "R3_TEMPLATE_REF_FACTORY$1"
|
||||
},
|
||||
{
|
||||
"name": "R3_VIEW_CONTAINER_REF_FACTORY$1"
|
||||
},
|
||||
{
|
||||
"name": "ReadKeyExpr"
|
||||
},
|
||||
|
@ -3389,6 +3401,9 @@
|
|||
{
|
||||
"name": "noop$3"
|
||||
},
|
||||
{
|
||||
"name": "noopFactory"
|
||||
},
|
||||
{
|
||||
"name": "noopScope"
|
||||
},
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
{
|
||||
"name": "ChangeDetectionStrategy"
|
||||
},
|
||||
{
|
||||
"name": "ChangeDetectorRef"
|
||||
},
|
||||
{
|
||||
"name": "DECLARATION_VIEW"
|
||||
},
|
||||
|
@ -50,9 +47,6 @@
|
|||
{
|
||||
"name": "ElementRef"
|
||||
},
|
||||
{
|
||||
"name": "ElementRef$1"
|
||||
},
|
||||
{
|
||||
"name": "FLAGS"
|
||||
},
|
||||
|
@ -137,6 +131,15 @@
|
|||
{
|
||||
"name": "QUERIES"
|
||||
},
|
||||
{
|
||||
"name": "R3_ELEMENT_REF_FACTORY"
|
||||
},
|
||||
{
|
||||
"name": "R3_TEMPLATE_REF_FACTORY"
|
||||
},
|
||||
{
|
||||
"name": "R3_VIEW_CONTAINER_REF_FACTORY"
|
||||
},
|
||||
{
|
||||
"name": "RENDERER"
|
||||
},
|
||||
|
@ -167,9 +170,6 @@
|
|||
{
|
||||
"name": "TemplateRef"
|
||||
},
|
||||
{
|
||||
"name": "TemplateRef$1"
|
||||
},
|
||||
{
|
||||
"name": "ToDoAppComponent_footer_Template_6"
|
||||
},
|
||||
|
@ -200,9 +200,6 @@
|
|||
{
|
||||
"name": "ViewContainerRef"
|
||||
},
|
||||
{
|
||||
"name": "ViewContainerRef$1"
|
||||
},
|
||||
{
|
||||
"name": "ViewEncapsulation$1"
|
||||
},
|
||||
|
@ -366,7 +363,7 @@
|
|||
"name": "bloomFindPossibleInjector"
|
||||
},
|
||||
{
|
||||
"name": "bloomHashBit"
|
||||
"name": "bloomHashBitOrFactory"
|
||||
},
|
||||
{
|
||||
"name": "cacheMatchingDirectivesForNode"
|
||||
|
@ -464,9 +461,6 @@
|
|||
{
|
||||
"name": "createViewQuery"
|
||||
},
|
||||
{
|
||||
"name": "createViewRef"
|
||||
},
|
||||
{
|
||||
"name": "defineComponent"
|
||||
},
|
||||
|
@ -722,6 +716,9 @@
|
|||
{
|
||||
"name": "inject"
|
||||
},
|
||||
{
|
||||
"name": "injectElementRef"
|
||||
},
|
||||
{
|
||||
"name": "injectTemplateRef"
|
||||
},
|
||||
|
@ -740,9 +737,6 @@
|
|||
{
|
||||
"name": "invertObject"
|
||||
},
|
||||
{
|
||||
"name": "isComponent"
|
||||
},
|
||||
{
|
||||
"name": "isContentQueryHost"
|
||||
},
|
||||
|
@ -944,6 +938,9 @@
|
|||
{
|
||||
"name": "setDirty"
|
||||
},
|
||||
{
|
||||
"name": "setEnvironment"
|
||||
},
|
||||
{
|
||||
"name": "setFlag"
|
||||
},
|
||||
|
|
|
@ -281,9 +281,6 @@
|
|||
{
|
||||
"name": "ElementRef"
|
||||
},
|
||||
{
|
||||
"name": "ElementRef$1"
|
||||
},
|
||||
{
|
||||
"name": "EmulatedEncapsulationDomRenderer2"
|
||||
},
|
||||
|
@ -662,6 +659,18 @@
|
|||
{
|
||||
"name": "R3Injector"
|
||||
},
|
||||
{
|
||||
"name": "R3_CHANGE_DETECTOR_REF_FACTORY"
|
||||
},
|
||||
{
|
||||
"name": "R3_ELEMENT_REF_FACTORY"
|
||||
},
|
||||
{
|
||||
"name": "R3_TEMPLATE_REF_FACTORY"
|
||||
},
|
||||
{
|
||||
"name": "R3_VIEW_CONTAINER_REF_FACTORY"
|
||||
},
|
||||
{
|
||||
"name": "REMOVE_EVENT_LISTENER"
|
||||
},
|
||||
|
@ -809,9 +818,6 @@
|
|||
{
|
||||
"name": "TemplateRef"
|
||||
},
|
||||
{
|
||||
"name": "TemplateRef$1"
|
||||
},
|
||||
{
|
||||
"name": "Testability"
|
||||
},
|
||||
|
@ -890,9 +896,6 @@
|
|||
{
|
||||
"name": "ViewContainerRef"
|
||||
},
|
||||
{
|
||||
"name": "ViewContainerRef$1"
|
||||
},
|
||||
{
|
||||
"name": "ViewEncapsulation$1"
|
||||
},
|
||||
|
@ -1200,7 +1203,7 @@
|
|||
"name": "bloomFindPossibleInjector"
|
||||
},
|
||||
{
|
||||
"name": "bloomHashBit"
|
||||
"name": "bloomHashBitOrFactory"
|
||||
},
|
||||
{
|
||||
"name": "cacheMatchingDirectivesForNode"
|
||||
|
@ -2288,6 +2291,9 @@
|
|||
{
|
||||
"name": "setDirty"
|
||||
},
|
||||
{
|
||||
"name": "setEnvironment"
|
||||
},
|
||||
{
|
||||
"name": "setFlag"
|
||||
},
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {ElementRef, TemplateRef} from '@angular/core';
|
||||
import {RenderFlags} from '@angular/core/src/render3';
|
||||
|
||||
import {AnimationContext, PlayState, Player, PlayerHandler} from '../../../src/render3/animations/interfaces';
|
||||
import {addPlayer, getOrCreateAnimationContext, getPlayers} from '../../../src/render3/animations/players';
|
||||
import {QUERY_READ_FROM_NODE, defineComponent, getHostElement} from '../../../src/render3/index';
|
||||
|
@ -13,6 +15,7 @@ import {element, elementEnd, elementStart, elementStyling, elementStylingApply,
|
|||
import {RElement} from '../../../src/render3/interfaces/renderer';
|
||||
import {QueryList, query, queryRefresh} from '../../../src/render3/query';
|
||||
import {ComponentFixture} from '../render_util';
|
||||
|
||||
import {MockPlayer} from './mock_player';
|
||||
|
||||
describe('animation player access', () => {
|
||||
|
@ -286,7 +289,7 @@ class SuperComp {
|
|||
},
|
||||
viewQuery: function(rf: RenderFlags, ctx: SuperComp) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['child'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['child'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
|
|
@ -10,7 +10,8 @@ import {withBody} from '@angular/private/testing';
|
|||
|
||||
import {ChangeDetectionStrategy, ChangeDetectorRef, DoCheck, RendererType2} from '../../src/core';
|
||||
import {getRenderedText, whenRendered} from '../../src/render3/component';
|
||||
import {LifecycleHooksFeature, defineComponent, defineDirective, injectChangeDetectorRef} from '../../src/render3/index';
|
||||
import {directiveInject} from '../../src/render3/di';
|
||||
import {LifecycleHooksFeature, defineComponent, defineDirective} from '../../src/render3/index';
|
||||
import {bind, container, containerRefreshEnd, containerRefreshStart, detectChanges, element, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, interpolation1, interpolation2, listener, markDirty, text, textBinding, tick} from '../../src/render3/instructions';
|
||||
import {RenderFlags} from '../../src/render3/interfaces/definition';
|
||||
import {RElement, Renderer3, RendererFactory3} from '../../src/render3/interfaces/renderer';
|
||||
|
@ -18,7 +19,6 @@ import {RElement, Renderer3, RendererFactory3} from '../../src/render3/interface
|
|||
import {containerEl, createComponent, renderComponent, requestAnimationFrame} from './render_util';
|
||||
|
||||
describe('change detection', () => {
|
||||
|
||||
describe('markDirty, detectChanges, whenRendered, getRenderedText', () => {
|
||||
class MyComponent implements DoCheck {
|
||||
value: string = 'works';
|
||||
|
@ -326,7 +326,7 @@ describe('change detection', () => {
|
|||
static ngComponentDef = defineComponent({
|
||||
type: MyComp,
|
||||
selectors: [['my-comp']],
|
||||
factory: () => myComp = new MyComp(injectChangeDetectorRef()),
|
||||
factory: () => myComp = new MyComp(directiveInject(ChangeDetectorRef as any)),
|
||||
consts: 1,
|
||||
vars: 1,
|
||||
/** {{ name }} */
|
||||
|
@ -352,7 +352,7 @@ describe('change detection', () => {
|
|||
static ngComponentDef = defineComponent({
|
||||
type: ParentComp,
|
||||
selectors: [['parent-comp']],
|
||||
factory: () => new ParentComp(injectChangeDetectorRef()),
|
||||
factory: () => new ParentComp(directiveInject(ChangeDetectorRef as any)),
|
||||
consts: 2,
|
||||
vars: 1,
|
||||
/**
|
||||
|
@ -378,7 +378,7 @@ describe('change detection', () => {
|
|||
static ngDirectiveDef = defineDirective({
|
||||
type: Dir,
|
||||
selectors: [['', 'dir', '']],
|
||||
factory: () => dir = new Dir(injectChangeDetectorRef())
|
||||
factory: () => dir = new Dir(directiveInject(ChangeDetectorRef as any))
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -487,7 +487,7 @@ describe('change detection', () => {
|
|||
static ngComponentDef = defineComponent({
|
||||
type: MyApp,
|
||||
selectors: [['my-app']],
|
||||
factory: () => new MyApp(injectChangeDetectorRef()),
|
||||
factory: () => new MyApp(directiveInject(ChangeDetectorRef as any)),
|
||||
consts: 2,
|
||||
vars: 1,
|
||||
/**
|
||||
|
@ -542,7 +542,7 @@ describe('change detection', () => {
|
|||
static ngComponentDef = defineComponent({
|
||||
type: DetectChangesComp,
|
||||
selectors: [['detect-changes-comp']],
|
||||
factory: () => new DetectChangesComp(injectChangeDetectorRef()),
|
||||
factory: () => new DetectChangesComp(directiveInject(ChangeDetectorRef as any)),
|
||||
consts: 1,
|
||||
vars: 1,
|
||||
/** {{ value }} */
|
||||
|
@ -575,7 +575,7 @@ describe('change detection', () => {
|
|||
static ngComponentDef = defineComponent({
|
||||
type: DetectChangesComp,
|
||||
selectors: [['detect-changes-comp']],
|
||||
factory: () => new DetectChangesComp(injectChangeDetectorRef()),
|
||||
factory: () => new DetectChangesComp(directiveInject(ChangeDetectorRef as any)),
|
||||
consts: 1,
|
||||
vars: 1,
|
||||
/** {{ doCheckCount }} */
|
||||
|
@ -605,7 +605,7 @@ describe('change detection', () => {
|
|||
static ngComponentDef = defineComponent({
|
||||
type: MyApp,
|
||||
selectors: [['my-app']],
|
||||
factory: () => new MyApp(injectChangeDetectorRef()),
|
||||
factory: () => new MyApp(directiveInject(ChangeDetectorRef as any)),
|
||||
consts: 1,
|
||||
vars: 0,
|
||||
/** <detached-comp></detached-comp> */
|
||||
|
@ -629,7 +629,7 @@ describe('change detection', () => {
|
|||
static ngComponentDef = defineComponent({
|
||||
type: DetachedComp,
|
||||
selectors: [['detached-comp']],
|
||||
factory: () => comp = new DetachedComp(injectChangeDetectorRef()),
|
||||
factory: () => comp = new DetachedComp(directiveInject(ChangeDetectorRef as any)),
|
||||
consts: 1,
|
||||
vars: 1,
|
||||
/** {{ value }} */
|
||||
|
@ -730,7 +730,7 @@ describe('change detection', () => {
|
|||
static ngComponentDef = defineComponent({
|
||||
type: OnPushComp,
|
||||
selectors: [['on-push-comp']],
|
||||
factory: () => onPushComp = new OnPushComp(injectChangeDetectorRef()),
|
||||
factory: () => onPushComp = new OnPushComp(directiveInject(ChangeDetectorRef as any)),
|
||||
consts: 1,
|
||||
vars: 1,
|
||||
/** {{ value }} */
|
||||
|
@ -791,7 +791,7 @@ describe('change detection', () => {
|
|||
static ngComponentDef = defineComponent({
|
||||
type: OnPushComp,
|
||||
selectors: [['on-push-comp']],
|
||||
factory: () => comp = new OnPushComp(injectChangeDetectorRef()),
|
||||
factory: () => comp = new OnPushComp(directiveInject(ChangeDetectorRef as any)),
|
||||
consts: 1,
|
||||
vars: 1,
|
||||
/** {{ value }} */
|
||||
|
@ -960,7 +960,7 @@ describe('change detection', () => {
|
|||
static ngComponentDef = defineComponent({
|
||||
type: NoChangesComp,
|
||||
selectors: [['no-changes-comp']],
|
||||
factory: () => comp = new NoChangesComp(injectChangeDetectorRef()),
|
||||
factory: () => comp = new NoChangesComp(directiveInject(ChangeDetectorRef as any)),
|
||||
consts: 1,
|
||||
vars: 1,
|
||||
template: (rf: RenderFlags, ctx: NoChangesComp) => {
|
||||
|
@ -982,7 +982,7 @@ describe('change detection', () => {
|
|||
static ngComponentDef = defineComponent({
|
||||
type: AppComp,
|
||||
selectors: [['app-comp']],
|
||||
factory: () => new AppComp(injectChangeDetectorRef()),
|
||||
factory: () => new AppComp(directiveInject(ChangeDetectorRef as any)),
|
||||
consts: 2,
|
||||
vars: 1,
|
||||
/**
|
||||
|
@ -1045,7 +1045,7 @@ describe('change detection', () => {
|
|||
static ngComponentDef = defineComponent({
|
||||
type: EmbeddedViewApp,
|
||||
selectors: [['embedded-view-app']],
|
||||
factory: () => new EmbeddedViewApp(injectChangeDetectorRef()),
|
||||
factory: () => new EmbeddedViewApp(directiveInject(ChangeDetectorRef as any)),
|
||||
consts: 1,
|
||||
vars: 0,
|
||||
/**
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
import {NgForOfContext} from '@angular/common';
|
||||
import {ElementRef, TemplateRef} from '@angular/core';
|
||||
|
||||
import {AttributeMarker, defineComponent, templateRefExtractor} from '../../src/render3/index';
|
||||
import {bind, template, elementEnd, elementProperty, elementStart, getCurrentView, interpolation1, interpolation2, interpolation3, interpolationV, listener, load, nextContext, restoreView, text, textBinding, elementContainerStart, elementContainerEnd, reference} from '../../src/render3/instructions';
|
||||
|
@ -896,11 +897,15 @@ describe('@angular/common integration', () => {
|
|||
*/
|
||||
template: (rf: RenderFlags, myApp: MyApp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, (rf1: RenderFlags) => {
|
||||
if (rf1 & RenderFlags.Create) {
|
||||
text(0, 'from tpl');
|
||||
}
|
||||
}, 1, 0, undefined, undefined, ['tpl', ''], templateRefExtractor);
|
||||
template(
|
||||
0,
|
||||
(rf1: RenderFlags) => {
|
||||
if (rf1 & RenderFlags.Create) {
|
||||
text(0, 'from tpl');
|
||||
}
|
||||
},
|
||||
1, 0, undefined, undefined, ['tpl', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
template(2, null, 0, 0, null, [AttributeMarker.SelectOnly, 'ngTemplateOutlet']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
|
@ -939,11 +944,15 @@ describe('@angular/common integration', () => {
|
|||
*/
|
||||
template: (rf: RenderFlags, myApp: MyApp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, (rf1: RenderFlags) => {
|
||||
if (rf1 & RenderFlags.Create) {
|
||||
text(0, 'from tpl');
|
||||
}
|
||||
}, 1, 0, undefined, undefined, ['tpl', ''], templateRefExtractor);
|
||||
template(
|
||||
0,
|
||||
(rf1: RenderFlags) => {
|
||||
if (rf1 & RenderFlags.Create) {
|
||||
text(0, 'from tpl');
|
||||
}
|
||||
},
|
||||
1, 0, undefined, undefined, ['tpl', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
elementContainerStart(2, [AttributeMarker.SelectOnly, 'ngTemplateOutlet']);
|
||||
elementContainerEnd();
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
*/
|
||||
|
||||
import {NgForOf as NgForOfDef, NgIf as NgIfDef, NgTemplateOutlet as NgTemplateOutletDef} from '@angular/common';
|
||||
import {IterableDiffers} from '@angular/core';
|
||||
import {IterableDiffers, TemplateRef, ViewContainerRef} from '@angular/core';
|
||||
|
||||
import {DirectiveType, NgOnChangesFeature, defineDirective, directiveInject, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index';
|
||||
import {DirectiveType, NgOnChangesFeature, defineDirective, directiveInject} from '../../src/render3/index';
|
||||
|
||||
export const NgForOf: DirectiveType<NgForOfDef<any>> = NgForOfDef as any;
|
||||
export const NgIf: DirectiveType<NgIfDef> = NgIfDef as any;
|
||||
|
@ -19,7 +19,8 @@ NgForOf.ngDirectiveDef = defineDirective({
|
|||
type: NgForOfDef,
|
||||
selectors: [['', 'ngForOf', '']],
|
||||
factory: () => new NgForOfDef(
|
||||
injectViewContainerRef(), injectTemplateRef(), directiveInject(IterableDiffers)),
|
||||
directiveInject(ViewContainerRef as any), directiveInject(TemplateRef as any),
|
||||
directiveInject(IterableDiffers)),
|
||||
inputs: {
|
||||
ngForOf: 'ngForOf',
|
||||
ngForTrackBy: 'ngForTrackBy',
|
||||
|
@ -30,14 +31,15 @@ NgForOf.ngDirectiveDef = defineDirective({
|
|||
(NgIf as any).ngDirectiveDef = defineDirective({
|
||||
type: NgIfDef,
|
||||
selectors: [['', 'ngIf', '']],
|
||||
factory: () => new NgIfDef(injectViewContainerRef(), injectTemplateRef()),
|
||||
factory: () => new NgIfDef(
|
||||
directiveInject(ViewContainerRef as any), directiveInject(TemplateRef as any)),
|
||||
inputs: {ngIf: 'ngIf', ngIfThen: 'ngIfThen', ngIfElse: 'ngIfElse'}
|
||||
});
|
||||
|
||||
(NgTemplateOutlet as any).ngDirectiveDef = defineDirective({
|
||||
type: NgTemplateOutletDef,
|
||||
selectors: [['', 'ngTemplateOutlet', '']],
|
||||
factory: () => new NgTemplateOutletDef(injectViewContainerRef()),
|
||||
factory: () => new NgTemplateOutletDef(directiveInject(ViewContainerRef as any)),
|
||||
features: [NgOnChangesFeature],
|
||||
inputs:
|
||||
{ngTemplateOutlet: 'ngTemplateOutlet', ngTemplateOutletContext: 'ngTemplateOutletContext'}
|
||||
|
|
|
@ -394,7 +394,7 @@ describe('components & directives', () => {
|
|||
static ngDirectiveDef = $r3$.ɵdefineDirective({
|
||||
type: IfDirective,
|
||||
selectors: [['', 'if', '']],
|
||||
factory: () => new IfDirective($r3$.ɵinjectTemplateRef()),
|
||||
factory: () => new IfDirective($r3$.ɵdirectiveInject(TemplateRef as any)),
|
||||
});
|
||||
// /NORMATIVE
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Attribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, INJECTOR, Inject, InjectFlags, Injectable, Injector, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, SkipSelf, TemplateRef, ViewChild, ViewChildren, ViewContainerRef, defineInjectable, defineInjector, inject} from '../../../src/core';
|
||||
import {Attribute, ChangeDetectorRef, Component, INJECTOR, Inject, InjectFlags, Injectable, Injector, SkipSelf, defineInjectable, inject} from '../../../src/core';
|
||||
import * as $r3$ from '../../../src/core_render3_private_export';
|
||||
import {renderComponent, toHtml} from '../render_util';
|
||||
|
||||
|
@ -32,7 +32,7 @@ describe('injection', () => {
|
|||
type: MyComp,
|
||||
selectors: [['my-comp']],
|
||||
factory: function MyComp_Factory() {
|
||||
return new MyComp($r3$.ɵinjectChangeDetectorRef());
|
||||
return new MyComp($r3$.ɵdirectiveInject(ChangeDetectorRef as any));
|
||||
},
|
||||
consts: 1,
|
||||
vars: 1,
|
||||
|
|
|
@ -6,10 +6,13 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ElementRef, TemplateRef} from '@angular/core';
|
||||
|
||||
import {Component} from '../../../src/core';
|
||||
import * as $r3$ from '../../../src/core_render3_private_export';
|
||||
import {ComponentFixture} from '../render_util';
|
||||
|
||||
|
||||
/// See: `normative.md`
|
||||
describe('local references', () => {
|
||||
type $RenderFlags$ = $r3$.ɵRenderFlags;
|
||||
|
@ -69,7 +72,7 @@ describe('local references', () => {
|
|||
if (rf & 1) {
|
||||
$r3$.ɵtemplate(
|
||||
0, MyComponent_Template_0, 0, 0, null, null, ['tpl', ''],
|
||||
$r3$.ɵtemplateRefExtractor);
|
||||
$r3$.ɵtemplateRefExtractor(TemplateRef, ElementRef));
|
||||
$r3$.ɵtext(2);
|
||||
}
|
||||
if (rf & 2) {
|
||||
|
|
|
@ -6,12 +6,13 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core';
|
||||
import {Component, Directive, Input, OnDestroy, Pipe, PipeTransform, TemplateRef, ViewContainerRef} from '../../../src/core';
|
||||
import * as $r3$ from '../../../src/core_render3_private_export';
|
||||
import {ComponentDefInternal} from '../../../src/render3/interfaces/definition';
|
||||
import {containerEl, renderComponent, toHtml} from '../render_util';
|
||||
|
||||
|
||||
|
||||
/// See: `normative.md`
|
||||
describe('pipes', () => {
|
||||
type $any$ = any;
|
||||
|
@ -145,7 +146,9 @@ describe('pipes', () => {
|
|||
static ngDirectiveDef = $r3$.ɵdefineDirective({
|
||||
type: OneTimeIf,
|
||||
selectors: [['', 'oneTimeIf', '']],
|
||||
factory: () => new OneTimeIf($r3$.ɵinjectViewContainerRef(), $r3$.ɵinjectTemplateRef()),
|
||||
factory: () => new OneTimeIf(
|
||||
$r3$.ɵdirectiveInject(ViewContainerRef as any),
|
||||
$r3$.ɵdirectiveInject(TemplateRef as any)),
|
||||
inputs: {oneTimeIf: 'oneTimeIf'}
|
||||
});
|
||||
// /NORMATIVE
|
||||
|
|
|
@ -6,12 +6,13 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core';
|
||||
import {Component, Directive, Input, SimpleChanges, TemplateRef, ViewContainerRef, inject} from '../../../src/core';
|
||||
import * as $r3$ from '../../../src/core_render3_private_export';
|
||||
import {ComponentDefInternal} from '../../../src/render3/interfaces/definition';
|
||||
import {renderComponent, toHtml} from '../render_util';
|
||||
|
||||
|
||||
|
||||
/// See: `normative.md`
|
||||
describe('template variables', () => {
|
||||
type $any$ = any;
|
||||
|
@ -69,7 +70,9 @@ describe('template variables', () => {
|
|||
type: ForOfDirective,
|
||||
selectors: [['', 'forOf', '']],
|
||||
factory: function ForOfDirective_Factory() {
|
||||
return new ForOfDirective($r3$.ɵinjectViewContainerRef(), $r3$.ɵinjectTemplateRef());
|
||||
return new ForOfDirective(
|
||||
$r3$.ɵdirectiveInject(ViewContainerRef as any),
|
||||
$r3$.ɵdirectiveInject(TemplateRef as any));
|
||||
},
|
||||
// TODO(chuckj): Enable when ngForOf enabling lands.
|
||||
// features: [NgOnChangesFeature],
|
||||
|
|
|
@ -8,9 +8,6 @@
|
|||
|
||||
import {SelectorFlags} from '@angular/core/src/render3/interfaces/projection';
|
||||
|
||||
import {Input, TemplateRef, ViewContainerRef, ViewRef} from '../../src/core';
|
||||
import {defineDirective} from '../../src/render3/definition';
|
||||
import {injectTemplateRef, injectViewContainerRef} from '../../src/render3/di';
|
||||
import {AttributeMarker, detectChanges} from '../../src/render3/index';
|
||||
import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, loadDirective, projection, projectionDef, template, text} from '../../src/render3/instructions';
|
||||
import {RenderFlags} from '../../src/render3/interfaces/definition';
|
||||
|
|
|
@ -11,7 +11,8 @@ import {RenderFlags} from '@angular/core/src/render3/interfaces/definition';
|
|||
|
||||
import {defineComponent} from '../../src/render3/definition';
|
||||
import {bloomAdd, bloomFindPossibleInjector, getOrCreateNodeInjector, injectAttribute} from '../../src/render3/di';
|
||||
import {PublicFeature, defineDirective, directiveInject, injectChangeDetectorRef, injectElementRef, injectRenderer2, injectTemplateRef, injectViewContainerRef, load} from '../../src/render3/index';
|
||||
import {PublicFeature, defineDirective, directiveInject, injectRenderer2, load} from '../../src/render3/index';
|
||||
|
||||
import {bind, container, containerRefreshEnd, containerRefreshStart, createNodeAtIndex, createLViewData, createTView, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, enterView, interpolation2, leaveView, projection, projectionDef, reference, template, text, textBinding, loadDirective, elementContainerStart, elementContainerEnd} from '../../src/render3/instructions';
|
||||
import {LInjector} from '../../src/render3/interfaces/injector';
|
||||
import {isProceduralRenderer} from '../../src/render3/interfaces/renderer';
|
||||
|
@ -786,445 +787,456 @@ describe('di', () => {
|
|||
|
||||
});
|
||||
|
||||
describe('ElementRef', () => {
|
||||
it('should create directive with ElementRef dependencies', () => {
|
||||
let dir !: Directive;
|
||||
let dirSameInstance !: DirectiveSameInstance;
|
||||
let divNode !: LElementNode;
|
||||
describe('Special tokens', () => {
|
||||
|
||||
describe('ElementRef', () => {
|
||||
|
||||
it('should create directive with ElementRef dependencies', () => {
|
||||
let dir !: Directive;
|
||||
let dirSameInstance !: DirectiveSameInstance;
|
||||
let divNode !: LElementNode;
|
||||
|
||||
class Directive {
|
||||
value: string;
|
||||
constructor(public elementRef: ElementRef) {
|
||||
this.value = (elementRef.constructor as any).name;
|
||||
}
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: Directive,
|
||||
selectors: [['', 'dir', '']],
|
||||
factory: () => dir = new Directive(directiveInject(ElementRef)),
|
||||
features: [PublicFeature],
|
||||
exportAs: 'dir'
|
||||
});
|
||||
}
|
||||
|
||||
class DirectiveSameInstance {
|
||||
isSameInstance: boolean;
|
||||
constructor(public elementRef: ElementRef, directive: Directive) {
|
||||
this.isSameInstance = elementRef === directive.elementRef;
|
||||
}
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: DirectiveSameInstance,
|
||||
selectors: [['', 'dirSame', '']],
|
||||
factory: () => dirSameInstance = new DirectiveSameInstance(
|
||||
directiveInject(ElementRef), directiveInject(Directive)),
|
||||
exportAs: 'dirSame'
|
||||
});
|
||||
}
|
||||
|
||||
/** <div dir dirSame></div> */
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'div', ['dir', '', 'dirSame', '']);
|
||||
elementEnd();
|
||||
divNode = load(0);
|
||||
}
|
||||
}, 1, 0, [Directive, DirectiveSameInstance]);
|
||||
|
||||
const fixture = new ComponentFixture(App);
|
||||
expect(dir.value).toContain('ElementRef');
|
||||
expect(dir.elementRef.nativeElement).toEqual(divNode.native);
|
||||
expect(dirSameInstance.elementRef.nativeElement).toEqual(divNode.native);
|
||||
|
||||
// Each ElementRef instance should be unique
|
||||
expect(dirSameInstance.isSameInstance).toBe(false);
|
||||
});
|
||||
|
||||
it('should create ElementRef with comment if requesting directive is on <ng-template> node',
|
||||
() => {
|
||||
let dir !: Directive;
|
||||
let commentNode !: LContainerNode;
|
||||
|
||||
class Directive {
|
||||
value: string;
|
||||
constructor(public elementRef: ElementRef) {
|
||||
this.value = (elementRef.constructor as any).name;
|
||||
}
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: Directive,
|
||||
selectors: [['', 'dir', '']],
|
||||
factory: () => dir = new Directive(directiveInject(ElementRef)),
|
||||
features: [PublicFeature],
|
||||
exportAs: 'dir'
|
||||
});
|
||||
}
|
||||
|
||||
/** <ng-template dir></ng-template> */
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, () => {}, 0, 0, null, ['dir', '']);
|
||||
commentNode = load(0);
|
||||
}
|
||||
}, 1, 0, [Directive]);
|
||||
|
||||
const fixture = new ComponentFixture(App);
|
||||
expect(dir.value).toContain('ElementRef');
|
||||
expect(dir.elementRef.nativeElement).toEqual(commentNode.native);
|
||||
});
|
||||
});
|
||||
|
||||
describe('TemplateRef', () => {
|
||||
it('should create directive with TemplateRef dependencies', () => {
|
||||
|
||||
class Directive {
|
||||
value: string;
|
||||
constructor(public templateRef: TemplateRef<any>) {
|
||||
this.value = (templateRef.constructor as any).name;
|
||||
}
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: Directive,
|
||||
selectors: [['', 'dir', '']],
|
||||
factory: () => new Directive(directiveInject(TemplateRef as any)),
|
||||
features: [PublicFeature],
|
||||
exportAs: 'dir'
|
||||
});
|
||||
}
|
||||
|
||||
class DirectiveSameInstance {
|
||||
isSameInstance: boolean;
|
||||
constructor(templateRef: TemplateRef<any>, directive: Directive) {
|
||||
this.isSameInstance = templateRef === directive.templateRef;
|
||||
}
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: DirectiveSameInstance,
|
||||
selectors: [['', 'dirSame', '']],
|
||||
factory: () => new DirectiveSameInstance(
|
||||
directiveInject(TemplateRef as any), directiveInject(Directive)),
|
||||
exportAs: 'dirSame'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* <ng-template dir dirSame #dir="dir" #dirSame="dirSame">
|
||||
* {{ dir.value }} - {{ dirSame.value }}
|
||||
* </ng-template>
|
||||
*/
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, function() {
|
||||
}, 0, 0, undefined, ['dir', '', 'dirSame', ''], ['dir', 'dir', 'dirSame', 'dirSame']);
|
||||
text(3);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
const tmp1 = reference(1) as any;
|
||||
const tmp2 = reference(2) as any;
|
||||
textBinding(3, interpolation2('', tmp1.value, '-', tmp2.isSameInstance, ''));
|
||||
}
|
||||
}, 4, 2, [Directive, DirectiveSameInstance]);
|
||||
|
||||
const fixture = new ComponentFixture(App);
|
||||
// Each TemplateRef instance should be unique
|
||||
expect(fixture.html).toContain('TemplateRef');
|
||||
expect(fixture.html).toContain('false');
|
||||
});
|
||||
});
|
||||
|
||||
describe('ViewContainerRef', () => {
|
||||
it('should create directive with ViewContainerRef dependencies', () => {
|
||||
class Directive {
|
||||
value: string;
|
||||
constructor(public viewContainerRef: ViewContainerRef) {
|
||||
this.value = (viewContainerRef.constructor as any).name;
|
||||
}
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: Directive,
|
||||
selectors: [['', 'dir', '']],
|
||||
factory: () => new Directive(directiveInject(ViewContainerRef as any)),
|
||||
features: [PublicFeature],
|
||||
exportAs: 'dir'
|
||||
});
|
||||
}
|
||||
|
||||
class DirectiveSameInstance {
|
||||
isSameInstance: boolean;
|
||||
constructor(viewContainerRef: ViewContainerRef, directive: Directive) {
|
||||
this.isSameInstance = viewContainerRef === directive.viewContainerRef;
|
||||
}
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: DirectiveSameInstance,
|
||||
selectors: [['', 'dirSame', '']],
|
||||
factory: () => new DirectiveSameInstance(
|
||||
directiveInject(ViewContainerRef as any), directiveInject(Directive)),
|
||||
exportAs: 'dirSame'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* <div dir dirSame #dir="dir" #dirSame="dirSame">
|
||||
* {{ dir.value }} - {{ dirSame.value }}
|
||||
* </div>
|
||||
*/
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(
|
||||
0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir', 'dirSame', 'dirSame']);
|
||||
{ text(3); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
const tmp1 = reference(1) as any;
|
||||
const tmp2 = reference(2) as any;
|
||||
textBinding(3, interpolation2('', tmp1.value, '-', tmp2.isSameInstance, ''));
|
||||
}
|
||||
}, 4, 2, [Directive, DirectiveSameInstance]);
|
||||
|
||||
const fixture = new ComponentFixture(App);
|
||||
// Each ViewContainerRef instance should be unique
|
||||
expect(fixture.html).toContain('ViewContainerRef');
|
||||
expect(fixture.html).toContain('false');
|
||||
});
|
||||
});
|
||||
|
||||
describe('ChangeDetectorRef', () => {
|
||||
let dir: Directive;
|
||||
let dirSameInstance: DirectiveSameInstance;
|
||||
let comp: MyComp;
|
||||
|
||||
class MyComp {
|
||||
constructor(public cdr: ChangeDetectorRef) {}
|
||||
|
||||
static ngComponentDef = defineComponent({
|
||||
type: MyComp,
|
||||
selectors: [['my-comp']],
|
||||
factory: () => comp = new MyComp(directiveInject(ChangeDetectorRef as any)),
|
||||
consts: 1,
|
||||
vars: 0,
|
||||
template: function(rf: RenderFlags, ctx: MyComp) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
projectionDef();
|
||||
projection(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class Directive {
|
||||
value: string;
|
||||
constructor(public elementRef: ElementRef) {
|
||||
this.value = (elementRef.constructor as any).name;
|
||||
}
|
||||
|
||||
constructor(public cdr: ChangeDetectorRef) { this.value = (cdr.constructor as any).name; }
|
||||
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: Directive,
|
||||
selectors: [['', 'dir', '']],
|
||||
factory: () => dir = new Directive(injectElementRef()),
|
||||
factory: () => dir = new Directive(directiveInject(ChangeDetectorRef as any)),
|
||||
features: [PublicFeature],
|
||||
exportAs: 'dir'
|
||||
});
|
||||
}
|
||||
|
||||
class DirectiveSameInstance {
|
||||
isSameInstance: boolean;
|
||||
constructor(public elementRef: ElementRef, directive: Directive) {
|
||||
this.isSameInstance = elementRef === directive.elementRef;
|
||||
}
|
||||
constructor(public cdr: ChangeDetectorRef) {}
|
||||
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: DirectiveSameInstance,
|
||||
selectors: [['', 'dirSame', '']],
|
||||
factory: () => dirSameInstance =
|
||||
new DirectiveSameInstance(injectElementRef(), directiveInject(Directive)),
|
||||
exportAs: 'dirSame'
|
||||
new DirectiveSameInstance(directiveInject(ChangeDetectorRef as any))
|
||||
});
|
||||
}
|
||||
|
||||
/** <div dir dirSame></div> */
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'div', ['dir', '', 'dirSame', '']);
|
||||
elementEnd();
|
||||
divNode = load(0);
|
||||
}
|
||||
}, 1, 0, [Directive, DirectiveSameInstance]);
|
||||
const directives = [MyComp, Directive, DirectiveSameInstance, NgIf];
|
||||
|
||||
const fixture = new ComponentFixture(App);
|
||||
expect(dir.value).toEqual('ElementRef');
|
||||
expect(dir.elementRef.nativeElement).toEqual(divNode.native);
|
||||
expect(dirSameInstance.elementRef.nativeElement).toEqual(divNode.native);
|
||||
it('should inject current component ChangeDetectorRef into directives on the same node as components',
|
||||
() => {
|
||||
/** <my-comp dir dirSameInstance #dir="dir"></my-comp> {{ dir.value }} */
|
||||
const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
element(0, 'my-comp', ['dir', '', 'dirSame', ''], ['dir', 'dir']);
|
||||
text(2);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
const tmp = reference(1) as any;
|
||||
textBinding(2, bind(tmp.value));
|
||||
}
|
||||
}, 3, 1, directives);
|
||||
|
||||
// Each ElementRef instance should be unique
|
||||
expect(dirSameInstance.isSameInstance).toBe(false);
|
||||
});
|
||||
const app = renderComponent(MyApp);
|
||||
// ChangeDetectorRef is the token, ViewRef has historically been the constructor
|
||||
expect(toHtml(app)).toEqual('<my-comp dir="" dirsame=""></my-comp>ViewRef');
|
||||
expect((comp !.cdr as ViewRef<MyComp>).context).toBe(comp);
|
||||
|
||||
it('should create ElementRef with comment if requesting directive is on <ng-template> node',
|
||||
() => {
|
||||
let dir !: Directive;
|
||||
let commentNode !: LContainerNode;
|
||||
// Each ChangeDetectorRef instance should be unique
|
||||
expect(dir !.cdr).not.toBe(comp !.cdr);
|
||||
expect(dir !.cdr).not.toBe(dirSameInstance !.cdr);
|
||||
});
|
||||
|
||||
class Directive {
|
||||
value: string;
|
||||
constructor(public elementRef: ElementRef) {
|
||||
this.value = (elementRef.constructor as any).name;
|
||||
it('should inject host component ChangeDetectorRef into directives on normal elements',
|
||||
() => {
|
||||
|
||||
class MyApp {
|
||||
constructor(public cdr: ChangeDetectorRef) {}
|
||||
|
||||
static ngComponentDef = defineComponent({
|
||||
type: MyApp,
|
||||
selectors: [['my-app']],
|
||||
consts: 3,
|
||||
vars: 1,
|
||||
factory: () => new MyApp(directiveInject(ChangeDetectorRef as any)),
|
||||
/** <div dir dirSameInstance #dir="dir"> {{ dir.value }} </div> */
|
||||
template: function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']);
|
||||
{ text(2); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
const tmp = reference(1) as any;
|
||||
textBinding(2, bind(tmp.value));
|
||||
}
|
||||
},
|
||||
directives: directives
|
||||
});
|
||||
}
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: Directive,
|
||||
selectors: [['', 'dir', '']],
|
||||
factory: () => dir = new Directive(injectElementRef()),
|
||||
features: [PublicFeature],
|
||||
exportAs: 'dir'
|
||||
});
|
||||
}
|
||||
|
||||
/** <ng-template dir></ng-template> */
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, () => {}, 0, 0, null, ['dir', '']);
|
||||
commentNode = load(0);
|
||||
const app = renderComponent(MyApp);
|
||||
expect(toHtml(app)).toEqual('<div dir="" dirsame="">ViewRef</div>');
|
||||
expect((app !.cdr as ViewRef<MyApp>).context).toBe(app);
|
||||
|
||||
// Each ChangeDetectorRef instance should be unique
|
||||
expect(dir !.cdr).not.toBe(app.cdr);
|
||||
expect(dir !.cdr).not.toBe(dirSameInstance !.cdr);
|
||||
});
|
||||
|
||||
it('should inject host component ChangeDetectorRef into directives in a component\'s ContentChildren',
|
||||
() => {
|
||||
class MyApp {
|
||||
constructor(public cdr: ChangeDetectorRef) {}
|
||||
|
||||
static ngComponentDef = defineComponent({
|
||||
type: MyApp,
|
||||
selectors: [['my-app']],
|
||||
consts: 4,
|
||||
vars: 1,
|
||||
factory: () => new MyApp(directiveInject(ChangeDetectorRef as any)),
|
||||
/**
|
||||
* <my-comp>
|
||||
* <div dir dirSameInstance #dir="dir"></div>
|
||||
* </my-comp>
|
||||
* {{ dir.value }}
|
||||
*/
|
||||
template: function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'my-comp');
|
||||
{ element(1, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']); }
|
||||
elementEnd();
|
||||
text(3);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
const tmp = reference(2) as any;
|
||||
textBinding(3, bind(tmp.value));
|
||||
}
|
||||
},
|
||||
directives: directives
|
||||
});
|
||||
}
|
||||
}, 1, 0, [Directive]);
|
||||
|
||||
const fixture = new ComponentFixture(App);
|
||||
expect(dir.value).toEqual('ElementRef');
|
||||
expect(dir.elementRef.nativeElement).toEqual(commentNode.native);
|
||||
});
|
||||
});
|
||||
const app = renderComponent(MyApp);
|
||||
expect(toHtml(app)).toEqual('<my-comp><div dir="" dirsame=""></div></my-comp>ViewRef');
|
||||
expect((app !.cdr as ViewRef<MyApp>).context).toBe(app);
|
||||
|
||||
describe('TemplateRef', () => {
|
||||
it('should create directive with TemplateRef dependencies', () => {
|
||||
class Directive {
|
||||
value: string;
|
||||
constructor(public templateRef: TemplateRef<any>) {
|
||||
this.value = (templateRef.constructor as any).name;
|
||||
}
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: Directive,
|
||||
selectors: [['', 'dir', '']],
|
||||
factory: () => new Directive(injectTemplateRef()),
|
||||
features: [PublicFeature],
|
||||
exportAs: 'dir'
|
||||
});
|
||||
}
|
||||
// Each ChangeDetectorRef instance should be unique
|
||||
expect(dir !.cdr).not.toBe(app !.cdr);
|
||||
expect(dir !.cdr).not.toBe(dirSameInstance !.cdr);
|
||||
});
|
||||
|
||||
class DirectiveSameInstance {
|
||||
isSameInstance: boolean;
|
||||
constructor(templateRef: TemplateRef<any>, directive: Directive) {
|
||||
this.isSameInstance = templateRef === directive.templateRef;
|
||||
}
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: DirectiveSameInstance,
|
||||
selectors: [['', 'dirSame', '']],
|
||||
factory: () => new DirectiveSameInstance(injectTemplateRef(), directiveInject(Directive)),
|
||||
exportAs: 'dirSame'
|
||||
});
|
||||
}
|
||||
it('should inject host component ChangeDetectorRef into directives in embedded views', () => {
|
||||
|
||||
/**
|
||||
* <ng-template dir dirSame #dir="dir" #dirSame="dirSame">
|
||||
* {{ dir.value }} - {{ dirSame.value }}
|
||||
* </ng-template>
|
||||
*/
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, function() {
|
||||
}, 0, 0, undefined, ['dir', '', 'dirSame', ''], ['dir', 'dir', 'dirSame', 'dirSame']);
|
||||
text(3);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
const tmp1 = reference(1) as any;
|
||||
const tmp2 = reference(2) as any;
|
||||
textBinding(3, interpolation2('', tmp1.value, '-', tmp2.isSameInstance, ''));
|
||||
}
|
||||
}, 4, 2, [Directive, DirectiveSameInstance]);
|
||||
class MyApp {
|
||||
showing = true;
|
||||
|
||||
const fixture = new ComponentFixture(App);
|
||||
// Each TemplateRef instance should be unique
|
||||
expect(fixture.html).toEqual('TemplateRef-false');
|
||||
});
|
||||
});
|
||||
constructor(public cdr: ChangeDetectorRef) {}
|
||||
|
||||
describe('ViewContainerRef', () => {
|
||||
it('should create directive with ViewContainerRef dependencies', () => {
|
||||
class Directive {
|
||||
value: string;
|
||||
constructor(public viewContainerRef: ViewContainerRef) {
|
||||
this.value = (viewContainerRef.constructor as any).name;
|
||||
}
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: Directive,
|
||||
selectors: [['', 'dir', '']],
|
||||
factory: () => new Directive(injectViewContainerRef()),
|
||||
features: [PublicFeature],
|
||||
exportAs: 'dir'
|
||||
});
|
||||
}
|
||||
|
||||
class DirectiveSameInstance {
|
||||
isSameInstance: boolean;
|
||||
constructor(viewContainerRef: ViewContainerRef, directive: Directive) {
|
||||
this.isSameInstance = viewContainerRef === directive.viewContainerRef;
|
||||
}
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: DirectiveSameInstance,
|
||||
selectors: [['', 'dirSame', '']],
|
||||
factory:
|
||||
() => new DirectiveSameInstance(injectViewContainerRef(), directiveInject(Directive)),
|
||||
exportAs: 'dirSame'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* <div dir dirSame #dir="dir" #dirSame="dirSame">
|
||||
* {{ dir.value }} - {{ dirSame.value }}
|
||||
* </div>
|
||||
*/
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir', 'dirSame', 'dirSame']);
|
||||
{ text(3); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
const tmp1 = reference(1) as any;
|
||||
const tmp2 = reference(2) as any;
|
||||
textBinding(3, interpolation2('', tmp1.value, '-', tmp2.isSameInstance, ''));
|
||||
}
|
||||
}, 4, 2, [Directive, DirectiveSameInstance]);
|
||||
|
||||
const fixture = new ComponentFixture(App);
|
||||
// Each ViewContainerRef instance should be unique
|
||||
expect(fixture.html).toEqual('<div dir="" dirsame="">ViewContainerRef-false</div>');
|
||||
});
|
||||
});
|
||||
|
||||
describe('ChangeDetectorRef', () => {
|
||||
let dir: Directive;
|
||||
let dirSameInstance: DirectiveSameInstance;
|
||||
let comp: MyComp;
|
||||
|
||||
class MyComp {
|
||||
constructor(public cdr: ChangeDetectorRef) {}
|
||||
|
||||
static ngComponentDef = defineComponent({
|
||||
type: MyComp,
|
||||
selectors: [['my-comp']],
|
||||
factory: () => comp = new MyComp(injectChangeDetectorRef()),
|
||||
consts: 1,
|
||||
vars: 0,
|
||||
template: function(rf: RenderFlags, ctx: MyComp) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
projectionDef();
|
||||
projection(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class Directive {
|
||||
value: string;
|
||||
|
||||
constructor(public cdr: ChangeDetectorRef) { this.value = (cdr.constructor as any).name; }
|
||||
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: Directive,
|
||||
selectors: [['', 'dir', '']],
|
||||
factory: () => dir = new Directive(injectChangeDetectorRef()),
|
||||
features: [PublicFeature],
|
||||
exportAs: 'dir'
|
||||
});
|
||||
}
|
||||
|
||||
class DirectiveSameInstance {
|
||||
constructor(public cdr: ChangeDetectorRef) {}
|
||||
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: DirectiveSameInstance,
|
||||
selectors: [['', 'dirSame', '']],
|
||||
factory: () => dirSameInstance = new DirectiveSameInstance(injectChangeDetectorRef())
|
||||
});
|
||||
}
|
||||
|
||||
const directives = [MyComp, Directive, DirectiveSameInstance, NgIf];
|
||||
|
||||
it('should inject current component ChangeDetectorRef into directives on the same node as components',
|
||||
() => {
|
||||
/** <my-comp dir dirSameInstance #dir="dir"></my-comp> {{ dir.value }} */
|
||||
const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
element(0, 'my-comp', ['dir', '', 'dirSame', ''], ['dir', 'dir']);
|
||||
text(2);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
const tmp = reference(1) as any;
|
||||
textBinding(2, bind(tmp.value));
|
||||
}
|
||||
}, 3, 1, directives);
|
||||
|
||||
const app = renderComponent(MyApp);
|
||||
// ChangeDetectorRef is the token, ViewRef has historically been the constructor
|
||||
expect(toHtml(app)).toEqual('<my-comp dir="" dirsame=""></my-comp>ViewRef');
|
||||
expect((comp !.cdr as ViewRef<MyComp>).context).toBe(comp);
|
||||
|
||||
// Each ChangeDetectorRef instance should be unique
|
||||
expect(dir !.cdr).not.toBe(comp !.cdr);
|
||||
expect(dir !.cdr).not.toBe(dirSameInstance !.cdr);
|
||||
});
|
||||
|
||||
it('should inject host component ChangeDetectorRef into directives on normal elements', () => {
|
||||
|
||||
class MyApp {
|
||||
constructor(public cdr: ChangeDetectorRef) {}
|
||||
|
||||
static ngComponentDef = defineComponent({
|
||||
type: MyApp,
|
||||
selectors: [['my-app']],
|
||||
consts: 3,
|
||||
vars: 1,
|
||||
factory: () => new MyApp(injectChangeDetectorRef()),
|
||||
/** <div dir dirSameInstance #dir="dir"> {{ dir.value }} </div> */
|
||||
template: function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']);
|
||||
{ text(2); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
const tmp = reference(1) as any;
|
||||
textBinding(2, bind(tmp.value));
|
||||
}
|
||||
},
|
||||
directives: directives
|
||||
});
|
||||
}
|
||||
|
||||
const app = renderComponent(MyApp);
|
||||
expect(toHtml(app)).toEqual('<div dir="" dirsame="">ViewRef</div>');
|
||||
expect((app !.cdr as ViewRef<MyApp>).context).toBe(app);
|
||||
|
||||
// Each ChangeDetectorRef instance should be unique
|
||||
expect(dir !.cdr).not.toBe(app.cdr);
|
||||
expect(dir !.cdr).not.toBe(dirSameInstance !.cdr);
|
||||
});
|
||||
|
||||
it('should inject host component ChangeDetectorRef into directives in a component\'s ContentChildren',
|
||||
() => {
|
||||
class MyApp {
|
||||
constructor(public cdr: ChangeDetectorRef) {}
|
||||
|
||||
static ngComponentDef = defineComponent({
|
||||
type: MyApp,
|
||||
selectors: [['my-app']],
|
||||
consts: 4,
|
||||
vars: 1,
|
||||
factory: () => new MyApp(injectChangeDetectorRef()),
|
||||
/**
|
||||
* <my-comp>
|
||||
* <div dir dirSameInstance #dir="dir"></div>
|
||||
* </my-comp>
|
||||
* {{ dir.value }}
|
||||
*/
|
||||
template: function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'my-comp');
|
||||
{ element(1, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']); }
|
||||
elementEnd();
|
||||
text(3);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
const tmp = reference(2) as any;
|
||||
textBinding(3, bind(tmp.value));
|
||||
}
|
||||
},
|
||||
directives: directives
|
||||
});
|
||||
}
|
||||
|
||||
const app = renderComponent(MyApp);
|
||||
expect(toHtml(app)).toEqual('<my-comp><div dir="" dirsame=""></div></my-comp>ViewRef');
|
||||
expect((app !.cdr as ViewRef<MyApp>).context).toBe(app);
|
||||
|
||||
// Each ChangeDetectorRef instance should be unique
|
||||
expect(dir !.cdr).not.toBe(app !.cdr);
|
||||
expect(dir !.cdr).not.toBe(dirSameInstance !.cdr);
|
||||
});
|
||||
|
||||
it('should inject host component ChangeDetectorRef into directives in embedded views', () => {
|
||||
|
||||
class MyApp {
|
||||
showing = true;
|
||||
|
||||
constructor(public cdr: ChangeDetectorRef) {}
|
||||
|
||||
static ngComponentDef = defineComponent({
|
||||
type: MyApp,
|
||||
selectors: [['my-app']],
|
||||
factory: () => new MyApp(injectChangeDetectorRef()),
|
||||
consts: 1,
|
||||
vars: 0,
|
||||
/**
|
||||
* % if (showing) {
|
||||
static ngComponentDef = defineComponent({
|
||||
type: MyApp,
|
||||
selectors: [['my-app']],
|
||||
factory: () => new MyApp(directiveInject(ChangeDetectorRef as any)),
|
||||
consts: 1,
|
||||
vars: 0,
|
||||
/**
|
||||
* % if (showing) {
|
||||
* <div dir dirSameInstance #dir="dir"> {{ dir.value }} </div>
|
||||
* % }
|
||||
*/
|
||||
template: function(rf: RenderFlags, ctx: MyApp) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
container(0);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
containerRefreshStart(0);
|
||||
{
|
||||
if (ctx.showing) {
|
||||
let rf1 = embeddedViewStart(0, 3, 1);
|
||||
if (rf1 & RenderFlags.Create) {
|
||||
elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']);
|
||||
{ text(2); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf1 & RenderFlags.Update) {
|
||||
const tmp = reference(1) as any;
|
||||
textBinding(2, bind(tmp.value));
|
||||
}
|
||||
}
|
||||
embeddedViewEnd();
|
||||
*/
|
||||
template: function(rf: RenderFlags, ctx: MyApp) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
container(0);
|
||||
}
|
||||
containerRefreshEnd();
|
||||
}
|
||||
},
|
||||
directives: directives
|
||||
});
|
||||
}
|
||||
|
||||
const app = renderComponent(MyApp);
|
||||
expect(toHtml(app)).toEqual('<div dir="" dirsame="">ViewRef</div>');
|
||||
expect((app !.cdr as ViewRef<MyApp>).context).toBe(app);
|
||||
|
||||
// Each ChangeDetectorRef instance should be unique
|
||||
expect(dir !.cdr).not.toBe(app.cdr);
|
||||
expect(dir !.cdr).not.toBe(dirSameInstance !.cdr);
|
||||
});
|
||||
|
||||
it('should inject host component ChangeDetectorRef into directives on containers', () => {
|
||||
function C1(rf1: RenderFlags, ctx1: any) {
|
||||
if (rf1 & RenderFlags.Create) {
|
||||
elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']);
|
||||
{ text(2); }
|
||||
elementEnd();
|
||||
if (rf & RenderFlags.Update) {
|
||||
containerRefreshStart(0);
|
||||
{
|
||||
if (ctx.showing) {
|
||||
let rf1 = embeddedViewStart(0, 3, 1);
|
||||
if (rf1 & RenderFlags.Create) {
|
||||
elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']);
|
||||
{ text(2); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf1 & RenderFlags.Update) {
|
||||
const tmp = reference(1) as any;
|
||||
textBinding(2, bind(tmp.value));
|
||||
}
|
||||
}
|
||||
embeddedViewEnd();
|
||||
}
|
||||
containerRefreshEnd();
|
||||
}
|
||||
},
|
||||
directives: directives
|
||||
});
|
||||
}
|
||||
if (rf1 & RenderFlags.Update) {
|
||||
const tmp = reference(1) as any;
|
||||
textBinding(2, bind(tmp.value));
|
||||
|
||||
const app = renderComponent(MyApp);
|
||||
expect(toHtml(app)).toEqual('<div dir="" dirsame="">ViewRef</div>');
|
||||
expect((app !.cdr as ViewRef<MyApp>).context).toBe(app);
|
||||
|
||||
// Each ChangeDetectorRef instance should be unique
|
||||
expect(dir !.cdr).not.toBe(app.cdr);
|
||||
expect(dir !.cdr).not.toBe(dirSameInstance !.cdr);
|
||||
});
|
||||
|
||||
it('should inject host component ChangeDetectorRef into directives on containers', () => {
|
||||
function C1(rf1: RenderFlags, ctx1: any) {
|
||||
if (rf1 & RenderFlags.Create) {
|
||||
elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']);
|
||||
{ text(2); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf1 & RenderFlags.Update) {
|
||||
const tmp = reference(1) as any;
|
||||
textBinding(2, bind(tmp.value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MyApp {
|
||||
showing = true;
|
||||
class MyApp {
|
||||
showing = true;
|
||||
|
||||
constructor(public cdr: ChangeDetectorRef) {}
|
||||
constructor(public cdr: ChangeDetectorRef) {}
|
||||
|
||||
static ngComponentDef = defineComponent({
|
||||
type: MyApp,
|
||||
selectors: [['my-app']],
|
||||
factory: () => new MyApp(injectChangeDetectorRef()),
|
||||
consts: 1,
|
||||
vars: 0,
|
||||
/** <div *ngIf="showing" dir dirSameInstance #dir="dir"> {{ dir.value }} </div> */
|
||||
template: function(rf: RenderFlags, ctx: MyApp) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, C1, 3, 1, null, ['ngIf', 'showing']);
|
||||
}
|
||||
},
|
||||
directives: directives
|
||||
});
|
||||
}
|
||||
static ngComponentDef = defineComponent({
|
||||
type: MyApp,
|
||||
selectors: [['my-app']],
|
||||
factory: () => new MyApp(directiveInject(ChangeDetectorRef as any)),
|
||||
consts: 1,
|
||||
vars: 0,
|
||||
/** <div *ngIf="showing" dir dirSameInstance #dir="dir"> {{ dir.value }} </div> */
|
||||
template: function(rf: RenderFlags, ctx: MyApp) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, C1, 3, 1, null, ['ngIf', 'showing']);
|
||||
}
|
||||
},
|
||||
directives: directives
|
||||
});
|
||||
}
|
||||
|
||||
const app = renderComponent(MyApp);
|
||||
expect(toHtml(app)).toEqual('<div dir="" dirsame="">ViewRef</div>');
|
||||
expect((app !.cdr as ViewRef<MyApp>).context).toBe(app);
|
||||
const app = renderComponent(MyApp);
|
||||
expect(toHtml(app)).toEqual('<div dir="" dirsame="">ViewRef</div>');
|
||||
expect((app !.cdr as ViewRef<MyApp>).context).toBe(app);
|
||||
|
||||
// Each ChangeDetectorRef instance should be unique
|
||||
expect(dir !.cdr).not.toBe(app.cdr);
|
||||
expect(dir !.cdr).not.toBe(dirSameInstance !.cdr);
|
||||
// Each ChangeDetectorRef instance should be unique
|
||||
expect(dir !.cdr).not.toBe(app.cdr);
|
||||
expect(dir !.cdr).not.toBe(dirSameInstance !.cdr);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -10,8 +10,7 @@ import {ElementRef, TemplateRef, ViewContainerRef} from '@angular/core';
|
|||
import {RenderFlags} from '@angular/core/src/render3';
|
||||
|
||||
import {RendererStyleFlags2, RendererType2} from '../../src/render/api';
|
||||
import {createTemplateRef, getOrCreateNodeInjectorForNode} from '../../src/render3/di';
|
||||
import {AttributeMarker, defineComponent, defineDirective, injectElementRef, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index';
|
||||
import {AttributeMarker, defineComponent, defineDirective} from '../../src/render3/index';
|
||||
|
||||
import {NO_CHANGE, bind, container, containerRefreshEnd, containerRefreshStart, element, elementAttribute, elementClassProp, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, elementStyleProp, elementStyling, elementStylingApply, embeddedViewEnd, embeddedViewStart, interpolation1, interpolation2, interpolation3, interpolation4, interpolation5, interpolation6, interpolation7, interpolation8, interpolationV, listener, load, loadDirective, projection, projectionDef, text, textBinding, template} from '../../src/render3/instructions';
|
||||
import {InitialStylingFlags} from '../../src/render3/interfaces/definition';
|
||||
|
@ -21,9 +20,10 @@ import {sanitizeUrl} from '../../src/sanitization/sanitization';
|
|||
import {Sanitizer, SecurityContext} from '../../src/sanitization/security';
|
||||
|
||||
import {NgIf} from './common_with_def';
|
||||
import {ComponentFixture, TemplateFixture, containerEl, createComponent, renderToHtml} from './render_util';
|
||||
import {ComponentFixture, TemplateFixture, createComponent, renderToHtml} from './render_util';
|
||||
import {MONKEY_PATCH_KEY_NAME, getContext} from '../../src/render3/context_discovery';
|
||||
import {StylingIndex} from '../../src/render3/styling';
|
||||
import {directiveInject} from '../../src/render3/di';
|
||||
|
||||
describe('render3 integration test', () => {
|
||||
|
||||
|
@ -649,7 +649,9 @@ describe('render3 integration test', () => {
|
|||
static ngDirectiveDef = defineDirective({
|
||||
type: TestDirective,
|
||||
selectors: [['', 'testDirective', '']],
|
||||
factory: () => new TestDirective(injectTemplateRef(), injectViewContainerRef()),
|
||||
factory:
|
||||
() => new TestDirective(
|
||||
directiveInject(TemplateRef as any), directiveInject(ViewContainerRef as any)),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -754,7 +756,9 @@ describe('render3 integration test', () => {
|
|||
static ngDirectiveDef = defineDirective({
|
||||
type: TestDirective,
|
||||
selectors: [['', 'testDirective', '']],
|
||||
factory: () => new TestDirective(injectTemplateRef(), injectViewContainerRef()),
|
||||
factory:
|
||||
() => new TestDirective(
|
||||
directiveInject(TemplateRef as any), directiveInject(ViewContainerRef as any)),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -822,7 +826,7 @@ describe('render3 integration test', () => {
|
|||
static ngDirectiveDef = defineDirective({
|
||||
type: Directive,
|
||||
selectors: [['', 'dir', '']],
|
||||
factory: () => new Directive(injectElementRef()),
|
||||
factory: () => new Directive(directiveInject(ElementRef)),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import 'reflect-metadata';
|
|||
import {InjectorDef, defineInjectable} from '@angular/core/src/di/defs';
|
||||
import {Injectable} from '@angular/core/src/di/injectable';
|
||||
import {inject, setCurrentInjector} from '@angular/core/src/di/injector';
|
||||
import {ivyEnabled} from '@angular/core/src/ivy_switch';
|
||||
import {ivyEnabled} from '@angular/core/src/ivy_switch/compiler/index';
|
||||
import {Component, HostBinding, HostListener, Input, Output, Pipe} from '@angular/core/src/metadata/directives';
|
||||
import {NgModule, NgModuleDefInternal} from '@angular/core/src/metadata/ng_module';
|
||||
import {ComponentDefInternal, PipeDefInternal} from '@angular/core/src/render3/interfaces/definition';
|
||||
|
|
|
@ -10,11 +10,14 @@ import {NgForOfContext} from '@angular/common';
|
|||
import {ElementRef, TemplateRef, ViewContainerRef} from '@angular/core';
|
||||
|
||||
import {EventEmitter} from '../..';
|
||||
import {QUERY_READ_CONTAINER_REF, QUERY_READ_ELEMENT_REF, QUERY_READ_FROM_NODE, QUERY_READ_TEMPLATE_REF, templateRefExtractor} from '../../src/render3/di';
|
||||
import {AttributeMarker, QueryList, defineComponent, defineDirective, detectChanges, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index';
|
||||
import {directiveInject} from '../../src/render3/di';
|
||||
|
||||
import {AttributeMarker, QueryList, defineComponent, defineDirective, detectChanges} from '../../src/render3/index';
|
||||
|
||||
import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, load, loadDirective, loadElement, loadQueryList, reference, registerContentQuery, template} from '../../src/render3/instructions';
|
||||
import {RenderFlags} from '../../src/render3/interfaces/definition';
|
||||
import {query, queryRefresh} from '../../src/render3/query';
|
||||
import {query, queryRefresh, QUERY_READ_CONTAINER_REF, QUERY_READ_ELEMENT_REF, QUERY_READ_FROM_NODE, QUERY_READ_TEMPLATE_REF} from '../../src/render3/query';
|
||||
import {templateRefExtractor} from '../../src/render3/view_engine_compatibility';
|
||||
|
||||
import {NgForOf, NgIf, NgTemplateOutlet} from './common_with_def';
|
||||
import {ComponentFixture, TemplateFixture, createComponent, createDirective, renderComponent} from './render_util';
|
||||
|
@ -118,7 +121,7 @@ describe('query', () => {
|
|||
2, 0, [Child], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, Child, false, QUERY_READ_ELEMENT_REF);
|
||||
query(0, Child, false, QUERY_READ_ELEMENT_REF(ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -226,7 +229,7 @@ describe('query', () => {
|
|||
4, 0, [], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], false, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], false, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -263,8 +266,8 @@ describe('query', () => {
|
|||
6, 0, [], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], false, QUERY_READ_FROM_NODE);
|
||||
query(1, ['bar'], false, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], false, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
query(1, ['bar'], false, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -312,7 +315,7 @@ describe('query', () => {
|
|||
6, 0, [], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo', 'bar'], undefined, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo', 'bar'], undefined, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -349,7 +352,7 @@ describe('query', () => {
|
|||
4, 0, [], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], false, QUERY_READ_ELEMENT_REF);
|
||||
query(0, ['foo'], false, QUERY_READ_ELEMENT_REF(ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -385,7 +388,7 @@ describe('query', () => {
|
|||
3, 0, [], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], false, QUERY_READ_ELEMENT_REF);
|
||||
query(0, ['foo'], false, QUERY_READ_ELEMENT_REF(ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -421,7 +424,7 @@ describe('query', () => {
|
|||
3, 0, [], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -485,8 +488,8 @@ describe('query', () => {
|
|||
5, 0, [], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], true, QUERY_READ_ELEMENT_REF);
|
||||
query(1, ['foo'], false, QUERY_READ_ELEMENT_REF);
|
||||
query(0, ['foo'], true, QUERY_READ_ELEMENT_REF(ElementRef));
|
||||
query(1, ['foo'], false, QUERY_READ_ELEMENT_REF(ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -520,7 +523,7 @@ describe('query', () => {
|
|||
3, 0, [], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], false, QUERY_READ_CONTAINER_REF);
|
||||
query(0, ['foo'], false, QUERY_READ_CONTAINER_REF(ViewContainerRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -551,7 +554,7 @@ describe('query', () => {
|
|||
3, 0, [], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], false, QUERY_READ_CONTAINER_REF);
|
||||
query(0, ['foo'], false, QUERY_READ_CONTAINER_REF(ViewContainerRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -584,7 +587,7 @@ describe('query', () => {
|
|||
function(rf: RenderFlags, ctx: any) {
|
||||
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], false, QUERY_READ_ELEMENT_REF);
|
||||
query(0, ['foo'], false, QUERY_READ_ELEMENT_REF(ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -618,7 +621,7 @@ describe('query', () => {
|
|||
3, 0, [], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], undefined, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], undefined, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -650,7 +653,7 @@ describe('query', () => {
|
|||
3, 0, [], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], false, QUERY_READ_TEMPLATE_REF);
|
||||
query(0, ['foo'], false, QUERY_READ_TEMPLATE_REF(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -687,7 +690,7 @@ describe('query', () => {
|
|||
3, 0, [Child], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -732,7 +735,7 @@ describe('query', () => {
|
|||
3, 0, [Child], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -770,7 +773,7 @@ describe('query', () => {
|
|||
3, 0, [Child], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -810,7 +813,7 @@ describe('query', () => {
|
|||
4, 0, [Child1, Child2], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo', 'bar'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo', 'bar'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -849,8 +852,8 @@ describe('query', () => {
|
|||
5, 0, [Child], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
||||
query(1, ['bar'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
query(1, ['bar'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -893,7 +896,7 @@ describe('query', () => {
|
|||
3, 0, [Child], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], undefined, QUERY_READ_ELEMENT_REF);
|
||||
query(0, ['foo'], undefined, QUERY_READ_ELEMENT_REF(ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -931,7 +934,7 @@ describe('query', () => {
|
|||
4, 0, [Child], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo', 'bar'], undefined, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo', 'bar'], undefined, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -993,7 +996,7 @@ describe('query', () => {
|
|||
selectors: [['', 'vc', '']],
|
||||
factory: () => {
|
||||
const directiveInstance =
|
||||
new ViewContainerManipulatorDirective(injectViewContainerRef());
|
||||
new ViewContainerManipulatorDirective(directiveInject(ViewContainerRef as any));
|
||||
directiveInstances.push(directiveInstance);
|
||||
return directiveInstance;
|
||||
}
|
||||
|
@ -1039,7 +1042,7 @@ describe('query', () => {
|
|||
3, 1, [NgIf], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -1100,7 +1103,7 @@ describe('query', () => {
|
|||
viewQuery: function(rf: RenderFlags, ctx: Cmpt) {
|
||||
let tmp: any;
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
|
||||
|
@ -1170,10 +1173,12 @@ describe('query', () => {
|
|||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
1, Cmpt_Template_1, 2, 1, null, null, ['tpl1', ''], templateRefExtractor);
|
||||
1, Cmpt_Template_1, 2, 1, null, null, ['tpl1', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
element(3, 'div', ['id', 'middle'], ['foo', '']);
|
||||
template(
|
||||
5, Cmpt_Template_5, 2, 1, null, null, ['tpl2', ''], templateRefExtractor);
|
||||
5, Cmpt_Template_5, 2, 1, null, null, ['tpl2', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
template(7, null, 0, 0, null, [AttributeMarker.SelectOnly, 'vc']);
|
||||
}
|
||||
|
||||
|
@ -1186,7 +1191,7 @@ describe('query', () => {
|
|||
9, 0, [ViewContainerManipulatorDirective], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -1268,7 +1273,9 @@ describe('query', () => {
|
|||
template: function(rf: RenderFlags, ctx: any) {
|
||||
let tmp: any;
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(1, Cmpt_Template_1, 2, 1, null, [], ['tpl', ''], templateRefExtractor);
|
||||
template(
|
||||
1, Cmpt_Template_1, 2, 1, null, [], ['tpl', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
template(3, null, 0, 0, null, [AttributeMarker.SelectOnly, 'vc']);
|
||||
template(4, null, 0, 0, null, [AttributeMarker.SelectOnly, 'vc']);
|
||||
}
|
||||
|
@ -1281,7 +1288,7 @@ describe('query', () => {
|
|||
viewQuery: (rf: RenderFlags, cmpt: Cmpt) => {
|
||||
let tmp: any;
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
queryRefresh(tmp = load<QueryList<any>>(0)) &&
|
||||
|
@ -1341,7 +1348,7 @@ describe('query', () => {
|
|||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
1, MyApp_Template_1, 2, 0, undefined, undefined, ['tpl', ''],
|
||||
templateRefExtractor);
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
template(3, null, 0, 0, null, [AttributeMarker.SelectOnly, 'ngTemplateOutlet']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
|
@ -1353,7 +1360,7 @@ describe('query', () => {
|
|||
viewQuery: (rf: RenderFlags, myApp: MyApp) => {
|
||||
let tmp: any;
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
queryRefresh(tmp = load<QueryList<any>>(0)) &&
|
||||
|
@ -1418,7 +1425,7 @@ describe('query', () => {
|
|||
2, 0, [], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -1483,7 +1490,7 @@ describe('query', () => {
|
|||
6, 0, [], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -1560,7 +1567,7 @@ describe('query', () => {
|
|||
2, 0, [], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -1640,7 +1647,7 @@ describe('query', () => {
|
|||
2, 0, [], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -1709,8 +1716,8 @@ describe('query', () => {
|
|||
5, 0, [], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
||||
query(1, ['foo'], false, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
query(1, ['foo'], false, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -1790,7 +1797,7 @@ describe('query', () => {
|
|||
2, 0, [], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], false, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], false, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -1844,7 +1851,8 @@ describe('query', () => {
|
|||
static ngDirectiveDef = defineDirective({
|
||||
type: SomeDir,
|
||||
selectors: [['', 'someDir', '']],
|
||||
factory: () => new SomeDir(injectViewContainerRef(), injectTemplateRef())
|
||||
factory: () => new SomeDir(
|
||||
directiveInject(ViewContainerRef as any), directiveInject(TemplateRef as any))
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1870,7 +1878,7 @@ describe('query', () => {
|
|||
4, 0, [SomeDir], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -1907,8 +1915,10 @@ describe('query', () => {
|
|||
type: WithContentDirective,
|
||||
selectors: [['', 'with-content', '']],
|
||||
factory: () => new WithContentDirective(),
|
||||
contentQueries:
|
||||
() => { registerContentQuery(query(null, ['foo'], true, QUERY_READ_FROM_NODE)); },
|
||||
contentQueries: () => {
|
||||
registerContentQuery(
|
||||
query(null, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef)));
|
||||
},
|
||||
contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => {
|
||||
let tmp: any;
|
||||
withContentInstance = loadDirective<WithContentDirective>(dirIndex);
|
||||
|
@ -1929,8 +1939,10 @@ describe('query', () => {
|
|||
template: function(rf: RenderFlags, ctx: any) {},
|
||||
consts: 0,
|
||||
vars: 0,
|
||||
contentQueries:
|
||||
() => { registerContentQuery(query(null, ['foo'], false, QUERY_READ_FROM_NODE)); },
|
||||
contentQueries: () => {
|
||||
registerContentQuery(
|
||||
query(null, ['foo'], false, QUERY_READ_FROM_NODE(TemplateRef, ElementRef)));
|
||||
},
|
||||
contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => {
|
||||
let tmp: any;
|
||||
shallowCompInstance = loadDirective<ShallowComp>(dirIndex);
|
||||
|
@ -2046,7 +2058,7 @@ describe('query', () => {
|
|||
6, 0, [WithContentDirective], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['foo', 'bar'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['foo', 'bar'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -2086,7 +2098,7 @@ describe('query', () => {
|
|||
6, 0, [WithContentDirective], [],
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
query(0, ['bar'], true, QUERY_READ_FROM_NODE);
|
||||
query(0, ['bar'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef));
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
let tmp: any;
|
||||
|
@ -2110,7 +2122,8 @@ describe('query', () => {
|
|||
contentQueries: () => {
|
||||
// @ContentChildren('foo, bar, baz', {descendants: true}) fooBars:
|
||||
// QueryList<ElementRef>;
|
||||
registerContentQuery(query(null, ['foo', 'bar', 'baz'], true, QUERY_READ_FROM_NODE));
|
||||
registerContentQuery(query(
|
||||
null, ['foo', 'bar', 'baz'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef)));
|
||||
},
|
||||
contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => {
|
||||
let tmp: any;
|
||||
|
@ -2174,7 +2187,8 @@ describe('query', () => {
|
|||
contentQueries: () => {
|
||||
// @ContentChildren('foo, bar, baz', {descendants: true}) fooBars:
|
||||
// QueryList<ElementRef>;
|
||||
registerContentQuery(query(null, ['foo'], false, QUERY_READ_FROM_NODE));
|
||||
registerContentQuery(
|
||||
query(null, ['foo'], false, QUERY_READ_FROM_NODE(TemplateRef, ElementRef)));
|
||||
},
|
||||
contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => {
|
||||
let tmp: any;
|
||||
|
@ -2227,7 +2241,8 @@ describe('query', () => {
|
|||
factory: () => new ShallowQueryDirective(),
|
||||
contentQueries: () => {
|
||||
// @ContentChildren('foo', {descendants: false}) foos: QueryList<ElementRef>;
|
||||
registerContentQuery(query(null, ['foo'], false, QUERY_READ_FROM_NODE));
|
||||
registerContentQuery(
|
||||
query(null, ['foo'], false, QUERY_READ_FROM_NODE(TemplateRef, ElementRef)));
|
||||
},
|
||||
contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => {
|
||||
let tmp: any;
|
||||
|
@ -2247,7 +2262,8 @@ describe('query', () => {
|
|||
factory: () => new DeepQueryDirective(),
|
||||
contentQueries: () => {
|
||||
// @ContentChildren('foo', {descendants: false}) foos: QueryList<ElementRef>;
|
||||
registerContentQuery(query(null, ['foo'], true, QUERY_READ_FROM_NODE));
|
||||
registerContentQuery(
|
||||
query(null, ['foo'], true, QUERY_READ_FROM_NODE(TemplateRef, ElementRef)));
|
||||
},
|
||||
contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => {
|
||||
let tmp: any;
|
||||
|
|
|
@ -6,13 +6,19 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ChangeDetectorRef} from '@angular/core/src/change_detection/change_detector_ref';
|
||||
import {ElementRef} from '@angular/core/src/linker/element_ref';
|
||||
import {TemplateRef} from '@angular/core/src/linker/template_ref';
|
||||
import {ViewContainerRef} from '@angular/core/src/linker/view_container_ref';
|
||||
import {stringifyElement} from '@angular/platform-browser/testing/src/browser_util';
|
||||
|
||||
import {Injector} from '../../src/di/injector';
|
||||
import {R3_CHANGE_DETECTOR_REF_FACTORY, R3_ELEMENT_REF_FACTORY, R3_TEMPLATE_REF_FACTORY, R3_VIEW_CONTAINER_REF_FACTORY} from '../../src/ivy_switch/runtime/ivy_switch_on';
|
||||
import {PlayerHandler} from '../../src/render3/animations/interfaces';
|
||||
import {CreateComponentOptions} from '../../src/render3/component';
|
||||
import {getContext, isComponentInstance} from '../../src/render3/context_discovery';
|
||||
import {extractDirectiveDef, extractPipeDef} from '../../src/render3/definition';
|
||||
import {NG_ELEMENT_ID} from '../../src/render3/fields';
|
||||
import {ComponentTemplate, ComponentType, DirectiveDefInternal, DirectiveType, PublicFeature, RenderFlags, defineComponent, defineDirective, renderComponent as _renderComponent, tick} from '../../src/render3/index';
|
||||
import {renderTemplate} from '../../src/render3/instructions';
|
||||
import {DirectiveDefList, DirectiveTypesOrFactory, PipeDefInternal, PipeDefList, PipeTypesOrFactory} from '../../src/render3/interfaces/definition';
|
||||
|
@ -208,6 +214,10 @@ function toDefs(
|
|||
|
||||
beforeEach(resetDOM);
|
||||
|
||||
// This is necessary so we can switch between the Render2 version and the Ivy version
|
||||
// of special objects like ElementRef and TemplateRef.
|
||||
beforeEach(enableIvyInjectableFactories);
|
||||
|
||||
/**
|
||||
* @deprecated use `TemplateFixture` or `ComponentFixture`
|
||||
*/
|
||||
|
@ -285,3 +295,17 @@ export function createDirective(
|
|||
export const renderer: Renderer3 = null as any as Document;
|
||||
export const element: RElement = null as any as HTMLElement;
|
||||
export const text: RText = null as any as Text;
|
||||
|
||||
|
||||
/**
|
||||
* Switches between Render2 version of special objects like ElementRef and the Ivy version
|
||||
* of these objects. It's necessary to keep them separate so that we don't pull in fns
|
||||
* like injectElementRef() prematurely.
|
||||
*/
|
||||
export function enableIvyInjectableFactories() {
|
||||
(ElementRef as any)[NG_ELEMENT_ID] = () => R3_ELEMENT_REF_FACTORY(ElementRef);
|
||||
(TemplateRef as any)[NG_ELEMENT_ID] = () => R3_TEMPLATE_REF_FACTORY(TemplateRef, ElementRef);
|
||||
(ViewContainerRef as any)[NG_ELEMENT_ID] = () =>
|
||||
R3_VIEW_CONTAINER_REF_FACTORY(ViewContainerRef, ElementRef);
|
||||
(ChangeDetectorRef as any)[NG_ELEMENT_ID] = () => R3_CHANGE_DETECTOR_REF_FACTORY();
|
||||
}
|
||||
|
|
|
@ -8,11 +8,12 @@
|
|||
|
||||
import {Component, ComponentFactoryResolver, ElementRef, EmbeddedViewRef, NgModuleRef, Pipe, PipeTransform, RendererFactory2, TemplateRef, ViewContainerRef, createInjector, defineInjector, ɵAPP_ROOT as APP_ROOT, ɵNgModuleDef as NgModuleDef} from '../../src/core';
|
||||
import {ViewEncapsulation} from '../../src/metadata';
|
||||
import {templateRefExtractor} from '../../src/render3/di';
|
||||
import {AttributeMarker, NgOnChangesFeature, defineComponent, defineDirective, definePipe, injectComponentFactoryResolver, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index';
|
||||
import {directiveInject} from '../../src/render3/di';
|
||||
import {AttributeMarker, NgOnChangesFeature, defineComponent, defineDirective, definePipe, injectComponentFactoryResolver} from '../../src/render3/index';
|
||||
|
||||
import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, interpolation1, interpolation3, loadDirective, nextContext, projection, projectionDef, reference, template, text, textBinding} from '../../src/render3/instructions';
|
||||
import {RenderFlags} from '../../src/render3/interfaces/definition';
|
||||
import {templateRefExtractor} from '../../src/render3/view_engine_compatibility';
|
||||
import {NgModuleFactory} from '../../src/render3/ng_module_ref';
|
||||
import {pipe, pipeBind1} from '../../src/render3/pipe';
|
||||
import {NgForOf} from '../../test/render3/common_with_def';
|
||||
|
@ -23,7 +24,7 @@ import {ComponentFixture, TemplateFixture, createComponent} from './render_util'
|
|||
describe('ViewContainerRef', () => {
|
||||
let directiveInstance: DirectiveWithVCRef|null;
|
||||
|
||||
beforeEach(() => { directiveInstance = null; });
|
||||
beforeEach(() => directiveInstance = null);
|
||||
|
||||
class DirectiveWithVCRef {
|
||||
static ngDirectiveDef = defineDirective({
|
||||
|
@ -31,7 +32,7 @@ describe('ViewContainerRef', () => {
|
|||
selectors: [['', 'vcref', '']],
|
||||
factory: () => directiveInstance = new DirectiveWithVCRef(
|
||||
|
||||
injectViewContainerRef(), injectComponentFactoryResolver()),
|
||||
directiveInject(ViewContainerRef as any), injectComponentFactoryResolver()),
|
||||
inputs: {tplRef: 'tplRef'}
|
||||
});
|
||||
|
||||
|
@ -66,7 +67,9 @@ describe('ViewContainerRef', () => {
|
|||
* <p vcref [tplRef]="tplRef"></p>
|
||||
*/
|
||||
function createTemplate() {
|
||||
template(0, embeddedTemplate, 1, 1, null, null, ['tplRef', ''], templateRefExtractor);
|
||||
template(
|
||||
0, embeddedTemplate, 1, 1, null, null, ['tplRef', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
element(2, 'p', ['vcref', '']);
|
||||
}
|
||||
|
||||
|
@ -83,7 +86,9 @@ describe('ViewContainerRef', () => {
|
|||
* <footer></footer>
|
||||
*/
|
||||
function createTemplate() {
|
||||
template(0, embeddedTemplate, 1, 1, null, null, ['tplRef', ''], templateRefExtractor);
|
||||
template(
|
||||
0, embeddedTemplate, 1, 1, null, null, ['tplRef', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
element(2, 'header', ['vcref', '']);
|
||||
element(3, 'footer');
|
||||
}
|
||||
|
@ -119,7 +124,9 @@ describe('ViewContainerRef', () => {
|
|||
* <footer></footer>
|
||||
*/
|
||||
function createTemplate() {
|
||||
template(0, embeddedTemplate, 1, 1, null, [], ['tplRef', ''], templateRefExtractor);
|
||||
template(
|
||||
0, embeddedTemplate, 1, 1, null, [], ['tplRef', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
element(2, 'header-cmp', ['vcref', '']);
|
||||
element(3, 'footer');
|
||||
}
|
||||
|
@ -155,7 +162,9 @@ describe('ViewContainerRef', () => {
|
|||
* <div vcref [tplRef]="tplRef"></div>
|
||||
*/
|
||||
function createTemplate() {
|
||||
template(0, embeddedTemplate, 1, 1, null, null, ['tplRef', ''], templateRefExtractor);
|
||||
template(
|
||||
0, embeddedTemplate, 1, 1, null, null, ['tplRef', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
element(2, 'div', ['vcref', '']);
|
||||
element(3, 'div', ['vcref', '']);
|
||||
|
||||
|
@ -186,7 +195,8 @@ describe('ViewContainerRef', () => {
|
|||
*/
|
||||
function createTemplate() {
|
||||
template(
|
||||
0, embeddedTemplate, 1, 1, null, ['vcref', ''], ['tplRef', ''], templateRefExtractor);
|
||||
0, embeddedTemplate, 1, 1, null, ['vcref', ''], ['tplRef', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
element(2, 'footer');
|
||||
}
|
||||
|
||||
|
@ -225,7 +235,8 @@ describe('ViewContainerRef', () => {
|
|||
type: TestDirective,
|
||||
selectors: [['', 'testdir', '']],
|
||||
factory: () => {
|
||||
const instance = new TestDirective(injectViewContainerRef(), injectTemplateRef());
|
||||
const instance = new TestDirective(
|
||||
directiveInject(ViewContainerRef as any), directiveInject(TemplateRef as any));
|
||||
|
||||
directiveInstances.push(instance);
|
||||
|
||||
|
@ -299,8 +310,9 @@ describe('ViewContainerRef', () => {
|
|||
static ngDirectiveDef = defineDirective({
|
||||
type: TestDirective,
|
||||
selectors: [['', 'testdir', '']],
|
||||
factory: () => directiveInstance =
|
||||
new TestDirective(injectViewContainerRef(), injectTemplateRef())
|
||||
factory: () => directiveInstance = new TestDirective(
|
||||
directiveInject(ViewContainerRef as any),
|
||||
directiveInject(TemplateRef as any))
|
||||
});
|
||||
|
||||
constructor(private _vcRef: ViewContainerRef, private _tplRef: TemplateRef<{}>) {}
|
||||
|
@ -455,7 +467,8 @@ describe('ViewContainerRef', () => {
|
|||
template: (rf: RenderFlags, cmp: SomeComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
0, SomeComponent_Template_0, 2, 3, null, [], ['foo', ''], templateRefExtractor);
|
||||
0, SomeComponent_Template_0, 2, 3, null, [], ['foo', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
pipe(2, 'starPipe');
|
||||
element(3, 'child', ['vcref', '']);
|
||||
pipe(4, 'starPipe');
|
||||
|
@ -495,7 +508,7 @@ describe('ViewContainerRef', () => {
|
|||
static ngDirectiveDef = defineDirective({
|
||||
type: InsertionDir,
|
||||
selectors: [['', 'tplDir', '']],
|
||||
factory: () => new InsertionDir(injectViewContainerRef()),
|
||||
factory: () => new InsertionDir(directiveInject(ViewContainerRef as any)),
|
||||
inputs: {tplDir: 'tplDir'}
|
||||
});
|
||||
}
|
||||
|
@ -546,7 +559,9 @@ describe('ViewContainerRef', () => {
|
|||
*/
|
||||
const Parent = createComponent('parent', function(rf: RenderFlags, parent: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, fooTemplate, 2, 1, null, null, ['foo', ''], templateRefExtractor);
|
||||
template(
|
||||
0, fooTemplate, 2, 1, null, null, ['foo', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
element(2, 'child');
|
||||
}
|
||||
|
||||
|
@ -637,7 +652,9 @@ describe('ViewContainerRef', () => {
|
|||
*/
|
||||
const Parent = createComponent('parent', function(rf: RenderFlags, parent: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, rowTemplate, 3, 2, null, null, ['rowTemplate', ''], templateRefExtractor);
|
||||
template(
|
||||
0, rowTemplate, 3, 2, null, null, ['rowTemplate', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
element(2, 'loop-comp');
|
||||
}
|
||||
|
||||
|
@ -651,7 +668,9 @@ describe('ViewContainerRef', () => {
|
|||
|
||||
function rowTemplate(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, cellTemplate, 2, 3, null, null, ['cellTemplate', ''], templateRefExtractor);
|
||||
template(
|
||||
0, cellTemplate, 2, 3, null, null, ['cellTemplate', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
element(2, 'loop-comp');
|
||||
}
|
||||
|
||||
|
@ -1196,7 +1215,9 @@ describe('ViewContainerRef', () => {
|
|||
vars: 2,
|
||||
template: (rf: RenderFlags, cmp: Parent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, embeddedTemplate, 2, 1, null, null, ['foo', ''], templateRefExtractor);
|
||||
template(
|
||||
0, embeddedTemplate, 2, 1, null, null, ['foo', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
elementStart(2, 'child');
|
||||
{
|
||||
elementStart(3, 'header', ['vcref', '']);
|
||||
|
@ -1291,7 +1312,8 @@ describe('ViewContainerRef', () => {
|
|||
template: (rf: RenderFlags, cmp: Parent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
0, embeddedTemplate, 2, 1, null, undefined, ['foo', ''], templateRefExtractor);
|
||||
0, embeddedTemplate, 2, 1, null, undefined, ['foo', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
elementStart(2, 'child-with-view');
|
||||
text(3, 'Before projected');
|
||||
elementStart(4, 'header', ['vcref', '']);
|
||||
|
@ -1375,7 +1397,8 @@ describe('ViewContainerRef', () => {
|
|||
let tplRef: any;
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
0, embeddedTemplate, 2, 1, null, null, ['foo', ''], templateRefExtractor);
|
||||
0, embeddedTemplate, 2, 1, null, null, ['foo', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
elementStart(2, 'child-with-selector');
|
||||
elementStart(3, 'header', ['vcref', '']);
|
||||
text(4, 'blah');
|
||||
|
@ -1428,7 +1451,8 @@ describe('ViewContainerRef', () => {
|
|||
let tplRef: any;
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
0, embeddedTemplate, 2, 1, null, null, ['foo', ''], templateRefExtractor);
|
||||
0, embeddedTemplate, 2, 1, null, null, ['foo', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
elementStart(2, 'child-with-selector');
|
||||
elementStart(3, 'footer', ['vcref', '']);
|
||||
text(4, 'blah');
|
||||
|
@ -1533,7 +1557,8 @@ describe('ViewContainerRef', () => {
|
|||
template: (rf: RenderFlags, cmp: SomeComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
0, SomeComponent_Template_0, 1, 1, null, [], ['foo', ''], templateRefExtractor);
|
||||
0, SomeComponent_Template_0, 1, 1, null, [], ['foo', ''],
|
||||
templateRefExtractor(TemplateRef, ElementRef));
|
||||
element(2, 'hooks', ['vcref', '']);
|
||||
element(3, 'hooks');
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue