1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license r.js 1.0.8 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
b1b6b62ef1fb82a380162e4f36ae713b58b74610James Phillpotts/*
b1b6b62ef1fb82a380162e4f36ae713b58b74610James Phillpotts * This file has been modified by ForgeRock to fix the now missing, previously deprecated,
b1b6b62ef1fb82a380162e4f36ae713b58b74610James Phillpotts * path.existsSync in nodejs.
b1b6b62ef1fb82a380162e4f36ae713b58b74610James Phillpotts *
b1b6b62ef1fb82a380162e4f36ae713b58b74610James Phillpotts * Portions Copyright 2015 ForgeRock AS.
b1b6b62ef1fb82a380162e4f36ae713b58b74610James Phillpotts */
b1b6b62ef1fb82a380162e4f36ae713b58b74610James Phillpotts
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * This is a bootstrap script to allow running RequireJS in the command line
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * in either a Java/Rhino or Node environment. It is modified by the top-level
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * dist.js file to inject other files to completely enable this file. It is
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * the shell of the r.js file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint strict: false, evil: true, nomen: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global readFile: true, process: false, Packages: false, print: false,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonconsole: false, java: false, module: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar requirejs, require, define;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington(function (console, args, readFileFunc) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var fileName, env, fs, vm, path, exec, rhinoContext, dir, nodeRequire,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington nodeDefine, exists, reqMain, loadedOptimizedLib,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington version = '1.0.8',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington jsSuffixRegExp = /\.js$/,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington commandOption = '',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington useLibLoaded = {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Used by jslib/rhino/args.js
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington rhinoArgs = args,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington readFile = typeof readFileFunc !== 'undefined' ? readFileFunc : null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function showHelp() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington console.log('See https://github.com/jrburke/r.js for usage.');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (typeof Packages !== 'undefined') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington env = 'rhino';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileName = args[0];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fileName && fileName.indexOf('-') === 0) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington commandOption = fileName.substring(1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileName = args[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set up execution context.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington rhinoContext = Packages.org.mozilla.javascript.ContextFactory.getGlobal().enterContext();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington exec = function (string, name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return rhinoContext.evaluateString(this, string, name, 0, null);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington exists = function (fileName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return (new java.io.File(fileName)).exists();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Define a console.log for easier logging. Don't
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //get fancy though.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (typeof console === 'undefined') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington console = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington log: function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington print.apply(undefined, arguments);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (typeof process !== 'undefined') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington env = 'node';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Get the fs module via Node's require before it
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //gets replaced. Used in require/node.js
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fs = require('fs');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington vm = require('vm');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington path = require('path');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington nodeRequire = require;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington nodeDefine = define;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington reqMain = require.main;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Temporarily hide require and define to allow require.js to define
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //them.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require = undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington define = undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington readFile = function (path) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return fs.readFileSync(path, 'utf8');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington exec = function (string, name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return vm.runInThisContext(this.requirejsVars.require.makeNodeWrapper(string),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name ? fs.realpathSync(name) : '');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington exists = function (fileName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return path.existsSync(fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileName = process.argv[2];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fileName && fileName.indexOf('-') === 0) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington commandOption = fileName.substring(1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileName = process.argv[3];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /** vim: et:ts=4:sw=4:sts=4
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license RequireJS 1.0.8 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint strict: false, plusplus: false, sub: true */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global window, navigator, document, importScripts, jQuery, setTimeout, opera */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington(function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Change this version number for each release.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var version = "1.0.8",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cjsRequireRegExp = /require\(\s*["']([^'"\s]+)["']\s*\)/g,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington currDirRegExp = /^\.\//,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington jsSuffixRegExp = /\.js$/,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ostring = Object.prototype.toString,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ap = Array.prototype,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington aps = ap.slice,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington apsp = ap.splice,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isBrowser = !!(typeof window !== "undefined" && navigator && document),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isWebWorker = !isBrowser && typeof importScripts !== "undefined",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //PS3 indicates loaded and complete, but need to wait for complete
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //specifically. Sequence is "loading", "loaded", execution,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // then "complete". The UA check is unfortunate, but not sure how
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //to feature test w/o causing perf issues.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ?
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /^complete$/ : /^(complete|loaded)$/,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington defContextName = "_",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Oh the tragedy, detecting opera. See the usage of isOpera for reason.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isOpera = typeof opera !== "undefined" && opera.toString() === "[object Opera]",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington empty = {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contexts = {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington globalDefQueue = [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington interactiveScript = null,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington checkLoadedDepth = 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington useInteractive = false,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington reservedDependencies = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require: true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington module: true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington exports: true
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req, cfg = {}, currentlyAddingScript, s, head, baseElement, scripts, script,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington src, subPath, mainScript, dataMain, globalI, ctx, jQueryCheck, checkLoadedTimeoutId;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function isFunction(it) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ostring.call(it) === "[object Function]";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function isArray(it) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ostring.call(it) === "[object Array]";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Simple function to mix in properties from source into target,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * but only if target does not already have a property of the same name.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * This is not robust in IE for transferring methods that match
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Object.prototype names, but the uses of mixin here seem unlikely to
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * trigger a problem related to that.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function mixin(target, source, force) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var prop in source) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!(prop in empty) && (!(prop in target) || force)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington target[prop] = source[prop];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return req;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Constructs an error with a pointer to an URL with more information.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} id the error ID that maps to an ID on a web page.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} message human readable error.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Error} [err] the original error, if there is one.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {Error}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function makeError(id, msg, err) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (err) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington e.originalError = err;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return e;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Used to set up package paths from a packagePaths or packages config object.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} pkgs the object to store the new package config
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Array} currentPackages an array of packages to configure
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} [dir] a prefix dir to use.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function configurePackageDir(pkgs, currentPackages, dir) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var i, location, pkgObj;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (pkgObj = currentPackages[i]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pkgObj = typeof pkgObj === "string" ? { name: pkgObj } : pkgObj;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington location = pkgObj.location;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Add dir to the path, but avoid paths that start with a slash
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //or have a colon (indicates a protocol)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (dir && (!location || (location.indexOf("/") !== 0 && location.indexOf(":") === -1))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington location = dir + "/" + (location || pkgObj.name);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Create a brand new object on pkgs, since currentPackages can
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //be passed in again, and config.pkgs is the internal transformed
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //state for all package configs.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pkgs[pkgObj.name] = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name: pkgObj.name,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington location: location || pkgObj.name,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Remove leading dot in main, so main paths are normalized,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //and remove any trailing .js, since different package
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //envs have different conventions: some use a module name,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //some use a file name.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington main: (pkgObj.main || "main")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington .replace(currDirRegExp, '')
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington .replace(jsSuffixRegExp, '')
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * jQuery 1.4.3-1.5.x use a readyWait/ready() pairing to hold DOM
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * ready callbacks, but jQuery 1.6 supports a holdReady() API instead.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * At some point remove the readyWait/ready() support and just stick
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * with using holdReady.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function jQueryHoldReady($, shouldHold) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if ($.holdReady) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington $.holdReady(shouldHold);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (shouldHold) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington $.readyWait += 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington $.ready(true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (typeof define !== "undefined") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If a define is already in play via another AMD loader,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //do not overwrite.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (typeof requirejs !== "undefined") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isFunction(requirejs)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Do not overwrite and existing requirejs instance.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cfg = requirejs;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington requirejs = undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Allow for a require config object
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (typeof require !== "undefined" && !isFunction(require)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //assume it is a config object.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cfg = require;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require = undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Creates a new context for use in require and define calls.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Handle most of the heavy lifting. Do not want to use an object
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * with prototype here to avoid using "this" in require, in case it
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * needs to be used in more super secure envs that do not want this.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Also there should not be that many contexts in the page. Usually just
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * one for the default context, but could be extra for multiversion cases
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * or if a package needs a special context for a dependency that conflicts
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * with the standard context.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function newContext(contextName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var context, resume,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington waitSeconds: 7,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington baseUrl: "./",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington paths: {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pkgs: {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington catchError: {}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington defQueue = [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington specified = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "require": true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "exports": true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "module": true
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington urlMap = {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington defined = {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington loaded = {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington waiting = {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington waitAry = [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington urlFetched = {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington managerCounter = 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington managerCallbacks = {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington plugins = {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Used to indicate which modules in a build scenario
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //need to be full executed.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington needFullExec = {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fullExec = {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington resumeDepth = 0;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Trims the . and .. from an array of path segments.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * It will keep a leading path segment if a .. will become
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * the first path segment, to help with module name lookups,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * which act like paths, but can be remapped. But the end result,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * all paths that use this function should look normalized.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * NOTE: this method MODIFIES the input array.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Array} ary the array of path segments.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function trimDots(ary) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var i, part;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (part = ary[i]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (part === ".") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ary.splice(i, 1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington i -= 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (part === "..") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (i === 1 && (ary[2] === '..' || ary[0] === '..')) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //End of the line. Keep at least one non-dot
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //path segment at the front so it can be mapped
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //correctly to disk. Otherwise, there is likely
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //no path mapping for a path starting with '..'.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //This can still fail, but catches the most reasonable
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //uses of ..
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (i > 0) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ary.splice(i - 1, 2);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington i -= 2;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Given a relative module name, like ./something, normalize it to
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * a real name that can be mapped to a path.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} name the relative name
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} baseName a real name that the name arg is relative
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * to.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {String} normalized name
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function normalize(name, baseName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var pkgName, pkgConfig;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Adjust any relative paths.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (name && name.charAt(0) === ".") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If have a base name, try to normalize against it,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //otherwise, assume it is a top-level require that will
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //be relative to baseUrl in the end.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (baseName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.pkgs[baseName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If the baseName is a package name, then just treat it as one
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //name to concat the name with.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington baseName = [baseName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Convert baseName to array, and lop off the last part,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //so that . matches that "directory" and not name of the baseName's
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //module. For instance, baseName of "one/two/three", maps to
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //"one/two/three.js", but we want the directory, "one/two" for
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //this normalization.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington baseName = baseName.split("/");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington baseName = baseName.slice(0, baseName.length - 1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = baseName.concat(name.split("/"));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington trimDots(name);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Some use of packages may use a . path to reference the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //"main" module name, so normalize for that.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pkgConfig = config.pkgs[(pkgName = name[0])];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = name.join("/");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (pkgConfig && name === pkgName + '/' + pkgConfig.main) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = pkgName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (name.indexOf("./") === 0) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // No baseName, so this is ID is resolved relative
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // to baseUrl, pull off the leading dot.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = name.substring(2);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return name;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Creates a module mapping that includes plugin prefix, module
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * name, and path. If parentModuleMap is provided it will
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * also normalize the name via require.normalize()
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} name the module name
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} [parentModuleMap] parent module map
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * for the module name, used to resolve relative names.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {Object}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function makeModuleMap(name, parentModuleMap) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var index = name ? name.indexOf("!") : -1,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prefix = null,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parentName = parentModuleMap ? parentModuleMap.name : null,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington originalName = name,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington normalizedName, url, pluginModule;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (index !== -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prefix = name.substring(0, index);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = name.substring(index + 1, name.length);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (prefix) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prefix = normalize(prefix, parentName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Account for relative paths if there is a base name.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (prefix) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pluginModule = defined[prefix];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (pluginModule && pluginModule.normalize) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Plugin is loaded, use its normalize method.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington normalizedName = pluginModule.normalize(name, function (name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return normalize(name, parentName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington normalizedName = normalize(name, parentName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //A regular module.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington normalizedName = normalize(name, parentName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington url = urlMap[normalizedName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!url) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Calculate url for the module, if it has a name.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Use name here since nameToUrl also calls normalize,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //and for relative names that are outside the baseUrl
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //this causes havoc. Was thinking of just removing
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //parentModuleMap to avoid extra normalization, but
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //normalize() still does a dot removal because of
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //issue #142, so just pass in name here and redo
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the normalization. Paths outside baseUrl are just
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //messy to support.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington url = context.nameToUrl(name, null, parentModuleMap);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Store the URL mapping for later.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington urlMap[normalizedName] = url;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prefix: prefix,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name: normalizedName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parentMap: parentModuleMap,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington url: url,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington originalName: originalName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fullName: prefix ? prefix + "!" + (normalizedName || '') : normalizedName
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Determine if priority loading is done. If so clear the priorityWait
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function isPriorityDone() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var priorityDone = true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington priorityWait = config.priorityWait,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington priorityName, i;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (priorityWait) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (priorityName = priorityWait[i]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!loaded[priorityName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington priorityDone = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (priorityDone) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington delete config.priorityWait;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return priorityDone;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function makeContextModuleFunc(func, relModuleMap, enableBuildCallback) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //A version of a require function that passes a moduleName
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //value for items that may need to
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //look up paths relative to the moduleName
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var args = aps.call(arguments, 0), lastArg;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (enableBuildCallback &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isFunction((lastArg = args[args.length - 1]))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lastArg.__requireJsBuild = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args.push(relModuleMap);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return func.apply(null, args);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Helper function that creates a require function object to give to
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * modules that ask for it as a dependency. It needs to be specific
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * per module because of the implication of path mappings that may
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * need to be relative to the module name.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function makeRequire(relModuleMap, enableBuildCallback, altRequire) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var modRequire = makeContextModuleFunc(altRequire || context.require, relModuleMap, enableBuildCallback);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington mixin(modRequire, {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington nameToUrl: makeContextModuleFunc(context.nameToUrl, relModuleMap),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington toUrl: makeContextModuleFunc(context.toUrl, relModuleMap),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington defined: makeContextModuleFunc(context.requireDefined, relModuleMap),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington specified: makeContextModuleFunc(context.requireSpecified, relModuleMap),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isBrowser: req.isBrowser
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return modRequire;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /*
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Queues a dependency for checking after the loader is out of a
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * "paused" state, for example while a script file is being loaded
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * in the browser, where it may have many modules defined in it.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function queueDependency(manager) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.paused.push(manager);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function execManager(manager) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var i, ret, err, errFile, errModuleTree,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cb = manager.callback,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington map = manager.map,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fullName = map.fullName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = manager.deps,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington listeners = manager.listeners,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cjsModule;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Call the callback to define the module, if necessary.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (cb && isFunction(cb)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.catchError.define) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = req.execCb(fullName, manager.callback, args, defined[fullName]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err = e;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = req.execCb(fullName, manager.callback, args, defined[fullName]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fullName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If setting exports via "module" is in play,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //favor that over return value and exports. After that,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //favor a non-undefined return value over exports use.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cjsModule = manager.cjsModule;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (cjsModule &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cjsModule.exports !== undefined &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make sure it is not already the exports value
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cjsModule.exports !== defined[fullName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = defined[fullName] = manager.cjsModule.exports;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (ret === undefined && manager.usingExports) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //exports already set the defined value.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = defined[fullName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Use the return value from the function.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington defined[fullName] = ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If this module needed full execution in a build
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //environment, mark that now.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (needFullExec[fullName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fullExec[fullName] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (fullName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //May just be an object definition for the module. Only
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //worry about defining if have a module name.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = defined[fullName] = cb;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If this module needed full execution in a build
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //environment, mark that now.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (needFullExec[fullName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fullExec[fullName] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Clean up waiting. Do this before error calls, and before
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //calling back listeners, so that bookkeeping is correct
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //in the event of an error and error is reported in correct order,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //since the listeners will likely have errors if the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //onError function does not throw.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (waiting[manager.id]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington delete waiting[manager.id];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington manager.isDone = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.waitCount -= 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (context.waitCount === 0) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Clear the wait array used for cycles.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington waitAry = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Do not need to track manager callback now that it is defined.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington delete managerCallbacks[fullName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Allow instrumentation like the optimizer to know the order
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //of modules executed and their dependencies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (req.onResourceLoad && !manager.placeholder) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.onResourceLoad(context, map, manager.depArray);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (err) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington errFile = (fullName ? makeModuleMap(fullName).url : '') ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err.fileName || err.sourceURL;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington errModuleTree = err.moduleTree;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err = makeError('defineerror', 'Error evaluating ' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'module "' + fullName + '" at location "' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington errFile + '":\n' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err + '\nfileName:' + errFile +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington '\nlineNumber: ' + (err.lineNumber || err.line), err);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err.moduleName = fullName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err.moduleTree = errModuleTree;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return req.onError(err);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Let listeners know of this manager's value.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (cb = listeners[i]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cb(ret);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Helper that creates a callack function that is called when a dependency
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * is ready, and sets the i-th dependency for the manager as the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * value passed to the callback generated by this function.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function makeArgCallback(manager, i) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return function (value) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Only do the work if it has not been done
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //already for a dependency. Cycle breaking
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //logic in forceExec could mean this function
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //is called more than once for a given dependency.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!manager.depDone[i]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington manager.depDone[i] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington manager.deps[i] = value;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington manager.depCount -= 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!manager.depCount) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //All done, execute!
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington execManager(manager);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function callPlugin(pluginName, depManager) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var map = depManager.map,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fullName = map.fullName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = map.name,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington plugin = plugins[pluginName] ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (plugins[pluginName] = defined[pluginName]),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington load;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //No need to continue if the manager is already
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //in the process of loading.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (depManager.loading) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depManager.loading = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington load = function (ret) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depManager.callback = function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington execManager(depManager);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington loaded[depManager.id] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //The loading of this plugin
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //might have placed other things
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //in the paused queue. In particular,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //a loader plugin that depends on
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //a different plugin loaded resource.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington resume();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Allow plugins to load other code without having to know the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //context or how to "complete" the load.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington load.fromText = function (moduleName, text) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /*jslint evil: true */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var hasInteractive = useInteractive;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Indicate a the module is in process of loading.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington loaded[moduleName] = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.scriptCount += 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Indicate this is not a "real" module, so do not track it
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //for builds, it does not map to a real file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.fake[moduleName] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Turn off interactive script matching for IE for any define
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //calls in the text, then turn it back on at the end.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (hasInteractive) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington useInteractive = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.exec(text);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (hasInteractive) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington useInteractive = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Support anonymous modules.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.completeLoad(moduleName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //No need to continue if the plugin value has already been
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //defined by a build.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fullName in defined) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington load(defined[fullName]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Use parentName here since the plugin's name is not reliable,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //could be some weird string with no path that actually wants to
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //reference the parentName's path.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington plugin.load(name, makeRequire(map.parentMap, true, function (deps, cb) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var moduleDeps = [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington i, dep, depMap;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Convert deps to full names and hold on to them
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //for reference later, when figuring out if they
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //are blocked by a circular dependency.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (dep = deps[i]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depMap = makeModuleMap(dep, map.parentMap);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps[i] = depMap.fullName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!depMap.prefix) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleDeps.push(deps[i]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depManager.moduleDeps = (depManager.moduleDeps || []).concat(moduleDeps);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return context.require(deps, cb);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }), load, config);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Adds the manager to the waiting queue. Only fully
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * resolved items should be in the waiting queue.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function addWait(manager) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!waiting[manager.id]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington waiting[manager.id] = manager;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington waitAry.push(manager);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.waitCount += 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Function added to every manager object. Created out here
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * to avoid new function creation for each manager instance.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function managerAdd(cb) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.listeners.push(cb);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function getManager(map, shouldQueue) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var fullName = map.fullName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prefix = map.prefix,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington plugin = prefix ? plugins[prefix] ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (plugins[prefix] = defined[prefix]) : null,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington manager, created, pluginManager, prefixMap;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fullName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington manager = managerCallbacks[fullName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!manager) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington created = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington manager = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //ID is just the full name, but if it is a plugin resource
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //for a plugin that has not been loaded,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //then add an ID counter to it.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington id: (prefix && !plugin ?
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (managerCounter++) + '__p@:' : '') +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (fullName || '__r@' + (managerCounter++)),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington map: map,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depCount: 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depDone: [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depCallbacks: [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps: [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington listeners: [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington add: managerAdd
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington specified[manager.id] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Only track the manager/reuse it if this is a non-plugin
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //resource. Also only track plugin resources once
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the plugin has been loaded, and so the fullName is the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //true normalized value.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fullName && (!prefix || plugins[prefix])) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington managerCallbacks[fullName] = manager;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If there is a plugin needed, but it is not loaded,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //first load the plugin, then continue on.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (prefix && !plugin) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prefixMap = makeModuleMap(prefix);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Clear out defined and urlFetched if the plugin was previously
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //loaded/defined, but not as full module (as in a build
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //situation). However, only do this work if the plugin is in
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //defined but does not have a module export value.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (prefix in defined && !defined[prefix]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington delete defined[prefix];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington delete urlFetched[prefixMap.url];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pluginManager = getManager(prefixMap, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pluginManager.add(function (plugin) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Create a new manager for the normalized
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //resource ID and have it call this manager when
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //done.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var newMap = makeModuleMap(map.originalName, map.parentMap),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington normalizedManager = getManager(newMap, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Indicate this manager is a placeholder for the real,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //normalized thing. Important for when trying to map
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //modules and dependencies, for instance, in a build.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington manager.placeholder = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington normalizedManager.add(function (resource) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington manager.callback = function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return resource;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington execManager(manager);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (created && shouldQueue) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Indicate the resource is not loaded yet if it is to be
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //queued.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington loaded[manager.id] = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington queueDependency(manager);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington addWait(manager);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return manager;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function main(inName, depArray, callback, relModuleMap) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var moduleMap = makeModuleMap(inName, relModuleMap),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = moduleMap.name,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fullName = moduleMap.fullName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington manager = getManager(moduleMap),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington id = manager.id,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = manager.deps,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington i, depArg, depName, depPrefix, cjsMod;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fullName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If module already defined for context, or already loaded,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //then leave. Also leave if jQuery is registering but it does
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //not match the desired version number in the config.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fullName in defined || loaded[id] === true ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (fullName === "jquery" && config.jQuery &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.jQuery !== callback().fn.jquery)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set specified/loaded here for modules that are also loaded
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //as part of a layer, where onScriptLoad is not fired
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //for those cases. Do this after the inline define and
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //dependency tracing is done.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington specified[id] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington loaded[id] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If module is jQuery set up delaying its dom ready listeners.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fullName === "jquery" && callback) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington jQueryCheck(callback());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Attach real depArray and callback to the manager. Do this
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //only if the module has not been defined already, so do this after
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the fullName checks above. IE can call main() more than once
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //for a module.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington manager.depArray = depArray;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington manager.callback = callback;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Add the dependencies to the deps field, and register for callbacks
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //on the dependencies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; i < depArray.length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depArg = depArray[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //There could be cases like in IE, where a trailing comma will
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //introduce a null dependency, so only treat a real dependency
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //value as a dependency.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (depArg) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Split the dependency name into plugin and name parts
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depArg = makeModuleMap(depArg, (name ? moduleMap : relModuleMap));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depName = depArg.fullName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depPrefix = depArg.prefix;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Fix the name in depArray to be just the name, since
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //that is how it will be called back later.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depArray[i] = depName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Fast path CommonJS standard dependencies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (depName === "require") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps[i] = makeRequire(moduleMap);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (depName === "exports") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //CommonJS module spec 1.1
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps[i] = defined[fullName] = {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington manager.usingExports = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (depName === "module") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //CommonJS module spec 1.1
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington manager.cjsModule = cjsMod = deps[i] = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington id: name,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington uri: name ? context.nameToUrl(name, null, relModuleMap) : undefined,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington exports: defined[fullName]
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (depName in defined && !(depName in waiting) &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (!(fullName in needFullExec) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (fullName in needFullExec && fullExec[depName]))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Module already defined, and not in a build situation
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //where the module is a something that needs full
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //execution and this dependency has not been fully
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //executed. See r.js's requirePatch.js for more info
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //on fullExec.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps[i] = defined[depName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Mark this dependency as needing full exec if
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the current module needs full exec.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fullName in needFullExec) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington needFullExec[depName] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Reset state so fully executed code will get
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //picked up correctly.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington delete defined[depName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington urlFetched[depArg.url] = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Either a resource that is not loaded yet, or a plugin
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //resource for either a plugin that has not
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //loaded yet.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington manager.depCount += 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington manager.depCallbacks[i] = makeArgCallback(manager, i);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington getManager(depArg, true).add(manager.depCallbacks[i]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Do not bother tracking the manager if it is all done.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!manager.depCount) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //All done, execute!
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington execManager(manager);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington addWait(manager);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Convenience method to call main for a define call that was put on
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * hold in the defQueue.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function callDefMain(args) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington main.apply(null, args);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * jQuery 1.4.3+ supports ways to hold off calling
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * calling jQuery ready callbacks until all scripts are loaded. Be sure
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * to track it if the capability exists.. Also, since jQuery 1.4.3 does
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * not register as a module, need to do some global inference checking.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Even if it does register as a module, not guaranteed to be the precise
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * name of the global. If a jQuery is tracked for this context, then go
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * ahead and register it as a module too, if not already in process.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington jQueryCheck = function (jqCandidate) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!context.jQuery) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var $ = jqCandidate || (typeof jQuery !== "undefined" ? jQuery : null);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if ($) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If a specific version of jQuery is wanted, make sure to only
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //use this jQuery if it matches.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.jQuery && $.fn.jquery !== config.jQuery) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if ("holdReady" in $ || "readyWait" in $) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.jQuery = $;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Manually create a "jquery" module entry if not one already
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //or in process. Note this could trigger an attempt at
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //a second jQuery registration, but does no harm since
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the first one wins, and it is the same value anyway.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington callDefMain(["jquery", [], function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return jQuery;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Ask jQuery to hold DOM ready callbacks.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (context.scriptCount) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington jQueryHoldReady($, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.jQueryIncremented = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function findCycle(manager, traced) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var fullName = manager.map.fullName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depArray = manager.depArray,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fullyLoaded = true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington i, depName, depManager, result;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (manager.isDone || !fullName || !loaded[fullName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return result;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Found the cycle.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (traced[fullName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return manager;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington traced[fullName] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Trace through the dependencies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (depArray) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; i < depArray.length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Some array members may be null, like if a trailing comma
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //IE, so do the explicit [i] access and check if it has a value.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depName = depArray[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!loaded[depName] && !reservedDependencies[depName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fullyLoaded = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depManager = waiting[depName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (depManager && !depManager.isDone && loaded[depName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington result = findCycle(depManager, traced);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (result) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!fullyLoaded) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Discard the cycle that was found, since it cannot
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //be forced yet. Also clear this module from traced.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington result = undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington delete traced[fullName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return result;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function forceExec(manager, traced) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var fullName = manager.map.fullName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depArray = manager.depArray,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington i, depName, depManager, prefix, prefixManager, value;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (manager.isDone || !fullName || !loaded[fullName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fullName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (traced[fullName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return defined[fullName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington traced[fullName] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Trace through the dependencies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (depArray) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; i < depArray.length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Some array members may be null, like if a trailing comma
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //IE, so do the explicit [i] access and check if it has a value.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depName = depArray[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (depName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //First, make sure if it is a plugin resource that the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //plugin is not blocked.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prefix = makeModuleMap(depName).prefix;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (prefix && (prefixManager = waiting[prefix])) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington forceExec(prefixManager, traced);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depManager = waiting[depName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (depManager && !depManager.isDone && loaded[depName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington value = forceExec(depManager, traced);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington manager.depCallbacks[i](value);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return defined[fullName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Checks if all modules for a context are loaded, and if so, evaluates the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * new ones in right dependency order.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @private
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function checkLoaded() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var waitInterval = config.waitSeconds * 1000,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //It is possible to disable the wait interval by using waitSeconds of 0.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington noLoads = "", hasLoadedProp = false, stillLoading = false,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cycleDeps = [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington i, prop, err, manager, cycleManager, moduleDeps;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If there are items still in the paused queue processing wait.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //This is particularly important in the sync case where each paused
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //item is processed right away but there may be more waiting.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (context.pausedCount > 0) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Determine if priority loading is done. If so clear the priority. If
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //not, then do not check
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.priorityWait) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isPriorityDone()) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Call resume, since it could have
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //some waiting dependencies to trace.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington resume();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //See if anything is still in flight.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (prop in loaded) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!(prop in empty)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington hasLoadedProp = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!loaded[prop]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (expired) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington noLoads += prop + " ";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington stillLoading = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (prop.indexOf('!') === -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //No reason to keep looking for unfinished
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //loading. If the only stillLoading is a
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //plugin resource though, keep going,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //because it may be that a plugin resource
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //is waiting on a non-plugin cycle.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cycleDeps = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleDeps = managerCallbacks[prop] && managerCallbacks[prop].moduleDeps;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (moduleDeps) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cycleDeps.push.apply(cycleDeps, moduleDeps);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Check for exit conditions.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!hasLoadedProp && !context.waitCount) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If the loaded object had no items, then the rest of
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the work below does not need to be done.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (expired && noLoads) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If wait time expired, throw error of unloaded modules.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err = makeError("timeout", "Load timeout for modules: " + noLoads);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err.requireType = "timeout";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err.requireModules = noLoads;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err.contextName = context.contextName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return req.onError(err);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If still loading but a plugin is waiting on a regular module cycle
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //break the cycle.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (stillLoading && cycleDeps.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (manager = waiting[cycleDeps[i]]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if ((cycleManager = findCycle(manager, {}))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington forceExec(cycleManager, {});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If still waiting on loads, and the waiting load is something
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //other than a plugin resource, or there are still outstanding
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //scripts, then just try back later.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!expired && (stillLoading || context.scriptCount)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Something is still waiting to load. Wait for it, but only
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //if a timeout is not already in effect.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington checkLoadedTimeoutId = setTimeout(function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington checkLoadedTimeoutId = 0;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington checkLoaded();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, 50);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If still have items in the waiting cue, but all modules have
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //been loaded, then it means there are some circular dependencies
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //that need to be broken.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //However, as a waiting thing is fired, then it can add items to
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the waiting cue, and those items should not be fired yet, so
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //make sure to redo the checkLoaded call after breaking a single
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //cycle, if nothing else loaded then this logic will pick it up
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //again.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (context.waitCount) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Cycle through the waitAry, and call items in sequence.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (manager = waitAry[i]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington forceExec(manager, {});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If anything got placed in the paused queue, run it down.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (context.paused.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington resume();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Only allow this recursion to a certain depth. Only
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //triggered by errors in calling a module in which its
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //modules waiting on it cannot finish loading, or some circular
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //dependencies that then may add more dependencies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //The value of 5 is a bit arbitrary. Hopefully just one extra
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //pass, or two for the case of circular dependencies generating
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //more work that gets resolved in the sync node case.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (checkLoadedDepth < 5) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington checkLoadedDepth += 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington checkLoaded();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington checkLoadedDepth = 0;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Check for DOM ready, and nothing is waiting across contexts.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.checkReadyState();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Resumes tracing of dependencies and then checks if everything is loaded.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington resume = function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var manager, map, url, i, p, args, fullName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Any defined modules in the global queue, intake them now.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.takeGlobalQueue();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington resumeDepth += 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (context.scriptCount <= 0) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Synchronous envs will push the number below zero with the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //decrement above, be sure to set it back to zero for good measure.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //require() calls that also do not end up loading scripts could
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //push the number negative too.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.scriptCount = 0;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make sure any remaining defQueue items get properly processed.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (defQueue.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = defQueue.shift();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (args[0] === null) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return req.onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1]));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington callDefMain(args);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Skip the resume of paused dependencies
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //if current context is in priority wait.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!config.priorityWait || isPriorityDone()) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (context.paused.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington p = context.paused;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.pausedCount += p.length;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Reset paused list
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.paused = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (manager = p[i]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington map = manager.map;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington url = map.url;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fullName = map.fullName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If the manager is for a plugin managed resource,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //ask the plugin to load it now.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (map.prefix) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington callPlugin(map.prefix, manager);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Regular dependency.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!urlFetched[url] && !loaded[fullName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.load(context, fullName, url);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Mark the URL as fetched, but only if it is
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //not an empty: URL, used by the optimizer.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //In that case we need to be sure to call
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //load() for each module that is mapped to
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //empty: so that dependencies are satisfied
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //correctly.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (url.indexOf('empty:') !== 0) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington urlFetched[url] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Move the start time for timeout forward.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.startTime = (new Date()).getTime();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.pausedCount -= p.length;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Only check if loaded when resume depth is 1. It is likely that
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //it is only greater than 1 in sync environments where a factory
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //function also then calls the callback-style require. In those
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //cases, the checkLoaded should not occur until the resume
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //depth is back at the top level.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (resumeDepth === 1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington checkLoaded();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington resumeDepth -= 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Define the context object. Many of these fields are on here
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //just to make debugging easier.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contextName: contextName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config: config,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington defQueue: defQueue,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington waiting: waiting,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington waitCount: 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington specified: specified,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington loaded: loaded,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington urlMap: urlMap,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington urlFetched: urlFetched,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington scriptCount: 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington defined: defined,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington paused: [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pausedCount: 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington plugins: plugins,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington needFullExec: needFullExec,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fake: {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fullExec: fullExec,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington managerCallbacks: managerCallbacks,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington makeModuleMap: makeModuleMap,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington normalize: normalize,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Set a configuration for the context.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} cfg config object to integrate.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington configure: function (cfg) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var paths, prop, packages, pkgs, packagePaths, requireWait;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make sure the baseUrl ends in a slash.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (cfg.baseUrl) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== "/") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cfg.baseUrl += "/";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Save off the paths and packages since they require special processing,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //they are additive.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington paths = config.paths;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington packages = config.packages;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pkgs = config.pkgs;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Mix in the config values, favoring the new values over
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //existing ones in context.config.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington mixin(config, cfg, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Adjust paths if necessary.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (cfg.paths) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (prop in cfg.paths) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!(prop in empty)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington paths[prop] = cfg.paths[prop];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.paths = paths;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington packagePaths = cfg.packagePaths;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (packagePaths || cfg.packages) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Convert packagePaths into a packages config.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (packagePaths) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (prop in packagePaths) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!(prop in empty)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington configurePackageDir(pkgs, packagePaths[prop], prop);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Adjust packages if necessary.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (cfg.packages) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington configurePackageDir(pkgs, cfg.packages);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Done with modifications, assing packages back to context config
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.pkgs = pkgs;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If priority loading is in effect, trigger the loads now
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (cfg.priority) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Hold on to requireWait value, and reset it after done
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington requireWait = context.requireWait;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Allow tracing some require calls to allow the fetching
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //of the priority config.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.requireWait = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //But first, call resume to register any defined modules that may
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //be in a data-main built file before the priority config
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //call.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington resume();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.require(cfg.priority);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Trigger a resume right away, for the case when
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the script with the priority load is done as part
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //of a data-main call. In that case the normal resume
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //call will not happen because the scriptCount will be
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //at 1, since the script for data-main is being processed.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington resume();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Restore previous state.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.requireWait = requireWait;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.priorityWait = cfg.priority;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If a deps array or a config callback is specified, then call
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //require with those args. This is useful when require is defined as a
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //config object before require.js is loaded.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (cfg.deps || cfg.callback) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.require(cfg.deps || [], cfg.callback);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington requireDefined: function (moduleName, relModuleMap) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return makeModuleMap(moduleName, relModuleMap).fullName in defined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington requireSpecified: function (moduleName, relModuleMap) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return makeModuleMap(moduleName, relModuleMap).fullName in specified;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require: function (deps, callback, relModuleMap) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var moduleName, fullName, moduleMap;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (typeof deps === "string") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isFunction(callback)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Invalid call
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return req.onError(makeError("requireargs", "Invalid require call"));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Synchronous access to one module. If require.get is
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //available (as in the Node adapter), prefer that.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //In this case deps is the moduleName and callback is
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the relModuleMap
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (req.get) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return req.get(context, deps, callback);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Just return the module wanted. In this scenario, the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //second arg (if passed) is just the relModuleMap.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleName = deps;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington relModuleMap = callback;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Normalize module name, if it contains . or ..
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleMap = makeModuleMap(moduleName, relModuleMap);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fullName = moduleMap.fullName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!(fullName in defined)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return req.onError(makeError("notloaded", "Module name '" +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleMap.fullName +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "' has not been loaded yet for context: " +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contextName));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return defined[fullName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Call main but only if there are dependencies or
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //a callback to call.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (deps && deps.length || callback) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington main(null, deps, callback, relModuleMap);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If the require call does not trigger anything new to load,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //then resume the dependency processing.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!context.requireWait) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (!context.scriptCount && context.paused.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington resume();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return context.require;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Internal method to transfer globalQueue items to this context's
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * defQueue.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington takeGlobalQueue: function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Push all the globalDefQueue items into the context's defQueue
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (globalDefQueue.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Array splice in the values since the context code has a
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //local var ref to defQueue, so cannot just reassign the one
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //on context.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington apsp.apply(context.defQueue,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington [context.defQueue.length - 1, 0].concat(globalDefQueue));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington globalDefQueue = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Internal method used by environment adapters to complete a load event.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * A load event could be a script load or just a load pass from a synchronous
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * load call.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} moduleName the name of the module to potentially complete.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington completeLoad: function (moduleName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var args;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.takeGlobalQueue();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (defQueue.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = defQueue.shift();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (args[0] === null) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args[0] = moduleName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (args[0] === moduleName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Found matching define call for this script!
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Some other named define call, most likely the result
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //of a build layer that included many define calls.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington callDefMain(args);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (args) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington callDefMain(args);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //A script that does not call define(), so just simulate
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the call for it. Special exception for jQuery dynamic load.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington callDefMain([moduleName, [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleName === "jquery" && typeof jQuery !== "undefined" ?
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return jQuery;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } : null]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Doing this scriptCount decrement branching because sync envs
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //need to decrement after resume, otherwise it looks like
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //loading is complete after the first dependency is fetched.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //For browsers, it works fine to decrement after, but it means
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the checkLoaded setTimeout 50 ms cost is taken. To avoid
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //that cost, decrement beforehand.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (req.isAsync) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.scriptCount -= 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington resume();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!req.isAsync) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.scriptCount -= 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Converts a module name + .extension into an URL path.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * *Requires* the use of a module name. It does not support using
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * plain URLs like nameToUrl.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington toUrl: function (moduleNamePlusExt, relModuleMap) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var index = moduleNamePlusExt.lastIndexOf("."),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ext = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (index !== -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleNamePlusExt = moduleNamePlusExt.substring(0, index);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return context.nameToUrl(moduleNamePlusExt, ext, relModuleMap);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Converts a module name to a file path. Supports cases where
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * moduleName may actually be just an URL.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington nameToUrl: function (moduleName, ext, relModuleMap) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config = context.config;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Normalize module name if have a base relative module name to work from.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleName = normalize(moduleName, relModuleMap && relModuleMap.fullName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If a colon is in the URL, it indicates a protocol is used and it is just
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //an URL to a file, or if it starts with a slash or ends with .js, it is just a plain file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //The slash is important for protocol-less URLs as well as full paths.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (req.jsExtRegExp.test(moduleName)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Just a plain path, not module name lookup, so just return it.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Add extension if it is included. This is a bit wonky, only non-.js things pass
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //an extension, this method probably needs to be reworked.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington url = moduleName + (ext ? ext : "");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //A module that needs to be converted to a path.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington paths = config.paths;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pkgs = config.pkgs;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington syms = moduleName.split("/");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //For each module name segment, see if there is a path
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //registered for it. Start with most specific name
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //and work up from it.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = syms.length; i > 0; i--) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parentModule = syms.slice(0, i).join("/");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (paths[parentModule]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington syms.splice(0, i, paths[parentModule]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if ((pkg = pkgs[parentModule])) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If module name is just the package name, then looking
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //for the main module.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (moduleName === pkg.name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pkgPath = pkg.location + '/' + pkg.main;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pkgPath = pkg.location;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington syms.splice(0, i, pkgPath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Join the path parts together, then figure out if baseUrl is needed.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington url = syms.join("/") + (ext || ".js");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington url = (url.charAt(0) === '/' || url.match(/^\w+:/) ? "" : config.baseUrl) + url;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return config.urlArgs ? url +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ((url.indexOf('?') === -1 ? '?' : '&') +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.urlArgs) : url;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make these visible on the context so can be called at the very
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //end of the file to bootstrap
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.jQueryCheck = jQueryCheck;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.resume = resume;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return context;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Main entry point.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * If the only argument to require is a string, then the module that
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * is represented by that string is fetched for the appropriate context.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * If the first argument is an array, then it will be treated as an array
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * of dependency string names to fetch. An optional function callback can
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * be specified to execute when all of those dependencies are available.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Make a local req variable to help Caja compliance (it assumes things
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * on a require that are not standardized), and to give a short
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * name for minification/local scope use.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req = requirejs = function (deps, callback) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Find the right context, use default
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var contextName = defContextName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context, config;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // Determine if have config object in the call.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!isArray(deps) && typeof deps !== "string") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // deps is a config object
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config = deps;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isArray(callback)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // Adjust args if there are dependencies
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = callback;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington callback = arguments[2];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config && config.context) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contextName = config.context;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context = contexts[contextName] ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (contexts[contextName] = newContext(contextName));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.configure(config);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return context.require(deps, callback);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Support require.config() to make it easier to cooperate with other
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * AMD loaders on globally agreed names.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.config = function (config) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return req(config);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Export require as a global, but only if it does not already exist.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!require) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require = req;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Global require.toUrl(), to match global require, mostly useful
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * for debugging/work in the global space.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.toUrl = function (moduleNamePlusExt) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return contexts[defContextName].toUrl(moduleNamePlusExt);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.version = version;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Used to filter out dependencies that are already paths.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.jsExtRegExp = /^\/|:|\?|\.js$/;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington s = req.s = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contexts: contexts,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Stores a list of URLs that should not get async script tag treatment.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington skipAsync: {}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.isAsync = req.isBrowser = isBrowser;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isBrowser) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington head = s.head = document.getElementsByTagName("head")[0];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If BASE tag is in play, using appendChild is a problem for IE6.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //When that browser dies, this can be removed. Details in this jQuery bug:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //http://dev.jquery.com/ticket/2709
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington baseElement = document.getElementsByTagName("base")[0];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (baseElement) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington head = s.head = baseElement.parentNode;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Any errors that require explicitly generates will be passed to this
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * function. Intercept/override it if you want custom error handling.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Error} err the error object.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.onError = function (err) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw err;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Does the request to load a module for the browser case.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Make this a separate function to allow other environments
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * to override it.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} context the require context to find state.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} moduleName the name of the module.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} url the URL to the module.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.load = function (context, moduleName, url) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.resourcesReady(false);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.scriptCount += 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.attach(url, context, moduleName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If tracking a jQuery, then make sure its ready callbacks
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //are put on hold to prevent its ready callbacks from
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //triggering too soon.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (context.jQuery && !context.jQueryIncremented) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington jQueryHoldReady(context.jQuery, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.jQueryIncremented = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function getInteractiveScript() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var scripts, i, script;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (interactiveScript && interactiveScript.readyState === 'interactive') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return interactiveScript;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington scripts = document.getElementsByTagName('script');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = scripts.length - 1; i > -1 && (script = scripts[i]); i--) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (script.readyState === 'interactive') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return (interactiveScript = script);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * The function that handles definitions of modules. Differs from
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * require() in that a string for the module should be the first argument,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * and the function to execute after dependencies are loaded should
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * return a value to define the module corresponding to the first argument's
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * name.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington define = function (name, deps, callback) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var node, context;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Allow for anonymous functions
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (typeof name !== 'string') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Adjust args appropriately
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington callback = deps;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = name;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //This module may not have dependencies
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!isArray(deps)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington callback = deps;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If no name, and callback is a function, then figure out if it a
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //CommonJS thing with dependencies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!deps.length && isFunction(callback)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Remove comments from the callback string,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //look for require calls, and pull them into the dependencies,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //but only if there are function args.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (callback.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington callback
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington .toString()
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington .replace(commentRegExp, "")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington .replace(cjsRequireRegExp, function (match, dep) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps.push(dep);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //May be a CommonJS thing even without require calls, but still
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //could use exports, and module. Avoid doing exports and module
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //work though if it just needs require.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //REQUIRES the function to expect the CommonJS variables in the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //order listed below.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = (callback.length === 1 ? ["require"] : ["require", "exports", "module"]).concat(deps);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If in IE 6-8 and hit an anonymous define() call, do the interactive
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //work.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (useInteractive) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node = currentlyAddingScript || getInteractiveScript();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (node) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = node.getAttribute("data-requiremodule");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context = contexts[node.getAttribute("data-requirecontext")];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Always save off evaluating the def call until the script onload handler.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //This allows multiple modules to be in a file without prematurely
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //tracing dependencies, and allows for anonymous module support,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //where the module name is not known until the script onload event
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //occurs. If no context, use the global queue, and get it processed
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //in the onscript load callback.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (context ? context.defQueue : globalDefQueue).push([name, deps, callback]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington define.amd = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington multiversion: true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington plugins: true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington jQuery: true
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Executes the text. Normally just uses eval, but can be modified
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * to use a more environment specific call.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} text the text to execute/evaluate.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.exec = function (text) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return eval(text);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Executes a module callack function. Broken out as a separate function
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * solely to allow the build system to sequence the files in the built
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * layer in the right sequence.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @private
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.execCb = function (name, callback, args, exports) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return callback.apply(exports, args);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Adds a node to the DOM. Public function since used by the order plugin.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * This method should not normally be called by outside code.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.addScriptToDom = function (node) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //For some cache cases in IE 6-8, the script executes before the end
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //of the appendChild execution, so to tie an anonymous define
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //call to the module name (which is stored on the node), hold on
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //to a reference to this node, but clear after the DOM insertion.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington currentlyAddingScript = node;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (baseElement) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington head.insertBefore(node, baseElement);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington head.appendChild(node);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington currentlyAddingScript = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * callback for script loads, used to check status of loading.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Event} evt the event from the browser for the script
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * that was loaded.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @private
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.onScriptLoad = function (evt) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Using currentTarget instead of target for Firefox 2.0's sake. Not
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //all old browsers will be supported, but this one was easy enough
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //to support and still makes sense.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var node = evt.currentTarget || evt.srcElement, contextName, moduleName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (evt.type === "load" || (node && readyRegExp.test(node.readyState))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Reset interactive script so a script node is not held onto for
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //to long.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington interactiveScript = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Pull out the name of the module and the context.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contextName = node.getAttribute("data-requirecontext");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleName = node.getAttribute("data-requiremodule");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context = contexts[contextName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contexts[contextName].completeLoad(moduleName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Clean up script binding. Favor detachEvent because of IE9
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //issue, see attachEvent/addEventListener comment elsewhere
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //in this file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (node.detachEvent && !isOpera) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Probably IE. If not it will throw an error, which will be
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //useful to know.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node.detachEvent("onreadystatechange", req.onScriptLoad);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node.removeEventListener("load", req.onScriptLoad, false);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Attaches the script represented by the URL to the current
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * environment. Right now only supports browser loading,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * but can be redefined in other environments to do the right thing.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} url the url of the script to attach.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} context the context that wants the script.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {moduleName} the name of the module that is associated with the script.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Function} [callback] optional callback, defaults to require.onScriptLoad
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} [type] optional type, defaults to text/javascript
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Function} [fetchOnlyFunction] optional function to indicate the script node
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * should be set up to fetch the script but do not attach it to the DOM
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * so that it can later be attached to execute it. This is a way for the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * order plugin to support ordered loading in IE. Once the script is fetched,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * but not executed, the fetchOnlyFunction will be called.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.attach = function (url, context, moduleName, callback, type, fetchOnlyFunction) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var node;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isBrowser) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //In the browser so use a script tag
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington callback = callback || req.onScriptLoad;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node = context && context.config && context.config.xhtml ?
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington document.createElementNS("http://www.w3.org/1999/xhtml", "html:script") :
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington document.createElement("script");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node.type = type || (context && context.config.scriptType) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "text/javascript";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node.charset = "utf-8";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Use async so Gecko does not block on executing the script if something
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //like a long-polling comet tag is being run first. Gecko likes
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //to evaluate scripts in DOM order, even for dynamic scripts.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //It will fetch them async, but only evaluate the contents in DOM
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //order, so a long-polling script tag can delay execution of scripts
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //after it. But telling Gecko we expect async gets us the behavior
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //we want -- execute it whenever it is finished downloading. Only
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Helps Firefox 3.6+
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Allow some URLs to not be fetched async. Mostly helps the order!
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //plugin
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node.async = !s.skipAsync[url];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (context) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node.setAttribute("data-requirecontext", context.contextName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node.setAttribute("data-requiremodule", moduleName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set up load listener. Test attachEvent first because IE9 has
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //a subtle issue in its addEventListener and script onload firings
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //that do not match the behavior of all other browsers with
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //addEventListener support, which fire the onload event for a
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //script right after the script execution. See:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //UNFORTUNATELY Opera implements attachEvent but does not follow the script
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //script execution mode.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (node.attachEvent && !isOpera) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Probably IE. IE (at least 6-8) do not fire
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //script onload right after executing the script, so
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //we cannot tie the anonymous define call to a name.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //However, IE reports the script as being in "interactive"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //readyState at the time of the define call.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington useInteractive = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fetchOnlyFunction) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Need to use old school onreadystate here since
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //when the event fires and the node is not attached
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //to the DOM, the evt.srcElement is null, so use
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //a closure to remember the node.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node.onreadystatechange = function (evt) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Script loaded but not executed.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Clear loaded handler, set the real one that
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //waits for script execution.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (node.readyState === 'loaded') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node.onreadystatechange = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node.attachEvent("onreadystatechange", callback);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fetchOnlyFunction(node);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node.attachEvent("onreadystatechange", callback);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node.addEventListener("load", callback, false);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node.src = url;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Fetch only means waiting to attach to DOM after loaded.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!fetchOnlyFunction) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.addScriptToDom(node);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return node;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (isWebWorker) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //In a web worker, use importScripts. This is not a very
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //efficient use of importScripts, importScripts will block until
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //its script is downloaded and evaluated. However, if web workers
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //are in play, the expectation that a build has been done so that
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //only one script needs to be loaded anyway. This may need to be
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //reevaluated if other use cases become common.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington importScripts(url);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Account for anonymous modules
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.completeLoad(moduleName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Look for a data-main script attribute, which could also adjust the baseUrl.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isBrowser) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Figure out baseUrl. Get it from the script tag with require.js in it.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington scripts = document.getElementsByTagName("script");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (globalI = scripts.length - 1; globalI > -1 && (script = scripts[globalI]); globalI--) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set the "head" where we can append children by
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //using the script's parent.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!head) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington head = script.parentNode;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Look for a data-main attribute to set main script for the page
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //to load. If it is there, the path to data main becomes the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //baseUrl, if it is not already set.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if ((dataMain = script.getAttribute('data-main'))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!cfg.baseUrl) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Pull off the directory of data-main for use as the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //baseUrl.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington src = dataMain.split('/');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington mainScript = src.pop();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington subPath = src.length ? src.join('/') + '/' : './';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set final config.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cfg.baseUrl = subPath;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Strip off any trailing .js since dataMain is now
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //like a module name.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dataMain = mainScript.replace(jsSuffixRegExp, '');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Put the data-main script in the files to load.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cfg.deps = cfg.deps ? cfg.deps.concat(dataMain) : [dataMain];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //See if there is nothing waiting across contexts, and if not, trigger
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //resourcesReady.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.checkReadyState = function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var contexts = s.contexts, prop;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (prop in contexts) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!(prop in empty)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (contexts[prop].waitCount) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.resourcesReady(true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Internal function that is triggered whenever all scripts/resources
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * have been loaded by the loader. Can be overridden by other, for
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * instance the domReady plugin, which wants to know when all resources
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * are loaded.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.resourcesReady = function (isReady) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var contexts, context, prop;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //First, set the public variable indicating that resources are loading.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.resourcesDone = isReady;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (req.resourcesDone) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If jQuery with DOM ready delayed, release it now.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contexts = s.contexts;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (prop in contexts) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!(prop in empty)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context = contexts[prop];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (context.jQueryIncremented) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington jQueryHoldReady(context.jQuery, false);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.jQueryIncremented = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //FF < 3.6 readyState fix. Needed so that domReady plugin
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //works well in that environment, since require.js is normally
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //loaded via an HTML script tag so it will be there before window load,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //where the domReady plugin is more likely to be loaded after window load.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.pageLoaded = function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (document.readyState !== "complete") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington document.readyState = "complete";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isBrowser) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (document.addEventListener) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!document.readyState) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington document.readyState = "loading";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington window.addEventListener("load", req.pageLoaded, false);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set up default context. If require was a configuration object, use that as base config.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req(cfg);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If modules are built into require.js, then need to make sure dependencies are
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //traced. Use a setTimeout in the browser world, to allow all the modules to register
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //themselves. In a non-browser env, assume that modules are not built into require.js,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //which seems odd to do on the server.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (req.isAsync && typeof setTimeout !== "undefined") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ctx = s.contexts[(cfg.context || defContextName)];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Indicate that the script that includes require() is still loading,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //so that require()'d dependencies are not traced until the end of the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //file is parsed (approximated via the setTimeout call).
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ctx.requireWait = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington setTimeout(function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ctx.requireWait = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!ctx.scriptCount) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ctx.resume();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.checkReadyState();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, 0);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington}());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (env === 'rhino') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license RequireJS rhino Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint strict: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global require: false, java: false, load: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington(function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require.load = function (context, moduleName, url) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Indicate a the module is in process of loading.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.scriptCount += 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington load(url);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Support anonymous modules.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.completeLoad(moduleName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington}());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (env === 'node') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.requirejsVars = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require: require,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington requirejs: require,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington define: define,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington nodeRequire: nodeRequire
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require.nodeRequire = nodeRequire;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license RequireJS node Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint regexp: false, strict: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global require: false, define: false, requirejsVars: false, process: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * This adapter assumes that x.js has loaded it and set up
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * some variables. This adapter just allows limited RequireJS
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * usage from within the requirejs directory. The general
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * node adapater is r.js.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington(function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var nodeReq = requirejsVars.nodeRequire,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req = requirejsVars.require,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington def = requirejsVars.define,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fs = nodeReq('fs'),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington path = nodeReq('path'),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington vm = nodeReq('vm');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Supply an implementation that allows synchronous get of a module.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.get = function (context, moduleName, relModuleMap) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (moduleName === "require" || moduleName === "exports" || moduleName === "module") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.onError(new Error("Explicit require of " + moduleName + " is not allowed."));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ret,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleMap = context.makeModuleMap(moduleName, relModuleMap);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Normalize module name, if it contains . or ..
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleName = moduleMap.fullName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (moduleName in context.defined) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = context.defined[moduleName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ret === undefined) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Try to dynamically fetch it.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.load(context, moduleName, moduleMap.url);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //The above call is sync, so can do the next thing safely.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = context.defined[moduleName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Add wrapper around the code so that it gets the requirejs
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //API instead of the Node API, and it is done lexically so
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //that it survives later execution.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.makeNodeWrapper = function (contents) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return '(function (require, requirejs, define) { ' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contents +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington '\n}(requirejsVars.require, requirejsVars.requirejs, requirejsVars.define));';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.load = function (context, moduleName, url) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var contents, err;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Indicate a the module is in process of loading.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.scriptCount += 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
b1b6b62ef1fb82a380162e4f36ae713b58b74610James Phillpotts if (fs.existsSync ? fs.existsSync(url) : path.existsSync(url)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contents = fs.readFileSync(url, 'utf8');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contents = req.makeNodeWrapper(contents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington vm.runInThisContext(contents, fs.realpathSync(url));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err = new Error('Evaluating ' + url + ' as module "' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleName + '" failed with error: ' + e);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err.originalError = e;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err.moduleName = moduleName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err.fileName = url;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return req.onError(err);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington def(moduleName, function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return (context.config.nodeRequire || req.nodeRequire)(moduleName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err = new Error('Calling node\'s require("' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleName + '") failed with error: ' + e);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err.originalError = e;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err.moduleName = moduleName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return req.onError(err);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Support anonymous modules.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.completeLoad(moduleName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Override to provide the function wrapper for define/require.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req.exec = function (text) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /*jslint evil: true */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington text = req.makeNodeWrapper(text);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return eval(text);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington}());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Support a default file name to execute. Useful for hosted envs
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //like Joyent where it defaults to a server.js as the only executed
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //script. But only do it if this is not an optimization run.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (commandOption !== 'o' && (!fileName || !jsSuffixRegExp.test(fileName))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileName = 'main.js';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Loads the library files that can be used for the optimizer, or for other
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * tasks.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function loadLib() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint strict: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global Packages: false, process: false, window: false, navigator: false,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington document: false, define: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * A plugin that modifies any /env/ path to be the right path based on
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * the host environment. Right now only works for Node, Rhino and browser.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington(function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var pathRegExp = /(\/|^)env\/|\{env\}/,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington env = 'unknown';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (typeof Packages !== 'undefined') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington env = 'rhino';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (typeof process !== 'undefined') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington env = 'node';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (typeof window !== "undefined" && navigator && document) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington env = 'browser';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington define('env', {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington load: function (name, req, load, config) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Allow override in the config.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.env) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington env = config.env;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = name.replace(pathRegExp, function (match, prefix) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (match.indexOf('{') === -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return prefix + env + '/';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return env;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req([name], function (mod) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington load(mod);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington}());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonif(env === 'node') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint strict: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global define: false, process: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('node/args', function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Do not return the "node" or "r.js" arguments
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var args = process.argv.slice(2);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Ignore any command option used for rq.js
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (args[0] && args[0].indexOf('-' === 0)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = args.slice(1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return args;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonif(env === 'rhino') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint strict: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global define: false, process: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar jsLibRhinoArgs = (typeof rhinoArgs !== 'undefined' && rhinoArgs) || [].concat(Array.prototype.slice.call(arguments, 0));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('rhino/args', function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var args = jsLibRhinoArgs;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Ignore any command option used for rq.js
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (args[0] && args[0].indexOf('-' === 0)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = args.slice(1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return args;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonif(env === 'node') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license RequireJS Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint strict: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global define: false, console: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('node/load', ['fs'], function (fs) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function load(fileName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var contents = fs.readFileSync(fileName, 'utf8');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington process.compile(contents, fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return load;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonif(env === 'rhino') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license RequireJS Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint strict: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global define: false, load: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('rhino/load', function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return load;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonif(env === 'node') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint plusplus: false, octal:false, strict: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global define: false, process: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('node/file', ['fs', 'path'], function (fs, path) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var isWindows = process.platform === 'win32',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington windowsDriveRegExp = /^[a-zA-Z]\:\/$/,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function frontSlash(path) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return path.replace(/\\/g, '/');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function exists(path) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isWindows && path.charAt(path.length - 1) === '/' &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington path.charAt(path.length - 2) !== ':') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington path = path.substring(0, path.length - 1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fs.statSync(path);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function mkDir(dir) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!exists(dir) && (!isWindows || !windowsDriveRegExp.test(dir))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fs.mkdirSync(dir, 511);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function mkFullDir(dir) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var parts = dir.split('/'),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington currDir = '',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington first = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parts.forEach(function (part) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //First part may be empty string if path starts with a slash.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington currDir += part + '/';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington first = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (part) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington mkDir(currDir);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington backSlashRegExp: /\\/g,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington exclusionRegExp: /^\./,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington getLineSeparator: function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return '/';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington exists: function (fileName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return exists(fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parent: function (fileName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var parts = fileName.split('/');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parts.pop();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return parts.join('/');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Gets the absolute file path as a string, normalized
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * to using front slashes for path separators.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileName
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington absPath: function (fileName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return frontSlash(path.normalize(frontSlash(fs.realpathSync(fileName))));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington normalize: function (fileName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return frontSlash(path.normalize(fileName));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isFile: function (path) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return fs.statSync(path).isFile();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isDirectory: function (path) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return fs.statSync(path).isDirectory();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington getFilteredFileList: function (/*String*/startDir, /*RegExp*/regExpFilters, /*boolean?*/makeUnixPaths) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //summary: Recurses startDir and finds matches to the files that match regExpFilters.include
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //and do not match regExpFilters.exclude. Or just one regexp can be passed in for regExpFilters,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //and it will be treated as the "include" case.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Ignores files/directories that start with a period (.) unless exclusionRegExp
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //is set to another value.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var files = [], topDir, regExpInclude, regExpExclude, dirFileArray,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington i, stat, filePath, ok, dirFiles, fileName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington topDir = startDir;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington regExpInclude = regExpFilters.include || regExpFilters;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington regExpExclude = regExpFilters.exclude || null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (file.exists(topDir)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dirFileArray = fs.readdirSync(topDir);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; i < dirFileArray.length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileName = dirFileArray[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington filePath = path.join(topDir, fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington stat = fs.statSync(filePath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (stat.isFile()) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (makeUnixPaths) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make sure we have a JS string.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (filePath.indexOf("/") === -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington filePath = frontSlash(filePath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ok = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (regExpInclude) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ok = filePath.match(regExpInclude);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ok && regExpExclude) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ok = !filePath.match(regExpExclude);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ok && (!file.exclusionRegExp ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington !file.exclusionRegExp.test(fileName))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington files.push(filePath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (stat.isDirectory() &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (!file.exclusionRegExp || !file.exclusionRegExp.test(fileName))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dirFiles = this.getFilteredFileList(filePath, regExpFilters, makeUnixPaths);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington files.push.apply(files, dirFiles);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return files; //Array
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington copyDir: function (/*String*/srcDir, /*String*/destDir, /*RegExp?*/regExpFilter, /*boolean?*/onlyCopyNew) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //summary: copies files from srcDir to destDir using the regExpFilter to determine if the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //file should be copied. Returns a list file name strings of the destinations that were copied.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington regExpFilter = regExpFilter || /\w/;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Normalize th directory names, but keep front slashes.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //path module on windows now returns backslashed paths.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington srcDir = frontSlash(path.normalize(srcDir));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington destDir = frontSlash(path.normalize(destDir));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var fileNames = file.getFilteredFileList(srcDir, regExpFilter, true),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington copiedFiles = [], i, srcFileName, destFileName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; i < fileNames.length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington srcFileName = fileNames[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington destFileName = srcFileName.replace(srcDir, destDir);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (file.copyFile(srcFileName, destFileName, onlyCopyNew)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington copiedFiles.push(destFileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return copiedFiles.length ? copiedFiles : null; //Array or null
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington copyFile: function (/*String*/srcFileName, /*String*/destFileName, /*boolean?*/onlyCopyNew) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //summary: copies srcFileName to destFileName. If onlyCopyNew is set, it only copies the file if
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //srcFileName is newer than destFileName. Returns a boolean indicating if the copy occurred.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var parentDir;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //logger.trace("Src filename: " + srcFileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //logger.trace("Dest filename: " + destFileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If onlyCopyNew is true, then compare dates and only copy if the src is newer
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //than dest.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (onlyCopyNew) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (file.exists(destFileName) && fs.statSync(destFileName).mtime.getTime() >= fs.statSync(srcFileName).mtime.getTime()) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false; //Boolean
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make sure destination dir exists.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parentDir = path.dirname(destFileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!file.exists(parentDir)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington mkFullDir(parentDir);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fs.writeFileSync(destFileName, fs.readFileSync(srcFileName, 'binary'), 'binary');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return true; //Boolean
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Renames a file. May fail if "to" already exists or is on another drive.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington renameFile: function (from, to) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return fs.renameSync(from, to);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Reads a *text* file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington readFile: function (/*String*/path, /*String?*/encoding) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (encoding === 'utf-8') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington encoding = 'utf8';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!encoding) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington encoding = 'utf8';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var text = fs.readFileSync(path, encoding);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Hmm, would not expect to get A BOM, but it seems to happen,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //remove it just in case.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (text.indexOf('\uFEFF') === 0) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington text = text.substring(1, text.length);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return text;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington saveUtf8File: function (/*String*/fileName, /*String*/fileContents) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //summary: saves a *text* file using UTF-8 encoding.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.saveFile(fileName, fileContents, "utf8");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington saveFile: function (/*String*/fileName, /*String*/fileContents, /*String?*/encoding) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //summary: saves a *text* file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var parentDir;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (encoding === 'utf-8') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington encoding = 'utf8';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!encoding) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington encoding = 'utf8';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make sure destination directories exist.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parentDir = path.dirname(fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!file.exists(parentDir)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington mkFullDir(parentDir);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fs.writeFileSync(fileName, fileContents, encoding);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deleteFile: function (/*String*/fileName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //summary: deletes a file or directory if it exists.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var files, i, stat;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (file.exists(fileName)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington stat = fs.statSync(fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (stat.isDirectory()) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington files = fs.readdirSync(fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; i < files.length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.deleteFile(path.join(fileName, files[i]));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fs.rmdirSync(fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fs.unlinkSync(fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return file;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonif(env === 'rhino') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license RequireJS Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington//Helper functions to deal with file I/O.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint plusplus: false, strict: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global java: false, define: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('rhino/file', function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var file = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington backSlashRegExp: /\\/g,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington exclusionRegExp: /^\./,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington getLineSeparator: function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return file.lineSeparator;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lineSeparator: java.lang.System.getProperty("line.separator"), //Java String
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington exists: function (fileName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return (new java.io.File(fileName)).exists();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parent: function (fileName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return file.absPath((new java.io.File(fileName)).getParentFile());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington normalize: function (fileName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return file.absPath(fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isFile: function (path) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return (new java.io.File(path)).isFile();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isDirectory: function (path) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return (new java.io.File(path)).isDirectory();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Gets the absolute file path as a string, normalized
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * to using front slashes for path separators.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {java.io.File||String} file
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington absPath: function (fileObj) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (typeof fileObj === "string") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileObj = new java.io.File(fileObj);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return (fileObj.getAbsolutePath() + "").replace(file.backSlashRegExp, "/");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington getFilteredFileList: function (/*String*/startDir, /*RegExp*/regExpFilters, /*boolean?*/makeUnixPaths, /*boolean?*/startDirIsJavaObject) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //summary: Recurses startDir and finds matches to the files that match regExpFilters.include
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //and do not match regExpFilters.exclude. Or just one regexp can be passed in for regExpFilters,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //and it will be treated as the "include" case.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Ignores files/directories that start with a period (.) unless exclusionRegExp
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //is set to another value.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var files = [], topDir, regExpInclude, regExpExclude, dirFileArray,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington i, fileObj, filePath, ok, dirFiles;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington topDir = startDir;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!startDirIsJavaObject) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington topDir = new java.io.File(startDir);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington regExpInclude = regExpFilters.include || regExpFilters;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington regExpExclude = regExpFilters.exclude || null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (topDir.exists()) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dirFileArray = topDir.listFiles();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; i < dirFileArray.length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileObj = dirFileArray[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fileObj.isFile()) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington filePath = fileObj.getPath();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (makeUnixPaths) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make sure we have a JS string.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington filePath = String(filePath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (filePath.indexOf("/") === -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington filePath = filePath.replace(/\\/g, "/");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ok = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (regExpInclude) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ok = filePath.match(regExpInclude);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ok && regExpExclude) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ok = !filePath.match(regExpExclude);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ok && (!file.exclusionRegExp ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington !file.exclusionRegExp.test(fileObj.getName()))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington files.push(filePath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (fileObj.isDirectory() &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (!file.exclusionRegExp || !file.exclusionRegExp.test(fileObj.getName()))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dirFiles = this.getFilteredFileList(fileObj, regExpFilters, makeUnixPaths, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington files.push.apply(files, dirFiles);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return files; //Array
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington copyDir: function (/*String*/srcDir, /*String*/destDir, /*RegExp?*/regExpFilter, /*boolean?*/onlyCopyNew) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //summary: copies files from srcDir to destDir using the regExpFilter to determine if the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //file should be copied. Returns a list file name strings of the destinations that were copied.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington regExpFilter = regExpFilter || /\w/;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var fileNames = file.getFilteredFileList(srcDir, regExpFilter, true),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington copiedFiles = [], i, srcFileName, destFileName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; i < fileNames.length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington srcFileName = fileNames[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington destFileName = srcFileName.replace(srcDir, destDir);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (file.copyFile(srcFileName, destFileName, onlyCopyNew)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington copiedFiles.push(destFileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return copiedFiles.length ? copiedFiles : null; //Array or null
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington copyFile: function (/*String*/srcFileName, /*String*/destFileName, /*boolean?*/onlyCopyNew) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //summary: copies srcFileName to destFileName. If onlyCopyNew is set, it only copies the file if
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //srcFileName is newer than destFileName. Returns a boolean indicating if the copy occurred.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var destFile = new java.io.File(destFileName), srcFile, parentDir,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington srcChannel, destChannel;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //logger.trace("Src filename: " + srcFileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //logger.trace("Dest filename: " + destFileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If onlyCopyNew is true, then compare dates and only copy if the src is newer
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //than dest.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (onlyCopyNew) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington srcFile = new java.io.File(srcFileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (destFile.exists() && destFile.lastModified() >= srcFile.lastModified()) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false; //Boolean
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make sure destination dir exists.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parentDir = destFile.getParentFile();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!parentDir.exists()) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!parentDir.mkdirs()) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw "Could not create directory: " + parentDir.getAbsolutePath();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Java's version of copy file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington srcChannel = new java.io.FileInputStream(srcFileName).getChannel();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington destChannel = new java.io.FileOutputStream(destFileName).getChannel();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington destChannel.transferFrom(srcChannel, 0, srcChannel.size());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington srcChannel.close();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington destChannel.close();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return true; //Boolean
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Renames a file. May fail if "to" already exists or is on another drive.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington renameFile: function (from, to) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return (new java.io.File(from)).renameTo((new java.io.File(to)));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington readFile: function (/*String*/path, /*String?*/encoding) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //A file read function that can deal with BOMs
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington encoding = encoding || "utf-8";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var fileObj = new java.io.File(path),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(fileObj), encoding)),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington stringBuffer, line;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington stringBuffer = new java.lang.StringBuffer();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington line = input.readLine();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // http://www.unicode.org/faq/utf_bom.html
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (line && line.length() && line.charAt(0) === 0xfeff) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // Eat the BOM, since we've already found the encoding on this file,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // and we plan to concatenating this buffer with others; the BOM should
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // only appear at the top of a file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington line = line.substring(1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (line !== null) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington stringBuffer.append(line);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington stringBuffer.append(file.lineSeparator);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington line = input.readLine();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make sure we return a JavaScript string and not a Java string.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return String(stringBuffer.toString()); //String
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } finally {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington input.close();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington saveUtf8File: function (/*String*/fileName, /*String*/fileContents) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //summary: saves a file using UTF-8 encoding.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.saveFile(fileName, fileContents, "utf-8");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington saveFile: function (/*String*/fileName, /*String*/fileContents, /*String?*/encoding) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //summary: saves a file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var outFile = new java.io.File(fileName), outWriter, parentDir, os;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parentDir = outFile.getAbsoluteFile().getParentFile();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!parentDir.exists()) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!parentDir.mkdirs()) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw "Could not create directory: " + parentDir.getAbsolutePath();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (encoding) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington outWriter = new java.io.OutputStreamWriter(new java.io.FileOutputStream(outFile), encoding);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington outWriter = new java.io.OutputStreamWriter(new java.io.FileOutputStream(outFile));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington os = new java.io.BufferedWriter(outWriter);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington os.write(fileContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } finally {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington os.close();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deleteFile: function (/*String*/fileName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //summary: deletes a file or directory if it exists.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var fileObj = new java.io.File(fileName), files, i;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fileObj.exists()) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fileObj.isDirectory()) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington files = fileObj.listFiles();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; i < files.length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.deleteFile(files[i]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileObj["delete"]();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return file;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint plusplus: true */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global define */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('lang', function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'use strict';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var lang = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington backSlashRegExp: /\\/g,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ostring: Object.prototype.toString,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isArray: Array.isArray || function (it) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return lang.ostring.call(it) === "[object Array]";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isFunction: function(it) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return lang.ostring.call(it) === "[object Function]";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isRegExp: function(it) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return it && it instanceof RegExp;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington _mixin: function(dest, source, override){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var name;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (name in source) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if(source.hasOwnProperty(name)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && (override || !dest.hasOwnProperty(name))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dest[name] = source[name];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return dest; // Object
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * mixin({}, obj1, obj2) is allowed. If the last argument is a boolean,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * then the source objects properties are force copied over to dest.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington mixin: function(dest){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var parameters = Array.prototype.slice.call(arguments),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington override, i, l;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!dest) { dest = {}; }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (parameters.length > 2 && typeof arguments[parameters.length-1] === 'boolean') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington override = parameters.pop();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 1, l = parameters.length; i < l; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lang._mixin(dest, parameters[i], override);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return dest; // Object
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington delegate: (function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // boodman/crockford delegation w/ cornford optimization
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function TMP() {}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return function (obj, props) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington TMP.prototype = obj;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var tmp = new TMP();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington TMP.prototype = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (props) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lang.mixin(tmp, props);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return tmp; // Object
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }())
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return lang;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonif(env === 'node') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license RequireJS Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint strict: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global define: false, console: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('node/print', function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function print(msg) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington console.log(msg);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return print;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonif(env === 'rhino') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license RequireJS Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint strict: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global define: false, print: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('rhino/print', function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return print;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license RequireJS Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint nomen: false, strict: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global define: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('logger', ['env!env/print'], function (print) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var logger = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington TRACE: 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington INFO: 1,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington WARN: 2,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ERROR: 3,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington SILENT: 4,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington level: 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington logPrefix: "",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington logLevel: function( level ) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.level = level;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington trace: function (message) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (this.level <= this.TRACE) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this._print(message);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington info: function (message) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (this.level <= this.INFO) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this._print(message);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington warn: function (message) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (this.level <= this.WARN) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this._print(message);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington error: function (message) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (this.level <= this.ERROR) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this._print(message);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington _print: function (message) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this._sysPrint((this.logPrefix ? (this.logPrefix + " ") : "") + message);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington _sysPrint: function (message) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington print(message);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return logger;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington//Just a blank file to use when building the optimizer with the optimizer,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington//so that the build does not attempt to inline some env modules,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington//like Node's fs and path.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington//Just a blank file to use when building the optimizer with the optimizer,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington//so that the build does not attempt to inline some env modules,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington//like Node's fs and path.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('uglifyjs/parse-js', ["require", "exports", "module"], function(require, exports, module) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/***********************************************************************
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington A JavaScript tokenizer / parser / beautifier / compressor.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington This version is suitable for Node.js. With minimal changes (the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington exports stuff) it should work on any JS platform.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington This file contains the tokenizer/parser. It is a port to JavaScript
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington of parse-js [1], a JavaScript parser library written in Common Lisp
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington by Marijn Haverbeke. Thank you Marijn!
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington [1] http://marijn.haverbeke.nl/parse-js/
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington Exported functions:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington - tokenizer(code) -- returns a function. Call the returned
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function to fetch the next token.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington - parse(code) -- returns an AST of the given JavaScript code.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington -------------------------------- (C) ---------------------------------
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington Author: Mihai Bazon
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington <mihai.bazon@gmail.com>
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington http://mihai.bazon.net/blog
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington Distributed under the BSD license:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington Copyright 2010 (c) Mihai Bazon <mihai.bazon@gmail.com>
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington Based on parse-js (http://marijn.haverbeke.nl/parse-js/).
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington Redistribution and use in source and binary forms, with or without
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington modification, are permitted provided that the following conditions
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington are met:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Redistributions of source code must retain the above
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington copyright notice, this list of conditions and the following
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington disclaimer.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Redistributions in binary form must reproduce the above
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington copyright notice, this list of conditions and the following
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington disclaimer in the documentation and/or other materials
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington provided with the distribution.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington SUCH DAMAGE.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ***********************************************************************/
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/* -----[ Tokenizer (constants) ]----- */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar KEYWORDS = array_to_hash([
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "break",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "case",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "catch",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "const",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "continue",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "default",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "delete",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "do",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "else",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "finally",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "for",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "function",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "if",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "in",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "instanceof",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "new",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "return",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "switch",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "throw",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "try",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "typeof",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "var",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "void",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "while",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "with"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar RESERVED_WORDS = array_to_hash([
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "abstract",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "boolean",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "byte",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "char",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "class",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "debugger",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "double",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "enum",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "export",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "extends",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "final",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "float",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "goto",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "implements",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "import",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "int",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "interface",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "long",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "native",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "package",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "private",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "protected",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "public",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "short",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "static",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "super",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "synchronized",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "throws",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "transient",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "volatile"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar KEYWORDS_BEFORE_EXPRESSION = array_to_hash([
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "return",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "new",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "delete",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "throw",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "else",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "case"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar KEYWORDS_ATOM = array_to_hash([
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "false",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "null",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "true",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "undefined"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar OPERATOR_CHARS = array_to_hash(characters("+-*&%=<>!?|~^"));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar RE_HEX_NUMBER = /^0x[0-9a-f]+$/i;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar RE_OCT_NUMBER = /^0[0-7]+$/;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar OPERATORS = array_to_hash([
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "in",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "instanceof",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "typeof",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "new",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "void",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "delete",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "++",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "--",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "+",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "-",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "!",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "~",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "&",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "|",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "^",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "*",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "/",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "%",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ">>",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "<<",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ">>>",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "<",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ">",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "<=",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ">=",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "==",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "===",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "!=",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "!==",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "?",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "=",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "+=",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "-=",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "/=",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "*=",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "%=",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ">>=",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "<<=",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ">>>=",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "|=",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "^=",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "&=",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "&&",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "||"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar WHITESPACE_CHARS = array_to_hash(characters(" \u00a0\n\r\t\f\u000b\u200b\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000"));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar PUNC_BEFORE_EXPRESSION = array_to_hash(characters("[{}(,.;:"));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar PUNC_CHARS = array_to_hash(characters("[]{}(),;:"));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar REGEXP_MODIFIERS = array_to_hash(characters("gmsiy"));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/* -----[ Tokenizer ]----- */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington// regexps adapted from http://xregexp.com/plugins/#unicode
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar UNICODE = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington letter: new RegExp("[\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u0523\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0621-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971\\u0972\\u097B-\\u097F\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D28\\u0D2A-\\u0D39\\u0D3D\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC\\u0EDD\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8B\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10D0-\\u10FA\\u10FC\\u1100-\\u1159\\u115F-\\u11A2\\u11A8-\\u11F9\\u1200-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u1676\\u1681-\\u169A\\u16A0-\\u16EA\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u1900-\\u191C\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19A9\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u2094\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2C6F\\u2C71-\\u2C7D\\u2C80-\\u2CE4\\u2D00-\\u2D25\\u2D30-\\u2D65\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31B7\\u31F0-\\u31FF\\u3400\\u4DB5\\u4E00\\u9FC3\\uA000-\\uA48C\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA65F\\uA662-\\uA66E\\uA67F-\\uA697\\uA717-\\uA71F\\uA722-\\uA788\\uA78B\\uA78C\\uA7FB-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA90A-\\uA925\\uA930-\\uA946\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAC00\\uD7A3\\uF900-\\uFA2D\\uFA30-\\uFA6A\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]"),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington non_spacing_mark: new RegExp("[\\u0300-\\u036F\\u0483-\\u0487\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065E\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0900-\\u0902\\u093C\\u0941-\\u0948\\u094D\\u0951-\\u0955\\u0962\\u0963\\u0981\\u09BC\\u09C1-\\u09C4\\u09CD\\u09E2\\u09E3\\u0A01\\u0A02\\u0A3C\\u0A41\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81\\u0A82\\u0ABC\\u0AC1-\\u0AC5\\u0AC7\\u0AC8\\u0ACD\\u0AE2\\u0AE3\\u0B01\\u0B3C\\u0B3F\\u0B41-\\u0B44\\u0B4D\\u0B56\\u0B62\\u0B63\\u0B82\\u0BC0\\u0BCD\\u0C3E-\\u0C40\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0CBC\\u0CBF\\u0CC6\\u0CCC\\u0CCD\\u0CE2\\u0CE3\\u0D41-\\u0D44\\u0D4D\\u0D62\\u0D63\\u0DCA\\u0DD2-\\u0DD4\\u0DD6\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F71-\\u0F7E\\u0F80-\\u0F84\\u0F86\\u0F87\\u0F90-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102D-\\u1030\\u1032-\\u1037\\u1039\\u103A\\u103D\\u103E\\u1058\\u1059\\u105E-\\u1060\\u1071-\\u1074\\u1082\\u1085\\u1086\\u108D\\u109D\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B7-\\u17BD\\u17C6\\u17C9-\\u17D3\\u17DD\\u180B-\\u180D\\u18A9\\u1920-\\u1922\\u1927\\u1928\\u1932\\u1939-\\u193B\\u1A17\\u1A18\\u1A56\\u1A58-\\u1A5E\\u1A60\\u1A62\\u1A65-\\u1A6C\\u1A73-\\u1A7C\\u1A7F\\u1B00-\\u1B03\\u1B34\\u1B36-\\u1B3A\\u1B3C\\u1B42\\u1B6B-\\u1B73\\u1B80\\u1B81\\u1BA2-\\u1BA5\\u1BA8\\u1BA9\\u1C2C-\\u1C33\\u1C36\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE0\\u1CE2-\\u1CE8\\u1CED\\u1DC0-\\u1DE6\\u1DFD-\\u1DFF\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2CEF-\\u2CF1\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F\\uA67C\\uA67D\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA825\\uA826\\uA8C4\\uA8E0-\\uA8F1\\uA926-\\uA92D\\uA947-\\uA951\\uA980-\\uA982\\uA9B3\\uA9B6-\\uA9B9\\uA9BC\\uAA29-\\uAA2E\\uAA31\\uAA32\\uAA35\\uAA36\\uAA43\\uAA4C\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uABE5\\uABE8\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE26]"),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington space_combining_mark: new RegExp("[\\u0903\\u093E-\\u0940\\u0949-\\u094C\\u094E\\u0982\\u0983\\u09BE-\\u09C0\\u09C7\\u09C8\\u09CB\\u09CC\\u09D7\\u0A03\\u0A3E-\\u0A40\\u0A83\\u0ABE-\\u0AC0\\u0AC9\\u0ACB\\u0ACC\\u0B02\\u0B03\\u0B3E\\u0B40\\u0B47\\u0B48\\u0B4B\\u0B4C\\u0B57\\u0BBE\\u0BBF\\u0BC1\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCC\\u0BD7\\u0C01-\\u0C03\\u0C41-\\u0C44\\u0C82\\u0C83\\u0CBE\\u0CC0-\\u0CC4\\u0CC7\\u0CC8\\u0CCA\\u0CCB\\u0CD5\\u0CD6\\u0D02\\u0D03\\u0D3E-\\u0D40\\u0D46-\\u0D48\\u0D4A-\\u0D4C\\u0D57\\u0D82\\u0D83\\u0DCF-\\u0DD1\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0F3E\\u0F3F\\u0F7F\\u102B\\u102C\\u1031\\u1038\\u103B\\u103C\\u1056\\u1057\\u1062-\\u1064\\u1067-\\u106D\\u1083\\u1084\\u1087-\\u108C\\u108F\\u109A-\\u109C\\u17B6\\u17BE-\\u17C5\\u17C7\\u17C8\\u1923-\\u1926\\u1929-\\u192B\\u1930\\u1931\\u1933-\\u1938\\u19B0-\\u19C0\\u19C8\\u19C9\\u1A19-\\u1A1B\\u1A55\\u1A57\\u1A61\\u1A63\\u1A64\\u1A6D-\\u1A72\\u1B04\\u1B35\\u1B3B\\u1B3D-\\u1B41\\u1B43\\u1B44\\u1B82\\u1BA1\\u1BA6\\u1BA7\\u1BAA\\u1C24-\\u1C2B\\u1C34\\u1C35\\u1CE1\\u1CF2\\uA823\\uA824\\uA827\\uA880\\uA881\\uA8B4-\\uA8C3\\uA952\\uA953\\uA983\\uA9B4\\uA9B5\\uA9BA\\uA9BB\\uA9BD-\\uA9C0\\uAA2F\\uAA30\\uAA33\\uAA34\\uAA4D\\uAA7B\\uABE3\\uABE4\\uABE6\\uABE7\\uABE9\\uABEA\\uABEC]"),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington connector_punctuation: new RegExp("[\\u005F\\u203F\\u2040\\u2054\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFF3F]")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction is_letter(ch) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return UNICODE.letter.test(ch);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction is_digit(ch) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ch = ch.charCodeAt(0);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ch >= 48 && ch <= 57; //XXX: find out if "UnicodeDigit" means something else than 0..9
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction is_alphanumeric_char(ch) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return is_digit(ch) || is_letter(ch);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction is_unicode_combining_mark(ch) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return UNICODE.non_spacing_mark.test(ch) || UNICODE.space_combining_mark.test(ch);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction is_unicode_connector_punctuation(ch) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return UNICODE.connector_punctuation.test(ch);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction is_identifier_start(ch) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ch == "$" || ch == "_" || is_letter(ch);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction is_identifier_char(ch) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return is_identifier_start(ch)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington || is_unicode_combining_mark(ch)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington || is_digit(ch)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington || is_unicode_connector_punctuation(ch)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington || ch == "\u200c" // zero-width non-joiner <ZWNJ>
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington || ch == "\u200d" // zero-width joiner <ZWJ> (in my ECMA-262 PDF, this is also 200c)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction parse_js_number(num) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (RE_HEX_NUMBER.test(num)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return parseInt(num.substr(2), 16);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (RE_OCT_NUMBER.test(num)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return parseInt(num.substr(1), 8);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (RE_DEC_NUMBER.test(num)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return parseFloat(num);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction JS_Parse_Error(message, line, col, pos) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.message = message;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.line = line + 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.col = col + 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.pos = pos + 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.stack = new Error().stack;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill CunningtonJS_Parse_Error.prototype.toString = function() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return this.message + " (line: " + this.line + ", col: " + this.col + ", pos: " + this.pos + ")" + "\n\n" + this.stack;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction js_error(message, line, col, pos) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw new JS_Parse_Error(message, line, col, pos);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction is_token(token, type, val) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return token.type == type && (val == null || token.value == val);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar EX_EOF = {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction tokenizer($TEXT) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var S = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington text : $TEXT.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, ''),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pos : 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington tokpos : 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington line : 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington tokline : 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington col : 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington tokcol : 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington newline_before : false,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington regex_allowed : false,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington comments_before : []
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function peek() { return S.text.charAt(S.pos); };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function next(signal_eof, in_string) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ch = S.text.charAt(S.pos++);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (signal_eof && !ch)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw EX_EOF;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ch == "\n") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.newline_before = S.newline_before || !in_string;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ++S.line;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.col = 0;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ++S.col;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ch;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function eof() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return !S.peek();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function find(what, signal_eof) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var pos = S.text.indexOf(what, S.pos);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (signal_eof && pos == -1) throw EX_EOF;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return pos;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function start_token() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.tokline = S.line;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.tokcol = S.col;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.tokpos = S.pos;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function token(type, value, is_comment) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.regex_allowed = ((type == "operator" && !HOP(UNARY_POSTFIX, value)) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (type == "keyword" && HOP(KEYWORDS_BEFORE_EXPRESSION, value)) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (type == "punc" && HOP(PUNC_BEFORE_EXPRESSION, value)));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ret = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington type : type,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington value : value,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington line : S.tokline,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington col : S.tokcol,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pos : S.tokpos,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington endpos : S.pos,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington nlb : S.newline_before
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!is_comment) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret.comments_before = S.comments_before;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.comments_before = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.newline_before = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function skip_whitespace() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (HOP(WHITESPACE_CHARS, peek()))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function read_while(pred) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ret = "", ch = peek(), i = 0;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (ch && pred(ch, i++)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret += next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ch = peek();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function parse_error(err) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington js_error(err, S.tokline, S.tokcol, S.tokpos);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function read_num(prefix) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var num = read_while(function(ch, i){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ch == "x" || ch == "X") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (has_x) return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return has_x = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!has_x && (ch == "E" || ch == "e")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (has_e) return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return has_e = after_e = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ch == "-") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (after_e || (i == 0 && !prefix)) return true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ch == "+") return after_e;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington after_e = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ch == ".") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!has_dot && !has_x)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return has_dot = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return is_alphanumeric_char(ch);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (prefix)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington num = prefix + num;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var valid = parse_js_number(num);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!isNaN(valid)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return token("num", valid);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse_error("Invalid syntax: " + num);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function read_escaped_char(in_string) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ch = next(true, in_string);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (ch) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "n" : return "\n";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "r" : return "\r";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "t" : return "\t";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "b" : return "\b";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "v" : return "\u000b";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "f" : return "\f";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "0" : return "\0";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "x" : return String.fromCharCode(hex_bytes(2));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "u" : return String.fromCharCode(hex_bytes(4));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "\n": return "";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington default : return ch;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function hex_bytes(n) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var num = 0;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (; n > 0; --n) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var digit = parseInt(next(true), 16);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isNaN(digit))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse_error("Invalid hex-character pattern in string");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington num = (num << 4) | digit;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return num;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function read_string() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return with_eof_error("Unterminated string constant", function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var quote = next(), ret = "";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (;;) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ch = next(true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ch == "\\") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // read OctalEscapeSequence (XXX: deprecated if "strict mode")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // https://github.com/mishoo/UglifyJS/issues/178
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var octal_len = 0, first = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ch = read_while(function(ch){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ch >= "0" && ch <= "7") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!first) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington first = ch;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ++octal_len;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (first <= "3" && octal_len <= 2) return ++octal_len;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (first >= "4" && octal_len <= 1) return ++octal_len;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (octal_len > 0) ch = String.fromCharCode(parseInt(ch, 8));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else ch = read_escaped_char(true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (ch == quote) break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret += ch;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return token("string", ret);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function read_line_comment() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var i = find("\n"), ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (i == -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = S.text.substr(S.pos);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.pos = S.text.length;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = S.text.substring(S.pos, i);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.pos = i;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return token("comment1", ret, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function read_multiline_comment() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return with_eof_error("Unterminated multiline comment", function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var i = find("*/", true),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington text = S.text.substring(S.pos, i);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.pos = i + 2;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.line += text.split("\n").length - 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.newline_before = text.indexOf("\n") >= 0;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // https://github.com/mishoo/UglifyJS/issues/#issue/100
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (/^@cc_on/i.test(text)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington warn("WARNING: at line " + S.line);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington warn("*** Found \"conditional comment\": " + text);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington warn("*** UglifyJS DISCARDS ALL COMMENTS. This means your code might no longer work properly in Internet Explorer.");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return token("comment2", text, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function read_name() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var backslash = false, name = "", ch;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while ((ch = peek()) != null) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!backslash) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ch == "\\") backslash = true, next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (is_identifier_char(ch)) name += next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ch != "u") parse_error("Expecting UnicodeEscapeSequence -- uXXXX");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ch = read_escaped_char();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!is_identifier_char(ch)) parse_error("Unicode char: " + ch.charCodeAt(0) + " is not valid in identifier");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name += ch;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington backslash = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return name;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function read_regexp(regexp) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return with_eof_error("Unterminated regular expression", function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var prev_backslash = false, ch, in_class = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while ((ch = next(true))) if (prev_backslash) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington regexp += "\\" + ch;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prev_backslash = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (ch == "[") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington in_class = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington regexp += ch;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (ch == "]" && in_class) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington in_class = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington regexp += ch;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (ch == "/" && !in_class) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (ch == "\\") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prev_backslash = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington regexp += ch;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var mods = read_name();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return token("regexp", [ regexp, mods ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function read_operator(prefix) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function grow(op) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!peek()) return op;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var bigger = op + peek();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (HOP(OPERATORS, bigger)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return grow(bigger);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return op;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return token("operator", grow(prefix || next()));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function handle_slash() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var regex_allowed = S.regex_allowed;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (peek()) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "/":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.comments_before.push(read_line_comment());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.regex_allowed = regex_allowed;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return next_token();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "*":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.comments_before.push(read_multiline_comment());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.regex_allowed = regex_allowed;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return next_token();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return S.regex_allowed ? read_regexp("") : read_operator("/");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function handle_dot() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return is_digit(peek())
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ? read_num(".")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington : token("punc", ".");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function read_word() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var word = read_name();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return !HOP(KEYWORDS, word)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ? token("name", word)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington : HOP(OPERATORS, word)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ? token("operator", word)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington : HOP(KEYWORDS_ATOM, word)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ? token("atom", word)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington : token("keyword", word);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function with_eof_error(eof_error, cont) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return cont();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch(ex) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ex === EX_EOF) parse_error(eof_error);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else throw ex;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function next_token(force_regexp) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (force_regexp != null)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return read_regexp(force_regexp);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington skip_whitespace();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington start_token();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ch = peek();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!ch) return token("eof");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is_digit(ch)) return read_num();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ch == '"' || ch == "'") return read_string();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (HOP(PUNC_CHARS, ch)) return token("punc", next());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ch == ".") return handle_dot();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ch == "/") return handle_slash();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (HOP(OPERATOR_CHARS, ch)) return read_operator();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ch == "\\" || is_identifier_start(ch)) return read_word();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse_error("Unexpected character '" + ch + "'");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next_token.context = function(nc) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (nc) S = nc;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return S;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return next_token;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/* -----[ Parser (constants) ]----- */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar UNARY_PREFIX = array_to_hash([
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "typeof",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "void",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "delete",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "--",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "++",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "!",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "~",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "-",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "+"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar UNARY_POSTFIX = array_to_hash([ "--", "++" ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar ASSIGNMENT = (function(a, ret, i){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (i < a.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret[a[i]] = a[i].substr(0, a[i].length - 1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington i++;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington})(
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ["+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&="],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington { "=": true },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 0
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar PRECEDENCE = (function(a, ret){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var i = 0, n = 1; i < a.length; ++i, ++n) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var b = a[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var j = 0; j < b.length; ++j) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret[b[j]] = n;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington})(
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington [
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ["||"],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ["&&"],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ["|"],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ["^"],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ["&"],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ["==", "===", "!=", "!=="],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ["<", ">", "<=", ">=", "in", "instanceof"],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington [">>", "<<", ">>>"],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ["+", "-"],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ["*", "/", "%"]
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington {}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/* -----[ Parser ]----- */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction NodeWithToken(str, start, end) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.name = str;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.start = start;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.end = end;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill CunningtonNodeWithToken.prototype.toString = function() { return this.name; };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction parse($TEXT, exigent_mode, embed_tokens) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var S = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington input : typeof $TEXT == "string" ? tokenizer($TEXT, true) : $TEXT,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington token : null,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prev : null,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington peeked : null,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington in_function : 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington in_loop : 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington labels : []
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.token = next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function is(type, value) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return is_token(S.token, type, value);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function peek() { return S.peeked || (S.peeked = S.input()); };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function next() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.prev = S.token;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (S.peeked) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.token = S.peeked;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.peeked = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.token = S.input();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return S.token;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function prev() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return S.prev;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function croak(msg, line, col, pos) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ctx = S.input.context();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington js_error(msg,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington line != null ? line : ctx.tokline,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington col != null ? col : ctx.tokcol,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pos != null ? pos : ctx.tokpos);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function token_error(token, msg) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington croak(msg, token.line, token.col);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function unexpected(token) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (token == null)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington token = S.token;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function expect_token(type, val) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is(type, val)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington token_error(S.token, "Unexpected token " + S.token.type + ", expected " + type);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function expect(punc) { return expect_token("punc", punc); };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function can_insert_semicolon() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return !exigent_mode && (
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.token.nlb || is("eof") || is("punc", "}")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington );
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function semicolon() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("punc", ";")) next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (!can_insert_semicolon()) unexpected();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function as() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return slice(arguments);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function parenthesised() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expect("(");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ex = expression();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expect(")");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ex;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function add_tokens(str, start, end) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return str instanceof NodeWithToken ? str : new NodeWithToken(str, start, end);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function maybe_embed_tokens(parser) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (embed_tokens) return function() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var start = S.token;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ast = parser.apply(this, arguments);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ast[0] = add_tokens(ast[0], start, prev());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ast;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else return parser;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var statement = maybe_embed_tokens(function() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("operator", "/") || is("operator", "/=")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.peeked = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.token = S.input(S.token.value.substr(1)); // force regexp
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (S.token.type) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "num":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "string":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "regexp":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "operator":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "atom":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return simple_statement();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "name":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return is_token(peek(), "punc", ":")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ? labeled_statement(prog1(S.token.value, next, next))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington : simple_statement();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "punc":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (S.token.value) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "{":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("block", block_());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "[":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "(":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return simple_statement();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case ";":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("block");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington default:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington unexpected();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "keyword":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (prog1(S.token.value, next)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "break":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return break_cont("break");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "continue":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return break_cont("continue");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "debugger":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington semicolon();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("debugger");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "do":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return (function(body){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expect_token("keyword", "while");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("do", prog1(parenthesised, semicolon), body);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington })(in_loop(statement));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "for":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return for_();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "function":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return function_(true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "if":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return if_();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "return":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (S.in_function == 0)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington croak("'return' outside of function");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("return",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington is("punc", ";")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ? (next(), null)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington : can_insert_semicolon()
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ? null
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington : prog1(expression, semicolon));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "switch":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("switch", parenthesised(), switch_block_());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "throw":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (S.token.nlb)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington croak("Illegal newline after 'throw'");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("throw", prog1(expression, semicolon));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "try":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return try_();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "var":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return prog1(var_, semicolon);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "const":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return prog1(const_, semicolon);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "while":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("while", parenthesised(), in_loop(statement));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "with":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("with", parenthesised(), statement());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington default:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington unexpected();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function labeled_statement(label) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.labels.push(label);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var start = S.token, stat = statement();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (exigent_mode && !HOP(STATEMENTS_WITH_LABELS, stat[0]))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington unexpected(start);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.labels.pop();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("label", label, stat);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function simple_statement() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("stat", prog1(expression, semicolon));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function break_cont(type) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var name;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!can_insert_semicolon()) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = is("name") ? S.token.value : null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (name != null) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!member(name, S.labels))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington croak("Label " + name + " without matching loop or statement");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (S.in_loop == 0)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington croak(type + " not inside a loop or switch");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington semicolon();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as(type, name);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function for_() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expect("(");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var init = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!is("punc", ";")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington init = is("keyword", "var")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ? (next(), var_(true))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington : expression(true, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("operator", "in"))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return for_in(init);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return regular_for(init);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function regular_for(init) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expect(";");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var test = is("punc", ";") ? null : expression();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expect(";");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var step = is("punc", ")") ? null : expression();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expect(")");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("for", init, test, step, in_loop(statement));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function for_in(init) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var lhs = init[0] == "var" ? as("name", init[1][0]) : init;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var obj = expression();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expect(")");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("for-in", init, lhs, obj, in_loop(statement));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var function_ = function(in_statement) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var name = is("name") ? prog1(S.token.value, next) : null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (in_statement && !name)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington unexpected();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expect("(");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as(in_statement ? "defun" : "function",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // arguments
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (function(first, a){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (!is("punc", ")")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (first) first = false; else expect(",");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!is("name")) unexpected();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push(S.token.value);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return a;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington })(true, []),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // body
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ++S.in_function;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var loop = S.in_loop;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.in_loop = 0;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var a = block_();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington --S.in_function;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington S.in_loop = loop;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return a;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington })());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function if_() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var cond = parenthesised(), body = statement(), belse;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("keyword", "else")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington belse = statement();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("if", cond, body, belse);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function block_() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expect("{");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var a = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (!is("punc", "}")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("eof")) unexpected();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push(statement());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return a;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var switch_block_ = curry(in_loop, function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expect("{");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var a = [], cur = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (!is("punc", "}")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("eof")) unexpected();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("keyword", "case")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cur = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push([ expression(), cur ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expect(":");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (is("keyword", "default")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expect(":");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cur = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push([ null, cur ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!cur) unexpected();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cur.push(statement());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return a;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function try_() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var body = block_(), bcatch, bfinally;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("keyword", "catch")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expect("(");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!is("name"))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington croak("Name expected");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var name = S.token.value;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expect(")");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington bcatch = [ name, block_() ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("keyword", "finally")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington bfinally = block_();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!bcatch && !bfinally)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington croak("Missing catch/finally blocks");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("try", body, bcatch, bfinally);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function vardefs(no_in) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var a = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (;;) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!is("name"))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington unexpected();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var name = S.token.value;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("operator", "=")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push([ name, expression(false, no_in) ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push([ name ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!is("punc", ","))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return a;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function var_(no_in) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("var", vardefs(no_in));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function const_() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("const", vardefs());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function new_() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var newexp = expr_atom(false), args;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("punc", "(")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = expr_list(")");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return subscripts(as("new", newexp, args), true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var expr_atom = maybe_embed_tokens(function(allow_calls) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("operator", "new")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return new_();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("punc")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (S.token.value) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "(":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return subscripts(prog1(expression, curry(expect, ")")), allow_calls);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "[":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return subscripts(array_(), allow_calls);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "{":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return subscripts(object_(), allow_calls);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington unexpected();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("keyword", "function")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return subscripts(function_(false), allow_calls);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (HOP(ATOMIC_START_TOKEN, S.token.type)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var atom = S.token.type == "regexp"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ? as("regexp", S.token.value[0], S.token.value[1])
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington : as(S.token.type, S.token.value);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return subscripts(prog1(atom, next), allow_calls);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington unexpected();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function expr_list(closing, allow_trailing_comma, allow_empty) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var first = true, a = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (!is("punc", closing)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (first) first = false; else expect(",");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (allow_trailing_comma && is("punc", closing)) break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("punc", ",") && allow_empty) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push([ "atom", "undefined" ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push(expression(false));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return a;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function array_() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("array", expr_list("]", !exigent_mode, true));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function object_() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var first = true, a = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (!is("punc", "}")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (first) first = false; else expect(",");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!exigent_mode && is("punc", "}"))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // allow trailing comma
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var type = S.token.type;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var name = as_property_name();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (type == "name" && (name == "get" || name == "set") && !is("punc", ":")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push([ as_name(), function_(false), name ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expect(":");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push([ name, expression(false) ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("object", a);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function as_property_name() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (S.token.type) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "num":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "string":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return prog1(S.token.value, next);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as_name();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function as_name() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (S.token.type) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "name":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "operator":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "keyword":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "atom":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return prog1(S.token.value, next);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington default:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington unexpected();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function subscripts(expr, allow_calls) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("punc", ".")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return subscripts(as("dot", expr, as_name()), allow_calls);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("punc", "[")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return subscripts(as("sub", expr, prog1(expression, curry(expect, "]"))), allow_calls);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (allow_calls && is("punc", "(")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return subscripts(as("call", expr, expr_list(")")), true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return expr;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function maybe_unary(allow_calls) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("operator") && HOP(UNARY_PREFIX, S.token.value)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return make_unary("unary-prefix",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prog1(S.token.value, next),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington maybe_unary(allow_calls));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var val = expr_atom(allow_calls);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (is("operator") && HOP(UNARY_POSTFIX, S.token.value) && !S.token.nlb) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington val = make_unary("unary-postfix", S.token.value, val);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return val;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function make_unary(tag, op, expr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if ((op == "++" || op == "--") && !is_assignable(expr))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington croak("Invalid use of " + op + " operator");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as(tag, op, expr);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function expr_op(left, min_prec, no_in) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var op = is("operator") ? S.token.value : null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (op && op == "in" && no_in) op = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var prec = op != null ? PRECEDENCE[op] : null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (prec != null && prec > min_prec) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var right = expr_op(maybe_unary(true), prec, no_in);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return expr_op(as("binary", op, left, right), min_prec, no_in);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return left;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function expr_ops(no_in) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return expr_op(maybe_unary(true), 0, no_in);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function maybe_conditional(no_in) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var expr = expr_ops(no_in);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("operator", "?")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var yes = expression(false);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expect(":");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("conditional", expr, yes, expression(false, no_in));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return expr;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function is_assignable(expr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!exigent_mode) return true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (expr[0]+"") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "dot":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "sub":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "new":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "call":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "name":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return expr[1] != "this";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function maybe_assign(no_in) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var left = maybe_conditional(no_in), val = S.token.value;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is("operator") && HOP(ASSIGNMENT, val)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is_assignable(left)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("assign", ASSIGNMENT[val], left, maybe_assign(no_in));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington croak("Invalid assignment");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return left;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var expression = maybe_embed_tokens(function(commas, no_in) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (arguments.length == 0)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington commas = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var expr = maybe_assign(no_in);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (commas && is("punc", ",")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("seq", expr, expression(true, no_in));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return expr;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function in_loop(cont) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ++S.in_loop;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return cont();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } finally {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington --S.in_loop;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return as("toplevel", (function(a){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (!is("eof"))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push(statement());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return a;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington })([]));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/* -----[ Utilities ]----- */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction curry(f) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var args = slice(arguments, 1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return function() { return f.apply(this, args.concat(slice(arguments))); };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction prog1(ret) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ret instanceof Function)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = ret();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var i = 1, n = arguments.length; --n > 0; ++i)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington arguments[i]();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction array_to_hash(a) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ret = {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var i = 0; i < a.length; ++i)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret[a[i]] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction slice(a, start) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return Array.prototype.slice.call(a, start || 0);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction characters(str) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return str.split("");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction member(name, array) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var i = array.length; --i >= 0;)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (array[i] == name)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction HOP(obj, prop) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return Object.prototype.hasOwnProperty.call(obj, prop);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar warn = function() {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/* -----[ Exports ]----- */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.tokenizer = tokenizer;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.parse = parse;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.slice = slice;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.curry = curry;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.member = member;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.array_to_hash = array_to_hash;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.PRECEDENCE = PRECEDENCE;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.KEYWORDS_ATOM = KEYWORDS_ATOM;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.RESERVED_WORDS = RESERVED_WORDS;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.KEYWORDS = KEYWORDS;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.ATOMIC_START_TOKEN = ATOMIC_START_TOKEN;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.OPERATORS = OPERATORS;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.is_alphanumeric_char = is_alphanumeric_char;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.set_logger = function(logger) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington warn = logger;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('uglifyjs/squeeze-more', ["require", "exports", "module", "./parse-js", "./process"], function(require, exports, module) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar jsp = require("./parse-js"),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pro = require("./process"),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington slice = jsp.slice,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington member = jsp.member,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington curry = jsp.curry,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington MAP = pro.MAP,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington PRECEDENCE = jsp.PRECEDENCE,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington OPERATORS = jsp.OPERATORS;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction ast_squeeze_more(ast) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var w = pro.ast_walker(), walk = w.walk, scope;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function with_scope(s, cont) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var save = scope, ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington scope = s;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = cont();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington scope = save;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function _lambda(name, args, body) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], name, args, with_scope(body.scope, curry(MAP, body, walk)) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return w.with_walkers({
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "toplevel": function(body) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], with_scope(this.scope, curry(MAP, body, walk)) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "function": _lambda,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "defun": _lambda,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "new": function(ctor, args) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ctor[0] == "name") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ctor[1] == "Array" && !scope.has("Array")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (args.length != 1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ "array", args ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return walk([ "call", [ "name", "Array" ], args ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (ctor[1] == "Object" && !scope.has("Object")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!args.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ "object", [] ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return walk([ "call", [ "name", "Object" ], args ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if ((ctor[1] == "RegExp" || ctor[1] == "Function" || ctor[1] == "Error") && !scope.has(ctor[1])) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return walk([ "call", [ "name", ctor[1] ], args]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "call": function(expr, args) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (expr[0] == "dot" && expr[2] == "toString" && args.length == 0) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // foo.toString() ==> foo+""
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ "binary", "+", expr[1], [ "string", "" ]];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (expr[0] == "name") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (expr[1] == "Array" && args.length != 1 && !scope.has("Array")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ "array", args ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (expr[1] == "Object" && !args.length && !scope.has("Object")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ "object", [] ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (expr[1] == "String" && !scope.has("String")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ "binary", "+", args[0], [ "string", "" ]];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, function() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return walk(pro.ast_add_scope(ast));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.ast_squeeze_more = ast_squeeze_more;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});define('uglifyjs/process', ["require", "exports", "module", "./parse-js", "./squeeze-more"], function(require, exports, module) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/***********************************************************************
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington A JavaScript tokenizer / parser / beautifier / compressor.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington This version is suitable for Node.js. With minimal changes (the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington exports stuff) it should work on any JS platform.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington This file implements some AST processors. They work on data built
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington by parse-js.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington Exported functions:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington - ast_mangle(ast, options) -- mangles the variable/function names
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington in the AST. Returns an AST.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington - ast_squeeze(ast) -- employs various optimizations to make the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington final generated code even smaller. Returns an AST.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington - gen_code(ast, options) -- generates JS code from the AST. Pass
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington true (or an object, see the code for some options) as second
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington argument to get "pretty" (indented) code.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington -------------------------------- (C) ---------------------------------
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington Author: Mihai Bazon
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington <mihai.bazon@gmail.com>
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington http://mihai.bazon.net/blog
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington Distributed under the BSD license:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington Copyright 2010 (c) Mihai Bazon <mihai.bazon@gmail.com>
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington Redistribution and use in source and binary forms, with or without
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington modification, are permitted provided that the following conditions
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington are met:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Redistributions of source code must retain the above
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington copyright notice, this list of conditions and the following
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington disclaimer.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Redistributions in binary form must reproduce the above
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington copyright notice, this list of conditions and the following
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington disclaimer in the documentation and/or other materials
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington provided with the distribution.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington SUCH DAMAGE.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ***********************************************************************/
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar jsp = require("./parse-js"),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington slice = jsp.slice,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington member = jsp.member,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington PRECEDENCE = jsp.PRECEDENCE,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington OPERATORS = jsp.OPERATORS;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/* -----[ helper for AST traversal ]----- */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction ast_walker() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function _vardefs(defs) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], MAP(defs, function(def){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var a = [ def[0] ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (def.length > 1)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a[1] = walk(def[1]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return a;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function _block(statements) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var out = [ this[0] ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (statements != null)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington out.push(MAP(statements, walk));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return out;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var walkers = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "string": function(str) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], str ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "num": function(num) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], num ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "name": function(name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], name ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "toplevel": function(statements) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], MAP(statements, walk) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "block": _block,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "splice": _block,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "var": _vardefs,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "const": _vardefs,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "try": function(t, c, f) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this[0],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington MAP(t, walk),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington c != null ? [ c[0], MAP(c[1], walk) ] : null,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington f != null ? MAP(f, walk) : null
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "throw": function(expr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], walk(expr) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "new": function(ctor, args) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], walk(ctor), MAP(args, walk) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "switch": function(expr, body) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], walk(expr), MAP(body, function(branch){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ branch[0] ? walk(branch[0]) : null,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington MAP(branch[1], walk) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "break": function(label) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], label ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "continue": function(label) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], label ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "conditional": function(cond, t, e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], walk(cond), walk(t), walk(e) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "assign": function(op, lvalue, rvalue) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], op, walk(lvalue), walk(rvalue) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "dot": function(expr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], walk(expr) ].concat(slice(arguments, 1));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "call": function(expr, args) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], walk(expr), MAP(args, walk) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "function": function(name, args, body) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], name, args.slice(), MAP(body, walk) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "defun": function(name, args, body) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], name, args.slice(), MAP(body, walk) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "if": function(conditional, t, e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], walk(conditional), walk(t), walk(e) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "for": function(init, cond, step, block) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], walk(init), walk(cond), walk(step), walk(block) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "for-in": function(vvar, key, hash, block) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], walk(vvar), walk(key), walk(hash), walk(block) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "while": function(cond, block) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], walk(cond), walk(block) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "do": function(cond, block) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], walk(cond), walk(block) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "return": function(expr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], walk(expr) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "binary": function(op, left, right) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], op, walk(left), walk(right) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "unary-prefix": function(op, expr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], op, walk(expr) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "unary-postfix": function(op, expr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], op, walk(expr) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "sub": function(expr, subscript) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], walk(expr), walk(subscript) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "object": function(props) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], MAP(props, function(p){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return p.length == 2
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ? [ p[0], walk(p[1]) ]
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington : [ p[0], walk(p[1]), p[2] ]; // get/set-ter
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "regexp": function(rx, mods) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], rx, mods ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "array": function(elements) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], MAP(elements, walk) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "stat": function(stat) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], walk(stat) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "seq": function() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0] ].concat(MAP(slice(arguments), walk));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "label": function(name, block) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], name, walk(block) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "with": function(expr, block) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], walk(expr), walk(block) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "atom": function(name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], name ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var user = {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var stack = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function walk(ast) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ast == null)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington stack.push(ast);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var type = ast[0];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var gen = user[type];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (gen) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ret = gen.apply(ast, ast.slice(1));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ret != null)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington gen = walkers[type];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return gen.apply(ast, ast.slice(1));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } finally {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington stack.pop();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function dive(ast) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ast == null)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington stack.push(ast);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return walkers[ast[0]].apply(ast, ast.slice(1));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } finally {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington stack.pop();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function with_walkers(walkers, cont){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var save = {}, i;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i in walkers) if (HOP(walkers, i)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington save[i] = user[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington user[i] = walkers[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ret = cont();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i in save) if (HOP(save, i)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!save[i]) delete user[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else user[i] = save[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington walk: walk,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dive: dive,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington with_walkers: with_walkers,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parent: function() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return stack[stack.length - 2]; // last one is current node
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington stack: function() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return stack;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/* -----[ Scope and mangling ]----- */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction Scope(parent) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.names = {}; // names defined in this scope
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.mangled = {}; // mangled names (orig.name => mangled)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.rev_mangled = {}; // reverse lookup (mangled => orig.name)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.cname = -1; // current mangled name
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.refs = {}; // names referenced from this scope
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.uses_with = false; // will become TRUE if with() is detected in this or any subscopes
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.uses_eval = false; // will become TRUE if eval() is detected in this or any subscopes
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.parent = parent; // parent scope
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.children = []; // sub-scopes
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (parent) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.level = parent.level + 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parent.children.push(this);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.level = 0;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar base54 = (function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var DIGITS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return function(num) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ret = "";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington do {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = DIGITS.charAt(num % 54) + ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington num = Math.floor(num / 54);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } while (num > 0);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington})();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill CunningtonScope.prototype = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington has: function(name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var s = this; s; s = s.parent)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (HOP(s.names, name))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return s;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington has_mangled: function(mname) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var s = this; s; s = s.parent)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (HOP(s.rev_mangled, mname))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return s;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington toJSON: function() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington names: this.names,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington uses_eval: this.uses_eval,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington uses_with: this.uses_with
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington next_mangled: function() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // we must be careful that the new mangled name:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // 1. doesn't shadow a mangled name from a parent
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // scope, unless we don't reference the original
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // name from this scope OR from any sub-scopes!
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // This will get slow.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // 2. doesn't shadow an original name from a parent
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // scope, in the event that the name is not mangled
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // in the parent scope and we reference that name
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // here OR IN ANY SUBSCOPES!
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // 3. doesn't shadow a name that is referenced but not
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // defined (possibly global defined elsewhere).
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (;;) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var m = base54(++this.cname), prior;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // case 1.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prior = this.has_mangled(m);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (prior && this.refs[prior.rev_mangled[m]] === prior)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington continue;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // case 2.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prior = this.has(m);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (prior && prior !== this && this.refs[m] === prior && !prior.has_mangled(m))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington continue;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // case 3.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (HOP(this.refs, m) && this.refs[m] == null)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington continue;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // I got "do" once. :-/
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!is_identifier(m))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington continue;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return m;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington set_mangle: function(name, m) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.rev_mangled[m] = name;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return this.mangled[name] = m;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington get_mangled: function(name, newMangle) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (this.uses_eval || this.uses_with) return name; // no mangle if eval or with is in use
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var s = this.has(name);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!s) return name; // not in visible scope, no mangle
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (HOP(s.mangled, name)) return s.mangled[name]; // already mangled in this scope
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!newMangle) return name; // not found and no mangling requested
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return s.set_mangle(name, s.next_mangled());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington references: function(name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return name && !this.parent || this.uses_with || this.uses_eval || this.refs[name];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington define: function(name, type) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (name != null) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (type == "var" || !HOP(this.names, name))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.names[name] = type || "var";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return name;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction ast_add_scope(ast) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var current_scope = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var w = ast_walker(), walk = w.walk;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var having_eval = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function with_new_scope(cont) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington current_scope = new Scope(current_scope);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington current_scope.labels = new Scope();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ret = current_scope.body = cont();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret.scope = current_scope;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington current_scope = current_scope.parent;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function define(name, type) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return current_scope.define(name, type);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function reference(name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington current_scope.refs[name] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function _lambda(name, args, body) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var is_defun = this[0] == "defun";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], is_defun ? define(name, "defun") : name, args, with_new_scope(function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!is_defun) define(name, "lambda");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington MAP(args, function(name){ define(name, "arg") });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return MAP(body, walk);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington })];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function _vardefs(type) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return function(defs) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington MAP(defs, function(d){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington define(d[0], type);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (d[1]) reference(d[0]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function _breacont(label) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (label)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington current_scope.labels.refs[label] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return with_new_scope(function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // process AST
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ret = w.with_walkers({
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "function": _lambda,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "defun": _lambda,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "label": function(name, stat) { current_scope.labels.define(name) },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "break": _breacont,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "continue": _breacont,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "with": function(expr, block) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var s = current_scope; s; s = s.parent)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington s.uses_with = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "var": _vardefs("var"),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "const": _vardefs("const"),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "try": function(t, c, f) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (c != null) return [
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this[0],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington MAP(t, walk),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington [ define(c[0], "catch"), MAP(c[1], walk) ],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington f != null ? MAP(f, walk) : null
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "name": function(name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (name == "eval")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington having_eval.push(current_scope);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington reference(name);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return walk(ast);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // the reason why we need an additional pass here is
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // that names can be used prior to their definition.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // scopes where eval was detected and their parents
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // are marked with uses_eval, unless they define the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // "eval" name.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington MAP(having_eval, function(scope){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!scope.has("eval")) while (scope) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington scope.uses_eval = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington scope = scope.parent;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // for referenced names it might be useful to know
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // their origin scope. current_scope here is the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // toplevel one.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function fixrefs(scope, i) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // do children first; order shouldn't matter
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = scope.children.length; --i >= 0;)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fixrefs(scope.children[i]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i in scope.refs) if (HOP(scope.refs, i)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // find origin scope and propagate the reference to origin
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var origin = scope.has(i), s = scope; s; s = s.parent) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington s.refs[i] = origin;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (s === origin) break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fixrefs(current_scope);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/* -----[ mangle names ]----- */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction ast_mangle(ast, options) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var w = ast_walker(), walk = w.walk, scope;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington options = options || {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function get_mangled(name, newMangle) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!options.toplevel && !scope.parent) return name; // don't mangle toplevel
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (options.except && member(name, options.except))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return name;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return scope.get_mangled(name, newMangle);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function get_define(name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (options.defines) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // we always lookup a defined symbol for the current scope FIRST, so declared
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // vars trump a DEFINE symbol, but if no such var is found, then match a DEFINE value
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!scope.has(name)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (HOP(options.defines, name)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return options.defines[name];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function _lambda(name, args, body) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!options.no_functions) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var is_defun = this[0] == "defun", extra;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is_defun) name = get_mangled(name);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (body.scope.references(name)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington extra = {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!(scope.uses_eval || scope.uses_with))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = extra[name] = scope.next_mangled();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington extra[name] = name;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else name = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington body = with_scope(body.scope, function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = MAP(args, function(name){ return get_mangled(name) });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return MAP(body, walk);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, extra);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], name, args, body ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function with_scope(s, cont, extra) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var _scope = scope;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington scope = s;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (extra) for (var i in extra) if (HOP(extra, i)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington s.set_mangle(i, extra[i]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var i in s.names) if (HOP(s.names, i)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington get_mangled(i, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ret = cont();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret.scope = s;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington scope = _scope;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function _vardefs(defs) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], MAP(defs, function(d){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ get_mangled(d[0]), walk(d[1]) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function _breacont(label) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (label) return [ this[0], scope.labels.get_mangled(label) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return w.with_walkers({
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "function": _lambda,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "defun": function() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // move function declarations to the top when
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // they are not in some block.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ast = _lambda.apply(this, arguments);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (w.parent()[0]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "toplevel":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "function":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "defun":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return MAP.at_top(ast);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ast;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "label": function(label, stat) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (scope.labels.refs[label]) return [
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this[0],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington scope.labels.get_mangled(label, true),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington walk(stat)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return walk(stat);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "break": _breacont,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "continue": _breacont,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "var": _vardefs,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "const": _vardefs,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "name": function(name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return get_define(name) || [ this[0], get_mangled(name) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "try": function(t, c, f) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington MAP(t, walk),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington c != null ? [ get_mangled(c[0]), MAP(c[1], walk) ] : null,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington f != null ? MAP(f, walk) : null ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "toplevel": function(body) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var self = this;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return with_scope(self.scope, function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ self[0], MAP(body, walk) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, function() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return walk(ast_add_scope(ast));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/* -----[
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington - compress foo["bar"] into foo.bar,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington - remove block brackets {} where possible
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington - join consecutive var declarations
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington - various optimizations for IFs:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington - if (cond) foo(); else bar(); ==> cond?foo():bar();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington - if (cond) foo(); ==> cond&&foo();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington - if (foo) return bar(); else return baz(); ==> return foo?bar():baz(); // also for throw
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington - if (foo) return bar(); else something(); ==> {if(foo)return bar();something()}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ]----- */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar warn = function(){};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction best_of(ast1, ast2) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return gen_code(ast1).length > gen_code(ast2[0] == "stat" ? ast2[1] : ast2).length ? ast2 : ast1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction last_stat(b) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (b[0] == "block" && b[1] && b[1].length > 0)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return b[1][b[1].length - 1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return b;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction aborts(t) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (t) switch (last_stat(t)[0]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "return":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "break":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "continue":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "throw":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction boolean_expr(expr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ( (expr[0] == "unary-prefix"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && member(expr[1], [ "!", "delete" ])) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (expr[0] == "binary"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && member(expr[1], [ "in", "instanceof", "==", "!=", "===", "!==", "<", "<=", ">=", ">" ])) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (expr[0] == "binary"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && member(expr[1], [ "&&", "||" ])
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && boolean_expr(expr[2])
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && boolean_expr(expr[3])) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (expr[0] == "conditional"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && boolean_expr(expr[2])
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && boolean_expr(expr[3])) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (expr[0] == "assign"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && expr[1] === true
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && boolean_expr(expr[3])) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (expr[0] == "seq"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && boolean_expr(expr[expr.length - 1]))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington );
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction empty(b) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return !b || (b[0] == "block" && (!b[1] || b[1].length == 0));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction is_string(node) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return (node[0] == "string" ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node[0] == "unary-prefix" && node[1] == "typeof" ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node[0] == "binary" && node[1] == "+" &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (is_string(node[2]) || is_string(node[3])));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar when_constant = (function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var $NOT_CONSTANT = {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // this can only evaluate constant expressions. If it finds anything
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // not constant, it throws $NOT_CONSTANT.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function evaluate(expr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (expr[0]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "string":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "num":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return expr[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "name":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "atom":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (expr[1]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "true": return true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "false": return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "null": return null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "unary-prefix":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (expr[1]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "!": return !evaluate(expr[2]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "typeof": return typeof evaluate(expr[2]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "~": return ~evaluate(expr[2]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "-": return -evaluate(expr[2]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "+": return +evaluate(expr[2]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "binary":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var left = expr[2], right = expr[3];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (expr[1]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "&&" : return evaluate(left) && evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "||" : return evaluate(left) || evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "|" : return evaluate(left) | evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "&" : return evaluate(left) & evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "^" : return evaluate(left) ^ evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "+" : return evaluate(left) + evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "*" : return evaluate(left) * evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "/" : return evaluate(left) / evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "%" : return evaluate(left) % evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "-" : return evaluate(left) - evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "<<" : return evaluate(left) << evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case ">>" : return evaluate(left) >> evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case ">>>" : return evaluate(left) >>> evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "==" : return evaluate(left) == evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "===" : return evaluate(left) === evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "!=" : return evaluate(left) != evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "!==" : return evaluate(left) !== evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "<" : return evaluate(left) < evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "<=" : return evaluate(left) <= evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case ">" : return evaluate(left) > evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case ">=" : return evaluate(left) >= evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "in" : return evaluate(left) in evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "instanceof" : return evaluate(left) instanceof evaluate(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw $NOT_CONSTANT;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return function(expr, yes, no) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var val = evaluate(expr), ast;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (typeof val) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "string": ast = [ "string", val ]; break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "number": ast = [ "num", val ]; break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "boolean": ast = [ "name", String(val) ]; break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington default: throw new Error("Can't handle constant of type: " + (typeof val));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return yes.call(expr, ast, val);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch(ex) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ex === $NOT_CONSTANT) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (expr[0] == "binary"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && (expr[1] == "===" || expr[1] == "!==")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && ((is_string(expr[2]) && is_string(expr[3]))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington || (boolean_expr(expr[2]) && boolean_expr(expr[3])))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expr[1] = expr[1].substr(0, 2);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (no && expr[0] == "binary"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && (expr[1] == "||" || expr[1] == "&&")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // the whole expression is not constant but the lval may be...
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var lval = evaluate(expr[2]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expr = ((expr[1] == "&&" && (lval ? expr[3] : lval)) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (expr[1] == "||" && (lval ? lval : expr[3])) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expr);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch(ex2) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // IGNORE... lval is not constant
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return no ? no.call(expr, expr) : null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else throw ex;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington})();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction warn_unreachable(ast) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!empty(ast))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington warn("Dropping unreachable code: " + gen_code(ast, true));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction prepare_ifs(ast) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var w = ast_walker(), walk = w.walk;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // In this first pass, we rewrite ifs which abort with no else with an
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // if-else. For example:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // if (x) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // blah();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // return y;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // foobar();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // is rewritten into:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // if (x) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // blah();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // return y;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // foobar();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function redo_if(statements) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington statements = MAP(statements, walk);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var i = 0; i < statements.length; ++i) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var fi = statements[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fi[0] != "if") continue;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fi[3] && walk(fi[3])) continue;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var t = walk(fi[2]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!aborts(t)) continue;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var conditional = walk(fi[1]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var e_body = statements.slice(i + 1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var e = e_body.length == 1 ? e_body[0] : [ "block", e_body ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ret = statements.slice(0, i).concat([ [
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fi[0], // "if"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington conditional, // conditional
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington t, // then
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington e // else
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ] ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return redo_if(ret);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return statements;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function redo_if_lambda(name, args, body) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington body = redo_if(body);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], name, args, body ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function redo_if_block(statements) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], statements != null ? redo_if(statements) : null ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return w.with_walkers({
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "defun": redo_if_lambda,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "function": redo_if_lambda,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "block": redo_if_block,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "splice": redo_if_block,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "toplevel": function(statements) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], redo_if(statements) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "try": function(t, c, f) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this[0],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington redo_if(t),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington c != null ? [ c[0], redo_if(c[1]) ] : null,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington f != null ? redo_if(f) : null
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, function() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return walk(ast);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction for_side_effects(ast, handler) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var w = ast_walker(), walk = w.walk;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var $stop = {}, $restart = {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function stop() { throw $stop };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function restart() { throw $restart };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function found(){ return handler.call(this, this, w, stop, restart) };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function unary(op) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (op == "++" || op == "--")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return found.apply(this, arguments);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return w.with_walkers({
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "try": found,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "throw": found,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "return": found,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "new": found,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "switch": found,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "break": found,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "continue": found,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "assign": found,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "call": found,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "if": found,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "for": found,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "for-in": found,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "while": found,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "do": found,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "return": found,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "unary-prefix": unary,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "unary-postfix": unary,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "defun": found
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (true) try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington walk(ast);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch(ex) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ex === $stop) break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ex === $restart) continue;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw ex;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction ast_lift_variables(ast) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var w = ast_walker(), walk = w.walk, scope;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function do_body(body, env) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var _scope = scope;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington scope = env;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington body = MAP(body, walk);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var hash = {}, names = MAP(env.names, function(type, name){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (type != "var") return MAP.skip;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!env.references(name)) return MAP.skip;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington hash[name] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ name ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (names.length > 0) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // looking for assignments to any of these variables.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // we can save considerable space by moving the definitions
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // in the var declaration.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for_side_effects([ "block", body ], function(ast, walker, stop, restart) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ast[0] == "assign"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && ast[1] === true
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && ast[2][0] == "name"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && HOP(hash, ast[2][1])) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // insert the definition into the var declaration
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var i = names.length; --i >= 0;) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (names[i][0] == ast[2][1]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (names[i][1]) // this name already defined, we must stop
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington stop();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington names[i][1] = ast[3]; // definition
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington names.push(names.splice(i, 1)[0]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // remove this assignment from the AST.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var p = walker.parent();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (p[0] == "seq") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var a = p[2];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.unshift(0, p.length);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington p.splice.apply(p, a);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (p[0] == "stat") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington p.splice(0, p.length, "block"); // empty statement
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington stop();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington restart();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington stop();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington body.unshift([ "var", names ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington scope = _scope;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return body;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function _vardefs(defs) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ret = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var i = defs.length; --i >= 0;) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var d = defs[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!d[1]) continue;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington d = [ "assign", true, [ "name", d[0] ], d[1] ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ret == null) ret = d;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else ret = [ "seq", d, ret ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ret == null) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (w.parent()[0] == "for-in")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ "name", defs[0][0] ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return MAP.skip;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ "stat", ret ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function _toplevel(body) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], do_body(body, this.scope) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return w.with_walkers({
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "function": function(name, args, body){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var i = args.length; --i >= 0 && !body.scope.references(args[i]);)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args.pop();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!body.scope.references(name)) name = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], name, args, do_body(body, body.scope) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "defun": function(name, args, body){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!scope.references(name)) return MAP.skip;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var i = args.length; --i >= 0 && !body.scope.references(args[i]);)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args.pop();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], name, args, do_body(body, body.scope) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "var": _vardefs,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "toplevel": _toplevel
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return walk(ast_add_scope(ast));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction ast_squeeze(ast, options) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington options = defaults(options, {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington make_seqs : true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dead_code : true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington no_warnings : false,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington keep_comps : true
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var w = ast_walker(), walk = w.walk;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function negate(c) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var not_c = [ "unary-prefix", "!", c ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (c[0]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "unary-prefix":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return c[1] == "!" && boolean_expr(c[2]) ? c[2] : not_c;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "seq":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington c = slice(c);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington c[c.length - 1] = negate(c[c.length - 1]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return c;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "conditional":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return best_of(not_c, [ "conditional", c[1], negate(c[2]), negate(c[3]) ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "binary":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var op = c[1], left = c[2], right = c[3];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!options.keep_comps) switch (op) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "<=" : return [ "binary", ">", left, right ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "<" : return [ "binary", ">=", left, right ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case ">=" : return [ "binary", "<", left, right ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case ">" : return [ "binary", "<=", left, right ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (op) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "==" : return [ "binary", "!=", left, right ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "!=" : return [ "binary", "==", left, right ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "===" : return [ "binary", "!==", left, right ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "!==" : return [ "binary", "===", left, right ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "&&" : return best_of(not_c, [ "binary", "||", negate(left), negate(right) ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "||" : return best_of(not_c, [ "binary", "&&", negate(left), negate(right) ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return not_c;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function make_conditional(c, t, e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var make_real_conditional = function() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (c[0] == "unary-prefix" && c[1] == "!") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return e ? [ "conditional", c[2], e, t ] : [ "binary", "||", c[2], t ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return e ? best_of(
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington [ "conditional", c, t, e ],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington [ "conditional", negate(c), e, t ]
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ) : [ "binary", "&&", c, t ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // shortcut the conditional if the expression has a constant value
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return when_constant(c, function(ast, val){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington warn_unreachable(val ? e : t);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return (val ? t : e);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, make_real_conditional);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function rmblock(block) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (block != null && block[0] == "block" && block[1]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (block[1].length == 1)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington block = block[1][0];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (block[1].length == 0)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington block = [ "block" ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return block;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function _lambda(name, args, body) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], name, args, tighten(body, "lambda") ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // this function does a few things:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // 1. discard useless blocks
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // 2. join consecutive var declarations
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // 3. remove obviously dead code
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // 4. transform consecutive statements using the comma operator
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // 5. if block_type == "lambda" and it detects constructs like if(foo) return ... - rewrite like if (!foo) { ... }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function tighten(statements, block_type) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington statements = MAP(statements, walk);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington statements = statements.reduce(function(a, stat){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (stat[0] == "block") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (stat[1]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push.apply(a, stat[1]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push(stat);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return a;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, []);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington statements = (function(a, prev){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington statements.forEach(function(cur){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (prev && ((cur[0] == "var" && prev[0] == "var") ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (cur[0] == "const" && prev[0] == "const"))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prev[1] = prev[1].concat(cur[1]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push(cur);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prev = cur;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return a;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington })([]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (options.dead_code) statements = (function(a, has_quit){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington statements.forEach(function(st){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (has_quit) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (st[0] == "function" || st[0] == "defun") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push(st);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (st[0] == "var" || st[0] == "const") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!options.no_warnings)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington warn("Variables declared in unreachable code");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington st[1] = MAP(st[1], function(def){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (def[1] && !options.no_warnings)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington warn_unreachable([ "assign", true, [ "name", def[0] ], def[1] ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ def[0] ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push(st);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (!options.no_warnings)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington warn_unreachable(st);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push(st);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (member(st[0], [ "return", "throw", "break", "continue" ]))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington has_quit = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return a;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington })([]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (options.make_seqs) statements = (function(a, prev) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington statements.forEach(function(cur){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (prev && prev[0] == "stat" && cur[0] == "stat") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prev[1] = [ "seq", prev[1], cur[1] ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push(cur);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prev = cur;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (a.length >= 2
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && a[a.length-2][0] == "stat"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && (a[a.length-1][0] == "return" || a[a.length-1][0] == "throw")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && a[a.length-1][1])
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.splice(a.length - 2, 2,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington [ a[a.length-1][0],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington [ "seq", a[a.length-2][1], a[a.length-1][1] ]]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return a;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington })([]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // this increases jQuery by 1K. Probably not such a good idea after all..
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // part of this is done in prepare_ifs anyway.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // if (block_type == "lambda") statements = (function(i, a, stat){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // while (i < statements.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // stat = statements[i++];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // if (stat[0] == "if" && !stat[3]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // if (stat[2][0] == "return" && stat[2][1] == null) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // a.push(make_if(negate(stat[1]), [ "block", statements.slice(i) ]));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // var last = last_stat(stat[2]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // if (last[0] == "return" && last[1] == null) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // a.push(make_if(stat[1], [ "block", stat[2][1].slice(0, -1) ], [ "block", statements.slice(i) ]));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // a.push(stat);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // return a;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // })(0, []);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return statements;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function make_if(c, t, e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return when_constant(c, function(ast, val){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (val) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington t = walk(t);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington warn_unreachable(e);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return t || [ "block" ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington e = walk(e);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington warn_unreachable(t);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return e || [ "block" ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, function() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return make_real_if(c, t, e);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function make_real_if(c, t, e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington c = walk(c);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington t = walk(t);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington e = walk(e);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (empty(t)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington c = negate(c);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington t = e;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington e = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (empty(e)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington e = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // if we have both else and then, maybe it makes sense to switch them?
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var a = gen_code(c);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var n = negate(c);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var b = gen_code(n);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (b.length < a.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var tmp = t;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington t = e;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington e = tmp;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington c = n;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington })();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (empty(e) && empty(t))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ "stat", c ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ret = [ "if", c, t, e ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (t[0] == "if" && empty(t[3]) && empty(e)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = best_of(ret, walk([ "if", [ "binary", "&&", c, t[1] ], t[2] ]));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (t[0] == "stat") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (e[0] == "stat") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = best_of(ret, [ "stat", make_conditional(c, t[1], e[1]) ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = best_of(ret, [ "stat", make_conditional(c, t[1]) ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (e && t[0] == e[0] && (t[0] == "return" || t[0] == "throw") && t[1] && e[1]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = best_of(ret, [ t[0], make_conditional(c, t[1], e[1] ) ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (e && aborts(t)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = [ [ "if", c, t ] ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (e[0] == "block") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (e[1]) ret = ret.concat(e[1]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret.push(e);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = walk([ "block", ret ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (t && aborts(e)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = [ [ "if", negate(c), e ] ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (t[0] == "block") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (t[1]) ret = ret.concat(t[1]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret.push(t);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = walk([ "block", ret ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function _do_while(cond, body) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return when_constant(cond, function(cond, val){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!val) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington warn_unreachable(body);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ "block" ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ "for", null, null, null, walk(body) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return w.with_walkers({
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "sub": function(expr, subscript) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (subscript[0] == "string") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var name = subscript[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (is_identifier(name))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ "dot", walk(expr), name ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (/^[1-9][0-9]*$/.test(name) || name === "0")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ "sub", walk(expr), [ "num", parseInt(name, 10) ] ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "if": make_if,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "toplevel": function(body) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ "toplevel", tighten(body) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "switch": function(expr, body) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var last = body.length - 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ "switch", walk(expr), MAP(body, function(branch, i){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var block = tighten(branch[1]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (i == last && block.length > 0) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var node = block[block.length - 1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (node[0] == "break" && !node[1])
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington block.pop();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ branch[0] ? walk(branch[0]) : null, block ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "function": _lambda,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "defun": _lambda,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "block": function(body) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (body) return rmblock([ "block", tighten(body) ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "binary": function(op, left, right) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return when_constant([ "binary", op, walk(left), walk(right) ], function yes(c){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return best_of(walk(c), this);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, function no() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if(op != "==" && op != "!=") return;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var l = walk(left), r = walk(right);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if(l && l[0] == "unary-prefix" && l[1] == "!" && l[2][0] == "num")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington left = ['num', +!l[2][1]];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (r && r[0] == "unary-prefix" && r[1] == "!" && r[2][0] == "num")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington right = ['num', +!r[2][1]];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ["binary", op, left, right];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }() || this;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "conditional": function(c, t, e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return make_conditional(walk(c), walk(t), walk(e));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "try": function(t, c, f) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "try",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington tighten(t),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington c != null ? [ c[0], tighten(c[1]) ] : null,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington f != null ? tighten(f) : null
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "unary-prefix": function(op, expr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington expr = walk(expr);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ret = [ "unary-prefix", op, expr ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (op == "!")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = best_of(ret, negate(expr));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return when_constant(ret, function(ast, val){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return walk(ast); // it's either true or false, so minifies to !0 or !1
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, function() { return ret });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "name": function(name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "true": return [ "unary-prefix", "!", [ "num", 0 ]];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "false": return [ "unary-prefix", "!", [ "num", 1 ]];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "while": _do_while,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "assign": function(op, lvalue, rvalue) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lvalue = walk(lvalue);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington rvalue = walk(rvalue);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var okOps = [ '+', '-', '/', '*', '%', '>>', '<<', '>>>', '|', '^', '&' ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (op === true && lvalue[0] === "name" && rvalue[0] === "binary" &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ~okOps.indexOf(rvalue[1]) && rvalue[2][0] === "name" &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington rvalue[2][1] === lvalue[1]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], rvalue[1], lvalue, rvalue[3] ]
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return [ this[0], op, lvalue, rvalue ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, function() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var i = 0; i < 2; ++i) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ast = prepare_ifs(ast);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ast = walk(ast);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ast;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/* -----[ re-generate code from the AST ]----- */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar DOT_CALL_NO_PARENS = jsp.array_to_hash([
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "name",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "array",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "object",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "string",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "dot",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "sub",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "call",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "regexp",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "defun"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction make_string(str, ascii_only) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var dq = 0, sq = 0;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington str = str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029\0]/g, function(s){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (s) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "\\": return "\\\\";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "\b": return "\\b";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "\f": return "\\f";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "\n": return "\\n";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "\r": return "\\r";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "\t": return "\\t";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "\u2028": return "\\u2028";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "\u2029": return "\\u2029";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case '"': ++dq; return '"';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "'": ++sq; return "'";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "\0": return "\\0";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return s;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ascii_only) str = to_ascii(str);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (dq > sq) return "'" + str.replace(/\x27/g, "\\'") + "'";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else return '"' + str.replace(/\x22/g, '\\"') + '"';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction to_ascii(str) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return str.replace(/[\u0080-\uffff]/g, function(ch) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var code = ch.charCodeAt(0).toString(16);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (code.length < 4) code = "0" + code;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return "\\u" + code;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar SPLICE_NEEDS_BRACKETS = jsp.array_to_hash([ "if", "while", "do", "for", "for-in", "with" ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction gen_code(ast, options) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington options = defaults(options, {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington indent_start : 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington indent_level : 4,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington quote_keys : false,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington space_colon : false,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington beautify : false,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ascii_only : false,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington inline_script: false
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var beautify = !!options.beautify;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var indentation = 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington newline = beautify ? "\n" : "",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington space = beautify ? " " : "";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function encode_string(str) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ret = make_string(str, options.ascii_only);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (options.inline_script)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret = ret.replace(/<\x2fscript([>\/\t\n\f\r ])/gi, "<\\/script$1");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function make_name(name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = name.toString();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (options.ascii_only)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = to_ascii(name);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return name;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function indent(line) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (line == null)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington line = "";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (beautify)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington line = repeat_string(" ", options.indent_start + indentation * options.indent_level) + line;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return line;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function with_indent(cont, incr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (incr == null) incr = 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington indentation += incr;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try { return cont.apply(null, slice(arguments, 1)); }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington finally { indentation -= incr; }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function add_spaces(a) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (beautify)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return a.join(" ");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var b = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var i = 0; i < a.length; ++i) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var next = a[i + 1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington b.push(a[i]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (next &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ((/[a-z0-9_\x24]$/i.test(a[i].toString()) && /^[a-z0-9_\x24]/i.test(next.toString())) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (/[\+\-]$/.test(a[i].toString()) && /^[\+\-]/.test(next.toString())))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington b.push(" ");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return b.join("");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function add_commas(a) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return a.join("," + space);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function parenthesize(expr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var gen = make(expr);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var i = 1; i < arguments.length; ++i) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var el = arguments[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if ((el instanceof Function && el(expr)) || expr[0] == el)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return "(" + gen + ")";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return gen;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function best_of(a) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (a.length == 1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return a[0];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (a.length == 2) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var b = a[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a = a[0];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return a.length <= b.length ? a : b;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return best_of([ a[0], best_of(a.slice(1)) ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function needs_parens(expr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (expr[0] == "function" || expr[0] == "object") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // dot/call on a literal function requires the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // function literal itself to be parenthesized
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // only if it's the first "thing" in a
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // statement. This means that the parent is
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // "stat", but it could also be a "seq" and
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // we're the first in this "seq" and the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // parent is "stat", and so on. Messy stuff,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // but it worths the trouble.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var a = slice(w.stack()), self = a.pop(), p = a.pop();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (p) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (p[0] == "stat") return true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (((p[0] == "seq" || p[0] == "call" || p[0] == "dot" || p[0] == "sub" || p[0] == "conditional") && p[1] === self) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ((p[0] == "binary" || p[0] == "assign" || p[0] == "unary-postfix") && p[2] === self)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington self = p;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington p = a.pop();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return !HOP(DOT_CALL_NO_PARENS, expr[0]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function make_num(num) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var str = num.toString(10), a = [ str.replace(/^0\./, ".") ], m;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (Math.floor(num) === num) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (num >= 0) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push("0x" + num.toString(16).toLowerCase(), // probably pointless
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "0" + num.toString(8)); // same.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push("-0x" + (-num).toString(16).toLowerCase(), // probably pointless
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "-0" + (-num).toString(8)); // same.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if ((m = /^(.*?)(0+)$/.exec(num))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push(m[1] + "e" + m[2].length);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if ((m = /^0?\.(0+)(.*)$/.exec(num))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push(m[2] + "e-" + (m[1].length + m[2].length),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington str.substr(str.indexOf(".")));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return best_of(a);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var w = ast_walker();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var make = w.walk;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return w.with_walkers({
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "string": encode_string,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "num": make_num,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "name": make_name,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "toplevel": function(statements) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return make_block_statements(statements)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington .join(newline + newline);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "splice": function(statements) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var parent = w.parent();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (HOP(SPLICE_NEEDS_BRACKETS, parent)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // we need block brackets in this case
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return make_block.apply(this, arguments);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return MAP(make_block_statements(statements, true),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function(line, i) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // the first line is already indented
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return i > 0 ? indent(line) : line;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }).join(newline);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "block": make_block,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "var": function(defs) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return "var " + add_commas(MAP(defs, make_1vardef)) + ";";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "const": function(defs) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return "const " + add_commas(MAP(defs, make_1vardef)) + ";";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "try": function(tr, ca, fi) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var out = [ "try", make_block(tr) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ca) out.push("catch", "(" + ca[0] + ")", make_block(ca[1]));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fi) out.push("finally", make_block(fi));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return add_spaces(out);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "throw": function(expr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return add_spaces([ "throw", make(expr) ]) + ";";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "new": function(ctor, args) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = args.length > 0 ? "(" + add_commas(MAP(args, function(expr){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return parenthesize(expr, "seq");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington })) + ")" : "";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return add_spaces([ "new", parenthesize(ctor, "seq", "binary", "conditional", "assign", function(expr){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var w = ast_walker(), has_call = {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington w.with_walkers({
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "call": function() { throw has_call },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "function": function() { return this }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington w.walk(expr);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch(ex) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ex === has_call)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw ex;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }) + args ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "switch": function(expr, body) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return add_spaces([ "switch", "(" + make(expr) + ")", make_switch_block(body) ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "break": function(label) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var out = "break";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (label != null)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington out += " " + make_name(label);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return out + ";";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "continue": function(label) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var out = "continue";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (label != null)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington out += " " + make_name(label);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return out + ";";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "conditional": function(co, th, el) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return add_spaces([ parenthesize(co, "assign", "seq", "conditional"), "?",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parenthesize(th, "seq"), ":",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parenthesize(el, "seq") ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "assign": function(op, lvalue, rvalue) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (op && op !== true) op += "=";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else op = "=";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return add_spaces([ make(lvalue), op, parenthesize(rvalue, "seq") ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "dot": function(expr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var out = make(expr), i = 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (expr[0] == "num") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!/\./.test(expr[1]))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington out += ".";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (needs_parens(expr))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington out = "(" + out + ")";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (i < arguments.length)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington out += "." + make_name(arguments[i++]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return out;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "call": function(func, args) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var f = make(func);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (f.charAt(0) != "(" && needs_parens(func))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington f = "(" + f + ")";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return f + "(" + add_commas(MAP(args, function(expr){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return parenthesize(expr, "seq");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington })) + ")";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "function": make_function,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "defun": make_function,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "if": function(co, th, el) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var out = [ "if", "(" + make(co) + ")", el ? make_then(th) : make(th) ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (el) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington out.push("else", make(el));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return add_spaces(out);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "for": function(init, cond, step, block) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var out = [ "for" ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington init = (init != null ? make(init) : "").replace(/;*\s*$/, ";" + space);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cond = (cond != null ? make(cond) : "").replace(/;*\s*$/, ";" + space);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington step = (step != null ? make(step) : "").replace(/;*\s*$/, "");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var args = init + cond + step;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (args == "; ; ") args = ";;";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington out.push("(" + args + ")", make(block));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return add_spaces(out);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "for-in": function(vvar, key, hash, block) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return add_spaces([ "for", "(" +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (vvar ? make(vvar).replace(/;+$/, "") : make(key)),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "in",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington make(hash) + ")", make(block) ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "while": function(condition, block) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return add_spaces([ "while", "(" + make(condition) + ")", make(block) ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "do": function(condition, block) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return add_spaces([ "do", make(block), "while", "(" + make(condition) + ")" ]) + ";";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "return": function(expr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var out = [ "return" ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (expr != null) out.push(make(expr));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return add_spaces(out) + ";";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "binary": function(operator, lvalue, rvalue) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var left = make(lvalue), right = make(rvalue);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // XXX: I'm pretty sure other cases will bite here.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // we need to be smarter.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // adding parens all the time is the safest bet.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (member(lvalue[0], [ "assign", "conditional", "seq" ]) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lvalue[0] == "binary" && PRECEDENCE[operator] > PRECEDENCE[lvalue[1]] ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lvalue[0] == "function" && needs_parens(this)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington left = "(" + left + ")";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (member(rvalue[0], [ "assign", "conditional", "seq" ]) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington rvalue[0] == "binary" && PRECEDENCE[operator] >= PRECEDENCE[rvalue[1]] &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington !(rvalue[1] == operator && member(operator, [ "&&", "||", "*" ]))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington right = "(" + right + ")";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (!beautify && options.inline_script && (operator == "<" || operator == "<<")
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && rvalue[0] == "regexp" && /^script/i.test(rvalue[1])) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington right = " " + right;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return add_spaces([ left, operator, right ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "unary-prefix": function(operator, expr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var val = make(expr);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!(expr[0] == "num" || (expr[0] == "unary-prefix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr)))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington val = "(" + val + ")";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return operator + (jsp.is_alphanumeric_char(operator.charAt(0)) ? " " : "") + val;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "unary-postfix": function(operator, expr) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var val = make(expr);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!(expr[0] == "num" || (expr[0] == "unary-postfix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr)))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington val = "(" + val + ")";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return val + operator;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "sub": function(expr, subscript) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var hash = make(expr);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (needs_parens(expr))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington hash = "(" + hash + ")";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return hash + "[" + make(subscript) + "]";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "object": function(props) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var obj_needs_parens = needs_parens(this);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (props.length == 0)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return obj_needs_parens ? "({})" : "{}";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var out = "{" + newline + with_indent(function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return MAP(props, function(p){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (p.length == 3) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // getter/setter. The name is in p[0], the arg.list in p[1][2], the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // body in p[1][3] and type ("get" / "set") in p[2].
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return indent(make_function(p[0], p[1][2], p[1][3], p[2]));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var key = p[0], val = parenthesize(p[1], "seq");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (options.quote_keys) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington key = encode_string(key);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if ((typeof key == "number" || !beautify && +key + "" == key)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && parseFloat(key) >= 0) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington key = make_num(+key);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (!is_identifier(key)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington key = encode_string(key);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return indent(add_spaces(beautify && options.space_colon
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ? [ key, ":", val ]
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington : [ key + ":", val ]));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }).join("," + newline);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }) + newline + indent("}");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return obj_needs_parens ? "(" + out + ")" : out;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "regexp": function(rx, mods) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return "/" + rx + "/" + mods;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "array": function(elements) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (elements.length == 0) return "[]";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return add_spaces([ "[", add_commas(MAP(elements, function(el, i){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!beautify && el[0] == "atom" && el[1] == "undefined") return i === elements.length - 1 ? "," : "";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return parenthesize(el, "seq");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington })), "]" ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "stat": function(stmt) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return make(stmt).replace(/;*\s*$/, ";");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "seq": function() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return add_commas(MAP(slice(arguments), make));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "label": function(name, block) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return add_spaces([ make_name(name), ":", make(block) ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "with": function(expr, block) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return add_spaces([ "with", "(" + make(expr) + ")", make(block) ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "atom": function(name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return make_name(name);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, function(){ return make(ast) });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // The squeezer replaces "block"-s that contain only a single
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // statement with the statement itself; technically, the AST
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // is correct, but this can create problems when we output an
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // IF having an ELSE clause where the THEN clause ends in an
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // IF *without* an ELSE block (then the outer ELSE would refer
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // to the inner IF). This function checks for this case and
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // adds the block brackets if needed.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function make_then(th) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (th == null) return ";";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (th[0] == "do") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // https://github.com/mishoo/UglifyJS/issues/#issue/57
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // IE croaks with "syntax error" on code like this:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // if (foo) do ... while(cond); else ...
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // we need block brackets around do/while
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return make_block([ th ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var b = th;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (true) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var type = b[0];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (type == "if") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!b[3])
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // no else, we must add the block
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return make([ "block", [ th ]]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington b = b[3];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (type == "while" || type == "do") b = b[2];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (type == "for" || type == "for-in") b = b[4];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return make(th);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function make_function(name, args, body, keyword) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var out = keyword || "function";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington out += " " + make_name(name);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington out += "(" + add_commas(MAP(args, make_name)) + ")";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington out = add_spaces([ out, make_block(body) ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return needs_parens(this) ? "(" + out + ")" : out;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function must_has_semicolon(node) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (node[0]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "with":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "while":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return empty(node[2]); // `with' or `while' with empty body?
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "for":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "for-in":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return empty(node[4]); // `for' with empty body?
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "if":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (empty(node[2]) && !node[3]) return true; // `if' with empty `then' and no `else'
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (node[3]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (empty(node[3])) return true; // `else' present but empty
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return must_has_semicolon(node[3]); // dive into the `else' branch
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return must_has_semicolon(node[2]); // dive into the `then' branch
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function make_block_statements(statements, noindent) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var a = [], last = statements.length - 1, i = 0; i <= last; ++i) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var stat = statements[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var code = make(stat);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (code != ";") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!beautify && i == last && !must_has_semicolon(stat)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington code = code.replace(/;+\s*$/, "");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington a.push(code);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return noindent ? a : MAP(a, indent);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function make_switch_block(body) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var n = body.length;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (n == 0) return "{}";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return "{" + newline + MAP(body, function(branch, i){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var has_body = branch[1].length > 0, code = with_indent(function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return indent(branch[0]
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ? add_spaces([ "case", make(branch[0]) + ":" ])
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington : "default:");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, 0.5) + (has_body ? newline + with_indent(function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return make_block_statements(branch[1]).join(newline);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }) : "");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!beautify && has_body && i < n - 1)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington code += ";";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return code;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }).join(newline) + newline + indent("}");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function make_block(statements) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!statements) return ";";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (statements.length == 0) return "{}";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return "{" + newline + with_indent(function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return make_block_statements(statements).join(newline);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }) + newline + indent("}");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function make_1vardef(def) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var name = def[0], val = def[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (val != null)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = add_spaces([ make_name(name), "=", parenthesize(val, "seq") ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return name;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction split_lines(code, max_line_length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var splits = [ 0 ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington jsp.parse(function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var next_token = jsp.tokenizer(code);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var last_split = 0;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var prev_token;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function current_length(tok) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return tok.pos - last_split;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function split_here(tok) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington last_split = tok.pos;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington splits.push(last_split);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function custom(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var tok = next_token.apply(this, arguments);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington out: {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (prev_token) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (prev_token.type == "keyword") break out;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (current_length(tok) > max_line_length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington switch (tok.type) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "keyword":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "atom":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "name":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington case "punc":
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington split_here(tok);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break out;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prev_token = tok;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return tok;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington custom.context = function() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return next_token.context.apply(this, arguments);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return custom;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return splits.map(function(pos, i){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return code.substring(pos, splits[i + 1] || code.length);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }).join("\n");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/* -----[ Utilities ]----- */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction repeat_string(str, i) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (i <= 0) return "";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (i == 1) return str;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var d = repeat_string(str, i >> 1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington d += d;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (i & 1) d += str;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return d;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction defaults(args, defs) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ret = {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (args === true)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var i in defs) if (HOP(defs, i)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ret;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction is_identifier(name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return /^[a-z_$][a-z0-9_$]*$/i.test(name)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && name != "this"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && !HOP(jsp.KEYWORDS_ATOM, name)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && !HOP(jsp.RESERVED_WORDS, name)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington && !HOP(jsp.KEYWORDS, name);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction HOP(obj, prop) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return Object.prototype.hasOwnProperty.call(obj, prop);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington// some utilities
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonvar MAP;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington(function(){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington MAP = function(a, f, o) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ret = [], top = [], i;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function doit() {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var val = f.call(o, a[i], i);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (val instanceof AtTop) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington val = val.v;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (val instanceof Splice) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington top.push.apply(top, val.v);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington top.push(val);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else if (val != skip) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (val instanceof Splice) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret.push.apply(ret, val.v);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ret.push(val);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (a instanceof Array) for (i = 0; i < a.length; ++i) doit();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington else for (i in a) if (HOP(a, i)) doit();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return top.concat(ret);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington MAP.at_top = function(val) { return new AtTop(val) };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington MAP.splice = function(val) { return new Splice(val) };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var skip = MAP.skip = {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function AtTop(val) { this.v = val };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function Splice(val) { this.v = val };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington})();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/* -----[ Exports ]----- */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.ast_walker = ast_walker;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.ast_mangle = ast_mangle;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.ast_squeeze = ast_squeeze;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.ast_lift_variables = ast_lift_variables;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.gen_code = gen_code;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.ast_add_scope = ast_add_scope;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.set_logger = function(logger) { warn = logger };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.make_string = make_string;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.split_lines = split_lines;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.MAP = MAP;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington// keep this last!
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonexports.ast_squeeze_more = require("./squeeze-more").ast_squeeze_more;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});define('uglifyjs/index', ["require", "exports", "module", "./parse-js", "./process"], function(require, exports, module) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington//convienence function(src, [options]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction uglify(orig_code, options){
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington options || (options = {});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var jsp = uglify.parser;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var pro = uglify.uglify;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var ast = jsp.parse(orig_code, options.strict_semicolons); // parse code and get the initial AST
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ast = pro.ast_mangle(ast, options.mangle_options); // get a new AST with mangled names
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ast = pro.ast_squeeze(ast, options.squeeze_options); // get an AST with compression optimizations
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var final_code = pro.gen_code(ast, options.gen_options); // compressed code here
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return final_code;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonuglify.parser = require("./parse-js");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonuglify.uglify = require("./process");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonmodule.exports = uglify
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint plusplus: false, strict: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global define: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('parse', ['./uglifyjs/index'], function (uglify) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var parser = uglify.parser,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington processor = uglify.uglify,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ostring = Object.prototype.toString,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isArray;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (Array.isArray) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isArray = Array.isArray;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isArray = function (it) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return ostring.call(it) === "[object Array]";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Determines if the AST node is an array literal
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function isArrayLiteral(node) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return node[0] === 'array';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Determines if the AST node is an object literal
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function isObjectLiteral(node) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return node[0] === 'object';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Converts a regular JS array of strings to an AST node that
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * represents that array.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Array} ary
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Node} an AST node that represents an array of strings.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function toAstArray(ary) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var output = [
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'array',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington []
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington i, item;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (item = ary[i]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington output[1].push([
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'string',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington item
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return output;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Validates a node as being an object literal (like for i18n bundles)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * or an array literal with just string members. If an array literal,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * only return array members that are full strings. So the caller of
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * this function should use the return value as the new value for the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * node.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * This function does not need to worry about comments, they are not
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * present in this AST.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Node} node an AST node.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {Node} an AST node to use for the valid dependencies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * If null is returned, then it means the input node was not a valid
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * dependency.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function validateDeps(node) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var newDeps = ['array', []],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington arrayArgs, i, dep;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!node) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isObjectLiteral(node) || node[0] === 'function') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return node;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Dependencies can be an object literal or an array.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!isArrayLiteral(node)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington arrayArgs = node[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; i < arrayArgs.length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dep = arrayArgs[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (dep[0] === 'string') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington newDeps[1].push(dep);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return newDeps[1].length ? newDeps : null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Gets dependencies from a node, but only if it is an array literal,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * and only if the dependency is a string literal.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * This function does not need to worry about comments, they are not
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * present in this AST.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Node} node an AST node.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {Array} of valid dependencies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * If null is returned, then it means the input node was not a valid
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * array literal, or did not have any string literals..
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function getValidDeps(node) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var newDeps = [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington arrayArgs, i, dep;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!node) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isObjectLiteral(node) || node[0] === 'function') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Dependencies can be an object literal or an array.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!isArrayLiteral(node)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington arrayArgs = node[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; i < arrayArgs.length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dep = arrayArgs[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (dep[0] === 'string') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington newDeps.push(dep[1]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return newDeps.length ? newDeps : null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Main parse function. Returns a string of any valid require or define/require.def
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * calls as part of one JavaScript source string.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} moduleName the module name that represents this file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * It is used to create a default define if there is not one already for the file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * This allows properly tracing dependencies for builds. Otherwise, if
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * the file just has a require() call, the file dependencies will not be
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * properly reflected: the file will come before its dependencies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} moduleName
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileName
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileContents
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} options optional options. insertNeedsDefine: true will
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * add calls to require.needsDefine() if appropriate.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {String} JS source string or null, if no require or define/require.def
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * calls are found.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function parse(moduleName, fileName, fileContents, options) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington options = options || {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set up source input
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var moduleDeps = [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington result = '',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleList = [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington needsDefine = true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington astRoot = parser.parse(fileContents),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington i, moduleCall, depString;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.recurse(astRoot, function (callName, config, name, deps) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If name is an array, it means it is an anonymous module,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //so adjust args appropriately. An anonymous module could
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //have a FUNCTION as the name type, but just ignore those
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //since we just want to find dependencies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (name && isArrayLiteral(name)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = name;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!(deps = getValidDeps(deps))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Get the name as a string literal, if it is available.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (name && name[0] === 'string') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = name[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (callName === 'define' && (!name || name === moduleName)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington needsDefine = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If there is no module name, the dependencies are for
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //this file/default module name.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleDeps = moduleDeps.concat(deps);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleList.push({
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name: name,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps: deps
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If define was found, no need to dive deeper, unless
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the config explicitly wants to dig deeper.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return !options.findNestedDependencies;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, options);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (options.insertNeedsDefine && needsDefine) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington result += 'require.needsDefine("' + moduleName + '");';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (moduleDeps.length || moduleList.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (moduleCall = moduleList[i]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (result) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington result += '\n';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If this is the main module for this file, combine any
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //"anonymous" dependencies (could come from a nested require
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //call) with this module.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (moduleCall.name === moduleName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleCall.deps = moduleCall.deps.concat(moduleDeps);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleDeps = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depString = moduleCall.deps.length ? '["' + moduleCall.deps.join('","') + '"]' : '[]';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington result += 'define("' + moduleCall.name + '",' + depString + ');';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (moduleDeps.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (result) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington result += '\n';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depString = moduleDeps.length ? '["' + moduleDeps.join('","') + '"]' : '[]';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington result += 'define("' + moduleName + '",' + depString + ');';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return result ? result : null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Add some private methods to object for use in derived objects.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.isArray = isArray;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.isObjectLiteral = isObjectLiteral;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.isArrayLiteral = isArrayLiteral;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Handles parsing a file recursively for require calls.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Array} parentNode the AST node to start with.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Function} onMatch function to call on a parse match.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} [options] This is normally the build config options if
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * it is passed.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Function} [recurseCallback] function to call on each valid
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * node, defaults to parse.parseNode.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.recurse = function (parentNode, onMatch, options, recurseCallback) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var hasHas = options && options.has,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington i, node;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington recurseCallback = recurseCallback || this.parseNode;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isArray(parentNode)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; i < parentNode.length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node = parentNode[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isArray(node)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If has config is in play, if calls have been converted
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //by this point to be true/false values. So, if
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //options has a 'has' value, skip if branches that have
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //literal false values.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //uglify returns if constructs in an array:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //[0]: 'if'
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //[1]: the condition, ['name', true | false] for the has replaced case.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //[2]: the block to process if true
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //[3]: the block to process if false
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //For if/else if/else, the else if is in the [3],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //so only ever have to deal with this structure.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (hasHas && node[0] === 'if' && node[1] && node[1][0] === 'name' &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (node[1][1] === 'true' || node[1][1] === 'false')) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (node[1][1] === 'true') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.recurse([node[2]], onMatch, options, recurseCallback);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.recurse([node[3]], onMatch, options, recurseCallback);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (recurseCallback(node, onMatch)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //The onMatch indicated parsing should
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //stop for children of this node.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington continue;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.recurse(node, onMatch, options, recurseCallback);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Determines if the file defines require().
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileName
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileContents
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {Boolean}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.definesRequire = function (fileName, fileContents) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var astRoot = parser.parse(fileContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return this.nodeHasRequire(astRoot);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Finds require("") calls inside a CommonJS anonymous module wrapped in a
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * define(function(require, exports, module){}) wrapper. These dependencies
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * will be added to a modified define() call that lists the dependencies
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * on the outside of the function.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileName
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileContents
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {Array} an array of module names that are dependencies. Always
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * returns an array, but could be of length zero.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.getAnonDeps = function (fileName, fileContents) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var astRoot = parser.parse(fileContents),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington defFunc = this.findAnonDefineFactory(astRoot);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return parse.getAnonDepsFromNode(defFunc);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Finds require("") calls inside a CommonJS anonymous module wrapped
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * in a define function, given an AST node for the definition function.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Node} node the AST node for the definition function.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {Array} and array of dependency names. Can be of zero length.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.getAnonDepsFromNode = function (node) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var deps = [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington funcArgLength;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (node) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.findRequireDepNames(node, deps);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If no deps, still add the standard CommonJS require, exports, module,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //in that order, to the deps, but only if specified as function args.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //In particular, if exports is used, it is favored over the return
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //value of the function, so only add it if asked.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington funcArgLength = node[2] && node[2].length;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (funcArgLength) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = (funcArgLength > 1 ? ["require", "exports", "module"] :
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ["require"]).concat(deps);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return deps;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Finds the function in define(function (require, exports, module){});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Array} node
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {Boolean}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.findAnonDefineFactory = function (node) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var callback, i, n, call, args;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isArray(node)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (node[0] === 'call') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington call = node[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = node[2];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if ((call[0] === 'name' && call[1] === 'define') ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (call[0] === 'dot' && call[1][1] === 'require' && call[2] === 'def')) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //There should only be one argument and it should be a function,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //or a named module with function as second arg
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (args.length === 1 && args[0][0] === 'function') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return args[0];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (args.length === 2 && args[0][0] === 'string' &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args[1][0] === 'function') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return args[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Check child nodes
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; i < node.length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington n = node[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if ((callback = this.findAnonDefineFactory(n))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return callback;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Finds any config that is passed to requirejs.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileName
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileContents
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {Object} a config object. Will be null if no config.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Can throw an error if the config in the file cannot be evaluated in
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * a build context to valid JavaScript.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.findConfig = function (fileName, fileContents) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /*jslint evil: true */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //This is a litle bit inefficient, it ends up with two uglifyjs parser
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //calls. Can revisit later, but trying to build out larger functional
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //pieces first.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var foundConfig = null,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington astRoot = parser.parse(fileContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.recurse(astRoot, function (configNode) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var jsConfig;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!foundConfig && configNode) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington jsConfig = parse.nodeToString(configNode);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington foundConfig = eval('(' + jsConfig + ')');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return foundConfig;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, null, parse.parseConfigNode);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return foundConfig;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Finds all dependencies specified in dependency arrays and inside
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * simplified commonjs wrappers.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileName
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileContents
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {Array} an array of dependency strings. The dependencies
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * have not been normalized, they may be relative IDs.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.findDependencies = function (fileName, fileContents, options) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //This is a litle bit inefficient, it ends up with two uglifyjs parser
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //calls. Can revisit later, but trying to build out larger functional
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //pieces first.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var dependencies = [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington astRoot = parser.parse(fileContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.recurse(astRoot, function (callName, config, name, deps) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Normalize the input args.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (name && isArrayLiteral(name)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = name;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if ((deps = getValidDeps(deps))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dependencies = dependencies.concat(deps);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, options);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return dependencies;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Finds only CJS dependencies, ones that are the form require('stringLiteral')
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.findCjsDependencies = function (fileName, fileContents, options) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //This is a litle bit inefficient, it ends up with two uglifyjs parser
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //calls. Can revisit later, but trying to build out larger functional
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //pieces first.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var dependencies = [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington astRoot = parser.parse(fileContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.recurse(astRoot, function (dep) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dependencies.push(dep);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, options, function (node, onMatch) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var call, args;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!isArray(node)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (node[0] === 'call') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington call = node[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = node[2];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (call) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //A require('') use.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (call[0] === 'name' && call[1] === 'require' &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args[0][0] === 'string') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return onMatch(args[0][1]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return dependencies;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Determines if define(), require({}|[]) or requirejs was called in the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * file. Also finds out if define() is declared and if define.amd is called.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.usesAmdOrRequireJs = function (fileName, fileContents, options) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var astRoot = parser.parse(fileContents),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington uses;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.recurse(astRoot, function (prop) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!uses) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington uses = {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington uses[prop] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, options, parse.findAmdOrRequireJsNode);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return uses;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Determines if require(''), exports.x =, module.exports =,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * __dirname, __filename are used. So, not strictly traditional CommonJS,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * also checks for Node variants.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.usesCommonJs = function (fileName, fileContents, options) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var uses = null,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington assignsExports = false,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington astRoot = parser.parse(fileContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.recurse(astRoot, function (prop) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (prop === 'varExports') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington assignsExports = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (prop !== 'exports' || !assignsExports) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!uses) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington uses = {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington uses[prop] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, options, function (node, onMatch) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var call, args;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!isArray(node)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (node[0] === 'name' && (node[1] === '__dirname' || node[1] === '__filename')) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return onMatch(node[1].substring(2));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (node[0] === 'var' && node[1] && node[1][0] && node[1][0][0] === 'exports') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Hmm, a variable assignment for exports, so does not use cjs exports.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return onMatch('varExports');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (node[0] === 'assign' && node[2] && node[2][0] === 'dot') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = node[2][1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (args) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //An exports or module.exports assignment.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (args[0] === 'name' && args[1] === 'module' &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node[2][2] === 'exports') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return onMatch('moduleExports');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (args[0] === 'name' && args[1] === 'exports') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return onMatch('exports');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (node[0] === 'call') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington call = node[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = node[2];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (call) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //A require('') use.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (call[0] === 'name' && call[1] === 'require' &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args[0][0] === 'string') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return onMatch('require');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return uses;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.findRequireDepNames = function (node, deps) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var moduleName, i, n, call, args;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isArray(node)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (node[0] === 'call') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington call = node[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = node[2];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (call && call[0] === 'name' && call[1] === 'require') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleName = args[0];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (moduleName[0] === 'string') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps.push(moduleName[1]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Check child nodes
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; i < node.length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington n = node[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.findRequireDepNames(n, deps);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Determines if a given node contains a require() definition.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Array} node
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {Boolean}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.nodeHasRequire = function (node) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (this.isDefineNode(node)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isArray(node)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (var i = 0, n; i < node.length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington n = node[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (this.nodeHasRequire(n)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Is the given node the actual definition of define(). Actually uses
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * the definition of define.amd to find require.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Array} node
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {Boolean}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.isDefineNode = function (node) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Actually look for the define.amd = assignment, since
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //that is more indicative of RequireJS vs a plain require definition.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var assign;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!node) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (node[0] === 'assign' && node[1] === true) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington assign = node[2];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (assign[0] === 'dot' && assign[1][0] === 'name' &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington assign[1][1] === 'define' && assign[2] === 'amd') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Determines if a specific node is a valid require or define/require.def call.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Array} node
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Function} onMatch a function to call when a match is found.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * It is passed the match name, and the config, name, deps possible args.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * The config, name and deps args are not normalized.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {String} a JS source string with the valid require/define call.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Otherwise null.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.parseNode = function (node, onMatch) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var call, name, config, deps, args, cjsDeps;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!isArray(node)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (node[0] === 'call') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington call = node[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = node[2];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (call) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (call[0] === 'name' &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (call[1] === 'require' || call[1] === 'requirejs')) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //It is a plain require() call.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config = args[0];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = args[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (isArrayLiteral(config)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = config;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!(deps = validateDeps(deps))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return onMatch("require", null, null, deps);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (call[0] === 'name' && call[1] === 'define') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //A define call
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = args[0];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = args[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Only allow define calls that match what is expected
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //in an AMD call:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //* first arg should be string, array, function or object
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //* second arg optional, or array, function or object.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //This helps weed out calls to a non-AMD define, but it is
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //not completely robust. Someone could create a define
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //function that still matches this shape, but this is the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //best that is possible, and at least allows UglifyJS,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //which does create its own internal define in one file,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //to be inlined.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (((name[0] === 'string' || isArrayLiteral(name) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name[0] === 'function' || isObjectLiteral(name))) &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (!deps || isArrayLiteral(deps) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps[0] === 'function' || isObjectLiteral(deps) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // allow define(['dep'], factory) pattern
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (isArrayLiteral(name) && deps[0] === 'name' && args.length === 2))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If first arg is a function, could be a commonjs wrapper,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //look inside for commonjs dependencies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Also, if deps is a function look for commonjs deps.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (name && name[0] === 'function') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cjsDeps = parse.getAnonDepsFromNode(name);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (cjsDeps.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = toAstArray(cjsDeps);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (deps && deps[0] === 'function') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cjsDeps = parse.getAnonDepsFromNode(deps);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (cjsDeps.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = toAstArray(cjsDeps);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return onMatch("define", null, name, deps);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Looks for define(), require({} || []), requirejs({} || []) calls.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.findAmdOrRequireJsNode = function (node, onMatch) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var call, args, configNode, type;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!isArray(node)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (node[0] === 'defun' && node[1] === 'define') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington type = 'declaresDefine';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (node[0] === 'assign' && node[2] && node[2][2] === 'amd' &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node[2][1] && node[2][1][0] === 'name' &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington node[2][1][1] === 'define') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington type = 'defineAmd';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (node[0] === 'call') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington call = node[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = node[2];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (call) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if ((call[0] === 'dot' &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (call[1] && call[1][0] === 'name' &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (call[1][1] === 'require' || call[1][1] === 'requirejs')) &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington call[2] === 'config')) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //A require.config() or requirejs.config() call.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington type = call[1][1] + 'Config';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (call[0] === 'name' &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (call[1] === 'require' || call[1] === 'requirejs')) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //A require() or requirejs() config call.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Only want ones that start with an object or an array.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington configNode = args[0];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (configNode[0] === 'object' || configNode[0] === 'array') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington type = call[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (call[0] === 'name' && call[1] === 'define') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //A define call.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington type = 'define';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (type) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return onMatch(type);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Determines if a specific node is a valid require/requirejs config
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * call. That includes calls to require/requirejs.config().
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Array} node
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Function} onMatch a function to call when a match is found.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * It is passed the match name, and the config, name, deps possible args.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * The config, name and deps args are not normalized.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {String} a JS source string with the valid require/define call.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Otherwise null.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.parseConfigNode = function (node, onMatch) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var call, configNode, args;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!isArray(node)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (node[0] === 'call') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington call = node[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args = node[2];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (call) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //A require.config() or requirejs.config() call.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if ((call[0] === 'dot' &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (call[1] && call[1][0] === 'name' &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (call[1][1] === 'require' || call[1][1] === 'requirejs')) &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington call[2] === 'config') ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //A require() or requirejs() config call.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (call[0] === 'name' &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (call[1] === 'require' || call[1] === 'requirejs'))
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //It is a plain require() call.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington configNode = args[0];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (configNode[0] !== 'object') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return onMatch(configNode);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Converts an AST node into a JS source string. Does not maintain formatting
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * or even comments from original source, just returns valid JS source.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Array} node
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {String} a JS source string.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parse.nodeToString = function (node) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return processor.gen_code(node, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return parse;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint regexp: false, strict: false, plusplus: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global define: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('pragma', ['parse', 'logger'], function (parse, logger) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function Temp() {}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function create(obj, mixin) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington Temp.prototype = obj;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var temp = new Temp(), prop;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Avoid any extra memory hanging around
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington Temp.prototype = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (mixin) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (prop in mixin) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (mixin.hasOwnProperty(prop) && !(prop in temp)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington temp[prop] = mixin[prop];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return temp; // Object
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var pragma = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington conditionalRegExp: /(exclude|include)Start\s*\(\s*["'](\w+)["']\s*,(.*)\)/,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington useStrictRegExp: /['"]use strict['"];/g,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington hasRegExp: /has\s*\(\s*['"]([^'"]+)['"]\s*\)/g,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington nsRegExp: /(^|[^\.])(requirejs|require|define)\s*\(/,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington nsWrapRegExp: /\/\*requirejs namespace: true \*\//,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington apiDefRegExp: /var requirejs, require, define;/,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington defineCheckRegExp: /typeof\s+define\s*===\s*["']function["']\s*&&\s*define\s*\.\s*amd/g,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington defineJQueryRegExp: /typeof\s+define\s*===\s*["']function["']\s*&&\s*define\s*\.\s*amd\s*&&\s*define\s*\.\s*amd\s*\.\s*jQuery/g,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington defineHasRegExp: /typeof\s+define\s*==(=)?\s*['"]function['"]\s*&&\s*typeof\s+define\.amd\s*==(=)?\s*['"]object['"]\s*&&\s*define\.amd/g,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington defineTernaryRegExp: /typeof\s+define\s*===\s*['"]function["']\s*&&\s*define\s*\.\s*amd\s*\?\s*define/,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington amdefineRegExp: /if\s*\(\s*typeof define\s*\!==\s*'function'\s*\)\s*\{\s*[^\{\}]+amdefine[^\{\}]+\}/g,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington removeStrict: function (contents, config) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return config.useStrict ? contents : contents.replace(pragma.useStrictRegExp, '');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington namespace: function (fileContents, ns, onLifecycleName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (ns) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Namespace require/define calls
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = fileContents.replace(pragma.nsRegExp, '$1' + ns + '.$2(');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Namespace define ternary use:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = fileContents.replace(pragma.defineTernaryRegExp,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "typeof " + ns + ".define === 'function' && " + ns + ".define.amd ? " + ns + ".define");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Namespace define jquery use:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = fileContents.replace(pragma.defineJQueryRegExp,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "typeof " + ns + ".define === 'function' && " + ns + ".define.amd && " + ns + ".define.amd.jQuery");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Namespace has.js define use:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = fileContents.replace(pragma.defineHasRegExp,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "typeof " + ns + ".define === 'function' && typeof " + ns + ".define.amd === 'object' && " + ns + ".define.amd");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Namespace define checks.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Do this one last, since it is a subset of the more specific
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //checks above.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = fileContents.replace(pragma.defineCheckRegExp,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "typeof " + ns + ".define === 'function' && " + ns + ".define.amd");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Check for require.js with the require/define definitions
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (pragma.apiDefRegExp.test(fileContents) &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents.indexOf("if (typeof " + ns + " === 'undefined')") === -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Wrap the file contents in a typeof check, and a function
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //to contain the API globals.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = "var " + ns + ";(function () { if (typeof " +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ns + " === 'undefined') {\n" +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ns + ' = {};\n' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "\n" +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ns + ".requirejs = requirejs;" +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ns + ".require = require;" +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ns + ".define = define;\n" +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "}\n}());";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Finally, if the file wants a special wrapper because it ties
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //in to the requirejs internals in a way that would not fit
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the above matches, do that. Look for /*requirejs namespace: true*/
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (pragma.nsWrapRegExp.test(fileContents)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Remove the pragma.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = fileContents.replace(pragma.nsWrapRegExp, '');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Alter the contents.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = '(function () {\n' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'var require = ' + ns + '.require,' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'requirejs = ' + ns + '.requirejs,' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'define = ' + ns + '.define;\n' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington '\n}());'
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return fileContents;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * processes the fileContents for some //>> conditional statements
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington process: function (fileName, fileContents, config, onLifecycleName, pluginCollector) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /*jslint evil: true */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var foundIndex = -1, startIndex = 0, lineEndIndex, conditionLine,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington matches, type, marker, condition, isTrue, endRegExp, endMatches,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington endMarkerIndex, shouldInclude, startLength, lifecycleHas, deps,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington i, dep, moduleName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lifecyclePragmas, pragmas = config.pragmas, hasConfig = config.has,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Legacy arg defined to help in dojo conversion script. Remove later
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //when dojo no longer needs conversion:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington kwArgs = pragmas;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Mix in a specific lifecycle scoped object, to allow targeting
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //some pragmas/has tests to only when files are saved, or at different
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //lifecycle events. Do not bother with kwArgs in this section, since
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the old dojo kwArgs were for all points in the build lifecycle.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (onLifecycleName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lifecyclePragmas = config['pragmas' + onLifecycleName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lifecycleHas = config['has' + onLifecycleName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (lifecyclePragmas) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pragmas = create(pragmas || {}, lifecyclePragmas);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (lifecycleHas) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington hasConfig = create(hasConfig || {}, lifecycleHas);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Replace has references if desired
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (hasConfig) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = fileContents.replace(pragma.hasRegExp, function (match, test) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (test in hasConfig) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return !!hasConfig[test];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return match;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!config.skipPragmas) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while ((foundIndex = fileContents.indexOf("//>>", startIndex)) !== -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Found a conditional. Get the conditional line.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lineEndIndex = fileContents.indexOf("\n", foundIndex);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (lineEndIndex === -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lineEndIndex = fileContents.length - 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Increment startIndex past the line so the next conditional search can be done.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington startIndex = lineEndIndex + 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Break apart the conditional.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington conditionLine = fileContents.substring(foundIndex, lineEndIndex + 1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington matches = conditionLine.match(pragma.conditionalRegExp);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (matches) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington type = matches[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington marker = matches[2];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington condition = matches[3];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isTrue = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //See if the condition is true.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isTrue = !!eval("(" + condition + ")");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw "Error in file: " +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileName +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ". Conditional comment: " +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington conditionLine +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington " failed with this error: " + e;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Find the endpoint marker.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington endRegExp = new RegExp('\\/\\/\\>\\>\\s*' + type + 'End\\(\\s*[\'"]' + marker + '[\'"]\\s*\\)', "g");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington endMatches = endRegExp.exec(fileContents.substring(startIndex, fileContents.length));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (endMatches) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington endMarkerIndex = startIndex + endRegExp.lastIndex - endMatches[0].length;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Find the next line return based on the match position.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lineEndIndex = fileContents.indexOf("\n", endMarkerIndex);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (lineEndIndex === -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lineEndIndex = fileContents.length - 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Should we include the segment?
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington shouldInclude = ((type === "exclude" && !isTrue) || (type === "include" && isTrue));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Remove the conditional comments, and optionally remove the content inside
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the conditional comments.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington startLength = startIndex - foundIndex;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = fileContents.substring(0, foundIndex) +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (shouldInclude ? fileContents.substring(startIndex, endMarkerIndex) : "") +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents.substring(lineEndIndex + 1, fileContents.length);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Move startIndex to foundIndex, since that is the new position in the file
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //where we need to look for more conditionals in the next while loop pass.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington startIndex = foundIndex;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw "Error in file: " +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileName +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ". Cannot find end marker for conditional comment: " +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington conditionLine;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If need to find all plugin resources to optimize, do that now,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //before namespacing, since the namespacing will change the API
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //names.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If there is a plugin collector, scan the file for plugin resources.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.optimizeAllPluginResources && pluginCollector) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = parse.findDependencies(fileName, fileContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (deps.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (dep = deps[i]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (dep.indexOf('!') !== -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (pluginCollector[moduleName] ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (pluginCollector[moduleName] = [])).push(dep);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (eDep) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington logger.error('Parse error looking for plugin resources in ' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileName + ', skipping.');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Strip amdefine use for node-shared modules.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = fileContents.replace(pragma.amdefineRegExp, '');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Do namespacing
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (onLifecycleName === 'OnSave' && config.namespace) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = pragma.namespace(fileContents, config.namespace, onLifecycleName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return pragma.removeStrict(fileContents, config);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return pragma;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonif(env === 'node') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint strict: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global define: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('node/optimize', {});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonif(env === 'rhino') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint strict: false, plusplus: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global define: false, java: false, Packages: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('rhino/optimize', ['logger'], function (logger) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Add .reduce to Rhino so UglifyJS can run in Rhino,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //inspired by https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/reduce
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //but rewritten for brevity, and to be good enough for use by UglifyJS.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!Array.prototype.reduce) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington Array.prototype.reduce = function (fn /*, initialValue */) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var i = 0,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington length = this.length,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington accumulator;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (arguments.length >= 2) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington accumulator = arguments[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington do {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (i in this) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington accumulator = this[i++];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington break;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while (true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (; i < length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (i in this) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington accumulator = fn.call(undefined, accumulator, this[i], i, this);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return accumulator;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var JSSourceFilefromCode, optimize;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Bind to Closure compiler, but if it is not available, do not sweat it.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington JSSourceFilefromCode = java.lang.Class.forName('com.google.javascript.jscomp.JSSourceFile').getMethod('fromCode', [java.lang.String, java.lang.String]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (e) {}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Helper for closure compiler, because of weird Java-JavaScript interactions.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function closurefromCode(filename, content) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return JSSourceFilefromCode.invoke(null, [filename, content]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington optimize = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington closure: function (fileName, fileContents, keepLines, config) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config = config || {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var jscomp = Packages.com.google.javascript.jscomp,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington flags = Packages.com.google.common.flags,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Fake extern
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington externSourceFile = closurefromCode("fakeextern.js", " "),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set up source input
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington jsSourceFile = closurefromCode(String(fileName), String(fileContents)),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington options, option, FLAG_compilation_level, compiler,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington Compiler = Packages.com.google.javascript.jscomp.Compiler,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington result;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington logger.trace("Minifying file: " + fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set up options
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington options = new jscomp.CompilerOptions();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (option in config.CompilerOptions) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington // options are false by default and jslint wanted an if statement in this for loop
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.CompilerOptions[option]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington options[option] = config.CompilerOptions[option];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington options.prettyPrint = keepLines || options.prettyPrint;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington FLAG_compilation_level = jscomp.CompilationLevel[config.CompilationLevel || 'SIMPLE_OPTIMIZATIONS'];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington FLAG_compilation_level.setOptionsForCompilationLevel(options);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Trigger the compiler
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington Compiler.setLoggingLevel(Packages.java.util.logging.Level[config.loggingLevel || 'WARNING']);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington compiler = new Compiler();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington result = compiler.compile(externSourceFile, jsSourceFile, options);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!result.success) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington logger.error('Cannot closure compile file: ' + fileName + '. Skipping it.');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = compiler.toSource();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return fileContents;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return optimize;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint plusplus: false, nomen: false, regexp: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global define: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('optimize', [ 'lang', 'logger', 'env!env/optimize', 'env!env/file', 'parse',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'pragma', 'uglifyjs/index'],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction (lang, logger, envOptimize, file, parse,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pragma, uglify) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var optimize,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cssImportRegExp = /\@import\s+(url\()?\s*([^);]+)\s*(\))?([\w, ]*)(;)?/g,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cssUrlRegExp = /\url\(\s*([^\)]+)\s*\)?/g;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * If an URL from a CSS url value contains start/end quotes, remove them.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * This is not done in the regexp, since my regexp fu is not that strong,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * and the CSS spec allows for ' and " in the URL if they are backslash escaped.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} url
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function cleanCssUrlQuotes(url) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make sure we are not ending in whitespace.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Not very confident of the css regexps above that there will not be ending
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //whitespace.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington url = url.replace(/\s+$/, "");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (url.charAt(0) === "'" || url.charAt(0) === "\"") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington url = url.substring(1, url.length - 1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return url;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Inlines nested stylesheets that have @import calls in them.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileName
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileContents
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} [cssImportIgnore]
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function flattenCss(fileName, fileContents, cssImportIgnore) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Find the last slash in the name.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileName = fileName.replace(lang.backSlashRegExp, "/");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var endIndex = fileName.lastIndexOf("/"),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make a file path based on the last slash.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If no slash, so must be just a file name. Use empty string then.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington filePath = (endIndex !== -1) ? fileName.substring(0, endIndex + 1) : "";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make sure we have a delimited ignore list to make matching faster
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (cssImportIgnore && cssImportIgnore.charAt(cssImportIgnore.length - 1) !== ",") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cssImportIgnore += ",";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return fileContents.replace(cssImportRegExp, function (fullMatch, urlStart, importFileName, urlEnd, mediaTypes) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Only process media type "all" or empty media type rules.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (mediaTypes && ((mediaTypes.replace(/^\s\s*/, '').replace(/\s\s*$/, '')) !== "all")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return fullMatch;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington importFileName = cleanCssUrlQuotes(importFileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Ignore the file import if it is part of an ignore list.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (cssImportIgnore && cssImportIgnore.indexOf(importFileName + ",") !== -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return fullMatch;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make sure we have a unix path for the rest of the operation.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington importFileName = importFileName.replace(lang.backSlashRegExp, "/");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //if a relative path, then tack on the filePath.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If it is not a relative path, then the readFile below will fail,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //and we will just skip that import.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var fullImportFileName = importFileName.charAt(0) === "/" ? importFileName : filePath + importFileName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington importContents = file.readFile(fullImportFileName), i,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington importEndIndex, importPath, fixedUrlMatch, colonIndex, parts;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make sure to flatten any nested imports.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington importContents = flattenCss(fullImportFileName, importContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make the full import path
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington importEndIndex = importFileName.lastIndexOf("/");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make a file path based on the last slash.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If no slash, so must be just a file name. Use empty string then.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington importPath = (importEndIndex !== -1) ? importFileName.substring(0, importEndIndex + 1) : "";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //fix url() on relative import (#5)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington importPath = importPath.replace(/^\.\//, '');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Modify URL paths to match the path represented by this file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington importContents = importContents.replace(cssUrlRegExp, function (fullMatch, urlMatch) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fixedUrlMatch = cleanCssUrlQuotes(urlMatch);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fixedUrlMatch = fixedUrlMatch.replace(lang.backSlashRegExp, "/");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Only do the work for relative URLs. Skip things that start with / or have
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //a protocol.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington colonIndex = fixedUrlMatch.indexOf(":");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fixedUrlMatch.charAt(0) !== "/" && (colonIndex === -1 || colonIndex > fixedUrlMatch.indexOf("/"))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //It is a relative URL, tack on the path prefix
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington urlMatch = importPath + fixedUrlMatch;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington logger.trace(importFileName + "\n URL not a relative URL, skipping: " + urlMatch);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Collapse .. and .
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parts = urlMatch.split("/");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = parts.length - 1; i > 0; i--) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (parts[i] === ".") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parts.splice(i, 1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (parts[i] === "..") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (i !== 0 && parts[i - 1] !== "..") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parts.splice(i - 1, 2);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington i -= 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return "url(" + parts.join("/") + ")";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return importContents;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington logger.trace(fileName + "\n Cannot inline css import, skipping: " + importFileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return fullMatch;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington optimize = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington licenseCommentRegExp: /\/\*[\s\S]*?\*\//g,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Optimizes a file that contains JavaScript content. Optionally collects
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * plugin resources mentioned in a file, and then passes the content
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * through an minifier if one is specified via config.optimize.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileName the name of the file to optimize
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} outFileName the name of the file to use for the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * saved optimized content.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} config the build config object.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} [moduleName] the module name to use for the file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Used for plugin resource collection.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Array} [pluginCollector] storage for any plugin resources
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * found.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington jsFile: function (fileName, outFileName, config, moduleName, pluginCollector) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var parts = (config.optimize + "").split('.'),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington optimizerName = parts[0],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington keepLines = parts[1] === 'keepLines',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = file.readFile(fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = optimize.js(fileName, fileContents, optimizerName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington keepLines, config, pluginCollector);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.saveUtf8File(outFileName, fileContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Optimizes a file that contains JavaScript content. Optionally collects
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * plugin resources mentioned in a file, and then passes the content
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * through an minifier if one is specified via config.optimize.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileName the name of the file that matches the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * fileContents.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileContents the string of JS to optimize.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} [optimizerName] optional name of the optimizer to
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * use. 'uglify' is default.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Boolean} [keepLines] whether to keep line returns in the optimization.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} [config] the build config object.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Array} [pluginCollector] storage for any plugin resources
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * found.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington js: function (fileName, fileContents, optimizerName, keepLines, config, pluginCollector) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var licenseContents = '',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington optFunc, match, comment;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config = config || {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Apply pragmas/namespace renaming
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = pragma.process(fileName, fileContents, config, 'OnSave', pluginCollector);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Optimize the JS files if asked.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (optimizerName && optimizerName !== 'none') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington optFunc = envOptimize[optimizerName] || optimize.optimizers[optimizerName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!optFunc) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw new Error('optimizer with name of "' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington optimizerName +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington '" not found for this environment');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.preserveLicenseComments) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Pull out any license comments for prepending after optimization.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington optimize.licenseCommentRegExp.lastIndex = 0;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while ((match = optimize.licenseCommentRegExp.exec(fileContents))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington comment = match[0];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Only keep the comments if they are license comments.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (comment.indexOf('@license') !== -1 ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington comment.indexOf('/*!') === 0) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington licenseContents += comment + '\n';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = licenseContents + optFunc(fileName, fileContents, keepLines,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config[optimizerName]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return fileContents;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Optimizes one CSS file, inlining @import calls, stripping comments, and
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * optionally removes line returns.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileName the path to the CSS file to optimize
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} outFileName the path to save the optimized file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} config the config object with the optimizeCss and
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * cssImportIgnore options.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cssFile: function (fileName, outFileName, config) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Read in the file. Make sure we have a JS string.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var originalFileContents = file.readFile(fileName),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = flattenCss(fileName, originalFileContents, config.cssImportIgnore),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington startIndex, endIndex;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Do comment removal.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington startIndex = -1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Get rid of comments.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while ((startIndex = fileContents.indexOf("/*")) !== -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington endIndex = fileContents.indexOf("*/", startIndex + 2);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (endIndex === -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw "Improper comment in CSS file: " + fileName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = fileContents.substring(0, startIndex) + fileContents.substring(endIndex + 2, fileContents.length);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Get rid of newlines.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.optimizeCss.indexOf(".keepLines") === -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = fileContents.replace(/[\r\n]/g, "");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = fileContents.replace(/\s+/g, " ");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = fileContents.replace(/\{\s/g, "{");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = fileContents.replace(/\s\}/g, "}");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Remove multiple empty lines.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = fileContents.replace(/(\r\n)+/g, "\r\n");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = fileContents.replace(/(\n)+/g, "\n");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = originalFileContents;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington logger.error("Could not optimized CSS file: " + fileName + ", error: " + e);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.saveUtf8File(outFileName, fileContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Optimizes CSS files, inlining @import calls, stripping comments, and
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * optionally removes line returns.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} startDir the path to the top level directory
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} config the config object with the optimizeCss and
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * cssImportIgnore options.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington css: function (startDir, config) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.optimizeCss.indexOf("standard") !== -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var i, fileName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileList = file.getFilteredFileList(startDir, /\.css$/, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (fileList) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; i < fileList.length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileName = fileList[i];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington logger.trace("Optimizing (" + config.optimizeCss + ") CSS file: " + fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington optimize.cssFile(fileName, fileName, config);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington optimizers: {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington uglify: function (fileName, fileContents, keepLines, config) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var parser = uglify.parser,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington processor = uglify.uglify,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ast;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config = config || {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington logger.trace("Uglifying file: " + fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ast = parser.parse(fileContents, config.strict_semicolons);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ast = processor.ast_mangle(ast, config);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ast = processor.ast_squeeze(ast, config);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = processor.gen_code(ast, config);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington logger.error('Cannot uglify file: ' + fileName + '. Skipping it. Error is:\n' + e.toString());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return fileContents;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return optimize;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license RequireJS Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * This file patches require.js to communicate with the build system.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint nomen: false, plusplus: false, regexp: false, strict: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global require: false, define: true */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington//NOT asking for require as a dependency since the goal is to modify the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington//global require below
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('requirePatch', [ 'env!env/file', 'pragma', 'parse'],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction (file, pragma, parse) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var allowRun = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //This method should be called when the patches to require should take hold.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!allowRun) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington allowRun = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var layer,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pluginBuilderRegExp = /(["']?)pluginBuilder(["']?)\s*[=\:]\s*["']([^'"\s]+)["']/,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington oldDef;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /** Print out some extrs info about the module tree that caused the error. **/
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require.onError = function (err) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var msg = '\nIn module tree:\n',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington standardIndent = ' ',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington tree = err.moduleTree,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington i, j, mod;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (tree && tree.length > 0) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = tree.length - 1; i > -1 && (mod = tree[i]); i--) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (j = tree.length - i; j > -1; j--) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington msg += standardIndent;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington msg += mod + '\n';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington err = new Error(err.toString() + msg);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw err;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Stored cached file contents for reuse in other layers.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require._cachedFileContents = {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /** Reset state for each build layer pass. */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require._buildReset = function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var oldContext = require.s.contexts._;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Clear up the existing context.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington delete require.s.contexts._;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set up new context, so the layer object can hold onto it.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require({});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer = require._layer = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildPathMap: {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildFileToModule: {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildFilePaths: [],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pathAdded: {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington modulesWithNames: {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington needsDefine: {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington existingRequireUrl: "",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context: require.s.contexts._
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Return the previous context in case it is needed, like for
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the basic config object.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return oldContext;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require._buildReset();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Makes sure the URL is something that can be supported by the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * optimization tool.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} url
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {Boolean}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require._isSupportedBuildUrl = function (url) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Ignore URLs with protocols, hosts or question marks, means either network
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //access is needed to fetch it or it is too dynamic. Note that
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //on Windows, full paths are used for some urls, which include
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the drive, like c:/something, so need to test for something other
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //than just a colon.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return url.indexOf("://") === -1 && url.indexOf("?") === -1 &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington url.indexOf('empty:') !== 0 && url.indexOf('//') !== 0;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Override define() to catch modules that just define an object, so that
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //a dummy define call is not put in the build file for them. They do
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //not end up getting defined via require.execCb, so we need to catch them
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //at the define call.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington oldDef = define;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //This function signature does not have to be exact, just match what we
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //are looking for.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington define = function (name, obj) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (typeof name === "string" && !layer.needsDefine[name]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.modulesWithNames[name] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return oldDef.apply(require, arguments);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington define.amd = oldDef.amd;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Add some utilities for plugins
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require._readFile = file.readFile;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require._fileExists = function (path) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return file.exists(path);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function normalizeUrlWithBase(context, moduleName, url) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Adjust the URL if it was not transformed to use baseUrl.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (require.jsExtRegExp.test(moduleName)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington url = (context.config.dir || context.config.dirBaseUrl) + url;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return url;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Override load so that the file paths can be collected.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require.load = function (context, moduleName, url) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /*jslint evil: true */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var contents, pluginBuilderMatch, builderName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.scriptCount += 1;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Only handle urls that can be inlined, so that means avoiding some
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //URLs like ones that require network access or may be too dynamic,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //like JSONP
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (require._isSupportedBuildUrl(url)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Adjust the URL if it was not transformed to use baseUrl.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington url = normalizeUrlWithBase(context, moduleName, url);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Save the module name to path and path to module name mappings.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.buildPathMap[moduleName] = url;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.buildFileToModule[url] = moduleName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (moduleName in context.plugins) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //plugins need to have their source evaled as-is.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.needFullExec[moduleName] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (url in require._cachedFileContents &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (!context.needFullExec[moduleName] || context.fullExec[moduleName])) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contents = require._cachedFileContents[url];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Load the file contents, process for conditionals, then
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //evaluate it.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contents = file.readFile(url);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If there is a read filter, run it now.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (context.config.onBuildRead) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contents = context.config.onBuildRead(moduleName, url, contents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contents = pragma.process(url, contents, context.config, 'OnExecute');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Find out if the file contains a require() definition. Need to know
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //this so we can inject plugins right after it, but before they are needed,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //and to make sure this file is first, so that define calls work.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //This situation mainly occurs when the build is done on top of the output
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //of another build, where the first build may include require somewhere in it.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!layer.existingRequireUrl && parse.definesRequire(url, contents)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.existingRequireUrl = url;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (e1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw new Error('Parse error using UglifyJS ' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'for file: ' + url + '\n' + e1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (moduleName in context.plugins) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //This is a loader plugin, check to see if it has a build extension,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //otherwise the plugin will act as the plugin builder too.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pluginBuilderMatch = pluginBuilderRegExp.exec(contents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (pluginBuilderMatch) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Load the plugin builder for the plugin contents.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington builderName = context.normalize(pluginBuilderMatch[3], moduleName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contents = file.readFile(context.nameToUrl(builderName));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Parse out the require and define calls.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Do this even for plugins in case they have their own
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //dependencies that may be separate to how the pluginBuilder works.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!context.needFullExec[moduleName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contents = parse(moduleName, url, contents, {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington insertNeedsDefine: true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington has: context.config.has,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington findNestedDependencies: context.config.findNestedDependencies
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (e2) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw new Error('Parse error using UglifyJS ' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'for file: ' + url + '\n' + e2);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require._cachedFileContents[url] = contents;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (contents) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington eval(contents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Need to close out completion of this module
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //so that listeners will get notified that it is available.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.completeLoad(moduleName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Track which module could not complete loading.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (e.moduleTree || (e.moduleTree = [])).push(moduleName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw e;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (eOuter) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!eOuter.fileName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington eOuter.fileName = url;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw eOuter;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //With unsupported URLs still need to call completeLoad to
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //finish loading.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.completeLoad(moduleName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Mark the module loaded.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.loaded[moduleName] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Called when execManager runs for a dependency. Used to figure out
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //what order of execution.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require.onResourceLoad = function (context, map) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var fullName = map.fullName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington url;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Ignore "fake" modules, usually generated by plugin code, since
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //they do not map back to a real file to include in the optimizer,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //or it will be included, but in a different form.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (context.fake[fullName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //A plugin.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (map.prefix) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!layer.pathAdded[fullName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.buildFilePaths.push(fullName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //For plugins the real path is not knowable, use the name
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //for both module to file and file to module mappings.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.buildPathMap[fullName] = fullName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.buildFileToModule[fullName] = fullName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.modulesWithNames[fullName] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.pathAdded[fullName] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (map.url && require._isSupportedBuildUrl(map.url)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If the url has not been added to the layer yet, and it
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //is from an actual file that was loaded, add it now.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington url = normalizeUrlWithBase(context, map.fullName, map.url);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!layer.pathAdded[url] && layer.buildPathMap[fullName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Remember the list of dependencies for this layer.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.buildFilePaths.push(url);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.pathAdded[url] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Called by output of the parse() function, when a file does not
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //explicitly call define, probably just require, but the parse()
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //function normalizes on define() for dependency mapping and file
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //ordering works correctly.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require.needsDefine = function (moduleName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.needsDefine[moduleName] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Marks module has having a name, and optionally executes the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //callback, but only if it meets certain criteria.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require.execCb = function (name, cb, args, exports) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!layer.needsDefine[name]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.modulesWithNames[name] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (cb.__requireJsBuild || layer.context.needFullExec[name]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return cb.apply(exports, args);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license RequireJS Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint plusplus: false, regexp: false, strict: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global define: false, console: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('commonJs', ['env!env/file', 'uglifyjs/index'], function (file, uglify) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var commonJs = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depRegExp: /require\s*\(\s*["']([\w-_\.\/]+)["']\s*\)/g,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set this to false in non-rhino environments. If rhino, then it uses
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //rhino's decompiler to remove comments before looking for require() calls,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //otherwise, it will use a crude regexp approach to remove comments. The
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //rhino way is more robust, but he regexp is more portable across environments.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington useRhino: true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set to false if you do not want this file to log. Useful in environments
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //like node where you want the work to happen without noise.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington useLog: true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington convertDir: function (commonJsPath, savePath) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var fileList, i,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington jsFileRegExp = /\.js$/,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileName, convertedFileName, fileContents;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Get list of files to convert.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileList = file.getFilteredFileList(commonJsPath, /\w/, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Normalize on front slashes and make sure the paths do not end in a slash.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington commonJsPath = commonJsPath.replace(/\\/g, "/");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington savePath = savePath.replace(/\\/g, "/");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (commonJsPath.charAt(commonJsPath.length - 1) === "/") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington commonJsPath = commonJsPath.substring(0, commonJsPath.length - 1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (savePath.charAt(savePath.length - 1) === "/") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington savePath = savePath.substring(0, savePath.length - 1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Cycle through all the JS files and convert them.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!fileList || !fileList.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (commonJs.useLog) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (commonJsPath === "convert") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //A request just to convert one file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington console.log('\n\n' + commonJs.convert(savePath, file.readFile(savePath)));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington console.log("No files to convert in directory: " + commonJsPath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (fileName = fileList[i]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington convertedFileName = fileName.replace(commonJsPath, savePath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Handle JS files.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (jsFileRegExp.test(fileName)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = file.readFile(fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = commonJs.convert(fileName, fileContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.saveUtf8File(convertedFileName, fileContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Just copy the file over.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.copyFile(fileName, convertedFileName, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Removes the comments from a string.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileContents
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileName mostly used for informative reasons if an error.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {String} a string of JS with comments removed.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington removeComments: function (fileContents, fileName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Uglify's ast generation removes comments, so just convert to ast,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //then back to source code to get rid of comments.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return uglify.uglify.gen_code(uglify.parser.parse(fileContents), true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington },
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Regexp for testing if there is already a require.def call in the file,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * in which case do not try to convert it.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington defRegExp: /define\s*\(\s*("|'|\[|function)/,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Regexp for testing if there is a require([]) or require(function(){})
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * call, indicating the file is already in requirejs syntax.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington rjsRegExp: /require\s*\(\s*(\[|function)/,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Does the actual file conversion.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileName the name of the file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} fileContents the contents of a file :)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Boolean} skipDeps if true, require("") dependencies
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * will not be searched, but the contents will just be wrapped in the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * standard require, exports, module dependencies. Only usable in sync
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * environments like Node where the require("") calls can be resolved on
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * the fly.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {String} the converted contents
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington convert: function (fileName, fileContents, skipDeps) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Strip out comments.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var deps = [], depName, match,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Remove comments
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington tempContents = commonJs.removeComments(fileContents, fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //First see if the module is not already RequireJS-formatted.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (commonJs.defRegExp.test(tempContents) || commonJs.rjsRegExp.test(tempContents)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return fileContents;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Reset the regexp to start at beginning of file. Do this
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //since the regexp is reused across files.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington commonJs.depRegExp.lastIndex = 0;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!skipDeps) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Find dependencies in the code that was not in comments.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington while ((match = commonJs.depRegExp.exec(tempContents))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington depName = match[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (depName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps.push('"' + depName + '"');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Construct the wrapper boilerplate.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = 'define(["require", "exports", "module"' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (deps.length ? ', ' + deps.join(",") : '') + '], ' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'function(require, exports, module) {\n' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington '\n});\n';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington console.log("COULD NOT CONVERT: " + fileName + ", so skipping it. Error was: " + e);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return fileContents;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return fileContents;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return commonJs;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint plusplus: true, nomen: true */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global define, require */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtondefine('build', [ 'lang', 'logger', 'env!env/file', 'parse', 'optimize', 'pragma',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'env!env/load', 'requirePatch'],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction (lang, logger, file, parse, optimize, pragma,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington load, requirePatch) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'use strict';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var build, buildBaseConfig,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington endsWithSemiColonRegExp = /;\s*$/;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildBaseConfig = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington appDir: "",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pragmas: {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington paths: {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington optimize: "uglify",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington optimizeCss: "standard.keepLines",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington inlineText: true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington isBuild: true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington optimizeAllPluginResources: false,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington findNestedDependencies: false,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington preserveLicenseComments: true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //By default, all files/directories are copied, unless
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //they match this regexp, by default just excludes .folders
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dirExclusionRegExp: file.dirExclusionRegExp
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Some JS may not be valid if concatenated with other JS, in particular
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * the style of omitting semicolons and rely on ASI. Add a semicolon in
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * those cases.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function addSemiColon(text) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (endsWithSemiColonRegExp.test(text)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return text;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return text + ";";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * If the path looks like an URL, throw an error. This is to prevent
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * people from using URLs with protocols in the build config, since
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * the optimizer is not set up to do network access. However, be
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * sure to allow absolute paths on Windows, like C:\directory.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function disallowUrls(path) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if ((path.indexOf('://') !== -1 || path.indexOf('//') === 0) && path !== 'empty:') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw new Error('Path is not supported: ' + path +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington '\nOptimizer can only handle' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ' local paths. Download the locally if necessary' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ' and update the config to use a local path.\n' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'http://requirejs.org/docs/errors.html#pathnotsupported');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function endsWithSlash(dirName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (dirName.charAt(dirName.length - 1) !== "/") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dirName += "/";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington disallowUrls(dirName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return dirName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Method used by plugin writeFile calls, defined up here to avoid
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //jslint warning about "making a function in a loop".
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function makeWriteFile(anonDefRegExp, namespaceWithDot, layer) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function writeFile(name, contents) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington logger.trace('Saving plugin-optimized file: ' + name);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.saveUtf8File(name, contents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington writeFile.asModule = function (moduleName, fileName, contents) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington writeFile(fileName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.toTransport(anonDefRegExp, namespaceWithDot, moduleName, fileName, contents, layer));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return writeFile;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Main API entry point into the build. The args argument can either be
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * an array of arguments (like the onese passed on a command-line),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * or it can be a JavaScript object that has the format of a build profile
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * If it is an object, then in addition to the normal properties allowed in
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * a build profile file, the object should contain one other property:
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * The object could also contain a "buildFile" property, which is a string
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * that is the file path to a build profile that contains the rest
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * of the build profile directives.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * This function does not return a status, it should throw an error if
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * there is a problem completing the build.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build = function (args) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var buildFile, cmdConfig;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!args || lang.isArray(args)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!args || args.length < 1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington logger.error("build.js buildProfile.js\n" +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "where buildProfile.js is the name of the build file (see example.build.js for hints on how to make a build file).");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return undefined;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Next args can include a build file path as well as other build args.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //build file path comes first. If it does not contain an = then it is
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //a build file path. Otherwise, just all build args.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (args[0].indexOf("=") === -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildFile = args[0];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington args.splice(0, 1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Remaining args are options to the build
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cmdConfig = build.convertArrayToObject(args);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cmdConfig.buildFile = buildFile;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington cmdConfig = args;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return build._run(cmdConfig);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build._run = function (cmdConfig) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var buildFileContents = "",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pluginCollector = {},
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildPaths, fileName, fileNames,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prop, paths, i,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington baseConfig, config,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington modules, builtModule, srcPath, buildContext,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington destPath, moduleName, moduleMap, parentModuleMap, context,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington resources, resource, pluginProcessed = {}, plugin;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Can now run the patches to require.js to allow it to be used for
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //build generation. Do it here instead of at the top of the module
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //because we want normal require behavior to load the build tool
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //then want to switch to build mode.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington requirePatch();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config = build.createConfig(cmdConfig);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington paths = config.paths;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.logLevel) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington logger.logLevel(config.logLevel);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!config.out && !config.cssIn) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //This is not just a one-off file build but a full build profile, with
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //lots of files to process.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //First copy all the baseUrl content
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.copyDir((config.appDir || config.baseUrl), config.dir, /\w/, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Adjust baseUrl if config.appDir is in play, and set up build output paths.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildPaths = {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.appDir) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //All the paths should be inside the appDir, so just adjust
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the paths to use the dirBaseUrl
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (prop in paths) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (paths.hasOwnProperty(prop)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildPaths[prop] = paths[prop].replace(config.baseUrl, config.dirBaseUrl);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If no appDir, then make sure to copy the other paths to this directory.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (prop in paths) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (paths.hasOwnProperty(prop)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set up build path for each path prefix.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildPaths[prop] = paths[prop] === 'empty:' ? 'empty:' : prop.replace(/\./g, "/");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make sure source path is fully formed with baseUrl,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //if it is a relative URL.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington srcPath = paths[prop];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (srcPath.indexOf('/') !== 0 && srcPath.indexOf(':') === -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington srcPath = config.baseUrl + srcPath;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington destPath = config.dirBaseUrl + buildPaths[prop];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Skip empty: paths
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (srcPath !== 'empty:') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If the srcPath is a directory, copy the whole directory.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (file.exists(srcPath) && file.isDirectory(srcPath)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Copy files to build area. Copy all files (the /\w/ regexp)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.copyDir(srcPath, destPath, /\w/, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Try a .js extension
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington srcPath += '.js';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington destPath += '.js';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.copyFile(srcPath, destPath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Figure out source file location for each module layer. Do this by seeding require
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //with source area configuration. This is needed so that later the module layers
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //can be manually copied over to the source area, since the build may be
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //require multiple times and the above copyDir call only copies newer files.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require({
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington baseUrl: config.baseUrl,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington paths: paths,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington packagePaths: config.packagePaths,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington packages: config.packages
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildContext = require.s.contexts._;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington modules = config.modules;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (modules) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington modules.forEach(function (module) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (module.name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington module._sourcePath = buildContext.nameToUrl(module.name);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If the module does not exist, and this is not a "new" module layer,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //as indicated by a true "create" property on the module, and
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //it is not a plugin-loaded resource, then throw an error.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!file.exists(module._sourcePath) && !module.create &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington module.name.indexOf('!') === -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw new Error("ERROR: module path does not exist: " +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington module._sourcePath + " for module named: " + module.name +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ". Path is relative to: " + file.absPath('.'));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.out) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Just set up the _buildPath for the module layer.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require(config);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!config.cssIn) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.modules[0]._buildPath = config.out;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (!config.cssIn) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Now set up the config for require to use the build area, and calculate the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //build file locations. Pass along any config info too.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington baseConfig = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington baseUrl: config.dirBaseUrl,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington paths: buildPaths
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lang.mixin(baseConfig, config);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require(baseConfig);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (modules) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington modules.forEach(function (module) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (module.name) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington module._buildPath = buildContext.nameToUrl(module.name, null);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!module.create) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.copyFile(module._sourcePath, module._buildPath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Run CSS optimizations before doing JS module tracing, to allow
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //things like text loader plugins loading CSS to get the optimized
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //CSS.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.optimizeCss && config.optimizeCss !== "none" && config.dir) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington optimize.css(config.dir, config);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (modules) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //For each module layer, call require to calculate dependencies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington modules.forEach(function (module) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington module.layer = build.traceDependencies(module, config);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Now build up shadow layers for anything that should be excluded.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Do this after tracing dependencies for each module, in case one
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //of those modules end up being one of the excluded values.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington modules.forEach(function (module) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (module.exclude) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington module.excludeLayers = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington module.exclude.forEach(function (exclude, i) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //See if it is already in the list of modules.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If not trace dependencies for it.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington module.excludeLayers[i] = build.findBuildModule(exclude, modules) ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington {layer: build.traceDependencies({name: exclude}, config)};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington modules.forEach(function (module) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (module.exclude) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //module.exclude is an array of module names. For each one,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //get the nested dependencies for it via a matching entry
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //in the module.excludeLayers array.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington module.exclude.forEach(function (excludeModule, i) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var excludeLayer = module.excludeLayers[i].layer, map = excludeLayer.buildPathMap, prop;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (prop in map) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (map.hasOwnProperty(prop)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.removeModulePath(prop, map[prop], module.layer);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (module.excludeShallow) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //module.excludeShallow is an array of module names.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //shallow exclusions are just that module itself, and not
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //its nested dependencies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington module.excludeShallow.forEach(function (excludeShallowModule) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var path = module.layer.buildPathMap[excludeShallowModule];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (path) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.removeModulePath(excludeShallowModule, path, module.layer);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Flatten them and collect the build output for each module.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington builtModule = build.flattenModule(module, module.layer, config);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Save it to a temp file for now, in case there are other layers that
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //contain optimized content that should not be included in later
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //layer optimizations. See issue #56.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.saveUtf8File(module._buildPath + '-temp', builtModule.text);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildFileContents += builtModule.buildText;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Now move the build layers to their final position.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington modules.forEach(function (module) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var finalPath = module._buildPath;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (file.exists(finalPath)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.deleteFile(finalPath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.renameFile(finalPath + '-temp', finalPath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Do other optimizations.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.out && !config.cssIn) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Just need to worry about one JS file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileName = config.modules[0]._buildPath;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington optimize.jsFile(fileName, fileName, config);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (!config.cssIn) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Normal optimizations across modules.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //JS optimizations.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileNames = file.getFilteredFileList(config.dir, /\.js$/, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (fileName = fileNames[i]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Generate the module name from the config.dir root.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleName = fileName.replace(config.dir, '');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Get rid of the extension
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleName = moduleName.substring(0, moduleName.length - 3);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington optimize.jsFile(fileName, fileName, config, moduleName, pluginCollector);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Normalize all the plugin resources.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context = require.s.contexts._;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (moduleName in pluginCollector) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (pluginCollector.hasOwnProperty(moduleName)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parentModuleMap = context.makeModuleMap(moduleName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington resources = pluginCollector[moduleName];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (resource = resources[i]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleMap = context.makeModuleMap(resource, parentModuleMap);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!context.plugins[moduleMap.prefix]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set the value in context.plugins so it
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //will be evaluated as a full plugin.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.plugins[moduleMap.prefix] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Do not bother if the plugin is not available.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!file.exists(require.toUrl(moduleMap.prefix + '.js'))) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington continue;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Rely on the require in the build environment
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //to be synchronous
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.require([moduleMap.prefix]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Now that the plugin is loaded, redo the moduleMap
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //since the plugin will need to normalize part of the path.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleMap = context.makeModuleMap(resource, parentModuleMap);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Only bother with plugin resources that can be handled
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //processed by the plugin, via support of the writeFile
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //method.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!pluginProcessed[moduleMap.fullName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Only do the work if the plugin was really loaded.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Using an internal access because the file may
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //not really be loaded.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington plugin = context.defined[moduleMap.prefix];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (plugin && plugin.writeFile) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington plugin.writeFile(
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleMap.prefix,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleMap.name,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington makeWriteFile(
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.anonDefRegExp,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.namespaceWithDot
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context.config
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington );
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pluginProcessed[moduleMap.fullName] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //console.log('PLUGIN COLLECTOR: ' + JSON.stringify(pluginCollector, null, " "));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //All module layers are done, write out the build.txt file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.saveUtf8File(config.dir + "build.txt", buildFileContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If just have one CSS file to optimize, do that here.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.cssIn) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington optimize.cssFile(config.cssIn, config.out, config);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Print out what was built into which layers.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (buildFileContents) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington logger.info(buildFileContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return buildFileContents;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return '';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Converts command line args like "paths.foo=../some/path"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * result.paths = { foo: '../some/path' } where prop = paths,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * name = paths.foo and value = ../some/path, so it assumes the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * name=value splitting has already happened.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function stringDotToObj(result, prop, name, value) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!result[prop]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington result[prop] = {};
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name = name.substring((prop + '.').length, name.length);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington result[prop][name] = value;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Used by convertArrayToObject to convert some things from prop.name=value
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //to a prop: { name: value}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.dotProps = [
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'paths.',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'wrap.',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'pragmas.',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'pragmasOnSave.',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'has.',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'hasOnSave.',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'wrap.',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'uglify.',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'closure.'
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.hasDotPropMatch = function (prop) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return build.dotProps.some(function (dotProp) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return prop.indexOf(dotProp) === 0;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Converts an array that has String members of "name=value"
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * into an object, where the properties on the object are the names in the array.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Also converts the strings "true" and "false" to booleans for the values.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * member name/value pairs, and converts some comma-separated lists into
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * arrays.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Array} ary
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.convertArrayToObject = function (ary) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var result = {}, i, separatorIndex, prop, value,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington needArray = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "include": true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "exclude": true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "excludeShallow": true
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; i < ary.length; i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington separatorIndex = ary[i].indexOf("=");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (separatorIndex === -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw "Malformed name/value pair: [" + ary[i] + "]. Format should be name=value";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington value = ary[i].substring(separatorIndex + 1, ary[i].length);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (value === "true") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington value = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (value === "false") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington value = false;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington prop = ary[i].substring(0, separatorIndex);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Convert to array if necessary
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (needArray[prop]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington value = value.split(",");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (build.hasDotPropMatch(prop)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington stringDotToObj(result, prop.split('.')[0], prop, value);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington result[prop] = value;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return result; //Object
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.makeAbsPath = function (path, absFilePath) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Add abspath if necessary. If path starts with a slash or has a colon,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //then already is an abolute path.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (path.indexOf('/') !== 0 && path.indexOf(':') === -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington path = absFilePath +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (absFilePath.charAt(absFilePath.length - 1) === '/' ? '' : '/') +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington path;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington path = file.normalize(path);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return path.replace(lang.backSlashRegExp, '/');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.makeAbsObject = function (props, obj, absFilePath) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var i, prop;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (obj) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (prop = props[i]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (obj.hasOwnProperty(prop)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington obj[prop] = build.makeAbsPath(obj[prop], absFilePath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * For any path in a possible config, make it absolute relative
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * to the absFilePath passed in.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.makeAbsConfig = function (config, absFilePath) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var props, prop, i;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington props = ["appDir", "dir", "baseUrl"];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (prop = props[i]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config[prop]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Add abspath if necessary, make sure these paths end in
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //slashes
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (prop === "baseUrl") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.originalBaseUrl = config.baseUrl;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.appDir) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If baseUrl with an appDir, the baseUrl is relative to
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the appDir, *not* the absFilePath. appDir and dir are
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //made absolute before baseUrl, so this will work.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.baseUrl = build.makeAbsPath(config.originalBaseUrl, config.appDir);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //The dir output baseUrl is same as regular baseUrl, both
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //relative to the absFilePath.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.baseUrl = build.makeAbsPath(config[prop], absFilePath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config[prop] = build.makeAbsPath(config[prop], absFilePath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config[prop] = endsWithSlash(config[prop]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Do not allow URLs for paths resources.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.paths) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (prop in config.paths) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.paths.hasOwnProperty(prop)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.paths[prop] = build.makeAbsPath(config.paths[prop],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (config.baseUrl || absFilePath));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.makeAbsObject(["out", "cssIn"], config, absFilePath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.makeAbsObject(["startFile", "endFile"], config.wrap, absFilePath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.nestedMix = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington paths: true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington has: true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington hasOnSave: true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pragmas: true,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington pragmasOnSave: true
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Mixes additional source config into target config, and merges some
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * nested config, like paths, correctly.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function mixConfig(target, source) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var prop, value;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (prop in source) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (source.hasOwnProperty(prop)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If the value of the property is a plain object, then
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //allow a one-level-deep mixing of it.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington value = source[prop];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (typeof value === 'object' && value &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington !lang.isArray(value) && !lang.isFunction(value) &&
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington !lang.isRegExp(value)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington target[prop] = lang.mixin({}, target[prop], value, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington target[prop] = value;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Creates a config object for an optimization build.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * It will also read the build profile if it is available, to create
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * the configuration.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} cfg config options that take priority
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * over defaults and ones in the build file. These options could
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * be from a command line, for instance.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} the created config object.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.createConfig = function (cfg) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /*jslint evil: true */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var config = {}, buildFileContents, buildFileConfig, mainConfig,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington mainConfigFile, prop, buildFile, absFilePath;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make sure all paths are relative to current directory.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington absFilePath = file.absPath('.');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.makeAbsConfig(cfg, absFilePath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.makeAbsConfig(buildBaseConfig, absFilePath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lang.mixin(config, buildBaseConfig);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lang.mixin(config, cfg, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.buildFile) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //A build file exists, load it to get more config.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildFile = file.absPath(config.buildFile);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Find the build file, and make sure it exists, if this is a build
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //that has a build profile, and not just command line args with an in=path
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!file.exists(buildFile)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw new Error("ERROR: build file does not exist: " + buildFile);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington absFilePath = config.baseUrl = file.absPath(file.parent(buildFile));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Load build file options.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildFileContents = file.readFile(buildFile);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildFileConfig = eval("(" + buildFileContents + ")");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.makeAbsConfig(buildFileConfig, absFilePath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!buildFileConfig.out && !buildFileConfig.dir) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildFileConfig.dir = (buildFileConfig.baseUrl || config.baseUrl) + "/build/";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (e) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw new Error("Build file " + buildFile + " is malformed: " + e);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington mainConfigFile = config.mainConfigFile || (buildFileConfig && buildFileConfig.mainConfigFile);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (mainConfigFile) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington mainConfigFile = build.makeAbsPath(mainConfigFile, absFilePath);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington mainConfig = parse.findConfig(mainConfigFile, file.readFile(mainConfigFile));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (configError) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw new Error('The config in mainConfigFile ' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington mainConfigFile +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ' cannot be used because it cannot be evaluated' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ' correctly while running in the optimizer. Try only' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ' using a config that is also valid JSON, or do not use' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ' mainConfigFile and instead copy the config values needed' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ' into a build file or command line arguments given to the optimizer.');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (mainConfig) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If no baseUrl, then use the directory holding the main config.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!mainConfig.baseUrl) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington mainConfig.baseUrl = mainConfigFile.substring(0, mainConfigFile.lastIndexOf('/'));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.makeAbsConfig(mainConfig, mainConfigFile);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington mixConfig(config, mainConfig);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Mix in build file config, but only after mainConfig has been mixed in.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (buildFileConfig) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington mixConfig(config, buildFileConfig);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Re-apply the override config values. Command line
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //args should take precedence over build file values.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington mixConfig(config, cfg);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set final output dir
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.hasOwnProperty("baseUrl")) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.appDir) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.dirBaseUrl = build.makeAbsPath(config.originalBaseUrl, config.dir);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.dirBaseUrl = config.dir || config.baseUrl;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make sure dirBaseUrl ends in a slash, since it is
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //concatenated with other strings.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.dirBaseUrl = endsWithSlash(config.dirBaseUrl);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Check for errors in config
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.cssIn && !config.out) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw new Error("ERROR: 'out' option missing.");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!config.cssIn && !config.baseUrl) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw new Error("ERROR: 'baseUrl' option missing.");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!config.out && !config.dir) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw new Error('Missing either an "out" or "dir" config value. ' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'If using "appDir" for a full project optimization, ' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'use "dir". If you want to optimize to one file, ' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'use "out".');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.appDir && config.out) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw new Error('"appDir" is not compatible with "out". Use "dir" ' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'instead. appDir is used to copy whole projects, ' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'where "out" is used to just optimize to one file.');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.out && config.dir) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw new Error('The "out" and "dir" options are incompatible.' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ' Use "out" if you are targeting a single file for' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ' for optimization, and "dir" if you want the appDir' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ' or baseUrl directories optimized.');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if ((config.name || config.include) && !config.modules) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Just need to build one file, but may be part of a whole appDir/
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //baseUrl copy, but specified on the command line, so cannot do
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the modules array setup. So create a modules section in that
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //case.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.modules = [
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington name: config.name,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington out: config.out,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington include: config.include,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington exclude: config.exclude,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington excludeShallow: config.excludeShallow
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.out && !config.cssIn) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Just one file to optimize.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Does not have a build file, so set up some defaults.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Optimizing CSS should not be allowed, unless explicitly
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //asked for on command line. In that case the only task is
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //to optimize a CSS file.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!cfg.optimizeCss) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.optimizeCss = "none";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Do not allow URLs for paths resources.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.paths) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (prop in config.paths) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.paths.hasOwnProperty(prop)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington disallowUrls(config.paths[prop]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Get any wrap text.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington try {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.wrap) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.wrap === true) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Use default values.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.wrap = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington start: '(function () {',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington end: '}());'
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.wrap.start = config.wrap.start ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.readFile(build.makeAbsPath(config.wrap.startFile, absFilePath));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.wrap.end = config.wrap.end ||
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.readFile(build.makeAbsPath(config.wrap.endFile, absFilePath));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } catch (wrapError) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw new Error('Malformed wrap config: need both start/end or ' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'startFile/endFile: ' + wrapError.toString());
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set up proper info for namespaces and using namespaces in transport
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //wrappings.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.namespaceWithDot = config.namespace ? config.namespace + '.' : '';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.anonDefRegExp = build.makeAnonDefRegExp(config.namespaceWithDot);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Do final input verification
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.context) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington throw new Error('The build argument "context" is not supported' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ' in a build. It should only be used in web' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington ' pages.');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set file.fileExclusionRegExp if desired
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if ('fileExclusionRegExp' in config) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (typeof config.fileExclusionRegExp === "string") {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.exclusionRegExp = new RegExp(config.fileExclusionRegExp);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.exclusionRegExp = config.fileExclusionRegExp;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if ('dirExclusionRegExp' in config) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Set file.dirExclusionRegExp if desired, this is the old
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //name for fileExclusionRegExp before 1.0.2. Support for backwards
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //compatibility
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington file.exclusionRegExp = config.dirExclusionRegExp;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return config;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * finds the module being built/optimized with the given moduleName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * or returns null.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} moduleName
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Array} modules
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {Object} the module object from the build profile, or null.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.findBuildModule = function (moduleName, modules) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var i, module;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (module = modules[i]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (module.name === moduleName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return module;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Removes a module name and path from a layer, if it is supposed to be
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * excluded from the layer.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} moduleName the name of the module
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} path the file path for the module
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} layer the layer to remove the module/path from
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.removeModulePath = function (module, path, layer) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var index = layer.buildFilePaths.indexOf(path);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (index !== -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.buildFilePaths.splice(index, 1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Take it out of the specified modules. Specified modules are mostly
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //used to find require modifiers.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington delete layer.specified[module];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Uses the module build config object to trace the dependencies for the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * given module.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} module the module object from the build config info.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} the build config object.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {Object} layer information about what paths and modules should
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * be in the flattened module.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.traceDependencies = function (module, config) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var include, override, layer, context, baseConfig, oldContext;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Reset some state set up in requirePatch.js, and clean up require's
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //current context.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington oldContext = require._buildReset();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Grab the reset layer and context after the reset, but keep the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //old config to reuse in the new context.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington baseConfig = oldContext.config;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer = require._layer;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context = layer.context;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Put back basic config, use a fresh object for it.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //WARNING: probably not robust for paths and packages/packagePaths,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //since those property's objects can be modified. But for basic
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //config clone it works out.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require(lang.delegate(baseConfig));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington logger.trace("\nTracing dependencies for: " + (module.name || module.out));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington include = module.name && !module.create ? [module.name] : [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (module.include) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington include = include.concat(module.include);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If there are overrides to basic config, set that up now.;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (module.override) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington override = lang.delegate(baseConfig);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lang.mixin(override, module.override, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require(override);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Figure out module layer dependencies by calling require to do the work.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require(include);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Pull out the layer dependencies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.specified = context.specified;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Reset config
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (module.override) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington require(baseConfig);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return layer;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Uses the module build config object to create an flattened version
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * of the module, with deep dependencies included.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} module the module object from the build config info.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} layer the layer object returned from build.traceDependencies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {Object} the build config object.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {Object} with two properties: "text", the text of the flattened
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * module, and "buildText", a string of text representing which files were
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * included in the flattened module text.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.flattenModule = function (module, layer, config) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var buildFileContents = "",
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington namespace = config.namespace ? config.namespace + '.' : '',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context = layer.context,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington anonDefRegExp = config.anonDefRegExp,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington path, reqIndex, fileContents, currContents,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington i, moduleName,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parts, builder, writeApi;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Use override settings, particularly for pragmas
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (module.override) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config = lang.delegate(config);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington lang.mixin(config, module.override, true);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Start build output for the module.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildFileContents += "\n" +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (config.dir ? module._buildPath.replace(config.dir, "") : module._buildPath) +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington "\n----------------\n";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If there was an existing file with require in it, hoist to the top.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (layer.existingRequireUrl) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington reqIndex = layer.buildFilePaths.indexOf(layer.existingRequireUrl);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (reqIndex !== -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.buildFilePaths.splice(reqIndex, 1);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.buildFilePaths.unshift(layer.existingRequireUrl);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Write the built module to disk, and build up the build output.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = "";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington for (i = 0; (path = layer.buildFilePaths[i]); i++) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington moduleName = layer.buildFileToModule[path];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Figure out if the module is a result of a build plugin, and if so,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //then delegate to that plugin.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington parts = context.makeModuleMap(moduleName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington builder = parts.prefix && context.defined[parts.prefix];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (builder) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (builder.write) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington writeApi = function (input) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents += "\n" + addSemiColon(input);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.onBuildWrite) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = config.onBuildWrite(moduleName, path, fileContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington writeApi.asModule = function (moduleName, input) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents += "\n" +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington addSemiColon(
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.toTransport(anonDefRegExp, namespace, moduleName, path, input, layer));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.onBuildWrite) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents = config.onBuildWrite(moduleName, path, fileContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington builder.write(parts.prefix, parts.name, writeApi);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington currContents = file.readFile(path);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.onBuildRead) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington currContents = config.onBuildRead(moduleName, path, currContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.namespace) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington currContents = pragma.namespace(currContents, config.namespace);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington currContents = build.toTransport(anonDefRegExp, namespace, moduleName, path, currContents, layer);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (config.onBuildWrite) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington currContents = config.onBuildWrite(moduleName, path, currContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Semicolon is for files that are not well formed when
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //concatenated with other content.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents += "\n" + addSemiColon(currContents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildFileContents += path.replace(config.dir, "") + "\n";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Some files may not have declared a require module, and if so,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //put in a placeholder call so the require does not try to load them
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //after the module is processed.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If we have a name, but no defined module, then add in the placeholder.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (moduleName && !layer.modulesWithNames[moduleName] && !config.skipModuleInsertion) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If including jquery, register the module correctly, otherwise
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //register an empty function. For jquery, make sure jQuery is
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //a real object, and perhaps not some other file mapping, like
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //to zepto.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (moduleName === 'jquery') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents += '\n(function () {\n' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'var jq = typeof jQuery !== "undefined" && jQuery;\n' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington namespace +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'define("jquery", [], function () { return jq; });\n' +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington '}());\n';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents += '\n' + namespace + 'define("' + moduleName + '", function(){});\n';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington text: config.wrap ?
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.wrap.start + fileContents + config.wrap.end :
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington fileContents,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington buildText: buildFileContents
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Creates the regexp to find anonymous defines.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @param {String} namespace an optional namespace to use. The namespace
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * should *include* a trailing dot. So a valid value would be 'foo.'
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @returns {RegExp}
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.makeAnonDefRegExp = function (namespace) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //This regexp is not bullet-proof, and it has one optional part to
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //avoid issues with some Dojo transition modules that use a
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //define(\n//begin v1.x content
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //for a comment.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return new RegExp('(^|[^\\.])(' + (namespace || '').replace(/\./g, '\\.') +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington 'define|define)\\s*\\(\\s*(\\/\\/[^\\n\\r]*[\\r\\n])?(\\[|function|[\\w\\d_\\-\\$]+\\s*\\)|\\{|["\']([^"\']+)["\'])(\\s*,\\s*f)?');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.leadingCommaRegExp = /^\s*,/;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build.toTransport = function (anonDefRegExp, namespace, moduleName, path, contents, layer) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If anonymous module, insert the module name.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return contents.replace(anonDefRegExp, function (match, start, callName, possibleComment, suffix, namedModule, namedFuncStart) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //A named module with either listed dependencies or an object
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //literal for a value. Skip it. If named module, only want ones
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //whose next argument is a function literal to scan for
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //require('') dependecies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (namedModule && !namedFuncStart) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return match;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Only mark this module as having a name if not a named module,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //or if a named module and the name matches expectations.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (layer && (!namedModule || namedModule === moduleName)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington layer.modulesWithNames[moduleName] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var deps = null;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Look for CommonJS require calls inside the function if this is
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //an anonymous define call that just has a function registered.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Also look if a named define function but has a factory function
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //as the second arg that should be scanned for dependencies.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (suffix.indexOf('f') !== -1 || (namedModule)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = parse.getAnonDeps(path, contents);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (deps.length) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = deps.map(function (dep) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return "'" + dep + "'";
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington deps = [];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return start + namespace + "define('" + (namedModule || moduleName) + "'," +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (deps ? ('[' + deps.toString() + '],') : '') +
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (namedModule ? namedFuncStart.replace(build.leadingCommaRegExp, '') : suffix);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return build;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Sets the default baseUrl for requirejs to be directory of top level
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * script.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function setBaseUrl(fileName) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Use the file name's directory as the baseUrl if available.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dir = fileName.replace(/\\/g, '/');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (dir.indexOf('/') !== -1) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dir = dir.split('/');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dir.pop();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington dir = dir.join('/');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington exec("require({baseUrl: '" + dir + "'});");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //If in Node, and included via a require('requirejs'), just export and
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //THROW IT ON THE GROUND!
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (env === 'node' && reqMain !== module) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington setBaseUrl(path.resolve(reqMain ? reqMain.filename : '.'));
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Create a method that will run the optimzer given an object
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //config.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington requirejs.optimize = function (config, callback) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!loadedOptimizedLib) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington loadLib();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington loadedOptimizedLib = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Create the function that will be called once build modules
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //have been loaded.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var runBuild = function (build, logger) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Make sure config has a log level, and if not,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //make it "silent" by default.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.logLevel = config.hasOwnProperty('logLevel') ?
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington config.logLevel : logger.SILENT;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var result = build(config);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Reset build internals on each run.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington requirejs._buildReset();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (callback) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington callback(result);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Enable execution of this callback in a build setting.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Normally, once requirePatch is run, by default it will
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //not execute callbacks, unless this property is set on
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //the callback.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington runBuild.__requireJsBuild = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington requirejs({
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context: 'build'
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }, ['build', 'logger'], runBuild);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington requirejs.tools = {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington useLib: function (contextName, callback) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!callback) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington callback = contextName;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington contextName = 'uselib';
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!useLibLoaded[contextName]) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington loadLib();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington useLibLoaded[contextName] = true;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var req = requirejs({
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context: contextName
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington req(['build'], function () {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington callback(req);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington };
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington requirejs.define = define;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington module.exports = requirejs;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (commandOption === 'o') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Do the optimizer work.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington loadLib();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /**
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Available via the MIT or new BSD license.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * see: http://github.com/jrburke/requirejs for details
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Create a build.js file that has the build options you want and pass that
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * build file to this file to do the build. See example.build.js for more information.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*jslint strict: false, nomen: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington/*global require: false */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonrequire({
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington baseUrl: require.s.contexts._.config.baseUrl,
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Use a separate context than the default context so that the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //build can use the default context.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington context: 'build',
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington catchError: {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington define: true
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington}, ['env!env/args', 'build'],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunningtonfunction (args, build) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington build(args);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington});
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (commandOption === 'v') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington console.log('r.js: ' + version + ', RequireJS: ' + this.requirejsVars.require.version);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else if (commandOption === 'convert') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington loadLib();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington this.requirejsVars.require(['env!env/args', 'commonJs', 'env!env/print'],
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington function (args, commonJs, print) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington var srcDir, outDir;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington srcDir = args[0];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington outDir = args[1];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (!srcDir || !outDir) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington print('Usage: path/to/commonjs/modules output/dir');
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington return;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington commonJs.convertDir(args[0], args[1]);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington });
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Just run an app
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington //Load the bundled libraries for use in the app.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (commandOption === 'lib') {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington loadLib();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington setBaseUrl(fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington if (exists(fileName)) {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington exec(readFile(fileName), fileName);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington } else {
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington showHelp();
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington }
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington}((typeof console !== 'undefined' ? console : undefined),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (typeof Packages !== 'undefined' ? Array.prototype.slice.call(arguments, 0) : []),
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington (typeof readFile !== 'undefined' ? readFile : undefined)));