/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ //---------------------------------------------------------------------------- // an implementation of the require() function as specified for use with // CommonJS Modules - see http://commonjs.org/specs/modules/1.0.html //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // inspired from David Flanagan's require() function documented here: // http://www.davidflanagan.com/2009/11/a-module-loader.html //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // only supports "preloaded" modules ala define() (AMD) // http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition // but the id parameter is required //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // function wrapper //---------------------------------------------------------------------------- (function(){ //---------------------------------------------------------------------------- // some constants //---------------------------------------------------------------------------- var PROGRAM = "modjewel" var VERSION = "2.0.0" var global = this //---------------------------------------------------------------------------- // if require() is already defined, leave //---------------------------------------------------------------------------- if (global.modjewel) { log("modjewel global variable already defined") return } global.modjewel = null //---------------------------------------------------------------------------- // "globals" (local to this function scope though) //---------------------------------------------------------------------------- var ModuleStore var ModulePreloadStore var MainModule var WarnOnRecursiveRequire = false //---------------------------------------------------------------------------- // the require function //---------------------------------------------------------------------------- function get_require(currentModule) { var result = function require(moduleId) { if (moduleId.match(/^\.{1,2}\//)) { moduleId = normalize(currentModule, moduleId) } if (hop(ModuleStore, moduleId)) { var module = ModuleStore[moduleId] if (module.__isLoading) { if (WarnOnRecursiveRequire) { var fromModule = currentModule ? currentModule.id : "" console.log("module '" + moduleId + "' recursively require()d from '" + fromModule + "', problem?") } } currentModule.moduleIdsRequired.push(moduleId) return module.exports } if (!hop(ModulePreloadStore, moduleId)) { var fromModule = currentModule ? currentModule.id : "" error("module '" + moduleId + "' not found from '" + fromModule + "', must be define()'d first") } var factory = ModulePreloadStore[moduleId][0] var prereqs = ModulePreloadStore[moduleId][1] var module = create_module(moduleId) var newRequire = get_require(module) ModuleStore[moduleId] = module module.__isLoading = true try { currentModule.moduleIdsRequired.push(moduleId) var prereqModules = [] for (var i=0; i // a simplification of // http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition // where id is required //---------------------------------------------------------------------------- function require_define(moduleId, prereqs, factory) { var rem = ["require", "exports", "module"] if (typeof moduleId != "string") { console.log("modjewel.define(): first parameter must be a string; was: " + moduleId) return } if (arguments.length == 2) { factory = prereqs prereqs = null } if (!prereqs || prereqs.length == 0) { prereqs = rem } if (typeof factory != "function") { if (factory) { ModulePreloadStore[moduleId] = [factory, prereqs] return } console.log("modjewel.define(): factory was falsy: " + factory) return } if (moduleId.match(/^\./)) { console.log("modjewel.define(): moduleId must not start with '.': '" + moduleName + "'") return } if (hop(ModulePreloadStore, moduleId)) { console.log("modjewel.define(): module '" + moduleId + "' has already been defined") return } ModulePreloadStore[moduleId] = [factory, prereqs] } //---------------------------------------------------------------------------- // get the path of a module //---------------------------------------------------------------------------- function getModulePath(module) { if (!module || !module.id) return "" var parts = module.id.split("/") return parts.slice(0, parts.length-1).join("/") } //---------------------------------------------------------------------------- // normalize a 'file name' with . and .. with a 'directory name' //---------------------------------------------------------------------------- function normalize(module, file) { var modulePath = getModulePath(module) var dirParts = ("" == modulePath) ? [] : modulePath.split("/") var fileParts = file.split("/") for (var i=0; i 0) { dirParts.pop() } else { // error("error normalizing '" + module + "' and '" + file + "'") // eat non-valid .. paths } } else { dirParts.push(filePart) } } return dirParts.join("/") } //---------------------------------------------------------------------------- // throw an error //---------------------------------------------------------------------------- function error(message) { throw new Error(PROGRAM + ": " + message) } //---------------------------------------------------------------------------- // get a list of loaded modules //---------------------------------------------------------------------------- function modjewel_getLoadedModuleIds() { var result = [] for (moduleId in ModuleStore) { result.push(moduleId) } return result } //---------------------------------------------------------------------------- // get a list of the preloaded module ids //---------------------------------------------------------------------------- function modjewel_getPreloadedModuleIds() { var result = [] for (moduleId in ModulePreloadStore) { result.push(moduleId) } return result } //---------------------------------------------------------------------------- // get a module by module id //---------------------------------------------------------------------------- function modjewel_getModule(moduleId) { if (null == moduleId) return MainModule return ModuleStore[moduleId] } //---------------------------------------------------------------------------- // get a list of module ids which have been required by the specified module id //---------------------------------------------------------------------------- function modjewel_getModuleIdsRequired(moduleId) { var module = modjewel_getModule(moduleId) if (null == module) return null return module.moduleIdsRequired.slice() } //---------------------------------------------------------------------------- // set the WarnOnRecursiveRequireFlag // - if you make use of "module.exports =" in your code, you will want this on //---------------------------------------------------------------------------- function modjewel_warnOnRecursiveRequire(value) { if (arguments.length == 0) return WarnOnRecursiveRequire WarnOnRecursiveRequire = !!value } //---------------------------------------------------------------------------- // the modjewel module //---------------------------------------------------------------------------- function modjewel_module(require, exports, module) { exports.VERSION = VERSION exports.require = null // filled in later exports.define = null // filled in later exports.getLoadedModuleIds = modjewel_getLoadedModuleIds exports.getPreloadedModuleIds = modjewel_getPreloadedModuleIds exports.getModule = modjewel_getModule exports.getModuleIdsRequired = modjewel_getModuleIdsRequired exports.warnOnRecursiveRequire = modjewel_warnOnRecursiveRequire } //---------------------------------------------------------------------------- // log a message //---------------------------------------------------------------------------- function log(message) { console.log("modjewel: " + message) } //---------------------------------------------------------------------------- // make the require function a global //---------------------------------------------------------------------------- require_reset() //---------------------------------------------------------------------------- })();