diff --git a/lib/ace/worker/worker.js b/lib/ace/worker/worker.js index 867d6c14..2f250afc 100644 --- a/lib/ace/worker/worker.js +++ b/lib/ace/worker/worker.js @@ -20,16 +20,16 @@ window.normalizeModule = function(parentId, moduleName) { // normalize plugin requires if (moduleName.indexOf("!") !== -1) { var chunks = moduleName.split("!"); - return normalizeModule(parentId, chunks[0]) + "!" + normalizeModule(parentId, chunks[1]); + return window.normalizeModule(parentId, chunks[0]) + "!" + window.normalizeModule(parentId, chunks[1]); } // normalize relative requires if (moduleName.charAt(0) == ".") { var base = parentId.split("/").slice(0, -1).join("/"); - moduleName = base + "/" + moduleName; + moduleName = (base ? base + "/" : "") + moduleName; while(moduleName.indexOf(".") !== -1 && previous != moduleName) { var previous = moduleName; - moduleName = moduleName.replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, ""); + moduleName = moduleName.replace(/^\.\//, "").replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, ""); } } @@ -44,9 +44,9 @@ window.require = function(parentId, id) { if (!id.charAt) throw new Error("worker.js require() accepts only (parentId, id) as arguments"); - id = normalizeModule(parentId, id); + id = window.normalizeModule(parentId, id); - var module = require.modules[id]; + var module = window.require.modules[id]; if (module) { if (!module.initialized) { module.initialized = true; @@ -56,49 +56,66 @@ window.require = function(parentId, id) { } var chunks = id.split("/"); - if (!require.tlns) + if (!window.require.tlns) return console.log("unable to load " + id); - chunks[0] = require.tlns[chunks[0]] || chunks[0]; + chunks[0] = window.require.tlns[chunks[0]] || chunks[0]; var path = chunks.join("/") + ".js"; - require.id = id; + window.require.id = id; importScripts(path); - return require(parentId, id); + return window.require(parentId, id); }; - -require.modules = {}; -require.tlns = {}; +window.require.modules = {}; +window.require.tlns = {}; window.define = function(id, deps, factory) { if (arguments.length == 2) { factory = deps; if (typeof id != "string") { deps = id; - id = require.id; + id = window.require.id; } } else if (arguments.length == 1) { factory = id; - id = require.id; + deps = [] + id = window.require.id; } + if (!deps.length) + // If there is no dependencies, we inject 'require', 'exports' and + // 'module' as dependencies, to provide CommonJS compatibility. + deps = ['require', 'exports', 'module'] + if (id.indexOf("text!") === 0) return; - var req = function(deps, factory) { - return require(id, deps, factory); + var req = function(childId) { + return window.require(id, childId); }; - require.modules[id] = { + window.require.modules[id] = { exports: {}, factory: function() { var module = this; - var returnExports = factory(req, module.exports, module); + var returnExports = factory.apply(this, deps.map(function(dep) { + switch(dep) { + // Because 'require', 'exports' and 'module' aren't actual + // dependencies, we must handle them seperately. + case 'require': return req + case 'exports': return module.exports + case 'module': return module + // But for all other dependencies, we can just go ahead and + // require them. + default: return req(dep) + } + })); if (returnExports) module.exports = returnExports; return module; } }; }; +window.define.amd = {} window.initBaseUrls = function initBaseUrls(topLevelNamespaces) { require.tlns = topLevelNamespaces; @@ -106,8 +123,8 @@ window.initBaseUrls = function initBaseUrls(topLevelNamespaces) { window.initSender = function initSender() { - var EventEmitter = require("ace/lib/event_emitter").EventEmitter; - var oop = require("ace/lib/oop"); + var EventEmitter = window.require("ace/lib/event_emitter").EventEmitter; + var oop = window.require("ace/lib/oop"); var Sender = function() {}; diff --git a/lib/ace/worker/worker_test.js b/lib/ace/worker/worker_test.js new file mode 100644 index 00000000..c0a5b0a7 --- /dev/null +++ b/lib/ace/worker/worker_test.js @@ -0,0 +1,125 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +// The loading of ace/worker/worker is complicated, because when we need to load +// it via RequireJS, it needs a shim to make it into a AMD-module. +// When using the AMD-loader it's just works, so we just it load the file now + +require("amd-loader"); + +define(function(require, exports, module) { +"use strict"; + +var assert = require("../test/assertions"); +var worker = require("./worker") + +module.exports = { + setUp : function() { + // And define a few mock dependency modules + worker.define("depA", [], function(require, exports, module) { + module.exports = 'dependency A'; + }) + worker.define("depB", [], function(require, exports, module) { + module.exports = 'dependency B'; + }) + }, + + "test: define() with no dependencies, and CommonJS-compatability require()-calls" : function() { + // We want to be able to call define without an id or deps, but + // since we aren't loading an external file, we must explicitly give + // it some kind of id, in this case 'test1'. + worker.require.id = 'test1'; + // Now define out module + worker.define(function(require, exports, module) { + var depA = require("depA"); + var depB = require("depB"); + assert.equal("dependency A", depA); + assert.equal("dependency B", depB); + module.exports = 'test 1'; + }) + // And then try and require it + var res = worker.require("test1") + assert.equal("test 1", res) + }, + "test: define() with dependencies" : function() { + // We want to be able to call define without an id, but since we aren't + // loading an external file, we must explicitly give it some kind of + // id, in this case 'test2'. + worker.require.id = 'test2'; + // Now define our module + worker.define(['depA', 'depB'], function(depA, depB) { + assert.equal("dependency A", depA); + assert.equal("dependency B", depB); + return 'test 2'; + }) + // And then try and require it + var res = worker.require("test2"); + assert.equal("test 2", res); + }, + "test: define() used require, exports and module as a dependency": function() { + // We want to be able to call define without an id, but since we aren't + // loading an external file, we must explicitly give it some kind of + // id, in this case 'test3'. + worker.require.id = 'test3'; + // Now define our module + worker.define(['require', 'exports', 'module', 'depA', 'depB'], function(require, exports, module) { + var depA = require("depA"); + var depB = require("depB"); + assert.equal("dependency A", depA); + assert.equal("dependency B", depB); + module.exports = 'test 3'; + }) + // And then try and require it + var res = worker.require("test3"); + assert.equal("test 3", res); + }, + "test: define() with a mix of require and actual dependecies": function() { + // We want to be able to call define without an id, but since we aren't + // loading an external file, we must explicitly give it some kind of + // id, in this case 'test4'. + worker.require.id = 'test4'; + // Now define our module + worker.define(['depA', 'require'], function(depA, require) { + var depB = require("depB"); + assert.equal("dependency A", depA); + assert.equal("dependency B", depB); + return 'test 4'; + }) + // And then try and require it + var res = worker.require("test4"); + assert.equal("test 4", res); + } +} + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec() +} \ No newline at end of file