UNPKG

funcunit

Version:
159 lines (129 loc) 4.89 kB
/* SystemJS Global Format Supports metadata.deps metadata.init metadata.exports Also detects writes to the global object avoiding global collisions. See the SystemJS readme global support section for further information. */ function global(loader) { loader._extensions.push(global); function readGlobalProperty(p, value) { var pParts = p.split('.'); while (pParts.length) value = value[pParts.shift()]; return value; } function createHelpers(loader) { if (loader.has('@@global-helpers')) return; var hasOwnProperty = loader.global.hasOwnProperty; var moduleGlobals = {}; var curGlobalObj; var ignoredGlobalProps; function makeLookupObject(arr) { var out = {}; for(var i = 0, len = arr.length; i < len; i++) { out[arr[i]] = true; } return out; } loader.set('@@global-helpers', loader.newModule({ prepareGlobal: function(moduleName, deps, exportName) { // first, we add all the dependency modules to the global for (var i = 0; i < deps.length; i++) { var moduleGlobal = moduleGlobals[deps[i]]; if (moduleGlobal) for (var m in moduleGlobal) loader.global[m] = moduleGlobal[m]; } // If an exportName is defined there is no need to perform the next // expensive operation. if(exportName || exportName === false || loader.inferGlobals === false) { return; } // now store a complete copy of the global object // in order to detect changes curGlobalObj = {}; ignoredGlobalProps = makeLookupObject(['indexedDB', 'sessionStorage', 'localStorage', 'clipboardData', 'frames', 'webkitStorageInfo', 'toolbar', 'statusbar', 'scrollbars', 'personalbar', 'menubar', 'locationbar', 'webkitIndexedDB', 'screenTop', 'screenLeft' ]); for (var g in loader.global) { if (ignoredGlobalProps[g]) { continue; } if (!hasOwnProperty || loader.global.hasOwnProperty(g)) { try { curGlobalObj[g] = loader.global[g]; } catch (e) { ignoredGlobalProps[g] = true; } } } }, retrieveGlobal: function(moduleName, exportName, init) { var singleGlobal; var multipleExports; var exports = {}; // run init if (init) singleGlobal = init.call(loader.global); // check for global changes, creating the globalObject for the module // if many globals, then a module object for those is created // if one global, then that is the module directly else if (exportName) { var firstPart = exportName.split('.')[0]; singleGlobal = readGlobalProperty(exportName, loader.global); exports[firstPart] = loader.global[firstPart]; } else if(exportName !== false && loader.inferGlobals !== false) { for (var g in loader.global) { if (ignoredGlobalProps[g]) continue; if ((!hasOwnProperty || loader.global.hasOwnProperty(g)) && g != loader.global && curGlobalObj[g] != loader.global[g]) { exports[g] = loader.global[g]; if (singleGlobal) { if (singleGlobal !== loader.global[g]) multipleExports = true; } else if (singleGlobal === undefined) { singleGlobal = loader.global[g]; } } } } moduleGlobals[moduleName] = exports; return multipleExports ? exports : singleGlobal; } })); } createHelpers(loader); var loaderInstantiate = loader.instantiate; loader.instantiate = function(load) { var loader = this; createHelpers(loader); var exportName = load.metadata.exports; if (!load.metadata.format) load.metadata.format = 'global'; // global is a fallback module format if (load.metadata.format == 'global') { load.metadata.execute = function(require, exports, module) { loader.get('@@global-helpers').prepareGlobal(module.id, load.metadata.deps, exportName); if (exportName) load.source += '\nthis["' + exportName + '"] = ' + exportName + ';'; // disable module detection var define = loader.global.define; var require = loader.global.require; loader.global.define = undefined; loader.global.module = undefined; loader.global.exports = undefined; loader.__exec(load); loader.global.require = require; loader.global.define = define; return loader.get('@@global-helpers').retrieveGlobal(module.id, exportName, load.metadata.init); } } return loaderInstantiate.call(loader, load); } }