Created
July 22, 2013 08:16
-
-
Save tjntun/6052167 to your computer and use it in GitHub Desktop.
A JavaScript URL parser v2.3.1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * Purl (A JavaScript URL parser) v2.3.1 | |
| * Developed and maintanined by Mark Perkins, [email protected] | |
| * Source repository: https://github.com/allmarkedup/jQuery-URL-Parser | |
| * Licensed under an MIT-style license. See https://github.com/allmarkedup/jQuery-URL-Parser/blob/master/LICENSE for details. | |
| */ | |
| ;(function(factory) { | |
| if (typeof define === 'function' && define.amd) { | |
| define(factory); | |
| } else { | |
| window.purl = factory(); | |
| } | |
| })(function() { | |
| var tag2attr = { | |
| a : 'href', | |
| img : 'src', | |
| form : 'action', | |
| base : 'href', | |
| script : 'src', | |
| iframe : 'src', | |
| link : 'href' | |
| }, | |
| key = ['source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'fragment'], // keys available to query | |
| aliases = { 'anchor' : 'fragment' }, // aliases for backwards compatability | |
| parser = { | |
| strict : /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, //less intuitive, more accurate to the specs | |
| loose : /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // more intuitive, fails on relative paths and deviates from specs | |
| }, | |
| isint = /^[0-9]+$/; | |
| function parseUri( url, strictMode ) { | |
| var str = decodeURI( url ), | |
| res = parser[ strictMode || false ? 'strict' : 'loose' ].exec( str ), | |
| uri = { attr : {}, param : {}, seg : {} }, | |
| i = 14; | |
| while ( i-- ) { | |
| uri.attr[ key[i] ] = res[i] || ''; | |
| } | |
| // build query and fragment parameters | |
| uri.param['query'] = parseString(uri.attr['query']); | |
| uri.param['fragment'] = parseString(uri.attr['fragment']); | |
| // split path and fragement into segments | |
| uri.seg['path'] = uri.attr.path.replace(/^\/+|\/+$/g,'').split('/'); | |
| uri.seg['fragment'] = uri.attr.fragment.replace(/^\/+|\/+$/g,'').split('/'); | |
| // compile a 'base' domain attribute | |
| uri.attr['base'] = uri.attr.host ? (uri.attr.protocol ? uri.attr.protocol+'://'+uri.attr.host : uri.attr.host) + (uri.attr.port ? ':'+uri.attr.port : '') : ''; | |
| return uri; | |
| } | |
| function getAttrName( elm ) { | |
| var tn = elm.tagName; | |
| if ( typeof tn !== 'undefined' ) return tag2attr[tn.toLowerCase()]; | |
| return tn; | |
| } | |
| function promote(parent, key) { | |
| if (parent[key].length === 0) return parent[key] = {}; | |
| var t = {}; | |
| for (var i in parent[key]) t[i] = parent[key][i]; | |
| parent[key] = t; | |
| return t; | |
| } | |
| function parse(parts, parent, key, val) { | |
| var part = parts.shift(); | |
| if (!part) { | |
| if (isArray(parent[key])) { | |
| parent[key].push(val); | |
| } else if ('object' == typeof parent[key]) { | |
| parent[key] = val; | |
| } else if ('undefined' == typeof parent[key]) { | |
| parent[key] = val; | |
| } else { | |
| parent[key] = [parent[key], val]; | |
| } | |
| } else { | |
| var obj = parent[key] = parent[key] || []; | |
| if (']' == part) { | |
| if (isArray(obj)) { | |
| if ('' !== val) obj.push(val); | |
| } else if ('object' == typeof obj) { | |
| obj[keys(obj).length] = val; | |
| } else { | |
| obj = parent[key] = [parent[key], val]; | |
| } | |
| } else if (~part.indexOf(']')) { | |
| part = part.substr(0, part.length - 1); | |
| if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); | |
| parse(parts, obj, part, val); | |
| // key | |
| } else { | |
| if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); | |
| parse(parts, obj, part, val); | |
| } | |
| } | |
| } | |
| function merge(parent, key, val) { | |
| if (~key.indexOf(']')) { | |
| var parts = key.split('['); | |
| parse(parts, parent, 'base', val); | |
| } else { | |
| if (!isint.test(key) && isArray(parent.base)) { | |
| var t = {}; | |
| for (var k in parent.base) t[k] = parent.base[k]; | |
| parent.base = t; | |
| } | |
| if (key !== '') { | |
| set(parent.base, key, val); | |
| } | |
| } | |
| return parent; | |
| } | |
| function parseString(str) { | |
| return reduce(String(str).split(/&|;/), function(ret, pair) { | |
| try { | |
| pair = decodeURIComponent(pair.replace(/\+/g, ' ')); | |
| } catch(e) { | |
| // ignore | |
| } | |
| var eql = pair.indexOf('='), | |
| brace = lastBraceInKey(pair), | |
| key = pair.substr(0, brace || eql), | |
| val = pair.substr(brace || eql, pair.length); | |
| val = val.substr(val.indexOf('=') + 1, val.length); | |
| if (key === '') { | |
| key = pair; | |
| val = ''; | |
| } | |
| return merge(ret, key, val); | |
| }, { base: {} }).base; | |
| } | |
| function set(obj, key, val) { | |
| var v = obj[key]; | |
| if (typeof v === 'undefined') { | |
| obj[key] = val; | |
| } else if (isArray(v)) { | |
| v.push(val); | |
| } else { | |
| obj[key] = [v, val]; | |
| } | |
| } | |
| function lastBraceInKey(str) { | |
| var len = str.length, | |
| brace, | |
| c; | |
| for (var i = 0; i < len; ++i) { | |
| c = str[i]; | |
| if (']' == c) brace = false; | |
| if ('[' == c) brace = true; | |
| if ('=' == c && !brace) return i; | |
| } | |
| } | |
| function reduce(obj, accumulator){ | |
| var i = 0, | |
| l = obj.length >> 0, | |
| curr = arguments[2]; | |
| while (i < l) { | |
| if (i in obj) curr = accumulator.call(undefined, curr, obj[i], i, obj); | |
| ++i; | |
| } | |
| return curr; | |
| } | |
| function isArray(vArg) { | |
| return Object.prototype.toString.call(vArg) === "[object Array]"; | |
| } | |
| function keys(obj) { | |
| var key_array = []; | |
| for ( var prop in obj ) { | |
| if ( obj.hasOwnProperty(prop) ) key_array.push(prop); | |
| } | |
| return key_array; | |
| } | |
| function purl( url, strictMode ) { | |
| if ( arguments.length === 1 && url === true ) { | |
| strictMode = true; | |
| url = undefined; | |
| } | |
| strictMode = strictMode || false; | |
| url = url || window.location.toString(); | |
| return { | |
| data : parseUri(url, strictMode), | |
| // get various attributes from the URI | |
| attr : function( attr ) { | |
| attr = aliases[attr] || attr; | |
| return typeof attr !== 'undefined' ? this.data.attr[attr] : this.data.attr; | |
| }, | |
| // return query string parameters | |
| param : function( param ) { | |
| return typeof param !== 'undefined' ? this.data.param.query[param] : this.data.param.query; | |
| }, | |
| // return fragment parameters | |
| fparam : function( param ) { | |
| return typeof param !== 'undefined' ? this.data.param.fragment[param] : this.data.param.fragment; | |
| }, | |
| // return path segments | |
| segment : function( seg ) { | |
| if ( typeof seg === 'undefined' ) { | |
| return this.data.seg.path; | |
| } else { | |
| seg = seg < 0 ? this.data.seg.path.length + seg : seg - 1; // negative segments count from the end | |
| return this.data.seg.path[seg]; | |
| } | |
| }, | |
| // return fragment segments | |
| fsegment : function( seg ) { | |
| if ( typeof seg === 'undefined' ) { | |
| return this.data.seg.fragment; | |
| } else { | |
| seg = seg < 0 ? this.data.seg.fragment.length + seg : seg - 1; // negative segments count from the end | |
| return this.data.seg.fragment[seg]; | |
| } | |
| } | |
| }; | |
| } | |
| purl.jQuery = function($){ | |
| if ($ != null) { | |
| $.fn.url = function( strictMode ) { | |
| var url = ''; | |
| if ( this.length ) { | |
| url = $(this).attr( getAttrName(this[0]) ) || ''; | |
| } | |
| return purl( url, strictMode ); | |
| }; | |
| $.url = purl; | |
| } | |
| }; | |
| purl.jQuery(window.jQuery); | |
| return purl; | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment