Skip to content

Instantly share code, notes, and snippets.

@unscriptable
Last active February 11, 2024 22:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save unscriptable/5c3ee194a6afc5a51c89 to your computer and use it in GitHub Desktop.
Save unscriptable/5c3ee194a6afc5a51c89 to your computer and use it in GitHub Desktop.
rave's captureDefines module as function closures and as Constructor-proto
module.exports = captureDefines;
function captureDefines (amdEval) {
var result;
define.amd = { jQuery: {} };
return function (load) {
result = { named: [], isAnon: false, anon: void 0, called: false };
return capture(amdEval, define, load, result);
};
function define () {
return _define(result, arguments);
}
}
function capture (amdEval, define, load, result) {
try {
amdEval(global, define, load.source);
}
catch (ex) {
ex.message += ' in ' + load.name;
throw ex;
}
if (!result.called) {
throw new Error('AMD define not called in ' + load.name);
}
return result;
}
function _define (result, args) {
var len, def, arg, undef;
len = args.length;
result.called = true;
// last arg is always the factory (or a plain value)
def = {
factory: ensureFactory(args[--len]),
depsList: undef,
name: undef
};
// if there are more args
if (len) {
// get second-to-last arg
arg = args[--len];
if (typeof arg === 'string') {
def.name = arg;
}
else {
def.depsList = arg;
}
}
// if there are at least one more args and it's a string
if (len && typeof args[--len] === 'string') {
def.name = args[len];
}
// if we didn't consume exactly the right number of args
if (len !== 0) {
throw new Error('Unparsable AMD define arguments ['
+ Array.prototype.slice.call(args) +
']'
);
}
if (!def.name) {
if (result.isAnon) {
throw new Error('Multiple anon defines');
}
result.isAnon = true;
result.anon = def;
}
else {
result.named.push(def);
}
}
function ensureFactory (thing) {
return typeof thing === 'function'
? thing
: function () { return thing; }
}
module.exports = captureDefines;
function captureDefines (amdEval) {
return function (load) {
var result, isAnon, _define;
result = { named: [] };
_define = function captureDefine () {
var args, def;
args = copy(arguments);
// last arg is always the factory (or a plain value)
def = { factory: ensureFactory(args.pop()) };
// if there are other args
if (args.length > 0) {
// get list of dependency module ids
def.depsList = args.pop();
// if this is a string, then there are no deps
if (typeof def.depsList === 'string') {
def.name = def.depsList;
delete def.depsList;
}
else {
def.name = args.pop() || null;
}
if (args.length > 0) {
throw new Error('Unparsable AMD define arguments ['
+ copy(arguments)
+ '] found in ' + load.name
);
}
}
if (!def.name) {
if (isAnon) {
throw new Error('Multiple anon defines in' + load.name);
}
isAnon = true;
result.anon = def;
}
else {
result.named.push(def);
}
};
// indicate we are AMD and we can handle the jqueries
_define.amd = { jQuery: {} };
amdEval(global, _define, load.source);
if (!result) {
throw new Error('AMD define not called in ' + load.name);
}
return result;
};
}
function ensureFactory (thing) {
return typeof thing === 'function'
? thing
: function () { return thing; }
}
var slice = Array.prototype.slice;
function copy (thing) {
return slice.call(thing);
}
module.exports = captureDefines;
function captureDefines (amdEval) {
var inst = new AmdCapture(amdEval);
return function (load) { return inst.capture(load); };
}
function AmdCapture (amdEval) {
var self = this;
this.eval = amdEval;
this.define = function () { return self._define.apply(self, arguments); }
// indicate we are AMD and we can handle the jqueries
this.define.amd = { jQuery: {} };
}
AmdCapture.prototype = {
capture: function (load) {
this.result = { named: [], isAnon: false };
try {
this.eval(global, this.define, load.source);
}
catch (ex) {
ex.message += ' in ' + load.name;
throw ex;
}
if (!this.result) {
throw new Error('AMD define not called in ' + load.name);
}
return this.result;
},
_define: function () {
var result, args, def;
result = this.result;
args = copy(arguments);
// last arg is always the factory (or a plain value)
def = { factory: ensureFactory(args.pop()) };
// if there are other args
if (args.length > 0) {
// get list of dependency module ids
def.depsList = args.pop();
// if this is a string, then there are no deps
if (typeof def.depsList === 'string') {
def.name = def.depsList;
delete def.depsList;
}
else {
def.name = args.pop() || null;
}
if (args.length > 0) {
throw new Error('Unparsable AMD define arguments ['
+ copy(arguments) + ']'
);
}
}
if (!def.name) {
if (result.isAnon) {
throw new Error('Multiple anon defines');
}
result.isAnon = true;
result.anon = def;
}
else {
result.named.push(def);
}
}
};
function ensureFactory (thing) {
return typeof thing === 'function'
? thing
: function () { return thing; }
}
var slice = Array.prototype.slice;
function copy (thing) {
return slice.call(thing);
}
module.exports = captureDefines;
function captureDefines (amdEval) {
var result;
define.amd = { jQuery: {} };
return function (load) {
result = { named: [], isAnon: false, anon: void 0, called: false };
return capture(amdEval, define, load, result);
};
function define () {
return _define(result, copy(arguments));
}
}
function capture (amdEval, define, load, result) {
try {
amdEval(global, define, load.source);
}
catch (ex) {
ex.message += ' in ' + load.name;
throw ex;
}
if (!result.called) {
throw new Error('AMD define not called in ' + load.name);
}
return result;
}
function _define (result, args) {
var def, undef;
result.called = true;
// last arg is always the factory (or a plain value)
def = {
factory: ensureFactory(args.pop()),
depsList: undef,
name: undef
};
// if there are other args
if (args.length > 0) {
// get list of dependency module ids
def.depsList = args.pop();
// if this is a string, then there are no deps
if (typeof def.depsList === 'string') {
def.name = def.depsList;
delete def.depsList;
}
else {
def.name = args.pop() || null;
}
if (args.length > 0) {
throw new Error('Unparsable AMD define arguments ['
+ copy(arguments) + ']'
);
}
}
if (!def.name) {
if (result.isAnon) {
throw new Error('Multiple anon defines');
}
result.isAnon = true;
result.anon = def;
}
else {
result.named.push(def);
}
}
function ensureFactory (thing) {
return typeof thing === 'function'
? thing
: function () { return thing; }
}
var slice = Array.prototype.slice;
function copy (thing) {
return slice.call(thing);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment