Comparing version 1.2.2 to 1.3.0-beta.1
{ | ||
"author": "Derek Watson <watson@dcw.ca> (http://dcw.ca)", | ||
"name": "jsuri", | ||
"description": "Uri and query string manipulation", | ||
"version": "1.2.2", | ||
"version": "1.3.0-beta.1", | ||
"author": "Derek Watson <watson@dcw.ca> (http://dcw.ca)", | ||
"contributors": [ | ||
{ | ||
"name": "James M. Greene", | ||
"email": "james.m.greene@gmail.com", | ||
"url": "http://jamesgreene.net/" | ||
} | ||
], | ||
"homepage": "https://github.com/derek-watson/jsUri", | ||
@@ -19,9 +26,12 @@ "repository": { | ||
"scripts": { | ||
"test": "jake test" | ||
"test": "./node_modules/.bin/mocha", | ||
"lint": "./node_modules/.bin/jshint Uri.js", | ||
"minify": "./node_modules/.bin/uglifyjs Uri.js > Uri.min.js" | ||
}, | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"jasmine-node": ">= 1.0.26", | ||
"jshint": ">= 0.9.0", | ||
"uglify-js": ">= 1.3.3" | ||
"jshint": "~2.1.11", | ||
"uglify-js": "~2.4.0", | ||
"mocha": "~1.14.0", | ||
"chai": "~1.8.1" | ||
}, | ||
@@ -28,0 +38,0 @@ "optionalDependencies": {}, |
123
README.md
@@ -1,40 +0,33 @@ | ||
jsUri | ||
===== | ||
[![Build Status](https://travis-ci.org/derek-watson/jsUri.png)](https://travis-ci.org/derek-watson/jsUri) | ||
Uri and query string manipulation in javascript. | ||
# jsUri | ||
This project incorporates the excellent [parseUri](http://blog.stevenlevithan.com/archives/parseuri) regular expression library by Steven Levithan. You can safely parse URLs of all shapes and sizes, however invalid or hideous. | ||
Uri parsing and manipulation for node.js and the browser. | ||
var uri = new Uri('http://user:pass@www.test.com:81/index.html?q=books#fragment') | ||
Usage | ||
----- | ||
Use property methods to get at the various parts | ||
Pass anything that your browser would recognize as a url to the new Uri() constructor | ||
uri.protocol() // http | ||
uri.userInfo() // user:pass | ||
uri.host() // www.test.com | ||
uri.port() // 81 | ||
uri.path() // /index.html | ||
uri.query() // q=books | ||
uri.anchor() // fragment | ||
var uri = new Uri('http://user:pass@www.test.com:81/index.html?q=books#fragment'); | ||
Property methods accept an optional value to set | ||
and then use the following accessor methods to get at the various parts. | ||
uri.protocol('https') | ||
uri.toString() // https://user:pass@www.test.com:81/index.html?q=books#fragment | ||
uri.protocol(); // http | ||
uri.userInfo(); // user:pass | ||
uri.host(); // www.test.com | ||
uri.port(); // 81 | ||
uri.path(); // /index.html | ||
uri.query(); // q=books | ||
uri.anchor(); // fragment | ||
uri.host('mydomain.com') | ||
uri.toString() // https://user:pass@www.mydomain.com:81/index.html?q=books#fragment | ||
The accessor methods accept an optional value for setting the property | ||
Chainable setter methods help you compose strings | ||
uri.protocol('https'); | ||
uri.toString(); // https://user:pass@www.test.com:81/index.html?q=books#fragment | ||
new Uri() | ||
.setPath('/archives/1979/') | ||
.setQuery('?page=1') // /archives/1979?page=1 | ||
uri.host('mydomain.com'); | ||
uri.toString(); // https://user:pass@www.mydomain.com:81/index.html?q=books#fragment | ||
Fluent Setters | ||
-------------- | ||
The fluent interface provides a simple way to chain property assignment | ||
new Uri() | ||
@@ -53,13 +46,5 @@ .setPath('/index.html') | ||
new Uri() | ||
.setPath('/archives/1979/') | ||
.setQuery('?page=1') // /archives/1979?page=1 | ||
Query Parameter Access and Manipulation | ||
--------------------------------------- | ||
## Query param methods | ||
Special methods are available for fetching, building and modifying query string parameters. An emhpasis is placed on query string integrity; duplicate parameter names and values are preserved. Parameter ordering is preserved when possible. URI Components are decoded for comparision, but are otherwise left in their original state. | ||
### Getting query param values by name | ||
Returns the first query param value for the key | ||
@@ -73,22 +58,20 @@ | ||
### Getting all query param keys and values | ||
Internally, query key/value pairs are stored as a series of two-value arrays in the Query object | ||
new Uri('?a=b&c=d').query().params // [ ['a', 'b'], ['c', 'd']] | ||
new Uri('?a=b&c=d').query().params // [ ['a', 'b'], ['c', 'd']] | ||
### Adding query param values | ||
Add query param values | ||
new Uri().addQueryParam('q', 'books') // ?q=books | ||
new Uri().addQueryParam('q', 'books') // ?q=books | ||
new Uri('http://www.github.com') | ||
.addQueryParam('testing', '123') | ||
.addQueryParam('one', 1) // http://www.github.com/?testing=123&one=1 | ||
.addQueryParam('one', 1) // http://www.github.com/?testing=123&one=1 | ||
// insert param at index 0 | ||
new Uri('?b=2&c=3&d=4').addQueryParam('a', '1', 0) // ?a=1&b=2&c=3&d=4 | ||
new Uri('?b=2&c=3&d=4').addQueryParam('a', '1', 0) // ?a=1&b=2&c=3&d=4 | ||
### Replacing query param values | ||
Replace every query string parameter named `key` with `newVal` | ||
Replaces every query string parameter named `key` with a single instance with the value `newVal`. If `oldValue` is supplied, only parameters valued `oldVal` will be replaced. | ||
new Uri().replaceQueryParam('page', 2) // ?page=2 | ||
@@ -101,9 +84,5 @@ new Uri('?a=1&b=2&c=3') | ||
new Uri().replaceQueryParam('page', 2) // ?page=2 | ||
Removes instances of query parameters named `key` | ||
### Deleting query param values | ||
Removes instances of query parameters named `key`. If `value` is passed, only params named `key` and valued `value` will be deleted. | ||
new Uri('?a=1&b=2&c=3') | ||
@@ -115,41 +94,9 @@ .deleteQueryParam('a') // ?b=2&c=3 | ||
Create an identical uri object with no shared state | ||
Object Cloning | ||
-------------- | ||
var baseUri = new Uri('http://localhost/') | ||
Duplication (via `.clone()`) is an easy way to inflate an identical uri object, which you can muck around with as much as you like without destroying the original. | ||
baseUri.clone().setProtocol('https') // https://localhost/ | ||
baseUri // http://localhost/ | ||
var baseUri = new Uri('http://localhost/'); | ||
baseUri.clone().setProtocol('https'); // https://localhost/ | ||
baseUri; // http://localhost/ | ||
Testing | ||
------- | ||
There is a comprensive set of unit tests written in [jasmine](http://pivotal.github.com/jasmine/). | ||
To run them, simply open `testrunner.html` from the root of the project in a browser. | ||
License | ||
------- | ||
Copyright (c) 2012 Derek Watson | ||
Copyright (c) 2007 Steven Levithan | ||
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. | ||
This project incorporates the [parseUri](http://blog.stevenlevithan.com/archives/parseuri) regular expression by Steven Levithan. |
648
Uri.js
@@ -5,3 +5,3 @@ /*! | ||
* | ||
* Copyright 2012, Derek Watson | ||
* Copyright 2013, Derek Watson | ||
* Released under the MIT license. | ||
@@ -13,361 +13,399 @@ * | ||
* Released under the MIT license. | ||
* | ||
*/ | ||
/*globals define, module */ | ||
(function(global) { | ||
/** | ||
* Define forEach for older js environments | ||
* @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach#Compatibility | ||
*/ | ||
if (!Array.prototype.forEach) { | ||
Array.prototype.forEach = function(fn, scope) { | ||
for (var i = 0, len = this.length; i < len; ++i) { | ||
fn.call(scope || this, this[i], i, this); | ||
} | ||
}; | ||
} | ||
var re = { | ||
starts_with_slashes: /^\/+/, | ||
ends_with_slashes: /\/+$/, | ||
pluses: /\+/g, | ||
query_separator: /[&;]/, | ||
uri_parser: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ | ||
}; | ||
/** | ||
* unescape a query param value | ||
* @param {string} s encoded value | ||
* @return {string} decoded value | ||
*/ | ||
function decode(s) { | ||
s = decodeURIComponent(s); | ||
s = s.replace('+', ' '); | ||
return s; | ||
} | ||
/** | ||
* Define forEach for older js environments | ||
* @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach#Compatibility | ||
*/ | ||
if (!Array.prototype.forEach) { | ||
Array.prototype.forEach = function(fn, scope) { | ||
for (var i = 0, len = this.length; i < len; ++i) { | ||
fn.call(scope || this, this[i], i, this); | ||
} | ||
}; | ||
} | ||
/** | ||
* Breaks a uri string down into its individual parts | ||
* @param {string} str uri | ||
* @return {object} parts | ||
*/ | ||
function parseUri(str) { | ||
var parser = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/, | ||
parserKeys = ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"], | ||
m = parser.exec(str || ''), | ||
parts = {}; | ||
parserKeys.forEach(function(key, i) { | ||
parts[key] = m[i] || ''; | ||
}); | ||
return parts; | ||
/** | ||
* unescape a query param value | ||
* @param {string} s encoded value | ||
* @return {string} decoded value | ||
*/ | ||
function decode(s) { | ||
if (s) { | ||
s = decodeURIComponent(s); | ||
s = s.replace(re.pluses, ' '); | ||
} | ||
return s; | ||
} | ||
/** | ||
* Breaks a query string down into an array of key/value pairs | ||
* @param {string} str query | ||
* @return {array} array of arrays (key/value pairs) | ||
*/ | ||
function parseQuery(str) { | ||
var i, ps, p, kvp, k, v, | ||
pairs = []; | ||
/** | ||
* Breaks a uri string down into its individual parts | ||
* @param {string} str uri | ||
* @return {object} parts | ||
*/ | ||
function parseUri(str) { | ||
var parser = re.uri_parser; | ||
var parserKeys = ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"]; | ||
var m = parser.exec(str || ''); | ||
var parts = {}; | ||
if (typeof(str) === 'undefined' || str === null || str === '') { | ||
return pairs; | ||
} | ||
parserKeys.forEach(function(key, i) { | ||
parts[key] = m[i] || ''; | ||
}); | ||
if (str.indexOf('?') === 0) { | ||
str = str.substring(1); | ||
} | ||
return parts; | ||
} | ||
ps = str.toString().split(/[&;]/); | ||
/** | ||
* Breaks a query string down into an array of key/value pairs | ||
* @param {string} str query | ||
* @return {array} array of arrays (key/value pairs) | ||
*/ | ||
function parseQuery(str) { | ||
var i, ps, p, n, k, v; | ||
var pairs = []; | ||
for (i = 0; i < ps.length; i++) { | ||
p = ps[i]; | ||
kvp = p.split('='); | ||
k = kvp[0]; | ||
v = p.indexOf('=') === -1 ? null : (kvp[1] === null ? '' : kvp[1]); | ||
pairs.push([k, v]); | ||
} | ||
return pairs; | ||
if (typeof(str) === 'undefined' || str === null || str === '') { | ||
return pairs; | ||
} | ||
/** | ||
* Creates a new Uri object | ||
* @constructor | ||
* @param {string} str | ||
*/ | ||
function Uri(str) { | ||
this.uriParts = parseUri(str); | ||
this.queryPairs = parseQuery(this.uriParts.query); | ||
this.hasAuthorityPrefixUserPref = null; | ||
if (str.indexOf('?') === 0) { | ||
str = str.substring(1); | ||
} | ||
/** | ||
* Define getter/setter methods | ||
*/ | ||
['protocol', 'userInfo', 'host', 'port', 'path', 'anchor'].forEach(function(key) { | ||
Uri.prototype[key] = function(val) { | ||
if (typeof val !== 'undefined') { | ||
this.uriParts[key] = val; | ||
} | ||
return this.uriParts[key]; | ||
}; | ||
}); | ||
ps = str.toString().split(re.query_separator); | ||
/** | ||
* if there is no protocol, the leading // can be enabled or disabled | ||
* @param {Boolean} val | ||
* @return {Boolean} | ||
*/ | ||
Uri.prototype.hasAuthorityPrefix = function(val) { | ||
if (typeof val !== 'undefined') { | ||
this.hasAuthorityPrefixUserPref = val; | ||
} | ||
for (i = 0; i < ps.length; i++) { | ||
p = ps[i]; | ||
n = p.indexOf('='); | ||
if (this.hasAuthorityPrefixUserPref === null) { | ||
return (this.uriParts.source.indexOf('//') !== -1); | ||
} else { | ||
return this.hasAuthorityPrefixUserPref; | ||
} | ||
}; | ||
if (n !== 0) { | ||
k = decodeURIComponent(p.substring(0, n)); | ||
v = decodeURIComponent(p.substring(n + 1)); | ||
pairs.push(n === -1 ? [p, null] : [k, v]); | ||
} | ||
/** | ||
* Serializes the internal state of the query pairs | ||
* @param {string} [val] set a new query string | ||
* @return {string} query string | ||
*/ | ||
Uri.prototype.query = function(val) { | ||
var s = '', | ||
i, param; | ||
} | ||
return pairs; | ||
} | ||
if (typeof val !== 'undefined') { | ||
this.queryPairs = parseQuery(val); | ||
} | ||
/** | ||
* Creates a new Uri object | ||
* @constructor | ||
* @param {string} str | ||
*/ | ||
function Uri(str) { | ||
this.uriParts = parseUri(str); | ||
this.queryPairs = parseQuery(this.uriParts.query); | ||
this.hasAuthorityPrefixUserPref = null; | ||
} | ||
for (i = 0; i < this.queryPairs.length; i++) { | ||
param = this.queryPairs[i]; | ||
if (s.length > 0) { | ||
s += '&'; | ||
} | ||
if (param[1] === null) { | ||
s += param[0]; | ||
} else { | ||
s += param.join('='); | ||
} | ||
} | ||
return s.length > 0 ? '?' + s : s; | ||
/** | ||
* Define getter/setter methods | ||
*/ | ||
['protocol', 'userInfo', 'host', 'port', 'path', 'anchor'].forEach(function(key) { | ||
Uri.prototype[key] = function(val) { | ||
if (typeof val !== 'undefined') { | ||
this.uriParts[key] = val; | ||
} | ||
return this.uriParts[key]; | ||
}; | ||
}); | ||
/** | ||
* returns the first query param value found for the key | ||
* @param {string} key query key | ||
* @return {string} first value found for key | ||
*/ | ||
Uri.prototype.getQueryParamValue = function (key) { | ||
var param, i; | ||
for (i = 0; i < this.queryPairs.length; i++) { | ||
param = this.queryPairs[i]; | ||
if (decode(key) === decode(param[0])) { | ||
return param[1]; | ||
} | ||
} | ||
}; | ||
/** | ||
* if there is no protocol, the leading // can be enabled or disabled | ||
* @param {Boolean} val | ||
* @return {Boolean} | ||
*/ | ||
Uri.prototype.hasAuthorityPrefix = function(val) { | ||
if (typeof val !== 'undefined') { | ||
this.hasAuthorityPrefixUserPref = val; | ||
} | ||
/** | ||
* returns an array of query param values for the key | ||
* @param {string} key query key | ||
* @return {array} array of values | ||
*/ | ||
Uri.prototype.getQueryParamValues = function (key) { | ||
var arr = [], | ||
i, param; | ||
for (i = 0; i < this.queryPairs.length; i++) { | ||
param = this.queryPairs[i]; | ||
if (decode(key) === decode(param[0])) { | ||
arr.push(param[1]); | ||
} | ||
} | ||
return arr; | ||
}; | ||
if (this.hasAuthorityPrefixUserPref === null) { | ||
return (this.uriParts.source.indexOf('//') !== -1); | ||
} else { | ||
return this.hasAuthorityPrefixUserPref; | ||
} | ||
}; | ||
/** | ||
* removes query parameters | ||
* @param {string} key remove values for key | ||
* @param {val} [val] remove a specific value, otherwise removes all | ||
* @return {Uri} returns self for fluent chaining | ||
*/ | ||
Uri.prototype.deleteQueryParam = function (key, val) { | ||
var arr = [], | ||
i, param, keyMatchesFilter, valMatchesFilter; | ||
/** | ||
* Serializes the internal state of the query pairs | ||
* @param {string} [val] set a new query string | ||
* @return {string} query string | ||
*/ | ||
Uri.prototype.query = function(val) { | ||
var s = '', i, param; | ||
for (i = 0; i < this.queryPairs.length; i++) { | ||
if (typeof val !== 'undefined') { | ||
this.queryPairs = parseQuery(val); | ||
} | ||
param = this.queryPairs[i]; | ||
keyMatchesFilter = decode(param[0]) === decode(key); | ||
valMatchesFilter = decode(param[1]) === decode(val); | ||
if ((arguments.length === 1 && !keyMatchesFilter) || (arguments.length === 2 && !keyMatchesFilter && !valMatchesFilter)) { | ||
arr.push(param); | ||
} | ||
for (i = 0; i < this.queryPairs.length; i++) { | ||
param = this.queryPairs[i]; | ||
if (s.length > 0) { | ||
s += '&'; | ||
} | ||
if (param[1] === null) { | ||
s += param[0]; | ||
} else { | ||
s += param[0]; | ||
s += '='; | ||
if (param[1]) { | ||
s += encodeURIComponent(param[1]); | ||
} | ||
} | ||
} | ||
return s.length > 0 ? '?' + s : s; | ||
}; | ||
this.queryPairs = arr; | ||
/** | ||
* returns the first query param value found for the key | ||
* @param {string} key query key | ||
* @return {string} first value found for key | ||
*/ | ||
Uri.prototype.getQueryParamValue = function (key) { | ||
var param, i; | ||
for (i = 0; i < this.queryPairs.length; i++) { | ||
param = this.queryPairs[i]; | ||
if (key === param[0]) { | ||
return param[1]; | ||
} | ||
} | ||
}; | ||
return this; | ||
}; | ||
/** | ||
* returns an array of query param values for the key | ||
* @param {string} key query key | ||
* @return {array} array of values | ||
*/ | ||
Uri.prototype.getQueryParamValues = function (key) { | ||
var arr = [], i, param; | ||
for (i = 0; i < this.queryPairs.length; i++) { | ||
param = this.queryPairs[i]; | ||
if (key === param[0]) { | ||
arr.push(param[1]); | ||
} | ||
} | ||
return arr; | ||
}; | ||
/** | ||
* adds a query parameter | ||
* @param {string} key add values for key | ||
* @param {string} val value to add | ||
* @param {integer} [index] specific index to add the value at | ||
* @return {Uri} returns self for fluent chaining | ||
*/ | ||
Uri.prototype.addQueryParam = function (key, val, index) { | ||
if (arguments.length === 3 && index !== -1) { | ||
index = Math.min(index, this.queryPairs.length); | ||
this.queryPairs.splice(index, 0, [key, val]); | ||
} else if (arguments.length > 0) { | ||
this.queryPairs.push([key, val]); | ||
} | ||
return this; | ||
}; | ||
/** | ||
* removes query parameters | ||
* @param {string} key remove values for key | ||
* @param {val} [val] remove a specific value, otherwise removes all | ||
* @return {Uri} returns self for fluent chaining | ||
*/ | ||
Uri.prototype.deleteQueryParam = function (key, val) { | ||
var arr = [], i, param, keyMatchesFilter, valMatchesFilter; | ||
/** | ||
* replaces query param values | ||
* @param {string} key key to replace value for | ||
* @param {string} newVal new value | ||
* @param {string} [oldVal] replace only one specific value (otherwise replaces all) | ||
* @return {Uri} returns self for fluent chaining | ||
*/ | ||
Uri.prototype.replaceQueryParam = function (key, newVal, oldVal) { | ||
for (i = 0; i < this.queryPairs.length; i++) { | ||
var index = -1, | ||
i, param; | ||
param = this.queryPairs[i]; | ||
keyMatchesFilter = decode(param[0]) === decode(key); | ||
valMatchesFilter = param[1] === val; | ||
if (arguments.length === 3) { | ||
for (i = 0; i < this.queryPairs.length; i++) { | ||
param = this.queryPairs[i]; | ||
if (decode(param[0]) === decode(key) && decodeURIComponent(param[1]) === decode(oldVal)) { | ||
index = i; | ||
break; | ||
} | ||
} | ||
this.deleteQueryParam(key, oldVal).addQueryParam(key, newVal, index); | ||
} else { | ||
for (i = 0; i < this.queryPairs.length; i++) { | ||
param = this.queryPairs[i]; | ||
if (decode(param[0]) === decode(key)) { | ||
index = i; | ||
break; | ||
} | ||
} | ||
this.deleteQueryParam(key); | ||
this.addQueryParam(key, newVal, index); | ||
} | ||
return this; | ||
}; | ||
if ((arguments.length === 1 && !keyMatchesFilter) || (arguments.length === 2 && (!keyMatchesFilter || !valMatchesFilter))) { | ||
arr.push(param); | ||
} | ||
} | ||
/** | ||
* Define fluent setter methods (setProtocol, setHasAuthorityPrefix, etc) | ||
*/ | ||
['protocol', 'hasAuthorityPrefix', 'userInfo', 'host', 'port', 'path', 'query', 'anchor'].forEach(function(key) { | ||
var method = 'set' + key.charAt(0).toUpperCase() + key.slice(1); | ||
Uri.prototype[method] = function(val) { | ||
this[key](val); | ||
return this; | ||
}; | ||
}); | ||
this.queryPairs = arr; | ||
/** | ||
* Scheme name, colon and doubleslash, as required | ||
* @return {string} http:// or possibly just // | ||
*/ | ||
Uri.prototype.scheme = function() { | ||
return this; | ||
}; | ||
var s = ''; | ||
/** | ||
* adds a query parameter | ||
* @param {string} key add values for key | ||
* @param {string} val value to add | ||
* @param {integer} [index] specific index to add the value at | ||
* @return {Uri} returns self for fluent chaining | ||
*/ | ||
Uri.prototype.addQueryParam = function (key, val, index) { | ||
if (arguments.length === 3 && index !== -1) { | ||
index = Math.min(index, this.queryPairs.length); | ||
this.queryPairs.splice(index, 0, [key, val]); | ||
} else if (arguments.length > 0) { | ||
this.queryPairs.push([key, val]); | ||
} | ||
return this; | ||
}; | ||
if (this.protocol()) { | ||
s += this.protocol(); | ||
if (this.protocol().indexOf(':') !== this.protocol().length - 1) { | ||
s += ':'; | ||
} | ||
s += '//'; | ||
} else { | ||
if (this.hasAuthorityPrefix() && this.host()) { | ||
s += '//'; | ||
} | ||
/** | ||
* replaces query param values | ||
* @param {string} key key to replace value for | ||
* @param {string} newVal new value | ||
* @param {string} [oldVal] replace only one specific value (otherwise replaces all) | ||
* @return {Uri} returns self for fluent chaining | ||
*/ | ||
Uri.prototype.replaceQueryParam = function (key, newVal, oldVal) { | ||
var index = -1, i, param; | ||
if (arguments.length === 3) { | ||
for (i = 0; i < this.queryPairs.length; i++) { | ||
param = this.queryPairs[i]; | ||
if (decode(param[0]) === decode(key) && decodeURIComponent(param[1]) === decode(oldVal)) { | ||
index = i; | ||
break; | ||
} | ||
} | ||
this.deleteQueryParam(key, oldVal).addQueryParam(key, newVal, index); | ||
} else { | ||
for (i = 0; i < this.queryPairs.length; i++) { | ||
param = this.queryPairs[i]; | ||
if (decode(param[0]) === decode(key)) { | ||
index = i; | ||
break; | ||
} | ||
} | ||
this.deleteQueryParam(key); | ||
this.addQueryParam(key, newVal, index); | ||
} | ||
return this; | ||
}; | ||
return s; | ||
/** | ||
* Define fluent setter methods (setProtocol, setHasAuthorityPrefix, etc) | ||
*/ | ||
['protocol', 'hasAuthorityPrefix', 'userInfo', 'host', 'port', 'path', 'query', 'anchor'].forEach(function(key) { | ||
var method = 'set' + key.charAt(0).toUpperCase() + key.slice(1); | ||
Uri.prototype[method] = function(val) { | ||
this[key](val); | ||
return this; | ||
}; | ||
}); | ||
/** | ||
* Same as Mozilla nsIURI.prePath | ||
* @return {string} scheme://user:password@host:port | ||
* @see https://developer.mozilla.org/en/nsIURI | ||
*/ | ||
Uri.prototype.origin = function() { | ||
/** | ||
* Scheme name, colon and doubleslash, as required | ||
* @return {string} http:// or possibly just // | ||
*/ | ||
Uri.prototype.scheme = function() { | ||
var s = ''; | ||
var s = this.scheme(); | ||
if (this.protocol()) { | ||
s += this.protocol(); | ||
if (this.protocol().indexOf(':') !== this.protocol().length - 1) { | ||
s += ':'; | ||
} | ||
s += '//'; | ||
} else { | ||
if (this.hasAuthorityPrefix() && this.host()) { | ||
s += '//'; | ||
} | ||
} | ||
if (this.userInfo() && this.host()) { | ||
s += this.userInfo(); | ||
if (this.userInfo().indexOf('@') !== this.userInfo().length - 1) { | ||
s += '@'; | ||
} | ||
} | ||
return s; | ||
}; | ||
if (this.host()) { | ||
s += this.host(); | ||
if (this.port()) { | ||
s += ':' + this.port(); | ||
} | ||
} | ||
/** | ||
* Same as Mozilla nsIURI.prePath | ||
* @return {string} scheme://user:password@host:port | ||
* @see https://developer.mozilla.org/en/nsIURI | ||
*/ | ||
Uri.prototype.origin = function() { | ||
var s = this.scheme(); | ||
return s; | ||
}; | ||
if (this.userInfo() && this.host()) { | ||
s += this.userInfo(); | ||
if (this.userInfo().indexOf('@') !== this.userInfo().length - 1) { | ||
s += '@'; | ||
} | ||
} | ||
/** | ||
* Serializes the internal state of the Uri object | ||
* @return {string} | ||
*/ | ||
Uri.prototype.toString = function() { | ||
if (this.host()) { | ||
s += this.host(); | ||
if (this.port()) { | ||
s += ':' + this.port(); | ||
} | ||
} | ||
var s = this.origin(); | ||
return s; | ||
}; | ||
if (this.path()) { | ||
s += this.path(); | ||
} else { | ||
if (this.host() && (this.query().toString() || this.anchor())) { | ||
s += '/'; | ||
} | ||
} | ||
if (this.query().toString()) { | ||
if (this.query().toString().indexOf('?') !== 0) { | ||
s += '?'; | ||
} | ||
s += this.query().toString(); | ||
} | ||
/** | ||
* Adds a trailing slash to the path | ||
*/ | ||
Uri.prototype.addTrailingSlash = function() { | ||
var path = this.path() || '' | ||
if (this.anchor()) { | ||
if (this.anchor().indexOf('#') !== 0) { | ||
s += '#'; | ||
} | ||
s += this.anchor(); | ||
} | ||
if (path.substr(-1) !== '/') { | ||
this.path(path + '/') | ||
} | ||
return s; | ||
}; | ||
return this; | ||
} | ||
/** | ||
* Clone a Uri object | ||
* @return {Uri} duplicate copy of the Uri | ||
*/ | ||
Uri.prototype.clone = function() { | ||
return new Uri(this.toString()); | ||
}; | ||
/** | ||
* Serializes the internal state of the Uri object | ||
* @return {string} | ||
*/ | ||
Uri.prototype.toString = function() { | ||
var path, s = this.origin(); | ||
/** | ||
* export via CommonJS, otherwise leak a global | ||
*/ | ||
if (typeof module === 'undefined') { | ||
global.Uri = Uri; | ||
if (this.path()) { | ||
path = this.path(); | ||
if (!(re.ends_with_slashes.test(s) || re.starts_with_slashes.test(path))) { | ||
s += '/'; | ||
} else { | ||
if (s) { | ||
s.replace(re.ends_with_slashes, '/'); | ||
} | ||
path = path.replace(re.starts_with_slashes, '/'); | ||
} | ||
s += path; | ||
} else { | ||
module.exports = Uri; | ||
if (this.host() && (this.query().toString() || this.anchor())) { | ||
s += '/'; | ||
} | ||
} | ||
if (this.query().toString()) { | ||
if (this.query().toString().indexOf('?') !== 0) { | ||
s += '?'; | ||
} | ||
s += this.query().toString(); | ||
} | ||
if (this.anchor()) { | ||
if (this.anchor().indexOf('#') !== 0) { | ||
s += '#'; | ||
} | ||
s += this.anchor(); | ||
} | ||
return s; | ||
}; | ||
/** | ||
* Clone a Uri object | ||
* @return {Uri} duplicate copy of the Uri | ||
*/ | ||
Uri.prototype.clone = function() { | ||
return new Uri(this.toString()); | ||
}; | ||
/** | ||
* export via AMD or CommonJS, otherwise leak a global | ||
*/ | ||
if (typeof define === 'function' && define.amd) { | ||
define(function() { | ||
return Uri; | ||
}); | ||
} else if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { | ||
module.exports = Uri; | ||
} else { | ||
global.Uri = Uri; | ||
} | ||
}(this)); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
13
824
40602
4
1
99
1