test(common): add fallback for URL parsing in older browsers (IE < Edge) (#30055)

PR Close #30055
This commit is contained in:
Jason Aden 2019-04-23 14:53:38 -07:00 committed by Ben Lesh
parent c0c8d2349c
commit efdbbe1aa6
2 changed files with 47 additions and 2 deletions

View File

@ -10,6 +10,27 @@ import {LocationChangeEvent, LocationChangeListener, PlatformLocation} from '@an
import {Injectable, InjectionToken, Optional} from '@angular/core'; import {Injectable, InjectionToken, Optional} from '@angular/core';
import {Subject} from 'rxjs'; import {Subject} from 'rxjs';
/**
* Parser from https://tools.ietf.org/html/rfc3986#appendix-B
* ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
* 12 3 4 5 6 7 8 9
*
* Example: http://www.ics.uci.edu/pub/ietf/uri/#Related
*
* Results in:
*
* $1 = http:
* $2 = http
* $3 = //www.ics.uci.edu
* $4 = www.ics.uci.edu
* $5 = /pub/ietf/uri/
* $6 = <undefined>
* $7 = <undefined>
* $8 = #Related
* $9 = Related
*/
const urlParse = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
function parseUrl(urlStr: string, baseHref: string) { function parseUrl(urlStr: string, baseHref: string) {
const verifyProtocol = /^((http[s]?|ftp):\/\/)/; const verifyProtocol = /^((http[s]?|ftp):\/\/)/;
let serverBase: string|undefined; let serverBase: string|undefined;
@ -19,7 +40,31 @@ function parseUrl(urlStr: string, baseHref: string) {
if (!verifyProtocol.test(urlStr)) { if (!verifyProtocol.test(urlStr)) {
serverBase = 'http://empty.com/'; serverBase = 'http://empty.com/';
} }
const parsedUrl = new URL(urlStr, serverBase); let parsedUrl: {
protocol: string,
hostname: string,
port: string,
pathname: string,
search: string,
hash: string
};
try {
parsedUrl = new URL(urlStr, serverBase);
} catch (e) {
const result = urlParse.exec(serverBase || '' + urlStr);
if (!result) {
throw new Error(`Invalid URL: ${urlStr} with base: ${baseHref}`);
}
const hostSplit = result[4].split(':');
parsedUrl = {
protocol: result[1],
hostname: hostSplit[0],
port: hostSplit[1] || '',
pathname: result[5],
search: result[6],
hash: result[8],
};
}
if (parsedUrl.pathname && parsedUrl.pathname.indexOf(baseHref) === 0) { if (parsedUrl.pathname && parsedUrl.pathname.indexOf(baseHref) === 0) {
parsedUrl.pathname = parsedUrl.pathname.substring(baseHref.length); parsedUrl.pathname = parsedUrl.pathname.substring(baseHref.length);
} }

View File

@ -37,7 +37,7 @@ export declare class MockPlatformLocation implements PlatformLocation {
replaceState(state: any, title: string, newUrl: string): void; replaceState(state: any, title: string, newUrl: string): void;
} }
export declare class SpyLocation extends Location { export declare class SpyLocation implements Location {
urlChanges: string[]; urlChanges: string[];
back(): void; back(): void;
forward(): void; forward(): void;