improve require support in worker

This commit is contained in:
nightwing 2015-05-22 02:34:30 +04:00
commit af5c7a9c3b

View file

@ -1,8 +1,9 @@
"no use strict"; "no use strict";
;(function(window) { ;(function(window) {
if (typeof window.window != "undefined" && window.document) { if (typeof window.window != "undefined" && window.document)
return;
if (window.require && window.define)
return; return;
}
window.console = function() { window.console = function() {
var msgs = Array.prototype.slice.call(arguments, 0); var msgs = Array.prototype.slice.call(arguments, 0);
@ -19,6 +20,7 @@ window.ace = window;
window.onerror = function(message, file, line, col, err) { window.onerror = function(message, file, line, col, err) {
postMessage({type: "error", data: { postMessage({type: "error", data: {
message: message, message: message,
data: err.data,
file: file, file: file,
line: line, line: line,
col: col, col: col,
@ -37,7 +39,7 @@ window.normalizeModule = function(parentId, moduleName) {
var base = parentId.split("/").slice(0, -1).join("/"); var base = parentId.split("/").slice(0, -1).join("/");
moduleName = (base ? base + "/" : "") + moduleName; moduleName = (base ? base + "/" : "") + moduleName;
while(moduleName.indexOf(".") !== -1 && previous != moduleName) { while (moduleName.indexOf(".") !== -1 && previous != moduleName) {
var previous = moduleName; var previous = moduleName;
moduleName = moduleName.replace(/^\.\//, "").replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, ""); moduleName = moduleName.replace(/^\.\//, "").replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, "");
} }
@ -46,7 +48,7 @@ window.normalizeModule = function(parentId, moduleName) {
return moduleName; return moduleName;
}; };
window.require = function(parentId, id) { window.require = function require(parentId, id) {
if (!id) { if (!id) {
id = parentId; id = parentId;
parentId = null; parentId = null;
@ -64,18 +66,36 @@ window.require = function(parentId, id) {
} }
return module.exports; return module.exports;
} }
var chunks = id.split("/");
if (!window.require.tlns) if (!window.require.tlns)
return console.log("unable to load " + id); return console.log("unable to load " + id);
chunks[0] = window.require.tlns[chunks[0]] || chunks[0];
var path = chunks.join("/"); var path = resolveModuleId(id, window.require.tlns);
if (path.slice(-3) != ".js") path += ".js"; if (path.slice(-3) != ".js") path += ".js";
window.require.id = id; window.require.id = id;
window.require.modules[id] = {}; // prevent infinite loop on broken modules
importScripts(path); importScripts(path);
return window.require(parentId, id); return window.require(parentId, id);
}; };
function resolveModuleId(id, paths) {
var testPath = id, tail = "";
while (testPath) {
var alias = paths[testPath];
if (typeof alias == "string") {
return alias + tail;
} else if (alias) {
return alias.location.replace(/\/*$/, "/") + (tail || alias.main || alias.name);
} else if (alias === false) {
return "";
}
var i = testPath.lastIndexOf("/");
if (i === -1) break;
tail = testPath.substr(i) + tail;
testPath = testPath.slice(0, i);
}
return id;
}
window.require.modules = {}; window.require.modules = {};
window.require.tlns = {}; window.require.tlns = {};
@ -101,9 +121,9 @@ window.define = function(id, deps, factory) {
} }
if (!deps.length) if (!deps.length)
// If there is no dependencies, we inject 'require', 'exports' and // If there is no dependencies, we inject "require", "exports" and
// 'module' as dependencies, to provide CommonJS compatibility. // "module" as dependencies, to provide CommonJS compatibility.
deps = ['require', 'exports', 'module']; deps = ["require", "exports", "module"];
var req = function(childId) { var req = function(childId) {
return window.require(id, childId); return window.require(id, childId);
@ -114,16 +134,16 @@ window.define = function(id, deps, factory) {
factory: function() { factory: function() {
var module = this; var module = this;
var returnExports = factory.apply(this, deps.map(function(dep) { var returnExports = factory.apply(this, deps.map(function(dep) {
switch(dep) { switch (dep) {
// Because 'require', 'exports' and 'module' aren't actual // Because "require", "exports" and "module" aren't actual
// dependencies, we must handle them seperately. // dependencies, we must handle them seperately.
case 'require': return req; case "require": return req;
case 'exports': return module.exports; case "exports": return module.exports;
case 'module': return module; case "module": return module;
// But for all other dependencies, we can just go ahead and // But for all other dependencies, we can just go ahead and
// require them. // require them.
default: return req(dep); default: return req(dep);
} }
})); }));
if (returnExports) if (returnExports)
module.exports = returnExports; module.exports = returnExports;
@ -132,9 +152,10 @@ window.define = function(id, deps, factory) {
}; };
}; };
window.define.amd = {}; window.define.amd = {};
require.tlns = {};
window.initBaseUrls = function initBaseUrls(topLevelNamespaces) { window.initBaseUrls = function initBaseUrls(topLevelNamespaces) {
require.tlns = topLevelNamespaces; for (var i in topLevelNamespaces)
require.tlns[i] = topLevelNamespaces[i];
}; };
window.initSender = function initSender() { window.initSender = function initSender() {
@ -174,21 +195,23 @@ var sender = window.sender = null;
window.onmessage = function(e) { window.onmessage = function(e) {
var msg = e.data; var msg = e.data;
if (msg.command) { if (msg.event && sender) {
sender._signal(msg.event, msg.data);
}
else if (msg.command) {
if (main[msg.command]) if (main[msg.command])
main[msg.command].apply(main, msg.args); main[msg.command].apply(main, msg.args);
else if (window[msg.command])
window[msg.command].apply(window, msg.args);
else else
throw new Error("Unknown command:" + msg.command); throw new Error("Unknown command:" + msg.command);
} }
else if (msg.init) { else if (msg.init) {
initBaseUrls(msg.tlns); window.initBaseUrls(msg.tlns);
require("ace/lib/es5-shim"); require("ace/lib/es5-shim");
sender = window.sender = initSender(); sender = window.sender = window.initSender();
var clazz = require(msg.module)[msg.classname]; var clazz = require(msg.module)[msg.classname];
main = window.main = new clazz(sender); main = window.main = new clazz(sender);
}
else if (msg.event && sender) {
sender._signal(msg.event, msg.data);
} }
}; };
})(this); })(this);