Mercurial > pub > ImplabJs
comparison core/src/js/Uri.js @ 29:acdcdf1a8d21
repository reorganized
author | cin |
---|---|
date | Tue, 26 Jun 2018 19:35:44 +0300 |
parents | src/implab/Uri.js@00779cb63b12 |
children |
comparison
equal
deleted
inserted
replaced
28:d796bbbe558c | 29:acdcdf1a8d21 |
---|---|
1 define( | |
2 [ "./declare" ], | |
3 function(declare) { | |
4 function parseURI(uri) { | |
5 var schema, host, port, path, query, hash, i; | |
6 if (typeof (uri) == "string") { | |
7 if ((i = uri.indexOf(":")) >= 0 && | |
8 uri.substr(0, i).match(/^\w+$/)) { | |
9 schema = uri.substr(0, i); | |
10 uri = uri.substr(i + 1); | |
11 } | |
12 | |
13 if (uri.indexOf("//") === 0) { | |
14 uri = uri.substr(2); | |
15 if ((i = uri.indexOf("/")) >= 0) { | |
16 host = uri.substr(0, i); | |
17 uri = uri.substr(i); | |
18 } else { | |
19 host = uri; | |
20 uri = ""; | |
21 } | |
22 } | |
23 | |
24 if ((i = uri.indexOf("?")) >= 0) { | |
25 path = uri.substr(0, i); | |
26 uri = uri.substr(i + 1); | |
27 | |
28 } else { | |
29 path = uri; | |
30 uri = ""; | |
31 | |
32 if ((i = path.indexOf("#")) >= 0) { | |
33 hash = path.substr(i + 1); | |
34 path = path.substr(0, i); | |
35 } | |
36 } | |
37 | |
38 if ((i = uri.indexOf("#")) >= 0) { | |
39 query = uri.substr(0, i); | |
40 hash = uri.substr(i + 1); | |
41 } else { | |
42 query = uri; | |
43 } | |
44 } | |
45 | |
46 if (host && (i = host.lastIndexOf(":")) >= 0) { | |
47 port = host.substr(i + 1); | |
48 host = host.substr(0, i); | |
49 } | |
50 | |
51 return { | |
52 schema : schema, | |
53 host : host, | |
54 port : port, | |
55 path : path, | |
56 query : query, | |
57 hash : hash | |
58 }; | |
59 } | |
60 | |
61 function makeURI(options) { | |
62 var uri = []; | |
63 | |
64 if (options.schema) | |
65 uri.push(options.schema, ":"); | |
66 if (options.host) | |
67 uri.push("//", options.host); | |
68 if (options.host && options.port) | |
69 uri.push(":", options.port); | |
70 | |
71 if (options.path) { | |
72 if (options.host && options.path[0] != "/") | |
73 uri.push("/"); | |
74 uri.push(options.path); | |
75 } else if (options.host) { | |
76 uri.push("/"); | |
77 } | |
78 | |
79 if (options.query) | |
80 uri.push("?", options.query); | |
81 if (options.hash) | |
82 uri.push("#", options.hash); | |
83 | |
84 return uri.join(""); | |
85 } | |
86 | |
87 function reducePath(parts) { | |
88 var balance = 0, result = [], isRoot; | |
89 | |
90 for (var i = 0; i < parts.length; i++) { | |
91 var part = parts[i]; | |
92 switch (part) { | |
93 case "..": | |
94 if (balance > 0) { | |
95 result.pop(); | |
96 } else { | |
97 if (isRoot) | |
98 throw new Error("Unbalanced path: " + parts); | |
99 | |
100 result.push(part); | |
101 } | |
102 balance--; | |
103 break; | |
104 case ".": | |
105 break; | |
106 case "": | |
107 if (i === 0) { | |
108 isRoot = true; | |
109 result.push(part); | |
110 } | |
111 break; | |
112 default: | |
113 result.push(part); | |
114 balance++; | |
115 break; | |
116 } | |
117 } | |
118 | |
119 return result.join("/"); | |
120 } | |
121 | |
122 var meta = { | |
123 schema : null, | |
124 host : null, | |
125 port : null, | |
126 path : null, | |
127 query : null, | |
128 hash : null | |
129 }; | |
130 | |
131 var URI = declare(null, { | |
132 constructor : function(opts) { | |
133 if (typeof (opts) == "string") | |
134 opts = parseURI(opts); | |
135 for ( var p in meta) | |
136 if (p in opts) | |
137 this[p] = opts[p]; | |
138 }, | |
139 | |
140 clone : function() { | |
141 return new URI(this); | |
142 }, | |
143 | |
144 combine : function(rel) { | |
145 var me = this; | |
146 | |
147 if (typeof (rel) === "string") | |
148 rel = new URI(rel); | |
149 else | |
150 rel = rel.clone(); | |
151 | |
152 // //some.host:123/path?q=a#123 | |
153 if (rel.host) | |
154 return rel; | |
155 | |
156 // /abs/path?q=a#123 | |
157 if (rel.path && rel.path[0] == "/") { | |
158 if (me.host) { | |
159 rel.schema = me.schema; | |
160 rel.host = me.host; | |
161 rel.port = me.port; | |
162 } | |
163 return rel; | |
164 } | |
165 | |
166 var base = me.clone(); | |
167 | |
168 // rel/path?a=b#cd | |
169 if (rel.path) { | |
170 var segments = base.getSegments(); | |
171 segments.pop(); | |
172 segments.push.apply(segments, rel.getSegments()); | |
173 | |
174 base.path = reducePath(segments); | |
175 } | |
176 | |
177 // ?q=a#123 | |
178 if (rel.query) | |
179 base.query = rel.query; | |
180 if (rel.hash) | |
181 base.hase = rel.hash; | |
182 | |
183 return base; | |
184 }, | |
185 | |
186 optimize : function() { | |
187 this.path = reducePath(this.getSegments()); | |
188 }, | |
189 | |
190 getSegments : function() { | |
191 if (typeof (this.path) === "string") | |
192 return this.path.split("/"); | |
193 else | |
194 return []; | |
195 }, | |
196 | |
197 toString : function() { | |
198 var uri = [], me = this; | |
199 | |
200 if (me.schema) | |
201 uri.push(me.schema, ":"); | |
202 if (me.host) | |
203 uri.push("//", me.host); | |
204 if (me.host && me.port) | |
205 uri.push(":", me.port); | |
206 | |
207 if (me.path) { | |
208 if (me.host && me.path[0] != "/") | |
209 uri.push("/"); | |
210 uri.push(me.path); | |
211 } else if (me.host) { | |
212 uri.push("/"); | |
213 } | |
214 | |
215 if (me.query) | |
216 uri.push("?", me.query); | |
217 if (me.hash) | |
218 uri.push("#", me.hash); | |
219 | |
220 return uri.join(""); | |
221 } | |
222 | |
223 }); | |
224 | |
225 URI.combine = function(base, rel) { | |
226 if (typeof (base) === "string") | |
227 base = new URI(base); | |
228 return base.combine(rel).toString(); | |
229 }; | |
230 | |
231 return URI; | |
232 }); |