fix(ivy): DebugNode throws exceptions when querying some properties (#32622)

PR Close #32622
This commit is contained in:
Andrew Scott 2019-09-11 13:48:09 -07:00 committed by Kara Erickson
parent 5328bb223a
commit bfb3995869
3 changed files with 40 additions and 8 deletions

View File

@ -42,7 +42,10 @@ import {unwrapRNode} from './view_utils';
* @publicApi * @publicApi
*/ */
export function getComponent<T = {}>(element: Element): T|null { export function getComponent<T = {}>(element: Element): T|null {
const context = loadLContextFromNode(element); if (!(element instanceof Node)) throw new Error('Expecting instance of DOM Node');
const context = loadLContext(element, false);
if (context === null) return null;
if (context.component === undefined) { if (context.component === undefined) {
context.component = getComponentAtNodeIndex(context.nodeIndex, context.lView); context.component = getComponentAtNodeIndex(context.nodeIndex, context.lView);
@ -72,7 +75,10 @@ export function getComponent<T = {}>(element: Element): T|null {
* @publicApi * @publicApi
*/ */
export function getContext<T = {}>(element: Element): T|null { export function getContext<T = {}>(element: Element): T|null {
const context = loadLContextFromNode(element) !; if (!(element instanceof Node)) throw new Error('Expecting instance of DOM Node');
const context = loadLContext(element, false);
if (context === null) return null;
return context.lView[CONTEXT] as T; return context.lView[CONTEXT] as T;
} }
@ -97,7 +103,9 @@ export function getContext<T = {}>(element: Element): T|null {
* @publicApi * @publicApi
*/ */
export function getViewComponent<T = {}>(element: Element | {}): T|null { export function getViewComponent<T = {}>(element: Element | {}): T|null {
const context = loadLContext(element) !; const context = loadLContext(element, false);
if (context === null) return null;
let lView = context.lView; let lView = context.lView;
let parent: LView|null; let parent: LView|null;
ngDevMode && assertLView(lView); ngDevMode && assertLView(lView);
@ -129,7 +137,9 @@ export function getRootComponents(target: {}): any[] {
* @publicApi * @publicApi
*/ */
export function getInjector(target: {}): Injector { export function getInjector(target: {}): Injector {
const context = loadLContext(target); const context = loadLContext(target, false);
if (context === null) return Injector.NULL;
const tNode = context.lView[TVIEW].data[context.nodeIndex] as TElementNode; const tNode = context.lView[TVIEW].data[context.nodeIndex] as TElementNode;
return new NodeInjector(tNode, context.lView); return new NodeInjector(tNode, context.lView);
} }
@ -142,7 +152,7 @@ export function getInjector(target: {}): Injector {
*/ */
export function getInjectionTokens(element: Element): any[] { export function getInjectionTokens(element: Element): any[] {
const context = loadLContext(element, false); const context = loadLContext(element, false);
if (!context) return []; if (context === null) return [];
const lView = context.lView; const lView = context.lView;
const tView = lView[TVIEW]; const tView = lView[TVIEW];
const tNode = tView.data[context.nodeIndex] as TNode; const tNode = tView.data[context.nodeIndex] as TNode;
@ -207,7 +217,8 @@ export function loadLContext(target: {}, throwOnNotFound: boolean = true): LCont
* @publicApi * @publicApi
*/ */
export function getLocalRefs(target: {}): {[key: string]: any} { export function getLocalRefs(target: {}): {[key: string]: any} {
const context = loadLContext(target) !; const context = loadLContext(target, false);
if (context === null) return {};
if (context.localRefs === undefined) { if (context.localRefs === undefined) {
context.localRefs = discoverLocalRefs(context.lView, context.nodeIndex); context.localRefs = discoverLocalRefs(context.lView, context.nodeIndex);
@ -285,7 +296,10 @@ export function isBrowserEvents(listener: Listener): boolean {
* @publicApi * @publicApi
*/ */
export function getListeners(element: Element): Listener[] { export function getListeners(element: Element): Listener[] {
const lContext = loadLContextFromNode(element); if (!(element instanceof Node)) throw new Error('Expecting instance of DOM Node');
const lContext = loadLContext(element, false);
if (lContext === null) return [];
const lView = lContext.lView; const lView = lContext.lView;
const tView = lView[TVIEW]; const tView = lView[TVIEW];
const lCleanup = lView[CLEANUP]; const lCleanup = lView[CLEANUP];

View File

@ -144,7 +144,7 @@ export function getComponentViewByIndex(nodeIndex: number, hostView: LView): LVi
*/ */
export function readPatchedData(target: any): LView|LContext|null { export function readPatchedData(target: any): LView|LContext|null {
ngDevMode && assertDefined(target, 'Target expected'); ngDevMode && assertDefined(target, 'Target expected');
return target[MONKEY_PATCH_KEY_NAME]; return target[MONKEY_PATCH_KEY_NAME] || null;
} }
export function readPatchedLView(target: any): LView|null { export function readPatchedLView(target: any): LView|null {

View File

@ -639,6 +639,24 @@ class TestCmptWithPropInterpolation {
it('when searching for elements by their properties', () => { it('when searching for elements by their properties', () => {
expect(() => el.query(e => e.properties['any prop'] === 'any value')).not.toThrow(); expect(() => el.query(e => e.properties['any prop'] === 'any value')).not.toThrow();
}); });
it('when searching by componentInstance',
() => { expect(() => el.query(e => e.componentInstance === null)).not.toThrow(); });
it('when searching by context',
() => { expect(() => el.query(e => e.context === null)).not.toThrow(); });
it('when searching by listeners',
() => { expect(() => el.query(e => e.listeners.length === 0)).not.toThrow(); });
it('when searching by references',
() => { expect(() => el.query(e => e.references === null)).not.toThrow(); });
it('when searching by providerTokens',
() => { expect(() => el.query(e => e.providerTokens.length === 0)).not.toThrow(); });
it('when searching by injector',
() => { expect(() => el.query(e => e.injector === null)).not.toThrow(); });
}); });
it('DebugElement.queryAll should pick up both elements inserted via the view and through Renderer2', it('DebugElement.queryAll should pick up both elements inserted via the view and through Renderer2',