feat: RendererV2 integration (#14469)
This commit is contained in:

committed by
Igor Minar

parent
b4d444a0a7
commit
bb9c7ae6e7
@ -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;
|
||||
|
Reference in New Issue
Block a user