refactor(core): split up interface files in render3 (#21433)
PR Close #21433
This commit is contained in:
parent
a33ff2c68f
commit
6be9c0466c
|
@ -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 {ComponentDef} from '@angular/core/src/render3/definition_interfaces';
|
||||
import {ComponentDef} from '@angular/core/src/render3/interfaces/definition';
|
||||
|
||||
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 {ComponentDef} from '@angular/core/src/render3/definition_interfaces';
|
||||
import {ComponentDef} from '@angular/core/src/render3/interfaces/definition';
|
||||
|
||||
import {TreeNode, buildTree, emptyTree} from '../util';
|
||||
|
||||
|
|
|
@ -13,10 +13,10 @@ import {ComponentRef as viewEngine_ComponentRef} from '../linker/component_facto
|
|||
import {EmbeddedViewRef as viewEngine_EmbeddedViewRef} from '../linker/view_ref';
|
||||
|
||||
import {assertNotNull} from './assert';
|
||||
import {ComponentDef, ComponentType} from './definition_interfaces';
|
||||
import {NG_HOST_SYMBOL, createError, createLView, directive, enterView, hostElement, leaveView, locateHostElement, renderComponentOrTemplate} from './instructions';
|
||||
import {LElementNode} from './interfaces';
|
||||
import {RElement, Renderer3, RendererFactory3, domRendererFactory3} from './renderer';
|
||||
import {ComponentDef, ComponentType} from './interfaces/definition';
|
||||
import {LElementNode} from './interfaces/node';
|
||||
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
|
||||
import {notImplemented, stringify} from './util';
|
||||
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ 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';
|
||||
import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs} from './interfaces/definition';
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -17,8 +17,9 @@ import {ViewContainerRef as viewEngine_ViewContainerRef} from '../linker/view_co
|
|||
import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, ViewRef as viewEngine_ViewRef} from '../linker/view_ref';
|
||||
import {Type} from '../type';
|
||||
|
||||
import {ComponentTemplate, DirectiveDef} from './definition_interfaces';
|
||||
import {LContainerNode, LElementNode, LInjector, LNodeFlags} from './interfaces';
|
||||
import {ComponentTemplate, DirectiveDef} from './interfaces/definition';
|
||||
import {LInjector} from './interfaces/injector';
|
||||
import {LContainerNode, LElementNode, LNodeFlags} from './interfaces/node';
|
||||
import {assertNodeType} from './node_assert';
|
||||
import {notImplemented, stringify} from './util';
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import {createComponentRef, detectChanges, getHostElement, markDirty, renderComponent} from './component';
|
||||
import {NgOnChangesFeature, PublicFeature, defineComponent, defineDirective} from './definition';
|
||||
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, DirectiveType} from './definition_interfaces';
|
||||
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, DirectiveType} from './interfaces/definition';
|
||||
|
||||
// Naming scheme:
|
||||
// - Capital letters are for creating things: T(Text), E(Element), D(Directive), V(View),
|
||||
|
|
|
@ -14,16 +14,20 @@ import {ViewContainerRef} from '../linker/view_container_ref';
|
|||
import {Type} from '../type';
|
||||
|
||||
import {assertEqual, assertLessThan, assertNotEqual, assertNotNull} from './assert';
|
||||
import {CssSelector, LContainer, LContainerNode, LElementNode, LInjector, LNode, LNodeFlags, LProjection, LProjectionNode, LQuery, LTextNode, LView, LViewNode, QueryReadType} from './interfaces';
|
||||
import {LContainer} from './interfaces/container';
|
||||
import {LInjector} from './interfaces/injector';
|
||||
import {CssSelector, LProjection} from './interfaces/projection';
|
||||
import {LQuery, QueryReadType} from './interfaces/query';
|
||||
import {LView} from './interfaces/view';
|
||||
|
||||
import {NgStaticData, TNode, TContainerNode, InitialInputData, InitialInputs, PropertyAliases, PropertyAliasValue,} from './t_node';
|
||||
import {LContainerNode, LElementNode, LNode, LNodeFlags, LProjectionNode, LTextNode, LViewNode, NgStaticData, TNode, TContainerNode, InitialInputData, InitialInputs, PropertyAliases, PropertyAliasValue,} from './interfaces/node';
|
||||
import {assertNodeType} from './node_assert';
|
||||
import {appendChild, insertChild, insertView, processProjectedNode, removeView} from './node_manipulation';
|
||||
import {isNodeMatchingSelector} from './node_selector_matcher';
|
||||
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef} from './definition_interfaces';
|
||||
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef} from './interfaces/definition';
|
||||
import {InjectFlags, diPublicInInjector, getOrCreateNodeInjectorForNode, getOrCreateElementRef, getOrCreateTemplateRef, getOrCreateContainerRef, getOrCreateInjectable} from './di';
|
||||
import {QueryList, LQuery_} from './query';
|
||||
import {RComment, RElement, RText, Renderer3, RendererFactory3, ProceduralRenderer3, ObjectOrientedRenderer3, RendererStyleFlags3} from './renderer';
|
||||
import {RComment, RElement, RText, Renderer3, RendererFactory3, ProceduralRenderer3, ObjectOrientedRenderer3, RendererStyleFlags3} from './interfaces/renderer';
|
||||
import {isDifferent, stringify} from './util';
|
||||
|
||||
export {queryRefresh} from './query';
|
||||
|
|
|
@ -1,555 +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 {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 {ComponentTemplate, DirectiveDef} from './definition_interfaces';
|
||||
import {RComment, RElement, RText, Renderer3} from './renderer';
|
||||
import {TNode} from './t_node';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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 LElementNode, then `data` will be null.
|
||||
* If LElementNode with component, then `data` contains LView.
|
||||
* If LViewNode, then `data` contains the LView.
|
||||
* If LContainerNode, then `data` contains LContainer.
|
||||
* If LProjectionNode, then `data` contains LProjection.
|
||||
*/
|
||||
readonly data: LView|LContainer|LProjection|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: LView;
|
||||
|
||||
/** The injector associated with this node. Necessary for DI. */
|
||||
nodeInjector: LInjector|null;
|
||||
|
||||
/**
|
||||
* Optional `QueryState` used for tracking queries.
|
||||
*
|
||||
* If present the node creation/updates are reported to the `QueryState`.
|
||||
*/
|
||||
query: LQuery|null;
|
||||
|
||||
/**
|
||||
* Pointer to the corresponding TNode object, which stores static
|
||||
* data about this node.
|
||||
*/
|
||||
tNode: TNode|null;
|
||||
}
|
||||
|
||||
|
||||
/** LNode representing an element. */
|
||||
export interface LElementNode extends LNode {
|
||||
/** The DOM element associated with this node. */
|
||||
readonly native: RElement;
|
||||
|
||||
child: LContainerNode|LElementNode|LTextNode|LProjectionNode|null;
|
||||
next: LContainerNode|LElementNode|LTextNode|LProjectionNode|null;
|
||||
|
||||
/** If Component then data has LView (light DOM) */
|
||||
readonly data: LView|null;
|
||||
|
||||
/** LElementNodes can be inside other LElementNodes or inside LViewNodes. */
|
||||
readonly parent: LElementNode|LViewNode;
|
||||
}
|
||||
|
||||
/** LNode representing a #text node. */
|
||||
export interface LTextNode extends LNode {
|
||||
/** The text node associated with this node. */
|
||||
native: RText;
|
||||
child: null;
|
||||
next: LContainerNode|LElementNode|LTextNode|LProjectionNode|null;
|
||||
|
||||
/** LTextNodes can be inside LElementNodes or inside LViewNodes. */
|
||||
readonly parent: LElementNode|LViewNode;
|
||||
readonly data: null;
|
||||
}
|
||||
|
||||
/** Abstract node which contains root nodes of a view. */
|
||||
export interface LViewNode extends LNode {
|
||||
readonly native: null;
|
||||
child: LContainerNode|LElementNode|LTextNode|LProjectionNode|null;
|
||||
next: LViewNode|null;
|
||||
|
||||
/** LViewNodes can only be added to LContainerNodes. */
|
||||
readonly parent: LContainerNode|null;
|
||||
readonly data: LView;
|
||||
}
|
||||
|
||||
/** Abstract node container which contains other views. */
|
||||
export interface LContainerNode 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: LContainer;
|
||||
child: null;
|
||||
next: LContainerNode|LElementNode|LTextNode|LProjectionNode|null;
|
||||
|
||||
/** Containers can be added to elements or views. */
|
||||
readonly parent: LElementNode|LViewNode|null;
|
||||
}
|
||||
|
||||
|
||||
export interface LProjectionNode extends LNode {
|
||||
readonly native: null;
|
||||
child: null;
|
||||
next: LContainerNode|LElementNode|LTextNode|LProjectionNode|null;
|
||||
|
||||
readonly data: LProjection;
|
||||
|
||||
/** Projections can be added to elements or views. */
|
||||
readonly parent: LElementNode|LViewNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 LInjector {
|
||||
/**
|
||||
* 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: LInjector|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: LElementNode|LContainerNode;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* `LView` stores all of the information needed to process the instructions as
|
||||
* they are invoked from the template. Each embedded view and component view has its
|
||||
* own `LView`. When processing a particular view, we set the `currentView` to that
|
||||
* `LView`. When that view is done processing, the `currentView` is set back to
|
||||
* whatever the original `currentView` was before(the parent `LView`).
|
||||
*
|
||||
* Keeping separate state for each view facilities view insertion / deletion, so we
|
||||
* don't have to edit the data array based on which views are present.
|
||||
*/
|
||||
export interface LView {
|
||||
/**
|
||||
* Whether or not the view is in creationMode.
|
||||
*
|
||||
* This must be stored in the view rather than using `data` as a marker so that
|
||||
* we can properly support embedded views. Otherwise, when exiting a child view
|
||||
* back into the parent view, `data` will be defined and `creationMode` will be
|
||||
* improperly reported as false.
|
||||
*/
|
||||
creationMode: boolean;
|
||||
|
||||
/** The index in the data array at which view hooks begin to be stored. */
|
||||
viewHookStartIndex: number|null;
|
||||
|
||||
/**
|
||||
* The parent view is needed when we exit the view and must restore the previous
|
||||
* `LView`. Without this, the render method would have to keep a stack of
|
||||
* views as it is recursively rendering templates.
|
||||
*/
|
||||
readonly parent: LView|null;
|
||||
|
||||
/**
|
||||
* Pointer to the `LViewNode` or `LElementNode` which represents the root of the view.
|
||||
*
|
||||
* If `LViewNode`, this is an embedded view of a container. We need this to be able to
|
||||
* efficiently find the `LViewNode` when inserting the view into an anchor.
|
||||
*
|
||||
* If `LElementNode`, this is the LView of a component.
|
||||
*/
|
||||
readonly node: LViewNode|LElementNode;
|
||||
|
||||
/**
|
||||
* ID to determine whether this view is the same as the previous view
|
||||
* in this position. If it's not, we know this view needs to be inserted
|
||||
* and the one that exists needs to be removed (e.g. if/else statements)
|
||||
*/
|
||||
readonly id: number;
|
||||
|
||||
/** Renderer to be used for this view. */
|
||||
readonly renderer: Renderer3;
|
||||
|
||||
/**
|
||||
* The binding start index is the index at which the nodes array
|
||||
* starts to store bindings only. Saving this value ensures that we
|
||||
* will begin reading bindings at the correct point in the array when
|
||||
* we are in update mode.
|
||||
*/
|
||||
bindingStartIndex: number|null;
|
||||
|
||||
/**
|
||||
* When a view is destroyed, listeners need to be released and onDestroy callbacks
|
||||
* need to be called. This cleanup array stores both listener data (in chunks of 4)
|
||||
* and onDestroy data (in chunks of 2) for a particular view. Combining the arrays
|
||||
* saves on memory (70 bytes per array) and on a few bytes of code size (for two
|
||||
* separate for loops).
|
||||
*
|
||||
* If it's a listener being stored:
|
||||
* 1st index is: event name to remove
|
||||
* 2nd index is: native element
|
||||
* 3rd index is: listener function
|
||||
* 4th index is: useCapture boolean
|
||||
*
|
||||
* If it's an onDestroy function:
|
||||
* 1st index is: onDestroy function
|
||||
* 2nd index is; context for function
|
||||
*/
|
||||
cleanup: any[]|null;
|
||||
|
||||
/**
|
||||
* The first LView or LContainer beneath this LView in the hierarchy.
|
||||
*
|
||||
* Necessary to store this so views can traverse through their nested views
|
||||
* to remove listeners and call onDestroy callbacks.
|
||||
*
|
||||
* For embedded views, we store the LContainer rather than the first ViewState
|
||||
* to avoid managing splicing when views are added/removed.
|
||||
*/
|
||||
child: LView|LContainer|null;
|
||||
|
||||
/**
|
||||
* The last LView or LContainer beneath this LView in the hierarchy.
|
||||
*
|
||||
* The tail allows us to quickly add a new state to the end of the view list
|
||||
* without having to propagate starting from the first child.
|
||||
*/
|
||||
tail: LView|LContainer|null;
|
||||
|
||||
/**
|
||||
* The next sibling LView or LContainer.
|
||||
*
|
||||
* Allows us to propagate between sibling view states that aren't in the same
|
||||
* container. Embedded views already have a node.next, but it is only set for
|
||||
* views in the same container. We need a way to link component views and views
|
||||
* across containers as well.
|
||||
*/
|
||||
next: LView|LContainer|null;
|
||||
|
||||
/**
|
||||
* This array stores all element/text/container nodes created inside this view
|
||||
* and their bindings. Stored as an array rather than a linked list so we can
|
||||
* look up nodes directly in the case of forward declaration or bindings
|
||||
* (e.g. E(1))..
|
||||
*
|
||||
* All bindings for a given view are stored in the order in which they
|
||||
* appear in the template, starting with `bindingStartIndex`.
|
||||
* We use `bindingIndex` to internally keep track of which binding
|
||||
* is currently active.
|
||||
*
|
||||
* NOTE: We also use data == null as a marker for creationMode. We
|
||||
* do this by creating ViewState in incomplete state with nodes == null
|
||||
* and we initialize it on first run.
|
||||
*/
|
||||
readonly data: any[];
|
||||
|
||||
/**
|
||||
* The static data array for the current view. We need a reference to this so we
|
||||
* can easily walk up the node tree in DI and get the ngStaticData array associated
|
||||
* with a node (where the directive defs are stored).
|
||||
*/
|
||||
ngStaticData: (TNode|DirectiveDef<any>|null)[];
|
||||
}
|
||||
|
||||
|
||||
/** The state associated with an LContainer */
|
||||
export interface LContainer {
|
||||
/**
|
||||
* The next active index in the views array to read or write to. This helps us
|
||||
* keep track of where we are in the views array.
|
||||
*/
|
||||
nextIndex: number;
|
||||
|
||||
/**
|
||||
* This allows us to jump from a container to a sibling container or
|
||||
* component view with the same parent, so we can remove listeners efficiently.
|
||||
*/
|
||||
next: LView|LContainer|null;
|
||||
|
||||
/**
|
||||
* Access to the parent view is necessary so we can propagate back
|
||||
* up from inside a container to parent.next.
|
||||
*/
|
||||
parent: LView|null;
|
||||
|
||||
/**
|
||||
* A list of the container's currently active child views. Views will be inserted
|
||||
* here as they are added and spliced from here when they are removed. We need
|
||||
* to keep a record of current views so we know which views are already in the DOM
|
||||
* (and don't need to be re-added) and so we can remove views from the DOM when they
|
||||
* are no longer required.
|
||||
*/
|
||||
readonly views: LViewNode[];
|
||||
|
||||
/**
|
||||
* Parent Element which will contain the location where all of the Views will be
|
||||
* inserted into to.
|
||||
*
|
||||
* If `renderParent` is `null` it is headless. This means that it is contained
|
||||
* in another `LViewNode` which in turn is contained in another `LContainerNode` and
|
||||
* therefore it does not yet have its own parent.
|
||||
*
|
||||
* If `renderParent` is not `null` then it may be:
|
||||
* - same as `LContainerNode.parent` in which case it is just a normal container.
|
||||
* - different from `LContainerNode.parent` in which case it has been re-projected.
|
||||
* In other words `LContainerNode.parent` is logical parent where as
|
||||
* `LContainer.projectedParent` is render parent.
|
||||
*
|
||||
* When views are inserted into `LContainerNode` then `renderParent` is:
|
||||
* - `null`, we are in `LViewNode` keep going up a hierarchy until actual
|
||||
* `renderParent` is found.
|
||||
* - not `null`, then use the `projectedParent.native` as the `RElement` to insert
|
||||
* `LViewNode`s into.
|
||||
*/
|
||||
renderParent: LElementNode|null;
|
||||
|
||||
/**
|
||||
* The template extracted from the location of the Container.
|
||||
*/
|
||||
readonly template: ComponentTemplate<any>|null;
|
||||
}
|
||||
|
||||
|
||||
/** Interface necessary to work with view tree traversal */
|
||||
export interface LViewOrLContainer {
|
||||
next: LView|LContainer|null;
|
||||
child?: LView|LContainer|null;
|
||||
views?: LViewNode[];
|
||||
parent: LView|null;
|
||||
}
|
||||
|
||||
/**
|
||||
* An LProjection is just an array of projected nodes.
|
||||
*
|
||||
* It would be nice if we could not need an array, but since a projected node can be
|
||||
* re-projected, the same node can be part of more than one LProjectionNode which makes
|
||||
* list approach not possible.
|
||||
*/
|
||||
export type LProjection = Array<LElementNode|LTextNode|LContainerNode>;
|
||||
|
||||
/** An enum representing possible values of the "read" option for queries. */
|
||||
export const enum QueryReadType {
|
||||
ElementRef = 0,
|
||||
ViewContainerRef = 1,
|
||||
TemplateRef = 2,
|
||||
}
|
||||
|
||||
/** Used for tracking queries (e.g. ViewChild, ContentChild). */
|
||||
export interface LQuery {
|
||||
/**
|
||||
* Used to ask query if it should be cloned to the child element.
|
||||
*
|
||||
* For example in the case of deep queries the `child()` returns
|
||||
* query for the child node. In case of shallow queries it returns
|
||||
* `null`.
|
||||
*/
|
||||
child(): LQuery|null;
|
||||
|
||||
/**
|
||||
* Notify `LQuery` that a `LNode` has been created.
|
||||
*/
|
||||
addNode(node: LNode): void;
|
||||
|
||||
/**
|
||||
* Notify `LQuery` that an `LViewNode` has been added to `LContainerNode`.
|
||||
*/
|
||||
insertView(container: LContainerNode, view: LViewNode, insertIndex: number): void;
|
||||
|
||||
/**
|
||||
* Notify `LQuery` that an `LViewNode` has been removed from `LContainerNode`.
|
||||
*/
|
||||
removeView(container: LContainerNode, view: LViewNode, removeIndex: number): void;
|
||||
|
||||
/**
|
||||
* Add additional `QueryList` to track.
|
||||
*
|
||||
* @param queryList `QueryList` to update with changes.
|
||||
* @param predicate Either `Type` or selector array of [key, value] predicates.
|
||||
* @param descend If true the query will recursively apply to the children.
|
||||
* @param read Indicates which token should be read from DI for this query.
|
||||
*/
|
||||
track<T>(
|
||||
queryList: QueryList<T>, predicate: Type<any>|string[], descend?: boolean,
|
||||
read?: QueryReadType|Type<T>): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parsed selector in the following format:
|
||||
* [tagName, attr1Name, attr1Val, ..., attrnName, attrnValue, 'class', className1, className2, ...,
|
||||
* classNameN]
|
||||
*
|
||||
* * For example, given the following selector:
|
||||
* `div.foo.bar[attr1=val1][attr2]` a parsed format would be:
|
||||
* `['div', 'attr1', 'val1', 'attr2', '', 'class', 'foo', 'bar']`.
|
||||
*
|
||||
* Things to notice:
|
||||
* - tag name is always at the position 0
|
||||
* - the `class` attribute is always the last attribute in a pre-parsed array
|
||||
* - class names in a selector are at the end of an array (after the attribute with the name
|
||||
* 'class').
|
||||
*/
|
||||
export type SimpleCssSelector = string[];
|
||||
|
||||
/**
|
||||
* A complex selector expressed as an Array where:
|
||||
* - element at index 0 is a selector (SimpleCSSSelector) to match
|
||||
* - elements at index 1..n is a selector (SimpleCSSSelector) that should NOT match
|
||||
*/
|
||||
export type CssSelectorWithNegations = [SimpleCssSelector | null, SimpleCssSelector[] | null];
|
||||
|
||||
/**
|
||||
* A collection of complex selectors (CSSSelectorWithNegations) in a parsed form
|
||||
*/
|
||||
export type CssSelector = CssSelectorWithNegations[];
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* @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 {ComponentTemplate} from './definition';
|
||||
import {LElementNode, LViewNode} from './node';
|
||||
import {LView} from './view';
|
||||
|
||||
|
||||
/** The state associated with an LContainer */
|
||||
export interface LContainer {
|
||||
/**
|
||||
* The next active index in the views array to read or write to. This helps us
|
||||
* keep track of where we are in the views array.
|
||||
*/
|
||||
nextIndex: number;
|
||||
|
||||
/**
|
||||
* This allows us to jump from a container to a sibling container or
|
||||
* component view with the same parent, so we can remove listeners efficiently.
|
||||
*/
|
||||
next: LView|LContainer|null;
|
||||
|
||||
/**
|
||||
* Access to the parent view is necessary so we can propagate back
|
||||
* up from inside a container to parent.next.
|
||||
*/
|
||||
parent: LView|null;
|
||||
|
||||
/**
|
||||
* A list of the container's currently active child views. Views will be inserted
|
||||
* here as they are added and spliced from here when they are removed. We need
|
||||
* to keep a record of current views so we know which views are already in the DOM
|
||||
* (and don't need to be re-added) and so we can remove views from the DOM when they
|
||||
* are no longer required.
|
||||
*/
|
||||
readonly views: LViewNode[];
|
||||
|
||||
/**
|
||||
* Parent Element which will contain the location where all of the Views will be
|
||||
* inserted into to.
|
||||
*
|
||||
* If `renderParent` is `null` it is headless. This means that it is contained
|
||||
* in another `LViewNode` which in turn is contained in another `LContainerNode` and
|
||||
* therefore it does not yet have its own parent.
|
||||
*
|
||||
* If `renderParent` is not `null` then it may be:
|
||||
* - same as `LContainerNode.parent` in which case it is just a normal container.
|
||||
* - different from `LContainerNode.parent` in which case it has been re-projected.
|
||||
* In other words `LContainerNode.parent` is logical parent where as
|
||||
* `LContainer.projectedParent` is render parent.
|
||||
*
|
||||
* When views are inserted into `LContainerNode` then `renderParent` is:
|
||||
* - `null`, we are in `LViewNode` keep going up a hierarchy until actual
|
||||
* `renderParent` is found.
|
||||
* - not `null`, then use the `projectedParent.native` as the `RElement` to insert
|
||||
* `LViewNode`s into.
|
||||
*/
|
||||
renderParent: LElementNode|null;
|
||||
|
||||
/**
|
||||
* The template extracted from the location of the Container.
|
||||
*/
|
||||
readonly template: ComponentTemplate<any>|null;
|
||||
}
|
||||
|
||||
// Note: This hack is necessary so we don't erroneously get a circular dependency
|
||||
// failure based on types.
|
||||
export const unusedValueExportToPlacateAjd = 1;
|
|
@ -6,11 +6,9 @@
|
|||
* 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 {RendererType2} from '../../render/api';
|
||||
import {Type} from '../../type';
|
||||
import {resolveRendererType2} from '../../view/util';
|
||||
|
||||
/**
|
||||
* Definition of what a template rendering function should look like.
|
||||
|
@ -146,3 +144,7 @@ export interface ComponentDefArgs<T> extends DirectiveDefArgs<T> {
|
|||
|
||||
export type DirectiveDefFeature = <T>(directiveDef: DirectiveDef<T>) => void;
|
||||
export type ComponentDefFeature = <T>(directiveDef: DirectiveDef<T>) => void;
|
||||
|
||||
// Note: This hack is necessary so we don't erroneously get a circular dependency
|
||||
// failure based on types.
|
||||
export const unusedValueExportToPlacateAjd = 1;
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* @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 {Injector} from '../../di/injector';
|
||||
import {ElementRef} from '../../linker/element_ref';
|
||||
import {TemplateRef} from '../../linker/template_ref';
|
||||
import {ViewContainerRef} from '../../linker/view_container_ref';
|
||||
|
||||
import {LContainerNode, LElementNode} from './node';
|
||||
|
||||
export interface LInjector {
|
||||
/**
|
||||
* 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: LInjector|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: LElementNode|LContainerNode;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
// Note: This hack is necessary so we don't erroneously get a circular dependency
|
||||
// failure based on types.
|
||||
export const unusedValueExportToPlacateAjd = 1;
|
|
@ -0,0 +1,348 @@
|
|||
/**
|
||||
* @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 {LContainer} from './container';
|
||||
import {DirectiveDef} from './definition';
|
||||
import {LInjector} from './injector';
|
||||
import {LProjection} from './projection';
|
||||
import {LQuery} from './query';
|
||||
import {RComment, RElement, RText} from './renderer';
|
||||
import {LView} from './view';
|
||||
|
||||
|
||||
/**
|
||||
* 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 LElementNode, then `data` will be null.
|
||||
* If LElementNode with component, then `data` contains LView.
|
||||
* If LViewNode, then `data` contains the LView.
|
||||
* If LContainerNode, then `data` contains LContainer.
|
||||
* If LProjectionNode, then `data` contains LProjection.
|
||||
*/
|
||||
readonly data: LView|LContainer|LProjection|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: LView;
|
||||
|
||||
/** The injector associated with this node. Necessary for DI. */
|
||||
nodeInjector: LInjector|null;
|
||||
|
||||
/**
|
||||
* Optional `QueryState` used for tracking queries.
|
||||
*
|
||||
* If present the node creation/updates are reported to the `QueryState`.
|
||||
*/
|
||||
query: LQuery|null;
|
||||
|
||||
/**
|
||||
* Pointer to the corresponding TNode object, which stores static
|
||||
* data about this node.
|
||||
*/
|
||||
tNode: TNode|null;
|
||||
}
|
||||
|
||||
|
||||
/** LNode representing an element. */
|
||||
export interface LElementNode extends LNode {
|
||||
/** The DOM element associated with this node. */
|
||||
readonly native: RElement;
|
||||
|
||||
child: LContainerNode|LElementNode|LTextNode|LProjectionNode|null;
|
||||
next: LContainerNode|LElementNode|LTextNode|LProjectionNode|null;
|
||||
|
||||
/** If Component then data has LView (light DOM) */
|
||||
readonly data: LView|null;
|
||||
|
||||
/** LElementNodes can be inside other LElementNodes or inside LViewNodes. */
|
||||
readonly parent: LElementNode|LViewNode;
|
||||
}
|
||||
|
||||
/** LNode representing a #text node. */
|
||||
export interface LTextNode extends LNode {
|
||||
/** The text node associated with this node. */
|
||||
native: RText;
|
||||
child: null;
|
||||
next: LContainerNode|LElementNode|LTextNode|LProjectionNode|null;
|
||||
|
||||
/** LTextNodes can be inside LElementNodes or inside LViewNodes. */
|
||||
readonly parent: LElementNode|LViewNode;
|
||||
readonly data: null;
|
||||
}
|
||||
|
||||
/** Abstract node which contains root nodes of a view. */
|
||||
export interface LViewNode extends LNode {
|
||||
readonly native: null;
|
||||
child: LContainerNode|LElementNode|LTextNode|LProjectionNode|null;
|
||||
next: LViewNode|null;
|
||||
|
||||
/** LViewNodes can only be added to LContainerNodes. */
|
||||
readonly parent: LContainerNode|null;
|
||||
readonly data: LView;
|
||||
}
|
||||
|
||||
/** Abstract node container which contains other views. */
|
||||
export interface LContainerNode 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: LContainer;
|
||||
child: null;
|
||||
next: LContainerNode|LElementNode|LTextNode|LProjectionNode|null;
|
||||
|
||||
/** Containers can be added to elements or views. */
|
||||
readonly parent: LElementNode|LViewNode|null;
|
||||
}
|
||||
|
||||
|
||||
export interface LProjectionNode extends LNode {
|
||||
readonly native: null;
|
||||
child: null;
|
||||
next: LContainerNode|LElementNode|LTextNode|LProjectionNode|null;
|
||||
|
||||
readonly data: LProjection;
|
||||
|
||||
/** Projections can be added to elements or views. */
|
||||
readonly parent: LElementNode|LViewNode;
|
||||
}
|
||||
|
||||
|
||||
/** The type of the global ngStaticData array. */
|
||||
export type NgStaticData = (TNode | DirectiveDef<any>| null)[];
|
||||
|
||||
/**
|
||||
* LNode binding data (flyweight) for a particular node that is shared between all templates
|
||||
* of a specific type.
|
||||
*
|
||||
* If a property is:
|
||||
* - PropertyAliases: that property's data was generated and this is it
|
||||
* - Null: that property's data was already generated and nothing was found.
|
||||
* - Undefined: that property's data has not yet been generated
|
||||
*
|
||||
* see: https://en.wikipedia.org/wiki/Flyweight_pattern for more on the Flyweight pattern
|
||||
*/
|
||||
export interface TNode {
|
||||
/** The tag name associated with this node. */
|
||||
tagName: string|null;
|
||||
|
||||
/**
|
||||
* Static attributes associated with an element. We need to store
|
||||
* static attributes to support content projection with selectors.
|
||||
* Attributes are stored statically because reading them from the DOM
|
||||
* would be way too slow for content projection and queries.
|
||||
*
|
||||
* Since attrs will always be calculated first, they will never need
|
||||
* to be marked undefined by other instructions.
|
||||
*
|
||||
* The name of the attribute and its value alternate in the array.
|
||||
* e.g. ['role', 'checkbox']
|
||||
*/
|
||||
attrs: string[]|null;
|
||||
|
||||
/**
|
||||
* A set of local names under which a given element is exported in a template and
|
||||
* visible to queries. An entry in this array can be created for different reasons:
|
||||
* - an element itself is referenced, ex.: `<div #foo>`
|
||||
* - a component is referenced, ex.: `<my-cmpt #foo>`
|
||||
* - a directive is referenced, ex.: `<my-cmpt #foo="directiveExportAs">`.
|
||||
*
|
||||
* A given element might have different local names and those names can be associated
|
||||
* with a directive. We store local names at even indexes while odd indexes are reserved
|
||||
* for directive index in a view (or `-1` if there is no associated directive).
|
||||
*
|
||||
* Some examples:
|
||||
* - `<div #foo>` => `["foo", -1]`
|
||||
* - `<my-cmpt #foo>` => `["foo", myCmptIdx]`
|
||||
* - `<my-cmpt #foo #bar="directiveExportAs">` => `["foo", myCmptIdx, "bar", directiveIdx]`
|
||||
* - `<div #foo #bar="directiveExportAs">` => `["foo", -1, "bar", directiveIdx]`
|
||||
*/
|
||||
localNames: (string|number)[]|null;
|
||||
|
||||
/**
|
||||
* This property contains information about input properties that
|
||||
* need to be set once from attribute data.
|
||||
*/
|
||||
initialInputs: InitialInputData|null|undefined;
|
||||
|
||||
/** Input data for all directives on this node. */
|
||||
inputs: PropertyAliases|null|undefined;
|
||||
|
||||
/** Output data for all directives on this node. */
|
||||
outputs: PropertyAliases|null|undefined;
|
||||
|
||||
/**
|
||||
* If this TNode corresponds to an LContainerNode, the container will
|
||||
* need to have nested static data for each of its embedded views.
|
||||
* Otherwise, nodes in embedded views with the same index as nodes
|
||||
* in their parent views will overwrite each other, as they are in
|
||||
* the same template.
|
||||
*
|
||||
* Each index in this array corresponds to the static data for a certain
|
||||
* view. So if you had V(0) and V(1) in a container, you might have:
|
||||
*
|
||||
* [
|
||||
* [{tagName: 'div', attrs: ...}, null], // V(0) ngData
|
||||
* [{tagName: 'button', attrs ...}, null] // V(1) ngData
|
||||
* ]
|
||||
*/
|
||||
containerStatic: (TNode|null)[][]|null;
|
||||
}
|
||||
|
||||
/** Static data for an LElementNode */
|
||||
export interface TElementNode extends TNode { containerStatic: null; }
|
||||
|
||||
/** Static data for an LContainerNode */
|
||||
export interface TContainerNode extends TNode { containerStatic: (TNode|null)[][]; }
|
||||
|
||||
/**
|
||||
* This mapping is necessary so we can set input properties and output listeners
|
||||
* properly at runtime when property names are minified or aliased.
|
||||
*
|
||||
* Key: unminified / public input or output name
|
||||
* Value: array containing minified / internal name and related directive index
|
||||
*
|
||||
* The value must be an array to support inputs and outputs with the same name
|
||||
* on the same node.
|
||||
*/
|
||||
export type PropertyAliases = {
|
||||
// This uses an object map because using the Map type would be too slow
|
||||
[key: string]: PropertyAliasValue
|
||||
};
|
||||
|
||||
/**
|
||||
* The value in PropertyAliases.
|
||||
*
|
||||
* In each array:
|
||||
* Even indices: directive index
|
||||
* Odd indices: minified / internal name
|
||||
*
|
||||
* e.g. [0, 'change-minified']
|
||||
*/
|
||||
export type PropertyAliasValue = (number | string)[];
|
||||
|
||||
|
||||
/**
|
||||
* This array contains information about input properties that
|
||||
* need to be set once from attribute data. It's ordered by
|
||||
* directive index (relative to element) so it's simple to
|
||||
* look up a specific directive's initial input data.
|
||||
*
|
||||
* Within each sub-array:
|
||||
*
|
||||
* Even indices: minified/internal input name
|
||||
* Odd indices: initial value
|
||||
*
|
||||
* If a directive on a node does not have any input properties
|
||||
* that should be set from attributes, its index is set to null
|
||||
* to avoid a sparse array.
|
||||
*
|
||||
* e.g. [null, ['role-min', 'button']]
|
||||
*/
|
||||
export type InitialInputData = (InitialInputs | null)[];
|
||||
|
||||
/**
|
||||
* Used by InitialInputData to store input properties
|
||||
* that should be set once from attributes.
|
||||
*
|
||||
* Even indices: minified/internal input name
|
||||
* Odd indices: initial value
|
||||
*
|
||||
* e.g. ['role-min', 'button']
|
||||
*/
|
||||
export type InitialInputs = string[];
|
||||
|
||||
// Note: This hack is necessary so we don't erroneously get a circular dependency
|
||||
// failure based on types.
|
||||
export const unusedValueExportToPlacateAjd = 1;
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* @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 {LContainerNode, LElementNode, LTextNode} from './node';
|
||||
|
||||
/**
|
||||
* An LProjection is just an array of projected nodes.
|
||||
*
|
||||
* It would be nice if we could not need an array, but since a projected node can be
|
||||
* re-projected, the same node can be part of more than one LProjectionNode which makes
|
||||
* list approach not possible.
|
||||
*/
|
||||
export type LProjection = Array<LElementNode|LTextNode|LContainerNode>;
|
||||
|
||||
|
||||
/**
|
||||
* Parsed selector in the following format:
|
||||
* [tagName, attr1Name, attr1Val, ..., attrnName, attrnValue, 'class', className1, className2, ...,
|
||||
* classNameN]
|
||||
*
|
||||
* * For example, given the following selector:
|
||||
* `div.foo.bar[attr1=val1][attr2]` a parsed format would be:
|
||||
* `['div', 'attr1', 'val1', 'attr2', '', 'class', 'foo', 'bar']`.
|
||||
*
|
||||
* Things to notice:
|
||||
* - tag name is always at the position 0
|
||||
* - the `class` attribute is always the last attribute in a pre-parsed array
|
||||
* - class names in a selector are at the end of an array (after the attribute with the name
|
||||
* 'class').
|
||||
*/
|
||||
export type SimpleCssSelector = string[];
|
||||
|
||||
/**
|
||||
* A complex selector expressed as an Array where:
|
||||
* - element at index 0 is a selector (SimpleCSSSelector) to match
|
||||
* - elements at index 1..n is a selector (SimpleCSSSelector) that should NOT match
|
||||
*/
|
||||
export type CssSelectorWithNegations = [SimpleCssSelector | null, SimpleCssSelector[] | null];
|
||||
|
||||
/**
|
||||
* A collection of complex selectors (CSSSelectorWithNegations) in a parsed form
|
||||
*/
|
||||
export type CssSelector = CssSelectorWithNegations[];
|
||||
|
||||
// Note: This hack is necessary so we don't erroneously get a circular dependency
|
||||
// failure based on types.
|
||||
export const unusedValueExportToPlacateAjd = 1;
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* @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 {QueryList} from '../../linker';
|
||||
import {Type} from '../../type';
|
||||
|
||||
import {LContainerNode, LNode, LViewNode} from './node';
|
||||
|
||||
|
||||
/** Used for tracking queries (e.g. ViewChild, ContentChild). */
|
||||
export interface LQuery {
|
||||
/**
|
||||
* Used to ask query if it should be cloned to the child element.
|
||||
*
|
||||
* For example in the case of deep queries the `child()` returns
|
||||
* query for the child node. In case of shallow queries it returns
|
||||
* `null`.
|
||||
*/
|
||||
child(): LQuery|null;
|
||||
|
||||
/**
|
||||
* Notify `LQuery` that a `LNode` has been created.
|
||||
*/
|
||||
addNode(node: LNode): void;
|
||||
|
||||
/**
|
||||
* Notify `LQuery` that an `LViewNode` has been added to `LContainerNode`.
|
||||
*/
|
||||
insertView(container: LContainerNode, view: LViewNode, insertIndex: number): void;
|
||||
|
||||
/**
|
||||
* Notify `LQuery` that an `LViewNode` has been removed from `LContainerNode`.
|
||||
*/
|
||||
removeView(container: LContainerNode, view: LViewNode, removeIndex: number): void;
|
||||
|
||||
/**
|
||||
* Add additional `QueryList` to track.
|
||||
*
|
||||
* @param queryList `QueryList` to update with changes.
|
||||
* @param predicate Either `Type` or selector array of [key, value] predicates.
|
||||
* @param descend If true the query will recursively apply to the children.
|
||||
* @param read Indicates which token should be read from DI for this query.
|
||||
*/
|
||||
track<T>(
|
||||
queryList: QueryList<T>, predicate: Type<any>|string[], descend?: boolean,
|
||||
read?: QueryReadType|Type<T>): void;
|
||||
}
|
||||
|
||||
/** An enum representing possible values of the "read" option for queries. */
|
||||
export const enum QueryReadType {
|
||||
ElementRef = 0,
|
||||
ViewContainerRef = 1,
|
||||
TemplateRef = 2,
|
||||
}
|
||||
|
||||
// Note: This hack is necessary so we don't erroneously get a circular dependency
|
||||
// failure based on types.
|
||||
export const unusedValueExportToPlacateAjd = 1;
|
|
@ -15,8 +15,8 @@
|
|||
* it will be easy to implement such API.
|
||||
*/
|
||||
|
||||
import {ViewEncapsulation} from '../metadata/view';
|
||||
import {RendererStyleFlags2, RendererType2} from '../render/api';
|
||||
import {ViewEncapsulation} from '../../metadata/view';
|
||||
import {RendererStyleFlags2, RendererType2} from '../../render/api';
|
||||
|
||||
|
||||
// TODO: cleanup once the code is merged in angular/angular
|
||||
|
@ -139,3 +139,7 @@ export interface RDomTokenList {
|
|||
export interface RText extends RNode { textContent: string|null; }
|
||||
|
||||
export interface RComment extends RNode {}
|
||||
|
||||
// Note: This hack is necessary so we don't erroneously get a circular dependency
|
||||
// failure based on types.
|
||||
export const unusedValueExportToPlacateAjd = 1;
|
|
@ -0,0 +1,157 @@
|
|||
/**
|
||||
* @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 {LContainer} from './container';
|
||||
import {DirectiveDef} from './definition';
|
||||
import {LElementNode, LViewNode, TNode} from './node';
|
||||
import {Renderer3} from './renderer';
|
||||
|
||||
|
||||
/**
|
||||
* `LView` stores all of the information needed to process the instructions as
|
||||
* they are invoked from the template. Each embedded view and component view has its
|
||||
* own `LView`. When processing a particular view, we set the `currentView` to that
|
||||
* `LView`. When that view is done processing, the `currentView` is set back to
|
||||
* whatever the original `currentView` was before(the parent `LView`).
|
||||
*
|
||||
* Keeping separate state for each view facilities view insertion / deletion, so we
|
||||
* don't have to edit the data array based on which views are present.
|
||||
*/
|
||||
export interface LView {
|
||||
/**
|
||||
* Whether or not the view is in creationMode.
|
||||
*
|
||||
* This must be stored in the view rather than using `data` as a marker so that
|
||||
* we can properly support embedded views. Otherwise, when exiting a child view
|
||||
* back into the parent view, `data` will be defined and `creationMode` will be
|
||||
* improperly reported as false.
|
||||
*/
|
||||
creationMode: boolean;
|
||||
|
||||
/** The index in the data array at which view hooks begin to be stored. */
|
||||
viewHookStartIndex: number|null;
|
||||
|
||||
/**
|
||||
* The parent view is needed when we exit the view and must restore the previous
|
||||
* `LView`. Without this, the render method would have to keep a stack of
|
||||
* views as it is recursively rendering templates.
|
||||
*/
|
||||
readonly parent: LView|null;
|
||||
|
||||
/**
|
||||
* Pointer to the `LViewNode` or `LElementNode` which represents the root of the view.
|
||||
*
|
||||
* If `LViewNode`, this is an embedded view of a container. We need this to be able to
|
||||
* efficiently find the `LViewNode` when inserting the view into an anchor.
|
||||
*
|
||||
* If `LElementNode`, this is the LView of a component.
|
||||
*/
|
||||
readonly node: LViewNode|LElementNode;
|
||||
|
||||
/**
|
||||
* ID to determine whether this view is the same as the previous view
|
||||
* in this position. If it's not, we know this view needs to be inserted
|
||||
* and the one that exists needs to be removed (e.g. if/else statements)
|
||||
*/
|
||||
readonly id: number;
|
||||
|
||||
/** Renderer to be used for this view. */
|
||||
readonly renderer: Renderer3;
|
||||
|
||||
/**
|
||||
* The binding start index is the index at which the nodes array
|
||||
* starts to store bindings only. Saving this value ensures that we
|
||||
* will begin reading bindings at the correct point in the array when
|
||||
* we are in update mode.
|
||||
*/
|
||||
bindingStartIndex: number|null;
|
||||
|
||||
/**
|
||||
* When a view is destroyed, listeners need to be released and onDestroy callbacks
|
||||
* need to be called. This cleanup array stores both listener data (in chunks of 4)
|
||||
* and onDestroy data (in chunks of 2) for a particular view. Combining the arrays
|
||||
* saves on memory (70 bytes per array) and on a few bytes of code size (for two
|
||||
* separate for loops).
|
||||
*
|
||||
* If it's a listener being stored:
|
||||
* 1st index is: event name to remove
|
||||
* 2nd index is: native element
|
||||
* 3rd index is: listener function
|
||||
* 4th index is: useCapture boolean
|
||||
*
|
||||
* If it's an onDestroy function:
|
||||
* 1st index is: onDestroy function
|
||||
* 2nd index is; context for function
|
||||
*/
|
||||
cleanup: any[]|null;
|
||||
|
||||
/**
|
||||
* The first LView or LContainer beneath this LView in the hierarchy.
|
||||
*
|
||||
* Necessary to store this so views can traverse through their nested views
|
||||
* to remove listeners and call onDestroy callbacks.
|
||||
*
|
||||
* For embedded views, we store the LContainer rather than the first ViewState
|
||||
* to avoid managing splicing when views are added/removed.
|
||||
*/
|
||||
child: LView|LContainer|null;
|
||||
|
||||
/**
|
||||
* The last LView or LContainer beneath this LView in the hierarchy.
|
||||
*
|
||||
* The tail allows us to quickly add a new state to the end of the view list
|
||||
* without having to propagate starting from the first child.
|
||||
*/
|
||||
tail: LView|LContainer|null;
|
||||
|
||||
/**
|
||||
* The next sibling LView or LContainer.
|
||||
*
|
||||
* Allows us to propagate between sibling view states that aren't in the same
|
||||
* container. Embedded views already have a node.next, but it is only set for
|
||||
* views in the same container. We need a way to link component views and views
|
||||
* across containers as well.
|
||||
*/
|
||||
next: LView|LContainer|null;
|
||||
|
||||
/**
|
||||
* This array stores all element/text/container nodes created inside this view
|
||||
* and their bindings. Stored as an array rather than a linked list so we can
|
||||
* look up nodes directly in the case of forward declaration or bindings
|
||||
* (e.g. E(1))..
|
||||
*
|
||||
* All bindings for a given view are stored in the order in which they
|
||||
* appear in the template, starting with `bindingStartIndex`.
|
||||
* We use `bindingIndex` to internally keep track of which binding
|
||||
* is currently active.
|
||||
*
|
||||
* NOTE: We also use data == null as a marker for creationMode. We
|
||||
* do this by creating ViewState in incomplete state with nodes == null
|
||||
* and we initialize it on first run.
|
||||
*/
|
||||
readonly data: any[];
|
||||
|
||||
/**
|
||||
* The static data array for the current view. We need a reference to this so we
|
||||
* can easily walk up the node tree in DI and get the ngStaticData array associated
|
||||
* with a node (where the directive defs are stored).
|
||||
*/
|
||||
ngStaticData: (TNode|DirectiveDef<any>|null)[];
|
||||
}
|
||||
|
||||
/** Interface necessary to work with view tree traversal */
|
||||
export interface LViewOrLContainer {
|
||||
next: LView|LContainer|null;
|
||||
child?: LView|LContainer|null;
|
||||
views?: LViewNode[];
|
||||
parent: LView|null;
|
||||
}
|
||||
|
||||
// Note: This hack is necessary so we don't erroneously get a circular dependency
|
||||
// failure based on types.
|
||||
export const unusedValueExportToPlacateAjd = 1;
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {assertEqual, assertNotEqual} from './assert';
|
||||
import {LNode, LNodeFlags} from './interfaces';
|
||||
import {LNode, LNodeFlags} from './interfaces/node';
|
||||
|
||||
export function assertNodeType(node: LNode, type: LNodeFlags) {
|
||||
assertNotEqual(node, null, 'node');
|
||||
|
|
|
@ -7,9 +7,12 @@
|
|||
*/
|
||||
|
||||
import {assertNotNull} from './assert';
|
||||
import {LContainer, LContainerNode, LElementNode, LNode, LNodeFlags, LProjection, LProjectionNode, LTextNode, LView, LViewNode, LViewOrLContainer} from './interfaces';
|
||||
import {LContainer} from './interfaces/container';
|
||||
import {LContainerNode, LElementNode, LNode, LNodeFlags, LProjectionNode, LTextNode, LViewNode} from './interfaces/node';
|
||||
import {LProjection} from './interfaces/projection';
|
||||
import {ProceduralRenderer3, RComment, RElement, RNode, RText} from './interfaces/renderer';
|
||||
import {LView, LViewOrLContainer} from './interfaces/view';
|
||||
import {assertNodeType} from './node_assert';
|
||||
import {ProceduralRenderer3, RComment, RElement, RNode, RText} from './renderer';
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
import './ng_dev_mode';
|
||||
|
||||
import {assertNotNull} from './assert';
|
||||
import {CssSelector, CssSelectorWithNegations, SimpleCssSelector} from './interfaces';
|
||||
import {TNode} from './t_node';
|
||||
import {TNode} from './interfaces/node';
|
||||
import {CssSelector, CssSelectorWithNegations, SimpleCssSelector} from './interfaces/projection';
|
||||
|
||||
function isCssClassMatching(nodeClassAttrVal: string, cssClassToMatch: string): boolean {
|
||||
const nodeClassesLen = nodeClassAttrVal.length;
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
## General 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
|
||||
|
||||
## Monomorphic vs Megamorphic code
|
||||
|
||||
1) Monomophic prop access is 100 times faster then megamorphic.
|
||||
2) Monomorphic call is 4 times faster the megamorphic call.
|
||||
|
||||
See benchmark [here](https://jsperf.com/mono-vs-megamorphic-property-access).
|
|
@ -16,12 +16,12 @@ import {TemplateRef as viewEngine_TemplateRef} from '../linker/template_ref';
|
|||
import {Type} from '../type';
|
||||
|
||||
import {assertNotNull} from './assert';
|
||||
import {DirectiveDef} from './definition_interfaces';
|
||||
import {getOrCreateContainerRef, getOrCreateElementRef, getOrCreateNodeInjectorForNode, getOrCreateTemplateRef} from './di';
|
||||
import {LContainerNode, LElementNode, LInjector, LNode, LNodeFlags, LQuery, LViewNode, QueryReadType} from './interfaces';
|
||||
import {DirectiveDef} from './interfaces/definition';
|
||||
import {LInjector} from './interfaces/injector';
|
||||
import {LContainerNode, LElementNode, LNode, LNodeFlags, LViewNode, TNode} from './interfaces/node';
|
||||
import {LQuery, QueryReadType} from './interfaces/query';
|
||||
import {assertNodeOfPossibleTypes} from './node_assert';
|
||||
import {TNode} from './t_node';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,153 +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 {DirectiveDef} from './definition_interfaces';
|
||||
|
||||
/** The type of the global ngStaticData array. */
|
||||
export type NgStaticData = (TNode | DirectiveDef<any>| null)[];
|
||||
|
||||
/**
|
||||
* LNode binding data (flyweight) for a particular node that is shared between all templates
|
||||
* of a specific type.
|
||||
*
|
||||
* If a property is:
|
||||
* - PropertyAliases: that property's data was generated and this is it
|
||||
* - Null: that property's data was already generated and nothing was found.
|
||||
* - Undefined: that property's data has not yet been generated
|
||||
*
|
||||
* see: https://en.wikipedia.org/wiki/Flyweight_pattern for more on the Flyweight pattern
|
||||
*/
|
||||
export interface TNode {
|
||||
/** The tag name associated with this node. */
|
||||
tagName: string|null;
|
||||
|
||||
/**
|
||||
* Static attributes associated with an element. We need to store
|
||||
* static attributes to support content projection with selectors.
|
||||
* Attributes are stored statically because reading them from the DOM
|
||||
* would be way too slow for content projection and queries.
|
||||
*
|
||||
* Since attrs will always be calculated first, they will never need
|
||||
* to be marked undefined by other instructions.
|
||||
*
|
||||
* The name of the attribute and its value alternate in the array.
|
||||
* e.g. ['role', 'checkbox']
|
||||
*/
|
||||
attrs: string[]|null;
|
||||
|
||||
/**
|
||||
* A set of local names under which a given element is exported in a template and
|
||||
* visible to queries. An entry in this array can be created for different reasons:
|
||||
* - an element itself is referenced, ex.: `<div #foo>`
|
||||
* - a component is referenced, ex.: `<my-cmpt #foo>`
|
||||
* - a directive is referenced, ex.: `<my-cmpt #foo="directiveExportAs">`.
|
||||
*
|
||||
* A given element might have different local names and those names can be associated
|
||||
* with a directive. We store local names at even indexes while odd indexes are reserved
|
||||
* for directive index in a view (or `-1` if there is no associated directive).
|
||||
*
|
||||
* Some examples:
|
||||
* - `<div #foo>` => `["foo", -1]`
|
||||
* - `<my-cmpt #foo>` => `["foo", myCmptIdx]`
|
||||
* - `<my-cmpt #foo #bar="directiveExportAs">` => `["foo", myCmptIdx, "bar", directiveIdx]`
|
||||
* - `<div #foo #bar="directiveExportAs">` => `["foo", -1, "bar", directiveIdx]`
|
||||
*/
|
||||
localNames: (string|number)[]|null;
|
||||
|
||||
/**
|
||||
* This property contains information about input properties that
|
||||
* need to be set once from attribute data.
|
||||
*/
|
||||
initialInputs: InitialInputData|null|undefined;
|
||||
|
||||
/** Input data for all directives on this node. */
|
||||
inputs: PropertyAliases|null|undefined;
|
||||
|
||||
/** Output data for all directives on this node. */
|
||||
outputs: PropertyAliases|null|undefined;
|
||||
|
||||
/**
|
||||
* If this TNode corresponds to an LContainerNode, the container will
|
||||
* need to have nested static data for each of its embedded views.
|
||||
* Otherwise, nodes in embedded views with the same index as nodes
|
||||
* in their parent views will overwrite each other, as they are in
|
||||
* the same template.
|
||||
*
|
||||
* Each index in this array corresponds to the static data for a certain
|
||||
* view. So if you had V(0) and V(1) in a container, you might have:
|
||||
*
|
||||
* [
|
||||
* [{tagName: 'div', attrs: ...}, null], // V(0) ngData
|
||||
* [{tagName: 'button', attrs ...}, null] // V(1) ngData
|
||||
* ]
|
||||
*/
|
||||
containerStatic: (TNode|null)[][]|null;
|
||||
}
|
||||
|
||||
/** Static data for an LElementNode */
|
||||
export interface TElementNode extends TNode { containerStatic: null; }
|
||||
|
||||
/** Static data for an LContainerNode */
|
||||
export interface TContainerNode extends TNode { containerStatic: (TNode|null)[][]; }
|
||||
|
||||
/**
|
||||
* This mapping is necessary so we can set input properties and output listeners
|
||||
* properly at runtime when property names are minified or aliased.
|
||||
*
|
||||
* Key: unminified / public input or output name
|
||||
* Value: array containing minified / internal name and related directive index
|
||||
*
|
||||
* The value must be an array to support inputs and outputs with the same name
|
||||
* on the same node.
|
||||
*/
|
||||
export type PropertyAliases = {
|
||||
// This uses an object map because using the Map type would be too slow
|
||||
[key: string]: PropertyAliasValue
|
||||
};
|
||||
|
||||
/**
|
||||
* The value in PropertyAliases.
|
||||
*
|
||||
* In each array:
|
||||
* Even indices: directive index
|
||||
* Odd indices: minified / internal name
|
||||
*
|
||||
* e.g. [0, 'change-minified']
|
||||
*/
|
||||
export type PropertyAliasValue = (number | string)[];
|
||||
|
||||
|
||||
/**
|
||||
* This array contains information about input properties that
|
||||
* need to be set once from attribute data. It's ordered by
|
||||
* directive index (relative to element) so it's simple to
|
||||
* look up a specific directive's initial input data.
|
||||
*
|
||||
* Within each sub-array:
|
||||
*
|
||||
* Even indices: minified/internal input name
|
||||
* Odd indices: initial value
|
||||
*
|
||||
* If a directive on a node does not have any input properties
|
||||
* that should be set from attributes, its index is set to null
|
||||
* to avoid a sparse array.
|
||||
*
|
||||
* e.g. [null, ['role-min', 'button']]
|
||||
*/
|
||||
export type InitialInputData = (InitialInputs | null)[];
|
||||
|
||||
/**
|
||||
* Used by InitialInputData to store input properties
|
||||
* that should be set once from attributes.
|
||||
*
|
||||
* Even indices: minified/internal input name
|
||||
* Odd indices: initial value
|
||||
*
|
||||
* e.g. ['role-min', 'button']
|
||||
*/
|
||||
export type InitialInputs = string[];
|
|
@ -11,7 +11,8 @@ import {ElementRef, TemplateRef, ViewContainerRef} from '@angular/core';
|
|||
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 {createLNode, createLView, enterView, getOrCreateNodeInjector, leaveView} from '../../src/render3/instructions';
|
||||
import {LInjector, LNodeFlags} from '../../src/render3/interfaces';
|
||||
import {LInjector} from '../../src/render3/interfaces/injector';
|
||||
import {LNodeFlags} from '../../src/render3/interfaces/node';
|
||||
|
||||
import {renderToHtml} from './render_util';
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {CssSelector, CssSelectorWithNegations, SimpleCssSelector} from '../../src/render3/interfaces';
|
||||
import {TNode} from '../../src/render3/interfaces/node';
|
||||
import {CssSelector, CssSelectorWithNegations, SimpleCssSelector} from '../../src/render3/interfaces/projection';
|
||||
import {isNodeMatchingSelector, isNodeMatchingSelectorWithNegations, isNodeMatchingSimpleSelector} from '../../src/render3/node_selector_matcher';
|
||||
import {TNode} from '../../src/render3/t_node';
|
||||
|
||||
function testLStaticData(tagName: string, attrs: string[] | null): TNode {
|
||||
return {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {C, D, E, Q, QueryList, c, e, m, qR} from '../../src/render3/index';
|
||||
import {QueryReadType} from '../../src/render3/interfaces';
|
||||
import {QueryReadType} from '../../src/render3/interfaces/query';
|
||||
|
||||
import {createComponent, createDirective, renderComponent} from './render_util';
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
import {stringifyElement} from '@angular/platform-browser/testing/src/browser_util';
|
||||
import {ComponentTemplate, ComponentType, DirectiveType, PublicFeature, defineComponent, defineDirective, renderComponent as _renderComponent} from '../../src/render3/index';
|
||||
import {NG_HOST_SYMBOL, createLNode, createLView, renderTemplate} from '../../src/render3/instructions';
|
||||
import {LElementNode, LNodeFlags} from '../../src/render3/interfaces';
|
||||
import {RElement, RText, Renderer3, RendererFactory3, domRendererFactory3} from '../../src/render3/renderer';
|
||||
import {LElementNode, LNodeFlags} from '../../src/render3/interfaces/node';
|
||||
import {RElement, RText, Renderer3, RendererFactory3, domRendererFactory3} from '../../src/render3/interfaces/renderer';
|
||||
import {getRendererFactory2} from './imported_renderer2';
|
||||
|
||||
export const document = ((global || window) as any).document;
|
||||
|
|
Loading…
Reference in New Issue