diff --git a/.travis.yml b/.travis.yml index 2d6cd8f4f4..2abe857893 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,4 +2,8 @@ language: node_js node_js: - 0.8 before_script: - - npm install -g grunt-cli \ No newline at end of file + - npm install -g grunt-cli +env: + global: + - secure: Besg41eyU+2mfxrywQ4ydOShMdc34ImaO0S0ENP+aCOBuyNBIgP59wy5tBMmyai2/8eInYeVps4Td96mWInMMxzTe3Bar7eTLG5tWVKRSr/wc4NBPZ/ppoPAmCEsz9Y+VptRH9/FO8n7hsL9EFZ+xBKbG+C0SccGoyBDpA5j7/w= + - secure: Ptiv7phCImFP3ALIz+sMQzrZg8k7C1gLZbFBhWxjnQr3g06wIfX3Ls5y9OHvxid+lOZZjISui3wzBVgpVHqwHUYf96+r0mo6/mJ+F4ffUmShZANVaIMD/JRTnXhUQJbvntGLvxn1EYWPdNM+2IHJrMipnjHxU9tkgAnlel4Zdew= diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ba2bfc52d3..060a3bd91d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,7 +48,7 @@ We only accept issues that are bug reports or feature requests. Bugs must be iso - Multiple-line approach (one property and value per line) - Always a space after a property's colon (.e.g, `display: block;` and not `display:block;`) - End all lines with a semi-colon -- For multiple, comma-separated selectors, place each selector on it's own line +- For multiple, comma-separated selectors, place each selector on its own line - Attribute selectors, like `input[type="text"]` should always wrap the attribute's value in double quotes, for consistency and safety (see this [blog post on unquoted attribute values](http://mathiasbynens.be/notes/unquoted-attribute-values) that can lead to XSS attacks). ### JS diff --git a/Gruntfile.js b/Gruntfile.js index 7aad9b339a..71a87bdb0a 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,127 +1,149 @@ /* jshint node: true */ + module.exports = function(grunt) { - "use strict"; + "use strict"; - // Project configuration. - grunt.initConfig({ - // Metadata. - pkg: grunt.file.readJSON('package.json'), - banner: '/**\n' + - '* <%= pkg.name %>.js v<%= pkg.version %> by @fat and @mdo\n' + - '* Copyright <%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' + - '* <%= _.pluck(pkg.licenses, "url").join(", ") %>\n' + - '*/\n', - jqueryCheck: 'if (!jQuery) { throw new Error(\"Bootstrap requires jQuery\") }\n\n', - // Task configuration. - clean: { - dist: ['dist'] + // Project configuration. + grunt.initConfig({ + + // Metadata. + pkg: grunt.file.readJSON('package.json'), + banner: '/**\n' + + '* <%= pkg.name %>.js v<%= pkg.version %> by @fat and @mdo\n' + + '* Copyright <%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' + + '* <%= _.pluck(pkg.licenses, "url").join(", ") %>\n' + + '*/\n', + jqueryCheck: 'if (!jQuery) { throw new Error(\"Bootstrap requires jQuery\") }\n\n', + + // Task configuration. + clean: { + dist: ['dist'] + }, + + jshint: { + options: { + jshintrc: 'js/.jshintrc' + }, + gruntfile: { + src: 'Gruntfile.js' + }, + src: { + src: ['js/*.js'] + }, + test: { + src: ['js/tests/unit/*.js'] + } + }, + concat: { + options: { + banner: '<%= banner %><%= 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: { + banner: '<%= banner %>' + }, + bootstrap: { + src: ['<%= concat.bootstrap.dest %>'], + dest: 'dist/js/<%= pkg.name %>.min.js' + } + }, + + recess: { + options: { + compile: true + }, + bootstrap: { + src: ['less/bootstrap.less'], + dest: 'dist/css/<%= pkg.name %>.css' + }, + min: { + options: { + compress: true }, - concat: { - options: { - banner: '<%= banner %><%= 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' - } - }, - jshint: { - options: { - jshintrc: 'js/.jshintrc' - }, - gruntfile: { - src: 'Gruntfile.js' - }, - src: { - src: ['js/*.js'] - }, - test: { - src: ['js/tests/unit/*.js'] - } - }, - recess: { - options: { - compile: true - }, - bootstrap: { - files: { - 'dist/css/bootstrap.css': ['less/bootstrap.less'] - } - }, - min: { - options: { - compress: true - }, - files: { - 'dist/css/bootstrap.min.css': ['less/bootstrap.less'] - } - } - }, - uglify: { - options: { - banner: '<%= banner %>' - }, - bootstrap: { - files: { - 'dist/js/<%= pkg.name %>.min.js': ['<%= concat.bootstrap.dest %>'] - } - } - }, - qunit: { - options: { - inject: 'js/tests/unit/phantom.js' - }, - files: ['js/tests/*.html'] - }, - connect: { - server: { - options: { - port: 3000, - base: '.' - } - } - }, - watch: { - src: { - files: '<%= jshint.src.src %>', - tasks: ['jshint:src', 'qunit'] - }, - test: { - files: '<%= jshint.test.src %>', - tasks: ['jshint:test', 'qunit'] - }, - recess: { - files: 'less/*.less', - tasks: ['recess'] - } + src: ['less/bootstrap.less'], + dest: 'dist/css/<%= pkg.name %>.min.css' + } + }, + + qunit: { + options: { + inject: 'js/tests/unit/phantom.js' + }, + files: ['js/tests/*.html'] + }, + connect: { + server: { + options: { + port: 3000, + base: '.' } - }); + } + }, + + watch: { + src: { + files: '<%= jshint.src.src %>', + tasks: ['jshint:src', 'qunit'] + }, + test: { + files: '<%= jshint.test.src %>', + tasks: ['jshint:test', 'qunit'] + }, + recess: { + files: 'less/*.less', + tasks: ['recess'] + } + } + }); - // These plugins provide necessary tasks. - grunt.loadNpmTasks('grunt-contrib-connect'); - grunt.loadNpmTasks('grunt-contrib-clean'); - grunt.loadNpmTasks('grunt-contrib-concat'); - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-contrib-qunit'); - grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-recess'); + // These plugins provide necessary tasks. + grunt.loadNpmTasks('grunt-contrib-clean'); + grunt.loadNpmTasks('grunt-contrib-concat'); + grunt.loadNpmTasks('grunt-contrib-connect'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-qunit'); + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-recess'); + grunt.loadNpmTasks('browserstack-runner'); - // Test task. - grunt.registerTask('test', ['jshint', 'qunit']); + // Test task. + var testSubtasks = ['jshint', 'qunit']; + if (process.env.TRAVIS) { + testSubtasks.push('browserstack_runner'); + } + grunt.registerTask('test', testSubtasks); - // JS distribution task. - grunt.registerTask('dist-js', ['concat', 'uglify']); + // JS distribution task. + grunt.registerTask('dist-js', ['concat', 'uglify']); - // CSS distribution task. - grunt.registerTask('dist-css', ['recess']); + // CSS distribution task. + grunt.registerTask('dist-css', ['recess']); - // Full distribution task. - grunt.registerTask('dist', ['clean', 'dist-css', 'dist-js']); + // Full distribution task. + grunt.registerTask('dist', ['clean', 'dist-css', 'dist-js']); - // Default task. - grunt.registerTask('default', ['test', 'dist']); + // Default task. + grunt.registerTask('default', ['test', 'dist']); }; diff --git a/README.md b/README.md index 68e14506d2..d6f5893c15 100644 --- a/README.md +++ b/README.md @@ -63,13 +63,13 @@ When completed, you'll be able to run the various Grunt commands provided from t ### Available Grunt commands #### Build - `grunt` -Run `grunt` to run tests locally and compile the CSS and JavaScript into `/dist`. **Requires recess and uglify-js.** +Run `grunt` to run tests locally and compile the CSS and JavaScript into `/dist`. **Requires [recess](https://github.com/twitter/recess) and [uglify-js](https://github.com/mishoo/UglifyJS).** #### Only compile CSS and JavaScript - `grunt dist` -`grunt dist` creates the `/dist` directory with compiled files. **Requires recess and uglify-js.** +`grunt dist` creates the `/dist` directory with compiled files. **Requires [recess](https://github.com/twitter/recess) and [uglify-js](https://github.com/mishoo/UglifyJS).** #### Tests - `grunt test` -Runs jshint and qunit tests headlessly in [phantomjs](http://code.google.com/p/phantomjs/) (used for ci). **Requires phantomjs.** +Runs jshint and qunit tests headlessly in [phantomjs](https://github.com/ariya/phantomjs/) (used for CI). **Requires [phantomjs](https://github.com/ariya/phantomjs/).** #### Watch - `grunt watch` This is a convenience method for watching just Less files and automatically building them whenever you save. diff --git a/_includes/ads.html b/_includes/ads.html index 495e7ba47f..ba4775f5e3 100644 --- a/_includes/ads.html +++ b/_includes/ads.html @@ -1 +1 @@ -