refactor(core): remove misc dom utils from DomAdapters (#32278)

PR Close #32278
This commit is contained in:
Kara Erickson 2019-08-22 19:48:08 -07:00 committed by atscott
parent 28c8b03797
commit cf4b944865
17 changed files with 59 additions and 56 deletions

View File

@ -28,8 +28,8 @@
"uncompressed": {
"runtime-es5": 2932,
"runtime-es2015": 2938,
"main-es5": 554933,
"main-es2015": 499846,
"main-es5": 554068,
"main-es2015": 495320,
"polyfills-es5": 131024,
"polyfills-es2015": 52433
}

View File

@ -15,7 +15,7 @@ import {ComponentRef} from '@angular/core/src/linker/component_factory';
import {getLocaleId} from '@angular/core/src/render3';
import {BrowserModule} from '@angular/platform-browser';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {dispatchEvent} from '@angular/platform-browser/testing/src/browser_util';
import {dispatchEvent, getContent} from '@angular/platform-browser/testing/src/browser_util';
import {expect} from '@angular/platform-browser/testing/src/matchers';
import {onlyInIvy} from '@angular/private/testing';
@ -35,7 +35,7 @@ class SomeComponent {
function createRootEl(selector = 'bootstrap-app') {
const doc = TestBed.get(DOCUMENT);
const rootEl = <HTMLElement>getDOM().firstChild(
getDOM().content(getDOM().createTemplate(`<${selector}></${selector}>`)));
getContent(getDOM().createTemplate(`<${selector}></${selector}>`)));
const oldRoots = getDOM().querySelectorAll(doc, selector);
for (let i = 0; i < oldRoots.length; i++) {
getDOM().remove(oldRoots[i]);

View File

@ -8,7 +8,7 @@
import {beforeEach, describe, expect, it} from '@angular/core/testing/src/testing_internal';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {el, stringifyElement} from '@angular/platform-browser/testing/src/browser_util';
import {el, isTextNode, stringifyElement} from '@angular/platform-browser/testing/src/browser_util';
{
describe('dom adapter', () => {
@ -41,17 +41,16 @@ import {el, stringifyElement} from '@angular/platform-browser/testing/src/browse
const secondChild = cNodes[1];
expect(getDOM().parentElement(firstChild)).toBe(clone);
expect(getDOM().nextSibling(firstChild)).toBe(secondChild);
expect(getDOM().isTextNode(firstChild)).toBe(true);
expect(isTextNode(firstChild)).toBe(true);
expect(getDOM().parentElement(secondChild)).toBe(clone);
expect(getDOM().nextSibling(secondChild)).toBeFalsy();
expect(getDOM().isElementNode(secondChild)).toBe(true);
});
it('should be able to create text nodes and use them with the other APIs', () => {
const t = getDOM().createTextNode('hello');
expect(getDOM().isTextNode(t)).toBe(true);
expect(isTextNode(t)).toBe(true);
const d = getDOM().createElement('div');
getDOM().appendChild(d, t);
expect(d.innerHTML).toEqual('hello');

View File

@ -11,7 +11,7 @@ import {MockResourceLoader} from '@angular/compiler/testing';
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, DebugElement, Directive, DoCheck, EventEmitter, HostBinding, Inject, Injectable, Input, OnChanges, OnDestroy, OnInit, Output, Pipe, PipeTransform, Provider, RenderComponentType, Renderer, RendererFactory2, RendererType2, RootRenderer, SimpleChange, SimpleChanges, TemplateRef, Type, ViewChild, ViewContainerRef, WrappedValue} from '@angular/core';
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';
import {isTextNode} from '@angular/platform-browser/testing/src/browser_util';
import {expect} from '@angular/platform-browser/testing/src/matchers';
import {ivyEnabled, modifiedInIvy, onlyInIvy} from '@angular/private/testing';
@ -1731,7 +1731,7 @@ function patchLoggingRenderer2(rendererFactory: RendererFactory2, log: RenderLog
origSetProperty.call(renderer, el, name, value);
};
renderer.setValue = function(node: any, value: string): void {
if (getDOM().isTextNode(node)) {
if (isTextNode(node)) {
log.setText(node, value);
}
origSetValue.call(renderer, node, value);

View File

@ -137,8 +137,7 @@ function declareTests(config?: {useJit: boolean}) {
fixture.componentInstance.ctxProp = null !;
fixture.detectChanges();
expect(getDOM().hasAttribute(fixture.debugElement.children[0].nativeElement, 'foo'))
.toBeFalsy();
expect(fixture.debugElement.children[0].nativeElement.hasAttribute('foo')).toBeFalsy();
});
it('should remove style when when style expression evaluates to null', () => {

View File

@ -60,7 +60,7 @@ function declareTests(config?: {useJit: boolean}) {
const children = getDOM().childNodes(el);
expect(children.length).toBe(2);
expect(isCommentNode(children[0])).toBe(true);
expect(getDOM().tagName(children[1]).toUpperCase()).toEqual('P');
expect((children[1] as Element).tagName.toUpperCase()).toEqual('P');
});
modifiedInIvy('FW-678: ivy generates different DOM structure for <ng-container>')
@ -99,8 +99,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(isCommentNode(children[0])).toBe(true);
// ng-container anchor
expect(isCommentNode(children[1])).toBe(true);
expect(getDOM().tagName(children[2]).toUpperCase()).toEqual('P');
expect(getDOM().tagName(children[3]).toUpperCase()).toEqual('B');
expect((children[2] as Element).tagName.toUpperCase()).toEqual('P');
expect((children[3] as Element).tagName.toUpperCase()).toEqual('B');
fixture.componentInstance.ctxBoolProp = false;
fixture.detectChanges();

View File

@ -980,7 +980,7 @@ class Tree {
class CmpD {
tagName: string;
constructor(elementRef: ElementRef) {
this.tagName = getDOM().tagName(elementRef.nativeElement).toLowerCase();
this.tagName = elementRef.nativeElement.tagName.toLowerCase();
}
}
@ -989,7 +989,7 @@ class CmpD {
class CmpC {
tagName: string;
constructor(elementRef: ElementRef) {
this.tagName = getDOM().tagName(elementRef.nativeElement).toLowerCase();
this.tagName = elementRef.nativeElement.tagName.toLowerCase();
}
}

View File

@ -418,7 +418,7 @@ function declareTests(config?: {useJit: boolean}) {
const compRef =
modRef.componentFactoryResolver.resolveComponentFactory(App).create(Injector.NULL);
expect(getDOM().hasAttribute(compRef.location.nativeElement, 'ng-version')).toBe(false);
expect(compRef.location.nativeElement.hasAttribute('ng-version')).toBe(false);
});
});
}

View File

@ -122,7 +122,7 @@ function declareTests(config?: {useJit: boolean}) {
const div = cmp.debugElement.children[0];
expect(div.injector.get(OnPrefixDir).onclick).toBe(value);
expect(getDOM().getProperty(div.nativeElement, 'onclick')).not.toBe(value);
expect(getDOM().hasAttribute(div.nativeElement, 'onclick')).toEqual(false);
expect(div.nativeElement.hasAttribute('onclick')).toEqual(false);
});
});

View File

@ -12,8 +12,8 @@ import {NgZone, RendererFactory2, RendererType2} from '@angular/core';
import {NoopNgZone} from '@angular/core/src/zone/ng_zone';
import {EventManager, ɵDomRendererFactory2, ɵDomSharedStylesHost} from '@angular/platform-browser';
import {ɵAnimationRendererFactory} from '@angular/platform-browser/animations';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {EventManagerPlugin} from '@angular/platform-browser/src/dom/events/event_manager';
import {isTextNode} from '@angular/platform-browser/testing/src/browser_util';
export class SimpleDomEventsPlugin extends EventManagerPlugin {
constructor(doc: any) { super(doc); }
@ -99,7 +99,7 @@ export function patchLoggingRenderer2(rendererFactory: RendererFactory2, log: Re
origSetProperty.call(renderer, el, name, value);
};
renderer.setValue = function(node: any, value: string): void {
if (getDOM().isTextNode(node)) {
if (isTextNode(node)) {
log.setText(node, value);
}
origSetValue.call(renderer, node, value);

View File

@ -20,7 +20,7 @@ export class DOMTestComponentRenderer extends TestComponentRenderer {
insertRootElement(rootElId: string) {
const rootEl = <HTMLElement>getDOM().firstChild(
getDOM().content(getDOM().createTemplate(`<div id="${rootElId}"></div>`)));
getContent(getDOM().createTemplate(`<div id="${rootElId}"></div>`)));
// TODO(juliemr): can/should this be optional?
const oldRoots = getDOM().querySelectorAll(this._doc, '[id^=root]');
@ -30,3 +30,11 @@ export class DOMTestComponentRenderer extends TestComponentRenderer {
getDOM().appendChild(this._doc.body, rootEl);
}
}
function getContent(node: Node): Node {
if ('content' in node) {
return (<any>node).content;
} else {
return node;
}
}

View File

@ -142,13 +142,6 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
nodeName(node: Node): string { return node.nodeName; }
nodeValue(node: Node): string|null { return node.nodeValue; }
type(node: HTMLInputElement): string { return node.type; }
content(node: Node): Node {
if (this.hasProperty(node, 'content')) {
return (<any>node).content;
} else {
return node;
}
}
firstChild(el: Node): Node|null { return el.firstChild; }
nextSibling(el: Node): Node|null { return el.nextSibling; }
parentElement(el: Node): Node|null { return el.parentNode; }
@ -222,11 +215,7 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
const value = this.getStyle(element, styleName) || '';
return styleValue ? value == styleValue : value.length > 0;
}
tagName(element: any): string { return element.tagName; }
hasAttribute(element: Element, attribute: string): boolean {
return element.hasAttribute(attribute);
}
getAttribute(element: Element, attribute: string): string|null {
return element.getAttribute(attribute);
}
@ -238,7 +227,7 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
removeAttributeNS(element: Element, ns: string, name: string) {
element.removeAttributeNS(ns, name);
}
templateAwareRoot(el: Node): any { return this.isTemplateElement(el) ? this.content(el) : el; }
createHtmlDocument(): HTMLDocument {
return document.implementation.createHTMLDocument('fakeTitle');
}
@ -254,10 +243,7 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
return false;
}
isTemplateElement(el: Node): boolean {
return this.isElementNode(el) && el.nodeName === 'TEMPLATE';
}
isTextNode(node: Node): boolean { return node.nodeType === Node.TEXT_NODE; }
isElementNode(node: Node): boolean { return node.nodeType === Node.ELEMENT_NODE; }
isShadowRoot(node: any): boolean { return node instanceof DocumentFragment; }

View File

@ -56,7 +56,6 @@ export abstract class DomAdapter {
abstract nodeName(node: any): string;
abstract nodeValue(node: any): string|null;
abstract type(node: any): string;
abstract content(node: any): any;
abstract firstChild(el: any): Node|null;
abstract nextSibling(el: any): Node|null;
abstract parentElement(el: any): Node|null;
@ -89,21 +88,24 @@ export abstract class DomAdapter {
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 hasAttribute(element: any, attribute: string): boolean;
// Used by Meta
abstract getAttribute(element: any, attribute: string): string|null;
// Used by platform-server
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 getDefaultDocument(): Document;
// Used by Title
abstract getTitle(doc: Document): string;
abstract setTitle(doc: Document, newTitle: string): any;
// Used by By.css
abstract elementMatches(n: any, selector: string): boolean;
abstract isTemplateElement(el: any): boolean;
abstract isTextNode(node: any): boolean;
abstract isElementNode(node: any): boolean;
// Used by Testability

View File

@ -95,7 +95,7 @@ export function dispatchEvent(element: any, eventType: any): void {
}
export function el(html: string): HTMLElement {
return <HTMLElement>getDOM().firstChild(getDOM().content(getDOM().createTemplate(html)));
return <HTMLElement>getDOM().firstChild(getContent(getDOM().createTemplate(html)));
}
export function normalizeCSS(css: string): string {
@ -121,7 +121,7 @@ const _selfClosingTags = ['br', 'hr', 'input'];
export function stringifyElement(el: any /** TODO #9100 */): string {
let result = '';
if (getDOM().isElementNode(el)) {
const tagName = getDOM().tagName(el).toLowerCase();
const tagName = el.tagName.toLowerCase();
// Opening tag
result += `<${tagName}`;
@ -147,7 +147,7 @@ export function stringifyElement(el: any /** TODO #9100 */): string {
result += '>';
// Children
const childrenRoot = getDOM().templateAwareRoot(el);
const childrenRoot = templateAwareRoot(el);
const children = childrenRoot ? getDOM().childNodes(childrenRoot) : [];
for (let j = 0; j < children.length; j++) {
result += stringifyElement(children[j]);
@ -174,6 +174,22 @@ export function isCommentNode(node: Node): boolean {
return node.nodeType === Node.COMMENT_NODE;
}
export function isTextNode(node: Node): boolean {
return node.nodeType === Node.TEXT_NODE;
}
export function getContent(node: Node): Node {
if ('content' in node) {
return (<any>node).content;
} else {
return node;
}
}
export function templateAwareRoot(el: Node): any {
return getDOM().isElementNode(el) && el.nodeName === 'TEMPLATE' ? getContent(el) : el;
}
export function setCookie(name: string, value: string) {
// document.cookie is magical, assigning into it assigns/overrides one cookie value, but does
// not clear other cookies.

View File

@ -10,7 +10,7 @@
import {Type, ɵglobal as global} from '@angular/core';
import {ComponentFixture} from '@angular/core/testing';
import {By, ɵgetDOM as getDOM} from '@angular/platform-browser';
import {isCommentNode} from '@angular/platform-browser/testing/src/browser_util';
import {isCommentNode} from './browser_util';
@ -292,7 +292,7 @@ function elementText(n: any): string {
return '';
}
if (getDOM().isElementNode(n) && getDOM().tagName(n) == 'CONTENT') {
if (getDOM().isElementNode(n) && (n as Element).tagName == 'CONTENT') {
return elementText(Array.prototype.slice.apply(getDOM().getDistributedNodes(n)));
}

View File

@ -79,7 +79,6 @@ export class DominoAdapter extends BrowserDomAdapter {
return DominoAdapter.defaultDoc;
}
isTextNode(node: any): boolean { return node.nodeType === DominoAdapter.defaultDoc.TEXT_NODE; }
isElementNode(node: any): boolean {
return node ? node.nodeType === DominoAdapter.defaultDoc.ELEMENT_NODE : false;
}

View File

@ -65,7 +65,6 @@ export class WorkerDomAdapter extends DomAdapter {
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'; }
@ -100,21 +99,16 @@ export class WorkerDomAdapter extends DomAdapter {
hasStyle(element: any, styleName: string, styleValue?: string): boolean {
throw 'not implemented';
}
tagName(element: any): string { throw 'not implemented'; }
hasAttribute(element: any, attribute: string): boolean { throw 'not implemented'; }
getAttribute(element: any, 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'; }
getDefaultDocument(): Document { throw 'not implemented'; }
getTitle(doc: Document): string { throw 'not implemented'; }
setTitle(doc: Document, newTitle: string) { throw 'not implemented'; }
elementMatches(n: any, selector: string): boolean { throw 'not implemented'; }
isTemplateElement(el: any): boolean { throw 'not implemented'; }
isTextNode(node: any): boolean { throw 'not implemented'; }
isElementNode(node: any): boolean { throw 'not implemented'; }
isShadowRoot(node: any): boolean { throw 'not implemented'; }
getEventKey(event: any): string { throw 'not implemented'; }