2016-06-23 09:47:54 -07:00
|
|
|
/**
|
|
|
|
* @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
|
|
|
|
*/
|
|
|
|
|
2019-08-22 19:16:25 -07:00
|
|
|
import {ɵparseCookieValue as parseCookieValue, ɵsetRootDomAdapter as setRootDomAdapter} from '@angular/common';
|
2017-03-01 15:18:10 -08:00
|
|
|
import {ɵglobal as global} from '@angular/core';
|
2017-07-13 17:22:02 -07:00
|
|
|
|
2015-05-12 11:19:47 -07:00
|
|
|
import {GenericBrowserDomAdapter} from './generic_browser_adapter';
|
|
|
|
|
2019-06-13 20:14:00 +02:00
|
|
|
const nodeContains: (this: Node, other: Node) => boolean = (() => {
|
2019-05-02 16:44:24 +01:00
|
|
|
if (global['Node']) {
|
2019-06-13 20:14:00 +02:00
|
|
|
return global['Node'].prototype.contains || function(this: Node, node: any) {
|
2019-05-02 16:44:24 +01:00
|
|
|
return !!(this.compareDocumentPosition(node) & 16);
|
|
|
|
};
|
|
|
|
}
|
2017-03-14 17:15:46 -07:00
|
|
|
|
2019-05-02 16:44:24 +01:00
|
|
|
return undefined as any;
|
|
|
|
})();
|
2017-03-14 17:15:46 -07:00
|
|
|
|
2015-12-03 15:49:09 -08:00
|
|
|
/**
|
|
|
|
* A `DomAdapter` powered by full browser DOM APIs.
|
2016-08-17 13:42:18 -07:00
|
|
|
*
|
|
|
|
* @security Tread carefully! Interacting with the DOM directly is dangerous and
|
|
|
|
* can introduce XSS risks.
|
2015-12-03 15:49:09 -08:00
|
|
|
*/
|
2016-12-21 03:18:24 +03:00
|
|
|
/* tslint:disable:requireParameterType no-console */
|
2015-05-12 11:19:47 -07:00
|
|
|
export class BrowserDomAdapter extends GenericBrowserDomAdapter {
|
2020-04-13 16:40:21 -07:00
|
|
|
static makeCurrent() {
|
|
|
|
setRootDomAdapter(new BrowserDomAdapter());
|
|
|
|
}
|
|
|
|
getProperty(el: Node, name: string): any {
|
|
|
|
return (<any>el)[name];
|
|
|
|
}
|
2015-05-12 11:19:47 -07:00
|
|
|
|
2016-11-11 21:46:53 +03:00
|
|
|
log(error: string): void {
|
|
|
|
if (window.console) {
|
|
|
|
window.console.log && window.console.log(error);
|
|
|
|
}
|
|
|
|
}
|
2015-07-23 18:00:19 -07:00
|
|
|
|
2016-11-11 21:46:53 +03:00
|
|
|
logGroup(error: string): void {
|
|
|
|
if (window.console) {
|
|
|
|
window.console.group && window.console.group(error);
|
|
|
|
}
|
2015-07-23 18:00:19 -07:00
|
|
|
}
|
|
|
|
|
2016-11-11 21:46:53 +03:00
|
|
|
logGroupEnd(): void {
|
|
|
|
if (window.console) {
|
|
|
|
window.console.groupEnd && window.console.groupEnd();
|
|
|
|
}
|
|
|
|
}
|
2015-07-23 18:00:19 -07:00
|
|
|
|
2016-09-27 17:30:26 -07:00
|
|
|
onAndCancel(el: Node, evt: any, listener: any): Function {
|
2015-05-12 11:19:47 -07:00
|
|
|
el.addEventListener(evt, listener, false);
|
|
|
|
// Needed to follow Dart's subscription semantic, until fix of
|
|
|
|
// https://code.google.com/p/dart/issues/detail?id=17406
|
2020-04-13 16:40:21 -07:00
|
|
|
return () => {
|
|
|
|
el.removeEventListener(evt, listener, false);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
dispatchEvent(el: Node, evt: any) {
|
|
|
|
el.dispatchEvent(evt);
|
2015-05-12 11:19:47 -07:00
|
|
|
}
|
2016-09-27 17:30:26 -07:00
|
|
|
remove(node: Node): Node {
|
2015-09-25 09:43:21 -07:00
|
|
|
if (node.parentNode) {
|
|
|
|
node.parentNode.removeChild(node);
|
|
|
|
}
|
2015-06-24 13:46:39 -07:00
|
|
|
return node;
|
2015-05-21 16:42:19 +02:00
|
|
|
}
|
2020-04-13 16:40:21 -07:00
|
|
|
getValue(el: any): string {
|
|
|
|
return el.value;
|
|
|
|
}
|
2017-08-08 02:17:40 -07:00
|
|
|
createElement(tagName: string, doc?: Document): HTMLElement {
|
|
|
|
doc = doc || this.getDefaultDocument();
|
|
|
|
return doc.createElement(tagName);
|
|
|
|
}
|
2015-06-26 11:10:52 -07:00
|
|
|
createHtmlDocument(): HTMLDocument {
|
|
|
|
return document.implementation.createHTMLDocument('fakeTitle');
|
|
|
|
}
|
2020-04-13 16:40:21 -07:00
|
|
|
getDefaultDocument(): Document {
|
|
|
|
return document;
|
|
|
|
}
|
2019-08-22 19:48:08 -07:00
|
|
|
|
2020-04-13 16:40:21 -07:00
|
|
|
isElementNode(node: Node): boolean {
|
|
|
|
return node.nodeType === Node.ELEMENT_NODE;
|
|
|
|
}
|
2019-08-22 18:26:01 -07:00
|
|
|
|
2020-04-13 16:40:21 -07:00
|
|
|
isShadowRoot(node: any): boolean {
|
|
|
|
return node instanceof DocumentFragment;
|
|
|
|
}
|
2016-10-28 19:53:42 -07:00
|
|
|
|
2017-03-24 09:59:41 -07:00
|
|
|
getGlobalEventTarget(doc: Document, target: string): EventTarget|null {
|
2016-09-27 17:30:26 -07:00
|
|
|
if (target === 'window') {
|
2015-05-21 16:42:19 +02:00
|
|
|
return window;
|
2016-09-27 17:30:26 -07:00
|
|
|
}
|
|
|
|
if (target === 'document') {
|
2017-08-08 02:17:40 -07:00
|
|
|
return doc;
|
2016-09-27 17:30:26 -07:00
|
|
|
}
|
|
|
|
if (target === 'body') {
|
2017-08-08 02:17:40 -07:00
|
|
|
return doc.body;
|
2015-05-21 16:42:19 +02:00
|
|
|
}
|
2017-03-24 09:59:41 -07:00
|
|
|
return null;
|
2015-05-21 16:42:19 +02:00
|
|
|
}
|
2020-04-13 16:40:21 -07:00
|
|
|
getHistory(): History {
|
|
|
|
return window.history;
|
|
|
|
}
|
|
|
|
getLocation(): Location {
|
|
|
|
return window.location;
|
|
|
|
}
|
2017-03-24 09:59:41 -07:00
|
|
|
getBaseHref(doc: Document): string|null {
|
2016-09-27 17:30:26 -07:00
|
|
|
const href = getBaseElementHref();
|
2017-03-02 09:37:01 -08:00
|
|
|
return href == null ? null : relativePath(href);
|
2015-07-17 12:13:20 -07:00
|
|
|
}
|
2020-04-13 16:40:21 -07:00
|
|
|
resetBaseElement(): void {
|
|
|
|
baseElement = null;
|
|
|
|
}
|
|
|
|
getUserAgent(): string {
|
|
|
|
return window.navigator.userAgent;
|
|
|
|
}
|
2015-09-09 12:23:04 +02:00
|
|
|
performanceNow(): number {
|
|
|
|
// performance.now() is not available in all browsers, see
|
|
|
|
// http://caniuse.com/#search=performance.now
|
2016-09-27 17:30:26 -07:00
|
|
|
return window.performance && window.performance.now ? window.performance.now() :
|
|
|
|
new Date().getTime();
|
2015-09-09 12:23:04 +02:00
|
|
|
}
|
2016-05-27 20:15:40 -07:00
|
|
|
|
2020-04-13 16:40:21 -07:00
|
|
|
supportsCookies(): boolean {
|
|
|
|
return true;
|
|
|
|
}
|
2016-05-27 20:15:40 -07:00
|
|
|
|
2020-04-13 16:40:21 -07:00
|
|
|
getCookie(name: string): string|null {
|
|
|
|
return parseCookieValue(document.cookie, name);
|
|
|
|
}
|
2015-05-12 11:19:47 -07:00
|
|
|
}
|
|
|
|
|
2017-03-24 09:59:41 -07:00
|
|
|
let baseElement: HTMLElement|null = null;
|
|
|
|
function getBaseElementHref(): string|null {
|
2016-09-27 17:30:26 -07:00
|
|
|
if (!baseElement) {
|
2020-04-13 16:40:21 -07:00
|
|
|
baseElement = document.querySelector('base')!;
|
2016-09-27 17:30:26 -07:00
|
|
|
if (!baseElement) {
|
2015-07-17 12:13:20 -07:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
2015-08-11 22:17:39 -07:00
|
|
|
return baseElement.getAttribute('href');
|
2015-07-17 12:13:20 -07:00
|
|
|
}
|
|
|
|
|
2015-05-12 11:19:47 -07:00
|
|
|
// based on urlUtils.js in AngularJS 1
|
2016-09-27 17:30:26 -07:00
|
|
|
let urlParsingNode: any;
|
|
|
|
function relativePath(url: any): string {
|
|
|
|
if (!urlParsingNode) {
|
2016-06-08 16:38:52 -07:00
|
|
|
urlParsingNode = document.createElement('a');
|
2015-05-12 11:19:47 -07:00
|
|
|
}
|
|
|
|
urlParsingNode.setAttribute('href', url);
|
|
|
|
return (urlParsingNode.pathname.charAt(0) === '/') ? urlParsingNode.pathname :
|
|
|
|
'/' + urlParsingNode.pathname;
|
|
|
|
}
|