4 * Copyright 2009, Moxiecode Systems AB
5 * Released under LGPL License.
7 * License: http://tinymce.moxiecode.com/license
8 * Contributing: http://tinymce.moxiecode.com/contributing
12 var each = tinymce.each;
15 * This class handles parsing, modification and serialization of URI/URL strings.
16 * @class tinymce.util.URI
18 tinymce.create('tinymce.util.URI', {
20 * Constucts a new URI instance.
24 * @param {String} u URI string to parse.
25 * @param {Object} s Optional settings object.
27 URI : function(u, s) {
28 var t = this, o, a, b;
34 s = t.settings = s || {};
36 // Strange app protocol or local anchor
37 if (/^(mailto|tel|news|javascript|about|data):/i.test(u) || /^\s*#/.test(u)) {
42 // Absolute path with no host, fake host and protocol
43 if (u.indexOf('/') === 0 && u.indexOf('//') !== 0)
44 u = (s.base_uri ? s.base_uri.protocol || 'http' : 'http') + '://mce_host' + u;
46 // Relative path http:// or protocol relative //path
47 if (!/^\w*:?\/\//.test(u))
48 u = (s.base_uri.protocol || 'http') + '://mce_host' + t.toAbsPath(s.base_uri.path, u);
50 // Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri)
51 u = u.replace(/@@/g, '(mce_at)'); // Zope 3 workaround, they use @@something
52 u = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(u);
53 each(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], function(v, i) {
56 // Zope 3 workaround, they use @@something
58 s = s.replace(/\(mce_at\)/g, '@@');
65 t.protocol = b.protocol;
68 t.userInfo = b.userInfo;
70 if (!t.port && t.host == 'mce_host')
73 if (!t.host || t.host == 'mce_host')
79 //t.path = t.path || '/';
83 * Sets the internal path part of the URI.
86 * @param {string} p Path string to set.
88 setPath : function(p) {
91 p = /^(.*?)\/?(\w+)?$/.exec(p);
104 * Converts the specified URI into a relative URI based on the current URI instance location.
107 * @param {String} u URI to convert into a relative path/URI.
108 * @return {String} Relative URI from the point specified in the current URI instance.
110 * // Converts an absolute URL to an relative URL url will be somedir/somefile.htm
111 * var url = new tinymce.util.URI('http://www.site.com/dir/').toRelative('http://www.site.com/dir/somedir/somefile.htm');
113 toRelative : function(u) {
119 u = new tinymce.util.URI(u, {base_uri : t});
121 // Not on same domain/port or protocol
122 if ((u.host != 'mce_host' && t.host != u.host && u.host) || t.port != u.port || t.protocol != u.protocol)
125 o = t.toRelPath(t.path, u.path);
139 * Converts the specified URI into a absolute URI based on the current URI instance location.
142 * @param {String} u URI to convert into a relative path/URI.
143 * @param {Boolean} nh No host and protocol prefix.
144 * @return {String} Absolute URI from the point specified in the current URI instance.
146 * // Converts an relative URL to an absolute URL url will be http://www.site.com/dir/somedir/somefile.htm
147 * var url = new tinymce.util.URI('http://www.site.com/dir/').toAbsolute('somedir/somefile.htm');
149 toAbsolute : function(u, nh) {
150 var u = new tinymce.util.URI(u, {base_uri : this});
152 return u.getURI(this.host == u.host && this.protocol == u.protocol ? nh : 0);
156 * Converts a absolute path into a relative path.
159 * @param {String} base Base point to convert the path from.
160 * @param {String} path Absolute path to convert into a relative path.
162 toRelPath : function(base, path) {
163 var items, bp = 0, out = '', i, l;
166 base = base.substring(0, base.lastIndexOf('/'));
167 base = base.split('/');
168 items = path.split('/');
170 if (base.length >= items.length) {
171 for (i = 0, l = base.length; i < l; i++) {
172 if (i >= items.length || base[i] != items[i]) {
179 if (base.length < items.length) {
180 for (i = 0, l = items.length; i < l; i++) {
181 if (i >= base.length || base[i] != items[i]) {
191 for (i = 0, l = base.length - (bp - 1); i < l; i++)
194 for (i = bp - 1, l = items.length; i < l; i++) {
196 out += "/" + items[i];
205 * Converts a relative path into a absolute path.
208 * @param {String} base Base point to convert the path from.
209 * @param {String} path Relative path to convert into an absolute path.
211 toAbsPath : function(base, path) {
212 var i, nb = 0, o = [], tr, outPath;
215 tr = /\/$/.test(path) ? '/' : '';
216 base = base.split('/');
217 path = path.split('/');
219 // Remove empty chunks
220 each(base, function(k) {
227 // Merge relURLParts chunks
228 for (i = path.length - 1, o = []; i >= 0; i--) {
230 if (path[i].length == 0 || path[i] == ".")
234 if (path[i] == '..') {
248 i = base.length - nb;
252 outPath = o.reverse().join('/');
254 outPath = base.slice(0, i).join('/') + '/' + o.reverse().join('/');
256 // Add front / if it's needed
257 if (outPath.indexOf('/') !== 0)
258 outPath = '/' + outPath;
260 // Add traling / if it's needed
261 if (tr && outPath.lastIndexOf('/') !== outPath.length - 1)
268 * Returns the full URI of the internal structure.
271 * @param {Boolean} nh Optional no host and protocol part. Defaults to false.
273 getURI : function(nh) {
277 if (!t.source || nh) {
282 s += t.protocol + '://';
285 s += t.userInfo + '@';