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