Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/twbs/rewire.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJohannes <johannes.ewald@roomieplanet.de>2012-07-02 19:58:09 +0400
committerJohannes <johannes.ewald@roomieplanet.de>2012-07-02 19:58:09 +0400
commit8bfdd979dabc1a0ab2e85fd80548d66bccdd1b82 (patch)
treee0f246aaa958e135af053276b3a75c817e710fb1 /lib
parent7d7eca0fbcecf677479b58ef8b84131cf656fd6d (diff)
- changed browserify version to 1.13.5
- fixed global var injection in the browser
Diffstat (limited to 'lib')
-rw-r--r--lib/__set__.js7
-rw-r--r--lib/browser/shims.js48
-rw-r--r--lib/browserify/browserInit.js44
-rw-r--r--lib/browserify/browserifyMiddleware.js56
-rw-r--r--lib/browserify/browserifyRewire.js166
-rw-r--r--lib/getImportGlobalsSrc.js17
6 files changed, 232 insertions, 106 deletions
diff --git a/lib/__set__.js b/lib/__set__.js
index 79175ed..61e8f94 100644
--- a/lib/__set__.js
+++ b/lib/__set__.js
@@ -25,9 +25,10 @@ function __set__() {
if (!arguments.env || Array.isArray(arguments.env)) {
throw new TypeError("__set__ expects an object as env");
}
- for (arguments.key in arguments.env) {
- if (arguments.env.hasOwnProperty(arguments.key)) {
- arguments.src += arguments.checkExistsSrc(arguments.key) + arguments.key + " = arguments.env." + arguments.key + ";";
+ for (arguments.varName in arguments.env) {
+ if (arguments.env.hasOwnProperty(arguments.varName)) {
+ arguments.varValue = arguments.env[arguments.varName];
+ arguments.src += arguments.checkExistsSrc(arguments.varName, arguments.varValue) + arguments.varName + " = arguments.env." + arguments.varName + ";";
}
}
} else if (typeof arguments.varName === "string") {
diff --git a/lib/browser/shims.js b/lib/browser/shims.js
new file mode 100644
index 0000000..df7bd63
--- /dev/null
+++ b/lib/browser/shims.js
@@ -0,0 +1,48 @@
+// Taken from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf#Compatibility
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
+ "use strict";
+ if (this == null) {
+ throw new TypeError();
+ }
+ var t = Object(this);
+ var len = t.length >>> 0;
+ if (len === 0) {
+ return -1;
+ }
+ var n = 0;
+ if (arguments.length > 0) {
+ n = Number(arguments[1]);
+ if (n != n) { // shortcut for verifying if it's NaN
+ n = 0;
+ } else if (n != 0 && n != Infinity && n != -Infinity) {
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
+ }
+ }
+ if (n >= len) {
+ return -1;
+ }
+ var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
+ for (; k < len; k++) {
+ if (k in t && t[k] === searchElement) {
+ return k;
+ }
+ }
+ return -1;
+ }
+}
+
+
+// Taken from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/trim#Compatibility
+if(!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return this.replace(/^\s+|\s+$/g,'');
+ };
+}
+
+// Taken from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray#Compatibility
+if(!Array.isArray) {
+ Array.isArray = function (vArg) {
+ return Object.prototype.toString.call(vArg) === "[object Array]";
+ };
+} \ No newline at end of file
diff --git a/lib/browserify/browserInit.js b/lib/browserify/browserInit.js
index 02fd9c1..b79005d 100644
--- a/lib/browserify/browserInit.js
+++ b/lib/browserify/browserInit.js
@@ -2,43 +2,11 @@
* This code gets injected at the end of the browserify bundle via b.append().
*/
-if (typeof window.browserifyRequire !== "undefined") {
- throw new Error("Naming collision detected: window.browserifyRequire seems to be occupied.");
+if (typeof window.browserifyRequire === "undefined") {
+ // Saves the browserifyRequire under a new name. Necessary to call the original browserifyRequire within
+ // a module where the variable name "require" is overridden by the module's internal require.
+ window.browserifyRequire = require;
+} else {
+ throw new Error("(rewire/browserify) Naming collision detected: window.browserifyRequire seems to be occupied.");
}
-// Saves the browserifyRequire under a new name. Necessary to call the original browserifyRequire within
-// a module where the variable name "require" is overridden by the module's internal require.
-window.browserifyRequire = require;
-
-/**
- * Provides a special require-proxy. Every module calls window.browserifyRequire.getProxy(require, __filename) at the
- * beginning and overrides its own require with this proxy.
- *
- * This is necessary to call rewire() with the original __filename. Thus you can use rewire() like require().
- *
- * @param {!Function} internalRequire the module's own require
- * @param {String} filename the __filename of the module
- * @return {Function} requireProxy
- */
-window.browserifyRequire.getProxy = function (internalRequire, filename) {
- var rewireModule = internalRequire("rewire"),
- key;
-
- function rewireProxy(path, cache) {
- return rewireModule(filename, path, cache);
- }
-
- for (key in rewireModule) {
- if (rewireModule.hasOwnProperty(key)) {
- rewireProxy[key] = rewireModule[key];
- }
- }
-
- return function requireProxy(path) {
- if (path === "rewire") {
- return rewireProxy;
- } else {
- return internalRequire(path);
- }
- };
-}; \ No newline at end of file
diff --git a/lib/browserify/browserifyMiddleware.js b/lib/browserify/browserifyMiddleware.js
index d62352e..8fa564a 100644
--- a/lib/browserify/browserifyMiddleware.js
+++ b/lib/browserify/browserifyMiddleware.js
@@ -7,7 +7,6 @@ var setterSrc = require("../__set__.js").toString(),
detectStrictMode = require("../detectStrictMode.js"),
browserInit = fs.readFileSync(__dirname + "/browserInit.js", "utf8"),
- importGlobalsSrc = getImportGlobalsSrc(),
injectionSrc = getInjectionSrc().replace(/\s+/g, " "); // strip out unnecessary spaces to be unobtrusive in the debug view
/**
@@ -19,18 +18,20 @@ var setterSrc = require("../__set__.js").toString(),
* @return {String}
*/
function getInjectionSrc() {
- // Registers the setters and getters of every module according to their filename. The setters and getters must be
- // injected as string here to gain access to the private scope of the module.
- return 'require("rewire").register(__filename, ' + setterSrc + ', ' + getterSrc + ');' +
- // Overrides the module internal require with a require proxy. This proxy is necessary to call rewire with the
- // module's filename at the first parameter to resolve the path. This way rewire() works exactly like require().
- 'require = window.browserifyRequire.getProxy(require, __filename);';
+ return 'var rewire = require("rewire"); ' +
+ // Registers the setters and getters of every module according to their filename. The setters and getters must be
+ // injected as string here to gain access to the private scope of the module.
+ 'rewire.register(__filename, module, ' + setterSrc + ', ' + getterSrc + ');' +
+ // Overrides the module internal require with a require proxy. This proxy is necessary to call rewire with the
+ // module's filename at the first parameter to resolve the path. This way rewire() works exactly like require().
+ 'require = rewire.getProxy(require, __dirname);' +
+ // Cleaning up
+ 'rewire = undefined;';
}
function browserifyMiddleware(b) {
function injectRewire(src, filename) {
- var rewireRequires,
- strictMode = "";
+ var rewireRequires;
// Search for all rewire() statements an return the required path.
rewireRequires = getRewireRequires(src);
@@ -45,24 +46,39 @@ function browserifyMiddleware(b) {
b.require(requirePath);
});
- // If the module uses strict mode we must ensure that "use strict" stays at the beginning of the module.
- if (detectStrictMode(src) === true) {
- strictMode = ' "use strict"; ';
+ // Convert back slashes to normal slashes on windows.
+ if (process.platform.indexOf("win") === 0) {
+ filename = filename.replace(/\\/g, "/");
}
- // Convert back slashes to normal slashes.
- filename = filename.replace(/\\/g, "/");
-
// We don't want to inject this code at the beginning of a rewire/lib-module. Otherwise
// it would cause a black hole that devours our universe.
if (filename.indexOf("/rewire/lib") === -1) {
src =
- strictMode + // either '' or ' "use strict"; '
- "/* this line was injected by rewire() */" +
- "var global = window; " + // window is our new global object
- importGlobalsSrc +
+ // Trying to hide the injected line in the debug view with extra whitespaces.
+ ' ' +
+ '/* this line was injected by rewire() */ ' + // Comment for the curious developer
+
+ // Now all global variables are declared with a var statement so they can be changed via __set__()
+ // without influencing global objects.
+ 'var global = window; ' + // window is our new global object
+ 'eval(require("rewire").getImportGlobalsSrc()); ' +
+
+ // The module src is wrapped inside a self-executing function.
+ // This is necessary to separate the module src from the preceding eval(importGlobalsSrc),
+ // because the module src can be in strict mode.
+ // In strict mode eval() can only declare vars the current scope. In this case our setters
+ // and getters won't work.
+ // @see https://developer.mozilla.org/en/JavaScript/Strict_mode#Making_eval_and_arguments_simpler
+ "(function () {" +
+
+ // If the module uses strict mode we must ensure that "use strict" stays at the beginning of the module.
+ (detectStrictMode(src)? ' "use strict"; ': ' ') +
+
injectionSrc + "\n" +
- src;
+ src +
+
+ "})();";
}
return src;
diff --git a/lib/browserify/browserifyRewire.js b/lib/browserify/browserifyRewire.js
index d70f31e..8e24c09 100644
--- a/lib/browserify/browserifyRewire.js
+++ b/lib/browserify/browserifyRewire.js
@@ -1,5 +1,38 @@
-var pathUtil = require("path"),
- browserifyRequire = window.browserifyRequire;
+require("../browser/shims.js"); // some shims for older browsers that are used by rewire()
+
+var browserifyRequire = window.browserifyRequire,
+ getImportGlobalsSrc = require("../getImportGlobalsSrc.js");
+
+/**
+ * Clones an object deeply. Used to clone the module-object that is
+ * stored in the cache. Because browserify doesn't create the module-
+ * object newly if the module is executed again we can't modify the
+ * exports object directly. Instead of we have to make an independent copy.
+ *
+ * @param {!Object} obj
+ * @return {Object}
+ */
+function clone(obj) {
+ var target = {},
+ value,
+ key;
+
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ value = obj[key];
+ if (Array.isArray(value)) {
+ target[key] = value.slice(0);
+ } else if (typeof value === "object" && value !== null) {
+ target[key] = clone(value);
+ } else {
+ target[key] = value;
+ }
+
+ }
+ }
+
+ return target;
+}
// Saves all setters and getters for every module according to its filename
var registry = {},
@@ -11,59 +44,55 @@ var registry = {},
* The parentModulePath is usually set by the requireProxy.
*
* @param {!String} parentModulePath __filename of the module, that wants to rewire() another module.
- * @param {!String} targetPath path to the module that shall be rewired
+ * @param {!String} path path to the module that shall be rewired
* @param {Boolean=true} cache indicates whether the rewired module should be cached or not
* @return {Object}
*/
-function browserifyRewire(parentModulePath, targetPath, cache) {
+function browserifyRewire(parentModulePath, path, cache) {
var originalModule,
- rewiredModule = {},
- registeredTargetModule;
+ absPath,
+ rewiredExports,
+ rewiredModule,
+ registryEntry;
// Default cache to true
if (cache === undefined) {
cache = true;
}
- // Make absolute paths
- if (targetPath.charAt(0) === ".") {
- targetPath = pathUtil.resolve(pathUtil.dirname(parentModulePath), targetPath);
- }
-
// Normalize path with file extensions
- targetPath = require.resolve(targetPath);
-
- // Deleting module from cache to trigger execution again
- delete browserifyRequire.modules[targetPath]._cached;
+ absPath = browserifyRequire.resolve(path, parentModulePath);
- // Require module to trigger rewire.register() if it hasnt been required yet
- // Putting (require) within brackets is a hack to disable browserifys require sniffing
- // @see https://github.com/substack/node-browserify/issues/132#issuecomment-5281470
- originalModule = (require)(targetPath);
+ // Delete the original module from the cache so the next call to browserifyRequre()
+ // executes the module
+ delete browserifyRequire.cache[absPath];
- // Copy all exported values to our rewired module
- for (var key in originalModule) {
- if (originalModule.hasOwnProperty(key)) {
- rewiredModule[key] = originalModule[key];
- }
- }
-
- // If caching is enabled we store the rewiredModule in the cache
- if (cache) {
- browserifyRequire.modules[targetPath]._cached = rewiredModule;
- }
+ // Require module to trigger rewire.register()
+ browserifyRequire(path, parentModulePath);
// Get registry entry of the target module
- registeredTargetModule = registry[targetPath];
+ registryEntry = registry[absPath];
+ originalModule = registryEntry.module;
+
+ // Make an independent copy of the original module so we can modify the copy
+ // without influencing the original module.
+ rewiredModule = clone(originalModule);
+ rewiredExports = rewiredModule.exports;
// Apply setter and getters
- rewiredModule.__set__ = registeredTargetModule.setter;
- rewiredModule.__get__ = registeredTargetModule.getter;
+ rewiredExports.__set__ = registryEntry.setter;
+ rewiredExports.__get__ = registryEntry.getter;
+
+ if (cache) {
+ browserifyRequire.cache[absPath] = rewiredModule;
+ } else {
+ browserifyRequire.cache[absPath] = originalModule; // returning originalModule to the cache
+ }
// Store rewired modules for rewire.reset()
- rewiredModules.push(targetPath);
+ rewiredModules.push(absPath);
- return rewiredModule;
+ return rewiredExports;
}
/**
@@ -73,8 +102,9 @@ function browserifyRewire(parentModulePath, targetPath, cache) {
* @param {!Function} setter
* @param {!Function} getter
*/
-browserifyRewire.register = function (filename, setter, getter) {
+browserifyRewire.register = function (filename, module, setter, getter) {
registry[filename] = {
+ module: module,
setter: setter,
getter: getter
};
@@ -84,14 +114,72 @@ browserifyRewire.register = function (filename, setter, getter) {
* Deletes all rewired modules from the cache
*/
browserifyRewire.reset = function () {
- var modules = browserifyRequire.modules,
- i;
+ var cache = browserifyRequire.cache,
+ i,
+ absPath;
for (i = 0; i < rewiredModules.length; i++) {
- delete modules[rewiredModules[i]]._cached;
+ absPath = rewiredModules[i];
+ delete cache[absPath];
}
rewiredModules = [];
};
+/**
+ * Provides a special require-proxy. Every module calls require("rewire").getProxy(require, __filename) at the
+ * beginning and overrides its own require with this proxy.
+ *
+ * This is necessary to call rewire() with the original __filename. Thus you can use rewire() like require().
+ *
+ * @param {!Function} internalRequire the module's own require
+ * @param {String} dirname the __dirname of the module
+ * @return {Function} requireProxy
+ */
+browserifyRewire.getProxy = function (internalRequire, dirname) {
+ var rewire = internalRequire("rewire"),
+ rewireProxyInit = false;
+
+ function copyProperties(from, to) {
+ var key;
+
+ for (key in from) {
+ if (from.hasOwnProperty(key)) {
+ to[key] = from[key];
+ }
+ }
+ }
+
+ function rewireProxy(path, cache) {
+ return rewire(dirname, path, cache);
+ }
+
+ function requireProxy(path) {
+ if (path === "rewire") {
+ if (rewireProxyInit === false) {
+ copyProperties(rewire, rewireProxy); // lazy copy
+ rewireProxyInit = true;
+ }
+ return rewireProxy;
+ } else {
+ return internalRequire(path);
+ }
+ }
+
+ copyProperties(internalRequire, requireProxy);
+
+ return requireProxy;
+};
+
+/**
+ * Scans for global vars an returns an evalable string that declares all globals as a var.
+ * This way a global variable can be overridden by __set__ without changing the global instance.
+ * It is
+ *
+ * @type {String}
+ */
+browserifyRewire.getImportGlobalsSrc = function () {
+ return getImportGlobalsSrc(['require','module','exports','__dirname','__filename','process']);
+};
+
module.exports = browserifyRewire; \ No newline at end of file
diff --git a/lib/getImportGlobalsSrc.js b/lib/getImportGlobalsSrc.js
index dc40a4b..f8c73c2 100644
--- a/lib/getImportGlobalsSrc.js
+++ b/lib/getImportGlobalsSrc.js
@@ -7,15 +7,20 @@
*
* @return {String}
*/
-function getImportGlobalsSrc() {
+function getImportGlobalsSrc(ignore) {
var key,
value,
- src = "";
+ src = "",
+ globalObj = typeof global === "undefined"? window: global;
- for (key in global) {
- if (global.hasOwnProperty(key) && key !== "global") {
- value = global[key];
- src += "var " + key + " = global." + key + "; ";
+ ignore = ignore || [];
+
+ for (key in globalObj) {
+ if (globalObj.hasOwnProperty === undefined || globalObj.hasOwnProperty(key)) { // in IE8 window.hasOwnProperty is undefined
+ if (key !== "global" && ignore.indexOf(key) === -1) {
+ value = globalObj[key];
+ src += "var " + key + " = global." + key + "; ";
+ }
}
}