feat(core): view engine - integrate with ComponentFactory
(#14237)
`ComponentFactory`s can now be created from a `ViewDefinitionFactory` via `RefFactory.createComponentFactory`. This commit also: - splits `Services` into `Refs` and `RootData` - changes `ViewState` into a bitmask - implements `ViewContainerRef.move` Part of #14013 PR Close #14237
This commit is contained in:

committed by
Miško Hevery

parent
388afa414e
commit
14d7844b2b
@ -6,12 +6,12 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, getDebugNode} from '@angular/core';
|
||||
import {DebugContext, DefaultServices, NodeDef, NodeFlags, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, elementDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, getDebugNode} from '@angular/core';
|
||||
import {DebugContext, NodeDef, NodeFlags, RootData, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, elementDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {inject} from '@angular/core/testing';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
|
||||
import {isBrowser, setupAndCheckRenderer} from './helper';
|
||||
import {createRootData, isBrowser, setupAndCheckRenderer} from './helper';
|
||||
|
||||
export function main() {
|
||||
if (isBrowser()) {
|
||||
@ -24,15 +24,14 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
describe(`View Anchor, directDom: ${config.directDom}`, () => {
|
||||
setupAndCheckRenderer(config);
|
||||
|
||||
let services: Services;
|
||||
let rootData: RootData;
|
||||
let renderComponentType: RenderComponentType;
|
||||
|
||||
beforeEach(
|
||||
inject([RootRenderer, Sanitizer], (rootRenderer: RootRenderer, sanitizer: Sanitizer) => {
|
||||
services = new DefaultServices(rootRenderer, sanitizer);
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
}));
|
||||
beforeEach(() => {
|
||||
rootData = createRootData();
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
});
|
||||
|
||||
function compViewDef(
|
||||
nodes: NodeDef[], update?: ViewUpdateFn, handleEvent?: ViewHandleEventFn): ViewDefinition {
|
||||
@ -41,7 +40,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
|
||||
function createAndGetRootNodes(
|
||||
viewDef: ViewDefinition, ctx?: any): {rootNodes: any[], view: ViewData} {
|
||||
const view = createRootView(services, () => viewDef, ctx);
|
||||
const view = createRootView(rootData, viewDef, ctx);
|
||||
const rootNodes = rootRenderNodes(view);
|
||||
return {rootNodes, view};
|
||||
}
|
||||
|
@ -6,12 +6,12 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation} from '@angular/core';
|
||||
import {BindingType, DefaultServices, NodeDef, NodeFlags, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewState, ViewUpdateFn, anchorDef, asProviderData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, destroyView, directiveDef, elementDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation} from '@angular/core';
|
||||
import {BindingType, NodeDef, NodeFlags, RootData, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewState, ViewUpdateFn, anchorDef, asProviderData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, destroyView, directiveDef, elementDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {inject} from '@angular/core/testing';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
|
||||
import {isBrowser, setupAndCheckRenderer} from './helper';
|
||||
import {createRootData, isBrowser, removeNodes, setupAndCheckRenderer} from './helper';
|
||||
|
||||
export function main() {
|
||||
if (isBrowser()) {
|
||||
@ -24,15 +24,14 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
describe(`Component Views, directDom: ${config.directDom}`, () => {
|
||||
setupAndCheckRenderer(config);
|
||||
|
||||
let services: Services;
|
||||
let rootData: RootData;
|
||||
let renderComponentType: RenderComponentType;
|
||||
|
||||
beforeEach(
|
||||
inject([RootRenderer, Sanitizer], (rootRenderer: RootRenderer, sanitizer: Sanitizer) => {
|
||||
services = new DefaultServices(rootRenderer, sanitizer);
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
}));
|
||||
beforeEach(() => {
|
||||
rootData = createRootData();
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
});
|
||||
|
||||
function compViewDef(
|
||||
nodes: NodeDef[], update?: ViewUpdateFn, handleEvent?: ViewHandleEventFn,
|
||||
@ -41,7 +40,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
}
|
||||
|
||||
function createAndGetRootNodes(viewDef: ViewDefinition): {rootNodes: any[], view: ViewData} {
|
||||
const view = createRootView(services, () => viewDef);
|
||||
const view = createRootView(rootData, viewDef);
|
||||
const rootNodes = rootRenderNodes(view);
|
||||
return {rootNodes, view};
|
||||
}
|
||||
@ -70,6 +69,54 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
expect(getDOM().nodeName(compRootEl).toLowerCase()).toBe('span');
|
||||
});
|
||||
|
||||
if (isBrowser()) {
|
||||
describe('root views', () => {
|
||||
let rootNode: HTMLElement;
|
||||
beforeEach(() => {
|
||||
rootNode = document.createElement('root');
|
||||
document.body.appendChild(rootNode);
|
||||
removeNodes.push(rootNode);
|
||||
});
|
||||
|
||||
it('should select root elements based on a selector', () => {
|
||||
rootData.selectorOrNode = 'root';
|
||||
const view = createRootView(rootData, compViewDef([
|
||||
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
||||
]));
|
||||
const rootNodes = rootRenderNodes(view);
|
||||
expect(rootNodes).toEqual([rootNode]);
|
||||
});
|
||||
|
||||
it('should select root elements based on a node', () => {
|
||||
rootData.selectorOrNode = rootNode;
|
||||
const view = createRootView(rootData, compViewDef([
|
||||
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
||||
]));
|
||||
const rootNodes = rootRenderNodes(view);
|
||||
expect(rootNodes).toEqual([rootNode]);
|
||||
});
|
||||
|
||||
it('should set attributes on the root node', () => {
|
||||
rootData.selectorOrNode = rootNode;
|
||||
const view =
|
||||
createRootView(rootData, compViewDef([
|
||||
elementDef(NodeFlags.None, null, null, 1, 'div', {'a': 'b'}),
|
||||
]));
|
||||
expect(rootNode.getAttribute('a')).toBe('b');
|
||||
});
|
||||
|
||||
it('should clear the content of the root node', () => {
|
||||
rootData.selectorOrNode = rootNode;
|
||||
rootNode.appendChild(document.createElement('div'));
|
||||
const view =
|
||||
createRootView(rootData, compViewDef([
|
||||
elementDef(NodeFlags.None, null, null, 1, 'div', {'a': 'b'}),
|
||||
]));
|
||||
expect(rootNode.childNodes.length).toBe(0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe('data binding', () => {
|
||||
it('should dirty check component views', () => {
|
||||
let value: any;
|
||||
@ -132,11 +179,11 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
checkAndUpdateView(view);
|
||||
update.calls.reset();
|
||||
|
||||
compView.state = ViewState.ChecksDisabled;
|
||||
compView.state &= ~ViewState.ChecksEnabled;
|
||||
checkAndUpdateView(view);
|
||||
expect(update).not.toHaveBeenCalled();
|
||||
|
||||
compView.state = ViewState.ChecksEnabled;
|
||||
compView.state |= ViewState.ChecksEnabled;
|
||||
checkAndUpdateView(view);
|
||||
expect(update).toHaveBeenCalled();
|
||||
});
|
||||
|
@ -6,12 +6,12 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, WrappedValue, getDebugNode} from '@angular/core';
|
||||
import {BindingType, DebugContext, DefaultServices, NodeDef, NodeFlags, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, destroyView, elementDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, WrappedValue, getDebugNode} from '@angular/core';
|
||||
import {BindingType, DebugContext, NodeDef, NodeFlags, RootData, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, destroyView, elementDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {inject} from '@angular/core/testing';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
|
||||
import {INLINE_DYNAMIC_VALUES, InlineDynamic, checkNodeInlineOrDynamic, isBrowser, setupAndCheckRenderer} from './helper';
|
||||
import {INLINE_DYNAMIC_VALUES, InlineDynamic, checkNodeInlineOrDynamic, createRootData, isBrowser, removeNodes, setupAndCheckRenderer} from './helper';
|
||||
|
||||
export function main() {
|
||||
if (isBrowser()) {
|
||||
@ -24,15 +24,14 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
describe(`View Elements, directDom: ${config.directDom}`, () => {
|
||||
setupAndCheckRenderer(config);
|
||||
|
||||
let services: Services;
|
||||
let rootData: RootData;
|
||||
let renderComponentType: RenderComponentType;
|
||||
|
||||
beforeEach(
|
||||
inject([RootRenderer, Sanitizer], (rootRenderer: RootRenderer, sanitizer: Sanitizer) => {
|
||||
services = new DefaultServices(rootRenderer, sanitizer);
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
}));
|
||||
beforeEach(() => {
|
||||
rootData = createRootData();
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
});
|
||||
|
||||
function compViewDef(
|
||||
nodes: NodeDef[], update?: ViewUpdateFn, handleEvent?: ViewHandleEventFn): ViewDefinition {
|
||||
@ -41,7 +40,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
|
||||
function createAndGetRootNodes(
|
||||
viewDef: ViewDefinition, context?: any): {rootNodes: any[], view: ViewData} {
|
||||
const view = createRootView(services, () => viewDef, context);
|
||||
const view = createRootView(rootData, viewDef, context);
|
||||
const rootNodes = rootRenderNodes(view);
|
||||
return {rootNodes, view};
|
||||
}
|
||||
@ -236,16 +235,6 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
|
||||
if (isBrowser()) {
|
||||
describe('listen to DOM events', () => {
|
||||
let removeNodes: Node[];
|
||||
beforeEach(() => { removeNodes = []; });
|
||||
afterEach(() => {
|
||||
removeNodes.forEach((node) => {
|
||||
if (node.parentNode) {
|
||||
node.parentNode.removeChild(node);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function createAndAttachAndGetRootNodes(viewDef: ViewDefinition):
|
||||
{rootNodes: any[], view: ViewData} {
|
||||
const result = createAndGetRootNodes(viewDef);
|
||||
|
@ -6,12 +6,12 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation} from '@angular/core';
|
||||
import {BindingType, DefaultServices, NodeDef, NodeFlags, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, attachEmbeddedView, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createEmbeddedView, createRootView, destroyView, detachEmbeddedView, directiveDef, elementDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation} from '@angular/core';
|
||||
import {BindingType, NodeDef, NodeFlags, RootData, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, attachEmbeddedView, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createEmbeddedView, createRootView, destroyView, detachEmbeddedView, directiveDef, elementDef, moveEmbeddedView, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {inject} from '@angular/core/testing';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
|
||||
import {isBrowser, setupAndCheckRenderer} from './helper';
|
||||
import {createRootData, isBrowser, setupAndCheckRenderer} from './helper';
|
||||
|
||||
export function main() {
|
||||
if (isBrowser()) {
|
||||
@ -24,15 +24,14 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
describe(`Embedded Views, directDom: ${config.directDom}`, () => {
|
||||
setupAndCheckRenderer(config);
|
||||
|
||||
let services: Services;
|
||||
let rootData: RootData;
|
||||
let renderComponentType: RenderComponentType;
|
||||
|
||||
beforeEach(
|
||||
inject([RootRenderer, Sanitizer], (rootRenderer: RootRenderer, sanitizer: Sanitizer) => {
|
||||
services = new DefaultServices(rootRenderer, sanitizer);
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
}));
|
||||
beforeEach(() => {
|
||||
rootData = createRootData();
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
});
|
||||
|
||||
function compViewDef(
|
||||
nodes: NodeDef[], update?: ViewUpdateFn, handleEvent?: ViewHandleEventFn): ViewDefinition {
|
||||
@ -45,7 +44,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
|
||||
function createAndGetRootNodes(
|
||||
viewDef: ViewDefinition, context: any = null): {rootNodes: any[], view: ViewData} {
|
||||
const view = createRootView(services, () => viewDef, context);
|
||||
const view = createRootView(rootData, viewDef, context);
|
||||
const rootNodes = rootRenderNodes(view);
|
||||
return {rootNodes, view};
|
||||
}
|
||||
@ -78,26 +77,54 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
elementDef(NodeFlags.None, null, null, 0, 'span', {'name': 'child1'})
|
||||
]))
|
||||
]));
|
||||
const viewContainerData = asElementData(parentView, 1);
|
||||
|
||||
const childView0 = createEmbeddedView(parentView, parentView.def.nodes[1]);
|
||||
|
||||
const childView1 = createEmbeddedView(parentView, parentView.def.nodes[2]);
|
||||
|
||||
const rootChildren = getDOM().childNodes(rootNodes[0]);
|
||||
attachEmbeddedView(asElementData(parentView, 1), 0, childView0);
|
||||
attachEmbeddedView(asElementData(parentView, 1), 1, childView1);
|
||||
attachEmbeddedView(viewContainerData, 0, childView0);
|
||||
attachEmbeddedView(viewContainerData, 1, childView1);
|
||||
|
||||
// 2 anchors + 2 elements
|
||||
const rootChildren = getDOM().childNodes(rootNodes[0]);
|
||||
expect(rootChildren.length).toBe(4);
|
||||
expect(getDOM().getAttribute(rootChildren[1], 'name')).toBe('child0');
|
||||
expect(getDOM().getAttribute(rootChildren[2], 'name')).toBe('child1');
|
||||
|
||||
detachEmbeddedView(asElementData(parentView, 1), 1);
|
||||
detachEmbeddedView(asElementData(parentView, 1), 0);
|
||||
detachEmbeddedView(viewContainerData, 1);
|
||||
detachEmbeddedView(viewContainerData, 0);
|
||||
|
||||
expect(getDOM().childNodes(rootNodes[0]).length).toBe(2);
|
||||
});
|
||||
|
||||
it('should move embedded views', () => {
|
||||
const {view: parentView, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||
elementDef(NodeFlags.None, null, null, 2, 'div'),
|
||||
anchorDef(NodeFlags.HasEmbeddedViews, null, null, 0, embeddedViewDef([
|
||||
elementDef(NodeFlags.None, null, null, 0, 'span', {'name': 'child0'})
|
||||
])),
|
||||
anchorDef(NodeFlags.None, null, null, 0, embeddedViewDef([
|
||||
elementDef(NodeFlags.None, null, null, 0, 'span', {'name': 'child1'})
|
||||
]))
|
||||
]));
|
||||
const viewContainerData = asElementData(parentView, 1);
|
||||
|
||||
const childView0 = createEmbeddedView(parentView, parentView.def.nodes[1]);
|
||||
const childView1 = createEmbeddedView(parentView, parentView.def.nodes[2]);
|
||||
|
||||
attachEmbeddedView(viewContainerData, 0, childView0);
|
||||
attachEmbeddedView(viewContainerData, 1, childView1);
|
||||
|
||||
moveEmbeddedView(viewContainerData, 0, 1);
|
||||
|
||||
expect(viewContainerData.embeddedViews).toEqual([childView1, childView0]);
|
||||
// 2 anchors + 2 elements
|
||||
const rootChildren = getDOM().childNodes(rootNodes[0]);
|
||||
expect(rootChildren.length).toBe(4);
|
||||
expect(getDOM().getAttribute(rootChildren[1], 'name')).toBe('child1');
|
||||
expect(getDOM().getAttribute(rootChildren[2], 'name')).toBe('child0');
|
||||
});
|
||||
|
||||
it('should include embedded views in root nodes', () => {
|
||||
const {view: parentView} = createAndGetRootNodes(compViewDef([
|
||||
anchorDef(NodeFlags.HasEmbeddedViews, null, null, 0, embeddedViewDef([
|
||||
|
@ -6,8 +6,8 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {RootRenderer} from '@angular/core';
|
||||
import {checkNodeDynamic, checkNodeInline} from '@angular/core/src/view/index';
|
||||
import {Injector, RootRenderer, Sanitizer} from '@angular/core';
|
||||
import {RootData, checkNodeDynamic, checkNodeInline} from '@angular/core/src/view/index';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
|
||||
@ -51,3 +51,19 @@ export function checkNodeInlineOrDynamic(inlineDynamic: InlineDynamic, values: a
|
||||
return checkNodeDynamic(values);
|
||||
}
|
||||
}
|
||||
|
||||
export function createRootData(projectableNodes?: any[][], rootSelectorOrNode?: any): RootData {
|
||||
const injector = TestBed.get(Injector);
|
||||
const renderer = injector.get(RootRenderer);
|
||||
const sanitizer = injector.get(Sanitizer);
|
||||
projectableNodes = projectableNodes || [];
|
||||
return <RootData>{
|
||||
injector,
|
||||
projectableNodes,
|
||||
selectorOrNode: rootSelectorOrNode, sanitizer, renderer
|
||||
};
|
||||
}
|
||||
|
||||
export let removeNodes: Node[];
|
||||
beforeEach(() => { removeNodes = []; });
|
||||
afterEach(() => { removeNodes.forEach((node) => getDOM().remove(node)); });
|
||||
|
@ -6,12 +6,12 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {RenderComponentType, RootRenderer, Sanitizer, SecurityContext, TemplateRef, ViewContainerRef, ViewEncapsulation, getDebugNode} from '@angular/core';
|
||||
import {DebugContext, DefaultServices, NodeDef, NodeFlags, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, asTextData, attachEmbeddedView, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createEmbeddedView, createRootView, detachEmbeddedView, directiveDef, elementDef, ngContentDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, TemplateRef, ViewContainerRef, ViewEncapsulation, getDebugNode} from '@angular/core';
|
||||
import {DebugContext, NodeDef, NodeFlags, RootData, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, asTextData, attachEmbeddedView, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createEmbeddedView, createRootView, detachEmbeddedView, directiveDef, elementDef, ngContentDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {inject} from '@angular/core/testing';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
|
||||
import {isBrowser, setupAndCheckRenderer} from './helper';
|
||||
import {createRootData, isBrowser, setupAndCheckRenderer} from './helper';
|
||||
|
||||
export function main() {
|
||||
if (isBrowser()) {
|
||||
@ -24,15 +24,14 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
describe(`View NgContent, directDom: ${config.directDom}`, () => {
|
||||
setupAndCheckRenderer(config);
|
||||
|
||||
let services: Services;
|
||||
let rootData: RootData;
|
||||
let renderComponentType: RenderComponentType;
|
||||
|
||||
beforeEach(
|
||||
inject([RootRenderer, Sanitizer], (rootRenderer: RootRenderer, sanitizer: Sanitizer) => {
|
||||
services = new DefaultServices(rootRenderer, sanitizer);
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
}));
|
||||
beforeEach(() => {
|
||||
rootData = createRootData();
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
});
|
||||
|
||||
function compViewDef(
|
||||
nodes: NodeDef[], update?: ViewUpdateFn, handleEvent?: ViewHandleEventFn): ViewDefinition {
|
||||
@ -57,7 +56,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
|
||||
function createAndGetRootNodes(
|
||||
viewDef: ViewDefinition, ctx?: any): {rootNodes: any[], view: ViewData} {
|
||||
const view = createRootView(services, () => viewDef, ctx || {});
|
||||
const view = createRootView(rootData, viewDef, ctx || {});
|
||||
const rootNodes = rootRenderNodes(view);
|
||||
return {rootNodes, view};
|
||||
}
|
||||
@ -136,5 +135,18 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
detachEmbeddedView(asElementData(componentView, 1), 0);
|
||||
expect(getDOM().childNodes(getDOM().firstChild(rootNodes[0])).length).toBe(1);
|
||||
});
|
||||
|
||||
if (isBrowser()) {
|
||||
it('should use root projectable nodes', () => {
|
||||
rootData.projectableNodes =
|
||||
[[document.createTextNode('a')], [document.createTextNode('b')]];
|
||||
|
||||
const {view, rootNodes} = createAndGetRootNodes(
|
||||
compViewDef(hostElDef([], [ngContentDef(null, 0), ngContentDef(null, 1)])));
|
||||
|
||||
expect(getDOM().childNodes(rootNodes[0])[0]).toBe(rootData.projectableNodes[0][0]);
|
||||
expect(getDOM().childNodes(rootNodes[0])[1]).toBe(rootData.projectableNodes[1][0]);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -7,11 +7,11 @@
|
||||
*/
|
||||
|
||||
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ChangeDetectorRef, DoCheck, ElementRef, EventEmitter, Injector, OnChanges, OnDestroy, OnInit, RenderComponentType, Renderer, RootRenderer, Sanitizer, SecurityContext, SimpleChange, TemplateRef, ViewContainerRef, ViewEncapsulation, WrappedValue, getDebugNode} from '@angular/core';
|
||||
import {BindingType, DebugContext, DefaultServices, DepFlags, NodeDef, NodeFlags, ProviderType, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, destroyView, directiveDef, elementDef, providerDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {BindingType, DebugContext, DepFlags, NodeDef, NodeFlags, ProviderType, RootData, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, destroyView, directiveDef, elementDef, providerDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {inject} from '@angular/core/testing';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
|
||||
import {INLINE_DYNAMIC_VALUES, InlineDynamic, checkNodeInlineOrDynamic, isBrowser, setupAndCheckRenderer} from './helper';
|
||||
import {INLINE_DYNAMIC_VALUES, InlineDynamic, checkNodeInlineOrDynamic, createRootData, isBrowser, setupAndCheckRenderer} from './helper';
|
||||
|
||||
export function main() {
|
||||
if (isBrowser()) {
|
||||
@ -24,15 +24,14 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
describe(`View Providers, directDom: ${config.directDom}`, () => {
|
||||
setupAndCheckRenderer(config);
|
||||
|
||||
let services: Services;
|
||||
let rootData: RootData;
|
||||
let renderComponentType: RenderComponentType;
|
||||
|
||||
beforeEach(
|
||||
inject([RootRenderer, Sanitizer], (rootRenderer: RootRenderer, sanitizer: Sanitizer) => {
|
||||
services = new DefaultServices(rootRenderer, sanitizer);
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
}));
|
||||
beforeEach(() => {
|
||||
rootData = createRootData();
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
});
|
||||
|
||||
function compViewDef(
|
||||
nodes: NodeDef[], update?: ViewUpdateFn, handleEvent?: ViewHandleEventFn): ViewDefinition {
|
||||
@ -44,7 +43,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
}
|
||||
|
||||
function createAndGetRootNodes(viewDef: ViewDefinition): {rootNodes: any[], view: ViewData} {
|
||||
const view = createRootView(services, () => viewDef);
|
||||
const view = createRootView(rootData, viewDef);
|
||||
const rootNodes = rootRenderNodes(view);
|
||||
return {rootNodes, view};
|
||||
}
|
||||
@ -229,6 +228,18 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
expect(instance.dep).toBe('someParentValue');
|
||||
});
|
||||
|
||||
it('should ask the root injector', () => {
|
||||
const getSpy = spyOn(rootData.injector, 'get');
|
||||
getSpy.and.returnValue('rootValue');
|
||||
createAndGetRootNodes(compViewDef([
|
||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||
directiveDef(NodeFlags.None, null, 0, SomeService, ['rootDep'])
|
||||
]));
|
||||
|
||||
expect(instance.dep).toBe('rootValue');
|
||||
expect(getSpy).toHaveBeenCalledWith('rootDep', Injector.THROW_IF_NOT_FOUND);
|
||||
});
|
||||
|
||||
describe('builtin tokens', () => {
|
||||
it('should inject ViewContainerRef', () => {
|
||||
createAndGetRootNodes(compViewDef([
|
||||
|
@ -6,23 +6,22 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {PipeTransform, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, WrappedValue} from '@angular/core';
|
||||
import {DefaultServices, NodeDef, NodeFlags, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asProviderData, asPureExpressionData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, directiveDef, elementDef, pureArrayDef, pureObjectDef, purePipeDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {Injector, PipeTransform, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, WrappedValue} from '@angular/core';
|
||||
import {NodeDef, NodeFlags, RootData, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asProviderData, asPureExpressionData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, directiveDef, elementDef, pureArrayDef, pureObjectDef, purePipeDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {inject} from '@angular/core/testing';
|
||||
|
||||
import {INLINE_DYNAMIC_VALUES, InlineDynamic, checkNodeInlineOrDynamic} from './helper';
|
||||
import {INLINE_DYNAMIC_VALUES, InlineDynamic, checkNodeInlineOrDynamic, createRootData} from './helper';
|
||||
|
||||
export function main() {
|
||||
describe(`View Pure Expressions`, () => {
|
||||
let services: Services;
|
||||
let rootData: RootData;
|
||||
let renderComponentType: RenderComponentType;
|
||||
|
||||
beforeEach(
|
||||
inject([RootRenderer, Sanitizer], (rootRenderer: RootRenderer, sanitizer: Sanitizer) => {
|
||||
services = new DefaultServices(rootRenderer, sanitizer);
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
}));
|
||||
beforeEach(() => {
|
||||
rootData = createRootData();
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
});
|
||||
|
||||
function compViewDef(
|
||||
nodes: NodeDef[], update?: ViewUpdateFn, handleEvent?: ViewHandleEventFn): ViewDefinition {
|
||||
@ -30,7 +29,7 @@ export function main() {
|
||||
}
|
||||
|
||||
function createAndGetRootNodes(viewDef: ViewDefinition): {rootNodes: any[], view: ViewData} {
|
||||
const view = createRootView(services, () => viewDef);
|
||||
const view = createRootView(rootData, viewDef);
|
||||
const rootNodes = rootRenderNodes(view);
|
||||
return {rootNodes, view};
|
||||
}
|
||||
|
@ -6,22 +6,23 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ElementRef, QueryList, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, TemplateRef, ViewContainerRef, ViewEncapsulation, getDebugNode} from '@angular/core';
|
||||
import {BindingType, DebugContext, DefaultServices, NodeDef, NodeFlags, QueryBindingType, QueryValueType, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, attachEmbeddedView, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createEmbeddedView, createRootView, destroyView, detachEmbeddedView, directiveDef, elementDef, queryDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {ElementRef, Injector, QueryList, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, TemplateRef, ViewContainerRef, ViewEncapsulation, getDebugNode} from '@angular/core';
|
||||
import {BindingType, DebugContext, NodeDef, NodeFlags, QueryBindingType, QueryValueType, RootData, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, attachEmbeddedView, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createEmbeddedView, createRootView, destroyView, detachEmbeddedView, directiveDef, elementDef, queryDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {inject} from '@angular/core/testing';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
|
||||
import {createRootData} from './helper';
|
||||
|
||||
export function main() {
|
||||
describe(`Query Views`, () => {
|
||||
let services: Services;
|
||||
let rootData: RootData;
|
||||
let renderComponentType: RenderComponentType;
|
||||
|
||||
beforeEach(
|
||||
inject([RootRenderer, Sanitizer], (rootRenderer: RootRenderer, sanitizer: Sanitizer) => {
|
||||
services = new DefaultServices(rootRenderer, sanitizer);
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
}));
|
||||
beforeEach(() => {
|
||||
rootData = createRootData();
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
});
|
||||
|
||||
function compViewDef(
|
||||
nodes: NodeDef[], update?: ViewUpdateFn, handleEvent?: ViewHandleEventFn): ViewDefinition {
|
||||
@ -34,7 +35,7 @@ export function main() {
|
||||
|
||||
function createAndGetRootNodes(
|
||||
viewDef: ViewDefinition, context: any = null): {rootNodes: any[], view: ViewData} {
|
||||
const view = createRootView(services, () => viewDef, context);
|
||||
const view = createRootView(rootData, viewDef, context);
|
||||
const rootNodes = rootRenderNodes(view);
|
||||
return {rootNodes, view};
|
||||
}
|
||||
|
@ -6,24 +6,23 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, getDebugNode} from '@angular/core';
|
||||
import {DebugContext, DefaultServices, NodeDef, NodeFlags, QueryValueType, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, asTextData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, directiveDef, elementDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, getDebugNode} from '@angular/core';
|
||||
import {DebugContext, NodeDef, NodeFlags, QueryValueType, Refs, RootData, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, asTextData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, directiveDef, elementDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {inject} from '@angular/core/testing';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
|
||||
import {isBrowser, setupAndCheckRenderer} from './helper';
|
||||
import {createRootData, isBrowser, setupAndCheckRenderer} from './helper';
|
||||
|
||||
export function main() {
|
||||
describe('View Services', () => {
|
||||
let services: Services;
|
||||
describe('View References', () => {
|
||||
let rootData: RootData;
|
||||
let renderComponentType: RenderComponentType;
|
||||
|
||||
beforeEach(
|
||||
inject([RootRenderer, Sanitizer], (rootRenderer: RootRenderer, sanitizer: Sanitizer) => {
|
||||
services = new DefaultServices(rootRenderer, sanitizer);
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
}));
|
||||
beforeEach(() => {
|
||||
rootData = createRootData();
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
});
|
||||
|
||||
function compViewDef(
|
||||
nodes: NodeDef[], update?: ViewUpdateFn, handleEvent?: ViewHandleEventFn): ViewDefinition {
|
||||
@ -32,7 +31,7 @@ export function main() {
|
||||
|
||||
function createAndGetRootNodes(
|
||||
viewDef: ViewDefinition, context: any = null): {rootNodes: any[], view: ViewData} {
|
||||
const view = createRootView(services, () => viewDef, context);
|
||||
const view = createRootView(rootData, viewDef, context);
|
||||
const rootNodes = rootRenderNodes(view);
|
||||
return {rootNodes, view};
|
||||
}
|
||||
@ -59,7 +58,7 @@ export function main() {
|
||||
const view = createViewWithData();
|
||||
const compView = asProviderData(view, 1).componentView;
|
||||
|
||||
const debugCtx = view.services.createDebugContext(compView, 0);
|
||||
const debugCtx = Refs.createDebugContext(compView, 0);
|
||||
|
||||
expect(debugCtx.componentRenderElement).toBe(asElementData(view, 0).renderElement);
|
||||
expect(debugCtx.renderNode).toBe(asElementData(compView, 0).renderElement);
|
||||
@ -76,7 +75,7 @@ export function main() {
|
||||
const view = createViewWithData();
|
||||
const compView = asProviderData(view, 1).componentView;
|
||||
|
||||
const debugCtx = view.services.createDebugContext(compView, 2);
|
||||
const debugCtx = Refs.createDebugContext(compView, 2);
|
||||
|
||||
expect(debugCtx.componentRenderElement).toBe(asElementData(view, 0).renderElement);
|
||||
expect(debugCtx.renderNode).toBe(asTextData(compView, 2).renderText);
|
||||
@ -90,7 +89,7 @@ export function main() {
|
||||
const view = createViewWithData();
|
||||
const compView = asProviderData(view, 1).componentView;
|
||||
|
||||
const debugCtx = view.services.createDebugContext(compView, 1);
|
||||
const debugCtx = Refs.createDebugContext(compView, 1);
|
||||
|
||||
expect(debugCtx.renderNode).toBe(asElementData(compView, 0).renderElement);
|
||||
});
|
@ -6,12 +6,12 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, WrappedValue, getDebugNode} from '@angular/core';
|
||||
import {DebugContext, DefaultServices, NodeDef, NodeFlags, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asTextData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, elementDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, WrappedValue, getDebugNode} from '@angular/core';
|
||||
import {DebugContext, NodeDef, NodeFlags, RootData, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asTextData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, elementDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {inject} from '@angular/core/testing';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
|
||||
import {INLINE_DYNAMIC_VALUES, InlineDynamic, checkNodeInlineOrDynamic, isBrowser, setupAndCheckRenderer} from './helper';
|
||||
import {INLINE_DYNAMIC_VALUES, InlineDynamic, checkNodeInlineOrDynamic, createRootData, isBrowser, setupAndCheckRenderer} from './helper';
|
||||
|
||||
export function main() {
|
||||
if (isBrowser()) {
|
||||
@ -24,15 +24,14 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
describe(`View Text, directDom: ${config.directDom}`, () => {
|
||||
setupAndCheckRenderer(config);
|
||||
|
||||
let services: Services;
|
||||
let rootData: RootData;
|
||||
let renderComponentType: RenderComponentType;
|
||||
|
||||
beforeEach(
|
||||
inject([RootRenderer, Sanitizer], (rootRenderer: RootRenderer, sanitizer: Sanitizer) => {
|
||||
services = new DefaultServices(rootRenderer, sanitizer);
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
}));
|
||||
beforeEach(() => {
|
||||
rootData = createRootData();
|
||||
renderComponentType =
|
||||
new RenderComponentType('1', 'someUrl', 0, ViewEncapsulation.None, [], {});
|
||||
});
|
||||
|
||||
function compViewDef(
|
||||
nodes: NodeDef[], update?: ViewUpdateFn, handleEvent?: ViewHandleEventFn): ViewDefinition {
|
||||
@ -41,7 +40,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
||||
|
||||
function createAndGetRootNodes(
|
||||
viewDef: ViewDefinition, context?: any): {rootNodes: any[], view: ViewData} {
|
||||
const view = createRootView(services, () => viewDef, context);
|
||||
const view = createRootView(rootData, viewDef, context);
|
||||
const rootNodes = rootRenderNodes(view);
|
||||
return {rootNodes, view};
|
||||
}
|
||||
|
Reference in New Issue
Block a user