comparison src/implab/Uri.js @ 34:27e8e9e38e07 default tip

Слияние
author nickolay
date Wed, 05 Jun 2019 20:44:15 +0300
parents 8af8e840dd49 1dc2fd263b90
children
comparison
equal deleted inserted replaced
33:8af8e840dd49 34:27e8e9e38e07
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 });