| 37 | */ |
| 38 | |
| 39 | export function url( |
| 40 | uri: string | ParsedUrl, |
| 41 | path: string = "", |
| 42 | loc?: Location, |
| 43 | ): ParsedUrl { |
| 44 | let obj = uri as ParsedUrl; |
| 45 | |
| 46 | // default to window.location |
| 47 | loc = loc || (typeof location !== "undefined" && location); |
| 48 | if (null == uri) uri = loc.protocol + "//" + loc.host; |
| 49 | |
| 50 | // relative path support |
| 51 | if (typeof uri === "string") { |
| 52 | if ("/" === uri.charAt(0)) { |
| 53 | if ("/" === uri.charAt(1)) { |
| 54 | uri = loc.protocol + uri; |
| 55 | } else { |
| 56 | uri = loc.host + uri; |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | if (!/^(https?|wss?):\/\//.test(uri)) { |
| 61 | debug("protocol-less url %s", uri); |
| 62 | if ("undefined" !== typeof loc) { |
| 63 | uri = loc.protocol + "//" + uri; |
| 64 | } else { |
| 65 | uri = "https://" + uri; |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | // parse |
| 70 | debug("parse %s", uri); |
| 71 | obj = parse(uri) as ParsedUrl; |
| 72 | } |
| 73 | |
| 74 | // make sure we treat `localhost:80` and `localhost` equally |
| 75 | if (!obj.port) { |
| 76 | if (/^(http|ws)$/.test(obj.protocol)) { |
| 77 | obj.port = "80"; |
| 78 | } else if (/^(http|ws)s$/.test(obj.protocol)) { |
| 79 | obj.port = "443"; |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | obj.path = obj.path || "/"; |
| 84 | |
| 85 | const ipv6 = obj.host.indexOf(":") !== -1; |
| 86 | const host = ipv6 ? "[" + obj.host + "]" : obj.host; |
| 87 | |
| 88 | // define unique id |
| 89 | obj.id = obj.protocol + "://" + host + ":" + obj.port + path; |
| 90 | // define href |
| 91 | obj.href = |
| 92 | obj.protocol + |
| 93 | "://" + |
| 94 | host + |
| 95 | (loc && loc.port === obj.port ? "" : ":" + obj.port); |
| 96 | |