Commit c16fee5e authored by Mark Otto's avatar Mark Otto

Merge branch 'master' into v4

Conflicts:
	.travis.yml
	Gruntfile.js
	bower.json
	dist/css/bootstrap.css
	dist/css/bootstrap.css.map
	dist/css/bootstrap.min.css
	dist/js/bootstrap.js
	dist/js/bootstrap.min.js
	docs/_data/glyphicons.yml
	docs/_includes/components/breadcrumbs.html
	docs/_includes/components/button-dropdowns.html
	docs/_includes/components/button-groups.html
	docs/_includes/components/dropdowns.html
	docs/_includes/components/glyphicons.html
	docs/_includes/components/labels.html
	docs/_includes/components/list-group.html
	docs/_includes/components/media.html
	docs/_includes/components/navs.html
	docs/_includes/components/panels.html
	docs/_includes/components/progress-bars.html
	docs/_includes/components/thumbnails.html
	docs/_includes/components/wells.html
	docs/_includes/css/buttons.html
	docs/_includes/css/forms.html
	docs/_includes/css/helpers.html
	docs/_includes/css/images.html
	docs/_includes/css/less.html
	docs/_includes/customizer-variables.html
	docs/_includes/getting-started/accessibility.html
	docs/_includes/getting-started/browser-device-support.html
	docs/_includes/getting-started/community.html
	docs/_includes/getting-started/examples.html
	docs/_includes/getting-started/grunt.html
	docs/_includes/getting-started/license.html
	docs/_includes/getting-started/template.html
	docs/_includes/header.html
	docs/_includes/js/affix.html
	docs/_includes/js/alerts.html
	docs/_includes/js/carousel.html
	docs/_includes/js/collapse.html
	docs/_includes/js/dropdowns.html
	docs/_includes/js/modal.html
	docs/_includes/js/overview.html
	docs/_includes/js/popovers.html
	docs/_includes/js/scrollspy.html
	docs/_includes/js/tabs.html
	docs/_includes/js/tooltips.html
	docs/_includes/js/transitions.html
	docs/_includes/nav/javascript.html
	docs/_layouts/default.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/assets/js/vendor/FileSaver.js
	docs/assets/js/vendor/autoprefixer.js
	docs/assets/js/vendor/uglify.min.js
	docs/dist/css/bootstrap.css
	docs/dist/css/bootstrap.css.map
	docs/dist/css/bootstrap.min.css
	docs/dist/js/bootstrap.min.js
	docs/examples/blog/index.html
	docs/examples/carousel/index.html
	docs/examples/cover/index.html
	docs/examples/dashboard/index.html
	docs/examples/narrow-jumbotron/narrow-jumbotron.css
	docs/examples/navbar-fixed-top/index.html
	docs/examples/navbar-static-top/index.html
	docs/examples/non-responsive/index.html
	docs/examples/non-responsive/non-responsive.css
	docs/examples/theme/index.html
	grunt/configBridge.json
	js/affix.js
	js/carousel.js
	js/collapse.js
	js/dropdown.js
	js/modal.js
	js/popover.js
	js/scrollspy.js
	js/tab.js
	js/tests/unit/affix.js
	js/tests/unit/button.js
	js/tests/unit/carousel.js
	js/tests/unit/modal.js
	js/tests/unit/tooltip.js
	js/tooltip.js
	less/badges.less
	less/glyphicons.less
	less/type.less
	less/variables.less
	package.json
	scss/_dropdown.scss
	scss/_forms.scss
	test-infra/npm-shrinkwrap.json
parents 50a51ffc 1ba2630c
...@@ -7,3 +7,9 @@ ...@@ -7,3 +7,9 @@
*.md text eol=lf *.md text eol=lf
*.svg text eol=lf *.svg text eol=lf
*.yml text eol=lf *.yml text eol=lf
# Don't diff or textually merge source maps
*.map binary
bootstrap-theme.css linguist-vendored=false
bootstrap.css linguist-vendored=false
bootstrap.js linguist-vendored=false
...@@ -2,12 +2,12 @@ language: node_js ...@@ -2,12 +2,12 @@ language: node_js
git: git:
depth: 10 depth: 10
node_js: node_js:
- "0.10" - "0.12"
before_install: before_install:
- travis_retry sudo pip install -r test-infra/requirements.txt - travis_retry sudo pip install -r test-infra/requirements.txt
- rvm use 1.9.3 --fuzzy - rvm use 1.9.3 --fuzzy
- export GEMDIR=$(rvm gemdir) - export GEMDIR=$(rvm gemdir)
- if [ "$TWBS_TEST" = validate-html ]; then echo "ruby=$(basename $GEMDIR) jekyll=$JEKYLL_VERSION rouge=$ROUGE_VERSION scss-lint=$SCSS_LINT_VERSION" > pseudo_Gemfile.lock; fi - if [ "$TWBS_TEST" = validate-html ]; then echo "ruby=$(basename $GEMDIR) jekyll=$JEKYLL_VERSION rouge=$ROUGE_VERSION" > pseudo_Gemfile.lock; fi
- "export TRAVIS_COMMIT_MSG=\"$(git log --format=%B --no-merges -n 1)\"" - "export TRAVIS_COMMIT_MSG=\"$(git log --format=%B --no-merges -n 1)\""
- echo "$TRAVIS_COMMIT_MSG" | grep '\[skip validator\]'; export TWBS_DO_VALIDATOR=$?; true - echo "$TRAVIS_COMMIT_MSG" | grep '\[skip validator\]'; export TWBS_DO_VALIDATOR=$?; true
- echo "$TRAVIS_COMMIT_MSG" | grep '\[skip sauce\]'; export TWBS_DO_SAUCE=$?; true - echo "$TRAVIS_COMMIT_MSG" | grep '\[skip sauce\]'; export TWBS_DO_SAUCE=$?; true
...@@ -15,12 +15,14 @@ before_install: ...@@ -15,12 +15,14 @@ before_install:
install: install:
- npm install -g grunt-cli - npm install -g grunt-cli
- ./test-infra/s3_cache.py download npm-modules - ./test-infra/s3_cache.py download npm-modules
- if [ -n "$BUNDLE_GEMFILE" ]; then ./test-infra/s3_cache.py download rubygems; fi - if [ "$TWBS_TEST" = validate-html ] && [ $TWBS_DO_VALIDATOR -ne 0 ]; then ./test-infra/s3_cache.py download rubygems; fi
after_script: after_script:
- if [ "$TRAVIS_REPO_SLUG" != twbs-savage/bootstrap ] && [ "$TWBS_TEST" = core ]; then ./test-infra/s3_cache.py upload npm-modules; fi - if [ "$TRAVIS_REPO_SLUG" != twbs-savage/bootstrap ] && [ "$TWBS_TEST" = core ]; then ./test-infra/s3_cache.py upload npm-modules; fi
- if [ "$TRAVIS_REPO_SLUG" != twbs-savage/bootstrap ] && [ -n "$BUNDLE_GEMFILE" ]; then ./test-infra/s3_cache.py upload rubygems; fi - if [ "$TRAVIS_REPO_SLUG" != twbs-savage/bootstrap ] && [ "$TWBS_TEST" = validate-html ] && [ $TWBS_DO_VALIDATOR -ne 0 ]; then ./test-infra/s3_cache.py upload rubygems; fi
env: env:
global: global:
- JEKYLL_VERSION="2.5.3"
- ROUGE_VERSION="1.8.0"
- 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="
...@@ -32,9 +34,8 @@ env: ...@@ -32,9 +34,8 @@ env:
- secure: "PabpUdG2dE40hHUkMCdxk1e9Ak3BOo0h7Y5/uekosLKOz5N60Xmn/ooyrSkvicLthXO4cfONFhO3/xSVRKQOxlUw4on5i0VuNK+QSqxJk0IDaRSZnTCcC8J7083K0YL+FvMdGQwcYwMY9LiwS8aS014IRkSQjsa+mjo3owP+dOU=" - secure: "PabpUdG2dE40hHUkMCdxk1e9Ak3BOo0h7Y5/uekosLKOz5N60Xmn/ooyrSkvicLthXO4cfONFhO3/xSVRKQOxlUw4on5i0VuNK+QSqxJk0IDaRSZnTCcC8J7083K0YL+FvMdGQwcYwMY9LiwS8aS014IRkSQjsa+mjo3owP+dOU="
- secure: "G4/f4PVyVi9o6UbZMqw9YFmDu7cHqe9iymiXYd1RcnPXwhWAePX12m0PWMhUj5itJ180PTEddVip8PNOgBdqyrDxEPKkcgAW2EElVAPIKJXVfvDW64UjQ0H7NS7XvF7iLQUJp/XfmR7NJ7tT393AQdh8SGmuQpJhgYbwIWbES/k=" - secure: "G4/f4PVyVi9o6UbZMqw9YFmDu7cHqe9iymiXYd1RcnPXwhWAePX12m0PWMhUj5itJ180PTEddVip8PNOgBdqyrDxEPKkcgAW2EElVAPIKJXVfvDW64UjQ0H7NS7XvF7iLQUJp/XfmR7NJ7tT393AQdh8SGmuQpJhgYbwIWbES/k="
matrix: matrix:
- TWBS_TEST=core TWBS_SASS=libsass BUNDLE_GEMFILE=test-infra/gemfiles/core.gemfile - TWBS_TEST=core
- TWBS_TEST=core TWBS_SASS=sass BUNDLE_GEMFILE=test-infra/gemfiles/core.gemfile - TWBS_TEST=validate-html
- TWBS_TEST=validate-html BUNDLE_GEMFILE=Gemfile
- TWBS_TEST=sauce-js-unit - TWBS_TEST=sauce-js-unit
matrix: matrix:
fast_finish: true fast_finish: true
......
...@@ -33,7 +33,7 @@ restrictions: ...@@ -33,7 +33,7 @@ restrictions:
Our bug tracker utilizes several labels to help organize and identify issues. Here's what they represent and how we use them: Our bug tracker utilizes several labels to help organize and identify issues. Here's what they represent and how we use them:
- `browser bug` - Issues that are reported to us, but actually are the result of a browser-specific bug. These are diagnosed with reduced test cases and result in a issue opened on that browser's own bug tracker. - `browser bug` - Issues that are reported to us, but actually are the result of a browser-specific bug. These are diagnosed with reduced test cases and result in an issue opened on that browser's own bug tracker.
- `confirmed` - Issues that have been confirmed with a reduced test case and identify a bug in Bootstrap. - `confirmed` - Issues that have been confirmed with a reduced test case and identify a bug in Bootstrap.
- `css` - Issues stemming from our compiled CSS or source Less files. - `css` - Issues stemming from our compiled CSS or source Less files.
- `docs` - Issues for improving or updating our documentation. - `docs` - Issues for improving or updating our documentation.
......
...@@ -294,8 +294,12 @@ module.exports = function (grunt) { ...@@ -294,8 +294,12 @@ module.exports = function (grunt) {
copy: { copy: {
docs: { docs: {
src: 'dist/*/*', expand: true,
dest: 'docs/' cwd: 'dist/',
src: [
'**/*'
],
dest: 'docs/dist/'
} }
}, },
...@@ -371,7 +375,7 @@ module.exports = function (grunt) { ...@@ -371,7 +375,7 @@ module.exports = function (grunt) {
concurrency: 10, concurrency: 10,
maxRetries: 3, maxRetries: 3,
maxPollRetries: 4, maxPollRetries: 4,
urls: ['http://127.0.0.1:3000/js/tests/index.html'], urls: ['http://127.0.0.1:3000/js/tests/index.html?hidepassed'],
browsers: grunt.file.readYAML('grunt/sauce_browsers.yml') browsers: grunt.file.readYAML('grunt/sauce_browsers.yml')
} }
} }
......
...@@ -28,7 +28,8 @@ Four quick start options are available: ...@@ -28,7 +28,8 @@ Four quick start options are available:
- [Download the latest release](https://github.com/twbs/bootstrap/archive/v3.3.2.zip). - [Download the latest release](https://github.com/twbs/bootstrap/archive/v3.3.2.zip).
- Clone the repo: `git clone https://github.com/twbs/bootstrap.git`. - Clone the repo: `git clone https://github.com/twbs/bootstrap.git`.
- Install with [Bower](http://bower.io): `bower install bootstrap`. - Install with [Bower](http://bower.io): `bower install bootstrap`.
- Install with [npm](https://www.npmjs.org): `npm install bootstrap`. - Install with [npm](https://www.npmjs.com): `npm install bootstrap`.
- Install with [Meteor](https://www.meteor.com/): `meteor add twbs:bootstrap`.
Read the [Getting started page](http://getbootstrap.com/getting-started/) for information on the framework contents, templates and examples, and more. Read the [Getting started page](http://getbootstrap.com/getting-started/) for information on the framework contents, templates and examples, and more.
...@@ -92,10 +93,11 @@ Editor preferences are available in the [editor config](https://github.com/twbs/ ...@@ -92,10 +93,11 @@ Editor preferences are available in the [editor config](https://github.com/twbs/
Keep track of development and community news. Keep track of development and community news.
- Follow [@twbootstrap on Twitter](https://twitter.com/twbootstrap). - Follow [@getbootstrap on Twitter](https://twitter.com/getbootstrap).
- Read and subscribe to [The Official Bootstrap Blog](http://blog.getbootstrap.com). - Read and subscribe to [The Official Bootstrap Blog](http://blog.getbootstrap.com).
- Chat with fellow Bootstrappers in IRC. On the `irc.freenode.net` server, in the `##bootstrap` channel. - Chat with fellow Bootstrappers in IRC. On the `irc.freenode.net` server, in the `##bootstrap` channel.
- Implementation help may be found at Stack Overflow (tagged [`twitter-bootstrap-3`](http://stackoverflow.com/questions/tagged/twitter-bootstrap-3)). - Implementation help may be found at Stack Overflow (tagged [`twitter-bootstrap-3`](http://stackoverflow.com/questions/tagged/twitter-bootstrap-3)).
- Developers should use the keyword `bootstrap` on packages which modify or add to the functionality of Bootstrap when distributing through [npm](https://www.npmjs.com/browse/keyword/twbs-bootstrap) or similar delivery mechanisms for maximum discoverability.
......
...@@ -78,6 +78,16 @@ ...@@ -78,6 +78,16 @@
origin: > origin: >
Offshoot of Bootstrap#8350 & Chromium#337668 Offshoot of Bootstrap#8350 & Chromium#337668
-
browser: >
Chrome (OS X)
summary: >
Caps Lock indicator not shown in `<input type="password">` with `display: block`
upstream_bug: >
Chromium#460200
origin: >
Bootstrap#15832
- -
browser: > browser: >
Chrome Chrome
...@@ -170,6 +180,16 @@ ...@@ -170,6 +180,16 @@
origin: > origin: >
Bootstrap#15205 Bootstrap#15205
-
browser: >
Safari (OS X)
summary: >
Caps Lock indicator not shown in `<input type="password">` with `display: block`
upstream_bug: >
WebKit#141804, Safari#19892433
origin: >
Bootstrap#15832
- -
browser: > browser: >
Safari (iOS) Safari (iOS)
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
- name: French - name: French
code: fr code: fr
description: Bootstrap en Français description: Bootstrap en Français
url: http://www.oneskyapp.com/docs/bootstrap/fr url: http://www.oneskyapp.com/fr/docs/bootstrap/getting-started/
- name: German - name: German
code: de code: de
...@@ -31,12 +31,12 @@ ...@@ -31,12 +31,12 @@
- name: Russian - name: Russian
code: ru code: ru
description: Bootstrap по-русски description: Bootstrap по-русски
url: http://www.oneskyapp.com/docs/bootstrap/ru url: http://www.oneskyapp.com/ru/docs/bootstrap/
- name: Spanish - name: Spanish
code: es code: es
description: Bootstrap en Español description: Bootstrap en Español
url: http://www.oneskyapp.com/docs/bootstrap/es url: http://www.oneskyapp.com/es/docs/bootstrap/
- name: Ukrainian - name: Ukrainian
code: uk code: uk
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<p>Designed and built with all the love in the world by <a href="https://twitter.com/mdo" target="_blank">@mdo</a> and <a href="https://twitter.com/fat" target="_blank">@fat</a>.</p> <p>Designed and built with all the love in the world by <a href="https://twitter.com/mdo" target="_blank">@mdo</a> and <a href="https://twitter.com/fat" target="_blank">@fat</a>.</p>
<p>Maintained by the <a href="https://github.com/orgs/twbs/people">core team</a> with the help of <a href="https://github.com/twbs/bootstrap/graphs/contributors">our contributors</a>.</p> <p>Maintained by the <a href="https://github.com/orgs/twbs/people">core team</a> with the help of <a href="https://github.com/twbs/bootstrap/graphs/contributors">our contributors</a>.</p>
<p>Code licensed under <a href="https://github.com/twbs/bootstrap/blob/master/LICENSE" target="_blank">MIT</a>, documentation under <a href="http://creativecommons.org/licenses/by/3.0/">CC BY 3.0</a>.</p> <p>Code licensed under <a rel="license" href="https://github.com/twbs/bootstrap/blob/master/LICENSE" target="_blank">MIT</a>, documentation under <a rel="license" href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC BY 3.0</a>.</p>
<ul class="bs-docs-footer-links text-muted"> <ul class="bs-docs-footer-links text-muted">
<li>Currently v{{ site.current_version }}</li> <li>Currently v{{ site.current_version }}</li>
<li>&middot;</li> <li>&middot;</li>
......
...@@ -7,10 +7,10 @@ ...@@ -7,10 +7,10 @@
<iframe class="github-btn" src="http://ghbtns.com/github-btn.html?user=twbs&amp;repo=bootstrap&amp;type=fork&amp;count=true" width="102" height="20" title="Fork on GitHub"></iframe> <iframe class="github-btn" src="http://ghbtns.com/github-btn.html?user=twbs&amp;repo=bootstrap&amp;type=fork&amp;count=true" width="102" height="20" title="Fork on GitHub"></iframe>
</li> </li>
<li class="follow-btn"> <li class="follow-btn">
<a href="https://twitter.com/twbootstrap" class="twitter-follow-button" data-link-color="#0069D6" data-show-count="true">Follow @twbootstrap</a> <a href="https://twitter.com/getbootstrap" class="twitter-follow-button" data-link-color="#0069D6" data-show-count="true">Follow @getbootstrap</a>
</li> </li>
<li class="tweet-btn"> <li class="tweet-btn">
<a href="https://twitter.com/share" class="twitter-share-button" data-url="http://getbootstrap.com/" data-count="horizontal" data-via="twbootstrap" data-related="mdo:Creator of Bootstrap">Tweet</a> <a href="https://twitter.com/share" class="twitter-share-button" data-url="http://getbootstrap.com/" data-count="horizontal" data-via="getbootstrap" data-related="mdo:Creator of Bootstrap">Tweet</a>
</li> </li>
</ul> </ul>
</div> </div>
...@@ -7,7 +7,7 @@ Bootstrap is released under the MIT license and is copyright {{ site.time | date ...@@ -7,7 +7,7 @@ Bootstrap is released under the MIT license and is copyright {{ site.time | date
#### It requires you to: #### It requires you to:
* Include the license and copyright notice in your works * Keep the license and copyright notice included in Bootstrap's CSS and JavaScript files when you use them in your works
#### It permits you to: #### It permits you to:
......
/**
* Store the link icon as a base64 embedded icon font.
*/
@font-face {
font-family: 'anchorjs-link';
src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg6v8yoAAAC8AAAAYGNtYXDL8RqdAAABHAAAADxnYXNwAAAAEAAAAVgAAAAIZ2x5Zkm2oNUAAAFgAAABWGhlYWQAHd4cAAACuAAAADZoaGVhB3sECwAAAvAAAAAkaG10eAYAAEcAAAMUAAAADGxvY2EACgCsAAADIAAAAAhtYXhwAAYAcAAAAygAAAAgbmFtZUQXtNYAAANIAAABOXBvc3QAAwAAAAAEhAAAACAAAwQAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAACDmAAPA/8D/wAPAAEAAAAAAAAAAAAAAAAAAAAAgAAAAAAACAAAAAwAAABQAAwABAAAAFAAEACgAAAAGAAQAAQACACDmAP//AAAAIOYA////4RoCAAEAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAIARwAHA7kDeQA2AG0AAAEnLgEiBg8BDgEUFh8BHgMXNy4DLwEuATQ2PwE+ATIWHwEeARQGDwEeAxU3PgE0JicBLgMnBx4DHwEeARQGDwEOASImLwEuATQ2PwEuAzUHDgEUFh8BHgEyNj8BPgE0Ji8BA7kEI1ldWiPaIyQkIwQDBgYGBFAEBwYHAwQTExMT2xMwMjETBBMTExNjBwkGA5gkIyMk/r4DBgYGBFAEBwYHAwQTExMT2xMwMjETBBMTExNjBwkGA5gkIyMkBCNZXVoj2iMkJCMEA3UEJCMjJNojWV1aIwQDBgUFA1ACBQUFAwQUMDIxE9oTExMTBBMxMjATYxAhISIRmSNaXVkj/sYDBgUFA1ACBQUFAwQUMDIxE9oTExMTBBMxMjATYxAhISIRmSNaXVkjBCQjIyTaI1ldWiMEAAEAAAABAABR/4xQXw889QALBAAAAAAAzqNM0wAAAADOo0zTAAAAAAO5A3kAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAABHA7kAAQAAAAAAAAAAAAAAAAAAAAMAAAAAAgAAAAQAAEcAAAAAAAoArAABAAAAAwBuAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADgAAAAEAAAAAAAIADgBHAAEAAAAAAAMADgAkAAEAAAAAAAQADgBVAAEAAAAAAAUAFgAOAAEAAAAAAAYABwAyAAEAAAAAAAoAKABjAAMAAQQJAAEADgAAAAMAAQQJAAIADgBHAAMAAQQJAAMADgAkAAMAAQQJAAQADgBVAAMAAQQJAAUAFgAOAAMAAQQJAAYADgA5AAMAAQQJAAoAKABjAGkAYwBvAG0AbwBvAG4AVgBlAHIAcwBpAG8AbgAgADAALgAwAGkAYwBvAG0AbwBvAG5pY29tb29uAGkAYwBvAG0AbwBvAG4AUgBlAGcAdQBsAGEAcgBpAGMAbwBtAG8AbwBuAEcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format('truetype'),
url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAATwAAsAAAAABKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAABCAAAAGAAAABgDq/zKmNtYXAAAAFoAAAAPAAAADzL8RqdZ2FzcAAAAaQAAAAIAAAACAAAABBnbHlmAAABrAAAAVgAAAFYSbag1WhlYWQAAAMEAAAANgAAADYAHd4caGhlYQAAAzwAAAAkAAAAJAd7BAtobXR4AAADYAAAAAwAAAAMBgAAR2xvY2EAAANsAAAACAAAAAgACgCsbWF4cAAAA3QAAAAgAAAAIAAGAHBuYW1lAAADlAAAATkAAAE5RBe01nBvc3QAAATQAAAAIAAAACAAAwAAAAMEAAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAg5gADwP/A/8ADwABAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAgAAAAMAAAAUAAMAAQAAABQABAAoAAAABgAEAAEAAgAg5gD//wAAACDmAP///+EaAgABAAAAAAAAAAEAAf//AA8AAQAAAAAAAAAAAAIAADc5AQAAAAACAEcABwO5A3kANgBtAAABJy4BIgYPAQ4BFBYfAR4DFzcuAy8BLgE0Nj8BPgEyFh8BHgEUBg8BHgMVNz4BNCYnAS4DJwceAx8BHgEUBg8BDgEiJi8BLgE0Nj8BLgM1Bw4BFBYfAR4BMjY/AT4BNCYvAQO5BCNZXVoj2iMkJCMEAwYGBgRQBAcGBwMEExMTE9sTMDIxEwQTExMTYwcJBgOYJCMjJP6+AwYGBgRQBAcGBwMEExMTE9sTMDIxEwQTExMTYwcJBgOYJCMjJAQjWV1aI9ojJCQjBAN1BCQjIyTaI1ldWiMEAwYFBQNQAgUFBQMEFDAyMRPaExMTEwQTMTIwE2MQISEiEZkjWl1ZI/7GAwYFBQNQAgUFBQMEFDAyMRPaExMTEwQTMTIwE2MQISEiEZkjWl1ZIwQkIyMk2iNZXVojBAABAAAAAQAAUf+MUF8PPPUACwQAAAAAAM6jTNMAAAAAzqNM0wAAAAADuQN5AAAACAACAAAAAAAAAAEAAAPA/8AAAAQAAAAARwO5AAEAAAAAAAAAAAAAAAAAAAADAAAAAAIAAAAEAABHAAAAAAAKAKwAAQAAAAMAbgACAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAA4AAAABAAAAAAACAA4ARwABAAAAAAADAA4AJAABAAAAAAAEAA4AVQABAAAAAAAFABYADgABAAAAAAAGAAcAMgABAAAAAAAKACgAYwADAAEECQABAA4AAAADAAEECQACAA4ARwADAAEECQADAA4AJAADAAEECQAEAA4AVQADAAEECQAFABYADgADAAEECQAGAA4AOQADAAEECQAKACgAYwBpAGMAbwBtAG8AbwBuAFYAZQByAHMAaQBvAG4AIAAwAC4AMABpAGMAbwBtAG8AbwBuaWNvbW9vbgBpAGMAbwBtAG8AbwBuAFIAZQBnAHUAbABhAHIAaQBjAG8AbQBvAG8AbgBHAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4AAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format('woff');
font-weight: normal;
font-style: normal;
}
.anchorjs-icon {
font-family: 'anchorjs-link';
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
/* Better Icon Rendering */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/**
* Link placement and hover behavior.
*/
.anchorjs-link {
float: left;
width: 1em;
height: 1em;
margin-left: -1.2em;
opacity: 0;
color: inherit;
text-align: center;
}
@media (max-width: 480px) {
.anchorjs-link {
display: none;
}
}
*:hover > .anchorjs-link,
.anchorjs-link:focus {
opacity: .75;
transition: color .16s linear;
}
*:hover > .anchorjs-link:hover {
opacity: 1;
text-decoration: none;
}
.anchorjs-icon {
font-size: 60%;
vertical-align: .2em;
}
.anchorjs-icon:before {
content: "\e600";
}
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* details, see http://creativecommons.org/licenses/by/3.0/. * details, see http://creativecommons.org/licenses/by/3.0/.
*/ */
/* global ZeroClipboard */ /* global ZeroClipboard, addAnchors */
!function ($) { !function ($) {
'use strict'; 'use strict';
...@@ -153,3 +153,8 @@ ...@@ -153,3 +153,8 @@
}) })
}(jQuery) }(jQuery)
;(function () {
'use strict';
addAnchors('.bs-docs-container h1, .bs-docs-container h2, .bs-docs-container h3, .bs-docs-container h4, .bs-docs-container h5');
})();
/*!
* AnchorJS - v0.1.0 - 2014-08-17
* https://github.com/bryanbraun/anchorjs
* Copyright (c) 2014 Bryan Braun; Licensed MIT
*/
function addAnchors(selector) {
'use strict';
// Sensible default selector, if none is provided.
if (!selector) {
selector = 'h1, h2, h3, h4, h5, h6';
} else if (typeof selector !== 'string') {
throw new Error('AnchorJS accepts only strings; you used a ' + typeof selector);
}
// Select any elements that match the provided selector.
var elements = document.querySelectorAll(selector);
// Loop through the selected elements.
for (var i = 0; i < elements.length; i++) {
var elementID;
if (elements[i].hasAttribute('id')) {
elementID = elements[i].getAttribute('id');
} else {
// We need to create an ID on our element. First, we find which text selection method is available to the browser.
var textMethod = document.body.textContent ? 'textContent' : 'innerText';
// Get the text inside our element
var roughText = elements[i][textMethod];
// Refine it so it makes a good ID. Makes all lowercase and hyphen separated.
// Ex. Hello World > hello-world
var tidyText = roughText.replace(/\s+/g, '-').toLowerCase();
// Assign it to our element.
// Currently the setAttribute element is only supported in IE9 and above.
elements[i].setAttribute('id', tidyText);
// Grab it for use in our anchor.
elementID = tidyText;
}
var anchor = '<a class="anchorjs-link" href="#' + elementID + '"><span class="anchorjs-icon"></span></a>';
elements[i].innerHTML += anchor;
}
}
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
// Import the syntax highlighting // Import the syntax highlighting
@import "syntax"; @import "syntax";
// @import "anchor"; // TODO: move anchor from src to scss directory
// Local docs variables // Local docs variables
$bs-purple: #563d7c; $bs-purple: #563d7c;
......
...@@ -94,14 +94,14 @@ Set an element to `display: block;` and center via `margin`. Available as a mixi ...@@ -94,14 +94,14 @@ Set an element to `display: block;` and center via `margin`. Available as a mixi
{% endexample %} {% endexample %}
{% highlight scss %} {% highlight scss %}
// Classes // Class
.center-block { .center-block {
display: block; display: block;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
} }
// Usage as mixins // Usage as a mixin
.element { .element {
@include center-block; @include center-block;
} }
...@@ -126,7 +126,7 @@ Easily clear `float`s by adding `.clearfix` **to the parent element**. Utilizes ...@@ -126,7 +126,7 @@ Easily clear `float`s by adding `.clearfix` **to the parent element**. Utilizes
} }
} }
// Usage as a Mixin // Usage as a mixin
.element { .element {
@include clearfix; @include clearfix;
} }
...@@ -151,12 +151,12 @@ The `.invisible` class can be used to toggle only the visibility of an element, ...@@ -151,12 +151,12 @@ The `.invisible` class can be used to toggle only the visibility of an element,
{% endhighlight %} {% endhighlight %}
{% highlight scss %} {% highlight scss %}
// Classes // Class
.invisible { .invisible {
visibility: hidden; visibility: hidden;
} }
// Usage as mixin // Usage as a mixin
.element { .element {
.invisible(); .invisible();
} }
...@@ -171,7 +171,7 @@ Hide an element to all devices **except screen readers** with `.sr-only`. Combin ...@@ -171,7 +171,7 @@ Hide an element to all devices **except screen readers** with `.sr-only`. Combin
{% endhighlight %} {% endhighlight %}
{% highlight scss %} {% highlight scss %}
// Usage as a Mixin // Usage as a mixin
.skip-navigation { .skip-navigation {
@include sr-only; @include sr-only;
@include sr-only-focusable; @include sr-only-focusable;
...@@ -187,7 +187,7 @@ Utilize the `.text-hide` class or mixin to help replace an element's text conten ...@@ -187,7 +187,7 @@ Utilize the `.text-hide` class or mixin to help replace an element's text conten
{% endhighlight %} {% endhighlight %}
{% highlight scss %} {% highlight scss %}
// Usage as a Mixin // Usage as a mixin
.heading { .heading {
@include text-hide; @include text-hide;
} }
......
...@@ -336,7 +336,7 @@ We remove the default `outline` styles on some form controls and apply a `box-sh ...@@ -336,7 +336,7 @@ We remove the default `outline` styles on some form controls and apply a `box-sh
## Disabled states ## Disabled states
Add the `disabled` boolean attribute on an `<input>`, `<select>`, or `<textarea>` to prevent user input and trigger a slightly different look. Add the `disabled` boolean attribute on an input to prevent user interactions. Disabled inputs appear lighter and add a `not-allowed` cursor.
{% highlight html %} {% highlight html %}
<input class="form-control" id="disabledInput" type="text" placeholder="Disabled input here..." disabled> <input class="form-control" id="disabledInput" type="text" placeholder="Disabled input here..." disabled>
...@@ -379,7 +379,7 @@ Add the `disabled` attribute to a `<fieldset>` to disable all the controls withi ...@@ -379,7 +379,7 @@ Add the `disabled` attribute to a `<fieldset>` to disable all the controls withi
## Readonly inputs ## Readonly inputs
Add the `readonly` boolean attribute on an input to prevent user input and style the input as disabled. Add the `readonly` boolean attribute on an input to prevent modification of the input's value. Read-only inputs appear lighter (just like disabled inputs), but retain the standard cursor.<
{% example html %} {% example html %}
<input class="form-control" type="text" placeholder="Readonly input here…" readonly> <input class="form-control" type="text" placeholder="Readonly input here…" readonly>
...@@ -389,6 +389,12 @@ Add the `readonly` boolean attribute on an input to prevent user input and style ...@@ -389,6 +389,12 @@ Add the `readonly` boolean attribute on an input to prevent user input and style
Bootstrap includes validation styles for error, warning, and success states on form controls. To use, add `.has-warning`, `.has-error`, or `.has-success` to the parent element. Any `.control-label`, `.form-control`, and `.help-block` within that element will receive the validation styles. Bootstrap includes validation styles for error, warning, and success states on form controls. To use, add `.has-warning`, `.has-error`, or `.has-success` to the parent element. Any `.control-label`, `.form-control`, and `.help-block` within that element will receive the validation styles.
<div class="bs-callout bs-callout-warning" id="callout-form-validation-state-accessibility">
<h4>Conveying validation state to assistive technologies and colorblind users</h4>
<p>Using these validation styles to denote the state of a form control only provides a visual, color-based indication, which will not be conveyed to users of assistive technologies - such as screen readers - or to colorblind users.</p>
<p>Ensure that an alternative indication of state is also provided. For instance, you can include a hint about state in the form control's <code>&lt;label&gt;</code> text itself (as is the case in the following code example), include a <a href="../components/#glyphicons">Glyphicon</a> (with appropriate alternative text using the <code>.sr-only</code> class - see the <a href="../components/#glyphicons-examples">Glyphicon examples</a>), or by providing an additional <a href="#forms-help-text">help text</a> block. Specifically for assistive technologies, invalid form controls can also be assigned an <code>aria-invalid="true"</code> attribute.</p>
</div>
{% example html %} {% example html %}
<div class="form-group has-success"> <div class="form-group has-success">
<label class="control-label" for="inputSuccess1">Input with success</label> <label class="control-label" for="inputSuccess1">Input with success</label>
......
...@@ -37,3 +37,7 @@ Add classes to an `<img>` element to easily style images in any project. ...@@ -37,3 +37,7 @@ Add classes to an `<img>` element to easily style images in any project.
<img src="..." alt="..." class="img-circle"> <img src="..." alt="..." class="img-circle">
<img src="..." alt="..." class="img-thumbnail"> <img src="..." alt="..." class="img-thumbnail">
{% endhighlight %} {% endhighlight %}
## Aligning images
To center images with `.img-responsive`, use `.center-block`. For all other images, use `.text-center`. [See the helper classes section](/css/helpers) for more details about `.center-block` usage.
...@@ -306,10 +306,10 @@ if (typeof jQuery === 'undefined') { ...@@ -306,10 +306,10 @@ if (typeof jQuery === 'undefined') {
this.$element = $(element) this.$element = $(element)
this.$indicators = this.$element.find('.carousel-indicators') this.$indicators = this.$element.find('.carousel-indicators')
this.options = options this.options = options
this.paused = this.paused = null
this.sliding = this.sliding = null
this.interval = this.interval = null
this.$active = this.$active = null
this.$items = null this.$items = null
this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
...@@ -811,7 +811,7 @@ if (typeof jQuery === 'undefined') { ...@@ -811,7 +811,7 @@ if (typeof jQuery === 'undefined') {
return $this.trigger('click') return $this.trigger('click')
} }
var desc = ' li:not(.divider):visible a' var desc = ' li:not(.disabled):visible a'
var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc) var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
if (!$items.length) return if (!$items.length) return
...@@ -918,8 +918,9 @@ if (typeof jQuery === 'undefined') { ...@@ -918,8 +918,9 @@ if (typeof jQuery === 'undefined') {
this.options = options this.options = options
this.$body = $(document.body) this.$body = $(document.body)
this.$element = $(element) this.$element = $(element)
this.$backdrop = this.$backdrop = null
this.isShown = null this.isShown = null
this.originalBodyPad = null
this.scrollbarWidth = 0 this.scrollbarWidth = 0
if (this.options.remote) { if (this.options.remote) {
...@@ -1149,17 +1150,23 @@ if (typeof jQuery === 'undefined') { ...@@ -1149,17 +1150,23 @@ if (typeof jQuery === 'undefined') {
} }
Modal.prototype.checkScrollbar = function () { Modal.prototype.checkScrollbar = function () {
this.bodyIsOverflowing = document.body.scrollHeight > document.documentElement.clientHeight var fullWindowWidth = window.innerWidth
if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
var documentElementRect = document.documentElement.getBoundingClientRect()
fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
}
this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
this.scrollbarWidth = this.measureScrollbar() this.scrollbarWidth = this.measureScrollbar()
} }
Modal.prototype.setScrollbar = function () { Modal.prototype.setScrollbar = function () {
var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
this.originalBodyPad = document.body.style.paddingRight || ''
if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
} }
Modal.prototype.resetScrollbar = function () { Modal.prototype.resetScrollbar = function () {
this.$body.css('padding-right', '') this.$body.css('padding-right', this.originalBodyPad)
} }
Modal.prototype.measureScrollbar = function () { // thx walsh Modal.prototype.measureScrollbar = function () { // thx walsh
...@@ -1241,11 +1248,11 @@ if (typeof jQuery === 'undefined') { ...@@ -1241,11 +1248,11 @@ if (typeof jQuery === 'undefined') {
// =============================== // ===============================
var Tooltip = function (element, options) { var Tooltip = function (element, options) {
this.type = this.type = null
this.options = this.options = null
this.enabled = this.enabled = null
this.timeout = this.timeout = null
this.hoverState = this.hoverState = null
this.$element = null this.$element = null
this.init('tooltip', element, options) this.init('tooltip', element, options)
...@@ -1278,6 +1285,10 @@ if (typeof jQuery === 'undefined') { ...@@ -1278,6 +1285,10 @@ if (typeof jQuery === 'undefined') {
this.options = this.getOptions(options) this.options = this.getOptions(options)
this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
if (this.$element[0] instanceof document.constructor && !this.options.selector) {
throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!');
}
var triggers = this.options.trigger.split(' ') var triggers = this.options.trigger.split(' ')
for (var i = triggers.length; i--;) { for (var i = triggers.length; i--;) {
...@@ -1498,10 +1509,10 @@ if (typeof jQuery === 'undefined') { ...@@ -1498,10 +1509,10 @@ if (typeof jQuery === 'undefined') {
this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
} }
Tooltip.prototype.replaceArrow = function (delta, dimension, isHorizontal) { Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
this.arrow() this.arrow()
.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
.css(isHorizontal ? 'top' : 'left', '') .css(isVertical ? 'top' : 'left', '')
} }
Tooltip.prototype.setContent = function () { Tooltip.prototype.setContent = function () {
...@@ -1514,7 +1525,7 @@ if (typeof jQuery === 'undefined') { ...@@ -1514,7 +1525,7 @@ if (typeof jQuery === 'undefined') {
Tooltip.prototype.hide = function (callback) { Tooltip.prototype.hide = function (callback) {
var that = this var that = this
var $tip = this.tip() var $tip = $(this.$tip)
var e = $.Event('hide.bs.' + this.type) var e = $.Event('hide.bs.' + this.type)
function complete() { function complete() {
...@@ -1531,7 +1542,7 @@ if (typeof jQuery === 'undefined') { ...@@ -1531,7 +1542,7 @@ if (typeof jQuery === 'undefined') {
$tip.removeClass('in') $tip.removeClass('in')
$.support.transition && this.$tip.hasClass('fade') ? $.support.transition && $tip.hasClass('fade') ?
$tip $tip
.one('bsTransitionEnd', complete) .one('bsTransitionEnd', complete)
.emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
...@@ -1774,11 +1785,6 @@ if (typeof jQuery === 'undefined') { ...@@ -1774,11 +1785,6 @@ if (typeof jQuery === 'undefined') {
return (this.$arrow = this.$arrow || this.tip().find('.popover-arrow')) return (this.$arrow = this.$arrow || this.tip().find('.popover-arrow'))
} }
Popover.prototype.tip = function () {
if (!this.$tip) this.$tip = $(this.options.template)
return this.$tip
}
// POPOVER PLUGIN DEFINITION // POPOVER PLUGIN DEFINITION
// ========================= // =========================
...@@ -1827,10 +1833,8 @@ if (typeof jQuery === 'undefined') { ...@@ -1827,10 +1833,8 @@ if (typeof jQuery === 'undefined') {
// ========================== // ==========================
function ScrollSpy(element, options) { function ScrollSpy(element, options) {
var process = $.proxy(this.process, this) this.$body = $(document.body)
this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
this.$body = $('body')
this.$scrollElement = $(element).is('body') ? $(window) : $(element)
this.options = $.extend({}, ScrollSpy.DEFAULTS, options) this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
this.selector = (this.options.target || '') + ' .nav li > a' this.selector = (this.options.target || '') + ' .nav li > a'
this.offsets = [] this.offsets = []
...@@ -1838,7 +1842,7 @@ if (typeof jQuery === 'undefined') { ...@@ -1838,7 +1842,7 @@ if (typeof jQuery === 'undefined') {
this.activeTarget = null this.activeTarget = null
this.scrollHeight = 0 this.scrollHeight = 0
this.$scrollElement.on('scroll.bs.scrollspy', process) this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
this.refresh() this.refresh()
this.process() this.process()
} }
...@@ -1854,19 +1858,18 @@ if (typeof jQuery === 'undefined') { ...@@ -1854,19 +1858,18 @@ if (typeof jQuery === 'undefined') {
} }
ScrollSpy.prototype.refresh = function () { ScrollSpy.prototype.refresh = function () {
var that = this
var offsetMethod = 'offset' var offsetMethod = 'offset'
var offsetBase = 0 var offsetBase = 0
if (!$.isWindow(this.$scrollElement[0])) {
offsetMethod = 'position'
offsetBase = this.$scrollElement.scrollTop()
}
this.offsets = [] this.offsets = []
this.targets = [] this.targets = []
this.scrollHeight = this.getScrollHeight() this.scrollHeight = this.getScrollHeight()
var self = this if (!$.isWindow(this.$scrollElement[0])) {
offsetMethod = 'position'
offsetBase = this.$scrollElement.scrollTop()
}
this.$body this.$body
.find(this.selector) .find(this.selector)
...@@ -1882,8 +1885,8 @@ if (typeof jQuery === 'undefined') { ...@@ -1882,8 +1885,8 @@ if (typeof jQuery === 'undefined') {
}) })
.sort(function (a, b) { return a[0] - b[0] }) .sort(function (a, b) { return a[0] - b[0] })
.each(function () { .each(function () {
self.offsets.push(this[0]) that.offsets.push(this[0])
self.targets.push(this[1]) that.targets.push(this[1])
}) })
} }
...@@ -2077,7 +2080,7 @@ if (typeof jQuery === 'undefined') { ...@@ -2077,7 +2080,7 @@ if (typeof jQuery === 'undefined') {
element.removeClass('fade') element.removeClass('fade')
} }
if (element.parent('.dropdown-menu')) { if (element.parent('.dropdown-menu').length) {
element element
.closest('li.dropdown') .closest('li.dropdown')
.addClass('active') .addClass('active')
...@@ -2164,8 +2167,8 @@ if (typeof jQuery === 'undefined') { ...@@ -2164,8 +2167,8 @@ if (typeof jQuery === 'undefined') {
.on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
this.$element = $(element) this.$element = $(element)
this.affixed = this.affixed = null
this.unpin = this.unpin = null
this.pinnedOffset = null this.pinnedOffset = null
this.checkPosition() this.checkPosition()
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="">
<link rel="icon" href="../../favicon.ico"> <link rel="icon" href="../../favicon.ico">
...@@ -164,6 +165,7 @@ ...@@ -164,6 +165,7 @@
<!-- Placed at the end of the document so the pages load faster --> <!-- Placed at the end of the document so the pages load faster -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="../../dist/js/bootstrap.min.js"></script> <script src="../../dist/js/bootstrap.min.js"></script>
<script src="../../assets/js/docs.min.js"></script> <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../assets/js/ie10-viewport-bug-workaround.js"></script>
</body> </body>
</html> </html>
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="">
<link rel="icon" href="../../favicon.ico"> <link rel="icon" href="../../favicon.ico">
...@@ -50,8 +51,13 @@ ...@@ -50,8 +51,13 @@
<li data-target="#myCarousel" data-slide-to="2"></li> <li data-target="#myCarousel" data-slide-to="2"></li>
</ol> </ol>
<div class="carousel-inner" role="listbox"> <div class="carousel-inner" role="listbox">
<<<<<<< HEAD
<div class="carousel-item active"> <div class="carousel-item active">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="First slide"> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="First slide">
=======
<div class="item active">
<img class="first-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="First slide">
>>>>>>> master
<div class="container"> <div class="container">
<div class="carousel-caption text-left"> <div class="carousel-caption text-left">
<h1>Example headline.</h1> <h1>Example headline.</h1>
...@@ -60,8 +66,13 @@ ...@@ -60,8 +66,13 @@
</div> </div>
</div> </div>
</div> </div>
<<<<<<< HEAD
<div class="carousel-item"> <div class="carousel-item">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAGZmZgAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Second slide"> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAGZmZgAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Second slide">
=======
<div class="item">
<img class="second-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Second slide">
>>>>>>> master
<div class="container"> <div class="container">
<div class="carousel-caption"> <div class="carousel-caption">
<h1>Another example headline.</h1> <h1>Another example headline.</h1>
...@@ -70,8 +81,13 @@ ...@@ -70,8 +81,13 @@
</div> </div>
</div> </div>
</div> </div>
<<<<<<< HEAD
<div class="carousel-item"> <div class="carousel-item">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAFVVVQAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Third slide"> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAFVVVQAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Third slide">
=======
<div class="item">
<img class="third-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Third slide">
>>>>>>> master
<div class="container"> <div class="container">
<div class="carousel-caption text-right"> <div class="carousel-caption text-right">
<h1>One more for good measure.</h1> <h1>One more for good measure.</h1>
...@@ -101,19 +117,19 @@ ...@@ -101,19 +117,19 @@
<!-- Three columns of text below the carousel --> <!-- Three columns of text below the carousel -->
<div class="row"> <div class="row">
<div class="col-lg-4"> <div class="col-lg-4">
<img class="img-circle" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Generic placeholder image" style="width: 140px; height: 140px;"> <img class="img-circle" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Generic placeholder image" width="140" height="140">
<h2>Heading</h2> <h2>Heading</h2>
<p>Donec sed odio dui. Etiam porta sem malesuada magna mollis euismod. Nullam id dolor id nibh ultricies vehicula ut id elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna.</p> <p>Donec sed odio dui. Etiam porta sem malesuada magna mollis euismod. Nullam id dolor id nibh ultricies vehicula ut id elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna.</p>
<p><a class="btn btn-secondary" href="#" role="button">View details &raquo;</a></p> <p><a class="btn btn-secondary" href="#" role="button">View details &raquo;</a></p>
</div><!-- /.col-lg-4 --> </div><!-- /.col-lg-4 -->
<div class="col-lg-4"> <div class="col-lg-4">
<img class="img-circle" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Generic placeholder image" style="width: 140px; height: 140px;"> <img class="img-circle" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Generic placeholder image" width="140" height="140">
<h2>Heading</h2> <h2>Heading</h2>
<p>Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Cras mattis consectetur purus sit amet fermentum. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh.</p> <p>Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Cras mattis consectetur purus sit amet fermentum. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh.</p>
<p><a class="btn btn-secondary" href="#" role="button">View details &raquo;</a></p> <p><a class="btn btn-secondary" href="#" role="button">View details &raquo;</a></p>
</div><!-- /.col-lg-4 --> </div><!-- /.col-lg-4 -->
<div class="col-lg-4"> <div class="col-lg-4">
<img class="img-circle" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Generic placeholder image" style="width: 140px; height: 140px;"> <img class="img-circle" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Generic placeholder image" width="140" height="140">
<h2>Heading</h2> <h2>Heading</h2>
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p> <p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
<p><a class="btn btn-secondary" href="#" role="button">View details &raquo;</a></p> <p><a class="btn btn-secondary" href="#" role="button">View details &raquo;</a></p>
...@@ -131,20 +147,20 @@ ...@@ -131,20 +147,20 @@
<p class="lead">Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.</p> <p class="lead">Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.</p>
</div> </div>
<div class="col-md-5"> <div class="col-md-5">
<img class="featurette-image img-responsive" data-src="holder.js/500x500/auto" alt="Generic placeholder image"> <img class="featurette-image img-responsive center-block" data-src="holder.js/500x500/auto" alt="Generic placeholder image">
</div> </div>
</div> </div>
<hr class="featurette-divider"> <hr class="featurette-divider">
<div class="row featurette"> <div class="row featurette">
<div class="col-md-5"> <div class="col-md-7 col-md-push-5">
<img class="featurette-image img-responsive" data-src="holder.js/500x500/auto" alt="Generic placeholder image">
</div>
<div class="col-md-7">
<h2 class="featurette-heading">Oh yeah, it's that good. <span class="text-muted">See for yourself.</span></h2> <h2 class="featurette-heading">Oh yeah, it's that good. <span class="text-muted">See for yourself.</span></h2>
<p class="lead">Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.</p> <p class="lead">Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.</p>
</div> </div>
<div class="col-md-5 col-md-pull-7">
<img class="featurette-image img-responsive center-block" data-src="holder.js/500x500/auto" alt="Generic placeholder image">
</div>
</div> </div>
<hr class="featurette-divider"> <hr class="featurette-divider">
...@@ -155,7 +171,7 @@ ...@@ -155,7 +171,7 @@
<p class="lead">Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.</p> <p class="lead">Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.</p>
</div> </div>
<div class="col-md-5"> <div class="col-md-5">
<img class="featurette-image img-responsive" data-src="holder.js/500x500/auto" alt="Generic placeholder image"> <img class="featurette-image img-responsive center-block" data-src="holder.js/500x500/auto" alt="Generic placeholder image">
</div> </div>
</div> </div>
...@@ -178,6 +194,9 @@ ...@@ -178,6 +194,9 @@
<!-- Placed at the end of the document so the pages load faster --> <!-- Placed at the end of the document so the pages load faster -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="../../dist/js/bootstrap.min.js"></script> <script src="../../dist/js/bootstrap.min.js"></script>
<script src="../../assets/js/docs.min.js"></script> <!-- Just to make our placeholder images work. Don't actually copy the next line! -->
<script src="../../assets/js/vendor/holder.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../assets/js/ie10-viewport-bug-workaround.js"></script>
</body> </body>
</html> </html>
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="">
<link rel="icon" href="../../favicon.ico"> <link rel="icon" href="../../favicon.ico">
...@@ -64,6 +65,7 @@ ...@@ -64,6 +65,7 @@
<!-- Placed at the end of the document so the pages load faster --> <!-- Placed at the end of the document so the pages load faster -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="../../dist/js/bootstrap.min.js"></script> <script src="../../dist/js/bootstrap.min.js"></script>
<script src="../../assets/js/docs.min.js"></script> <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../assets/js/ie10-viewport-bug-workaround.js"></script>
</body> </body>
</html> </html>
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="">
<link rel="icon" href="../../favicon.ico"> <link rel="icon" href="../../favicon.ico">
...@@ -232,6 +233,9 @@ ...@@ -232,6 +233,9 @@
<!-- Placed at the end of the document so the pages load faster --> <!-- Placed at the end of the document so the pages load faster -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="../../dist/js/bootstrap.min.js"></script> <script src="../../dist/js/bootstrap.min.js"></script>
<script src="../../assets/js/docs.min.js"></script> <!-- Just to make our placeholder images work. Don't actually copy the next line! -->
<script src="../../assets/js/vendor/holder.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../assets/js/ie10-viewport-bug-workaround.js"></script>
</body> </body>
</html> </html>
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="">
<link rel="icon" href="../../favicon.ico"> <link rel="icon" href="../../favicon.ico">
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="">
<link rel="icon" href="../../favicon.ico"> <link rel="icon" href="../../favicon.ico">
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="">
<link rel="icon" href="../../favicon.ico"> <link rel="icon" href="../../favicon.ico">
...@@ -24,6 +25,8 @@ ...@@ -24,6 +25,8 @@
<div class="container"> <div class="container">
<!-- The justified navigation menu is meant for single line per list item.
Multiple lines will require custom code not provided by Bootstrap. -->
<div class="masthead"> <div class="masthead">
<h3 class="text-muted">Project name</h3> <h3 class="text-muted">Project name</h3>
<nav> <nav>
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="">
<link rel="icon" href="../../favicon.ico"> <link rel="icon" href="../../favicon.ico">
...@@ -23,7 +24,7 @@ ...@@ -23,7 +24,7 @@
<body> <body>
<div class="container"> <div class="container">
<div class="header"> <div class="header clearfix">
<nav> <nav>
<ul class="nav nav-pills pull-right"> <ul class="nav nav-pills pull-right">
<li class="nav-item active"> <li class="nav-item active">
......
...@@ -14,11 +14,11 @@ body { ...@@ -14,11 +14,11 @@ body {
/* Custom page header */ /* Custom page header */
.header { .header {
padding-bottom: 1rem;
border-bottom: .05rem solid #e5e5e5; border-bottom: .05rem solid #e5e5e5;
} }
/* Make the masthead heading the same height as the navigation */ /* Make the masthead heading the same height as the navigation */
.header h3 { .header h3 {
padding-bottom: 1.5rem;
margin-top: 0; margin-top: 0;
margin-bottom: 0; margin-bottom: 0;
line-height: 3rem; line-height: 3rem;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="">
<link rel="icon" href="../../favicon.ico"> <link rel="icon" href="../../favicon.ico">
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="">
<link rel="icon" href="../../favicon.ico"> <link rel="icon" href="../../favicon.ico">
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="">
<link rel="icon" href="../../favicon.ico"> <link rel="icon" href="../../favicon.ico">
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="">
<link rel="icon" href="../../favicon.ico"> <link rel="icon" href="../../favicon.ico">
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="">
<link rel="icon" href="../../favicon.ico"> <link rel="icon" href="../../favicon.ico">
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="">
<link rel="icon" href="../../favicon.ico"> <link rel="icon" href="../../favicon.ico">
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="">
<link rel="shortcut icon" href="../../assets/ico/favicon.ico"> <link rel="shortcut icon" href="../../assets/ico/favicon.ico">
......
...@@ -7,13 +7,20 @@ Bootstrap follows common web standards and—with minimal extra effort—can be ...@@ -7,13 +7,20 @@ Bootstrap follows common web standards and—with minimal extra effort—can be
### Skip navigation ### Skip navigation
If your navigation contains many links and comes before the main content in the DOM, add a `Skip to main content` link [before the navigation](http://a11yproject.com/posts/skip-nav-links/). Using the `.sr-only` class will visually hide the skip link, and the `.sr-only-focusable` class will ensure that the link becomes visible once focused (for sighted keyboard users). If your navigation contains many links and comes before the main content in the DOM, add a `Skip to main content` link before the navigation (for a simple explanation, see this [A11Y Project article on skip navigation links](http://a11yproject.com/posts/skip-nav-links/)). Using the `.sr-only` class will visually hide the skip link, and the <code>.sr-only-focusable</code> class will ensure that the link becomes visible once focused (for sighted keyboard users).
<div class="bs-callout bs-callout-danger" id="callout-skiplinks">
<p>Due to long-standing shortcomings/bugs in Chrome (see <a href="https://code.google.com/p/chromium/issues/detail?id=262171" title="Chromium bug tracker - Issue 262171: Focus should cycle from named anchor">issue 262171 in the Chromium bug tracker</a>) and Internet Explorer (see this article on <a href="http://accessibleculture.org/articles/2010/05/in-page-links/">in-page links and focus order</a>), you will need to make sure that the target of your skip link is at least programmatically focusable by adding <code>tabindex="-1"</code>.</p>
<p>In addition, you may want to explicitly suppress a visible focus indication on the target (particularly as Chrome currently also sets focus on elements with <code>tabindex="-1"</code> when they are clicked with the mouse) with <code>#content:focus { outline: none; }</code>.</p>
<p>Note that this bug will also affect any other in-page links your site may be using, rendering them useless for keyboard users. You may consider adding a similar stop-gap fix to all other named anchors / fragment identifiers that act as link targets.</p>
</div>
{% highlight html %} {% highlight html %}
<body> <body>
<a href="#content" class="sr-only sr-only-focusable">Skip to main content</a> <a href="#content" class="sr-only sr-only-focusable">Skip to main content</a>
<div class="container" id="content"> ...
The main page content. <div class="container" id="content" tabindex="-1">
<!-- The main page content -->
</div> </div>
</body> </body>
{% endhighlight %} {% endhighlight %}
......
...@@ -9,6 +9,7 @@ Stay up to date on the development of Bootstrap and reach out to the community w ...@@ -9,6 +9,7 @@ Stay up to date on the development of Bootstrap and reach out to the community w
- Chat with fellow Bootstrappers using IRC in the `irc.freenode.net` server, in the [##twitter-bootstrap channel](irc://irc.freenode.net/%23twitter-bootstrap). - Chat with fellow Bootstrappers using IRC in the `irc.freenode.net` server, in the [##twitter-bootstrap channel](irc://irc.freenode.net/%23twitter-bootstrap).
- For help using Bootstrap, ask on [StackOverflow using the tag `twitter-bootstrap-3`](http://stackoverflow.com/questions/tagged/twitter-bootstrap-3). - For help using Bootstrap, ask on [StackOverflow using the tag `twitter-bootstrap-3`](http://stackoverflow.com/questions/tagged/twitter-bootstrap-3).
- Find inspiring examples of people building with Bootstrap at the [Bootstrap Expo](http://expo.getbootstrap.com). - Find inspiring examples of people building with Bootstrap at the [Bootstrap Expo](http://expo.getbootstrap.com).
- Developers should use the keyword `bootstrap` on packages which modify or add to the functionality of Bootstrap when distributing through [npm](https://www.npmjs.com/browse/keyword/bootstrap) or similar delivery mechanisms for maximum discoverability.
You can also follow [@twbootstrap on Twitter](https://twitter.com/twbootstrap) for the latest gossip and awesome music videos. You can also follow [@getbootstrap on Twitter](https://twitter.com/getbootstrap) for the latest gossip and awesome music videos.
...@@ -7,7 +7,7 @@ Bootstrap uses [Grunt](http://gruntjs.com) for its build system, with convenient ...@@ -7,7 +7,7 @@ Bootstrap uses [Grunt](http://gruntjs.com) for its build system, with convenient
### Install Grunt ### Install Grunt
**To install Grunt, you must first [download and install node.js](http://nodejs.org/download/)** (which includes npm). npm stands for [node packaged modules](http://npmjs.org/) and is a way to manage development dependencies through node.js. **To install Grunt, you must first [download and install node.js](http://nodejs.org/download/)** (which includes npm). npm stands for [node packaged modules](http://npmjs.com/) and is a way to manage development dependencies through node.js.
From the command line: From the command line:
...@@ -17,7 +17,7 @@ From the command line: ...@@ -17,7 +17,7 @@ From the command line:
When completed, you'll be able to run the various Grunt commands provided from the command line. When completed, you'll be able to run the various Grunt commands provided from the command line.
**Unfamiliar with npm? Don't have node installed?** That's a-okay. npm stands for [node packaged modules](http://npmjs.org/) and is a way to manage development dependencies through node.js. [Download and install node.js](http://nodejs.org/download/) before proceeding. **Unfamiliar with npm? Don't have node installed?** That's a-okay. npm stands for [node packaged modules](http://npmjs.com/) and is a way to manage development dependencies through node.js. [Download and install node.js](http://nodejs.org/download/) before proceeding.
[install-ruby]: https://www.ruby-lang.org/en/documentation/installation/ [install-ruby]: https://www.ruby-lang.org/en/documentation/installation/
[gembundler]: http://bundler.io/ [gembundler]: http://bundler.io/
......
...@@ -14,6 +14,7 @@ Copy the HTML below to begin working with a minimal Bootstrap document. ...@@ -14,6 +14,7 @@ Copy the HTML below to begin working with a minimal Bootstrap document.
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags. -->
<title>Bootstrap 101 Template</title> <title>Bootstrap 101 Template</title>
<!-- Bootstrap --> <!-- Bootstrap -->
...@@ -23,7 +24,7 @@ Copy the HTML below to begin working with a minimal Bootstrap document. ...@@ -23,7 +24,7 @@ Copy the HTML below to begin working with a minimal Bootstrap document.
<h1>Hello, world!</h1> <h1>Hello, world!</h1>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed --> <!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script> <script src="js/bootstrap.min.js"></script>
</body> </body>
......
...@@ -4,7 +4,7 @@ title: Bootstrap &middot; The world's most popular mobile-first and responsive f ...@@ -4,7 +4,7 @@ title: Bootstrap &middot; The world's most popular mobile-first and responsive f
--- ---
<main class="bs-docs-masthead" id="content" role="main"> <main class="bs-docs-masthead" id="content" role="main" tabindex="-1">
<div class="container"> <div class="container">
<span class="bs-docs-booticon outline">B</span> <span class="bs-docs-booticon outline">B</span>
<p class="lead">Bootstrap is the most popular HTML, CSS, and JS framework for developing responsive, mobile first projects on the web.</p> <p class="lead">Bootstrap is the most popular HTML, CSS, and JS framework for developing responsive, mobile first projects on the web.</p>
......
...@@ -208,6 +208,7 @@ Bootstrap's carousel class exposes two events for hooking into carousel function ...@@ -208,6 +208,7 @@ Bootstrap's carousel class exposes two events for hooking into carousel function
- `direction`: The direction in which the carousel is sliding (either `"left"` or `"right"`). - `direction`: The direction in which the carousel is sliding (either `"left"` or `"right"`).
- `relatedTarget`: The DOM element that is being slid into place as the active item. - `relatedTarget`: The DOM element that is being slid into place as the active item.
All carousel events are fired at the carousel itself (i.e. at the `<div class="carousel">`).
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-bordered table-striped"> <table class="table table-bordered table-striped">
......
...@@ -248,52 +248,70 @@ For modals that simply appear rather than fade in to view, remove the `.fade` cl ...@@ -248,52 +248,70 @@ For modals that simply appear rather than fade in to view, remove the `.fade` cl
</div> </div>
{% endhighlight %} {% endhighlight %}
## Varying modal content based on trigger button ## Using the grid system
Have a bunch of buttons that all trigger the same modal, just with slightly different contents? Use `event.relatedTarget` and [HTML `data-*` attributes](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes) (possibly [via jQuery](http://api.jquery.com/data/)) to vary the contents of the modal depending on which button was clicked. See the Modal Events docs for details on `relatedTarget`.
<div class="bs-example" style="padding-bottom: 24px;"> To take advantage of the Bootstrap grid system within a modal, just nest `.container-fluid within the `.modal-body` and then use the normal grid system classes within this container.
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@mdo">Open modal for @mdo</button>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@fat">Open modal for @fat</button>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@twbootstrap">Open modal for @twbootstrap</button>
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> {% example html %}
<div id="gridSystemModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="gridModalLabel" aria-hidden="true">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<span aria-hidden="true">&times;</span> <h4 class="modal-title" id="gridModalLabel">Modal title</h4>
<span class="sr-only">Close</span>
</button>
<h4 class="modal-title" id="exampleModalLabel">New message</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form> <div class="container-fluid">
<div class="form-group"> <div class="row">
<label for="recipient-name" class="control-label">Recipient:</label> <div class="col-md-4">.col-md-4</div>
<input type="text" class="form-control" id="recipient-name"> <div class="col-md-4 col-md-offset-4">.col-md-4 .col-md-offset-4</div>
</div> </div>
<div class="form-group"> <div class="row">
<label for="message-text" class="control-label">Message:</label> <div class="col-md-3 col-md-offset-3">.col-md-3 .col-md-offset-3</div>
<textarea class="form-control" id="message-text"></textarea> <div class="col-md-2 col-md-offset-4">.col-md-2 .col-md-offset-4</div>
</div> </div>
</form> <div class="row">
<div class="col-md-6 col-md-offset-3">.col-md-6 .col-md-offset-3</div>
</div> </div>
<div class="modal-footer"> <div class="row">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> <div class="col-sm-9">
<button type="button" class="btn btn-primary">Send message</button> Level 1: .col-sm-9
<div class="row">
<div class="col-xs-8 col-sm-6">
Level 2: .col-xs-8 .col-sm-6
</div> </div>
<div class="col-xs-4 col-sm-6">
Level 2: .col-xs-4 .col-sm-6
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
<div class="bs-example bs-example-padded-bottom">
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#gridSystemModal">
Launch demo modal
</button>
</div> </div>
{% endexample %}
{% highlight html %} ## Varying modal content based on trigger button
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@mdo">Open modal for @mdo</button>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@fat">Open modal for @fat</button> Have a bunch of buttons that all trigger the same modal, just with slightly different contents? Use `event.relatedTarget` and [HTML `data-*` attributes](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes) (possibly [via jQuery](http://api.jquery.com/data/)) to vary the contents of the modal depending on which button was clicked. See the Modal Events docs for details on `relatedTarget`.
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@twbootstrap">Open modal for @twbootstrap</button>
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> {% example html %}
<div class="bs-example">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@mdo">Open modal for @mdo</button>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@fat">Open modal for @fat</button>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@getbootstrap">Open modal for @getbootstrap</button>
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
...@@ -321,8 +339,9 @@ Have a bunch of buttons that all trigger the same modal, just with slightly diff ...@@ -321,8 +339,9 @@ Have a bunch of buttons that all trigger the same modal, just with slightly diff
</div> </div>
</div> </div>
</div> </div>
</div>
</div> </div>
{% endhighlight %} {% endexample %}
{% highlight js %} {% highlight js %}
$('#exampleModal').on('show.bs.modal', function (event) { $('#exampleModal').on('show.bs.modal', function (event) {
...@@ -336,6 +355,10 @@ $('#exampleModal').on('show.bs.modal', function (event) { ...@@ -336,6 +355,10 @@ $('#exampleModal').on('show.bs.modal', function (event) {
}) })
{% endhighlight %} {% endhighlight %}
## Modals with dynamic heights
If the height of a modal changes while it is open, you should call `$('#myModal').data('bs.modal').handleUpdate()` to readjust the modal's position in case a scrollbar appears.
## Usage ## Usage
The modal plugin toggles your hidden content on demand, via data attributes or JavaScript. It also adds `.modal-open` to the `<body>` to override default scrolling behavior and generates a `.modal-backdrop` to provide a click area for dismissing shown modals when clicking outside the modal. The modal plugin toggles your hidden content on demand, via data attributes or JavaScript. It also adds `.modal-open` to the `<body>` to override default scrolling behavior and generates a `.modal-backdrop` to provide a click area for dismissing shown modals when clicking outside the modal.
...@@ -423,7 +446,7 @@ Manually hides a modal. **Returns to the caller before the modal has actually be ...@@ -423,7 +446,7 @@ Manually hides a modal. **Returns to the caller before the modal has actually be
### Events ### Events
Bootstrap's modal class exposes a few events for hooking into modal functionality. Bootstrap's modal class exposes a few events for hooking into modal functionality. All modal events are fired at the modal itself (i.e. at the `<div class="modal">`).
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-bordered table-striped"> <table class="table table-bordered table-striped">
......
...@@ -289,7 +289,8 @@ Toggles an element's popover. **Returns to the caller before the popover has act ...@@ -289,7 +289,8 @@ Toggles an element's popover. **Returns to the caller before the popover has act
#### .popover('destroy') #### .popover('destroy')
Hides and destroys an element's popover. Hides and destroys an element's popover. Popvoers that use delegation (which are created using [the `selector` option](#popovers-options)) cannot be individually destroyed on descendant trigger elements.
{% highlight js %}$('#element').popover('destroy'){% endhighlight %} {% highlight js %}$('#element').popover('destroy'){% endhighlight %}
......
...@@ -74,9 +74,9 @@ body { ...@@ -74,9 +74,9 @@ body {
{% endhighlight %} {% endhighlight %}
{% highlight html %} {% highlight html %}
<body data-spy="scroll" data-target=".navbar-example"> <body data-spy="scroll" data-target="#navbar-example">
... ...
<div class="navbar-example"> <div id="navbar-example">
<ul class="nav nav-tabs" role="tablist"> <ul class="nav nav-tabs" role="tablist">
... ...
</ul> </ul>
...@@ -90,7 +90,7 @@ body { ...@@ -90,7 +90,7 @@ body {
After adding `position: relative;` in your CSS, call the scrollspy via JavaScript: After adding `position: relative;` in your CSS, call the scrollspy via JavaScript:
{% highlight js %} {% highlight js %}
$('body').scrollspy({ target: '.navbar-example' }) $('body').scrollspy({ target: '#navbar-example' })
{% endhighlight %} {% endhighlight %}
<div class="bs-callout bs-callout-danger"> <div class="bs-callout bs-callout-danger">
......
...@@ -259,7 +259,7 @@ Toggles an element's tooltip. **Returns to the caller before the tooltip has act ...@@ -259,7 +259,7 @@ Toggles an element's tooltip. **Returns to the caller before the tooltip has act
#### .tooltip('destroy') #### .tooltip('destroy')
Hides and destroys an element's tooltip. Hides and destroys an element's tooltip. Tooltips that use delegation (which are created using [the `selector` option](#tooltips-options)) cannot be individually destroyed on descendant trigger elements.
{% highlight js %}$('#element').tooltip('destroy'){% endhighlight %} {% highlight js %}$('#element').tooltip('destroy'){% endhighlight %}
......
{ {
"paths": { "paths": {
"docsJs": [ "docsJs": [
"assets/js/vendor/holder.js", "assets/js/vendor/holder.js",
"assets/js/vendor/jekyll-search.js", "assets/js/vendor/jekyll-search.js",
"assets/js/vendor/ZeroClipboard.min.js", "assets/js/vendor/ZeroClipboard.min.js",
"assets/js/vendor/anchor.js",
"assets/js/src/application.js" "assets/js/src/application.js"
] ]
},
"config": {
"autoprefixerBrowsers": [
"Android 2.3",
"Android >= 4",
"Chrome >= 20",
"Firefox >= 24",
"Explorer >= 8",
"iOS >= 6",
"Opera >= 12",
"Safari >= 6"
],
"jqueryCheck": [
"if (typeof jQuery === 'undefined') {",
" throw new Error('Bootstrap\\'s JavaScript requires jQuery')",
"}\n"
],
"jqueryVersionCheck": [
"+function ($) {",
" 'use strict';",
" var version = $.fn.jquery.split(' ')[0].split('.')",
" if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {",
" throw new Error('Bootstrap\\'s JavaScript requires jQuery version 1.9.1 or higher')",
" }",
"}(jQuery);\n\n"
]
} }
} }
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
{ {
browserName: "iphone", browserName: "iphone",
platform: "OS X 10.9", platform: "OS X 10.10",
version: "8.1" version: "8.1"
}, },
......
...@@ -12,10 +12,6 @@ ...@@ -12,10 +12,6 @@
<link rel="stylesheet" href="vendor/qunit.css" media="screen"> <link rel="stylesheet" href="vendor/qunit.css" media="screen">
<script src="vendor/qunit.js"></script> <script src="vendor/qunit.js"></script>
<style> <style>
#qunit-tests > li.pass {
display: none;/* Make it easier to see failing tests in Sauce screencasts */
}
#qunit-fixture { #qunit-fixture {
top: 0; top: 0;
left: 0; left: 0;
...@@ -43,12 +39,12 @@ ...@@ -43,12 +39,12 @@
QUnit.testStart(function (testDetails) { QUnit.testStart(function (testDetails) {
$(window).scrollTop(0) $(window).scrollTop(0)
QUnit.log = function (details) { QUnit.log(function (details) {
if (!details.result) { if (!details.result) {
details.name = testDetails.name details.name = testDetails.name
log.push(details) log.push(details)
} }
} })
}) })
// Cleanup // Cleanup
......
$(function () { $(function () {
'use strict'; 'use strict';
module('alert plugin') QUnit.module('alert plugin')
test('should be defined on jquery object', function () { QUnit.test('should be defined on jquery object', function (assert) {
ok($(document.body).alert, 'alert method is defined') assert.ok($(document.body).alert, 'alert method is defined')
}) })
module('alert', { QUnit.module('alert', {
setup: function () { beforeEach: function () {
// Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode
$.fn.bootstrapAlert = $.fn.alert.noConflict() $.fn.bootstrapAlert = $.fn.alert.noConflict()
}, },
teardown: function () { afterEach: function () {
$.fn.alert = $.fn.bootstrapAlert $.fn.alert = $.fn.bootstrapAlert
delete $.fn.bootstrapAlert delete $.fn.bootstrapAlert
} }
}) })
test('should provide no conflict', function () { QUnit.test('should provide no conflict', function (assert) {
strictEqual($.fn.alert, undefined, 'alert was set back to undefined (org value)') assert.strictEqual($.fn.alert, undefined, 'alert was set back to undefined (org value)')
}) })
test('should return jquery collection containing the element', function () { QUnit.test('should return jquery collection containing the element', function (assert) {
var $el = $('<div/>') var $el = $('<div/>')
var $alert = $el.bootstrapAlert() var $alert = $el.bootstrapAlert()
ok($alert instanceof $, 'returns jquery collection') assert.ok($alert instanceof $, 'returns jquery collection')
strictEqual($alert[0], $el[0], 'collection contains element') assert.strictEqual($alert[0], $el[0], 'collection contains element')
}) })
test('should fade element out on clicking .close', function () { QUnit.test('should fade element out on clicking .close', function (assert) {
var alertHTML = '<div class="alert alert-danger fade in">' var alertHTML = '<div class="alert alert-danger fade in">'
+ '<a class="close" href="#" data-dismiss="alert">×</a>' + '<a class="close" href="#" data-dismiss="alert">×</a>'
+ '<p><strong>Holy guacamole!</strong> Best check yo self, you\'re not looking too good.</p>' + '<p><strong>Holy guacamole!</strong> Best check yo self, you\'re not looking too good.</p>'
...@@ -38,33 +38,33 @@ $(function () { ...@@ -38,33 +38,33 @@ $(function () {
$alert.find('.close').click() $alert.find('.close').click()
equal($alert.hasClass('in'), false, 'remove .in class on .close click') assert.strictEqual($alert.hasClass('in'), false, 'remove .in class on .close click')
}) })
test('should remove element when clicking .close', function () { QUnit.test('should remove element when clicking .close', function (assert) {
var alertHTML = '<div class="alert alert-danger fade in">' var alertHTML = '<div class="alert alert-danger fade in">'
+ '<a class="close" href="#" data-dismiss="alert">×</a>' + '<a class="close" href="#" data-dismiss="alert">×</a>'
+ '<p><strong>Holy guacamole!</strong> Best check yo self, you\'re not looking too good.</p>' + '<p><strong>Holy guacamole!</strong> Best check yo self, you\'re not looking too good.</p>'
+ '</div>' + '</div>'
var $alert = $(alertHTML).appendTo('#qunit-fixture').bootstrapAlert() var $alert = $(alertHTML).appendTo('#qunit-fixture').bootstrapAlert()
notEqual($('#qunit-fixture').find('.alert').length, 0, 'element added to dom') assert.notEqual($('#qunit-fixture').find('.alert').length, 0, 'element added to dom')
$alert.find('.close').click() $alert.find('.close').click()
equal($('#qunit-fixture').find('.alert').length, 0, 'element removed from dom') assert.strictEqual($('#qunit-fixture').find('.alert').length, 0, 'element removed from dom')
}) })
test('should not fire closed when close is prevented', function (assert) { QUnit.test('should not fire closed when close is prevented', function (assert) {
var done = assert.async() var done = assert.async()
$('<div class="alert"/>') $('<div class="alert"/>')
.on('close.bs.alert', function (e) { .on('close.bs.alert', function (e) {
e.preventDefault() e.preventDefault()
ok(true, 'close event fired') assert.ok(true, 'close event fired')
done() done()
}) })
.on('closed.bs.alert', function () { .on('closed.bs.alert', function () {
ok(false, 'closed event fired') assert.ok(false, 'closed event fired')
}) })
.bootstrapAlert('close') .bootstrapAlert('close')
}) })
......
$(function () { $(function () {
'use strict'; 'use strict';
module('collapse plugin') QUnit.module('collapse plugin')
test('should be defined on jquery object', function () { QUnit.test('should be defined on jquery object', function (assert) {
ok($(document.body).collapse, 'collapse method is defined') assert.ok($(document.body).collapse, 'collapse method is defined')
}) })
module('collapse', { QUnit.module('collapse', {
setup: function () { beforeEach: function () {
// Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode
$.fn.bootstrapCollapse = $.fn.collapse.noConflict() $.fn.bootstrapCollapse = $.fn.collapse.noConflict()
}, },
teardown: function () { afterEach: function () {
$.fn.collapse = $.fn.bootstrapCollapse $.fn.collapse = $.fn.bootstrapCollapse
delete $.fn.bootstrapCollapse delete $.fn.bootstrapCollapse
} }
}) })
test('should provide no conflict', function () { QUnit.test('should provide no conflict', function (assert) {
strictEqual($.fn.collapse, undefined, 'collapse was set back to undefined (org value)') assert.strictEqual($.fn.collapse, undefined, 'collapse was set back to undefined (org value)')
}) })
test('should return jquery collection containing the element', function () { QUnit.test('should return jquery collection containing the element', function (assert) {
var $el = $('<div/>') var $el = $('<div/>')
var $collapse = $el.bootstrapCollapse() var $collapse = $el.bootstrapCollapse()
ok($collapse instanceof $, 'returns jquery collection') assert.ok($collapse instanceof $, 'returns jquery collection')
strictEqual($collapse[0], $el[0], 'collection contains element') assert.strictEqual($collapse[0], $el[0], 'collection contains element')
}) })
test('should show a collapsed element', function () { QUnit.test('should show a collapsed element', function (assert) {
var $el = $('<div class="collapse"/>').bootstrapCollapse('show') var $el = $('<div class="collapse"/>').bootstrapCollapse('show')
ok($el.hasClass('in'), 'has class "in"') assert.ok($el.hasClass('in'), 'has class "in"')
ok(!/height/i.test($el.attr('style')), 'has height reset') assert.ok(!/height/i.test($el.attr('style')), 'has height reset')
}) })
test('should hide a collapsed element', function () { QUnit.test('should hide a collapsed element', function (assert) {
var $el = $('<div class="collapse"/>').bootstrapCollapse('hide') var $el = $('<div class="collapse"/>').bootstrapCollapse('hide')
ok(!$el.hasClass('in'), 'does not have class "in"') assert.ok(!$el.hasClass('in'), 'does not have class "in"')
ok(/height/i.test($el.attr('style')), 'has height set') assert.ok(/height/i.test($el.attr('style')), 'has height set')
}) })
test('should not fire shown when show is prevented', function (assert) { QUnit.test('should not fire shown when show is prevented', function (assert) {
var done = assert.async() var done = assert.async()
$('<div class="collapse"/>') $('<div class="collapse"/>')
.on('show.bs.collapse', function (e) { .on('show.bs.collapse', function (e) {
e.preventDefault() e.preventDefault()
ok(true, 'show event fired') assert.ok(true, 'show event fired')
done() done()
}) })
.on('shown.bs.collapse', function () { .on('shown.bs.collapse', function () {
ok(false, 'shown event fired') assert.ok(false, 'shown event fired')
}) })
.bootstrapCollapse('show') .bootstrapCollapse('show')
}) })
test('should reset style to auto after finishing opening collapse', function (assert) { QUnit.test('should reset style to auto after finishing opening collapse', function (assert) {
var done = assert.async() var done = assert.async()
$('<div class="collapse" style="height: 0px"/>') $('<div class="collapse" style="height: 0px"/>')
.on('show.bs.collapse', function () { .on('show.bs.collapse', function () {
equal(this.style.height, '0px', 'height is 0px') assert.strictEqual(this.style.height, '0px', 'height is 0px')
}) })
.on('shown.bs.collapse', function () { .on('shown.bs.collapse', function () {
strictEqual(this.style.height, '', 'height is auto') assert.strictEqual(this.style.height, '', 'height is auto')
done() done()
}) })
.bootstrapCollapse('show') .bootstrapCollapse('show')
}) })
test('should remove "collapsed" class from target when collapse is shown', function (assert) { QUnit.test('should remove "collapsed" class from target when collapse is shown', function (assert) {
var done = assert.async() var done = assert.async()
var $target = $('<a data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture') var $target = $('<a data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
...@@ -80,14 +80,14 @@ $(function () { ...@@ -80,14 +80,14 @@ $(function () {
$('<div id="test1"/>') $('<div id="test1"/>')
.appendTo('#qunit-fixture') .appendTo('#qunit-fixture')
.on('shown.bs.collapse', function () { .on('shown.bs.collapse', function () {
ok(!$target.hasClass('collapsed')) assert.ok(!$target.hasClass('collapsed'), 'target does not have collapsed class')
done() done()
}) })
$target.click() $target.click()
}) })
test('should add "collapsed" class to target when collapse is hidden', function (assert) { QUnit.test('should add "collapsed" class to target when collapse is hidden', function (assert) {
var done = assert.async() var done = assert.async()
var $target = $('<a data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture') var $target = $('<a data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
...@@ -95,22 +95,56 @@ $(function () { ...@@ -95,22 +95,56 @@ $(function () {
$('<div id="test1" class="in"/>') $('<div id="test1" class="in"/>')
.appendTo('#qunit-fixture') .appendTo('#qunit-fixture')
.on('hidden.bs.collapse', function () { .on('hidden.bs.collapse', function () {
ok($target.hasClass('collapsed')) assert.ok($target.hasClass('collapsed'), 'target has collapsed class')
done() done()
}) })
$target.click() $target.click()
}) })
test('should not close a collapse when initialized with "show" if already shown', function (assert) { QUnit.test('should remove "collapsed" class from all triggers targeting the collapse when the collapse is shown', function (assert) {
var done = assert.async() var done = assert.async()
expect(0) var $target = $('<a data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
var $alt = $('<a data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
$('<div id="test1"/>')
.appendTo('#qunit-fixture')
.on('shown.bs.collapse', function () {
assert.ok(!$target.hasClass('collapsed'), 'target trigger does not have collapsed class')
assert.ok(!$alt.hasClass('collapsed'), 'alt trigger does not have collapsed class')
done()
})
$target.click()
})
QUnit.test('should add "collapsed" class to all triggers targeting the collapse when the collapse is hidden', function (assert) {
var done = assert.async()
var $target = $('<a data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
var $alt = $('<a data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
$('<div id="test1" class="in"/>')
.appendTo('#qunit-fixture')
.on('hidden.bs.collapse', function () {
assert.ok($target.hasClass('collapsed'), 'target has collapsed class')
assert.ok($alt.hasClass('collapsed'), 'alt trigger has collapsed class')
done()
})
$target.click()
})
QUnit.test('should not close a collapse when initialized with "show" if already shown', function (assert) {
var done = assert.async()
assert.expect(0)
var $test = $('<div id="test1" class="in"/>') var $test = $('<div id="test1" class="in"/>')
.appendTo('#qunit-fixture') .appendTo('#qunit-fixture')
.on('hide.bs.collapse', function () { .on('hide.bs.collapse', function () {
ok(false) assert.ok(false)
}) })
$test.bootstrapCollapse('show') $test.bootstrapCollapse('show')
...@@ -118,15 +152,15 @@ $(function () { ...@@ -118,15 +152,15 @@ $(function () {
setTimeout(done, 0) setTimeout(done, 0)
}) })
test('should open a collapse when initialized with "show" if not already shown', function (assert) { QUnit.test('should open a collapse when initialized with "show" if not already shown', function (assert) {
var done = assert.async() var done = assert.async()
expect(1) assert.expect(1)
var $test = $('<div id="test1" />') var $test = $('<div id="test1" />')
.appendTo('#qunit-fixture') .appendTo('#qunit-fixture')
.on('show.bs.collapse', function () { .on('show.bs.collapse', function () {
ok(true) assert.ok(true)
}) })
$test.bootstrapCollapse('show') $test.bootstrapCollapse('show')
...@@ -134,7 +168,7 @@ $(function () { ...@@ -134,7 +168,7 @@ $(function () {
setTimeout(done, 0) setTimeout(done, 0)
}) })
test('should remove "collapsed" class from active accordion target', function (assert) { QUnit.test('should remove "collapsed" class from active accordion target', function (assert) {
var done = assert.async() var done = assert.async()
var accordionHTML = '<div class="panel-group" id="accordion">' var accordionHTML = '<div class="panel-group" id="accordion">'
...@@ -157,9 +191,9 @@ $(function () { ...@@ -157,9 +191,9 @@ $(function () {
$('<div id="body3"/>') $('<div id="body3"/>')
.appendTo($groups.eq(2)) .appendTo($groups.eq(2))
.on('shown.bs.collapse', function () { .on('shown.bs.collapse', function () {
ok($target1.hasClass('collapsed'), 'inactive target 1 does have class "collapsed"') assert.ok($target1.hasClass('collapsed'), 'inactive target 1 does have class "collapsed"')
ok($target2.hasClass('collapsed'), 'inactive target 2 does have class "collapsed"') assert.ok($target2.hasClass('collapsed'), 'inactive target 2 does have class "collapsed"')
ok(!$target3.hasClass('collapsed'), 'active target 3 does not have class "collapsed"') assert.ok(!$target3.hasClass('collapsed'), 'active target 3 does not have class "collapsed"')
done() done()
}) })
...@@ -167,7 +201,7 @@ $(function () { ...@@ -167,7 +201,7 @@ $(function () {
$target3.click() $target3.click()
}) })
test('should allow dots in data-parent', function (assert) { QUnit.test('should allow dots in data-parent', function (assert) {
var done = assert.async() var done = assert.async()
var accordionHTML = '<div class="panel-group accordion">' var accordionHTML = '<div class="panel-group accordion">'
...@@ -190,9 +224,9 @@ $(function () { ...@@ -190,9 +224,9 @@ $(function () {
$('<div id="body3"/>') $('<div id="body3"/>')
.appendTo($groups.eq(2)) .appendTo($groups.eq(2))
.on('shown.bs.collapse', function () { .on('shown.bs.collapse', function () {
ok($target1.hasClass('collapsed'), 'inactive target 1 does have class "collapsed"') assert.ok($target1.hasClass('collapsed'), 'inactive target 1 does have class "collapsed"')
ok($target2.hasClass('collapsed'), 'inactive target 2 does have class "collapsed"') assert.ok($target2.hasClass('collapsed'), 'inactive target 2 does have class "collapsed"')
ok(!$target3.hasClass('collapsed'), 'active target 3 does not have class "collapsed"') assert.ok(!$target3.hasClass('collapsed'), 'active target 3 does not have class "collapsed"')
done() done()
}) })
...@@ -200,37 +234,71 @@ $(function () { ...@@ -200,37 +234,71 @@ $(function () {
$target3.click() $target3.click()
}) })
test('should set aria-expanded="true" on target when collapse is shown', function (assert) { QUnit.test('should set aria-expanded="true" on target when collapse is shown', function (assert) {
var done = assert.async()
var $target = $('<a data-toggle="collapse" class="collapsed" href="#test1" aria-expanded="false"/>').appendTo('#qunit-fixture')
$('<div id="test1"/>')
.appendTo('#qunit-fixture')
.on('shown.bs.collapse', function () {
assert.strictEqual($target.attr('aria-expanded'), 'true', 'aria-expanded on target is "true"')
done()
})
$target.click()
})
QUnit.test('should set aria-expanded="false" on target when collapse is hidden', function (assert) {
var done = assert.async()
var $target = $('<a data-toggle="collapse" href="#test1" aria-expanded="true"/>').appendTo('#qunit-fixture')
$('<div id="test1" class="in"/>')
.appendTo('#qunit-fixture')
.on('hidden.bs.collapse', function () {
assert.strictEqual($target.attr('aria-expanded'), 'false', 'aria-expanded on target is "false"')
done()
})
$target.click()
})
QUnit.test('should set aria-expanded="true" on all triggers targeting the collapse when the collapse is shown', function (assert) {
var done = assert.async() var done = assert.async()
var $target = $('<a data-toggle="collapse" class="collapsed" href="#test1" aria-expanded="false"/>').appendTo('#qunit-fixture') var $target = $('<a data-toggle="collapse" class="collapsed" href="#test1" aria-expanded="false"/>').appendTo('#qunit-fixture')
var $alt = $('<a data-toggle="collapse" class="collapsed" href="#test1" aria-expanded="false"/>').appendTo('#qunit-fixture')
$('<div id="test1"/>') $('<div id="test1"/>')
.appendTo('#qunit-fixture') .appendTo('#qunit-fixture')
.on('shown.bs.collapse', function () { .on('shown.bs.collapse', function () {
equal($target.attr('aria-expanded'), 'true', 'aria-expanded on target is "true"') assert.strictEqual($target.attr('aria-expanded'), 'true', 'aria-expanded on target is "true"')
assert.strictEqual($alt.attr('aria-expanded'), 'true', 'aria-expanded on alt is "true"')
done() done()
}) })
$target.click() $target.click()
}) })
test('should set aria-expanded="false" on target when collapse is hidden', function (assert) { QUnit.test('should set aria-expanded="false" on all triggers targeting the collapse when the collapse is hidden', function (assert) {
var done = assert.async() var done = assert.async()
var $target = $('<a data-toggle="collapse" href="#test1" aria-expanded="true"/>').appendTo('#qunit-fixture') var $target = $('<a data-toggle="collapse" href="#test1" aria-expanded="true"/>').appendTo('#qunit-fixture')
var $alt = $('<a data-toggle="collapse" href="#test1" aria-expanded="true"/>').appendTo('#qunit-fixture')
$('<div id="test1" class="in"/>') $('<div id="test1" class="in"/>')
.appendTo('#qunit-fixture') .appendTo('#qunit-fixture')
.on('hidden.bs.collapse', function () { .on('hidden.bs.collapse', function () {
equal($target.attr('aria-expanded'), 'false', 'aria-expanded on target is "false"') assert.strictEqual($target.attr('aria-expanded'), 'false', 'aria-expanded on target is "false"')
assert.strictEqual($alt.attr('aria-expanded'), 'false', 'aria-expanded on alt is "false"')
done() done()
}) })
$target.click() $target.click()
}) })
test('should change aria-expanded from active accordion target to "false" and set the newly active one to "true"', function (assert) { QUnit.test('should change aria-expanded from active accordion target to "false" and set the newly active one to "true"', function (assert) {
var done = assert.async() var done = assert.async()
var accordionHTML = '<div class="panel-group" id="accordion">' var accordionHTML = '<div class="panel-group" id="accordion">'
...@@ -253,9 +321,9 @@ $(function () { ...@@ -253,9 +321,9 @@ $(function () {
$('<div id="body3" aria-expanded="false"/>') $('<div id="body3" aria-expanded="false"/>')
.appendTo($groups.eq(2)) .appendTo($groups.eq(2))
.on('shown.bs.collapse', function () { .on('shown.bs.collapse', function () {
equal($target1.attr('aria-expanded'), 'false', 'inactive target 1 has aria-expanded="false"') assert.strictEqual($target1.attr('aria-expanded'), 'false', 'inactive target 1 has aria-expanded="false"')
equal($target2.attr('aria-expanded'), 'false', 'inactive target 2 has aria-expanded="false"') assert.strictEqual($target2.attr('aria-expanded'), 'false', 'inactive target 2 has aria-expanded="false"')
equal($target3.attr('aria-expanded'), 'true', 'active target 3 has aria-expanded="false"') assert.strictEqual($target3.attr('aria-expanded'), 'true', 'active target 3 has aria-expanded="false"')
done() done()
}) })
...@@ -263,7 +331,7 @@ $(function () { ...@@ -263,7 +331,7 @@ $(function () {
$target3.click() $target3.click()
}) })
test('should not fire show event if show is prevented because other element is still transitioning', function (assert) { QUnit.test('should not fire show event if show is prevented because other element is still transitioning', function (assert) {
var done = assert.async() var done = assert.async()
var accordionHTML = '<div id="accordion">' var accordionHTML = '<div id="accordion">'
...@@ -293,12 +361,12 @@ $(function () { ...@@ -293,12 +361,12 @@ $(function () {
$target1.click() $target1.click()
setTimeout(function () { setTimeout(function () {
ok(!showFired, 'show event didn\'t fire') assert.ok(!showFired, 'show event did not fire')
done() done()
}, 1) }, 1)
}) })
test('should add "collapsed" class to target when collapse is hidden via manual invocation', function (assert) { QUnit.test('should add "collapsed" class to target when collapse is hidden via manual invocation', function (assert) {
var done = assert.async() var done = assert.async()
var $target = $('<a data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture') var $target = $('<a data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
...@@ -306,13 +374,13 @@ $(function () { ...@@ -306,13 +374,13 @@ $(function () {
$('<div id="test1" class="in"/>') $('<div id="test1" class="in"/>')
.appendTo('#qunit-fixture') .appendTo('#qunit-fixture')
.on('hidden.bs.collapse', function () { .on('hidden.bs.collapse', function () {
ok($target.hasClass('collapsed')) assert.ok($target.hasClass('collapsed'))
done() done()
}) })
.bootstrapCollapse('hide') .bootstrapCollapse('hide')
}) })
test('should remove "collapsed" class from target when collapse is shown via manual invocation', function (assert) { QUnit.test('should remove "collapsed" class from target when collapse is shown via manual invocation', function (assert) {
var done = assert.async() var done = assert.async()
var $target = $('<a data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture') var $target = $('<a data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
...@@ -320,7 +388,7 @@ $(function () { ...@@ -320,7 +388,7 @@ $(function () {
$('<div id="test1"/>') $('<div id="test1"/>')
.appendTo('#qunit-fixture') .appendTo('#qunit-fixture')
.on('shown.bs.collapse', function () { .on('shown.bs.collapse', function () {
ok(!$target.hasClass('collapsed')) assert.ok(!$target.hasClass('collapsed'))
done() done()
}) })
.bootstrapCollapse('show') .bootstrapCollapse('show')
......
$(function () { $(function () {
'use strict'; 'use strict';
module('dropdowns plugin') QUnit.module('dropdowns plugin')
test('should be defined on jquery object', function () { QUnit.test('should be defined on jquery object', function (assert) {
ok($(document.body).dropdown, 'dropdown method is defined') assert.ok($(document.body).dropdown, 'dropdown method is defined')
}) })
module('dropdowns', { QUnit.module('dropdowns', {
setup: function () { beforeEach: function () {
// Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode
$.fn.bootstrapDropdown = $.fn.dropdown.noConflict() $.fn.bootstrapDropdown = $.fn.dropdown.noConflict()
}, },
teardown: function () { afterEach: function () {
$.fn.dropdown = $.fn.bootstrapDropdown $.fn.dropdown = $.fn.bootstrapDropdown
delete $.fn.bootstrapDropdown delete $.fn.bootstrapDropdown
} }
}) })
test('should provide no conflict', function () { QUnit.test('should provide no conflict', function (assert) {
strictEqual($.fn.dropdown, undefined, 'dropdown was set back to undefined (org value)') assert.strictEqual($.fn.dropdown, undefined, 'dropdown was set back to undefined (org value)')
}) })
test('should return jquery collection containing the element', function () { QUnit.test('should return jquery collection containing the element', function (assert) {
var $el = $('<div/>') var $el = $('<div/>')
var $dropdown = $el.bootstrapDropdown() var $dropdown = $el.bootstrapDropdown()
ok($dropdown instanceof $, 'returns jquery collection') assert.ok($dropdown instanceof $, 'returns jquery collection')
strictEqual($dropdown[0], $el[0], 'collection contains element') assert.strictEqual($dropdown[0], $el[0], 'collection contains element')
}) })
test('should not open dropdown if target is disabled via attribute', function () { QUnit.test('should not open dropdown if target is disabled via attribute', function (assert) {
var dropdownHTML = '<ul class="tabs">' var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">' + '<li class="dropdown">'
+ '<button disabled href="#" class="btn dropdown-toggle" data-toggle="dropdown">Dropdown</button>' + '<button disabled href="#" class="btn dropdown-toggle" data-toggle="dropdown">Dropdown</button>'
...@@ -43,10 +43,59 @@ $(function () { ...@@ -43,10 +43,59 @@ $(function () {
+ '</ul>' + '</ul>'
var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click() var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click()
ok(!$dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click') assert.ok(!$dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click')
}) })
test('should not open dropdown if target is disabled via class', function () { QUnit.test('should set aria-expanded="true" on target when dropdown menu is shown', function (assert) {
var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">Dropdown</a>'
+ '<ul class="dropdown-menu">'
+ '<li><a href="#">Secondary link</a></li>'
+ '<li><a href="#">Something else here</a></li>'
+ '<li class="divider"/>'
+ '<li><a href="#">Another link</a></li>'
+ '</ul>'
+ '</li>'
+ '</ul>'
var $dropdown = $(dropdownHTML)
.find('[data-toggle="dropdown"]')
.bootstrapDropdown()
.click()
assert.strictEqual($dropdown.attr('aria-expanded'), 'true', 'aria-expanded is set to string "true" on click')
})
QUnit.test('should set aria-expanded="false" on target when dropdown menu is hidden', function (assert) {
var done = assert.async()
var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">'
+ '<a href="#" class="dropdown-toggle" aria-expanded="false" data-toggle="dropdown">Dropdown</a>'
+ '<ul class="dropdown-menu">'
+ '<li><a href="#">Secondary link</a></li>'
+ '<li><a href="#">Something else here</a></li>'
+ '<li class="divider"/>'
+ '<li><a href="#">Another link</a></li>'
+ '</ul>'
+ '</li>'
+ '</ul>'
var $dropdown = $(dropdownHTML)
.appendTo('#qunit-fixture')
.find('[data-toggle="dropdown"]')
.bootstrapDropdown()
$dropdown
.parent('.dropdown')
.on('hidden.bs.dropdown', function () {
assert.strictEqual($dropdown.attr('aria-expanded'), 'false', 'aria-expanded is set to string "false" on hide')
done()
})
$dropdown.click()
$(document.body).click()
})
QUnit.test('should not open dropdown if target is disabled via class', function (assert) {
var dropdownHTML = '<ul class="tabs">' var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">' + '<li class="dropdown">'
+ '<button href="#" class="btn dropdown-toggle disabled" data-toggle="dropdown">Dropdown</button>' + '<button href="#" class="btn dropdown-toggle disabled" data-toggle="dropdown">Dropdown</button>'
...@@ -60,10 +109,10 @@ $(function () { ...@@ -60,10 +109,10 @@ $(function () {
+ '</ul>' + '</ul>'
var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click() var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click()
ok(!$dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click') assert.ok(!$dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click')
}) })
test('should add class open to menu if clicked', function () { QUnit.test('should add class open to menu if clicked', function (assert) {
var dropdownHTML = '<ul class="tabs">' var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">' + '<li class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' + '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
...@@ -77,10 +126,10 @@ $(function () { ...@@ -77,10 +126,10 @@ $(function () {
+ '</ul>' + '</ul>'
var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click() var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click()
ok($dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click') assert.ok($dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click')
}) })
test('should test if element has a # before assuming it\'s a selector', function () { QUnit.test('should test if element has a # before assuming it\'s a selector', function (assert) {
var dropdownHTML = '<ul class="tabs">' var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">' + '<li class="dropdown">'
+ '<a href="/foo/" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' + '<a href="/foo/" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
...@@ -94,11 +143,11 @@ $(function () { ...@@ -94,11 +143,11 @@ $(function () {
+ '</ul>' + '</ul>'
var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click() var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click()
ok($dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click') assert.ok($dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click')
}) })
test('should remove "open" class if body is clicked', function () { QUnit.test('should remove "open" class if body is clicked', function (assert) {
var dropdownHTML = '<ul class="tabs">' var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">' + '<li class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' + '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
...@@ -116,12 +165,12 @@ $(function () { ...@@ -116,12 +165,12 @@ $(function () {
.bootstrapDropdown() .bootstrapDropdown()
.click() .click()
ok($dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click') assert.ok($dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click')
$(document.body).click() $(document.body).click()
ok(!$dropdown.parent('.dropdown').hasClass('open'), '"open" class removed') assert.ok(!$dropdown.parent('.dropdown').hasClass('open'), '"open" class removed')
}) })
test('should remove "open" class if body is clicked, with multiple dropdowns', function () { QUnit.test('should remove "open" class if body is clicked, with multiple dropdowns', function (assert) {
var dropdownHTML = '<ul class="nav">' var dropdownHTML = '<ul class="nav">'
+ '<li><a href="#menu1">Menu 1</a></li>' + '<li><a href="#menu1">Menu 1</a></li>'
+ '<li class="dropdown" id="testmenu">' + '<li class="dropdown" id="testmenu">'
...@@ -142,22 +191,22 @@ $(function () { ...@@ -142,22 +191,22 @@ $(function () {
var $first = $dropdowns.first() var $first = $dropdowns.first()
var $last = $dropdowns.last() var $last = $dropdowns.last()
strictEqual($dropdowns.length, 2, 'two dropdowns') assert.strictEqual($dropdowns.length, 2, 'two dropdowns')
$first.click() $first.click()
strictEqual($first.parents('.open').length, 1, '"open" class added on click') assert.strictEqual($first.parents('.open').length, 1, '"open" class added on click')
strictEqual($('#qunit-fixture .open').length, 1, 'only one dropdown is open') assert.strictEqual($('#qunit-fixture .open').length, 1, 'only one dropdown is open')
$(document.body).click() $(document.body).click()
strictEqual($('#qunit-fixture .open').length, 0, '"open" class removed') assert.strictEqual($('#qunit-fixture .open').length, 0, '"open" class removed')
$last.click() $last.click()
strictEqual($last.parent('.open').length, 1, '"open" class added on click') assert.strictEqual($last.parent('.open').length, 1, '"open" class added on click')
strictEqual($('#qunit-fixture .open').length, 1, 'only one dropdown is open') assert.strictEqual($('#qunit-fixture .open').length, 1, 'only one dropdown is open')
$(document.body).click() $(document.body).click()
strictEqual($('#qunit-fixture .open').length, 0, '"open" class removed') assert.strictEqual($('#qunit-fixture .open').length, 0, '"open" class removed')
}) })
test('should fire show and hide event', function (assert) { QUnit.test('should fire show and hide event', function (assert) {
var dropdownHTML = '<ul class="tabs">' var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">' + '<li class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' + '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
...@@ -179,10 +228,10 @@ $(function () { ...@@ -179,10 +228,10 @@ $(function () {
$dropdown $dropdown
.parent('.dropdown') .parent('.dropdown')
.on('show.bs.dropdown', function () { .on('show.bs.dropdown', function () {
ok(true, 'show was fired') assert.ok(true, 'show was fired')
}) })
.on('hide.bs.dropdown', function () { .on('hide.bs.dropdown', function () {
ok(true, 'hide was fired') assert.ok(true, 'hide was fired')
done() done()
}) })
...@@ -191,7 +240,7 @@ $(function () { ...@@ -191,7 +240,7 @@ $(function () {
}) })
test('should fire shown and hidden event', function (assert) { QUnit.test('should fire shown and hidden event', function (assert) {
var dropdownHTML = '<ul class="tabs">' var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">' + '<li class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' + '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
...@@ -213,10 +262,10 @@ $(function () { ...@@ -213,10 +262,10 @@ $(function () {
$dropdown $dropdown
.parent('.dropdown') .parent('.dropdown')
.on('shown.bs.dropdown', function () { .on('shown.bs.dropdown', function () {
ok(true, 'shown was fired') assert.ok(true, 'shown was fired')
}) })
.on('hidden.bs.dropdown', function () { .on('hidden.bs.dropdown', function () {
ok(true, 'hidden was fired') assert.ok(true, 'hidden was fired')
done() done()
}) })
...@@ -224,7 +273,7 @@ $(function () { ...@@ -224,7 +273,7 @@ $(function () {
$(document.body).click() $(document.body).click()
}) })
test('should ignore keyboard events within <input>s and <textarea>s', function (assert) { QUnit.test('should ignore keyboard events within <input>s and <textarea>s', function (assert) {
var done = assert.async() var done = assert.async()
var dropdownHTML = '<ul class="tabs">' var dropdownHTML = '<ul class="tabs">'
...@@ -251,13 +300,13 @@ $(function () { ...@@ -251,13 +300,13 @@ $(function () {
$dropdown $dropdown
.parent('.dropdown') .parent('.dropdown')
.on('shown.bs.dropdown', function () { .on('shown.bs.dropdown', function () {
ok(true, 'shown was fired') assert.ok(true, 'shown was fired')
$input.focus().trigger($.Event('keydown', { which: 38 })) $input.focus().trigger($.Event('keydown', { which: 38 }))
ok($(document.activeElement).is($input), 'input still focused') assert.ok($(document.activeElement).is($input), 'input still focused')
$textarea.focus().trigger($.Event('keydown', { which: 38 })) $textarea.focus().trigger($.Event('keydown', { which: 38 }))
ok($(document.activeElement).is($textarea), 'textarea still focused') assert.ok($(document.activeElement).is($textarea), 'textarea still focused')
done() done()
}) })
...@@ -265,4 +314,25 @@ $(function () { ...@@ -265,4 +314,25 @@ $(function () {
$dropdown.click() $dropdown.click()
}) })
QUnit.test('should skip disabled element when using keyboard navigation', function (assert) {
var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
+ '<ul class="dropdown-menu" role="menu">'
+ '<li class="disabled"><a href="#">Disabled link</a></li>'
+ '<li><a href="#">Another link</a></li>'
+ '</ul>'
+ '</li>'
+ '</ul>'
var $dropdown = $(dropdownHTML)
.appendTo('#qunit-fixture')
.find('[data-toggle="dropdown"]')
.bootstrapDropdown()
.click()
$dropdown.trigger($.Event('keydown', { which: 40 }))
$dropdown.trigger($.Event('keydown', { which: 40 }))
assert.ok(!$(document.activeElement).parent().is('.disabled'), '.disabled is not focused')
})
}) })
...@@ -31,8 +31,8 @@ ...@@ -31,8 +31,8 @@
if (!obj.result) { if (!obj.result) {
// Dumping large objects can be very slow, and the dump isn't used for // Dumping large objects can be very slow, and the dump isn't used for
// passing tests, so only dump if the test failed. // passing tests, so only dump if the test failed.
actual = QUnit.jsDump.parse(obj.actual) actual = QUnit.dump.parse(obj.actual)
expected = QUnit.jsDump.parse(obj.expected) expected = QUnit.dump.parse(obj.expected)
} }
// Send it. // Send it.
sendMessage('qunit.log', obj.result, actual, expected, obj.message, obj.source) sendMessage('qunit.log', obj.result, actual, expected, obj.message, obj.source)
......
$(function () { $(function () {
'use strict'; 'use strict';
module('popover plugin') QUnit.module('popover plugin')
test('should be defined on jquery object', function () { QUnit.test('should be defined on jquery object', function (assert) {
ok($(document.body).popover, 'popover method is defined') assert.ok($(document.body).popover, 'popover method is defined')
}) })
module('popover', { QUnit.module('popover', {
setup: function () { beforeEach: function () {
// Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode
$.fn.bootstrapPopover = $.fn.popover.noConflict() $.fn.bootstrapPopover = $.fn.popover.noConflict()
}, },
teardown: function () { afterEach: function () {
$.fn.popover = $.fn.bootstrapPopover $.fn.popover = $.fn.bootstrapPopover
delete $.fn.bootstrapPopover delete $.fn.bootstrapPopover
} }
}) })
test('should provide no conflict', function () { QUnit.test('should provide no conflict', function (assert) {
strictEqual($.fn.popover, undefined, 'popover was set back to undefined (org value)') assert.strictEqual($.fn.popover, undefined, 'popover was set back to undefined (org value)')
}) })
test('should return jquery collection containing the element', function () { QUnit.test('should return jquery collection containing the element', function (assert) {
var $el = $('<div/>') var $el = $('<div/>')
var $popover = $el.bootstrapPopover() var $popover = $el.bootstrapPopover()
ok($popover instanceof $, 'returns jquery collection') assert.ok($popover instanceof $, 'returns jquery collection')
strictEqual($popover[0], $el[0], 'collection contains element') assert.strictEqual($popover[0], $el[0], 'collection contains element')
}) })
test('should render popover element', function () { QUnit.test('should render popover element', function (assert) {
var $popover = $('<a href="#" title="mdo" data-content="https://twitter.com/mdo">@mdo</a>') var $popover = $('<a href="#" title="mdo" data-content="https://twitter.com/mdo">@mdo</a>')
.appendTo('#qunit-fixture') .appendTo('#qunit-fixture')
.bootstrapPopover('show') .bootstrapPopover('show')
notEqual($('.popover').length, 0, 'popover was inserted') assert.notEqual($('.popover').length, 0, 'popover was inserted')
$popover.bootstrapPopover('hide') $popover.bootstrapPopover('hide')
equal($('.popover').length, 0, 'popover removed') assert.strictEqual($('.popover').length, 0, 'popover removed')
}) })
test('should store popover instance in popover data object', function () { QUnit.test('should store popover instance in popover data object', function (assert) {
var $popover = $('<a href="#" title="mdo" data-content="https://twitter.com/mdo">@mdo</a>').bootstrapPopover() var $popover = $('<a href="#" title="mdo" data-content="https://twitter.com/mdo">@mdo</a>').bootstrapPopover()
ok($popover.data('bs.popover'), 'popover instance exists') assert.ok($popover.data('bs.popover'), 'popover instance exists')
}) })
test('should store popover trigger in popover instance data object', function () { QUnit.test('should store popover trigger in popover instance data object', function (assert) {
var $popover = $('<a href="#" title="ResentedHook">@ResentedHook</a>') var $popover = $('<a href="#" title="ResentedHook">@ResentedHook</a>')
.appendTo('#qunit-fixture') .appendTo('#qunit-fixture')
.bootstrapPopover() .bootstrapPopover()
$popover.bootstrapPopover('show') $popover.bootstrapPopover('show')
ok($('.popover').data('bs.popover'), 'popover trigger stored in instance data') assert.ok($('.popover').data('bs.popover'), 'popover trigger stored in instance data')
}) })
test('should get title and content from options', function () { QUnit.test('should get title and content from options', function (assert) {
var $popover = $('<a href="#">@fat</a>') var $popover = $('<a href="#">@fat</a>')
.appendTo('#qunit-fixture') .appendTo('#qunit-fixture')
.bootstrapPopover({ .bootstrapPopover({
...@@ -69,15 +69,15 @@ $(function () { ...@@ -69,15 +69,15 @@ $(function () {
$popover.bootstrapPopover('show') $popover.bootstrapPopover('show')
notEqual($('.popover').length, 0, 'popover was inserted') assert.notEqual($('.popover').length, 0, 'popover was inserted')
equal($('.popover .popover-title').text(), '@fat', 'title correctly inserted') assert.strictEqual($('.popover .popover-title').text(), '@fat', 'title correctly inserted')
equal($('.popover .popover-content').text(), 'loves writing tests (╯°□°)╯︵ ┻━┻', 'content correctly inserted') assert.strictEqual($('.popover .popover-content').text(), 'loves writing tests (╯°□°)╯︵ ┻━┻', 'content correctly inserted')
$popover.bootstrapPopover('hide') $popover.bootstrapPopover('hide')
equal($('.popover').length, 0, 'popover was removed') assert.strictEqual($('.popover').length, 0, 'popover was removed')
}) })
test('should not duplicate HTML object', function () { QUnit.test('should not duplicate HTML object', function (assert) {
var $div = $('<div/>').html('loves writing tests (╯°□°)╯︵ ┻━┻') var $div = $('<div/>').html('loves writing tests (╯°□°)╯︵ ┻━┻')
var $popover = $('<a href="#">@fat</a>') var $popover = $('<a href="#">@fat</a>')
...@@ -89,36 +89,36 @@ $(function () { ...@@ -89,36 +89,36 @@ $(function () {
}) })
$popover.bootstrapPopover('show') $popover.bootstrapPopover('show')
notEqual($('.popover').length, 0, 'popover was inserted') assert.notEqual($('.popover').length, 0, 'popover was inserted')
equal($('.popover .popover-content').html(), $div, 'content correctly inserted') assert.equal($('.popover .popover-content').html(), $div, 'content correctly inserted')
$popover.bootstrapPopover('hide') $popover.bootstrapPopover('hide')
equal($('.popover').length, 0, 'popover was removed') assert.strictEqual($('.popover').length, 0, 'popover was removed')
$popover.bootstrapPopover('show') $popover.bootstrapPopover('show')
notEqual($('.popover').length, 0, 'popover was inserted') assert.notEqual($('.popover').length, 0, 'popover was inserted')
equal($('.popover .popover-content').html(), $div, 'content correctly inserted') assert.equal($('.popover .popover-content').html(), $div, 'content correctly inserted')
$popover.bootstrapPopover('hide') $popover.bootstrapPopover('hide')
equal($('.popover').length, 0, 'popover was removed') assert.strictEqual($('.popover').length, 0, 'popover was removed')
}) })
test('should get title and content from attributes', function () { QUnit.test('should get title and content from attributes', function (assert) {
var $popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>') var $popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>')
.appendTo('#qunit-fixture') .appendTo('#qunit-fixture')
.bootstrapPopover() .bootstrapPopover()
.bootstrapPopover('show') .bootstrapPopover('show')
notEqual($('.popover').length, 0, 'popover was inserted') assert.notEqual($('.popover').length, 0, 'popover was inserted')
equal($('.popover .popover-title').text(), '@mdo', 'title correctly inserted') assert.strictEqual($('.popover .popover-title').text(), '@mdo', 'title correctly inserted')
equal($('.popover .popover-content').text(), 'loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻', 'content correctly inserted') assert.strictEqual($('.popover .popover-content').text(), 'loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻', 'content correctly inserted')
$popover.bootstrapPopover('hide') $popover.bootstrapPopover('hide')
equal($('.popover').length, 0, 'popover was removed') assert.strictEqual($('.popover').length, 0, 'popover was removed')
}) })
test('should get title and content from attributes ignoring options passed via js', function () { QUnit.test('should get title and content from attributes ignoring options passed via js', function (assert) {
var $popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>') var $popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>')
.appendTo('#qunit-fixture') .appendTo('#qunit-fixture')
.bootstrapPopover({ .bootstrapPopover({
...@@ -127,15 +127,15 @@ $(function () { ...@@ -127,15 +127,15 @@ $(function () {
}) })
.bootstrapPopover('show') .bootstrapPopover('show')
notEqual($('.popover').length, 0, 'popover was inserted') assert.notEqual($('.popover').length, 0, 'popover was inserted')
equal($('.popover .popover-title').text(), '@mdo', 'title correctly inserted') assert.strictEqual($('.popover .popover-title').text(), '@mdo', 'title correctly inserted')
equal($('.popover .popover-content').text(), 'loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻', 'content correctly inserted') assert.strictEqual($('.popover .popover-content').text(), 'loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻', 'content correctly inserted')
$popover.bootstrapPopover('hide') $popover.bootstrapPopover('hide')
equal($('.popover').length, 0, 'popover was removed') assert.strictEqual($('.popover').length, 0, 'popover was removed')
}) })
test('should respect custom template', function () { QUnit.test('should respect custom template', function (assert) {
var $popover = $('<a href="#">@fat</a>') var $popover = $('<a href="#">@fat</a>')
.appendTo('#qunit-fixture') .appendTo('#qunit-fixture')
.bootstrapPopover({ .bootstrapPopover({
...@@ -146,34 +146,34 @@ $(function () { ...@@ -146,34 +146,34 @@ $(function () {
$popover.bootstrapPopover('show') $popover.bootstrapPopover('show')
notEqual($('.popover').length, 0, 'popover was inserted') assert.notEqual($('.popover').length, 0, 'popover was inserted')
ok($('.popover').hasClass('foobar'), 'custom class is present') assert.ok($('.popover').hasClass('foobar'), 'custom class is present')
$popover.bootstrapPopover('hide') $popover.bootstrapPopover('hide')
equal($('.popover').length, 0, 'popover was removed') assert.strictEqual($('.popover').length, 0, 'popover was removed')
}) })
test('should destroy popover', function () { QUnit.test('should destroy popover', function (assert) {
var $popover = $('<div/>') var $popover = $('<div/>')
.bootstrapPopover({ .bootstrapPopover({
trigger: 'hover' trigger: 'hover'
}) })
.on('click.foo', $.noop) .on('click.foo', $.noop)
ok($popover.data('bs.popover'), 'popover has data') assert.ok($popover.data('bs.popover'), 'popover has data')
ok($._data($popover[0], 'events').mouseover && $._data($popover[0], 'events').mouseout, 'popover has hover event') assert.ok($._data($popover[0], 'events').mouseover && $._data($popover[0], 'events').mouseout, 'popover has hover event')
equal($._data($popover[0], 'events').click[0].namespace, 'foo', 'popover has extra click.foo event') assert.strictEqual($._data($popover[0], 'events').click[0].namespace, 'foo', 'popover has extra click.foo event')
$popover.bootstrapPopover('show') $popover.bootstrapPopover('show')
$popover.bootstrapPopover('destroy') $popover.bootstrapPopover('destroy')
ok(!$popover.hasClass('in'), 'popover is hidden') assert.ok(!$popover.hasClass('in'), 'popover is hidden')
ok(!$popover.data('popover'), 'popover does not have data') assert.ok(!$popover.data('popover'), 'popover does not have data')
equal($._data($popover[0], 'events').click[0].namespace, 'foo', 'popover still has click.foo') assert.strictEqual($._data($popover[0], 'events').click[0].namespace, 'foo', 'popover still has click.foo')
ok(!$._data($popover[0], 'events').mouseover && !$._data($popover[0], 'events').mouseout, 'popover does not have any events') assert.ok(!$._data($popover[0], 'events').mouseover && !$._data($popover[0], 'events').mouseout, 'popover does not have any events')
}) })
test('should render popover element using delegated selector', function () { QUnit.test('should render popover element using delegated selector', function (assert) {
var $div = $('<div><a href="#" title="mdo" data-content="http://twitter.com/mdo">@mdo</a></div>') var $div = $('<div><a href="#" title="mdo" data-content="http://twitter.com/mdo">@mdo</a></div>')
.appendTo('#qunit-fixture') .appendTo('#qunit-fixture')
.bootstrapPopover({ .bootstrapPopover({
...@@ -182,13 +182,13 @@ $(function () { ...@@ -182,13 +182,13 @@ $(function () {
}) })
$div.find('a').click() $div.find('a').click()
notEqual($('.popover').length, 0, 'popover was inserted') assert.notEqual($('.popover').length, 0, 'popover was inserted')
$div.find('a').click() $div.find('a').click()
equal($('.popover').length, 0, 'popover was removed') assert.strictEqual($('.popover').length, 0, 'popover was removed')
}) })
test('should detach popover content rather than removing it so that event handlers are left intact', function (assert) { QUnit.test('should detach popover content rather than removing it so that event handlers are left intact', function (assert) {
var $content = $('<div class="content-with-handler"><a class="btn btn-warning">Button with event handler</a></div>').appendTo('#qunit-fixture') var $content = $('<div class="content-with-handler"><a class="btn btn-warning">Button with event handler</a></div>').appendTo('#qunit-fixture')
var handlerCalled = false var handlerCalled = false
...@@ -216,7 +216,7 @@ $(function () { ...@@ -216,7 +216,7 @@ $(function () {
.one('shown.bs.popover', function () { .one('shown.bs.popover', function () {
$('.content-with-handler .btn').click() $('.content-with-handler .btn').click()
$div.bootstrapPopover('destroy') $div.bootstrapPopover('destroy')
ok(handlerCalled, 'content\'s event handler still present') assert.ok(handlerCalled, 'content\'s event handler still present')
done() done()
}) })
.bootstrapPopover('show') .bootstrapPopover('show')
...@@ -225,4 +225,11 @@ $(function () { ...@@ -225,4 +225,11 @@ $(function () {
}) })
.bootstrapPopover('show') .bootstrapPopover('show')
}) })
QUnit.test('should throw an error when initializing popover on the document object without specifying a delegation selector', function (assert) {
assert.throws(function () {
$(document).bootstrapPopover({ title: 'What am I on?', content: 'My selector is missing' })
}, new Error('`selector` option must be specified when initializing popover on the window.document object!'))
})
}) })
$(function () { $(function () {
'use strict'; 'use strict';
module('scrollspy plugin') QUnit.module('scrollspy plugin')
test('should be defined on jquery object', function () { QUnit.test('should be defined on jquery object', function (assert) {
ok($(document.body).scrollspy, 'scrollspy method is defined') assert.ok($(document.body).scrollspy, 'scrollspy method is defined')
}) })
module('scrollspy', { QUnit.module('scrollspy', {
setup: function () { beforeEach: function () {
// Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode
$.fn.bootstrapScrollspy = $.fn.scrollspy.noConflict() $.fn.bootstrapScrollspy = $.fn.scrollspy.noConflict()
}, },
teardown: function () { afterEach: function () {
$.fn.scrollspy = $.fn.bootstrapScrollspy $.fn.scrollspy = $.fn.bootstrapScrollspy
delete $.fn.bootstrapScrollspy delete $.fn.bootstrapScrollspy
} }
}) })
test('should provide no conflict', function () { QUnit.test('should provide no conflict', function (assert) {
strictEqual($.fn.scrollspy, undefined, 'scrollspy was set back to undefined (org value)') assert.strictEqual($.fn.scrollspy, undefined, 'scrollspy was set back to undefined (org value)')
}) })
test('should return jquery collection containing the element', function () { QUnit.test('should return jquery collection containing the element', function (assert) {
var $el = $('<div/>') var $el = $('<div/>')
var $scrollspy = $el.bootstrapScrollspy() var $scrollspy = $el.bootstrapScrollspy()
ok($scrollspy instanceof $, 'returns jquery collection') assert.ok($scrollspy instanceof $, 'returns jquery collection')
strictEqual($scrollspy[0], $el[0], 'collection contains element') assert.strictEqual($scrollspy[0], $el[0], 'collection contains element')
}) })
test('should only switch "active" class on current target', function (assert) { QUnit.test('should only switch "active" class on current target', function (assert) {
var done = assert.async() var done = assert.async()
var sectionHTML = '<div id="root" class="active">' var sectionHTML = '<div id="root" class="active">'
...@@ -66,14 +66,14 @@ $(function () { ...@@ -66,14 +66,14 @@ $(function () {
.bootstrapScrollspy({ target: '#ss-target' }) .bootstrapScrollspy({ target: '#ss-target' })
$scrollspy.on('scroll.bs.scrollspy', function () { $scrollspy.on('scroll.bs.scrollspy', function () {
ok($section.hasClass('active'), '"active" class still on root node') assert.ok($section.hasClass('active'), '"active" class still on root node')
done() done()
}) })
$scrollspy.scrollTop(350) $scrollspy.scrollTop(350)
}) })
test('should correctly select middle navigation option when large offset is used', function (assert) { QUnit.test('should correctly select middle navigation option when large offset is used', function (assert) {
var done = assert.async() var done = assert.async()
var sectionHTML = '<div id="header" style="height: 500px;"></div>' var sectionHTML = '<div id="header" style="height: 500px;"></div>'
...@@ -97,16 +97,16 @@ $(function () { ...@@ -97,16 +97,16 @@ $(function () {
$scrollspy.bootstrapScrollspy({ target: '#navigation', offset: $scrollspy.position().top }) $scrollspy.bootstrapScrollspy({ target: '#navigation', offset: $scrollspy.position().top })
$scrollspy.on('scroll.bs.scrollspy', function () { $scrollspy.on('scroll.bs.scrollspy', function () {
ok(!$section.find('#one-link').parent().hasClass('active'), '"active" class removed from first section') assert.ok(!$section.find('#one-link').parent().hasClass('active'), '"active" class removed from first section')
ok($section.find('#two-link').parent().hasClass('active'), '"active" class on middle section') assert.ok($section.find('#two-link').parent().hasClass('active'), '"active" class on middle section')
ok(!$section.find('#three-link').parent().hasClass('active'), '"active" class not on last section') assert.ok(!$section.find('#three-link').parent().hasClass('active'), '"active" class not on last section')
done() done()
}) })
$scrollspy.scrollTop(550) $scrollspy.scrollTop(550)
}) })
test('should add the active class to the correct element', function (assert) { QUnit.test('should add the active class to the correct element', function (assert) {
var navbarHtml = var navbarHtml =
'<nav class="navbar">' '<nav class="navbar">'
+ '<ul class="nav">' + '<ul class="nav">'
...@@ -130,7 +130,7 @@ $(function () { ...@@ -130,7 +130,7 @@ $(function () {
var scrollHeight = Math.ceil($content.scrollTop() + $(target).position().top) var scrollHeight = Math.ceil($content.scrollTop() + $(target).position().top)
var done = assert.async() var done = assert.async()
$content.one('scroll', function () { $content.one('scroll', function () {
ok($(element).hasClass('active'), 'target:' + target + ', element' + element) assert.ok($(element).hasClass('active'), 'target:' + target + ', element' + element)
done() done()
deferred.resolve() deferred.resolve()
}) })
...@@ -142,7 +142,7 @@ $(function () { ...@@ -142,7 +142,7 @@ $(function () {
.then(function () { return testElementIsActiveAfterScroll('#li-2', '#div-2') }) .then(function () { return testElementIsActiveAfterScroll('#li-2', '#div-2') })
}) })
test('should clear selection if above the first section', function (assert) { QUnit.test('should clear selection if above the first section', function (assert) {
var done = assert.async() var done = assert.async()
var sectionHTML = '<div id="header" style="height: 500px;"></div>' var sectionHTML = '<div id="header" style="height: 500px;"></div>'
...@@ -170,12 +170,12 @@ $(function () { ...@@ -170,12 +170,12 @@ $(function () {
offset: $scrollspy.position().top offset: $scrollspy.position().top
}) })
.one('scroll.bs.scrollspy', function () { .one('scroll.bs.scrollspy', function () {
strictEqual($('.active').length, 1, '"active" class on only one element present') assert.strictEqual($('.active').length, 1, '"active" class on only one element present')
strictEqual($('.active').has('#two-link').length, 1, '"active" class on second section') assert.strictEqual($('.active').has('#two-link').length, 1, '"active" class on second section')
$scrollspy $scrollspy
.one('scroll.bs.scrollspy', function () { .one('scroll.bs.scrollspy', function () {
strictEqual($('.active').length, 0, 'selection cleared') assert.strictEqual($('.active').length, 0, 'selection cleared')
done() done()
}) })
.scrollTop(0) .scrollTop(0)
......
$(function () { $(function () {
'use strict'; 'use strict';
module('tabs plugin') QUnit.module('tabs plugin')
test('should be defined on jquery object', function () { QUnit.test('should be defined on jquery object', function (assert) {
ok($(document.body).tab, 'tabs method is defined') assert.ok($(document.body).tab, 'tabs method is defined')
}) })
module('tabs', { QUnit.module('tabs', {
setup: function () { beforeEach: function () {
// Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode
$.fn.bootstrapTab = $.fn.tab.noConflict() $.fn.bootstrapTab = $.fn.tab.noConflict()
}, },
teardown: function () { afterEach: function () {
$.fn.tab = $.fn.bootstrapTab $.fn.tab = $.fn.bootstrapTab
delete $.fn.bootstrapTab delete $.fn.bootstrapTab
} }
}) })
test('should provide no conflict', function () { QUnit.test('should provide no conflict', function (assert) {
strictEqual($.fn.tab, undefined, 'tab was set back to undefined (org value)') assert.strictEqual($.fn.tab, undefined, 'tab was set back to undefined (org value)')
}) })
test('should return jquery collection containing the element', function () { QUnit.test('should return jquery collection containing the element', function (assert) {
var $el = $('<div/>') var $el = $('<div/>')
var $tab = $el.bootstrapTab() var $tab = $el.bootstrapTab()
ok($tab instanceof $, 'returns jquery collection') assert.ok($tab instanceof $, 'returns jquery collection')
strictEqual($tab[0], $el[0], 'collection contains element') assert.strictEqual($tab[0], $el[0], 'collection contains element')
}) })
test('should activate element by tab id', function () { QUnit.test('should activate element by tab id', function (assert) {
var tabsHTML = '<ul class="tabs">' var tabsHTML = '<ul class="tabs">'
+ '<li><a href="#home">Home</a></li>' + '<li><a href="#home">Home</a></li>'
+ '<li><a href="#profile">Profile</a></li>' + '<li><a href="#profile">Profile</a></li>'
...@@ -38,13 +38,13 @@ $(function () { ...@@ -38,13 +38,13 @@ $(function () {
$('<ul><li id="home"/><li id="profile"/></ul>').appendTo('#qunit-fixture') $('<ul><li id="home"/><li id="profile"/></ul>').appendTo('#qunit-fixture')
$(tabsHTML).find('li:last a').bootstrapTab('show') $(tabsHTML).find('li:last a').bootstrapTab('show')
equal($('#qunit-fixture').find('.active').attr('id'), 'profile') assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'profile')
$(tabsHTML).find('li:first a').bootstrapTab('show') $(tabsHTML).find('li:first a').bootstrapTab('show')
equal($('#qunit-fixture').find('.active').attr('id'), 'home') assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'home')
}) })
test('should activate element by tab id', function () { QUnit.test('should activate element by tab id', function (assert) {
var pillsHTML = '<ul class="pills">' var pillsHTML = '<ul class="pills">'
+ '<li><a href="#home">Home</a></li>' + '<li><a href="#home">Home</a></li>'
+ '<li><a href="#profile">Profile</a></li>' + '<li><a href="#profile">Profile</a></li>'
...@@ -53,28 +53,28 @@ $(function () { ...@@ -53,28 +53,28 @@ $(function () {
$('<ul><li id="home"/><li id="profile"/></ul>').appendTo('#qunit-fixture') $('<ul><li id="home"/><li id="profile"/></ul>').appendTo('#qunit-fixture')
$(pillsHTML).find('li:last a').bootstrapTab('show') $(pillsHTML).find('li:last a').bootstrapTab('show')
equal($('#qunit-fixture').find('.active').attr('id'), 'profile') assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'profile')
$(pillsHTML).find('li:first a').bootstrapTab('show') $(pillsHTML).find('li:first a').bootstrapTab('show')
equal($('#qunit-fixture').find('.active').attr('id'), 'home') assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'home')
}) })
test('should not fire shown when show is prevented', function (assert) { QUnit.test('should not fire shown when show is prevented', function (assert) {
var done = assert.async() var done = assert.async()
$('<div class="tab"/>') $('<div class="tab"/>')
.on('show.bs.tab', function (e) { .on('show.bs.tab', function (e) {
e.preventDefault() e.preventDefault()
ok(true, 'show event fired') assert.ok(true, 'show event fired')
done() done()
}) })
.on('shown.bs.tab', function () { .on('shown.bs.tab', function () {
ok(false, 'shown event fired') assert.ok(false, 'shown event fired')
}) })
.bootstrapTab('show') .bootstrapTab('show')
}) })
test('show and shown events should reference correct relatedTarget', function (assert) { QUnit.test('show and shown events should reference correct relatedTarget', function (assert) {
var done = assert.async() var done = assert.async()
var dropHTML = '<ul class="drop">' var dropHTML = '<ul class="drop">'
...@@ -92,16 +92,16 @@ $(function () { ...@@ -92,16 +92,16 @@ $(function () {
.end() .end()
.find('ul > li:last a') .find('ul > li:last a')
.on('show.bs.tab', function (e) { .on('show.bs.tab', function (e) {
equal(e.relatedTarget.hash, '#1-1', 'references correct element as relatedTarget') assert.strictEqual(e.relatedTarget.hash, '#1-1', 'references correct element as relatedTarget')
}) })
.on('shown.bs.tab', function (e) { .on('shown.bs.tab', function (e) {
equal(e.relatedTarget.hash, '#1-1', 'references correct element as relatedTarget') assert.strictEqual(e.relatedTarget.hash, '#1-1', 'references correct element as relatedTarget')
done() done()
}) })
.bootstrapTab('show') .bootstrapTab('show')
}) })
test('should fire hide and hidden events', function (assert) { QUnit.test('should fire hide and hidden events', function (assert) {
var done = assert.async() var done = assert.async()
var tabsHTML = '<ul class="tabs">' var tabsHTML = '<ul class="tabs">'
...@@ -112,7 +112,7 @@ $(function () { ...@@ -112,7 +112,7 @@ $(function () {
$(tabsHTML) $(tabsHTML)
.find('li:first a') .find('li:first a')
.on('hide.bs.tab', function () { .on('hide.bs.tab', function () {
ok(true, 'hide event fired') assert.ok(true, 'hide event fired')
}) })
.bootstrapTab('show') .bootstrapTab('show')
.end() .end()
...@@ -122,7 +122,7 @@ $(function () { ...@@ -122,7 +122,7 @@ $(function () {
$(tabsHTML) $(tabsHTML)
.find('li:first a') .find('li:first a')
.on('hidden.bs.tab', function () { .on('hidden.bs.tab', function () {
ok(true, 'hidden event fired') assert.ok(true, 'hidden event fired')
done() done()
}) })
.bootstrapTab('show') .bootstrapTab('show')
...@@ -131,7 +131,7 @@ $(function () { ...@@ -131,7 +131,7 @@ $(function () {
.bootstrapTab('show') .bootstrapTab('show')
}) })
test('should not fire hidden when hide is prevented', function (assert) { QUnit.test('should not fire hidden when hide is prevented', function (assert) {
var done = assert.async() var done = assert.async()
var tabsHTML = '<ul class="tabs">' var tabsHTML = '<ul class="tabs">'
...@@ -143,11 +143,11 @@ $(function () { ...@@ -143,11 +143,11 @@ $(function () {
.find('li:first a') .find('li:first a')
.on('hide.bs.tab', function (e) { .on('hide.bs.tab', function (e) {
e.preventDefault() e.preventDefault()
ok(true, 'hide event fired') assert.ok(true, 'hide event fired')
done() done()
}) })
.on('hidden.bs.tab', function () { .on('hidden.bs.tab', function () {
ok(false, 'hidden event fired') assert.ok(false, 'hidden event fired')
}) })
.bootstrapTab('show') .bootstrapTab('show')
.end() .end()
...@@ -155,7 +155,7 @@ $(function () { ...@@ -155,7 +155,7 @@ $(function () {
.bootstrapTab('show') .bootstrapTab('show')
}) })
test('hide and hidden events contain correct relatedTarget', function (assert) { QUnit.test('hide and hidden events contain correct relatedTarget', function (assert) {
var done = assert.async() var done = assert.async()
var tabsHTML = '<ul class="tabs">' var tabsHTML = '<ul class="tabs">'
...@@ -166,10 +166,10 @@ $(function () { ...@@ -166,10 +166,10 @@ $(function () {
$(tabsHTML) $(tabsHTML)
.find('li:first a') .find('li:first a')
.on('hide.bs.tab', function (e) { .on('hide.bs.tab', function (e) {
equal(e.relatedTarget.hash, '#profile', 'references correct element as relatedTarget') assert.strictEqual(e.relatedTarget.hash, '#profile', 'references correct element as relatedTarget')
}) })
.on('hidden.bs.tab', function (e) { .on('hidden.bs.tab', function (e) {
equal(e.relatedTarget.hash, '#profile', 'references correct element as relatedTarget') assert.strictEqual(e.relatedTarget.hash, '#profile', 'references correct element as relatedTarget')
done() done()
}) })
.bootstrapTab('show') .bootstrapTab('show')
...@@ -178,7 +178,7 @@ $(function () { ...@@ -178,7 +178,7 @@ $(function () {
.bootstrapTab('show') .bootstrapTab('show')
}) })
test('selected tab should have aria-expanded', function () { QUnit.test('selected tab should have aria-expanded', function (assert) {
var tabsHTML = '<ul class="nav nav-tabs">' var tabsHTML = '<ul class="nav nav-tabs">'
+ '<li class="active"><a href="#home" toggle="tab" aria-expanded="true">Home</a></li>' + '<li class="active"><a href="#home" toggle="tab" aria-expanded="true">Home</a></li>'
+ '<li><a href="#profile" toggle="tab" aria-expanded="false">Profile</a></li>' + '<li><a href="#profile" toggle="tab" aria-expanded="false">Profile</a></li>'
...@@ -186,20 +186,20 @@ $(function () { ...@@ -186,20 +186,20 @@ $(function () {
var $tabs = $(tabsHTML).appendTo('#qunit-fixture') var $tabs = $(tabsHTML).appendTo('#qunit-fixture')
$tabs.find('li:first a').bootstrapTab('show') $tabs.find('li:first a').bootstrapTab('show')
equal($tabs.find('.active a').attr('aria-expanded'), 'true', 'shown tab has aria-expanded = true') assert.strictEqual($tabs.find('.active a').attr('aria-expanded'), 'true', 'shown tab has aria-expanded = true')
equal($tabs.find('li:not(.active) a').attr('aria-expanded'), 'false', 'hidden tab has aria-expanded = false') assert.strictEqual($tabs.find('li:not(.active) a').attr('aria-expanded'), 'false', 'hidden tab has aria-expanded = false')
$tabs.find('li:last a').click() $tabs.find('li:last a').click()
equal($tabs.find('.active a').attr('aria-expanded'), 'true', 'after click, shown tab has aria-expanded = true') assert.strictEqual($tabs.find('.active a').attr('aria-expanded'), 'true', 'after click, shown tab has aria-expanded = true')
equal($tabs.find('li:not(.active) a').attr('aria-expanded'), 'false', 'after click, hidden tab has aria-expanded = false') assert.strictEqual($tabs.find('li:not(.active) a').attr('aria-expanded'), 'false', 'after click, hidden tab has aria-expanded = false')
$tabs.find('li:first a').bootstrapTab('show') $tabs.find('li:first a').bootstrapTab('show')
equal($tabs.find('.active a').attr('aria-expanded'), 'true', 'shown tab has aria-expanded = true') assert.strictEqual($tabs.find('.active a').attr('aria-expanded'), 'true', 'shown tab has aria-expanded = true')
equal($tabs.find('li:not(.active) a').attr('aria-expanded'), 'false', 'hidden tab has aria-expanded = false') assert.strictEqual($tabs.find('li:not(.active) a').attr('aria-expanded'), 'false', 'hidden tab has aria-expanded = false')
$tabs.find('li:first a').click() $tabs.find('li:first a').click()
equal($tabs.find('.active a').attr('aria-expanded'), 'true', 'after second show event, shown tab still has aria-expanded = true') assert.strictEqual($tabs.find('.active a').attr('aria-expanded'), 'true', 'after second show event, shown tab still has aria-expanded = true')
equal($tabs.find('li:not(.active) a').attr('aria-expanded'), 'false', 'after second show event, hidden tab has aria-expanded = false') assert.strictEqual($tabs.find('li:not(.active) a').attr('aria-expanded'), 'false', 'after second show event, hidden tab has aria-expanded = false')
}) })
}) })
/*! /*!
* QUnit 1.17.0 * QUnit 1.17.1
* http://qunitjs.com/ * http://qunitjs.com/
* *
* Copyright jQuery Foundation and other contributors * Copyright jQuery Foundation and other contributors
* Released under the MIT license * Released under the MIT license
* http://jquery.org/license * http://jquery.org/license
* *
* Date: 2015-01-19T11:58Z * Date: 2015-01-20T19:39Z
*/ */
/** Font Family and Sizes */ /** Font Family and Sizes */
......
/*! /*!
* QUnit 1.17.0 * QUnit 1.17.1
* http://qunitjs.com/ * http://qunitjs.com/
* *
* Copyright jQuery Foundation and other contributors * Copyright jQuery Foundation and other contributors
* Released under the MIT license * Released under the MIT license
* http://jquery.org/license * http://jquery.org/license
* *
* Date: 2015-01-19T11:58Z * Date: 2015-01-20T19:39Z
*/ */
(function( window ) { (function( window ) {
...@@ -2522,7 +2522,7 @@ function toolbarModuleFilter() { ...@@ -2522,7 +2522,7 @@ function toolbarModuleFilter() {
moduleFilter = document.createElement( "span" ), moduleFilter = document.createElement( "span" ),
moduleFilterHtml = toolbarModuleFilterHtml(); moduleFilterHtml = toolbarModuleFilterHtml();
if ( !moduleFilterHtml ) { if ( !toolbar || !moduleFilterHtml ) {
return false; return false;
} }
......
// package metadata file for Meteor.js
Package.describe({
name: 'twbs:bootstrap', // http://atmospherejs.com/twbs/bootstrap
summary: 'The most popular front-end framework for developing responsive, mobile first projects on the web.',
version: '3.3.2',
git: 'https://github.com/twbs/bootstrap.git'
});
Package.onUse(function (api) {
api.versionsFrom('METEOR@1.0');
api.use('jquery', 'client');
api.addFiles([
'dist/fonts/glyphicons-halflings-regular.eot',
'dist/fonts/glyphicons-halflings-regular.svg',
'dist/fonts/glyphicons-halflings-regular.ttf',
'dist/fonts/glyphicons-halflings-regular.woff',
'dist/fonts/glyphicons-halflings-regular.woff2',
'dist/css/bootstrap.css',
'dist/js/bootstrap.js',
], 'client');
});
...@@ -144,11 +144,14 @@ output { ...@@ -144,11 +144,14 @@ output {
&:disabled, &:disabled,
&[readonly], &[readonly],
fieldset[disabled] & { fieldset[disabled] & {
cursor: $cursor-disabled;
background-color: $input-bg-disabled; background-color: $input-bg-disabled;
opacity: 1; // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655 opacity: 1; // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655
} }
}
&[disabled],
fieldset[disabled] & {
cursor: $cursor-disabled;
}
// Reset height for `textarea`s // Reset height for `textarea`s
textarea.form-control { textarea.form-control {
...@@ -203,7 +206,7 @@ input[type="search"] { ...@@ -203,7 +206,7 @@ input[type="search"] {
// horizontal forms, use the predefined grid classes. // horizontal forms, use the predefined grid classes.
.form-group { .form-group {
margin-bottom: 15px; margin-bottom: @form-group-margin-bottom;
} }
...@@ -243,6 +246,7 @@ input[type="search"] { ...@@ -243,6 +246,7 @@ input[type="search"] {
// Radios and checkboxes on same line // Radios and checkboxes on same line
.radio-inline, .radio-inline,
.checkbox-inline { .checkbox-inline {
position: relative;
display: inline-block; display: inline-block;
padding-left: 20px; padding-left: 20px;
margin-bottom: 0; margin-bottom: 0;
...@@ -299,6 +303,7 @@ input[type="checkbox"] { ...@@ -299,6 +303,7 @@ input[type="checkbox"] {
padding-bottom: ($padding-base-vertical + 1); padding-bottom: ($padding-base-vertical + 1);
// Remove default margin from `p` // Remove default margin from `p`
margin-bottom: 0; margin-bottom: 0;
min-height: (@line-height-computed + @font-size-base);
&.input-lg, &.input-lg,
&.input-sm { &.input-sm {
...@@ -326,6 +331,7 @@ input[type="checkbox"] { ...@@ -326,6 +331,7 @@ input[type="checkbox"] {
padding: $padding-sm-vertical $padding-sm-horizontal; padding: $padding-sm-vertical $padding-sm-horizontal;
font-size: $font-size-sm; font-size: $font-size-sm;
line-height: $line-height-sm; line-height: $line-height-sm;
min-height: ($line-height-computed + $font-size-sm);
} }
} }
...@@ -339,6 +345,7 @@ input[type="checkbox"] { ...@@ -339,6 +345,7 @@ input[type="checkbox"] {
padding: $padding-lg-vertical $padding-lg-horizontal; padding: $padding-lg-vertical $padding-lg-horizontal;
font-size: $font-size-lg; font-size: $font-size-lg;
line-height: $line-height-lg; line-height: $line-height-lg;
min-height: ($line-height-computed + $font-size-lg);
} }
} }
......
...@@ -22,14 +22,14 @@ ...@@ -22,14 +22,14 @@
height: 100%; height: 100%;
border: 0; border: 0;
} }
}
// Modifier class for 16:9 aspect ratio // Modifier class for 16:9 aspect ratio
&.embed-responsive-16by9 { .embed-responsive-16by9 {
padding-bottom: 56.25%; padding-bottom: 56.25%;
} }
// Modifier class for 4:3 aspect ratio // Modifier class for 4:3 aspect ratio
&.embed-responsive-4by3 { .embed-responsive-4by3 {
padding-bottom: 75%; padding-bottom: 75%;
}
} }
...@@ -162,7 +162,7 @@ abbr[data-original-title] { ...@@ -162,7 +162,7 @@ abbr[data-original-title] {
} }
.initialism { .initialism {
font-size: 90%; font-size: 90%;
text-transform: uppercase; @include text-uppercase;
} }
// Blockquotes // Blockquotes
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
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