diff options
Diffstat (limited to 'node_modules/mdurl')
-rw-r--r-- | node_modules/mdurl/CHANGELOG.md | 16 | ||||
-rw-r--r-- | node_modules/mdurl/LICENSE | 45 | ||||
-rw-r--r-- | node_modules/mdurl/README.md | 102 | ||||
-rw-r--r-- | node_modules/mdurl/decode.js | 122 | ||||
-rw-r--r-- | node_modules/mdurl/encode.js | 98 | ||||
-rw-r--r-- | node_modules/mdurl/format.js | 25 | ||||
-rw-r--r-- | node_modules/mdurl/index.js | 7 | ||||
-rw-r--r-- | node_modules/mdurl/package.json | 16 | ||||
-rw-r--r-- | node_modules/mdurl/parse.js | 312 |
9 files changed, 743 insertions, 0 deletions
diff --git a/node_modules/mdurl/CHANGELOG.md b/node_modules/mdurl/CHANGELOG.md new file mode 100644 index 0000000..ed33c78 --- /dev/null +++ b/node_modules/mdurl/CHANGELOG.md @@ -0,0 +1,16 @@ +1.0.1 / 2015-09-15 +------------------ + +- Fixed closure compiler compatibility (#1). + + +1.0.0 / 2015-03-04 +------------------ + +- Added `.decode()`, `.parse()`, `.format()`. + + +0.0.1 / 2015-03-02 +------------------ + +- First release. diff --git a/node_modules/mdurl/LICENSE b/node_modules/mdurl/LICENSE new file mode 100644 index 0000000..3b2c7bf --- /dev/null +++ b/node_modules/mdurl/LICENSE @@ -0,0 +1,45 @@ +Copyright (c) 2015 Vitaly Puzrin, Alex Kocharin. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +-------------------------------------------------------------------------------- + +.parse() is based on Joyent's node.js `url` code: + +Copyright Joyent, Inc. and other Node contributors. All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/node_modules/mdurl/README.md b/node_modules/mdurl/README.md new file mode 100644 index 0000000..72aebef --- /dev/null +++ b/node_modules/mdurl/README.md @@ -0,0 +1,102 @@ +# mdurl + +[![Build Status](https://img.shields.io/travis/markdown-it/mdurl/master.svg?style=flat)](https://travis-ci.org/markdown-it/mdurl) +[![NPM version](https://img.shields.io/npm/v/mdurl.svg?style=flat)](https://www.npmjs.org/package/mdurl) + +> URL utilities for [markdown-it](https://github.com/markdown-it/markdown-it) parser. + + +## API + +### .encode(str [, exclude, keepEncoded]) -> String + +Percent-encode a string, avoiding double encoding. Don't touch `/a-zA-Z0-9/` + +excluded chars + `/%[a-fA-F0-9]{2}/` (if not disabled). Broken surrorates are +replaced with `U+FFFD`. + +Params: + +- __str__ - input string. +- __exclude__ - optional, `;/?:@&=+$,-_.!~*'()#`. Additional chars to keep intact + (except `/a-zA-Z0-9/`). +- __keepEncoded__ - optional, `true`. By default it skips already encoded sequences + (`/%[a-fA-F0-9]{2}/`). If set to `false`, `%` will be encoded. + + +### encode.defaultChars, encode.componentChars + +You can use these constants as second argument to `encode` function. + + - `encode.defaultChars` is the same exclude set as in the standard `encodeURI()` function + - `encode.componentChars` is the same exclude set as in the `encodeURIComponent()` function + +For example, `encode('something', encode.componentChars, true)` is roughly the equivalent of +the `encodeURIComponent()` function (except `encode()` doesn't throw). + + +### .decode(str [, exclude]) -> String + +Decode percent-encoded string. Invalid percent-encoded sequences (e.g. `%2G`) +are left as is. Invalid UTF-8 characters are replaced with `U+FFFD`. + + +Params: + +- __str__ - input string. +- __exclude__ - set of characters to leave encoded, optional, `;/?:@&=+$,#`. + + +### decode.defaultChars, decode.componentChars + +You can use these constants as second argument to `decode` function. + + - `decode.defaultChars` is the same exclude set as in the standard `decodeURI()` function + - `decode.componentChars` is the same exclude set as in the `decodeURIComponent()` function + +For example, `decode('something', decode.defaultChars)` has the same behavior as +`decodeURI('something')` on a correctly encoded input. + + +### .parse(url, slashesDenoteHost) -> urlObs + +Parse url string. Similar to node's [url.parse](http://nodejs.org/api/url.html#url_url_parse_urlstr_parsequerystring_slashesdenotehost), but without any +normalizations and query string parse. + + - __url__ - input url (string) + - __slashesDenoteHost__ - if url starts with `//`, expect a hostname after it. Optional, `false`. + +Result (hash): + +- protocol +- slashes +- auth +- port +- hostname +- hash +- search +- pathname + +Difference with node's `url`: + +1. No leading slash in paths, e.g. in `url.parse('http://foo?bar')` pathname is + ``, not `/` +2. Backslashes are not replaced with slashes, so `http:\\example.org\` is + treated like a relative path +3. Trailing colon is treated like a part of the path, i.e. in + `http://example.org:foo` pathname is `:foo` +4. Nothing is URL-encoded in the resulting object, (in joyent/node some chars + in auth and paths are encoded) +5. `url.parse()` does not have `parseQueryString` argument +6. Removed extraneous result properties: `host`, `path`, `query`, etc., + which can be constructed using other parts of the url. + + +### .format(urlObject) + +Format an object previously obtained with `.parse()` function. Similar to node's +[url.format](http://nodejs.org/api/url.html#url_url_format_urlobj). + + +## License + +[MIT](https://github.com/markdown-it/mdurl/blob/master/LICENSE) diff --git a/node_modules/mdurl/decode.js b/node_modules/mdurl/decode.js new file mode 100644 index 0000000..189d7b9 --- /dev/null +++ b/node_modules/mdurl/decode.js @@ -0,0 +1,122 @@ + +'use strict'; + + +/* eslint-disable no-bitwise */ + +var decodeCache = {}; + +function getDecodeCache(exclude) { + var i, ch, cache = decodeCache[exclude]; + if (cache) { return cache; } + + cache = decodeCache[exclude] = []; + + for (i = 0; i < 128; i++) { + ch = String.fromCharCode(i); + cache.push(ch); + } + + for (i = 0; i < exclude.length; i++) { + ch = exclude.charCodeAt(i); + cache[ch] = '%' + ('0' + ch.toString(16).toUpperCase()).slice(-2); + } + + return cache; +} + + +// Decode percent-encoded string. +// +function decode(string, exclude) { + var cache; + + if (typeof exclude !== 'string') { + exclude = decode.defaultChars; + } + + cache = getDecodeCache(exclude); + + return string.replace(/(%[a-f0-9]{2})+/gi, function(seq) { + var i, l, b1, b2, b3, b4, chr, + result = ''; + + for (i = 0, l = seq.length; i < l; i += 3) { + b1 = parseInt(seq.slice(i + 1, i + 3), 16); + + if (b1 < 0x80) { + result += cache[b1]; + continue; + } + + if ((b1 & 0xE0) === 0xC0 && (i + 3 < l)) { + // 110xxxxx 10xxxxxx + b2 = parseInt(seq.slice(i + 4, i + 6), 16); + + if ((b2 & 0xC0) === 0x80) { + chr = ((b1 << 6) & 0x7C0) | (b2 & 0x3F); + + if (chr < 0x80) { + result += '\ufffd\ufffd'; + } else { + result += String.fromCharCode(chr); + } + + i += 3; + continue; + } + } + + if ((b1 & 0xF0) === 0xE0 && (i + 6 < l)) { + // 1110xxxx 10xxxxxx 10xxxxxx + b2 = parseInt(seq.slice(i + 4, i + 6), 16); + b3 = parseInt(seq.slice(i + 7, i + 9), 16); + + if ((b2 & 0xC0) === 0x80 && (b3 & 0xC0) === 0x80) { + chr = ((b1 << 12) & 0xF000) | ((b2 << 6) & 0xFC0) | (b3 & 0x3F); + + if (chr < 0x800 || (chr >= 0xD800 && chr <= 0xDFFF)) { + result += '\ufffd\ufffd\ufffd'; + } else { + result += String.fromCharCode(chr); + } + + i += 6; + continue; + } + } + + if ((b1 & 0xF8) === 0xF0 && (i + 9 < l)) { + // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx + b2 = parseInt(seq.slice(i + 4, i + 6), 16); + b3 = parseInt(seq.slice(i + 7, i + 9), 16); + b4 = parseInt(seq.slice(i + 10, i + 12), 16); + + if ((b2 & 0xC0) === 0x80 && (b3 & 0xC0) === 0x80 && (b4 & 0xC0) === 0x80) { + chr = ((b1 << 18) & 0x1C0000) | ((b2 << 12) & 0x3F000) | ((b3 << 6) & 0xFC0) | (b4 & 0x3F); + + if (chr < 0x10000 || chr > 0x10FFFF) { + result += '\ufffd\ufffd\ufffd\ufffd'; + } else { + chr -= 0x10000; + result += String.fromCharCode(0xD800 + (chr >> 10), 0xDC00 + (chr & 0x3FF)); + } + + i += 9; + continue; + } + } + + result += '\ufffd'; + } + + return result; + }); +} + + +decode.defaultChars = ';/?:@&=+$,#'; +decode.componentChars = ''; + + +module.exports = decode; diff --git a/node_modules/mdurl/encode.js b/node_modules/mdurl/encode.js new file mode 100644 index 0000000..6dff4f9 --- /dev/null +++ b/node_modules/mdurl/encode.js @@ -0,0 +1,98 @@ + +'use strict'; + + +var encodeCache = {}; + + +// Create a lookup array where anything but characters in `chars` string +// and alphanumeric chars is percent-encoded. +// +function getEncodeCache(exclude) { + var i, ch, cache = encodeCache[exclude]; + if (cache) { return cache; } + + cache = encodeCache[exclude] = []; + + for (i = 0; i < 128; i++) { + ch = String.fromCharCode(i); + + if (/^[0-9a-z]$/i.test(ch)) { + // always allow unencoded alphanumeric characters + cache.push(ch); + } else { + cache.push('%' + ('0' + i.toString(16).toUpperCase()).slice(-2)); + } + } + + for (i = 0; i < exclude.length; i++) { + cache[exclude.charCodeAt(i)] = exclude[i]; + } + + return cache; +} + + +// Encode unsafe characters with percent-encoding, skipping already +// encoded sequences. +// +// - string - string to encode +// - exclude - list of characters to ignore (in addition to a-zA-Z0-9) +// - keepEscaped - don't encode '%' in a correct escape sequence (default: true) +// +function encode(string, exclude, keepEscaped) { + var i, l, code, nextCode, cache, + result = ''; + + if (typeof exclude !== 'string') { + // encode(string, keepEscaped) + keepEscaped = exclude; + exclude = encode.defaultChars; + } + + if (typeof keepEscaped === 'undefined') { + keepEscaped = true; + } + + cache = getEncodeCache(exclude); + + for (i = 0, l = string.length; i < l; i++) { + code = string.charCodeAt(i); + + if (keepEscaped && code === 0x25 /* % */ && i + 2 < l) { + if (/^[0-9a-f]{2}$/i.test(string.slice(i + 1, i + 3))) { + result += string.slice(i, i + 3); + i += 2; + continue; + } + } + + if (code < 128) { + result += cache[code]; + continue; + } + + if (code >= 0xD800 && code <= 0xDFFF) { + if (code >= 0xD800 && code <= 0xDBFF && i + 1 < l) { + nextCode = string.charCodeAt(i + 1); + if (nextCode >= 0xDC00 && nextCode <= 0xDFFF) { + result += encodeURIComponent(string[i] + string[i + 1]); + i++; + continue; + } + } + result += '%EF%BF%BD'; + continue; + } + + result += encodeURIComponent(string[i]); + } + + return result; +} + +encode.defaultChars = ";/?:@&=+$,-_.!~*'()#"; +encode.componentChars = "-_.!~*'()"; + + +module.exports = encode; diff --git a/node_modules/mdurl/format.js b/node_modules/mdurl/format.js new file mode 100644 index 0000000..c4eb9f4 --- /dev/null +++ b/node_modules/mdurl/format.js @@ -0,0 +1,25 @@ + +'use strict'; + + +module.exports = function format(url) { + var result = ''; + + result += url.protocol || ''; + result += url.slashes ? '//' : ''; + result += url.auth ? url.auth + '@' : ''; + + if (url.hostname && url.hostname.indexOf(':') !== -1) { + // ipv6 address + result += '[' + url.hostname + ']'; + } else { + result += url.hostname || ''; + } + + result += url.port ? ':' + url.port : ''; + result += url.pathname || ''; + result += url.search || ''; + result += url.hash || ''; + + return result; +}; diff --git a/node_modules/mdurl/index.js b/node_modules/mdurl/index.js new file mode 100644 index 0000000..194abff --- /dev/null +++ b/node_modules/mdurl/index.js @@ -0,0 +1,7 @@ +'use strict'; + + +module.exports.encode = require('./encode'); +module.exports.decode = require('./decode'); +module.exports.format = require('./format'); +module.exports.parse = require('./parse'); diff --git a/node_modules/mdurl/package.json b/node_modules/mdurl/package.json new file mode 100644 index 0000000..017d740 --- /dev/null +++ b/node_modules/mdurl/package.json @@ -0,0 +1,16 @@ +{ + "name": "mdurl", + "version": "1.0.1", + "description": "URL utilities for markdown-it", + "repository": "markdown-it/mdurl", + "license": "MIT", + "scripts": { + "test": "make test" + }, + "devDependencies": { + "mocha": "*", + "eslint": "0.13.0", + "eslint-plugin-nodeca": "^1.0.0", + "istanbul": "*" + } +} diff --git a/node_modules/mdurl/parse.js b/node_modules/mdurl/parse.js new file mode 100644 index 0000000..6c33ac1 --- /dev/null +++ b/node_modules/mdurl/parse.js @@ -0,0 +1,312 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +// +// Changes from joyent/node: +// +// 1. No leading slash in paths, +// e.g. in `url.parse('http://foo?bar')` pathname is ``, not `/` +// +// 2. Backslashes are not replaced with slashes, +// so `http:\\example.org\` is treated like a relative path +// +// 3. Trailing colon is treated like a part of the path, +// i.e. in `http://example.org:foo` pathname is `:foo` +// +// 4. Nothing is URL-encoded in the resulting object, +// (in joyent/node some chars in auth and paths are encoded) +// +// 5. `url.parse()` does not have `parseQueryString` argument +// +// 6. Removed extraneous result properties: `host`, `path`, `query`, etc., +// which can be constructed using other parts of the url. +// + + +function Url() { + this.protocol = null; + this.slashes = null; + this.auth = null; + this.port = null; + this.hostname = null; + this.hash = null; + this.search = null; + this.pathname = null; +} + +// Reference: RFC 3986, RFC 1808, RFC 2396 + +// define these here so at least they only have to be +// compiled once on the first module load. +var protocolPattern = /^([a-z0-9.+-]+:)/i, + portPattern = /:[0-9]*$/, + + // Special case for a simple path URL + simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/, + + // RFC 2396: characters reserved for delimiting URLs. + // We actually just auto-escape these. + delims = [ '<', '>', '"', '`', ' ', '\r', '\n', '\t' ], + + // RFC 2396: characters not allowed for various reasons. + unwise = [ '{', '}', '|', '\\', '^', '`' ].concat(delims), + + // Allowed by RFCs, but cause of XSS attacks. Always escape these. + autoEscape = [ '\'' ].concat(unwise), + // Characters that are never ever allowed in a hostname. + // Note that any invalid chars are also handled, but these + // are the ones that are *expected* to be seen, so we fast-path + // them. + nonHostChars = [ '%', '/', '?', ';', '#' ].concat(autoEscape), + hostEndingChars = [ '/', '?', '#' ], + hostnameMaxLen = 255, + hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/, + hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/, + // protocols that can allow "unsafe" and "unwise" chars. + /* eslint-disable no-script-url */ + // protocols that never have a hostname. + hostlessProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that always contain a // bit. + slashedProtocol = { + 'http': true, + 'https': true, + 'ftp': true, + 'gopher': true, + 'file': true, + 'http:': true, + 'https:': true, + 'ftp:': true, + 'gopher:': true, + 'file:': true + }; + /* eslint-enable no-script-url */ + +function urlParse(url, slashesDenoteHost) { + if (url && url instanceof Url) { return url; } + + var u = new Url(); + u.parse(url, slashesDenoteHost); + return u; +} + +Url.prototype.parse = function(url, slashesDenoteHost) { + var i, l, lowerProto, hec, slashes, + rest = url; + + // trim before proceeding. + // This is to support parse stuff like " http://foo.com \n" + rest = rest.trim(); + + if (!slashesDenoteHost && url.split('#').length === 1) { + // Try fast path regexp + var simplePath = simplePathPattern.exec(rest); + if (simplePath) { + this.pathname = simplePath[1]; + if (simplePath[2]) { + this.search = simplePath[2]; + } + return this; + } + } + + var proto = protocolPattern.exec(rest); + if (proto) { + proto = proto[0]; + lowerProto = proto.toLowerCase(); + this.protocol = proto; + rest = rest.substr(proto.length); + } + + // figure out if it's got a host + // user@server is *always* interpreted as a hostname, and url + // resolution will treat //foo/bar as host=foo,path=bar because that's + // how the browser resolves relative URLs. + if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { + slashes = rest.substr(0, 2) === '//'; + if (slashes && !(proto && hostlessProtocol[proto])) { + rest = rest.substr(2); + this.slashes = true; + } + } + + if (!hostlessProtocol[proto] && + (slashes || (proto && !slashedProtocol[proto]))) { + + // there's a hostname. + // the first instance of /, ?, ;, or # ends the host. + // + // If there is an @ in the hostname, then non-host chars *are* allowed + // to the left of the last @ sign, unless some host-ending character + // comes *before* the @-sign. + // URLs are obnoxious. + // + // ex: + // http://a@b@c/ => user:a@b host:c + // http://a@b?@c => user:a host:c path:/?@c + + // v0.12 TODO(isaacs): This is not quite how Chrome does things. + // Review our test case against browsers more comprehensively. + + // find the first instance of any hostEndingChars + var hostEnd = -1; + for (i = 0; i < hostEndingChars.length; i++) { + hec = rest.indexOf(hostEndingChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) { + hostEnd = hec; + } + } + + // at this point, either we have an explicit point where the + // auth portion cannot go past, or the last @ char is the decider. + var auth, atSign; + if (hostEnd === -1) { + // atSign can be anywhere. + atSign = rest.lastIndexOf('@'); + } else { + // atSign must be in auth portion. + // http://a@b/c@d => host:b auth:a path:/c@d + atSign = rest.lastIndexOf('@', hostEnd); + } + + // Now we have a portion which is definitely the auth. + // Pull that off. + if (atSign !== -1) { + auth = rest.slice(0, atSign); + rest = rest.slice(atSign + 1); + this.auth = auth; + } + + // the host is the remaining to the left of the first non-host char + hostEnd = -1; + for (i = 0; i < nonHostChars.length; i++) { + hec = rest.indexOf(nonHostChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) { + hostEnd = hec; + } + } + // if we still have not hit it, then the entire thing is a host. + if (hostEnd === -1) { + hostEnd = rest.length; + } + + if (rest[hostEnd - 1] === ':') { hostEnd--; } + var host = rest.slice(0, hostEnd); + rest = rest.slice(hostEnd); + + // pull out port. + this.parseHost(host); + + // we've indicated that there is a hostname, + // so even if it's empty, it has to be present. + this.hostname = this.hostname || ''; + + // if hostname begins with [ and ends with ] + // assume that it's an IPv6 address. + var ipv6Hostname = this.hostname[0] === '[' && + this.hostname[this.hostname.length - 1] === ']'; + + // validate a little. + if (!ipv6Hostname) { + var hostparts = this.hostname.split(/\./); + for (i = 0, l = hostparts.length; i < l; i++) { + var part = hostparts[i]; + if (!part) { continue; } + if (!part.match(hostnamePartPattern)) { + var newpart = ''; + for (var j = 0, k = part.length; j < k; j++) { + if (part.charCodeAt(j) > 127) { + // we replace non-ASCII char with a temporary placeholder + // we need this to make sure size of hostname is not + // broken by replacing non-ASCII by nothing + newpart += 'x'; + } else { + newpart += part[j]; + } + } + // we test again with ASCII char only + if (!newpart.match(hostnamePartPattern)) { + var validParts = hostparts.slice(0, i); + var notHost = hostparts.slice(i + 1); + var bit = part.match(hostnamePartStart); + if (bit) { + validParts.push(bit[1]); + notHost.unshift(bit[2]); + } + if (notHost.length) { + rest = notHost.join('.') + rest; + } + this.hostname = validParts.join('.'); + break; + } + } + } + } + + if (this.hostname.length > hostnameMaxLen) { + this.hostname = ''; + } + + // strip [ and ] from the hostname + // the host field still retains them, though + if (ipv6Hostname) { + this.hostname = this.hostname.substr(1, this.hostname.length - 2); + } + } + + // chop off from the tail first. + var hash = rest.indexOf('#'); + if (hash !== -1) { + // got a fragment string. + this.hash = rest.substr(hash); + rest = rest.slice(0, hash); + } + var qm = rest.indexOf('?'); + if (qm !== -1) { + this.search = rest.substr(qm); + rest = rest.slice(0, qm); + } + if (rest) { this.pathname = rest; } + if (slashedProtocol[lowerProto] && + this.hostname && !this.pathname) { + this.pathname = ''; + } + + return this; +}; + +Url.prototype.parseHost = function(host) { + var port = portPattern.exec(host); + if (port) { + port = port[0]; + if (port !== ':') { + this.port = port.substr(1); + } + host = host.substr(0, host.length - port.length); + } + if (host) { this.hostname = host; } +}; + +module.exports = urlParse; |