From cf4b944865c988e164cf29896d8aead3025dc3c9 Mon Sep 17 00:00:00 2001 From: Kara Erickson Date: Thu, 22 Aug 2019 19:48:08 -0700 Subject: [PATCH] refactor(core): remove misc dom utils from DomAdapters (#32278) PR Close #32278 --- aio/scripts/_payload-limits.json | 4 ++-- packages/core/test/application_ref_spec.ts | 4 ++-- packages/core/test/dom/dom_adapter_spec.ts | 7 +++--- .../change_detection_integration_spec.ts | 4 ++-- packages/core/test/linker/integration_spec.ts | 3 +-- .../linker/ng_container_integration_spec.ts | 6 ++--- .../linker/projection_integration_spec.ts | 4 ++-- .../linker/regression_integration_spec.ts | 2 +- .../test/linker/security_integration_spec.ts | 2 +- .../core/test/render3/imported_renderer2.ts | 4 ++-- .../src/dom_test_component_renderer.ts | 10 ++++++++- .../src/browser/browser_adapter.ts | 18 ++------------- .../platform-browser/src/dom/dom_adapter.ts | 14 +++++++----- .../testing/src/browser_util.ts | 22 ++++++++++++++++--- .../platform-browser/testing/src/matchers.ts | 4 ++-- .../platform-server/src/domino_adapter.ts | 1 - .../src/web_workers/worker/worker_adapter.ts | 6 ----- 17 files changed, 59 insertions(+), 56 deletions(-) diff --git a/aio/scripts/_payload-limits.json b/aio/scripts/_payload-limits.json index 37aff66168..ad9cc918ef 100755 --- a/aio/scripts/_payload-limits.json +++ b/aio/scripts/_payload-limits.json @@ -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 } diff --git a/packages/core/test/application_ref_spec.ts b/packages/core/test/application_ref_spec.ts index ba9589ccb5..943baf6b50 100644 --- a/packages/core/test/application_ref_spec.ts +++ b/packages/core/test/application_ref_spec.ts @@ -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 = getDOM().firstChild( - getDOM().content(getDOM().createTemplate(`<${selector}>`))); + getContent(getDOM().createTemplate(`<${selector}>`))); const oldRoots = getDOM().querySelectorAll(doc, selector); for (let i = 0; i < oldRoots.length; i++) { getDOM().remove(oldRoots[i]); diff --git a/packages/core/test/dom/dom_adapter_spec.ts b/packages/core/test/dom/dom_adapter_spec.ts index eaeaebe4e8..63e366b2d7 100644 --- a/packages/core/test/dom/dom_adapter_spec.ts +++ b/packages/core/test/dom/dom_adapter_spec.ts @@ -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'); diff --git a/packages/core/test/linker/change_detection_integration_spec.ts b/packages/core/test/linker/change_detection_integration_spec.ts index a6450ee57b..a2cc8f21b5 100644 --- a/packages/core/test/linker/change_detection_integration_spec.ts +++ b/packages/core/test/linker/change_detection_integration_spec.ts @@ -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); diff --git a/packages/core/test/linker/integration_spec.ts b/packages/core/test/linker/integration_spec.ts index ed47037bad..68ca936052 100644 --- a/packages/core/test/linker/integration_spec.ts +++ b/packages/core/test/linker/integration_spec.ts @@ -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', () => { diff --git a/packages/core/test/linker/ng_container_integration_spec.ts b/packages/core/test/linker/ng_container_integration_spec.ts index 2491c1b779..0c4f904aff 100644 --- a/packages/core/test/linker/ng_container_integration_spec.ts +++ b/packages/core/test/linker/ng_container_integration_spec.ts @@ -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 ') @@ -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(); diff --git a/packages/core/test/linker/projection_integration_spec.ts b/packages/core/test/linker/projection_integration_spec.ts index 25b97fbdb4..98ac4abd87 100644 --- a/packages/core/test/linker/projection_integration_spec.ts +++ b/packages/core/test/linker/projection_integration_spec.ts @@ -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(); } } diff --git a/packages/core/test/linker/regression_integration_spec.ts b/packages/core/test/linker/regression_integration_spec.ts index 85c472b201..98556e5ebf 100644 --- a/packages/core/test/linker/regression_integration_spec.ts +++ b/packages/core/test/linker/regression_integration_spec.ts @@ -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); }); }); } diff --git a/packages/core/test/linker/security_integration_spec.ts b/packages/core/test/linker/security_integration_spec.ts index 0e03177797..d2ed96e5fe 100644 --- a/packages/core/test/linker/security_integration_spec.ts +++ b/packages/core/test/linker/security_integration_spec.ts @@ -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); }); }); diff --git a/packages/core/test/render3/imported_renderer2.ts b/packages/core/test/render3/imported_renderer2.ts index 14ddcb19c3..d04587b35b 100644 --- a/packages/core/test/render3/imported_renderer2.ts +++ b/packages/core/test/render3/imported_renderer2.ts @@ -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); diff --git a/packages/platform-browser-dynamic/testing/src/dom_test_component_renderer.ts b/packages/platform-browser-dynamic/testing/src/dom_test_component_renderer.ts index c22a2abf2f..cecb67241b 100644 --- a/packages/platform-browser-dynamic/testing/src/dom_test_component_renderer.ts +++ b/packages/platform-browser-dynamic/testing/src/dom_test_component_renderer.ts @@ -20,7 +20,7 @@ export class DOMTestComponentRenderer extends TestComponentRenderer { insertRootElement(rootElId: string) { const rootEl = getDOM().firstChild( - getDOM().content(getDOM().createTemplate(`
`))); + getContent(getDOM().createTemplate(`
`))); // 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 (node).content; + } else { + return node; + } +} diff --git a/packages/platform-browser/src/browser/browser_adapter.ts b/packages/platform-browser/src/browser/browser_adapter.ts index 7fd6fdc15b..68f67d0435 100644 --- a/packages/platform-browser/src/browser/browser_adapter.ts +++ b/packages/platform-browser/src/browser/browser_adapter.ts @@ -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 (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; } diff --git a/packages/platform-browser/src/dom/dom_adapter.ts b/packages/platform-browser/src/dom/dom_adapter.ts index f4ffa806d6..fdda5991a4 100644 --- a/packages/platform-browser/src/dom/dom_adapter.ts +++ b/packages/platform-browser/src/dom/dom_adapter.ts @@ -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 diff --git a/packages/platform-browser/testing/src/browser_util.ts b/packages/platform-browser/testing/src/browser_util.ts index 384f6ee755..9336b78ea9 100644 --- a/packages/platform-browser/testing/src/browser_util.ts +++ b/packages/platform-browser/testing/src/browser_util.ts @@ -95,7 +95,7 @@ export function dispatchEvent(element: any, eventType: any): void { } export function el(html: string): HTMLElement { - return getDOM().firstChild(getDOM().content(getDOM().createTemplate(html))); + return 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 (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. diff --git a/packages/platform-browser/testing/src/matchers.ts b/packages/platform-browser/testing/src/matchers.ts index 7cb01216a0..f60e8c411d 100644 --- a/packages/platform-browser/testing/src/matchers.ts +++ b/packages/platform-browser/testing/src/matchers.ts @@ -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))); } diff --git a/packages/platform-server/src/domino_adapter.ts b/packages/platform-server/src/domino_adapter.ts index 582f974e2d..038994ed11 100644 --- a/packages/platform-server/src/domino_adapter.ts +++ b/packages/platform-server/src/domino_adapter.ts @@ -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; } diff --git a/packages/platform-webworker/src/web_workers/worker/worker_adapter.ts b/packages/platform-webworker/src/web_workers/worker/worker_adapter.ts index d082f026cc..4169438f13 100644 --- a/packages/platform-webworker/src/web_workers/worker/worker_adapter.ts +++ b/packages/platform-webworker/src/web_workers/worker/worker_adapter.ts @@ -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'; }