diff options
Diffstat (limited to 'url.js')
-rw-r--r-- | url.js | 671 |
1 files changed, 0 insertions, 671 deletions
diff --git a/url.js b/url.js deleted file mode 100644 index 76e32cc86..000000000 --- a/url.js +++ /dev/null @@ -1,671 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - * Forked from https://github.com/github/url-polyfill - * Version 16c1aa Feb 9 2018. - */ - -(function(scope) { - "use strict"; - - // feature detect for URL constructor - var hasWorkingUrl = false; - if (!scope.forceJURL) { - try { - var u = new URL("b", "http://a"); - u.pathname = "c%20d"; - hasWorkingUrl = u.href === "http://a/c%20d"; - } catch (e) {} - } - - if (hasWorkingUrl) return; - - var relative = Object.create(null); - relative["ftp"] = 21; - relative["file"] = 0; - relative["gopher"] = 70; - relative["http"] = 80; - relative["https"] = 443; - relative["ws"] = 80; - relative["wss"] = 443; - - var relativePathDotMapping = Object.create(null); - relativePathDotMapping["%2e"] = "."; - relativePathDotMapping[".%2e"] = ".."; - relativePathDotMapping["%2e."] = ".."; - relativePathDotMapping["%2e%2e"] = ".."; - - function isRelativeScheme(scheme) { - return relative[scheme] !== undefined; - } - - function invalid() { - clear.call(this); - this._isInvalid = true; - } - - function IDNAToASCII(h) { - if ("" == h) { - invalid.call(this); - } - // XXX - return h.toLowerCase(); - } - - function percentEscape(c) { - var unicode = c.charCodeAt(0); - if ( - unicode > 0x20 && - unicode < 0x7f && - // " # < > ? ` - [0x22, 0x23, 0x3c, 0x3e, 0x3f, 0x60].indexOf(unicode) == -1 - ) { - return c; - } - return encodeURIComponent(c); - } - - function percentEscapeQuery(c) { - // XXX This actually needs to encode c using encoding and then - // convert the bytes one-by-one. - - var unicode = c.charCodeAt(0); - if ( - unicode > 0x20 && - unicode < 0x7f && - // " # < > ` (do not escape '?') - [0x22, 0x23, 0x3c, 0x3e, 0x60].indexOf(unicode) == -1 - ) { - return c; - } - return encodeURIComponent(c); - } - - var EOF = undefined, - ALPHA = /[a-zA-Z]/, - ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/; - - function parse(input, stateOverride, base) { - function err(message) { - errors.push(message); - } - - var state = stateOverride || "scheme start", - cursor = 0, - buffer = "", - seenAt = false, - seenBracket = false, - errors = []; - - loop: while ( - (input[cursor - 1] != EOF || cursor == 0) && - !this._isInvalid - ) { - var c = input[cursor]; - switch (state) { - case "scheme start": - if (c && ALPHA.test(c)) { - buffer += c.toLowerCase(); // ASCII-safe - state = "scheme"; - } else if (!stateOverride) { - buffer = ""; - state = "no scheme"; - continue; - } else { - err("Invalid scheme."); - break loop; - } - break; - - case "scheme": - if (c && ALPHANUMERIC.test(c)) { - buffer += c.toLowerCase(); // ASCII-safe - } else if (":" == c) { - this._scheme = buffer; - buffer = ""; - if (stateOverride) { - break loop; - } - if (isRelativeScheme(this._scheme)) { - this._isRelative = true; - } - if ("file" == this._scheme) { - state = "relative"; - } else if ( - this._isRelative && - base && - base._scheme == this._scheme - ) { - state = "relative or authority"; - } else if (this._isRelative) { - state = "authority first slash"; - } else { - state = "scheme data"; - } - } else if (!stateOverride) { - buffer = ""; - cursor = 0; - state = "no scheme"; - continue; - } else if (EOF == c) { - break loop; - } else { - err("Code point not allowed in scheme: " + c); - break loop; - } - break; - - case "scheme data": - if ("?" == c) { - query = "?"; - state = "query"; - } else if ("#" == c) { - this._fragment = "#"; - state = "fragment"; - } else { - // XXX error handling - if (EOF != c && "\t" != c && "\n" != c && "\r" != c) { - this._schemeData += percentEscape(c); - } - } - break; - - case "no scheme": - if (!base || !isRelativeScheme(base._scheme)) { - err("Missing scheme."); - invalid.call(this); - } else { - state = "relative"; - continue; - } - break; - - case "relative or authority": - if ("/" == c && "/" == input[cursor + 1]) { - state = "authority ignore slashes"; - } else { - err("Expected /, got: " + c); - state = "relative"; - continue; - } - break; - - case "relative": - this._isRelative = true; - if ("file" != this._scheme) this._scheme = base._scheme; - if (EOF == c) { - this._host = base._host; - this._port = base._port; - this._path = base._path.slice(); - this._query = base._query; - this._username = base._username; - this._password = base._password; - break loop; - } else if ("/" == c || "\\" == c) { - if ("\\" == c) err("\\ is an invalid code point."); - state = "relative slash"; - } else if ("?" == c) { - this._host = base._host; - this._port = base._port; - this._path = base._path.slice(); - this._query = "?"; - this._username = base._username; - this._password = base._password; - state = "query"; - } else if ("#" == c) { - this._host = base._host; - this._port = base._port; - this._path = base._path.slice(); - this._query = base._query; - this._fragment = "#"; - this._username = base._username; - this._password = base._password; - state = "fragment"; - } else { - var nextC = input[cursor + 1]; - var nextNextC = input[cursor + 2]; - if ( - "file" != this._scheme || - !ALPHA.test(c) || - (nextC != ":" && nextC != "|") || - (EOF != nextNextC && - "/" != nextNextC && - "\\" != nextNextC && - "?" != nextNextC && - "#" != nextNextC) - ) { - this._host = base._host; - this._port = base._port; - this._username = base._username; - this._password = base._password; - this._path = base._path.slice(); - this._path.pop(); - } - state = "relative path"; - continue; - } - break; - - case "relative slash": - if ("/" == c || "\\" == c) { - if ("\\" == c) { - err("\\ is an invalid code point."); - } - if ("file" == this._scheme) { - state = "file host"; - } else { - state = "authority ignore slashes"; - } - } else { - if ("file" != this._scheme) { - this._host = base._host; - this._port = base._port; - this._username = base._username; - this._password = base._password; - } - state = "relative path"; - continue; - } - break; - - case "authority first slash": - if ("/" == c) { - state = "authority second slash"; - } else { - err("Expected '/', got: " + c); - state = "authority ignore slashes"; - continue; - } - break; - - case "authority second slash": - state = "authority ignore slashes"; - if ("/" != c) { - err("Expected '/', got: " + c); - continue; - } - break; - - case "authority ignore slashes": - if ("/" != c && "\\" != c) { - state = "authority"; - continue; - } else { - err("Expected authority, got: " + c); - } - break; - - case "authority": - if ("@" == c) { - if (seenAt) { - err("@ already seen."); - buffer += "%40"; - } - seenAt = true; - for (var i = 0; i < buffer.length; i++) { - var cp = buffer[i]; - if ("\t" == cp || "\n" == cp || "\r" == cp) { - err("Invalid whitespace in authority."); - continue; - } - // XXX check URL code points - if (":" == cp && null === this._password) { - this._password = ""; - continue; - } - var tempC = percentEscape(cp); - null !== this._password - ? (this._password += tempC) - : (this._username += tempC); - } - buffer = ""; - } else if ( - EOF == c || - "/" == c || - "\\" == c || - "?" == c || - "#" == c - ) { - cursor -= buffer.length; - buffer = ""; - state = "host"; - continue; - } else { - buffer += c; - } - break; - - case "file host": - if (EOF == c || "/" == c || "\\" == c || "?" == c || "#" == c) { - if ( - buffer.length == 2 && - ALPHA.test(buffer[0]) && - (buffer[1] == ":" || buffer[1] == "|") - ) { - state = "relative path"; - } else if (buffer.length == 0) { - state = "relative path start"; - } else { - this._host = IDNAToASCII.call(this, buffer); - buffer = ""; - state = "relative path start"; - } - continue; - } else if ("\t" == c || "\n" == c || "\r" == c) { - err("Invalid whitespace in file host."); - } else { - buffer += c; - } - break; - - case "host": - case "hostname": - if (":" == c && !seenBracket) { - // XXX host parsing - this._host = IDNAToASCII.call(this, buffer); - buffer = ""; - state = "port"; - if ("hostname" == stateOverride) { - break loop; - } - } else if ( - EOF == c || - "/" == c || - "\\" == c || - "?" == c || - "#" == c - ) { - this._host = IDNAToASCII.call(this, buffer); - buffer = ""; - state = "relative path start"; - if (stateOverride) { - break loop; - } - continue; - } else if ("\t" != c && "\n" != c && "\r" != c) { - if ("[" == c) { - seenBracket = true; - } else if ("]" == c) { - seenBracket = false; - } - buffer += c; - } else { - err("Invalid code point in host/hostname: " + c); - } - break; - - case "port": - if (/[0-9]/.test(c)) { - buffer += c; - } else if ( - EOF == c || - "/" == c || - "\\" == c || - "?" == c || - "#" == c || - stateOverride - ) { - if ("" != buffer) { - var temp = parseInt(buffer, 10); - if (temp != relative[this._scheme]) { - this._port = temp + ""; - } - buffer = ""; - } - if (stateOverride) { - break loop; - } - state = "relative path start"; - continue; - } else if ("\t" == c || "\n" == c || "\r" == c) { - err("Invalid code point in port: " + c); - } else { - invalid.call(this); - } - break; - - case "relative path start": - if ("\\" == c) err("'\\' not allowed in path."); - state = "relative path"; - if ("/" != c && "\\" != c) { - continue; - } - break; - - case "relative path": - if ( - EOF == c || - "/" == c || - "\\" == c || - (!stateOverride && ("?" == c || "#" == c)) - ) { - if ("\\" == c) { - err("\\ not allowed in relative path."); - } - var tmp; - if ((tmp = relativePathDotMapping[buffer.toLowerCase()])) { - buffer = tmp; - } - if (".." == buffer) { - this._path.pop(); - if ("/" != c && "\\" != c) { - this._path.push(""); - } - } else if ("." == buffer && "/" != c && "\\" != c) { - this._path.push(""); - } else if ("." != buffer) { - if ( - "file" == this._scheme && - this._path.length == 0 && - buffer.length == 2 && - ALPHA.test(buffer[0]) && - buffer[1] == "|" - ) { - buffer = buffer[0] + ":"; - } - this._path.push(buffer); - } - buffer = ""; - if ("?" == c) { - this._query = "?"; - state = "query"; - } else if ("#" == c) { - this._fragment = "#"; - state = "fragment"; - } - } else if ("\t" != c && "\n" != c && "\r" != c) { - buffer += percentEscape(c); - } - break; - - case "query": - if (!stateOverride && "#" == c) { - this._fragment = "#"; - state = "fragment"; - } else if (EOF != c && "\t" != c && "\n" != c && "\r" != c) { - this._query += percentEscapeQuery(c); - } - break; - - case "fragment": - if (EOF != c && "\t" != c && "\n" != c && "\r" != c) { - this._fragment += c; - } - break; - } - - cursor++; - } - } - - function clear() { - this._scheme = ""; - this._schemeData = ""; - this._username = ""; - this._password = null; - this._host = ""; - this._port = ""; - this._path = []; - this._query = ""; - this._fragment = ""; - this._isInvalid = false; - this._isRelative = false; - } - - // Does not process domain names or IP addresses. - // Does not handle encoding for the query parameter. - function jURL(url, base /* , encoding */) { - if (base !== undefined && !(base instanceof jURL)) - base = new jURL(String(base)); - - url = String(url); - - this._url = url; - clear.call(this); - - var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, ""); - // encoding = encoding || 'utf-8' - - parse.call(this, input, null, base); - } - - jURL.prototype = { - toString: function() { - return this.href; - }, - get href() { - if (this._isInvalid) return this._url; - - var authority = ""; - if ("" != this._username || null != this._password) { - authority = - this._username + - (null != this._password ? ":" + this._password : "") + - "@"; - } - - return ( - this.protocol + - (this._isRelative ? "//" + authority + this.host : "") + - this.pathname + - this._query + - this._fragment - ); - }, - set href(href) { - clear.call(this); - parse.call(this, href); - }, - - get protocol() { - return this._scheme + ":"; - }, - set protocol(protocol) { - if (this._isInvalid) return; - parse.call(this, protocol + ":", "scheme start"); - }, - - get host() { - return this._isInvalid - ? "" - : this._port - ? this._host + ":" + this._port - : this._host; - }, - set host(host) { - if (this._isInvalid || !this._isRelative) return; - parse.call(this, host, "host"); - }, - - get hostname() { - return this._host; - }, - set hostname(hostname) { - if (this._isInvalid || !this._isRelative) return; - parse.call(this, hostname, "hostname"); - }, - - get port() { - return this._port; - }, - set port(port) { - if (this._isInvalid || !this._isRelative) return; - parse.call(this, port, "port"); - }, - - get pathname() { - return this._isInvalid - ? "" - : this._isRelative - ? "/" + this._path.join("/") - : this._schemeData; - }, - set pathname(pathname) { - if (this._isInvalid || !this._isRelative) return; - this._path = []; - parse.call(this, pathname, "relative path start"); - }, - - get search() { - return this._isInvalid || !this._query || "?" == this._query - ? "" - : this._query; - }, - set search(search) { - if (this._isInvalid || !this._isRelative) return; - this._query = "?"; - if ("?" == search[0]) search = search.slice(1); - parse.call(this, search, "query"); - }, - - get hash() { - return this._isInvalid || !this._fragment || "#" == this._fragment - ? "" - : this._fragment; - }, - set hash(hash) { - if (this._isInvalid) return; - this._fragment = "#"; - if ("#" == hash[0]) hash = hash.slice(1); - parse.call(this, hash, "fragment"); - }, - - get origin() { - var host; - if (this._isInvalid || !this._scheme) { - return ""; - } - // javascript: Gecko returns String(""), WebKit/Blink String("null") - // Gecko throws error for "data://" - // data: Gecko returns "", Blink returns "data://", WebKit returns "null" - // Gecko returns String("") for file: mailto: - // WebKit/Blink returns String("SCHEME://") for file: mailto: - switch (this._scheme) { - case "data": - case "file": - case "javascript": - case "mailto": - return "null"; - } - host = this.host; - if (!host) { - return ""; - } - return this._scheme + "://" + host; - } - }; - - // Copy over the static methods - var OriginalURL = scope.URL; - if (OriginalURL) { - jURL.createObjectURL = function(blob) { - // IE extension allows a second optional options argument. - // http://msdn.microsoft.com/en-us/library/ie/hh772302(v=vs.85).aspx - return OriginalURL.createObjectURL.apply(OriginalURL, arguments); - }; - jURL.revokeObjectURL = function(url) { - OriginalURL.revokeObjectURL(url); - }; - } - - scope.URL = jURL; -})(window); |