diff --git a/.gitignore b/.gitignore index d60e71a5fd..042d47047f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,11 @@ # Ignore docs files _gh_pages _site + +# Ignore ruby files .ruby-version -Gemfile.lock +.bundle +vendor/cache # Numerous always-ignore extensions *.diff @@ -41,6 +44,9 @@ validation-status.json # SCSS-Lint scss-lint-report.xml +# grunt-contrib-sass cache +.sass-cache + # Folders to ignore bower_components node_modules diff --git a/.travis.yml b/.travis.yml index 5899bbf0f7..bb85115f61 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,15 +15,12 @@ before_install: install: - npm install -g grunt-cli - ./test-infra/s3_cache.py download npm-modules - - if [ "$TWBS_TEST" = validate-html ] && [ $TWBS_DO_VALIDATOR -ne 0 ]; then ./test-infra/s3_cache.py download rubygems; fi + - if [ -n "$BUNDLE_GEMFILE" ]; then ./test-infra/s3_cache.py download rubygems; fi after_script: - if [ "$TRAVIS_REPO_SLUG" != twbs-savage/bootstrap ] && [ "$TWBS_TEST" = core ]; then ./test-infra/s3_cache.py upload npm-modules; fi - - if [ "$TRAVIS_REPO_SLUG" != twbs-savage/bootstrap ] && [ "$TWBS_TEST" = validate-html ] && [ $TWBS_DO_VALIDATOR -ne 0 ]; then ./test-infra/s3_cache.py upload rubygems; fi + - if [ "$TRAVIS_REPO_SLUG" != twbs-savage/bootstrap ] && [ -n "$BUNDLE_GEMFILE" ]; then ./test-infra/s3_cache.py upload rubygems; fi env: global: - - JEKYLL_VERSION="2.5.1" - - ROUGE_VERSION="1.7.2" - - SCSS_LINT_VERSION="0.30.0" - SAUCE_USERNAME="bootstrap" - secure: "pJkBwnuae9dKU5tEcCqccfS1QQw7/meEcfz63fM7ba7QJNjoA6BaXj08L5Z3Vb5vBmVPwBawxo5Hp0jC0r/Z/O0hGnAmz/Cz09L+cy7dSAZ9x4hvZePSja/UAusaB5ogMoO8l2b773MzgQeSmrLbExr9BWLeqEfjC2hFgdgHLaQ=" - secure: "gqjqISbxBJK6byFbsmr1AyP1qoWH+rap06A2gI7v72+Tn2PU2nYkIMUkCvhZw6K889jv+LhQ/ybcBxDOXHpNCExCnSgB4dcnmYp+9oeNZb37jSP0rQ+Ib4OTLjzc3/FawE/fUq5kukZTC7porzc/k0qJNLAZRx3YLALmK1GIdUY=" @@ -35,8 +32,9 @@ env: - secure: "PabpUdG2dE40hHUkMCdxk1e9Ak3BOo0h7Y5/uekosLKOz5N60Xmn/ooyrSkvicLthXO4cfONFhO3/xSVRKQOxlUw4on5i0VuNK+QSqxJk0IDaRSZnTCcC8J7083K0YL+FvMdGQwcYwMY9LiwS8aS014IRkSQjsa+mjo3owP+dOU=" - secure: "G4/f4PVyVi9o6UbZMqw9YFmDu7cHqe9iymiXYd1RcnPXwhWAePX12m0PWMhUj5itJ180PTEddVip8PNOgBdqyrDxEPKkcgAW2EElVAPIKJXVfvDW64UjQ0H7NS7XvF7iLQUJp/XfmR7NJ7tT393AQdh8SGmuQpJhgYbwIWbES/k=" matrix: - - TWBS_TEST=core - - TWBS_TEST=validate-html + - TWBS_TEST=core TWBS_SASS=libsass BUNDLE_GEMFILE=test-infra/gemfiles/core.gemfile + - TWBS_TEST=core TWBS_SASS=sass BUNDLE_GEMFILE=test-infra/gemfiles/core.gemfile + - TWBS_TEST=validate-html BUNDLE_GEMFILE=Gemfile - TWBS_TEST=sauce-js-unit matrix: fast_finish: true diff --git a/Gemfile b/Gemfile index eb9646efef..23068bdfeb 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,11 @@ +# Ruby Gems for building and testing Bootstrap +# Run `grunt update-gemfile-lock` to update to the latest compatible versions + source 'https://rubygems.org' -group :development do +group :development, :test do gem 'jekyll', '~> 2.5.2' gem 'rouge', '~> 1.7.4' + gem 'sass', '~> 3.4.9' + gem 'scss-lint', '~> 0.31' end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000000..725379399c --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,78 @@ +GEM + remote: https://rubygems.org/ + specs: + blankslate (2.1.2.4) + celluloid (0.16.0) + timers (~> 4.0.0) + classifier-reborn (2.0.2) + fast-stemmer (~> 1.0) + coffee-script (2.3.0) + coffee-script-source + execjs + coffee-script-source (1.8.0) + colorator (0.1) + execjs (2.2.2) + fast-stemmer (1.0.2) + ffi (1.9.6) + hitimes (1.2.2) + jekyll (2.5.2) + classifier-reborn (~> 2.0) + colorator (~> 0.1) + jekyll-coffeescript (~> 1.0) + jekyll-gist (~> 1.0) + jekyll-paginate (~> 1.0) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 1.1) + kramdown (~> 1.3) + liquid (~> 2.6.1) + mercenary (~> 0.3.3) + pygments.rb (~> 0.6.0) + redcarpet (~> 3.1) + safe_yaml (~> 1.0) + toml (~> 0.1.0) + jekyll-coffeescript (1.0.1) + coffee-script (~> 2.2) + jekyll-gist (1.1.0) + jekyll-paginate (1.1.0) + jekyll-sass-converter (1.3.0) + sass (~> 3.2) + jekyll-watch (1.2.0) + listen (~> 2.7) + kramdown (1.5.0) + liquid (2.6.1) + listen (2.8.4) + celluloid (>= 0.15.2) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9) + mercenary (0.3.5) + parslet (1.5.0) + blankslate (~> 2.0) + posix-spawn (0.3.9) + pygments.rb (0.6.0) + posix-spawn (~> 0.3.6) + yajl-ruby (~> 1.1.0) + rainbow (2.0.0) + rb-fsevent (0.9.4) + rb-inotify (0.9.5) + ffi (>= 0.5.0) + redcarpet (3.2.2) + rouge (1.7.4) + safe_yaml (1.0.4) + sass (3.4.9) + scss-lint (0.31.0) + rainbow (~> 2.0) + sass (~> 3.4.1) + timers (4.0.1) + hitimes + toml (0.1.2) + parslet (~> 1.5.0) + yajl-ruby (1.1.0) + +PLATFORMS + ruby + +DEPENDENCIES + jekyll (~> 2.5.2) + rouge (~> 1.7.4) + sass (~> 3.4.9) + scss-lint (~> 0.31) diff --git a/Gruntfile.js b/Gruntfile.js index d09e6f5606..582f4ac308 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -17,6 +17,7 @@ module.exports = function (grunt) { var fs = require('fs'); var path = require('path'); + var glob = require('glob'); var npmShrinkwrap = require('npm-shrinkwrap'); var generateCommonJSModule = require('./grunt/bs-commonjs-generator.js'); @@ -144,25 +145,6 @@ module.exports = function (grunt) { files: 'js/tests/index.html' }, - sass: { - options: { - includePaths: ['scss'], - precision: 6, - sourceComments: false, - sourceMap: true - }, - core: { - files: { - 'dist/css/<%= pkg.name %>.css': 'scss/<%= pkg.name %>.scss' - } - }, - docs: { - files: { - 'docs/assets/css/docs.min.css': 'docs/assets/scss/docs.scss' - } - } - }, - scsslint: { scss: ['scss/*.scss', '!scss/_normalize.scss'], options: { @@ -342,13 +324,23 @@ module.exports = function (grunt) { exec: { npmUpdate: { command: 'npm update' + }, + bundleUpdate: { + command: function () { + // Update dev gems and all the test gemsets + return 'bundle update && ' + glob.sync('test-infra/gemfiles/*.gemfile').map(function (gemfile) { + return 'BUNDLE_GEMFILE=' + gemfile + ' bundle update'; + }).join(' && '); + } } } }); // These plugins provide necessary tasks. - require('load-grunt-tasks')(grunt, { scope: 'devDependencies' }); + 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 @@ -366,7 +358,8 @@ module.exports = function (grunt) { // 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', 'test-js', 'docs']); + process.env.TRAVIS_REPO_SLUG !== 'twbs-savage/bootstrap') { + testSubtasks = testSubtasks.concat(['dist-css', 'dist-js', 'test-scss', 'test-js', 'docs']); } // Skip HTML validation if running a different subset of the test suite if (runSubset('validate-html') && @@ -392,7 +385,12 @@ module.exports = function (grunt) { grunt.registerTask('test-scss', ['scsslint:scss']); // 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:docs']); + grunt.registerTask('dist-css', ['sass-compile', 'autoprefixer:core', 'usebanner', 'csscomb:dist', 'cssmin:core', 'cssmin:docs']); // Full distribution task. @@ -435,4 +433,7 @@ module.exports = function (grunt) { done(); }); }); + // Task for updating the cached RubyGem packages used by the Travis build (which are controlled by test-infra/Gemfile.lock). + // This task should be run and the updated file should be committed whenever Bootstrap's RubyGem dependencies change. + grunt.registerTask('update-gemfile-lock', ['exec:bundleUpdate']); }; diff --git a/dist/css/bootstrap.css b/dist/css/bootstrap.css index fbb56e0946..5045aa462c 100644 --- a/dist/css/bootstrap.css +++ b/dist/css/bootstrap.css @@ -447,7 +447,7 @@ ul ul, ul ol, ol ul, ol ol { margin-bottom: 0; } -.list-unstyled, .nav { +.list-unstyled, .list-inline, .nav { padding-left: 0; list-style: none; } @@ -607,7 +607,7 @@ pre code { } @media (min-width: 34em) { .container { - max-width: 34em; + max-width: 34rem; } } @media (min-width: 48em) { @@ -620,6 +620,11 @@ pre code { max-width: 60rem; } } +@media (min-width: 75em) { + .container { + max-width: 72.25rem; + } +} .container-fluid { padding-right: .75rem; @@ -647,7 +652,7 @@ pre code { clear: both; } -.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xl-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xl-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xl-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xl-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xl-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xl-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xl-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xl-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xl-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xl-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xl-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12, .col-xl-12 { +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 { position: relative; min-height: 1px; padding-right: .75rem; @@ -1492,7 +1497,7 @@ pre code { } } -@media (min-width: 62em) { +@media (min-width: 75em) { .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 { float: left; } @@ -2725,7 +2730,7 @@ input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="butto z-index: 990; } -.pull-right > .dropdown-menu, .navbar-right > .dropdown-menu { +.pull-right > .dropdown-menu { right: 0; left: auto; } @@ -3485,7 +3490,12 @@ input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="butto } @media (min-width: 34em) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; margin-right: -1rem; } .navbar-right ~ .navbar-right { @@ -3990,7 +4000,7 @@ a.label:hover, a.label:focus { .badge:empty { display: none; } -.badge.pull-left, .badge.navbar-left, .badge.pull-right, .badge.navbar-right { +.badge.pull-left, .badge.pull-right { top: .2em; } .list-group-item.active > .badge, .nav-pills > .active > a > .badge { @@ -4322,11 +4332,11 @@ a.badge:hover, a.badge:focus { display: block; } -.media-right, .media > .pull-right, .media > .navbar-right { +.media-right, .media > .pull-right { padding-left: 10px; } -.media-left, .media > .pull-left, .media > .navbar-left { +.media-left, .media > .pull-left { padding-right: 10px; } @@ -4705,19 +4715,23 @@ a.list-group-item-state.active, a.list-group-item-state.active:hover, a.list-gro .tooltip.in { opacity: .9; } -.tooltip.top { + +.tooltip-top { padding: 5px 0; margin-top: -3px; } -.tooltip.right { + +.tooltip-right { padding: 0 5px; margin-left: 3px; } -.tooltip.bottom { + +.tooltip-bottom { padding: 5px 0; margin-top: 3px; } -.tooltip.left { + +.tooltip-left { padding: 0 5px; margin-left: -3px; } @@ -4740,62 +4754,37 @@ a.list-group-item-state.active, a.list-group-item-state.active:hover, a.list-gro border-style: solid; } -.tooltip.top .tooltip-arrow { +.tooltip-top .tooltip-arrow { bottom: 0; left: 50%; margin-left: -5px; border-width: 5px 5px 0; border-top-color: #000; } -.tooltip.top-left .tooltip-arrow { - right: 5px; - bottom: 0; - margin-bottom: -5px; - border-width: 5px 5px 0; - border-top-color: #000; -} -.tooltip.top-right .tooltip-arrow { - bottom: 0; - left: 5px; - margin-bottom: -5px; - border-width: 5px 5px 0; - border-top-color: #000; -} -.tooltip.right .tooltip-arrow { + +.tooltip-right .tooltip-arrow { top: 50%; left: 0; margin-top: -5px; border-width: 5px 5px 5px 0; border-right-color: #000; } -.tooltip.left .tooltip-arrow { + +.tooltip-left .tooltip-arrow { top: 50%; right: 0; margin-top: -5px; border-width: 5px 0 5px 5px; border-left-color: #000; } -.tooltip.bottom .tooltip-arrow { + +.tooltip-bottom .tooltip-arrow { top: 0; left: 50%; margin-left: -5px; border-width: 0 5px 5px; border-bottom-color: #000; } -.tooltip.bottom-left .tooltip-arrow { - top: 0; - right: 5px; - margin-top: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000; -} -.tooltip.bottom-right .tooltip-arrow { - top: 0; - left: 5px; - margin-top: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000; -} .popover { position: absolute; @@ -4819,16 +4808,20 @@ a.list-group-item-state.active, a.list-group-item-state.active:hover, a.list-gro -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); box-shadow: 0 5px 10px rgba(0, 0, 0, .2); } -.popover.top { + +.popover-top { margin-top: -10px; } -.popover.right { + +.popover-right { margin-left: 10px; } -.popover.bottom { + +.popover-bottom { margin-top: 10px; } -.popover.left { + +.popover-left { margin-left: -10px; } @@ -4845,7 +4838,7 @@ a.list-group-item-state.active, a.list-group-item-state.active:hover, a.list-gro padding: 9px 14px; } -.popover > .arrow, .popover > .arrow:after { +.popover-arrow, .popover-arrow:after { position: absolute; display: block; width: 0; @@ -4854,65 +4847,68 @@ a.list-group-item-state.active, a.list-group-item-state.active:hover, a.list-gro border-style: solid; } -.popover > .arrow { +.popover-arrow { border-width: 11px; } -.popover > .arrow:after { +.popover-arrow:after { content: ""; border-width: 10px; } -.popover.top > .arrow { +.popover-top > .popover-arrow { bottom: -11px; left: 50%; margin-left: -11px; border-top-color: rgba(0, 0, 0, .25); border-bottom-width: 0; } -.popover.top > .arrow:after { +.popover-top > .popover-arrow:after { bottom: 1px; margin-left: -10px; content: ""; border-top-color: #fff; border-bottom-width: 0; } -.popover.right > .arrow { + +.popover-right > .popover-arrow { top: 50%; left: -11px; margin-top: -11px; border-right-color: rgba(0, 0, 0, .25); border-left-width: 0; } -.popover.right > .arrow:after { +.popover-right > .popover-arrow:after { bottom: -10px; left: 1px; content: ""; border-right-color: #fff; border-left-width: 0; } -.popover.bottom > .arrow { + +.popover-bottom > .popover-arrow { top: -11px; left: 50%; margin-left: -11px; border-top-width: 0; border-bottom-color: rgba(0, 0, 0, .25); } -.popover.bottom > .arrow:after { +.popover-bottom > .popover-arrow:after { top: 1px; margin-left: -10px; content: ""; border-top-width: 0; border-bottom-color: #fff; } -.popover.left > .arrow { + +.popover-left > .popover-arrow { top: 50%; right: -11px; margin-top: -11px; border-right-width: 0; border-left-color: rgba(0, 0, 0, .25); } -.popover.left > .arrow:after { +.popover-left > .popover-arrow:after { right: 1px; bottom: -10px; content: ""; @@ -5139,11 +5135,11 @@ a.list-group-item-state.active, a.list-group-item-state.active:hover, a.list-gro margin-left: auto; } -.pull-right, .navbar-right { +.pull-right { float: right !important; } -.pull-left, .navbar-left { +.pull-left { float: left !important; } diff --git a/docs/_includes/js/popovers.html b/docs/_includes/js/popovers.html index ab33baccbd..4557a44a42 100644 --- a/docs/_includes/js/popovers.html +++ b/docs/_includes/js/popovers.html @@ -39,24 +39,24 @@ $(function () {

Static popover

Four options are available: top, right, bottom, and left aligned.

-
-
+
+

Popover top

Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.

-
-
+
+

Popover right

Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.

-
-
+
+

Popover bottom

@@ -64,8 +64,8 @@ $(function () {
-
-
+
+

Popover left

Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.

@@ -207,12 +207,12 @@ sagittis lacus vel augue laoreet rutrum faucibus."> template string - '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>' + '<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'

Base HTML to use when creating the popover.

The popover's title will be injected into the .popover-title.

The popover's content will be injected into the .popover-content.

-

.arrow will become the popover's arrow.

+

.popover-arrow will become the popover's arrow.

The outermost wrapper element should have the .popover class.

diff --git a/docs/_includes/js/tooltips.html b/docs/_includes/js/tooltips.html index ae553e0df0..b8293c9f5d 100644 --- a/docs/_includes/js/tooltips.html +++ b/docs/_includes/js/tooltips.html @@ -12,25 +12,25 @@

Static tooltip

Four options are available: top, right, bottom, and left aligned.

-