mirror of https://github.com/twbs/bootstrap.git
Merge branch 'master' into equal-height-experiment
This commit is contained in:
commit
11a835f566
11
.travis.yml
11
.travis.yml
|
|
@ -4,14 +4,15 @@ node_js:
|
|||
before_install:
|
||||
- time sudo pip install --use-mirrors -r test-infra/requirements.txt
|
||||
- rvm use 1.9.3 --fuzzy
|
||||
- if [ "$TWBS_TEST" = validate-html ]; then echo "ruby=$(basename $(rvm gemdir)) jekyll=$JEKYLL_VERSION" > pseudo_Gemfile.lock; fi
|
||||
- export GEMDIR=$(rvm gemdir)
|
||||
- if [ "$TWBS_TEST" = validate-html ]; then echo "ruby=$(basename $GEMDIR) jekyll=$JEKYLL_VERSION" > pseudo_Gemfile.lock; fi
|
||||
install:
|
||||
- time npm install -g grunt-cli
|
||||
- time ./test-infra/s3_cache.py download 'npm packages' test-infra/npm-shrinkwrap.canonical.json ./node_modules || time ./test-infra/uncached-npm-install.sh
|
||||
- if [ "$TWBS_TEST" = validate-html ]; then time ./test-infra/s3_cache.py download rubygems pseudo_Gemfile.lock $(rvm gemdir) || gem install -N jekyll -v $JEKYLL_VERSION; fi
|
||||
- ./test-infra/s3_cache.py download npm-modules
|
||||
- if [ "$TWBS_TEST" = validate-html ]; then ./test-infra/s3_cache.py download rubygems; fi
|
||||
after_script:
|
||||
- if [ "$TWBS_TEST" = core ]; then time ./test-infra/s3_cache.py upload 'npm packages' test-infra/npm-shrinkwrap.canonical.json ./node_modules; fi
|
||||
- if [ "$TWBS_TEST" = validate-html ]; then time ./test-infra/s3_cache.py upload rubygems pseudo_Gemfile.lock $(rvm gemdir); fi
|
||||
- if [ "$TWBS_TEST" = core ]; then ./test-infra/s3_cache.py upload npm-modules; fi
|
||||
- if [ "$TWBS_TEST" = validate-html ]; then ./test-infra/s3_cache.py upload rubygems; fi
|
||||
env:
|
||||
global:
|
||||
- JEKYLL_VERSION: 1.5.0
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@ module.exports = function (grunt) {
|
|||
src: '<%= jshint.test.src %>'
|
||||
},
|
||||
assets: {
|
||||
options: {
|
||||
requireCamelCaseOrUpperCaseIdentifiers: null
|
||||
},
|
||||
src: '<%= jshint.assets.src %>'
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# [Bootstrap](http://getbootstrap.com) [](http://badge.fury.io/bo/bootstrap) [](http://travis-ci.org/twbs/bootstrap) [](https://david-dm.org/twbs/bootstrap#info=devDependencies)
|
||||
# [Bootstrap](http://getbootstrap.com) [](http://badge.fury.io/bo/bootstrap) [](http://travis-ci.org/twbs/bootstrap) [](https://david-dm.org/twbs/bootstrap#info=devDependencies)
|
||||
[](https://saucelabs.com/u/bootstrap)
|
||||
|
||||
Bootstrap is a sleek, intuitive, and powerful front-end framework for faster and easier web development, created by [Mark Otto](http://twitter.com/mdo) and [Jacob Thornton](http://twitter.com/fat), and maintained by the [core team](https://github.com/twbs?tab=members) with the massive support and involvement of the community.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
|
||||
/*! normalize.css v3.0.0 | MIT License | git.io/normalize */
|
||||
/*! normalize.css v3.0.1 | MIT License | git.io/normalize */
|
||||
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
|
|
@ -6684,7 +6684,7 @@ button.close {
|
|||
|
||||
.tooltip {
|
||||
position: absolute;
|
||||
z-index: 1030;
|
||||
z-index: 1070;
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
line-height: 1.4;
|
||||
|
|
@ -6800,7 +6800,7 @@ button.close {
|
|||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 1010;
|
||||
z-index: 1060;
|
||||
display: none;
|
||||
max-width: 276px;
|
||||
padding: 1px;
|
||||
|
|
@ -7053,11 +7053,13 @@ button.close {
|
|||
.carousel-control .icon-prev,
|
||||
.carousel-control .glyphicon-chevron-left {
|
||||
right: 50%;
|
||||
margin-right: -10px;
|
||||
}
|
||||
|
||||
.carousel-control .icon-next,
|
||||
.carousel-control .glyphicon-chevron-right {
|
||||
left: 50%;
|
||||
margin-left: -10px;
|
||||
}
|
||||
|
||||
.carousel-control .icon-prev,
|
||||
|
|
@ -7065,7 +7067,6 @@ button.close {
|
|||
width: 20px;
|
||||
height: 20px;
|
||||
margin-top: -10px;
|
||||
margin-right: -10px;
|
||||
font-family: serif;
|
||||
}
|
||||
|
||||
|
|
@ -7134,10 +7135,19 @@ button.close {
|
|||
width: 30px;
|
||||
height: 30px;
|
||||
margin-top: -15px;
|
||||
margin-right: -15px;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.carousel-control .glyphicon-chevron-left,
|
||||
.carousel-control .icon-prev {
|
||||
margin-right: -15px;
|
||||
}
|
||||
|
||||
.carousel-control .glyphicon-chevron-right,
|
||||
.carousel-control .icon-next {
|
||||
margin-left: -15px;
|
||||
}
|
||||
|
||||
.carousel-caption {
|
||||
right: 20%;
|
||||
left: 20%;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -4,7 +4,7 @@
|
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
|
||||
/*! normalize.css v3.0.0 | MIT License | git.io/normalize */
|
||||
/*! normalize.css v3.0.1 | MIT License | git.io/normalize */
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
|
|
@ -5399,7 +5399,7 @@ button.close {
|
|||
}
|
||||
.tooltip {
|
||||
position: absolute;
|
||||
z-index: 1030;
|
||||
z-index: 1070;
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
line-height: 1.4;
|
||||
|
|
@ -5499,7 +5499,7 @@ button.close {
|
|||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1010;
|
||||
z-index: 1060;
|
||||
display: none;
|
||||
max-width: 276px;
|
||||
padding: 1px;
|
||||
|
|
@ -5717,17 +5717,18 @@ button.close {
|
|||
.carousel-control .icon-prev,
|
||||
.carousel-control .glyphicon-chevron-left {
|
||||
left: 50%;
|
||||
margin-left: -10px;
|
||||
}
|
||||
.carousel-control .icon-next,
|
||||
.carousel-control .glyphicon-chevron-right {
|
||||
right: 50%;
|
||||
margin-right: -10px;
|
||||
}
|
||||
.carousel-control .icon-prev,
|
||||
.carousel-control .icon-next {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-top: -10px;
|
||||
margin-left: -10px;
|
||||
font-family: serif;
|
||||
}
|
||||
.carousel-control .icon-prev:before {
|
||||
|
|
@ -5788,9 +5789,16 @@ button.close {
|
|||
width: 30px;
|
||||
height: 30px;
|
||||
margin-top: -15px;
|
||||
margin-left: -15px;
|
||||
font-size: 30px;
|
||||
}
|
||||
.carousel-control .glyphicon-chevron-left,
|
||||
.carousel-control .icon-prev {
|
||||
margin-left: -15px;
|
||||
}
|
||||
.carousel-control .glyphicon-chevron-right,
|
||||
.carousel-control .icon-next {
|
||||
margin-right: -15px;
|
||||
}
|
||||
.carousel-caption {
|
||||
right: 20%;
|
||||
left: 20%;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -313,7 +313,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
|
|||
|
||||
if (pos > (this.$items.length - 1) || pos < 0) return
|
||||
|
||||
if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) })
|
||||
if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid". not a typo. past tense of "to slide".
|
||||
if (activeIndex == pos) return this.pause().cycle()
|
||||
|
||||
return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
|
||||
|
|
@ -367,7 +367,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
|
|||
|
||||
if (this.$indicators.length) {
|
||||
this.$indicators.find('.active').removeClass('active')
|
||||
this.$element.one('slid.bs.carousel', function () {
|
||||
this.$element.one('slid.bs.carousel', function () { // yes, "slid". not a typo. past tense of "to slide".
|
||||
var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])
|
||||
$nextIndicator && $nextIndicator.addClass('active')
|
||||
})
|
||||
|
|
@ -383,14 +383,14 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
|
|||
$next.removeClass([type, direction].join(' ')).addClass('active')
|
||||
$active.removeClass(['active', direction].join(' '))
|
||||
that.sliding = false
|
||||
setTimeout(function () { that.$element.trigger('slid.bs.carousel') }, 0)
|
||||
setTimeout(function () { that.$element.trigger('slid.bs.carousel') }, 0) // yes, "slid". not a typo. past tense of "to slide".
|
||||
})
|
||||
.emulateTransitionEnd($active.css('transition-duration').slice(0, -1) * 1000)
|
||||
} else {
|
||||
$active.removeClass('active')
|
||||
$next.addClass('active')
|
||||
this.sliding = false
|
||||
this.$element.trigger('slid.bs.carousel')
|
||||
this.$element.trigger('slid.bs.carousel') // yes, "slid". not a typo. past tense of "to slide".
|
||||
}
|
||||
|
||||
isCycling && this.cycle()
|
||||
|
|
@ -511,8 +511,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
|
|||
|
||||
this.$element
|
||||
.removeClass('collapse')
|
||||
.addClass('collapsing')
|
||||
[dimension](0)
|
||||
.addClass('collapsing')[dimension](0)
|
||||
|
||||
this.transitioning = 1
|
||||
|
||||
|
|
@ -520,8 +519,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
|
|||
if (e && e.target != this.$element[0]) return
|
||||
this.$element
|
||||
.removeClass('collapsing')
|
||||
.addClass('collapse in')
|
||||
[dimension]('auto')
|
||||
.addClass('collapse in')[dimension]('auto')
|
||||
this.transitioning = 0
|
||||
this.$element.trigger('shown.bs.collapse')
|
||||
}
|
||||
|
|
@ -532,8 +530,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
|
|||
|
||||
this.$element
|
||||
.one($.support.transition.end, $.proxy(complete, this))
|
||||
.emulateTransitionEnd(350)
|
||||
[dimension](this.$element[0][scrollSize])
|
||||
.emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize])
|
||||
}
|
||||
|
||||
Collapse.prototype.hide = function () {
|
||||
|
|
@ -545,9 +542,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
|
|||
|
||||
var dimension = this.dimension()
|
||||
|
||||
this.$element
|
||||
[dimension](this.$element[dimension]())
|
||||
[0].offsetHeight
|
||||
this.$element[dimension](this.$element[dimension]())[0].offsetHeight
|
||||
|
||||
this.$element
|
||||
.addClass('collapsing')
|
||||
|
|
@ -795,11 +790,12 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
|
|||
// ======================
|
||||
|
||||
var Modal = function (element, options) {
|
||||
this.options = options
|
||||
this.$body = $(document.body)
|
||||
this.$element = $(element)
|
||||
this.$backdrop =
|
||||
this.isShown = null
|
||||
this.options = options
|
||||
this.$body = $(document.body)
|
||||
this.$element = $(element)
|
||||
this.$backdrop =
|
||||
this.isShown = null
|
||||
this.scrollbarWidth = 0
|
||||
|
||||
if (this.options.remote) {
|
||||
this.$element
|
||||
|
|
@ -830,6 +826,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
|
|||
|
||||
this.isShown = true
|
||||
|
||||
this.checkScrollbar()
|
||||
this.$body.addClass('modal-open')
|
||||
|
||||
this.setScrollbar()
|
||||
|
|
@ -976,11 +973,14 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
|
|||
}
|
||||
}
|
||||
|
||||
Modal.prototype.checkScrollbar = function () {
|
||||
if (document.body.clientWidth >= window.innerWidth) return
|
||||
this.scrollbarWidth = this.scrollbarWidth || this.measureScrollbar()
|
||||
}
|
||||
|
||||
Modal.prototype.setScrollbar = function () {
|
||||
if (document.body.clientHeight <= window.innerHeight) return
|
||||
var scrollbarWidth = this.measureScrollbar()
|
||||
var bodyPad = parseInt(this.$body.css('padding-right') || 0)
|
||||
if (scrollbarWidth) this.$body.css('padding-right', bodyPad + scrollbarWidth)
|
||||
var bodyPad = parseInt(this.$body.css('padding-right') || 0)
|
||||
if (this.scrollbarWidth) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
|
||||
}
|
||||
|
||||
Modal.prototype.resetScrollbar = function () {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -13,6 +13,11 @@
|
|||
description: Bootstrap auf Deutsch
|
||||
url: http://holdirbootstrap.de/
|
||||
|
||||
- name: Italian
|
||||
code: it
|
||||
description: Bootstrap in Italiano
|
||||
url: http://www.hackerstribe.com/guide/IT-bootstrap-3.1.1/
|
||||
|
||||
- name: Korean
|
||||
code: ko
|
||||
description: Bootstrap 한국어
|
||||
|
|
|
|||
|
|
@ -21,6 +21,10 @@
|
|||
<h4>Don't mix with other components</h4>
|
||||
<p>Icon classes cannot be directly combined with other components. They should not be used along with other classes on the same element. Instead, add a nested <code><span></code> and apply the icon classes to the <code><span></code>.</p>
|
||||
</div>
|
||||
<div class="bs-callout bs-callout-danger">
|
||||
<h4>Only for use on empty elements</h4>
|
||||
<p>Icon classes should only be used on elements that contain no text content and have no child elements.</p>
|
||||
</div>
|
||||
{% highlight html %}
|
||||
<span class="glyphicon glyphicon-search"></span>
|
||||
{% endhighlight %}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@
|
|||
<h4>Requires JavaScript</h4>
|
||||
<p>If JavaScript is disabled and the viewport is narrow enough that the navbar collapses, it will be impossible to expand the navbar and view the content within the <code>.navbar-collapse</code>.</p>
|
||||
</div>
|
||||
<div class="bs-callout bs-callout-info">
|
||||
<h4>Changing the collapsed mobile navbar breakpoint</h4>
|
||||
<p>The navbar collapses into its vertical mobile view when the viewport is narrower than <code>@grid-float-breakpoint</code>, and expands into its horizontal non-mobile view when the viewport is at least <code>@grid-float-breakpoint</code> in width. Adjust this variable in the Less source to control when the navbar collapses/expands. The default value is <code>768px</code> (the smallest "small" or "tablet" screen).</p>
|
||||
</div>
|
||||
|
||||
<div class="bs-example">
|
||||
<nav class="navbar navbar-default" role="navigation">
|
||||
|
|
@ -38,7 +42,7 @@
|
|||
<li class="active"><a href="#">Link</a></li>
|
||||
<li><a href="#">Link</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
|
|
@ -59,7 +63,7 @@
|
|||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="#">Link</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
|
|
@ -93,7 +97,7 @@
|
|||
<li class="active"><a href="#">Link</a></li>
|
||||
<li><a href="#">Link</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
|
|
@ -114,7 +118,7 @@
|
|||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="#">Link</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@
|
|||
|
||||
|
||||
<h2 id="tables-responsive">Responsive tables</h2>
|
||||
<p>Create responsive tables by wrapping any <code>.table</code> in <code>.table-responsive</code> to make them scroll horizontally up to small devices (under 768px). When viewing on anything larger than 768px wide, you will not see any difference in these tables.</p>
|
||||
<p>Create responsive tables by wrapping any <code>.table</code> in <code>.table-responsive</code> to make them scroll horizontally on small devices (under 768px). When viewing on anything larger than 768px wide, you will not see any difference in these tables.</p>
|
||||
<div class="bs-example">
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
|
|
|
|||
|
|
@ -146,10 +146,10 @@ You can use the mark tag to <mark>highlight</mark> text.
|
|||
<h3>Underlined text</h3>
|
||||
<p>To underline text use the <code><u></code> tag.</p>
|
||||
<div class="bs-example">
|
||||
<p><u>This line of text is will render as underlined</u></p>
|
||||
<p><u>This line of text will render as underlined</u></p>
|
||||
</div>
|
||||
{% highlight html %}
|
||||
<u>This line of text is will render as underlined</u>
|
||||
<u>This line of text will render as underlined</u>
|
||||
{% endhighlight %}
|
||||
|
||||
<p>Make use of HTML's default emphasis tags with lightweight styles.</p>
|
||||
|
|
|
|||
|
|
@ -176,11 +176,13 @@ if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
|
|||
<p>On <code><select></code> elements, the Android stock browser will not display the side controls if there is a <code>border-radius</code> and/or <code>border</code> applied. Use the snippet of code below to remove the offending CSS and render the <code><select></code> as an unstyled element on the Android stock browser. The user agent sniffing avoids interference with Chrome, Safari, and Mozilla browsers.</p>
|
||||
{% highlight html %}
|
||||
<script>
|
||||
var nua = navigator.userAgent
|
||||
var isAndroid = (nua.indexOf('Mozilla/5.0') > -1 && nua.indexOf('Android ') > -1 && nua.indexOf('AppleWebKit') > -1 && nua.indexOf('Chrome') === -1)
|
||||
if (isAndroid) {
|
||||
$('select.form-control').removeClass('form-control').css('width', '100%')
|
||||
}
|
||||
$(function () {
|
||||
var nua = navigator.userAgent
|
||||
var isAndroid = (nua.indexOf('Mozilla/5.0') > -1 && nua.indexOf('Android ') > -1 && nua.indexOf('AppleWebKit') > -1 && nua.indexOf('Chrome') === -1)
|
||||
if (isAndroid) {
|
||||
$('select.form-control').removeClass('form-control').css('width', '100%')
|
||||
}
|
||||
})
|
||||
</script>
|
||||
{% endhighlight %}
|
||||
<p>Want to see an example? <a href="http://jsbin.com/OyaqoDO/2">Check out this JS Bin demo.</a></p>
|
||||
|
|
|
|||
|
|
@ -8,21 +8,21 @@
|
|||
<h3 id="download-bootstrap">Bootstrap</h3>
|
||||
<p>Compiled and minified CSS, JavaScript, and fonts. No docs or original source files are included.</p>
|
||||
<p>
|
||||
<a href="{{ site.download.dist }}" class="btn btn-lg btn-outline" role="button" onclick="_gaq.push(['_trackEvent', 'Getting started', 'Download', 'Download compiled']);">Download Bootstrap</a>
|
||||
<a href="{{ site.download.dist }}" class="btn btn-lg btn-outline" role="button" onclick="ga('send', 'event', 'Getting started', 'Download', 'Download compiled');">Download Bootstrap</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<h3 id="download-source">Source code</h3>
|
||||
<p>Source Less, JavaScript, and font files, along with our docs. <strong>Requires a Less compiler and <a href="{{ site.repo }}#compiling-css-and-javascript">some setup.</a></strong></p>
|
||||
<p>
|
||||
<a href="{{ site.download.source }}" class="btn btn-lg btn-outline" role="button" onclick="_gaq.push(['_trackEvent', 'Getting started', 'Download', 'Download source']);">Download source</a>
|
||||
<a href="{{ site.download.source }}" class="btn btn-lg btn-outline" role="button" onclick="ga('send', 'event', 'Getting started', 'Download', 'Download source');">Download source</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<h3 id="download-sass">Sass</h3>
|
||||
<p><a href="{{ site.sass_repo }}">Bootstrap ported from Less to Sass</a> for easy inclusion in Rails, Compass, or Sass-only projects.</p>
|
||||
<p>
|
||||
<a href="{{ site.download.sass }}" class="btn btn-lg btn-outline" role="button" onclick="_gaq.push(['_trackEvent', 'Getting started', 'Download', 'Download Sass']);">Download Sass</a>
|
||||
<a href="{{ site.download.sass }}" class="btn btn-lg btn-outline" role="button" onclick="ga('send', 'event', 'Getting started', 'Download', 'Download Sass');">Download Sass</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', 'UA-146052-10', 'getbootstrap.com');
|
||||
ga('send', 'pageview');
|
||||
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@
|
|||
</table>
|
||||
</div><!-- /.table-responsive -->
|
||||
{% highlight js %}
|
||||
$('#my-alert').bind('closed.bs.alert', function () {
|
||||
$('#my-alert').on('closed.bs.alert', function () {
|
||||
// do something…
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
|
|
|||
|
|
@ -37,10 +37,14 @@
|
|||
|
||||
<h4>Checkbox</h4>
|
||||
<p>Add <code>data-toggle="buttons"</code> to a group of checkboxes for checkbox style toggling on btn-group.</p>
|
||||
<div class="bs-callout bs-callout-warning">
|
||||
<h4>Pre-checked options need <code>.active</code></h4>
|
||||
<p>For pre-checked options, you must add the <code>.active</code> class to the input's <code>label</code> yourself.</p>
|
||||
</div>
|
||||
<div class="bs-example" style="padding-bottom: 24px;">
|
||||
<div class="btn-group" data-toggle="buttons">
|
||||
<label class="btn btn-primary">
|
||||
<input type="checkbox"> Option 1
|
||||
<label class="btn btn-primary active">
|
||||
<input type="checkbox" checked> Option 1 (pre-checked)
|
||||
</label>
|
||||
<label class="btn btn-primary">
|
||||
<input type="checkbox"> Option 2
|
||||
|
|
@ -52,8 +56,8 @@
|
|||
</div><!-- /example -->
|
||||
{% highlight html %}
|
||||
<div class="btn-group" data-toggle="buttons">
|
||||
<label class="btn btn-primary">
|
||||
<input type="checkbox"> Option 1
|
||||
<label class="btn btn-primary active">
|
||||
<input type="checkbox" checked> Option 1 (pre-checked)
|
||||
</label>
|
||||
<label class="btn btn-primary">
|
||||
<input type="checkbox"> Option 2
|
||||
|
|
@ -66,10 +70,14 @@
|
|||
|
||||
<h4>Radio</h4>
|
||||
<p>Add <code>data-toggle="buttons"</code> to a group of radio inputs for radio style toggling on btn-group.</p>
|
||||
<div class="bs-callout bs-callout-warning">
|
||||
<h4>Preselected options need <code>.active</code></h4>
|
||||
<p>For preselected options, you must add the <code>.active</code> class to the input's <code>label</code> yourself.</p>
|
||||
</div>
|
||||
<div class="bs-example" style="padding-bottom: 24px;">
|
||||
<div class="btn-group" data-toggle="buttons">
|
||||
<label class="btn btn-primary">
|
||||
<input type="radio" name="options" id="option1"> Option 1
|
||||
<label class="btn btn-primary active">
|
||||
<input type="radio" name="options" id="option1" checked> Option 1 (preselected)
|
||||
</label>
|
||||
<label class="btn btn-primary">
|
||||
<input type="radio" name="options" id="option2"> Option 2
|
||||
|
|
@ -81,8 +89,8 @@
|
|||
</div><!-- /example -->
|
||||
{% highlight html %}
|
||||
<div class="btn-group" data-toggle="buttons">
|
||||
<label class="btn btn-primary">
|
||||
<input type="radio" name="options" id="option1"> Option 1
|
||||
<label class="btn btn-primary active">
|
||||
<input type="radio" name="options" id="option1" checked> Option 1 (preselected)
|
||||
</label>
|
||||
<label class="btn btn-primary">
|
||||
<input type="radio" name="options" id="option2"> Option 2
|
||||
|
|
|
|||
|
|
@ -46,6 +46,12 @@
|
|||
...
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img src="..." alt="...">
|
||||
<div class="carousel-caption">
|
||||
...
|
||||
</div>
|
||||
</div>
|
||||
...
|
||||
</div>
|
||||
|
||||
|
|
@ -105,7 +111,7 @@
|
|||
</div>
|
||||
</div><!-- /example -->
|
||||
{% highlight html %}
|
||||
<div class="item active">
|
||||
<div class="item">
|
||||
<img src="..." alt="...">
|
||||
<div class="carousel-caption">
|
||||
<h3>...</h3>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
<div class="collapse navbar-collapse bs-example-js-navbar-collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="dropdown">
|
||||
<a id="drop1" href="#" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a id="drop1" href="#" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu" aria-labelledby="drop1">
|
||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Action</a></li>
|
||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Another action</a></li>
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" id="drop2" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown 2 <b class="caret"></b></a>
|
||||
<a href="#" id="drop2" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown 2 <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu" aria-labelledby="drop2">
|
||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Action</a></li>
|
||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Another action</a></li>
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li id="fat-menu" class="dropdown">
|
||||
<a href="#" id="drop3" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown 3 <b class="caret"></b></a>
|
||||
<a href="#" id="drop3" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown 3 <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu" aria-labelledby="drop3">
|
||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Action</a></li>
|
||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Another action</a></li>
|
||||
|
|
@ -62,7 +62,7 @@
|
|||
<ul class="nav nav-pills">
|
||||
<li class="active"><a href="#">Regular link</a></li>
|
||||
<li class="dropdown">
|
||||
<a id="drop4" role="button" data-toggle="dropdown" href="#">Dropdown <b class="caret"></b></a>
|
||||
<a id="drop4" role="button" data-toggle="dropdown" href="#">Dropdown <span class="caret"></span></a>
|
||||
<ul id="menu1" class="dropdown-menu" role="menu" aria-labelledby="drop4">
|
||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Action</a></li>
|
||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Another action</a></li>
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a id="drop5" role="button" data-toggle="dropdown" href="#">Dropdown 2 <b class="caret"></b></a>
|
||||
<a id="drop5" role="button" data-toggle="dropdown" href="#">Dropdown 2 <span class="caret"></span></a>
|
||||
<ul id="menu2" class="dropdown-menu" role="menu" aria-labelledby="drop5">
|
||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Action</a></li>
|
||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Another action</a></li>
|
||||
|
|
@ -82,7 +82,7 @@
|
|||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a id="drop6" role="button" data-toggle="dropdown" href="#">Dropdown 3 <b class="caret"></b></a>
|
||||
<a id="drop6" role="button" data-toggle="dropdown" href="#">Dropdown 3 <span class="caret"></span></a>
|
||||
<ul id="menu3" class="dropdown-menu" role="menu" aria-labelledby="drop6">
|
||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Action</a></li>
|
||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Another action</a></li>
|
||||
|
|
|
|||
|
|
@ -193,7 +193,10 @@ $('.popover-dismiss').popover({
|
|||
<td>content</td>
|
||||
<td>string | function</td>
|
||||
<td>''</td>
|
||||
<td>Default content value if <code>data-content</code> attribute isn't present</td>
|
||||
<td>
|
||||
<p>Default content value if <code>data-content</code> attribute isn't present.</p>
|
||||
<p>If a function is given, it will be called with 1 argument, which is the element that the popover is attached to.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>delay</td>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
<li><a href="#fat">@fat</a></li>
|
||||
<li><a href="#mdo">@mdo</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" id="navbarDrop1" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" id="navbarDrop1" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu" aria-labelledby="navbarDrop1">
|
||||
<li><a href="#one" tabindex="-1">one</a></li>
|
||||
<li><a href="#two" tabindex="-1">two</a></li>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<li class="active"><a href="#home" data-toggle="tab">Home</a></li>
|
||||
<li><a href="#profile" data-toggle="tab">Profile</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" id="myTabDrop1" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" id="myTabDrop1" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu" aria-labelledby="myTabDrop1">
|
||||
<li><a href="#dropdown1" tabindex="-1" data-toggle="tab">@fat</a></li>
|
||||
<li><a href="#dropdown2" tabindex="-1" data-toggle="tab">@mdo</a></li>
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@
|
|||
</li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="{{ site.expo }}" onclick="_gaq.push(['_trackEvent', 'Navbar', 'Community links', 'Expo']);">Expo</a></li>
|
||||
<li><a href="{{ site.blog }}" onclick="_gaq.push(['_trackEvent', 'Navbar', 'Community links', 'Blog']);">Blog</a></li>
|
||||
<li><a href="{{ site.expo }}" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Expo');">Expo</a></li>
|
||||
<li><a href="{{ site.blog }}" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Blog');">Blog</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ window.onload = function () { // wait for load in a dumb way because B-0
|
|||
return match && decodeURIComponent(match[1].replace(/\+/g, ' '))
|
||||
}
|
||||
|
||||
function createGist(configJson) {
|
||||
function createGist(configJson, callback) {
|
||||
var data = {
|
||||
description: 'Bootstrap Customizer Config',
|
||||
'public': true,
|
||||
|
|
@ -61,10 +61,18 @@ window.onload = function () { // wait for load in a dumb way because B-0
|
|||
})
|
||||
.success(function (result) {
|
||||
var origin = window.location.protocol + '//' + window.location.host
|
||||
history.replaceState(false, document.title, origin + window.location.pathname + '?id=' + result.id)
|
||||
var newUrl = origin + window.location.pathname + '?id=' + result.id
|
||||
history.replaceState(false, document.title, newUrl)
|
||||
callback(result.html_url, newUrl)
|
||||
})
|
||||
.error(function (err) {
|
||||
showError('<strong>Ruh roh!</strong> Could not save gist file, configuration not saved.', err)
|
||||
try {
|
||||
showError('<strong>Ruh roh!</strong> Could not save gist file, configuration not saved.', err)
|
||||
}
|
||||
catch (sameErr) {
|
||||
// deliberately ignore the error
|
||||
}
|
||||
callback('<none>', '<none>')
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -155,7 +163,7 @@ window.onload = function () { // wait for load in a dumb way because B-0
|
|||
complete(content)
|
||||
}
|
||||
|
||||
function generateCustomCSS(vars) {
|
||||
function generateCustomLess(vars) {
|
||||
var result = ''
|
||||
|
||||
for (var key in vars) {
|
||||
|
|
@ -178,10 +186,20 @@ window.onload = function () { // wait for load in a dumb way because B-0
|
|||
var IMPORT_REGEX = /^@import \"(.*?)\";$/
|
||||
var lessLines = __less[lessFilename].split('\n')
|
||||
|
||||
for (var i = 0, imports = []; i < lessLines.length; i++) {
|
||||
var match = IMPORT_REGEX.exec(lessLines[i])
|
||||
if (match) imports.push(match[1])
|
||||
}
|
||||
var imports = []
|
||||
$.each(lessLines, function (index, lessLine) {
|
||||
var match = IMPORT_REGEX.exec(lessLine)
|
||||
if (match) {
|
||||
var importee = match[1]
|
||||
var transitiveImports = includedLessFilenames(importee)
|
||||
$.each(transitiveImports, function (index, transitiveImportee) {
|
||||
if ($.inArray(transitiveImportee, imports) === -1) {
|
||||
imports.push(transitiveImportee)
|
||||
}
|
||||
})
|
||||
imports.push(importee)
|
||||
}
|
||||
})
|
||||
|
||||
return imports
|
||||
}
|
||||
|
|
@ -189,7 +207,8 @@ window.onload = function () { // wait for load in a dumb way because B-0
|
|||
function generateLESS(lessFilename, lessFileIncludes, vars) {
|
||||
var lessSource = __less[lessFilename]
|
||||
|
||||
$.each(includedLessFilenames(lessFilename), function(index, filename) {
|
||||
var lessFilenames = includedLessFilenames(lessFilename)
|
||||
$.each(lessFilenames, function(index, filename) {
|
||||
var fileInclude = lessFileIncludes[filename]
|
||||
|
||||
// Files not explicitly unchecked are compiled into the final stylesheet.
|
||||
|
|
@ -200,7 +219,7 @@ window.onload = function () { // wait for load in a dumb way because B-0
|
|||
|
||||
// Custom variables are added after Bootstrap variables so the custom
|
||||
// ones take precedence.
|
||||
if (('variables.less' === filename) && vars) lessSource += generateCustomCSS(vars)
|
||||
if (('variables.less' === filename) && vars) lessSource += generateCustomLess(vars)
|
||||
})
|
||||
|
||||
lessSource = lessSource.replace(/@import[^\n]*/gi, '') //strip any imports
|
||||
|
|
@ -221,7 +240,7 @@ window.onload = function () { // wait for load in a dumb way because B-0
|
|||
})
|
||||
}
|
||||
|
||||
function generateCSS() {
|
||||
function generateCSS(preamble) {
|
||||
var oneChecked = false
|
||||
var lessFileIncludes = {}
|
||||
$('#less-section input').each(function() {
|
||||
|
|
@ -242,8 +261,8 @@ window.onload = function () { // wait for load in a dumb way because B-0
|
|||
$(this).val() && (vars[$(this).prev().text()] = $(this).val())
|
||||
})
|
||||
|
||||
var bsLessSource = generateLESS('bootstrap.less', lessFileIncludes, vars)
|
||||
var themeLessSource = generateLESS('theme.less', lessFileIncludes, vars)
|
||||
var bsLessSource = preamble + generateLESS('bootstrap.less', lessFileIncludes, vars)
|
||||
var themeLessSource = preamble + generateLESS('theme.less', lessFileIncludes, vars)
|
||||
|
||||
try {
|
||||
compileLESS(bsLessSource, 'bootstrap', result)
|
||||
|
|
@ -255,7 +274,7 @@ window.onload = function () { // wait for load in a dumb way because B-0
|
|||
return result
|
||||
}
|
||||
|
||||
function generateJavascript() {
|
||||
function generateJavascript(preamble) {
|
||||
var $checked = $('#plugin-section input:checked')
|
||||
if (!$checked.length) return false
|
||||
|
||||
|
|
@ -265,8 +284,8 @@ window.onload = function () { // wait for load in a dumb way because B-0
|
|||
.join('\n')
|
||||
|
||||
return {
|
||||
'bootstrap.js': js,
|
||||
'bootstrap.min.js': cw + uglify(js)
|
||||
'bootstrap.js': preamble + js,
|
||||
'bootstrap.min.js': preamble + cw + uglify(js)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -322,10 +341,19 @@ window.onload = function () { // wait for load in a dumb way because B-0
|
|||
|
||||
$compileBtn.attr('disabled', 'disabled')
|
||||
|
||||
generateZip(generateCSS(), generateJavascript(), generateFonts(), configJson, function (blob) {
|
||||
$compileBtn.removeAttr('disabled')
|
||||
saveAs(blob, 'bootstrap.zip')
|
||||
createGist(configJson)
|
||||
createGist(configJson, function (gistUrl, customizerUrl) {
|
||||
configData.customizerUrl = customizerUrl
|
||||
configJson = JSON.stringify(configData, null, 2)
|
||||
|
||||
var preamble = '/*!\n' +
|
||||
' * Generated using the Bootstrap Customizer (' + customizerUrl + ')\n' +
|
||||
' * Config saved to config.json and ' + gistUrl + '\n' +
|
||||
' */\n'
|
||||
|
||||
generateZip(generateCSS(preamble), generateJavascript(preamble), generateFonts(), configJson, function (blob) {
|
||||
$compileBtn.removeAttr('disabled')
|
||||
saveAs(blob, 'bootstrap.zip')
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -356,7 +356,7 @@ lead: Customize Bootstrap's components, Less variables, and jQuery plugins to ge
|
|||
|
||||
<p class="lead">Hooray! Your custom version of Bootstrap is now ready to be compiled. Just click the button below to finish the process.</p>
|
||||
<div class="bs-customize-download">
|
||||
<button type="submit" id="btn-compile" disabled class="btn btn-block btn-lg btn-outline" onclick="_gaq.push(['_trackEvent', 'Customize', 'Download', 'Customize and Download']);">Compile and Download</button>
|
||||
<button type="submit" id="btn-compile" disabled class="btn btn-block btn-lg btn-outline" onclick="ga('send', 'event', 'Customize', 'Download', 'Customize and Download');">Compile and Download</button>
|
||||
</div>
|
||||
</div><!-- /download -->
|
||||
</form>
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -48,7 +48,7 @@
|
|||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
<li><a href="#">Link</a></li>
|
||||
<li><a href="#">Link</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
|
|
@ -343,7 +343,7 @@
|
|||
<h1>Dropdown menus</h1>
|
||||
</div>
|
||||
<div class="dropdown theme-dropdown clearfix">
|
||||
<a id="dropdownMenu1" href="#" role="button" class="sr-only dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a id="dropdownMenu1" href="#" role="button" class="sr-only dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
|
||||
<li class="active" role="presentation"><a role="menuitem" tabindex="-1" href="#">Action</a></li>
|
||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">Another action</a></li>
|
||||
|
|
@ -392,7 +392,7 @@
|
|||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
|
|
@ -425,7 +425,7 @@
|
|||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
|
|
@ -345,7 +345,7 @@
|
|||
<h1>Dropdown menus</h1>
|
||||
</div>
|
||||
<div class="dropdown theme-dropdown clearfix">
|
||||
<a id="dropdownMenu1" href="#" role="button" class="sr-only dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a id="dropdownMenu1" href="#" role="button" class="sr-only dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
|
||||
<li class="active" role="presentation"><a role="menuitem" tabindex="-1" href="#">Action</a></li>
|
||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">Another action</a></li>
|
||||
|
|
@ -394,7 +394,7 @@
|
|||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
|
|
@ -427,7 +427,7 @@
|
|||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<link rel="icon" href="../../assets/ico/favicon.ico">
|
||||
|
||||
<title>Tooltip Viewport Example for Bootstrap</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link href="../../dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this template -->
|
||||
<link href="tooltip-viewport.css" rel="stylesheet">
|
||||
|
||||
<!-- Just for debugging purposes. Don't actually copy this line! -->
|
||||
<!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
|
||||
|
||||
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
|
||||
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<button class="btn pull-right tooltip-bottom" title="This should be shifted to the left">Shift Left</button>
|
||||
<button class="btn tooltip-bottom" title="This should be shifted to the right">Shift Right</button>
|
||||
<button class="btn tooltip-right" title="This should be shifted down">Shift Down</button>
|
||||
|
||||
<div class="placeholder">There is a button down there ↓</div>
|
||||
|
||||
<button class="btn tooltip-right" title="This should be shifted up">Shift Up</button>
|
||||
|
||||
<div class="container-viewport">
|
||||
<button class="btn tooltip-viewport-bottom" title="This should be shifted to the left">Shift Left</button>
|
||||
<button class="btn tooltip-viewport-right" title="This should be shifted down">Shift Down</button>
|
||||
|
||||
<button class="btn pull-right tooltip-viewport-bottom" title="This should be shifted to the right">Shift Right</button>
|
||||
|
||||
<button class="btn tooltip-viewport-right btn-bottom" title="This should be shifted up">Shift Up</button>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Bootstrap core JavaScript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
|
||||
<script src="../../dist/js/bootstrap.min.js"></script>
|
||||
<script src="tooltip-viewport.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
body {
|
||||
height: 1200px;
|
||||
}
|
||||
.tooltip {
|
||||
min-width: 250px;
|
||||
max-width: 500px;
|
||||
}
|
||||
.tooltip .tooltip-inner {
|
||||
min-width: 250px;
|
||||
max-width: 500px;
|
||||
min-height: 200px;
|
||||
}
|
||||
.placeholder {
|
||||
height: 900px;
|
||||
}
|
||||
.container-viewport {
|
||||
position: absolute;
|
||||
top: 600px;
|
||||
left: 200px;
|
||||
width: 600px;
|
||||
height: 400px;
|
||||
background: #c00;
|
||||
}
|
||||
.btn-bottom {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
$(document).ready(function () {
|
||||
$('.tooltip-right').tooltip({
|
||||
placement: 'right',
|
||||
viewport: {selector: 'body', padding: 2}
|
||||
})
|
||||
$('.tooltip-bottom').tooltip({
|
||||
placement: 'bottom',
|
||||
viewport: {selector: 'body', padding: 2}
|
||||
})
|
||||
$('.tooltip-viewport-right').tooltip({
|
||||
placement: 'right',
|
||||
viewport: {selector: '.container-viewport', padding: 2}
|
||||
})
|
||||
$('.tooltip-viewport-bottom').tooltip({
|
||||
placement: 'bottom',
|
||||
viewport: {selector: '.container-viewport', padding: 2}
|
||||
})
|
||||
})
|
||||
|
|
@ -9,7 +9,7 @@ title: Bootstrap
|
|||
<!-- <h1>Bootstrap</h1> -->
|
||||
<p class="lead">The most popular front-end framework for developing responsive, mobile first projects on the web.</p>
|
||||
<p class="lead">
|
||||
<a href="getting-started#download" class="btn btn-outline-inverse btn-lg" onclick="_gaq.push(['_trackEvent', 'Jumbotron actions', 'Download', 'Download {{ site.current_version }}']);">Download Bootstrap</a>
|
||||
<a href="getting-started#download" class="btn btn-outline-inverse btn-lg" onclick="ga('send', 'event', 'Jumbotron actions', 'Download', 'Download {{ site.current_version }}');">Download Bootstrap</a>
|
||||
</p>
|
||||
<p class="version">Currently v{{ site.current_version }}</p>
|
||||
{% include ads.html %}
|
||||
|
|
|
|||
|
|
@ -1,103 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<link rel="shortcut icon" href="../../docs-assets/ico/favicon.png">
|
||||
|
||||
<title>Tooltip Viewport Example for Bootstrap</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link href="../../dist/css/bootstrap.css" rel="stylesheet">
|
||||
|
||||
<!-- Just for debugging purposes. Don't actually copy this line! -->
|
||||
<!--[if lt IE 9]><script src="../../docs-assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
|
||||
|
||||
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
|
||||
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<style>
|
||||
body {
|
||||
height: 1200px;
|
||||
}
|
||||
.tooltip {
|
||||
min-width: 250px;
|
||||
max-width: 500px;
|
||||
}
|
||||
.tooltip .tooltip-inner {
|
||||
min-height: 200px;
|
||||
min-width: 250px;
|
||||
max-width: 500px;
|
||||
}
|
||||
.placeholder {
|
||||
height: 900px;
|
||||
}
|
||||
.container-viewport {
|
||||
position: absolute;
|
||||
left: 200px;
|
||||
top: 600px;
|
||||
width: 600px;
|
||||
height: 400px;
|
||||
background: #c00;
|
||||
}
|
||||
.btn-bottom {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<button class="btn pull-right tooltip-bottom", title="This should be shifted to the left">Shift Left</button>
|
||||
<button class="btn tooltip-bottom", title="This should be shifted to the right">Shift Right</button>
|
||||
<button class="btn tooltip-right", title="This should be shifted down">Shift Down</button>
|
||||
|
||||
<div class="placeholder">There is a button down there ↓</div>
|
||||
|
||||
<button class="btn tooltip-right", title="This should be shifted up">Shift Up</button>
|
||||
|
||||
<div class="container-viewport">
|
||||
<button class="btn tooltip-viewport-bottom", title="This should be shifted Left">Shift Left</button>
|
||||
<button class="btn tooltip-viewport-right", title="This should be shifted Down">Shift Down</button>
|
||||
|
||||
<button class="btn pull-right tooltip-viewport-bottom", title="This should be shifted Right">Shift Right</button>
|
||||
|
||||
<button class="btn tooltip-viewport-right btn-bottom", title="This should be shifted up">Shift Up</button>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap core JavaScript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
|
||||
<script src="../../js/tooltip.js"></script>
|
||||
|
||||
<script>
|
||||
$(function(){
|
||||
$('.tooltip-right').tooltip({
|
||||
placement: 'right',
|
||||
viewport: {selector: 'body', padding: 2}
|
||||
});
|
||||
$('.tooltip-bottom').tooltip({
|
||||
placement: 'bottom',
|
||||
viewport: {selector: 'body', padding: 2}
|
||||
});
|
||||
$('.tooltip-viewport-right').tooltip({
|
||||
placement: 'right',
|
||||
viewport: {selector: '.container-viewport', padding: 2}
|
||||
});
|
||||
$('.tooltip-viewport-bottom').tooltip({
|
||||
placement: 'bottom',
|
||||
viewport: {selector: '.container-viewport', padding: 2}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -10,16 +10,19 @@
|
|||
'use strict';
|
||||
var fs = require('fs');
|
||||
var btoa = require('btoa');
|
||||
var glob = require('glob');
|
||||
|
||||
function getFiles(type) {
|
||||
var files = {};
|
||||
fs.readdirSync(type)
|
||||
var recursive = (type === 'less');
|
||||
var globExpr = (recursive ? '/**/*' : '/*');
|
||||
glob.sync(type + globExpr)
|
||||
.filter(function (path) {
|
||||
return type === 'fonts' ? true : new RegExp('\\.' + type + '$').test(path);
|
||||
})
|
||||
.forEach(function (path) {
|
||||
var fullPath = type + '/' + path;
|
||||
files[path] = (type === 'fonts' ? btoa(fs.readFileSync(fullPath)) : fs.readFileSync(fullPath, 'utf8'));
|
||||
.forEach(function (fullPath) {
|
||||
var relativePath = fullPath.replace(/^[^/]+\//, '');
|
||||
files[relativePath] = (type === 'fonts' ? btoa(fs.readFileSync(fullPath)) : fs.readFileSync(fullPath, 'utf8'));
|
||||
});
|
||||
return 'var __' + type + ' = ' + JSON.stringify(files) + '\n';
|
||||
}
|
||||
|
|
@ -28,7 +31,10 @@ module.exports = function generateRawFilesJs(grunt, banner) {
|
|||
if (!banner) {
|
||||
banner = '';
|
||||
}
|
||||
var files = banner + getFiles('js') + getFiles('less') + getFiles('fonts');
|
||||
var dirs = ['js', 'less', 'fonts'];
|
||||
var files = banner + dirs.map(getFiles).reduce(function (combined, file) {
|
||||
return combined + file;
|
||||
}, '');
|
||||
var rawFilesJs = 'docs/assets/js/raw-files.min.js';
|
||||
try {
|
||||
fs.writeFileSync(rawFilesJs, files);
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
{
|
||||
browserName: "iphone",
|
||||
platform: "OS X 10.9",
|
||||
version: "7"
|
||||
version: "7.1"
|
||||
},
|
||||
|
||||
# iOS Chrome not currently supported by Sauce Labs
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@
|
|||
|
||||
if (pos > (this.$items.length - 1) || pos < 0) return
|
||||
|
||||
if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) })
|
||||
if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid". not a typo. past tense of "to slide".
|
||||
if (activeIndex == pos) return this.pause().cycle()
|
||||
|
||||
return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
|
||||
|
|
@ -113,7 +113,7 @@
|
|||
|
||||
if (this.$indicators.length) {
|
||||
this.$indicators.find('.active').removeClass('active')
|
||||
this.$element.one('slid.bs.carousel', function () {
|
||||
this.$element.one('slid.bs.carousel', function () { // yes, "slid". not a typo. past tense of "to slide".
|
||||
var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])
|
||||
$nextIndicator && $nextIndicator.addClass('active')
|
||||
})
|
||||
|
|
@ -129,14 +129,14 @@
|
|||
$next.removeClass([type, direction].join(' ')).addClass('active')
|
||||
$active.removeClass(['active', direction].join(' '))
|
||||
that.sliding = false
|
||||
setTimeout(function () { that.$element.trigger('slid.bs.carousel') }, 0)
|
||||
setTimeout(function () { that.$element.trigger('slid.bs.carousel') }, 0) // yes, "slid". not a typo. past tense of "to slide".
|
||||
})
|
||||
.emulateTransitionEnd($active.css('transition-duration').slice(0, -1) * 1000)
|
||||
} else {
|
||||
$active.removeClass('active')
|
||||
$next.addClass('active')
|
||||
this.sliding = false
|
||||
this.$element.trigger('slid.bs.carousel')
|
||||
this.$element.trigger('slid.bs.carousel') // yes, "slid". not a typo. past tense of "to slide".
|
||||
}
|
||||
|
||||
isCycling && this.cycle()
|
||||
|
|
|
|||
|
|
@ -51,8 +51,7 @@
|
|||
|
||||
this.$element
|
||||
.removeClass('collapse')
|
||||
.addClass('collapsing')
|
||||
[dimension](0)
|
||||
.addClass('collapsing')[dimension](0)
|
||||
|
||||
this.transitioning = 1
|
||||
|
||||
|
|
@ -60,8 +59,7 @@
|
|||
if (e && e.target != this.$element[0]) return
|
||||
this.$element
|
||||
.removeClass('collapsing')
|
||||
.addClass('collapse in')
|
||||
[dimension]('auto')
|
||||
.addClass('collapse in')[dimension]('auto')
|
||||
this.transitioning = 0
|
||||
this.$element.trigger('shown.bs.collapse')
|
||||
}
|
||||
|
|
@ -72,8 +70,7 @@
|
|||
|
||||
this.$element
|
||||
.one($.support.transition.end, $.proxy(complete, this))
|
||||
.emulateTransitionEnd(350)
|
||||
[dimension](this.$element[0][scrollSize])
|
||||
.emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize])
|
||||
}
|
||||
|
||||
Collapse.prototype.hide = function () {
|
||||
|
|
@ -85,9 +82,7 @@
|
|||
|
||||
var dimension = this.dimension()
|
||||
|
||||
this.$element
|
||||
[dimension](this.$element[dimension]())
|
||||
[0].offsetHeight
|
||||
this.$element[dimension](this.$element[dimension]())[0].offsetHeight
|
||||
|
||||
this.$element
|
||||
.addClass('collapsing')
|
||||
|
|
|
|||
23
js/modal.js
23
js/modal.js
|
|
@ -14,11 +14,12 @@
|
|||
// ======================
|
||||
|
||||
var Modal = function (element, options) {
|
||||
this.options = options
|
||||
this.$body = $(document.body)
|
||||
this.$element = $(element)
|
||||
this.$backdrop =
|
||||
this.isShown = null
|
||||
this.options = options
|
||||
this.$body = $(document.body)
|
||||
this.$element = $(element)
|
||||
this.$backdrop =
|
||||
this.isShown = null
|
||||
this.scrollbarWidth = 0
|
||||
|
||||
if (this.options.remote) {
|
||||
this.$element
|
||||
|
|
@ -49,6 +50,7 @@
|
|||
|
||||
this.isShown = true
|
||||
|
||||
this.checkScrollbar()
|
||||
this.$body.addClass('modal-open')
|
||||
|
||||
this.setScrollbar()
|
||||
|
|
@ -195,11 +197,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
Modal.prototype.checkScrollbar = function () {
|
||||
if (document.body.clientWidth >= window.innerWidth) return
|
||||
this.scrollbarWidth = this.scrollbarWidth || this.measureScrollbar()
|
||||
}
|
||||
|
||||
Modal.prototype.setScrollbar = function () {
|
||||
if (document.body.clientHeight <= window.innerHeight) return
|
||||
var scrollbarWidth = this.measureScrollbar()
|
||||
var bodyPad = parseInt(this.$body.css('padding-right') || 0)
|
||||
if (scrollbarWidth) this.$body.css('padding-right', bodyPad + scrollbarWidth)
|
||||
var bodyPad = parseInt(this.$body.css('padding-right') || 0)
|
||||
if (this.scrollbarWidth) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
|
||||
}
|
||||
|
||||
Modal.prototype.resetScrollbar = function () {
|
||||
|
|
|
|||
|
|
@ -169,10 +169,10 @@ $(function () {
|
|||
|
||||
dropdown
|
||||
.parent('.dropdown')
|
||||
.bind('show.bs.dropdown', function () {
|
||||
.on('show.bs.dropdown', function () {
|
||||
ok(true, 'show was called')
|
||||
})
|
||||
.bind('hide.bs.dropdown', function () {
|
||||
.on('hide.bs.dropdown', function () {
|
||||
ok(true, 'hide was called')
|
||||
start()
|
||||
})
|
||||
|
|
@ -203,10 +203,10 @@ $(function () {
|
|||
|
||||
dropdown
|
||||
.parent('.dropdown')
|
||||
.bind('shown.bs.dropdown', function () {
|
||||
.on('shown.bs.dropdown', function () {
|
||||
ok(true, 'show was called')
|
||||
})
|
||||
.bind('hidden.bs.dropdown', function () {
|
||||
.on('hidden.bs.dropdown', function () {
|
||||
ok(true, 'hide was called')
|
||||
start()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -140,13 +140,13 @@ $(function () {
|
|||
$.support.transition = false
|
||||
var div = $('<div id="modal-test"><div class="contents"></div></div>')
|
||||
div
|
||||
.bind('shown.bs.modal', function () {
|
||||
.on('shown.bs.modal', function () {
|
||||
ok($('#modal-test').length, 'modal insterted into dom')
|
||||
$('.contents').click()
|
||||
ok($('#modal-test').is(':visible'), 'modal visible')
|
||||
$('#modal-test').click()
|
||||
})
|
||||
.bind('hidden.bs.modal', function () {
|
||||
.on('hidden.bs.modal', function () {
|
||||
ok(!$('#modal-test').is(':visible'), 'modal hidden')
|
||||
div.remove()
|
||||
start()
|
||||
|
|
@ -162,11 +162,11 @@ $(function () {
|
|||
var div = $('<div id="modal-test"><div class="contents"></div></div>')
|
||||
|
||||
div
|
||||
.bind('shown.bs.modal', function () {
|
||||
.on('shown.bs.modal', function () {
|
||||
triggered = 0
|
||||
$('#modal-test').click()
|
||||
})
|
||||
.bind('hide.bs.modal', function () {
|
||||
.on('hide.bs.modal', function () {
|
||||
triggered += 1
|
||||
ok(triggered === 1, 'modal hide triggered once')
|
||||
start()
|
||||
|
|
@ -179,7 +179,7 @@ $(function () {
|
|||
$.support.transition = false
|
||||
var div = $('<div id="modal-test"><div class="contents"><div id="close" data-dismiss="modal"></div></div></div>')
|
||||
div
|
||||
.bind('shown.bs.modal', function () {
|
||||
.on('shown.bs.modal', function () {
|
||||
$('#close').click()
|
||||
ok(!$('#modal-test').is(':visible'), 'modal hidden')
|
||||
})
|
||||
|
|
|
|||
|
|
@ -110,20 +110,22 @@
|
|||
.icon-prev,
|
||||
.glyphicon-chevron-left {
|
||||
left: 50%;
|
||||
margin-left: -10px;
|
||||
}
|
||||
.icon-next,
|
||||
.glyphicon-chevron-right {
|
||||
right: 50%;
|
||||
margin-right: -10px;
|
||||
}
|
||||
.icon-prev,
|
||||
.icon-next {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-top: -10px;
|
||||
margin-left: -10px;
|
||||
font-family: serif;
|
||||
}
|
||||
|
||||
|
||||
.icon-prev {
|
||||
&:before {
|
||||
content: '\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)
|
||||
|
|
@ -213,9 +215,16 @@
|
|||
width: 30px;
|
||||
height: 30px;
|
||||
margin-top: -15px;
|
||||
margin-left: -15px;
|
||||
font-size: 30px;
|
||||
}
|
||||
.glyphicon-chevron-left,
|
||||
.icon-prev {
|
||||
margin-left: -15px;
|
||||
}
|
||||
.glyphicon-chevron-right,
|
||||
.icon-next {
|
||||
margin-right: -15px;
|
||||
}
|
||||
}
|
||||
|
||||
// Show and left align the captions
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/*! normalize.css v3.0.0 | MIT License | git.io/normalize */
|
||||
/*! normalize.css v3.0.1 | MIT License | git.io/normalize */
|
||||
|
||||
//
|
||||
// 1. Set default font family to sans-serif.
|
||||
|
|
@ -24,7 +24,9 @@ body {
|
|||
// ==========================================================================
|
||||
|
||||
//
|
||||
// Correct `block` display not defined in IE 8/9.
|
||||
// Correct `block` display not defined for any HTML5 element in IE 8/9.
|
||||
// Correct `block` display not defined for `details` or `summary` in IE 10/11 and Firefox.
|
||||
// Correct `block` display not defined for `main` in IE 11.
|
||||
//
|
||||
|
||||
article,
|
||||
|
|
@ -66,8 +68,8 @@ audio:not([controls]) {
|
|||
}
|
||||
|
||||
//
|
||||
// Address `[hidden]` styling not present in IE 8/9.
|
||||
// Hide the `template` element in IE, Safari, and Firefox < 22.
|
||||
// Address `[hidden]` styling not present in IE 8/9/10.
|
||||
// Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
|
||||
//
|
||||
|
||||
[hidden],
|
||||
|
|
@ -99,7 +101,7 @@ a:hover {
|
|||
// ==========================================================================
|
||||
|
||||
//
|
||||
// Address styling not present in IE 8/9, Safari 5, and Chrome.
|
||||
// Address styling not present in IE 8/9/10/11, Safari, and Chrome.
|
||||
//
|
||||
|
||||
abbr[title] {
|
||||
|
|
@ -107,7 +109,7 @@ abbr[title] {
|
|||
}
|
||||
|
||||
//
|
||||
// Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
|
||||
// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
|
||||
//
|
||||
|
||||
b,
|
||||
|
|
@ -116,7 +118,7 @@ strong {
|
|||
}
|
||||
|
||||
//
|
||||
// Address styling not present in Safari 5 and Chrome.
|
||||
// Address styling not present in Safari and Chrome.
|
||||
//
|
||||
|
||||
dfn {
|
||||
|
|
@ -125,7 +127,7 @@ dfn {
|
|||
|
||||
//
|
||||
// Address variable `h1` font-size and margin within `section` and `article`
|
||||
// contexts in Firefox 4+, Safari 5, and Chrome.
|
||||
// contexts in Firefox 4+, Safari, and Chrome.
|
||||
//
|
||||
|
||||
h1 {
|
||||
|
|
@ -174,7 +176,7 @@ sub {
|
|||
// ==========================================================================
|
||||
|
||||
//
|
||||
// Remove border when inside `a` element in IE 8/9.
|
||||
// Remove border when inside `a` element in IE 8/9/10.
|
||||
//
|
||||
|
||||
img {
|
||||
|
|
@ -182,7 +184,7 @@ img {
|
|||
}
|
||||
|
||||
//
|
||||
// Correct overflow displayed oddly in IE 9.
|
||||
// Correct overflow not hidden in IE 9/10/11.
|
||||
//
|
||||
|
||||
svg:not(:root) {
|
||||
|
|
@ -193,7 +195,7 @@ svg:not(:root) {
|
|||
// ==========================================================================
|
||||
|
||||
//
|
||||
// Address margin not present in IE 8/9 and Safari 5.
|
||||
// Address margin not present in IE 8/9 and Safari.
|
||||
//
|
||||
|
||||
figure {
|
||||
|
|
@ -242,7 +244,7 @@ samp {
|
|||
// 1. Correct color not being inherited.
|
||||
// Known issue: affects color of disabled elements.
|
||||
// 2. Correct font properties not being inherited.
|
||||
// 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.
|
||||
// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
|
||||
//
|
||||
|
||||
button,
|
||||
|
|
@ -256,7 +258,7 @@ textarea {
|
|||
}
|
||||
|
||||
//
|
||||
// Address `overflow` set to `hidden` in IE 8/9/10.
|
||||
// Address `overflow` set to `hidden` in IE 8/9/10/11.
|
||||
//
|
||||
|
||||
button {
|
||||
|
|
@ -266,7 +268,7 @@ button {
|
|||
//
|
||||
// Address inconsistent `text-transform` inheritance for `button` and `select`.
|
||||
// All other form control elements do not inherit `text-transform` values.
|
||||
// Correct `button` style inheritance in Firefox, IE 8+, and Opera
|
||||
// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
|
||||
// Correct `select` style inheritance in Firefox.
|
||||
//
|
||||
|
||||
|
|
@ -345,8 +347,8 @@ input[type="number"]::-webkit-outer-spin-button {
|
|||
}
|
||||
|
||||
//
|
||||
// 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
|
||||
// 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
|
||||
// 1. Address `appearance` set to `searchfield` in Safari and Chrome.
|
||||
// 2. Address `box-sizing` set to `border-box` in Safari and Chrome
|
||||
// (include `-moz` to future-proof).
|
||||
//
|
||||
|
||||
|
|
@ -379,7 +381,7 @@ fieldset {
|
|||
}
|
||||
|
||||
//
|
||||
// 1. Correct `color` not being inherited in IE 8/9.
|
||||
// 1. Correct `color` not being inherited in IE 8/9/10/11.
|
||||
// 2. Remove padding so people aren't caught out if they zero out fieldsets.
|
||||
//
|
||||
|
||||
|
|
@ -389,7 +391,7 @@ legend {
|
|||
}
|
||||
|
||||
//
|
||||
// Remove default vertical scrollbar in IE 8/9.
|
||||
// Remove default vertical scrollbar in IE 8/9/10/11.
|
||||
//
|
||||
|
||||
textarea {
|
||||
|
|
@ -420,4 +422,4 @@ table {
|
|||
td,
|
||||
th {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -249,8 +249,8 @@
|
|||
|
||||
@zindex-navbar: 1000;
|
||||
@zindex-dropdown: 1000;
|
||||
@zindex-popover: 1010;
|
||||
@zindex-tooltip: 1030;
|
||||
@zindex-popover: 1060; // @fix #13216
|
||||
@zindex-tooltip: 1070; // @fix #13216
|
||||
@zindex-navbar-fixed: 1030;
|
||||
@zindex-modal-background: 1040;
|
||||
@zindex-modal: 1050;
|
||||
|
|
@ -262,6 +262,7 @@
|
|||
|
||||
// Extra small screen / phone
|
||||
// Note: Deprecated @screen-xs and @screen-phone as of v3.0.1
|
||||
// Note: Deprecated @screen-xs-min as of v3.2.0
|
||||
@screen-xs: 480px;
|
||||
@screen-xs-min: @screen-xs;
|
||||
@screen-phone: @screen-xs-min;
|
||||
|
|
|
|||
13
package.json
13
package.json
|
|
@ -32,28 +32,29 @@
|
|||
"devDependencies": {
|
||||
"btoa": "~1.1.1",
|
||||
"canonical-json": "~0.0.4",
|
||||
"glob": "^3.2.9",
|
||||
"grunt": "~0.4.4",
|
||||
"grunt-autoprefixer": "~0.7.2",
|
||||
"grunt-banner": "~0.2.2",
|
||||
"grunt-contrib-clean": "~0.5.0",
|
||||
"grunt-contrib-concat": "~0.3.0",
|
||||
"grunt-contrib-concat": "~0.4.0",
|
||||
"grunt-contrib-connect": "~0.7.1",
|
||||
"grunt-contrib-copy": "~0.5.0",
|
||||
"grunt-contrib-csslint": "~0.2.0",
|
||||
"grunt-contrib-cssmin": "~0.9.0",
|
||||
"grunt-contrib-jade": "~0.11.0",
|
||||
"grunt-contrib-jshint": "~0.9.2",
|
||||
"grunt-contrib-jshint": "~0.10.0",
|
||||
"grunt-contrib-less": "~0.11.0",
|
||||
"grunt-contrib-qunit": "~0.4.0",
|
||||
"grunt-contrib-uglify": "~0.4.0",
|
||||
"grunt-contrib-watch": "~0.6.0",
|
||||
"grunt-contrib-watch": "~0.6.1",
|
||||
"grunt-csscomb": "~2.0.1",
|
||||
"grunt-css-flip": "~0.2.1",
|
||||
"grunt-exec": "~0.4.5",
|
||||
"grunt-html-validation": "~0.1.13",
|
||||
"grunt-html-validation": "~0.1.15",
|
||||
"grunt-jekyll": "~0.4.1",
|
||||
"grunt-jscs-checker": "~0.4.0",
|
||||
"grunt-saucelabs": "~5.1.0",
|
||||
"grunt-jscs-checker": "~0.4.1",
|
||||
"grunt-saucelabs": "~5.1.1",
|
||||
"grunt-sed": "~0.1.1",
|
||||
"load-grunt-tasks": "~0.4.0",
|
||||
"markdown": "~0.5.0",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"npm-modules": {
|
||||
"key": "./npm-shrinkwrap.canonical.json",
|
||||
"cache": "../node_modules",
|
||||
"generate": "./uncached-npm-install.sh"
|
||||
},
|
||||
"rubygems": {
|
||||
"key": "../pseudo_Gemfile.lock",
|
||||
"cache": "$GEMDIR",
|
||||
"generate": "gem install -N jekyll -v $JEKYLL_VERSION"
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,23 +1,51 @@
|
|||
#!/usr/bin/env python2.7
|
||||
# pylint: disable=C0301
|
||||
from __future__ import absolute_import, unicode_literals, print_function, division
|
||||
|
||||
from sys import argv
|
||||
from os import environ, stat, remove as _delete_file
|
||||
from os.path import isfile, dirname, basename, abspath
|
||||
from os import environ, stat, chdir, remove as _delete_file
|
||||
from os.path import dirname, basename, abspath, realpath, expandvars
|
||||
from hashlib import sha256
|
||||
from subprocess import check_call as run
|
||||
from json import load, dump as save
|
||||
from contextlib import contextmanager
|
||||
from datetime import datetime
|
||||
|
||||
from boto.s3.connection import S3Connection
|
||||
from boto.s3.key import Key
|
||||
from boto.exception import S3ResponseError
|
||||
|
||||
|
||||
NEED_TO_UPLOAD_MARKER = '.need-to-upload'
|
||||
CONFIG_FILE = './S3Cachefile.json'
|
||||
UPLOAD_TODO_FILE = './S3CacheTodo.json'
|
||||
BYTES_PER_MB = 1024 * 1024
|
||||
try:
|
||||
BUCKET_NAME = environ['TWBS_S3_BUCKET']
|
||||
except KeyError:
|
||||
raise SystemExit("TWBS_S3_BUCKET environment variable not set!")
|
||||
|
||||
|
||||
@contextmanager
|
||||
def timer():
|
||||
start = datetime.utcnow()
|
||||
yield
|
||||
end = datetime.utcnow()
|
||||
elapsed = end - start
|
||||
print("\tDone. Took", int(elapsed.total_seconds()), "second(s).")
|
||||
|
||||
|
||||
@contextmanager
|
||||
def todo_file(writeback=True):
|
||||
try:
|
||||
with open(UPLOAD_TODO_FILE, 'rt') as json_file:
|
||||
todo = load(json_file)
|
||||
except (IOError, OSError, ValueError):
|
||||
todo = {}
|
||||
|
||||
yield todo
|
||||
|
||||
if writeback:
|
||||
try:
|
||||
with open(UPLOAD_TODO_FILE, 'wt') as json_file:
|
||||
save(todo, json_file)
|
||||
except (OSError, IOError) as save_err:
|
||||
print("Error saving {}:".format(UPLOAD_TODO_FILE), save_err)
|
||||
|
||||
|
||||
def _sha256_of_file(filename):
|
||||
|
|
@ -36,6 +64,21 @@ def _delete_file_quietly(filename):
|
|||
pass
|
||||
|
||||
|
||||
def mark_needs_uploading(cache_name):
|
||||
with todo_file() as todo:
|
||||
todo[cache_name] = True
|
||||
|
||||
|
||||
def mark_uploaded(cache_name):
|
||||
with todo_file() as todo:
|
||||
todo.pop(cache_name, None)
|
||||
|
||||
|
||||
def need_to_upload(cache_name):
|
||||
with todo_file(writeback=False) as todo:
|
||||
return todo.get(cache_name, False)
|
||||
|
||||
|
||||
def _tarball_size(directory):
|
||||
kib = stat(_tarball_filename_for(directory)).st_size // BYTES_PER_MB
|
||||
return "{} MiB".format(kib)
|
||||
|
|
@ -47,34 +90,37 @@ def _tarball_filename_for(directory):
|
|||
|
||||
def _create_tarball(directory):
|
||||
print("Creating tarball of {}...".format(directory))
|
||||
run(['tar', '-czf', _tarball_filename_for(directory), '-C', dirname(directory), basename(directory)])
|
||||
with timer():
|
||||
run(['tar', '-czf', _tarball_filename_for(directory), '-C', dirname(directory), basename(directory)])
|
||||
|
||||
|
||||
def _extract_tarball(directory):
|
||||
print("Extracting tarball of {}...".format(directory))
|
||||
run(['tar', '-xzf', _tarball_filename_for(directory), '-C', dirname(directory)])
|
||||
with timer():
|
||||
run(['tar', '-xzf', _tarball_filename_for(directory), '-C', dirname(directory)])
|
||||
|
||||
|
||||
def download(directory):
|
||||
_delete_file_quietly(NEED_TO_UPLOAD_MARKER)
|
||||
mark_uploaded(cache_name) # reset
|
||||
try:
|
||||
print("Downloading {} tarball from S3...".format(friendly_name))
|
||||
key.get_contents_to_filename(_tarball_filename_for(directory))
|
||||
print("Downloading {} tarball from S3...".format(cache_name))
|
||||
with timer():
|
||||
key.get_contents_to_filename(_tarball_filename_for(directory))
|
||||
except S3ResponseError as err:
|
||||
open(NEED_TO_UPLOAD_MARKER, 'a').close()
|
||||
print(err)
|
||||
raise SystemExit("Cached {} download failed!".format(friendly_name))
|
||||
mark_needs_uploading(cache_name)
|
||||
raise SystemExit("Cached {} download failed!".format(cache_name))
|
||||
print("Downloaded {}.".format(_tarball_size(directory)))
|
||||
_extract_tarball(directory)
|
||||
print("{} successfully installed from cache.".format(friendly_name))
|
||||
print("{} successfully installed from cache.".format(cache_name))
|
||||
|
||||
|
||||
def upload(directory):
|
||||
_create_tarball(directory)
|
||||
print("Uploading {} tarball to S3... ({})".format(friendly_name, _tarball_size(directory)))
|
||||
key.set_contents_from_filename(_tarball_filename_for(directory))
|
||||
print("{} cache successfully updated.".format(friendly_name))
|
||||
_delete_file_quietly(NEED_TO_UPLOAD_MARKER)
|
||||
print("Uploading {} tarball to S3... ({})".format(cache_name, _tarball_size(directory)))
|
||||
with timer():
|
||||
key.set_contents_from_filename(_tarball_filename_for(directory))
|
||||
print("{} cache successfully updated.".format(cache_name))
|
||||
mark_uploaded(cache_name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
@ -82,26 +128,57 @@ if __name__ == '__main__':
|
|||
# AWS_ACCESS_KEY_ID -- AWS Access Key ID
|
||||
# AWS_SECRET_ACCESS_KEY -- AWS Secret Access Key
|
||||
argv.pop(0)
|
||||
if len(argv) != 4:
|
||||
raise SystemExit("USAGE: s3_cache.py <download | upload> <friendly name> <dependencies file> <directory>")
|
||||
mode, friendly_name, dependencies_file, directory = argv
|
||||
if len(argv) != 2:
|
||||
raise SystemExit("USAGE: s3_cache.py <download | upload> <cache name>")
|
||||
mode, cache_name = argv
|
||||
script_dir = dirname(realpath(__file__))
|
||||
chdir(script_dir)
|
||||
try:
|
||||
with open(CONFIG_FILE, 'rt') as config_file:
|
||||
config = load(config_file)
|
||||
except (IOError, OSError, ValueError) as config_err:
|
||||
print(config_err)
|
||||
raise SystemExit("Error when trying to load config from JSON file!")
|
||||
|
||||
conn = S3Connection()
|
||||
bucket = conn.lookup(BUCKET_NAME)
|
||||
if bucket is None:
|
||||
raise SystemExit("Could not access bucket!")
|
||||
try:
|
||||
cache_info = config[cache_name]
|
||||
key_file = expandvars(cache_info["key"])
|
||||
fallback_cmd = cache_info["generate"]
|
||||
directory = expandvars(cache_info["cache"])
|
||||
except (TypeError, KeyError) as load_err:
|
||||
print(load_err)
|
||||
raise SystemExit("Config for cache named {!r} is missing or malformed!".format(cache_name))
|
||||
|
||||
dependencies_file_hash = _sha256_of_file(dependencies_file)
|
||||
try:
|
||||
try:
|
||||
BUCKET_NAME = environ['TWBS_S3_BUCKET']
|
||||
except KeyError:
|
||||
raise SystemExit("TWBS_S3_BUCKET environment variable not set!")
|
||||
|
||||
key = Key(bucket, dependencies_file_hash)
|
||||
key.storage_class = 'REDUCED_REDUNDANCY'
|
||||
conn = S3Connection()
|
||||
bucket = conn.lookup(BUCKET_NAME)
|
||||
if bucket is None:
|
||||
raise SystemExit("Could not access bucket!")
|
||||
|
||||
if mode == 'download':
|
||||
download(directory)
|
||||
elif mode == 'upload':
|
||||
if isfile(NEED_TO_UPLOAD_MARKER): # FIXME
|
||||
upload(directory)
|
||||
key_file_hash = _sha256_of_file(key_file)
|
||||
|
||||
key = Key(bucket, key_file_hash)
|
||||
key.storage_class = 'REDUCED_REDUNDANCY'
|
||||
|
||||
if mode == 'download':
|
||||
download(directory)
|
||||
elif mode == 'upload':
|
||||
if need_to_upload(cache_name):
|
||||
upload(directory)
|
||||
else:
|
||||
print("No need to upload anything.")
|
||||
else:
|
||||
print("No need to upload anything.")
|
||||
else:
|
||||
raise SystemExit("Unrecognized mode {!r}".format(mode))
|
||||
raise SystemExit("Unrecognized mode {!r}".format(mode))
|
||||
except BaseException as exc:
|
||||
if mode != 'download':
|
||||
raise
|
||||
print("Error!:", exc)
|
||||
print("Unable to download from cache.")
|
||||
print("Running fallback command to generate cache directory {!r}: {}".format(directory, fallback_cmd))
|
||||
with timer():
|
||||
run(fallback_cmd, shell=True)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
cd .. # /bootstrap/
|
||||
cp test-infra/npm-shrinkwrap.canonical.json npm-shrinkwrap.json
|
||||
npm install
|
||||
rm npm-shrinkwrap.json
|
||||
|
|
|
|||
Loading…
Reference in New Issue