refactor(ivy): ensure hello world doesn't pull in context discovery creation code (#25895)

PR Close #25895
This commit is contained in:
Matias Niemelä 2018-09-10 11:22:35 -07:00
parent 8dc2b119fb
commit 10a656fc38
7 changed files with 49 additions and 67 deletions

View File

@ -133,7 +133,7 @@ export function renderComponent<T>(
executeInitAndContentHooks();
setHostBindings(rootView[TVIEW].hostBindings);
detectChangesInternal(elementNode.data as LViewData, elementNode, component);
detectChangesInternal(elementNode.data as LViewData, component);
} finally {
leaveView(oldView);
if (rendererFactory.end) rendererFactory.end();

View File

@ -185,10 +185,11 @@ export function getLElementNode(target: any): LElementNode|null {
return context ? getLNodeFromViewData(context.lViewData, context.lNodeIndex) : null;
}
export function getLElementFromRootComponent(componentInstance: {}): LElementNode|null {
export function getLElementFromRootComponent(rootComponentInstance: {}): LElementNode|null {
// the host element for the root component is ALWAYS the first element
// in the lViewData array (which is where HEADER_OFFSET points to)
return getLElementFromComponent(componentInstance, HEADER_OFFSET);
const lViewData = readPatchedLViewData(rootComponentInstance) !;
return readElementValue(lViewData[HEADER_OFFSET]);
}
/**
@ -198,15 +199,14 @@ export function getLElementFromRootComponent(componentInstance: {}): LElementNod
* that `getContext` has in the event that an Angular application doesn't need to have
* any programmatic access to an element's context (only change detection uses this function).
*/
export function getLElementFromComponent(
componentInstance: {}, expectedLNodeIndex?: number): LElementNode|null {
export function getLElementFromComponent(componentInstance: {}): LElementNode|null {
let lViewData = readPatchedData(componentInstance);
let lNode: LElementNode;
if (Array.isArray(lViewData)) {
expectedLNodeIndex = expectedLNodeIndex || findViaComponent(lViewData, componentInstance);
lNode = readElementValue(lViewData[expectedLNodeIndex]);
const context = createLContext(lViewData, expectedLNodeIndex, lNode.native);
const lNodeIndex = findViaComponent(lViewData, componentInstance);
lNode = readElementValue(lViewData[lNodeIndex]);
const context = createLContext(lViewData, lNodeIndex, lNode.native);
context.component = componentInstance;
attachPatchData(componentInstance, context);
attachPatchData(context.native, context);
@ -234,6 +234,14 @@ export function readPatchedData(target: any): LViewData|LContext|null {
return target[MONKEY_PATCH_KEY_NAME];
}
export function readPatchedLViewData(target: any): LViewData|null {
const value = readPatchedData(target);
if (value) {
return Array.isArray(value) ? value : (value as LContext).lViewData;
}
return null;
}
export function isComponentInstance(instance: any): boolean {
return instance && instance.constructor && instance.constructor.ngComponentDef;
}

View File

@ -13,7 +13,7 @@ import {Sanitizer} from '../sanitization/security';
import {StyleSanitizeFn} from '../sanitization/style_sanitizer';
import {assertDefined, assertEqual, assertLessThan, assertNotDefined, assertNotEqual} from './assert';
import {attachPatchData, getLElementFromComponent, getLElementFromRootComponent} from './context_discovery';
import {attachPatchData, getLElementFromComponent, getLElementFromRootComponent, readPatchedData, readPatchedLViewData} from './context_discovery';
import {throwCyclicDependencyError, throwErrorIfNoChangesMode, throwMultipleComponentError} from './errors';
import {executeHooks, executeInitHooks, queueInitHooks, queueLifecycleHooks} from './hooks';
import {ACTIVE_INDEX, LContainer, RENDER_PARENT, VIEWS} from './interfaces/container';
@ -1769,6 +1769,9 @@ export function baseDirectiveCreate<T>(
ngDevMode && assertPreviousIsParent();
attachPatchData(directive, viewData);
if (hostNode) {
attachPatchData(hostNode.native, viewData);
}
if (directives == null) viewData[DIRECTIVES] = directives = [];
@ -2175,7 +2178,7 @@ export function componentRefresh<T>(adjustedElementIndex: number): void {
// Only attached CheckAlways components or attached, dirty OnPush components should be checked
if (viewAttached(hostView) && hostView[FLAGS] & (LViewFlags.CheckAlways | LViewFlags.Dirty)) {
detectChangesInternal(hostView, element, hostView[CONTEXT]);
detectChangesInternal(hostView, hostView[CONTEXT]);
}
}
@ -2435,7 +2438,7 @@ export function tick<T>(component: T): void {
function tickRootContext(rootContext: RootContext) {
for (let i = 0; i < rootContext.components.length; i++) {
const rootComponent = rootContext.components[i];
renderComponentOrTemplate(getRootView(rootComponent), rootComponent);
renderComponentOrTemplate(readPatchedLViewData(rootComponent) !, rootComponent);
}
}
@ -2448,8 +2451,7 @@ function tickRootContext(rootContext: RootContext) {
export function getRootView(component: any): LViewData {
ngDevMode && assertDefined(component, 'component');
const lElementNode = _getComponentHostLElementNode(component);
let lViewData = lElementNode.view;
let lViewData = readPatchedLViewData(component) !;
while (lViewData[PARENT]) {
lViewData = lViewData[PARENT] !;
}
@ -2470,11 +2472,10 @@ export function getRootView(component: any): LViewData {
* @param component The component which the change detection should be performed on.
*/
export function detectChanges<T>(component: T): void {
const hostNode = _getComponentHostLElementNode(component);
const hostNode = getLElementFromComponent(component) !;
ngDevMode &&
assertDefined(
hostNode.data, 'Component host node should be attached to an LViewData instance.');
detectChangesInternal(hostNode.data as LViewData, hostNode, component);
assertDefined(hostNode, 'Component host node should be attached to an LViewData instance.');
detectChangesInternal(hostNode.data !, component);
}
/**
@ -2521,8 +2522,7 @@ export function checkNoChangesInRootView(lViewData: LViewData): void {
}
/** Checks the view of the component provided. Does not gate on dirty checks or execute doCheck. */
export function detectChangesInternal<T>(
hostView: LViewData, hostNode: LElementNode, component: T) {
export function detectChangesInternal<T>(hostView: LViewData, component: T) {
const hostTView = hostView[TVIEW];
const oldView = enterView(hostView, null);
const templateFn = hostTView.template !;
@ -2569,8 +2569,8 @@ function updateViewQuery<T>(viewQuery: ComponentQuery<{}>| null, component: T):
*/
export function markDirty<T>(component: T) {
ngDevMode && assertDefined(component, 'component');
const lElementNode = _getComponentHostLElementNode(component);
markViewDirty(lElementNode.view);
const lViewData = readPatchedLViewData(component) !;
markViewDirty(lViewData);
}
///////////////////////////////
@ -2881,11 +2881,9 @@ function assertDataNext(index: number, arr?: any[]) {
arr.length, index, `index ${index} expected to be at the end of arr (length ${arr.length})`);
}
export function _getComponentHostLElementNode<T>(
component: T, isRootComponent?: boolean): LElementNode {
export function _getComponentHostLElementNode(component: any): LElementNode {
ngDevMode && assertDefined(component, 'expecting component got null');
const lElementNode = isRootComponent ? getLElementFromRootComponent(component) ! :
getLElementFromComponent(component) !;
const lElementNode = getLElementFromComponent(component) !;
ngDevMode && assertDefined(component, 'object is not a component');
return lElementNode;
}

View File

@ -98,9 +98,6 @@
{
"name": "_CLEAN_PROMISE"
},
{
"name": "_getComponentHostLElementNode"
},
{
"name": "_renderCompCount"
},
@ -137,9 +134,6 @@
{
"name": "componentRefresh"
},
{
"name": "createLContext"
},
{
"name": "createLNode"
},
@ -200,9 +194,6 @@
{
"name": "extractPipeDef"
},
{
"name": "findViaComponent"
},
{
"name": "firstTemplatePass"
},
@ -218,12 +209,6 @@
{
"name": "getDirectiveDef"
},
{
"name": "getLElementFromComponent"
},
{
"name": "getLElementFromRootComponent"
},
{
"name": "getLViewChild"
},
@ -251,9 +236,6 @@
{
"name": "getRenderParent"
},
{
"name": "getRootView"
},
{
"name": "hostElement"
},
@ -290,6 +272,9 @@
{
"name": "readPatchedData"
},
{
"name": "readPatchedLViewData"
},
{
"name": "refreshChildComponents"
},

View File

@ -314,9 +314,6 @@
{
"name": "_devMode"
},
{
"name": "_getComponentHostLElementNode"
},
{
"name": "_global"
},
@ -596,9 +593,6 @@
{
"name": "getLElementFromComponent"
},
{
"name": "getLElementFromRootComponent"
},
{
"name": "getLViewChild"
},
@ -671,9 +665,6 @@
{
"name": "getRendererFactory"
},
{
"name": "getRootView"
},
{
"name": "getStyleSanitizer"
},
@ -854,6 +845,9 @@
{
"name": "readPatchedData"
},
{
"name": "readPatchedLViewData"
},
{
"name": "reference"
},

View File

@ -1622,9 +1622,6 @@
{
"name": "getLElementFromComponent"
},
{
"name": "getLElementFromRootComponent"
},
{
"name": "getLViewChild"
},
@ -1772,9 +1769,6 @@
{
"name": "getRendererFactory"
},
{
"name": "getRootView"
},
{
"name": "getStyleSanitizer"
},
@ -2174,6 +2168,9 @@
{
"name": "readPatchedData"
},
{
"name": "readPatchedLViewData"
},
{
"name": "recursivelyProcessProviders"
},

View File

@ -1581,7 +1581,7 @@ describe('render3 integration test', () => {
const host = fixture.hostElement;
const child = host.querySelector('child-comp') as any;
expect(child[MONKEY_PATCH_KEY_NAME]).toBeFalsy();
expect(child[MONKEY_PATCH_KEY_NAME]).toBeTruthy();
const [kid1, kid2, kid3] = Array.from(host.querySelectorAll('child-comp > *'));
expect(kid1[MONKEY_PATCH_KEY_NAME]).toBeTruthy();
@ -1859,7 +1859,7 @@ describe('render3 integration test', () => {
expect(textNode[MONKEY_PATCH_KEY_NAME]).toBeTruthy();
expect(section[MONKEY_PATCH_KEY_NAME]).toBeTruthy();
expect(projectorComp[MONKEY_PATCH_KEY_NAME]).toBeFalsy();
expect(projectorComp[MONKEY_PATCH_KEY_NAME]).toBeTruthy();
expect(header[MONKEY_PATCH_KEY_NAME]).toBeTruthy();
expect(h1[MONKEY_PATCH_KEY_NAME]).toBeFalsy();
expect(p[MONKEY_PATCH_KEY_NAME]).toBeTruthy();
@ -1936,19 +1936,19 @@ describe('render3 integration test', () => {
const hostElm = fixture.hostElement;
const component = fixture.component;
const componentContext = (component as any)[MONKEY_PATCH_KEY_NAME];
expect(Array.isArray(componentContext)).toBeFalsy();
const componentLViewData = (component as any)[MONKEY_PATCH_KEY_NAME];
expect(Array.isArray(componentLViewData)).toBeTruthy();
const hostContext = (hostElm as any)[MONKEY_PATCH_KEY_NAME];
expect(hostContext).toBe(componentContext);
const hostLViewData = (hostElm as any)[MONKEY_PATCH_KEY_NAME];
expect(hostLViewData).toBe(componentLViewData);
const context1 = getContext(hostElm) !;
expect(context1).toBe(hostContext);
expect(context1.lViewData).toBe(hostLViewData);
expect(context1.native).toEqual(hostElm);
const context2 = getContext(component) !;
expect(context2).toBe(context1);
expect(context2).toBe(hostContext);
expect(context2.lViewData).toBe(hostLViewData);
expect(context2.native).toEqual(hostElm);
});
@ -2183,7 +2183,7 @@ describe('render3 integration test', () => {
const host = fixture.hostElement;
const child = host.querySelector('child-comp') as any;
expect(child[MONKEY_PATCH_KEY_NAME]).toBeFalsy();
expect(child[MONKEY_PATCH_KEY_NAME]).toBeTruthy();
const context = getContext(child) !;
expect(child[MONKEY_PATCH_KEY_NAME]).toBeTruthy();