"use strict";
- // Integrate build task
- require( "./build/build" )( grunt );
-
- var distpaths = [
- "dist/jquery.js",
- "dist/jquery.min.map",
- "dist/jquery.min.js"
- ],
- gzip = require("gzip-js"),
+ var gzip = require( "gzip-js" ),
readOptionalJSON = function( filepath ) {
var data = {};
try {
} catch(e) {}
return data;
},
- fs = require( "fs" ),
srcHintOptions = readOptionalJSON( "src/.jshintrc" );
// The concatenated file won't pass onevar
options: srcHintOptions
},
grunt: {
- src: [ "Gruntfile.js", "build/build.js" ],
+ src: [ "Gruntfile.js", "build/tasks/*" ],
options: {
jshintrc: ".jshintrc"
}
}
});
- grunt.registerTask( "testswarm", function( commit, configFile ) {
- var jobName,
- testswarm = require( "testswarm" ),
- runs = {},
- done = this.async(),
- pull = /PR-(\d+)/.exec( commit ),
- config = grunt.file.readJSON( configFile ).jquery,
- tests = grunt.config([ this.name, "tests" ]);
-
- if ( pull ) {
- jobName = "jQuery pull <a href='https://github.com/jquery/jquery/pull/" +
- pull[ 1 ] + "'>#" + pull[ 1 ] + "</a>";
- } else {
- jobName = "jQuery commit #<a href='https://github.com/jquery/jquery/commit/" +
- commit + "'>" + commit.substr( 0, 10 ) + "</a>";
- }
-
- tests.forEach(function( test ) {
- runs[test] = config.testUrl + commit + "/test/index.html?module=" + test;
- });
-
- testswarm.createClient( {
- url: config.swarmUrl,
- pollInterval: 10000,
- timeout: 1000 * 60 * 30
- } )
- .addReporter( testswarm.reporters.cli )
- .auth( {
- id: config.authUsername,
- token: config.authToken
- })
- .addjob(
- {
- name: jobName,
- runs: runs,
- runMax: config.runMax,
- browserSets: config.browserSets
- }, function( err, passed ) {
- if ( err ) {
- grunt.log.error( err );
- }
- done( passed );
- }
- );
- });
-
- // Process files for distribution
- grunt.registerTask( "dist", function() {
- var stored, flags, paths, nonascii;
-
- // Check for stored destination paths
- // ( set in dist/.destination.json )
- stored = Object.keys( grunt.config( "dst" ) );
-
- // Allow command line input as well
- flags = Object.keys( this.flags );
-
- // Combine all output target paths
- paths = [].concat( stored, flags ).filter(function( path ) {
- return path !== "*";
- });
-
- // Ensure the dist files are pure ASCII
- nonascii = false;
-
- distpaths.forEach(function( filename ) {
- var i, c,
- text = fs.readFileSync( filename, "utf8" );
-
- // Ensure files use only \n for line endings, not \r\n
- if ( /\x0d\x0a/.test( text ) ) {
- grunt.log.writeln( filename + ": Incorrect line endings (\\r\\n)" );
- nonascii = true;
- }
-
- // Ensure only ASCII chars so script tags don't need a charset attribute
- if ( text.length !== Buffer.byteLength( text, "utf8" ) ) {
- grunt.log.writeln( filename + ": Non-ASCII characters detected:" );
- for ( i = 0; i < text.length; i++ ) {
- c = text.charCodeAt( i );
- if ( c > 127 ) {
- grunt.log.writeln( "- position " + i + ": " + c );
- grunt.log.writeln( "-- " + text.substring( i - 20, i + 20 ) );
- break;
- }
- }
- nonascii = true;
- }
-
- // Modify map/min so that it points to files in the same folder;
- // see https://github.com/mishoo/UglifyJS2/issues/47
- if ( /\.map$/.test( filename ) ) {
- text = text.replace( /"dist\//g, "\"" );
- fs.writeFileSync( filename, text, "utf-8" );
-
- // Use our hard-coded sourceMap directive instead of the autogenerated one (#13274; #13776)
- } else if ( /\.min\.js$/.test( filename ) ) {
- i = 0;
- text = text.replace( /(?:\/\*|)\n?\/\/@\s*sourceMappingURL=.*(\n\*\/|)/g,
- function( match ) {
- if ( i++ ) {
- return "";
- }
- return match;
- });
- fs.writeFileSync( filename, text, "utf-8" );
- }
-
- // Optionally copy dist files to other locations
- paths.forEach(function( path ) {
- var created;
-
- if ( !/\/$/.test( path ) ) {
- path += "/";
- }
-
- created = path + filename.replace( "dist/", "" );
- grunt.file.write( created, text );
- grunt.log.writeln( "File '" + created + "' created." );
- });
- });
-
- return !nonascii;
- });
-
- // Work around grunt-contrib-uglify sourceMap issues (jQuery #13776)
- grunt.registerMultiTask( "pre-uglify", function() {
- var banner = this.options().banner;
-
- this.files.forEach(function( mapping ) {
- // Join src
- var input = mapping.src.map(function( file ) {
- var contents = grunt.file.read( file );
-
- // Strip banners
- return contents
- // Remove the main jQuery banner, it'll be replaced by the new banner anyway.
- .replace( /^\/\*![\W\w]*?\*\/\n?/g, "" )
- // Strip other banners preserving line count.
- .replace( /^\/\*!(?:.|\n)*?\*\/\n?/gm, function ( match ) {
- return match.replace( /[^\n]/gm, "" );
- });
- }).join("\n");
-
- // Write temp file (with optional banner)
- grunt.file.write( mapping.dest, ( banner || "" ) + input );
- });
- });
-
- // Change the map file to point back to jquery.js instead of jquery.pre-min.js.
- // The problem is caused by the pre-uglify task.
- // Also, remove temporary files.
- grunt.registerMultiTask( "post-uglify", function() {
- this.files.forEach(function( mapping ) {
- var mapFileName = mapping.src[ 0 ];
-
- // Rename the file to a temporary name.
- fs.renameSync( mapFileName, mapping.dest);
- grunt.file.write( mapFileName, grunt.file.read( mapping.dest )
- // The uglify task erroneously prepends dist/ to file names.
- .replace( /"dist\//g, "\"" )
- // Refer to the source jquery.js, not the temporary jquery.pre-min.js.
- .replace( /\.pre-min\./g, "." )
- // There's already a pragma at the beginning of the file, remove the one at the end.
- .replace( /\/\/@ sourceMappingURL=jquery\.min\.map$/g, "" ));
- });
-
- // Remove temporary files.
- this.options().tempFiles.forEach(function( fileName ) {
- fs.unlink( fileName );
- });
- });
-
// Load grunt tasks from NPM packages
- grunt.loadNpmTasks("grunt-compare-size");
- grunt.loadNpmTasks("grunt-git-authors");
- grunt.loadNpmTasks("grunt-contrib-watch");
- grunt.loadNpmTasks("grunt-contrib-jshint");
- grunt.loadNpmTasks("grunt-contrib-uglify");
- grunt.loadNpmTasks("grunt-jsonlint");
+ grunt.loadNpmTasks( "grunt-compare-size" );
+ grunt.loadNpmTasks( "grunt-git-authors" );
+ grunt.loadNpmTasks( "grunt-contrib-watch" );
+ grunt.loadNpmTasks( "grunt-contrib-jshint" );
+ grunt.loadNpmTasks( "grunt-contrib-uglify" );
+ grunt.loadNpmTasks( "grunt-jsonlint" );
+
+ // Integrate jQuery specific tasks
+ grunt.loadTasks( "build/tasks" );
// Short list as a high frequency watch task
grunt.registerTask( "dev", [ "build:*:*", "jshint" ] );
+++ /dev/null
-/**
- * Special concat/build task to handle various jQuery build requirements
- * Concats AMD modules, removes their definitions, and includes/excludes specified modules
- */
-
-module.exports = function( grunt ) {
-
- var fs = require("fs"),
- srcFolder = __dirname + "/../src/",
- rdefineEnd = /\}\);[^}\w]*$/,
- // This is temporary until the skipSemiColonInsertion option makes it to NPM
- requirejs = require("./r"),
- config = {
- baseUrl: "src",
- name: "jquery",
- out: "dist/jquery.js",
- // We have multiple minify steps
- optimize: "none",
- skipSemiColonInsertion: true,
- wrap: {
- startFile: "src/intro.js",
- endFile: "src/outro.js"
- },
- onBuildWrite: convert
- };
-
- /**
- * Strip all definitions generated by requirejs
- * Convert "var" modules to var declarations
- * "var module" means the module only contains a return statement that should be converted to a var declaration
- * This is indicated by including the file in any "var" folder
- * @param {String} name
- * @param {String} path
- * @param {String} contents The contents to be written (including their AMD wrappers)
- */
- function convert( name, path, contents ) {
- // Convert var modules
- if ( /.\/var\//.test( path ) ) {
- contents = contents
- .replace( /define\([\w\W]*?return/, "var " + (/var\/([\w-]+)/.exec(name)[1]) + " =" )
- .replace( rdefineEnd, "" );
-
- // Sizzle treatment
- } else if ( /\/sizzle$/.test( name ) ) {
- contents = "var Sizzle =\n" + contents
- // Remove EXPOSE lines from Sizzle
- .replace( /\/\/\s*EXPOSE[\w\W]*\/\/\s*EXPOSE/, "return Sizzle;" );
-
- } else {
-
- // Ignore jQuery's return statement (the only necessary one)
- if ( name !== "jquery" ) {
- contents = contents
- .replace( /return\s+[^\}]+(\}\);[^\w\}]*)$/, "$1" );
- }
-
- // Remove define wrappers, closure ends, and empty declarations
- contents = contents
- .replace( /define\([^{]*?{/, "" )
- .replace( rdefineEnd, "" )
- // Remove empty definitions
- .replace( /define\(\[[^\]]+\]\)[\W\n]+$/, "" );
- }
- return contents;
- }
-
- grunt.registerMultiTask(
- "build",
- "Concatenate source, remove sub AMD definitions, (include/exclude modules with +/- flags), embed date/version",
- function() {
- var flag,
- done = this.async(),
- flags = this.flags,
- name = this.data.dest,
- minimum = this.data.minimum,
- removeWith = this.data.removeWith,
- excluded = [],
- included = [],
- version = grunt.config( "pkg.version" ),
- /**
- * Recursively calls the excluder to remove on all modules in the list
- * @param {Array} list
- * @param {String} [prepend] Prepend this to the module name. Indicates we're walking a directory
- */
- excludeList = function( list, prepend ) {
- if ( list ) {
- prepend = prepend ? prepend + "/" : "";
- list.forEach(function( module ) {
- // Exclude var modules as well
- if ( module === "var" ) {
- excludeList( fs.readdirSync( srcFolder + prepend + module ), prepend + module );
- return;
- }
- if ( prepend ) {
- // Skip if this is not a js file and we're walking files in a dir
- if ( !(module = /([\w-\/]+)\.js$/.exec( module )) ) {
- return;
- }
- // Prepend folder name if passed
- // Remove .js extension
- module = prepend + module[1];
- }
-
- // Avoid infinite recursion
- if ( excluded.indexOf( module ) === -1 ) {
- excluder( "-" + module );
- }
- });
- }
- },
- /**
- * Adds the specified module to the excluded or included list, depending on the flag
- * @param {String} flag A module path relative to the src directory starting with + or - to indicate whether it should included or excluded
- */
- excluder = function( flag ) {
- var m = /^(\+|\-|)([\w\/-]+)$/.exec( flag ),
- exclude = m[1] === "-",
- module = m[2];
-
- if ( exclude ) {
- // Can't exclude certain modules
- if ( minimum.indexOf( module ) === -1 ) {
- // Add to excluded
- if ( excluded.indexOf( module ) === -1 ) {
- grunt.log.writeln( flag );
- excluded.push( module );
- // Exclude all files in the folder of the same name
- // These are the removable dependencies
- // It's fine if the directory is not there
- try {
- excludeList( fs.readdirSync( srcFolder + module ), module );
- } catch( e ) {
- grunt.verbose.writeln( e );
- }
- }
- // Check removeWith list
- excludeList( removeWith[ module ] );
- } else {
- grunt.log.error( "Module \"" + module + "\" is a mimimum requirement.");
- }
- } else {
- grunt.log.writeln( flag );
- included.push( module );
- }
- };
-
- // append commit id to version
- if ( process.env.COMMIT ) {
- version += " " + process.env.COMMIT;
- }
-
- // figure out which files to exclude based on these rules in this order:
- // dependency explicit exclude
- // > explicit exclude
- // > explicit include
- // > dependency implicit exclude
- // > implicit exclude
- // examples:
- // * none (implicit exclude)
- // *:* all (implicit include)
- // *:*:-css all except css and dependents (explicit > implicit)
- // *:*:-css:+effects same (excludes effects because explicit include is trumped by explicit exclude of dependency)
- // *:+effects none except effects and its dependencies (explicit include trumps implicit exclude of dependency)
- for ( flag in flags ) {
- if ( flag !== "*" ) {
- excluder( flag );
- }
- }
-
- grunt.verbose.writeflags( excluded, "Excluded" );
- grunt.verbose.writeflags( included, "Included" );
-
- // append excluded modules to version
- if ( excluded.length ) {
- version += " -" + excluded.join( ",-" );
- // set pkg.version to version with excludes, so minified file picks it up
- grunt.config.set( "pkg.version", version );
- grunt.verbose.writeln( "Version changed to " + version );
- // Have to use shallow or core will get excluded since it is a dependency
- config.excludeShallow = excluded;
- }
- config.include = included;
-
- /**
- * Handle Final output from the optimizer
- * @param {String} compiled
- */
- config.out = function( compiled ) {
- compiled = compiled
- // Embed Version
- .replace( /@VERSION/g, version )
- // Embed Date
- // yyyy-mm-ddThh:mmZ
- .replace( /@DATE/g, ( new Date() ).toISOString().replace( /:\d+\.\d+Z$/, "Z" ) );
-
- // Write concatenated source to file
- grunt.file.write( name, compiled );
- };
-
- // Trace dependencies and concatenate files
- requirejs.optimize( config, function( response ) {
- grunt.verbose.writeln( response );
- grunt.log.ok( "File '" + name + "' created." );
- done();
- }, function( err ) {
- done( err );
- });
- });
-
- // Special "alias" task to make custom build creation less grawlix-y
- // Translation example
- //
- // grunt custom:+ajax,-dimensions,-effects,-offset
- //
- // Becomes:
- //
- // grunt build:*:*:+ajax:-dimensions:-effects:-offset
- grunt.registerTask( "custom", function() {
- var args = [].slice.call(arguments),
- modules = args.length ? args[0].replace(/,/g, ":") : "";
-
- grunt.log.writeln( "Creating custom build...\n" );
-
- grunt.task.run([ "build:*:*:" + modules, "pre-uglify", "uglify", "dist" ]);
- });
-};
--- /dev/null
+/**
+ * Special concat/build task to handle various jQuery build requirements
+ * Concats AMD modules, removes their definitions, and includes/excludes specified modules
+ */
+
+module.exports = function( grunt ) {
+
+ "use strict";
+
+ var fs = require( "fs" ),
+ srcFolder = __dirname + "/../src/",
+ rdefineEnd = /\}\);[^}\w]*$/,
+ // This is temporary until the skipSemiColonInsertion option makes it to NPM
+ requirejs = require( "../r" ),
+ config = {
+ baseUrl: "src",
+ name: "jquery",
+ out: "dist/jquery.js",
+ // We have multiple minify steps
+ optimize: "none",
+ skipSemiColonInsertion: true,
+ wrap: {
+ startFile: "src/intro.js",
+ endFile: "src/outro.js"
+ },
+ onBuildWrite: convert
+ };
+
+ /**
+ * Strip all definitions generated by requirejs
+ * Convert "var" modules to var declarations
+ * "var module" means the module only contains a return statement that should be converted to a var declaration
+ * This is indicated by including the file in any "var" folder
+ * @param {String} name
+ * @param {String} path
+ * @param {String} contents The contents to be written (including their AMD wrappers)
+ */
+ function convert( name, path, contents ) {
+ // Convert var modules
+ if ( /.\/var\//.test( path ) ) {
+ contents = contents
+ .replace( /define\([\w\W]*?return/, "var " + (/var\/([\w-]+)/.exec(name)[1]) + " =" )
+ .replace( rdefineEnd, "" );
+
+ // Sizzle treatment
+ } else if ( /\/sizzle$/.test( name ) ) {
+ contents = "var Sizzle =\n" + contents
+ // Remove EXPOSE lines from Sizzle
+ .replace( /\/\/\s*EXPOSE[\w\W]*\/\/\s*EXPOSE/, "return Sizzle;" );
+
+ } else {
+
+ // Ignore jQuery's return statement (the only necessary one)
+ if ( name !== "jquery" ) {
+ contents = contents
+ .replace( /return\s+[^\}]+(\}\);[^\w\}]*)$/, "$1" );
+ }
+
+ // Remove define wrappers, closure ends, and empty declarations
+ contents = contents
+ .replace( /define\([^{]*?{/, "" )
+ .replace( rdefineEnd, "" )
+ // Remove empty definitions
+ .replace( /define\(\[[^\]]+\]\)[\W\n]+$/, "" );
+ }
+ return contents;
+ }
+
+ grunt.registerMultiTask(
+ "build",
+ "Concatenate source, remove sub AMD definitions, (include/exclude modules with +/- flags), embed date/version",
+ function() {
+ var flag,
+ done = this.async(),
+ flags = this.flags,
+ name = this.data.dest,
+ minimum = this.data.minimum,
+ removeWith = this.data.removeWith,
+ excluded = [],
+ included = [],
+ version = grunt.config( "pkg.version" ),
+ /**
+ * Recursively calls the excluder to remove on all modules in the list
+ * @param {Array} list
+ * @param {String} [prepend] Prepend this to the module name. Indicates we're walking a directory
+ */
+ excludeList = function( list, prepend ) {
+ if ( list ) {
+ prepend = prepend ? prepend + "/" : "";
+ list.forEach(function( module ) {
+ // Exclude var modules as well
+ if ( module === "var" ) {
+ excludeList( fs.readdirSync( srcFolder + prepend + module ), prepend + module );
+ return;
+ }
+ if ( prepend ) {
+ // Skip if this is not a js file and we're walking files in a dir
+ if ( !(module = /([\w-\/]+)\.js$/.exec( module )) ) {
+ return;
+ }
+ // Prepend folder name if passed
+ // Remove .js extension
+ module = prepend + module[1];
+ }
+
+ // Avoid infinite recursion
+ if ( excluded.indexOf( module ) === -1 ) {
+ excluder( "-" + module );
+ }
+ });
+ }
+ },
+ /**
+ * Adds the specified module to the excluded or included list, depending on the flag
+ * @param {String} flag A module path relative to the src directory starting with + or - to indicate whether it should included or excluded
+ */
+ excluder = function( flag ) {
+ var m = /^(\+|\-|)([\w\/-]+)$/.exec( flag ),
+ exclude = m[ 1 ] === "-",
+ module = m[ 2 ];
+
+ if ( exclude ) {
+ // Can't exclude certain modules
+ if ( minimum.indexOf( module ) === -1 ) {
+ // Add to excluded
+ if ( excluded.indexOf( module ) === -1 ) {
+ grunt.log.writeln( flag );
+ excluded.push( module );
+ // Exclude all files in the folder of the same name
+ // These are the removable dependencies
+ // It's fine if the directory is not there
+ try {
+ excludeList( fs.readdirSync( srcFolder + module ), module );
+ } catch( e ) {
+ grunt.verbose.writeln( e );
+ }
+ }
+ // Check removeWith list
+ excludeList( removeWith[ module ] );
+ } else {
+ grunt.log.error( "Module \"" + module + "\" is a mimimum requirement.");
+ }
+ } else {
+ grunt.log.writeln( flag );
+ included.push( module );
+ }
+ };
+
+ // append commit id to version
+ if ( process.env.COMMIT ) {
+ version += " " + process.env.COMMIT;
+ }
+
+ // figure out which files to exclude based on these rules in this order:
+ // dependency explicit exclude
+ // > explicit exclude
+ // > explicit include
+ // > dependency implicit exclude
+ // > implicit exclude
+ // examples:
+ // * none (implicit exclude)
+ // *:* all (implicit include)
+ // *:*:-css all except css and dependents (explicit > implicit)
+ // *:*:-css:+effects same (excludes effects because explicit include is trumped by explicit exclude of dependency)
+ // *:+effects none except effects and its dependencies (explicit include trumps implicit exclude of dependency)
+ for ( flag in flags ) {
+ if ( flag !== "*" ) {
+ excluder( flag );
+ }
+ }
+
+ grunt.verbose.writeflags( excluded, "Excluded" );
+ grunt.verbose.writeflags( included, "Included" );
+
+ // append excluded modules to version
+ if ( excluded.length ) {
+ version += " -" + excluded.join( ",-" );
+ // set pkg.version to version with excludes, so minified file picks it up
+ grunt.config.set( "pkg.version", version );
+ grunt.verbose.writeln( "Version changed to " + version );
+ // Have to use shallow or core will get excluded since it is a dependency
+ config.excludeShallow = excluded;
+ }
+ config.include = included;
+
+ /**
+ * Handle Final output from the optimizer
+ * @param {String} compiled
+ */
+ config.out = function( compiled ) {
+ compiled = compiled
+ // Embed Version
+ .replace( /@VERSION/g, version )
+ // Embed Date
+ // yyyy-mm-ddThh:mmZ
+ .replace( /@DATE/g, ( new Date() ).toISOString().replace( /:\d+\.\d+Z$/, "Z" ) );
+
+ // Write concatenated source to file
+ grunt.file.write( name, compiled );
+ };
+
+ // Trace dependencies and concatenate files
+ requirejs.optimize( config, function( response ) {
+ grunt.verbose.writeln( response );
+ grunt.log.ok( "File '" + name + "' created." );
+ done();
+ }, function( err ) {
+ done( err );
+ });
+ });
+
+ // Special "alias" task to make custom build creation less grawlix-y
+ // Translation example
+ //
+ // grunt custom:+ajax,-dimensions,-effects,-offset
+ //
+ // Becomes:
+ //
+ // grunt build:*:*:+ajax:-dimensions:-effects:-offset
+ grunt.registerTask( "custom", function() {
+ var args = [].slice.call( arguments ),
+ modules = args.length ? args[ 0 ].replace( /,/g, ":" ) : "";
+
+ grunt.log.writeln( "Creating custom build...\n" );
+
+ grunt.task.run([ "build:*:*:" + modules, "pre-uglify", "uglify", "dist" ]);
+ });
+};
--- /dev/null
+module.exports = function( grunt ) {
+
+ "use strict";
+
+ var fs = require( "fs" ),
+ distpaths = [
+ "dist/jquery.js",
+ "dist/jquery.min.map",
+ "dist/jquery.min.js"
+ ];
+
+ // Process files for distribution
+ grunt.registerTask( "dist", function() {
+ var stored, flags, paths, nonascii;
+
+ // Check for stored destination paths
+ // ( set in dist/.destination.json )
+ stored = Object.keys( grunt.config( "dst" ) );
+
+ // Allow command line input as well
+ flags = Object.keys( this.flags );
+
+ // Combine all output target paths
+ paths = [].concat( stored, flags ).filter(function( path ) {
+ return path !== "*";
+ });
+
+ // Ensure the dist files are pure ASCII
+ nonascii = false;
+
+ distpaths.forEach(function( filename ) {
+ var i, c,
+ text = fs.readFileSync( filename, "utf8" );
+
+ // Ensure files use only \n for line endings, not \r\n
+ if ( /\x0d\x0a/.test( text ) ) {
+ grunt.log.writeln( filename + ": Incorrect line endings (\\r\\n)" );
+ nonascii = true;
+ }
+
+ // Ensure only ASCII chars so script tags don't need a charset attribute
+ if ( text.length !== Buffer.byteLength( text, "utf8" ) ) {
+ grunt.log.writeln( filename + ": Non-ASCII characters detected:" );
+ for ( i = 0; i < text.length; i++ ) {
+ c = text.charCodeAt( i );
+ if ( c > 127 ) {
+ grunt.log.writeln( "- position " + i + ": " + c );
+ grunt.log.writeln( "-- " + text.substring( i - 20, i + 20 ) );
+ break;
+ }
+ }
+ nonascii = true;
+ }
+
+ // Modify map/min so that it points to files in the same folder;
+ // see https://github.com/mishoo/UglifyJS2/issues/47
+ if ( /\.map$/.test( filename ) ) {
+ text = text.replace( /"dist\//g, "\"" );
+ fs.writeFileSync( filename, text, "utf-8" );
+
+ // Use our hard-coded sourceMap directive instead of the autogenerated one (#13274; #13776)
+ } else if ( /\.min\.js$/.test( filename ) ) {
+ i = 0;
+ text = text.replace( /(?:\/\*|)\n?\/\/@\s*sourceMappingURL=.*(\n\*\/|)/g,
+ function( match ) {
+ if ( i++ ) {
+ return "";
+ }
+ return match;
+ });
+ fs.writeFileSync( filename, text, "utf-8" );
+ }
+
+ // Optionally copy dist files to other locations
+ paths.forEach(function( path ) {
+ var created;
+
+ if ( !/\/$/.test( path ) ) {
+ path += "/";
+ }
+
+ created = path + filename.replace( "dist/", "" );
+ grunt.file.write( created, text );
+ grunt.log.writeln( "File '" + created + "' created." );
+ });
+ });
+
+ return !nonascii;
+ });
+};
--- /dev/null
+module.exports = function( grunt ) {
+
+ "use strict";
+
+ grunt.registerTask( "testswarm", function( commit, configFile ) {
+ var jobName,
+ testswarm = require( "testswarm" ),
+ runs = {},
+ done = this.async(),
+ pull = /PR-(\d+)/.exec( commit ),
+ config = grunt.file.readJSON( configFile ).jquery,
+ tests = grunt.config([ this.name, "tests" ]);
+
+ if ( pull ) {
+ jobName = "jQuery pull <a href='https://github.com/jquery/jquery/pull/" +
+ pull[ 1 ] + "'>#" + pull[ 1 ] + "</a>";
+ } else {
+ jobName = "jQuery commit #<a href='https://github.com/jquery/jquery/commit/" +
+ commit + "'>" + commit.substr( 0, 10 ) + "</a>";
+ }
+
+ tests.forEach(function( test ) {
+ runs[ test ] = config.testUrl + commit + "/test/index.html?module=" + test;
+ });
+
+ testswarm.createClient( {
+ url: config.swarmUrl,
+ pollInterval: 10000,
+ timeout: 1000 * 60 * 30
+ } )
+ .addReporter( testswarm.reporters.cli )
+ .auth( {
+ id: config.authUsername,
+ token: config.authToken
+ })
+ .addjob(
+ {
+ name: jobName,
+ runs: runs,
+ runMax: config.runMax,
+ browserSets: config.browserSets
+ }, function( err, passed ) {
+ if ( err ) {
+ grunt.log.error( err );
+ }
+ done( passed );
+ }
+ );
+ });
+};
--- /dev/null
+module.exports = function( grunt ) {
+
+ "use strict";
+
+ var fs = require( "fs" );
+
+ // Work around grunt-contrib-uglify sourceMap issues (jQuery #13776)
+ grunt.registerMultiTask( "pre-uglify", function() {
+ var banner = this.options().banner;
+
+ this.files.forEach(function( mapping ) {
+ // Join src
+ var input = mapping.src.map(function( file ) {
+ var contents = grunt.file.read( file );
+
+ // Strip banners
+ return contents
+ // Remove the main jQuery banner, it'll be replaced by the new banner anyway.
+ .replace( /^\/\*![\W\w]*?\*\/\n?/g, "" )
+ // Strip other banners preserving line count.
+ .replace( /^\/\*!(?:.|\n)*?\*\/\n?/gm, function ( match ) {
+ return match.replace( /[^\n]/gm, "" );
+ });
+ }).join("\n");
+
+ // Write temp file (with optional banner)
+ grunt.file.write( mapping.dest, ( banner || "" ) + input );
+ });
+ });
+
+ // Change the map file to point back to jquery.js instead of jquery.pre-min.js.
+ // The problem is caused by the pre-uglify task.
+ // Also, remove temporary files.
+ grunt.registerMultiTask( "post-uglify", function() {
+ this.files.forEach(function( mapping ) {
+ var mapFileName = mapping.src[ 0 ];
+
+ // Rename the file to a temporary name.
+ fs.renameSync( mapFileName, mapping.dest);
+ grunt.file.write( mapFileName, grunt.file.read( mapping.dest )
+ // The uglify task erroneously prepends dist/ to file names.
+ .replace( /"dist\//g, "\"" )
+ // Refer to the source jquery.js, not the temporary jquery.pre-min.js.
+ .replace( /\.pre-min\./g, "." )
+ // There's already a pragma at the beginning of the file, remove the one at the end.
+ .replace( /\/\/@ sourceMappingURL=jquery\.min\.map$/g, "" ));
+ });
+
+ // Remove temporary files.
+ this.options().tempFiles.forEach(function( fileName ) {
+ fs.unlink( fileName );
+ });
+ });
+};