toolkit/devtools/Require.jsm

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 "use strict";
     7 /**
     8  * Require.jsm is a small module loader that loads JavaScript modules as
     9  * defined by AMD/RequireJS and CommonJS, or specifically as used by:
    10  * GCLI, Orion, Firebug, CCDump, NetPanel/HTTPMonitor and others.
    11  *
    12  * To date, no attempt has been made to ensure that Require.jsm closely follows
    13  * either the AMD or CommonJS specs. It is hoped that a more formal JavaScript
    14  * module standard will arrive before this is necessary. In the mean time it
    15  * serves the projects it loads.
    16  */
    18 this.EXPORTED_SYMBOLS = [ "define", "require" ];
    20 const console = (function() {
    21   const tempScope = {};
    22   Components.utils.import("resource://gre/modules/devtools/Console.jsm", tempScope);
    23   return tempScope.console;
    24 })();
    26 /**
    27  * Define a module along with a payload.
    28  * @param moduleName Name for the payload
    29  * @param deps Ignored. For compatibility with CommonJS AMD Spec
    30  * @param payload Function with (require, exports, module) params
    31  */
    32 this.define = function define(moduleName, deps, payload) {
    33   if (typeof moduleName != "string") {
    34     throw new Error("Error: Module name is not a string");
    35   }
    37   if (arguments.length == 2) {
    38     payload = deps;
    39   }
    40   else {
    41     payload.deps = deps;
    42   }
    44   if (define.debugDependencies) {
    45     console.log("define: " + moduleName + " -> " + payload.toString()
    46         .slice(0, 40).replace(/\n/, '\\n').replace(/\r/, '\\r') + "...");
    47   }
    49   if (moduleName in define.modules) {
    50     throw new Error("Error: Redefining module: " + moduleName);
    51   }
    53   // Mark the payload so we know we need to call it to get the real module
    54   payload.__uncompiled = true;
    55   define.modules[moduleName] = payload;
    56 }
    58 /**
    59  * The global store of un-instantiated modules
    60  */
    61 define.modules = {};
    63 /**
    64  * Should we console.log on module definition/instantiation/requirement?
    65  */
    66 define.debugDependencies = false;
    69 /**
    70  * We invoke require() in the context of a Domain so we can have multiple
    71  * sets of modules running separate from each other.
    72  * This contrasts with JSMs which are singletons, Domains allows us to
    73  * optionally load a CommonJS module twice with separate data each time.
    74  * Perhaps you want 2 command lines with a different set of commands in each,
    75  * for example.
    76  */
    77 function Domain() {
    78   this.modules = {};
    80   if (define.debugDependencies) {
    81     this.depth = "";
    82   }
    83 }
    85 /**
    86  * Lookup module names and resolve them by calling the definition function if
    87  * needed.
    88  * There are 2 ways to call this, either with an array of dependencies and a
    89  * callback to call when the dependencies are found (which can happen
    90  * asynchronously in an in-page context) or with a single string an no
    91  * callback where the dependency is resolved synchronously and returned.
    92  * The API is designed to be compatible with the CommonJS AMD spec and
    93  * RequireJS.
    94  * @param deps A name, or array of names for the payload
    95  * @param callback Function to call when the dependencies are resolved
    96  * @return The module required or undefined for array/callback method
    97  */
    98 Domain.prototype.require = function(config, deps, callback) {
    99   if (arguments.length <= 2) {
   100     callback = deps;
   101     deps = config;
   102     config = undefined;
   103   }
   105   if (Array.isArray(deps)) {
   106     var params = deps.map(function(dep) {
   107       return this.lookup(dep);
   108     }, this);
   109     if (callback) {
   110       callback.apply(null, params);
   111     }
   112     return undefined;
   113   }
   114   else {
   115     return this.lookup(deps);
   116   }
   117 };
   119 /**
   120  * Lookup module names and resolve them by calling the definition function if
   121  * needed.
   122  * @param moduleName A name for the payload to lookup
   123  * @return The module specified by aModuleName or null if not found
   124  */
   125 Domain.prototype.lookup = function(moduleName) {
   126   if (moduleName in this.modules) {
   127     var module = this.modules[moduleName];
   128     if (define.debugDependencies) {
   129       console.log(this.depth + " Using module: " + moduleName);
   130     }
   131     return module;
   132   }
   134   if (!(moduleName in define.modules)) {
   135     throw new Error("Missing module: " + moduleName);
   136   }
   138   var module = define.modules[moduleName];
   140   if (define.debugDependencies) {
   141     console.log(this.depth + " Compiling module: " + moduleName);
   142   }
   144   if (module.__uncompiled) {
   145     if (define.debugDependencies) {
   146       this.depth += ".";
   147     }
   149     var exports = {};
   150     try {
   151       var params = module.deps.map(function(dep) {
   152         if (dep === "require") {
   153           return this.require.bind(this);
   154         }
   155         if (dep === "exports") {
   156           return exports;
   157         }
   158         if (dep === "module") {
   159           return { id: moduleName, uri: "" };
   160         }
   161         return this.lookup(dep);
   162       }.bind(this));
   164       var reply = module.apply(null, params);
   165       module = (reply !== undefined) ? reply : exports;
   166     }
   167     catch (ex) {
   168       dump("Error using module '" + moduleName + "' - " + ex + "\n");
   169       throw ex;
   170     }
   172     if (define.debugDependencies) {
   173       this.depth = this.depth.slice(0, -1);
   174     }
   175   }
   177   // cache the resulting module object for next time
   178   this.modules[moduleName] = module;
   180   return module;
   181 };
   183 /**
   184  * Expose the Domain constructor and a global domain (on the define function
   185  * to avoid exporting more than we need. This is a common pattern with
   186  * require systems)
   187  */
   188 define.Domain = Domain;
   189 define.globalDomain = new Domain();
   191 /**
   192  * Expose a default require function which is the require of the global
   193  * sandbox to make it easy to use.
   194  */
   195 this.require = define.globalDomain.require.bind(define.globalDomain);

mercurial