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 @@ -
\ No newline at end of file +
diff --git a/_includes/footer.html b/_includes/footer.html index 47a671b26f..83ff87e269 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -4,7 +4,7 @@ - + @@ -15,7 +15,6 @@ var _gauges = _gauges || []; (function() { var t = document.createElement('script'); - t.type = 'text/javascript'; t.async = true; t.id = 'gauges-tracker'; t.setAttribute('data-site-id', '4f0dc9fef5a1f55508000013'); diff --git a/_includes/header.html b/_includes/header.html index b5eff5f5ed..827b1c2c91 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -31,12 +31,12 @@ - - + @@ -124,11 +120,11 @@ bootstrap/ -

Bootstrap is built to work best in the latest desktop and mobile browsers, meaning older and less advanced browsers might receive a less stylized, though fully functional, version of certain components.

@@ -153,10 +149,64 @@ bootstrap/ {% endhighlight %}

See this StackOverflow question for more information.

+ +

Windows Phone 8 and Internet Explorer 10

+

Internet Explorer 10 doesn't differentiate device width from viewport width, and thus doesn't properly apply the media queries in Bootstrap's CSS. To address this, you can optionally include the following CSS and JavaScript to work around this problem until Microsoft issues a fix.

+{% highlight css %} +@-webkit-viewport { width: device-width; } +@-moz-viewport { width: device-width; } +@-ms-viewport { width: device-width; } +@-o-viewport { width: device-width; } +@viewport { width: device-width; } +{% endhighlight %} + +{% highlight js %} +if (navigator.userAgent.match(/IEMobile\/10\.0/)) { + var msViewportStyle = document.createElement("style"); + msViewportStyle.appendChild( + document.createTextNode( + "@-ms-viewport{width:auto!important}" + ) + ); + document.getElementsByTagName("head")[0].appendChild(msViewportStyle); +} +{% endhighlight %} +

For more information and usage guidelines, read Windows Phone 8 and Device-Width.

+ +
+ +

While we don't officially support any third party plugins or add-ons, we do offer some helpful advice to help avoid potential issues in your projects.

+ +

Google Maps

+

If you're using Google Maps on a Bootstrapped project, you might run into some display problems due to our use of * { box-sizing: border-box; }. Previously, you may have also ran into issues with the use of max-width on images. The following snippet should avoid all those problems.

+{% highlight css %} +/* Fix Google Maps canvas + * + * Wrap your Google Maps embed in a `.google-map-canvas` to reset Bootstrap's + * global `box-sizing` changes. You may optionally need to reset the `max-width` + * on images in case you've applied that anywhere else. (That shouldn't be as + * necessary with Bootstrap 3 though as that behavior is relegated to the + * `.img-responsive` class.) + */ + +.google-map-canvas, +.google-map-canvas * { .box-sizing(content-box); } + +/* Optional responsive image override */ +img { max-width: none; } +{% endhighlight %} +
+ + + +
diff --git a/index.html b/index.html index 37b634b42e..d6f4cf28f0 100644 --- a/index.html +++ b/index.html @@ -9,7 +9,8 @@ base_url: "./"

Bootstrap 3

Sleek, intuitive, and powerful mobile-first front-end framework for faster and easier web development.

- Download Bootstrap + Download latest BS3

+

Heads up! Downloads are pulled directly from the latest commited code on GitHub, and as a result our docs may at times be out of sync.

diff --git a/javascript.html b/javascript.html index 6d7b7ccad1..3dafc4ff16 100644 --- a/javascript.html +++ b/javascript.html @@ -15,7 +15,7 @@ base_url: "../"

Individual or compiled

-

Plugins can be included individually (using bootstrap's individual *.js files, or all at once (using bootstrap.js or the minified bootstrap.min.js.

+

Plugins can be included individually (using Bootstrap's individual *.js files, or all at once (using bootstrap.js or the minified bootstrap.min.js.

Do not attempt to include both.

@@ -24,11 +24,11 @@ base_url: "../"

Plugin dependencies

-

Some plugins and CSS components depend on other plugins. If you include plugins individually, make sure to check for these dependencies in the docs.

+

Some plugins and CSS components depend on other plugins. If you include plugins individually, make sure to check for these dependencies in the docs. Also note that all plugins depend on jQuery (this means jQuery must be included before the plugin files).

Data attributes

-

You can use all Bootstrap plugins purely through the markup API without writing a single line of JavaScript. This is Bootstrap's first class API and should be your first consideration when using a plugin.

+

You can use all Bootstrap plugins purely through the markup API without writing a single line of JavaScript. This is Bootstrap's first-class API and should be your first consideration when using a plugin.

That said, in some situations it may be desirable to turn this functionality off. Therefore, we also provide the ability to disable the data attribute API by unbinding all events on the document namespaced with data-api. This looks like this: {% highlight js %} @@ -59,12 +59,12 @@ $("#myModal").modal('show') // initializes and invokes show immed

Sometimes it is necessary to use Bootstrap plugins with other UI frameworks. In these circumstances, namespace collisions can occasionally occur. If this happens, you may call .noConflict on the plugin you wish to revert the value of.

{% highlight js %} var bootstrapButton = $.fn.button.noConflict() // return $.fn.button to previously assigned value -$.fn.bootstrapBtn = bootstrapButton // give $().bootstrapBtn the bootstrap functionality +$.fn.bootstrapBtn = bootstrapButton // give $().bootstrapBtn the Bootstrap functionality {% endhighlight %}

Events

Bootstrap provides custom events for most plugin's unique actions. Generally, these come in an infinitive and past participle form - where the infinitive (ex. show) is triggered at the start of an event, and its past participle form (ex. shown) is trigger on the completion of an action.

-

As of 3.0.0, all bootstrap events are namespaced.

+

As of 3.0.0, all Bootstrap events are namespaced.

All infinitive events provide preventDefault functionality. This provides the ability to stop the execution of an action before it starts.

{% highlight js %} $('#myModal').on('show.bs.modal', function (e) { @@ -89,7 +89,7 @@ $('#myModal').on('show.bs.modal', function (e) {

About transitions

For simple transition effects, include transition.js once alongside the other JS files. If you're using the compiled (or minified) bootstrap.js, there is no need to include this—it's already there.

What's inside

-

Transition.js is a basic helper for transitionEnd events as well as a css transition emulator. It's used by the other plugins to check for css transition support and to catch hanging transitions.

+

Transition.js is a basic helper for transitionEnd events as well as a CSS transition emulator. It's used by the other plugins to check for CSS transition support and to catch hanging transitions.

@@ -189,11 +189,11 @@ $('#myModal').on('show.bs.modal', function (e) {
- Launch demo modal + Launch demo modal
{% highlight html %} - Launch demo modal + Launch demo modal @@ -262,7 +262,7 @@ $('#myModal').on('show.bs.modal', function (e) { remote path false -

If a remote URL is provided, content will be loaded via jQuery's load method and injected into the .modal-body. If you're using the data api, you may alternatively use the href tag to specify the remote source. An example of this is shown below:

+

If a remote URL is provided, content will be loaded via jQuery's load method and injected into the .modal-body. If you're using the data api, you may alternatively use the href attribute to specify the remote source. An example of this is shown below:

{% highlight html %} Click me {% endhighlight %} @@ -397,7 +397,7 @@ $('#myModal').on('hidden.bs.modal', function () {