feat: RendererV2 integration (#14469)
This commit is contained in:
parent
b4d444a0a7
commit
bb9c7ae6e7
|
@ -15,7 +15,7 @@ export function main() {
|
|||
|
||||
function detectChangesAndExpectClassName(classes: string): void {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.children[0].nativeElement.className).toEqual(classes);
|
||||
expect(fixture.debugElement.children[0].nativeElement.className.trim()).toEqual(classes);
|
||||
}
|
||||
|
||||
function getComponent(): TestComponent { return fixture.debugElement.componentInstance; }
|
||||
|
|
|
@ -107,7 +107,8 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver, BuiltinConverter
|
|||
}
|
||||
|
||||
templateVisitAll(this, astNodes, {elementDepth});
|
||||
if (astNodes.length === 0 || (this.parent && hasViewContainer(astNodes[astNodes.length - 1]))) {
|
||||
if (astNodes.length === 0 ||
|
||||
(this.parent && needsAdditionalRootNode(astNodes[astNodes.length - 1]))) {
|
||||
// if the view is empty, or an embedded view has a view container as last root nde,
|
||||
// create an additional root node.
|
||||
this.nodeDefs.push(o.importExpr(createIdentifier(Identifiers.anchorDef)).callFn([
|
||||
|
@ -752,13 +753,16 @@ function depDef(dep: CompileDiDependencyMetadata): o.Expression {
|
|||
return flags === viewEngine.DepFlags.None ? expr : o.literalArr([o.literal(flags), expr]);
|
||||
}
|
||||
|
||||
function hasViewContainer(ast: TemplateAst): boolean {
|
||||
function needsAdditionalRootNode(ast: TemplateAst): boolean {
|
||||
if (ast instanceof EmbeddedTemplateAst) {
|
||||
return ast.hasViewContainer;
|
||||
} else if (ast instanceof ElementAst) {
|
||||
}
|
||||
|
||||
if (ast instanceof ElementAst) {
|
||||
return ast.hasViewContainer;
|
||||
}
|
||||
return false;
|
||||
|
||||
return ast instanceof NgContentAst;
|
||||
}
|
||||
|
||||
function calcQueryId(queryId: QueryId): string {
|
||||
|
|
|
@ -92,6 +92,8 @@ export const __core_private__: {
|
|||
makeDecorator: typeof decorators.makeDecorator,
|
||||
DebugDomRootRenderer: typeof debug.DebugDomRootRenderer,
|
||||
_DebugDomRootRenderer: debug.DebugDomRootRenderer,
|
||||
DebugDomRendererV2: typeof debug.DebugDomRendererV2,
|
||||
_DebugDomRendererV2: debug.DebugDomRendererV2,
|
||||
Console: typeof console.Console,
|
||||
_Console: console.Console,
|
||||
reflector: typeof reflection.reflector,
|
||||
|
@ -101,9 +103,6 @@ export const __core_private__: {
|
|||
_NoOpAnimationPlayer: NoOpAnimationPlayer_,
|
||||
AnimationPlayer: typeof AnimationPlayer_,
|
||||
_AnimationPlayer: AnimationPlayer_,
|
||||
|
||||
|
||||
|
||||
AnimationSequencePlayer: typeof AnimationSequencePlayer_,
|
||||
_AnimationSequencePlayer: AnimationSequencePlayer_,
|
||||
AnimationGroupPlayer: typeof AnimationGroupPlayer_,
|
||||
|
@ -157,6 +156,7 @@ export const __core_private__: {
|
|||
ReflectionCapabilities: reflection_capabilities.ReflectionCapabilities,
|
||||
makeDecorator: decorators.makeDecorator,
|
||||
DebugDomRootRenderer: debug.DebugDomRootRenderer,
|
||||
DebugDomRendererV2: debug.DebugDomRendererV2,
|
||||
Console: console.Console,
|
||||
reflector: reflection.reflector,
|
||||
Reflector: reflection.Reflector,
|
||||
|
|
|
@ -85,16 +85,26 @@ export class DebugElement extends DebugNode {
|
|||
insertChildrenAfter(child: DebugNode, newChildren: DebugNode[]) {
|
||||
const siblingIndex = this.childNodes.indexOf(child);
|
||||
if (siblingIndex !== -1) {
|
||||
const previousChildren = this.childNodes.slice(0, siblingIndex + 1);
|
||||
const nextChildren = this.childNodes.slice(siblingIndex + 1);
|
||||
this.childNodes = previousChildren.concat(newChildren, nextChildren);
|
||||
for (let i = 0; i < newChildren.length; ++i) {
|
||||
const newChild = newChildren[i];
|
||||
if (newChild.parent) {
|
||||
newChild.parent.removeChild(newChild);
|
||||
this.childNodes.splice(siblingIndex + 1, 0, ...newChildren);
|
||||
newChildren.forEach(c => {
|
||||
if (c.parent) {
|
||||
c.parent.removeChild(c);
|
||||
}
|
||||
newChild.parent = this;
|
||||
c.parent = this;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
insertBefore(refChild: DebugNode, newChild: DebugNode): void {
|
||||
const refIndex = this.childNodes.indexOf(refChild);
|
||||
if (refIndex === -1) {
|
||||
this.addChild(newChild);
|
||||
} else {
|
||||
if (newChild.parent) {
|
||||
newChild.parent.removeChild(newChild);
|
||||
}
|
||||
newChild.parent = this;
|
||||
this.childNodes.splice(refIndex, 0, newChild);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import {AnimationKeyframe} from '../animation/animation_keyframe';
|
|||
import {AnimationPlayer} from '../animation/animation_player';
|
||||
import {AnimationStyles} from '../animation/animation_styles';
|
||||
import {isPresent} from '../facade/lang';
|
||||
import {RenderComponentType, RenderDebugInfo, Renderer, RootRenderer} from '../render/api';
|
||||
import {RenderComponentType, RenderDebugInfo, Renderer, RendererV2, RootRenderer} from '../render/api';
|
||||
|
||||
import {DebugElement, DebugNode, EventListener, getDebugNode, indexDebugNode, removeDebugNodeFromIndex} from './debug_node';
|
||||
|
||||
|
@ -22,7 +22,7 @@ export class DebugDomRootRenderer implements RootRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
export class DebugDomRenderer {
|
||||
export class DebugDomRenderer implements Renderer {
|
||||
constructor(private _delegate: Renderer) {}
|
||||
|
||||
selectRootElement(selectorOrNode: string|any, debugInfo?: RenderDebugInfo): any {
|
||||
|
@ -81,7 +81,7 @@ export class DebugDomRenderer {
|
|||
detachView(viewRootNodes: any[]) {
|
||||
viewRootNodes.forEach((node) => {
|
||||
const debugNode = getDebugNode(node);
|
||||
if (isPresent(debugNode) && isPresent(debugNode.parent)) {
|
||||
if (debugNode && debugNode.parent) {
|
||||
debugNode.parent.removeChild(debugNode);
|
||||
}
|
||||
});
|
||||
|
@ -156,3 +156,151 @@ export class DebugDomRenderer {
|
|||
element, startingStyles, keyframes, duration, delay, easing, previousPlayers);
|
||||
}
|
||||
}
|
||||
|
||||
export class DebugDomRendererV2 implements RendererV2 {
|
||||
constructor(private _delegate: RendererV2) {}
|
||||
|
||||
createElement(name: string, namespace?: string, debugInfo?: any): any {
|
||||
const el = this._delegate.createElement(name, namespace, debugInfo);
|
||||
const debugEl = new DebugElement(el, null, debugInfo);
|
||||
debugEl.name = name;
|
||||
indexDebugNode(debugEl);
|
||||
return el;
|
||||
}
|
||||
|
||||
createComment(value: string, debugInfo?: any): any {
|
||||
const comment = this._delegate.createComment(value, debugInfo);
|
||||
const debugEl = new DebugNode(comment, null, debugInfo);
|
||||
indexDebugNode(debugEl);
|
||||
return comment;
|
||||
}
|
||||
|
||||
createText(value: string, debugInfo?: any): any {
|
||||
const text = this._delegate.createText(value, debugInfo);
|
||||
const debugEl = new DebugNode(text, null, debugInfo);
|
||||
indexDebugNode(debugEl);
|
||||
return text;
|
||||
}
|
||||
|
||||
appendChild(parent: any, newChild: any): void {
|
||||
const debugEl = getDebugNode(parent);
|
||||
const debugChildEl = getDebugNode(newChild);
|
||||
if (debugEl && debugChildEl && debugEl instanceof DebugElement) {
|
||||
debugEl.addChild(debugChildEl);
|
||||
}
|
||||
this._delegate.appendChild(parent, newChild);
|
||||
}
|
||||
|
||||
insertBefore(parent: any, newChild: any, refChild: any): void {
|
||||
const debugEl = getDebugNode(parent);
|
||||
const debugChildEl = getDebugNode(newChild);
|
||||
const debugRefEl = getDebugNode(refChild);
|
||||
if (debugEl && debugChildEl && debugEl instanceof DebugElement) {
|
||||
debugEl.insertBefore(debugRefEl, debugChildEl);
|
||||
}
|
||||
|
||||
this._delegate.insertBefore(parent, newChild, refChild);
|
||||
}
|
||||
|
||||
removeChild(parent: any, oldChild: any): void {
|
||||
const debugEl = getDebugNode(parent);
|
||||
const debugChildEl = getDebugNode(oldChild);
|
||||
if (debugEl && debugChildEl && debugEl instanceof DebugElement) {
|
||||
debugEl.removeChild(debugChildEl);
|
||||
}
|
||||
this._delegate.removeChild(parent, oldChild);
|
||||
}
|
||||
|
||||
selectRootElement(selectorOrNode: string|any, debugInfo?: any): any {
|
||||
const el = this._delegate.selectRootElement(selectorOrNode, debugInfo);
|
||||
const debugEl = new DebugElement(el, null, debugInfo);
|
||||
indexDebugNode(debugEl);
|
||||
return el;
|
||||
}
|
||||
|
||||
parentNode(node: any): any { return this._delegate.parentNode(node); }
|
||||
|
||||
nextSibling(node: any): any { return this._delegate.nextSibling(node); }
|
||||
|
||||
setAttribute(el: any, name: string, value: string, namespace?: string): void {
|
||||
const debugEl = getDebugNode(el);
|
||||
if (debugEl && debugEl instanceof DebugElement) {
|
||||
const fullName = namespace ? namespace + ':' + name : name;
|
||||
debugEl.attributes[fullName] = value;
|
||||
}
|
||||
this._delegate.setAttribute(el, name, value, namespace);
|
||||
}
|
||||
|
||||
removeAttribute(el: any, name: string, namespace?: string): void {
|
||||
const debugEl = getDebugNode(el);
|
||||
if (debugEl && debugEl instanceof DebugElement) {
|
||||
const fullName = namespace ? namespace + ':' + name : name;
|
||||
debugEl.attributes[fullName] = null;
|
||||
}
|
||||
this._delegate.removeAttribute(el, name, namespace);
|
||||
}
|
||||
|
||||
setBindingDebugInfo(el: any, propertyName: string, propertyValue: string): void {
|
||||
this._delegate.setBindingDebugInfo(el, propertyName, propertyValue);
|
||||
}
|
||||
|
||||
removeBindingDebugInfo(el: any, propertyName: string): void {
|
||||
this._delegate.removeBindingDebugInfo(el, propertyName);
|
||||
}
|
||||
|
||||
addClass(el: any, name: string): void {
|
||||
const debugEl = getDebugNode(el);
|
||||
if (debugEl && debugEl instanceof DebugElement) {
|
||||
debugEl.classes[name] = true;
|
||||
}
|
||||
this._delegate.addClass(el, name);
|
||||
}
|
||||
|
||||
removeClass(el: any, name: string): void {
|
||||
const debugEl = getDebugNode(el);
|
||||
if (debugEl && debugEl instanceof DebugElement) {
|
||||
debugEl.classes[name] = false;
|
||||
}
|
||||
this._delegate.removeClass(el, name);
|
||||
}
|
||||
|
||||
setStyle(el: any, style: string, value: any, hasVendorPrefix: boolean, hasImportant: boolean):
|
||||
void {
|
||||
const debugEl = getDebugNode(el);
|
||||
if (debugEl && debugEl instanceof DebugElement) {
|
||||
debugEl.styles[style] = value;
|
||||
}
|
||||
this._delegate.setStyle(el, style, value, hasVendorPrefix, hasImportant);
|
||||
}
|
||||
|
||||
removeStyle(el: any, style: string, hasVendorPrefix: boolean): void {
|
||||
const debugEl = getDebugNode(el);
|
||||
if (debugEl && debugEl instanceof DebugElement) {
|
||||
debugEl.styles[style] = null;
|
||||
}
|
||||
this._delegate.removeStyle(el, style, hasVendorPrefix);
|
||||
}
|
||||
|
||||
setProperty(el: any, name: string, value: any): void {
|
||||
const debugEl = getDebugNode(el);
|
||||
if (debugEl && debugEl instanceof DebugElement) {
|
||||
debugEl.properties[name] = value;
|
||||
}
|
||||
this._delegate.setProperty(el, name, value);
|
||||
}
|
||||
|
||||
setText(node: any, value: string): void { this._delegate.setText(node, value); }
|
||||
|
||||
listen(
|
||||
target: 'document'|'windows'|'body'|any, eventName: string,
|
||||
callback: (event: any) => boolean): () => void {
|
||||
if (typeof target !== 'string') {
|
||||
const debugEl = getDebugNode(target);
|
||||
if (debugEl) {
|
||||
debugEl.listeners.push(new EventListener(eventName, callback));
|
||||
}
|
||||
}
|
||||
|
||||
return this._delegate.listen(target, eventName, callback);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Type} from './type';
|
||||
import {DebugContext} from './view';
|
||||
|
||||
export const ERROR_TYPE = 'ngType';
|
||||
|
|
|
@ -80,8 +80,8 @@ export class ViewContainer {
|
|||
return result;
|
||||
}
|
||||
|
||||
moveView(view: AppView<any>, currentIndex: number) {
|
||||
const previousIndex = this.nestedViews.indexOf(view);
|
||||
moveView(view: AppView<any>, toIndex: number) {
|
||||
const fromIndex = this.nestedViews.indexOf(view);
|
||||
if (view.type === ViewType.COMPONENT) {
|
||||
throw new Error(`Component views can't be moved!`);
|
||||
}
|
||||
|
@ -90,9 +90,9 @@ export class ViewContainer {
|
|||
nestedViews = [];
|
||||
this.nestedViews = nestedViews;
|
||||
}
|
||||
nestedViews.splice(previousIndex, 1);
|
||||
nestedViews.splice(currentIndex, 0, view);
|
||||
const prevView = currentIndex > 0 ? nestedViews[currentIndex - 1] : null;
|
||||
nestedViews.splice(fromIndex, 1);
|
||||
nestedViews.splice(toIndex, 0, view);
|
||||
const prevView = toIndex > 0 ? nestedViews[toIndex - 1] : null;
|
||||
view.moveAfter(this, prevView);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
*/
|
||||
|
||||
import {Injector} from '../di/injector';
|
||||
import {isPresent} from '../facade/lang';
|
||||
import {WtfScopeFn, wtfCreateScope, wtfLeave} from '../profile/profile';
|
||||
|
||||
import {ComponentFactory, ComponentRef} from './component_factory';
|
||||
|
@ -133,7 +132,7 @@ export class ViewContainerRef_ implements ViewContainerRef {
|
|||
get(index: number): ViewRef { return this._element.nestedViews[index].ref; }
|
||||
get length(): number {
|
||||
const views = this._element.nestedViews;
|
||||
return isPresent(views) ? views.length : 0;
|
||||
return views ? views.length : 0;
|
||||
}
|
||||
|
||||
get element(): ElementRef { return this._element.elementRef; }
|
||||
|
|
|
@ -7,4 +7,4 @@
|
|||
*/
|
||||
|
||||
// Public API for render
|
||||
export {RenderComponentType, Renderer, RootRenderer} from './render/api';
|
||||
export {RENDERER_V2_DIRECT, RenderComponentType, Renderer, RendererV2, RootRenderer} from './render/api';
|
||||
|
|
|
@ -9,9 +9,16 @@
|
|||
import {AnimationKeyframe} from '../../src/animation/animation_keyframe';
|
||||
import {AnimationPlayer} from '../../src/animation/animation_player';
|
||||
import {AnimationStyles} from '../../src/animation/animation_styles';
|
||||
import {Injector} from '../di/injector';
|
||||
import {InjectionToken, Injector} from '../di';
|
||||
import {ViewEncapsulation} from '../metadata/view';
|
||||
|
||||
/**
|
||||
* Provide a concrete implementation of {@link RendererV2}
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export const RENDERER_V2_DIRECT = new InjectionToken<RendererV2>('Renderer V2');
|
||||
|
||||
/**
|
||||
* @experimental
|
||||
*/
|
||||
|
@ -91,6 +98,56 @@ export abstract class Renderer {
|
|||
previousPlayers?: AnimationPlayer[]): AnimationPlayer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @experimental
|
||||
*/
|
||||
export abstract class RendererV2 {
|
||||
abstract createElement(name: string, namespace?: string, debugInfo?: RenderDebugContext): any;
|
||||
abstract createComment(value: string, debugInfo?: RenderDebugContext): any;
|
||||
abstract createText(value: string, debugInfo?: RenderDebugContext): any;
|
||||
abstract appendChild(parent: any, newChild: any): void;
|
||||
abstract insertBefore(parent: any, newChild: any, refChild: any): void;
|
||||
abstract removeChild(parent: any, oldChild: any): void;
|
||||
abstract selectRootElement(selectorOrNode: string|any, debugInfo?: RenderDebugContext): any;
|
||||
/**
|
||||
* Attention: On WebWorkers, this will always return a value,
|
||||
* as we are asking for a result synchronously. I.e.
|
||||
* the caller can't rely on checking whether this is null or not.
|
||||
*/
|
||||
abstract parentNode(node: any): any;
|
||||
/**
|
||||
* Attention: On WebWorkers, this will always return a value,
|
||||
* as we are asking for a result synchronously. I.e.
|
||||
* the caller can't rely on checking whether this is null or not.
|
||||
*/
|
||||
abstract nextSibling(node: any): any;
|
||||
abstract setAttribute(el: any, name: string, value: string, namespace?: string): void;
|
||||
abstract removeAttribute(el: any, name: string, namespace?: string): void;
|
||||
abstract setBindingDebugInfo(el: any, propertyName: string, propertyValue: string): void;
|
||||
abstract removeBindingDebugInfo(el: any, propertyName: string): void;
|
||||
abstract addClass(el: any, name: string): void;
|
||||
abstract removeClass(el: any, name: string): void;
|
||||
abstract setStyle(
|
||||
el: any, style: string, value: any, hasVendorPrefix: boolean, hasImportant: boolean): void;
|
||||
abstract removeStyle(el: any, style: string, hasVendorPrefix: boolean): void;
|
||||
abstract setProperty(el: any, name: string, value: any): void;
|
||||
abstract setText(node: any, value: string): void;
|
||||
abstract listen(
|
||||
target: 'window'|'document'|'body'|any, eventName: string,
|
||||
callback: (event: any) => boolean): () => void;
|
||||
}
|
||||
|
||||
export abstract class RenderDebugContext {
|
||||
abstract get injector(): Injector;
|
||||
abstract get component(): any;
|
||||
abstract get providerTokens(): any[];
|
||||
abstract get references(): {[key: string]: any};
|
||||
abstract get context(): any;
|
||||
abstract get source(): string;
|
||||
abstract get componentRenderElement(): any;
|
||||
abstract get renderNode(): any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injectable service that provides a low-level interface for modifying the UI.
|
||||
*
|
||||
|
|
|
@ -137,7 +137,13 @@ export function createElement(view: ViewData, renderHost: any, def: NodeDef): El
|
|||
if (view.parent || !rootSelectorOrNode) {
|
||||
const parentNode =
|
||||
def.parent != null ? asElementData(view, def.parent).renderElement : renderHost;
|
||||
el = elDef.name ? renderer.createElement(elDef.name) : renderer.createComment('');
|
||||
if (elDef.name) {
|
||||
// TODO(vicb): move the namespace to the node definition
|
||||
const nsAndName = splitNamespace(elDef.name);
|
||||
el = renderer.createElement(nsAndName[1], nsAndName[0]);
|
||||
} else {
|
||||
el = renderer.createComment('');
|
||||
}
|
||||
if (parentNode) {
|
||||
renderer.appendChild(parentNode, el);
|
||||
}
|
||||
|
@ -146,7 +152,9 @@ export function createElement(view: ViewData, renderHost: any, def: NodeDef): El
|
|||
}
|
||||
if (elDef.attrs) {
|
||||
for (let attrName in elDef.attrs) {
|
||||
renderer.setAttribute(el, attrName, elDef.attrs[attrName]);
|
||||
// TODO(vicb): move the namespace to the node definition
|
||||
const nsAndName = splitNamespace(attrName);
|
||||
renderer.setAttribute(el, nsAndName[1], elDef.attrs[attrName], nsAndName[0]);
|
||||
}
|
||||
}
|
||||
if (elDef.outputs.length) {
|
||||
|
@ -234,10 +242,12 @@ function setElementAttribute(
|
|||
let renderValue = securityContext ? view.root.sanitizer.sanitize(securityContext, value) : value;
|
||||
renderValue = renderValue != null ? renderValue.toString() : null;
|
||||
const renderer = view.root.renderer;
|
||||
// TODO(vicb): move the namespace to the node definition
|
||||
const nsAndName = splitNamespace(name);
|
||||
if (value != null) {
|
||||
renderer.setAttribute(renderNode, name, renderValue);
|
||||
renderer.setAttribute(renderNode, nsAndName[1], renderValue, nsAndName[0]);
|
||||
} else {
|
||||
renderer.removeAttribute(renderNode, name);
|
||||
renderer.removeAttribute(renderNode, nsAndName[1], nsAndName[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,9 +274,9 @@ function setElementStyle(
|
|||
}
|
||||
const renderer = view.root.renderer;
|
||||
if (renderValue != null) {
|
||||
renderer.setStyle(renderNode, name, renderValue);
|
||||
renderer.setStyle(renderNode, name, renderValue, false, false);
|
||||
} else {
|
||||
renderer.removeStyle(renderNode, name);
|
||||
renderer.removeStyle(renderNode, name, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,3 +286,13 @@ function setElementProperty(
|
|||
let renderValue = securityContext ? view.root.sanitizer.sanitize(securityContext, value) : value;
|
||||
view.root.renderer.setProperty(renderNode, name, renderValue);
|
||||
}
|
||||
|
||||
const NS_PREFIX_RE = /^:([^:]+):(.+)$/;
|
||||
|
||||
function splitNamespace(name: string): string[] {
|
||||
if (name[0] === ':') {
|
||||
const match = name.match(NS_PREFIX_RE);
|
||||
return [match[1], match[2]];
|
||||
}
|
||||
return ['', name];
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import {ElementRef} from '../linker/element_ref';
|
|||
import {TemplateRef} from '../linker/template_ref';
|
||||
import {ViewContainerRef} from '../linker/view_container_ref';
|
||||
import * as v1renderer from '../render/api';
|
||||
import {Type} from '../type';
|
||||
|
||||
import {createChangeDetectorRef, createInjector, createTemplateRef, createViewContainerRef} from './refs';
|
||||
import {BindingDef, BindingType, DepDef, DepFlags, DirectiveOutputDef, DisposableFn, NodeData, NodeDef, NodeFlags, NodeType, ProviderData, ProviderType, QueryBindingType, QueryDef, QueryValueType, RootData, Services, ViewData, ViewDefinition, ViewFlags, ViewState, asElementData, asProviderData} from './types';
|
||||
|
|
|
@ -6,20 +6,16 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {isDevMode} from '../application_ref';
|
||||
import {ChangeDetectorRef} from '../change_detection/change_detection';
|
||||
import {Injectable, Injector} from '../di';
|
||||
import {Injector} from '../di';
|
||||
import {ComponentFactory, ComponentRef} from '../linker/component_factory';
|
||||
import {ElementRef} from '../linker/element_ref';
|
||||
import {TemplateRef} from '../linker/template_ref';
|
||||
import {ViewContainerRef} from '../linker/view_container_ref';
|
||||
import {EmbeddedViewRef, ViewRef} from '../linker/view_ref';
|
||||
import * as v1renderer from '../render/api';
|
||||
import {Sanitizer, SecurityContext} from '../security';
|
||||
import {Type} from '../type';
|
||||
|
||||
import {DirectDomRenderer, LegacyRendererAdapter} from './renderer';
|
||||
import {ArgumentType, BindingType, DebugContext, DepFlags, ElementData, NodeCheckFn, NodeData, NodeDef, NodeFlags, NodeType, RendererV2, RootData, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewState, asElementData, asProviderData} from './types';
|
||||
import {ArgumentType, BindingType, DebugContext, DepFlags, ElementData, NodeCheckFn, NodeData, NodeDef, NodeFlags, NodeType, RootData, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewState, asElementData, asProviderData} from './types';
|
||||
import {isComponentView, renderNode, resolveViewDefinition, rootRenderNodes, tokenKey, viewParentElIndex} from './util';
|
||||
|
||||
const EMPTY_CONTEXT = new Object();
|
||||
|
|
|
@ -1,147 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ViewEncapsulation} from '../metadata/view';
|
||||
import * as v1 from '../render/api';
|
||||
|
||||
import {DebugContext, RendererV2} from './types';
|
||||
|
||||
export class DirectDomRenderer implements RendererV2 {
|
||||
createElement(name: string): any { return document.createElement(name); }
|
||||
createComment(value: string): any { return document.createComment(value); }
|
||||
createText(value: string): any { return document.createTextNode(value); }
|
||||
appendChild(parent: any, newChild: any): void { parent.appendChild(newChild); }
|
||||
insertBefore(parent: any, newChild: any, refChild: any): void {
|
||||
if (parent) {
|
||||
parent.insertBefore(newChild, refChild);
|
||||
}
|
||||
}
|
||||
removeChild(parent: any, oldChild: any): void {
|
||||
if (parent) {
|
||||
parent.removeChild(oldChild);
|
||||
}
|
||||
}
|
||||
selectRootElement(selectorOrNode: string|any, debugInfo?: DebugContext): any {
|
||||
let el: any;
|
||||
if (typeof selectorOrNode === 'string') {
|
||||
el = document.querySelector(selectorOrNode);
|
||||
} else {
|
||||
el = selectorOrNode;
|
||||
}
|
||||
el.textContent = '';
|
||||
return el;
|
||||
}
|
||||
parentNode(node: any): any { return node.parentNode; }
|
||||
nextSibling(node: any): any { return node.nextSiblibng; }
|
||||
setAttribute(el: any, name: string, value: string): void { return el.setAttribute(name, value); }
|
||||
removeAttribute(el: any, name: string): void { el.removeAttribute(name); }
|
||||
setBindingDebugInfo(el: any, propertyName: string, propertyValue: string): void {}
|
||||
removeBindingDebugInfo(el: any, propertyName: string): void {}
|
||||
addClass(el: any, name: string): void { el.classList.add(name); }
|
||||
removeClass(el: any, name: string): void { el.classList.remove(name); }
|
||||
setStyle(el: any, style: string, value: any): void { el.style[style] = value; }
|
||||
removeStyle(el: any, style: string): void {
|
||||
// IE requires '' instead of null
|
||||
// see https://github.com/angular/angular/issues/7916
|
||||
(el.style as any)[style] = '';
|
||||
}
|
||||
setProperty(el: any, name: string, value: any): void { el[name] = value; }
|
||||
setText(node: any, value: string): void { node.nodeValue = value; }
|
||||
listen(target: any, eventName: string, callback: (event: any) => boolean): () => void {
|
||||
let renderTarget: any;
|
||||
switch (target) {
|
||||
case 'window':
|
||||
renderTarget = window;
|
||||
break;
|
||||
case 'document':
|
||||
renderTarget = document;
|
||||
break;
|
||||
default:
|
||||
renderTarget = target;
|
||||
}
|
||||
const closure = (event: any) => {
|
||||
if (callback(event) === false) {
|
||||
event.preventDefault();
|
||||
}
|
||||
};
|
||||
renderTarget.addEventListener(eventName, closure);
|
||||
return () => renderTarget.removeEventListener(eventName, closure);
|
||||
}
|
||||
}
|
||||
|
||||
const EMPTY_V1_RENDER_COMPONENT_TYPE =
|
||||
new v1.RenderComponentType('EMPTY', '', 0, ViewEncapsulation.None, [], {});
|
||||
|
||||
/**
|
||||
* A temporal implementation of `Renderer` until we migrated our current renderer
|
||||
* in all packages to the new API.
|
||||
*
|
||||
* Note that this is not complete, e.g. does not support shadow dom, view encapsulation, ...!
|
||||
*/
|
||||
export class LegacyRendererAdapter implements RendererV2 {
|
||||
private _delegate: v1.Renderer;
|
||||
constructor(rootDelegate: v1.RootRenderer) {
|
||||
this._delegate = rootDelegate.renderComponent(EMPTY_V1_RENDER_COMPONENT_TYPE);
|
||||
}
|
||||
createElement(name: string, debugInfo?: DebugContext): any {
|
||||
return this._delegate.createElement(null, name, debugInfo);
|
||||
}
|
||||
createComment(value: string, debugInfo?: DebugContext): any {
|
||||
return this._delegate.createTemplateAnchor(null, debugInfo);
|
||||
}
|
||||
createText(value: string, debugInfo?: DebugContext): any {
|
||||
return this._delegate.createText(null, value, debugInfo);
|
||||
}
|
||||
appendChild(parent: any, newChild: any): void { this._delegate.projectNodes(parent, [newChild]); }
|
||||
insertBefore(parent: any, newChild: any, refChild: any): void {
|
||||
if (refChild) {
|
||||
this._delegate.attachViewAfter(refChild.previousSibling, [newChild]);
|
||||
} else {
|
||||
this.appendChild(parent, newChild);
|
||||
}
|
||||
}
|
||||
removeChild(parent: any, oldChild: any): void {
|
||||
if (parent) {
|
||||
this._delegate.detachView([oldChild]);
|
||||
}
|
||||
}
|
||||
selectRootElement(selectorOrNode: any, debugInfo?: DebugContext): any {
|
||||
return this._delegate.selectRootElement(selectorOrNode, debugInfo);
|
||||
}
|
||||
parentNode(node: any): any { return node.parentNode; }
|
||||
nextSibling(node: any): any { return node.nextSibling; }
|
||||
setAttribute(el: any, name: string, value: string): void {
|
||||
this._delegate.setElementAttribute(el, name, value);
|
||||
}
|
||||
removeAttribute(el: any, name: string): void {
|
||||
this._delegate.setElementAttribute(el, name, null);
|
||||
}
|
||||
setBindingDebugInfo(el: any, propertyName: string, propertyValue: string): void {
|
||||
this._delegate.setBindingDebugInfo(el, propertyName, propertyValue);
|
||||
}
|
||||
removeBindingDebugInfo(el: any, propertyName: string): void {
|
||||
this._delegate.setBindingDebugInfo(el, propertyName, null);
|
||||
}
|
||||
addClass(el: any, name: string): void { this._delegate.setElementClass(el, name, true); }
|
||||
removeClass(el: any, name: string): void { this._delegate.setElementClass(el, name, false); }
|
||||
setStyle(el: any, style: string, value: any): void {
|
||||
this._delegate.setElementStyle(el, style, value);
|
||||
}
|
||||
removeStyle(el: any, style: string): void { this._delegate.setElementStyle(el, style, null); }
|
||||
setProperty(el: any, name: string, value: any): void {
|
||||
this._delegate.setElementProperty(el, name, value);
|
||||
}
|
||||
setText(node: any, value: string): void { this._delegate.setText(node, value); }
|
||||
listen(target: any, eventName: string, callback: (event: any) => boolean): () => void {
|
||||
if (typeof target === 'string') {
|
||||
return <any>this._delegate.listenGlobal(target, eventName, callback);
|
||||
} else {
|
||||
return <any>this._delegate.listen(target, eventName, callback);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,20 +7,16 @@
|
|||
*/
|
||||
|
||||
import {isDevMode} from '../application_ref';
|
||||
import {Injectable, Injector} from '../di';
|
||||
import {looseIdentical} from '../facade/lang';
|
||||
import {ElementRef} from '../linker/element_ref';
|
||||
import * as v1renderer from '../render/api';
|
||||
import {Injector} from '../di';
|
||||
import {RendererV2} from '../render/api';
|
||||
import {Sanitizer, SecurityContext} from '../security';
|
||||
import {Type} from '../type';
|
||||
|
||||
import {isViewDebugError, viewDestroyedError, viewWrappedDebugError} from './errors';
|
||||
import {resolveDep} from './provider';
|
||||
import {getQueryValue} from './query';
|
||||
import {createInjector} from './refs';
|
||||
import {DirectDomRenderer, LegacyRendererAdapter} from './renderer';
|
||||
import {ArgumentType, BindingType, DebugContext, DepFlags, ElementData, NodeCheckFn, NodeData, NodeDef, NodeFlags, NodeType, RendererV2, RootData, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewState, ViewUpdateFn, asElementData, asProviderData} from './types';
|
||||
import {checkBinding, isComponentView, queryIdIsReference, renderNode, resolveViewDefinition, rootRenderNodes, viewParentElIndex} from './util';
|
||||
import {ArgumentType, BindingType, DebugContext, DepFlags, ElementData, NodeCheckFn, NodeData, NodeDef, NodeFlags, NodeType, RootData, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewState, asElementData, asProviderData} from './types';
|
||||
import {checkBinding, isComponentView, queryIdIsReference, renderNode, viewParentElIndex} from './util';
|
||||
import {checkAndUpdateView, checkNoChangesView, createEmbeddedView, createRootView, destroyView} from './view';
|
||||
import {attachEmbeddedView, detachEmbeddedView, moveEmbeddedView} from './view_attach';
|
||||
|
||||
|
@ -112,10 +108,8 @@ function debugCreateRootView(
|
|||
function createRootData(
|
||||
injector: Injector, projectableNodes: any[][], rootSelectorOrNode: any): RootData {
|
||||
const sanitizer = injector.get(Sanitizer);
|
||||
// TODO(tbosch): once the new renderer interface is implemented via platform-browser,
|
||||
// just get it via the injector and drop LegacyRendererAdapter and DirectDomRenderer.
|
||||
const renderer = isDevMode() ? new LegacyRendererAdapter(injector.get(v1renderer.RootRenderer)) :
|
||||
new DirectDomRenderer();
|
||||
const renderer = injector.get(RendererV2);
|
||||
|
||||
const rootElement =
|
||||
rootSelectorOrNode ? renderer.selectRootElement(rootSelectorOrNode) : undefined;
|
||||
return {injector, projectableNodes, selectorOrNode: rootSelectorOrNode, sanitizer, renderer};
|
||||
|
@ -183,7 +177,7 @@ function debugUpdateRenderer(check: NodeCheckFn, view: ViewData) {
|
|||
const result = debugCheckFn(check, view, nodeIndex, argStyle, values);
|
||||
debugSetCurrentNode(view, nextRenderNodeWithBinding(view, nodeIndex));
|
||||
return result;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function debugCheckFn(
|
||||
|
@ -249,8 +243,9 @@ function nextRenderNodeWithBinding(view: ViewData, nodeIndex: number): number {
|
|||
|
||||
class DebugRenderer implements RendererV2 {
|
||||
constructor(private _delegate: RendererV2) {}
|
||||
createElement(name: string): any {
|
||||
return this._delegate.createElement(name, getCurrentDebugContext());
|
||||
|
||||
createElement(name: string, namespace?: string): any {
|
||||
return this._delegate.createElement(name, namespace, getCurrentDebugContext());
|
||||
}
|
||||
createComment(value: string): any {
|
||||
return this._delegate.createComment(value, getCurrentDebugContext());
|
||||
|
@ -272,10 +267,12 @@ class DebugRenderer implements RendererV2 {
|
|||
}
|
||||
parentNode(node: any): any { return this._delegate.parentNode(node); }
|
||||
nextSibling(node: any): any { return this._delegate.nextSibling(node); }
|
||||
setAttribute(el: any, name: string, value: string): void {
|
||||
return this._delegate.setAttribute(el, name, value);
|
||||
setAttribute(el: any, name: string, value: string, namespace?: string): void {
|
||||
return this._delegate.setAttribute(el, name, value, namespace);
|
||||
}
|
||||
removeAttribute(el: any, name: string, namespace?: string): void {
|
||||
return this._delegate.removeAttribute(el, name, namespace);
|
||||
}
|
||||
removeAttribute(el: any, name: string): void { return this._delegate.removeAttribute(el, name); }
|
||||
setBindingDebugInfo(el: any, propertyName: string, propertyValue: string): void {
|
||||
this._delegate.setBindingDebugInfo(el, propertyName, propertyValue);
|
||||
}
|
||||
|
@ -284,16 +281,20 @@ class DebugRenderer implements RendererV2 {
|
|||
}
|
||||
addClass(el: any, name: string): void { return this._delegate.addClass(el, name); }
|
||||
removeClass(el: any, name: string): void { return this._delegate.removeClass(el, name); }
|
||||
setStyle(el: any, style: string, value: any): void {
|
||||
return this._delegate.setStyle(el, style, value);
|
||||
setStyle(el: any, style: string, value: any, hasVendorPrefix: boolean, hasImportant: boolean):
|
||||
void {
|
||||
return this._delegate.setStyle(el, style, value, hasVendorPrefix, hasImportant);
|
||||
}
|
||||
removeStyle(el: any, style: string, hasVendorPrefix: boolean): void {
|
||||
return this._delegate.removeStyle(el, style, hasVendorPrefix);
|
||||
}
|
||||
removeStyle(el: any, style: string): void { return this._delegate.removeStyle(el, style); }
|
||||
setProperty(el: any, name: string, value: any): void {
|
||||
return this._delegate.setProperty(el, name, value);
|
||||
}
|
||||
setText(node: any, value: string): void { return this._delegate.setText(node, value); }
|
||||
listen(target: 'window'|'document'|any, eventName: string, callback: (event: any) => boolean):
|
||||
() => void {
|
||||
listen(
|
||||
target: 'window'|'document'|'body'|any, eventName: string,
|
||||
callback: (event: any) => boolean): () => void {
|
||||
return this._delegate.listen(target, eventName, callback);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import {TemplateRef} from '../linker/template_ref';
|
|||
import {ViewContainerRef} from '../linker/view_container_ref';
|
||||
import {ViewRef} from '../linker/view_ref';
|
||||
import {ViewEncapsulation} from '../metadata/view';
|
||||
import {RenderDebugContext, RendererV2} from '../render/api';
|
||||
import {Sanitizer, SecurityContext} from '../security';
|
||||
|
||||
// -------------------------------------
|
||||
|
@ -408,61 +409,6 @@ export interface RootData {
|
|||
sanitizer: Sanitizer;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO(tbosch): move this interface into @angular/core/src/render/api,
|
||||
* and implement it in @angular/platform-browser, ...
|
||||
*/
|
||||
export interface RendererV2 {
|
||||
createElement(name: string, debugInfo?: RenderDebugContext): any;
|
||||
createComment(value: string, debugInfo?: RenderDebugContext): any;
|
||||
createText(value: string, debugInfo?: RenderDebugContext): any;
|
||||
appendChild(parent: any, newChild: any): void;
|
||||
insertBefore(parent: any, newChild: any, refChild: any): void;
|
||||
removeChild(parent: any, oldChild: any): void;
|
||||
selectRootElement(selectorOrNode: string|any, debugInfo?: RenderDebugContext): any;
|
||||
/**
|
||||
* Attention: On WebWorkers, this will always return a value,
|
||||
* as we are asking for a result synchronously. I.e.
|
||||
* the caller can't rely on checking whether this is null or not.
|
||||
*/
|
||||
parentNode(node: any): any;
|
||||
/**
|
||||
* Attention: On WebWorkers, this will always return a value,
|
||||
* as we are asking for a result synchronously. I.e.
|
||||
* the caller can't rely on checking whether this is null or not.
|
||||
*/
|
||||
nextSibling(node: any): any;
|
||||
/**
|
||||
* Used only in debug mode to serialize property changes to dom nodes as attributes.
|
||||
*/
|
||||
setBindingDebugInfo(el: any, propertyName: string, propertyValue: string): void;
|
||||
/**
|
||||
* Used only in debug mode to serialize property changes to dom nodes as attributes.
|
||||
*/
|
||||
removeBindingDebugInfo(el: any, propertyName: string): void;
|
||||
setAttribute(el: any, name: string, value: string): void;
|
||||
removeAttribute(el: any, name: string): void;
|
||||
addClass(el: any, name: string): void;
|
||||
removeClass(el: any, name: string): void;
|
||||
setStyle(el: any, style: string, value: any): void;
|
||||
removeStyle(el: any, style: string): void;
|
||||
setProperty(el: any, name: string, value: any): void;
|
||||
setText(node: any, value: string): void;
|
||||
listen(target: 'window'|'document'|any, eventName: string, callback: (event: any) => boolean):
|
||||
() => void;
|
||||
}
|
||||
|
||||
export abstract class RenderDebugContext {
|
||||
abstract get injector(): Injector;
|
||||
abstract get component(): any;
|
||||
abstract get providerTokens(): any[];
|
||||
abstract get references(): {[key: string]: any};
|
||||
abstract get context(): any;
|
||||
abstract get source(): string;
|
||||
abstract get componentRenderElement(): any;
|
||||
abstract get renderNode(): any;
|
||||
}
|
||||
|
||||
export abstract class DebugContext extends RenderDebugContext {
|
||||
abstract get view(): ViewData;
|
||||
abstract get nodeIndex(): number;
|
||||
|
|
|
@ -183,6 +183,11 @@ export enum RenderNodeAction {
|
|||
|
||||
export function visitRootRenderNodes(
|
||||
view: ViewData, action: RenderNodeAction, parentNode: any, nextSibling: any, target: any[]) {
|
||||
// We need to re-compute the parent node in case the nodes have been moved around manually
|
||||
if (action === RenderNodeAction.RemoveChild) {
|
||||
parentNode = view.root.renderer.parentNode(renderNode(view, view.def.lastRootNode));
|
||||
}
|
||||
|
||||
const len = view.def.nodes.length;
|
||||
for (let i = 0; i < len; i++) {
|
||||
const nodeDef = view.def.nodes[i];
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
import {USE_VIEW_ENGINE} from '@angular/compiler/src/config';
|
||||
import {ElementSchemaRegistry} from '@angular/compiler/src/schema/element_schema_registry';
|
||||
import {TEST_COMPILER_PROVIDERS} from '@angular/compiler/testing/test_bindings';
|
||||
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, DebugElement, Directive, DoCheck, Injectable, Input, OnChanges, OnDestroy, OnInit, Output, Pipe, PipeTransform, RenderComponentType, Renderer, RootRenderer, SimpleChange, SimpleChanges, TemplateRef, Type, ViewChild, ViewContainerRef, WrappedValue} from '@angular/core';
|
||||
import {DebugDomRenderer} from '@angular/core/src/debug/debug_renderer';
|
||||
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, DebugElement, Directive, DoCheck, Inject, Injectable, Input, OnChanges, OnDestroy, OnInit, Output, Pipe, PipeTransform, RENDERER_V2_DIRECT, RenderComponentType, Renderer, RendererV2, RootRenderer, SimpleChange, SimpleChanges, TemplateRef, Type, ViewChild, ViewContainerRef, WrappedValue} from '@angular/core';
|
||||
import {DebugDomRenderer, DebugDomRendererV2} from '@angular/core/src/debug/debug_renderer';
|
||||
import {ComponentFixture, TestBed, fakeAsync} from '@angular/core/testing';
|
||||
import {By} from '@angular/platform-browser/src/dom/debug/by';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
|
@ -24,8 +24,12 @@ export function main() {
|
|||
|
||||
describe('View Engine compiler', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureCompiler(
|
||||
{useJit: true, providers: [{provide: USE_VIEW_ENGINE, useValue: true}]});
|
||||
TestBed.configureCompiler({
|
||||
useJit: true,
|
||||
providers: [
|
||||
{provide: USE_VIEW_ENGINE, useValue: true},
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
createTests({viewEngine: true});
|
||||
|
@ -115,8 +119,16 @@ function createTests({viewEngine}: {viewEngine: boolean}) {
|
|||
IdentityPipe,
|
||||
WrappedPipe,
|
||||
],
|
||||
providers:
|
||||
[RenderLog, DirectiveLog, {provide: RootRenderer, useClass: LoggingRootRenderer}]
|
||||
providers: [
|
||||
RenderLog,
|
||||
DirectiveLog,
|
||||
{provide: RootRenderer, useClass: LoggingRootRenderer},
|
||||
{
|
||||
provide: RendererV2,
|
||||
useFactory: (r: RendererV2, log: RenderLog) => new LoggingRendererV2(r, log),
|
||||
deps: [[new Inject(RENDERER_V2_DIRECT)], [RenderLog]],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1303,6 +1315,20 @@ class DirectiveLogEntry {
|
|||
constructor(public directiveName: string, public method: string) {}
|
||||
}
|
||||
|
||||
class LoggingRendererV2 extends DebugDomRendererV2 {
|
||||
constructor(private delegate: RendererV2, private log: RenderLog) { super(delegate); }
|
||||
|
||||
setProperty(el: any, name: string, value: any): void {
|
||||
this.log.setElementProperty(el, name, value);
|
||||
super.setProperty(el, name, value);
|
||||
}
|
||||
|
||||
setText(node: any, value: string): void {
|
||||
this.log.setText(node, value);
|
||||
super.setText(node, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
class DirectiveLog {
|
||||
entries: DirectiveLogEntry[] = [];
|
||||
|
|
|
@ -18,7 +18,6 @@ import {TemplateRef, TemplateRef_} from '@angular/core/src/linker/template_ref';
|
|||
import {ViewContainerRef} from '@angular/core/src/linker/view_container_ref';
|
||||
import {EmbeddedViewRef} from '@angular/core/src/linker/view_ref';
|
||||
import {Attribute, Component, ContentChildren, Directive, HostBinding, HostListener, Input, Output, Pipe} from '@angular/core/src/metadata';
|
||||
import {Renderer} from '@angular/core/src/render';
|
||||
import {TestBed, async, fakeAsync, getTestBed, tick} from '@angular/core/testing';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
import {DOCUMENT} from '@angular/platform-browser/src/dom/dom_tokens';
|
||||
|
@ -26,7 +25,7 @@ import {dispatchEvent, el} from '@angular/platform-browser/testing/browser_util'
|
|||
import {expect} from '@angular/platform-browser/testing/matchers';
|
||||
|
||||
import {EventEmitter} from '../../src/facade/async';
|
||||
import {isBlank, isPresent, stringify} from '../../src/facade/lang';
|
||||
import {stringify} from '../../src/facade/lang';
|
||||
|
||||
const ANCHOR_ELEMENT = new InjectionToken('AnchorElement');
|
||||
|
||||
|
@ -37,18 +36,24 @@ export function main() {
|
|||
|
||||
describe('view engine', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureCompiler(
|
||||
{useJit: true, providers: [{provide: USE_VIEW_ENGINE, useValue: true}]});
|
||||
TestBed.configureCompiler({
|
||||
useJit: true,
|
||||
providers: [{
|
||||
provide: USE_VIEW_ENGINE,
|
||||
useValue: true,
|
||||
}],
|
||||
});
|
||||
});
|
||||
|
||||
declareTests({useJit: true, viewEngine: true});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function declareTests({useJit, viewEngine}: {useJit: boolean, viewEngine: boolean}) {
|
||||
describe('integration tests', function() {
|
||||
|
||||
beforeEach(() => { TestBed.configureCompiler({useJit: useJit}); });
|
||||
beforeEach(() => { TestBed.configureCompiler({useJit}); });
|
||||
|
||||
describe('react to record changes', function() {
|
||||
it('should consume text node changes', () => {
|
||||
|
@ -1472,7 +1477,7 @@ function declareTests({useJit, viewEngine}: {useJit: boolean, viewEngine: boolea
|
|||
fixture.detectChanges();
|
||||
|
||||
const el = getDOM().querySelector(fixture.nativeElement, 'span');
|
||||
expect(isBlank(el.title) || el.title == '').toBeTruthy();
|
||||
expect(el.title).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should work when a directive uses hostProperty to update the DOM element', () => {
|
||||
|
@ -2084,8 +2089,7 @@ class ToolbarPart {
|
|||
|
||||
@Directive({selector: '[toolbarVc]', inputs: ['toolbarVc']})
|
||||
class ToolbarViewContainer {
|
||||
vc: ViewContainerRef;
|
||||
constructor(vc: ViewContainerRef) { this.vc = vc; }
|
||||
constructor(public vc: ViewContainerRef) {}
|
||||
|
||||
set toolbarVc(part: ToolbarPart) {
|
||||
this.vc.createEmbeddedView(part.templateRef, new ToolbarContext('From toolbar'), 0);
|
||||
|
@ -2098,9 +2102,9 @@ class ToolbarViewContainer {
|
|||
})
|
||||
class ToolbarComponent {
|
||||
@ContentChildren(ToolbarPart) query: QueryList<ToolbarPart>;
|
||||
ctxProp: string;
|
||||
ctxProp: string = 'hello world';
|
||||
|
||||
constructor() { this.ctxProp = 'hello world'; }
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
@Directive({selector: '[two-way]', inputs: ['control'], outputs: ['controlChange']})
|
||||
|
@ -2238,10 +2242,11 @@ class SomeImperativeViewport {
|
|||
}
|
||||
|
||||
set someImpvp(value: boolean) {
|
||||
if (isPresent(this.view)) {
|
||||
if (this.view) {
|
||||
this.vc.clear();
|
||||
this.view = null;
|
||||
}
|
||||
|
||||
if (value) {
|
||||
this.view = this.vc.createEmbeddedView(this.templateRef);
|
||||
const nodes = this.view.rootNodes;
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
import {Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, getDebugNode} from '@angular/core';
|
||||
import {DebugContext, NodeDef, NodeFlags, RootData, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, elementDef, rootRenderNodes, 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 {createRootView, isBrowser} from './helper';
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
import {Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation} from '@angular/core';
|
||||
import {ArgumentType, BindingType, NodeCheckFn, NodeDef, NodeFlags, RootData, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewState, ViewUpdateFn, anchorDef, asProviderData, directiveDef, elementDef, rootRenderNodes, 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 {createRootView, isBrowser, removeNodes} from './helper';
|
||||
|
@ -182,23 +181,19 @@ export function main() {
|
|||
const update = jasmine.createSpy('updater');
|
||||
|
||||
const addListenerSpy = spyOn(HTMLElement.prototype, 'addEventListener').and.callThrough();
|
||||
const {view, rootNodes} =
|
||||
createAndGetRootNodes(
|
||||
compViewDef(
|
||||
[
|
||||
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
||||
directiveDef(
|
||||
NodeFlags.None, null, 0, AComp, [], {a: [0, 'a']}, null,
|
||||
() =>
|
||||
compViewDef(
|
||||
[
|
||||
elementDef(NodeFlags.None, null, null, 0, 'span', null, null, ['click']),
|
||||
],
|
||||
update, null, null, ViewFlags.OnPush)),
|
||||
],
|
||||
(check, view) => { check(view, 1, ArgumentType.Inline, compInputValue); }));
|
||||
|
||||
const compView = asProviderData(view, 1).componentView;
|
||||
const {view} = createAndGetRootNodes(compViewDef(
|
||||
[
|
||||
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
||||
directiveDef(
|
||||
NodeFlags.None, null, 0, AComp, [], {a: [0, 'a']}, null,
|
||||
() => compViewDef(
|
||||
[
|
||||
elementDef(NodeFlags.None, null, null, 0, 'span', null, null, ['click']),
|
||||
],
|
||||
update, null, null, ViewFlags.OnPush)),
|
||||
],
|
||||
(check, view) => { check(view, 1, ArgumentType.Inline, compInputValue); }));
|
||||
|
||||
Services.checkAndUpdateView(view);
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
import {Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, WrappedValue, getDebugNode} from '@angular/core';
|
||||
import {getDebugContext} from '@angular/core/src/errors';
|
||||
import {ArgumentType, BindingType, DebugContext, NodeDef, NodeFlags, RootData, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, elementDef, rootRenderNodes, 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 {ARG_TYPE_VALUES, checkNodeInlineOrDynamic, createRootView, isBrowser, removeNodes} from './helper';
|
||||
|
|
|
@ -36,7 +36,7 @@ export function main() {
|
|||
const parentContext = new Object();
|
||||
const childContext = new Object();
|
||||
|
||||
const {view: parentView, rootNodes} = createAndGetRootNodes(
|
||||
const {view: parentView} = createAndGetRootNodes(
|
||||
compViewDef([
|
||||
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
||||
anchorDef(
|
||||
|
@ -146,7 +146,6 @@ export function main() {
|
|||
|
||||
const childView0 = Services.createEmbeddedView(parentView, parentView.def.nodes[1]);
|
||||
|
||||
const rootEl = rootNodes[0];
|
||||
attachEmbeddedView(asElementData(parentView, 1), 0, childView0);
|
||||
|
||||
Services.checkAndUpdateView(parentView);
|
||||
|
@ -171,7 +170,7 @@ export function main() {
|
|||
ngOnDestroy() { log.push('ngOnDestroy'); };
|
||||
}
|
||||
|
||||
const {view: parentView, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||
const {view: parentView} = createAndGetRootNodes(compViewDef([
|
||||
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
||||
anchorDef(NodeFlags.HasEmbeddedViews, null, null, 0, embeddedViewDef([
|
||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
import {Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, TemplateRef, ViewContainerRef, ViewEncapsulation, getDebugNode} from '@angular/core';
|
||||
import {DebugContext, NodeDef, NodeFlags, RootData, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, asTextData, attachEmbeddedView, detachEmbeddedView, directiveDef, elementDef, ngContentDef, rootRenderNodes, 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 {createRootView, isBrowser} from './helper';
|
||||
|
@ -104,14 +103,18 @@ export function main() {
|
|||
it('should include projected nodes when attaching / detaching embedded views', () => {
|
||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(hostElDef([textDef(0, ['a'])], [
|
||||
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
||||
anchorDef(NodeFlags.HasEmbeddedViews, null, 0, 0, embeddedViewDef([ngContentDef(null, 0)])),
|
||||
anchorDef(NodeFlags.HasEmbeddedViews, null, 0, 0, embeddedViewDef([
|
||||
ngContentDef(null, 0),
|
||||
// The anchor would be added by the compiler after the ngContent
|
||||
anchorDef(NodeFlags.None, null, null, 0),
|
||||
])),
|
||||
])));
|
||||
|
||||
const componentView = asProviderData(view, 1).componentView;
|
||||
const view0 = Services.createEmbeddedView(componentView, componentView.def.nodes[1]);
|
||||
|
||||
attachEmbeddedView(asElementData(componentView, 1), 0, view0);
|
||||
expect(getDOM().childNodes(getDOM().firstChild(rootNodes[0])).length).toBe(2);
|
||||
expect(getDOM().childNodes(getDOM().firstChild(rootNodes[0])).length).toBe(3);
|
||||
expect(getDOM().childNodes(getDOM().firstChild(rootNodes[0]))[1])
|
||||
.toBe(asTextData(view, 2).renderText);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {CommonModule, PlatformLocation} from '@angular/common';
|
||||
import {ApplicationModule, ErrorHandler, NgModule, Optional, PLATFORM_INITIALIZER, PlatformRef, Provider, RootRenderer, Sanitizer, SkipSelf, Testability, createPlatformFactory, platformCore} from '@angular/core';
|
||||
import {ApplicationModule, ErrorHandler, NgModule, Optional, PLATFORM_INITIALIZER, PlatformRef, Provider, RENDERER_V2_DIRECT, RendererV2, RootRenderer, Sanitizer, SkipSelf, Testability, createPlatformFactory, platformCore} from '@angular/core';
|
||||
|
||||
import {AnimationDriver} from '../src/dom/animation_driver';
|
||||
import {WebAnimationsDriver} from '../src/dom/web_animations_driver';
|
||||
|
@ -19,7 +19,7 @@ import {BrowserGetTestability} from './browser/testability';
|
|||
import {Title} from './browser/title';
|
||||
import {ELEMENT_PROBE_PROVIDERS} from './dom/debug/ng_probe';
|
||||
import {getDOM} from './dom/dom_adapter';
|
||||
import {DomRootRenderer, DomRootRenderer_} from './dom/dom_renderer';
|
||||
import {DomRendererV2, DomRootRenderer, DomRootRenderer_} from './dom/dom_renderer';
|
||||
import {DOCUMENT} from './dom/dom_tokens';
|
||||
import {DomEventsPlugin} from './dom/events/dom_events';
|
||||
import {EVENT_MANAGER_PLUGINS, EventManager} from './dom/events/event_manager';
|
||||
|
@ -86,6 +86,8 @@ export function _resolveDefaultAnimationDriver(): AnimationDriver {
|
|||
{provide: HAMMER_GESTURE_CONFIG, useClass: HammerGestureConfig},
|
||||
{provide: DomRootRenderer, useClass: DomRootRenderer_},
|
||||
{provide: RootRenderer, useExisting: DomRootRenderer},
|
||||
{provide: RENDERER_V2_DIRECT, useClass: DomRendererV2},
|
||||
{provide: RendererV2, useExisting: RENDERER_V2_DIRECT},
|
||||
{provide: SharedStylesHost, useExisting: DomSharedStylesHost},
|
||||
{provide: AnimationDriver, useFactory: _resolveDefaultAnimationDriver},
|
||||
DomSharedStylesHost,
|
||||
|
|
|
@ -175,11 +175,11 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
|
|||
}
|
||||
return node;
|
||||
}
|
||||
insertBefore(el: Node, node: Node) { el.parentNode.insertBefore(node, el); }
|
||||
insertAllBefore(el: Node, nodes: Node[]) {
|
||||
nodes.forEach((n: any) => el.parentNode.insertBefore(n, el));
|
||||
insertBefore(parent: Node, ref: Node, node: Node) { parent.insertBefore(node, ref); }
|
||||
insertAllBefore(parent: Node, ref: Node, nodes: Node[]) {
|
||||
nodes.forEach((n: any) => parent.insertBefore(n, ref));
|
||||
}
|
||||
insertAfter(el: Node, node: any) { el.parentNode.insertBefore(node, el.nextSibling); }
|
||||
insertAfter(parent: Node, ref: Node, node: any) { parent.insertBefore(node, ref.nextSibling); }
|
||||
setInnerHTML(el: Element, value: string) { el.innerHTML = value; }
|
||||
getText(el: Node): string { return el.textContent; }
|
||||
setText(el: Node, value: string) { el.textContent = value; }
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import * as core from '@angular/core';
|
||||
|
||||
import {StringMapWrapper} from '../../facade/collection';
|
||||
import {DebugDomRootRenderer} from '../../private_import_core';
|
||||
import {DebugDomRendererV2, DebugDomRootRenderer} from '../../private_import_core';
|
||||
import {getDOM} from '../dom_adapter';
|
||||
import {DomRootRenderer} from '../dom_renderer';
|
||||
|
||||
|
@ -58,14 +58,26 @@ function _ngProbeTokensToMap(tokens: NgProbeToken[]): {[name: string]: any} {
|
|||
return tokens.reduce((prev: any, t: any) => (prev[t.name] = t.token, prev), {});
|
||||
}
|
||||
|
||||
export function _createDebugRendererV2(renderer: core.RendererV2): core.RendererV2 {
|
||||
return core.isDevMode() ? new DebugDomRendererV2(renderer) : renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Providers which support debugging Angular applications (e.g. via `ng.probe`).
|
||||
*/
|
||||
export const ELEMENT_PROBE_PROVIDERS: core.Provider[] = [{
|
||||
provide: core.RootRenderer,
|
||||
useFactory: _createConditionalRootRenderer,
|
||||
deps: [
|
||||
DomRootRenderer, [NgProbeToken, new core.Optional()],
|
||||
[core.NgProbeToken, new core.Optional()]
|
||||
]
|
||||
}];
|
||||
export const ELEMENT_PROBE_PROVIDERS: core.Provider[] = [
|
||||
{
|
||||
provide: core.RootRenderer,
|
||||
useFactory: _createConditionalRootRenderer,
|
||||
deps: [
|
||||
DomRootRenderer,
|
||||
[NgProbeToken, new core.Optional()],
|
||||
[core.NgProbeToken, new core.Optional()],
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: core.RendererV2,
|
||||
useFactory: _createDebugRendererV2,
|
||||
deps: [core.RENDERER_V2_DIRECT],
|
||||
}
|
||||
];
|
|
@ -33,15 +33,15 @@ export function setRootDomAdapter(adapter: DomAdapter) {
|
|||
*/
|
||||
export abstract class DomAdapter {
|
||||
public resourceLoaderType: Type<any> = null;
|
||||
abstract hasProperty(element: any /** TODO #9100 */, name: string): boolean;
|
||||
abstract setProperty(el: Element, name: string, value: any): any /** TODO #9100 */;
|
||||
abstract hasProperty(element: any, name: string): boolean;
|
||||
abstract setProperty(el: Element, name: string, value: any): any;
|
||||
abstract getProperty(el: Element, name: string): any;
|
||||
abstract invoke(el: Element, methodName: string, args: any[]): any;
|
||||
|
||||
abstract logError(error: any /** TODO #9100 */): any /** TODO #9100 */;
|
||||
abstract log(error: any /** TODO #9100 */): any /** TODO #9100 */;
|
||||
abstract logGroup(error: any /** TODO #9100 */): any /** TODO #9100 */;
|
||||
abstract logGroupEnd(): any /** TODO #9100 */;
|
||||
abstract logError(error: any): any;
|
||||
abstract log(error: any): any;
|
||||
abstract logGroup(error: any): any;
|
||||
abstract logGroupEnd(): any;
|
||||
|
||||
/**
|
||||
* Maps attribute names to their corresponding property names for cases
|
||||
|
@ -52,114 +52,93 @@ export abstract class DomAdapter {
|
|||
/** @internal */
|
||||
_attrToPropMap: {[key: string]: string};
|
||||
|
||||
abstract parse(templateHtml: string): any /** TODO #9100 */;
|
||||
abstract querySelector(el: any /** TODO #9100 */, selector: string): any;
|
||||
abstract querySelectorAll(el: any /** TODO #9100 */, selector: string): any[];
|
||||
abstract on(
|
||||
el: any /** TODO #9100 */, evt: any /** TODO #9100 */, listener: any /** TODO #9100 */): any
|
||||
/** TODO #9100 */;
|
||||
abstract onAndCancel(
|
||||
el: any /** TODO #9100 */, evt: any /** TODO #9100 */,
|
||||
listener: any /** TODO #9100 */): Function;
|
||||
abstract dispatchEvent(el: any /** TODO #9100 */, evt: any /** TODO #9100 */): any
|
||||
/** TODO #9100 */;
|
||||
abstract createMouseEvent(eventType: any /** TODO #9100 */): any;
|
||||
abstract parse(templateHtml: string): any;
|
||||
abstract querySelector(el: any, selector: string): any;
|
||||
abstract querySelectorAll(el: any, selector: string): any[];
|
||||
abstract on(el: any, evt: any, listener: any): any;
|
||||
abstract onAndCancel(el: any, evt: any, listener: any): Function;
|
||||
abstract dispatchEvent(el: any, evt: any): any;
|
||||
abstract createMouseEvent(eventType: any): any;
|
||||
abstract createEvent(eventType: string): any;
|
||||
abstract preventDefault(evt: any /** TODO #9100 */): any /** TODO #9100 */;
|
||||
abstract isPrevented(evt: any /** TODO #9100 */): boolean;
|
||||
abstract getInnerHTML(el: any /** TODO #9100 */): string;
|
||||
abstract preventDefault(evt: any): any;
|
||||
abstract isPrevented(evt: any): boolean;
|
||||
abstract getInnerHTML(el: any): string;
|
||||
/** Returns content if el is a <template> element, null otherwise. */
|
||||
abstract getTemplateContent(el: any /** TODO #9100 */): any;
|
||||
abstract getOuterHTML(el: any /** TODO #9100 */): string;
|
||||
abstract nodeName(node: any /** TODO #9100 */): string;
|
||||
abstract nodeValue(node: any /** TODO #9100 */): string;
|
||||
abstract type(node: any /** TODO #9100 */): string;
|
||||
abstract content(node: any /** TODO #9100 */): any;
|
||||
abstract firstChild(el: any /** TODO #9100 */): Node;
|
||||
abstract nextSibling(el: any /** TODO #9100 */): Node;
|
||||
abstract parentElement(el: any /** TODO #9100 */): Node;
|
||||
abstract childNodes(el: any /** TODO #9100 */): Node[];
|
||||
abstract childNodesAsList(el: any /** TODO #9100 */): Node[];
|
||||
abstract clearNodes(el: any /** TODO #9100 */): any /** TODO #9100 */;
|
||||
abstract appendChild(el: any /** TODO #9100 */, node: any /** TODO #9100 */): any
|
||||
/** TODO #9100 */;
|
||||
abstract removeChild(el: any /** TODO #9100 */, node: any /** TODO #9100 */): any
|
||||
/** TODO #9100 */;
|
||||
abstract replaceChild(
|
||||
el: any /** TODO #9100 */, newNode: any /** TODO #9100 */,
|
||||
oldNode: any /** TODO #9100 */): any /** TODO #9100 */;
|
||||
abstract remove(el: any /** TODO #9100 */): Node;
|
||||
abstract insertBefore(el: any /** TODO #9100 */, node: any /** TODO #9100 */): any
|
||||
/** TODO #9100 */;
|
||||
abstract insertAllBefore(el: any /** TODO #9100 */, nodes: any /** TODO #9100 */): any
|
||||
/** TODO #9100 */;
|
||||
abstract insertAfter(el: any /** TODO #9100 */, node: any /** TODO #9100 */): any
|
||||
/** TODO #9100 */;
|
||||
abstract setInnerHTML(el: any /** TODO #9100 */, value: any /** TODO #9100 */): any
|
||||
/** TODO #9100 */;
|
||||
abstract getText(el: any /** TODO #9100 */): string;
|
||||
abstract setText(el: any /** TODO #9100 */, value: string): any /** TODO #9100 */;
|
||||
abstract getValue(el: any /** TODO #9100 */): string;
|
||||
abstract setValue(el: any /** TODO #9100 */, value: string): any /** TODO #9100 */;
|
||||
abstract getChecked(el: any /** TODO #9100 */): boolean;
|
||||
abstract setChecked(el: any /** TODO #9100 */, value: boolean): any /** TODO #9100 */;
|
||||
abstract getTemplateContent(el: any): any;
|
||||
abstract getOuterHTML(el: any): string;
|
||||
abstract nodeName(node: any): string;
|
||||
abstract nodeValue(node: any): string;
|
||||
abstract type(node: any): string;
|
||||
abstract content(node: any): any;
|
||||
abstract firstChild(el: any): Node;
|
||||
abstract nextSibling(el: any): Node;
|
||||
abstract parentElement(el: any): Node;
|
||||
abstract childNodes(el: any): Node[];
|
||||
abstract childNodesAsList(el: any): Node[];
|
||||
abstract clearNodes(el: any): any;
|
||||
abstract appendChild(el: any, node: any): any;
|
||||
abstract removeChild(el: any, node: any): any;
|
||||
abstract replaceChild(el: any, newNode: any, oldNode: any): any;
|
||||
abstract remove(el: any): Node;
|
||||
abstract insertBefore(parent: any, ref: any, node: any): any;
|
||||
abstract insertAllBefore(parent: any, ref: any, nodes: any): any;
|
||||
abstract insertAfter(parent: any, el: any, node: any): any;
|
||||
abstract setInnerHTML(el: any, value: any): any;
|
||||
abstract getText(el: any): string;
|
||||
abstract setText(el: any, value: string): any;
|
||||
abstract getValue(el: any): string;
|
||||
abstract setValue(el: any, value: string): any;
|
||||
abstract getChecked(el: any): boolean;
|
||||
abstract setChecked(el: any, value: boolean): any;
|
||||
abstract createComment(text: string): any;
|
||||
abstract createTemplate(html: any /** TODO #9100 */): HTMLElement;
|
||||
abstract createElement(tagName: any /** TODO #9100 */, doc?: any /** TODO #9100 */): HTMLElement;
|
||||
abstract createElementNS(ns: string, tagName: string, doc?: any /** TODO #9100 */): Element;
|
||||
abstract createTextNode(text: string, doc?: any /** TODO #9100 */): Text;
|
||||
abstract createScriptTag(attrName: string, attrValue: string, doc?: any /** TODO #9100 */):
|
||||
HTMLElement;
|
||||
abstract createStyleElement(css: string, doc?: any /** TODO #9100 */): HTMLStyleElement;
|
||||
abstract createShadowRoot(el: any /** TODO #9100 */): any;
|
||||
abstract getShadowRoot(el: any /** TODO #9100 */): any;
|
||||
abstract getHost(el: any /** TODO #9100 */): any;
|
||||
abstract getDistributedNodes(el: any /** TODO #9100 */): Node[];
|
||||
abstract createTemplate(html: any): HTMLElement;
|
||||
abstract createElement(tagName: any, doc?: any): HTMLElement;
|
||||
abstract createElementNS(ns: string, tagName: string, doc?: any): Element;
|
||||
abstract createTextNode(text: string, doc?: any): Text;
|
||||
abstract createScriptTag(attrName: string, attrValue: string, doc?: any): HTMLElement;
|
||||
abstract createStyleElement(css: string, doc?: any): HTMLStyleElement;
|
||||
abstract createShadowRoot(el: any): any;
|
||||
abstract getShadowRoot(el: any): any;
|
||||
abstract getHost(el: any): any;
|
||||
abstract getDistributedNodes(el: any): Node[];
|
||||
abstract clone /*<T extends Node>*/ (node: Node /*T*/): Node /*T*/;
|
||||
abstract getElementsByClassName(element: any /** TODO #9100 */, name: string): HTMLElement[];
|
||||
abstract getElementsByTagName(element: any /** TODO #9100 */, name: string): HTMLElement[];
|
||||
abstract classList(element: any /** TODO #9100 */): any[];
|
||||
abstract addClass(element: any /** TODO #9100 */, className: string): any /** TODO #9100 */;
|
||||
abstract removeClass(element: any /** TODO #9100 */, className: string): any /** TODO #9100 */;
|
||||
abstract hasClass(element: any /** TODO #9100 */, className: string): boolean;
|
||||
abstract setStyle(element: any /** TODO #9100 */, styleName: string, styleValue: string): any
|
||||
/** TODO #9100 */;
|
||||
abstract removeStyle(element: any /** TODO #9100 */, styleName: string): any /** TODO #9100 */;
|
||||
abstract getStyle(element: any /** TODO #9100 */, styleName: string): string;
|
||||
abstract hasStyle(element: any /** TODO #9100 */, styleName: string, styleValue?: string):
|
||||
boolean;
|
||||
abstract tagName(element: any /** TODO #9100 */): string;
|
||||
abstract attributeMap(element: any /** TODO #9100 */): Map<string, string>;
|
||||
abstract hasAttribute(element: any /** TODO #9100 */, attribute: string): boolean;
|
||||
abstract hasAttributeNS(element: any /** TODO #9100 */, ns: string, attribute: string): boolean;
|
||||
abstract getAttribute(element: any /** TODO #9100 */, attribute: string): string;
|
||||
abstract getAttributeNS(element: any /** TODO #9100 */, ns: string, attribute: string): string;
|
||||
abstract setAttribute(element: any /** TODO #9100 */, name: string, value: string): any
|
||||
/** TODO #9100 */;
|
||||
abstract setAttributeNS(element: any /** TODO #9100 */, ns: string, name: string, value: string):
|
||||
any /** TODO #9100 */;
|
||||
abstract removeAttribute(element: any /** TODO #9100 */, attribute: string): any
|
||||
/** TODO #9100 */;
|
||||
abstract removeAttributeNS(element: any /** TODO #9100 */, ns: string, attribute: string): any
|
||||
/** TODO #9100 */;
|
||||
abstract templateAwareRoot(el: any /** TODO #9100 */): any /** TODO #9100 */;
|
||||
abstract getElementsByClassName(element: any, name: string): HTMLElement[];
|
||||
abstract getElementsByTagName(element: any, name: string): HTMLElement[];
|
||||
abstract classList(element: any): any[];
|
||||
abstract addClass(element: any, className: string): any;
|
||||
abstract removeClass(element: any, className: string): any;
|
||||
abstract hasClass(element: any, className: string): boolean;
|
||||
abstract setStyle(element: any, styleName: string, styleValue: string): any;
|
||||
abstract removeStyle(element: any, styleName: string): any;
|
||||
abstract getStyle(element: any, styleName: string): string;
|
||||
abstract hasStyle(element: any, styleName: string, styleValue?: string): boolean;
|
||||
abstract tagName(element: any): string;
|
||||
abstract attributeMap(element: any): Map<string, string>;
|
||||
abstract hasAttribute(element: any, attribute: string): boolean;
|
||||
abstract hasAttributeNS(element: any, ns: string, attribute: string): boolean;
|
||||
abstract getAttribute(element: any, attribute: string): string;
|
||||
abstract getAttributeNS(element: any, ns: string, attribute: string): string;
|
||||
abstract setAttribute(element: any, name: string, value: string): any;
|
||||
abstract setAttributeNS(element: any, ns: string, name: string, value: string): any;
|
||||
abstract removeAttribute(element: any, attribute: string): any;
|
||||
abstract removeAttributeNS(element: any, ns: string, attribute: string): any;
|
||||
abstract templateAwareRoot(el: any): any;
|
||||
abstract createHtmlDocument(): HTMLDocument;
|
||||
abstract getBoundingClientRect(el: any /** TODO #9100 */): any /** TODO #9100 */;
|
||||
abstract getBoundingClientRect(el: any): any;
|
||||
abstract getTitle(doc: Document): string;
|
||||
abstract setTitle(doc: Document, newTitle: string): any /** TODO #9100 */;
|
||||
abstract elementMatches(n: any /** TODO #9100 */, selector: string): boolean;
|
||||
abstract setTitle(doc: Document, newTitle: string): any;
|
||||
abstract elementMatches(n: any, selector: string): boolean;
|
||||
abstract isTemplateElement(el: any): boolean;
|
||||
abstract isTextNode(node: any /** TODO #9100 */): boolean;
|
||||
abstract isCommentNode(node: any /** TODO #9100 */): boolean;
|
||||
abstract isElementNode(node: any /** TODO #9100 */): boolean;
|
||||
abstract hasShadowRoot(node: any /** TODO #9100 */): boolean;
|
||||
abstract isShadowRoot(node: any /** TODO #9100 */): boolean;
|
||||
abstract isTextNode(node: any): boolean;
|
||||
abstract isCommentNode(node: any): boolean;
|
||||
abstract isElementNode(node: any): boolean;
|
||||
abstract hasShadowRoot(node: any): boolean;
|
||||
abstract isShadowRoot(node: any): boolean;
|
||||
abstract importIntoDoc /*<T extends Node>*/ (node: Node /*T*/): Node /*T*/;
|
||||
abstract adoptNode /*<T extends Node>*/ (node: Node /*T*/): Node /*T*/;
|
||||
abstract getHref(element: any /** TODO #9100 */): string;
|
||||
abstract getEventKey(event: any /** TODO #9100 */): string;
|
||||
abstract resolveAndSetHref(element: any /** TODO #9100 */, baseUrl: string, href: string): any
|
||||
/** TODO #9100 */;
|
||||
abstract getHref(element: any): string;
|
||||
abstract getEventKey(event: any): string;
|
||||
abstract resolveAndSetHref(element: any, baseUrl: string, href: string): any;
|
||||
abstract supportsDOMEvents(): boolean;
|
||||
abstract supportsNativeShadowDOM(): boolean;
|
||||
abstract getGlobalEventTarget(doc: Document, target: string): any;
|
||||
|
@ -168,11 +147,10 @@ export abstract class DomAdapter {
|
|||
abstract getBaseHref(doc: Document): string;
|
||||
abstract resetBaseElement(): void;
|
||||
abstract getUserAgent(): string;
|
||||
abstract setData(element: any /** TODO #9100 */, name: string, value: string): any
|
||||
/** TODO #9100 */;
|
||||
abstract getComputedStyle(element: any /** TODO #9100 */): any;
|
||||
abstract getData(element: any /** TODO #9100 */, name: string): string;
|
||||
abstract setGlobalVar(name: string, value: any): any /** TODO #9100 */;
|
||||
abstract setData(element: any, name: string, value: string): any;
|
||||
abstract getComputedStyle(element: any): any;
|
||||
abstract getData(element: any, name: string): string;
|
||||
abstract setGlobalVar(name: string, value: any): any;
|
||||
abstract supportsWebAnimation(): boolean;
|
||||
abstract performanceNow(): number;
|
||||
abstract getAnimationPrefix(): string;
|
||||
|
@ -181,5 +159,5 @@ export abstract class DomAdapter {
|
|||
|
||||
abstract supportsCookies(): boolean;
|
||||
abstract getCookie(name: string): string;
|
||||
abstract setCookie(name: string, value: string): any /** TODO #9100 */;
|
||||
abstract setCookie(name: string, value: string): any;
|
||||
}
|
||||
|
|
|
@ -6,16 +6,15 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {APP_ID, Inject, Injectable, RenderComponentType, Renderer, RootRenderer, ViewEncapsulation} from '@angular/core';
|
||||
import {APP_ID, Inject, Injectable, RenderComponentType, Renderer, RendererV2, RootRenderer, ViewEncapsulation} from '@angular/core';
|
||||
|
||||
import {isBlank, isPresent, stringify} from '../facade/lang';
|
||||
import {isPresent, stringify} from '../facade/lang';
|
||||
import {AnimationKeyframe, AnimationPlayer, AnimationStyles, DirectRenderer, NoOpAnimationPlayer, RenderDebugInfo} from '../private_import_core';
|
||||
|
||||
import {AnimationDriver} from './animation_driver';
|
||||
import {DOCUMENT} from './dom_tokens';
|
||||
import {EventManager} from './events/event_manager';
|
||||
import {DomSharedStylesHost} from './shared_styles_host';
|
||||
import {camelCaseToDashCase} from './util';
|
||||
|
||||
export const NAMESPACE_URIS: {[ns: string]: string} = {
|
||||
'xlink': 'http://www.w3.org/1999/xlink',
|
||||
|
@ -231,7 +230,7 @@ export class DomRenderer implements Renderer {
|
|||
} else {
|
||||
// Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
|
||||
if (propertyName[propertyName.length - 1] === '$') {
|
||||
const attrNode: Attr = createAttrNode(propertyName).cloneNode(true) as Attr;
|
||||
const attrNode: Attr = createAttributeNode(propertyName).cloneNode(true) as Attr;
|
||||
attrNode.value = propertyValue;
|
||||
renderElement.setAttributeNode(attrNode);
|
||||
} else {
|
||||
|
@ -348,19 +347,140 @@ export function splitNamespace(name: string): string[] {
|
|||
return [match[1], match[2]];
|
||||
}
|
||||
|
||||
|
||||
let attrCache: Map<string, Attr>;
|
||||
|
||||
function createAttrNode(name: string): Attr {
|
||||
function createAttributeNode(name: string): Attr {
|
||||
if (!attrCache) {
|
||||
attrCache = new Map<string, Attr>();
|
||||
}
|
||||
if (attrCache.has(name)) {
|
||||
return attrCache.get(name);
|
||||
} else {
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = `<div ${name}>`;
|
||||
const attr: Attr = div.firstChild.attributes[0];
|
||||
attrCache.set(name, attr);
|
||||
return attr;
|
||||
}
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = `<div ${name}>`;
|
||||
const attr: Attr = div.firstChild.attributes[0];
|
||||
attrCache.set(name, attr);
|
||||
return attr;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class DomRendererV2 implements RendererV2 {
|
||||
constructor(private eventManager: EventManager){};
|
||||
|
||||
createElement(name: string, namespace?: string, debugInfo?: any): any {
|
||||
if (namespace) {
|
||||
return document.createElementNS(NAMESPACE_URIS[namespace], name);
|
||||
}
|
||||
|
||||
return document.createElement(name);
|
||||
}
|
||||
|
||||
createComment(value: string, debugInfo?: any): any { return document.createComment(value); }
|
||||
|
||||
createText(value: string, debugInfo?: any): any { return document.createTextNode(value); }
|
||||
|
||||
appendChild(parent: any, newChild: any): void { parent.appendChild(newChild); }
|
||||
|
||||
insertBefore(parent: any, newChild: any, refChild: any): void {
|
||||
if (parent) {
|
||||
parent.insertBefore(newChild, refChild);
|
||||
}
|
||||
}
|
||||
|
||||
removeChild(parent: any, oldChild: any): void { parent.removeChild(oldChild); }
|
||||
|
||||
selectRootElement(selectorOrNode: string|any, debugInfo?: any): any {
|
||||
let el: any = typeof selectorOrNode === 'string' ? document.querySelector(selectorOrNode) :
|
||||
selectorOrNode;
|
||||
el.textContent = '';
|
||||
return el;
|
||||
}
|
||||
|
||||
parentNode(node: any): any { return node.parentNode; }
|
||||
|
||||
nextSibling(node: any): any { return node.nextSibling; }
|
||||
|
||||
setAttribute(el: any, name: string, value: string, namespace?: string): void {
|
||||
if (namespace) {
|
||||
el.setAttributeNS(NAMESPACE_URIS[namespace], namespace + ':' + name, value);
|
||||
} else {
|
||||
el.setAttribute(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
removeAttribute(el: any, name: string, namespace?: string): void {
|
||||
if (namespace) {
|
||||
el.removeAttributeNS(NAMESPACE_URIS[namespace], name);
|
||||
} else {
|
||||
el.removeAttribute(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setBindingDebugInfo(el: any, propertyName: string, propertyValue: string): void {
|
||||
if (el.nodeType === Node.COMMENT_NODE) {
|
||||
const m = el.nodeValue.replace(/\n/g, '').match(TEMPLATE_BINDINGS_EXP);
|
||||
const obj = m === null ? {} : JSON.parse(m[1]);
|
||||
obj[propertyName] = propertyValue;
|
||||
el.nodeValue = TEMPLATE_COMMENT_TEXT.replace('{}', JSON.stringify(obj, null, 2));
|
||||
} else {
|
||||
// Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
|
||||
if (propertyName[propertyName.length - 1] === '$') {
|
||||
const attrNode: Attr = createAttributeNode(propertyName).cloneNode(true) as Attr;
|
||||
attrNode.value = propertyValue;
|
||||
el.setAttributeNode(attrNode);
|
||||
} else {
|
||||
this.setAttribute(el, propertyName, propertyValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
removeBindingDebugInfo(el: any, propertyName: string): void {
|
||||
if (el.nodeType === Node.COMMENT_NODE) {
|
||||
const m = el.nodeValue.replace(/\n/g, '').match(TEMPLATE_BINDINGS_EXP);
|
||||
const obj = m === null ? {} : JSON.parse(m[1]);
|
||||
delete obj[propertyName];
|
||||
el.nodeValue = TEMPLATE_COMMENT_TEXT.replace('{}', JSON.stringify(obj, null, 2));
|
||||
} else {
|
||||
// Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
|
||||
if (propertyName[propertyName.length - 1] === '$') {
|
||||
const attrNode: Attr = createAttributeNode(propertyName).cloneNode(true) as Attr;
|
||||
attrNode.value = '';
|
||||
el.setAttributeNode(attrNode);
|
||||
} else {
|
||||
this.removeAttribute(el, propertyName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addClass(el: any, name: string): void { el.classList.add(name); }
|
||||
|
||||
removeClass(el: any, name: string): void { el.classList.remove(name); }
|
||||
|
||||
setStyle(el: any, style: string, value: any, hasVendorPrefix: boolean, hasImportant: boolean):
|
||||
void {
|
||||
el.style[style] = value;
|
||||
}
|
||||
|
||||
removeStyle(el: any, style: string, hasVendorPrefix: boolean): void {
|
||||
// IE requires '' instead of null
|
||||
// see https://github.com/angular/angular/issues/7916
|
||||
el.style[style] = '';
|
||||
}
|
||||
|
||||
setProperty(el: any, name: string, value: any): void { el[name] = value; }
|
||||
|
||||
setText(node: any, value: string): void { node.nodeValue = value; }
|
||||
|
||||
listen(target: 'window'|'document'|'body'|any, event: string, callback: (event: any) => boolean):
|
||||
() => void {
|
||||
if (typeof target === 'string') {
|
||||
return <() => void>this.eventManager.addGlobalEventListener(
|
||||
target, event, decoratePreventDefault(callback));
|
||||
}
|
||||
return <() => void>this.eventManager.addEventListener(
|
||||
target, event, decoratePreventDefault(callback)) as() => void;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,9 @@ export const ReflectionCapabilities: typeof r.ReflectionCapabilities = r.Reflect
|
|||
|
||||
export type DebugDomRootRenderer = typeof r._DebugDomRootRenderer;
|
||||
export const DebugDomRootRenderer: typeof r.DebugDomRootRenderer = r.DebugDomRootRenderer;
|
||||
export type DebugDomRendererV2 = typeof r._DebugDomRendererV2;
|
||||
export const DebugDomRendererV2: typeof r.DebugDomRendererV2 = r.DebugDomRendererV2;
|
||||
|
||||
export const reflector: typeof r.reflector = r.reflector;
|
||||
|
||||
export type NoOpAnimationPlayer = typeof r._NoOpAnimationPlayer;
|
||||
|
|
|
@ -228,16 +228,22 @@ export class Parse5DomAdapter extends DomAdapter {
|
|||
el.parent = null;
|
||||
return el;
|
||||
}
|
||||
insertBefore(el: any, node: any) {
|
||||
this.remove(node);
|
||||
treeAdapter.insertBefore(el.parent, node, el);
|
||||
}
|
||||
insertAllBefore(el: any, nodes: any) { nodes.forEach((n: any) => this.insertBefore(el, n)); }
|
||||
insertAfter(el: any, node: any) {
|
||||
if (el.nextSibling) {
|
||||
this.insertBefore(el.nextSibling, node);
|
||||
insertBefore(parent: any, ref: any, newNode: any) {
|
||||
this.remove(newNode);
|
||||
if (ref) {
|
||||
treeAdapter.insertBefore(parent, newNode, ref);
|
||||
} else {
|
||||
this.appendChild(el.parent, node);
|
||||
this.appendChild(parent, newNode);
|
||||
}
|
||||
}
|
||||
insertAllBefore(parent: any, ref: any, nodes: any) {
|
||||
nodes.forEach((n: any) => this.insertBefore(parent, ref, n));
|
||||
}
|
||||
insertAfter(parent: any, ref: any, node: any) {
|
||||
if (ref.nextSibling) {
|
||||
this.insertBefore(parent, ref.nextSibling, node);
|
||||
} else {
|
||||
this.appendChild(parent, node);
|
||||
}
|
||||
}
|
||||
setInnerHTML(el: any, value: any) {
|
||||
|
|
|
@ -21,3 +21,5 @@ export type RenderDebugInfo = typeof r._RenderDebugInfo;
|
|||
export const RenderDebugInfo: typeof r.RenderDebugInfo = r.RenderDebugInfo;
|
||||
export type DebugDomRootRenderer = typeof r._DebugDomRootRenderer;
|
||||
export const DebugDomRootRenderer: typeof r.DebugDomRootRenderer = r.DebugDomRootRenderer;
|
||||
export type DebugDomRendererV2 = typeof r._DebugDomRendererV2;
|
||||
export const DebugDomRendererV2: typeof r.DebugDomRendererV2 = r.DebugDomRendererV2;
|
||||
|
|
|
@ -8,16 +8,15 @@
|
|||
|
||||
import {PlatformLocation} from '@angular/common';
|
||||
import {platformCoreDynamic} from '@angular/compiler';
|
||||
import {Injectable, InjectionToken, Injector, NgModule, PLATFORM_INITIALIZER, PlatformRef, Provider, RootRenderer, createPlatformFactory, isDevMode, platformCore} from '@angular/core';
|
||||
import {InjectionToken, Injector, NgModule, PLATFORM_INITIALIZER, PlatformRef, Provider, RENDERER_V2_DIRECT, RendererV2, RootRenderer, createPlatformFactory, isDevMode, platformCore} from '@angular/core';
|
||||
import {BrowserModule, DOCUMENT} from '@angular/platform-browser';
|
||||
|
||||
import {ServerPlatformLocation} from './location';
|
||||
import {Parse5DomAdapter, parseDocument} from './parse5_adapter';
|
||||
import {PlatformState} from './platform_state';
|
||||
import {DebugDomRootRenderer} from './private_import_core';
|
||||
import {DebugDomRendererV2, DebugDomRootRenderer} from './private_import_core';
|
||||
import {SharedStylesHost, getDOM} from './private_import_platform-browser';
|
||||
import {ServerRootRenderer} from './server_renderer';
|
||||
|
||||
import {ServerRendererV2, ServerRootRenderer} from './server_renderer';
|
||||
|
||||
function notSupported(feature: string): Error {
|
||||
throw new Error(`platform-server does not support '${feature}'.`);
|
||||
|
@ -35,14 +34,16 @@ function initParse5Adapter(injector: Injector) {
|
|||
}
|
||||
|
||||
export function _createConditionalRootRenderer(rootRenderer: any) {
|
||||
if (isDevMode()) {
|
||||
return new DebugDomRootRenderer(rootRenderer);
|
||||
}
|
||||
return rootRenderer;
|
||||
return isDevMode() ? new DebugDomRootRenderer(rootRenderer) : rootRenderer;
|
||||
}
|
||||
|
||||
export function _createDebugRendererV2(renderer: RendererV2): RendererV2 {
|
||||
return isDevMode() ? new DebugDomRendererV2(renderer) : renderer;
|
||||
}
|
||||
|
||||
export const SERVER_RENDER_PROVIDERS: Provider[] = [
|
||||
ServerRootRenderer,
|
||||
ServerRootRenderer, {provide: RENDERER_V2_DIRECT, useClass: ServerRendererV2},
|
||||
{provide: RendererV2, useFactory: _createDebugRendererV2, deps: [RENDERER_V2_DIRECT]},
|
||||
{provide: RootRenderer, useFactory: _createConditionalRootRenderer, deps: [ServerRootRenderer]},
|
||||
// use plain SharedStylesHost, not the DomSharedStylesHost
|
||||
SharedStylesHost
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {APP_ID, Inject, Injectable, NgZone, RenderComponentType, Renderer, RootRenderer, ViewEncapsulation} from '@angular/core';
|
||||
import {APP_ID, Inject, Injectable, NgZone, RenderComponentType, Renderer, RendererV2, RootRenderer, ViewEncapsulation} from '@angular/core';
|
||||
import {AnimationDriver, DOCUMENT} from '@angular/platform-browser';
|
||||
|
||||
import {isBlank, isPresent, stringify} from './facade/lang';
|
||||
|
@ -17,7 +17,7 @@ const TEMPLATE_COMMENT_TEXT = 'template bindings={}';
|
|||
const TEMPLATE_BINDINGS_EXP = /^template bindings=(.*)$/;
|
||||
|
||||
@Injectable()
|
||||
export class ServerRootRenderer {
|
||||
export class ServerRootRenderer implements RootRenderer {
|
||||
protected registeredComponents: Map<string, ServerRenderer> = new Map<string, ServerRenderer>();
|
||||
constructor(
|
||||
@Inject(DOCUMENT) public document: any, public sharedStylesHost: SharedStylesHost,
|
||||
|
@ -213,13 +213,13 @@ export class ServerRenderer implements Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
function moveNodesAfterSibling(sibling: any /** TODO #9100 */, nodes: any /** TODO #9100 */) {
|
||||
const parent = getDOM().parentElement(sibling);
|
||||
if (nodes.length > 0 && isPresent(parent)) {
|
||||
const nextSibling = getDOM().nextSibling(sibling);
|
||||
if (isPresent(nextSibling)) {
|
||||
function moveNodesAfterSibling(ref: any, nodes: any) {
|
||||
const parent = getDOM().parentElement(ref);
|
||||
if (nodes.length > 0 && parent) {
|
||||
const nextSibling = getDOM().nextSibling(ref);
|
||||
if (nextSibling) {
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
getDOM().insertBefore(nextSibling, nodes[i]);
|
||||
getDOM().insertBefore(parent, nextSibling, nodes[i]);
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
|
@ -229,18 +229,119 @@ function moveNodesAfterSibling(sibling: any /** TODO #9100 */, nodes: any /** TO
|
|||
}
|
||||
}
|
||||
|
||||
function appendNodes(parent: any /** TODO #9100 */, nodes: any /** TODO #9100 */) {
|
||||
function appendNodes(parent: any, nodes: any) {
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
getDOM().appendChild(parent, nodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function decoratePreventDefault(eventHandler: Function): Function {
|
||||
return (event: any /** TODO #9100 */) => {
|
||||
const allowDefaultBehavior = eventHandler(event);
|
||||
if (allowDefaultBehavior === false) {
|
||||
// TODO(tbosch): move preventDefault into event plugins...
|
||||
getDOM().preventDefault(event);
|
||||
@Injectable()
|
||||
export class ServerRendererV2 implements RendererV2 {
|
||||
constructor(private ngZone: NgZone, @Inject(DOCUMENT) private document: any) {}
|
||||
|
||||
createElement(name: string, namespace?: string, debugInfo?: any): any {
|
||||
if (namespace) {
|
||||
return getDOM().createElementNS(NAMESPACE_URIS[namespace], name);
|
||||
}
|
||||
};
|
||||
|
||||
return getDOM().createElement(name);
|
||||
}
|
||||
|
||||
createComment(value: string, debugInfo?: any): any { return getDOM().createComment(value); }
|
||||
|
||||
createText(value: string, debugInfo?: any): any { return getDOM().createTextNode(value); }
|
||||
|
||||
appendChild(parent: any, newChild: any): void { getDOM().appendChild(parent, newChild); }
|
||||
|
||||
insertBefore(parent: any, newChild: any, refChild: any): void {
|
||||
if (parent) {
|
||||
getDOM().insertBefore(parent, refChild, newChild);
|
||||
}
|
||||
}
|
||||
|
||||
removeChild(parent: any, oldChild: any): void { getDOM().removeChild(parent, oldChild); }
|
||||
|
||||
selectRootElement(selectorOrNode: string|any, debugInfo?: any): any {
|
||||
let el: any;
|
||||
if (typeof selectorOrNode === 'string') {
|
||||
el = getDOM().querySelector(this.document, selectorOrNode);
|
||||
if (!el) {
|
||||
throw new Error(`The selector "${selectorOrNode}" did not match any elements`);
|
||||
}
|
||||
} else {
|
||||
el = selectorOrNode;
|
||||
}
|
||||
getDOM().clearNodes(el);
|
||||
return el;
|
||||
}
|
||||
|
||||
parentNode(node: any): any { return getDOM().parentElement(node); }
|
||||
|
||||
nextSibling(node: any): any { return getDOM().nextSibling(node); }
|
||||
|
||||
setAttribute(el: any, name: string, value: string, namespace?: string): void {
|
||||
if (namespace) {
|
||||
getDOM().setAttributeNS(el, NAMESPACE_URIS[namespace], namespace + ':' + name, value);
|
||||
} else {
|
||||
getDOM().setAttribute(el, name, value);
|
||||
}
|
||||
}
|
||||
|
||||
removeAttribute(el: any, name: string, namespace?: string): void {
|
||||
if (namespace) {
|
||||
getDOM().removeAttributeNS(el, NAMESPACE_URIS[namespace], name);
|
||||
} else {
|
||||
getDOM().removeAttribute(el, name);
|
||||
}
|
||||
}
|
||||
|
||||
setBindingDebugInfo(el: any, propertyName: string, propertyValue: string): void {
|
||||
if (getDOM().isCommentNode(el)) {
|
||||
const m = getDOM().getText(el).replace(/\n/g, '').match(TEMPLATE_BINDINGS_EXP);
|
||||
const obj = m === null ? {} : JSON.parse(m[1]);
|
||||
obj[propertyName] = propertyValue;
|
||||
getDOM().setText(el, TEMPLATE_COMMENT_TEXT.replace('{}', JSON.stringify(obj, null, 2)));
|
||||
} else {
|
||||
this.setAttribute(el, propertyName, propertyValue);
|
||||
}
|
||||
}
|
||||
|
||||
removeBindingDebugInfo(el: any, propertyName: string): void {
|
||||
if (getDOM().isCommentNode(el)) {
|
||||
const m = getDOM().getText(el).replace(/\n/g, '').match(TEMPLATE_BINDINGS_EXP);
|
||||
const obj = m === null ? {} : JSON.parse(m[1]);
|
||||
delete obj[propertyName];
|
||||
getDOM().setText(el, TEMPLATE_COMMENT_TEXT.replace('{}', JSON.stringify(obj, null, 2)));
|
||||
} else {
|
||||
this.removeAttribute(el, propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
addClass(el: any, name: string): void { getDOM().addClass(el, name); }
|
||||
|
||||
removeClass(el: any, name: string): void { getDOM().removeClass(el, name); }
|
||||
|
||||
setStyle(el: any, style: string, value: any, hasVendorPrefix: boolean, hasImportant: boolean):
|
||||
void {
|
||||
getDOM().setStyle(el, style, value);
|
||||
}
|
||||
|
||||
removeStyle(el: any, style: string, hasVendorPrefix: boolean): void {
|
||||
getDOM().removeStyle(el, style);
|
||||
}
|
||||
|
||||
setProperty(el: any, name: string, value: any): void { getDOM().setProperty(el, name, value); }
|
||||
|
||||
setText(node: any, value: string): void { getDOM().setText(node, value); }
|
||||
|
||||
listen(
|
||||
target: 'document'|'window'|'body'|any, eventName: string,
|
||||
callback: (event: any) => boolean): () => void {
|
||||
// Note: We are not using the EventsPlugin here as this is not needed
|
||||
// to run our tests.
|
||||
const el =
|
||||
typeof target === 'string' ? getDOM().getGlobalEventTarget(this.document, target) : target;
|
||||
const outsideHandler = (event: any) => this.ngZone.runGuarded(() => callback(event));
|
||||
return this.ngZone.runOutsideAngular(() => getDOM().onAndCancel(el, eventName, outsideHandler));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import {DomAdapter, setRootDomAdapter} from '../../private_import_platform-brows
|
|||
export class WorkerDomAdapter extends DomAdapter {
|
||||
static makeCurrent() { setRootDomAdapter(new WorkerDomAdapter()); }
|
||||
|
||||
logError(error: any /** TODO #9100 */) {
|
||||
logError(error: any) {
|
||||
if (console.error) {
|
||||
console.error(error);
|
||||
} else {
|
||||
|
@ -28,9 +28,9 @@ export class WorkerDomAdapter extends DomAdapter {
|
|||
}
|
||||
|
||||
// tslint:disable-next-line:no-console
|
||||
log(error: any /** TODO #9100 */) { console.log(error); }
|
||||
log(error: any) { console.log(error); }
|
||||
|
||||
logGroup(error: any /** TODO #9100 */) {
|
||||
logGroup(error: any) {
|
||||
if (console.group) {
|
||||
console.group(error);
|
||||
this.logError(error);
|
||||
|
@ -46,7 +46,7 @@ export class WorkerDomAdapter extends DomAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
hasProperty(element: any /** TODO #9100 */, name: string): boolean { throw 'not implemented'; }
|
||||
hasProperty(element: any, name: string): boolean { throw 'not implemented'; }
|
||||
setProperty(el: Element, name: string, value: any) { throw 'not implemented'; }
|
||||
getProperty(el: Element, name: string): any { throw 'not implemented'; }
|
||||
invoke(el: Element, methodName: string, args: any[]): any { throw 'not implemented'; }
|
||||
|
@ -55,136 +55,95 @@ export class WorkerDomAdapter extends DomAdapter {
|
|||
set attrToPropMap(value: {[key: string]: string}) { throw 'not implemented'; }
|
||||
|
||||
parse(templateHtml: string) { throw 'not implemented'; }
|
||||
querySelector(el: any /** TODO #9100 */, selector: string): HTMLElement {
|
||||
throw 'not implemented';
|
||||
}
|
||||
querySelectorAll(el: any /** TODO #9100 */, selector: string): any[] { throw 'not implemented'; }
|
||||
on(el: any /** TODO #9100 */, evt: any /** TODO #9100 */, listener: any /** TODO #9100 */) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
onAndCancel(
|
||||
el: any /** TODO #9100 */, evt: any /** TODO #9100 */,
|
||||
listener: any /** TODO #9100 */): Function {
|
||||
throw 'not implemented';
|
||||
}
|
||||
dispatchEvent(el: any /** TODO #9100 */, evt: any /** TODO #9100 */) { throw 'not implemented'; }
|
||||
createMouseEvent(eventType: any /** TODO #9100 */): any { throw 'not implemented'; }
|
||||
querySelector(el: any, selector: string): HTMLElement { throw 'not implemented'; }
|
||||
querySelectorAll(el: any, selector: string): any[] { throw 'not implemented'; }
|
||||
on(el: any, evt: any, listener: any) { throw 'not implemented'; }
|
||||
onAndCancel(el: any, evt: any, listener: any): Function { throw 'not implemented'; }
|
||||
dispatchEvent(el: any, evt: any) { throw 'not implemented'; }
|
||||
createMouseEvent(eventType: any): any { throw 'not implemented'; }
|
||||
createEvent(eventType: string): any { throw 'not implemented'; }
|
||||
preventDefault(evt: any /** TODO #9100 */) { throw 'not implemented'; }
|
||||
isPrevented(evt: any /** TODO #9100 */): boolean { throw 'not implemented'; }
|
||||
getInnerHTML(el: any /** TODO #9100 */): string { throw 'not implemented'; }
|
||||
getTemplateContent(el: any /** TODO #9100 */): any { throw 'not implemented'; }
|
||||
getOuterHTML(el: any /** TODO #9100 */): string { throw 'not implemented'; }
|
||||
nodeName(node: any /** TODO #9100 */): string { throw 'not implemented'; }
|
||||
nodeValue(node: any /** TODO #9100 */): string { throw 'not implemented'; }
|
||||
type(node: any /** TODO #9100 */): string { throw 'not implemented'; }
|
||||
content(node: any /** TODO #9100 */): any { throw 'not implemented'; }
|
||||
firstChild(el: any /** TODO #9100 */): Node { throw 'not implemented'; }
|
||||
nextSibling(el: any /** TODO #9100 */): Node { throw 'not implemented'; }
|
||||
parentElement(el: any /** TODO #9100 */): Node { throw 'not implemented'; }
|
||||
childNodes(el: any /** TODO #9100 */): Node[] { throw 'not implemented'; }
|
||||
childNodesAsList(el: any /** TODO #9100 */): Node[] { throw 'not implemented'; }
|
||||
clearNodes(el: any /** TODO #9100 */) { throw 'not implemented'; }
|
||||
appendChild(el: any /** TODO #9100 */, node: any /** TODO #9100 */) { throw 'not implemented'; }
|
||||
removeChild(el: any /** TODO #9100 */, node: any /** TODO #9100 */) { throw 'not implemented'; }
|
||||
replaceChild(
|
||||
el: any /** TODO #9100 */, newNode: any /** TODO #9100 */, oldNode: any /** TODO #9100 */) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
remove(el: any /** TODO #9100 */): Node { throw 'not implemented'; }
|
||||
insertBefore(el: any /** TODO #9100 */, node: any /** TODO #9100 */) { throw 'not implemented'; }
|
||||
insertAllBefore(el: any /** TODO #9100 */, nodes: any /** TODO #9100 */) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
insertAfter(el: any /** TODO #9100 */, node: any /** TODO #9100 */) { throw 'not implemented'; }
|
||||
setInnerHTML(el: any /** TODO #9100 */, value: any /** TODO #9100 */) { throw 'not implemented'; }
|
||||
getText(el: any /** TODO #9100 */): string { throw 'not implemented'; }
|
||||
setText(el: any /** TODO #9100 */, value: string) { throw 'not implemented'; }
|
||||
getValue(el: any /** TODO #9100 */): string { throw 'not implemented'; }
|
||||
setValue(el: any /** TODO #9100 */, value: string) { throw 'not implemented'; }
|
||||
getChecked(el: any /** TODO #9100 */): boolean { throw 'not implemented'; }
|
||||
setChecked(el: any /** TODO #9100 */, value: boolean) { throw 'not implemented'; }
|
||||
preventDefault(evt: any) { throw 'not implemented'; }
|
||||
isPrevented(evt: any): boolean { throw 'not implemented'; }
|
||||
getInnerHTML(el: any): string { throw 'not implemented'; }
|
||||
getTemplateContent(el: any): any { throw 'not implemented'; }
|
||||
getOuterHTML(el: any): string { throw 'not implemented'; }
|
||||
nodeName(node: any): string { throw 'not implemented'; }
|
||||
nodeValue(node: any): string { throw 'not implemented'; }
|
||||
type(node: any): string { throw 'not implemented'; }
|
||||
content(node: any): any { throw 'not implemented'; }
|
||||
firstChild(el: any): Node { throw 'not implemented'; }
|
||||
nextSibling(el: any): Node { throw 'not implemented'; }
|
||||
parentElement(el: any): Node { throw 'not implemented'; }
|
||||
childNodes(el: any): Node[] { throw 'not implemented'; }
|
||||
childNodesAsList(el: any): Node[] { throw 'not implemented'; }
|
||||
clearNodes(el: any) { throw 'not implemented'; }
|
||||
appendChild(el: any, node: any) { throw 'not implemented'; }
|
||||
removeChild(el: any, node: any) { throw 'not implemented'; }
|
||||
replaceChild(el: any, newNode: any, oldNode: any) { throw 'not implemented'; }
|
||||
remove(el: any): Node { throw 'not implemented'; }
|
||||
insertBefore(parent: any, el: any, node: any) { throw 'not implemented'; }
|
||||
insertAllBefore(parent: any, el: any, nodes: any) { throw 'not implemented'; }
|
||||
insertAfter(parent: any, el: any, node: any) { throw 'not implemented'; }
|
||||
setInnerHTML(el: any, value: any) { throw 'not implemented'; }
|
||||
getText(el: any): string { throw 'not implemented'; }
|
||||
setText(el: any, value: string) { throw 'not implemented'; }
|
||||
getValue(el: any): string { throw 'not implemented'; }
|
||||
setValue(el: any, value: string) { throw 'not implemented'; }
|
||||
getChecked(el: any): boolean { throw 'not implemented'; }
|
||||
setChecked(el: any, value: boolean) { throw 'not implemented'; }
|
||||
createComment(text: string): any { throw 'not implemented'; }
|
||||
createTemplate(html: any /** TODO #9100 */): HTMLElement { throw 'not implemented'; }
|
||||
createElement(tagName: any /** TODO #9100 */, doc?: any /** TODO #9100 */): HTMLElement {
|
||||
createTemplate(html: any): HTMLElement { throw 'not implemented'; }
|
||||
createElement(tagName: any, doc?: any): HTMLElement { throw 'not implemented'; }
|
||||
createElementNS(ns: string, tagName: string, doc?: any): Element { throw 'not implemented'; }
|
||||
createTextNode(text: string, doc?: any): Text { throw 'not implemented'; }
|
||||
createScriptTag(attrName: string, attrValue: string, doc?: any): HTMLElement {
|
||||
throw 'not implemented';
|
||||
}
|
||||
createElementNS(ns: string, tagName: string, doc?: any /** TODO #9100 */): Element {
|
||||
throw 'not implemented';
|
||||
}
|
||||
createTextNode(text: string, doc?: any /** TODO #9100 */): Text { throw 'not implemented'; }
|
||||
createScriptTag(attrName: string, attrValue: string, doc?: any /** TODO #9100 */): HTMLElement {
|
||||
throw 'not implemented';
|
||||
}
|
||||
createStyleElement(css: string, doc?: any /** TODO #9100 */): HTMLStyleElement {
|
||||
throw 'not implemented';
|
||||
}
|
||||
createShadowRoot(el: any /** TODO #9100 */): any { throw 'not implemented'; }
|
||||
getShadowRoot(el: any /** TODO #9100 */): any { throw 'not implemented'; }
|
||||
getHost(el: any /** TODO #9100 */): any { throw 'not implemented'; }
|
||||
getDistributedNodes(el: any /** TODO #9100 */): Node[] { throw 'not implemented'; }
|
||||
createStyleElement(css: string, doc?: any): HTMLStyleElement { throw 'not implemented'; }
|
||||
createShadowRoot(el: any): any { throw 'not implemented'; }
|
||||
getShadowRoot(el: any): any { throw 'not implemented'; }
|
||||
getHost(el: any): any { throw 'not implemented'; }
|
||||
getDistributedNodes(el: any): Node[] { throw 'not implemented'; }
|
||||
clone(node: Node): Node { throw 'not implemented'; }
|
||||
getElementsByClassName(element: any /** TODO #9100 */, name: string): HTMLElement[] {
|
||||
getElementsByClassName(element: any, name: string): HTMLElement[] { throw 'not implemented'; }
|
||||
getElementsByTagName(element: any, name: string): HTMLElement[] { throw 'not implemented'; }
|
||||
classList(element: any): any[] { throw 'not implemented'; }
|
||||
addClass(element: any, className: string) { throw 'not implemented'; }
|
||||
removeClass(element: any, className: string) { throw 'not implemented'; }
|
||||
hasClass(element: any, className: string): boolean { throw 'not implemented'; }
|
||||
setStyle(element: any, styleName: string, styleValue: string) { throw 'not implemented'; }
|
||||
removeStyle(element: any, styleName: string) { throw 'not implemented'; }
|
||||
getStyle(element: any, styleName: string): string { throw 'not implemented'; }
|
||||
hasStyle(element: any, styleName: string, styleValue?: string): boolean {
|
||||
throw 'not implemented';
|
||||
}
|
||||
getElementsByTagName(element: any /** TODO #9100 */, name: string): HTMLElement[] {
|
||||
throw 'not implemented';
|
||||
}
|
||||
classList(element: any /** TODO #9100 */): any[] { throw 'not implemented'; }
|
||||
addClass(element: any /** TODO #9100 */, className: string) { throw 'not implemented'; }
|
||||
removeClass(element: any /** TODO #9100 */, className: string) { throw 'not implemented'; }
|
||||
hasClass(element: any /** TODO #9100 */, className: string): boolean { throw 'not implemented'; }
|
||||
setStyle(element: any /** TODO #9100 */, styleName: string, styleValue: string) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
removeStyle(element: any /** TODO #9100 */, styleName: string) { throw 'not implemented'; }
|
||||
getStyle(element: any /** TODO #9100 */, styleName: string): string { throw 'not implemented'; }
|
||||
hasStyle(element: any /** TODO #9100 */, styleName: string, styleValue?: string): boolean {
|
||||
throw 'not implemented';
|
||||
}
|
||||
tagName(element: any /** TODO #9100 */): string { throw 'not implemented'; }
|
||||
attributeMap(element: any /** TODO #9100 */): Map<string, string> { throw 'not implemented'; }
|
||||
hasAttribute(element: any /** TODO #9100 */, attribute: string): boolean {
|
||||
throw 'not implemented';
|
||||
}
|
||||
hasAttributeNS(element: any /** TODO #9100 */, ns: string, attribute: string): boolean {
|
||||
throw 'not implemented';
|
||||
}
|
||||
getAttribute(element: any /** TODO #9100 */, attribute: string): string {
|
||||
throw 'not implemented';
|
||||
}
|
||||
getAttributeNS(element: any /** TODO #9100 */, ns: string, attribute: string): string {
|
||||
throw 'not implemented';
|
||||
}
|
||||
setAttribute(element: any /** TODO #9100 */, name: string, value: string) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
setAttributeNS(element: any /** TODO #9100 */, ns: string, name: string, value: string) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
removeAttribute(element: any /** TODO #9100 */, attribute: string) { throw 'not implemented'; }
|
||||
removeAttributeNS(element: any /** TODO #9100 */, ns: string, attribute: string) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
templateAwareRoot(el: any /** TODO #9100 */) { throw 'not implemented'; }
|
||||
tagName(element: any): string { throw 'not implemented'; }
|
||||
attributeMap(element: any): Map<string, string> { throw 'not implemented'; }
|
||||
hasAttribute(element: any, attribute: string): boolean { throw 'not implemented'; }
|
||||
hasAttributeNS(element: any, ns: string, attribute: string): boolean { throw 'not implemented'; }
|
||||
getAttribute(element: any, attribute: string): string { throw 'not implemented'; }
|
||||
getAttributeNS(element: any, ns: string, attribute: string): string { throw 'not implemented'; }
|
||||
setAttribute(element: any, name: string, value: string) { throw 'not implemented'; }
|
||||
setAttributeNS(element: any, ns: string, name: string, value: string) { throw 'not implemented'; }
|
||||
removeAttribute(element: any, attribute: string) { throw 'not implemented'; }
|
||||
removeAttributeNS(element: any, ns: string, attribute: string) { throw 'not implemented'; }
|
||||
templateAwareRoot(el: any) { throw 'not implemented'; }
|
||||
createHtmlDocument(): HTMLDocument { throw 'not implemented'; }
|
||||
getBoundingClientRect(el: any /** TODO #9100 */) { throw 'not implemented'; }
|
||||
getBoundingClientRect(el: any) { throw 'not implemented'; }
|
||||
getTitle(doc: Document): string { throw 'not implemented'; }
|
||||
setTitle(doc: Document, newTitle: string) { throw 'not implemented'; }
|
||||
elementMatches(n: any /** TODO #9100 */, selector: string): boolean { throw 'not implemented'; }
|
||||
elementMatches(n: any, selector: string): boolean { throw 'not implemented'; }
|
||||
isTemplateElement(el: any): boolean { throw 'not implemented'; }
|
||||
isTextNode(node: any /** TODO #9100 */): boolean { throw 'not implemented'; }
|
||||
isCommentNode(node: any /** TODO #9100 */): boolean { throw 'not implemented'; }
|
||||
isElementNode(node: any /** TODO #9100 */): boolean { throw 'not implemented'; }
|
||||
hasShadowRoot(node: any /** TODO #9100 */): boolean { throw 'not implemented'; }
|
||||
isShadowRoot(node: any /** TODO #9100 */): boolean { throw 'not implemented'; }
|
||||
isTextNode(node: any): boolean { throw 'not implemented'; }
|
||||
isCommentNode(node: any): boolean { throw 'not implemented'; }
|
||||
isElementNode(node: any): boolean { throw 'not implemented'; }
|
||||
hasShadowRoot(node: any): boolean { throw 'not implemented'; }
|
||||
isShadowRoot(node: any): boolean { throw 'not implemented'; }
|
||||
importIntoDoc(node: Node): Node { throw 'not implemented'; }
|
||||
adoptNode(node: Node): Node { throw 'not implemented'; }
|
||||
getHref(element: any /** TODO #9100 */): string { throw 'not implemented'; }
|
||||
getEventKey(event: any /** TODO #9100 */): string { throw 'not implemented'; }
|
||||
resolveAndSetHref(element: any /** TODO #9100 */, baseUrl: string, href: string) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
getHref(element: any): string { throw 'not implemented'; }
|
||||
getEventKey(event: any): string { throw 'not implemented'; }
|
||||
resolveAndSetHref(element: any, baseUrl: string, href: string) { throw 'not implemented'; }
|
||||
supportsDOMEvents(): boolean { throw 'not implemented'; }
|
||||
supportsNativeShadowDOM(): boolean { throw 'not implemented'; }
|
||||
getGlobalEventTarget(doc: Document, target: string): any { throw 'not implemented'; }
|
||||
|
@ -193,9 +152,9 @@ export class WorkerDomAdapter extends DomAdapter {
|
|||
getBaseHref(doc: Document): string { throw 'not implemented'; }
|
||||
resetBaseElement(): void { throw 'not implemented'; }
|
||||
getUserAgent(): string { throw 'not implemented'; }
|
||||
setData(element: any /** TODO #9100 */, name: string, value: string) { throw 'not implemented'; }
|
||||
getComputedStyle(element: any /** TODO #9100 */): any { throw 'not implemented'; }
|
||||
getData(element: any /** TODO #9100 */, name: string): string { throw 'not implemented'; }
|
||||
setData(element: any, name: string, value: string) { throw 'not implemented'; }
|
||||
getComputedStyle(element: any): any { throw 'not implemented'; }
|
||||
getData(element: any, name: string): string { throw 'not implemented'; }
|
||||
setGlobalVar(name: string, value: any) { throw 'not implemented'; }
|
||||
performanceNow(): number { throw 'not implemented'; }
|
||||
getAnimationPrefix(): string { throw 'not implemented'; }
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ApplicationRef, NgModuleRef, enableProdMode} from '@angular/core';
|
||||
import {enableProdMode} from '@angular/core';
|
||||
|
||||
import {bindAction, profile} from '../../util';
|
||||
import {buildTree, emptyTree} from '../util';
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
*/
|
||||
|
||||
import {NgIf} from '@angular/common';
|
||||
import {Component, ComponentFactory, ComponentRef, Injector, NgModule, RootRenderer, Sanitizer, TemplateRef, ViewContainerRef, ViewEncapsulation} from '@angular/core';
|
||||
import {ArgumentType, BindingType, NodeFlags, ViewData, ViewDefinition, ViewFlags, anchorDef, createComponentFactory, directiveDef, elementDef, initServicesIfNeeded, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {ComponentFactory, ComponentRef, Injector, RendererV2, RootRenderer, Sanitizer, TemplateRef, ViewContainerRef} from '@angular/core';
|
||||
import {ArgumentType, BindingType, NodeFlags, ViewDefinition, ViewFlags, anchorDef, createComponentFactory, directiveDef, elementDef, initServicesIfNeeded, textDef, viewDef} from '@angular/core/src/view/index';
|
||||
import {DomRendererV2} from '@angular/platform-browser/src/dom/dom_renderer';
|
||||
import {DomSanitizerImpl, SafeStyle} from '@angular/platform-browser/src/security/dom_sanitization_service';
|
||||
|
||||
import {TreeNode, emptyTree} from '../util';
|
||||
|
@ -88,11 +89,14 @@ function TreeComponent_0(): ViewDefinition {
|
|||
export class AppModule implements Injector {
|
||||
private sanitizer: DomSanitizerImpl;
|
||||
private componentFactory: ComponentFactory<TreeComponent>;
|
||||
private rendererV2: RendererV2;
|
||||
|
||||
componentRef: ComponentRef<TreeComponent>;
|
||||
|
||||
constructor() {
|
||||
initServicesIfNeeded();
|
||||
this.sanitizer = new DomSanitizerImpl(document);
|
||||
this.rendererV2 = new DomRendererV2(null);
|
||||
trustedEmptyColor = this.sanitizer.bypassSecurityTrustStyle('');
|
||||
trustedGreyColor = this.sanitizer.bypassSecurityTrustStyle('grey');
|
||||
this.componentFactory = createComponentFactory('#root', TreeComponent, TreeComponent_Host);
|
||||
|
@ -100,6 +104,8 @@ export class AppModule implements Injector {
|
|||
|
||||
get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND): any {
|
||||
switch (token) {
|
||||
case RendererV2:
|
||||
return this.rendererV2;
|
||||
case Sanitizer:
|
||||
return this.sanitizer;
|
||||
case RootRenderer:
|
||||
|
|
|
@ -349,6 +349,7 @@ export declare class DebugElement extends DebugNode {
|
|||
};
|
||||
constructor(nativeNode: any, parent: any, _debugInfo: RenderDebugInfo);
|
||||
addChild(child: DebugNode): void;
|
||||
insertBefore(refChild: DebugNode, newChild: DebugNode): void;
|
||||
insertChildrenAfter(child: DebugNode, newChildren: DebugNode[]): void;
|
||||
query(predicate: Predicate<DebugElement>): DebugElement;
|
||||
queryAll(predicate: Predicate<DebugElement>): DebugElement[];
|
||||
|
@ -846,6 +847,33 @@ export declare abstract class Renderer {
|
|||
abstract setText(renderNode: any, text: string): void;
|
||||
}
|
||||
|
||||
/** @experimental */
|
||||
export declare const RENDERER_V2_DIRECT: InjectionToken<RendererV2>;
|
||||
|
||||
/** @experimental */
|
||||
export declare abstract class RendererV2 {
|
||||
abstract addClass(el: any, name: string): void;
|
||||
abstract appendChild(parent: any, newChild: any): void;
|
||||
abstract createComment(value: string, debugInfo?: RenderDebugContext): any;
|
||||
abstract createElement(name: string, namespace?: string, debugInfo?: RenderDebugContext): any;
|
||||
abstract createText(value: string, debugInfo?: RenderDebugContext): any;
|
||||
abstract insertBefore(parent: any, newChild: any, refChild: any): void;
|
||||
abstract listen(target: 'window' | 'document' | 'body' | any, eventName: string, callback: (event: any) => boolean): () => void;
|
||||
abstract nextSibling(node: any): any;
|
||||
abstract parentNode(node: any): any;
|
||||
abstract removeAttribute(el: any, name: string, namespace?: string): void;
|
||||
abstract removeBindingDebugInfo(el: any, propertyName: string): void;
|
||||
abstract removeChild(parent: any, oldChild: any): void;
|
||||
abstract removeClass(el: any, name: string): void;
|
||||
abstract removeStyle(el: any, style: string, hasVendorPrefix: boolean): void;
|
||||
abstract selectRootElement(selectorOrNode: string | any, debugInfo?: RenderDebugContext): any;
|
||||
abstract setAttribute(el: any, name: string, value: string, namespace?: string): void;
|
||||
abstract setBindingDebugInfo(el: any, propertyName: string, propertyValue: string): void;
|
||||
abstract setProperty(el: any, name: string, value: any): void;
|
||||
abstract setStyle(el: any, style: string, value: any, hasVendorPrefix: boolean, hasImportant: boolean): void;
|
||||
abstract setText(node: any, value: string): void;
|
||||
}
|
||||
|
||||
/** @experimental */
|
||||
export declare class ResolvedReflectiveFactory {
|
||||
dependencies: ReflectiveDependency[];
|
||||
|
|
Loading…
Reference in New Issue