-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
parse-url.ts
66 lines (53 loc) · 2.14 KB
/
parse-url.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/**
* Copyright (c) 2017, Philip Walton <philip@philipwalton.com>
*/
import { browserOrNode } from '@aws-amplify/core';
const HTTP_PORT = '80';
const HTTPS_PORT = '443';
const DEFAULT_PORT = RegExp(':(' + HTTP_PORT + '|' + HTTPS_PORT + ')$');
const a = browserOrNode().isBrowser ? document.createElement('a') : null;
const cache = {};
/**
* Parses the given url and returns an object mimicing a `Location` object.
* @param {string} url The url to parse.
* @return {!Object} An object with the same properties as a `Location`.
*/
export function parseUrl(u) {
let url = u;
// All falsy values (as well as ".") should map to the current URL.
url = !url || url === '.' ? location.href : url;
if (cache[url]) return cache[url];
a.href = url;
// When parsing file relative paths (e.g. `../index.html`), IE will correctly
// resolve the `href` property but will keep the `..` in the `path` property.
// It will also not include the `host` or `hostname` properties. Furthermore,
// IE will sometimes return no protocol or just a colon, especially for things
// like relative protocol URLs (e.g. "//google.com").
// To workaround all of these issues, we reparse with the full URL from the
// `href` property.
if (url.charAt(0) === '.' || url.charAt(0) === '/') return parseUrl(a.href);
// Don't include default ports.
let port = a.port === HTTP_PORT || a.port === HTTPS_PORT ? '' : a.port;
// PhantomJS sets the port to "0" when using the file: protocol.
port = port === '0' ? '' : port;
// Sometimes IE incorrectly includes a port for default ports
// (e.g. `:80` or `:443`) even when no port is specified in the URL.
// http://bit.ly/1rQNoMg
const host = a.host.replace(DEFAULT_PORT, '');
// Not all browser support `origin` so we have to build it.
const origin = a['origin'] ? a['origin'] : a.protocol + '//' + host;
// Sometimes IE doesn't include the leading slash for pathname.
// http://bit.ly/1rQNoMg
const pathname = a.pathname.charAt(0) === '/' ? a.pathname : '/' + a.pathname;
return (cache[url] = {
hash: a.hash,
host,
hostname: a.hostname,
href: a.href,
origin,
pathname,
port,
protocol: a.protocol,
search: a.search,
});
}