uri.js (4886B)
1 // Implementing URI-specific functions 2 // 3 // See RFC 2386 4 // 5 // This is or was http://www.w3.org/2005/10/ajaw/uri.js 6 // 2005 W3C open source licence 7 // 8 // 9 // Take a URI given in relative or absolute form and a base 10 // URI, and return an absolute URI 11 // 12 // See also http://www.w3.org/2000/10/swap/uripath.py 13 // 14 if(typeof $rdf.Util.uri == "undefined") { 15 $rdf.Util.uri = {}; 16 }; 17 18 $rdf.Util.uri.join = function (given, base) { 19 // if (typeof $rdf.log.debug != 'undefined') $rdf.log.debug(" URI given="+given+" base="+base) 20 var baseHash = base.indexOf('#') 21 if(baseHash > 0) base = base.slice(0, baseHash) 22 if(given.length == 0) return base // before chopping its filename off 23 if(given.indexOf('#') == 0) return base + given 24 var colon = given.indexOf(':') 25 if(colon >= 0) return given // Absolute URI form overrides base URI 26 var baseColon = base.indexOf(':') 27 if(base == "") return given; 28 if(baseColon < 0) { 29 alert("Invalid base: " + base + ' in join with ' + given); 30 return given 31 } 32 var baseScheme = base.slice(0, baseColon + 1) // eg http: 33 if(given.indexOf("//") == 0) // Starts with // 34 return baseScheme + given; 35 if(base.indexOf('//', baseColon) == baseColon + 1) { // Any hostpart? 36 var baseSingle = base.indexOf("/", baseColon + 3) 37 if(baseSingle < 0) { 38 if(base.length - baseColon - 3 > 0) { 39 return base + "/" + given 40 } else { 41 return baseScheme + given 42 } 43 } 44 } else { 45 var baseSingle = base.indexOf("/", baseColon + 1) 46 if(baseSingle < 0) { 47 if(base.length - baseColon - 1 > 0) { 48 return base + "/" + given 49 } else { 50 return baseScheme + given 51 } 52 } 53 } 54 55 if(given.indexOf('/') == 0) // starts with / but not // 56 return base.slice(0, baseSingle) + given 57 58 var path = base.slice(baseSingle) 59 var lastSlash = path.lastIndexOf("/") 60 if(lastSlash < 0) return baseScheme + given 61 if((lastSlash >= 0) 62 && (lastSlash < (path.length - 1))) 63 path = path.slice(0, lastSlash + 1) // Chop trailing filename from base 64 path = path + given 65 while(path.match(/[^\/]*\/\.\.\//)) // must apply to result of prev 66 path = path.replace(/[^\/]*\/\.\.\//, '') // ECMAscript spec 7.8.5 67 path = path.replace(/\.\//g, '') // spec vague on escaping 68 path = path.replace(/\/\.$/, '/') 69 return base.slice(0, baseSingle) + path 70 } 71 72 if(typeof tabulator != 'undefined' && tabulator.isExtension) { 73 $rdf.Util.uri.join2 = function (given, base) { 74 var tIOService = Components.classes['@mozilla.org/network/io-service;1'] 75 .getService(Components.interfaces.nsIIOService); 76 77 var baseURI = tIOService.newURI(base, null, null); 78 return tIOService.newURI(baseURI.resolve(given), null, null).spec; 79 } 80 } else 81 $rdf.Util.uri.join2 = $rdf.Util.uri.join; 82 83 // refTo: Make a URI relative to a given base 84 // 85 // based on code in http://www.w3.org/2000/10/swap/uripath.py 86 // 87 $rdf.Util.uri.commonHost = new RegExp("^[-_a-zA-Z0-9.]+:(//[^/]*)?/[^/]*$"); 88 89 $rdf.Util.uri.hostpart = function (u) { 90 var m = /[^\/]*\/\/([^\/]*)\//.exec(u); 91 return m ? m[1] : '' 92 }; 93 94 $rdf.Util.uri.refTo = function (base, uri) { 95 if(!base) return uri; 96 if(base == uri) return ""; 97 var i = 0; // How much are they identical? 98 while(i < uri.length && i < base.length) 99 if(uri[i] == base[i]) i++; 100 else break; 101 if(base.slice(0, i).match($rdf.Util.uri.commonHost)) { 102 var k = uri.indexOf('//'); 103 if(k < 0) k = -2; // no host 104 var l = uri.indexOf('/', k + 2); // First *single* slash 105 if(uri.slice(l + 1, l + 2) != '/' 106 && base.slice(l + 1, l + 2) != '/' 107 && uri.slice(0, l) == base.slice(0, l)) 108 // common path to single slash 109 return uri.slice(l); // but no other common path segments 110 } 111 // fragment of base? 112 if(uri.slice(i, i + 1) == '#' && base.length == i) return uri.slice(i); 113 while(i > 0 && uri[i - 1] != '/') i--; 114 115 if(i < 3) return uri; // No way 116 if((base.indexOf('//', i - 2) > 0) 117 || uri.indexOf('//', i - 2) > 0) 118 return uri; // an unshared '//' 119 if(base.indexOf(':', i) > 0) return uri; // unshared ':' 120 var n = 0; 121 for(var j = i; j < base.length; j++) if(base[j] == '/') n++; 122 if(n == 0 && i < uri.length && uri[i] == '#') return './' + uri.slice(i); 123 if(n == 0 && i == uri.length) return './'; 124 var str = ''; 125 for(var j = 0; j < n; j++) str += '../'; 126 return str + uri.slice(i); 127 } 128 129 130 /** returns URI without the frag **/ 131 $rdf.Util.uri.docpart = function (uri) { 132 var i = uri.indexOf("#") 133 if(i < 0) return uri 134 return uri.slice(0, i) 135 } 136 137 /** The document in which something a thing defined **/ 138 $rdf.Util.uri.document = function (x) { 139 return $rdf.sym($rdf.Util.uri.docpart(x.uri)); 140 } 141 142 /** return the protocol of a uri **/ 143 /** return null if there isn't one **/ 144 $rdf.Util.uri.protocol = function (uri) { 145 var index = uri.indexOf(':'); 146 if(index >= 0) return uri.slice(0, index); 147 else return null; 148 } //protocol 149 //ends