Commit 089d4348 authored by Mark Otto's avatar Mark Otto
Browse files

Merge branch 'master' into derp

Conflicts:
	_config.yml
	dist/css/bootstrap-theme.css.map
	dist/css/bootstrap.css
	dist/css/bootstrap.css.map
	dist/css/bootstrap.min.css
	docs/_includes/components/glyphicons.html
	docs/_includes/css/forms.html
	docs/_includes/css/tables.html
	docs/_includes/getting-started/browser-device-support.html
	docs/_includes/header.html
	docs/_includes/js/affix.html
	docs/_includes/js/alerts.html
	docs/_includes/js/buttons.html
	docs/_includes/js/dropdowns.html
	docs/_includes/js/overview.html
	docs/_includes/js/popovers.html
	docs/_includes/js/tooltips.html
	docs/_includes/nav/javascript.html
	docs/assets/css/docs.min.css
	docs/assets/css/src/docs.css
	docs/assets/js/customize.min.js
	docs/assets/js/docs.min.js
	docs/assets/js/raw-files.min.js
	docs/browser-bugs.html
	docs/dist/css/bootstrap-theme.css.map
	docs/dist/css/bootstrap.css
	docs/dist/css/bootstrap.css.map
	docs/dist/css/bootstrap.min.css
	docs/examples/blog/index.html
	docs/examples/carousel/index.html
	docs/examples/c...
parents f200c396 033f1654
main cleanup-floating-forms cssvar-function dependabot/npm_and_yarn/stylelint-and-stylelint-config-twbs-bootstrap-15.3.0 extend-snippets feat/data-target floating-always-visible floating-labels-icons fod-main-banner form-controls-with-icons github/fork/719media/patch-13 github/fork/719media/patch-14 github/fork/719media/patch-9 github/fork/ChellyAhmed/fix-typo-reboot.md github/fork/ChellyAhmed/offcanvas-scroll-back github/fork/CtrlAltLilith/main github/fork/Elysiome/offcanvas-optional-window-resizing github/fork/JanSargsyan/main github/fork/LunicLynx/support-different-line-height-for-buttons github/fork/Psixodelik/main github/fork/Ronid1/ronid1/offcanvas_static_backdrop github/fork/RyanBerliner/tooltip-accessibility github/fork/SantiagoPVazquez/Feature-default-border-bottom-to-dropdown-item github/fork/Sir-Genius/utils github/fork/Sumit-Singh-8/main github/fork/Viktor-VERA2020/offcanvas-slide github/fork/Zivangu9/input-group-for-form-control-plaintext github/fork/alpadev/alpadev/call-dispose-on-component-reinstantiation github/fork/astagi/fix/tree-shake-modules github/fork/compnerd/dark-accordion-icon github/fork/derSascha/dropdown-dont-close-on-input-click github/fork/dev-ph1l/main github/fork/donquixote/issue-33861-utl-mixin github/fork/florianlacreuse/mixin-make-row-gutter-y github/fork/gregorw/main github/fork/iteggmbh/transitionend-dispose-race github/fork/jdelStrother/patch-1 github/fork/jonnysp/form-floating github/fork/jonnysp/independent-offcanvas github/fork/jonnysp/theme-dark-on-card-and-modal-fix github/fork/josefdlange/floating-label-placeholder-opacity github/fork/julien-deramond/enhance-change-version.js github/fork/julien-deramond/main-jd-fix-offset-content github/fork/julien-deramond/main-jd-issue-with-utitlies github/fork/julien-deramond/main-xmr-pa11y-ci-jd-add-hideElements github/fork/kyletsang/fix-tooltip-padding github/fork/lacutah/CheckboxCenteringDocumentation github/fork/lekoala/patch-3 github/fork/louismaximepiton/main-kld-lmp-collapse-proposal github/fork/louismaximepiton/main-lmp-card-inner-border-radius-fix github/fork/louismaximepiton/main-lmp-carousel-multiple-images github/fork/louismaximepiton/main-lmp-css-var-init github/fork/louismaximepiton/main-lmp-disabled-floating-label-fix github/fork/louismaximepiton/main-lmp-input-range-fix github/fork/louismaximepiton/main-lmp-shift-color github/fork/louismaximepiton/main-lmp-table-active-tr-fix github/fork/maciek-szn/switch github/fork/michael-roth/feature/19964-multiple-tab-targets github/fork/mistic100/dom-utils github/fork/nkdas91/accordion github/fork/nstungcom/fix-missing-modal-open-class github/fork/oraliahdz/animation-utilities github/fork/pine3ree/patch-7 github/fork/pouwerkerk/unindent-scss-docs-shortcode github/fork/smares/smares-no-scolling-on-modal-close github/fork/tgm-git/patch-1 gs-forms gs-toasts-with-animated-progress-bar gs/add-history-helper gs/change-version-dir-on-docs gs/data-must-set-onlu-one-instance gs/docs/fix-drop-down-error gs/event-handler-2 gs/make-docs-js-build gs/make-simple-attribute-toggler gs/popover-fix-doc gs/provide-steConfig-method gs/scrollspy-smoothscroll-option-use-browser-history gs/streamline-jqueryInterface gs/support-drop-down-in-navbar gs/test-js-generic-trigger gs/try-web-components gs/tweak-collapse-js-selector gs/use-event-handler-in-cocmponent gs/use-rollup-replace-for-version jo-docs-thanks-page jo-ssr-friendly logical-props-spacing-utils main-fod-disabled-form-check-label main-fod-nested-accordion main-fod-simpler-table-structure main-fod-table-separator main-fod-utilities-contrast main-jd-abbr-title main-jd-add-chips main-jd-add-doc-for-sass-custom-colors main-jd-add-enable-host-to-handle-web-components main-jd-browserstack-fine-tune main-jd-browserstack-updates main-jd-docs-consistent-usage-of-css-sections-step-2 main-jd-fix-docs-headers-in-white main-jd-fix-highlight-docs-border-radius main-jd-fix-placeholder-color-background-params-for-img-markup main-jd-glossary-experiment main-jd-postcss-drop-empty-css-vars main-jd-proto-doc-astro main-jd-skip-navigation-component main-jd-stackblitz-for-examples main-jd-upgrade-browserlistrc main-jd-use-host main-lmp-dark-theme-customization main-lmp-handle-scroll-target main-lmp-tab-fix main-mc-opensearch main-xmr-bundlewatch-action main-xmr-eslint-plugin-compat main-xmr-hugo-docs-vendor main-xmr-hugo-rm-ver main-xmr-linkinator-prod main-xmr-min-mangle main-xmr-pa11y-ci more-darkmode-examples nested-dropdowns patrickhlauke-issue37428 patrickhlauke-use-of-color-tweaks pr/34102 pr/37590 previous-next-docs-links sticky-thead utilities-functions-mixin v4-dev v4-dev-dropdown-hide-method v530-dev v6-postcss-custom-media v6-spinner-dots v6/gs/use-floating-ui-in-place-of-popper xmr/dev xmr/docs-png xmr/docs-svgs xmr/hugo-reorg-files xmr/js-2 xmr/markdownlint xmr/prepare-530-alpha2 xmr/xo v5.3.0-alpha1 v5.2.3 v5.2.2 v5.2.1 v5.2.0 v5.2.0-beta1 v5.1.3 v5.1.2 v5.1.1 v5.1.0 v5.0.2 v5.0.1 v5.0.0 v5.0.0-beta3 v5.0.0-beta2 v5.0.0-beta1 v5.0.0-alpha3 v5.0.0-alpha2 v5.0.0-alpha1 v4.6.2 v4.6.1 v4.6.0 v4.5.3 v4.5.2 v4.5.1 v4.5.0 v4.4.1 v4.4.0 v4.3.1 v4.3.0 v4.2.1 v4.2.0 v4.1.3 v4.1.2 v4.1.1 v4.1.0 v4.0.0 v4.0.0-beta.3 v4.0.0-beta.2 v4.0.0-beta v4.0.0-alpha.6 v4.0.0-alpha.5 v4.0.0-alpha.4 v4.0.0-alpha.3 v4.0.0-alpha.2 v4.0.0-alpha
48 merge requests!28721Hot test,!27561Adds font-weight-medium to font weight classes,!26437merge,!26197V4 dev xmr,!20778V4 dev,!20539Allow multiple modals,!18047#17986,!18988Blockquote border width,!20854Fixes 15534,!19272V4 dev xmr grunt html,!17218Issue 17066,!19581V4 fix popover,!18283Tether docs fix,!17229Include documentation for .navbar-static-top,!20493V4 dev display,!20636Fix docs for heading sizes,!19824blockquote-center,!22547Finished a new translation for bootstrap,!19534Docs 17264,!19533Npm deps,!22143Fix selectable disabled toggle radio buttons,!19084V4 rhythm,!18085Ie9 click comment,!22598test,!18829Add prefix to carousel classes,!18581Check getting started files for broken links - Issue 18568,!18067replace grunt-autoprefixer with gruntpostcss + autoprefixer,!20099V4.0.0 alpha.3,!20438V4 grid classes,!17307Vertical alignment on Bootstrap columns with equal height,!18477add utility color-contrast function,!18864Feature/navbar toggler support color schemes,!19602V4 palettes arun,!18311V4 dev xmr,!19448New pull request for testing,!19358XXL grid size,!19825.blockquote-center,!17508Fix usage of “its” and “it’s” (v4 docs),!25326Adjust examples,!23995Add back cursor: pointer for .btn-link,!23178Spinner,!19754Issue template,!19753Card img overlay padding,!19747Blockquote border width,!19580ExitStars,!18684Docs: change "Button" to "Go somewhere",!18661Docs: accessibility fix-up of collapsible content navbar, change site-wide main navbar,!17021v4
Showing with 248 additions and 123 deletions
+248 -123
...@@ -18,8 +18,8 @@ after_script: ...@@ -18,8 +18,8 @@ after_script:
- if [ "$TWBS_TEST" = validate-html ] && [ $TWBS_DO_VALIDATOR -ne 0 ]; then ./test-infra/s3_cache.py upload rubygems; fi - if [ "$TWBS_TEST" = validate-html ] && [ $TWBS_DO_VALIDATOR -ne 0 ]; then ./test-infra/s3_cache.py upload rubygems; fi
env: env:
global: global:
- JEKYLL_VERSION: 2.1.0 - JEKYLL_VERSION: 2.1.1
- ROUGE_VERSION: 1.4.0 - ROUGE_VERSION: 1.6.1
- SAUCE_USERNAME: bootstrap - SAUCE_USERNAME: bootstrap
- secure: "pJkBwnuae9dKU5tEcCqccfS1QQw7/meEcfz63fM7ba7QJNjoA6BaXj08L5Z3Vb5vBmVPwBawxo5Hp0jC0r/Z/O0hGnAmz/Cz09L+cy7dSAZ9x4hvZePSja/UAusaB5ogMoO8l2b773MzgQeSmrLbExr9BWLeqEfjC2hFgdgHLaQ=" - secure: "pJkBwnuae9dKU5tEcCqccfS1QQw7/meEcfz63fM7ba7QJNjoA6BaXj08L5Z3Vb5vBmVPwBawxo5Hp0jC0r/Z/O0hGnAmz/Cz09L+cy7dSAZ9x4hvZePSja/UAusaB5ogMoO8l2b773MzgQeSmrLbExr9BWLeqEfjC2hFgdgHLaQ="
- secure: "gqjqISbxBJK6byFbsmr1AyP1qoWH+rap06A2gI7v72+Tn2PU2nYkIMUkCvhZw6K889jv+LhQ/ybcBxDOXHpNCExCnSgB4dcnmYp+9oeNZb37jSP0rQ+Ib4OTLjzc3/FawE/fUq5kukZTC7porzc/k0qJNLAZRx3YLALmK1GIdUY=" - secure: "gqjqISbxBJK6byFbsmr1AyP1qoWH+rap06A2gI7v72+Tn2PU2nYkIMUkCvhZw6K889jv+LhQ/ybcBxDOXHpNCExCnSgB4dcnmYp+9oeNZb37jSP0rQ+Ib4OTLjzc3/FawE/fUq5kukZTC7porzc/k0qJNLAZRx3YLALmK1GIdUY="
......
...@@ -320,7 +320,8 @@ module.exports = function (grunt) { ...@@ -320,7 +320,8 @@ module.exports = function (grunt) {
reset: true, reset: true,
relaxerror: [ relaxerror: [
'Bad value X-UA-Compatible for attribute http-equiv on element meta.', 'Bad value X-UA-Compatible for attribute http-equiv on element meta.',
'Element img is missing required attribute src.' 'Element img is missing required attribute src.',
'Attribute autocomplete not allowed on element input at this point.'
] ]
}, },
files: { files: {
...@@ -338,7 +339,7 @@ module.exports = function (grunt) { ...@@ -338,7 +339,7 @@ module.exports = function (grunt) {
tasks: ['jshint:test', 'qunit'] tasks: ['jshint:test', 'qunit']
}, },
less: { less: {
files: 'less/*.less', files: 'less/**/*.less',
tasks: 'less' tasks: 'less'
}, },
docs: { docs: {
......
...@@ -31,9 +31,9 @@ blog: http://blog.getbootstrap.com ...@@ -31,9 +31,9 @@ blog: http://blog.getbootstrap.com
expo: http://expo.getbootstrap.com expo: http://expo.getbootstrap.com
cdn: cdn:
css: //maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css css: https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css
css_theme: //maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css css_theme: https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css
js: //maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js js: https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js
jquery: //code.jquery.com/jquery-2.1.1.min.js jquery: //code.jquery.com/jquery-2.1.1.min.js
bug: bug:
......
...@@ -714,6 +714,7 @@ kbd { ...@@ -714,6 +714,7 @@ kbd {
kbd kbd { kbd kbd {
padding: 0; padding: 0;
font-size: 100%; font-size: 100%;
font-weight: bold;
-webkit-box-shadow: none; -webkit-box-shadow: none;
box-shadow: none; box-shadow: none;
} }
...@@ -1597,11 +1598,13 @@ table th[class*="col-"] { ...@@ -1597,11 +1598,13 @@ table th[class*="col-"] {
.table-hover > tbody > tr.danger:hover > th { .table-hover > tbody > tr.danger:hover > th {
background-color: #ebcccc; background-color: #ebcccc;
} }
.table-responsive {
overflow-x: auto;
}
@media screen and (max-width: 47.9em) { @media screen and (max-width: 47.9em) {
.table-responsive { .table-responsive {
width: 100%; width: 100%;
margin-bottom: 18px; margin-bottom: 18px;
overflow-x: auto;
overflow-y: hidden; overflow-y: hidden;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
-ms-overflow-style: -ms-autohiding-scrollbar; -ms-overflow-style: -ms-autohiding-scrollbar;
...@@ -1786,12 +1789,14 @@ input[type="time"].input-sm, ...@@ -1786,12 +1789,14 @@ input[type="time"].input-sm,
input[type="datetime-local"].input-sm, input[type="datetime-local"].input-sm,
input[type="month"].input-sm { input[type="month"].input-sm {
line-height: 1.975rem; line-height: 1.975rem;
line-height: 1.5 \0;
} }
input[type="date"].input-lg, input[type="date"].input-lg,
input[type="time"].input-lg, input[type="time"].input-lg,
input[type="datetime-local"].input-lg, input[type="datetime-local"].input-lg,
input[type="month"].input-lg { input[type="month"].input-lg {
line-height: 3.2625rem; line-height: 3.2625rem;
line-height: 1.33 \0;
} }
.form-group { .form-group {
margin-bottom: 15px; margin-bottom: 15px;
...@@ -2046,6 +2051,9 @@ select[multiple].form-group-lg .form-control { ...@@ -2046,6 +2051,9 @@ select[multiple].form-group-lg .form-control {
width: auto; width: auto;
vertical-align: middle; vertical-align: middle;
} }
.form-inline .form-control-static {
display: inline-block;
}
.form-inline .input-group { .form-inline .input-group {
display: inline-table; display: inline-table;
vertical-align: middle; vertical-align: middle;
...@@ -3390,6 +3398,9 @@ select[multiple].input-group-sm > .input-group-btn > .btn { ...@@ -3390,6 +3398,9 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
width: auto; width: auto;
vertical-align: middle; vertical-align: middle;
} }
.navbar-form .form-control-static {
display: inline-block;
}
.navbar-form .input-group { .navbar-form .input-group {
display: inline-table; display: inline-table;
vertical-align: middle; vertical-align: middle;
......
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
This diff is collapsed.
...@@ -88,6 +88,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -88,6 +88,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
Alert.VERSION = '3.2.0' Alert.VERSION = '3.2.0'
Alert.TRANSITION_DURATION = 150
Alert.prototype.close = function (e) { Alert.prototype.close = function (e) {
var $this = $(this) var $this = $(this)
var selector = $this.attr('data-target') var selector = $this.attr('data-target')
...@@ -119,7 +121,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -119,7 +121,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
$.support.transition && $parent.hasClass('fade') ? $.support.transition && $parent.hasClass('fade') ?
$parent $parent
.one('bsTransitionEnd', removeElement) .one('bsTransitionEnd', removeElement)
.emulateTransitionEnd(150) : .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
removeElement() removeElement()
} }
...@@ -258,15 +260,6 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -258,15 +260,6 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
} }
// FOCUS SHIM (FOR BUTTON GROUPS)
// ==============================
function getBtnTarget(target) {
var $target = $(target)
return $target.hasClass('btn') ? $target : $target.parent('.btn')
}
// BUTTON DATA-API // BUTTON DATA-API
// =============== // ===============
...@@ -277,11 +270,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -277,11 +270,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
Plugin.call($btn, 'toggle') Plugin.call($btn, 'toggle')
e.preventDefault() e.preventDefault()
}) })
.on('focus.bs.button.data-api', '[data-toggle^="button"]', function (e) { .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
getBtnTarget(e.target).addClass('focus') $(e.target).closest('.btn').toggleClass('focus', e.type == 'focus')
})
.on('blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
getBtnTarget(e.target).removeClass('focus')
}) })
}(jQuery); }(jQuery);
...@@ -318,6 +308,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -318,6 +308,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
Carousel.VERSION = '3.2.0' Carousel.VERSION = '3.2.0'
Carousel.TRANSITION_DURATION = 600
Carousel.DEFAULTS = { Carousel.DEFAULTS = {
interval: 5000, interval: 5000,
pause: 'hover', pause: 'hover',
...@@ -351,6 +343,13 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -351,6 +343,13 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
return this.$items.index(item || this.$active) return this.$items.index(item || this.$active)
} }
Carousel.prototype.getItemForDirection = function (direction, active) {
var delta = direction == 'prev' ? -1 : 1
var activeIndex = this.getItemIndex(active)
var itemIndex = (activeIndex + delta) % this.$items.length
return this.$items.eq(itemIndex)
}
Carousel.prototype.to = function (pos) { Carousel.prototype.to = function (pos) {
var that = this var that = this
var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
...@@ -360,7 +359,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -360,7 +359,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
if (activeIndex == pos) return this.pause().cycle() if (activeIndex == pos) return this.pause().cycle()
return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
} }
Carousel.prototype.pause = function (e) { Carousel.prototype.pause = function (e) {
...@@ -388,7 +387,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -388,7 +387,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
Carousel.prototype.slide = function (type, next) { Carousel.prototype.slide = function (type, next) {
var $active = this.$element.find('.item.active') var $active = this.$element.find('.item.active')
var $next = next || $active[type]() var $next = next || this.getItemForDirection(type, $active)
var isCycling = this.interval var isCycling = this.interval
var direction = type == 'next' ? 'left' : 'right' var direction = type == 'next' ? 'left' : 'right'
var fallback = type == 'next' ? 'first' : 'last' var fallback = type == 'next' ? 'first' : 'last'
...@@ -434,7 +433,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -434,7 +433,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
that.$element.trigger(slidEvent) that.$element.trigger(slidEvent)
}, 0) }, 0)
}) })
.emulateTransitionEnd($active.css('transition-duration').slice(0, -1) * 1000) .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
} else { } else {
$active.removeClass('active') $active.removeClass('active')
$next.addClass('active') $next.addClass('active')
...@@ -536,6 +535,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -536,6 +535,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
Collapse.VERSION = '3.2.0' Collapse.VERSION = '3.2.0'
Collapse.TRANSITION_DURATION = 350
Collapse.DEFAULTS = { Collapse.DEFAULTS = {
toggle: true toggle: true
} }
...@@ -584,7 +585,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -584,7 +585,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
this.$element this.$element
.one('bsTransitionEnd', $.proxy(complete, this)) .one('bsTransitionEnd', $.proxy(complete, this))
.emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize]) .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
} }
Collapse.prototype.hide = function () { Collapse.prototype.hide = function () {
...@@ -617,7 +618,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -617,7 +618,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
this.$element this.$element
[dimension](0) [dimension](0)
.one('bsTransitionEnd', $.proxy(complete, this)) .one('bsTransitionEnd', $.proxy(complete, this))
.emulateTransitionEnd(350) .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
} }
Collapse.prototype.toggle = function () { Collapse.prototype.toggle = function () {
...@@ -724,7 +725,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -724,7 +725,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
if (e.isDefaultPrevented()) return if (e.isDefaultPrevented()) return
$this.trigger('focus') $this
.trigger('focus')
.attr('aria-expanded', 'true')
$parent $parent
.toggleClass('open') .toggleClass('open')
...@@ -770,11 +773,17 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -770,11 +773,17 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
if (e && e.which === 3) return if (e && e.which === 3) return
$(backdrop).remove() $(backdrop).remove()
$(toggle).each(function () { $(toggle).each(function () {
var $parent = getParent($(this)) var $this = $(this)
var $parent = getParent($this)
var relatedTarget = { relatedTarget: this } var relatedTarget = { relatedTarget: this }
if (!$parent.hasClass('open')) return if (!$parent.hasClass('open')) return
$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
if (e.isDefaultPrevented()) return if (e.isDefaultPrevented()) return
$this.attr('aria-expanded', 'false')
$parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget) $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
}) })
} }
...@@ -866,6 +875,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -866,6 +875,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
Modal.VERSION = '3.2.0' Modal.VERSION = '3.2.0'
Modal.TRANSITION_DURATION = 300
Modal.BACKDROP_TRANSITION_DURATION = 150
Modal.DEFAULTS = { Modal.DEFAULTS = {
backdrop: true, backdrop: true,
keyboard: true, keyboard: true,
...@@ -922,7 +934,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -922,7 +934,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
.one('bsTransitionEnd', function () { .one('bsTransitionEnd', function () {
that.$element.trigger('focus').trigger(e) that.$element.trigger('focus').trigger(e)
}) })
.emulateTransitionEnd(300) : .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
that.$element.trigger('focus').trigger(e) that.$element.trigger('focus').trigger(e)
}) })
} }
...@@ -953,7 +965,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -953,7 +965,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
$.support.transition && this.$element.hasClass('fade') ? $.support.transition && this.$element.hasClass('fade') ?
this.$element this.$element
.one('bsTransitionEnd', $.proxy(this.hideModal, this)) .one('bsTransitionEnd', $.proxy(this.hideModal, this))
.emulateTransitionEnd(300) : .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
this.hideModal() this.hideModal()
} }
...@@ -1016,7 +1028,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -1016,7 +1028,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
doAnimate ? doAnimate ?
this.$backdrop this.$backdrop
.one('bsTransitionEnd', callback) .one('bsTransitionEnd', callback)
.emulateTransitionEnd(150) : .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
callback() callback()
} else if (!this.isShown && this.$backdrop) { } else if (!this.isShown && this.$backdrop) {
...@@ -1029,7 +1041,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -1029,7 +1041,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
$.support.transition && this.$element.hasClass('fade') ? $.support.transition && this.$element.hasClass('fade') ?
this.$backdrop this.$backdrop
.one('bsTransitionEnd', callbackRemove) .one('bsTransitionEnd', callbackRemove)
.emulateTransitionEnd(150) : .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
callbackRemove() callbackRemove()
} else if (callback) { } else if (callback) {
...@@ -1142,6 +1154,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -1142,6 +1154,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
Tooltip.VERSION = '3.2.0' Tooltip.VERSION = '3.2.0'
Tooltip.TRANSITION_DURATION = 150
Tooltip.DEFAULTS = { Tooltip.DEFAULTS = {
animation: true, animation: true,
placement: 'top', placement: 'top',
...@@ -1322,7 +1336,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -1322,7 +1336,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
$.support.transition && this.$tip.hasClass('fade') ? $.support.transition && this.$tip.hasClass('fade') ?
$tip $tip
.one('bsTransitionEnd', complete) .one('bsTransitionEnd', complete)
.emulateTransitionEnd(150) : .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
complete() complete()
} }
} }
...@@ -1410,7 +1424,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -1410,7 +1424,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
$.support.transition && this.$tip.hasClass('fade') ? $.support.transition && this.$tip.hasClass('fade') ?
$tip $tip
.one('bsTransitionEnd', complete) .one('bsTransitionEnd', complete)
.emulateTransitionEnd(150) : .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
complete() complete()
this.hoverState = null this.hoverState = null
...@@ -1884,6 +1898,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -1884,6 +1898,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
Tab.VERSION = '3.2.0' Tab.VERSION = '3.2.0'
Tab.TRANSITION_DURATION = 150
Tab.prototype.show = function () { Tab.prototype.show = function () {
var $this = this.element var $this = this.element
var $ul = $this.closest('ul:not(.dropdown-menu)') var $ul = $this.closest('ul:not(.dropdown-menu)')
...@@ -1947,7 +1963,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -1947,7 +1963,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
$active.length && transition ? $active.length && transition ?
$active $active
.one('bsTransitionEnd', next) .one('bsTransitionEnd', next)
.emulateTransitionEnd(150) : .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
next() next()
$active.removeClass('in') $active.removeClass('in')
...@@ -2031,6 +2047,28 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -2031,6 +2047,28 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
target: window target: window
} }
Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
var scrollTop = this.$target.scrollTop()
var position = this.$element.offset()
var targetHeight = this.$target.height()
if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
if (this.affixed == 'bottom') {
if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
}
var initializing = this.affixed == null
var colliderTop = initializing ? scrollTop : position.top
var colliderHeight = initializing ? targetHeight : height
if (offsetTop != null && colliderTop <= offsetTop) return 'top'
if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
return false
}
Affix.prototype.getPinnedOffset = function () { Affix.prototype.getPinnedOffset = function () {
if (this.pinnedOffset) return this.pinnedOffset if (this.pinnedOffset) return this.pinnedOffset
this.$element.removeClass(Affix.RESET).addClass('affix') this.$element.removeClass(Affix.RESET).addClass('affix')
...@@ -2046,42 +2084,40 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re ...@@ -2046,42 +2084,40 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
Affix.prototype.checkPosition = function () { Affix.prototype.checkPosition = function () {
if (!this.$element.is(':visible')) return if (!this.$element.is(':visible')) return
var scrollHeight = $(document).height() var height = this.$element.height()
var scrollTop = this.$target.scrollTop()
var position = this.$element.offset()
var offset = this.options.offset var offset = this.options.offset
var offsetTop = offset.top var offsetTop = offset.top
var offsetBottom = offset.bottom var offsetBottom = offset.bottom
var scrollHeight = $('body').height()
if (typeof offset != 'object') offsetBottom = offsetTop = offset if (typeof offset != 'object') offsetBottom = offsetTop = offset
if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
var affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? false : var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false
if (this.affixed === affix) return if (this.affixed != affix) {
if (this.unpin != null) this.$element.css('top', '') if (this.unpin != null) this.$element.css('top', '')
var affixType = 'affix' + (affix ? '-' + affix : '') var affixType = 'affix' + (affix ? '-' + affix : '')
var e = $.Event(affixType + '.bs.affix') var e = $.Event(affixType + '.bs.affix')
this.$element.trigger(e) this.$element.trigger(e)
if (e.isDefaultPrevented()) return if (e.isDefaultPrevented()) return
this.affixed = affix this.affixed = affix
this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
this.$element this.$element
.removeClass(Affix.RESET) .removeClass(Affix.RESET)
.addClass(affixType) .addClass(affixType)
.trigger(affixType.replace('affix', 'affixed') + '.bs.affix') .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
}
if (affix == 'bottom') { if (affix == 'bottom') {
this.$element.offset({ this.$element.offset({
top: scrollHeight - this.$element.height() - offsetBottom top: scrollHeight - height - offsetBottom
}) })
} }
} }
......
This diff is collapsed.
...@@ -46,6 +46,8 @@ ...@@ -46,6 +46,8 @@
{% if page.slug == "customize" %} {% if page.slug == "customize" %}
<script src="{{ site.baseurl }}assets/js/customize.min.js"></script> <script src="{{ site.baseurl }}assets/js/customize.min.js"></script>
{% endif %} {% endif %}
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../assets/js/ie10-viewport-bug-workaround.js"></script>
{% comment %} {% comment %}
Inject Twitter widgets asynchronously. Snippet snipped from Twitter's Inject Twitter widgets asynchronously. Snippet snipped from Twitter's
......
// NOTE: DO NOT EDIT THE FOLLOWING SECTION DIRECTLY! It is autogenerated via the `build-customizer-html` Grunt task using the customizer-nav.jade template. // NOTE: DO NOT EDIT THE FOLLOWING SECTION DIRECTLY! It is autogenerated via the `build-customizer-html` Grunt task using the customizer-nav.jade template.
li
a(href='#import') Import
li li
a(href='#less') Less components a(href='#less') Less components
li li
......
This diff is collapsed.
This diff is collapsed.
...@@ -21,4 +21,4 @@ var Holder=Holder||{};!function(a,b){function c(a,b,c){b=parseInt(b,10),a=parseI ...@@ -21,4 +21,4 @@ var Holder=Holder||{};!function(a,b){function c(a,b,c){b=parseInt(b,10),a=parseI
* Licensed under the Creative Commons Attribution 3.0 Unported License. For * Licensed under the Creative Commons Attribution 3.0 Unported License. For
* details, see http://creativecommons.org/licenses/by/3.0/. * details, see http://creativecommons.org/licenses/by/3.0/.
*/ */
!function(a){"use strict";a(function(){a(".tooltip-demo").tooltip({selector:'[data-toggle="tooltip"]',container:"body"}),a(".popover-demo").popover({selector:'[data-toggle="popover"]',container:"body"}),a(".tooltip-test").tooltip(),a(".popover-test").popover(),a(".bs-docs-popover").popover(),a(".bs-docs-popover-dismiss").popover({trigger:"focus"}),a("#loading-example-btn").click(function(){var b=a(this);b.button("loading"),setTimeout(function(){b.button("reset")},3e3)}),ZeroClipboard.config({moviePath:"/assets/flash/ZeroClipboard.swf",hoverClass:"btn-clipboard-hover"}),a(".highlight").each(function(){var b=a(this),c=b.prev(),d='<div class="zero-clipboard"><span class="btn-clipboard">Copy</span></div>';c.hasClass("bs-example")?c.before(d.replace(/btn-clipboard/,"btn-clipboard with-example")):b.before(d)});var b=new ZeroClipboard(a(".btn-clipboard")),c=a("#global-zeroclipboard-html-bridge");b.on("load",function(){c.data("placement","top").attr("title","Copy to clipboard").tooltip()}),b.on("dataRequested",function(b){var c=a(this).parent().nextAll(".highlight").first();b.setText(c.text())}),b.on("complete",function(){c.attr("title","Copied!").tooltip("fixTitle").tooltip("show").attr("title","Copy to clipboard").tooltip("fixTitle")}),b.on("noflash wrongflash",function(){c.attr("title","Flash required").tooltip("fixTitle").tooltip("show")})})}(jQuery); !function(a){"use strict";a(function(){a(".tooltip-demo").tooltip({selector:'[data-toggle="tooltip"]',container:"body"}),a(".popover-demo").popover({selector:'[data-toggle="popover"]',container:"body"}),a(".tooltip-test").tooltip(),a(".popover-test").popover(),a(".bs-docs-popover").popover(),a("#loading-example-btn").click(function(){var b=a(this);b.button("loading"),setTimeout(function(){b.button("reset")},3e3)}),ZeroClipboard.config({moviePath:"/assets/flash/ZeroClipboard.swf",hoverClass:"btn-clipboard-hover"}),a(".highlight").each(function(){var b=a(this),c=b.prev(),d='<div class="zero-clipboard"><span class="btn-clipboard">Copy</span></div>';c.hasClass("bs-example")?c.before(d.replace(/btn-clipboard/,"btn-clipboard with-example")):b.before(d)});var b=new ZeroClipboard(a(".btn-clipboard")),c=a("#global-zeroclipboard-html-bridge");b.on("load",function(){c.data("placement","top").attr("title","Copy to clipboard").tooltip()}),b.on("dataRequested",function(b){var c=a(this).parent().nextAll(".highlight").first();b.setText(c.text())}),b.on("complete",function(){c.attr("title","Copied!").tooltip("fixTitle").tooltip("show").attr("title","Copy to clipboard").tooltip("fixTitle")}),b.on("noflash wrongflash",function(){c.attr("title","Flash required").tooltip("fixTitle").tooltip("show")})})}(jQuery);
\ No newline at end of file \ No newline at end of file
...@@ -73,9 +73,8 @@ ...@@ -73,9 +73,8 @@
$('.tooltip-test').tooltip() $('.tooltip-test').tooltip()
$('.popover-test').popover() $('.popover-test').popover()
// Default & dismissible popover demos // Popover demos
$('.bs-docs-popover').popover() $('.bs-docs-popover').popover()
$('.bs-docs-popover-dismiss').popover({ trigger: 'focus' })
// Button state demo // Button state demo
$('#loading-example-btn').click(function () { $('#loading-example-btn').click(function () {
......
...@@ -16,6 +16,9 @@ window.onload = function () { // wait for load in a dumb way because B-0 ...@@ -16,6 +16,9 @@ window.onload = function () { // wait for load in a dumb way because B-0
' * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n' + ' * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n' +
' */\n\n' ' */\n\n'
var supportsFile = (window.File && window.FileReader && window.FileList && window.Blob)
var importDropTarget = $('#import-drop-target')
function showError(msg, err) { function showError(msg, err) {
$('<div id="bsCustomizerAlert" class="bs-customizer-alert">' + $('<div id="bsCustomizerAlert" class="bs-customizer-alert">' +
'<div class="container">' + '<div class="container">' +
...@@ -46,6 +49,11 @@ window.onload = function () { // wait for load in a dumb way because B-0 ...@@ -46,6 +49,11 @@ window.onload = function () { // wait for load in a dumb way because B-0
} }
} }
function showAlert(type, msg, insertAfter) {
$('<div class="alert alert-' + type + '">' + msg + '<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button></div>')
.insertAfter(insertAfter)
}
function getQueryParam(key) { function getQueryParam(key) {
key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, '\\$&') // escape RegEx meta chars key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, '\\$&') // escape RegEx meta chars
var match = location.search.match(new RegExp('[?&]' + key + '=([^&]+)(&|$)')) var match = location.search.match(new RegExp('[?&]' + key + '=([^&]+)(&|$)'))
...@@ -106,6 +114,24 @@ window.onload = function () { // wait for load in a dumb way because B-0 ...@@ -106,6 +114,24 @@ window.onload = function () { // wait for load in a dumb way because B-0
return data return data
} }
function updateCustomizerFromJson(data) {
if (data.js) {
$('#plugin-section input').each(function () {
$(this).prop('checked', ~$.inArray(this.value, data.js))
})
}
if (data.css) {
$('#less-section input').each(function () {
$(this).prop('checked', ~$.inArray(this.value, data.css))
})
}
if (data.vars) {
for (var i in data.vars) {
$('input[data-var="' + i + '"]').val(data.vars[i])
}
}
}
function parseUrl() { function parseUrl() {
var id = getQueryParam('id') var id = getQueryParam('id')
...@@ -118,21 +144,7 @@ window.onload = function () { // wait for load in a dumb way because B-0 ...@@ -118,21 +144,7 @@ window.onload = function () { // wait for load in a dumb way because B-0
}) })
.success(function (result) { .success(function (result) {
var data = JSON.parse(result.files['config.json'].content) var data = JSON.parse(result.files['config.json'].content)
if (data.js) { updateCustomizerFromJson(data)
$('#plugin-section input').each(function () {
$(this).prop('checked', ~$.inArray(this.value, data.js))
})
}
if (data.css) {
$('#less-section input').each(function () {
$(this).prop('checked', ~$.inArray(this.value, data.css))
})
}
if (data.vars) {
for (var i in data.vars) {
$('input[data-var="' + i + '"]').val(data.vars[i])
}
}
}) })
.error(function (err) { .error(function (err) {
showError('Error fetching bootstrap config file', err) showError('Error fetching bootstrap config file', err)
...@@ -324,6 +336,61 @@ window.onload = function () { // wait for load in a dumb way because B-0 ...@@ -324,6 +336,61 @@ window.onload = function () { // wait for load in a dumb way because B-0
} }
} }
function removeImportAlerts() {
importDropTarget.nextAll('.alert').remove()
}
function handleConfigFileSelect(e) {
e.stopPropagation()
e.preventDefault()
var file = (e.originalEvent.hasOwnProperty('dataTransfer')) ? e.originalEvent.dataTransfer.files[0] : e.originalEvent.target.files[0]
if (!file.type.match('application/json')) {
return showAlert('danger', '<strong>Ruh roh.</strong> We can only read <code>.json</code> files. Please try again.', importDropTarget)
}
var reader = new FileReader()
reader.onload = (function () {
return function (e) {
var text = e.target.result
try {
var json = JSON.parse(text)
if (typeof json != 'object') {
throw new Error('JSON data from config file is not an object.')
}
updateCustomizerFromJson(json)
showAlert('success', '<strong>Woohoo!</strong> Your configuration was successfully uploaded. Tweak your settings, then hit Download.', importDropTarget)
} catch (err) {
return showAlert('danger', '<strong>Shucks.</strong> We can only read valid <code>.json</code> files. Please try again.', importDropTarget)
}
}
})(file)
reader.readAsText(file)
}
function handleConfigDragOver(e) {
e.stopPropagation()
e.preventDefault()
e.originalEvent.dataTransfer.dropEffect = 'copy'
removeImportAlerts()
}
if (supportsFile) {
importDropTarget
.on('dragover', handleConfigDragOver)
.on('drop', handleConfigFileSelect)
}
$('#import-file-select').on('select', handleConfigFileSelect)
$('#import-manual-trigger').on('click', removeImportAlerts)
var inputsComponent = $('#less-section input') var inputsComponent = $('#less-section input')
var inputsPlugin = $('#plugin-section input') var inputsPlugin = $('#plugin-section input')
var inputsVariables = $('#less-variables-section input') var inputsVariables = $('#less-variables-section input')
...@@ -410,7 +477,8 @@ window.onload = function () { // wait for load in a dumb way because B-0 ...@@ -410,7 +477,8 @@ window.onload = function () { // wait for load in a dumb way because B-0
{ type: 'image/svg+xml;charset=utf-8' } { type: 'image/svg+xml;charset=utf-8' }
) )
var objectUrl = url.createObjectURL(svg); var objectUrl = url.createObjectURL(svg);
if (/^blob:/.exec(objectUrl) === null) {
if (/^blob:/.exec(objectUrl) === null || !supportsFile) {
// `URL.createObjectURL` created a URL that started with something other // `URL.createObjectURL` created a URL that started with something other
// than "blob:", which means it has been polyfilled and is not supported by // than "blob:", which means it has been polyfilled and is not supported by
// this browser. // this browser.
......
/* Blob.js /* Blob.js
* A Blob implementation. * A Blob implementation.
* 2014-05-31 * 2014-07-01
* *
* By Eli Grey, http://eligrey.com * By Eli Grey, http://eligrey.com
* By Devin Samarin, https://github.com/eboyjr * By Devin Samarin, https://github.com/eboyjr
...@@ -166,7 +166,7 @@ ...@@ -166,7 +166,7 @@
return FakeBlobBuilder; return FakeBlobBuilder;
}(view)); }(view));
view.Blob = function Blob(blobParts, options) { view.Blob = function(blobParts, options) {
var type = options ? (options.type || "") : ""; var type = options ? (options.type || "") : "";
var builder = new BlobBuilder(); var builder = new BlobBuilder();
if (blobParts) { if (blobParts) {
......
/* FileSaver.js /* FileSaver.js
* A saveAs() FileSaver implementation. * A saveAs() FileSaver implementation.
* 2014-05-27 * 2014-07-21
* *
* By Eli Grey, http://eligrey.com * By Eli Grey, http://eligrey.com
* License: X11/MIT * License: X11/MIT
* See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
*/ */
/*global self */ /*global self */
...@@ -49,18 +49,17 @@ var saveAs = saveAs ...@@ -49,18 +49,17 @@ var saveAs = saveAs
} }
, force_saveable_type = "application/octet-stream" , force_saveable_type = "application/octet-stream"
, fs_min_size = 0 , fs_min_size = 0
, deletion_queue = [] // See https://code.google.com/p/chromium/issues/detail?id=375297#c7 for
, process_deletion_queue = function() { // the reasoning behind the timeout and revocation flow
var i = deletion_queue.length; , arbitrary_revoke_timeout = 10
while (i--) { , revoke = function(file) {
var file = deletion_queue[i]; setTimeout(function() {
if (typeof file === "string") { // file is an object URL if (typeof file === "string") { // file is an object URL
get_URL().revokeObjectURL(file); get_URL().revokeObjectURL(file);
} else { // file is a File } else { // file is a File
file.remove(); file.remove();
} }
} }, arbitrary_revoke_timeout);
deletion_queue.length = 0; // clear queue
} }
, dispatch = function(filesaver, event_types, event) { , dispatch = function(filesaver, event_types, event) {
event_types = [].concat(event_types); event_types = [].concat(event_types);
...@@ -84,11 +83,6 @@ var saveAs = saveAs ...@@ -84,11 +83,6 @@ var saveAs = saveAs
, blob_changed = false , blob_changed = false
, object_url , object_url
, target_view , target_view
, get_object_url = function() {
var object_url = get_URL().createObjectURL(blob);
deletion_queue.push(object_url);
return object_url;
}
, dispatch_all = function() { , dispatch_all = function() {
dispatch(filesaver, "writestart progress write writeend".split(" ")); dispatch(filesaver, "writestart progress write writeend".split(" "));
} }
...@@ -96,15 +90,16 @@ var saveAs = saveAs ...@@ -96,15 +90,16 @@ var saveAs = saveAs
, fs_error = function() { , fs_error = function() {
// don't create more object URLs than needed // don't create more object URLs than needed
if (blob_changed || !object_url) { if (blob_changed || !object_url) {
object_url = get_object_url(blob); object_url = get_URL().createObjectURL(blob);
} }
if (target_view) { if (target_view) {
target_view.location.href = object_url; target_view.location.href = object_url;
} else { } else {
window.open(object_url, "_blank"); view.open(object_url, "_blank");
} }
filesaver.readyState = filesaver.DONE; filesaver.readyState = filesaver.DONE;
dispatch_all(); dispatch_all();
revoke(object_url);
} }
, abortable = function(func) { , abortable = function(func) {
return function() { return function() {
...@@ -121,17 +116,20 @@ var saveAs = saveAs ...@@ -121,17 +116,20 @@ var saveAs = saveAs
name = "download"; name = "download";
} }
if (can_use_save_link) { if (can_use_save_link) {
object_url = get_object_url(blob); object_url = get_URL().createObjectURL(blob);
save_link.href = object_url; save_link.href = object_url;
save_link.download = name; save_link.download = name;
click(save_link); click(save_link);
filesaver.readyState = filesaver.DONE; filesaver.readyState = filesaver.DONE;
dispatch_all(); dispatch_all();
revoke(object_url);
return; return;
} }
// Object and web filesystem URLs have a problem saving in Google Chrome when // Object and web filesystem URLs have a problem saving in Google Chrome when
// viewed in a tab, so I force save with application/octet-stream // viewed in a tab, so I force save with application/octet-stream
// http://code.google.com/p/chromium/issues/detail?id=91158 // http://code.google.com/p/chromium/issues/detail?id=91158
// Update: Google errantly closed 91158, I submitted it again:
// https://code.google.com/p/chromium/issues/detail?id=389642
if (view.chrome && type && type !== force_saveable_type) { if (view.chrome && type && type !== force_saveable_type) {
slice = blob.slice || blob.webkitSlice; slice = blob.slice || blob.webkitSlice;
blob = slice.call(blob, 0, blob.size, force_saveable_type); blob = slice.call(blob, 0, blob.size, force_saveable_type);
...@@ -158,9 +156,9 @@ var saveAs = saveAs ...@@ -158,9 +156,9 @@ var saveAs = saveAs
file.createWriter(abortable(function(writer) { file.createWriter(abortable(function(writer) {
writer.onwriteend = function(event) { writer.onwriteend = function(event) {
target_view.location.href = file.toURL(); target_view.location.href = file.toURL();
deletion_queue.push(file);
filesaver.readyState = filesaver.DONE; filesaver.readyState = filesaver.DONE;
dispatch(filesaver, "writeend", event); dispatch(filesaver, "writeend", event);
revoke(file);
}; };
writer.onerror = function() { writer.onerror = function() {
var error = writer.error; var error = writer.error;
...@@ -217,11 +215,6 @@ var saveAs = saveAs ...@@ -217,11 +215,6 @@ var saveAs = saveAs
FS_proto.onwriteend = FS_proto.onwriteend =
null; null;
view.addEventListener("unload", process_deletion_queue, false);
saveAs.unload = function() {
process_deletion_queue();
view.removeEventListener("unload", process_deletion_queue, false);
};
return saveAs; return saveAs;
}( }(
typeof self !== "undefined" && self typeof self !== "undefined" && self
......
...@@ -36,24 +36,12 @@ We publicly list browser bugs that are impacting us here, in the hopes of expedi ...@@ -36,24 +36,12 @@ We publicly list browser bugs that are impacting us here, in the hopes of expedi
<td><a href="{{ site.bug.firefox }}975632">Mozilla bug #975632</a></td> <td><a href="{{ site.bug.firefox }}975632">Mozilla bug #975632</a></td>
<td><a href="{{ site.bug.github }}10690">#10690</a></td> <td><a href="{{ site.bug.github }}10690">#10690</a></td>
</tr> </tr>
<tr>
<td>Firefox <strong>&lt;31</strong></td>
<td><code>position: relative;</code> doesn't work inside tables</td>
<td><a href="{{ site.bug.firefox }}63895">Mozilla bug #63895</a></td>
<td><a href="{{ site.bug.github }}12467">#12467</a></td>
</tr>
<tr> <tr>
<td>Chrome</td> <td>Chrome</td>
<td>Weird button behavior with some number <code>&lt;input&gt;</code>s</td> <td>Weird button behavior with some number <code>&lt;input&gt;</code>s</td>
<td><a href="{{ site.bug.chrome }}337668">Chromium issue #337668</a></td> <td><a href="{{ site.bug.chrome }}337668">Chromium issue #337668</a></td>
<td><a href="{{ site.bug.github }}8350">#8350</a>, <a href="https://github.com/necolas/normalize.css/issues/283">Normalize #283</a></td> <td><a href="{{ site.bug.github }}8350">#8350</a>, <a href="https://github.com/necolas/normalize.css/issues/283">Normalize #283</a></td>
</tr> </tr>
<tr>
<td>Chrome</td>
<td>Navbar rendering problem on Windows after several clicks</td>
<td><a href="{{ site.bug.chrome }}272750">Chromium issue #272750</a>, <a href="{{ site.bug.webkit }}119793">WebKit bug #119793</a></td>
<td><a href="{{ site.bug.github }}9226">#9226</a></td>
</tr>
<tr> <tr>
<td>Chrome</td> <td>Chrome</td>
<td><code>display: table;</code> within <code>display: block;</code> forces sibling content to new line</td> <td><code>display: table;</code> within <code>display: block;</code> forces sibling content to new line</td>
......
...@@ -233,7 +233,7 @@ Use the default option, or add `multiple` to show multiple options at once. ...@@ -233,7 +233,7 @@ Use the default option, or add `multiple` to show multiple options at once.
## Static controls ## Static controls
When you need to place plain text next to a form label within a horizontal form, use the `.form-control-static` class on a `<p>`. When you need to place plain text next to a form label within a form, use the `.form-control-static` class on a `<p>`.
{% example html %} {% example html %}
<form class="form-horizontal" role="form"> <form class="form-horizontal" role="form">
...@@ -252,6 +252,20 @@ When you need to place plain text next to a form label within a horizontal form, ...@@ -252,6 +252,20 @@ When you need to place plain text next to a form label within a horizontal form,
</form> </form>
{% endexample %} {% endexample %}
{% example html %}
<form class="form-inline" role="form">
<div class="form-group">
<label class="sr-only">Email</label>
<p class="form-control-static">email@example.com</p>
</div>
<div class="form-group">
<label for="inputPassword2" class="sr-only">Password</label>
<input type="password" class="form-control" id="inputPassword2" placeholder="Password">
</div>
<button type="submit" class="btn btn-default">Confirm identity</button>
</form>
{% endexample %}
## Focus state ## Focus state
We remove the default `outline` styles on some form controls and apply a `box-shadow` in its place for `:focus`. We remove the default `outline` styles on some form controls and apply a `box-shadow` in its place for `:focus`.
......
...@@ -12,6 +12,7 @@ lead: Customize Bootstrap's components, Less variables, and jQuery plugins to ge ...@@ -12,6 +12,7 @@ lead: Customize Bootstrap's components, Less variables, and jQuery plugins to ge
<!--[if lt IE 9]> <!--[if lt IE 9]>
<style> <style>
.bs-customizer, .bs-customizer,
.bs-customizer-import,
.bs-docs-sidebar { .bs-docs-sidebar {
display: none; display: none;
} }
...@@ -23,6 +24,17 @@ lead: Customize Bootstrap's components, Less variables, and jQuery plugins to ge ...@@ -23,6 +24,17 @@ lead: Customize Bootstrap's components, Less variables, and jQuery plugins to ge
<![endif]--> <![endif]-->
<!-- Customizer form --> <!-- Customizer form -->
<div class="bs-docs-section bs-customizer-import">
<div id="import-drop-target" class="bs-dropzone">
<h2></h2>
<p class="lead">Have an existing configuration? Upload your <code>config.json</code> to import it.</p>
<p>Drag and drop here, or <label id="import-manual-trigger" class="btn-link">manually upload<input type="file" id="import-file-select" class="hidden"></label>.</p>
<hr>
<p><strong>Don't have one?</strong> That's okay—just start customizing the fields below.</p>
</div>
</div><!-- /import -->
<form class="bs-customizer" role="form"> <form class="bs-customizer" role="form">
<div class="bs-docs-section" id="less-section"> <div class="bs-docs-section" id="less-section">
<button class="btn btn-secondary toggle" type="button">Toggle all</button> <button class="btn btn-secondary toggle" type="button">Toggle all</button>
...@@ -358,8 +370,6 @@ lead: Customize Bootstrap's components, Less variables, and jQuery plugins to ge ...@@ -358,8 +370,6 @@ lead: Customize Bootstrap's components, Less variables, and jQuery plugins to ge
{% include customizer-variables.html %} {% include customizer-variables.html %}
</div> </div>
<div class="bs-docs-section"> <div class="bs-docs-section">
<h1 id="download" class="page-header">Download</h1> <h1 id="download" class="page-header">Download</h1>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment