/base/000_base/node_modules/bootstrap-validator/sandbox/bootstrap/Gruntfile.js |
@@ -0,0 +1,421 @@ |
/*! |
* Bootstrap's Gruntfile |
* http://getbootstrap.com |
* Copyright 2013-2014 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 generateGlyphiconsData = require('./grunt/bs-glyphicons-data-generator.js'); |
var BsLessdocParser = require('./grunt/bs-lessdoc-parser.js'); |
var generateRawFilesJs = require('./grunt/bs-raw-files-generator.js'); |
var updateShrinkwrap = require('./grunt/shrinkwrap.js'); |
|
// 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 <%= pkg.license.type %> (<%= pkg.license.url %>)\n' + |
' */\n', |
jqueryCheck: 'if (typeof jQuery === \'undefined\') { throw new Error(\'Bootstrap\\\'s JavaScript requires jQuery\') }\n\n', |
|
// Task configuration. |
clean: { |
dist: ['dist', 'docs/dist'] |
}, |
|
jshint: { |
options: { |
jshintrc: 'js/.jshintrc' |
}, |
grunt: { |
options: { |
jshintrc: 'grunt/.jshintrc' |
}, |
src: ['Gruntfile.js', 'grunt/*.js'] |
}, |
src: { |
src: 'js/*.js' |
}, |
test: { |
src: 'js/tests/unit/*.js' |
}, |
assets: { |
src: ['docs/assets/js/application.js', 'docs/assets/js/customizer.js'] |
} |
}, |
|
jscs: { |
options: { |
config: 'js/.jscs.json', |
}, |
grunt: { |
src: ['Gruntfile.js', 'grunt/*.js'] |
}, |
src: { |
src: 'js/*.js' |
}, |
test: { |
src: 'js/tests/unit/*.js' |
}, |
assets: { |
src: ['docs/assets/js/application.js', 'docs/assets/js/customizer.js'] |
} |
}, |
|
csslint: { |
options: { |
csslintrc: 'less/.csslintrc' |
}, |
src: [ |
'dist/css/bootstrap.css', |
'dist/css/bootstrap-theme.css', |
'docs/assets/css/docs.css', |
'docs/examples/**/*.css' |
] |
}, |
|
concat: { |
options: { |
banner: '<%= banner %>\n<%= jqueryCheck %>', |
stripBanners: false |
}, |
bootstrap: { |
src: [ |
'js/transition.js', |
'js/alert.js', |
'js/button.js', |
'js/carousel.js', |
'js/collapse.js', |
'js/dropdown.js', |
'js/modal.js', |
'js/tooltip.js', |
'js/popover.js', |
'js/scrollspy.js', |
'js/tab.js', |
'js/affix.js' |
], |
dest: 'dist/js/<%= pkg.name %>.js' |
} |
}, |
|
uglify: { |
options: { |
report: 'min' |
}, |
bootstrap: { |
options: { |
banner: '<%= banner %>' |
}, |
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/raw-files.min.js', |
'docs/assets/js/customizer.js' |
], |
dest: 'docs/assets/js/customize.min.js' |
}, |
docsJs: { |
options: { |
preserveComments: 'some' |
}, |
src: [ |
'docs/assets/js/vendor/holder.js', |
'docs/assets/js/application.js' |
], |
dest: 'docs/assets/js/docs.min.js' |
} |
}, |
|
less: { |
compileCore: { |
options: { |
strictMath: true, |
sourceMap: true, |
outputSourceFiles: true, |
sourceMapURL: '<%= pkg.name %>.css.map', |
sourceMapFilename: 'dist/css/<%= pkg.name %>.css.map' |
}, |
files: { |
'dist/css/<%= pkg.name %>.css': 'less/bootstrap.less' |
} |
}, |
compileTheme: { |
options: { |
strictMath: true, |
sourceMap: true, |
outputSourceFiles: true, |
sourceMapURL: '<%= pkg.name %>-theme.css.map', |
sourceMapFilename: 'dist/css/<%= pkg.name %>-theme.css.map' |
}, |
files: { |
'dist/css/<%= pkg.name %>-theme.css': 'less/theme.less' |
} |
}, |
minify: { |
options: { |
cleancss: true, |
report: 'min' |
}, |
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' |
} |
} |
}, |
|
cssmin: { |
compress: { |
options: { |
keepSpecialComments: '*', |
noAdvanced: true, // turn advanced optimizations off until the issue is fixed in clean-css |
report: 'min', |
selectorsMergeMode: 'ie8' |
}, |
src: [ |
'docs/assets/css/docs.css', |
'docs/assets/css/pygments-manni.css' |
], |
dest: 'docs/assets/css/docs.min.css' |
} |
}, |
|
usebanner: { |
dist: { |
options: { |
position: 'top', |
banner: '<%= banner %>' |
}, |
files: { |
src: [ |
'dist/css/<%= pkg.name %>.css', |
'dist/css/<%= pkg.name %>.min.css', |
'dist/css/<%= pkg.name %>-theme.css', |
'dist/css/<%= pkg.name %>-theme.min.css' |
] |
} |
} |
}, |
|
csscomb: { |
options: { |
config: 'less/.csscomb.json' |
}, |
dist: { |
files: { |
'dist/css/<%= pkg.name %>.css': 'dist/css/<%= pkg.name %>.css', |
'dist/css/<%= pkg.name %>-theme.css': 'dist/css/<%= pkg.name %>-theme.css' |
} |
}, |
examples: { |
expand: true, |
cwd: 'docs/examples/', |
src: ['**/*.css'], |
dest: 'docs/examples/' |
} |
}, |
|
copy: { |
fonts: { |
expand: true, |
src: 'fonts/*', |
dest: 'dist/' |
}, |
docs: { |
expand: true, |
cwd: './dist', |
src: [ |
'{css,js}/*.min.*', |
'css/*.map', |
'fonts/*' |
], |
dest: 'docs/dist' |
} |
}, |
|
qunit: { |
options: { |
inject: 'js/tests/unit/phantom.js' |
}, |
files: 'js/tests/index.html' |
}, |
|
connect: { |
server: { |
options: { |
port: 3000, |
base: '.' |
} |
} |
}, |
|
jekyll: { |
docs: {} |
}, |
|
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' |
} |
} |
}, |
|
validation: { |
options: { |
charset: 'utf-8', |
doctype: 'HTML5', |
failHard: true, |
reset: true, |
relaxerror: [ |
'Bad value X-UA-Compatible for attribute http-equiv on element meta.', |
'Element img is missing required attribute src.' |
] |
}, |
files: { |
src: '_gh_pages/**/*.html' |
} |
}, |
|
watch: { |
src: { |
files: '<%= jshint.src.src %>', |
tasks: ['jshint:src', 'qunit'] |
}, |
test: { |
files: '<%= jshint.test.src %>', |
tasks: ['jshint:test', 'qunit'] |
}, |
less: { |
files: 'less/*.less', |
tasks: 'less' |
} |
}, |
|
sed: { |
versionNumber: { |
pattern: (function () { |
var old = grunt.option('oldver'); |
return old ? RegExp.quote(old) : old; |
})(), |
replacement: grunt.option('newver'), |
recursive: true |
} |
}, |
|
'saucelabs-qunit': { |
all: { |
options: { |
build: process.env.TRAVIS_JOB_ID, |
concurrency: 10, |
urls: ['http://127.0.0.1:3000/js/tests/index.html'], |
browsers: grunt.file.readYAML('test-infra/sauce_browsers.yml') |
} |
} |
}, |
|
exec: { |
npmUpdate: { |
command: 'npm update' |
}, |
npmShrinkWrap: { |
command: 'npm shrinkwrap --dev' |
} |
} |
}); |
|
|
// These plugins provide necessary tasks. |
require('load-grunt-tasks')(grunt, {scope: 'devDependencies'}); |
|
// Docs HTML validation task |
grunt.registerTask('validate-html', ['jekyll', 'validation']); |
|
// Test task. |
var testSubtasks = []; |
// Skip core tests if running a different subset of the test suite |
if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'core') { |
testSubtasks = testSubtasks.concat(['dist-css', 'csslint', 'jshint', 'jscs', 'qunit', 'build-customizer-html']); |
} |
// Skip HTML validation if running a different subset of the test suite |
if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'validate-html') { |
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 |
(!process.env.TWBS_TEST || process.env.TWBS_TEST === 'sauce-js-unit')) { |
testSubtasks.push('connect'); |
testSubtasks.push('saucelabs-qunit'); |
} |
grunt.registerTask('test', testSubtasks); |
|
// JS distribution task. |
grunt.registerTask('dist-js', ['concat', 'uglify']); |
|
// CSS distribution task. |
grunt.registerTask('dist-css', ['less', 'cssmin', 'csscomb', 'usebanner']); |
|
// Docs distribution task. |
grunt.registerTask('dist-docs', 'copy:docs'); |
|
// Full distribution task. |
grunt.registerTask('dist', ['clean', 'dist-css', 'copy:fonts', 'dist-js', 'dist-docs']); |
|
// Default task. |
grunt.registerTask('default', ['test', 'dist', 'build-glyphicons-data', 'build-customizer', 'update-shrinkwrap']); |
|
// 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', generateGlyphiconsData); |
|
// task for building customizer |
grunt.registerTask('build-customizer', ['build-customizer-html', 'build-raw-files']); |
grunt.registerTask('build-customizer-html', 'jade'); |
grunt.registerTask('build-raw-files', 'Add scripts/less files to customizer.', function () { |
var banner = grunt.template.process('<%= banner %>'); |
generateRawFilesJs(banner); |
}); |
|
// 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); }); |
}; |