1 /* 2 * ilib-web.js - glue code for web apps to load local ilib code and data 3 * using XHR 4 * 5 * Copyright © 2015, JEDLSoft 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 var path = { 22 dirname: function(pathname) { 23 var i = pathname.lastIndexOf("/"); 24 return i !== -1 ? pathname.substring(0,i) : pathname; 25 }, 26 27 join: function() { 28 var arr = []; 29 for (var i = 0; i < arguments.length; i++) { 30 arr.push(arguments[i]); 31 } 32 return arr.join("/"); 33 }, 34 35 normalize: function(pathname) { 36 if (pathname) { 37 var previousLen; 38 do { 39 previousLen = pathname.length; 40 pathname = pathname.replace(/\/\.\//g, "/").replace(/\/[^/]+[^\.]\/\.\./g, "").replace(/^\.\//, "").replace(/\/\//g, "/"); 41 } while (pathname.length < previousLen); 42 } 43 return pathname; 44 } 45 }; 46 47 48 var requireClass = function() { 49 this.cache = {}; 50 this.loading = {}; 51 this.updateRequire = /\brequire\s*\(\s*"([^/][^"+]*)"/g; 52 53 var pos; 54 var scripts = document.getElementsByTagName("script"); 55 56 this.protocol = "file://"; 57 this.root = "."; 58 59 for (var i = 0; i < scripts.length; i++) { 60 var source = scripts[i].src; 61 62 if (navigator && navigator.userAgent && (navigator.userAgent.indexOf(" .NET") > -1) ){ 63 // IE brower 64 var colon = source.indexOf('://'); 65 this.protocol = source.substring(0, colon+3); 66 this.root = source.substring(colon+3, pos-1); 67 if (this.root.indexOf("/") !== 0) { 68 this.root = "/" + this.root; 69 } 70 break; 71 } else { 72 if (source && (pos = source.search(/ilib-web\.js$/)) !== -1) { 73 var url = new URL(source); 74 this.protocol = url.protocol + "//"; 75 this.root = url.pathname; 76 break; 77 } 78 } 79 } 80 }; 81 82 requireClass.prototype.loadFile = function(pathname) { 83 // special case for IE because it has a @#$%ed up XMLHttpRequest implementation 84 var req = (navigator.userAgent.indexOf(" .NET") > -1) ? 85 new ActiveXObject("MSXML2.XMLHTTP") : 86 new XMLHttpRequest(); 87 88 req.open("GET", this.protocol + pathname, false); 89 req.send(); 90 91 return req.responseText; 92 }; 93 94 requireClass.prototype.require = function(pathname) { 95 96 //console.log("this.root is " + this.root + " and pathname before was " + pathname); 97 98 if (pathname.charAt(0) !== '/') { 99 // make the current path be relative to the parent's path, otherwise use the root 100 pathname = path.join((module && module.filename) ? path.dirname(module.filename) : this.root, pathname); 101 } 102 103 pathname = path.normalize(pathname); 104 105 if (this.cache[pathname]) { 106 return this.cache[pathname]; 107 } 108 109 // don't try to load things that are currently in the process of loading 110 if (this.loading[pathname]) { 111 //console.log("require: already loading..."); 112 return {}; 113 } 114 115 //console.log("loading module " + pathname); 116 117 this.loading[pathname] = true; 118 119 var text = this.loadFile(pathname); 120 var dirname = path.dirname(pathname); 121 var match, replacement; 122 123 if (text) { 124 var tmp = module.filename; 125 module.filename = pathname; 126 module.exports = null; 127 module.require = requireClass.prototype.require.bind(r); 128 129 while ((match = this.updateRequire.exec(text)) !== null) { 130 replacement = path.normalize(path.join(dirname, match[1])); 131 text = text.replace(new RegExp('"' + match[1] + '"', "g"), '"' + replacement + '"'); 132 this.updateRequire.lastIndex = match.index + replacement.length + 2; 133 } 134 // for debugging in chrome with nice file names instead of random ids like "VM (2342)" 135 text = text + "\n//# sourceURL=" + pathname + "\n"; 136 137 // console.log("text is " + text); 138 try { 139 eval(text); 140 141 this.cache[pathname] = module.exports; 142 } finally { 143 this.loading[pathname] = undefined; 144 module.filename = tmp; 145 } 146 147 return module.exports; 148 } 149 150 return undefined; 151 }; 152 153 if (typeof(window.module) === 'undefined') { 154 window.module = { 155 exports: {}, 156 filename: null 157 }; 158 } 159 160 var r = new requireClass(); 161 var require = requireClass.prototype.require.bind(r); 162 163 var WebLoader = require("../lib/WebLoader.js"); 164 165 var ilib = require("../lib/ilib.js"); 166 ilib.setLoaderCallback(new WebLoader(ilib)); 167 168 ilib._dyncode = true; // indicate that we are using dynamically loaded code 169 ilib._dyndata = true;