mirror of
https://github.com/wahyd4/Libr-mobile.git
synced 2026-08-16 16:28:29 +10:00
307 lines
12 KiB
HTML
307 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>JSDoc: Source: urlMatcherFactory.js</title>
|
|
|
|
<script src="scripts/prettify/prettify.js"> </script>
|
|
<script src="scripts/prettify/lang-css.js"> </script>
|
|
<!--[if lt IE 9]>
|
|
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
<![endif]-->
|
|
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
|
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id="main">
|
|
|
|
<h1 class="page-title">Source: urlMatcherFactory.js</h1>
|
|
|
|
|
|
|
|
|
|
|
|
<section>
|
|
<article>
|
|
<pre class="prettyprint source"><code>/**
|
|
* Matches URLs against patterns and extracts named parameters from the path or the search
|
|
* part of the URL. A URL pattern consists of a path pattern, optionally followed by '?' and a list
|
|
* of search parameters. Multiple search parameter names are separated by '&'. Search parameters
|
|
* do not influence whether or not a URL is matched, but their values are passed through into
|
|
* the matched parameters returned by {@link UrlMatcher#exec exec}.
|
|
*
|
|
* Path parameter placeholders can be specified using simple colon/catch-all syntax or curly brace
|
|
* syntax, which optionally allows a regular expression for the parameter to be specified:
|
|
*
|
|
* * ':' name - colon placeholder
|
|
* * '*' name - catch-all placeholder
|
|
* * '{' name '}' - curly placeholder
|
|
* * '{' name ':' regexp '}' - curly placeholder with regexp. Should the regexp itself contain
|
|
* curly braces, they must be in matched pairs or escaped with a backslash.
|
|
*
|
|
* Parameter names may contain only word characters (latin letters, digits, and underscore) and
|
|
* must be unique within the pattern (across both path and search parameters). For colon
|
|
* placeholders or curly placeholders without an explicit regexp, a path parameter matches any
|
|
* number of characters other than '/'. For catch-all placeholders the path parameter matches
|
|
* any number of characters.
|
|
*
|
|
* ### Examples
|
|
*
|
|
* * '/hello/' - Matches only if the path is exactly '/hello/'. There is no special treatment for
|
|
* trailing slashes, and patterns have to match the entire path, not just a prefix.
|
|
* * '/user/:id' - Matches '/user/bob' or '/user/1234!!!' or even '/user/' but not '/user' or
|
|
* '/user/bob/details'. The second path segment will be captured as the parameter 'id'.
|
|
* * '/user/{id}' - Same as the previous example, but using curly brace syntax.
|
|
* * '/user/{id:[^/]*}' - Same as the previous example.
|
|
* * '/user/{id:[0-9a-fA-F]{1,8}}' - Similar to the previous example, but only matches if the id
|
|
* parameter consists of 1 to 8 hex digits.
|
|
* * '/files/{path:.*}' - Matches any URL starting with '/files/' and captures the rest of the
|
|
* path into the parameter 'path'.
|
|
* * '/files/*path' - ditto.
|
|
*
|
|
* @constructor
|
|
* @param {string} pattern the pattern to compile into a matcher.
|
|
*
|
|
* @property {string} prefix A static prefix of this pattern. The matcher guarantees that any
|
|
* URL matching this matcher (i.e. any string for which {@link UrlMatcher#exec exec()} returns
|
|
* non-null) will start with this prefix.
|
|
*/
|
|
function UrlMatcher(pattern) {
|
|
|
|
// Find all placeholders and create a compiled pattern, using either classic or curly syntax:
|
|
// '*' name
|
|
// ':' name
|
|
// '{' name '}'
|
|
// '{' name ':' regexp '}'
|
|
// The regular expression is somewhat complicated due to the need to allow curly braces
|
|
// inside the regular expression. The placeholder regexp breaks down as follows:
|
|
// ([:*])(\w+) classic placeholder ($1 / $2)
|
|
// \{(\w+)(?:\:( ... ))?\} curly brace placeholder ($3) with optional regexp ... ($4)
|
|
// (?: ... | ... | ... )+ the regexp consists of any number of atoms, an atom being either
|
|
// [^{}\\]+ - anything other than curly braces or backslash
|
|
// \\. - a backslash escape
|
|
// \{(?:[^{}\\]+|\\.)*\} - a matched set of curly braces containing other atoms
|
|
var placeholder = /([:*])(\w+)|\{(\w+)(?:\:((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,
|
|
names = {}, compiled = '^', last = 0, m,
|
|
segments = this.segments = [],
|
|
params = this.params = [];
|
|
|
|
function addParameter(id) {
|
|
if (!/^\w+(-+\w+)*$/.test(id)) throw new Error("Invalid parameter name '" + id + "' in pattern '" + pattern + "'");
|
|
if (names[id]) throw new Error("Duplicate parameter name '" + id + "' in pattern '" + pattern + "'");
|
|
names[id] = true;
|
|
params.push(id);
|
|
}
|
|
|
|
function quoteRegExp(string) {
|
|
return string.replace(/[\\\[\]\^$*+?.()|{}]/g, "\\$&");
|
|
}
|
|
|
|
this.source = pattern;
|
|
|
|
// Split into static segments separated by path parameter placeholders.
|
|
// The number of segments is always 1 more than the number of parameters.
|
|
var id, regexp, segment;
|
|
while ((m = placeholder.exec(pattern))) {
|
|
id = m[2] || m[3]; // IE[78] returns '' for unmatched groups instead of null
|
|
regexp = m[4] || (m[1] == '*' ? '.*' : '[^/]*');
|
|
segment = pattern.substring(last, m.index);
|
|
if (segment.indexOf('?') >= 0) break; // we're into the search part
|
|
compiled += quoteRegExp(segment) + '(' + regexp + ')';
|
|
addParameter(id);
|
|
segments.push(segment);
|
|
last = placeholder.lastIndex;
|
|
}
|
|
segment = pattern.substring(last);
|
|
|
|
// Find any search parameter names and remove them from the last segment
|
|
var i = segment.indexOf('?');
|
|
if (i >= 0) {
|
|
var search = this.sourceSearch = segment.substring(i);
|
|
segment = segment.substring(0, i);
|
|
this.sourcePath = pattern.substring(0, last+i);
|
|
|
|
// Allow parameters to be separated by '?' as well as '&' to make concat() easier
|
|
forEach(search.substring(1).split(/[&?]/), addParameter);
|
|
} else {
|
|
this.sourcePath = pattern;
|
|
this.sourceSearch = '';
|
|
}
|
|
|
|
compiled += quoteRegExp(segment) + '$';
|
|
segments.push(segment);
|
|
this.regexp = new RegExp(compiled);
|
|
this.prefix = segments[0];
|
|
}
|
|
|
|
/**
|
|
* Returns a new matcher for a pattern constructed by appending the path part and adding the
|
|
* search parameters of the specified pattern to this pattern. The current pattern is not
|
|
* modified. This can be understood as creating a pattern for URLs that are relative to (or
|
|
* suffixes of) the current pattern.
|
|
*
|
|
* ### Example
|
|
* The following two matchers are equivalent:
|
|
* ```
|
|
* new UrlMatcher('/user/{id}?q').concat('/details?date');
|
|
* new UrlMatcher('/user/{id}/details?q&date');
|
|
* ```
|
|
*
|
|
* @param {string} pattern The pattern to append.
|
|
* @return {UrlMatcher} A matcher for the concatenated pattern.
|
|
*/
|
|
UrlMatcher.prototype.concat = function (pattern) {
|
|
// Because order of search parameters is irrelevant, we can add our own search
|
|
// parameters to the end of the new pattern. Parse the new pattern by itself
|
|
// and then join the bits together, but it's much easier to do this on a string level.
|
|
return new UrlMatcher(this.sourcePath + pattern + this.sourceSearch);
|
|
};
|
|
|
|
UrlMatcher.prototype.toString = function () {
|
|
return this.source;
|
|
};
|
|
|
|
/**
|
|
* Tests the specified path against this matcher, and returns an object containing the captured
|
|
* parameter values, or null if the path does not match. The returned object contains the values
|
|
* of any search parameters that are mentioned in the pattern, but their value may be null if
|
|
* they are not present in `searchParams`. This means that search parameters are always treated
|
|
* as optional.
|
|
*
|
|
* ### Example
|
|
* ```
|
|
* new UrlMatcher('/user/{id}?q&r').exec('/user/bob', { x:'1', q:'hello' });
|
|
* // returns { id:'bob', q:'hello', r:null }
|
|
* ```
|
|
*
|
|
* @param {string} path The URL path to match, e.g. `$location.path()`.
|
|
* @param {Object} searchParams URL search parameters, e.g. `$location.search()`.
|
|
* @return {Object} The captured parameter values.
|
|
*/
|
|
UrlMatcher.prototype.exec = function (path, searchParams) {
|
|
var m = this.regexp.exec(path);
|
|
if (!m) return null;
|
|
|
|
var params = this.params, nTotal = params.length,
|
|
nPath = this.segments.length-1,
|
|
values = {}, i;
|
|
|
|
if (nPath !== m.length - 1) throw new Error("Unbalanced capture group in route '" + this.source + "'");
|
|
|
|
for (i=0; i<nPath; i++) values[params[i]] = m[i+1];
|
|
for (/**/; i<nTotal; i++) values[params[i]] = searchParams[params[i]];
|
|
|
|
return values;
|
|
};
|
|
|
|
/**
|
|
* Returns the names of all path and search parameters of this pattern in an unspecified order.
|
|
* @return {Array.<string>} An array of parameter names. Must be treated as read-only. If the
|
|
* pattern has no parameters, an empty array is returned.
|
|
*/
|
|
UrlMatcher.prototype.parameters = function () {
|
|
return this.params;
|
|
};
|
|
|
|
/**
|
|
* Creates a URL that matches this pattern by substituting the specified values
|
|
* for the path and search parameters. Null values for path parameters are
|
|
* treated as empty strings.
|
|
*
|
|
* ### Example
|
|
* ```
|
|
* new UrlMatcher('/user/{id}?q').format({ id:'bob', q:'yes' });
|
|
* // returns '/user/bob?q=yes'
|
|
* ```
|
|
*
|
|
* @param {Object} values the values to substitute for the parameters in this pattern.
|
|
* @return {string} the formatted URL (path and optionally search part).
|
|
*/
|
|
UrlMatcher.prototype.format = function (values) {
|
|
var segments = this.segments, params = this.params;
|
|
if (!values) return segments.join('');
|
|
|
|
var nPath = segments.length-1, nTotal = params.length,
|
|
result = segments[0], i, search, value;
|
|
|
|
for (i=0; i<nPath; i++) {
|
|
value = values[params[i]];
|
|
// TODO: Maybe we should throw on null here? It's not really good style to use '' and null interchangeabley
|
|
if (value != null) result += encodeURIComponent(value);
|
|
result += segments[i+1];
|
|
}
|
|
for (/**/; i<nTotal; i++) {
|
|
value = values[params[i]];
|
|
if (value != null) {
|
|
result += (search ? '&' : '?') + params[i] + '=' + encodeURIComponent(value);
|
|
search = true;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Service. Factory for {@link UrlMatcher} instances. The factory is also available to providers
|
|
* under the name `$urlMatcherFactoryProvider`.
|
|
* @constructor
|
|
* @name $urlMatcherFactory
|
|
*/
|
|
function $UrlMatcherFactory() {
|
|
/**
|
|
* Creates a {@link UrlMatcher} for the specified pattern.
|
|
* @function
|
|
* @name $urlMatcherFactory#compile
|
|
* @methodOf $urlMatcherFactory
|
|
* @param {string} pattern The URL pattern.
|
|
* @return {UrlMatcher} The UrlMatcher.
|
|
*/
|
|
this.compile = function (pattern) {
|
|
return new UrlMatcher(pattern);
|
|
};
|
|
|
|
/**
|
|
* Returns true if the specified object is a UrlMatcher, or false otherwise.
|
|
* @function
|
|
* @name $urlMatcherFactory#isMatcher
|
|
* @methodOf $urlMatcherFactory
|
|
* @param {Object} o
|
|
* @return {boolean}
|
|
*/
|
|
this.isMatcher = function (o) {
|
|
return isObject(o) && isFunction(o.exec) && isFunction(o.format) && isFunction(o.concat);
|
|
};
|
|
|
|
this.$get = function () {
|
|
return this;
|
|
};
|
|
}
|
|
|
|
// Register as a provider so it's available to other providers
|
|
angular.module('ui.router.util').provider('$urlMatcherFactory', $UrlMatcherFactory);
|
|
</code></pre>
|
|
</article>
|
|
</section>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
<nav>
|
|
<h2><a href="index.html">Index</a></h2><h3>Modules</h3><ul><li><a href="$resolve.html">$resolve</a></li></ul><h3>Classes</h3><ul><li><a href="$templateFactory.html">$templateFactory</a></li><li><a href="$urlMatcherFactory.html">$urlMatcherFactory</a></li><li><a href="UrlMatcher.html">UrlMatcher</a></li></ul><h3>Global</h3><ul><li><a href="global.html#ancestors">ancestors</a></li><li><a href="global.html#arraySearch">arraySearch</a></li><li><a href="global.html#equalForKeys">equalForKeys</a></li><li><a href="global.html#filterByKeys">filterByKeys</a></li><li><a href="global.html#inheritParams">inheritParams</a></li><li><a href="global.html#keys">keys</a></li><li><a href="global.html#normalize">normalize</a></li></ul>
|
|
</nav>
|
|
|
|
<br clear="both">
|
|
|
|
<footer>
|
|
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Mon Dec 09 2013 13:59:32 GMT-0500 (EST)
|
|
</footer>
|
|
|
|
<script> prettyPrint(); </script>
|
|
<script src="scripts/linenumber.js"> </script>
|
|
</body>
|
|
</html>
|