bin/r.js in requirejs-rails-0.5.1 vs bin/r.js in requirejs-rails-0.5.2

- old
+ new

@@ -1,7 +1,7 @@ /** - * @license r.js 1.0.2+ 20111207 10:15pm Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved. + * @license r.js 1.0.3 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved. * Available via the MIT or new BSD license. * see: http://github.com/jrburke/requirejs for details */ /* @@ -18,11 +18,11 @@ var requirejs, require, define; (function (console, args, readFileFunc) { var fileName, env, fs, vm, path, exec, rhinoContext, dir, nodeRequire, nodeDefine, exists, reqMain, loadedOptimizedLib, - version = '1.0.2+ 20111207 10:15pm', + version = '1.0.3', jsSuffixRegExp = /\.js$/, commandOption = '', //Used by jslib/rhino/args.js rhinoArgs = args, readFile = typeof readFileFunc !== 'undefined' ? readFileFunc : null; @@ -99,11 +99,11 @@ fileName = process.argv[3]; } } /** vim: et:ts=4:sw=4:sts=4 - * @license RequireJS 1.0.2 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved. + * @license RequireJS 1.0.3 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved. * Available via the MIT or new BSD license. * see: http://github.com/jrburke/requirejs for details */ /*jslint strict: false, plusplus: false, sub: true */ /*global window: false, navigator: false, document: false, importScripts: false, @@ -111,11 +111,11 @@ setTimeout: false, opera: false */ (function () { //Change this version number for each release. - var version = "1.0.2", + var version = "1.0.3", commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, cjsRequireRegExp = /require\(\s*["']([^'"\s]+)["']\s*\)/g, currDirRegExp = /^\.\//, jsSuffixRegExp = /\.js$/, ostring = Object.prototype.toString, @@ -1421,15 +1421,10 @@ function () { return jQuery; } : null]); } - //If a global jQuery is defined, check for it. Need to do it here - //instead of main() since stock jQuery does not register as - //a module via define. - jQueryCheck(); - //Doing this scriptCount decrement branching because sync envs //need to decrement after resume, otherwise it looks like //loading is complete after the first dependency is fetched. //For browsers, it works fine to decrement after, but it means //the checkLoaded setTimeout 50 ms cost is taken. To avoid @@ -2039,14 +2034,10 @@ //Any modules included with the require.js file will be in the //global queue, assign them to this context. ctx.takeGlobalQueue(); - //Allow for jQuery to be loaded/already in the page, and if jQuery 1.4.3, - //make sure to hold onto it for readyWait triggering. - ctx.jQueryCheck(); - if (!ctx.scriptCount) { ctx.resume(); } req.checkReadyState(); }, 0); @@ -2373,11 +2364,11 @@ } } function mkDir(dir) { if (!exists(dir)) { - fs.mkdirSync(dir, 0777); + fs.mkdirSync(dir, 511); } } function mkFullDir(dir) { var parts = dir.split('/'), @@ -2535,10 +2526,17 @@ return true; //Boolean }, /** + * Renames a file. May fail if "to" already exists or is on another drive. + */ + renameFile: function (from, to) { + return fs.renameSync(from, to); + }, + + /** * Reads a *text* file. */ readFile: function (/*String*/path, /*String?*/encoding) { if (encoding === 'utf-8') { encoding = 'utf8'; @@ -2770,10 +2768,17 @@ destChannel.close(); return true; //Boolean }, + /** + * Renames a file. May fail if "to" already exists or is on another drive. + */ + renameFile: function (from, to) { + return (new java.io.File(from)).renameTo((new java.io.File(to))); + }, + readFile: function (/*String*/path, /*String?*/encoding) { //A file read function that can deal with BOMs encoding = encoding || "utf-8"; var fileObj = new java.io.File(path), input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(fileObj), encoding)), @@ -3260,13 +3265,13 @@ } }; function JS_Parse_Error(message, line, col, pos) { this.message = message; - this.line = line; - this.col = col; - this.pos = pos; + this.line = line + 1; + this.col = col + 1; + this.pos = pos + 1; this.stack = new Error().stack; }; JS_Parse_Error.prototype.toString = function() { return this.message + " (line: " + this.line + ", col: " + this.col + ", pos: " + this.pos + ")" + "\n\n" + this.stack; @@ -3332,16 +3337,17 @@ function token(type, value, is_comment) { S.regex_allowed = ((type == "operator" && !HOP(UNARY_POSTFIX, value)) || (type == "keyword" && HOP(KEYWORDS_BEFORE_EXPRESSION, value)) || (type == "punc" && HOP(PUNC_BEFORE_EXPRESSION, value))); var ret = { - type : type, - value : value, - line : S.tokline, - col : S.tokcol, - pos : S.tokpos, - nlb : S.newline_before + type : type, + value : value, + line : S.tokline, + col : S.tokcol, + pos : S.tokpos, + endpos : S.pos, + nlb : S.newline_before }; if (!is_comment) { ret.comments_before = S.comments_before; S.comments_before = []; } @@ -3474,12 +3480,11 @@ function read_multiline_comment() { next(); return with_eof_error("Unterminated multiline comment", function(){ var i = find("*/", true), - text = S.text.substring(S.pos, i), - tok = token("comment2", text, true); + text = S.text.substring(S.pos, i); S.pos = i + 2; S.line += text.split("\n").length - 1; S.newline_before = text.indexOf("\n") >= 0; // https://github.com/mishoo/UglifyJS/issues/#issue/100 @@ -3487,11 +3492,11 @@ warn("WARNING: at line " + S.line); warn("*** Found \"conditional comment\": " + text); warn("*** UglifyJS DISCARDS ALL COMMENTS. This means your code might no longer work properly in Internet Explorer."); } - return tok; + return token("comment2", text, true); }); }; function read_name() { var backslash = false, name = "", ch; @@ -3938,11 +3943,11 @@ var obj = expression(); expect(")"); return as("for-in", init, lhs, obj, in_loop(statement)); }; - var function_ = maybe_embed_tokens(function(in_statement) { + var function_ = function(in_statement) { var name = is("name") ? prog1(S.token.value, next) : null; if (in_statement && !name) unexpected(); expect("("); return as(in_statement ? "defun" : "function", @@ -3966,11 +3971,11 @@ var a = block_(); --S.in_function; S.in_loop = loop; return a; })()); - }); + }; function if_() { var cond = parenthesised(), body = statement(), belse; if (is("keyword", "else")) { next(); @@ -4314,11 +4319,11 @@ return str.split(""); }; function member(name, array) { for (var i = array.length; --i >= 0;) - if (array[i] === name) + if (array[i] == name) return true; return false; }; function HOP(obj, prop) { @@ -4375,25 +4380,43 @@ return [ this[0], with_scope(this.scope, curry(MAP, body, walk)) ]; }, "function": _lambda, "defun": _lambda, "new": function(ctor, args) { - if (ctor[0] == "name" && ctor[1] == "Array" && !scope.has("Array")) { - if (args.length != 1) { - return [ "array", args ]; - } else { - return walk([ "call", [ "name", "Array" ], args ]); + if (ctor[0] == "name") { + if (ctor[1] == "Array" && !scope.has("Array")) { + if (args.length != 1) { + return [ "array", args ]; + } else { + return walk([ "call", [ "name", "Array" ], args ]); + } + } else if (ctor[1] == "Object" && !scope.has("Object")) { + if (!args.length) { + return [ "object", [] ]; + } else { + return walk([ "call", [ "name", "Object" ], args ]); + } + } else if ((ctor[1] == "RegExp" || ctor[1] == "Function" || ctor[1] == "Error") && !scope.has(ctor[1])) { + return walk([ "call", [ "name", ctor[1] ], args]); } } }, "call": function(expr, args) { if (expr[0] == "dot" && expr[2] == "toString" && args.length == 0) { // foo.toString() ==> foo+"" return [ "binary", "+", expr[1], [ "string", "" ]]; } - if (expr[0] == "name" && expr[1] == "Array" && args.length != 1 && !scope.has("Array")) { - return [ "array", args ]; + if (expr[0] == "name") { + if (expr[1] == "Array" && args.length != 1 && !scope.has("Array")) { + return [ "array", args ]; + } + if (expr[1] == "Object" && !args.length && !scope.has("Object")) { + return [ "object", [] ]; + } + if (expr[1] == "String" && !scope.has("String")) { + return [ "binary", "+", args[0], [ "string", "" ]]; + } } } }, function() { return walk(pro.ast_add_scope(ast)); }); @@ -4786,10 +4809,11 @@ var w = ast_walker(), walk = w.walk; var having_eval = []; function with_new_scope(cont) { current_scope = new Scope(current_scope); + current_scope.labels = new Scope(); var ret = current_scope.body = cont(); ret.scope = current_scope; current_scope = current_scope.parent; return ret; }; @@ -4818,18 +4842,23 @@ if (d[1]) reference(d[0]); }); }; }; + function _breacont(label) { + if (label) + current_scope.labels.refs[label] = true; + }; + return with_new_scope(function(){ // process AST var ret = w.with_walkers({ "function": _lambda, "defun": _lambda, - "label": function(name, stat) { define(name, "label") }, - "break": function(label) { if (label) reference(label) }, - "continue": function(label) { if (label) reference(label) }, + "label": function(name, stat) { current_scope.labels.define(name) }, + "break": _breacont, + "continue": _breacont, "with": function(expr, block) { for (var s = current_scope; s; s = s.parent) s.uses_with = true; }, "var": _vardefs("var"), @@ -4911,19 +4940,22 @@ return null; } }; function _lambda(name, args, body) { - var is_defun = this[0] == "defun", extra; - if (name) { - if (is_defun) name = get_mangled(name); - else { - extra = {}; - if (!(scope.uses_eval || scope.uses_with)) - name = extra[name] = scope.next_mangled(); - else - extra[name] = name; + if (!options.no_functions) { + var is_defun = this[0] == "defun", extra; + if (name) { + if (is_defun) name = get_mangled(name); + else if (body.scope.references(name)) { + extra = {}; + if (!(scope.uses_eval || scope.uses_with)) + name = extra[name] = scope.next_mangled(); + else + extra[name] = name; + } + else name = null; } } body = with_scope(body.scope, function(){ args = MAP(args, function(name){ return get_mangled(name) }); return MAP(body, walk); @@ -4950,10 +4982,14 @@ return [ this[0], MAP(defs, function(d){ return [ get_mangled(d[0]), walk(d[1]) ]; }) ]; }; + function _breacont(label) { + if (label) return [ this[0], scope.labels.get_mangled(label) ]; + }; + return w.with_walkers({ "function": _lambda, "defun": function() { // move function declarations to the top when // they are not in some block. @@ -4964,13 +5000,20 @@ case "defun": return MAP.at_top(ast); } return ast; }, - "label": function(label, stat) { return [ this[0], get_mangled(label), walk(stat) ] }, - "break": function(label) { if (label) return [ this[0], get_mangled(label) ] }, - "continue": function(label) { if (label) return [ this[0], get_mangled(label) ] }, + "label": function(label, stat) { + if (scope.labels.refs[label]) return [ + this[0], + scope.labels.get_mangled(label, true), + walk(stat) + ]; + return walk(stat); + }, + "break": _breacont, + "continue": _breacont, "var": _vardefs, "const": _vardefs, "name": function(name) { return get_define(name) || [ this[0], get_mangled(name) ]; }, @@ -5380,11 +5423,11 @@ dead_code : true, no_warnings : false, keep_comps : true }); - var w = ast_walker(), walk = w.walk, scope; + var w = ast_walker(), walk = w.walk; function negate(c) { var not_c = [ "unary-prefix", "!", c ]; switch (c[0]) { case "unary-prefix": @@ -5432,19 +5475,10 @@ warn_unreachable(val ? e : t); return (val ? t : e); }, make_real_conditional); }; - function with_scope(s, cont) { - var _scope = scope; - scope = s; - var ret = cont(); - ret.scope = s; - scope = _scope; - return ret; - }; - function rmblock(block) { if (block != null && block[0] == "block" && block[1]) { if (block[1].length == 1) block = block[1][0]; else if (block[1].length == 0) @@ -5452,18 +5486,11 @@ } return block; }; function _lambda(name, args, body) { - var is_defun = this[0] == "defun"; - body = with_scope(body.scope, function(){ - var ret = tighten(body, "lambda"); - if (!is_defun && name && !scope.references(name)) - name = null; - return ret; - }); - return [ this[0], name, args, body ]; + return [ this[0], name, args, tighten(body, "lambda") ]; }; // this function does a few things: // 1. discard useless blocks // 2. join consecutive var declarations @@ -5673,13 +5700,11 @@ return [ "sub", walk(expr), [ "num", parseInt(name, 10) ] ]; } }, "if": make_if, "toplevel": function(body) { - return [ "toplevel", with_scope(this.scope, function(){ - return tighten(body); - }) ]; + return [ "toplevel", tighten(body) ]; }, "switch": function(expr, body) { var last = body.length - 1; return [ "switch", walk(expr), MAP(body, function(branch, i){ var block = tighten(branch[1]); @@ -5750,11 +5775,10 @@ return [ this[0], op, lvalue, rvalue ]; } }, function() { for (var i = 0; i < 2; ++i) { ast = prepare_ifs(ast); - ast = ast_add_scope(ast); ast = walk(ast); } return ast; }); }; @@ -5822,11 +5846,11 @@ space = beautify ? " " : ""; function encode_string(str) { var ret = make_string(str, options.ascii_only); if (options.inline_script) - ret = ret.replace(/<\x2fscript([>/\t\n\f\r ])/gi, "<\\/script$1"); + ret = ret.replace(/<\x2fscript([>\/\t\n\f\r ])/gi, "<\\/script$1"); return ret; }; function make_name(name) { name = name.toString(); @@ -6403,12 +6427,11 @@ exports.MAP = MAP; // keep this last! exports.ast_squeeze_more = require("./squeeze-more").ast_squeeze_more; -}); -define('uglifyjs/index', ["require", "exports", "module", "./parse-js", "./process"], function(require, exports, module) { +});define('uglifyjs/index', ["require", "exports", "module", "./parse-js", "./process"], function(require, exports, module) { //convienence function(src, [options]); function uglify(orig_code, options){ options || (options = {}); var jsp = uglify.parser; @@ -6646,10 +6669,19 @@ if (moduleDeps.length || moduleList.length) { for (i = 0; (moduleCall = moduleList[i]); i++) { if (result) { result += '\n'; } + + //If this is the main module for this file, combine any + //"anonymous" dependencies (could come from a nested require + //call) with this module. + if (moduleCall.name === moduleName) { + moduleCall.deps = moduleCall.deps.concat(moduleDeps); + moduleDeps = []; + } + depString = moduleCall.deps.length ? '["' + moduleCall.deps.join('","') + '"]' : '[]'; result += 'define("' + moduleCall.name + '",' + depString + ');'; } if (moduleDeps.length) { if (result) { @@ -7045,30 +7077,35 @@ nsRegExp: /(^|[^\.])(requirejs|require|define)\s*\(/, nsWrapRegExp: /\/\*requirejs namespace: true \*\//, apiDefRegExp: /var requirejs, require, define;/, defineCheckRegExp: /typeof\s+define\s*===\s*["']function["']\s*&&\s*define\s*\.\s*amd/g, defineJQueryRegExp: /typeof\s+define\s*===\s*["']function["']\s*&&\s*define\s*\.\s*amd\s*&&\s*define\s*\.\s*amd\s*\.\s*jQuery/g, + defineHasRegExp: /typeof\s+define\s*==(=)?\s*['"]function['"]\s*&&\s*typeof\s+define\.amd\s*==(=)?\s*['"]object['"]\s*&&\s*define\.amd/g, defineTernaryRegExp: /typeof\s+define\s*===\s*['"]function["']\s*&&\s*define\s*\.\s*amd\s*\?\s*define/, + amdefineRegExp: /if\s*\(\s*typeof define\s*\!==\s*'function'\s*\)\s*\{\s*[^\{\}]+amdefine[^\{\}]+\}/g, removeStrict: function (contents, config) { return config.useStrict ? contents : contents.replace(pragma.useStrictRegExp, ''); }, namespace: function (fileContents, ns, onLifecycleName) { if (ns) { //Namespace require/define calls fileContents = fileContents.replace(pragma.nsRegExp, '$1' + ns + '.$2('); - //Namespace define ternary use: fileContents = fileContents.replace(pragma.defineTernaryRegExp, "typeof " + ns + ".define === 'function' && " + ns + ".define.amd ? " + ns + ".define"); //Namespace define jquery use: fileContents = fileContents.replace(pragma.defineJQueryRegExp, - "typeof " + ns + ".define === 'function' && " + ns + ".define.amd && " + ns + ".define.jQuery"); + "typeof " + ns + ".define === 'function' && " + ns + ".define.amd && " + ns + ".define.amd.jQuery"); + //Namespace has.js define use: + fileContents = fileContents.replace(pragma.defineHasRegExp, + "typeof " + ns + ".define === 'function' && typeof " + ns + ".define.amd === 'object' && " + ns + ".define.amd"); + //Namespace define checks. //Do this one last, since it is a subset of the more specific //checks above. fileContents = fileContents.replace(pragma.defineCheckRegExp, "typeof " + ns + ".define === 'function' && " + ns + ".define.amd"); @@ -7236,10 +7273,13 @@ logger.error('Parse error looking for plugin resources in ' + fileName + ', skipping.'); } } + //Strip amdefine use for node-shared modules. + fileContents = fileContents.replace(pragma.amdefineRegExp, ''); + //Do namespacing if (onLifecycleName === 'OnSave' && config.namespace) { fileContents = pragma.namespace(fileContents, config.namespace, onLifecycleName); } @@ -7531,18 +7571,20 @@ throw new Error('optimizer with name of "' + optimizerName + '" not found for this environment'); } - //Pull out any license comments for prepending after optimization. - optimize.licenseCommentRegExp.lastIndex = 0; - while ((match = optimize.licenseCommentRegExp.exec(fileContents))) { - comment = match[0]; - //Only keep the comments if they are license comments. - if (comment.indexOf('@license') !== -1 || - comment.indexOf('/*!') === 0) { - licenseContents += comment + '\n'; + if (config.preserveLicenseComments) { + //Pull out any license comments for prepending after optimization. + optimize.licenseCommentRegExp.lastIndex = 0; + while ((match = optimize.licenseCommentRegExp.exec(fileContents))) { + comment = match[0]; + //Only keep the comments if they are license comments. + if (comment.indexOf('@license') !== -1 || + comment.indexOf('/*!') === 0) { + licenseContents += comment + '\n'; + } } } fileContents = licenseContents + optFunc(fileName, fileContents, keepLines, config[optimizerName]); @@ -7618,23 +7660,22 @@ optimizers: { uglify: function (fileName, fileContents, keepLines, config) { var parser = uglify.parser, processor = uglify.uglify, - ast, genCodeConfig; + ast; config = config || {}; - genCodeConfig = config.gen_codeOptions || keepLines; logger.trace("Uglifying file: " + fileName); try { - ast = parser.parse(fileContents, config.strict_semicolons); - ast = processor.ast_mangle(ast, config.do_toplevel); - ast = processor.ast_squeeze(ast, config.ast_squeezeOptions); + ast = parser.parse(fileContents, config); + ast = processor.ast_mangle(ast, config); + ast = processor.ast_squeeze(ast, config); - fileContents = processor.gen_code(ast, genCodeConfig); + fileContents = processor.gen_code(ast, config); } catch (e) { logger.error('Cannot uglify file: ' + fileName + '. Skipping it. Error is:\n' + e.toString()); } return fileContents; } @@ -8105,10 +8146,11 @@ optimizeCss: "standard.keepLines", inlineText: true, isBuild: true, optimizeAllPluginResources: false, findNestedDependencies: false, + preserveLicenseComments: true, //By default, all files/directories are copied, unless //they match this regexp, by default just excludes .folders dirExclusionRegExp: file.dirExclusionRegExp }; @@ -8391,13 +8433,26 @@ }); } //Flatten them and collect the build output for each module. builtModule = build.flattenModule(module, module.layer, config); - file.saveUtf8File(module._buildPath, builtModule.text); + + //Save it to a temp file for now, in case there are other layers that + //contain optimized content that should not be included in later + //layer optimizations. See issue #56. + file.saveUtf8File(module._buildPath + '-temp', builtModule.text); buildFileContents += builtModule.buildText; }); + + //Now move the build layers to their final position. + modules.forEach(function (module) { + var finalPath = module._buildPath; + if (file.exists(finalPath)) { + file.deleteFile(finalPath); + } + file.renameFile(finalPath + '-temp', finalPath); + }); } //Do other optimizations. if (config.out && !config.cssIn) { //Just need to worry about one JS file. @@ -8505,10 +8560,30 @@ } name = name.substring((prop + '.').length, name.length); result[prop][name] = value; } + //Used by convertArrayToObject to convert some things from prop.name=value + //to a prop: { name: value} + build.dotProps = [ + 'paths.', + 'wrap.', + 'pragmas.', + 'pragmasOnSave.', + 'has.', + 'hasOnSave.', + 'wrap.', + 'uglify.', + 'closure.' + ]; + + build.hasDotPropMatch = function (prop) { + return build.dotProps.some(function (dotProp) { + return prop.indexOf(dotProp) === 0; + }); + }; + /** * Converts an array that has String members of "name=value" * into an object, where the properties on the object are the names in the array. * Also converts the strings "true" and "false" to booleans for the values. * member name/value pairs, and converts some comma-separated lists into @@ -8541,11 +8616,11 @@ //Convert to array if necessary if (needArray[prop]) { value = value.split(","); } - if (prop.indexOf("paths.") === 0 || prop.indexOf("wrap.") === 0) { + if (build.hasDotPropMatch(prop)) { stringDotToObj(result, prop.split('.')[0], prop, value); } else { result[prop] = value; } } @@ -8734,13 +8809,13 @@ } //Set file.fileExclusionRegExp if desired if ('fileExclusionRegExp' in config) { if (typeof config.fileExclusionRegExp === "string") { - file.exclusionRegExp = new RegExp(config.fileExclusionRegExp); + file.exclusionRegExp = new RegExp(config.fileExclusionRegExp); } else { - file.exclusionRegExp = config.fileExclusionRegExp; + file.exclusionRegExp = config.fileExclusionRegExp; } } else if ('dirExclusionRegExp' in config) { //Set file.dirExclusionRegExp if desired, this is the old //name for fileExclusionRegExp before 1.0.2. Support for backwards //compatibility @@ -8976,11 +9051,13 @@ //require('') dependecies. if (namedModule && !namedFuncStart) { return match; } - if (layer) { + //Only mark this module as having a name if not a named module, + //or if a named module and the name matches expectations. + if (layer && (!namedModule || namedModule === moduleName)) { layer.modulesWithNames[moduleName] = true; } var deps = null; @@ -8998,10 +9075,10 @@ } else { deps = []; } } - return start + namespace + "define('" + moduleName + "'," + + return start + namespace + "define('" + (namedModule || moduleName) + "'," + (deps ? ('[' + deps.toString() + '],') : '') + (namedModule ? namedFuncStart.replace(build.leadingCommaRegExp, '') : suffix); }); };