diff --git a/jsdoc.js b/jsdoc.js index 90a0145a..3a14f36e 100644 --- a/jsdoc.js +++ b/jsdoc.js @@ -19,17 +19,6 @@ env = { finish: null }, - /** - * The type of VM that is executing jsdoc: - * - * + {@link modules:jsdoc/util/vm.RHINO}: Mozilla Rhino. - * + {@link modules:jsdoc/util/vm.NODEJS}: Node.js. - * - * **Note**: Rhino is the only VM that is currently supported. - * @type string - */ - vm: require('jsdoc/util/vm').vm, - /** The command line arguments passed into jsdoc. @type Array @@ -44,6 +33,7 @@ env = { /** The absolute path to the base directory of the jsdoc application. + @private @deprecated Use `__dirname` instead. @type string */ @@ -57,40 +47,12 @@ env = { opts: {} }; -var args = Array.prototype.slice.call(arguments, 0); -env.dirname = (function() { - var dirname; - - if ( require('jsdoc/util/vm').isRhino() ) { - // Rhino has no native way to get the base dirname of the current script, - // so this information must be manually passed in from the command line. - for (var i = 0; i < args.length; i++) { - if ( /^--dirname(?:=(.+?)(\/|\/\.)?)?$/i.test(args[i]) ) { - if (RegExp.$1) { - dirname = RegExp.$1; // last wins - args.splice(i--, 1); // remove --dirname opt from arguments - } - else { - dirname = args[i + 1]; - args.splice(i--, 2); - } - } - } - } else { - // TODO: can't assign to __dirname here because on Rhino, it's not defined yet - // dirname = __dirname; - } - - return dirname; -})(); -// must be assigned after env.dirname, which modifies args -env.args = args; -args = undefined; - -// TODO: consider always including an initializer for the current VM -if ( require('jsdoc/util/vm').isRhino() ) { - require('jsdoc/util/include')(env.dirname + '/rhino/rhino-shim.js'); -} +// initialize the environment for the current JavaScript VM +(function(args) { + var vm = require('jsdoc/util/vm').vm; + // TODO: may need to move this file to support Node.js + require('initialize')[vm](args); +})( Array.prototype.slice.call(arguments, 0) ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// @@ -159,36 +121,22 @@ function main() { /** - * If the current VM is Rhino, convert a path to a URI that meets the operating system's + * If required by the current VM, convert a path to a URI that meets the operating system's * requirements. Otherwise, return the original path. + * @function * @param {string} path The path to convert. * @return {string} A URI that meets the operating system's requirements, or the original path. */ - function pathToUri(_path) { - var result = _path; - - if ( vm.isRhino() ) { - result = new java.io.File(result).toURI() + ''; - } - - return result; - } + var pathToUri = vm.getModule('jsdoc').pathToUri; /** - * If the current VM is Rhino, convert a URI to a path that meets the operating system's + * If required by the current VM, convert a URI to a path that meets the operating system's * requirements. Otherwise, assume the "URI" is really a path, and return the original path. + * @function * @param {string} uri The URI to convert. * @return {string} A path that meets the operating system's requirements. */ - function uriToPath(uri) { - var result = uri; - - if ( vm.isRhino() ) { - result = new java.io.File( new java.net.URI(result) ) + ''; - } - - return result; - } + var uriToPath = vm.getModule('jsdoc').uriToPath; /** Retrieve the fully resolved path to the requested template. @@ -223,7 +171,6 @@ function main() { } } - // this only messes with the path on Rhino if (result) { result = pathToUri(result); } diff --git a/lib/initialize.js b/lib/initialize.js new file mode 100644 index 00000000..774b9d76 --- /dev/null +++ b/lib/initialize.js @@ -0,0 +1,40 @@ +/*global env: true */ +exports.rhino = function(args) { + var myGlobal = require('jsdoc/util/global'); + + // note: mutates args + function getDirname() { + var dirname; + + // Rhino has no native way to get the base dirname of the current script, + // so this information must be manually passed in from the command line. + for (var i = 0; i < args.length; i++) { + if ( /^--dirname(?:=(.+?)(\/|\/\.)?)?$/i.test(args[i]) ) { + if (RegExp.$1) { + dirname = RegExp.$1; // last wins + args.splice(i--, 1); // remove --dirname opt from arguments + } + else { + dirname = args[i + 1]; + args.splice(i--, 2); + } + } + } + + return dirname; + } + + myGlobal.__dirname = env.dirname = getDirname(); + env.args = args; + + require('jsdoc/util/include')(__dirname + '/rhino/rhino-shim.js'); +}; + +exports.nodejs = function(args) { + throw new Error('Node.js is not currently supported!'); + /* + env.dirname = __dirname; + env.args = args; + // TODO: add lib/ to the library paths + */ +}; diff --git a/lib/jsdoc/util/include.js b/lib/jsdoc/util/include.js index 5c29a547..54d1efa4 100644 --- a/lib/jsdoc/util/include.js +++ b/lib/jsdoc/util/include.js @@ -1,22 +1,6 @@ -/*global env: true, Packages: true */ - -var fs = require('fs'); -var myGlobal = require('jsdoc/util/global'); var path = require('path'); var vm = require('jsdoc/util/vm'); -function rhinoInclude(filepath) { - var cx = Packages.org.mozilla.javascript.Context.getCurrentContext(); - Packages.org.mozilla.javascript.tools.shell.Main.processFile(cx, myGlobal, filepath); -} - -// TODO: not tested -function nodejsInclude(filepath) { - var nodevm = require('vm'); - var script = fs.readFileSync(filepath, 'utf8'); - nodevm.runInNewContext(script, myGlobal, filepath); -} - /** * Read and execute a JavaScript file in global scope. * @private @@ -24,16 +8,10 @@ function nodejsInclude(filepath) { * path relative to env.dirname. */ module.exports = function(filepath) { - // we use env.dirname because, on Rhino, we need this function before __dirname is defined - filepath = path.resolve(env.dirname, filepath); + filepath = path.resolve(__dirname, filepath); try { - if ( vm.isRhino() ) { - rhinoInclude(filepath); - } - else { - nodejsInclude(filepath); - } + vm.getModule('jsdoc/util/include')(filepath); } catch (e) { console.log('Cannot include ' + filepath + ': ' + e); diff --git a/lib/jsdoc/util/vm.js b/lib/jsdoc/util/vm.js index ac80bcf3..a4a1be50 100644 --- a/lib/jsdoc/util/vm.js +++ b/lib/jsdoc/util/vm.js @@ -1,14 +1,22 @@ /*global Packages: true */ /** - * Helper functions for running JSDoc on multiple JavaScript VMs. + * Helper functions to enable JSDoc to run on multiple JavaScript virtual machines. * @module jsdoc/util/vm */ -// These strings represent JSDoc directory names; do not modify them! +// These strings represent directory names; do not modify them! +/** @private */ const RHINO = exports.RHINO = 'rhino'; +/** @private */ const NODEJS = exports.NODEJS = 'nodejs'; -exports.vm = (function() { +/** + * The JavaScript VM that is executing JSDoc: + * + * + `module:jsdoc/util/vm.RHINO`: Mozilla Rhino. + * + `module:jsdoc/util/vm.NODEJS`: Node.js (not currently supported). + */ +var vm = exports.vm = (function() { if (Packages && typeof Packages === 'object' && Object.prototype.toString.call(Packages) === '[object JavaPackage]') { return RHINO; @@ -16,14 +24,33 @@ exports.vm = (function() { return NODEJS; } else { // unknown VM - throw new Error('Unable to identify the current JavaScript runtime.'); + throw new Error('Unable to identify the current JavaScript VM.'); } })(); -exports.isRhino = function() { - return exports.vm === RHINO; +/** + * Load the VM-specific implementation of a module. + * + * @param {string} modulePath - The relative path to the module. Use the same format as when calling + * `require()`. + * @return {object} An object containing VM-specific functions for the requested module. + */ +exports.getModule = function(modulePath) { + return require( [__dirname, vm, modulePath].join('/') ); }; -exports.isNodejs = function() { - return exports.vm === NODEJS; +/** + * Check whether Mozilla Rhino is running JSDoc. + * @return {boolean} Set to `true` if the current VM is Mozilla Rhino. + */ +exports.isRhino = function() { + return vm === RHINO; +}; + +/** + * Check whether Node.js is running JSDoc. (Node.js is not currently supported.) + * @return {boolean} Set to `true` if the current VM is Node.js. + */ +exports.isNodejs = function() { + return vm === NODEJS; }; diff --git a/nodejs/jsdoc/util/include.js b/nodejs/jsdoc/util/include.js new file mode 100644 index 00000000..cee0369c --- /dev/null +++ b/nodejs/jsdoc/util/include.js @@ -0,0 +1,8 @@ +// TODO: not tested +module.exports = function(filepath) { + var fs = require('fs'); + var vm = require('vm'); + + var script = fs.readFileSync(filepath, 'utf8'); + vm.runInNewContext(script, global, filepath); +}; diff --git a/rhino/jsdoc.js b/rhino/jsdoc.js new file mode 100644 index 00000000..f3de7b89 --- /dev/null +++ b/rhino/jsdoc.js @@ -0,0 +1,9 @@ +// Platform-specific functions to support jsdoc.js + +exports.pathToUri = function(_path) { + return String( new java.io.File(_path).toURI() ); +}; + +exports.uriToPath = function(uri) { + return String( new java.io.File(new java.net.URI(uri)) ); +}; diff --git a/rhino/jsdoc/util/include.js b/rhino/jsdoc/util/include.js new file mode 100644 index 00000000..db0ef197 --- /dev/null +++ b/rhino/jsdoc/util/include.js @@ -0,0 +1,7 @@ +/*global Packages: true */ +module.exports = function(filepath) { + var myGlobal = require('jsdoc/util/global'); + + var cx = Packages.org.mozilla.javascript.Context.getCurrentContext(); + Packages.org.mozilla.javascript.tools.shell.Main.processFile(cx, myGlobal, filepath); +}; diff --git a/rhino/rhino-shim.js b/rhino/rhino-shim.js index 04a020f8..fde081ee 100644 --- a/rhino/rhino-shim.js +++ b/rhino/rhino-shim.js @@ -4,13 +4,6 @@ * to get JSDoc to run. */ -/** - * Emulate Node.js globals. - * @see http://nodejs.org/api/globals.html - */ - -__dirname = env.dirname; - /** * Emulate DOM timeout/interval functions. * @see https://developer.mozilla.org/en-US/docs/DOM/window#Methods