refactor(ivy): split util functions into different files (#28382)

Google3 detected circular references here, so splitting up this rather hodge-podge list of functions into slightly better organizational units.

PR Close #28382
This commit is contained in:
Ben Lesh 2019-02-20 14:21:20 -08:00
parent 7bae49b419
commit c64b13e593
42 changed files with 528 additions and 469 deletions

View File

@ -262,7 +262,7 @@ export {getModuleFactory__POST_R3__ as ɵgetModuleFactory__POST_R3__} from './li
export { export {
publishGlobalUtil as ɵpublishGlobalUtil, publishGlobalUtil as ɵpublishGlobalUtil,
publishDefaultGlobalUtils as ɵpublishDefaultGlobalUtils publishDefaultGlobalUtils as ɵpublishDefaultGlobalUtils
} from './render3/global_utils'; } from './render3/util/global_utils';
export {createInjector as ɵcreateInjector} from './di/r3_injector'; export {createInjector as ɵcreateInjector} from './di/r3_injector';

View File

@ -7,13 +7,14 @@
*/ */
import {Injector} from '../di'; import {Injector} from '../di';
import {getComponent, getContext, getInjectionTokens, getInjector, getListeners, getLocalRefs, getViewComponent, isBrowserEvents, loadLContext, loadLContextFromNode} from '../render3/discovery_utils'; import {getViewComponent} from '../render3/global_utils_api';
import {TNode} from '../render3/interfaces/node'; import {TNode} from '../render3/interfaces/node';
import {StylingIndex} from '../render3/interfaces/styling'; import {StylingIndex} from '../render3/interfaces/styling';
import {LView, TData, TVIEW} from '../render3/interfaces/view'; import {LView, TData, TVIEW} from '../render3/interfaces/view';
import {getProp, getValue, isClassBasedValue} from '../render3/styling/class_and_style_bindings'; import {getProp, getValue, isClassBasedValue} from '../render3/styling/class_and_style_bindings';
import {getStylingContext} from '../render3/styling/util'; import {getStylingContext} from '../render3/styling/util';
import {INTERPOLATION_DELIMITER, isPropMetadataString, renderStringify} from '../render3/util'; import {getComponent, getContext, getInjectionTokens, getInjector, getListeners, getLocalRefs, isBrowserEvents, loadLContext, loadLContextFromNode} from '../render3/util/discovery_utils';
import {INTERPOLATION_DELIMITER, isPropMetadataString, renderStringify} from '../render3/util/misc_utils';
import {assertDomNode} from '../util/assert'; import {assertDomNode} from '../util/assert';
import {DebugContext} from '../view/index'; import {DebugContext} from '../view/index';

View File

@ -11,7 +11,7 @@ import {assertDefined, assertEqual, throwError} from '../util/assert';
import {getComponentDef, getNgModuleDef} from './definition'; import {getComponentDef, getNgModuleDef} from './definition';
import {TNode} from './interfaces/node'; import {TNode} from './interfaces/node';
import {LView} from './interfaces/view'; import {LView} from './interfaces/view';
import {isLContainer, isLView} from './util'; import {isLContainer, isLView} from './util/view_utils';
export function assertComponentType( export function assertComponentType(

View File

@ -12,7 +12,7 @@ import {throwErrorIfNoChangesMode} from './errors';
import {LView} from './interfaces/view'; import {LView} from './interfaces/view';
import {getCheckNoChangesMode} from './state'; import {getCheckNoChangesMode} from './state';
import {NO_CHANGE} from './tokens'; import {NO_CHANGE} from './tokens';
import {isDifferent} from './util'; import {isDifferent} from './util/misc_utils';

View File

@ -16,7 +16,6 @@ import {assertDefined} from '../util/assert';
import {assertComponentType} from './assert'; import {assertComponentType} from './assert';
import {getComponentDef} from './definition'; import {getComponentDef} from './definition';
import {diPublicInInjector, getOrCreateNodeInjectorForNode} from './di'; import {diPublicInInjector, getOrCreateNodeInjectorForNode} from './di';
import {publishDefaultGlobalUtils} from './global_utils';
import {registerPostOrderHooks, registerPreOrderHooks} from './hooks'; import {registerPostOrderHooks, registerPreOrderHooks} from './hooks';
import {CLEAN_PROMISE, addToViewTree, createLView, createNodeAtIndex, createTView, getOrCreateTView, initNodeFlags, instantiateRootComponent, invokeHostBindingsInCreationMode, locateHostElement, queueComponentIndexForCheck, refreshDescendantViews} from './instructions'; import {CLEAN_PROMISE, addToViewTree, createLView, createNodeAtIndex, createTView, getOrCreateTView, initNodeFlags, instantiateRootComponent, invokeHostBindingsInCreationMode, locateHostElement, queueComponentIndexForCheck, refreshDescendantViews} from './instructions';
import {ComponentDef, ComponentType, RenderFlags} from './interfaces/definition'; import {ComponentDef, ComponentType, RenderFlags} from './interfaces/definition';
@ -24,8 +23,12 @@ import {TElementNode, TNode, TNodeFlags, TNodeType} from './interfaces/node';
import {PlayerHandler} from './interfaces/player'; import {PlayerHandler} from './interfaces/player';
import {RElement, Renderer3, RendererFactory3, domRendererFactory3} from './interfaces/renderer'; import {RElement, Renderer3, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
import {CONTEXT, FLAGS, HEADER_OFFSET, LView, LViewFlags, RootContext, RootContextFlags, TVIEW} from './interfaces/view'; import {CONTEXT, FLAGS, HEADER_OFFSET, LView, LViewFlags, RootContext, RootContextFlags, TVIEW} from './interfaces/view';
import {applyOnCreateInstructions} from './node_util';
import {enterView, getPreviousOrParentTNode, leaveView, resetComponentState, setCurrentDirectiveDef} from './state'; import {enterView, getPreviousOrParentTNode, leaveView, resetComponentState, setCurrentDirectiveDef} from './state';
import {applyOnCreateInstructions, defaultScheduler, getRootView, readPatchedLView, renderStringify} from './util'; import {publishDefaultGlobalUtils} from './util/global_utils';
import {defaultScheduler, renderStringify} from './util/misc_utils';
import {getRootContext, getRootView} from './util/view_traversal_utils';
import {readPatchedLView} from './util/view_utils';
@ -245,19 +248,6 @@ export function LifecycleHooksFeature(component: any, def: ComponentDef<any>): v
rootTView, { directiveStart: dirIndex, directiveEnd: dirIndex + 1 } as TNode); rootTView, { directiveStart: dirIndex, directiveEnd: dirIndex + 1 } as TNode);
} }
/**
* Retrieve the root context for any component by walking the parent `LView` until
* reaching the root `LView`.
*
* @param component any component
*/
function getRootContext(component: any): RootContext {
const rootContext = getRootView(component)[CONTEXT] as RootContext;
ngDevMode && assertDefined(rootContext, 'rootContext');
return rootContext;
}
/** /**
* Wait on component until it is rendered. * Wait on component until it is rendered.
* *

View File

@ -32,7 +32,8 @@ import {TContainerNode, TElementContainerNode, TElementNode} from './interfaces/
import {RNode, RendererFactory3, domRendererFactory3, isProceduralRenderer} from './interfaces/renderer'; import {RNode, RendererFactory3, domRendererFactory3, isProceduralRenderer} from './interfaces/renderer';
import {HEADER_OFFSET, LView, LViewFlags, RootContext, TVIEW} from './interfaces/view'; import {HEADER_OFFSET, LView, LViewFlags, RootContext, TVIEW} from './interfaces/view';
import {enterView, leaveView} from './state'; import {enterView, leaveView} from './state';
import {defaultScheduler, getTNode} from './util'; import {defaultScheduler} from './util/misc_utils';
import {getTNode} from './util/view_utils';
import {createElementRef} from './view_engine_compatibility'; import {createElementRef} from './view_engine_compatibility';
import {RootViewRef, ViewRef} from './view_ref'; import {RootViewRef, ViewRef} from './view_ref';

View File

@ -6,13 +6,15 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import '../util/ng_dev_mode'; import '../util/ng_dev_mode';
import {assertDomNode} from '../util/assert'; import {assertDomNode} from '../util/assert';
import {EMPTY_ARRAY} from './empty'; import {EMPTY_ARRAY} from './empty';
import {LContext, MONKEY_PATCH_KEY_NAME} from './interfaces/context'; import {LContext, MONKEY_PATCH_KEY_NAME} from './interfaces/context';
import {TNode, TNodeFlags} from './interfaces/node'; import {TNode, TNodeFlags} from './interfaces/node';
import {RElement} from './interfaces/renderer'; import {RElement} from './interfaces/renderer';
import {CONTEXT, HEADER_OFFSET, HOST, LView, TVIEW} from './interfaces/view'; import {CONTEXT, HEADER_OFFSET, HOST, LView, TVIEW} from './interfaces/view';
import {getComponentViewByIndex, getNativeByTNode, readElementValue, readPatchedData} from './util'; import {getComponentViewByIndex, getNativeByTNode, readElementValue, readPatchedData} from './util/view_utils';

View File

@ -21,7 +21,10 @@ import {AttributeMarker, TContainerNode, TElementContainerNode, TElementNode, TN
import {DECLARATION_VIEW, INJECTOR, LView, TData, TVIEW, TView, T_HOST} from './interfaces/view'; import {DECLARATION_VIEW, INJECTOR, LView, TData, TVIEW, TView, T_HOST} from './interfaces/view';
import {assertNodeOfPossibleTypes} from './node_assert'; import {assertNodeOfPossibleTypes} from './node_assert';
import {getLView, getPreviousOrParentTNode, setTNodeAndViewData} from './state'; import {getLView, getPreviousOrParentTNode, setTNodeAndViewData} from './state';
import {findComponentView, getParentInjectorIndex, getParentInjectorView, hasParentInjector, isComponent, isComponentDef, renderStringify} from './util'; import {getParentInjectorIndex, getParentInjectorView, hasParentInjector} from './util/injector_utils';
import {renderStringify} from './util/misc_utils';
import {findComponentView} from './util/view_traversal_utils';
import {isComponent, isComponentDef} from './util/view_utils';

View File

@ -18,7 +18,7 @@ import {NodeInjectorFactory} from './interfaces/injector';
import {TContainerNode, TElementContainerNode, TElementNode, TNodeFlags, TNodeProviderIndexes} from './interfaces/node'; import {TContainerNode, TElementContainerNode, TElementNode, TNodeFlags, TNodeProviderIndexes} from './interfaces/node';
import {LView, TData, TVIEW, TView} from './interfaces/view'; import {LView, TData, TVIEW, TView} from './interfaces/view';
import {getLView, getPreviousOrParentTNode} from './state'; import {getLView, getPreviousOrParentTNode} from './state';
import {isComponentDef} from './util'; import {isComponentDef} from './util/view_utils';

View File

@ -10,7 +10,7 @@ import {Type} from '../../interface/type';
import {fillProperties} from '../../util/property'; import {fillProperties} from '../../util/property';
import {EMPTY_ARRAY, EMPTY_OBJ} from '../empty'; import {EMPTY_ARRAY, EMPTY_OBJ} from '../empty';
import {ComponentDef, DirectiveDef, DirectiveDefFeature, RenderFlags} from '../interfaces/definition'; import {ComponentDef, DirectiveDef, DirectiveDefFeature, RenderFlags} from '../interfaces/definition';
import {isComponentDef} from '../util'; import {isComponentDef} from '../util/view_utils';
import {NgOnChangesFeature} from './ng_onchanges_feature'; import {NgOnChangesFeature} from './ng_onchanges_feature';

View File

@ -15,6 +15,6 @@
* file in the public_api_guard test. * file in the public_api_guard test.
*/ */
export {getComponent, getContext, getDirectives, getHostElement, getInjector, getListeners, getRootComponents, getViewComponent} from './discovery_utils';
export {markDirty} from './instructions'; export {markDirty} from './instructions';
export {getPlayers} from './players'; export {getPlayers} from './players';
export {getComponent, getContext, getDirectives, getHostElement, getInjector, getListeners, getRootComponents, getViewComponent} from './util/discovery_utils';

View File

@ -22,7 +22,9 @@ import {BINDING_INDEX, HEADER_OFFSET, LView, RENDERER, TVIEW, TView, T_HOST} fro
import {appendChild, createTextNode, nativeRemoveNode} from './node_manipulation'; import {appendChild, createTextNode, nativeRemoveNode} from './node_manipulation';
import {getIsParent, getLView, getPreviousOrParentTNode, setIsParent, setPreviousOrParentTNode} from './state'; import {getIsParent, getLView, getPreviousOrParentTNode, setIsParent, setPreviousOrParentTNode} from './state';
import {NO_CHANGE} from './tokens'; import {NO_CHANGE} from './tokens';
import {addAllToArray, getNativeByIndex, getNativeByTNode, getTNode, isLContainer, renderStringify} from './util'; import {addAllToArray} from './util/array_utils';
import {renderStringify} from './util/misc_utils';
import {getNativeByIndex, getNativeByTNode, getTNode, isLContainer} from './util/view_utils';
const MARKER = `<EFBFBD>`; const MARKER = `<EFBFBD>`;
const ICU_BLOCK_REGEXP = /^\s*(<28>\d+:?\d*<2A>)\s*,\s*(select|plural)\s*,/; const ICU_BLOCK_REGEXP = /^\s*(<28>\d+:?\d*<2A>)\s*,\s*(select|plural)\s*,/;

View File

@ -7,11 +7,11 @@
*/ */
import {LifecycleHooksFeature, renderComponent, whenRendered} from './component'; import {LifecycleHooksFeature, renderComponent, whenRendered} from './component';
import {defineBase, defineComponent, defineDirective, defineNgModule, definePipe, setComponentScope} from './definition'; import {defineBase, defineComponent, defineDirective, defineNgModule, definePipe, setComponentScope} from './definition';
import {getComponent, getDirectives, getHostElement, getRenderedText} from './discovery_utils';
import {InheritDefinitionFeature} from './features/inherit_definition_feature'; import {InheritDefinitionFeature} from './features/inherit_definition_feature';
import {NgOnChangesFeature} from './features/ng_onchanges_feature'; import {NgOnChangesFeature} from './features/ng_onchanges_feature';
import {ProvidersFeature} from './features/providers_feature'; import {ProvidersFeature} from './features/providers_feature';
import {BaseDef, ComponentDef, ComponentDefWithMeta, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, DirectiveDefWithMeta, DirectiveType, PipeDef, PipeDefWithMeta} from './interfaces/definition'; import {BaseDef, ComponentDef, ComponentDefWithMeta, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, DirectiveDefWithMeta, DirectiveType, PipeDef, PipeDefWithMeta} from './interfaces/definition';
import {getComponent, getDirectives, getHostElement, getRenderedText} from './util/discovery_utils';
export {ComponentFactory, ComponentFactoryResolver, ComponentRef, injectComponentFactoryResolver} from './component_ref'; export {ComponentFactory, ComponentFactoryResolver, ComponentRef, injectComponentFactoryResolver} from './component_ref';
export {getFactoryOf, getInheritedFactory} from './di'; export {getFactoryOf, getInheritedFactory} from './di';
@ -19,6 +19,7 @@ export {RenderFlags} from './interfaces/definition';
export {CssSelectorList} from './interfaces/projection'; export {CssSelectorList} from './interfaces/projection';
// clang-format off // clang-format off
export { export {
allocHostVars, allocHostVars,
@ -146,7 +147,7 @@ export {
export {templateRefExtractor} from './view_engine_compatibility_prebound'; export {templateRefExtractor} from './view_engine_compatibility_prebound';
export {resolveWindow, resolveDocument, resolveBody} from './util'; export {resolveWindow, resolveDocument, resolveBody} from './util/misc_utils';
// clang-format on // clang-format on

View File

@ -38,12 +38,15 @@ import {BINDING_INDEX, CHILD_HEAD, CHILD_TAIL, CLEANUP, CONTEXT, DECLARATION_VIE
import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert'; import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert';
import {appendChild, appendProjectedNode, createTextNode, insertView, removeView} from './node_manipulation'; import {appendChild, appendProjectedNode, createTextNode, insertView, removeView} from './node_manipulation';
import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher'; import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher';
import {decreaseElementDepthCount, enterView, getBindingsEnabled, getCheckNoChangesMode, getContextLView, getCurrentDirectiveDef, getElementDepthCount, getIsParent, getLView, getPreviousOrParentTNode, increaseElementDepthCount, isCreationMode, leaveView, nextContextImpl, resetComponentState, setBindingRoot, setCheckNoChangesMode, setCurrentDirectiveDef, setCurrentQueryIndex, setIsParent, setPreviousOrParentTNode,} from './state'; import {applyOnCreateInstructions} from './node_util';
import {decreaseElementDepthCount, enterView, getBindingsEnabled, getCheckNoChangesMode, getContextLView, getCurrentDirectiveDef, getElementDepthCount, getIsParent, getLView, getPreviousOrParentTNode, increaseElementDepthCount, isCreationMode, leaveView, nextContextImpl, resetComponentState, setBindingRoot, setCheckNoChangesMode, setCurrentDirectiveDef, setCurrentQueryIndex, setIsParent, setPreviousOrParentTNode} from './state';
import {getInitialClassNameValue, getInitialStyleStringValue, initializeStaticContext as initializeStaticStylingContext, patchContextWithStaticAttrs, renderInitialClasses, renderInitialStyles, renderStyling, updateClassProp as updateElementClassProp, updateContextWithBindings, updateStyleProp as updateElementStyleProp, updateStylingMap} from './styling/class_and_style_bindings'; import {getInitialClassNameValue, getInitialStyleStringValue, initializeStaticContext as initializeStaticStylingContext, patchContextWithStaticAttrs, renderInitialClasses, renderInitialStyles, renderStyling, updateClassProp as updateElementClassProp, updateContextWithBindings, updateStyleProp as updateElementStyleProp, updateStylingMap} from './styling/class_and_style_bindings';
import {BoundPlayerFactory} from './styling/player_factory'; import {BoundPlayerFactory} from './styling/player_factory';
import {ANIMATION_PROP_PREFIX, allocateDirectiveIntoContext, createEmptyStylingContext, forceClassesAsString, forceStylesAsString, getStylingContext, hasClassInput, hasStyleInput, hasStyling, isAnimationProp} from './styling/util'; import {ANIMATION_PROP_PREFIX, allocateDirectiveIntoContext, createEmptyStylingContext, forceClassesAsString, forceStylesAsString, getStylingContext, hasClassInput, hasStyleInput, hasStyling, isAnimationProp} from './styling/util';
import {NO_CHANGE} from './tokens'; import {NO_CHANGE} from './tokens';
import {INTERPOLATION_DELIMITER, applyOnCreateInstructions, findComponentView, getComponentViewByIndex, getLViewParent, getNativeByIndex, getNativeByTNode, getRootContext, getRootView, getTNode, isComponent, isComponentDef, isContentQueryHost, isRootView, loadInternal, readElementValue, readPatchedLView, renderStringify} from './util'; import {INTERPOLATION_DELIMITER, renderStringify} from './util/misc_utils';
import {findComponentView, getLViewParent, getRootContext, getRootView} from './util/view_traversal_utils';
import {getComponentViewByIndex, getNativeByIndex, getNativeByTNode, getTNode, isComponent, isComponentDef, isContentQueryHost, isRootView, loadInternal, readElementValue, readPatchedLView} from './util/view_utils';

View File

@ -18,7 +18,7 @@ import {componentNeedsResolution, maybeQueueResolutionOfComponentResources} from
import {ViewEncapsulation} from '../../metadata/view'; import {ViewEncapsulation} from '../../metadata/view';
import {EMPTY_ARRAY, EMPTY_OBJ} from '../empty'; import {EMPTY_ARRAY, EMPTY_OBJ} from '../empty';
import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF} from '../fields'; import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF} from '../fields';
import {renderStringify} from '../util'; import {renderStringify} from '../util/misc_utils';
import {angularCoreEnv} from './environment'; import {angularCoreEnv} from './environment';
import {flushModuleScopingQueueAsMuchAsPossible, patchComponentDefWithScope, transitiveScopesFor} from './module'; import {flushModuleScopingQueueAsMuchAsPossible, patchComponentDefWithScope, transitiveScopesFor} from './module';

View File

@ -19,7 +19,7 @@ import {getComponentDef, getDirectiveDef, getNgModuleDef, getPipeDef} from '../d
import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF, NG_MODULE_DEF, NG_PIPE_DEF} from '../fields'; import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF, NG_MODULE_DEF, NG_PIPE_DEF} from '../fields';
import {ComponentDef} from '../interfaces/definition'; import {ComponentDef} from '../interfaces/definition';
import {NgModuleType} from '../ng_module_ref'; import {NgModuleType} from '../ng_module_ref';
import {renderStringify} from '../util'; import {renderStringify} from '../util/misc_utils';
import {angularCoreEnv} from './environment'; import {angularCoreEnv} from './environment';

View File

@ -11,7 +11,7 @@ import {reflectDependencies} from '../../di/jit/util';
import {Type} from '../../interface/type'; import {Type} from '../../interface/type';
import {Pipe} from '../../metadata/directives'; import {Pipe} from '../../metadata/directives';
import {NG_PIPE_DEF} from '../fields'; import {NG_PIPE_DEF} from '../fields';
import {renderStringify} from '../util'; import {renderStringify} from '../util/misc_utils';
import {angularCoreEnv} from './environment'; import {angularCoreEnv} from './environment';

View File

@ -19,7 +19,9 @@ import {unusedValueExportToPlacateAjd as unused3} from './interfaces/projection'
import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, isProceduralRenderer, unusedValueExportToPlacateAjd as unused4} from './interfaces/renderer'; import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, isProceduralRenderer, unusedValueExportToPlacateAjd as unused4} from './interfaces/renderer';
import {CHILD_HEAD, CLEANUP, FLAGS, HEADER_OFFSET, HookData, LView, LViewFlags, NEXT, PARENT, QUERIES, RENDERER, TVIEW, T_HOST, unusedValueExportToPlacateAjd as unused5} from './interfaces/view'; import {CHILD_HEAD, CLEANUP, FLAGS, HEADER_OFFSET, HookData, LView, LViewFlags, NEXT, PARENT, QUERIES, RENDERER, TVIEW, T_HOST, unusedValueExportToPlacateAjd as unused5} from './interfaces/view';
import {assertNodeType} from './node_assert'; import {assertNodeType} from './node_assert';
import {findComponentView, getLViewParent, getNativeByTNode, isComponent, isLContainer, isLView, isRootView, readElementValue, renderStringify} from './util'; import {renderStringify} from './util/misc_utils';
import {findComponentView, getLViewParent} from './util/view_traversal_utils';
import {getNativeByTNode, isComponent, isLContainer, isLView, isRootView, readElementValue} from './util/view_utils';
const unusedValueToPlacateAjd = unused1 + unused2 + unused3 + unused4 + unused5; const unusedValueToPlacateAjd = unused1 + unused2 + unused3 + unused4 + unused5;

View File

@ -0,0 +1,61 @@
/**
* @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 {RelativeInjectorLocation} from './interfaces/injector';
import {TContainerNode, TElementNode, TNode} from './interfaces/node';
import {DECLARATION_VIEW, LView, T_HOST} from './interfaces/view';
import {getParentInjectorViewOffset} from './util/injector_utils';
export function applyOnCreateInstructions(tNode: TNode) {
// there may be some instructions that need to run in a specific
// order because the CREATE block in a directive runs before the
// CREATE block in a template. To work around this instructions
// can get access to the function array below and defer any code
// to run after the element is created.
let fns: Function[]|null;
if (fns = tNode.onElementCreationFns) {
for (let i = 0; i < fns.length; i++) {
fns[i]();
}
tNode.onElementCreationFns = null;
}
}
/**
* Unwraps a parent injector location number to find the view offset from the current injector,
* then walks up the declaration view tree until the TNode of the parent injector is found.
*
* @param location The location of the parent injector, which contains the view offset
* @param startView The LView instance from which to start walking up the view tree
* @param startTNode The TNode instance of the starting element
* @returns The TNode of the parent injector
*/
export function getParentInjectorTNode(
location: RelativeInjectorLocation, startView: LView, startTNode: TNode): TElementNode|
TContainerNode|null {
if (startTNode.parent && startTNode.parent.injectorIndex !== -1) {
// view offset is 0
const injectorIndex = startTNode.parent.injectorIndex;
let parentTNode = startTNode.parent;
while (parentTNode.parent != null && injectorIndex == parentTNode.injectorIndex) {
parentTNode = parentTNode.parent;
}
return parentTNode;
}
let viewOffset = getParentInjectorViewOffset(location);
// view offset is 1
let parentView = startView;
let parentTNode = startView[T_HOST] as TElementNode;
// view offset is superior to 1
while (viewOffset > 1) {
parentView = parentView[DECLARATION_VIEW] !;
parentTNode = parentView[T_HOST] as TElementNode;
viewOffset--;
}
return parentTNode;
}

View File

@ -12,7 +12,7 @@ import {scheduleTick} from './instructions';
import {ComponentInstance, DirectiveInstance, Player} from './interfaces/player'; import {ComponentInstance, DirectiveInstance, Player} from './interfaces/player';
import {RootContextFlags} from './interfaces/view'; import {RootContextFlags} from './interfaces/view';
import {addPlayerInternal, getOrCreatePlayerContext, getPlayerContext, getPlayersInternal, getStylingContext, throwInvalidRefError} from './styling/util'; import {addPlayerInternal, getOrCreatePlayerContext, getPlayerContext, getPlayersInternal, getStylingContext, throwInvalidRefError} from './styling/util';
import {getRootContext} from './util'; import {getRootContext} from './util/view_traversal_utils';
/** /**
* Adds a player to an element, directive or component instance that will later be * Adds a player to an element, directive or component instance that will later be

View File

@ -13,7 +13,7 @@ import {RElement, Renderer3, RendererStyleFlags3, isProceduralRenderer} from '..
import {DirectiveOwnerAndPlayerBuilderIndex, DirectiveRegistryValues, DirectiveRegistryValuesIndex, InitialStylingValues, InitialStylingValuesIndex, MapBasedOffsetValues, MapBasedOffsetValuesIndex, SinglePropOffsetValues, SinglePropOffsetValuesIndex, StylingContext, StylingFlags, StylingIndex} from '../interfaces/styling'; import {DirectiveOwnerAndPlayerBuilderIndex, DirectiveRegistryValues, DirectiveRegistryValuesIndex, InitialStylingValues, InitialStylingValuesIndex, MapBasedOffsetValues, MapBasedOffsetValuesIndex, SinglePropOffsetValues, SinglePropOffsetValuesIndex, StylingContext, StylingFlags, StylingIndex} from '../interfaces/styling';
import {LView, RootContext} from '../interfaces/view'; import {LView, RootContext} from '../interfaces/view';
import {NO_CHANGE} from '../tokens'; import {NO_CHANGE} from '../tokens';
import {getRootContext} from '../util'; import {getRootContext} from '../util/view_traversal_utils';
import {BoundPlayerFactory} from './player_factory'; import {BoundPlayerFactory} from './player_factory';
import {addPlayerInternal, allocPlayerContext, allocateDirectiveIntoContext, createEmptyStylingContext, getPlayerContext} from './util'; import {addPlayerInternal, allocPlayerContext, allocateDirectiveIntoContext, createEmptyStylingContext, getPlayerContext} from './util';

View File

@ -16,7 +16,7 @@ import {PlayState, Player, PlayerContext, PlayerIndex} from '../interfaces/playe
import {RElement} from '../interfaces/renderer'; import {RElement} from '../interfaces/renderer';
import {InitialStylingValues, InitialStylingValuesIndex, StylingContext, StylingFlags, StylingIndex} from '../interfaces/styling'; import {InitialStylingValues, InitialStylingValuesIndex, StylingContext, StylingFlags, StylingIndex} from '../interfaces/styling';
import {HEADER_OFFSET, HOST, LView, RootContext} from '../interfaces/view'; import {HEADER_OFFSET, HOST, LView, RootContext} from '../interfaces/view';
import {getTNode} from '../util'; import {getTNode} from '../util/view_utils';
import {CorePlayerHandler} from './core_player_handler'; import {CorePlayerHandler} from './core_player_handler';

View File

@ -1,363 +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 {assertDataInRange, assertDefined, assertGreaterThan, assertLessThan} from '../util/assert';
import {global} from '../util/global';
import {assertLView} from './assert';
import {LCONTAINER_LENGTH, LContainer} from './interfaces/container';
import {LContext, MONKEY_PATCH_KEY_NAME} from './interfaces/context';
import {ComponentDef, DirectiveDef} from './interfaces/definition';
import {NO_PARENT_INJECTOR, RelativeInjectorLocation, RelativeInjectorLocationFlags} from './interfaces/injector';
import {TContainerNode, TElementNode, TNode, TNodeFlags, TNodeType} from './interfaces/node';
import {RComment, RElement, RText} from './interfaces/renderer';
import {CONTEXT, DECLARATION_VIEW, FLAGS, HEADER_OFFSET, HOST, LView, LViewFlags, PARENT, RootContext, TData, TVIEW, T_HOST} from './interfaces/view';
/**
* Gets the parent LView of the passed LView, if the PARENT is an LContainer, will get the parent of
* that LContainer, which is an LView
* @param lView the lView whose parent to get
*/
export function getLViewParent(lView: LView): LView|null {
ngDevMode && assertLView(lView);
const parent = lView[PARENT];
return isLContainer(parent) ? parent[PARENT] ! : parent;
}
/**
* Returns true if the value is an {@link LView}
* @param value the value to check
*/
export function isLView(value: any): value is LView {
return Array.isArray(value) && value.length >= HEADER_OFFSET;
}
/**
* Returns whether the values are different from a change detection stand point.
*
* Constraints are relaxed in checkNoChanges mode. See `devModeEqual` for details.
*/
export function isDifferent(a: any, b: any): boolean {
// NaN is the only value that is not equal to itself so the first
// test checks if both a and b are not NaN
return !(a !== a && b !== b) && a !== b;
}
/**
* Used for stringify render output in Ivy.
*/
export function renderStringify(value: any): string {
if (typeof value == 'function') return value.name || value;
if (typeof value == 'string') return value;
if (value == null) return '';
if (typeof value == 'object' && typeof value.type == 'function')
return value.type.name || value.type;
return '' + value;
}
/**
* Flattens an array in non-recursive way. Input arrays are not modified.
*/
export function flatten(list: any[]): any[] {
const result: any[] = [];
let i = 0;
while (i < list.length) {
const item = list[i];
if (Array.isArray(item)) {
if (item.length > 0) {
list = item.concat(list.slice(i + 1));
i = 0;
} else {
i++;
}
} else {
result.push(item);
i++;
}
}
return result;
}
/** Retrieves a value from any `LView` or `TData`. */
export function loadInternal<T>(view: LView | TData, index: number): T {
ngDevMode && assertDataInRange(view, index + HEADER_OFFSET);
return view[index + HEADER_OFFSET];
}
/**
* Takes the value of a slot in `LView` and returns the element node.
*
* Normally, element nodes are stored flat, but if the node has styles/classes on it,
* it might be wrapped in a styling context. Or if that node has a directive that injects
* ViewContainerRef, it may be wrapped in an LContainer. Or if that node is a component,
* it will be wrapped in LView. It could even have all three, so we keep looping
* until we find something that isn't an array.
*
* @param value The initial value in `LView`
*/
export function readElementValue(value: any): RElement {
while (Array.isArray(value)) {
value = value[HOST] as any;
}
return value;
}
/**
* Retrieves an element value from the provided `viewData`, by unwrapping
* from any containers, component views, or style contexts.
*/
export function getNativeByIndex(index: number, lView: LView): RElement {
return readElementValue(lView[index + HEADER_OFFSET]);
}
export function getNativeByTNode(tNode: TNode, hostView: LView): RElement|RText|RComment {
return readElementValue(hostView[tNode.index]);
}
export function getTNode(index: number, view: LView): TNode {
ngDevMode && assertGreaterThan(index, -1, 'wrong index for TNode');
ngDevMode && assertLessThan(index, view[TVIEW].data.length, 'wrong index for TNode');
return view[TVIEW].data[index + HEADER_OFFSET] as TNode;
}
export function getComponentViewByIndex(nodeIndex: number, hostView: LView): LView {
// Could be an LView or an LContainer. If LContainer, unwrap to find LView.
const slotValue = hostView[nodeIndex];
const lView = isLView(slotValue) ? slotValue : slotValue[HOST];
ngDevMode && assertLView(lView);
return lView;
}
export function isContentQueryHost(tNode: TNode): boolean {
return (tNode.flags & TNodeFlags.hasContentQuery) !== 0;
}
export function isComponent(tNode: TNode): boolean {
return (tNode.flags & TNodeFlags.isComponent) === TNodeFlags.isComponent;
}
export function isComponentDef<T>(def: DirectiveDef<T>): def is ComponentDef<T> {
return (def as ComponentDef<T>).template !== null;
}
export function isLContainer(value: any): value is LContainer {
// Styling contexts are also arrays, but their first index contains an element node
return Array.isArray(value) && value.length === LCONTAINER_LENGTH;
}
export function isRootView(target: LView): boolean {
return (target[FLAGS] & LViewFlags.IsRoot) !== 0;
}
/**
* Retrieve the root view from any component or `LView` by walking the parent `LView` until
* reaching the root `LView`.
*
* @param componentOrLView any component or `LView`
*/
export function getRootView(componentOrLView: LView | {}): LView {
ngDevMode && assertDefined(componentOrLView, 'component');
let lView = isLView(componentOrLView) ? componentOrLView : readPatchedLView(componentOrLView) !;
while (lView && !(lView[FLAGS] & LViewFlags.IsRoot)) {
lView = getLViewParent(lView) !;
}
ngDevMode && assertLView(lView);
return lView;
}
/**
* Returns the `RootContext` instance that is associated with
* the application where the target is situated. It does this by walking the parent views until it
* gets to the root view, then getting the context off of that.
*
* @param viewOrComponent the `LView` or component to get the root context for.
*/
export function getRootContext(viewOrComponent: LView | {}): RootContext {
const rootView = getRootView(viewOrComponent);
ngDevMode &&
assertDefined(rootView[CONTEXT], 'RootView has no context. Perhaps it is disconnected?');
return rootView[CONTEXT] as RootContext;
}
/**
* Returns the monkey-patch value data present on the target (which could be
* a component, directive or a DOM node).
*/
export function readPatchedData(target: any): LView|LContext|null {
ngDevMode && assertDefined(target, 'Target expected');
return target[MONKEY_PATCH_KEY_NAME];
}
export function readPatchedLView(target: any): LView|null {
const value = readPatchedData(target);
if (value) {
return Array.isArray(value) ? value : (value as LContext).lView;
}
return null;
}
export function hasParentInjector(parentLocation: RelativeInjectorLocation): boolean {
return parentLocation !== NO_PARENT_INJECTOR;
}
export function getParentInjectorIndex(parentLocation: RelativeInjectorLocation): number {
return (parentLocation as any as number) & RelativeInjectorLocationFlags.InjectorIndexMask;
}
export function getParentInjectorViewOffset(parentLocation: RelativeInjectorLocation): number {
return (parentLocation as any as number) >> RelativeInjectorLocationFlags.ViewOffsetShift;
}
/**
* Unwraps a parent injector location number to find the view offset from the current injector,
* then walks up the declaration view tree until the view is found that contains the parent
* injector.
*
* @param location The location of the parent injector, which contains the view offset
* @param startView The LView instance from which to start walking up the view tree
* @returns The LView instance that contains the parent injector
*/
export function getParentInjectorView(location: RelativeInjectorLocation, startView: LView): LView {
let viewOffset = getParentInjectorViewOffset(location);
let parentView = startView;
// For most cases, the parent injector can be found on the host node (e.g. for component
// or container), but we must keep the loop here to support the rarer case of deeply nested
// <ng-template> tags or inline views, where the parent injector might live many views
// above the child injector.
while (viewOffset > 0) {
parentView = parentView[DECLARATION_VIEW] !;
viewOffset--;
}
return parentView;
}
/**
* Unwraps a parent injector location number to find the view offset from the current injector,
* then walks up the declaration view tree until the TNode of the parent injector is found.
*
* @param location The location of the parent injector, which contains the view offset
* @param startView The LView instance from which to start walking up the view tree
* @param startTNode The TNode instance of the starting element
* @returns The TNode of the parent injector
*/
export function getParentInjectorTNode(
location: RelativeInjectorLocation, startView: LView, startTNode: TNode): TElementNode|
TContainerNode|null {
if (startTNode.parent && startTNode.parent.injectorIndex !== -1) {
// view offset is 0
const injectorIndex = startTNode.parent.injectorIndex;
let parentTNode = startTNode.parent;
while (parentTNode.parent != null && injectorIndex == parentTNode.injectorIndex) {
parentTNode = parentTNode.parent;
}
return parentTNode;
}
let viewOffset = getParentInjectorViewOffset(location);
// view offset is 1
let parentView = startView;
let parentTNode = startView[T_HOST] as TElementNode;
// view offset is superior to 1
while (viewOffset > 1) {
parentView = parentView[DECLARATION_VIEW] !;
parentTNode = parentView[T_HOST] as TElementNode;
viewOffset--;
}
return parentTNode;
}
export const defaultScheduler =
(typeof requestAnimationFrame !== 'undefined' && requestAnimationFrame || // browser only
setTimeout // everything else
).bind(global);
/**
* Equivalent to ES6 spread, add each item to an array.
*
* @param items The items to add
* @param arr The array to which you want to add the items
*/
export function addAllToArray(items: any[], arr: any[]) {
for (let i = 0; i < items.length; i++) {
arr.push(items[i]);
}
}
/**
* Given a current view, finds the nearest component's host (LElement).
*
* @param lView LView for which we want a host element node
* @returns The host node
*/
export function findComponentView(lView: LView): LView {
let rootTNode = lView[T_HOST];
while (rootTNode && rootTNode.type === TNodeType.View) {
ngDevMode && assertDefined(lView[DECLARATION_VIEW], 'lView[DECLARATION_VIEW]');
lView = lView[DECLARATION_VIEW] !;
rootTNode = lView[T_HOST];
}
ngDevMode && assertLView(lView);
return lView;
}
export function resolveWindow(element: RElement & {ownerDocument: Document}) {
return {name: 'window', target: element.ownerDocument.defaultView};
}
export function resolveDocument(element: RElement & {ownerDocument: Document}) {
return {name: 'document', target: element.ownerDocument};
}
export function resolveBody(element: RElement & {ownerDocument: Document}) {
return {name: 'body', target: element.ownerDocument.body};
}
/**
* The special delimiter we use to separate property names, prefixes, and suffixes
* in property binding metadata. See storeBindingMetadata().
*
* We intentionally use the Unicode "REPLACEMENT CHARACTER" (U+FFFD) as a delimiter
* because it is a very uncommon character that is unlikely to be part of a user's
* property names or interpolation strings. If it is in fact used in a property
* binding, DebugElement.properties will not return the correct value for that
* binding. However, there should be no runtime effect for real applications.
*
* This character is typically rendered as a question mark inside of a diamond.
* See https://en.wikipedia.org/wiki/Specials_(Unicode_block)
*
*/
export const INTERPOLATION_DELIMITER = `<EFBFBD>`;
/**
* Determines whether or not the given string is a property metadata string.
* See storeBindingMetadata().
*/
export function isPropMetadataString(str: string): boolean {
return str.indexOf(INTERPOLATION_DELIMITER) >= 0;
}
export function applyOnCreateInstructions(tNode: TNode) {
// there may be some instructions that need to run in a specific
// order because the CREATE block in a directive runs before the
// CREATE block in a template. To work around this instructions
// can get access to the function array below and defer any code
// to run after the element is created.
let fns: Function[]|null;
if (fns = tNode.onElementCreationFns) {
for (let i = 0; i < fns.length; i++) {
fns[i]();
}
tNode.onElementCreationFns = null;
}
}

View File

@ -0,0 +1,42 @@
/**
* @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
*/
/**
* Equivalent to ES6 spread, add each item to an array.
*
* @param items The items to add
* @param arr The array to which you want to add the items
*/
export function addAllToArray(items: any[], arr: any[]) {
for (let i = 0; i < items.length; i++) {
arr.push(items[i]);
}
}
/**
* Flattens an array in non-recursive way. Input arrays are not modified.
*/
export function flatten(list: any[]): any[] {
const result: any[] = [];
let i = 0;
while (i < list.length) {
const item = list[i];
if (Array.isArray(item)) {
if (item.length > 0) {
list = item.concat(list.slice(i + 1));
i = 0;
} else {
i++;
}
} else {
result.push(item);
i++;
}
}
return result;
}

View File

@ -6,16 +6,18 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {Injector} from '../di/injector'; import {Injector} from '../../di/injector';
import {assertLView} from './assert'; import {assertLView} from '../assert';
import {discoverLocalRefs, getComponentAtNodeIndex, getDirectivesAtNodeIndex, getLContext} from './context_discovery'; import {discoverLocalRefs, getComponentAtNodeIndex, getDirectivesAtNodeIndex, getLContext} from '../context_discovery';
import {NodeInjector} from './di'; import {NodeInjector} from '../di';
import {LContext} from './interfaces/context'; import {LContext} from '../interfaces/context';
import {DirectiveDef} from './interfaces/definition'; import {DirectiveDef} from '../interfaces/definition';
import {TElementNode, TNode, TNodeProviderIndexes} from './interfaces/node'; import {TElementNode, TNode, TNodeProviderIndexes} from '../interfaces/node';
import {CLEANUP, CONTEXT, FLAGS, HOST, LView, LViewFlags, TVIEW} from './interfaces/view'; import {CLEANUP, CONTEXT, FLAGS, HOST, LView, LViewFlags, TVIEW} from '../interfaces/view';
import {getLViewParent, getRootContext, readElementValue, renderStringify} from './util'; import {renderStringify} from './misc_utils';
import {getLViewParent, getRootContext} from './view_traversal_utils';
import {readElementValue} from './view_utils';

View File

@ -5,10 +5,10 @@
* Use of this source code is governed by an MIT-style license that can be * 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 * found in the LICENSE file at https://angular.io/license
*/ */
import {assertDefined} from '../util/assert'; import {assertDefined} from '../../util/assert';
import {global} from '../util/global'; import {global} from '../../util/global';
import {getComponent, getContext, getDirectives, getHostElement, getInjector, getListeners, getPlayers, getRootComponents, getViewComponent, markDirty} from './global_utils_api'; import {getComponent, getContext, getDirectives, getHostElement, getInjector, getListeners, getPlayers, getRootComponents, getViewComponent, markDirty} from '../global_utils_api';

View File

@ -0,0 +1,44 @@
/**
* @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 {NO_PARENT_INJECTOR, RelativeInjectorLocation, RelativeInjectorLocationFlags} from '../interfaces/injector';
import {DECLARATION_VIEW, LView} from '../interfaces/view';
/// Parent Injector Utils ///////////////////////////////////////////////////////////////
export function hasParentInjector(parentLocation: RelativeInjectorLocation): boolean {
return parentLocation !== NO_PARENT_INJECTOR;
}
export function getParentInjectorIndex(parentLocation: RelativeInjectorLocation): number {
return (parentLocation as any as number) & RelativeInjectorLocationFlags.InjectorIndexMask;
}
export function getParentInjectorViewOffset(parentLocation: RelativeInjectorLocation): number {
return (parentLocation as any as number) >> RelativeInjectorLocationFlags.ViewOffsetShift;
}
/**
* Unwraps a parent injector location number to find the view offset from the current injector,
* then walks up the declaration view tree until the view is found that contains the parent
* injector.
*
* @param location The location of the parent injector, which contains the view offset
* @param startView The LView instance from which to start walking up the view tree
* @returns The LView instance that contains the parent injector
*/
export function getParentInjectorView(location: RelativeInjectorLocation, startView: LView): LView {
let viewOffset = getParentInjectorViewOffset(location);
let parentView = startView;
// For most cases, the parent injector can be found on the host node (e.g. for component
// or container), but we must keep the loop here to support the rarer case of deeply nested
// <ng-template> tags or inline views, where the parent injector might live many views
// above the child injector.
while (viewOffset > 0) {
parentView = parentView[DECLARATION_VIEW] !;
viewOffset--;
}
return parentView;
}

View File

@ -0,0 +1,78 @@
/**
* @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 {assertDefined} from '../../util/assert';
import {global} from '../../util/global';
import {RElement} from '../interfaces/renderer';
import {CONTEXT, LView, RootContext} from '../interfaces/view';
import {getRootView} from './view_traversal_utils';
/**
* Returns whether the values are different from a change detection stand point.
*
* Constraints are relaxed in checkNoChanges mode. See `devModeEqual` for details.
*/
export function isDifferent(a: any, b: any): boolean {
// NaN is the only value that is not equal to itself so the first
// test checks if both a and b are not NaN
return !(a !== a && b !== b) && a !== b;
}
/**
* Used for stringify render output in Ivy.
*/
export function renderStringify(value: any): string {
if (typeof value == 'function') return value.name || value;
if (typeof value == 'string') return value;
if (value == null) return '';
if (typeof value == 'object' && typeof value.type == 'function')
return value.type.name || value.type;
return '' + value;
}
export const defaultScheduler =
(typeof requestAnimationFrame !== 'undefined' && requestAnimationFrame || // browser only
setTimeout // everything else
).bind(global);
export function resolveWindow(element: RElement & {ownerDocument: Document}) {
return {name: 'window', target: element.ownerDocument.defaultView};
}
export function resolveDocument(element: RElement & {ownerDocument: Document}) {
return {name: 'document', target: element.ownerDocument};
}
export function resolveBody(element: RElement & {ownerDocument: Document}) {
return {name: 'body', target: element.ownerDocument.body};
}
/**
* The special delimiter we use to separate property names, prefixes, and suffixes
* in property binding metadata. See storeBindingMetadata().
*
* We intentionally use the Unicode "REPLACEMENT CHARACTER" (U+FFFD) as a delimiter
* because it is a very uncommon character that is unlikely to be part of a user's
* property names or interpolation strings. If it is in fact used in a property
* binding, DebugElement.properties will not return the correct value for that
* binding. However, there should be no runtime effect for real applications.
*
* This character is typically rendered as a question mark inside of a diamond.
* See https://en.wikipedia.org/wiki/Specials_(Unicode_block)
*
*/
export const INTERPOLATION_DELIMITER = `<EFBFBD>`;
/**
* Determines whether or not the given string is a property metadata string.
* See storeBindingMetadata().
*/
export function isPropMetadataString(str: string): boolean {
return str.indexOf(INTERPOLATION_DELIMITER) >= 0;
}

View File

@ -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 {assertDefined} from '../../util/assert';
import {assertLView} from '../assert';
import {TNodeType} from '../interfaces/node';
import {CONTEXT, DECLARATION_VIEW, FLAGS, LView, LViewFlags, PARENT, RootContext, T_HOST} from '../interfaces/view';
import {isLContainer, isLView, readPatchedLView} from './view_utils';
/**
* Gets the parent LView of the passed LView, if the PARENT is an LContainer, will get the parent of
* that LContainer, which is an LView
* @param lView the lView whose parent to get
*/
export function getLViewParent(lView: LView): LView|null {
ngDevMode && assertLView(lView);
const parent = lView[PARENT];
return isLContainer(parent) ? parent[PARENT] ! : parent;
}
/**
* Retrieve the root view from any component or `LView` by walking the parent `LView` until
* reaching the root `LView`.
*
* @param componentOrLView any component or `LView`
*/
export function getRootView(componentOrLView: LView | {}): LView {
ngDevMode && assertDefined(componentOrLView, 'component');
let lView = isLView(componentOrLView) ? componentOrLView : readPatchedLView(componentOrLView) !;
while (lView && !(lView[FLAGS] & LViewFlags.IsRoot)) {
lView = getLViewParent(lView) !;
}
ngDevMode && assertLView(lView);
return lView;
}
/**
* Given a current view, finds the nearest component's host (LElement).
*
* @param lView LView for which we want a host element node
* @returns The host node
*/
export function findComponentView(lView: LView): LView {
let rootTNode = lView[T_HOST];
while (rootTNode && rootTNode.type === TNodeType.View) {
ngDevMode && assertDefined(lView[DECLARATION_VIEW], 'lView[DECLARATION_VIEW]');
lView = lView[DECLARATION_VIEW] !;
rootTNode = lView[T_HOST];
}
ngDevMode && assertLView(lView);
return lView;
}
/**
* Returns the `RootContext` instance that is associated with
* the application where the target is situated. It does this by walking the parent views until it
* gets to the root view, then getting the context off of that.
*
* @param viewOrComponent the `LView` or component to get the root context for.
*/
export function getRootContext(viewOrComponent: LView | {}): RootContext {
const rootView = getRootView(viewOrComponent);
ngDevMode &&
assertDefined(rootView[CONTEXT], 'RootView has no context. Perhaps it is disconnected?');
return rootView[CONTEXT] as RootContext;
}

View File

@ -0,0 +1,112 @@
/**
* @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 {assertDataInRange, assertDefined, assertGreaterThan, assertLessThan} from '../../util/assert';
import {LCONTAINER_LENGTH, LContainer} from '../interfaces/container';
import {LContext, MONKEY_PATCH_KEY_NAME} from '../interfaces/context';
import {ComponentDef, DirectiveDef} from '../interfaces/definition';
import {TNode, TNodeFlags} from '../interfaces/node';
import {RComment, RElement, RText} from '../interfaces/renderer';
import {FLAGS, HEADER_OFFSET, HOST, LView, LViewFlags, TData, TVIEW} from '../interfaces/view';
/**
* Takes the value of a slot in `LView` and returns the element node.
*
* Normally, element nodes are stored flat, but if the node has styles/classes on it,
* it might be wrapped in a styling context. Or if that node has a directive that injects
* ViewContainerRef, it may be wrapped in an LContainer. Or if that node is a component,
* it will be wrapped in LView. It could even have all three, so we keep looping
* until we find something that isn't an array.
*
* @param value The initial value in `LView`
*/
export function readElementValue(value: any): RElement {
while (Array.isArray(value)) {
value = value[HOST] as any;
}
return value;
}
/**
* Retrieves an element value from the provided `viewData`, by unwrapping
* from any containers, component views, or style contexts.
*/
export function getNativeByIndex(index: number, lView: LView): RElement {
return readElementValue(lView[index + HEADER_OFFSET]);
}
export function getNativeByTNode(tNode: TNode, hostView: LView): RElement|RText|RComment {
return readElementValue(hostView[tNode.index]);
}
export function getTNode(index: number, view: LView): TNode {
ngDevMode && assertGreaterThan(index, -1, 'wrong index for TNode');
ngDevMode && assertLessThan(index, view[TVIEW].data.length, 'wrong index for TNode');
return view[TVIEW].data[index + HEADER_OFFSET] as TNode;
}
/**
* Returns true if the value is an {@link LView}
* @param value the value to check
*/
export function isLView(value: any): value is LView {
return Array.isArray(value) && value.length >= HEADER_OFFSET;
}
/** Retrieves a value from any `LView` or `TData`. */
export function loadInternal<T>(view: LView | TData, index: number): T {
ngDevMode && assertDataInRange(view, index + HEADER_OFFSET);
return view[index + HEADER_OFFSET];
}
export function getComponentViewByIndex(nodeIndex: number, hostView: LView): LView {
// Could be an LView or an LContainer. If LContainer, unwrap to find LView.
const slotValue = hostView[nodeIndex];
const lView = isLView(slotValue) ? slotValue : slotValue[HOST];
return lView;
}
export function isContentQueryHost(tNode: TNode): boolean {
return (tNode.flags & TNodeFlags.hasContentQuery) !== 0;
}
export function isComponent(tNode: TNode): boolean {
return (tNode.flags & TNodeFlags.isComponent) === TNodeFlags.isComponent;
}
export function isComponentDef<T>(def: DirectiveDef<T>): def is ComponentDef<T> {
return (def as ComponentDef<T>).template !== null;
}
export function isLContainer(value: any): value is LContainer {
// Styling contexts are also arrays, but their first index contains an element node
return Array.isArray(value) && value.length === LCONTAINER_LENGTH;
}
export function isRootView(target: LView): boolean {
return (target[FLAGS] & LViewFlags.IsRoot) !== 0;
}
/**
* Returns the monkey-patch value data present on the target (which could be
* a component, directive or a DOM node).
*/
export function readPatchedData(target: any): LView|LContext|null {
ngDevMode && assertDefined(target, 'Target expected');
return target[MONKEY_PATCH_KEY_NAME];
}
export function readPatchedLView(target: any): LView|null {
const value = readPatchedData(target);
if (value) {
return Array.isArray(value) ? value : (value as LContext).lView;
}
return null;
}

View File

@ -25,8 +25,11 @@ import {RComment, RElement, isProceduralRenderer} from './interfaces/renderer';
import {CONTEXT, LView, QUERIES, RENDERER, TView, T_HOST} from './interfaces/view'; import {CONTEXT, LView, QUERIES, RENDERER, TView, T_HOST} from './interfaces/view';
import {assertNodeOfPossibleTypes} from './node_assert'; import {assertNodeOfPossibleTypes} from './node_assert';
import {addRemoveViewFromContainer, appendChild, detachView, getBeforeNodeForView, insertView, nativeInsertBefore, nativeNextSibling, nativeParentNode, removeView} from './node_manipulation'; import {addRemoveViewFromContainer, appendChild, detachView, getBeforeNodeForView, insertView, nativeInsertBefore, nativeNextSibling, nativeParentNode, removeView} from './node_manipulation';
import {getParentInjectorTNode} from './node_util';
import {getLView, getPreviousOrParentTNode} from './state'; import {getLView, getPreviousOrParentTNode} from './state';
import {findComponentView, getComponentViewByIndex, getNativeByTNode, getParentInjectorTNode, getParentInjectorView, hasParentInjector, isComponent, isLContainer, isRootView} from './util'; import {getParentInjectorView, hasParentInjector} from './util/injector_utils';
import {findComponentView} from './util/view_traversal_utils';
import {getComponentViewByIndex, getNativeByTNode, isComponent, isLContainer, isRootView} from './util/view_utils';
import {ViewRef} from './view_ref'; import {ViewRef} from './view_ref';

View File

@ -15,7 +15,8 @@ import {checkNoChangesInRootView, checkNoChangesInternal, detectChangesInRootVie
import {TNode, TNodeType, TViewNode} from './interfaces/node'; import {TNode, TNodeType, TViewNode} from './interfaces/node';
import {FLAGS, HOST, LView, LViewFlags, PARENT, T_HOST} from './interfaces/view'; import {FLAGS, HOST, LView, LViewFlags, PARENT, T_HOST} from './interfaces/view';
import {destroyLView} from './node_manipulation'; import {destroyLView} from './node_manipulation';
import {getLViewParent, getNativeByTNode} from './util'; import {getLViewParent} from './util/view_traversal_utils';
import {getNativeByTNode} from './util/view_utils';

View File

@ -8,7 +8,7 @@
import {SANITIZER} from '../render3/interfaces/view'; import {SANITIZER} from '../render3/interfaces/view';
import {getLView} from '../render3/state'; import {getLView} from '../render3/state';
import {renderStringify} from '../render3/util'; import {renderStringify} from '../render3/util/misc_utils';
import {BypassType, allowSanitizationBypass} from './bypass'; import {BypassType, allowSanitizationBypass} from './bypass';
import {_sanitizeHtml as _sanitizeHtml} from './html_sanitizer'; import {_sanitizeHtml as _sanitizeHtml} from './html_sanitizer';

View File

@ -16,7 +16,7 @@ import {ProvidersFeature, defineDirective, elementProperty, load, templateRefExt
import {allocHostVars, bind, container, containerRefreshEnd, containerRefreshStart, createNodeAtIndex, createLView, createTView, directiveInject, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, injectAttribute, interpolation2, projection, projectionDef, reference, template, text, textBinding, elementContainerStart, elementContainerEnd} from '../../src/render3/instructions'; import {allocHostVars, bind, container, containerRefreshEnd, containerRefreshStart, createNodeAtIndex, createLView, createTView, directiveInject, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, injectAttribute, interpolation2, projection, projectionDef, reference, template, text, textBinding, elementContainerStart, elementContainerEnd} from '../../src/render3/instructions';
import {isProceduralRenderer, RElement} from '../../src/render3/interfaces/renderer'; import {isProceduralRenderer, RElement} from '../../src/render3/interfaces/renderer';
import {AttributeMarker, TNodeType} from '../../src/render3/interfaces/node'; import {AttributeMarker, TNodeType} from '../../src/render3/interfaces/node';
import {getNativeByIndex} from '../../src/render3/util'; import {getNativeByIndex} from '../../src/render3/util/view_utils';
import {LViewFlags} from '../../src/render3/interfaces/view'; import {LViewFlags} from '../../src/render3/interfaces/view';
import {enterView, leaveView, getLView} from '../../src/render3/state'; import {enterView, leaveView, getLView} from '../../src/render3/state';
import {ViewRef} from '../../src/render3/view_ref'; import {ViewRef} from '../../src/render3/view_ref';

View File

@ -7,8 +7,8 @@
*/ */
import {StaticInjector} from '../../src/di/injector'; import {StaticInjector} from '../../src/di/injector';
import {createInjector} from '../../src/di/r3_injector'; import {createInjector} from '../../src/di/r3_injector';
import {getComponent, getContext, getDirectives, getInjectionTokens, getInjector, getListeners, getLocalRefs, getRootComponents, getViewComponent, loadLContext} from '../../src/render3/discovery_utils';
import {ProvidersFeature, RenderFlags, defineComponent, defineDirective, elementContainerEnd, elementContainerStart, getHostElement, i18n, i18nApply, i18nExp} from '../../src/render3/index'; import {ProvidersFeature, RenderFlags, defineComponent, defineDirective, elementContainerEnd, elementContainerStart, getHostElement, i18n, i18nApply, i18nExp} from '../../src/render3/index';
import {getComponent, getContext, getDirectives, getInjectionTokens, getInjector, getListeners, getLocalRefs, getRootComponents, getViewComponent, loadLContext} from '../../src/render3/util/discovery_utils';
import {element, elementEnd, elementStart, elementStyling, elementStylingApply, template, bind, elementProperty, text, textBinding, markDirty, listener} from '../../src/render3/instructions'; import {element, elementEnd, elementStart, elementStyling, elementStylingApply, template, bind, elementProperty, text, textBinding, markDirty, listener} from '../../src/render3/instructions';
import {ComponentFixture} from './render_util'; import {ComponentFixture} from './render_util';

View File

@ -7,9 +7,9 @@
*/ */
import {ɵmarkDirty as markDirty} from '@angular/core'; import {ɵmarkDirty as markDirty} from '@angular/core';
import {getComponent, getContext, getDirectives, getHostElement, getInjector, getListeners, getRootComponents, getViewComponent} from '../../src/render3/discovery_utils';
import {GLOBAL_PUBLISH_EXPANDO_KEY, GlobalDevModeContainer, publishDefaultGlobalUtils, publishGlobalUtil} from '../../src/render3/global_utils';
import {getPlayers} from '../../src/render3/players'; import {getPlayers} from '../../src/render3/players';
import {getComponent, getContext, getDirectives, getHostElement, getInjector, getListeners, getRootComponents, getViewComponent} from '../../src/render3/util/discovery_utils';
import {GLOBAL_PUBLISH_EXPANDO_KEY, GlobalDevModeContainer, publishDefaultGlobalUtils, publishGlobalUtil} from '../../src/render3/util/global_utils';
import {global} from '../../src/util/global'; import {global} from '../../src/util/global';
describe('global utils', () => { describe('global utils', () => {

View File

@ -12,7 +12,7 @@ import {defineComponent, defineDirective} from '../../src/render3/definition';
import {getTranslationForTemplate, i18n, i18nApply, i18nAttributes, i18nEnd, i18nExp, i18nPostprocess, i18nStart} from '../../src/render3/i18n'; import {getTranslationForTemplate, i18n, i18nApply, i18nAttributes, i18nEnd, i18nExp, i18nPostprocess, i18nStart} from '../../src/render3/i18n';
import {RenderFlags} from '../../src/render3/interfaces/definition'; import {RenderFlags} from '../../src/render3/interfaces/definition';
import {AttributeMarker} from '../../src/render3/interfaces/node'; import {AttributeMarker} from '../../src/render3/interfaces/node';
import {getNativeByIndex, getTNode} from '../../src/render3/util'; import {getNativeByIndex, getTNode} from '../../src/render3/util/view_utils';
import {NgIf} from './common_with_def'; import {NgIf} from './common_with_def';
import {allocHostVars, element, elementEnd, elementStart, template, text, nextContext, bind, elementProperty, projectionDef, projection, elementContainerStart, elementContainerEnd} from '../../src/render3/instructions'; import {allocHostVars, element, elementEnd, elementStart, template, text, nextContext, bind, elementProperty, projectionDef, projection, elementContainerStart, elementContainerEnd} from '../../src/render3/instructions';
import {COMMENT_MARKER, ELEMENT_MARKER, I18nMutateOpCode, I18nUpdateOpCode, I18nUpdateOpCodes, TI18n} from '../../src/render3/interfaces/i18n'; import {COMMENT_MARKER, ELEMENT_MARKER, I18nMutateOpCode, I18nUpdateOpCode, I18nUpdateOpCodes, TI18n} from '../../src/render3/interfaces/i18n';

View File

@ -9,11 +9,11 @@
import {Component as _Component, ComponentFactoryResolver, ElementRef, InjectFlags, Injectable as _Injectable, InjectionToken, InjectorType, Provider, RendererFactory2, ViewContainerRef, defineInjectable, defineInjector, inject, ɵNgModuleDef as NgModuleDef} from '../../src/core'; import {Component as _Component, ComponentFactoryResolver, ElementRef, InjectFlags, Injectable as _Injectable, InjectionToken, InjectorType, Provider, RendererFactory2, ViewContainerRef, defineInjectable, defineInjector, inject, ɵNgModuleDef as NgModuleDef} from '../../src/core';
import {forwardRef} from '../../src/di/forward_ref'; import {forwardRef} from '../../src/di/forward_ref';
import {createInjector} from '../../src/di/r3_injector'; import {createInjector} from '../../src/di/r3_injector';
import {getInjector} from '../../src/render3/discovery_utils';
import {ProvidersFeature, defineComponent, defineDirective, directiveInject, injectComponentFactoryResolver} from '../../src/render3/index'; import {ProvidersFeature, defineComponent, defineDirective, directiveInject, injectComponentFactoryResolver} from '../../src/render3/index';
import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, interpolation1, text, textBinding} from '../../src/render3/instructions'; import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, interpolation1, text, textBinding} from '../../src/render3/instructions';
import {RenderFlags} from '../../src/render3/interfaces/definition'; import {RenderFlags} from '../../src/render3/interfaces/definition';
import {NgModuleFactory} from '../../src/render3/ng_module_ref'; import {NgModuleFactory} from '../../src/render3/ng_module_ref';
import {getInjector} from '../../src/render3/util/discovery_utils';
import {getRendererFactory2} from './imported_renderer2'; import {getRendererFactory2} from './imported_renderer2';
import {ComponentFixture} from './render_util'; import {ComponentFixture} from './render_util';

View File

@ -11,7 +11,7 @@ import {ElementRef, QueryList, TemplateRef, ViewContainerRef} from '@angular/cor
import {EventEmitter} from '../..'; import {EventEmitter} from '../..';
import {AttributeMarker, ProvidersFeature, defineComponent, defineDirective, detectChanges} from '../../src/render3/index'; import {AttributeMarker, ProvidersFeature, defineComponent, defineDirective, detectChanges} from '../../src/render3/index';
import {getNativeByIndex} from '../../src/render3/util'; import {getNativeByIndex} from '../../src/render3/util/view_utils';
import {bind, container, containerRefreshEnd, containerRefreshStart, directiveInject, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, load, reference, template, text} from '../../src/render3/instructions'; import {bind, container, containerRefreshEnd, containerRefreshStart, directiveInject, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, load, reference, template, text} from '../../src/render3/instructions';
import {RenderFlags} from '../../src/render3/interfaces/definition'; import {RenderFlags} from '../../src/render3/interfaces/definition';

View File

@ -33,7 +33,7 @@ import {PlayerHandler} from '../../src/render3/interfaces/player';
import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, RendererFactory3, RendererStyleFlags3, domRendererFactory3} from '../../src/render3/interfaces/renderer'; import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, RendererFactory3, RendererStyleFlags3, domRendererFactory3} from '../../src/render3/interfaces/renderer';
import {HEADER_OFFSET, LView} from '../../src/render3/interfaces/view'; import {HEADER_OFFSET, LView} from '../../src/render3/interfaces/view';
import {destroyLView} from '../../src/render3/node_manipulation'; import {destroyLView} from '../../src/render3/node_manipulation';
import {getRootView} from '../../src/render3/util'; import {getRootView} from '../../src/render3/util/view_traversal_utils';
import {Sanitizer} from '../../src/sanitization/security'; import {Sanitizer} from '../../src/sanitization/security';
import {getRendererFactory2} from './imported_renderer2'; import {getRendererFactory2} from './imported_renderer2';

View File

@ -8,7 +8,8 @@
import {devModeEqual} from '@angular/core/src/change_detection/change_detection_util'; import {devModeEqual} from '@angular/core/src/change_detection/change_detection_util';
import {flatten, isDifferent} from '../../src/render3/util'; import {flatten} from '../../src/render3/util/array_utils';
import {isDifferent} from '../../src/render3/util/misc_utils';
describe('util', () => { describe('util', () => {

View File

@ -17,7 +17,7 @@ import {RElement} from '../../src/render3/interfaces/renderer';
import {NgModuleFactory} from '../../src/render3/ng_module_ref'; import {NgModuleFactory} from '../../src/render3/ng_module_ref';
import {pipe, pipeBind1} from '../../src/render3/pipe'; import {pipe, pipeBind1} from '../../src/render3/pipe';
import {getLView} from '../../src/render3/state'; import {getLView} from '../../src/render3/state';
import {getNativeByIndex} from '../../src/render3/util'; import {getNativeByIndex} from '../../src/render3/util/view_utils';
import {templateRefExtractor} from '../../src/render3/view_engine_compatibility_prebound'; import {templateRefExtractor} from '../../src/render3/view_engine_compatibility_prebound';
import {NgForOf} from '../../test/render3/common_with_def'; import {NgForOf} from '../../test/render3/common_with_def';