From 8fe92b94ce5e1e2857d088752d94e19db7e3d8a8 Mon Sep 17 00:00:00 2001 From: Valerio Virgillito Date: Sun, 17 Jun 2012 22:31:44 -0700 Subject: montage v11 merge into ninja Signed-off-by: Valerio Virgillito --- node_modules/montage/require/browser.js | 4 +- node_modules/montage/require/require.js | 67 ++++++-- node_modules/montage/require/worker-script.js | 233 ++++++++++++++++++++++++++ node_modules/montage/require/worker.js | 62 +++++++ 4 files changed, 351 insertions(+), 15 deletions(-) create mode 100644 node_modules/montage/require/worker-script.js create mode 100644 node_modules/montage/require/worker.js (limited to 'node_modules/montage/require') diff --git a/node_modules/montage/require/browser.js b/node_modules/montage/require/browser.js index a6a8af5a..1b4029ad 100755 --- a/node_modules/montage/require/browser.js +++ b/node_modules/montage/require/browser.js @@ -17,7 +17,7 @@ Require.getLocation = function() { return URL.resolve(window.location, "."); }; -Require.overlays = ["browser", "montage"]; +Require.overlays = ["window", "browser", "montage"]; // Due to crazy variabile availability of new and old XHR APIs across // platforms, this implementation registers every known name for the event @@ -116,8 +116,6 @@ Require.Compiler = function (config) { // module.factory = new Function("require", "exports", "module", module.text + "\n//*/"+sourceURLComment); module.factory.displayName = displayName; - - return module; } }; diff --git a/node_modules/montage/require/require.js b/node_modules/montage/require/require.js index eaa2d9fc..36372053 100755 --- a/node_modules/montage/require/require.js +++ b/node_modules/montage/require/require.js @@ -8,12 +8,24 @@ // Boostrapping Browser if (typeof bootstrap !== "undefined") { - bootstrap("require/require", function (require, exports) { - var Promise = require("core/promise").Promise; - var URL = require("core/mini-url"); - definition(exports, Promise, URL); - require("require/browser"); - }); + + // Window + if (typeof window !== "undefined") { + bootstrap("require/require", function (require, exports) { + var Promise = require("core/promise").Promise; + var URL = require("core/mini-url"); + definition(exports, Promise, URL); + require("require/browser"); + }); + + // Worker + } else { + bootstrap("require/require", function (require, exports) { + var Promise = require("core/promise").Promise; + var URL = require("core/url"); + definition(exports, Promise, URL); + }); + } // Node Server } else if (typeof process !== "undefined") { @@ -183,8 +195,8 @@ // Modules should never have a return value. if (returnValue !== void 0) { console.warn( - 'require: module ' + JSON.stringify(topId) + - ' returned a value.' + "require: module " + JSON.stringify(topId) + + " returned a value." ); } @@ -258,6 +270,8 @@ return resolve(id, viaId); }; + require.getModule = getModule; + require.load = load; require.deepLoad = deepLoad; @@ -269,10 +283,18 @@ } }; + require.getPackage = function (dependency) { + return config.getPackage(dependency, config); + }; + require.injectPackageDescription = function (location, description) { Require.injectPackageDescription(location, description, config); }; + require.injectPackageDescriptionLocation = function (location, descriptionLocation) { + Require.injectPackageDescriptionLocation(location, descriptionLocation, config); + }; + require.identify = identify; require.inject = inject; require.progress = Require.progress; @@ -283,6 +305,8 @@ require.config = config; + require.read = Require.read; + return require; } @@ -297,17 +321,35 @@ }; Require.injectPackageDescription = function (location, description, config) { - var descriptions = config.descriptions = config.descriptions || {}; + var descriptions = + config.descriptions = + config.descriptions || {}; descriptions[location] = Promise.call(function () { return description; }); }; + Require.injectPackageDescriptionLocation = function (location, descriptionLocation, config) { + var descriptionLocations = + config.descriptionLocations = + config.descriptionLocations || {}; + descriptionLocations[location] = descriptionLocation; + }; + Require.loadPackageDescription = function (location, config) { - var descriptions = config.descriptions = config.descriptions || {}; + var descriptions = + config.descriptions = + config.descriptions || {}; if (descriptions[location] === void 0) { - var jsonPath = URL.resolve(location, 'package.json'); - descriptions[location] = Require.read(jsonPath) + var descriptionLocations = + config.descriptionLocations = + config.descriptionLocations || {}; + if (descriptionLocations[location]) { + descriptionLocation = descriptionLocations[location]; + } else { + descriptionLocation = URL.resolve(location, "package.json"); + } + descriptions[location] = Require.read(descriptionLocation) .then(function (json) { try { return JSON.parse(json); @@ -447,6 +489,7 @@ // overlay var overlay = description.overlay || {}; + var layer; Require.overlays.forEach(function (engine) { if (overlay[engine]) { var layer = overlay[engine]; diff --git a/node_modules/montage/require/worker-script.js b/node_modules/montage/require/worker-script.js new file mode 100644 index 00000000..58a3da7f --- /dev/null +++ b/node_modules/montage/require/worker-script.js @@ -0,0 +1,233 @@ +(function (global) { + +var postMessage = global.postMessage.bind(global); +var addEventListener = global.addEventListener.bind(global); +var removeEventListener = global.removeEventListener.bind(global); + +console = { + log: function () { + postMessage({ + type: "console", + method: "log", + args: Array.prototype.map.call(arguments, function (value) { + if (typeof value === "string") { + return value; + } else { + return JSON.stringify(value); + } + }) + }); + }, + error: function () { + postMessage({ + type: "console", + method: "error", + args: Array.prototype.map.call(arguments, function (value) { + if (typeof value === "string") { + return value; + } else { + return JSON.stringify(value); + } + }) + }); + } +}; + +var factories = {}; +bootstrap = function (id, factory) { + factories[id] = factory; +}; + +importScripts( + "require.js", + "../core/promise.js", + "../core/next-tick.js", + "../core/url.js" +); + +delete bootstrap; + +var modules = {}; +function bootRequire(id) { + if (!modules[id]) { + var exports = modules[id] = {}; + factories[id](bootRequire, exports); + } + return modules[id]; +} + +var Require = bootRequire("require/require"); +var Promise = bootRequire("core/promise").Promise; + +var packageDeferred = Promise.defer(); +var location; +var module; + +Require.getLocation = function () { + return location; +}; + +Require.overlays = ["worker", "browser", "montage"]; + +var reads = {}; +Require.read = function (url) { + if (reads[url] === void 0) { + var deferred = Promise.defer(); + postMessage({ + type: "read", + url: url + }); + reads[url] = deferred; + } + return reads[url].promise; +}; + +// By using a named "eval" most browsers will execute in the global scope. +// http://www.davidflanagan.com/2010/12/global-eval-in.html +// Unfortunately execScript doesn't always return the value of the evaluated expression (at least in Chrome) +var globalEval = /*this.execScript ||*/eval; +// For Firebug evaled code isn't debuggable otherwise +// http://code.google.com/p/fbug/issues/detail?id=2198 +if (global.navigator && global.navigator.userAgent.indexOf("Firefox") >= 0) { + globalEval = new Function("_", "return eval(_)"); +} + +var __FILE__String = "__FILE__", + DoubleUnderscoreString = "__", + globalEvalConstantA = "(function ", + globalEvalConstantB = "(require, exports, module) {", + globalEvalConstantC = "//*/\n})\n//@ sourceURL="; + +Require.Compiler = function (config) { + return function (module) { + if (module.factory || module.text === void 0) + return module; + // Here we use a couple tricks to make debugging better in various browsers: + // TODO: determine if these are all necessary / the best options + // 1. name the function with something inteligible since some debuggers display the first part of each eval (Firebug) + // 2. append the "//@ sourceURL=location" hack (Safari, Chrome, Firebug) + // * http://pmuellr.blogspot.com/2009/06/debugger-friendly.html + // * http://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/ + // TODO: investigate why this isn't working in Firebug. + // 3. set displayName property on the factory function (Safari, Chrome) + + var displayName = __FILE__String+module.location.replace(/\.\w+$|\W/g, DoubleUnderscoreString); + + try { + module.factory = globalEval(globalEvalConstantA+displayName+globalEvalConstantB+module.text+globalEvalConstantC+module.location); + } catch (exception) { + throw new SyntaxError("in " + module.location + ": " + exception.message); + } + + // This should work and would be simpler, but Firebug does not show scripts executed via "new Function()" constructor. + // TODO: sniff browser? + // module.factory = new Function("require", "exports", "module", module.text + "\n//*/"+sourceURLComment); + + module.factory.displayName = displayName; + }; +}; + +Require.ReadLoader = function (config) { + return function (url, module) { + return Require.read(url) + .then(function (text) { + module.type = "javascript"; + module.text = text; + module.location = url; + }); + }; +}; + +Require.makeLoader = function (config) { + return Require.MappingsLoader( + config, + Require.ExtensionsLoader( + config, + Require.PathsLoader( + config, + Require.MemoizedLoader( + config, + Require.ReadLoader(config) + ) + ) + ) + ); +}; + + +global.postMessage = function (event) { + postMessage({ + type: "forward", + data: event.data + }) +}; + +var workerDeferred = Promise.defer(); + +var handlers = []; +function dispatch(event) { + handlers.forEach(function (handler) { + if (handler.handleEvent) { + handler.handleEvent(event); + } else { + handler(event); + } + }); + if (global.onmessage) { + global.onmessage(event); + } +} + +global.addEventListener = function (name, handler, capture, untrusted) { + if (name === "message") { + handlers.push(handler); + } else { + return addEventListener(name, handler, caputre, untrusted); + } +}; + +global.removeEventListener = function (name, handler) { + if (name === "message") { + var pos = handlers.indexOf(handler); + if (pos !== -1) { + handlers.splice(pos, 1); + } + } else { + return removeEventListener(name, handler); + } +}; + +addEventListener("message", function (event) { + event.stopPropagation(); + event.preventDefault(); + if (event.data.type === "init") { + location = event.data.package; + module = event.data.module; + var packagePromise = Require.loadPackage(location) + .then(function (package) { + return package.async(module) + .then(function () { + workerDeferred.resolve(global); + }) + }) + .end() + } else if (event.data.type === "read") { + if (event.data.content !== void 0) { + reads[event.data.url].resolve(event.data.content); + } else { + reads[event.data.url].reject(event.data.error); + } + delete reads[event.data.url]; + } else if (event.data.type === "forward") { + workerDeferred.promise.then(function (worker) { + dispatch({ + data: event.data.data + }); + }) + .end() + } else { + // XXX + } +}, false); + +})(this); diff --git a/node_modules/montage/require/worker.js b/node_modules/montage/require/worker.js new file mode 100644 index 00000000..3b06aad2 --- /dev/null +++ b/node_modules/montage/require/worker.js @@ -0,0 +1,62 @@ + +var URL = require("core/mini-url"); + +exports.Worker = function (package, id) { + var worker = new Worker( + URL.resolve(module.location, 'worker-script.js') + ); + worker.postMessage({ + "type": "init", + "package": package, + "module": id + }) + worker.onmessage = function (event) { + // request module text + // handle URL resolution + // console log + // read a url + if (event.data.type === "console") { + console[event.data.method].apply(console, event.data.args); + } else if (event.data.type === "read") { + require.read(event.data.url) + .then(function (content) { + worker.postMessage({ + type: "read", + url: event.data.url, + content: content + }) + }, function (error) { + worker.postMessage({ + type: "read", + url: event.data.url, + error: error + }); + }) + .end(); + } else if (event.data.type === "forward") { + if (proxy.onmessage) { + proxy.onmessage({ + data: event.data.data + }); + } else { + // XXX + } + } else { + // XXX + } + }; + var proxy = { + postMessage: function (data) { + worker.postMessage({ + type: "forward", + data: data + }); + }, + onmessage: null, + terminate: function () { + return worker.terminate(); + } + }; + return proxy; +}; + -- cgit v1.2.3