mirror of
https://github.com/twbs/bootstrap.git
synced 2024-11-29 11:24:18 +01:00
8e9a9a5960
- Creates new flexbox grid Sass file in our docs assets - Updates the Gruntfile to compile said new Sass file and minify the output - Update notice on flexbox docs page for how it works - Only enable compiled flexbox grid CSS in hosted docs site, not in dev (for easier and specific debugging of all flexbox features)
410 lines
13 KiB
JavaScript
410 lines
13 KiB
JavaScript
/*!
|
|
* Bootstrap's Gruntfile
|
|
* http://getbootstrap.com
|
|
* Copyright 2013-2016 The Bootstrap Authors
|
|
* Copyright 2013-2016 Twitter, Inc.
|
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
*/
|
|
|
|
module.exports = function (grunt) {
|
|
'use strict';
|
|
|
|
// Force use of Unix newlines
|
|
grunt.util.linefeed = '\n';
|
|
|
|
RegExp.quote = function (string) {
|
|
return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
};
|
|
|
|
var fs = require('fs');
|
|
var path = require('path');
|
|
var isTravis = require('is-travis');
|
|
|
|
var configBridge = grunt.file.readJSON('./grunt/configBridge.json', { encoding: 'utf8' });
|
|
|
|
Object.keys(configBridge.paths).forEach(function (key) {
|
|
configBridge.paths[key].forEach(function (val, i, arr) {
|
|
arr[i] = path.join('./docs', val);
|
|
});
|
|
});
|
|
|
|
// Project configuration.
|
|
grunt.initConfig({
|
|
|
|
// Metadata.
|
|
pkg: grunt.file.readJSON('package.json'),
|
|
banner: '/*!\n' +
|
|
' * Bootstrap v<%= pkg.version %> (<%= pkg.homepage %>)\n' +
|
|
' * Copyright 2011-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
|
|
' * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n' +
|
|
' */\n',
|
|
jqueryCheck: 'if (typeof jQuery === \'undefined\') {\n' +
|
|
' throw new Error(\'Bootstrap\\\'s JavaScript requires jQuery\')\n' +
|
|
'}\n',
|
|
jqueryVersionCheck: '+function ($) {\n' +
|
|
' var version = $.fn.jquery.split(\' \')[0].split(\'.\')\n' +
|
|
' if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] >= 4)) {\n' +
|
|
' throw new Error(\'Bootstrap\\\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0\')\n' +
|
|
' }\n' +
|
|
'}(jQuery);\n\n',
|
|
|
|
// Task configuration.
|
|
clean: {
|
|
dist: 'dist',
|
|
docs: 'docs/dist'
|
|
},
|
|
|
|
// JS build configuration
|
|
babel: {
|
|
dev: {
|
|
options: {
|
|
sourceMap: true,
|
|
modules: 'ignore'
|
|
},
|
|
files: {
|
|
'js/dist/util.js' : 'js/src/util.js',
|
|
'js/dist/alert.js' : 'js/src/alert.js',
|
|
'js/dist/button.js' : 'js/src/button.js',
|
|
'js/dist/carousel.js' : 'js/src/carousel.js',
|
|
'js/dist/collapse.js' : 'js/src/collapse.js',
|
|
'js/dist/dropdown.js' : 'js/src/dropdown.js',
|
|
'js/dist/modal.js' : 'js/src/modal.js',
|
|
'js/dist/scrollspy.js' : 'js/src/scrollspy.js',
|
|
'js/dist/tab.js' : 'js/src/tab.js',
|
|
'js/dist/tooltip.js' : 'js/src/tooltip.js',
|
|
'js/dist/popover.js' : 'js/src/popover.js'
|
|
}
|
|
},
|
|
dist: {
|
|
options: {
|
|
modules: 'ignore'
|
|
},
|
|
files: {
|
|
'<%= concat.bootstrap.dest %>' : '<%= concat.bootstrap.dest %>'
|
|
}
|
|
}
|
|
},
|
|
|
|
stamp: {
|
|
options: {
|
|
banner: '<%= banner %>\n<%= jqueryCheck %>\n<%= jqueryVersionCheck %>\n+function ($) {\n',
|
|
footer: '\n}(jQuery);'
|
|
},
|
|
bootstrap: {
|
|
files: {
|
|
src: '<%= concat.bootstrap.dest %>'
|
|
}
|
|
}
|
|
},
|
|
|
|
concat: {
|
|
options: {
|
|
// Custom function to remove all export and import statements
|
|
process: function (src) {
|
|
return src.replace(/^(export|import).*/gm, '');
|
|
},
|
|
stripBanners: false
|
|
},
|
|
bootstrap: {
|
|
src: [
|
|
'js/src/util.js',
|
|
'js/src/alert.js',
|
|
'js/src/button.js',
|
|
'js/src/carousel.js',
|
|
'js/src/collapse.js',
|
|
'js/src/dropdown.js',
|
|
'js/src/modal.js',
|
|
'js/src/scrollspy.js',
|
|
'js/src/tab.js',
|
|
'js/src/tooltip.js',
|
|
'js/src/popover.js'
|
|
],
|
|
dest: 'dist/js/<%= pkg.name %>.js'
|
|
}
|
|
},
|
|
|
|
uglify: {
|
|
options: {
|
|
compress: {
|
|
warnings: false
|
|
},
|
|
mangle: true,
|
|
preserveComments: /^!|@preserve|@license|@cc_on/i
|
|
},
|
|
core: {
|
|
src: '<%= concat.bootstrap.dest %>',
|
|
dest: 'dist/js/<%= pkg.name %>.min.js'
|
|
},
|
|
docsJs: {
|
|
src: configBridge.paths.docsJs,
|
|
dest: 'docs/assets/js/docs.min.js'
|
|
}
|
|
},
|
|
|
|
qunit: {
|
|
options: {
|
|
inject: 'js/tests/unit/phantom.js'
|
|
},
|
|
files: 'js/tests/index.html'
|
|
},
|
|
|
|
// CSS build configuration
|
|
scsslint: {
|
|
options: {
|
|
bundleExec: true,
|
|
config: 'scss/.scss-lint.yml',
|
|
reporterOutput: null
|
|
},
|
|
core: {
|
|
src: ['scss/*.scss', '!scss/_normalize.scss']
|
|
},
|
|
docs: {
|
|
src: ['docs/assets/scss/*.scss', '!docs/assets/scss/docs.scss']
|
|
}
|
|
},
|
|
|
|
cssmin: {
|
|
options: {
|
|
// TODO: disable `zeroUnits` optimization once clean-css 3.2 is released
|
|
// and then simplify the fix for https://github.com/twbs/bootstrap/issues/14837 accordingly
|
|
compatibility: 'ie9',
|
|
keepSpecialComments: '*',
|
|
sourceMap: true,
|
|
advanced: false
|
|
},
|
|
core: {
|
|
files: [
|
|
{
|
|
expand: true,
|
|
cwd: 'dist/css',
|
|
src: ['*.css', '!*.min.css'],
|
|
dest: 'dist/css',
|
|
ext: '.min.css'
|
|
}
|
|
]
|
|
},
|
|
docs: {
|
|
files: [
|
|
{
|
|
expand: true,
|
|
cwd: 'docs/assets/css',
|
|
src: ['*.css', '!*.min.css'],
|
|
dest: 'docs/assets/css',
|
|
ext: '.min.css'
|
|
}
|
|
]
|
|
}
|
|
},
|
|
|
|
copy: {
|
|
docs: {
|
|
expand: true,
|
|
cwd: 'dist/',
|
|
src: [
|
|
'**/*'
|
|
],
|
|
dest: 'docs/dist/'
|
|
}
|
|
},
|
|
|
|
connect: {
|
|
server: {
|
|
options: {
|
|
port: 3000,
|
|
base: '.'
|
|
}
|
|
}
|
|
},
|
|
|
|
jekyll: {
|
|
options: {
|
|
bundleExec: true,
|
|
config: '_config.yml',
|
|
incremental: false
|
|
},
|
|
docs: {},
|
|
github: {
|
|
options: {
|
|
raw: 'github: true'
|
|
}
|
|
}
|
|
},
|
|
|
|
htmllint: {
|
|
options: {
|
|
ignore: [
|
|
'Attribute “autocomplete” is only allowed when the input type is “color”, “date”, “datetime”, “datetime-local”, “email”, “hidden”, “month”, “number”, “password”, “range”, “search”, “tel”, “text”, “time”, “url”, or “week”.',
|
|
'Attribute “autocomplete” not allowed on element “button” at this point.',
|
|
'Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).',
|
|
'Element “div” not allowed as child of element “progress” in this context. (Suppressing further errors from this subtree.)',
|
|
'Element “img” is missing required attribute “src”.',
|
|
'The “color” input type is not supported in all browsers. Please be sure to test, and consider using a polyfill.',
|
|
'The “date” input type is not supported in all browsers. Please be sure to test, and consider using a polyfill.',
|
|
'The “datetime” input type is not supported in all browsers. Please be sure to test, and consider using a polyfill.',
|
|
'The “datetime-local” input type is not supported in all browsers. Please be sure to test, and consider using a polyfill.',
|
|
'The “month” input type is not supported in all browsers. Please be sure to test, and consider using a polyfill.',
|
|
'The “time” input type is not supported in all browsers. Please be sure to test, and consider using a polyfill.',
|
|
'The “week” input type is not supported in all browsers. Please be sure to test, and consider using a polyfill.'
|
|
]
|
|
},
|
|
src: ['_gh_pages/**/*.html', 'js/tests/visual/*.html']
|
|
},
|
|
|
|
watch: {
|
|
src: {
|
|
files: '<%= concat.bootstrap.src %>',
|
|
tasks: ['babel:dev']
|
|
},
|
|
sass: {
|
|
files: 'scss/**/*.scss',
|
|
tasks: ['dist-css', 'docs']
|
|
},
|
|
docs: {
|
|
files: 'docs/assets/scss/**/*.scss',
|
|
tasks: ['dist-css', 'docs']
|
|
}
|
|
},
|
|
|
|
'saucelabs-qunit': {
|
|
all: {
|
|
options: {
|
|
build: process.env.TRAVIS_JOB_ID,
|
|
concurrency: 10,
|
|
maxRetries: 3,
|
|
maxPollRetries: 4,
|
|
urls: ['http://127.0.0.1:3000/js/tests/index.html?hidepassed'],
|
|
browsers: grunt.file.readYAML('grunt/sauce_browsers.yml')
|
|
}
|
|
}
|
|
},
|
|
|
|
exec: {
|
|
postcss: {
|
|
command: 'npm run postcss'
|
|
},
|
|
'postcss-docs': {
|
|
command: 'npm run postcss-docs'
|
|
},
|
|
htmlhint: {
|
|
command: 'npm run htmlhint'
|
|
},
|
|
'upload-preview': {
|
|
command: './grunt/upload-preview.sh'
|
|
}
|
|
},
|
|
|
|
buildcontrol: {
|
|
options: {
|
|
dir: '_gh_pages',
|
|
commit: true,
|
|
push: true,
|
|
message: 'Built %sourceName% from commit %sourceCommit% on branch %sourceBranch%'
|
|
},
|
|
pages: {
|
|
options: {
|
|
remote: 'git@github.com:twbs/derpstrap.git',
|
|
branch: 'gh-pages'
|
|
}
|
|
}
|
|
},
|
|
|
|
compress: {
|
|
main: {
|
|
options: {
|
|
archive: 'bootstrap-<%= pkg.version %>-dist.zip',
|
|
mode: 'zip',
|
|
level: 9,
|
|
pretty: true
|
|
},
|
|
files: [
|
|
{
|
|
expand: true,
|
|
cwd: 'dist/',
|
|
src: ['**'],
|
|
dest: 'bootstrap-<%= pkg.version %>-dist'
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
|
|
// These plugins provide necessary tasks.
|
|
require('load-grunt-tasks')(grunt, { scope: 'devDependencies',
|
|
// Exclude Sass compilers. We choose the one to load later on.
|
|
pattern: ['grunt-*', '!grunt-sass', '!grunt-contrib-sass'] });
|
|
require('time-grunt')(grunt);
|
|
|
|
// Docs HTML validation task
|
|
grunt.registerTask('validate-html', ['jekyll:docs', 'htmllint', 'exec:htmlhint']);
|
|
|
|
var runSubset = function (subset) {
|
|
return !process.env.TWBS_TEST || process.env.TWBS_TEST === subset;
|
|
};
|
|
var isUndefOrNonZero = function (val) {
|
|
return val === undefined || val !== '0';
|
|
};
|
|
|
|
// Test task.
|
|
var testSubtasks = [];
|
|
// Skip core tests if running a different subset of the test suite
|
|
if (runSubset('core') &&
|
|
// Skip core tests if this is a Savage build
|
|
process.env.TRAVIS_REPO_SLUG !== 'twbs-savage/bootstrap') {
|
|
testSubtasks = testSubtasks.concat(['dist-css', 'dist-js', 'test-scss', 'qunit', 'docs']);
|
|
}
|
|
// Skip HTML validation if running a different subset of the test suite
|
|
if (runSubset('validate-html') &&
|
|
isTravis &&
|
|
// Skip HTML5 validator when [skip validator] is in the commit message
|
|
isUndefOrNonZero(process.env.TWBS_DO_VALIDATOR)) {
|
|
testSubtasks.push('validate-html');
|
|
}
|
|
// Only run Sauce Labs tests if there's a Sauce access key
|
|
if (typeof process.env.SAUCE_ACCESS_KEY !== 'undefined' &&
|
|
// Skip Sauce if running a different subset of the test suite
|
|
runSubset('sauce-js-unit')) {
|
|
testSubtasks = testSubtasks.concat(['dist', 'docs-css', 'docs-js', 'clean:docs', 'copy:docs', 'exec:upload-preview']);
|
|
// Skip Sauce on Travis when [skip sauce] is in the commit message
|
|
if (isUndefOrNonZero(process.env.TWBS_DO_SAUCE)) {
|
|
testSubtasks.push('connect');
|
|
testSubtasks.push('saucelabs-qunit');
|
|
}
|
|
}
|
|
grunt.registerTask('test', testSubtasks);
|
|
|
|
// JS distribution task.
|
|
grunt.registerTask('dist-js', ['babel:dev', 'concat', 'babel:dist', 'stamp', 'uglify:core']);
|
|
|
|
grunt.registerTask('test-scss', ['scsslint:core']);
|
|
|
|
// CSS distribution task.
|
|
// Supported Compilers: sass (Ruby) and libsass.
|
|
(function (sassCompilerName) {
|
|
require('./grunt/bs-sass-compile/' + sassCompilerName + '.js')(grunt);
|
|
})(process.env.TWBS_SASS || 'libsass');
|
|
// grunt.registerTask('sass-compile', ['sass:core', 'sass:extras', 'sass:docs']);
|
|
grunt.registerTask('sass-compile', ['sass:core', 'sass:docs']);
|
|
|
|
grunt.registerTask('dist-css', ['sass-compile', 'exec:postcss', 'cssmin:core', 'cssmin:docs']);
|
|
|
|
// Full distribution task.
|
|
grunt.registerTask('dist', ['clean:dist', 'dist-css', 'dist-js']);
|
|
|
|
// Default task.
|
|
grunt.registerTask('default', ['clean:dist', 'test']);
|
|
|
|
// Docs task.
|
|
grunt.registerTask('docs-css', ['cssmin:docs', 'exec:postcss-docs']);
|
|
grunt.registerTask('lint-docs-css', ['scsslint:docs']);
|
|
grunt.registerTask('docs-js', ['uglify:docsJs']);
|
|
grunt.registerTask('docs', ['lint-docs-css', 'docs-css', 'docs-js', 'clean:docs', 'copy:docs']);
|
|
grunt.registerTask('docs-github', ['jekyll:github']);
|
|
|
|
grunt.registerTask('prep-release', ['dist', 'docs', 'docs-github', 'compress']);
|
|
|
|
// Publish to GitHub
|
|
grunt.registerTask('publish', ['buildcontrol:pages']);
|
|
};
|