1/* 2 * JQuery URL Parser plugin 3 * Developed and maintanined by Mark Perkins, [email protected] 4 * Source repository: https://github.com/allmarkedup/jQuery-URL-Parser 5 * Licensed under an MIT-style license. See https://github.com/allmarkedup/jQuery-URL-Parser/blob/master/LICENSE for details. 6 */ 7 8;(function($, undefined) { 9 10 var tag2attr = { 11 a : 'href', 12 img : 'src', 13 form : 'action', 14 base : 'href', 15 script : 'src', 16 iframe : 'src', 17 link : 'href' 18 }, 19 20 key = ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","fragment"], // keys available to query 21 22 aliases = { "anchor" : "fragment" }, // aliases for backwards compatability 23 24 parser = { 25 strict : /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, //less intuitive, more accurate to the specs 26 loose : /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // more intuitive, fails on relative paths and deviates from specs 27 }, 28 29 querystring_parser = /(?:^|&|;)([^&=;]*)=?([^&;]*)/g, // supports both ampersand and semicolon-delimted query string key/value pairs 30 31 fragment_parser = /(?:^|&|;)([^&=;]*)=?([^&;]*)/g; // supports both ampersand and semicolon-delimted fragment key/value pairs 32 33 function parseUri( url, strictMode ) 34 { 35 var str = decodeURI( url ), 36 res = parser[ strictMode || false ? "strict" : "loose" ].exec( str ), 37 uri = { attr : {}, param : {}, seg : {} }, 38 i = 14; 39 40 while ( i-- ) 41 { 42 uri.attr[ key[i] ] = res[i] || ""; 43 } 44 45 // build query and fragment parameters 46 47 uri.param['query'] = {}; 48 uri.param['fragment'] = {}; 49 50 uri.attr['query'].replace( querystring_parser, function ( $0, $1, $2 ){ 51 if ($1) 52 { 53 uri.param['query'][$1] = $2; 54 } 55 }); 56 57 uri.attr['fragment'].replace( fragment_parser, function ( $0, $1, $2 ){ 58 if ($1) 59 { 60 uri.param['fragment'][$1] = $2; 61 } 62 }); 63 64 // split path and fragement into segments 65 66 uri.seg['path'] = uri.attr.path.replace(/^\/+|\/+$/g,'').split('/'); 67 68 uri.seg['fragment'] = uri.attr.fragment.replace(/^\/+|\/+$/g,'').split('/'); 69 70 // compile a 'base' domain attribute 71 72 uri.attr['base'] = uri.attr.host ? uri.attr.protocol+"://"+uri.attr.host + (uri.attr.port ? ":"+uri.attr.port : '') : ''; 73 74 return uri; 75 }; 76 77 function getAttrName( elm ) 78 { 79 var tn = elm.tagName; 80 if ( tn !== undefined ) return tag2attr[tn.toLowerCase()]; 81 return tn; 82 } 83 84 $.fn.url = function( strictMode ) 85 { 86 var url = ''; 87 88 if ( this.length ) 89 { 90 url = $(this).attr( getAttrName(this[0]) ) || ''; 91 } 92 93 return $.url( url, strictMode ); 94 }; 95 96 $.url = function( url, strictMode ) 97 { 98 if ( arguments.length === 1 && url === true ) 99 { 100 strictMode = true; 101 url = undefined; 102 } 103 104 strictMode = strictMode || false; 105 url = url || window.location.toString(); 106 107 return { 108 109 data : parseUri(url, strictMode), 110 111 // get various attributes from the URI 112 attr : function( attr ) 113 { 114 attr = aliases[attr] || attr; 115 return attr !== undefined ? this.data.attr[attr] : this.data.attr; 116 }, 117 118 // return query string parameters 119 param : function( param ) 120 { 121 return param !== undefined ? this.data.param.query[param] : this.data.param.query; 122 }, 123 124 // return fragment parameters 125 fparam : function( param ) 126 { 127 return param !== undefined ? this.data.param.fragment[param] : this.data.param.fragment; 128 }, 129 130 // return path segments 131 segment : function( seg ) 132 { 133 if ( seg === undefined ) 134 { 135 return this.data.seg.path; 136 } 137 else 138 { 139 seg = seg < 0 ? this.data.seg.path.length + seg : seg - 1; // negative segments count from the end 140 return this.data.seg.path[seg]; 141 } 142 }, 143 144 // return fragment segments 145 fsegment : function( seg ) 146 { 147 if ( seg === undefined ) 148 { 149 return this.data.seg.fragment; 150 } 151 else 152 { 153 seg = seg < 0 ? this.data.seg.fragment.length + seg : seg - 1; // negative segments count from the end 154 return this.data.seg.fragment[seg]; 155 } 156 } 157 158 }; 159 160 }; 161 162})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.