diff --git a/packages/core/test/linker/projection_integration_spec.ts b/packages/core/test/linker/projection_integration_spec.ts index 7af3b13c37..25b97fbdb4 100644 --- a/packages/core/test/linker/projection_integration_spec.ts +++ b/packages/core/test/linker/projection_integration_spec.ts @@ -491,7 +491,7 @@ describe('projection', () => { expect(main.nativeElement).toHaveText('TREE(0:TREE2(1:TREE(2:)))'); }); - if (getDOM().supportsNativeShadowDOM()) { + if (supportsNativeShadowDOM()) { it('should support native content projection and isolate styles per component', () => { TestBed.configureTestingModule({declarations: [SimpleNative1, SimpleNative2]}); TestBed.overrideComponent(MainComp, { @@ -1032,3 +1032,7 @@ class CmpA1 { }) class CmpA2 { } + +function supportsNativeShadowDOM(): boolean { + return typeof(document.body).createShadowRoot === 'function'; +} diff --git a/packages/platform-browser/src/browser/browser_adapter.ts b/packages/platform-browser/src/browser/browser_adapter.ts index 8ddc410d5d..7fd6fdc15b 100644 --- a/packages/platform-browser/src/browser/browser_adapter.ts +++ b/packages/platform-browser/src/browser/browser_adapter.ts @@ -198,8 +198,6 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter { doc = doc || this.getDefaultDocument(); return doc.createTextNode(text); } - createShadowRoot(el: HTMLElement): DocumentFragment { return (el).createShadowRoot(); } - getShadowRoot(el: HTMLElement): DocumentFragment { return (el).shadowRoot; } getHost(el: HTMLElement): HTMLElement { return (el).host; } clone(node: Node): Node { return node.cloneNode(true); } getElementsByTagName(element: any, name: string): HTMLElement[] { @@ -261,11 +259,8 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter { } isTextNode(node: Node): boolean { return node.nodeType === Node.TEXT_NODE; } isElementNode(node: Node): boolean { return node.nodeType === Node.ELEMENT_NODE; } - hasShadowRoot(node: any): boolean { - return node.shadowRoot != null && node instanceof HTMLElement; - } + isShadowRoot(node: any): boolean { return node instanceof DocumentFragment; } - getHref(el: Element): string { return el.getAttribute('href') !; } getEventKey(event: any): string { let key = event.key; diff --git a/packages/platform-browser/src/browser/generic_browser_adapter.ts b/packages/platform-browser/src/browser/generic_browser_adapter.ts index acd9039347..3b630f0d65 100644 --- a/packages/platform-browser/src/browser/generic_browser_adapter.ts +++ b/packages/platform-browser/src/browser/generic_browser_adapter.ts @@ -21,7 +21,4 @@ export abstract class GenericBrowserDomAdapter extends DomAdapter { getDistributedNodes(el: HTMLElement): Node[] { return (el).getDistributedNodes(); } supportsDOMEvents(): boolean { return true; } - supportsNativeShadowDOM(): boolean { - return typeof(document.body).createShadowRoot === 'function'; - } } diff --git a/packages/platform-browser/src/dom/dom_adapter.ts b/packages/platform-browser/src/dom/dom_adapter.ts index bd592ff141..f4ffa806d6 100644 --- a/packages/platform-browser/src/dom/dom_adapter.ts +++ b/packages/platform-browser/src/dom/dom_adapter.ts @@ -77,8 +77,6 @@ export abstract class DomAdapter { abstract createElement(tagName: any, doc?: any): HTMLElement; abstract createElementNS(ns: string, tagName: string, doc?: any): Element; abstract createTextNode(text: string, doc?: any): Text; - abstract createShadowRoot(el: any): any; - abstract getShadowRoot(el: any): any; abstract getHost(el: any): any; abstract getDistributedNodes(el: any): Node[]; abstract clone /**/ (node: Node /*T*/): Node /*T*/; @@ -107,13 +105,18 @@ export abstract class DomAdapter { abstract isTemplateElement(el: any): boolean; abstract isTextNode(node: any): boolean; abstract isElementNode(node: any): boolean; - abstract hasShadowRoot(node: any): boolean; + + // Used by Testability abstract isShadowRoot(node: any): boolean; - abstract getHref(element: any): string; + + // Used by KeyEventsPlugin abstract getEventKey(event: any): string; abstract supportsDOMEvents(): boolean; - abstract supportsNativeShadowDOM(): boolean; + + // Used by PlatformLocation and ServerEventManagerPlugin abstract getGlobalEventTarget(doc: Document, target: string): any; + + // Used by PlatformLocation abstract getHistory(): History; abstract getLocation(): Location; abstract getBaseHref(doc: Document): string|null; diff --git a/packages/platform-browser/testing/src/matchers.ts b/packages/platform-browser/testing/src/matchers.ts index 538a3147ac..7cb01216a0 100644 --- a/packages/platform-browser/testing/src/matchers.ts +++ b/packages/platform-browser/testing/src/matchers.ts @@ -16,6 +16,8 @@ import {isCommentNode} from '@angular/platform-browser/testing/src/browser_util' /** * Jasmine matchers that check Angular specific conditions. + * + * Note: These matchers will only work in a browser environment. */ export interface NgMatchers extends jasmine.Matchers { /** @@ -294,8 +296,8 @@ function elementText(n: any): string { return elementText(Array.prototype.slice.apply(getDOM().getDistributedNodes(n))); } - if (getDOM().hasShadowRoot(n)) { - return elementText(getDOM().childNodesAsList(getDOM().getShadowRoot(n))); + if (hasShadowRoot(n)) { + return elementText(getDOM().childNodesAsList((n).shadowRoot)); } if (hasNodes(n)) { @@ -304,3 +306,7 @@ function elementText(n: any): string { return getDOM().getText(n) !; } + +function hasShadowRoot(node: any): boolean { + return node.shadowRoot != null && node instanceof HTMLElement; +} diff --git a/packages/platform-server/src/domino_adapter.ts b/packages/platform-server/src/domino_adapter.ts index bb5313b815..582f974e2d 100644 --- a/packages/platform-server/src/domino_adapter.ts +++ b/packages/platform-server/src/domino_adapter.ts @@ -58,7 +58,6 @@ export class DominoAdapter extends BrowserDomAdapter { logGroupEnd() {} supportsDOMEvents(): boolean { return false; } - supportsNativeShadowDOM(): boolean { return false; } contains(nodeA: any, nodeB: any): boolean { let inner = nodeB; @@ -80,19 +79,11 @@ export class DominoAdapter extends BrowserDomAdapter { return DominoAdapter.defaultDoc; } - createShadowRoot(el: any, doc: Document = document): DocumentFragment { - el.shadowRoot = doc.createDocumentFragment(); - el.shadowRoot.parent = el; - return el.shadowRoot; - } - getShadowRoot(el: any): DocumentFragment { return el.shadowRoot; } - isTextNode(node: any): boolean { return node.nodeType === DominoAdapter.defaultDoc.TEXT_NODE; } isElementNode(node: any): boolean { return node ? node.nodeType === DominoAdapter.defaultDoc.ELEMENT_NODE : false; } - hasShadowRoot(node: any): boolean { return node.shadowRoot != null; } - isShadowRoot(node: any): boolean { return this.getShadowRoot(node) == node; } + isShadowRoot(node: any): boolean { return node.shadowRoot == node; } getProperty(el: Element, name: string): any { if (name === 'href') { @@ -135,7 +126,7 @@ export class DominoAdapter extends BrowserDomAdapter { const base = this.querySelector(doc.documentElement !, 'base'); let href = ''; if (base) { - href = this.getHref(base); + href = base.getAttribute('href') !; } // TODO(alxhub): Need relative path logic from BrowserDomAdapter here? return href; 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 25709b3ec8..d082f026cc 100644 --- a/packages/platform-webworker/src/web_workers/worker/worker_adapter.ts +++ b/packages/platform-webworker/src/web_workers/worker/worker_adapter.ts @@ -86,8 +86,6 @@ export class WorkerDomAdapter extends DomAdapter { 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'; } - 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'; } @@ -118,12 +116,9 @@ export class WorkerDomAdapter extends DomAdapter { isTemplateElement(el: any): boolean { throw 'not implemented'; } isTextNode(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'; } - getHref(element: any): string { throw 'not implemented'; } getEventKey(event: any): string { throw 'not implemented'; } supportsDOMEvents(): boolean { throw 'not implemented'; } - supportsNativeShadowDOM(): boolean { throw 'not implemented'; } getGlobalEventTarget(doc: Document, target: string): any { throw 'not implemented'; } getHistory(): History { throw 'not implemented'; } getLocation(): Location { throw 'not implemented'; }