Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

fast-url-parser

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fast-url-parser - npm Package Compare versions

Comparing version
1.0.2-0
to
1.0.3-0
+10
-74
Gruntfile.js
"use strict";
Error.stackTraceLimit = 100;
var astPasses = require("./ast_passes.js");
module.exports = function( grunt ) {
var isCI = !!grunt.option("ci");
var license;
function getLicense() {
if( !license ) {
var fs = require("fs");
var text = fs.readFileSync("LICENSE", "utf8");
text = text.split("\n").map(function(line, index){
return " * " + line;
}).join("\n")
license = "/**\n" + text + "\n */\n";
}
return license
}
function writeFile( dest, content ) {

@@ -28,21 +12,2 @@ grunt.file.write( dest, content );

var getGlobals = function() {
var fs = require("fs");
var file = "./src/constants.js";
var contents = fs.readFileSync(file, "utf8");
var rconstantname = /CONSTANT\(\s*([^,]+)/g;
var m;
var globals = {
"console": false,
"require": false,
"module": false,
"define": false,
"escape": false
};
while( ( m = rconstantname.exec( contents ) ) ) {
globals[m[1]] = false;
}
return globals;
}
gruntConfig.pkg = grunt.file.readJSON("package.json");

@@ -53,3 +18,9 @@

options: {
globals: getGlobals(),
globals: {
"console": false,
"require": false,
"module": false,
"define": false,
"escape": false
},

@@ -117,42 +88,7 @@ "bitwise": false,

if( !isCI ) {
gruntConfig.jshint.all.options.reporter = require("jshint-stylish");
}
gruntConfig.bump = {
options: {
files: ['package.json'],
updateConfigs: [],
commit: true,
commitMessage: 'Release v%VERSION%',
commitFiles: ['-a'],
createTag: true,
tagName: 'v%VERSION%',
tagMessage: 'Version %VERSION%',
false: true,
pushTo: 'master',
gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d' // options to use with '$ git describe'
}
};
gruntConfig.jshint.all.options.reporter = require("jshint-stylish");
grunt.initConfig(gruntConfig);
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-bump');
grunt.registerTask( "build", function() {
var fs = require("fs");
var CONSTANTS_FILE = "./src/constants.js";
astPasses.readConstants(fs.readFileSync(CONSTANTS_FILE, "utf8"), CONSTANTS_FILE);
var fileNames = ["urlparser.js"];
fileNames.forEach(function(fileName){
var src = fs.readFileSync("./src/" + fileName, "utf8");
src = astPasses.removeComments(src, fileName);
src = astPasses.expandConstants(src, fileName);
src = getLicense() + src;
writeFile("./js/" + fileName, src);
});
});
grunt.registerTask( "testrun", function() {

@@ -189,5 +125,5 @@ var fs = require("fs");

grunt.registerTask( "test", ["jshint", "build", "testrun"] );
grunt.registerTask( "default", ["jshint", "build"] );
grunt.registerTask( "test", ["jshint", "testrun"] );
grunt.registerTask( "default", ["jshint"] );
};
+3
-3

@@ -1,2 +0,2 @@

Copyright (c) 2013 Petka Antonov
Copyright (c) 2014 Petka Antonov

@@ -8,3 +8,3 @@ Permission is hereby granted, free of charge, to any person obtaining a copy

copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:</p>
furnished to do so, subject to the following conditions:

@@ -20,2 +20,2 @@ The above copyright notice and this permission notice shall be included in

OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
THE SOFTWARE.
{
"name": "fast-url-parser",
"description": "Extremely fast implementation of node core url library",
"version": "1.0.2-0",
"version": "1.0.3-0",
"keywords": [

@@ -6,0 +6,0 @@ "fast",

@@ -0,1 +1,29 @@

#Introduction
Fast implementation of an url parser for node.js.
#Quick start
npm install fast-url-parser
```js
var url = require("fast-url-parser");
```
#API
This module has exactly the same API and semantics as the `require("url");`- module that comes with node.
See [Node.JS URL API documentation](http://nodejs.org/docs/latest/api/url.html).
If in your application you may want all modules use this parser automatically, you can do so by inserting this line at the beginning of your application:
```js
require("fast-url-parser").replace();
```
Anything that now calls `require("url")` will instead get an instance of this module instead of the url parser that comes with node core.
#Performance
Petka Antonov@PETKAANTONOV-PC ~/urlparser (master)

@@ -18,1 +46,25 @@ $ node ./benchmark/urlparser.js

misc/url.js resolve("./foo/bar?baz"): 6968.4
#License
MIT License:
Copyright (c) 2014 Petka Antonov
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.
/**
* Copyright (c) 2013 Petka Antonov
*
* 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:</p>
*
* 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";
function Url() {
this._protocol = null;
this._href = "";
this._port = -1;
this._query = null;
this.auth = null;
this.slashes = null;
this.host = null;
this.hostname = null;
this.hash = null;
this.search = null;
this.pathname = null;
this._prependSlash = false;
}
var querystring = require("querystring");
Url.prototype.parse =
function Url$parse(str, parseQueryString, hostDenotesSlash) {
if (typeof str !== "string") {
throw new TypeError("Parameter 'url' must be a string, not " +
typeof str);
}
var start = 0;
var end = str.length - 1;
while (str.charCodeAt(start) <= 32) start++;
while (str.charCodeAt(end) <= 32) end--;
start = this._parseProtocol(str, start, end);
if (this._protocol !== "javascript") {
start = this._parseHost(str, start, end, hostDenotesSlash);
var proto = this._protocol;
if (!this.hostname &&
(this.slashes || (proto && !slashProtocols[proto]))) {
this.hostname = this.host = "";
}
}
if (start <= end) {
var ch = str.charCodeAt(start);
if (ch === 47) {
this._parsePath(str, start, end);
}
else if (ch === 63) {
this._parseQuery(str, start, end);
}
else if (ch === 35) {
this._parseHash(str, start, end);
}
else if (this._protocol !== "javascript") {
this._parsePath(str, start, end);
}
else { this.pathname = str.slice(start, end + 1 );
}
}
if (!this.pathname && this.hostname &&
this._slashProtocols[this._protocol]) {
this.pathname = "/";
}
if (parseQueryString) {
var search = this.search;
if (search == null) {
search = this.search = "";
}
if (search.charCodeAt(0) === 63) {
search = search.slice(1);
}
this.query = querystring.parse(search);
}
};
Url.prototype.resolve = function Url$resolve(relative) {
return this.resolveObject(Url.parse(relative, false, true)).format();
};
Url.prototype.format = function Url$format() {
var auth = this.auth || "";
if (auth) {
auth = encodeURIComponent(auth);
auth = auth.replace(/%3A/i, ":");
auth += "@";
}
var protocol = this.protocol || "";
var pathname = this.pathname || "";
var hash = this.hash || "";
var search = this.search || "";
var query = "";
var hostname = this.hostname || "";
var port = this.port || "";
var host = false;
var scheme = "";
var q = this.query;
if (q && typeof q === "object") {
query = querystring.stringify(q);
}
if (!search) {
search = query ? "?" + query : "";
}
if (protocol && protocol.charCodeAt(protocol.length - 1) !== 58)
protocol += ":";
if (this.host) {
host = auth + this.host;
}
else if (hostname) {
var ip6 = hostname.indexOf(":") > -1;
if (ip6) hostname = "[" + hostname + "]";
host = auth + hostname + (port ? ":" + port : "");
}
var slashes = this.slashes ||
((!protocol ||
slashProtocols[protocol]) && host !== false);
if (protocol) scheme = protocol + (slashes ? "//" : "");
else if (slashes && auth) scheme = "//";
if (slashes && pathname && pathname.charCodeAt(0) !== 47) {
pathname = "/" + pathname;
}
else if (!slashes && pathname === "/") {
pathname = "";
}
if (search && search.charCodeAt(0) !== 63)
search = "?" + search;
if (hash && hash.charCodeAt(0) !== 35)
hash = "#" + hash;
pathname = escapePathName(pathname);
search = escapeSearch(search);
return scheme + (host === false ? "" : host) + pathname + search + hash;
};
Url.prototype.resolveObject = function Url$resolveObject(relative) {
if (typeof relative === "string")
relative = Url.parse(relative, false, true);
var result = this._clone();
result.hash = relative.hash;
if (!relative.href) {
result._href = "";
return result;
}
if (relative.slashes && !relative._protocol) {
relative._copyPropsTo(result, true);
if (slashProtocols[result._protocol] &&
result.hostname && !result.pathname) {
result.pathname = "/";
}
result._href = "";
return result;
}
if (relative._protocol && relative._protocol !== result._protocol) {
if (!slashProtocols[relative._protocol]) {
relative._copyPropsTo(result, false);
result._href = "";
return result;
}
result._protocol = relative._protocol;
if (!relative.host && relative._protocol !== "javascript") {
var relPath = (relative.pathname || "").split("/");
while (relPath.length && !(relative.host = relPath.shift()));
if (!relative.host) relative.host = "";
if (!relative.hostname) relative.hostname = "";
if (relPath[0] !== "") relPath.unshift("");
if (relPath.length < 2) relPath.unshift("");
result.pathname = relPath.join("/");
} else {
result.pathname = relative.pathname;
}
result.search = relative.search;
result.host = relative.host || "";
result.auth = relative.auth;
result.hostname = relative.hostname || relative.host;
result._port = relative._port;
result.slashes = result.slashes || relative.slashes;
result._href = "";
return result;
}
var isSourceAbs =
(result.pathname && result.pathname.charCodeAt(0) === 47);
var isRelAbs = (
relative.host ||
relative.pathname && relative.pathname.charCodeAt(0) === 47
);
var mustEndAbs = (isRelAbs || isSourceAbs ||
(result.host && relative.pathname));
var removeAllDots = mustEndAbs;
var srcPath = result.pathname && result.pathname.split("/") || [];
var relPath = relative.pathname && relative.pathname.split("/") || [];
var psychotic = result._protocol && !slashProtocols[result._protocol];
if (psychotic) {
result.hostname = "";
result._port = -1;
if (result.host) {
if (srcPath[0] === "") srcPath[0] = result.host;
else srcPath.unshift(result.host);
}
result.host = "";
if (relative._protocol) {
relative.hostname = "";
relative._port = -1;
if (relative.host) {
if (relPath[0] === "") relPath[0] = relative.host;
else relPath.unshift(relative.host);
}
relative.host = "";
}
mustEndAbs = mustEndAbs && (relPath[0] === "" || srcPath[0] === "");
}
if (isRelAbs) {
result.host = relative.host ?
relative.host : result.host;
result.hostname = relative.hostname ?
relative.hostname : result.hostname;
result.search = relative.search;
srcPath = relPath;
} else if (relPath.length) {
if (!srcPath) srcPath = [];
srcPath.pop();
srcPath = srcPath.concat(relPath);
result.search = relative.search;
} else if (relative.search) {
if (psychotic) {
result.hostname = result.host = srcPath.shift();
var authInHost = result.host && result.host.indexOf("@") > 0 ?
result.host.split("@") : false;
if (authInHost) {
result.auth = authInHost.shift();
result.host = result.hostname = authInHost.shift();
}
}
result.search = relative.search;
result._href = "";
return result;
}
if (!srcPath.length) {
result.pathname = null;
result._href = "";
return result;
}
var last = srcPath.slice(-1)[0];
var hasTrailingSlash = (
(result.host || relative.host) && (last === "." || last === "..") ||
last === "");
var up = 0;
for (var i = srcPath.length; i >= 0; i--) {
last = srcPath[i];
if (last == ".") {
srcPath.splice(i, 1);
} else if (last === "..") {
srcPath.splice(i, 1);
up++;
} else if (up) {
srcPath.splice(i, 1);
up--;
}
}
if (!mustEndAbs && !removeAllDots) {
for (; up--; up) {
srcPath.unshift("..");
}
}
if (mustEndAbs && srcPath[0] !== "" &&
(!srcPath[0] || srcPath[0].charCodeAt(0) !== 47)) {
srcPath.unshift("");
}
if (hasTrailingSlash && (srcPath.join("/").substr(-1) !== "/")) {
srcPath.push("");
}
var isAbsolute = srcPath[0] === "" ||
(srcPath[0] && srcPath[0].charCodeAt(0) === 47);
if (psychotic) {
result.hostname = result.host = isAbsolute ? "" :
srcPath.length ? srcPath.shift() : "";
var authInHost = result.host && result.host.indexOf("@") > 0 ?
result.host.split("@") : false;
if (authInHost) {
result.auth = authInHost.shift();
result.host = result.hostname = authInHost.shift();
}
}
mustEndAbs = mustEndAbs || (result.host && srcPath.length);
if (mustEndAbs && !isAbsolute) {
srcPath.unshift("");
}
result.pathname = srcPath.length === 0 ? null : srcPath.join("/");
result.auth = relative.auth || result.auth;
result.slashes = result.slashes || relative.slashes;
result._href = "";
return result;
};
var punycode = require("punycode");
Url.prototype._hostIdna = function Url$_hostIdna(hostname) {
var domainArray = hostname.split(".");
var newOut = [];
for (var i = 0; i < domainArray.length; ++i) {
var s = domainArray[i];
newOut.push(s.match(/[^A-Za-z0-9_-]/) ?
"xn--" + punycode.encode(s) : s);
}
return newOut.join(".");
};
var escapePathName = Url.prototype._escapePathName =
function Url$_escapePathName(pathname) {
if (!containsCharacter2(pathname, 35, 63)) return pathname;
return _escapePath(pathname);
};
var escapeSearch = Url.prototype._escapeSearch =
function Url$_escapeSearch(search) {
if (!containsCharacter2(search, 35, -1)) return search;
return _escapeSearch(search);
};
Url.prototype._parseProtocol = function Url$_parseProtocol(str, start, end) {
var doLowerCase = false;
var protocolCharacters = this._protocolCharacters;
for (var i = start; i <= end; ++i) {
var ch = str.charCodeAt(i);
if (ch === 58) {
var protocol = str.slice(start, i);
if (doLowerCase) protocol = protocol.toLowerCase();
this._protocol = protocol;
return i + 1;
}
else if (protocolCharacters[ch] === 1) {
if (ch < 97)
doLowerCase = true;
}
else {
return start;
}
}
return start;
};
Url.prototype._parseAuth = function Url$_parseAuth(str, start, end, decode) {
var auth = str.slice(start, end + 1);
if (decode) {
auth = decodeURIComponent(auth);
}
this.auth = auth;
};
Url.prototype._parsePort = function Url$_parsePort(str, start, end) {
var port = 0;
var hadChars = false;
for (var i = start; i <= end; ++i) {
var ch = str.charCodeAt(i);
if (48 <= ch && ch <= 57) {
port = (10 * port) + (ch - 48);
hadChars = true;
}
else break;
}
if (port === 0 && !hadChars) {
return 0;
}
this._port = port;
return i - start;
};
Url.prototype._parseHost =
function Url$_parseHost(str, start, end, slashesDenoteHost) {
var hostEndingCharacters = this._hostEndingCharacters;
if (str.charCodeAt(start) === 47 &&
str.charCodeAt(start + 1) === 47) {
this.slashes = true;
if (start === 0) {
if (end < 2) return start;
var hasAuth =
containsCharacter(str, 64, 2, hostEndingCharacters);
if (!hasAuth && !slashesDenoteHost) {
return start;
}
}
start += 2;
}
else if (!this._protocol ||
slashProtocols[this._protocol]
) {
return start;
}
var doLowerCase = false;
var idna = false;
var hostNameStart = start;
var hostNameEnd = end;
var lastCh = -1;
var portLength = 0;
var charsAfterDot = 0;
var authNeedsDecoding = false;
var j = -1;
for (var i = start; i <= end; ++i) {
var ch = str.charCodeAt(i);
if (ch === 64) {
j = i;
}
else if (ch === 37) {
authNeedsDecoding = true;
}
else if (hostEndingCharacters[ch] === 1) {
break;
}
}
if (j > -1) {
this._parseAuth(str, start, j - 1, authNeedsDecoding);
start = hostNameStart = j + 1;
}
if (str.charCodeAt(start) === 91) {
for (var i = start + 1; i <= end; ++i) {
var ch = str.charCodeAt(i);
if (ch === 93) {
if (str.charCodeAt(i + 1) === 58) {
portLength = this._parsePort(str, i + 2, end) + 1;
}
var hostname = str.slice(start + 1, i).toLowerCase();
this.hostname = hostname;
this.host = this._port > 0
? "[" + hostname + "]:" + this._port
: "[" + hostname + "]";
this.pathname = "/";
return i + portLength + 1;
}
}
return start;
}
for (var i = start; i <= end; ++i) {
if (charsAfterDot > 62) {
this.hostname = this.host = str.slice(start, i);
return i;
}
var ch = str.charCodeAt(i);
if (ch === 58) {
portLength = this._parsePort(str, i + 1, end) + 1;
hostNameEnd = i - 1;
break;
}
else if (ch < 97) {
if (ch === 46) {
charsAfterDot = -1;
}
else if (65 <= ch && ch <= 90) {
doLowerCase = true;
}
else if (!(ch === 45 || ch === 95 ||
(48 <= ch && ch <= 57))) {
if (hostEndingCharacters[ch] === 0 &&
this._noPrependSlashHostEnders[ch] === 0) {
this._prependSlash = true;
}
hostNameEnd = i - 1;
break;
}
}
else if (ch >= 0x7B) {
if (ch <= 0x7E) {
if (this._noPrependSlashHostEnders[ch] === 0) {
this._prependSlash = true;
}
hostNameEnd = i - 1;
break;
}
idna = true;
}
lastCh = ch;
charsAfterDot++;
}
if (hostNameEnd + 1 !== start &&
hostNameEnd - hostNameStart <= 256) {
var hostname = str.slice(hostNameStart, hostNameEnd + 1);
if (doLowerCase) hostname = hostname.toLowerCase();
if (idna) hostname = this._hostIdna(hostname);
this.hostname = hostname;
this.host = this._port > 0 ? hostname + ":" + this._port : hostname;
}
return hostNameEnd + 1 + portLength;
};
Url.prototype._copyPropsTo = function Url$_copyPropsTo(input, noProtocol) {
if (!noProtocol) {
input._protocol = this._protocol;
}
input._href = this._href;
input._port = this._port;
input._prependSlash = this._prependSlash;
input.auth = this.auth;
input.slashes = this.slashes;
input.host = this.host;
input.hostname = this.hostname;
input.hash = this.hash;
input.search = this.search;
input.pathname = this.pathname;
};
Url.prototype._clone = function Url$_clone() {
var ret = new Url();
ret._protocol = this._protocol;
ret._href = this._href;
ret._port = this._port;
ret._prependSlash = this._prependSlash;
ret.auth = this.auth;
ret.slashes = this.slashes;
ret.host = this.host;
ret.hostname = this.hostname;
ret.hash = this.hash;
ret.search = this.search;
ret.pathname = this.pathname;
return ret;
};
Url.prototype._getComponentEscaped =
function Url$_getComponentEscaped(str, start, end) {
var cur = start;
var i = start;
var ret = "";
var autoEscapeMap = this._autoEscapeMap;
for (; i <= end; ++i) {
var ch = str.charCodeAt(i);
var escaped = autoEscapeMap[ch];
if (escaped !== "") {
if (cur < i) ret += str.slice(cur, i);
ret += escaped;
cur = i + 1;
}
}
if (cur < i + 1) ret += str.slice(cur, i);
return ret;
};
Url.prototype._parsePath =
function Url$_parsePath(str, start, end) {
var pathStart = start;
var pathEnd = end;
var escape = false;
var autoEscapeCharacters = this._autoEscapeCharacters;
for (var i = start; i <= end; ++i) {
var ch = str.charCodeAt(i);
if (ch === 35) {
this._parseHash(str, i, end);
pathEnd = i - 1;
break;
}
else if (ch === 63) {
this._parseQuery(str, i, end);
pathEnd = i - 1;
break;
}
else if (!escape && autoEscapeCharacters[ch] === 1) {
escape = true;
}
}
if (pathStart > pathEnd) {
this.pathname = "/";
return;
}
var path;
if (escape) {
path = this._getComponentEscaped(str, pathStart, pathEnd);
}
else {
path = str.slice(pathStart, pathEnd + 1);
}
this.pathname = this._prependSlash ? "/" + path : path;
};
Url.prototype._parseQuery = function Url$_parseQuery(str, start, end) {
var queryStart = start;
var queryEnd = end;
var escape = false;
var autoEscapeCharacters = this._autoEscapeCharacters;
for (var i = start; i <= end; ++i) {
var ch = str.charCodeAt(i);
if (ch === 35) {
this._parseHash(str, i, end);
queryEnd = i - 1;
break;
}
else if (!escape && autoEscapeCharacters[ch] === 1) {
escape = true;
}
}
if (queryStart > queryEnd) {
this.search = "";
return;
}
var query;
if (escape) {
query = this._getComponentEscaped(str, queryStart, queryEnd);
}
else {
query = str.slice(queryStart, queryEnd + 1);
}
this.search = query;
};
Url.prototype._parseHash = function Url$_parseHash(str, start, end) {
if (start > end) {
this.hash = "";
return;
}
this.hash = this._getComponentEscaped(str, start, end);
};
Object.defineProperty(Url.prototype, "port", {
get: function() {
if (this._port >= 0) {
return ("" + this._port);
}
return null;
},
set: function(v) {
this._port = parseInt(v, 10);
}
});
Object.defineProperty(Url.prototype, "query", {
get: function() {
var query = this._query;
if (query != null) {
return query;
}
var search = this.search;
if (search) {
if (search.charCodeAt(0) === 63) {
search = search.slice(1);
}
if (search !== "") {
this._query = search;
return search;
}
}
return search;
},
set: function(v) {
this._query = v;
}
});
Object.defineProperty(Url.prototype, "path", {
get: function() {
var p = this.pathname || "";
var s = this.search || "";
if (p || s) {
return p + s;
}
return (p == null && s) ? ("/" + s) : null;
},
set: function() {}
});
Object.defineProperty(Url.prototype, "protocol", {
get: function() {
var proto = this._protocol;
return proto ? proto + ":" : proto;
},
set: function(v) {
var end = v.length - 1;
if (v.charCodeAt(end) === 58) {
this._protocol = v.slice(0, end);
}
else {
this._protocol = v;
}
}
});
Object.defineProperty(Url.prototype, "href", {
get: function() {
var href = this._href;
if (!href) {
href = this._href = this.format();
}
return href;
},
set: function(v) {
this._href = v;
}
});
Url.parse = function Url$Parse(str, parseQueryString, hostDenotesSlash) {
if (str instanceof Url) return str;
var ret = new Url();
ret.parse(str, !!parseQueryString, !!hostDenotesSlash);
return ret;
};
Url.format = function Url$Format(obj) {
if (typeof obj === "string") {
obj = Url.parse(obj);
}
if (!(obj instanceof Url)) {
return Url.prototype.format.call(obj);
}
return obj.format();
};
Url.resolve = function Url$Resolve(source, relative) {
return Url.parse(source, false, true).resolve(relative);
};
Url.resolveObject = function Url$ResolveObject(source, relative) {
if (!source) return relative;
return Url.parse(source, false, true).resolveObject(relative);
};
function _escapePath(pathname) {
return pathname.replace(/[?#]/g, function(match) {
return encodeURIComponent(match);
});
}
function _escapeSearch(search) {
return search.replace(/#/g, function(match) {
return encodeURIComponent(match);
});
}
function containsCharacter(string, char1, fromIndex, stopCharacterTable) {
var len = string.length;
for (var i = fromIndex; i < len; ++i) {
var ch = string.charCodeAt(i);
if (ch === char1) {
return true;
}
else if (stopCharacterTable[ch] === 1) {
return false;
}
}
return false;
}
function containsCharacter2(string, char1, char2) {
for (var i = 0, len = string.length; i < len; ++i) {
var ch = string.charCodeAt(i);
if (ch === char1 || ch === char2) return true;
}
return false;
}
function makeAsciiTable(spec) {
var ret = new Uint8Array(128);
spec.forEach(function(item){
if (typeof item === "number") {
ret[item] = 1;
}
else {
var start = item[0];
var end = item[1];
for (var j = start; j <= end; ++j) {
ret[j] = 1;
}
}
});
return ret;
}
var autoEscape = ["<", ">", "\"", "`", " ", "\r", "\n",
"\t", "{", "}", "|", "\\", "^", "`", "'"];
var autoEscapeMap = new Array(128);
for (var i = 0, len = autoEscapeMap.length; i < len; ++i) {
autoEscapeMap[i] = "";
}
for (var i = 0, len = autoEscape.length; i < len; ++i) {
var c = autoEscape[i];
var esc = encodeURIComponent(c);
if (esc === c) {
esc = escape(c);
}
autoEscapeMap[c.charCodeAt(0)] = esc;
}
var slashProtocols = Url.prototype._slashProtocols = {
http: true,
https: true,
gopher: true,
file: true,
ftp: true,
"http:": true,
"https:": true,
"gopher:": true,
"file:": true,
"ftp:": true
};
function f(){}
f.prototype = slashProtocols;
Url.prototype._protocolCharacters = makeAsciiTable([
[97, 122],
[65, 90],
46, 43, 45
]);
Url.prototype._hostEndingCharacters = makeAsciiTable([
35, 63, 47
]);
Url.prototype._autoEscapeCharacters = makeAsciiTable(
autoEscape.map(function(v) {
return v.charCodeAt(0);
})
);
Url.prototype._noPrependSlashHostEnders = makeAsciiTable(
[
"<", ">", "'", "`", " ", "\r",
"\n", "\t", "{", "}", "|", "\\",
"^", "`", "\"", "%", ";"
].map(function(v) {
return v.charCodeAt(0);
})
);
Url.prototype._autoEscapeMap = autoEscapeMap;
module.exports = Url;