Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LFrame #33178

Closed
wants to merge 3 commits into from
Closed

LFrame #33178

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
/bazel-out
/integration/bazel/bazel-*
e2e_test.*
*.log
node_modules
tools/gulp-tasks/cldr/cldr-data/

Expand Down
4 changes: 2 additions & 2 deletions integration/_payload-limits.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"master": {
"uncompressed": {
"runtime-es2015": 1485,
"main-es2015": 14440,
"main-es2015": 14678,
"polyfills-es2015": 36808
}
}
Expand Down Expand Up @@ -64,4 +64,4 @@
}
}
}
}
}
11 changes: 3 additions & 8 deletions packages/core/src/render3/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {TElementNode, TNode, TNodeType} from './interfaces/node';
import {PlayerHandler} from './interfaces/player';
import {RElement, Renderer3, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
import {CONTEXT, HEADER_OFFSET, LView, LViewFlags, RootContext, RootContextFlags, TVIEW} from './interfaces/view';
import {getPreviousOrParentTNode, incrementActiveDirectiveId, resetComponentState, selectView, setActiveHostElement} from './state';
import {enterView, getPreviousOrParentTNode, incrementActiveDirectiveId, leaveView, setActiveHostElement} from './state';
import {publishDefaultGlobalUtils} from './util/global_utils';
import {defaultScheduler, stringifyForError} from './util/misc_utils';
import {getRootContext} from './util/view_traversal_utils';
Expand Down Expand Up @@ -111,10 +111,6 @@ export function renderComponent<T>(
ngDevMode && publishDefaultGlobalUtils();
ngDevMode && assertComponentType(componentType);

// this is preemptively set to avoid having test and debug code accidentally
// read data from a previous application state...
setActiveHostElement(null);

const rendererFactory = opts.rendererFactory || domRendererFactory3;
const sanitizer = opts.sanitizer || null;
const componentDef = getComponentDef<T>(componentType) !;
Expand All @@ -133,7 +129,7 @@ export function renderComponent<T>(
null, rootTView, rootContext, rootFlags, null, null, rendererFactory, renderer, undefined,
opts.injector || null);

const oldView = selectView(rootView, null);
enterView(rootView, null);
let component: T;

try {
Expand All @@ -149,7 +145,7 @@ export function renderComponent<T>(
refreshView(rootView, rootTView, null, null);

} finally {
selectView(oldView, null);
leaveView();
if (rendererFactory.end) rendererFactory.end();
}

Expand All @@ -170,7 +166,6 @@ export function renderComponent<T>(
export function createRootComponentView(
rNode: RElement | null, def: ComponentDef<any>, rootView: LView,
rendererFactory: RendererFactory3, renderer: Renderer3, sanitizer?: Sanitizer | null): LView {
resetComponentState();
const tView = rootView[TVIEW];
ngDevMode && assertDataInRange(rootView, 0 + HEADER_OFFSET);
rootView[0 + HEADER_OFFSET] = rNode;
Expand Down
13 changes: 7 additions & 6 deletions packages/core/src/render3/component_ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {ComponentDef} from './interfaces/definition';
import {TContainerNode, TElementContainerNode, TElementNode} from './interfaces/node';
import {RNode, RendererFactory3, domRendererFactory3, isProceduralRenderer} from './interfaces/renderer';
import {LView, LViewFlags, TVIEW} from './interfaces/view';
import {namespaceHTMLInternal, selectView} from './state';
import {enterView, leaveView} from './state';
import {defaultScheduler} from './util/misc_utils';
import {getTNode} from './util/view_utils';
import {createElementRef} from './view_engine_compatibility';
Expand Down Expand Up @@ -133,9 +133,6 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
rootViewInjector.get(RendererFactory2, domRendererFactory3) as RendererFactory3;
const sanitizer = rootViewInjector.get(Sanitizer, null);

// Ensure that the namespace for the root node is correct,
// otherwise the browser might not render out the element properly.
namespaceHTMLInternal();
const hostRNode = rootSelectorOrNode ?
locateHostElement(rendererFactory, rootSelectorOrNode) :
elementCreate(this.selector, rendererFactory.createRenderer(null, this.componentDef), null);
Expand Down Expand Up @@ -167,7 +164,11 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
rootViewInjector);

// rootView is the parent when bootstrapping
const oldLView = selectView(rootLView, null);
// TODO(misko): it looks like we are entering view here but we don't really need to as

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, we should fix it, I was toying with this once

// `renderView` does that. However as the code is written it is needed because
// `createRootComponentView` and `createRootComponent` both read global state. Fixing those
// issues would allow us to drop this.
enterView(rootLView, null);

let component: T;
let tElementNode: TElementNode;
Expand All @@ -194,7 +195,7 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {

renderView(rootLView, rootTView, null);
} finally {
selectView(oldLView, null);
leaveView();
}

const componentRef = new ComponentRef(
Expand Down
24 changes: 10 additions & 14 deletions packages/core/src/render3/di.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {isForwardRef, resolveForwardRef} from '../di/forward_ref';
import {InjectionToken} from '../di/injection_token';
import {Injector} from '../di/injector';
import {injectRootLimpMode, setInjectImplementation} from '../di/injector_compatibility';
import {getInjectableDef, getInjectorDef} from '../di/interface/defs';
import {getInjectorDef} from '../di/interface/defs';
import {InjectFlags} from '../di/interface/injector';
import {Type} from '../interface/type';
import {assertDefined, assertEqual} from '../util/assert';
Expand All @@ -19,11 +19,11 @@ import {getFactoryDef} from './definition';
import {NG_ELEMENT_ID, NG_FACTORY_DEF} from './fields';
import {DirectiveDef, FactoryFn} from './interfaces/definition';
import {NO_PARENT_INJECTOR, NodeInjectorFactory, PARENT_INJECTOR, RelativeInjectorLocation, RelativeInjectorLocationFlags, TNODE, isFactory} from './interfaces/injector';
import {AttributeMarker, TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeProviderIndexes, TNodeType} from './interfaces/node';
import {AttributeMarker, TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeProviderIndexes, TNodeType} from './interfaces/node';
import {isComponentDef, isComponentHost} from './interfaces/type_checks';
import {DECLARATION_VIEW, INJECTOR, LView, TData, TVIEW, TView, T_HOST} from './interfaces/view';
import {assertNodeOfPossibleTypes} from './node_assert';
import {getLView, getPreviousOrParentTNode, setTNodeAndViewData} from './state';
import {enterDI, leaveDI} from './state';
import {isNameOnlyAttributeMarker} from './util/attrs_utils';
import {getParentInjectorIndex, getParentInjectorView, hasParentInjector} from './util/injector_utils';
import {stringifyForError} from './util/misc_utils';
Expand Down Expand Up @@ -334,9 +334,7 @@ export function getOrCreateInjectable<T>(
// If the ID stored here is a function, this is a special object like ElementRef or TemplateRef
// so just call the factory function to create it.
if (typeof bloomHash === 'function') {
const savePreviousOrParentTNode = getPreviousOrParentTNode();
const saveLView = getLView();
setTNodeAndViewData(tNode, lView);
enterDI(lView, tNode);
try {
const value = bloomHash();
if (value == null && !(flags & InjectFlags.Optional)) {
Expand All @@ -345,7 +343,7 @@ export function getOrCreateInjectable<T>(
return value;
}
} finally {
setTNodeAndViewData(savePreviousOrParentTNode, saveLView);
leaveDI();
}
} else if (typeof bloomHash == 'number') {
if (bloomHash === -1) {
Expand Down Expand Up @@ -530,8 +528,8 @@ export function locateDirectiveOrProvider<T>(
* instantiates the `injectable` and caches the value.
*/
export function getNodeInjectable(
tData: TData, lData: LView, index: number, tNode: TElementNode): any {
let value = lData[index];
tData: TData, lView: LView, index: number, tNode: TElementNode): any {
let value = lView[index];
if (isFactory(value)) {
const factory: NodeInjectorFactory = value;
if (factory.resolving) {
Expand All @@ -543,16 +541,14 @@ export function getNodeInjectable(
if (factory.injectImpl) {
previousInjectImplementation = setInjectImplementation(factory.injectImpl);
}
const savePreviousOrParentTNode = getPreviousOrParentTNode();
const saveLView = getLView();
setTNodeAndViewData(tNode, lData);
enterDI(lView, tNode);
try {
value = lData[index] = factory.factory(undefined, tData, lData, tNode);
value = lView[index] = factory.factory(undefined, tData, lView, tNode);
} finally {
if (factory.injectImpl) setInjectImplementation(previousInjectImplementation);
setIncludeViewProviders(previousIncludeViewProviders);
factory.resolving = false;
setTNodeAndViewData(savePreviousOrParentTNode, saveLView);
leaveDI();
}
}
return value;
Expand Down
10 changes: 5 additions & 5 deletions packages/core/src/render3/instructions/embedded_view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ import {TContainerNode, TNodeType} from '../interfaces/node';
import {CONTEXT, LView, LViewFlags, PARENT, TVIEW, TView, T_HOST} from '../interfaces/view';
import {assertNodeType} from '../node_assert';
import {insertView, removeView} from '../node_manipulation';
import {getIsParent, getLView, getPreviousOrParentTNode, selectView, setIsParent, setPreviousOrParentTNode} from '../state';
import {enterView, getIsParent, getLView, getPreviousOrParentTNode, leaveViewProcessExit, setIsParent, setPreviousOrParentTNode} from '../state';
import {isCreationMode} from '../util/view_utils';

import {assignTViewNodeToLView, createLView, createTView, refreshView, renderView} from './shared';



/**
* Marks the start of an embedded view.
*
Expand All @@ -42,7 +42,7 @@ export function ɵɵembeddedViewStart(viewBlockId: number, decls: number, vars:

if (viewToRender) {
setIsParent();
selectView(viewToRender, viewToRender[TVIEW].node);
enterView(viewToRender, viewToRender[TVIEW].node);
} else {
// When we create a new LView, we always reset the state of the instructions.
viewToRender = createLView(
Expand All @@ -52,7 +52,7 @@ export function ɵɵembeddedViewStart(viewBlockId: number, decls: number, vars:
const tParentNode = getIsParent() ? previousOrParentTNode :
previousOrParentTNode && previousOrParentTNode.parent;
assignTViewNodeToLView(viewToRender[TVIEW], tParentNode, viewBlockId, viewToRender);
selectView(viewToRender, viewToRender[TVIEW].node);
enterView(viewToRender, viewToRender[TVIEW].node);
}
if (lContainer) {
if (isCreationMode(viewToRender)) {
Expand Down Expand Up @@ -138,6 +138,6 @@ export function ɵɵembeddedViewEnd(): void {

const lContainer = lView[PARENT] as LContainer;
ngDevMode && assertLContainerOrUndefined(lContainer);
selectView(lContainer[PARENT] !, null);
leaveViewProcessExit();
setPreviousOrParentTNode(viewHost !, false);
}
9 changes: 6 additions & 3 deletions packages/core/src/render3/instructions/listener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ import {CLEANUP, FLAGS, LView, LViewFlags, RENDERER, TVIEW} from '../interfaces/
import {assertNodeOfPossibleTypes} from '../node_assert';
import {getLView, getPreviousOrParentTNode} from '../state';
import {getComponentLViewByIndex, getNativeByTNode, unwrapRNode} from '../util/view_utils';

import {getCleanup, handleError, loadComponentRenderer, markViewDirty} from './shared';



/**
* Adds an event listener to the current node.
*
Expand Down Expand Up @@ -213,7 +216,7 @@ function listenerInternal(
}

function executeListenerWithErrorHandling(
lView: LView, listenerFn: (e?: any) => any, e: any): boolean {
lView: LView, tNode: TNode, listenerFn: (e?: any) => any, e: any): boolean {
try {
// Only explicitly returning false from a listener should preventDefault
return listenerFn(e) !== false;
Expand Down Expand Up @@ -256,13 +259,13 @@ function wrapListener(
markViewDirty(startView);
}

let result = executeListenerWithErrorHandling(lView, listenerFn, e);
let result = executeListenerWithErrorHandling(lView, tNode, listenerFn, e);
// A just-invoked listener function might have coalesced listeners so we need to check for
// their presence and invoke as needed.
let nextListenerFn = (<any>wrapListenerIn_markDirtyAndPreventDefault).__ngNextListenerFn__;
while (nextListenerFn) {
// We should prevent default if any of the listeners explicitly return false
result = executeListenerWithErrorHandling(lView, nextListenerFn, e) && result;
result = executeListenerWithErrorHandling(lView, tNode, nextListenerFn, e) && result;
nextListenerFn = (<any>nextListenerFn).__ngNextListenerFn__;
}

Expand Down
32 changes: 6 additions & 26 deletions packages/core/src/render3/instructions/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {createNamedArrayType} from '../../util/named_array_type';
import {initNgDevMode} from '../../util/ng_dev_mode';
import {normalizeDebugBindingName, normalizeDebugBindingValue} from '../../util/ng_reflect';
import {assertFirstTemplatePass, assertLView} from '../assert';
import {attachPatchData, getComponentViewByInstance} from '../context_discovery';
import {attachPatchData} from '../context_discovery';
import {getFactoryDef} from '../definition';
import {diPublicInInjector, getNodeInjectable, getOrCreateNodeInjectorForNode} from '../di';
import {throwMultipleComponentError} from '../errors';
Expand All @@ -30,7 +30,7 @@ import {isComponentDef, isComponentHost, isContentQueryHost, isLContainer, isRoo
import {BINDING_INDEX, CHILD_HEAD, CHILD_TAIL, CLEANUP, CONTEXT, DECLARATION_VIEW, ExpandoInstructions, FLAGS, HEADER_OFFSET, HOST, INJECTOR, InitPhaseState, LView, LViewFlags, NEXT, PARENT, RENDERER, RENDERER_FACTORY, RootContext, RootContextFlags, SANITIZER, TData, TVIEW, TView, T_HOST} from '../interfaces/view';
import {assertNodeOfPossibleTypes} from '../node_assert';
import {isNodeMatchingSelectorList} from '../node_selector_matcher';
import {ActiveElementFlags, executeElementExitFn, getBindingsEnabled, getCheckNoChangesMode, getIsParent, getPreviousOrParentTNode, getSelectedIndex, hasActiveElementFlag, incrementActiveDirectiveId, namespaceHTMLInternal, selectView, setActiveHostElement, setBindingRoot, setCheckNoChangesMode, setCurrentDirectiveDef, setCurrentQueryIndex, setPreviousOrParentTNode, setSelectedIndex} from '../state';
import {ActiveElementFlags, enterView, executeElementExitFn, getBindingsEnabled, getCheckNoChangesMode, getIsParent, getPreviousOrParentTNode, getSelectedIndex, hasActiveElementFlag, incrementActiveDirectiveId, leaveView, leaveViewProcessExit, setActiveHostElement, setBindingRoot, setCheckNoChangesMode, setCurrentDirectiveDef, setCurrentQueryIndex, setPreviousOrParentTNode, setSelectedIndex} from '../state';
import {renderStylingMap} from '../styling/bindings';
import {NO_CHANGE} from '../tokens';
import {isAnimationProp} from '../util/attrs_utils';
Expand Down Expand Up @@ -312,7 +312,7 @@ export function allocExpando(view: LView, numSlotsToAlloc: number) {
*/
export function renderView<T>(lView: LView, tView: TView, context: T): void {
ngDevMode && assertEqual(isCreationMode(lView), true, 'Should be run in creation mode');
const oldView = selectView(lView, lView[T_HOST]);
enterView(lView, lView[T_HOST]);
try {
const viewQuery = tView.viewQuery;
if (viewQuery !== null) {
Expand Down Expand Up @@ -357,7 +357,7 @@ export function renderView<T>(lView: LView, tView: TView, context: T): void {

} finally {
lView[FLAGS] &= ~LViewFlags.CreationMode;
selectView(oldView, null);
leaveView();
}
}

Expand All @@ -372,7 +372,7 @@ export function renderView<T>(lView: LView, tView: TView, context: T): void {
export function refreshView<T>(
lView: LView, tView: TView, templateFn: ComponentTemplate<{}>| null, context: T) {
ngDevMode && assertEqual(isCreationMode(lView), false, 'Should be run in update mode');
const oldView = selectView(lView, lView[T_HOST]);
enterView(lView, lView[T_HOST]);
const flags = lView[FLAGS];
try {
resetPreOrderHookFlags(lView);
Expand Down Expand Up @@ -463,7 +463,7 @@ export function refreshView<T>(

} finally {
lView[FLAGS] &= ~(LViewFlags.Dirty | LViewFlags.FirstLViewPass);
selectView(oldView, null);
leaveViewProcessExit();
}
}

Expand All @@ -472,8 +472,6 @@ export function renderComponentOrTemplate<T>(
const rendererFactory = hostView[RENDERER_FACTORY];
const normalExecutionPath = !getCheckNoChangesMode();
const creationModeIsActive = isCreationMode(hostView);
const previousOrParentTNode = getPreviousOrParentTNode();
const isParent = getIsParent();
try {
if (normalExecutionPath && !creationModeIsActive && rendererFactory.begin) {
rendererFactory.begin();
Expand All @@ -487,13 +485,11 @@ export function renderComponentOrTemplate<T>(
if (normalExecutionPath && !creationModeIsActive && rendererFactory.end) {
rendererFactory.end();
}
setPreviousOrParentTNode(previousOrParentTNode, isParent);
}
}

function executeTemplate<T>(
lView: LView, templateFn: ComponentTemplate<T>, rf: RenderFlags, context: T) {
namespaceHTMLInternal();
const prevSelectedIndex = getSelectedIndex();
try {
setActiveHostElement(null);
Expand Down Expand Up @@ -1659,9 +1655,6 @@ export function tickRootContext(rootContext: RootContext) {

export function detectChangesInternal<T>(view: LView, context: T) {
const rendererFactory = view[RENDERER_FACTORY];
const previousOrParentTNode = getPreviousOrParentTNode();
const isParent = getIsParent();

if (rendererFactory.begin) rendererFactory.begin();
try {
const tView = view[TVIEW];
Expand All @@ -1671,7 +1664,6 @@ export function detectChangesInternal<T>(view: LView, context: T) {
throw error;
} finally {
if (rendererFactory.end) rendererFactory.end();
setPreviousOrParentTNode(previousOrParentTNode, isParent);
}
}

Expand All @@ -1684,18 +1676,6 @@ export function detectChangesInRootView(lView: LView): void {
tickRootContext(lView[CONTEXT] as RootContext);
}


/**
* Checks the change detector and its children, and throws if any changes are detected.
*
* This is used in development mode to verify that running change detection doesn't
* introduce other changes.
*/
export function checkNoChanges<T>(component: T): void {
const view = getComponentViewByInstance(component);
checkNoChangesInternal<T>(view, component);
}

export function checkNoChangesInternal<T>(view: LView, context: T) {
setCheckNoChangesMode(true);
try {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/render3/interfaces/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ export const enum InitPhaseState {
InitPhaseCompleted = 0b11,
}

/** More flags associated with an LView (saved in LView[FLAGS_MORE]) */
/** More flags associated with an LView (saved in LView[PREORDER_HOOK_FLAGS]) */
export const enum PreOrderHookFlags {
/** The index of the next pre-order hook to be called in the hooks array, on the first 16
bits */
Expand Down