Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (function (bn, $) {
- var MAIN_MODULE_ID = ""; // per commonjs modules 2.0 draft browser environment's main module identifier should be empty string
- var MODULE_ROOT_PATH = "";
- var mainModuleDir;
- var requireMemo;
- var pendingDeclarations;
- var scriptTagMemo;
- var modulesMemo;
- var loadingMemo;
- var loadListeners;
- var scriptTagEls = []; // keep track of the elements we insert so that when we want to reset we can remove them
- ///#region Helper functions
- /**
- * Extract the directory portion of a path
- */
- function dirname(path) {
- if (typeof path !== "string") {
- throw new TypeError("dirname expects path to be a string.");
- }
- // remove trailing slash
- if (path.charAt(path.length - 1) === '/') {
- return path.slice(0, -1);
- }
- // split and remove last part from array and rejoin
- var s = path.split('/').slice(0, -1).join('/');
- // if empty, return current working directory
- if (!s) {
- return ".";
- }
- return s;
- }
- /** Canonicalize path, compacting slashes and dots per basic UNIX rules.
- * Treats paths with trailing slashes as though they end with INDEX instead.
- * Not rigorous.
- */
- function getIdFromPath(path) {
- if (typeof path !== "string") {
- path = path.toString();
- }
- var oldPath = path.split('/');
- var newPath = [];
- for (var i = 0; i < oldPath.length; i++) {
- if (oldPath[i] == '.' || !oldPath[i].length) {
- continue;
- }
- if (oldPath[i] == '..') {
- if (!newPath.length) {
- throw new Error("Invalid module path: " + path);
- }
- newPath.pop();
- continue;
- }
- newPath.push(oldPath[i]);
- }
- // not going to prefix w/ slash
- // since the location of the source is not referenced absolutely
- // because we serve files off of filesystem not http
- // newPath.unshift('');
- return newPath.join('/') || null;
- }
- function makeModuleId(relativeModuleDir, moduleIdentifier) {
- if (moduleIdentifier === MAIN_MODULE_ID) {
- return MAIN_MODULE_ID;
- }
- if (typeof moduleIdentifier !== "string") {
- throw new Error("Invalid module identifier: " + moduleIdentifier);
- }
- var id;
- if (moduleIdentifier.indexOf("./") === 0 || moduleIdentifier.indexOf("../") === 0) {
- id = relativeModuleDir + "/" + moduleIdentifier;
- } else {
- id = MODULE_ROOT_PATH + "/" + moduleIdentifier;
- }
- return getIdFromPath(id);
- }
- function urlToId(moduleURL, relaxValidation) {
- var id = moduleURL;
- var i;
- if ((i = id.indexOf('?')) !== -1) {
- id = id.slice(0, i);
- }
- if ((i = id.indexOf('#')) !== -1) {
- id = id.slice(0, i);
- }
- if (!relaxValidation && (id.slice(-3) !== ".js")) {
- throw new Error("Invalid module URL: " + moduleURL);
- }
- id = id.slice(0, -3);
- return id;
- }
- function idsFromIdentifiers(identifiers, startingModuleId) {
- var startingModuleDir = dirname(startingModuleId);
- return identifiers.map(function (identifier) {
- return makeModuleId(startingModuleDir, identifier);
- });
- }
- function addLoadListener(uri, listener) {
- if (loadListeners.hasOwnProperty(uri)) {
- loadListeners[uri].push(listener);
- } else {
- loadListeners[uri] = [listener];
- }
- }
- function fireLoadListeners(uri) {
- if (loadListeners.hasOwnProperty(uri)) {
- loadListeners[uri].forEach(function (listener) {
- listener(uri);
- });
- }
- }
- function loadScript(uri, onLoaded, onError) {
- if (document.head.querySelector('script[src^="' + uri + '"]') === null) {
- var el = document.createElement("script");
- if (typeof onLoaded === "function") {
- el.addEventListener("load", function onScriptLoad() {
- onLoaded();
- fireLoadListeners(uri);
- el.removeEventListener("load", onScriptLoad);
- });
- }
- if (typeof onError === "function") {
- el.addEventListener("error", function onScriptError() {
- onError();
- fireLoadListeners(uri);
- el.removeEventListener("error", onScriptError);
- });
- }
- el.src = MainApp.hasInspector() ? uri + '?___________________________________ts_=' + (new Date().getTime()) : uri;
- document.head.appendChild(el);
- scriptTagEls.push(el);
- } else {
- throw new Error("[BN::REQUIRE] loadScript was called for " + uri + "; however, the script was already in the DOM.");
- }
- }
- //#endregion
- //#region require namespace implementation
- function requireFactory(moduleDir, dependencies) {
- var require = function (moduleIdentifier) {
- var id = makeModuleId(moduleDir, moduleIdentifier);
- if (!requireMemo[id] && pendingDeclarations[id]) {
- initializeModule(id);
- }
- if (id === null || !requireMemo[id]) {
- throw new Error("Module {0} has not been provided and is not available.".format(id));
- }
- return requireMemo[id];
- };
- require.id = function (moduleIdentifier) {
- return makeModuleId(moduleDir, moduleIdentifier);
- };
- require.uri = function (moduleIdentifier) {
- var id = makeModuleId(moduleDir, moduleIdentifier);
- if (id === null) {
- throw new Error("Require could not create id from module identifier passed in: " + moduleIdentifier);
- }
- return id + ".js";
- }
- require.memoize = function requireMemoize(id, dependencies, moduleFactory) {
- pendingDeclarations[id] = { moduleFactory: moduleFactory, dependencies: dependencies };
- };
- require.isMemoized = function requireIsMemoized(id) {
- return (pendingDeclarations[id] || requireMemo[id]) ? true : false;
- };
- return require;
- }
- //#endregion
- function packagesFromDependencies(dependencies) {
- return dependencies
- .filter(function (moduleId) {
- return moduleId.indexOf('packages/') === 0;
- })
- .map(function (moduleId) {
- var packageName = moduleId.split('/')[1];
- if (!packageName) {
- throw new Error('invalid package name in module id ' + moduleId);
- }
- return packageName;
- });
- }
- /**
- * loads each dependency module one at a time, when all done,
- * when all dependencies are loaded, the callback is invoked (if passed in)
- *
- * NB! for packages that are required, but filtered out because they are being loaded, we should listen for when that module has been provided so that callback can guarantee all require calls
- *
- * TODO! still needs to be fully implemented, for now, we will only load packages
- */
- function provide(dependencies, onProvided) {
- var packages = packagesFromDependencies(dependencies).filter(function (packageName) { !bn.packageLoader.isBeingLoaded(packageName); });
- if (packages.length > 0) {
- bn.packageLoader.ready(packages, onProvided);
- } else {
- onProvided();
- }
- }
- //#region Module namespace implementation
- function provideModule(dependencies, moduleFactory, id, callback) {
- /* Memoize the the factory, satistfy the dependencies, and invoke the callback */
- if (moduleFactory) {
- bn.require.memoize(id, dependencies, moduleFactory);
- }
- if (dependencies) {
- bn.module.provide(dependencies, callback);
- } else {
- if (callback) {
- callback();
- }
- }
- }
- function makeModuleForId(id) {
- var dependencies = pendingDeclarations[id].dependencies;
- return new NobleJSModule(id, dependencies);
- }
- function initializeModule(id) {
- var moduleDirectory = id ? dirname(id) : MODULE_ROOT_PATH;
- var moduleFactory = pendingDeclarations[id].moduleFactory;
- var dependencies = pendingDeclarations[id].dependencies;
- // create context aware require from factory method
- var require = requireFactory(moduleDirectory, dependencies);
- var exports = requireMemo[id] = {};
- var module = id === MAIN_MODULE_ID ? bn.module : modulesMemo[id];
- var factoryResult = moduleFactory(require, exports, module);
- // if module does not return anything use our exports object, otherwise exported api is the factory's returned result
- requireMemo[id] = factoryResult === undefined
- ? exports
- : factoryResult;
- delete pendingDeclarations[id];
- }
- function initializeMainModule(dependencies, moduleFactory) {
- if (bn.module.main) {
- throw new Error("bn Main module has already been created!");
- }
- bn.require.memoize(MAIN_MODULE_ID, dependencies, moduleFactory);
- function requireMainModule() {
- bn.module.constructor.prototype.main = bn.require(MAIN_MODULE_ID);
- }
- provideModule(dependencies, moduleFactory, MAIN_MODULE_ID, requireMainModule);
- }
- function NobleJSModule(id, dependencies) {
- this.id = id;
- this.dependencies = dependencies;
- }
- // Be careful not to assign NobleJS.prototype directly because of the following phenomenon:
- // function F() { }
- // F.prototype = {};
- // var f = new F();
- // f.constructor.prototype.main = "something";
- // for (var i in { a: 1, b: 2 }) { console.log(i); }
- // This outputs "a", "b", "main"!!
- NobleJSModule.prototype.declare = function bnModuleDeclare(dependencies, moduleFactory) {
- if (typeof dependencies === "function") {
- moduleFactory = dependencies;
- dependencies = [];
- }
- if (!bn.module.main) { // first time called, we declare this module as the main module
- initializeMainModule(dependencies, moduleFactory);
- } else { // otherwise script-inserted module
- scriptTagMemo = { moduleFactory: moduleFactory, dependencies: dependencies };
- }
- };
- NobleJSModule.prototype.define = function bnModuleDefine(id, factoryMethod) {
- if (typeof factoryMethod !== "function") {
- throw new Error("module.define must be passed a factory method.");
- }
- bn.require.memoize(id, [], factoryMethod);
- modulesMemo[id] = new NobleJSModule(id, []);
- initializeModule(id);
- };
- NobleJSModule.prototype.load = function bnModuleLoad(moduleIdentifier, onModuleLoaded) {
- var js = bn.require.uri(moduleIdentifier);
- var id = urlToId(js);
- loadingMemo[id] = {};
- loadScript(
- js,
- function onModuleFileLoaded() {
- if (scriptTagMemo) {
- // TODO: use provideModule
- var moduleDependencies = scriptTagMemo.dependencies;
- bn.require.memoize(id, scriptTagMemo.dependencies, scriptTagMemo.moduleFactory);
- scriptTagMemo = null;
- delete loadingMemo[id];
- modulesMemo[id] = makeModuleForId(id);
- if (moduleDependencies.length > 0) {
- modulesMemo[id].provide(moduleDependencies, onModuleLoaded);
- } else {
- onModuleLoaded();
- }
- } else {
- throw new Error("module.declare was not used inside module js file: {0}".format(js));
- }
- },
- function onError() {
- onModuleLoaded();
- }
- );
- };
- function isMemoizedOrIsLoading(id) {
- return bn.require.isMemoized(id) || loadingMemo.hasOwnProperty(id);
- }
- NobleJSModule.prototype.provide = function (dependencyIdentifiers, onProvided) {
- if (dependencyIdentifiers.length === 0) {
- onProvided();
- return;
- }
- var loadedSoFar = [];
- function onLoaded(id) {
- loadedSoFar.push(id);
- if (loadedSoFar.length === dependencyIds.length) {
- onProvided();
- }
- }
- var load = this.load.bind(this);
- var dependencyIds = idsFromIdentifiers(dependencyIdentifiers, this.id);
- dependencyIds.forEach(function (id) {
- // NOTE: we don't do a .filter, because execution of the loop body could change the memoization status of this module.
- if (!isMemoizedOrIsLoading(id)) {
- load(id, function () { onLoaded(id); });
- } else if (bn.require.isMemoized(id)) {
- onLoaded(id);
- } else {
- var uri = bn.require.uri(id);
- addLoadListener(uri, function onScriptLoaded() { onLoaded(id); });
- }
- });
- };
- //#endregion
- bn.resetNobleJS = function (injectedMainModuleDir) {
- if (!injectedMainModuleDir) {
- if (mainModuleDir) {
- injectedMainModuleDir = mainModuleDir;
- } else {
- injectedMainModuleDir = dirname(urlToId(window.location.href + ".js", true));
- }
- }
- requireMemo = {};
- modulesMemo = {};
- loadingMemo = {};
- loadListeners = {};
- pendingDeclarations = {};
- scriptTagEls.forEach(function (el) {
- document.head.removeChild(el);
- });
- scriptTagEls.length = 0;
- bn.module = new NobleJSModule(MAIN_MODULE_ID, []);
- bn.module.constructor.prototype.main = null;
- // create global bn require
- bn.require = requireFactory(MODULE_ROOT_PATH, []);
- bn.require.factory = function (url) { // TODO: why??
- return requireFactory(dirname(url));
- };
- // debug directory helper
- bn.require.__dir__ = function () {
- console.dir(Object.keys(requireMemo).concat(Object.keys(pendingDeclarations)));
- };
- }
- bn.resetNobleJS();
- // provide default modules
- $.extend(requireMemo, {
- bn: bn,
- "bn/event": bn.event
- });
- } (bn, jQuery));
Add Comment
Please, Sign In to add comment