perf(common): remove unused methods from DomAdapter (#41102)
The `DomAdapter` is present in all Angular apps and its methods aren't tree shakeable. These changes remove the methods that either aren't being used anymore or were only used by our own tests. Note that these changes aren't breaking, because the adapter is an internal API. The following methods were removed: * `getProperty` - only used within our own tests. * `log` - Guaranteed to be defined on `console`. * `logGroup` and `logGroupEnd` - Only used in one place. It was in the DomAdapter for built-in null checking. * `logGroupEnd` - Only used in one place. It was placed in the DomAdapter for built in null checking. * `performanceNow` - Only used in one place that has to be invoked through the browser console. * `supportsCookies` - Unused. * `getCookie` - Unused. * `getLocation` and `getHistory` - Only used in one place which appears to have access to the DOM already, because it had direct accesses to `window`. Furthermore, even if this was being used in a non-browser context already, the `DominoAdapter` was set up to throw an error. The following APIs were changed to be more compact: * `supportsDOMEvents` - Changed to a readonly property. * `remove` - No longer returns the removed node. PR Close #41102
This commit is contained in:
parent
4c79b8a644
commit
3c66b100dd
|
@ -3,7 +3,7 @@
|
||||||
"master": {
|
"master": {
|
||||||
"uncompressed": {
|
"uncompressed": {
|
||||||
"runtime-es2015": 1485,
|
"runtime-es2015": 1485,
|
||||||
"main-es2015": 138937,
|
"main-es2015": 138189,
|
||||||
"polyfills-es2015": 36964
|
"polyfills-es2015": 36964
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
"master": {
|
"master": {
|
||||||
"uncompressed": {
|
"uncompressed": {
|
||||||
"runtime-es2015": 1485,
|
"runtime-es2015": 1485,
|
||||||
"main-es2015": 144899,
|
"main-es2015": 144151,
|
||||||
"polyfills-es2015": 36964
|
"polyfills-es2015": 36964
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
"master": {
|
"master": {
|
||||||
"uncompressed": {
|
"uncompressed": {
|
||||||
"runtime-es2015": 1485,
|
"runtime-es2015": 1485,
|
||||||
"main-es2015": 137236,
|
"main-es2015": 136546,
|
||||||
"polyfills-es2015": 37641
|
"polyfills-es2015": 37641
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
"master": {
|
"master": {
|
||||||
"uncompressed": {
|
"uncompressed": {
|
||||||
"runtime-es2015": 2285,
|
"runtime-es2015": 2285,
|
||||||
"main-es2015": 241085,
|
"main-es2015": 240352,
|
||||||
"polyfills-es2015": 36975,
|
"polyfills-es2015": 36975,
|
||||||
"5-es2015": 753
|
"5-es2015": 753
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
"master": {
|
"master": {
|
||||||
"uncompressed": {
|
"uncompressed": {
|
||||||
"runtime-es2015": 2289,
|
"runtime-es2015": 2289,
|
||||||
"main-es2015": 216925,
|
"main-es2015": 216267,
|
||||||
"polyfills-es2015": 36723,
|
"polyfills-es2015": 36723,
|
||||||
"5-es2015": 781
|
"5-es2015": 781
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
"master": {
|
"master": {
|
||||||
"uncompressed": {
|
"uncompressed": {
|
||||||
"runtime-es2015": 1485,
|
"runtime-es2015": 1485,
|
||||||
"main-es2015": 169047,
|
"main-es2015": 168534,
|
||||||
"polyfills-es2015": 36975
|
"polyfills-es2015": 36975
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,16 +31,11 @@ export function setRootDomAdapter(adapter: DomAdapter) {
|
||||||
*/
|
*/
|
||||||
export abstract class DomAdapter {
|
export abstract class DomAdapter {
|
||||||
// Needs Domino-friendly test utility
|
// Needs Domino-friendly test utility
|
||||||
abstract getProperty(el: Element, name: string): any;
|
|
||||||
abstract dispatchEvent(el: any, evt: any): any;
|
abstract dispatchEvent(el: any, evt: any): any;
|
||||||
|
abstract readonly supportsDOMEvents: boolean;
|
||||||
// Used by router
|
|
||||||
abstract log(error: any): any;
|
|
||||||
abstract logGroup(error: any): any;
|
|
||||||
abstract logGroupEnd(): any;
|
|
||||||
|
|
||||||
// Used by Meta
|
// Used by Meta
|
||||||
abstract remove(el: any): Node;
|
abstract remove(el: any): void;
|
||||||
abstract createElement(tagName: any, doc?: any): HTMLElement;
|
abstract createElement(tagName: any, doc?: any): HTMLElement;
|
||||||
abstract createHtmlDocument(): HTMLDocument;
|
abstract createHtmlDocument(): HTMLDocument;
|
||||||
abstract getDefaultDocument(): Document;
|
abstract getDefaultDocument(): Document;
|
||||||
|
@ -53,25 +48,17 @@ export abstract class DomAdapter {
|
||||||
|
|
||||||
// Used by KeyEventsPlugin
|
// Used by KeyEventsPlugin
|
||||||
abstract onAndCancel(el: any, evt: any, listener: any): Function;
|
abstract onAndCancel(el: any, evt: any, listener: any): Function;
|
||||||
abstract supportsDOMEvents(): boolean;
|
|
||||||
|
|
||||||
// Used by PlatformLocation and ServerEventManagerPlugin
|
// Used by PlatformLocation and ServerEventManagerPlugin
|
||||||
abstract getGlobalEventTarget(doc: Document, target: string): any;
|
abstract getGlobalEventTarget(doc: Document, target: string): any;
|
||||||
|
|
||||||
// Used by PlatformLocation
|
// Used by PlatformLocation
|
||||||
abstract getHistory(): History;
|
|
||||||
abstract getLocation():
|
|
||||||
any; /** This is the ambient Location definition, NOT Location from @angular/common. */
|
|
||||||
abstract getBaseHref(doc: Document): string|null;
|
abstract getBaseHref(doc: Document): string|null;
|
||||||
abstract resetBaseElement(): void;
|
abstract resetBaseElement(): void;
|
||||||
|
|
||||||
// TODO: remove dependency in DefaultValueAccessor
|
// TODO: remove dependency in DefaultValueAccessor
|
||||||
abstract getUserAgent(): string;
|
abstract getUserAgent(): string;
|
||||||
|
|
||||||
// Used by AngularProfiler
|
// Used in the legacy @angular/http package which has some usage in g3.
|
||||||
abstract performanceNow(): number;
|
|
||||||
|
|
||||||
// Used by CookieXSRFStrategy
|
|
||||||
abstract supportsCookies(): boolean;
|
|
||||||
abstract getCookie(name: string): string|null;
|
abstract getCookie(name: string): string|null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,8 +120,8 @@ export class BrowserPlatformLocation extends PlatformLocation {
|
||||||
// This is moved to its own method so that `MockPlatformLocationStrategy` can overwrite it
|
// This is moved to its own method so that `MockPlatformLocationStrategy` can overwrite it
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_init() {
|
_init() {
|
||||||
(this as {location: Location}).location = getDOM().getLocation();
|
(this as {location: Location}).location = window.location;
|
||||||
this._history = getDOM().getHistory();
|
this._history = window.history;
|
||||||
}
|
}
|
||||||
|
|
||||||
getBaseHrefFromDOM(): string {
|
getBaseHrefFromDOM(): string {
|
||||||
|
|
|
@ -59,7 +59,7 @@ class SomeComponent {
|
||||||
const errorHandler = new ErrorHandler();
|
const errorHandler = new ErrorHandler();
|
||||||
(errorHandler as any)._console = mockConsole as any;
|
(errorHandler as any)._console = mockConsole as any;
|
||||||
|
|
||||||
const platformModule = getDOM().supportsDOMEvents() ?
|
const platformModule = getDOM().supportsDOMEvents ?
|
||||||
BrowserModule :
|
BrowserModule :
|
||||||
require('@angular/platform-server').ServerModule;
|
require('@angular/platform-server').ServerModule;
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ import {isTextNode} from '@angular/platform-browser/testing/src/browser_util';
|
||||||
describe('dom adapter', () => {
|
describe('dom adapter', () => {
|
||||||
let defaultDoc: any;
|
let defaultDoc: any;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
defaultDoc = getDOM().supportsDOMEvents() ? document : getDOM().createHtmlDocument();
|
defaultDoc = getDOM().supportsDOMEvents ? document : getDOM().createHtmlDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to create text nodes and use them with the other APIs', () => {
|
it('should be able to create text nodes and use them with the other APIs', () => {
|
||||||
|
@ -36,7 +36,7 @@ import {isTextNode} from '@angular/platform-browser/testing/src/browser_util';
|
||||||
expect(() => getDOM().remove(d)).not.toThrow();
|
expect(() => getDOM().remove(d)).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (getDOM().supportsDOMEvents()) {
|
if (getDOM().supportsDOMEvents) {
|
||||||
describe('getBaseHref', () => {
|
describe('getBaseHref', () => {
|
||||||
beforeEach(() => getDOM().resetBaseElement());
|
beforeEach(() => getDOM().resetBaseElement());
|
||||||
|
|
||||||
|
|
|
@ -109,8 +109,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
fixture.componentInstance.ctxProp = 'Hello World!';
|
fixture.componentInstance.ctxProp = 'Hello World!';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
expect(getDOM().getProperty(fixture.debugElement.children[0].nativeElement, 'id'))
|
expect(fixture.debugElement.children[0].nativeElement.id).toEqual('Hello World!');
|
||||||
.toEqual('Hello World!');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should consume binding to aria-* attributes', () => {
|
it('should consume binding to aria-* attributes', () => {
|
||||||
|
@ -168,13 +167,11 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
const fixture = TestBed.createComponent(MyComp);
|
const fixture = TestBed.createComponent(MyComp);
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(getDOM().getProperty(fixture.debugElement.children[0].nativeElement, 'tabIndex'))
|
expect(fixture.debugElement.children[0].nativeElement.tabIndex).toEqual(0);
|
||||||
.toEqual(0);
|
|
||||||
|
|
||||||
fixture.componentInstance.ctxNumProp = 5;
|
fixture.componentInstance.ctxNumProp = 5;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(getDOM().getProperty(fixture.debugElement.children[0].nativeElement, 'tabIndex'))
|
expect(fixture.debugElement.children[0].nativeElement.tabIndex).toEqual(5);
|
||||||
.toEqual(5);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should consume binding to camel-cased properties', () => {
|
it('should consume binding to camel-cased properties', () => {
|
||||||
|
@ -184,13 +181,11 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
const fixture = TestBed.createComponent(MyComp);
|
const fixture = TestBed.createComponent(MyComp);
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(getDOM().getProperty(fixture.debugElement.children[0].nativeElement, 'readOnly'))
|
expect(fixture.debugElement.children[0].nativeElement.readOnly).toBeFalsy();
|
||||||
.toBeFalsy();
|
|
||||||
|
|
||||||
fixture.componentInstance.ctxBoolProp = true;
|
fixture.componentInstance.ctxBoolProp = true;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(getDOM().getProperty(fixture.debugElement.children[0].nativeElement, 'readOnly'))
|
expect(fixture.debugElement.children[0].nativeElement.readOnly).toBeTruthy();
|
||||||
.toBeTruthy();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should consume binding to innerHtml', () => {
|
it('should consume binding to innerHtml', () => {
|
||||||
|
@ -236,7 +231,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
fixture.debugElement.componentInstance.ctxProp = 'foo';
|
fixture.debugElement.componentInstance.ctxProp = 'foo';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
expect(getDOM().getProperty(nativeEl, 'htmlFor')).toBe('foo');
|
expect(nativeEl.htmlFor).toBe('foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should consume directive watch expression change.', () => {
|
it('should consume directive watch expression change.', () => {
|
||||||
|
@ -617,7 +612,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
expect(cmp.numberOfChecks).toEqual(2);
|
expect(cmp.numberOfChecks).toEqual(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (getDOM().supportsDOMEvents()) {
|
if (getDOM().supportsDOMEvents) {
|
||||||
it('should allow to destroy a component from within a host event handler',
|
it('should allow to destroy a component from within a host event handler',
|
||||||
fakeAsync(() => {
|
fakeAsync(() => {
|
||||||
TestBed.configureTestingModule({declarations: [MyComp, [[PushCmpWithHostEvent]]]});
|
TestBed.configureTestingModule({declarations: [MyComp, [[PushCmpWithHostEvent]]]});
|
||||||
|
@ -922,7 +917,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
expect(getDOM().getProperty(tc.nativeElement, 'id')).toEqual('newId');
|
expect(tc.nativeElement.id).toEqual('newId');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not use template variables for expressions in hostProperties', () => {
|
it('should not use template variables for expressions in hostProperties', () => {
|
||||||
|
@ -996,7 +991,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (getDOM().supportsDOMEvents()) {
|
if (getDOM().supportsDOMEvents) {
|
||||||
it('should support preventing default on render events', () => {
|
it('should support preventing default on render events', () => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations:
|
declarations:
|
||||||
|
@ -1881,7 +1876,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
const el = fixture.nativeElement.querySelector('span');
|
const el = fixture.nativeElement.querySelector('span');
|
||||||
expect(getDOM().getProperty(el, 'title')).toEqual('TITLE');
|
expect(el.title).toEqual('TITLE');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2097,7 +2092,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
expect(fixture.debugElement.children[0].nativeElement.outerHTML).toContain('my-attr="aaa"');
|
expect(fixture.debugElement.children[0].nativeElement.outerHTML).toContain('my-attr="aaa"');
|
||||||
});
|
});
|
||||||
|
|
||||||
if (getDOM().supportsDOMEvents()) {
|
if (getDOM().supportsDOMEvents) {
|
||||||
it('should support event decorators', fakeAsync(() => {
|
it('should support event decorators', fakeAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [MyComp, DirectiveWithPropDecorators],
|
declarations: [MyComp, DirectiveWithPropDecorators],
|
||||||
|
@ -2200,7 +2195,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (getDOM().supportsDOMEvents()) {
|
if (getDOM().supportsDOMEvents) {
|
||||||
describe('svg', () => {
|
describe('svg', () => {
|
||||||
it('should support svg elements', () => {
|
it('should support svg elements', () => {
|
||||||
TestBed.configureTestingModule({declarations: [MyComp]});
|
TestBed.configureTestingModule({declarations: [MyComp]});
|
||||||
|
@ -2211,12 +2206,10 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
const el = fixture.nativeElement;
|
const el = fixture.nativeElement;
|
||||||
const svg = el.childNodes[0];
|
const svg = el.childNodes[0];
|
||||||
const use = svg.childNodes[0];
|
const use = svg.childNodes[0];
|
||||||
expect(getDOM().getProperty(<Element>svg, 'namespaceURI'))
|
expect(svg.namespaceURI).toEqual('http://www.w3.org/2000/svg');
|
||||||
.toEqual('http://www.w3.org/2000/svg');
|
expect(use.namespaceURI).toEqual('http://www.w3.org/2000/svg');
|
||||||
expect(getDOM().getProperty(<Element>use, 'namespaceURI'))
|
|
||||||
.toEqual('http://www.w3.org/2000/svg');
|
|
||||||
|
|
||||||
const firstAttribute = getDOM().getProperty(<Element>use, 'attributes')[0];
|
const firstAttribute = use.attributes[0];
|
||||||
expect(firstAttribute.name).toEqual('xlink:href');
|
expect(firstAttribute.name).toEqual('xlink:href');
|
||||||
expect(firstAttribute.namespaceURI).toEqual('http://www.w3.org/1999/xlink');
|
expect(firstAttribute.namespaceURI).toEqual('http://www.w3.org/1999/xlink');
|
||||||
});
|
});
|
||||||
|
@ -2232,12 +2225,9 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
const svg = el.childNodes[0];
|
const svg = el.childNodes[0];
|
||||||
const foreignObject = svg.childNodes[0];
|
const foreignObject = svg.childNodes[0];
|
||||||
const p = foreignObject.childNodes[0];
|
const p = foreignObject.childNodes[0];
|
||||||
expect(getDOM().getProperty(<Element>svg, 'namespaceURI'))
|
expect(svg.namespaceURI).toEqual('http://www.w3.org/2000/svg');
|
||||||
.toEqual('http://www.w3.org/2000/svg');
|
expect(foreignObject.namespaceURI).toEqual('http://www.w3.org/2000/svg');
|
||||||
expect(getDOM().getProperty(<Element>foreignObject, 'namespaceURI'))
|
expect(p.namespaceURI).toEqual('http://www.w3.org/1999/xhtml');
|
||||||
.toEqual('http://www.w3.org/2000/svg');
|
|
||||||
expect(getDOM().getProperty(<Element>p, 'namespaceURI'))
|
|
||||||
.toEqual('http://www.w3.org/1999/xhtml');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -508,7 +508,7 @@ describe('projection', () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getDOM().supportsDOMEvents()) {
|
if (getDOM().supportsDOMEvents) {
|
||||||
it('should support non emulated styles', () => {
|
it('should support non emulated styles', () => {
|
||||||
TestBed.configureTestingModule({declarations: [OtherComp]});
|
TestBed.configureTestingModule({declarations: [OtherComp]});
|
||||||
TestBed.overrideComponent(MainComp, {
|
TestBed.overrideComponent(MainComp, {
|
||||||
|
|
|
@ -156,7 +156,7 @@ import {beforeEach, describe, expect, it} from '@angular/core/testing/src/testin
|
||||||
expect(data.length).toBe(0);
|
expect(data.length).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (getDOM().supportsDOMEvents()) {
|
if (getDOM().supportsDOMEvents) {
|
||||||
describe('simple observable interface', () => {
|
describe('simple observable interface', () => {
|
||||||
it('should fire callbacks on change', fakeAsync(() => {
|
it('should fire callbacks on change', fakeAsync(() => {
|
||||||
let fires = 0;
|
let fires = 0;
|
||||||
|
|
|
@ -462,7 +462,7 @@ function declareTestsUsingBootstrap() {
|
||||||
destroyPlatform();
|
destroyPlatform();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (getDOM().supportsDOMEvents()) {
|
if (getDOM().supportsDOMEvents) {
|
||||||
// This test needs a real DOM....
|
// This test needs a real DOM....
|
||||||
|
|
||||||
it('should keep change detecting if there was an error', (done) => {
|
it('should keep change detecting if there was an error', (done) => {
|
||||||
|
|
|
@ -49,13 +49,9 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
let originalLog: (msg: any) => any;
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
originalLog = getDOM().log;
|
// Disable logging for these tests.
|
||||||
getDOM().log = (msg) => { /* disable logging */ };
|
spyOn(console, 'log').and.callFake(() => {});
|
||||||
});
|
|
||||||
afterEach(() => {
|
|
||||||
getDOM().log = originalLog;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('events', () => {
|
describe('events', () => {
|
||||||
|
@ -128,7 +124,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
cmp.detectChanges();
|
cmp.detectChanges();
|
||||||
const div = cmp.debugElement.children[0];
|
const div = cmp.debugElement.children[0];
|
||||||
expect(div.injector.get(OnPrefixDir).onclick).toBe(value);
|
expect(div.injector.get(OnPrefixDir).onclick).toBe(value);
|
||||||
expect(getDOM().getProperty(div.nativeElement, 'onclick')).not.toBe(value);
|
expect(div.nativeElement.onclick).not.toBe(value);
|
||||||
expect(div.nativeElement.hasAttribute('onclick')).toEqual(false);
|
expect(div.nativeElement.hasAttribute('onclick')).toEqual(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -145,7 +141,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
const trusted = sanitizer.bypassSecurityTrustUrl('javascript:alert(1)');
|
const trusted = sanitizer.bypassSecurityTrustUrl('javascript:alert(1)');
|
||||||
ci.ctxProp = trusted;
|
ci.ctxProp = trusted;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(getDOM().getProperty(e, 'href')).toEqual('javascript:alert(1)');
|
expect(e.getAttribute('href')).toEqual('javascript:alert(1)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error when using the wrong trusted value', () => {
|
it('should error when using the wrong trusted value', () => {
|
||||||
|
@ -171,25 +167,21 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
const ci = fixture.componentInstance;
|
const ci = fixture.componentInstance;
|
||||||
ci.ctxProp = trusted;
|
ci.ctxProp = trusted;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(getDOM().getProperty(e, 'href')).toMatch(/SafeValue(%20| )must(%20| )use/);
|
expect(e.href).toMatch(/SafeValue(%20| )must(%20| )use/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('sanitizing', () => {
|
describe('sanitizing', () => {
|
||||||
function checkEscapeOfHrefProperty(fixture: ComponentFixture<any>, isAttribute: boolean) {
|
function checkEscapeOfHrefProperty(fixture: ComponentFixture<any>) {
|
||||||
const e = fixture.debugElement.children[0].nativeElement;
|
const e = fixture.debugElement.children[0].nativeElement;
|
||||||
const ci = fixture.componentInstance;
|
const ci = fixture.componentInstance;
|
||||||
ci.ctxProp = 'hello';
|
ci.ctxProp = 'hello';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
// In the browser, reading href returns an absolute URL. On the server side,
|
expect(e.getAttribute('href')).toMatch(/.*\/?hello$/);
|
||||||
// it just echoes back the property.
|
|
||||||
let value = isAttribute ? e.getAttribute('href') : getDOM().getProperty(e, 'href');
|
|
||||||
expect(value).toMatch(/.*\/?hello$/);
|
|
||||||
|
|
||||||
ci.ctxProp = 'javascript:alert(1)';
|
ci.ctxProp = 'javascript:alert(1)';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
value = isAttribute ? e.getAttribute('href') : getDOM().getProperty(e, 'href');
|
expect(e.getAttribute('href')).toEqual('unsafe:javascript:alert(1)');
|
||||||
expect(value).toEqual('unsafe:javascript:alert(1)');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should escape unsafe properties', () => {
|
it('should escape unsafe properties', () => {
|
||||||
|
@ -197,7 +189,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
TestBed.overrideComponent(SecuredComponent, {set: {template}});
|
TestBed.overrideComponent(SecuredComponent, {set: {template}});
|
||||||
const fixture = TestBed.createComponent(SecuredComponent);
|
const fixture = TestBed.createComponent(SecuredComponent);
|
||||||
|
|
||||||
checkEscapeOfHrefProperty(fixture, false);
|
checkEscapeOfHrefProperty(fixture);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should escape unsafe attributes', () => {
|
it('should escape unsafe attributes', () => {
|
||||||
|
@ -205,7 +197,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
TestBed.overrideComponent(SecuredComponent, {set: {template}});
|
TestBed.overrideComponent(SecuredComponent, {set: {template}});
|
||||||
const fixture = TestBed.createComponent(SecuredComponent);
|
const fixture = TestBed.createComponent(SecuredComponent);
|
||||||
|
|
||||||
checkEscapeOfHrefProperty(fixture, true);
|
checkEscapeOfHrefProperty(fixture);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should escape unsafe properties if they are used in host bindings', () => {
|
it('should escape unsafe properties if they are used in host bindings', () => {
|
||||||
|
@ -220,7 +212,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
TestBed.overrideComponent(SecuredComponent, {set: {template}});
|
TestBed.overrideComponent(SecuredComponent, {set: {template}});
|
||||||
const fixture = TestBed.createComponent(SecuredComponent);
|
const fixture = TestBed.createComponent(SecuredComponent);
|
||||||
|
|
||||||
checkEscapeOfHrefProperty(fixture, false);
|
checkEscapeOfHrefProperty(fixture);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should escape unsafe attributes if they are used in host bindings', () => {
|
it('should escape unsafe attributes if they are used in host bindings', () => {
|
||||||
|
@ -235,7 +227,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
TestBed.overrideComponent(SecuredComponent, {set: {template}});
|
TestBed.overrideComponent(SecuredComponent, {set: {template}});
|
||||||
const fixture = TestBed.createComponent(SecuredComponent);
|
const fixture = TestBed.createComponent(SecuredComponent);
|
||||||
|
|
||||||
checkEscapeOfHrefProperty(fixture, true);
|
checkEscapeOfHrefProperty(fixture);
|
||||||
});
|
});
|
||||||
|
|
||||||
modifiedInIvy('Unknown property error thrown during update mode, not creation mode')
|
modifiedInIvy('Unknown property error thrown during update mode, not creation mode')
|
||||||
|
|
|
@ -87,8 +87,8 @@ const removeEventListener = 'removeEventListener';
|
||||||
Services.checkAndUpdateView(view);
|
Services.checkAndUpdateView(view);
|
||||||
|
|
||||||
const el = rootNodes[0];
|
const el = rootNodes[0];
|
||||||
expect(getDOM().getProperty(el, 'title')).toBe('v1');
|
expect(el.title).toBe('v1');
|
||||||
expect(getDOM().getProperty(el, 'value')).toBe('v2');
|
expect(el.value).toBe('v2');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {ArgumentType, initServicesIfNeeded, NodeCheckFn, NodeDef, rootRenderNode
|
||||||
import {TestBed} from '@angular/core/testing';
|
import {TestBed} from '@angular/core/testing';
|
||||||
|
|
||||||
export function isBrowser() {
|
export function isBrowser() {
|
||||||
return getDOM().supportsDOMEvents();
|
return getDOM().supportsDOMEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ARG_TYPE_VALUES = [ArgumentType.Inline, ArgumentType.Dynamic];
|
export const ARG_TYPE_VALUES = [ArgumentType.Inline, ArgumentType.Dynamic];
|
||||||
|
|
|
@ -7,20 +7,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {ɵparseCookieValue as parseCookieValue, ɵsetRootDomAdapter as setRootDomAdapter} from '@angular/common';
|
import {ɵparseCookieValue as parseCookieValue, ɵsetRootDomAdapter as setRootDomAdapter} from '@angular/common';
|
||||||
import {ɵglobal as global} from '@angular/core';
|
|
||||||
|
|
||||||
import {GenericBrowserDomAdapter} from './generic_browser_adapter';
|
import {GenericBrowserDomAdapter} from './generic_browser_adapter';
|
||||||
|
|
||||||
const nodeContains: (this: Node, other: Node) => boolean = (() => {
|
|
||||||
if (global['Node']) {
|
|
||||||
return global['Node'].prototype.contains || function(this: Node, node: any) {
|
|
||||||
return !!(this.compareDocumentPosition(node) & 16);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined as any;
|
|
||||||
})();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `DomAdapter` powered by full browser DOM APIs.
|
* A `DomAdapter` powered by full browser DOM APIs.
|
||||||
*
|
*
|
||||||
|
@ -32,27 +21,6 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
|
||||||
static makeCurrent() {
|
static makeCurrent() {
|
||||||
setRootDomAdapter(new BrowserDomAdapter());
|
setRootDomAdapter(new BrowserDomAdapter());
|
||||||
}
|
}
|
||||||
getProperty(el: Node, name: string): any {
|
|
||||||
return (<any>el)[name];
|
|
||||||
}
|
|
||||||
|
|
||||||
log(error: string): void {
|
|
||||||
if (window.console) {
|
|
||||||
window.console.log && window.console.log(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logGroup(error: string): void {
|
|
||||||
if (window.console) {
|
|
||||||
window.console.group && window.console.group(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logGroupEnd(): void {
|
|
||||||
if (window.console) {
|
|
||||||
window.console.groupEnd && window.console.groupEnd();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onAndCancel(el: Node, evt: any, listener: any): Function {
|
onAndCancel(el: Node, evt: any, listener: any): Function {
|
||||||
el.addEventListener(evt, listener, false);
|
el.addEventListener(evt, listener, false);
|
||||||
|
@ -65,14 +33,10 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
|
||||||
dispatchEvent(el: Node, evt: any) {
|
dispatchEvent(el: Node, evt: any) {
|
||||||
el.dispatchEvent(evt);
|
el.dispatchEvent(evt);
|
||||||
}
|
}
|
||||||
remove(node: Node): Node {
|
remove(node: Node): void {
|
||||||
if (node.parentNode) {
|
if (node.parentNode) {
|
||||||
node.parentNode.removeChild(node);
|
node.parentNode.removeChild(node);
|
||||||
}
|
}
|
||||||
return node;
|
|
||||||
}
|
|
||||||
getValue(el: any): string {
|
|
||||||
return el.value;
|
|
||||||
}
|
}
|
||||||
createElement(tagName: string, doc?: Document): HTMLElement {
|
createElement(tagName: string, doc?: Document): HTMLElement {
|
||||||
doc = doc || this.getDefaultDocument();
|
doc = doc || this.getDefaultDocument();
|
||||||
|
@ -105,12 +69,6 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
getHistory(): History {
|
|
||||||
return window.history;
|
|
||||||
}
|
|
||||||
getLocation(): Location {
|
|
||||||
return window.location;
|
|
||||||
}
|
|
||||||
getBaseHref(doc: Document): string|null {
|
getBaseHref(doc: Document): string|null {
|
||||||
const href = getBaseElementHref();
|
const href = getBaseElementHref();
|
||||||
return href == null ? null : relativePath(href);
|
return href == null ? null : relativePath(href);
|
||||||
|
@ -121,17 +79,6 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
|
||||||
getUserAgent(): string {
|
getUserAgent(): string {
|
||||||
return window.navigator.userAgent;
|
return window.navigator.userAgent;
|
||||||
}
|
}
|
||||||
performanceNow(): number {
|
|
||||||
// performance.now() is not available in all browsers, see
|
|
||||||
// https://caniuse.com/high-resolution-time
|
|
||||||
return window.performance && window.performance.now ? window.performance.now() :
|
|
||||||
new Date().getTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
supportsCookies(): boolean {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
getCookie(name: string): string|null {
|
getCookie(name: string): string|null {
|
||||||
return parseCookieValue(document.cookie, name);
|
return parseCookieValue(document.cookie, name);
|
||||||
}
|
}
|
||||||
|
@ -139,22 +86,15 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
|
||||||
|
|
||||||
let baseElement: HTMLElement|null = null;
|
let baseElement: HTMLElement|null = null;
|
||||||
function getBaseElementHref(): string|null {
|
function getBaseElementHref(): string|null {
|
||||||
if (!baseElement) {
|
baseElement = baseElement || document.querySelector('base');
|
||||||
baseElement = document.querySelector('base')!;
|
return baseElement ? baseElement.getAttribute('href') : null;
|
||||||
if (!baseElement) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return baseElement.getAttribute('href');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// based on urlUtils.js in AngularJS 1
|
// based on urlUtils.js in AngularJS 1
|
||||||
let urlParsingNode: any;
|
let urlParsingNode: HTMLAnchorElement|undefined;
|
||||||
function relativePath(url: any): string {
|
function relativePath(url: any): string {
|
||||||
if (!urlParsingNode) {
|
urlParsingNode = urlParsingNode || document.createElement('a');
|
||||||
urlParsingNode = document.createElement('a');
|
|
||||||
}
|
|
||||||
urlParsingNode.setAttribute('href', url);
|
urlParsingNode.setAttribute('href', url);
|
||||||
return (urlParsingNode.pathname.charAt(0) === '/') ? urlParsingNode.pathname :
|
const pathName = urlParsingNode.pathname;
|
||||||
'/' + urlParsingNode.pathname;
|
return pathName.charAt(0) === '/' ? pathName : `/${pathName}`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,5 @@ import {ɵDomAdapter as DomAdapter} from '@angular/common';
|
||||||
* can introduce XSS risks.
|
* can introduce XSS risks.
|
||||||
*/
|
*/
|
||||||
export abstract class GenericBrowserDomAdapter extends DomAdapter {
|
export abstract class GenericBrowserDomAdapter extends DomAdapter {
|
||||||
constructor() {
|
readonly supportsDOMEvents: boolean = true;
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
supportsDOMEvents(): boolean {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {ɵgetDOM as getDOM} from '@angular/common';
|
|
||||||
import {ApplicationRef, ComponentRef} from '@angular/core';
|
import {ApplicationRef, ComponentRef} from '@angular/core';
|
||||||
import {window} from './browser';
|
import {window} from './browser';
|
||||||
|
|
||||||
|
@ -50,13 +49,13 @@ export class AngularProfiler {
|
||||||
if (record && isProfilerAvailable) {
|
if (record && isProfilerAvailable) {
|
||||||
window.console.profile(profileName);
|
window.console.profile(profileName);
|
||||||
}
|
}
|
||||||
const start = getDOM().performanceNow();
|
const start = performanceNow();
|
||||||
let numTicks = 0;
|
let numTicks = 0;
|
||||||
while (numTicks < 5 || (getDOM().performanceNow() - start) < 500) {
|
while (numTicks < 5 || (performanceNow() - start) < 500) {
|
||||||
this.appRef.tick();
|
this.appRef.tick();
|
||||||
numTicks++;
|
numTicks++;
|
||||||
}
|
}
|
||||||
const end = getDOM().performanceNow();
|
const end = performanceNow();
|
||||||
if (record && isProfilerAvailable) {
|
if (record && isProfilerAvailable) {
|
||||||
window.console.profileEnd(profileName);
|
window.console.profileEnd(profileName);
|
||||||
}
|
}
|
||||||
|
@ -67,3 +66,8 @@ export class AngularProfiler {
|
||||||
return new ChangeDetectionPerfRecord(msPerTick, numTicks);
|
return new ChangeDetectionPerfRecord(msPerTick, numTicks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function performanceNow() {
|
||||||
|
return window.performance && window.performance.now ? window.performance.now() :
|
||||||
|
new Date().getTime();
|
||||||
|
}
|
||||||
|
|
|
@ -273,7 +273,7 @@ function bootstrap(
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (getDOM().supportsDOMEvents()) {
|
if (getDOM().supportsDOMEvents) {
|
||||||
it('should forward the error to promise when bootstrap fails',
|
it('should forward the error to promise when bootstrap fails',
|
||||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||||
const logger = new MockConsole();
|
const logger = new MockConsole();
|
||||||
|
|
|
@ -21,7 +21,7 @@ let zone: NgZone;
|
||||||
|
|
||||||
describe('EventManager', () => {
|
describe('EventManager', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
doc = getDOM().supportsDOMEvents() ? document : getDOM().createHtmlDocument();
|
doc = getDOM().supportsDOMEvents ? document : getDOM().createHtmlDocument();
|
||||||
zone = new NgZone({});
|
zone = new NgZone({});
|
||||||
domEventPlugin = new DomEventsPlugin(doc);
|
domEventPlugin = new DomEventsPlugin(doc);
|
||||||
});
|
});
|
||||||
|
@ -337,7 +337,7 @@ describe('EventManager', () => {
|
||||||
|
|
||||||
it('should only trigger one Change detection when bubbling with shouldCoalesceEventChangeDetection = true',
|
it('should only trigger one Change detection when bubbling with shouldCoalesceEventChangeDetection = true',
|
||||||
(done: DoneFn) => {
|
(done: DoneFn) => {
|
||||||
doc = getDOM().supportsDOMEvents() ? document : getDOM().createHtmlDocument();
|
doc = getDOM().supportsDOMEvents ? document : getDOM().createHtmlDocument();
|
||||||
zone = new NgZone({shouldCoalesceEventChangeDetection: true});
|
zone = new NgZone({shouldCoalesceEventChangeDetection: true});
|
||||||
domEventPlugin = new DomEventsPlugin(doc);
|
domEventPlugin = new DomEventsPlugin(doc);
|
||||||
const element = el('<div></div>');
|
const element = el('<div></div>');
|
||||||
|
@ -374,7 +374,7 @@ describe('EventManager', () => {
|
||||||
|
|
||||||
it('should only trigger one Change detection when bubbling with shouldCoalesceRunChangeDetection = true',
|
it('should only trigger one Change detection when bubbling with shouldCoalesceRunChangeDetection = true',
|
||||||
(done: DoneFn) => {
|
(done: DoneFn) => {
|
||||||
doc = getDOM().supportsDOMEvents() ? document : getDOM().createHtmlDocument();
|
doc = getDOM().supportsDOMEvents ? document : getDOM().createHtmlDocument();
|
||||||
zone = new NgZone({shouldCoalesceRunChangeDetection: true});
|
zone = new NgZone({shouldCoalesceRunChangeDetection: true});
|
||||||
domEventPlugin = new DomEventsPlugin(doc);
|
domEventPlugin = new DomEventsPlugin(doc);
|
||||||
const element = el('<div></div>');
|
const element = el('<div></div>');
|
||||||
|
@ -411,7 +411,7 @@ describe('EventManager', () => {
|
||||||
|
|
||||||
it('should not drain micro tasks queue too early with shouldCoalesceEventChangeDetection=true',
|
it('should not drain micro tasks queue too early with shouldCoalesceEventChangeDetection=true',
|
||||||
(done: DoneFn) => {
|
(done: DoneFn) => {
|
||||||
doc = getDOM().supportsDOMEvents() ? document : getDOM().createHtmlDocument();
|
doc = getDOM().supportsDOMEvents ? document : getDOM().createHtmlDocument();
|
||||||
zone = new NgZone({shouldCoalesceEventChangeDetection: true});
|
zone = new NgZone({shouldCoalesceEventChangeDetection: true});
|
||||||
domEventPlugin = new DomEventsPlugin(doc);
|
domEventPlugin = new DomEventsPlugin(doc);
|
||||||
const element = el('<div></div>');
|
const element = el('<div></div>');
|
||||||
|
@ -457,7 +457,7 @@ describe('EventManager', () => {
|
||||||
|
|
||||||
it('should not drain micro tasks queue too early with shouldCoalesceRunChangeDetection=true',
|
it('should not drain micro tasks queue too early with shouldCoalesceRunChangeDetection=true',
|
||||||
(done: DoneFn) => {
|
(done: DoneFn) => {
|
||||||
doc = getDOM().supportsDOMEvents() ? document : getDOM().createHtmlDocument();
|
doc = getDOM().supportsDOMEvents ? document : getDOM().createHtmlDocument();
|
||||||
zone = new NgZone({shouldCoalesceRunChangeDetection: true});
|
zone = new NgZone({shouldCoalesceRunChangeDetection: true});
|
||||||
domEventPlugin = new DomEventsPlugin(doc);
|
domEventPlugin = new DomEventsPlugin(doc);
|
||||||
const element = el('<div></div>');
|
const element = el('<div></div>');
|
||||||
|
|
|
@ -10,10 +10,6 @@ const domino = require('domino');
|
||||||
import {ɵBrowserDomAdapter as BrowserDomAdapter} from '@angular/platform-browser';
|
import {ɵBrowserDomAdapter as BrowserDomAdapter} from '@angular/platform-browser';
|
||||||
import {ɵsetRootDomAdapter as setRootDomAdapter} from '@angular/common';
|
import {ɵsetRootDomAdapter as setRootDomAdapter} from '@angular/common';
|
||||||
|
|
||||||
function _notImplemented(methodName: string) {
|
|
||||||
return new Error('This method is not implemented in DominoAdapter: ' + methodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setDomTypes() {
|
export function setDomTypes() {
|
||||||
// Make all Domino types available in the global env.
|
// Make all Domino types available in the global env.
|
||||||
Object.assign(global, domino.impl);
|
Object.assign(global, domino.impl);
|
||||||
|
@ -45,23 +41,9 @@ export class DominoAdapter extends BrowserDomAdapter {
|
||||||
setRootDomAdapter(new DominoAdapter());
|
setRootDomAdapter(new DominoAdapter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readonly supportsDOMEvents = false;
|
||||||
private static defaultDoc: Document;
|
private static defaultDoc: Document;
|
||||||
|
|
||||||
log(error: string) {
|
|
||||||
// tslint:disable-next-line:no-console
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
logGroup(error: string) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
logGroupEnd() {}
|
|
||||||
|
|
||||||
supportsDOMEvents(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
createHtmlDocument(): HTMLDocument {
|
createHtmlDocument(): HTMLDocument {
|
||||||
return parseDocument('<html><head><title>fakeTitle</title></head><body></body></html>');
|
return parseDocument('<html><head><title>fakeTitle</title></head><body></body></html>');
|
||||||
}
|
}
|
||||||
|
@ -80,18 +62,6 @@ export class DominoAdapter extends BrowserDomAdapter {
|
||||||
return node.shadowRoot == node;
|
return node.shadowRoot == node;
|
||||||
}
|
}
|
||||||
|
|
||||||
getProperty(el: Element, name: string): any {
|
|
||||||
if (name === 'href') {
|
|
||||||
// Domino tries to resolve href-s which we do not want. Just return the
|
|
||||||
// attribute value.
|
|
||||||
return el.getAttribute('href');
|
|
||||||
} else if (name === 'innerText') {
|
|
||||||
// Domino does not support innerText. Just map it to textContent.
|
|
||||||
return el.textContent;
|
|
||||||
}
|
|
||||||
return (<any>el)[name];
|
|
||||||
}
|
|
||||||
|
|
||||||
getGlobalEventTarget(doc: Document, target: string): EventTarget|null {
|
getGlobalEventTarget(doc: Document, target: string): EventTarget|null {
|
||||||
if (target === 'window') {
|
if (target === 'window') {
|
||||||
return doc.defaultView;
|
return doc.defaultView;
|
||||||
|
@ -106,13 +76,8 @@ export class DominoAdapter extends BrowserDomAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
getBaseHref(doc: Document): string {
|
getBaseHref(doc: Document): string {
|
||||||
const base = doc.documentElement!.querySelector('base');
|
|
||||||
let href = '';
|
|
||||||
if (base) {
|
|
||||||
href = base.getAttribute('href')!;
|
|
||||||
}
|
|
||||||
// TODO(alxhub): Need relative path logic from BrowserDomAdapter here?
|
// TODO(alxhub): Need relative path logic from BrowserDomAdapter here?
|
||||||
return href;
|
return doc.documentElement!.querySelector('base')?.getAttribute('href') || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatchEvent(el: Node, evt: any) {
|
dispatchEvent(el: Node, evt: any) {
|
||||||
|
@ -126,24 +91,11 @@ export class DominoAdapter extends BrowserDomAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getHistory(): History {
|
|
||||||
throw _notImplemented('getHistory');
|
|
||||||
}
|
|
||||||
getLocation(): Location {
|
|
||||||
throw _notImplemented('getLocation');
|
|
||||||
}
|
|
||||||
getUserAgent(): string {
|
getUserAgent(): string {
|
||||||
return 'Fake user agent';
|
return 'Fake user agent';
|
||||||
}
|
}
|
||||||
|
|
||||||
performanceNow(): number {
|
|
||||||
return Date.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
supportsCookies(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
getCookie(name: string): string {
|
getCookie(name: string): string {
|
||||||
throw _notImplemented('getCookie');
|
throw new Error('getCookie has not been implemented');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -402,7 +402,7 @@ class HiddenModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
if (getDOM().supportsDOMEvents()) return; // NODE only
|
if (getDOM().supportsDOMEvents) return; // NODE only
|
||||||
|
|
||||||
describe('platform-server integration', () => {
|
describe('platform-server integration', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {ServerStylesHost} from '@angular/platform-server/src/styles_host';
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
if (getDOM().supportsDOMEvents()) return; // NODE only
|
if (getDOM().supportsDOMEvents) return; // NODE only
|
||||||
|
|
||||||
describe('ServerStylesHost', () => {
|
describe('ServerStylesHost', () => {
|
||||||
let ssh: ServerStylesHost;
|
let ssh: ServerStylesHost;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {APP_BASE_HREF, HashLocationStrategy, Location, LOCATION_INITIALIZED, LocationStrategy, PathLocationStrategy, PlatformLocation, ViewportScroller, ɵgetDOM as getDOM} from '@angular/common';
|
import {APP_BASE_HREF, HashLocationStrategy, Location, LOCATION_INITIALIZED, LocationStrategy, PathLocationStrategy, PlatformLocation, ViewportScroller} from '@angular/common';
|
||||||
import {ANALYZE_FOR_ENTRY_COMPONENTS, APP_BOOTSTRAP_LISTENER, APP_INITIALIZER, ApplicationRef, Compiler, ComponentRef, Inject, Injectable, InjectionToken, Injector, ModuleWithProviders, NgModule, NgModuleFactoryLoader, NgProbeToken, Optional, Provider, SkipSelf, SystemJsNgModuleLoader} from '@angular/core';
|
import {ANALYZE_FOR_ENTRY_COMPONENTS, APP_BOOTSTRAP_LISTENER, APP_INITIALIZER, ApplicationRef, Compiler, ComponentRef, Inject, Injectable, InjectionToken, Injector, ModuleWithProviders, NgModule, NgModuleFactoryLoader, NgProbeToken, Optional, Provider, SkipSelf, SystemJsNgModuleLoader} from '@angular/core';
|
||||||
import {of, Subject} from 'rxjs';
|
import {of, Subject} from 'rxjs';
|
||||||
|
|
||||||
|
@ -448,12 +448,13 @@ export function setupRouter(
|
||||||
assignExtraOptionsToRouter(opts, router);
|
assignExtraOptionsToRouter(opts, router);
|
||||||
|
|
||||||
if (opts.enableTracing) {
|
if (opts.enableTracing) {
|
||||||
const dom = getDOM();
|
|
||||||
router.events.subscribe((e: Event) => {
|
router.events.subscribe((e: Event) => {
|
||||||
dom.logGroup(`Router Event: ${(<any>e.constructor).name}`);
|
// tslint:disable:no-console
|
||||||
dom.log(e.toString());
|
console.group?.(`Router Event: ${(<any>e.constructor).name}`);
|
||||||
dom.log(e);
|
console.log(e.toString());
|
||||||
dom.logGroupEnd();
|
console.log(e);
|
||||||
|
console.groupEnd?.();
|
||||||
|
// tslint:enable:no-console
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue