refactor(ivy): use context discovery in TestBed implementation (#26211)
PR Close #26211
This commit is contained in:

committed by
Miško Hevery

parent
39f42bad1c
commit
053bf27fb3
@ -11,11 +11,10 @@ import {Renderer2, RendererType2} from '../render/api';
|
||||
import {DebugContext} from '../view';
|
||||
import {DebugRenderer2, DebugRendererFactory2} from '../view/services';
|
||||
|
||||
import * as di from './di';
|
||||
import {_getViewData} from './instructions';
|
||||
import {TNodeFlags} from './interfaces/node';
|
||||
import {CONTEXT, LViewData, TVIEW} from './interfaces/view';
|
||||
|
||||
import {getHostComponent, getInjector, getLocalRefs, loadContext} from './discovery_utils';
|
||||
import {DirectiveDef} from './interfaces/definition';
|
||||
import {TNode, TNodeFlags} from './interfaces/node';
|
||||
import {TVIEW} from './interfaces/view';
|
||||
|
||||
/**
|
||||
* Adapts the DebugRendererFactory2 to create a DebugRenderer2 specific for IVY.
|
||||
@ -25,7 +24,7 @@ import {CONTEXT, LViewData, TVIEW} from './interfaces/view';
|
||||
export class Render3DebugRendererFactory2 extends DebugRendererFactory2 {
|
||||
createRenderer(element: any, renderData: RendererType2|null): Renderer2 {
|
||||
const renderer = super.createRenderer(element, renderData) as DebugRenderer2;
|
||||
renderer.debugContextFactory = () => new Render3DebugContext(_getViewData());
|
||||
renderer.debugContextFactory = (nativeElement: any) => new Render3DebugContext(nativeElement);
|
||||
return renderer;
|
||||
}
|
||||
}
|
||||
@ -36,68 +35,46 @@ export class Render3DebugRendererFactory2 extends DebugRendererFactory2 {
|
||||
* Used in tests to retrieve information those nodes.
|
||||
*/
|
||||
class Render3DebugContext implements DebugContext {
|
||||
readonly nodeIndex: number|null;
|
||||
constructor(private _nativeNode: any) {}
|
||||
|
||||
constructor(private viewData: LViewData) {
|
||||
// The LNode will be created next and appended to viewData
|
||||
this.nodeIndex = viewData ? viewData.length : null;
|
||||
}
|
||||
get nodeIndex(): number|null { return loadContext(this._nativeNode).nodeIndex; }
|
||||
|
||||
get view(): any { return this.viewData; }
|
||||
get view(): any { return loadContext(this._nativeNode).lViewData; }
|
||||
|
||||
get injector(): Injector {
|
||||
if (this.nodeIndex !== null) {
|
||||
const tNode = this.view[TVIEW].data[this.nodeIndex];
|
||||
return new di.NodeInjector(tNode, this.view);
|
||||
}
|
||||
return Injector.NULL;
|
||||
}
|
||||
get injector(): Injector { return getInjector(this._nativeNode); }
|
||||
|
||||
get component(): any {
|
||||
// TODO(vicb): why/when
|
||||
if (this.nodeIndex === null) {
|
||||
return null;
|
||||
}
|
||||
get component(): any { return getHostComponent(this._nativeNode); }
|
||||
|
||||
const tView = this.view[TVIEW];
|
||||
const components: number[]|null = tView.components;
|
||||
|
||||
return (components && components.indexOf(this.nodeIndex) == -1) ?
|
||||
null :
|
||||
this.view[this.nodeIndex].data[CONTEXT];
|
||||
}
|
||||
|
||||
// TODO(vicb): add view providers when supported
|
||||
get providerTokens(): any[] {
|
||||
// TODO(vicb): why/when
|
||||
const directiveDefs = this.view[TVIEW].data;
|
||||
if (this.nodeIndex === null || directiveDefs == null) {
|
||||
return [];
|
||||
const lDebugCtx = loadContext(this._nativeNode);
|
||||
const lViewData = lDebugCtx.lViewData;
|
||||
const tNode = lViewData[TVIEW].data[lDebugCtx.nodeIndex] as TNode;
|
||||
const directivesCount = tNode.flags & TNodeFlags.DirectiveCountMask;
|
||||
|
||||
if (directivesCount > 0) {
|
||||
const directiveIdxStart = tNode.flags >> TNodeFlags.DirectiveStartingIndexShift;
|
||||
const directiveIdxEnd = directiveIdxStart + directivesCount;
|
||||
const viewDirectiveDefs = this.view[TVIEW].data;
|
||||
const directiveDefs =
|
||||
viewDirectiveDefs.slice(directiveIdxStart, directiveIdxEnd) as DirectiveDef<any>[];
|
||||
|
||||
return directiveDefs.map(directiveDef => directiveDef.type);
|
||||
}
|
||||
|
||||
const currentTNode = this.view[TVIEW].data[this.nodeIndex];
|
||||
const dirStart = currentTNode >> TNodeFlags.DirectiveStartingIndexShift;
|
||||
const dirEnd = dirStart + (currentTNode & TNodeFlags.DirectiveCountMask);
|
||||
return directiveDefs.slice(dirStart, dirEnd);
|
||||
return [];
|
||||
}
|
||||
|
||||
get references(): {[key: string]: any} {
|
||||
// TODO(vicb): implement retrieving references
|
||||
throw new Error('Not implemented yet in ivy');
|
||||
}
|
||||
get references(): {[key: string]: any} { return getLocalRefs(this._nativeNode); }
|
||||
|
||||
get context(): any {
|
||||
if (this.nodeIndex === null) {
|
||||
return null;
|
||||
}
|
||||
const lNode = this.view[this.nodeIndex];
|
||||
return lNode.view[CONTEXT];
|
||||
}
|
||||
// TODO(pk): check previous implementation and re-implement
|
||||
get context(): any { throw new Error('Not implemented in ivy'); }
|
||||
|
||||
// TODO(pk): check previous implementation and re-implement
|
||||
get componentRenderElement(): any { throw new Error('Not implemented in ivy'); }
|
||||
|
||||
// TODO(pk): check previous implementation and re-implement
|
||||
get renderNode(): any { throw new Error('Not implemented in ivy'); }
|
||||
|
||||
// TODO(vicb): check previous implementation
|
||||
// TODO(pk): check previous implementation and re-implement
|
||||
logError(console: Console, ...values: any[]): void { console.error(...values); }
|
||||
}
|
||||
|
@ -110,7 +110,11 @@ export function getDirectives(target: {}): Array<{}> {
|
||||
return context.directives || [];
|
||||
}
|
||||
|
||||
function loadContext(target: {}): LContext {
|
||||
/**
|
||||
* Returns LContext associated with a target passed as an argument.
|
||||
* Throws if a given target doesn't have associated LContext.
|
||||
*/
|
||||
export function loadContext(target: {}): LContext {
|
||||
const context = getContext(target);
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
|
@ -395,8 +395,8 @@ export function detachView(lContainer: LContainer, removeIndex: number, detached
|
||||
export function removeView(
|
||||
lContainer: LContainer, tContainer: TContainerNode, removeIndex: number) {
|
||||
const view = lContainer[VIEWS][removeIndex];
|
||||
destroyLView(view);
|
||||
detachView(lContainer, removeIndex, !!tContainer.detached);
|
||||
destroyLView(view);
|
||||
}
|
||||
|
||||
/** Gets the child of the given LViewData */
|
||||
|
Reference in New Issue
Block a user