build: fix circular dep between interface and l_node by merging (#20855)
PR Close #20855
This commit is contained in:
parent
66528a21f6
commit
5a7bf36723
|
@ -7,7 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {ɵC as C, ɵE as E, ɵT as T, ɵV as V, ɵb as b, ɵc as c, ɵcR as cR, ɵcr as cr, ɵdefineComponent as defineComponent, ɵdetectChanges as detectChanges, ɵe as e, ɵs as s, ɵt as t, ɵv as v} from '@angular/core';
|
import {ɵC as C, ɵE as E, ɵT as T, ɵV as V, ɵb as b, ɵc as c, ɵcR as cR, ɵcr as cr, ɵdefineComponent as defineComponent, ɵdetectChanges as detectChanges, ɵe as e, ɵs as s, ɵt as t, ɵv as v} from '@angular/core';
|
||||||
import {ComponentDef} from '@angular/core/src/render3/public_interfaces';
|
import {ComponentDef} from '@angular/core/src/render3/definition_interfaces';
|
||||||
|
|
||||||
import {TableCell, buildTable, emptyTable} from '../util';
|
import {TableCell, buildTable, emptyTable} from '../util';
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {ɵC as C, ɵD as D, ɵE as E, ɵT as T, ɵV as V, ɵb as b, ɵb1 as b1, ɵc as c, ɵcR as cR, ɵcr as cr, ɵdefineComponent as defineComponent, ɵdetectChanges as _detectChanges, ɵe as e, ɵp as p, ɵs as s, ɵt as t, ɵv as v} from '@angular/core';
|
import {ɵC as C, ɵD as D, ɵE as E, ɵT as T, ɵV as V, ɵb as b, ɵb1 as b1, ɵc as c, ɵcR as cR, ɵcr as cr, ɵdefineComponent as defineComponent, ɵdetectChanges as _detectChanges, ɵe as e, ɵp as p, ɵs as s, ɵt as t, ɵv as v} from '@angular/core';
|
||||||
import {ComponentDef} from '@angular/core/src/render3/public_interfaces';
|
import {ComponentDef} from '@angular/core/src/render3/definition_interfaces';
|
||||||
|
|
||||||
import {TreeNode, buildTree, emptyTree} from '../util';
|
import {TreeNode, buildTree, emptyTree} from '../util';
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,14 @@
|
||||||
|
|
||||||
// We are temporarily importing the existing viewEngine from core so we can be sure we are
|
// We are temporarily importing the existing viewEngine from core so we can be sure we are
|
||||||
// correctly implementing its interfaces for backwards compatibility.
|
// correctly implementing its interfaces for backwards compatibility.
|
||||||
import * as viewEngine from '../core';
|
import {Injector} from '../di/injector';
|
||||||
|
import {ComponentRef as viewEngine_ComponentRef} from '../linker/component_factory';
|
||||||
|
import {EmbeddedViewRef as viewEngine_EmbeddedViewRef} from '../linker/view_ref';
|
||||||
|
|
||||||
import {assertNotNull} from './assert';
|
import {assertNotNull} from './assert';
|
||||||
|
import {ComponentDef, ComponentType} from './definition_interfaces';
|
||||||
import {NG_HOST_SYMBOL, createError, createViewState, directive, enterView, hostElement, leaveView, locateHostElement, renderComponentOrTemplate} from './instructions';
|
import {NG_HOST_SYMBOL, createError, createViewState, directive, enterView, hostElement, leaveView, locateHostElement, renderComponentOrTemplate} from './instructions';
|
||||||
import {LElement} from './l_node';
|
import {LElement} from './interfaces';
|
||||||
import {ComponentDef, ComponentType} from './public_interfaces';
|
|
||||||
import {RElement, Renderer3, RendererFactory3, domRendererFactory3} from './renderer';
|
import {RElement, Renderer3, RendererFactory3, domRendererFactory3} from './renderer';
|
||||||
import {notImplemented, stringify} from './util';
|
import {notImplemented, stringify} from './util';
|
||||||
|
|
||||||
|
@ -32,7 +34,7 @@ export interface CreateComponentOptions {
|
||||||
host?: RElement|string;
|
host?: RElement|string;
|
||||||
|
|
||||||
/** Module injector for the component. If unspecified, the injector will be NULL_INJECTOR. */
|
/** Module injector for the component. If unspecified, the injector will be NULL_INJECTOR. */
|
||||||
injector?: viewEngine.Injector;
|
injector?: Injector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of features to be applied to the created component. Features are simply
|
* List of features to be applied to the created component. Features are simply
|
||||||
|
@ -51,7 +53,7 @@ export interface CreateComponentOptions {
|
||||||
* @param options Optional parameters which control bootstrapping
|
* @param options Optional parameters which control bootstrapping
|
||||||
*/
|
*/
|
||||||
export function createComponentRef<T>(
|
export function createComponentRef<T>(
|
||||||
componentType: ComponentType<T>, opts: CreateComponentOptions): viewEngine.ComponentRef<T> {
|
componentType: ComponentType<T>, opts: CreateComponentOptions): viewEngine_ComponentRef<T> {
|
||||||
const component = renderComponent(componentType, opts);
|
const component = renderComponent(componentType, opts);
|
||||||
const hostView = createViewRef(() => detectChanges(component), component);
|
const hostView = createViewRef(() => detectChanges(component), component);
|
||||||
return {
|
return {
|
||||||
|
@ -78,7 +80,7 @@ function createViewRef<T>(detectChanges: () => void, context: T): EmbeddedViewRe
|
||||||
return addDestroyable(new EmbeddedViewRef(detectChanges), context);
|
return addDestroyable(new EmbeddedViewRef(detectChanges), context);
|
||||||
}
|
}
|
||||||
|
|
||||||
class EmbeddedViewRef<T> implements viewEngine.EmbeddedViewRef<T> {
|
class EmbeddedViewRef<T> implements viewEngine_EmbeddedViewRef<T> {
|
||||||
// TODO: rootNodes should be replaced when properly implemented
|
// TODO: rootNodes should be replaced when properly implemented
|
||||||
rootNodes = null !;
|
rootNodes = null !;
|
||||||
context: T;
|
context: T;
|
||||||
|
@ -147,7 +149,7 @@ function addDestroyable<T, C>(obj: any, context: C): T&DestroyRef<C> {
|
||||||
|
|
||||||
|
|
||||||
// TODO: A hack to not pull in the NullInjector from @angular/core.
|
// TODO: A hack to not pull in the NullInjector from @angular/core.
|
||||||
export const NULL_INJECTOR: viewEngine.Injector = {
|
export const NULL_INJECTOR: Injector = {
|
||||||
get: (token: any, notFoundValue?: any) => {
|
get: (token: any, notFoundValue?: any) => {
|
||||||
throw new Error('NullInjector: Not found: ' + stringify(token));
|
throw new Error('NullInjector: Not found: ' + stringify(token));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
/**
|
||||||
|
* @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 {RendererType2} from '../render/api';
|
||||||
|
import {Type} from '../type';
|
||||||
|
import {resolveRendererType2} from '../view/util';
|
||||||
|
|
||||||
|
import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs} from './definition_interfaces';
|
||||||
|
import {componentRefresh, diPublic} from './instructions';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a component definition object.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* # Example
|
||||||
|
* ```
|
||||||
|
* class MyDirective {
|
||||||
|
* // Generated by Angular Template Compiler
|
||||||
|
* // [Symbol] syntax will not be supported by TypeScript until v2.7
|
||||||
|
* static [COMPONENT_DEF_SYMBOL] = defineComponent({
|
||||||
|
* ...
|
||||||
|
* });
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export function defineComponent<T>(componentDefinition: ComponentDefArgs<T>): ComponentDef<T> {
|
||||||
|
const def = <ComponentDef<any>>{
|
||||||
|
type: componentDefinition.type,
|
||||||
|
diPublic: null,
|
||||||
|
n: componentDefinition.factory,
|
||||||
|
tag: (componentDefinition as ComponentDefArgs<T>).tag || null !,
|
||||||
|
template: (componentDefinition as ComponentDefArgs<T>).template || null !,
|
||||||
|
r: componentDefinition.refresh ||
|
||||||
|
function(d: number, e: number) { componentRefresh(d, e, componentDefinition.template); },
|
||||||
|
inputs: invertObject(componentDefinition.inputs),
|
||||||
|
outputs: invertObject(componentDefinition.outputs),
|
||||||
|
methods: invertObject(componentDefinition.methods),
|
||||||
|
rendererType: resolveRendererType2(componentDefinition.rendererType) || null,
|
||||||
|
};
|
||||||
|
const feature = componentDefinition.features;
|
||||||
|
feature && feature.forEach((fn) => fn(def));
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function NgOnChangesFeature<T>(definition: DirectiveDef<T>) {
|
||||||
|
// TODO: implement. See: https://app.asana.com/0/443577627818617/465170715764659
|
||||||
|
}
|
||||||
|
|
||||||
|
export function PublicFeature<T>(definition: DirectiveDef<T>) {
|
||||||
|
definition.diPublic = diPublic;
|
||||||
|
}
|
||||||
|
|
||||||
|
const EMPTY = {};
|
||||||
|
|
||||||
|
/** Swaps the keys and values of an object. */
|
||||||
|
function invertObject(obj: any): any {
|
||||||
|
if (obj == null) return EMPTY;
|
||||||
|
const newObj: any = {};
|
||||||
|
for (let minifiedKey in obj) {
|
||||||
|
newObj[obj[minifiedKey]] = minifiedKey;
|
||||||
|
}
|
||||||
|
return newObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a directive definition object.
|
||||||
|
*
|
||||||
|
* # Example
|
||||||
|
* ```
|
||||||
|
* class MyDirective {
|
||||||
|
* // Generated by Angular Template Compiler
|
||||||
|
* // [Symbol] syntax will not be supported by TypeScript until v2.7
|
||||||
|
* static [DIRECTIVE_DEF_SYMBOL] = defineDirective({
|
||||||
|
* ...
|
||||||
|
* });
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export const defineDirective = defineComponent as<T>(directiveDefinition: DirectiveDefArgs<T>) =>
|
||||||
|
DirectiveDef<T>;
|
|
@ -6,9 +6,9 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {RendererType2, Type} from '../core';
|
import {RendererType2} from '../render/api';
|
||||||
|
import {Type} from '../type';
|
||||||
import {resolveRendererType2} from '../view/util';
|
import {resolveRendererType2} from '../view/util';
|
||||||
import {componentRefresh, diPublic} from './instructions';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ export interface DirectiveDef<T> {
|
||||||
* @param directiveIndex index of the directive in the containing template
|
* @param directiveIndex index of the directive in the containing template
|
||||||
* @param elementIndex index of an host element for a given directive.
|
* @param elementIndex index of an host element for a given directive.
|
||||||
*/
|
*/
|
||||||
r(this: DirectiveDef<T>, directiveIndex: number, elementIndex: number): void;
|
r(directiveIndex: number, elementIndex: number): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ComponentDef<T> extends DirectiveDef<T> {
|
export interface ComponentDef<T> extends DirectiveDef<T> {
|
||||||
|
@ -93,7 +93,7 @@ export interface ComponentDef<T> extends DirectiveDef<T> {
|
||||||
* @param directiveIndex index of the directive in the containing template
|
* @param directiveIndex index of the directive in the containing template
|
||||||
* @param elementIndex index of an host element for a given component.
|
* @param elementIndex index of an host element for a given component.
|
||||||
*/
|
*/
|
||||||
r(this: ComponentDef<T>, directiveIndex: number, elementIndex: number): void;
|
r(directiveIndex: number, elementIndex: number): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The tag name which should be used by the component.
|
* The tag name which should be used by the component.
|
||||||
|
@ -120,7 +120,7 @@ export interface ComponentDef<T> extends DirectiveDef<T> {
|
||||||
export interface DirectiveDefArgs<T> {
|
export interface DirectiveDefArgs<T> {
|
||||||
type: Type<T>;
|
type: Type<T>;
|
||||||
factory: () => T;
|
factory: () => T;
|
||||||
refresh?: (this: DirectiveDef<T>, directiveIndex: number, elementIndex: number) => void;
|
refresh?: (directiveIndex: number, elementIndex: number) => void;
|
||||||
inputs?: {[P in keyof T]?: string};
|
inputs?: {[P in keyof T]?: string};
|
||||||
outputs?: {[P in keyof T]?: string};
|
outputs?: {[P in keyof T]?: string};
|
||||||
methods?: {[P in keyof T]?: string};
|
methods?: {[P in keyof T]?: string};
|
||||||
|
@ -130,80 +130,10 @@ export interface DirectiveDefArgs<T> {
|
||||||
export interface ComponentDefArgs<T> extends DirectiveDefArgs<T> {
|
export interface ComponentDefArgs<T> extends DirectiveDefArgs<T> {
|
||||||
tag: string;
|
tag: string;
|
||||||
template: ComponentTemplate<T>;
|
template: ComponentTemplate<T>;
|
||||||
refresh?: (this: ComponentDef<T>, directiveIndex: number, elementIndex: number) => void;
|
refresh?: (directiveIndex: number, elementIndex: number) => void;
|
||||||
features?: ComponentDefFeature[];
|
features?: ComponentDefFeature[];
|
||||||
rendererType?: RendererType2;
|
rendererType?: RendererType2;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DirectiveDefFeature = <T>(directiveDef: DirectiveDef<T>) => void;
|
export type DirectiveDefFeature = <T>(directiveDef: DirectiveDef<T>) => void;
|
||||||
export type ComponentDefFeature = <T>(directiveDef: DirectiveDef<T>) => void;
|
export type ComponentDefFeature = <T>(directiveDef: DirectiveDef<T>) => void;
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a component definition object.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* # Example
|
|
||||||
* ```
|
|
||||||
* class MyDirective {
|
|
||||||
* // Generated by Angular Template Compiler
|
|
||||||
* // [Symbol] syntax will not be supported by TypeScript until v2.7
|
|
||||||
* static [COMPONENT_DEF_SYMBOL] = defineComponent({
|
|
||||||
* ...
|
|
||||||
* });
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export function defineComponent<T>(componentDefinition: ComponentDefArgs<T>): ComponentDef<T> {
|
|
||||||
const def = <ComponentDef<any>>{
|
|
||||||
type: componentDefinition.type,
|
|
||||||
diPublic: null,
|
|
||||||
n: componentDefinition.factory,
|
|
||||||
tag: (componentDefinition as ComponentDefArgs<T>).tag || null !,
|
|
||||||
template: (componentDefinition as ComponentDefArgs<T>).template || null !,
|
|
||||||
r: componentDefinition.refresh || componentRefresh,
|
|
||||||
inputs: invertObject(componentDefinition.inputs),
|
|
||||||
outputs: invertObject(componentDefinition.outputs),
|
|
||||||
methods: invertObject(componentDefinition.methods),
|
|
||||||
rendererType: resolveRendererType2(componentDefinition.rendererType) || null,
|
|
||||||
};
|
|
||||||
const feature = componentDefinition.features;
|
|
||||||
feature && feature.forEach((fn) => fn(def));
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function NgOnChangesFeature<T>(definition: DirectiveDef<T>) {
|
|
||||||
// TODO: implement. See: https://app.asana.com/0/443577627818617/465170715764659
|
|
||||||
}
|
|
||||||
|
|
||||||
export function PublicFeature<T>(definition: DirectiveDef<T>) {
|
|
||||||
definition.diPublic = diPublic;
|
|
||||||
}
|
|
||||||
|
|
||||||
const EMPTY = {};
|
|
||||||
|
|
||||||
/** Swaps the keys and values of an object. */
|
|
||||||
function invertObject(obj: any): any {
|
|
||||||
if (obj == null) return EMPTY;
|
|
||||||
const newObj: any = {};
|
|
||||||
for (let minifiedKey in obj) {
|
|
||||||
newObj[obj[minifiedKey]] = minifiedKey;
|
|
||||||
}
|
|
||||||
return newObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a directive definition object.
|
|
||||||
*
|
|
||||||
* # Example
|
|
||||||
* ```
|
|
||||||
* class MyDirective {
|
|
||||||
* // Generated by Angular Template Compiler
|
|
||||||
* // [Symbol] syntax will not be supported by TypeScript until v2.7
|
|
||||||
* static [DIRECTIVE_DEF_SYMBOL] = defineDirective({
|
|
||||||
* ...
|
|
||||||
* });
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export const defineDirective = defineComponent as<T>(directiveDefinition: DirectiveDefArgs<T>) =>
|
|
||||||
DirectiveDef<T>;
|
|
|
@ -6,13 +6,20 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// We are temporarily importing the existing viewEngine from core so we can be sure we are
|
// We are temporarily importing the existing viewEngine_from core so we can be sure we are
|
||||||
// correctly implementing its interfaces for backwards compatibility.
|
// correctly implementing its interfaces for backwards compatibility.
|
||||||
import * as viewEngine from '../core';
|
import {Injector} 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 {Type} from '../type';
|
||||||
|
|
||||||
import {LContainer, LElement, LNodeFlags, LNodeInjector} from './l_node';
|
import {ComponentTemplate, DirectiveDef} from './definition_interfaces';
|
||||||
|
import {LContainer, LElement, LNodeFlags, LNodeInjector} from './interfaces';
|
||||||
import {assertNodeType} from './node_assert';
|
import {assertNodeType} from './node_assert';
|
||||||
import {ComponentTemplate, DirectiveDef} from './public_interfaces';
|
|
||||||
import {notImplemented, stringify} from './util';
|
import {notImplemented, stringify} from './util';
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,7 +48,7 @@ let nextNgElementId = 0;
|
||||||
* @param injector The node injector in which the directive should be registered
|
* @param injector The node injector in which the directive should be registered
|
||||||
* @param type The directive to register
|
* @param type The directive to register
|
||||||
*/
|
*/
|
||||||
export function bloomAdd(injector: LNodeInjector, type: viewEngine.Type<any>): void {
|
export function bloomAdd(injector: LNodeInjector, type: Type<any>): void {
|
||||||
let id: number|undefined = (type as any)[NG_ELEMENT_ID];
|
let id: number|undefined = (type as any)[NG_ELEMENT_ID];
|
||||||
|
|
||||||
// Set a unique ID on the directive type, so if something tries to inject the directive,
|
// Set a unique ID on the directive type, so if something tries to inject the directive,
|
||||||
|
@ -161,7 +168,7 @@ export function diPublicInInjector(di: LNodeInjector, def: DirectiveDef<any>): v
|
||||||
* @returns The instance found
|
* @returns The instance found
|
||||||
*/
|
*/
|
||||||
export function getOrCreateInjectable<T>(
|
export function getOrCreateInjectable<T>(
|
||||||
di: LNodeInjector, token: viewEngine.Type<T>, flags?: InjectFlags): T {
|
di: LNodeInjector, token: Type<T>, flags?: InjectFlags): T {
|
||||||
const bloomHash = bloomHashBit(token);
|
const bloomHash = bloomHashBit(token);
|
||||||
|
|
||||||
// If the token has a bloom hash, then it is a directive that is public to the injection system
|
// If the token has a bloom hash, then it is a directive that is public to the injection system
|
||||||
|
@ -234,7 +241,7 @@ export function getOrCreateInjectable<T>(
|
||||||
* @param type The directive type
|
* @param type The directive type
|
||||||
* @returns The bloom bit to check for the directive
|
* @returns The bloom bit to check for the directive
|
||||||
*/
|
*/
|
||||||
function bloomHashBit(type: viewEngine.Type<any>): number|null {
|
function bloomHashBit(type: Type<any>): number|null {
|
||||||
let id: number|undefined = (type as any)[NG_ELEMENT_ID];
|
let id: number|undefined = (type as any)[NG_ELEMENT_ID];
|
||||||
return typeof id === 'number' ? id % BLOOM_SIZE : null;
|
return typeof id === 'number' ? id % BLOOM_SIZE : null;
|
||||||
}
|
}
|
||||||
|
@ -300,12 +307,12 @@ export function bloomFindPossibleInjector(
|
||||||
* @param di The node injector where we should store a created ElementRef
|
* @param di The node injector where we should store a created ElementRef
|
||||||
* @returns The ElementRef instance to use
|
* @returns The ElementRef instance to use
|
||||||
*/
|
*/
|
||||||
export function getOrCreateElementRef(di: LNodeInjector): viewEngine.ElementRef {
|
export function getOrCreateElementRef(di: LNodeInjector): viewEngine_ElementRef {
|
||||||
return di.elementRef || (di.elementRef = new ElementRef(di.node.native));
|
return di.elementRef || (di.elementRef = new ElementRef(di.node.native));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A ref to a node's native element. */
|
/** A ref to a node's native element. */
|
||||||
class ElementRef implements viewEngine.ElementRef {
|
class ElementRef implements viewEngine_ElementRef {
|
||||||
readonly nativeElement: any;
|
readonly nativeElement: any;
|
||||||
constructor(nativeElement: any) { this.nativeElement = nativeElement; }
|
constructor(nativeElement: any) { this.nativeElement = nativeElement; }
|
||||||
}
|
}
|
||||||
|
@ -317,7 +324,7 @@ class ElementRef implements viewEngine.ElementRef {
|
||||||
* @param di The node injector where we should store a created TemplateRef
|
* @param di The node injector where we should store a created TemplateRef
|
||||||
* @returns The TemplateRef instance to use
|
* @returns The TemplateRef instance to use
|
||||||
*/
|
*/
|
||||||
export function getOrCreateTemplateRef<T>(di: LNodeInjector): viewEngine.TemplateRef<T> {
|
export function getOrCreateTemplateRef<T>(di: LNodeInjector): viewEngine_TemplateRef<T> {
|
||||||
ngDevMode && assertNodeType(di.node, LNodeFlags.Container);
|
ngDevMode && assertNodeType(di.node, LNodeFlags.Container);
|
||||||
const data = (di.node as LContainer).data;
|
const data = (di.node as LContainer).data;
|
||||||
return di.templateRef ||
|
return di.templateRef ||
|
||||||
|
@ -325,14 +332,14 @@ export function getOrCreateTemplateRef<T>(di: LNodeInjector): viewEngine.Templat
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A ref to a particular template. */
|
/** A ref to a particular template. */
|
||||||
class TemplateRef<T> implements viewEngine.TemplateRef<T> {
|
class TemplateRef<T> implements viewEngine_TemplateRef<T> {
|
||||||
readonly elementRef: viewEngine.ElementRef;
|
readonly elementRef: viewEngine_ElementRef;
|
||||||
|
|
||||||
constructor(elementRef: viewEngine.ElementRef, template: ComponentTemplate<T>|null) {
|
constructor(elementRef: viewEngine_ElementRef, template: ComponentTemplate<T>|null) {
|
||||||
this.elementRef = elementRef;
|
this.elementRef = elementRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
createEmbeddedView(context: T): viewEngine.EmbeddedViewRef<T> { throw notImplemented(); }
|
createEmbeddedView(context: T): viewEngine_EmbeddedViewRef<T> { throw notImplemented(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -341,7 +348,7 @@ class TemplateRef<T> implements viewEngine.TemplateRef<T> {
|
||||||
*
|
*
|
||||||
* @returns The ViewContainerRef instance to use
|
* @returns The ViewContainerRef instance to use
|
||||||
*/
|
*/
|
||||||
export function getOrCreateContainerRef(di: LNodeInjector): viewEngine.ViewContainerRef {
|
export function getOrCreateContainerRef(di: LNodeInjector): viewEngine_ViewContainerRef {
|
||||||
return di.viewContainerRef || (di.viewContainerRef = new ViewContainerRef(di.node as LContainer));
|
return di.viewContainerRef || (di.viewContainerRef = new ViewContainerRef(di.node as LContainer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,34 +356,34 @@ export function getOrCreateContainerRef(di: LNodeInjector): viewEngine.ViewConta
|
||||||
* A ref to a container that enables adding and removing views from that container
|
* A ref to a container that enables adding and removing views from that container
|
||||||
* imperatively.
|
* imperatively.
|
||||||
*/
|
*/
|
||||||
class ViewContainerRef implements viewEngine.ViewContainerRef {
|
class ViewContainerRef implements viewEngine_ViewContainerRef {
|
||||||
element: viewEngine.ElementRef;
|
element: viewEngine_ElementRef;
|
||||||
injector: viewEngine.Injector;
|
injector: Injector;
|
||||||
parentInjector: viewEngine.Injector;
|
parentInjector: Injector;
|
||||||
|
|
||||||
constructor(node: LContainer) {}
|
constructor(node: LContainer) {}
|
||||||
|
|
||||||
clear(): void { throw notImplemented(); }
|
clear(): void { throw notImplemented(); }
|
||||||
get(index: number): viewEngine.ViewRef|null { throw notImplemented(); }
|
get(index: number): viewEngine_ViewRef|null { throw notImplemented(); }
|
||||||
length: number;
|
length: number;
|
||||||
createEmbeddedView<C>(
|
createEmbeddedView<C>(
|
||||||
templateRef: viewEngine.TemplateRef<C>, context?: C|undefined,
|
templateRef: viewEngine_TemplateRef<C>, context?: C|undefined,
|
||||||
index?: number|undefined): viewEngine.EmbeddedViewRef<C> {
|
index?: number|undefined): viewEngine_EmbeddedViewRef<C> {
|
||||||
throw notImplemented();
|
throw notImplemented();
|
||||||
}
|
}
|
||||||
createComponent<C>(
|
createComponent<C>(
|
||||||
componentFactory: viewEngine.ComponentFactory<C>, index?: number|undefined,
|
componentFactory: viewEngine_ComponentFactory<C>, index?: number|undefined,
|
||||||
injector?: viewEngine.Injector|undefined, projectableNodes?: any[][]|undefined,
|
injector?: Injector|undefined, projectableNodes?: any[][]|undefined,
|
||||||
ngModule?: viewEngine.NgModuleRef<any>|undefined): viewEngine.ComponentRef<C> {
|
ngModule?: viewEngine_NgModuleRef<any>|undefined): viewEngine_ComponentRef<C> {
|
||||||
throw notImplemented();
|
throw notImplemented();
|
||||||
}
|
}
|
||||||
insert(viewRef: viewEngine.ViewRef, index?: number|undefined): viewEngine.ViewRef {
|
insert(viewRef: viewEngine_ViewRef, index?: number|undefined): viewEngine_ViewRef {
|
||||||
throw notImplemented();
|
throw notImplemented();
|
||||||
}
|
}
|
||||||
move(viewRef: viewEngine.ViewRef, currentIndex: number): viewEngine.ViewRef {
|
move(viewRef: viewEngine_ViewRef, currentIndex: number): viewEngine_ViewRef {
|
||||||
throw notImplemented();
|
throw notImplemented();
|
||||||
}
|
}
|
||||||
indexOf(viewRef: viewEngine.ViewRef): number { throw notImplemented(); }
|
indexOf(viewRef: viewEngine_ViewRef): number { throw notImplemented(); }
|
||||||
remove(index?: number|undefined): void { throw notImplemented(); }
|
remove(index?: number|undefined): void { throw notImplemented(); }
|
||||||
detach(index?: number|undefined): viewEngine.ViewRef|null { throw notImplemented(); }
|
detach(index?: number|undefined): viewEngine_ViewRef|null { throw notImplemented(); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {createComponentRef, detectChanges, getHostElement, markDirty, renderComponent} from './component';
|
import {createComponentRef, detectChanges, getHostElement, markDirty, renderComponent} from './component';
|
||||||
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, NgOnChangesFeature, PublicFeature, defineComponent, defineDirective} from './public_interfaces';
|
import {NgOnChangesFeature, PublicFeature, defineComponent, defineDirective} from './definition';
|
||||||
|
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags} from './definition_interfaces';
|
||||||
|
|
||||||
|
|
||||||
// Naming scheme:
|
// Naming scheme:
|
||||||
// - Capital letters are for creating things: T(Text), E(Element), D(Directive), V(View),
|
// - Capital letters are for creating things: T(Text), E(Element), D(Directive), V(View),
|
||||||
|
|
|
@ -8,17 +8,19 @@
|
||||||
|
|
||||||
import './ng_dev_mode';
|
import './ng_dev_mode';
|
||||||
|
|
||||||
import {ElementRef, TemplateRef, Type, ViewContainerRef} from '../core';
|
import {ElementRef} from '../linker/element_ref';
|
||||||
|
import {TemplateRef} from '../linker/template_ref';
|
||||||
|
import {ViewContainerRef} from '../linker/view_container_ref';
|
||||||
|
import {Type} from '../type';
|
||||||
|
|
||||||
import {assertEqual, assertLessThan, assertNotEqual, assertNotNull} from './assert';
|
import {assertEqual, assertLessThan, assertNotEqual, assertNotNull} from './assert';
|
||||||
import {ContainerState, CssSelector, ProjectionState, QueryReadType, QueryState, ViewState} from './interfaces';
|
import {ContainerState, CssSelector, LContainer, LElement, LNode, LNodeFlags, LNodeInjector, LProjection, LText, LView, ProjectionState, QueryReadType, QueryState, ViewState} from './interfaces';
|
||||||
import {LContainer, LElement, LNode, LNodeFlags, LNodeInjector, LProjection, LText, LView} from './l_node';
|
|
||||||
|
|
||||||
import {NgStaticData, LNodeStatic, LContainerStatic, InitialInputData, InitialInputs, PropertyAliases, PropertyAliasValue,} from './l_node_static';
|
import {NgStaticData, LNodeStatic, LContainerStatic, InitialInputData, InitialInputs, PropertyAliases, PropertyAliasValue,} from './l_node_static';
|
||||||
import {assertNodeType} from './node_assert';
|
import {assertNodeType} from './node_assert';
|
||||||
import {appendChild, insertChild, insertView, processProjectedNode, removeView} from './node_manipulation';
|
import {appendChild, insertChild, insertView, processProjectedNode, removeView} from './node_manipulation';
|
||||||
import {isNodeMatchingSelector} from './node_selector_matcher';
|
import {isNodeMatchingSelector} from './node_selector_matcher';
|
||||||
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef} from './public_interfaces';
|
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef} from './definition_interfaces';
|
||||||
import {InjectFlags, diPublicInInjector, getOrCreateNodeInjectorForNode, getOrCreateElementRef, getOrCreateTemplateRef, getOrCreateContainerRef, getOrCreateInjectable} from './di';
|
import {InjectFlags, diPublicInInjector, getOrCreateNodeInjectorForNode, getOrCreateElementRef, getOrCreateTemplateRef, getOrCreateContainerRef, getOrCreateInjectable} from './di';
|
||||||
import {QueryList, QueryState_} from './query';
|
import {QueryList, QueryState_} from './query';
|
||||||
import {RComment, RElement, RText, Renderer3, RendererFactory3, ProceduralRenderer3, ObjectOrientedRenderer3, RendererStyleFlags3} from './renderer';
|
import {RComment, RElement, RText, Renderer3, RendererFactory3, ProceduralRenderer3, ObjectOrientedRenderer3, RendererStyleFlags3} from './renderer';
|
||||||
|
@ -82,7 +84,9 @@ let ngStaticData: NgStaticData;
|
||||||
/**
|
/**
|
||||||
* State of the current view being processed.
|
* State of the current view being processed.
|
||||||
*/
|
*/
|
||||||
let currentView: ViewState = createViewState(null !, null !, []);
|
let currentView: ViewState;
|
||||||
|
// The initialization has to be after the `let`, otherwise `createViewState` can't see `let`.
|
||||||
|
currentView = createViewState(null !, null !, []);
|
||||||
|
|
||||||
let currentQuery: QueryState|null;
|
let currentQuery: QueryState|null;
|
||||||
|
|
||||||
|
@ -1138,8 +1142,7 @@ export function viewEnd(): void {
|
||||||
export const componentRefresh:
|
export const componentRefresh:
|
||||||
<T>(directiveIndex: number, elementIndex: number, template: ComponentTemplate<T>) =>
|
<T>(directiveIndex: number, elementIndex: number, template: ComponentTemplate<T>) =>
|
||||||
void = function<T>(
|
void = function<T>(
|
||||||
this: undefined | {template: ComponentTemplate<T>}, directiveIndex: number,
|
directiveIndex: number, elementIndex: number, template: ComponentTemplate<T>) {
|
||||||
elementIndex: number, template: ComponentTemplate<T>) {
|
|
||||||
ngDevMode && assertDataInRange(elementIndex);
|
ngDevMode && assertDataInRange(elementIndex);
|
||||||
const element = data ![elementIndex] as LElement;
|
const element = data ![elementIndex] as LElement;
|
||||||
ngDevMode && assertNodeType(element, LNodeFlags.Element);
|
ngDevMode && assertNodeType(element, LNodeFlags.Element);
|
||||||
|
@ -1150,7 +1153,7 @@ export const componentRefresh:
|
||||||
const directive = data[directiveIndex];
|
const directive = data[directiveIndex];
|
||||||
const oldView = enterView(hostView, element);
|
const oldView = enterView(hostView, element);
|
||||||
try {
|
try {
|
||||||
(template || this !.template)(directive, creationMode);
|
template(directive, creationMode);
|
||||||
} finally {
|
} finally {
|
||||||
leaveView(oldView);
|
leaveView(oldView);
|
||||||
}
|
}
|
||||||
|
@ -1284,18 +1287,11 @@ export function addToViewTree<T extends ViewState|ContainerState>(state: T): T {
|
||||||
//// Bindings
|
//// Bindings
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
|
|
||||||
/**
|
export interface NO_CHANGE {
|
||||||
* The type of the NO_CHANGE constant, which can never be structurally matched
|
|
||||||
* because of its private member.
|
|
||||||
*/
|
|
||||||
export declare class NO_CHANGE_TYPE {
|
|
||||||
// This is a brand that ensures that this type can never match anything else
|
// This is a brand that ensures that this type can never match anything else
|
||||||
private _;
|
brand: 'NO_CHANGE';
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is an alias for NO_CHANGE_TYPE for brevity throughout the codebase.
|
|
||||||
export type NO_CHANGE = typeof NO_CHANGE_TYPE;
|
|
||||||
|
|
||||||
/** A special value which designates that a value has not changed. */
|
/** A special value which designates that a value has not changed. */
|
||||||
export const NO_CHANGE = {} as NO_CHANGE;
|
export const NO_CHANGE = {} as NO_CHANGE;
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,274 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {QueryList, Type} from '../core';
|
import {Injector} from '../di/injector';
|
||||||
|
import {ElementRef} from '../linker/element_ref';
|
||||||
|
import {QueryList} from '../linker/query_list';
|
||||||
|
import {TemplateRef} from '../linker/template_ref';
|
||||||
|
import {ViewContainerRef} from '../linker/view_container_ref';
|
||||||
|
import {Type} from '../type';
|
||||||
|
|
||||||
import {LContainer, LElement, LNode, LText, LView} from './l_node';
|
import {ComponentTemplate, DirectiveDef} from './definition_interfaces';
|
||||||
import {LNodeStatic} from './l_node_static';
|
import {LNodeStatic} from './l_node_static';
|
||||||
import {ComponentTemplate, DirectiveDef} from './public_interfaces';
|
import {RComment, RElement, RText, Renderer3} from './renderer';
|
||||||
import {Renderer3} from './renderer';
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LNodeFlags corresponds to the LNode.flags property. It contains information
|
||||||
|
* on how to map a particular set of bits in LNode.flags to the node type, directive
|
||||||
|
* count, or directive starting index.
|
||||||
|
*
|
||||||
|
* For example, if you wanted to check the type of a certain node, you would mask
|
||||||
|
* node.flags with TYPE_MASK and compare it to the value for a certain node type. e.g:
|
||||||
|
*
|
||||||
|
*```ts
|
||||||
|
* if ((node.flags & LNodeFlags.TYPE_MASK) === LNodeFlags.Element) {...}
|
||||||
|
*```
|
||||||
|
*/
|
||||||
|
export const enum LNodeFlags {
|
||||||
|
Container = 0b00,
|
||||||
|
Projection = 0b01,
|
||||||
|
View = 0b10,
|
||||||
|
Element = 0b11,
|
||||||
|
ViewOrElement = 0b10,
|
||||||
|
SIZE_SKIP = 0b100,
|
||||||
|
SIZE_SHIFT = 2,
|
||||||
|
INDX_SHIFT = 12,
|
||||||
|
TYPE_MASK = 0b00000000000000000000000000000011,
|
||||||
|
SIZE_MASK = 0b00000000000000000000111111111100,
|
||||||
|
INDX_MASK = 0b11111111111111111111000000000000
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LNode is an internal data structure which is used for the incremental DOM algorithm.
|
||||||
|
* The "L" stands for "Logical" to differentiate between `RNodes` (actual rendered DOM
|
||||||
|
* node) and our logical representation of DOM nodes, `LNodes`.
|
||||||
|
*
|
||||||
|
* The data structure is optimized for speed and size.
|
||||||
|
*
|
||||||
|
* In order to be fast, all subtypes of `LNode` should have the same shape.
|
||||||
|
* Because size of the `LNode` matters, many fields have multiple roles depending
|
||||||
|
* on the `LNode` subtype.
|
||||||
|
*
|
||||||
|
* See: https://en.wikipedia.org/wiki/Inline_caching#Monomorphic_inline_caching
|
||||||
|
*
|
||||||
|
* NOTE: This is a private data structure and should not be exported by any of the
|
||||||
|
* instructions.
|
||||||
|
*/
|
||||||
|
export interface LNode {
|
||||||
|
/**
|
||||||
|
* This number stores three values using its bits:
|
||||||
|
*
|
||||||
|
* - the type of the node (first 2 bits)
|
||||||
|
* - the number of directives on that node (next 10 bits)
|
||||||
|
* - the starting index of the node's directives in the directives array (last 20 bits).
|
||||||
|
*
|
||||||
|
* The latter two values are necessary so DI can effectively search the directives associated
|
||||||
|
* with a node without searching the whole directives array.
|
||||||
|
*/
|
||||||
|
flags: LNodeFlags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The associated DOM node. Storing this allows us to:
|
||||||
|
* - append children to their element parents in the DOM (e.g. `parent.native.appendChild(...)`)
|
||||||
|
* - retrieve the sibling elements of text nodes whose creation / insertion has been delayed
|
||||||
|
* - mark locations where child views should be inserted (for containers)
|
||||||
|
*/
|
||||||
|
readonly native: RElement|RText|RComment|null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We need a reference to a node's parent so we can append the node to its parent's native
|
||||||
|
* element at the appropriate time.
|
||||||
|
*/
|
||||||
|
readonly parent: LNode|null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* First child of the current node.
|
||||||
|
*/
|
||||||
|
child: LNode|null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The next sibling node. Necessary so we can propagate through the root nodes of a view
|
||||||
|
* to insert them or remove them from the DOM.
|
||||||
|
*/
|
||||||
|
next: LNode|null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If regular LElement, then `data` will be null.
|
||||||
|
* If LElement with component, then `data` contains ViewState.
|
||||||
|
* If LView, then `data` contains the ViewState.
|
||||||
|
* If LContainer, then `data` contains ContainerState.
|
||||||
|
* If LProjection, then `data` contains ProjectionState.
|
||||||
|
*/
|
||||||
|
readonly data: ViewState|ContainerState|ProjectionState|null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Each node belongs to a view.
|
||||||
|
*
|
||||||
|
* When the injector is walking up a tree, it needs access to the `directives` (part of view).
|
||||||
|
*/
|
||||||
|
readonly view: ViewState;
|
||||||
|
|
||||||
|
/** The injector associated with this node. Necessary for DI. */
|
||||||
|
nodeInjector: LNodeInjector|null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional `QueryState` used for tracking queries.
|
||||||
|
*
|
||||||
|
* If present the node creation/updates are reported to the `QueryState`.
|
||||||
|
*/
|
||||||
|
query: QueryState|null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pointer to the corresponding LNodeStatic object, which stores static
|
||||||
|
* data about this node.
|
||||||
|
*/
|
||||||
|
staticData: LNodeStatic|null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** LNode representing an element. */
|
||||||
|
export interface LElement extends LNode {
|
||||||
|
/** The DOM element associated with this node. */
|
||||||
|
readonly native: RElement;
|
||||||
|
|
||||||
|
child: LContainer|LElement|LText|LProjection|null;
|
||||||
|
next: LContainer|LElement|LText|LProjection|null;
|
||||||
|
|
||||||
|
/** If Component than data has ViewState (light DOM) */
|
||||||
|
readonly data: ViewState|null;
|
||||||
|
|
||||||
|
/** LElement nodes can be inside other LElement nodes or inside LViews. */
|
||||||
|
readonly parent: LElement|LView;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** LNode representing a #text node. */
|
||||||
|
export interface LText extends LNode {
|
||||||
|
/** The text node associated with this node. */
|
||||||
|
native: RText;
|
||||||
|
child: null;
|
||||||
|
next: LContainer|LElement|LText|LProjection|null;
|
||||||
|
|
||||||
|
/** LText nodes can be inside LElement nodes or inside LViews. */
|
||||||
|
readonly parent: LElement|LView;
|
||||||
|
readonly data: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract node which contains root nodes of a view.
|
||||||
|
*/
|
||||||
|
export interface LView extends LNode {
|
||||||
|
readonly native: null;
|
||||||
|
child: LContainer|LElement|LText|LProjection|null;
|
||||||
|
next: LView|null;
|
||||||
|
|
||||||
|
/** LView nodes can only be added to LContainers. */
|
||||||
|
readonly parent: LContainer|null;
|
||||||
|
readonly data: ViewState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract node container which contains other views.
|
||||||
|
*/
|
||||||
|
export interface LContainer extends LNode {
|
||||||
|
/**
|
||||||
|
* This comment node is appended to the container's parent element to mark where
|
||||||
|
* in the DOM the container's child views should be added.
|
||||||
|
*
|
||||||
|
* If the container is a root node of a view, this comment will not be appended
|
||||||
|
* until the parent view is processed.
|
||||||
|
*/
|
||||||
|
readonly native: RComment;
|
||||||
|
readonly data: ContainerState;
|
||||||
|
child: null;
|
||||||
|
next: LContainer|LElement|LText|LProjection|null;
|
||||||
|
|
||||||
|
/** Containers can be added to elements or views. */
|
||||||
|
readonly parent: LElement|LView|null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface LProjection extends LNode {
|
||||||
|
readonly native: null;
|
||||||
|
child: null;
|
||||||
|
next: LContainer|LElement|LText|LProjection|null;
|
||||||
|
|
||||||
|
readonly data: ProjectionState;
|
||||||
|
|
||||||
|
/** Projections can be added to elements or views. */
|
||||||
|
readonly parent: LElement|LView;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NOTES:
|
||||||
|
*
|
||||||
|
* Each Array costs 70 bytes and is composed of `Array` and `(array)` object
|
||||||
|
* - `Array` javascript visible object: 32 bytes
|
||||||
|
* - `(array)` VM object where the array is actually stored in: 38 bytes
|
||||||
|
*
|
||||||
|
* Each Object cost is 24 bytes plus 8 bytes per property.
|
||||||
|
*
|
||||||
|
* For small arrays, it is more efficient to store the data as a linked list
|
||||||
|
* of items rather than small arrays. However, the array access is faster as
|
||||||
|
* shown here: https://jsperf.com/small-arrays-vs-linked-objects
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface LNodeInjector {
|
||||||
|
/**
|
||||||
|
* We need to store a reference to the injector's parent so DI can keep looking up
|
||||||
|
* the injector tree until it finds the dependency it's looking for.
|
||||||
|
*/
|
||||||
|
readonly parent: LNodeInjector|null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows access to the directives array in that node's static data and to
|
||||||
|
* the node's flags (for starting directive index and directive size). Necessary
|
||||||
|
* for DI to retrieve a directive from the data array if injector indicates
|
||||||
|
* it is there.
|
||||||
|
*/
|
||||||
|
readonly node: LElement|LContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The following bloom filter determines whether a directive is available
|
||||||
|
* on the associated node or not. This prevents us from searching the directives
|
||||||
|
* array at this level unless it's probable the directive is in it.
|
||||||
|
*
|
||||||
|
* - bf0: Check directive IDs 0-31 (IDs are % 128)
|
||||||
|
* - bf1: Check directive IDs 33-63
|
||||||
|
* - bf2: Check directive IDs 64-95
|
||||||
|
* - bf3: Check directive IDs 96-127
|
||||||
|
*
|
||||||
|
* See: https://en.wikipedia.org/wiki/Bloom_filter for more about bloom filters.
|
||||||
|
*/
|
||||||
|
bf0: number;
|
||||||
|
bf1: number;
|
||||||
|
bf2: number;
|
||||||
|
bf3: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cbf0 - cbf3 properties determine whether a directive is available through a
|
||||||
|
* parent injector. They refer to the merged values of parent bloom filters. This
|
||||||
|
* allows us to skip looking up the chain unless it's probable that directive exists
|
||||||
|
* up the chain.
|
||||||
|
*/
|
||||||
|
cbf0: number;
|
||||||
|
cbf1: number;
|
||||||
|
cbf2: number;
|
||||||
|
cbf3: number;
|
||||||
|
injector: Injector|null;
|
||||||
|
|
||||||
|
/** Stores the TemplateRef so subsequent injections of the TemplateRef get the same instance. */
|
||||||
|
templateRef: TemplateRef<any>|null;
|
||||||
|
|
||||||
|
/** Stores the ViewContainerRef so subsequent injections of the ViewContainerRef get the same
|
||||||
|
* instance. */
|
||||||
|
viewContainerRef: ViewContainerRef|null;
|
||||||
|
|
||||||
|
/** Stores the ElementRef so subsequent injections of the ElementRef get the same instance. */
|
||||||
|
elementRef: ElementRef|null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `ViewState` stores all of the information needed to process the instructions as
|
* `ViewState` stores all of the information needed to process the instructions as
|
||||||
|
|
|
@ -1,270 +0,0 @@
|
||||||
/**
|
|
||||||
* @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 {ElementRef, Injector, TemplateRef, ViewContainerRef} from '../core';
|
|
||||||
|
|
||||||
import {ContainerState, ProjectionState, QueryState, ViewState} from './interfaces';
|
|
||||||
import {LNodeStatic} from './l_node_static';
|
|
||||||
import {RComment, RElement, RText} from './renderer';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* LNodeFlags corresponds to the LNode.flags property. It contains information
|
|
||||||
* on how to map a particular set of bits in LNode.flags to the node type, directive
|
|
||||||
* count, or directive starting index.
|
|
||||||
*
|
|
||||||
* For example, if you wanted to check the type of a certain node, you would mask
|
|
||||||
* node.flags with TYPE_MASK and compare it to the value for a certain node type. e.g:
|
|
||||||
*
|
|
||||||
*```ts
|
|
||||||
* if ((node.flags & LNodeFlags.TYPE_MASK) === LNodeFlags.Element) {...}
|
|
||||||
*```
|
|
||||||
*/
|
|
||||||
export const enum LNodeFlags {
|
|
||||||
Container = 0b00,
|
|
||||||
Projection = 0b01,
|
|
||||||
View = 0b10,
|
|
||||||
Element = 0b11,
|
|
||||||
ViewOrElement = 0b10,
|
|
||||||
SIZE_SKIP = 0b100,
|
|
||||||
SIZE_SHIFT = 2,
|
|
||||||
INDX_SHIFT = 12,
|
|
||||||
TYPE_MASK = 0b00000000000000000000000000000011,
|
|
||||||
SIZE_MASK = 0b00000000000000000000111111111100,
|
|
||||||
INDX_MASK = 0b11111111111111111111000000000000
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* LNode is an internal data structure which is used for the incremental DOM algorithm.
|
|
||||||
* The "L" stands for "Logical" to differentiate between `RNodes` (actual rendered DOM
|
|
||||||
* node) and our logical representation of DOM nodes, `LNodes`.
|
|
||||||
*
|
|
||||||
* The data structure is optimized for speed and size.
|
|
||||||
*
|
|
||||||
* In order to be fast, all subtypes of `LNode` should have the same shape.
|
|
||||||
* Because size of the `LNode` matters, many fields have multiple roles depending
|
|
||||||
* on the `LNode` subtype.
|
|
||||||
*
|
|
||||||
* See: https://en.wikipedia.org/wiki/Inline_caching#Monomorphic_inline_caching
|
|
||||||
*
|
|
||||||
* NOTE: This is a private data structure and should not be exported by any of the
|
|
||||||
* instructions.
|
|
||||||
*/
|
|
||||||
export interface LNode {
|
|
||||||
/**
|
|
||||||
* This number stores three values using its bits:
|
|
||||||
*
|
|
||||||
* - the type of the node (first 2 bits)
|
|
||||||
* - the number of directives on that node (next 10 bits)
|
|
||||||
* - the starting index of the node's directives in the directives array (last 20 bits).
|
|
||||||
*
|
|
||||||
* The latter two values are necessary so DI can effectively search the directives associated
|
|
||||||
* with a node without searching the whole directives array.
|
|
||||||
*/
|
|
||||||
flags: LNodeFlags;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The associated DOM node. Storing this allows us to:
|
|
||||||
* - append children to their element parents in the DOM (e.g. `parent.native.appendChild(...)`)
|
|
||||||
* - retrieve the sibling elements of text nodes whose creation / insertion has been delayed
|
|
||||||
* - mark locations where child views should be inserted (for containers)
|
|
||||||
*/
|
|
||||||
readonly native: RElement|RText|RComment|null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We need a reference to a node's parent so we can append the node to its parent's native
|
|
||||||
* element at the appropriate time.
|
|
||||||
*/
|
|
||||||
readonly parent: LNode|null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* First child of the current node.
|
|
||||||
*/
|
|
||||||
child: LNode|null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The next sibling node. Necessary so we can propagate through the root nodes of a view
|
|
||||||
* to insert them or remove them from the DOM.
|
|
||||||
*/
|
|
||||||
next: LNode|null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If regular LElement, then `data` will be null.
|
|
||||||
* If LElement with component, then `data` contains ViewState.
|
|
||||||
* If LView, then `data` contains the ViewState.
|
|
||||||
* If LContainer, then `data` contains ContainerState.
|
|
||||||
* If LProjection, then `data` contains ProjectionState.
|
|
||||||
*/
|
|
||||||
readonly data: ViewState|ContainerState|ProjectionState|null;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Each node belongs to a view.
|
|
||||||
*
|
|
||||||
* When the injector is walking up a tree, it needs access to the `directives` (part of view).
|
|
||||||
*/
|
|
||||||
readonly view: ViewState;
|
|
||||||
|
|
||||||
/** The injector associated with this node. Necessary for DI. */
|
|
||||||
nodeInjector: LNodeInjector|null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optional `QueryState` used for tracking queries.
|
|
||||||
*
|
|
||||||
* If present the node creation/updates are reported to the `QueryState`.
|
|
||||||
*/
|
|
||||||
query: QueryState|null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pointer to the corresponding LNodeStatic object, which stores static
|
|
||||||
* data about this node.
|
|
||||||
*/
|
|
||||||
staticData: LNodeStatic|null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** LNode representing an element. */
|
|
||||||
export interface LElement extends LNode {
|
|
||||||
/** The DOM element associated with this node. */
|
|
||||||
readonly native: RElement;
|
|
||||||
|
|
||||||
child: LContainer|LElement|LText|LProjection|null;
|
|
||||||
next: LContainer|LElement|LText|LProjection|null;
|
|
||||||
|
|
||||||
/** If Component than data has ViewState (light DOM) */
|
|
||||||
readonly data: ViewState|null;
|
|
||||||
|
|
||||||
/** LElement nodes can be inside other LElement nodes or inside LViews. */
|
|
||||||
readonly parent: LElement|LView;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** LNode representing a #text node. */
|
|
||||||
export interface LText extends LNode {
|
|
||||||
/** The text node associated with this node. */
|
|
||||||
native: RText;
|
|
||||||
child: null;
|
|
||||||
next: LContainer|LElement|LText|LProjection|null;
|
|
||||||
|
|
||||||
/** LText nodes can be inside LElement nodes or inside LViews. */
|
|
||||||
readonly parent: LElement|LView;
|
|
||||||
readonly data: null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract node which contains root nodes of a view.
|
|
||||||
*/
|
|
||||||
export interface LView extends LNode {
|
|
||||||
readonly native: null;
|
|
||||||
child: LContainer|LElement|LText|LProjection|null;
|
|
||||||
next: LView|null;
|
|
||||||
|
|
||||||
/** LView nodes can only be added to LContainers. */
|
|
||||||
readonly parent: LContainer|null;
|
|
||||||
readonly data: ViewState;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract node container which contains other views.
|
|
||||||
*/
|
|
||||||
export interface LContainer extends LNode {
|
|
||||||
/**
|
|
||||||
* This comment node is appended to the container's parent element to mark where
|
|
||||||
* in the DOM the container's child views should be added.
|
|
||||||
*
|
|
||||||
* If the container is a root node of a view, this comment will not be appended
|
|
||||||
* until the parent view is processed.
|
|
||||||
*/
|
|
||||||
readonly native: RComment;
|
|
||||||
readonly data: ContainerState;
|
|
||||||
child: null;
|
|
||||||
next: LContainer|LElement|LText|LProjection|null;
|
|
||||||
|
|
||||||
/** Containers can be added to elements or views. */
|
|
||||||
readonly parent: LElement|LView|null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export interface LProjection extends LNode {
|
|
||||||
readonly native: null;
|
|
||||||
child: null;
|
|
||||||
next: LContainer|LElement|LText|LProjection|null;
|
|
||||||
|
|
||||||
readonly data: ProjectionState;
|
|
||||||
|
|
||||||
/** Projections can be added to elements or views. */
|
|
||||||
readonly parent: LElement|LView;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NOTES:
|
|
||||||
*
|
|
||||||
* Each Array costs 70 bytes and is composed of `Array` and `(array)` object
|
|
||||||
* - `Array` javascript visible object: 32 bytes
|
|
||||||
* - `(array)` VM object where the array is actually stored in: 38 bytes
|
|
||||||
*
|
|
||||||
* Each Object cost is 24 bytes plus 8 bytes per property.
|
|
||||||
*
|
|
||||||
* For small arrays, it is more efficient to store the data as a linked list
|
|
||||||
* of items rather than small arrays. However, the array access is faster as
|
|
||||||
* shown here: https://jsperf.com/small-arrays-vs-linked-objects
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface LNodeInjector {
|
|
||||||
/**
|
|
||||||
* We need to store a reference to the injector's parent so DI can keep looking up
|
|
||||||
* the injector tree until it finds the dependency it's looking for.
|
|
||||||
*/
|
|
||||||
readonly parent: LNodeInjector|null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows access to the directives array in that node's static data and to
|
|
||||||
* the node's flags (for starting directive index and directive size). Necessary
|
|
||||||
* for DI to retrieve a directive from the data array if injector indicates
|
|
||||||
* it is there.
|
|
||||||
*/
|
|
||||||
readonly node: LElement|LContainer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The following bloom filter determines whether a directive is available
|
|
||||||
* on the associated node or not. This prevents us from searching the directives
|
|
||||||
* array at this level unless it's probable the directive is in it.
|
|
||||||
*
|
|
||||||
* - bf0: Check directive IDs 0-31 (IDs are % 128)
|
|
||||||
* - bf1: Check directive IDs 33-63
|
|
||||||
* - bf2: Check directive IDs 64-95
|
|
||||||
* - bf3: Check directive IDs 96-127
|
|
||||||
*
|
|
||||||
* See: https://en.wikipedia.org/wiki/Bloom_filter for more about bloom filters.
|
|
||||||
*/
|
|
||||||
bf0: number;
|
|
||||||
bf1: number;
|
|
||||||
bf2: number;
|
|
||||||
bf3: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cbf0 - cbf3 properties determine whether a directive is available through a
|
|
||||||
* parent injector. They refer to the merged values of parent bloom filters. This
|
|
||||||
* allows us to skip looking up the chain unless it's probable that directive exists
|
|
||||||
* up the chain.
|
|
||||||
*/
|
|
||||||
cbf0: number;
|
|
||||||
cbf1: number;
|
|
||||||
cbf2: number;
|
|
||||||
cbf3: number;
|
|
||||||
injector: Injector|null;
|
|
||||||
|
|
||||||
/** Stores the TemplateRef so subsequent injections of the TemplateRef get the same instance. */
|
|
||||||
templateRef: TemplateRef<any>|null;
|
|
||||||
|
|
||||||
/** Stores the ViewContainerRef so subsequent injections of the ViewContainerRef get the same
|
|
||||||
* instance. */
|
|
||||||
viewContainerRef: ViewContainerRef|null;
|
|
||||||
|
|
||||||
/** Stores the ElementRef so subsequent injections of the ElementRef get the same instance. */
|
|
||||||
elementRef: ElementRef|null;
|
|
||||||
}
|
|
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {DirectiveDef} from './public_interfaces';
|
import {DirectiveDef} from './definition_interfaces';
|
||||||
|
|
||||||
/** The type of the global ngStaticData array. */
|
/** The type of the global ngStaticData array. */
|
||||||
export type NgStaticData = (LNodeStatic | DirectiveDef<any>| null)[];
|
export type NgStaticData = (LNodeStatic | DirectiveDef<any>| null)[];
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {assertEqual, assertNotEqual} from './assert';
|
import {assertEqual, assertNotEqual} from './assert';
|
||||||
import {LNode, LNodeFlags} from './l_node';
|
import {LNode, LNodeFlags} from './interfaces';
|
||||||
|
|
||||||
export function assertNodeType(node: LNode, type: LNodeFlags) {
|
export function assertNodeType(node: LNode, type: LNodeFlags) {
|
||||||
assertNotEqual(node, null, 'node');
|
assertNotEqual(node, null, 'node');
|
||||||
|
|
|
@ -7,12 +7,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {assertNotNull} from './assert';
|
import {assertNotNull} from './assert';
|
||||||
import {ContainerState, ProjectionState, ViewOrContainerState, ViewState} from './interfaces';
|
import {ContainerState, LContainer, LElement, LNode, LNodeFlags, LProjection, LText, LView, ProjectionState, ViewOrContainerState, ViewState} from './interfaces';
|
||||||
import {LContainer, LElement, LNode, LNodeFlags, LProjection, LText, LView} from './l_node';
|
|
||||||
import {assertNodeType} from './node_assert';
|
import {assertNodeType} from './node_assert';
|
||||||
import {ProceduralRenderer3, RComment, RElement, RNode, RText} from './renderer';
|
import {ProceduralRenderer3, RComment, RElement, RNode, RText} from './renderer';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the closest DOM node above a given container in the hierarchy.
|
* Finds the closest DOM node above a given container in the hierarchy.
|
||||||
*
|
*
|
||||||
|
@ -56,8 +56,7 @@ export function findNativeParent(containerNode: LContainer): RNode|null {
|
||||||
* @param native Comment anchor for container
|
* @param native Comment anchor for container
|
||||||
* @returns The DOM element for which the view should insert elements
|
* @returns The DOM element for which the view should insert elements
|
||||||
*/
|
*/
|
||||||
export function findBeforeNode(index: number, state: ContainerState, native: RComment): RElement|
|
function findBeforeNode(index: number, state: ContainerState, native: RNode): RNode {
|
||||||
RText|RComment {
|
|
||||||
const views = state.views;
|
const views = state.views;
|
||||||
// Find the node to insert in front of
|
// Find the node to insert in front of
|
||||||
return index + 1 < views.length ?
|
return index + 1 < views.length ?
|
||||||
|
|
|
@ -6,18 +6,21 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// We are temporarily importing the existing viewEngine from core so we can be sure we are
|
// We are temporarily importing the existing viewEngine_from core so we can be sure we are
|
||||||
// correctly implementing its interfaces for backwards compatibility.
|
// correctly implementing its interfaces for backwards compatibility.
|
||||||
import {Observable} from 'rxjs/Observable';
|
import {Observable} from 'rxjs/Observable';
|
||||||
|
|
||||||
import * as viewEngine from '../core';
|
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 {assertNotNull} from './assert';
|
import {assertNotNull} from './assert';
|
||||||
|
import {DirectiveDef} from './definition_interfaces';
|
||||||
import {getOrCreateContainerRef, getOrCreateElementRef, getOrCreateNodeInjectorForNode, getOrCreateTemplateRef} from './di';
|
import {getOrCreateContainerRef, getOrCreateElementRef, getOrCreateNodeInjectorForNode, getOrCreateTemplateRef} from './di';
|
||||||
import {QueryReadType, QueryState} from './interfaces';
|
import {LContainer, LElement, LNode, LNodeFlags, LNodeInjector, LView, QueryReadType, QueryState} from './interfaces';
|
||||||
import {LContainer, LElement, LNode, LNodeFlags, LNodeInjector, LView} from './l_node';
|
|
||||||
import {assertNodeOfPossibleTypes} from './node_assert';
|
import {assertNodeOfPossibleTypes} from './node_assert';
|
||||||
import {DirectiveDef} from './public_interfaces';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,7 +41,7 @@ export interface QueryPredicate<T> {
|
||||||
/**
|
/**
|
||||||
* If looking for directives than it contains the directive type.
|
* If looking for directives than it contains the directive type.
|
||||||
*/
|
*/
|
||||||
type: viewEngine.Type<T>|null;
|
type: Type<T>|null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If selector then contains local names to query for.
|
* If selector then contains local names to query for.
|
||||||
|
@ -65,7 +68,7 @@ export class QueryState_ implements QueryState {
|
||||||
constructor(deep?: QueryPredicate<any>) { this.deep = deep == null ? null : deep; }
|
constructor(deep?: QueryPredicate<any>) { this.deep = deep == null ? null : deep; }
|
||||||
|
|
||||||
track<T>(
|
track<T>(
|
||||||
queryList: viewEngine.QueryList<T>, predicate: viewEngine.Type<T>|string[], descend?: boolean,
|
queryList: viewEngine_QueryList<T>, predicate: Type<T>|string[], descend?: boolean,
|
||||||
read?: QueryReadType): void {
|
read?: QueryReadType): void {
|
||||||
// TODO(misko): This is not right. In case of inherited state, a calling track will incorrectly
|
// TODO(misko): This is not right. In case of inherited state, a calling track will incorrectly
|
||||||
// mutate parent.
|
// mutate parent.
|
||||||
|
@ -106,8 +109,8 @@ export class QueryState_ implements QueryState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function readDefaultInjectable(nodeInjector: LNodeInjector, node: LNode):
|
function readDefaultInjectable(nodeInjector: LNodeInjector, node: LNode): viewEngine_ElementRef|
|
||||||
viewEngine.ElementRef|viewEngine.TemplateRef<any>|undefined {
|
viewEngine_TemplateRef<any>|undefined {
|
||||||
ngDevMode && assertNodeOfPossibleTypes(node, LNodeFlags.Container, LNodeFlags.Element);
|
ngDevMode && assertNodeOfPossibleTypes(node, LNodeFlags.Container, LNodeFlags.Element);
|
||||||
if ((node.flags & LNodeFlags.TYPE_MASK) === LNodeFlags.Element) {
|
if ((node.flags & LNodeFlags.TYPE_MASK) === LNodeFlags.Element) {
|
||||||
return getOrCreateElementRef(nodeInjector);
|
return getOrCreateElementRef(nodeInjector);
|
||||||
|
@ -117,7 +120,7 @@ function readDefaultInjectable(nodeInjector: LNodeInjector, node: LNode):
|
||||||
}
|
}
|
||||||
|
|
||||||
function readFromNodeInjector(nodeInjector: LNodeInjector, node: LNode, read: QueryReadType | null):
|
function readFromNodeInjector(nodeInjector: LNodeInjector, node: LNode, read: QueryReadType | null):
|
||||||
viewEngine.ElementRef|viewEngine.ViewContainerRef|viewEngine.TemplateRef<any>|undefined {
|
viewEngine_ElementRef|viewEngine_ViewContainerRef|viewEngine_TemplateRef<any>|undefined {
|
||||||
if (read === null) {
|
if (read === null) {
|
||||||
return readDefaultInjectable(nodeInjector, node);
|
return readDefaultInjectable(nodeInjector, node);
|
||||||
} else if (read === QueryReadType.ElementRef) {
|
} else if (read === QueryReadType.ElementRef) {
|
||||||
|
@ -166,8 +169,8 @@ function add(predicate: QueryPredicate<any>| null, node: LNode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function createPredicate<T>(
|
function createPredicate<T>(
|
||||||
previous: QueryPredicate<any>| null, queryList: QueryList<T>,
|
previous: QueryPredicate<any>| null, queryList: QueryList<T>, predicate: Type<T>| string[],
|
||||||
predicate: viewEngine.Type<T>| string[], read: QueryReadType | null): QueryPredicate<T> {
|
read: QueryReadType | null): QueryPredicate<T> {
|
||||||
const isArray = Array.isArray(predicate);
|
const isArray = Array.isArray(predicate);
|
||||||
const values = <any>[];
|
const values = <any>[];
|
||||||
if ((queryList as any as QueryList_<T>)._valuesTree === null) {
|
if ((queryList as any as QueryList_<T>)._valuesTree === null) {
|
||||||
|
@ -176,14 +179,14 @@ function createPredicate<T>(
|
||||||
return {
|
return {
|
||||||
next: previous,
|
next: previous,
|
||||||
list: queryList,
|
list: queryList,
|
||||||
type: isArray ? null : predicate as viewEngine.Type<T>,
|
type: isArray ? null : predicate as Type<T>,
|
||||||
selector: isArray ? predicate as string[] : null,
|
selector: isArray ? predicate as string[] : null,
|
||||||
read: read,
|
read: read,
|
||||||
values: values
|
values: values
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class QueryList_<T>/* implements viewEngine.QueryList<T> */ {
|
class QueryList_<T>/* implements viewEngine_QueryList<T> */ {
|
||||||
dirty: boolean = false;
|
dirty: boolean = false;
|
||||||
changes: Observable<T>;
|
changes: Observable<T>;
|
||||||
|
|
||||||
|
@ -250,8 +253,8 @@ class QueryList_<T>/* implements viewEngine.QueryList<T> */ {
|
||||||
|
|
||||||
// NOTE: this hack is here because IQueryList has private members and therefore
|
// NOTE: this hack is here because IQueryList has private members and therefore
|
||||||
// it can't be implemented only extended.
|
// it can't be implemented only extended.
|
||||||
export type QueryList<T> = viewEngine.QueryList<T>;
|
export type QueryList<T> = viewEngine_QueryList<T>;
|
||||||
export const QueryList: typeof viewEngine.QueryList = QueryList_ as any;
|
export const QueryList: typeof viewEngine_QueryList = QueryList_ as any;
|
||||||
|
|
||||||
export function queryRefresh(query: QueryList<any>): boolean {
|
export function queryRefresh(query: QueryList<any>): boolean {
|
||||||
return (query as any as QueryList_<any>)._refresh();
|
return (query as any as QueryList_<any>)._refresh();
|
||||||
|
|
|
@ -15,8 +15,9 @@
|
||||||
* it will be easy to implement such API.
|
* it will be easy to implement such API.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {RendererStyleFlags2, RendererType2, ViewEncapsulation} from '../core';
|
import {ViewEncapsulation} from '../metadata/view';
|
||||||
import {ComponentDef} from './public_interfaces';
|
import {RendererStyleFlags2, RendererType2} from '../render/api';
|
||||||
|
|
||||||
|
|
||||||
// TODO: cleanup once the code is merged in angular/angular
|
// TODO: cleanup once the code is merged in angular/angular
|
||||||
export enum RendererStyleFlags3 {
|
export enum RendererStyleFlags3 {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {ElementRef, TemplateRef, ViewContainerRef} from '@angular/core';
|
||||||
import {bloomAdd, bloomFindPossibleInjector} from '../../src/render3/di';
|
import {bloomAdd, bloomFindPossibleInjector} from '../../src/render3/di';
|
||||||
import {C, D, E, PublicFeature, T, V, b, b2, c, cR, cr, defineDirective, e, inject, injectElementRef, injectTemplateRef, injectViewContainerRef, t, v} from '../../src/render3/index';
|
import {C, D, E, PublicFeature, T, V, b, b2, c, cR, cr, defineDirective, e, inject, injectElementRef, injectTemplateRef, injectViewContainerRef, t, v} from '../../src/render3/index';
|
||||||
import {createLNode, createViewState, enterView, getOrCreateNodeInjector, leaveView} from '../../src/render3/instructions';
|
import {createLNode, createViewState, enterView, getOrCreateNodeInjector, leaveView} from '../../src/render3/instructions';
|
||||||
import {LNodeFlags, LNodeInjector} from '../../src/render3/l_node';
|
import {LNodeFlags, LNodeInjector} from '../../src/render3/interfaces';
|
||||||
|
|
||||||
import {renderToHtml} from './render_util';
|
import {renderToHtml} from './render_util';
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
import {ComponentTemplate, ComponentType, PublicFeature, defineComponent, renderComponent as _renderComponent} from '../../src/render3/index';
|
import {ComponentTemplate, ComponentType, PublicFeature, defineComponent, renderComponent as _renderComponent} from '../../src/render3/index';
|
||||||
import {NG_HOST_SYMBOL, createLNode, createViewState, renderTemplate} from '../../src/render3/instructions';
|
import {NG_HOST_SYMBOL, createLNode, createViewState, renderTemplate} from '../../src/render3/instructions';
|
||||||
import {LElement, LNodeFlags} from '../../src/render3/l_node';
|
import {LElement, LNodeFlags} from '../../src/render3/interfaces';
|
||||||
import {RElement, RText, Renderer3, RendererFactory3, domRendererFactory3} from '../../src/render3/renderer';
|
import {RElement, RText, Renderer3, RendererFactory3, domRendererFactory3} from '../../src/render3/renderer';
|
||||||
import {getRendererFactory2} from './imported_renderer2';
|
import {getRendererFactory2} from './imported_renderer2';
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue