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, base_url;
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 base_url = s.base_uri ? s.base_uri.path : new tinymce.util.URI(location.href).directory;
49 u = ((s.base_uri && s.base_uri.protocol) || 'http') + '://mce_host' + t.toAbsPath(base_url, u);
52 // Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri)
53 u = u.replace(/@@/g, '(mce_at)'); // Zope 3 workaround, they use @@something
54 u = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(u);
55 each(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], function(v, i) {
58 // Zope 3 workaround, they use @@something
60 s = s.replace(/\(mce_at\)/g, '@@');
67 t.protocol = b.protocol;
70 t.userInfo = b.userInfo;
72 if (!t.port && t.host == 'mce_host')
75 if (!t.host || t.host == 'mce_host')
81 //t.path = t.path || '/';
85 * Sets the internal path part of the URI.
88 * @param {string} p Path string to set.
90 setPath : function(p) {
93 p = /^(.*?)\/?(\w+)?$/.exec(p);
106 * Converts the specified URI into a relative URI based on the current URI instance location.
109 * @param {String} u URI to convert into a relative path/URI.
110 * @return {String} Relative URI from the point specified in the current URI instance.
112 * // Converts an absolute URL to an relative URL url will be somedir/somefile.htm
113 * var url = new tinymce.util.URI('http://www.site.com/dir/').toRelative('http://www.site.com/dir/somedir/somefile.htm');
115 toRelative : function(u) {
121 u = new tinymce.util.URI(u, {base_uri : t});
123 // Not on same domain/port or protocol
124 if ((u.host != 'mce_host' && t.host != u.host && u.host) || t.port != u.port || t.protocol != u.protocol)
127 o = t.toRelPath(t.path, u.path);
141 * Converts the specified URI into a absolute URI based on the current URI instance location.
144 * @param {String} u URI to convert into a relative path/URI.
145 * @param {Boolean} nh No host and protocol prefix.
146 * @return {String} Absolute URI from the point specified in the current URI instance.
148 * // Converts an relative URL to an absolute URL url will be http://www.site.com/dir/somedir/somefile.htm
149 * var url = new tinymce.util.URI('http://www.site.com/dir/').toAbsolute('somedir/somefile.htm');
151 toAbsolute : function(u, nh) {
152 var u = new tinymce.util.URI(u, {base_uri : this});
154 return u.getURI(this.host == u.host && this.protocol == u.protocol ? nh : 0);
158 * Converts a absolute path into a relative path.
161 * @param {String} base Base point to convert the path from.
162 * @param {String} path Absolute path to convert into a relative path.
164 toRelPath : function(base, path) {
165 var items, bp = 0, out = '', i, l;
168 base = base.substring(0, base.lastIndexOf('/'));
169 base = base.split('/');
170 items = path.split('/');
172 if (base.length >= items.length) {
173 for (i = 0, l = base.length; i < l; i++) {
174 if (i >= items.length || base[i] != items[i]) {
181 if (base.length < items.length) {
182 for (i = 0, l = items.length; i < l; i++) {
183 if (i >= base.length || base[i] != items[i]) {
193 for (i = 0, l = base.length - (bp - 1); i < l; i++)
196 for (i = bp - 1, l = items.length; i < l; i++) {
198 out += "/" + items[i];
207 * Converts a relative path into a absolute path.
210 * @param {String} base Base point to convert the path from.
211 * @param {String} path Relative path to convert into an absolute path.
213 toAbsPath : function(base, path) {
214 var i, nb = 0, o = [], tr, outPath;
217 tr = /\/$/.test(path) ? '/' : '';
218 base = base.split('/');
219 path = path.split('/');
221 // Remove empty chunks
222 each(base, function(k) {
229 // Merge relURLParts chunks
230 for (i = path.length - 1, o = []; i >= 0; i--) {
232 if (path[i].length == 0 || path[i] == ".")
236 if (path[i] == '..') {
250 i = base.length - nb;
254 outPath = o.reverse().join('/');
256 outPath = base.slice(0, i).join('/') + '/' + o.reverse().join('/');
258 // Add front / if it's needed
259 if (outPath.indexOf('/') !== 0)
260 outPath = '/' + outPath;
262 // Add traling / if it's needed
263 if (tr && outPath.lastIndexOf('/') !== outPath.length - 1)
270 * Returns the full URI of the internal structure.
273 * @param {Boolean} nh Optional no host and protocol part. Defaults to false.
275 getURI : function(nh) {
279 if (!t.source || nh) {
284 s += t.protocol + '://';
287 s += t.userInfo + '@';