2
0
mirror of https://github.com/tenrok/bootstrap.git synced 2026-06-11 18:02:28 +03:00

Merge remote-tracking branch 'upstream/master' into node-requirable

Conflicts:
	Gruntfile.js
This commit is contained in:
James Friend
2014-08-28 09:32:08 +08:00
174 changed files with 18513 additions and 4600 deletions
+106 -84
View File
@@ -17,11 +17,16 @@ module.exports = function (grunt) {
var fs = require('fs');
var path = require('path');
var generateGlyphiconsData = require('./grunt/bs-glyphicons-data-generator.js');
var npmShrinkwrap = require('npm-shrinkwrap');
var BsLessdocParser = require('./grunt/bs-lessdoc-parser.js');
var getLessVarsData = function () {
var filePath = path.join(__dirname, 'less/variables.less');
var fileContent = fs.readFileSync(filePath, { encoding: 'utf8' });
var parser = new BsLessdocParser(fileContent);
return { sections: parser.parseFile() };
};
var generateRawFiles = require('./grunt/bs-raw-files-generator.js');
var generateCommonJSModule = require('./grunt/bs-commonjs-generator.js');
var updateShrinkwrap = require('./grunt/shrinkwrap.js');
// Project configuration.
grunt.initConfig({
@@ -33,11 +38,13 @@ module.exports = function (grunt) {
' * Copyright 2011-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
' * Licensed under <%= pkg.license.type %> (<%= pkg.license.url %>)\n' +
' */\n',
// NOTE: This jqueryCheck code is duplicated in customizer.js; if making changes here, be sure to update the other copy too.
jqueryCheck: 'if (typeof jQuery === \'undefined\') { throw new Error(\'Bootstrap\\\'s JavaScript requires jQuery\') }\n\n',
// Task configuration.
clean: {
dist: ['dist', 'docs/dist']
dist: 'dist',
docs: 'docs/dist'
},
jshint: {
@@ -50,7 +57,7 @@ module.exports = function (grunt) {
},
src: ['Gruntfile.js', 'grunt/*.js']
},
src: {
core: {
src: 'js/*.js'
},
test: {
@@ -60,7 +67,7 @@ module.exports = function (grunt) {
src: 'js/tests/unit/*.js'
},
assets: {
src: ['docs/assets/js/_src/*.js', 'docs/assets/js/*.js', '!docs/assets/js/*.min.js']
src: ['docs/assets/js/src/*.js', 'docs/assets/js/*.js', '!docs/assets/js/*.min.js']
}
},
@@ -71,8 +78,8 @@ module.exports = function (grunt) {
grunt: {
src: '<%= jshint.grunt.src %>'
},
src: {
src: '<%= jshint.src.src %>'
core: {
src: '<%= jshint.core.src %>'
},
test: {
src: '<%= jshint.test.src %>'
@@ -110,36 +117,31 @@ module.exports = function (grunt) {
},
uglify: {
bootstrap: {
options: {
banner: '<%= banner %>'
},
options: {
preserveComments: 'some'
},
core: {
src: '<%= concat.bootstrap.dest %>',
dest: 'dist/js/<%= pkg.name %>.min.js'
},
customize: {
options: {
preserveComments: 'some'
},
src: [
'docs/assets/js/_vendor/less.min.js',
'docs/assets/js/_vendor/jszip.min.js',
'docs/assets/js/_vendor/uglify.min.js',
'docs/assets/js/_vendor/blob.js',
'docs/assets/js/_vendor/filesaver.js',
'docs/assets/js/vendor/less.min.js',
'docs/assets/js/vendor/jszip.min.js',
'docs/assets/js/vendor/uglify.min.js',
'docs/assets/js/vendor/blob.js',
'docs/assets/js/vendor/filesaver.js',
'docs/assets/js/raw-files.min.js',
'docs/assets/js/_src/customizer.js'
'docs/assets/js/src/customizer.js'
],
dest: 'docs/assets/js/customize.min.js'
},
docsJs: {
options: {
preserveComments: 'some'
},
// NOTE: This src list is duplicated in footer.html; if making changes here, be sure to update the other copy too.
src: [
'docs/assets/js/_vendor/holder.js',
'docs/assets/js/_vendor/ZeroClipboard.min.js',
'docs/assets/js/_src/application.js'
'docs/assets/js/vendor/holder.js',
'docs/assets/js/vendor/ZeroClipboard.min.js',
'docs/assets/js/src/application.js'
],
dest: 'docs/assets/js/docs.min.js'
}
@@ -161,9 +163,8 @@ module.exports = function (grunt) {
sourceMapURL: '<%= pkg.name %>.css.map',
sourceMapFilename: 'dist/css/<%= pkg.name %>.css.map'
},
files: {
'dist/css/<%= pkg.name %>.css': 'less/bootstrap.less'
}
src: 'less/bootstrap.less',
dest: 'dist/css/<%= pkg.name %>.css'
},
compileTheme: {
options: {
@@ -173,15 +174,23 @@ module.exports = function (grunt) {
sourceMapURL: '<%= pkg.name %>-theme.css.map',
sourceMapFilename: 'dist/css/<%= pkg.name %>-theme.css.map'
},
files: {
'dist/css/<%= pkg.name %>-theme.css': 'less/theme.less'
}
src: 'less/theme.less',
dest: 'dist/css/<%= pkg.name %>-theme.css'
}
},
autoprefixer: {
options: {
browsers: ['last 2 versions', 'ie 8', 'ie 9', 'android 2.3', 'android 4', 'opera 12']
browsers: [
'Android 2.3',
'Android >= 4',
'Chrome >= 20',
'Firefox >= 24', // Firefox 24 is the latest ESR
'Explorer >= 8',
'iOS >= 6',
'Opera >= 12',
'Safari >= 6'
]
},
core: {
options: {
@@ -196,7 +205,7 @@ module.exports = function (grunt) {
src: 'dist/css/<%= pkg.name %>-theme.css'
},
docs: {
src: 'docs/assets/css/_src/docs.css'
src: 'docs/assets/css/src/docs.css'
},
examples: {
expand: true,
@@ -210,7 +219,7 @@ module.exports = function (grunt) {
options: {
csslintrc: 'less/.csslintrc'
},
src: [
dist: [
'dist/css/bootstrap.css',
'dist/css/bootstrap-theme.css'
],
@@ -222,25 +231,28 @@ module.exports = function (grunt) {
ids: false,
'overqualified-elements': false
},
src: 'docs/assets/css/_src/docs.css'
src: 'docs/assets/css/src/docs.css'
}
},
cssmin: {
options: {
compatibility: 'ie8',
keepSpecialComments: '*'
keepSpecialComments: '*',
noAdvanced: true
},
core: {
files: {
'dist/css/<%= pkg.name %>.min.css': 'dist/css/<%= pkg.name %>.css',
'dist/css/<%= pkg.name %>-theme.min.css': 'dist/css/<%= pkg.name %>-theme.css'
}
minifyCore: {
src: 'dist/css/<%= pkg.name %>.css',
dest: 'dist/css/<%= pkg.name %>.min.css'
},
minifyTheme: {
src: 'dist/css/<%= pkg.name %>-theme.css',
dest: 'dist/css/<%= pkg.name %>-theme.min.css'
},
docs: {
src: [
'docs/assets/css/_src/docs.css',
'docs/assets/css/_src/pygments-manni.css'
'docs/assets/css/src/docs.css',
'docs/assets/css/src/pygments-manni.css'
],
dest: 'docs/assets/css/docs.min.css'
}
@@ -273,9 +285,8 @@ module.exports = function (grunt) {
dest: 'docs/examples/'
},
docs: {
files: {
'docs/assets/css/_src/docs.css': 'docs/assets/css/_src/docs.css'
}
src: 'docs/assets/css/src/docs.css',
dest: 'docs/assets/css/src/docs.css'
}
},
@@ -289,8 +300,8 @@ module.exports = function (grunt) {
expand: true,
cwd: './dist',
src: [
'{css,js}/*.min.*',
'css/*.map',
'css/*',
'js/*',
'fonts/*'
],
dest: 'docs/dist'
@@ -311,20 +322,17 @@ module.exports = function (grunt) {
},
jade: {
compile: {
options: {
pretty: true,
data: function () {
var filePath = path.join(__dirname, 'less/variables.less');
var fileContent = fs.readFileSync(filePath, { encoding: 'utf8' });
var parser = new BsLessdocParser(fileContent);
return { sections: parser.parseFile() };
}
},
files: {
'docs/_includes/customizer-variables.html': 'docs/_jade/customizer-variables.jade',
'docs/_includes/nav/customize.html': 'docs/_jade/customizer-nav.jade'
}
options: {
pretty: true,
data: getLessVarsData
},
customizerVars: {
src: 'docs/_jade/customizer-variables.jade',
dest: 'docs/_includes/customizer-variables.html'
},
customizerNav: {
src: 'docs/_jade/customizer-nav.jade',
dest: 'docs/_includes/nav/customize.html'
}
},
@@ -336,7 +344,9 @@ module.exports = function (grunt) {
reset: true,
relaxerror: [
'Bad value X-UA-Compatible for attribute http-equiv on element meta.',
'Element img is missing required attribute src.'
'Element img is missing required attribute src.',
'Attribute autocomplete not allowed on element input at this point.',
'Attribute autocomplete not allowed on element button at this point.'
]
},
files: {
@@ -346,15 +356,15 @@ module.exports = function (grunt) {
watch: {
src: {
files: '<%= jshint.src.src %>',
tasks: ['jshint:src', 'qunit']
files: '<%= jshint.core.src %>',
tasks: ['jshint:src', 'qunit', 'concat']
},
test: {
files: '<%= jshint.test.src %>',
tasks: ['jshint:test', 'qunit']
},
less: {
files: 'less/*.less',
files: 'less/**/*.less',
tasks: 'less'
}
},
@@ -375,6 +385,7 @@ module.exports = function (grunt) {
options: {
build: process.env.TRAVIS_JOB_ID,
concurrency: 10,
maxRetries: 3,
urls: ['http://127.0.0.1:3000/js/tests/index.html'],
browsers: grunt.file.readYAML('grunt/sauce_browsers.yml')
}
@@ -384,9 +395,6 @@ module.exports = function (grunt) {
exec: {
npmUpdate: {
command: 'npm update'
},
npmShrinkWrap: {
command: 'npm shrinkwrap --dev'
}
}
});
@@ -410,7 +418,7 @@ module.exports = function (grunt) {
var testSubtasks = [];
// Skip core tests if running a different subset of the test suite
if (runSubset('core')) {
testSubtasks = testSubtasks.concat(['dist-css', 'csslint', 'jshint', 'jscs', 'qunit', 'build-customizer-html']);
testSubtasks = testSubtasks.concat(['dist-css', 'dist-js', 'csslint:dist', 'jshint:core', 'jshint:test', 'jshint:grunt', 'jscs:core', 'jscs:test', 'jscs:grunt', 'qunit', 'docs']);
}
// Skip HTML validation if running a different subset of the test suite
if (runSubset('validate-html') &&
@@ -430,28 +438,23 @@ module.exports = function (grunt) {
grunt.registerTask('test', testSubtasks);
// JS distribution task.
grunt.registerTask('dist-js', ['concat', 'uglify']);
grunt.registerTask('dist-js', ['concat', 'uglify:core']);
// CSS distribution task.
grunt.registerTask('less-compile', ['less:compileCore', 'less:compileTheme']);
grunt.registerTask('dist-css', ['less-compile', 'autoprefixer', 'usebanner', 'csscomb', 'cssmin']);
// Docs distribution task.
grunt.registerTask('dist-docs', 'copy:docs');
grunt.registerTask('dist-css', ['less-compile', 'autoprefixer:core', 'autoprefixer:theme', 'usebanner', 'csscomb:dist', 'cssmin:minifyCore', 'cssmin:minifyTheme']);
// Full distribution task.
grunt.registerTask('dist', ['clean', 'dist-css', 'copy:fonts', 'dist-js', 'dist-docs']);
grunt.registerTask('dist', ['clean:dist', 'dist-css', 'copy:fonts', 'dist-js']);
// Default task.
grunt.registerTask('default', ['test', 'dist', 'build-glyphicons-data', 'build-customizer']);
grunt.registerTask('default', ['clean:dist', 'copy:fonts', 'test']);
// Version numbering task.
// grunt change-version-number --oldver=A.B.C --newver=X.Y.Z
// This can be overzealous, so its changes should always be manually reviewed!
grunt.registerTask('change-version-number', 'sed');
grunt.registerTask('build-glyphicons-data', function () { generateGlyphiconsData.call(this, grunt); });
// task for building customizer
grunt.registerTask('build-customizer', ['build-customizer-html', 'build-raw-files']);
grunt.registerTask('build-customizer-html', 'jade');
@@ -460,12 +463,31 @@ module.exports = function (grunt) {
generateRawFiles(grunt, banner);
});
grunt.registerTask('build-commonjs', 'Build CommonJS entrypoint module for JS.', function () {
grunt.registerTask('commonjs', 'Generate CommonJS entrypoint module in dist dir.', function () {
var files = grunt.config.get('concat.bootstrap.src');
generateCommonJSModule(grunt, files);
});
// Task for updating the npm packages used by the Travis build.
grunt.registerTask('update-shrinkwrap', ['exec:npmUpdate', 'exec:npmShrinkWrap', '_update-shrinkwrap']);
grunt.registerTask('_update-shrinkwrap', function () { updateShrinkwrap.call(this, grunt); });
// Docs task.
grunt.registerTask('docs-css', ['autoprefixer:docs', 'autoprefixer:examples', 'csscomb:docs', 'csscomb:examples', 'cssmin:docs']);
grunt.registerTask('lint-docs-css', ['csslint:docs', 'csslint:examples']);
grunt.registerTask('docs-js', ['uglify:docsJs', 'uglify:customize']);
grunt.registerTask('lint-docs-js', ['jshint:assets', 'jscs:assets']);
grunt.registerTask('docs', ['docs-css', 'lint-docs-css', 'docs-js', 'lint-docs-js', 'clean:docs', 'copy:docs', 'build-customizer']);
// Task for updating the cached npm packages used by the Travis build (which are controlled by test-infra/npm-shrinkwrap.json).
// This task should be run and the updated file should be committed whenever Bootstrap's dependencies change.
grunt.registerTask('update-shrinkwrap', ['exec:npmUpdate', '_update-shrinkwrap']);
grunt.registerTask('_update-shrinkwrap', function () {
var done = this.async();
npmShrinkwrap({ dev: true, dirname: __dirname }, function (err) {
if (err) {
grunt.fail.warn(err);
}
var dest = 'test-infra/npm-shrinkwrap.json';
fs.renameSync('npm-shrinkwrap.json', dest);
grunt.log.writeln('File ' + dest.cyan + ' updated.');
done();
});
});
};