Mercurial > pub > ImplabJs
comparison src/implab/Uri.js @ 0:fc2517695ee1
Initial commit, draft import of existing work
| author | cin |
|---|---|
| date | Thu, 01 Jun 2017 13:20:03 +0300 |
| parents | |
| children | 00779cb63b12 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:fc2517695ee1 |
|---|---|
| 1 define( | |
| 2 [ "dojo/_base/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 }); |
