Skip to content
This repository has been archived by the owner on Feb 26, 2019. It is now read-only.

allows for amd module to be loaded by shadow plugin #21

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 22 additions & 8 deletions shadow.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @license MIT http://troopjs.mit-license.org/
*/
define([ "text" ], function (text) {
define([ "text"], function(text) {
"use strict";

/**
Expand All @@ -21,12 +21,19 @@ define([ "text" ], function (text) {
var REQUIRE_VERSION = require.version;
var buildMap = {};

function amdify (scriptText, hashVal) {
function amdify(scriptText, hashVal) {
var pattern = /([^=&]+)=([^&]+)/g;
var m;
var deps = [];
var args = [];

var isAmd = scriptText.indexOf("define(") !== -1;

// export amd module
if (isAmd) {
scriptText += ";\nreturn __export__;\n";
}

while (hashVal && (m = pattern.exec(hashVal))) {
if (m[1] === EXPORTS) {
scriptText += ";\nreturn " + m[2] + ";\n";
Expand All @@ -37,9 +44,16 @@ define([ "text" ], function (text) {
}
}

return "define([" + deps.join(", ") + "], function (" + args.join(", ") + ") {\n"
+ scriptText
// minified content of shadow_define.js is reflected here
var define_stub = 'var args=arguments;var __export__;function define(r,n){var e=/\\(([^)]+)\\)/;function t(r){return e.exec(r.toString())[1].split(",").map(function(r){return r.trim()})}var a=t(n);var u=t(moduleDefine);var i=a.map(function(r){return args[u.indexOf(r)]});return __export__=n.apply(null,i)}';

var source;
source = "define([" + deps.join(", ") + "], function moduleDefine(" + args.join(", ") + ") {\n"
+ ( isAmd ? define_stub + ";\n" : "")
+ scriptText
+ "});";

return source;
}

function cmpVersion(a, b) {
Expand All @@ -61,7 +75,7 @@ define([ "text" ], function (text) {
}

return {
load : function (name, req, onLoad, config) {
load: function(name, req, onLoad, config) {
var m;
var hashVal;
var content;
Expand Down Expand Up @@ -92,17 +106,17 @@ define([ "text" ], function (text) {
// need to manually require the module after the call to onLoad.fromText()
if (cmpVersion(REQUIRE_VERSION, "2.1.0") < 0) {
req([ name ], onLoad);
}
}
});
}
},

write : function (pluginName, moduleName, write) {
write: function(pluginName, moduleName, write) {
var content;

if (moduleName in buildMap) {
content = buildMap[moduleName];
content = content.replace(/define\(/, function (match) {
content = content.replace(/define\(/, function(match) {
return match + '"' + [pluginName, moduleName].join('!') + '",';
});
write(content);
Expand Down
29 changes: 29 additions & 0 deletions shadow_define.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Note: This script is part of the shadow plugin and it not to be used standalone.
* content of which is to be injected to prepend to an AMD module, overriding the original "define" function there.
*/

var args = arguments;
var __export__;

// override the "define" function in the shadow scope
function define(list, callback) {
var RE_FUNC_PARAMS = /\(([^)]+)\)/;

function getargs(fn) {
return RE_FUNC_PARAMS.exec(fn.toString())[1].split(',').map(function(arg) {
return arg.trim();
});
}

var deps = getargs(callback);
var actuals = getargs(moduleDefine);

// re-order the dependencies according to name match.
var vals = deps.map(function(dep) {
return args[actuals.indexOf(dep)];
});

// invoke the module and to export the return value.
return (__export__ = callback.apply(null, vals));
}
2 changes: 1 addition & 1 deletion test/assets/dep1.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
define(function() {
return "dep1";
return "export1";
});
2 changes: 1 addition & 1 deletion test/assets/dep2.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
define(function() {
return "dep2";
return "export2";
});
3 changes: 3 additions & 0 deletions test/assets/foo-amd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
define(['test/dep1', 'test/dep2'], function(dep1, dep2) {
return [dep1, dep2, "foo"].join(',');
});
2 changes: 1 addition & 1 deletion test/plugin-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ buster.testCase("plugin", function (run){
},
"shadow load non-amd module": function(done) {
this.require(['shadow!test/foo#dep1=test/dep1&dep2=test/dep2&exports=Foo'], function(foo) {
assert.equals(foo, "dep1,dep2,foo");
assert.equals(foo, "export1,export2,foo");
done();
});
}
Expand Down
24 changes: 16 additions & 8 deletions test/plugin-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,39 @@ buster.testCase("plugin", function (run) {
var self = this;
self.timeout = 1000;
requirejs.config({
"baseUrl": "./",
"baseUrl": "./bower_components",
"paths": {
"shadow": "../shadow",
"json": "../json",
"mv": "../multiversion"
},
"packages": [
{
"name" : "test",
"location" : "test/assets"
"location": "../test/assets"
},
{
"name": "text",
"location": "bower_components/requirejs-text",
"location": "requirejs-text",
"main": "text"
}
],
"maps": {
"mv": "multiversion"
},
deps: ['require'],
"callback": function(localRequire) {
self.require = localRequire;
done();
}
});
},
"shadow load non-amd module": function (done) {
"shadow load - non-amd module": function(done) {
this.require(['shadow!test/foo#dep1=test/dep1&dep2=test/dep2&exports=Foo'], function(foo) {
assert.equals(foo, "dep1,dep2,foo");
assert.equals(foo, "export1,export2,foo");
done();
});
},
"shadow load - amd module": function(done) {
this.require(['shadow!test/foo-amd#dep2=test/dep2&dep1=test/dep1'], function(foo) {
assert.equals(foo, "export1,export2,foo");
done();
});
}
Expand Down