Bootstrap update to 3.3.1.

This commit is contained in:
Antoine Nguyen
2014-12-03 11:19:50 +01:00
parent 7ffc317842
commit ff1d9b1920
220 changed files with 4865 additions and 2421 deletions
+2 -2
View File
@@ -54,13 +54,13 @@ you did choose. See :ref:`webservers` for more details.
1.2.0: radicale extension, bootstrap3 and more
==============================================
A new notification service let administrator know about new Modoboa
A new notification service let administrators know about new Modoboa
versions. To activate it, you need to:
#. Add `'modoboa.core.context_processors.top_notifications'`` to the
``TEMPLATE_CONTEXT_PROCESSORS`` variable
#. Define the ``MODOBOA_API_URL``::
#. Define the ``MODOBOA_API_URL`` variable::
MODOBOA_API_URL = 'http://api.modoboa.org/1/'
+5 -5
View File
@@ -5,7 +5,7 @@
"dist/css/bootstrap-select.css",
"dist/js/bootstrap-select.js"
],
"version": "1.6.0",
"version": "1.6.3",
"homepage": "https://github.com/silviomoreto/bootstrap-select",
"authors": [
"silviomoreto"
@@ -27,14 +27,14 @@
"test",
"tests"
],
"_release": "1.6.0",
"_release": "1.6.3",
"_resolution": {
"type": "version",
"tag": "v1.6.0",
"commit": "32032e001d1ac735ed0a8c00c00c50ddaacefbdd"
"tag": "v1.6.3",
"commit": "83d5a1bc0158270fe17f3d745113e89a3a58f9a7"
},
"_source": "git://github.com/silviomoreto/bootstrap-select.git",
"_target": "1.6.0",
"_target": "1.6",
"_originalSource": "bootstrap-select",
"_direct": true
}
+71 -34
View File
@@ -12,11 +12,11 @@ module.exports = function (grunt) {
// Metadata.
pkg: grunt.file.readJSON('package.json'),
banner: '/*!\n' +
' * Bootstrap-select v<%= pkg.version %> (<%= pkg.homepage %>)\n' +
' *\n' +
' * Copyright 2013-<%= grunt.template.today("yyyy") %> bootstrap-select\n' +
' * Licensed under <%= pkg.license.type %> (<%= pkg.license.url %>)\n' +
' */\n',
' * Bootstrap-select v<%= pkg.version %> (<%= pkg.homepage %>)\n' +
' *\n' +
' * Copyright 2013-<%= grunt.template.today(\'yyyy\') %> bootstrap-select\n' +
' * Licensed under <%= pkg.license.type %> (<%= pkg.license.url %>)\n' +
' */\n',
// Task configuration.
@@ -31,7 +31,7 @@ module.exports = function (grunt) {
},
gruntfile: {
options: {
"node": true
'node': true
},
src: 'Gruntfile.js'
},
@@ -130,24 +130,24 @@ module.exports = function (grunt) {
csslint: {
options: {
"adjoining-classes": false,
"box-sizing": false,
"box-model": false,
"compatible-vendor-prefixes": false,
"floats": false,
"font-sizes": false,
"gradients": false,
"important": false,
"known-properties": false,
"outline-none": false,
"qualified-headings": false,
"regex-selectors": false,
"shorthand": false,
"text-indent": false,
"unique-headings": false,
"universal-selector": false,
"unqualified-attributes": false,
"overqualified-elements": false
'adjoining-classes': false,
'box-sizing': false,
'box-model': false,
'compatible-vendor-prefixes': false,
'floats': false,
'font-sizes': false,
'gradients': false,
'important': false,
'known-properties': false,
'outline-none': false,
'qualified-headings': false,
'regex-selectors': false,
'shorthand': false,
'text-indent': false,
'unique-headings': false,
'universal-selector': false,
'unqualified-attributes': false,
'overqualified-elements': false
},
css: {
src: '<%= less.css.dest %>'
@@ -157,12 +157,12 @@ module.exports = function (grunt) {
sed: {
versionNumber: {
path: [
"less",
"js",
"bootstrap-select.jquery.json",
"bower.json",
"composer.json",
"package.json"
'less',
'js',
'bootstrap-select.jquery.json',
'bower.json',
'composer.json',
'package.json'
],
pattern: (function () {
var old = grunt.option('old');
@@ -173,6 +173,43 @@ module.exports = function (grunt) {
}
},
autoprefixer: {
options: {
browsers: [
'Android 2.3',
'Android >= 4',
'Chrome >= 20',
'Firefox >= 24', // Firefox 24 is the latest ESR
'Explorer >= 8',
'iOS >= 6',
'Opera >= 12',
'Safari >= 6'
]
},
css: {
options: {
map: true
},
src: '<%= less.css.dest %>'
}
},
compress: {
main: {
options: {
archive: 'bootstrap-select-<%= pkg.version %>.zip',
mode: 'zip'
},
files: [
{expand: true, cwd: 'dist/', src: ['**'], dest: 'bootstrap-select-<%= pkg.version %>/'},
{
src: ['bootstrap-select.jquery.json', 'bower.json', 'composer.json', 'package.json'],
dest: 'bootstrap-select-<%= pkg.version %>/'
}
]
}
},
watch: {
gruntfile: {
files: '<%= jshint.gruntfile.src %>',
@@ -198,15 +235,15 @@ module.exports = function (grunt) {
grunt.registerTask('change-version-number', 'sed');
// CSS distribution
grunt.registerTask('dist-css', ['less', 'usebanner', 'cssmin']);
grunt.registerTask('dist-css', ['clean:css', 'less', 'autoprefixer', 'usebanner', 'cssmin']);
// JS distribution
grunt.registerTask('dist-js', ['concat', 'uglify']);
grunt.registerTask('dist-js', ['clean:js', 'concat', 'uglify']);
// Full distribution
grunt.registerTask('dist', ['dist-css', 'dist-js']);
grunt.registerTask('dist', ['dist-css', 'dist-js', 'compress']);
// Default task.
grunt.registerTask('default', ['clean', 'dist']);
grunt.registerTask('default', ['clean', 'dist-css', 'dist-js']);
};
+26 -18
View File
@@ -1,17 +1,24 @@
bootstrap-select
================
A custom select / multiselect for Bootstrap using button dropdown, designed to behave like regular Bootstrap selects;
[![Latest release](http://img.shields.io/github/release/silviomoreto/bootstrap-select.svg)](https://github.com/silviomoreto/bootstrap-select/releases/latest)
[![Dependency Status](https://david-dm.org/silviomoreto/bootstrap-select.svg)](https://david-dm.org/silviomoreto/bootstrap-select)
[![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE)
[![devDependency Status](https://david-dm.org/silviomoreto/bootstrap-select/dev-status.svg)](https://david-dm.org/silviomoreto/bootstrap-select#info=devDependencies)
A custom select / multiselect for Bootstrap using button dropdown, designed to behave like regular Bootstrap selects.
## Demo and Documentation
See a Bootstrap 2.3.2 example [here](http://silviomoreto.github.com/bootstrap-select/). <br/>
See a Bootstrap 3.0.3 example [here](http://silviomoreto.github.com/bootstrap-select/3) (work-in-progress).
See a Bootstrap 3.2.0 example [here](http://silviomoreto.github.io/bootstrap-select/3).
See a Bootstrap 2.3.2 example [here](http://silviomoreto.github.io/bootstrap-select) (deprecated).
## Authors
[Silvio Moreto](http://github.com/silviomoreto),
[Ana Carolina](http://github.com/anacarolinats),
[Silvio Moreto](https://github.com/silviomoreto),
[Ana Carolina](https://github.com/anacarolinats),
[caseyjhol](https://github.com/caseyjhol),
[Matt Bryson](https://github.com/mattbryson), and
[t0xicCode](https://github.com/t0xicCode).
@@ -26,6 +33,7 @@ Create your `<select>` with the `.selectpicker` class.
<option>Barbecue</option>
</select>
```
Enable Bootstrap-Select via JavaScript:
```js
$('.selectpicker').selectpicker();
@@ -34,29 +42,29 @@ Or just
```js
$('select').selectpicker();
```
Checkout the [documentation](http://silviomoreto.github.com/bootstrap-select/) for further information.
***Starting with the current dev version, we support bootstrap's data-api, which means that you don't even have to manually instanciate bootstrap-select.***
Checkout the [documentation](http://silviomoreto.github.io/bootstrap-select) for further information.
## CDN
* https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.5.4/bootstrap-select.min.js
* https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.5.4/bootstrap-select.min.css
**N.B.**: The CDN is updated after the release is made public, which means that there is a delay between the publishing of a release and its availability on the CDN. Check [the GitHub page](https://github.com/silviomoreto/bootstrap-select/releases) for the latest release.
* [//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.6.2/css/bootstrap-select.min.css](//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.6.2/css/bootstrap-select.min.css)
* [//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.6.2/js/bootstrap-select.min.js](//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.6.2/js/bootstrap-select.min.js)
* //cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.6.2/js/i18n/defaults-*.min.js (The translation files)
## Bugs and feature requests
Anyone and everyone is welcome to contribute. Please take a moment to
review the [guidelines for contributing](CONTRIBUTING.md). Make sure you're using the latest version of bootstrap-select before submitting an issue.
* [Bug reports](CONTRIBUTING.md#bugs)
* [Feature requests](CONTRIBUTING.md#features)
* [Bug reports](CONTRIBUTING.md#bug-reports)
* [Feature requests](CONTRIBUTING.md#feature-requests)
## Copyright and license
Copyright (C) 2013 bootstrap-select
Copyright (C) 2013-2014 bootstrap-select
Licensed under the MIT license.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Licensed under [the MIT license](LICENSE).
@@ -8,7 +8,7 @@
"select",
"replacement"
],
"version": "1.6.0",
"version": "1.6.3",
"author": {
"name": "Silvio Moreto",
"url": "https://github.com/silviomoreto/"
+1 -1
View File
@@ -5,7 +5,7 @@
"dist/css/bootstrap-select.css",
"dist/js/bootstrap-select.js"
],
"version": "1.6.0",
"version": "1.6.3",
"homepage": "https://github.com/silviomoreto/bootstrap-select",
"authors": [
"silviomoreto"
+2 -2
View File
@@ -3,7 +3,7 @@
"description": "A custom <select> for Bootstrap using button dropdown as replacement",
"keywords": ["form", "bootstrap", "select", "replacement"],
"homepage": "https://github.com/silviomoreto/bootstrap-select",
"version": "1.6.0",
"version": "1.6.3",
"authors": [
{
"name": "Silvio Moreto",
@@ -12,6 +12,6 @@
],
"license": "MIT",
"suggest": {
"components/jquery": "1.8.*"
"components/jquery": ">=1.8"
}
}
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -17,24 +17,37 @@
.error .bootstrap-select .btn {
border: 1px solid #b94a48;
}
.control-group.error .bootstrap-select .dropdown-toggle {
border-color: #b94a48;
}
.bootstrap-select.fit-width {
width: auto !important;
}
.bootstrap-select.btn-group:not(.input-group-btn),
.bootstrap-select.btn-group[class*="span"] {
float: none;
display: inline-block;
margin-bottom: 10px;
margin-left: 0;
.bootstrap-select:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) {
width: 220px;
}
.bootstrap-select .btn:focus {
outline: thin dotted #333333 !important;
outline: 5px auto -webkit-focus-ring-color !important;
outline-offset: -2px;
}
.bootstrap-select.form-control {
margin-bottom: 0;
padding: 0;
border: none;
}
.bootstrap-select.btn-group.pull-right,
.bootstrap-select.btn-group[class*="span"].pull-right,
.row-fluid .bootstrap-select.btn-group[class*="span"].pull-right {
.bootstrap-select.form-control:not([class*="col-"]) {
width: 100%;
}
.bootstrap-select.btn-group:not(.input-group-btn),
.bootstrap-select.btn-group[class*="col-"] {
float: none;
display: inline-block;
margin-left: 0;
}
.bootstrap-select.btn-group.dropdown-menu-right,
.bootstrap-select.btn-group[class*="col-"].dropdown-menu-right,
.row-fluid .bootstrap-select.btn-group[class*="col-"].dropdown-menu-right {
float: right;
}
.form-search .bootstrap-select.btn-group,
@@ -43,25 +56,24 @@
.form-group .bootstrap-select.btn-group {
margin-bottom: 0;
}
.form-group-lg .bootstrap-select.btn-group.form-control,
.form-group-sm .bootstrap-select.btn-group.form-control {
padding: 0;
}
.form-inline .bootstrap-select.btn-group .form-control {
width: 100%;
}
.input-append .bootstrap-select.btn-group {
margin-left: -1px;
}
.input-prepend .bootstrap-select.btn-group {
margin-right: -1px;
}
.bootstrap-select:not([class*="span"]):not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) {
width: 220px;
.bootstrap-select.btn-group > .disabled {
cursor: not-allowed;
}
.bootstrap-select.form-control:not([class*="span"]) {
width: 100%;
}
.bootstrap-select.show-menu-arrow.open > .btn {
z-index: 2051;
}
.bootstrap-select .btn:focus {
outline: thin dotted #333333 !important;
outline: 5px auto -webkit-focus-ring-color !important;
outline-offset: -2px;
.bootstrap-select.btn-group > .disabled:focus {
outline: none !important;
}
.bootstrap-select.btn-group .btn .filter-option {
display: inline-block;
@@ -76,82 +88,94 @@
margin-top: -2px;
vertical-align: middle;
}
.bootstrap-select.btn-group > .disabled,
.bootstrap-select.btn-group .dropdown-menu li.disabled > a {
cursor: not-allowed;
}
.bootstrap-select.btn-group > .disabled:focus {
outline: none !important;
}
.bootstrap-select.btn-group[class*="span"] .btn {
.bootstrap-select.btn-group[class*="col-"] .btn {
width: 100%;
}
.bootstrap-select.btn-group .dropdown-menu {
min-width: 100%;
z-index: 2000;
z-index: 1035;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.bootstrap-select.btn-group .dropdown-menu.inner {
position: static;
border: 0;
padding: 0;
margin: 0;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
.bootstrap-select.btn-group .dropdown-menu dt {
display: block;
padding: 3px 20px;
cursor: default;
}
.bootstrap-select.btn-group .div-contain {
overflow: hidden;
box-shadow: none;
}
.bootstrap-select.btn-group .dropdown-menu li {
position: relative;
}
.bootstrap-select.btn-group .dropdown-menu li > a.opt {
position: relative;
padding-left: 35px;
.bootstrap-select.btn-group .dropdown-menu li:not(.disabled) a:hover small,
.bootstrap-select.btn-group .dropdown-menu li:not(.disabled) a:focus small,
.bootstrap-select.btn-group .dropdown-menu li.active:not(.disabled) a small {
color: #64b1d8;
color: rgba(100, 177, 216, 0.4);
}
.bootstrap-select.btn-group .dropdown-menu li > a {
.bootstrap-select.btn-group .dropdown-menu li.disabled a {
cursor: not-allowed;
}
.bootstrap-select.btn-group .dropdown-menu li a {
cursor: pointer;
}
.bootstrap-select.btn-group .dropdown-menu li > dt small {
font-weight: normal;
.bootstrap-select.btn-group .dropdown-menu li a.opt {
position: relative;
padding-left: 2.25em;
}
.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a i.check-mark {
position: absolute;
display: inline-block;
right: 15px;
margin-top: 2.5px;
}
.bootstrap-select.btn-group .dropdown-menu li a i.check-mark {
.bootstrap-select.btn-group .dropdown-menu li a span.check-mark {
display: none;
}
.bootstrap-select.btn-group .dropdown-menu li a span.text {
display: inline-block;
}
.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text {
margin-right: 34px;
}
.bootstrap-select.btn-group .dropdown-menu li small {
padding-left: 0.5em;
}
.bootstrap-select.btn-group .dropdown-menu li:not(.disabled) > a:hover small,
.bootstrap-select.btn-group .dropdown-menu li:not(.disabled) > a:focus small,
.bootstrap-select.btn-group .dropdown-menu li.active:not(.disabled) > a small {
color: #64b1d8;
color: rgba(100, 177, 216, 0.4);
.bootstrap-select.btn-group .dropdown-menu .notify {
position: absolute;
bottom: 5px;
width: 96%;
margin: 0 2%;
min-height: 26px;
padding: 3px 5px;
background: #f5f5f5;
border: 1px solid #e3e3e3;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
pointer-events: none;
opacity: 0.9;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.bootstrap-select.btn-group .dropdown-menu li > dt small {
font-weight: normal;
.bootstrap-select.btn-group .no-results {
padding: 3px;
background: #f5f5f5;
margin: 0 5px;
}
.bootstrap-select.btn-group.fit-width .btn .filter-option {
position: static;
}
.bootstrap-select.btn-group.fit-width .btn .caret {
position: static;
top: auto;
margin-top: -1px;
}
.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark {
position: absolute;
display: inline-block;
right: 15px;
margin-top: 5px;
}
.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text {
margin-right: 34px;
}
.bootstrap-select.show-menu-arrow.open > .btn {
z-index: 1035 + 1;
}
.bootstrap-select.show-menu-arrow .dropdown-toggle:before {
content: '';
@@ -188,7 +212,7 @@
.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after {
bottom: auto;
top: -3px;
border-top: 6px solid #FFFFFF;
border-top: 6px solid white;
border-bottom: 0;
}
.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before {
@@ -203,57 +227,24 @@
.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:after {
display: block;
}
.bootstrap-select.btn-group .no-results {
padding: 3px;
background: #f5f5f5;
margin: 0 5px;
}
.bootstrap-select.btn-group .dropdown-menu .notify {
position: absolute;
bottom: 5px;
width: 96%;
margin: 0 2%;
min-height: 26px;
padding: 3px 5px;
background: #f5f5f5;
border: 1px solid #e3e3e3;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
pointer-events: none;
opacity: 0.9;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.bootstrap-select.btn-group.fit-width .btn .filter-option {
position: static;
}
.bootstrap-select.btn-group.fit-width .btn .caret {
position: static;
top: auto;
margin-top: -1px;
}
.control-group.error .bootstrap-select .dropdown-toggle {
border-color: #b94a48;
}
.bootstrap-select-searchbox,
.bootstrap-select .bs-actionsbox {
.bs-searchbox,
.bs-actionsbox {
padding: 4px 8px;
}
.bootstrap-select .bs-actionsbox {
.bs-actionsbox {
float: left;
width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.bootstrap-select .bs-actionsbox .btn-group button {
.bs-actionsbox .btn-group button {
width: 50%;
}
.bootstrap-select-searchbox + .bs-actionsbox {
.bs-searchbox + .bs-actionsbox {
padding: 0 8px 4px;
}
.bootstrap-select-searchbox input,
.bootstrap-select-searchbox .form-control {
.bs-searchbox input.form-control {
margin-bottom: 0;
width: 100%;
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -8,8 +8,19 @@
$.fn.selectpicker.defaults = {
noneSelectedText: 'Nothing selected',
noneResultsText: 'No results match',
countSelectedText: '{0} of {1} selected',
maxOptionsText: ['Limit reached ({n} {var} max)', 'Group limit reached ({n} {var} max)', ['items', 'item']],
countSelectedText: function (numSelected, numTotal) {
return (numSelected == 1) ? "{0} item selected" : "{0} items selected";
},
maxOptionsText: function (numAll, numGroup) {
var arr = [];
arr[0] = (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)';
arr[1] = (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)';
return arr;
},
selectAllText: 'Select All',
deselectAllText: 'Deselect All',
multipleSeparator: ', '
};
}(jQuery));
@@ -1,7 +1,7 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
*/
!function(a){a.fn.selectpicker.defaults={noneSelectedText:"Nothing selected",noneResultsText:"No results match",countSelectedText:"{0} of {1} selected",maxOptionsText:["Limit reached ({n} {var} max)","Group limit reached ({n} {var} max)",["items","item"]],multipleSeparator:", "}}(jQuery);
!function(a){a.fn.selectpicker.defaults={noneSelectedText:"Nothing selected",noneResultsText:"No results match",countSelectedText:function(a){return 1==a?"{0} item selected":"{0} items selected"},maxOptionsText:function(a,b){var c=[];return c[0]=1==a?"Limit reached ({n} item max)":"Limit reached ({n} items max)",c[1]=1==b?"Group limit reached ({n} item max)":"Group limit reached ({n} items max)",c},selectAllText:"Select All",deselectAllText:"Deselect All",multipleSeparator:", "}}(jQuery);
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -8,8 +8,17 @@
$.fn.selectpicker.defaults = {
noneSelectedText: 'Aucune s&eacute;lection',
noneResultsText: 'Aucun r&eacute;sultat',
countSelectedText: '{0} sur {1} s&eacute;lection(s)',
maxOptionsText: ['Limite atteinte ({n} {var} max)', 'Limite du groupe atteinte ({n} {var} max)', ['&eacute;l&eacute;ments', '&eacute;l&eacute;ment']],
countSelectedText: function (numSelected, numTotal) {
return (numSelected > 1) ? "{0} &eacute;l&eacute;ments s&eacute;lection&eacute;s" : "{0} &eacute;l&eacute;ment s&eacute;lection&eacute;";
},
maxOptionsText: function (numAll, numGroup) {
var arr = [];
arr[0] = (numAll > 1) ? 'Limite atteinte ({n} &eacute;l&eacute;ments max)' : 'Limite atteinte ({n} &eacute;l&eacute;ment max)';
arr[1] = (numGroup > 1) ? 'Limite du groupe atteinte ({n} &eacute;l&eacute;ments max)' : 'Limite du groupe atteinte ({n} &eacute;l&eacute;ment max)';
return arr;
},
multipleSeparator: ', '
};
}(jQuery));
@@ -1,7 +1,7 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
*/
!function(a){a.fn.selectpicker.defaults={noneSelectedText:"Aucune s&eacute;lection",noneResultsText:"Aucun r&eacute;sultat",countSelectedText:"{0} sur {1} s&eacute;lection(s)",maxOptionsText:["Limite atteinte ({n} {var} max)","Limite du groupe atteinte ({n} {var} max)",["&eacute;l&eacute;ments","&eacute;l&eacute;ment"]],multipleSeparator:", "}}(jQuery);
!function(a){a.fn.selectpicker.defaults={noneSelectedText:"Aucune s&eacute;lection",noneResultsText:"Aucun r&eacute;sultat",countSelectedText:function(a){return a>1?"{0} &eacute;l&eacute;ments s&eacute;lection&eacute;s":"{0} &eacute;l&eacute;ment s&eacute;lection&eacute;"},maxOptionsText:function(a,b){var c=[];return c[0]=a>1?"Limite atteinte ({n} &eacute;l&eacute;ments max)":"Limite atteinte ({n} &eacute;l&eacute;ment max)",c[1]=b>1?"Limite du groupe atteinte ({n} &eacute;l&eacute;ments max)":"Limite du groupe atteinte ({n} &eacute;l&eacute;ment max)",c},multipleSeparator:", "}}(jQuery);
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -10,6 +10,8 @@
noneResultsText: 'Brak wyników wyszukiwania',
countSelectedText: 'Zaznaczono {0} z {1}',
maxOptionsText: ['Osiągnięto limit ({n} {var} max)', 'Limit grupy osiągnięty ({n} {var} max)', ['elementy', 'element']],
selectAll: 'Zaznacz wszystkie',
deselectAll: 'Odznacz wszystkie',
multipleSeparator: ', '
};
}(jQuery));
@@ -1,7 +1,7 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
*/
!function(a){a.fn.selectpicker.defaults={noneSelectedText:"Nic nie zaznaczono",noneResultsText:"Brak wyników wyszukiwania",countSelectedText:"Zaznaczono {0} z {1}",maxOptionsText:["Osiągnięto limit ({n} {var} max)","Limit grupy osiągnięty ({n} {var} max)",["elementy","element"]],multipleSeparator:", "}}(jQuery);
!function(a){a.fn.selectpicker.defaults={noneSelectedText:"Nic nie zaznaczono",noneResultsText:"Brak wyników wyszukiwania",countSelectedText:"Zaznaczono {0} z {1}",maxOptionsText:["Osiągnięto limit ({n} {var} max)","Limit grupy osiągnięty ({n} {var} max)",["elementy","element"]],selectAll:"Zaznacz wszystkie",deselectAll:"Odznacz wszystkie",multipleSeparator:", "}}(jQuery);
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -0,0 +1,15 @@
/*!
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
*/
(function ($) {
$.fn.selectpicker.defaults = {
noneSelectedText: 'Nu a fost selectat nimic',
noneResultsText: 'Nu exista niciun rezultat',
countSelectedText: '{0} din {1} selectat(e)',
maxOptionsText: ['Limita a fost atinsa ({n} {var} max)', 'Limita de grup a fost atinsa ({n} {var} max)', ['iteme', 'item']],
multipleSeparator: ', '
};
}(jQuery));
@@ -0,0 +1,7 @@
/*!
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
*/
!function(a){a.fn.selectpicker.defaults={noneSelectedText:"Nu a fost selectat nimic",noneResultsText:"Nu exista niciun rezultat",countSelectedText:"{0} din {1} selectat(e)",maxOptionsText:["Limita a fost atinsa ({n} {var} max)","Limita de grup a fost atinsa ({n} {var} max)",["iteme","item"]],multipleSeparator:", "}}(jQuery);
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -7,7 +7,7 @@
(function ($) {
$.fn.selectpicker.defaults = {
noneSelectedText: 'Ничего не выбрано',
noneResultsText: 'Не найдено совпадений',
noneResultsText: 'Совпадений не найдено',
countSelectedText: 'Выбрано {0} из {1}',
maxOptionsText: ['Достигнут предел ({n} {var} максимум)', 'Достигнут предел в группе ({n} {var} максимум)', ['items', 'item']],
multipleSeparator: ', '
@@ -1,7 +1,7 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
*/
!function(a){a.fn.selectpicker.defaults={noneSelectedText:"Ничего не выбрано",noneResultsText:"Не найдено совпадений",countSelectedText:"Выбрано {0} из {1}",maxOptionsText:["Достигнут предел ({n} {var} максимум)","Достигнут предел в группе ({n} {var} максимум)",["items","item"]],multipleSeparator:", "}}(jQuery);
!function(a){a.fn.selectpicker.defaults={noneSelectedText:"Ничего не выбрано",noneResultsText:"Совпадений не найдено",countSelectedText:"Выбрано {0} из {1}",maxOptionsText:["Достигнут предел ({n} {var} максимум)","Достигнут предел в группе ({n} {var} максимум)",["items","item"]],multipleSeparator:", "}}(jQuery);
@@ -0,0 +1,15 @@
/*!
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
*/
(function ($) {
$.fn.selectpicker.defaults = {
noneSelectedText: 'Нічого не вибрано',
noneResultsText: 'Збігів не знайдено',
countSelectedText: 'Вибрано {0} із {1}',
maxOptionsText: ['Досягнута межа ({n} {var} максимум)', 'Досягнута межа в групі ({n} {var} максимум)', ['items', 'item']],
multipleSeparator: ', '
};
}(jQuery));
@@ -0,0 +1,7 @@
/*!
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
*/
!function(a){a.fn.selectpicker.defaults={noneSelectedText:"Нічого не вибрано",noneResultsText:"Збігів не знайдено",countSelectedText:"Вибрано {0} із {1}",maxOptionsText:["Досягнута межа ({n} {var} максимум)","Досягнута межа в групі ({n} {var} максимум)",["items","item"]],multipleSeparator:", "}}(jQuery);
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -1,5 +1,5 @@
/*!
* Bootstrap-select v1.6.0 (http://silviomoreto.github.io/bootstrap-select/)
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
@@ -0,0 +1,17 @@
/*!
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
*/
(function ($) {
$.fn.selectpicker.defaults = {
noneSelectedText: '沒有選取任何項目',
noneResultsText: '沒有找到符合的結果',
countSelectedText: '已經選取{0}個項目',
maxOptionsText: ['超過限制 (最多選擇{n}項)', '超過限制(最多選擇{n}組)'],
selectAllText: '選取全部',
deselectAllText: '全部取消',
multipleSeparator: ', '
};
}(jQuery));
@@ -0,0 +1,7 @@
/*!
* Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/)
*
* Copyright 2013-2014 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
*/
!function(a){a.fn.selectpicker.defaults={noneSelectedText:"沒有選取任何項目",noneResultsText:"沒有找到符合的結果",countSelectedText:"已經選取{0}個項目",maxOptionsText:["超過限制 (最多選擇{n}項)","超過限制(最多選擇{n}組)"],selectAllText:"選取全部",deselectAllText:"全部取消",multipleSeparator:", "}}(jQuery);
+409 -224
View File
@@ -1,11 +1,74 @@
(function ($) {
'use strict';
// Case insensitive search
$.expr[':'].icontains = function (obj, index, meta) {
return $(obj).text().toUpperCase().indexOf(meta[3].toUpperCase()) >= 0;
return icontains($(obj).text(), meta[3]);
};
// Case and accent insensitive search
$.expr[':'].aicontains = function (obj, index, meta) {
return icontains($(obj).data('normalizedText') || $(obj).text(), meta[3]);
};
/**
* Actual implementation of the case insensitive search.
* @access private
* @param {String} haystack
* @param {String} needle
* @returns {boolean}
*/
function icontains(haystack, needle) {
return haystack.toUpperCase().indexOf(needle.toUpperCase()) > -1;
}
/**
* Remove all diatrics from the given text.
* @access private
* @param {String} text
* @returns {String}
*/
function normalizeToBase(text) {
var rExps = [
{re: /[\xC0-\xC6]/g, ch: "A"},
{re: /[\xE0-\xE6]/g, ch: "a"},
{re: /[\xC8-\xCB]/g, ch: "E"},
{re: /[\xE8-\xEB]/g, ch: "e"},
{re: /[\xCC-\xCF]/g, ch: "I"},
{re: /[\xEC-\xEF]/g, ch: "i"},
{re: /[\xD2-\xD6]/g, ch: "O"},
{re: /[\xF2-\xF6]/g, ch: "o"},
{re: /[\xD9-\xDC]/g, ch: "U"},
{re: /[\xF9-\xFC]/g, ch: "u"},
{re: /[\xC7-\xE7]/g, ch: "c"},
{re: /[\xD1]/g, ch: "N"},
{re: /[\xF1]/g, ch: "n"}
];
$.each(rExps, function () {
text = text.replace(this.re, this.ch);
});
return text;
}
function htmlEscape(html) {
var escapeMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;',
'`': '&#x60;'
};
var source = '(?:' + Object.keys(escapeMap).join('|') + ')',
testRegexp = new RegExp(source),
replaceRegexp = new RegExp(source, 'g'),
string = html == null ? '' : '' + html;
return testRegexp.test(string) ? string.replace(replaceRegexp, function (match) {
return escapeMap[match];
}) : string;
}
var Selectpicker = function (element, options, e) {
if (e) {
e.stopPropagation();
@@ -19,7 +82,8 @@
this.$lis = null;
this.options = options;
//If we have no title yet, check the attribute 'title' (this is missed by jq as its not a data-attribute
// If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a
// data-attribute)
if (this.options.title === null) {
this.options.title = this.$element.attr('title');
}
@@ -31,26 +95,38 @@
this.setStyle = Selectpicker.prototype.setStyle;
this.selectAll = Selectpicker.prototype.selectAll;
this.deselectAll = Selectpicker.prototype.deselectAll;
this.destroy = Selectpicker.prototype.destroy;
this.remove = Selectpicker.prototype.destroy;
this.destroy = Selectpicker.prototype.remove;
this.remove = Selectpicker.prototype.remove;
this.show = Selectpicker.prototype.show;
this.hide = Selectpicker.prototype.hide;
this.init();
};
Selectpicker.VERSION = '1.6.0';
Selectpicker.VERSION = '1.6.3';
// part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both.
Selectpicker.DEFAULTS = {
noneSelectedText: 'Nothing selected',
noneResultsText: 'No results match',
countSelectedText: function (numSelected, numTotal) {
return (numSelected == 1) ? "{0} item selected" : "{0} items selected";
},
maxOptionsText: function (numAll, numGroup) {
var arr = [];
arr[0] = (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)';
arr[1] = (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)';
return arr;
},
selectAllText: 'Select All',
deselectAllText: 'Deselect All',
multipleSeparator: ', ',
style: 'btn-default',
size: 'auto',
title: null,
selectedTextFormat: 'values',
noneSelectedText: 'Nothing selected',
noneResultsText: 'No results match',
countSelectedText: '{0} of {1} selected',
maxOptionsText: ['Limit reached ({n} {var} max)', 'Group limit reached ({n} {var} max)', ['items', 'item']],
width: false,
container: false,
hideDisabled: false,
@@ -61,11 +137,13 @@
header: false,
liveSearch: false,
actionsBox: false,
multipleSeparator: ', ',
iconBase: 'glyphicon',
tickIcon: 'glyphicon-ok',
maxOptions: false,
mobile: false
mobile: false,
selectOnTab: false,
dropdownAlignRight: false,
searchAccentInsensitive: false
};
Selectpicker.prototype = {
@@ -85,7 +163,10 @@
this.$button = this.$newElement.find('> button');
this.$searchbox = this.$newElement.find('input');
if (id !== undefined) {
if (this.options.dropdownAlignRight)
this.$menu.addClass('dropdown-menu-right');
if (typeof id !== 'undefined') {
this.$button.attr('data-id', id);
$('label[for="' + id + '"]').click(function (e) {
e.preventDefault();
@@ -107,36 +188,39 @@
},
createDropdown: function () {
//If we are multiple, then add the show-tick class by default
var multiple = this.multiple ? ' show-tick' : '';
var inputGroup = this.$element.parent().hasClass('input-group') ? ' input-group-btn' : '';
var autofocus = this.autofocus ? ' autofocus' : '';
// Options
// If we are multiple, then add the show-tick class by default
var multiple = this.multiple ? ' show-tick' : '',
inputGroup = this.$element.parent().hasClass('input-group') ? ' input-group-btn' : '',
autofocus = this.autofocus ? ' autofocus' : '',
btnSize = this.$element.parents().hasClass('form-group-lg') ? ' btn-lg' : (this.$element.parents().hasClass('form-group-sm') ? ' btn-sm' : '');
// Elements
var header = this.options.header ? '<div class="popover-title"><button type="button" class="close" aria-hidden="true">&times;</button>' + this.options.header + '</div>' : '';
var searchbox = this.options.liveSearch ? '<div class="bootstrap-select-searchbox"><input type="text" class="input-block-level form-control" autocomplete="off" /></div>' : '';
var searchbox = this.options.liveSearch ? '<div class="bs-searchbox"><input type="text" class="input-block-level form-control" autocomplete="off" /></div>' : '';
var actionsbox = this.options.actionsBox ? '<div class="bs-actionsbox">' +
'<div class="btn-group btn-block">' +
'<button class="actions-btn bs-select-all btn btn-sm btn-default">' +
'Select All' +
'</button>' +
'<button class="actions-btn bs-deselect-all btn btn-sm btn-default">' +
'Deselect All' +
'</button>' +
'</div>' +
'</div>' : '';
'<div class="btn-group btn-block">' +
'<button class="actions-btn bs-select-all btn btn-sm btn-default">' +
this.options.selectAllText +
'</button>' +
'<button class="actions-btn bs-deselect-all btn btn-sm btn-default">' +
this.options.deselectAllText +
'</button>' +
'</div>' +
'</div>' : '';
var drop =
'<div class="btn-group bootstrap-select' + multiple + inputGroup + '">' +
'<button type="button" class="btn dropdown-toggle selectpicker" data-toggle="dropdown"' + autofocus + '>' +
'<span class="filter-option pull-left"></span>&nbsp;' +
'<span class="caret"></span>' +
'</button>' +
'<div class="dropdown-menu open">' +
header +
searchbox +
actionsbox +
'<ul class="dropdown-menu inner selectpicker" role="menu">' +
'</ul>' +
'</div>' +
'</div>';
'<button type="button" class="btn dropdown-toggle selectpicker' + btnSize + '" data-toggle="dropdown"' + autofocus + '>' +
'<span class="filter-option pull-left"></span>&nbsp;' +
'<span class="caret"></span>' +
'</button>' +
'<div class="dropdown-menu open">' +
header +
searchbox +
actionsbox +
'<ul class="dropdown-menu inner selectpicker" role="menu">' +
'</ul>' +
'</div>' +
'</div>';
return $(drop);
},
@@ -162,94 +246,108 @@
createLi: function () {
var that = this,
_liA = [],
_liHtml = '',
_li = [],
optID = 0;
// Helper functions
/**
* @param content
* @param [index]
* @param [classes]
* @returns {string}
*/
var generateLI = function (content, index, classes) {
return '<li' +
(typeof classes !== 'undefined' ? ' class="' + classes + '"' : '') +
(typeof index !== 'undefined' | null === index ? ' data-original-index="' + index + '"' : '') +
'>' + content + '</li>';
};
/**
* @param text
* @param [classes]
* @param [inline]
* @param [optgroup]
* @returns {string}
*/
var generateA = function (text, classes, inline, optgroup) {
var normText = normalizeToBase(htmlEscape(text));
return '<a tabindex="0"' +
(typeof classes !== 'undefined' ? ' class="' + classes + '"' : '') +
(typeof inline !== 'undefined' ? ' style="' + inline + '"' : '') +
(typeof optgroup !== 'undefined' ? 'data-optgroup="' + optgroup + '"' : '') +
' data-normalized-text="' + normText + '"' +
'>' + text +
'<span class="' + that.options.iconBase + ' ' + that.options.tickIcon + ' check-mark"></span>' +
'</a>';
};
this.$element.find('option').each(function () {
var $this = $(this);
//Get the class and text for the option
var optionClass = $this.attr('class') || '';
var inline = $this.attr('style') || '';
var text = $this.data('content') ? $this.data('content') : $this.html();
var subtext = $this.data('subtext') !== undefined ? '<small class="muted text-muted">' + $this.data('subtext') + '</small>' : '';
var icon = $this.data('icon') !== undefined ? '<i class="' + that.options.iconBase + ' ' + $this.data('icon') + '"></i> ' : '';
if (icon !== '' && ($this.is(':disabled') || $this.parent().is(':disabled'))) {
// Get the class and text for the option
var optionClass = $this.attr('class') || '',
inline = $this.attr('style'),
text = $this.data('content') ? $this.data('content') : $this.html(),
subtext = typeof $this.data('subtext') !== 'undefined' ? '<small class="muted text-muted">' + $this.data('subtext') + '</small>' : '',
icon = typeof $this.data('icon') !== 'undefined' ? '<span class="' + that.options.iconBase + ' ' + $this.data('icon') + '"></span> ' : '',
isDisabled = $this.is(':disabled') || $this.parent().is(':disabled'),
index = $this[0].index;
if (icon !== '' && isDisabled) {
icon = '<span>' + icon + '</span>';
}
if (!$this.data('content')) {
//Prepend any icon and append any subtext to the main text.
// Prepend any icon and append any subtext to the main text.
text = icon + '<span class="text">' + text + subtext + '</span>';
}
if (that.options.hideDisabled && ($this.is(':disabled') || $this.parent().is(':disabled'))) {
_liA.push('<a style="min-height: 0; padding: 0"></a>');
} else if ($this.parent().is('optgroup') && $this.data('divider') !== true) {
if ($this.index() === 0) {
//Get the opt group label
var label = $this.parent().attr('label');
var labelSubtext = $this.parent().data('subtext') !== undefined ? '<small class="muted text-muted">' + $this.parent().data('subtext') + '</small>' : '';
var labelIcon = $this.parent().data('icon') ? '<i class="' + that.options.iconBase + ' ' + $this.parent().data('icon') + '"></i> ' : '';
label = labelIcon + '<span class="text">' + label + labelSubtext + '</span>';
if (that.options.hideDisabled && isDisabled) {
return;
}
if ($this.parent().is('optgroup') && $this.data('divider') !== true) {
if ($this.index() === 0) { // Is it the first option of the optgroup?
optID += 1;
if ($this[0].index !== 0) {
_liA.push(
'<div class="div-contain"><div class="divider"></div></div>' +
'<dt>' + label + '</dt>' +
that.createA(text, 'opt ' + optionClass, inline, optID)
);
} else {
_liA.push(
'<dt>' + label + '</dt>' +
that.createA(text, 'opt ' + optionClass, inline, optID));
// Get the opt group label
var label = $this.parent().attr('label');
var labelSubtext = typeof $this.parent().data('subtext') !== 'undefined' ? '<small class="muted text-muted">' + $this.parent().data('subtext') + '</small>' : '';
var labelIcon = $this.parent().data('icon') ? '<span class="' + that.options.iconBase + ' ' + $this.parent().data('icon') + '"></span> ' : '';
label = labelIcon + '<span class="text">' + label + labelSubtext + '</span>';
if (index !== 0 && _li.length > 0) { // Is it NOT the first option of the select && are there elements in the dropdown?
_li.push(generateLI('', null, 'divider'));
}
} else {
_liA.push(that.createA(text, 'opt ' + optionClass, inline, optID));
_li.push(generateLI(label, null, 'dropdown-header'));
}
_li.push(generateLI(generateA(text, 'opt ' + optionClass, inline, optID), index));
} else if ($this.data('divider') === true) {
_liA.push('<div class="div-contain"><div class="divider"></div></div>');
} else if ($(this).data('hidden') === true) {
_liA.push('<a></a>');
_li.push(generateLI('', index, 'divider'));
} else if ($this.data('hidden') === true) {
_li.push(generateLI(generateA(text, optionClass, inline), index, 'hide is-hidden'));
} else {
_liA.push(that.createA(text, optionClass, inline));
_li.push(generateLI(generateA(text, optionClass, inline), index));
}
});
$.each(_liA, function (i, item) {
var hide = item === '<a></a>' ? 'class="hide is-hidden"' : '';
_liHtml += '<li rel="' + i + '"' + hide + '>' + item + '</li>';
});
//If we are not multiple, and we dont have a selected item, and we dont have a title, select the first element so something is set in the button
//If we are not multiple, we don't have a selected item, and we don't have a title, select the first element so something is set in the button
if (!this.multiple && this.$element.find('option:selected').length === 0 && !this.options.title) {
this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');
}
return $(_liHtml);
return $(_li.join(''));
},
findLis: function () {
if (this.$lis == null) this.$lis = this.$menu.find('li');
return this.$lis;
},
/**
*
* @param text
* @param classes
* @param inline
* @param [optgroup]
* @returns {string}
*/
createA: function (text, classes, inline, optgroup) {
return '<a tabindex="0" class="' + classes + '" style="' + inline + '"' +
(typeof optgroup !== 'undefined' ? 'data-optgroup="' + optgroup + '"' : '') + '>' +
text +
'<i class="' + this.options.iconBase + ' ' + this.options.tickIcon + ' icon-ok check-mark"></i>' +
'</a>';
},
/**
* @param [updateLi]
* @param [updateLi] defaults to true
*/
render: function (updateLi) {
var that = this;
@@ -263,8 +361,8 @@
}
this.tabIndex();
var selectedItems = this.$element.find('option:selected').map(function () {
var notDisabled = this.options.hideDisabled ? ':not([disabled])' : '';
var selectedItems = this.$element.find('option:selected' + notDisabled).map(function () {
var $this = $(this);
var icon = $this.data('icon') && that.options.showIcon ? '<i class="' + that.options.iconBase + ' ' + $this.data('icon') + '"></i> ' : '';
var subtext;
@@ -275,7 +373,7 @@
}
if ($this.data('content') && that.options.showContent) {
return $this.data('content');
} else if ($this.attr('title') !== undefined) {
} else if (typeof $this.attr('title') !== 'undefined') {
return $this.attr('title');
} else {
return icon + $this.html() + subtext;
@@ -289,9 +387,11 @@
//If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..
if (this.multiple && this.options.selectedTextFormat.indexOf('count') > -1) {
var max = this.options.selectedTextFormat.split('>');
var notDisabled = this.options.hideDisabled ? ':not([disabled])' : '';
if ((max.length > 1 && selectedItems.length > max[1]) || (max.length == 1 && selectedItems.length >= 2)) {
title = this.options.countSelectedText.replace('{0}', selectedItems.length).replace('{1}', this.$element.find('option:not([data-divider="true"], [data-hidden="true"])' + notDisabled).length);
notDisabled = this.options.hideDisabled ? ', [disabled]' : '';
var totalCount = this.$element.find('option').not('[data-divider="true"], [data-hidden="true"]' + notDisabled).length,
tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedItems.length, totalCount) : this.options.countSelectedText;
title = tr8nText.replace('{0}', selectedItems.length.toString()).replace('{1}', totalCount.toString());
}
}
@@ -303,10 +403,10 @@
//If we dont have a title, then use the default, or if nothing is set at all, use the not selected text
if (!title) {
title = this.options.title !== undefined ? this.options.title : this.options.noneSelectedText;
title = typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText;
}
this.$button.attr('title', $.trim($("<div/>").html(title).text()).replace(/\s\s+/g, ' '));
this.$button.attr('title', htmlEscape(title));
this.$newElement.find('.filter-option').html(title);
},
@@ -336,9 +436,9 @@
var $selectClone = this.$menu.parent().clone().find('> .dropdown-toggle').prop('autofocus', false).end().appendTo('body'),
$menuClone = $selectClone.addClass('open').find('> .dropdown-menu'),
liHeight = $menuClone.find('li > a').outerHeight(),
liHeight = $menuClone.find('li').not('.divider').not('.dropdown-header').filter(':visible').children('a').outerHeight(),
headerHeight = this.options.header ? $menuClone.find('.popover-title').outerHeight() : 0,
searchHeight = this.options.liveSearch ? $menuClone.find('.bootstrap-select-searchbox').outerHeight() : 0,
searchHeight = this.options.liveSearch ? $menuClone.find('.bs-searchbox').outerHeight() : 0,
actionsHeight = this.options.actionsBox ? $menuClone.find('.bs-actionsbox').outerHeight() : 0;
$selectClone.remove();
@@ -351,6 +451,7 @@
},
setSize: function () {
this.findLis();
var that = this,
menu = this.$menu,
menuInner = menu.find('.inner'),
@@ -359,19 +460,19 @@
headerHeight = this.$newElement.data('headerHeight'),
searchHeight = this.$newElement.data('searchHeight'),
actionsHeight = this.$newElement.data('actionsHeight'),
divHeight = menu.find('li .divider').outerHeight(true),
divHeight = this.$lis.filter('.divider').outerHeight(true),
menuPadding = parseInt(menu.css('padding-top')) +
parseInt(menu.css('padding-bottom')) +
parseInt(menu.css('border-top-width')) +
parseInt(menu.css('border-bottom-width')),
notDisabled = this.options.hideDisabled ? ':not(.disabled)' : '',
notDisabled = this.options.hideDisabled ? ', .disabled' : '',
$window = $(window),
menuExtras = menuPadding + parseInt(menu.css('margin-top')) + parseInt(menu.css('margin-bottom')) + 2,
menuHeight,
selectOffsetTop,
selectOffsetBot,
posVert = function () {
//JQuery defines a scrollTop function, but in pure JS it's a property
// JQuery defines a scrollTop function, but in pure JS it's a property
//noinspection JSValidateTypes
selectOffsetTop = that.$newElement.offset().top - $window.scrollTop();
selectOffsetBot = $window.height() - selectOffsetTop - selectHeight;
@@ -394,24 +495,33 @@
menuHeight = selectOffsetTop - menuExtras;
}
if ((lisVis.length + lisVis.find('dt').length) > 3) {
if ((lisVis.length + lisVis.filter('.dropdown-header').length) > 3) {
minHeight = liHeight * 3 + menuExtras - 2;
} else {
minHeight = 0;
}
menu.css({'max-height': menuHeight + 'px', 'overflow': 'hidden', 'min-height': minHeight + headerHeight + searchHeight + actionsHeight + 'px'});
menuInner.css({'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - menuPadding + 'px', 'overflow-y': 'auto', 'min-height': Math.max(minHeight - menuPadding, 0) + 'px'});
menu.css({
'max-height': menuHeight + 'px',
'overflow': 'hidden',
'min-height': minHeight + headerHeight + searchHeight + actionsHeight + 'px'
});
menuInner.css({
'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - menuPadding + 'px',
'overflow-y': 'auto',
'min-height': Math.max(minHeight - menuPadding, 0) + 'px'
});
};
getSize();
this.$searchbox.off('input.getSize propertychange.getSize').on('input.getSize propertychange.getSize', getSize);
$(window).off('resize.getSize').on('resize.getSize', getSize);
$(window).off('scroll.getSize').on('scroll.getSize', getSize);
} else if (this.options.size && this.options.size != 'auto' && menu.find('li' + notDisabled).length > this.options.size) {
var optIndex = menu.find('li' + notDisabled + ' > *').not('.div-contain').slice(0, this.options.size).last().parent().index();
var divLength = menu.find('li').slice(0, optIndex + 1).find('.div-contain').length;
var optIndex = this.$lis.not('.divider' + notDisabled).find(' > *').slice(0, this.options.size).last().parent().index();
var divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length;
menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding;
if (that.options.dropupAuto) {
//noinspection JSUnusedAssignment
this.$newElement.toggleClass('dropup', (selectOffsetTop > selectOffsetBot) && (menuHeight < menu.height()));
}
menu.css({'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + 'px', 'overflow': 'hidden'});
@@ -460,7 +570,12 @@
$drop.addClass($element.attr('class').replace(/form-control/gi, '')).toggleClass('dropup', $element.hasClass('dropup'));
pos = $element.offset();
actualHeight = $element.hasClass('dropup') ? 0 : $element[0].offsetHeight;
$drop.css({'top': pos.top + actualHeight, 'left': pos.left, 'width': $element[0].offsetWidth, 'position': 'absolute'});
$drop.css({
'top': pos.top + actualHeight,
'left': pos.left,
'width': $element[0].offsetWidth,
'position': 'absolute'
});
};
this.$newElement.on('click', function () {
if (that.isDisabled()) {
@@ -484,40 +599,17 @@
});
},
mobile: function () {
this.$element.addClass('mobile-device').appendTo(this.$newElement);
if (this.options.container) this.$menu.hide();
},
refresh: function () {
this.$lis = null;
this.reloadLi();
this.render();
this.setWidth();
this.setStyle();
this.checkDisabled();
this.liHeight();
},
update: function () {
this.reloadLi();
this.setWidth();
this.setStyle();
this.checkDisabled();
this.liHeight();
},
setSelected: function (index, selected) {
if (this.$lis == null) this.$lis = this.$menu.find('li');
$(this.$lis[index]).toggleClass('selected', selected);
this.findLis();
this.$lis.filter('[data-original-index="' + index + '"]').toggleClass('selected', selected);
},
setDisabled: function (index, disabled) {
if (this.$lis == null) this.$lis = this.$menu.find('li');
this.findLis();
if (disabled) {
$(this.$lis[index]).addClass('disabled').find('a').attr('href', '#').attr('tabindex', -1);
this.$lis.filter('[data-original-index="' + index + '"]').addClass('disabled').find('a').attr('href', '#').attr('tabindex', -1);
} else {
$(this.$lis[index]).removeClass('disabled').find('a').removeAttr('href').attr('tabindex', 0);
this.$lis.filter('[data-original-index="' + index + '"]').removeClass('disabled').find('a').removeAttr('href').attr('tabindex', 0);
}
},
@@ -569,19 +661,20 @@
});
this.$menu.on('click', 'li a', function (e) {
var clickedIndex = $(this).parent().index(),
var $this = $(this),
clickedIndex = $this.parent().data('originalIndex'),
prevValue = that.$element.val(),
prevIndex = that.$element.prop('selectedIndex');
//Dont close on multi choice menu
// Don't close on multi choice menu
if (that.multiple) {
e.stopPropagation();
}
e.preventDefault();
//Dont run if we have been disabled
if (!that.isDisabled() && !$(this).parent().hasClass('disabled')) {
//Don't run if we have been disabled
if (!that.isDisabled() && !$this.parent().hasClass('disabled')) {
var $options = that.$element.find('option'),
$option = $options.eq(clickedIndex),
state = $option.prop('selected'),
@@ -589,26 +682,19 @@
maxOptions = that.options.maxOptions,
maxOptionsGrp = $optgroup.data('maxOptions') || false;
//Deselect all others if not multi select box
if (!that.multiple) {
if (!that.multiple) { // Deselect all others if not multi select box
$options.prop('selected', false);
$option.prop('selected', true);
that.$menu.find('.selected').removeClass('selected');
that.setSelected(clickedIndex, true);
}
//Else toggle the one we have chosen if we are multi select.
else {
} else { // Toggle the one we have chosen if we are multi select.
$option.prop('selected', !state);
that.setSelected(clickedIndex, !state);
$(this).blur();
$this.blur();
if ((maxOptions !== false) || (maxOptionsGrp !== false)) {
var maxReached = maxOptions < $options.filter(':selected').length,
maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length,
maxOptionsArr = that.options.maxOptionsText,
maxTxt = maxOptionsArr[0].replace('{n}', maxOptions),
maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp),
$notify = $('<div class="notify"></div>');
maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length;
if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) {
if (maxOptions && maxOptions == 1) {
@@ -619,13 +705,19 @@
} else if (maxOptionsGrp && maxOptionsGrp == 1) {
$optgroup.find('option:selected').prop('selected', false);
$option.prop('selected', true);
var optgroupID = $(this).data('optgroup');
var optgroupID = $this.data('optgroup');
that.$menu.find('.selected').has('a[data-optgroup="'+optgroupID+'"]').removeClass('selected');
that.$menu.find('.selected').has('a[data-optgroup="' + optgroupID + '"]').removeClass('selected');
that.setSelected(clickedIndex, true);
} else {
var maxOptionsArr = (typeof that.options.maxOptionsText === 'function') ?
that.options.maxOptionsText(maxOptions, maxOptionsGrp) : that.options.maxOptionsText,
maxTxt = maxOptionsArr[0].replace('{n}', maxOptions),
maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp),
$notify = $('<div class="notify"></div>');
// If {var} is set in array, replace it
/** @deprecated */
if (maxOptionsArr[2]) {
maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]);
maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]);
@@ -670,7 +762,7 @@
}
});
this.$menu.on('click', 'li.disabled a, li dt, li .div-contain, .popover-title, .popover-title :not(.close)', function (e) {
this.$menu.on('click', 'li.disabled a, .popover-title, .popover-title :not(.close)', function (e) {
if (e.target == this) {
e.preventDefault();
e.stopPropagation();
@@ -682,6 +774,16 @@
}
});
this.$menu.on('click', 'li.divider, li.dropdown-header', function (e) {
e.preventDefault();
e.stopPropagation();
if (!that.options.liveSearch) {
that.$button.focus();
} else {
that.$searchbox.focus();
}
});
this.$menu.on('click', '.popover-title .close', function () {
that.$button.focus();
});
@@ -718,7 +820,7 @@
var that = this,
no_results = $('<li class="no-results"></li>');
this.$newElement.on('click.dropdown.data-api', function () {
this.$newElement.on('click.dropdown.data-api touchstart.dropdown.data-api', function () {
that.$menu.find('.active').removeClass('active');
if (!!that.$searchbox.val()) {
that.$searchbox.val('');
@@ -731,13 +833,22 @@
}, 10);
});
this.$searchbox.on('click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api', function (e) {
e.stopPropagation();
});
this.$searchbox.on('input propertychange', function () {
if (that.$searchbox.val()) {
that.$lis.not('.is-hidden').removeClass('hide').find('a').not(':icontains(' + that.$searchbox.val() + ')').parent().addClass('hide');
if (that.options.searchAccentInsensitive) {
that.$lis.not('.is-hidden').removeClass('hide').find('a').not(':aicontains(' + normalizeToBase(that.$searchbox.val()) + ')').parent().addClass('hide');
} else {
that.$lis.not('.is-hidden').removeClass('hide').find('a').not(':icontains(' + that.$searchbox.val() + ')').parent().addClass('hide');
}
if (!that.$menu.find('li').filter(':visible:not(.no-results)').length) {
if (!!no_results.parent().length) no_results.remove();
no_results.html(that.options.noneResultsText + ' "' + that.$searchbox.val() + '"').show();
no_results.html(that.options.noneResultsText + ' "' + htmlEscape(that.$searchbox.val()) + '"').show();
that.$menu.find('li').last().after(no_results);
} else if (!!no_results.parent().length) {
no_results.remove();
@@ -752,22 +863,11 @@
that.$menu.find('li').filter(':visible:not(.divider)').eq(0).addClass('active').find('a').focus();
$(this).focus();
});
this.$menu.on('mouseenter', 'a', function (e) {
that.$menu.find('.active').removeClass('active');
$(e.currentTarget).parent().not('.disabled').addClass('active');
});
this.$menu.on('mouseleave', 'a', function () {
that.$menu.find('.active').removeClass('active');
});
},
val: function (value) {
if (value !== undefined) {
if (typeof value !== 'undefined') {
this.$element.val(value);
this.$element.change();
this.render();
return this.$element;
@@ -777,52 +877,84 @@
},
selectAll: function () {
if (this.$lis == null) this.$lis = this.$menu.find('li');
this.$element.find('option:enabled').prop('selected', true);
$(this.$lis).not('.disabled').addClass('selected');
this.render(false);
this.findLis();
this.$lis.not('.divider').not('.disabled').not('.selected').filter(':visible').find('a').click();
},
deselectAll: function () {
if (this.$lis == null) this.$lis = this.$menu.find('li');
this.$element.find('option:enabled').prop('selected', false);
$(this.$lis).not('.disabled').removeClass('selected');
this.render(false);
this.findLis();
this.$lis.not('.divider').not('.disabled').filter('.selected').filter(':visible').find('a').click();
},
keydown: function (e) {
var $this,
var $this = $(this),
$parent = ($this.is('input')) ? $this.parent().parent() : $this.parent(),
$items,
$parent,
that = $parent.data('this'),
index,
next,
first,
last,
prev,
nextPrev,
that,
prevIndex,
isActive,
keyCodeMap = {
32: ' ', 48: '0', 49: '1', 50: '2', 51: '3', 52: '4', 53: '5', 54: '6', 55: '7', 56: '8', 57: '9', 59: ';',
65: 'a', 66: 'b', 67: 'c', 68: 'd', 69: 'e', 70: 'f', 71: 'g', 72: 'h', 73: 'i', 74: 'j', 75: 'k', 76: 'l',
77: 'm', 78: 'n', 79: 'o', 80: 'p', 81: 'q', 82: 'r', 83: 's', 84: 't', 85: 'u', 86: 'v', 87: 'w', 88: 'x',
89: 'y', 90: 'z', 96: '0', 97: '1', 98: '2', 99: '3', 100: '4', 101: '5', 102: '6', 103: '7', 104: '8', 105: '9'
32: ' ',
48: '0',
49: '1',
50: '2',
51: '3',
52: '4',
53: '5',
54: '6',
55: '7',
56: '8',
57: '9',
59: ';',
65: 'a',
66: 'b',
67: 'c',
68: 'd',
69: 'e',
70: 'f',
71: 'g',
72: 'h',
73: 'i',
74: 'j',
75: 'k',
76: 'l',
77: 'm',
78: 'n',
79: 'o',
80: 'p',
81: 'q',
82: 'r',
83: 's',
84: 't',
85: 'u',
86: 'v',
87: 'w',
88: 'x',
89: 'y',
90: 'z',
96: '0',
97: '1',
98: '2',
99: '3',
100: '4',
101: '5',
102: '6',
103: '7',
104: '8',
105: '9'
};
$this = $(this);
$parent = $this.parent();
if ($this.is('input')) $parent = $this.parent().parent();
that = $parent.data('this');
if (that.options.liveSearch) $parent = $this.parent().parent();
if (that.options.container) $parent = that.$menu;
$items = $('[role=menu] li:not(.divider) a', $parent);
$items = $('[role=menu] li a', $parent);
isActive = that.$menu.parent().hasClass('open');
@@ -843,10 +975,14 @@
that.$menu.parent().removeClass('open');
that.$button.focus();
}
$items = $('[role=menu] li:not(.divider):visible', $parent);
$items = $('[role=menu] li:not(.divider):not(.dropdown-header):visible', $parent);
if (!$this.val() && !/(38|40)/.test(e.keyCode.toString(10))) {
if ($items.filter('.active').length === 0) {
$items = that.$newElement.find('li').filter(':icontains(' + keyCodeMap[e.keyCode] + ')');
if (that.options.searchAccentInsensitive) {
$items = that.$newElement.find('li').filter(':aicontains(' + normalizeToBase(keyCodeMap[e.keyCode]) + ')');
} else {
$items = that.$newElement.find('li').filter(':icontains(' + keyCodeMap[e.keyCode] + ')');
}
}
}
}
@@ -854,7 +990,6 @@
if (!$items.length) return;
if (/(38|40)/.test(e.keyCode.toString(10))) {
index = $items.index($items.filter(':focus'));
first = $items.parent(':not(.disabled):visible').first().index();
last = $items.parent(':not(.disabled):visible').last().index();
@@ -907,7 +1042,6 @@
}
} else if (!$this.is('input')) {
var keyIndex = [],
count,
prevKey;
@@ -937,8 +1071,8 @@
$items.eq(keyIndex[count - 1]).focus();
}
// Select focused option if "Enter", "Spacebar" are pressed inside the menu.
if (/(13|32)/.test(e.keyCode.toString(10)) && isActive) {
// Select focused option if "Enter", "Spacebar" or "Tab" (when selectOnTab is true) are pressed inside the menu.
if ((/(13|32)/.test(e.keyCode.toString(10)) || (/(^9$)/.test(e.keyCode.toString(10)) && that.options.selectOnTab)) && isActive) {
if (!/(32)/.test(e.keyCode.toString(10))) e.preventDefault();
if (!that.options.liveSearch) {
$(':focus').click();
@@ -953,7 +1087,29 @@
that.$menu.parent().removeClass('open');
that.$button.focus();
}
},
mobile: function () {
this.$element.addClass('mobile-device').appendTo(this.$newElement);
if (this.options.container) this.$menu.hide();
},
refresh: function () {
this.$lis = null;
this.reloadLi();
this.render();
this.setWidth();
this.setStyle();
this.checkDisabled();
this.liHeight();
},
update: function () {
this.reloadLi();
this.setWidth();
this.setStyle();
this.checkDisabled();
this.liHeight();
},
hide: function () {
@@ -964,24 +1120,40 @@
this.$newElement.show();
},
destroy: function () {
remove: function () {
this.$newElement.remove();
this.$element.remove();
}
};
$.fn.selectpicker = function (option, event) {
//get the args of the outer function..
// SELECTPICKER PLUGIN DEFINITION
// ==============================
function Plugin(option, event) {
// get the args of the outer function..
var args = arguments;
// The arguments of the function are explicitly re-defined from the argument list, because the shift causes them
// to get lost
//noinspection JSDuplicatedDeclaration
var _option = option,
option = args[0],
event = args[1];
[].shift.apply(args);
// This fixes a bug in the js implementation on android 2.3 #715
if (typeof option == 'undefined') {
option = _option;
}
var value;
var chain = this.each(function () {
if ($(this).is('select')) {
var $this = $(this),
data = $this.data('selectpicker'),
var $this = $(this);
if ($this.is('select')) {
var data = $this.data('selectpicker'),
options = typeof option == 'object' && option;
if (!data) {
$this.data('selectpicker', (data = new Selectpicker(this, $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, $this.data(), options), event)));
var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, $this.data(), options);
$this.data('selectpicker', (data = new Selectpicker(this, config, event)));
} else if (options) {
for (var i in options) {
if (options.hasOwnProperty(i)) {
@@ -991,14 +1163,10 @@
}
if (typeof option == 'string') {
//Copy the value of option, as once we shift the arguments
//it also shifts the value of option.
var property = option;
if (data[property] instanceof Function) {
[].shift.apply(args);
value = data[property].apply(data, args);
if (data[option] instanceof Function) {
value = data[option].apply(data, args);
} else {
value = data.options[property];
value = data.options[option];
}
}
}
@@ -1010,15 +1178,32 @@
} else {
return chain;
}
};
}
var old = $.fn.selectpicker;
$.fn.selectpicker = Plugin;
$.fn.selectpicker.Constructor = Selectpicker;
// SELECTPICKER NO CONFLICT
// ========================
$.fn.selectpicker.noConflict = function () {
$.fn.selectpicker = old;
return this;
};
$(document)
.data('keycount', 0)
.on('keydown', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=menu], .bootstrap-select-searchbox input', Selectpicker.prototype.keydown)
.on('focusin.modal', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=menu], .bootstrap-select-searchbox input', function (e) {
.on('keydown', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=menu], .bs-searchbox input', Selectpicker.prototype.keydown)
.on('focusin.modal', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=menu], .bs-searchbox input', function (e) {
e.stopPropagation();
});
// SELECTPICKER DATA-API
// =====================
$(window).on('load.bs.select.data-api', function () {
$('.selectpicker').each(function () {
var $selectpicker = $(this);
Plugin.call($selectpicker, $selectpicker.data());
})
});
})(jQuery);
@@ -7,8 +7,19 @@
$.fn.selectpicker.defaults = {
noneSelectedText: 'Nothing selected',
noneResultsText: 'No results match',
countSelectedText: '{0} of {1} selected',
maxOptionsText: ['Limit reached ({n} {var} max)', 'Group limit reached ({n} {var} max)', ['items', 'item']],
countSelectedText: function (numSelected, numTotal) {
return (numSelected == 1) ? "{0} item selected" : "{0} items selected";
},
maxOptionsText: function (numAll, numGroup) {
var arr = [];
arr[0] = (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)';
arr[1] = (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)';
return arr;
},
selectAllText: 'Select All',
deselectAllText: 'Deselect All',
multipleSeparator: ', '
};
}(jQuery));
@@ -7,8 +7,17 @@
$.fn.selectpicker.defaults = {
noneSelectedText: 'Aucune s&eacute;lection',
noneResultsText: 'Aucun r&eacute;sultat',
countSelectedText: '{0} sur {1} s&eacute;lection(s)',
maxOptionsText: ['Limite atteinte ({n} {var} max)', 'Limite du groupe atteinte ({n} {var} max)', ['&eacute;l&eacute;ments', '&eacute;l&eacute;ment']],
countSelectedText: function (numSelected, numTotal) {
return (numSelected > 1) ? "{0} &eacute;l&eacute;ments s&eacute;lection&eacute;s" : "{0} &eacute;l&eacute;ment s&eacute;lection&eacute;";
},
maxOptionsText: function (numAll, numGroup) {
var arr = [];
arr[0] = (numAll > 1) ? 'Limite atteinte ({n} &eacute;l&eacute;ments max)' : 'Limite atteinte ({n} &eacute;l&eacute;ment max)';
arr[1] = (numGroup > 1) ? 'Limite du groupe atteinte ({n} &eacute;l&eacute;ments max)' : 'Limite du groupe atteinte ({n} &eacute;l&eacute;ment max)';
return arr;
},
multipleSeparator: ', '
};
}(jQuery));
@@ -9,6 +9,8 @@
noneResultsText: 'Brak wyników wyszukiwania',
countSelectedText: 'Zaznaczono {0} z {1}',
maxOptionsText: ['Osiągnięto limit ({n} {var} max)', 'Limit grupy osiągnięty ({n} {var} max)', ['elementy', 'element']],
selectAll: 'Zaznacz wszystkie',
deselectAll: 'Odznacz wszystkie',
multipleSeparator: ', '
};
}(jQuery));
@@ -0,0 +1,15 @@
/*
* Translated default messages for bootstrap-select.
* Locale: RO (Romanian)
* Region: RO (Romania)
* Alex Florea <alecz.fia@gmail.com>
*/
(function ($) {
$.fn.selectpicker.defaults = {
noneSelectedText: 'Nu a fost selectat nimic',
noneResultsText: 'Nu exista niciun rezultat',
countSelectedText: '{0} din {1} selectat(e)',
maxOptionsText: ['Limita a fost atinsa ({n} {var} max)', 'Limita de grup a fost atinsa ({n} {var} max)', ['iteme', 'item']],
multipleSeparator: ', '
};
}(jQuery));
@@ -6,7 +6,7 @@
(function ($) {
$.fn.selectpicker.defaults = {
noneSelectedText: 'Ничего не выбрано',
noneResultsText: 'Не найдено совпадений',
noneResultsText: 'Совпадений не найдено',
countSelectedText: 'Выбрано {0} из {1}',
maxOptionsText: ['Достигнут предел ({n} {var} максимум)', 'Достигнут предел в группе ({n} {var} максимум)', ['items', 'item']],
multipleSeparator: ', '
@@ -0,0 +1,14 @@
/*
* Translated default messages for bootstrap-select.
* Locale: UA (Ukrainian; Українська)
* Region: UA (Ukraine)
*/
(function ($) {
$.fn.selectpicker.defaults = {
noneSelectedText: 'Нічого не вибрано',
noneResultsText: 'Збігів не знайдено',
countSelectedText: 'Вибрано {0} із {1}',
maxOptionsText: ['Досягнута межа ({n} {var} максимум)', 'Досягнута межа в групі ({n} {var} максимум)', ['items', 'item']],
multipleSeparator: ', '
};
}(jQuery));
@@ -0,0 +1,16 @@
/*
* Translated default messages for bootstrap-select.
* Locale: ZH (Chinese)
* Region: TW (Taiwan)
*/
(function ($) {
$.fn.selectpicker.defaults = {
noneSelectedText: '沒有選取任何項目',
noneResultsText: '沒有找到符合的結果',
countSelectedText: '已經選取{0}個項目',
maxOptionsText: ['超過限制 (最多選擇{n}項)', '超過限制(最多選擇{n}組)'],
selectAllText: '選取全部',
deselectAllText: '全部取消',
multipleSeparator: ', '
};
}(jQuery));
@@ -1,43 +1,75 @@
@import "variables";
// Mixins
.cursor-disabled() {
cursor: not-allowed;
}
// Rules
.bootstrap-select {
/*width: 220px\9; IE8 and below*/
//noinspection CssShorthandPropertyValue
width: 220px \0; /*IE9 and below*/
& > .btn {
// The selectpicker button
> .btn {
width: 100%;
padding-right: 25px;
}
// Error display
.error & .btn {
border: 1px solid #b94a48;
border: 1px solid @color-red-error;
}
// Error display
.control-group.error & .dropdown-toggle {
border-color: @color-red-error;
}
&.fit-width {
width: auto !important;
}
}
.bootstrap-select.btn-group:not(.input-group-btn),
.bootstrap-select.btn-group[class*="span"] {
float: none;
display: inline-block;
margin-bottom: 10px;
margin-left: 0;
&:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) {
width: @width-default;
}
.btn:focus {
outline: thin dotted #333333 !important;
outline: 5px auto -webkit-focus-ring-color !important;
outline-offset: -2px;
}
}
.bootstrap-select.form-control {
margin-bottom: 0;
padding: 0;
border: none;
&:not([class*="col-"]) {
width: 100%;
}
}
.bootstrap-select.btn-group.pull-right,
.bootstrap-select.btn-group[class*="span"].pull-right,
.row-fluid .bootstrap-select.btn-group[class*="span"].pull-right {
float: right;
}
// The selectpicker components
.bootstrap-select.btn-group {
&:not(.input-group-btn),
&[class*="col-"] {
float: none;
display: inline-block;
margin-left: 0;
}
// Forces the pull to the right, if necessary
&,
&[class*="col-"],
.row-fluid &[class*="col-"] {
&.dropdown-menu-right {
float: right;
}
}
.form-search &,
.form-inline &,
.form-horizontal &,
@@ -45,6 +77,17 @@
margin-bottom: 0;
}
.form-group-lg &.form-control,
.form-group-sm &.form-control {
padding: 0;
}
// Set the width of the live search (and any other form control within an inline form)
// see https://github.com/silviomoreto/bootstrap-select/issues/685
.form-inline & .form-control {
width: 100%;
}
.input-append & {
margin-left: -1px;
}
@@ -52,139 +95,140 @@
.input-prepend & {
margin-right: -1px;
}
}
.bootstrap-select:not([class*="span"]):not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) {
width: 220px;
}
> .disabled {
.cursor-disabled();
.bootstrap-select.form-control:not([class*="span"]) {
width: 100%;
}
.bootstrap-select.show-menu-arrow.open > .btn {
z-index: 2051;
}
.bootstrap-select .btn:focus {
outline: thin dotted #333333 !important;
outline: 5px auto -webkit-focus-ring-color !important;
outline-offset: -2px;
}
.bootstrap-select.btn-group .btn .filter-option {
display: inline-block;
overflow: hidden;
width: 100%;
text-align: left;
}
.bootstrap-select.btn-group .btn .caret {
position: absolute;
top: 50%;
right: 12px;
margin-top: -2px;
vertical-align: middle;
}
.bootstrap-select.btn-group > .disabled,
.bootstrap-select.btn-group .dropdown-menu li.disabled > a {
cursor: not-allowed;
}
.bootstrap-select.btn-group > .disabled:focus {
outline: none !important;
}
.bootstrap-select.btn-group[class*="span"] .btn {
width: 100%;
}
.bootstrap-select.btn-group .dropdown-menu {
min-width: 100%;
z-index: 2000;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.bootstrap-select.btn-group .dropdown-menu.inner {
position: static;
border: 0;
padding: 0;
margin: 0;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
.bootstrap-select.btn-group .dropdown-menu dt {
display: block;
padding: 3px 20px;
cursor: default;
}
.bootstrap-select.btn-group .div-contain {
overflow: hidden;
}
.bootstrap-select.btn-group .dropdown-menu li {
position: relative;
}
.bootstrap-select.btn-group .dropdown-menu li > a.opt {
position: relative;
padding-left: 35px;
}
.bootstrap-select.btn-group .dropdown-menu li > a {
cursor: pointer;
}
.bootstrap-select.btn-group .dropdown-menu li > dt small {
font-weight: normal;
}
.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a i.check-mark {
position: absolute;
display: inline-block;
right: 15px;
margin-top: 2.5px;
}
.bootstrap-select.btn-group .dropdown-menu li a i.check-mark {
display: none;
}
.bootstrap-select.btn-group .dropdown-menu li a span.text {
display: inline-block;
}
.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text {
margin-right: 34px;
}
.bootstrap-select.btn-group .dropdown-menu li small {
padding-left: 0.5em;
}
.bootstrap-select.btn-group .dropdown-menu {
& li:not(.disabled) > a:hover small,
& li:not(.disabled) > a:focus small,
& li.active:not(.disabled) > a small {
color: rgb(100, 177, 216);
color: rgba(100, 177, 216, 0.4);
&:focus {
outline: none !important;
}
}
& li > dt small {
font-weight: normal;
// The selectpicker button
.btn {
.filter-option {
display: inline-block;
overflow: hidden;
width: 100%;
text-align: left;
}
.caret {
position: absolute;
top: 50%;
right: 12px;
margin-top: -2px;
vertical-align: middle;
}
}
&[class*="col-"] .btn {
width: 100%;
}
// The selectpicker dropdown
.dropdown-menu {
min-width: 100%;
z-index: @zindex-select-dropdown;
box-sizing: border-box;
&.inner {
position: static;
border: 0;
padding: 0;
margin: 0;
border-radius: 0;
box-shadow: none;
}
li {
position: relative;
&:not(.disabled) a:hover small,
&:not(.disabled) a:focus small,
&.active:not(.disabled) a small {
color: @color-blue-hover;
color: fade(@color-blue-hover, 40%);
}
&.disabled a {
.cursor-disabled();
}
a {
cursor: pointer;
&.opt {
position: relative;
padding-left: 2.25em;
}
span.check-mark {
display: none;
}
span.text {
display: inline-block;
}
}
small {
padding-left: 0.5em;
}
}
.notify {
position: absolute;
bottom: 5px;
width: 96%;
margin: 0 2%;
min-height: 26px;
padding: 3px 5px;
background: rgb(245, 245, 245);
border: 1px solid rgb(227, 227, 227);
box-shadow: inset 0 1px 1px fade(rgb(0, 0, 0), 5%);
pointer-events: none;
opacity: 0.9;
box-sizing: border-box;
}
}
.no-results {
padding: 3px;
background: #f5f5f5;
margin: 0 5px;
}
&.fit-width .btn {
.filter-option {
position: static;
}
.caret {
position: static;
top: auto;
margin-top: -1px;
}
}
&.show-tick .dropdown-menu li {
&.selected a span.check-mark {
position: absolute;
display: inline-block;
right: 15px;
margin-top: 5px;
}
a span.text {
margin-right: 34px;
}
}
}
.bootstrap-select.show-menu-arrow {
&.open > .btn {
z-index: @zindex-select-dropdown + 1;
}
.dropdown-toggle {
&:before {
content: '';
@@ -192,8 +236,8 @@
border-right: 7px solid transparent;
border-bottom-width: 7px;
border-bottom-style: solid;
border-bottom-color: rgb(204, 204, 204);
border-bottom-color: rgba(204, 204, 204, 0.2);
border-bottom-color: @color-grey-arrow;
border-bottom-color: fade(@color-grey-arrow, 20%);
position: absolute;
bottom: -4px;
left: 9px;
@@ -212,38 +256,34 @@
}
}
&.dropup {
.dropdown-toggle {
&:before {
bottom: auto;
top: -3px;
border-bottom: 0;
border-top-width: 7px;
border-top-style: solid;
border-top-color: rgb(204, 204, 204);
border-top-color: rgba(204, 204, 204, 0.2);
}
&.dropup .dropdown-toggle {
&:before {
bottom: auto;
top: -3px;
border-bottom: 0;
border-top-width: 7px;
border-top-style: solid;
border-top-color: @color-grey-arrow;
border-top-color: fade(@color-grey-arrow, 20%);
}
&:after {
bottom: auto;
top: -3px;
border-top: 6px solid #FFFFFF;
border-bottom: 0;
}
&:after {
bottom: auto;
top: -3px;
border-top: 6px solid white;
border-bottom: 0;
}
}
&.pull-right {
.dropdown-toggle {
&:before {
right: 12px;
left: auto;
}
&.pull-right .dropdown-toggle {
&:before {
right: 12px;
left: auto;
}
&:after {
right: 13px;
left: auto;
}
&:after {
right: 13px;
left: auto;
}
}
@@ -255,53 +295,14 @@
}
}
.bootstrap-select.btn-group .no-results {
padding: 3px;
background: #f5f5f5;
margin: 0 5px;
}
.bootstrap-select.btn-group .dropdown-menu .notify {
position: absolute;
bottom: 5px;
width: 96%;
margin: 0 2%;
min-height: 26px;
padding: 3px 5px;
background: #f5f5f5;
border: 1px solid #e3e3e3;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
pointer-events: none;
opacity: 0.9;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.bootstrap-select.btn-group.fit-width .btn .filter-option {
position: static;
}
.bootstrap-select.btn-group.fit-width .btn .caret {
position: static;
top: auto;
margin-top: -1px;
}
.control-group.error .bootstrap-select .dropdown-toggle {
border-color: #b94a48;
}
.bootstrap-select-searchbox,
.bootstrap-select .bs-actionsbox {
.bs-searchbox,
.bs-actionsbox {
padding: 4px 8px;
}
.bootstrap-select .bs-actionsbox {
.bs-actionsbox {
float: left;
width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
& .btn-group button {
@@ -309,12 +310,12 @@
}
}
.bootstrap-select-searchbox {
.bs-searchbox {
& + .bs-actionsbox {
padding: 0 8px 4px;
}
& input, & .form-control {
& input.form-control {
margin-bottom: 0;
width: 100%;
}
@@ -0,0 +1,7 @@
@color-red-error: rgb(185, 74, 72);
@color-blue-hover: rgb(100, 177, 216);
@color-grey-arrow: rgb(204, 204, 204);
@width-default: 220px; // 3 960px-grid columns
@zindex-select-dropdown: 1035; // must be lower than a modal background (1040) but higher than the fixed navbar (1030)
+14 -12
View File
@@ -3,7 +3,7 @@
"title": "bootstrap-select",
"filename": "bootstrap-select.js",
"description": "A custom <select> for Bootstrap using button dropdown as replacement",
"version": "1.6.0",
"version": "1.6.3",
"homepage": "http://silviomoreto.github.io/bootstrap-select/",
"author": {
"name": "Silvio Moreto",
@@ -43,22 +43,24 @@
"url": "https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE"
},
"dependencies": {
"jquery": "1.8"
"jquery": ">=1.8"
},
"devDependencies": {
"grunt": "~0.4.5",
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-watch": "~0.6.1",
"grunt-contrib-qunit": "~0.5.2",
"grunt-contrib-concat": "~0.4.0",
"grunt-contrib-uglify": "~0.5.0",
"grunt-contrib-less": "~0.11.3",
"grunt-contrib-csslint": "~0.2.0",
"grunt-contrib-clean": "~0.5.0",
"load-grunt-tasks": "~0.6.0",
"grunt-autoprefixer": "~1.0.0",
"grunt-banner": "~0.2.3",
"grunt-contrib-clean": "~0.6.0",
"grunt-contrib-compress": "^0.12.0",
"grunt-contrib-concat": "~0.5.0",
"grunt-contrib-csslint": "~0.2.0",
"grunt-contrib-cssmin": "~0.10.0",
"grunt-sed": "~0.1.1"
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-less": "~0.11.3",
"grunt-contrib-qunit": "~0.5.2",
"grunt-contrib-uglify": "~0.5.0",
"grunt-contrib-watch": "~0.6.1",
"grunt-sed": "~0.1.1",
"load-grunt-tasks": "~0.6.0"
},
"keywords": [
"form",
+157 -25
View File
@@ -5,42 +5,39 @@
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="dist/css/bootstrap-select.css">
<link href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
padding-top: 70px;
}
</style>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script type="text/javascript" src="dist/js/bootstrap-select.js"></script>
<link rel="stylesheet" type="text/css" href="dist/css/bootstrap-select.css">
<!-- 3.2 -->
<link href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<!-- 2.3.2
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.js"></script>
-->
<script type="text/javascript">
$(window).on('load', function () {
$('.selectpicker').selectpicker({
'selectedText': 'cat'
});
// $('.selectpicker').selectpicker('hide');
});
</script>
</head>
<body>
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">Bootstrap-select usability tests</a>
</div>
</div>
</nav>
<div class="container">
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="basic" class="col-lg-2 control-label">Test bootstrap 3 form</label>
<label for="basic" class="col-lg-2 control-label">"Basic"</label>
<div class="col-lg-10">
<select id="basic" class="selectpicker show-tick form-control" multiple data-live-search="true">
<select id="basic" class="selectpicker show-tick form-control" data-live-search="true">
<option>cow</option>
<option>bull</option>
<option class="get-class" disabled>ox</option>
<optgroup label="test" data-subtext="another test" data-icon="icon-ok">
<optgroup label="test" data-subtext="another test">
<option>ASD</option>
<option selected>Bla</option>
<option>Ble</option>
@@ -49,16 +46,17 @@
</div>
</div>
</form>
<hr>
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="maxOption2" class="col-lg-2 control-label">multiple & max-option = 2</label>
<label for="basic2" class="col-lg-2 control-label">"Basic" #2 (multiple max-option=1)</label>
<div class="col-lg-10">
<select id="maxOption2" class="selectpicker show-tick form-control" multiple data-max-options="2">
<select id="basic2" class="show-tick form-control" multiple>
<option>cow</option>
<option>bull</option>
<option class="get-class" disabled>ox</option>
<optgroup label="test" data-subtext="another test" data-icon="icon-ok">
<optgroup label="test" data-subtext="another test">
<option>ASD</option>
<option selected>Bla</option>
<option>Ble</option>
@@ -67,6 +65,140 @@
</div>
</div>
</form>
<hr>
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="maxOption2" class="col-lg-2 control-label">multiple, show-menu-arrow, & max-option = 2</label>
<div class="col-lg-10">
<select id="maxOption2" class="selectpicker show-menu-arrow form-control" multiple data-max-options="2">
<option>chicken</option>
<option>turkey</option>
<option disabled>duck</option>
<option>goose</option>
</select>
</div>
</div>
</form>
<hr>
<form class="form-inline">
<div class="form-group">
<label class="col-md-1 control-label" for="lunch">Lunch: </label>
</div>
<div class="form-group">
<select id="lunch" class="selectpicker" data-live-search="true" title="Please select a lunch ...">
<option>Hot Dog, Fries and a Soda</option>
<option>Burger, Shake and a Smile</option>
<option>Sugar, Spice and all things nice</option>
<option>Baby Back Ribs</option>
<option>A really really long option made to illustrate an issue with the live search in an inline form</option>
</select>
</div>
</form>
<hr>
<form class="form-horizontal" role="form">
<div class="form-group form-group-lg">
<label for="error" class="col-lg-2 control-label">error</label>
<div class="col-lg-10 error">
<select id="error" class="selectpicker show-tick form-control">
<option>pen</option>
<option>pencil</option>
<option selected>brush</option>
</select>
</div>
</div>
</form>
<hr>
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">Navbar</a>
</div>
<form class="navbar-form navbar-left" role="search">
<div class="form-group">
<select class="selectpicker" multiple data-live-search="true" data-actions-box="true">
<optgroup label="filter1">
<option>option1</option>
<option>option2</option>
<option>option3</option>
<option>option4</option>
</optgroup>
<optgroup label="filter2">
<option>option1</option>
<option>option2</option>
<option>option3</option>
<option>option4</option>
</optgroup>
<optgroup label="filter3">
<option>option1</option>
<option>option2</option>
<option>option3</option>
<option>option4</option>
</optgroup>
</select>
</div>
<div class="input-group">
<input type="text" class="form-control" placeholder="Search" name="q">
<div class="input-group-btn">
<button class="btn btn-default" type="submit"><i class="glyphicon glyphicon-search"></i></button>
</div>
</div>
<button type="submit" class="btn btn-default">Search</button>
</form>
</div>
<!-- .container-fluid -->
</nav>
<hr>
<select id="first-disabled" class="selectpicker" data-hide-disabled="true" data-live-search="true">
<optgroup disabled="disabled" label="disabled">
<option>Hidden</option>
</optgroup>
<optgroup label="Fruit">
<option>Apple</option>
<option>Orange</option>
</optgroup>
<optgroup label="Vegetable">
<option>Corn</option>
<option>Carrot</option>
</optgroup>
</select>
<hr>
<select id="first-disabled2" class="selectpicker" multiple data-hide-disabled="true" data-size="5">
<option>Apple</option>
<option>Banana</option>
<option>Orange</option>
<option>Pineapple</option>
<option>Apple2</option>
<option>Banana2</option>
<option>Orange2</option>
<option>Pineapple2</option>
<option>Apple2</option>
<option>Banana2</option>
<option>Orange2</option>
<option>Pineapple2</option>
</select>
<button id="special" class="btn btn-default">Hide selected by disabling</button>
<p>Just select 1st element, click button and check list again</p>
<script>
$(document).ready(function () {
var mySelect = $('#first-disabled2');
$('#special').on('click', function () {
mySelect.find('option:selected').attr('disabled', 'disabled');
mySelect.selectpicker('refresh');
});
var $basic2 = $('#basic2').selectpicker({
liveSearch: true,
maxOptions: 1
});
});
</script>
</div>
</body>
</html>
+7 -7
View File
@@ -1,7 +1,7 @@
{
"name": "bootstrap",
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
"version": "3.2.0",
"version": "3.3.1",
"keywords": [
"css",
"js",
@@ -23,7 +23,7 @@
"dist/fonts/glyphicons-halflings-regular.woff"
],
"ignore": [
".*",
"/.*",
"_config.yml",
"CNAME",
"composer.json",
@@ -33,16 +33,16 @@
"test-infra"
],
"dependencies": {
"jquery": ">= 1.9.0"
"jquery": ">= 1.9.1"
},
"_release": "3.2.0",
"_release": "3.3.1",
"_resolution": {
"type": "version",
"tag": "v3.2.0",
"commit": "c068162161154a4b85110ea1e7dd3d7897ce2b72"
"tag": "v3.3.1",
"commit": "9a7e365c2c4360335d25246dac11afb1f577210a"
},
"_source": "git://github.com/twbs/bootstrap.git",
"_target": "3.2.0",
"_target": "3.3.1",
"_originalSource": "bootstrap",
"_direct": true
}
+84 -92
View File
@@ -18,9 +18,22 @@ module.exports = function (grunt) {
var fs = require('fs');
var path = require('path');
var npmShrinkwrap = require('npm-shrinkwrap');
var generateGlyphiconsData = require('./grunt/bs-glyphicons-data-generator.js');
var BsLessdocParser = require('./grunt/bs-lessdoc-parser.js');
var getLessVarsData = function () {
var filePath = path.join(__dirname, 'less/variables.less');
var fileContent = fs.readFileSync(filePath, { encoding: 'utf8' });
var parser = new BsLessdocParser(fileContent);
return { sections: parser.parseFile() };
};
var generateRawFiles = require('./grunt/bs-raw-files-generator.js');
var generateCommonJSModule = require('./grunt/bs-commonjs-generator.js');
var configBridge = grunt.file.readJSON('./grunt/configBridge.json', { encoding: 'utf8' });
Object.keys(configBridge.paths).forEach(function (key) {
configBridge.paths[key].forEach(function (val, i, arr) {
arr[i] = path.join('./docs/assets', val);
});
});
// Project configuration.
grunt.initConfig({
@@ -32,12 +45,13 @@ module.exports = function (grunt) {
' * Copyright 2011-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
' * Licensed under <%= pkg.license.type %> (<%= pkg.license.url %>)\n' +
' */\n',
// NOTE: This jqueryCheck code is duplicated in customizer.js; if making changes here, be sure to update the other copy too.
jqueryCheck: 'if (typeof jQuery === \'undefined\') { throw new Error(\'Bootstrap\\\'s JavaScript requires jQuery\') }\n\n',
jqueryCheck: configBridge.config.jqueryCheck.join('\n'),
jqueryVersionCheck: configBridge.config.jqueryVersionCheck.join('\n'),
// Task configuration.
clean: {
dist: ['dist', 'docs/dist']
dist: 'dist',
docs: 'docs/dist'
},
jshint: {
@@ -50,7 +64,7 @@ module.exports = function (grunt) {
},
src: ['Gruntfile.js', 'grunt/*.js']
},
src: {
core: {
src: 'js/*.js'
},
test: {
@@ -60,7 +74,7 @@ module.exports = function (grunt) {
src: 'js/tests/unit/*.js'
},
assets: {
src: ['docs/assets/js/_src/*.js', 'docs/assets/js/*.js', '!docs/assets/js/*.min.js']
src: ['docs/assets/js/src/*.js', 'docs/assets/js/*.js', '!docs/assets/js/*.min.js']
}
},
@@ -71,8 +85,8 @@ module.exports = function (grunt) {
grunt: {
src: '<%= jshint.grunt.src %>'
},
src: {
src: '<%= jshint.src.src %>'
core: {
src: '<%= jshint.core.src %>'
},
test: {
src: '<%= jshint.test.src %>'
@@ -87,7 +101,7 @@ module.exports = function (grunt) {
concat: {
options: {
banner: '<%= banner %>\n<%= jqueryCheck %>',
banner: '<%= banner %>\n<%= jqueryCheck %>\n<%= jqueryVersionCheck %>',
stripBanners: false
},
bootstrap: {
@@ -113,28 +127,16 @@ module.exports = function (grunt) {
options: {
preserveComments: 'some'
},
bootstrap: {
core: {
src: '<%= concat.bootstrap.dest %>',
dest: 'dist/js/<%= pkg.name %>.min.js'
},
customize: {
src: [
'docs/assets/js/_vendor/less.min.js',
'docs/assets/js/_vendor/jszip.min.js',
'docs/assets/js/_vendor/uglify.min.js',
'docs/assets/js/_vendor/blob.js',
'docs/assets/js/_vendor/filesaver.js',
'docs/assets/js/raw-files.min.js',
'docs/assets/js/_src/customizer.js'
],
src: configBridge.paths.customizerJs,
dest: 'docs/assets/js/customize.min.js'
},
docsJs: {
src: [
'docs/assets/js/_vendor/holder.js',
'docs/assets/js/_vendor/ZeroClipboard.min.js',
'docs/assets/js/_src/application.js'
],
src: configBridge.paths.docsJs,
dest: 'docs/assets/js/docs.min.js'
}
},
@@ -155,9 +157,8 @@ module.exports = function (grunt) {
sourceMapURL: '<%= pkg.name %>.css.map',
sourceMapFilename: 'dist/css/<%= pkg.name %>.css.map'
},
files: {
'dist/css/<%= pkg.name %>.css': 'less/bootstrap.less'
}
src: 'less/bootstrap.less',
dest: 'dist/css/<%= pkg.name %>.css'
},
compileTheme: {
options: {
@@ -167,24 +168,14 @@ module.exports = function (grunt) {
sourceMapURL: '<%= pkg.name %>-theme.css.map',
sourceMapFilename: 'dist/css/<%= pkg.name %>-theme.css.map'
},
files: {
'dist/css/<%= pkg.name %>-theme.css': 'less/theme.less'
}
src: 'less/theme.less',
dest: 'dist/css/<%= pkg.name %>-theme.css'
}
},
autoprefixer: {
options: {
browsers: [
'Android 2.3',
'Android >= 4',
'Chrome >= 20',
'Firefox >= 24', // Firefox 24 is the latest ESR
'Explorer >= 8',
'iOS >= 6',
'Opera >= 12',
'Safari >= 6'
]
browsers: configBridge.config.autoprefixerBrowsers
},
core: {
options: {
@@ -199,7 +190,7 @@ module.exports = function (grunt) {
src: 'dist/css/<%= pkg.name %>-theme.css'
},
docs: {
src: 'docs/assets/css/_src/docs.css'
src: 'docs/assets/css/src/docs.css'
},
examples: {
expand: true,
@@ -213,7 +204,7 @@ module.exports = function (grunt) {
options: {
csslintrc: 'less/.csslintrc'
},
src: [
dist: [
'dist/css/bootstrap.css',
'dist/css/bootstrap-theme.css'
],
@@ -225,7 +216,7 @@ module.exports = function (grunt) {
ids: false,
'overqualified-elements': false
},
src: 'docs/assets/css/_src/docs.css'
src: 'docs/assets/css/src/docs.css'
}
},
@@ -235,16 +226,18 @@ module.exports = function (grunt) {
keepSpecialComments: '*',
noAdvanced: true
},
core: {
files: {
'dist/css/<%= pkg.name %>.min.css': 'dist/css/<%= pkg.name %>.css',
'dist/css/<%= pkg.name %>-theme.min.css': 'dist/css/<%= pkg.name %>-theme.css'
}
minifyCore: {
src: 'dist/css/<%= pkg.name %>.css',
dest: 'dist/css/<%= pkg.name %>.min.css'
},
minifyTheme: {
src: 'dist/css/<%= pkg.name %>-theme.css',
dest: 'dist/css/<%= pkg.name %>-theme.min.css'
},
docs: {
src: [
'docs/assets/css/_src/docs.css',
'docs/assets/css/_src/pygments-manni.css'
'docs/assets/css/src/docs.css',
'docs/assets/css/src/pygments-manni.css'
],
dest: 'docs/assets/css/docs.min.css'
}
@@ -277,27 +270,19 @@ module.exports = function (grunt) {
dest: 'docs/examples/'
},
docs: {
files: {
'docs/assets/css/_src/docs.css': 'docs/assets/css/_src/docs.css'
}
src: 'docs/assets/css/src/docs.css',
dest: 'docs/assets/css/src/docs.css'
}
},
copy: {
fonts: {
expand: true,
src: 'fonts/*',
dest: 'dist/'
},
docs: {
expand: true,
cwd: './dist',
src: [
'{css,js}/*.min.*',
'css/*.map',
'fonts/*'
],
dest: 'docs/dist'
src: 'dist/*/*',
dest: 'docs/'
}
},
@@ -315,20 +300,17 @@ module.exports = function (grunt) {
},
jade: {
compile: {
options: {
pretty: true,
data: function () {
var filePath = path.join(__dirname, 'less/variables.less');
var fileContent = fs.readFileSync(filePath, { encoding: 'utf8' });
var parser = new BsLessdocParser(fileContent);
return { sections: parser.parseFile() };
}
},
files: {
'docs/_includes/customizer-variables.html': 'docs/_jade/customizer-variables.jade',
'docs/_includes/nav/customize.html': 'docs/_jade/customizer-nav.jade'
}
options: {
pretty: true,
data: getLessVarsData
},
customizerVars: {
src: 'docs/_jade/customizer-variables.jade',
dest: 'docs/_includes/customizer-variables.html'
},
customizerNav: {
src: 'docs/_jade/customizer-nav.jade',
dest: 'docs/_includes/nav/customize.html'
}
},
@@ -339,8 +321,9 @@ module.exports = function (grunt) {
failHard: true,
reset: true,
relaxerror: [
'Bad value X-UA-Compatible for attribute http-equiv on element meta.',
'Element img is missing required attribute src.'
'Element img is missing required attribute src.',
'Attribute autocomplete not allowed on element input at this point.',
'Attribute autocomplete not allowed on element button at this point.'
]
},
files: {
@@ -350,15 +333,15 @@ module.exports = function (grunt) {
watch: {
src: {
files: '<%= jshint.src.src %>',
tasks: ['jshint:src', 'qunit']
files: '<%= jshint.core.src %>',
tasks: ['jshint:src', 'qunit', 'concat']
},
test: {
files: '<%= jshint.test.src %>',
tasks: ['jshint:test', 'qunit']
},
less: {
files: 'less/*.less',
files: 'less/**/*.less',
tasks: 'less'
}
},
@@ -412,7 +395,7 @@ module.exports = function (grunt) {
var testSubtasks = [];
// Skip core tests if running a different subset of the test suite
if (runSubset('core')) {
testSubtasks = testSubtasks.concat(['dist-css', 'csslint', 'jshint', 'jscs', 'qunit', 'build-customizer-html']);
testSubtasks = testSubtasks.concat(['dist-css', 'dist-js', 'csslint:dist', 'test-js', 'docs']);
}
// Skip HTML validation if running a different subset of the test suite
if (runSubset('validate-html') &&
@@ -430,30 +413,26 @@ module.exports = function (grunt) {
testSubtasks.push('saucelabs-qunit');
}
grunt.registerTask('test', testSubtasks);
grunt.registerTask('test-js', ['jshint:core', 'jshint:test', 'jshint:grunt', 'jscs:core', 'jscs:test', 'jscs:grunt', 'qunit']);
// JS distribution task.
grunt.registerTask('dist-js', ['concat', 'uglify']);
grunt.registerTask('dist-js', ['concat', 'uglify:core', 'commonjs']);
// CSS distribution task.
grunt.registerTask('less-compile', ['less:compileCore', 'less:compileTheme']);
grunt.registerTask('dist-css', ['less-compile', 'autoprefixer', 'usebanner', 'csscomb', 'cssmin']);
// Docs distribution task.
grunt.registerTask('dist-docs', 'copy:docs');
grunt.registerTask('dist-css', ['less-compile', 'autoprefixer:core', 'autoprefixer:theme', 'usebanner', 'csscomb:dist', 'cssmin:minifyCore', 'cssmin:minifyTheme']);
// Full distribution task.
grunt.registerTask('dist', ['clean', 'dist-css', 'copy:fonts', 'dist-js', 'dist-docs']);
grunt.registerTask('dist', ['clean:dist', 'dist-css', 'copy:fonts', 'dist-js']);
// Default task.
grunt.registerTask('default', ['test', 'dist', 'build-glyphicons-data', 'build-customizer']);
grunt.registerTask('default', ['clean:dist', 'copy:fonts', 'test']);
// Version numbering task.
// grunt change-version-number --oldver=A.B.C --newver=X.Y.Z
// This can be overzealous, so its changes should always be manually reviewed!
grunt.registerTask('change-version-number', 'sed');
grunt.registerTask('build-glyphicons-data', function () { generateGlyphiconsData.call(this, grunt); });
// task for building customizer
grunt.registerTask('build-customizer', ['build-customizer-html', 'build-raw-files']);
grunt.registerTask('build-customizer-html', 'jade');
@@ -462,6 +441,19 @@ module.exports = function (grunt) {
generateRawFiles(grunt, banner);
});
grunt.registerTask('commonjs', 'Generate CommonJS entrypoint module in dist dir.', function () {
var srcFiles = grunt.config.get('concat.bootstrap.src');
var destFilepath = 'dist/js/npm.js';
generateCommonJSModule(grunt, srcFiles, destFilepath);
});
// Docs task.
grunt.registerTask('docs-css', ['autoprefixer:docs', 'autoprefixer:examples', 'csscomb:docs', 'csscomb:examples', 'cssmin:docs']);
grunt.registerTask('lint-docs-css', ['csslint:docs', 'csslint:examples']);
grunt.registerTask('docs-js', ['uglify:docsJs', 'uglify:customize']);
grunt.registerTask('lint-docs-js', ['jshint:assets', 'jscs:assets']);
grunt.registerTask('docs', ['docs-css', 'lint-docs-css', 'docs-js', 'lint-docs-js', 'clean:docs', 'copy:docs', 'build-customizer']);
// Task for updating the cached npm packages used by the Travis build (which are controlled by test-infra/npm-shrinkwrap.json).
// This task should be run and the updated file should be committed whenever Bootstrap's dependencies change.
grunt.registerTask('update-shrinkwrap', ['exec:npmUpdate', '_update-shrinkwrap']);
@@ -469,7 +461,7 @@ module.exports = function (grunt) {
var done = this.async();
npmShrinkwrap({ dev: true, dirname: __dirname }, function (err) {
if (err) {
grunt.fail.warn(err)
grunt.fail.warn(err);
}
var dest = 'test-infra/npm-shrinkwrap.json';
fs.renameSync('npm-shrinkwrap.json', dest);
+25 -23
View File
@@ -1,32 +1,33 @@
# [Bootstrap](http://getbootstrap.com)
[![Bower version](https://badge.fury.io/bo/bootstrap.svg)](http://badge.fury.io/bo/bootstrap)
[![NPM version](https://badge.fury.io/js/bootstrap.svg)](http://badge.fury.io/js/bootstrap)
[![Build Status](https://secure.travis-ci.org/twbs/bootstrap.svg?branch=master)](http://travis-ci.org/twbs/bootstrap)
[![Build Status](https://secure.travis-ci.org/twbs/bootstrap.svg?branch=master)](https://travis-ci.org/twbs/bootstrap)
[![devDependency Status](https://david-dm.org/twbs/bootstrap/dev-status.svg)](https://david-dm.org/twbs/bootstrap#info=devDependencies)
[![Selenium Test Status](https://saucelabs.com/browser-matrix/bootstrap.svg)](https://saucelabs.com/u/bootstrap)
Bootstrap is a sleek, intuitive, and powerful front-end framework for faster and easier web development, created by [Mark Otto](http://twitter.com/mdo) and [Jacob Thornton](http://twitter.com/fat), and maintained by the [core team](https://github.com/twbs?tab=members) with the massive support and involvement of the community.
Bootstrap is a sleek, intuitive, and powerful front-end framework for faster and easier web development, created by [Mark Otto](https://twitter.com/mdo) and [Jacob Thornton](https://twitter.com/fat), and maintained by the [core team](https://github.com/twbs?tab=members) with the massive support and involvement of the community.
To get started, check out <http://getbootstrap.com>!
## Table of contents
- [Quick start](#quick-start)
- [Bugs and feature requests](#bugs-and-feature-requests)
- [Documentation](#documentation)
- [Contributing](#contributing)
- [Community](#community)
- [Versioning](#versioning)
- [Creators](#creators)
- [Copyright and license](#copyright-and-license)
- [Quick start](#quick-start)
- [Bugs and feature requests](#bugs-and-feature-requests)
- [Documentation](#documentation)
- [Contributing](#contributing)
- [Community](#community)
- [Versioning](#versioning)
- [Creators](#creators)
- [Copyright and license](#copyright-and-license)
## Quick start
Three quick start options are available:
Four quick start options are available:
- [Download the latest release](https://github.com/twbs/bootstrap/archive/v3.2.0.zip).
- [Download the latest release](https://github.com/twbs/bootstrap/archive/v3.3.1.zip).
- Clone the repo: `git clone https://github.com/twbs/bootstrap.git`.
- Install with [Bower](http://bower.io): `bower install bootstrap`.
- Install with [npm](https://www.npmjs.org): `npm install bootstrap`.
Read the [Getting started page](http://getbootstrap.com/getting-started/) for information on the framework contents, templates and examples, and more.
@@ -66,10 +67,11 @@ Bootstrap's documentation, included in this repo in the root directory, is built
### Running documentation locally
1. If necessary, [install Jekyll](http://jekyllrb.com/docs/installation) (requires v2.0.x).
- **Windows users:** Read [this unofficial guide](https://github.com/juthilo/run-jekyll-on-windows/) to get Jekyll up and running without problems. We use Pygments for syntax highlighting, so make sure to read the sections on installing Python and Pygments.
2. From the root `/bootstrap` directory, run `jekyll serve` in the command line.
3. Open <http://localhost:9001> in your browser, and voilà.
1. If necessary, [install Jekyll](http://jekyllrb.com/docs/installation) (requires v2.5.x).
- **Windows users:** Read [this unofficial guide](http://jekyll-windows.juthilo.com/) to get Jekyll up and running without problems.
2. Install the Ruby-based syntax highlighter, [Rouge](https://github.com/jneen/rouge), with `gem install rouge`.
3. From the root `/bootstrap` directory, run `jekyll serve` in the command line.
4. Open <http://localhost:9001> in your browser, and voilà.
Learn more about using Jekyll by reading its [documentation](http://jekyllrb.com/docs/home/).
@@ -85,7 +87,7 @@ Documentation for v2.3.2 has been made available for the time being at <http://g
Please read through our [contributing guidelines](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md). Included are directions for opening issues, coding standards, and notes on development.
Moreover, if your pull request contains JavaScript patches or features, you must include relevant unit tests. All HTML and CSS should conform to the [Code Guide](http://github.com/mdo/code-guide), maintained by [Mark Otto](http://github.com/mdo).
Moreover, if your pull request contains JavaScript patches or features, you must include relevant unit tests. All HTML and CSS should conform to the [Code Guide](https://github.com/mdo/code-guide), maintained by [Mark Otto](https://github.com/mdo).
Editor preferences are available in the [editor config](https://github.com/twbs/bootstrap/blob/master/.editorconfig) for easy use in common text editors. Read more and download plugins at <http://editorconfig.org>.
@@ -95,9 +97,9 @@ Editor preferences are available in the [editor config](https://github.com/twbs/
Keep track of development and community news.
- Follow [@twbootstrap on Twitter](http://twitter.com/twbootstrap).
- Follow [@twbootstrap on Twitter](https://twitter.com/twbootstrap).
- 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 `##twitter-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)).
@@ -112,13 +114,13 @@ For transparency into our release cycle and in striving to maintain backward com
**Mark Otto**
- <http://twitter.com/mdo>
- <http://github.com/mdo>
- <https://twitter.com/mdo>
- <https://github.com/mdo>
**Jacob Thornton**
- <http://twitter.com/fat>
- <http://github.com/fat>
- <https://twitter.com/fat>
- <https://github.com/fat>
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "bootstrap",
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
"version": "3.2.0",
"version": "3.3.1",
"keywords": [
"css",
"js",
@@ -23,7 +23,7 @@
"dist/fonts/glyphicons-halflings-regular.woff"
],
"ignore": [
".*",
"/.*",
"_config.yml",
"CNAME",
"composer.json",
@@ -33,6 +33,6 @@
"test-infra"
],
"dependencies": {
"jquery": ">= 1.9.0"
"jquery": ">= 1.9.1"
}
}
@@ -1,5 +1,5 @@
/*!
* Bootstrap v3.2.0 (http://getbootstrap.com)
* Bootstrap v3.3.1 (http://getbootstrap.com)
* Copyright 2011-2014 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
@@ -29,6 +29,14 @@
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
}
.btn-default .badge,
.btn-primary .badge,
.btn-success .badge,
.btn-info .badge,
.btn-warning .badge,
.btn-danger .badge {
text-shadow: none;
}
.btn:active,
.btn.active {
background-image: none;
@@ -61,28 +69,28 @@
background-image: none;
}
.btn-primary {
background-image: -webkit-linear-gradient(top, #428bca 0%, #2d6ca2 100%);
background-image: -o-linear-gradient(top, #428bca 0%, #2d6ca2 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#2d6ca2));
background-image: linear-gradient(to bottom, #428bca 0%, #2d6ca2 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);
background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #2b669a;
border-color: #245580;
}
.btn-primary:hover,
.btn-primary:focus {
background-color: #2d6ca2;
background-color: #265a88;
background-position: 0 -15px;
}
.btn-primary:active,
.btn-primary.active {
background-color: #2d6ca2;
border-color: #2b669a;
background-color: #265a88;
border-color: #245580;
}
.btn-primary:disabled,
.btn-primary[disabled] {
background-color: #2d6ca2;
background-color: #265a88;
background-image: none;
}
.btn-success {
@@ -203,12 +211,12 @@
.dropdown-menu > .active > a,
.dropdown-menu > .active > a:hover,
.dropdown-menu > .active > a:focus {
background-color: #357ebd;
background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%);
background-image: -o-linear-gradient(top, #428bca 0%, #357ebd 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#357ebd));
background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);
background-color: #2e6da4;
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
background-repeat: repeat-x;
}
.navbar-default {
@@ -223,12 +231,13 @@
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
}
.navbar-default .navbar-nav > .open > a,
.navbar-default .navbar-nav > .active > a {
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%);
background-image: -o-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f3f3f3));
background-image: linear-gradient(to bottom, #ebebeb 0%, #f3f3f3 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);
background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
background-repeat: repeat-x;
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
@@ -246,12 +255,13 @@
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
}
.navbar-inverse .navbar-nav > .open > a,
.navbar-inverse .navbar-nav > .active > a {
background-image: -webkit-linear-gradient(top, #222 0%, #282828 100%);
background-image: -o-linear-gradient(top, #222 0%, #282828 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#222), to(#282828));
background-image: linear-gradient(to bottom, #222 0%, #282828 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);
background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
background-repeat: repeat-x;
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
@@ -265,6 +275,19 @@
.navbar-fixed-bottom {
border-radius: 0;
}
@media (max-width: 767px) {
.navbar .navbar-nav .open .dropdown-menu > .active > a,
.navbar .navbar-nav .open .dropdown-menu > .active > a:hover,
.navbar .navbar-nav .open .dropdown-menu > .active > a:focus {
color: #fff;
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
background-repeat: repeat-x;
}
}
.alert {
text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
@@ -315,11 +338,11 @@
background-repeat: repeat-x;
}
.progress-bar {
background-image: -webkit-linear-gradient(top, #428bca 0%, #3071a9 100%);
background-image: -o-linear-gradient(top, #428bca 0%, #3071a9 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#3071a9));
background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0);
background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar-success {
@@ -367,14 +390,19 @@
.list-group-item.active,
.list-group-item.active:hover,
.list-group-item.active:focus {
text-shadow: 0 -1px 0 #3071a9;
background-image: -webkit-linear-gradient(top, #428bca 0%, #3278b3 100%);
background-image: -o-linear-gradient(top, #428bca 0%, #3278b3 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#3278b3));
background-image: linear-gradient(to bottom, #428bca 0%, #3278b3 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);
text-shadow: 0 -1px 0 #286090;
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
background-repeat: repeat-x;
border-color: #3278b3;
border-color: #2b669a;
}
.list-group-item.active .badge,
.list-group-item.active:hover .badge,
.list-group-item.active:focus .badge {
text-shadow: none;
}
.panel {
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
@@ -389,11 +417,11 @@
background-repeat: repeat-x;
}
.panel-primary > .panel-heading {
background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%);
background-image: -o-linear-gradient(top, #428bca 0%, #357ebd 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#357ebd));
background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
background-repeat: repeat-x;
}
.panel-success > .panel-heading {
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -226,4 +226,4 @@
<glyph unicode="&#xe199;" d="M100 200h400v-155l-75 -45h350l-75 45v155h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170z" />
<glyph unicode="&#xe200;" d="M121 700q0 -53 28.5 -97t75.5 -65q-4 -16 -4 -38q0 -74 52.5 -126.5t126.5 -52.5q56 0 100 30v-306l-75 -45h350l-75 45v306q46 -30 100 -30q74 0 126.5 52.5t52.5 126.5q0 24 -9 55q50 32 79.5 83t29.5 112q0 90 -61.5 155.5t-150.5 71.5q-26 89 -99.5 145.5 t-167.5 56.5q-116 0 -197.5 -81.5t-81.5 -197.5q0 -4 1 -11.5t1 -11.5q-14 2 -23 2q-74 0 -126.5 -52.5t-52.5 -126.5z" />
</font>
</defs></svg>
</defs></svg>

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+13
View File
@@ -0,0 +1,13 @@
// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
require('../../js/transition.js')
require('../../js/alert.js')
require('../../js/button.js')
require('../../js/carousel.js')
require('../../js/collapse.js')
require('../../js/dropdown.js')
require('../../js/modal.js')
require('../../js/tooltip.js')
require('../../js/popover.js')
require('../../js/scrollspy.js')
require('../../js/tab.js')
require('../../js/affix.js')
@@ -226,4 +226,4 @@
<glyph unicode="&#xe199;" d="M100 200h400v-155l-75 -45h350l-75 45v155h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170z" />
<glyph unicode="&#xe200;" d="M121 700q0 -53 28.5 -97t75.5 -65q-4 -16 -4 -38q0 -74 52.5 -126.5t126.5 -52.5q56 0 100 30v-306l-75 -45h350l-75 45v306q46 -30 100 -30q74 0 126.5 52.5t52.5 126.5q0 24 -9 55q50 32 79.5 83t29.5 112q0 90 -61.5 155.5t-150.5 71.5q-26 89 -99.5 145.5 t-167.5 56.5q-116 0 -197.5 -81.5t-81.5 -197.5q0 -4 1 -11.5t1 -11.5q-14 2 -23 2q-74 0 -126.5 -52.5t-52.5 -126.5z" />
</font>
</defs></svg>
</defs></svg>

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

+7
View File
@@ -0,0 +1,7 @@
{
"extends" : "../js/.jshintrc",
"asi" : false,
"browser" : false,
"es3" : false,
"node" : true
}
@@ -0,0 +1,23 @@
'use strict';
var fs = require('fs');
var path = require('path');
var COMMONJS_BANNER = '// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.\n';
module.exports = function generateCommonJSModule(grunt, srcFiles, destFilepath) {
var destDir = path.dirname(destFilepath);
function srcPathToDestRequire(srcFilepath) {
var requirePath = path.relative(destDir, srcFilepath).replace(/\\/g, '/');
return 'require(\'' + requirePath + '\')';
}
var moduleOutputJs = COMMONJS_BANNER + srcFiles.map(srcPathToDestRequire).join('\n');
try {
fs.writeFileSync(destFilepath, moduleOutputJs);
}
catch (err) {
grunt.fail.warn(err);
}
grunt.log.writeln('File ' + destFilepath.cyan + ' created.');
};
@@ -1,41 +0,0 @@
/*!
* Bootstrap Grunt task for Glyphicons data generation
* http://getbootstrap.com
* Copyright 2014 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
'use strict';
var fs = require('fs');
module.exports = function generateGlyphiconsData(grunt) {
// Pass encoding, utf8, so `readFileSync` will return a string instead of a
// buffer
var glyphiconsFile = fs.readFileSync('less/glyphicons.less', 'utf8');
var glyphiconsLines = glyphiconsFile.split('\n');
// Use any line that starts with ".glyphicon-" and capture the class name
var iconClassName = /^\.(glyphicon-[^\s]+)/;
var glyphiconsData = '# This file is generated via Grunt task. **Do not edit directly.**\n' +
'# See the \'build-glyphicons-data\' task in Gruntfile.js.\n\n';
var glyphiconsYml = 'docs/_data/glyphicons.yml';
for (var i = 0, len = glyphiconsLines.length; i < len; i++) {
var match = glyphiconsLines[i].match(iconClassName);
if (match !== null) {
glyphiconsData += '- ' + match[1] + '\n';
}
}
// Create the `_data` directory if it doesn't already exist
if (!fs.existsSync('docs/_data')) {
fs.mkdirSync('docs/_data');
}
try {
fs.writeFileSync(glyphiconsYml, glyphiconsData);
}
catch (err) {
grunt.fail.warn(err);
}
grunt.log.writeln('File ' + glyphiconsYml.cyan + ' created.');
};
@@ -6,11 +6,13 @@
*/
'use strict';
var markdown = require('markdown').markdown;
var Remarkable = require('remarkable');
function markdown2html(markdownString) {
var md = new Remarkable();
// the slice removes the <p>...</p> wrapper output by Markdown processor
return markdown.toHTML(markdownString.trim()).slice(3, -4);
return md.render(markdownString.trim()).slice(3, -5);
}
@@ -33,9 +35,9 @@ Mini-language:
var CUSTOMIZABLE_HEADING = /^[/]{2}={2}(.*)$/;
var UNCUSTOMIZABLE_HEADING = /^[/]{2}-{2}(.*)$/;
var SUBSECTION_HEADING = /^[/]{2}={3}(.*)$/;
var SECTION_DOCSTRING = /^[/]{2}#{2}(.*)$/;
var VAR_ASSIGNMENT = /^(@[a-zA-Z0-9_-]+):[ ]*([^ ;][^;]+);[ ]*$/;
var VAR_DOCSTRING = /^[/]{2}[*]{2}(.*)$/;
var SECTION_DOCSTRING = /^[/]{2}#{2}(.+)$/;
var VAR_ASSIGNMENT = /^(@[a-zA-Z0-9_-]+):[ ]*([^ ;][^;]*);[ ]*$/;
var VAR_DOCSTRING = /^[/]{2}[*]{2}(.+)$/;
function Section(heading, customizable) {
this.heading = heading.trim();
@@ -0,0 +1,44 @@
{
"paths": {
"customizerJs": [
"../assets/js/vendor/autoprefixer.js",
"../assets/js/vendor/less.min.js",
"../assets/js/vendor/jszip.min.js",
"../assets/js/vendor/uglify.min.js",
"../assets/js/vendor/Blob.js",
"../assets/js/vendor/FileSaver.js",
"../assets/js/raw-files.min.js",
"../assets/js/src/customizer.js"
],
"docsJs": [
"../assets/js/vendor/holder.js",
"../assets/js/vendor/ZeroClipboard.min.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 ($) {",
" 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"
]
}
}
@@ -57,7 +57,7 @@
{
browserName: "iphone",
platform: "OS X 10.9",
version: "7.1"
version: "8.0"
},
# iOS Chrome not currently supported by Sauce Labs
+34
View File
@@ -0,0 +1,34 @@
{
"disallowEmptyBlocks": true,
"disallowKeywords": ["with"],
"disallowMixedSpacesAndTabs": true,
"disallowMultipleLineStrings": true,
"disallowMultipleVarDecl": true,
"disallowQuotedKeysInObjects": "allButReserved",
"disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
"disallowSpaceBeforeBinaryOperators": [","],
"disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
"disallowSpacesInNamedFunctionExpression": { "beforeOpeningRoundBrace": true },
"disallowSpacesInsideArrayBrackets": true,
"disallowSpacesInsideParentheses": true,
"disallowTrailingComma": true,
"disallowTrailingWhitespace": true,
"requireCamelCaseOrUpperCaseIdentifiers": true,
"requireCapitalizedConstructors": true,
"requireCommaBeforeLineBreak": true,
"requireDotNotation": true,
"requireLineFeedAtFileEnd": true,
"requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", "<", ">=", "<="],
"requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"],
"requireSpaceAfterLineComment": true,
"requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", "<", ">=", "<="],
"requireSpacesInAnonymousFunctionExpression": { "beforeOpeningCurlyBrace": true, "beforeOpeningRoundBrace": true },
"requireSpacesInConditionalExpression": true,
"requireSpacesInFunctionDeclaration": { "beforeOpeningCurlyBrace": true },
"requireSpacesInFunctionExpression": { "beforeOpeningCurlyBrace": true },
"requireSpacesInNamedFunctionExpression": { "beforeOpeningCurlyBrace": true },
"requireSpacesInsideObjectBrackets": "allButNested",
"validateIndentation": 2,
"validateLineBreaks": "LF",
"validateQuoteMarks": "'"
}
+15
View File
@@ -0,0 +1,15 @@
{
"asi" : true,
"browser" : true,
"eqeqeq" : false,
"eqnull" : true,
"es3" : true,
"expr" : true,
"jquery" : true,
"latedef" : true,
"laxbreak" : true,
"nonbsp" : true,
"strict" : true,
"undef" : true,
"unused" : true
}
+43 -23
View File
@@ -1,5 +1,5 @@
/* ========================================================================
* Bootstrap: affix.js v3.2.0
* Bootstrap: affix.js v3.3.1
* http://getbootstrap.com/javascript/#affix
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -28,7 +28,7 @@
this.checkPosition()
}
Affix.VERSION = '3.2.0'
Affix.VERSION = '3.3.1'
Affix.RESET = 'affix affix-top affix-bottom'
@@ -37,6 +37,28 @@
target: window
}
Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
var scrollTop = this.$target.scrollTop()
var position = this.$element.offset()
var targetHeight = this.$target.height()
if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
if (this.affixed == 'bottom') {
if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
}
var initializing = this.affixed == null
var colliderTop = initializing ? scrollTop : position.top
var colliderHeight = initializing ? targetHeight : height
if (offsetTop != null && colliderTop <= offsetTop) return 'top'
if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
return false
}
Affix.prototype.getPinnedOffset = function () {
if (this.pinnedOffset) return this.pinnedOffset
this.$element.removeClass(Affix.RESET).addClass('affix')
@@ -52,42 +74,40 @@
Affix.prototype.checkPosition = function () {
if (!this.$element.is(':visible')) return
var scrollHeight = $(document).height()
var scrollTop = this.$target.scrollTop()
var position = this.$element.offset()
var height = this.$element.height()
var offset = this.options.offset
var offsetTop = offset.top
var offsetBottom = offset.bottom
var scrollHeight = $('body').height()
if (typeof offset != 'object') offsetBottom = offsetTop = offset
if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
var affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? false :
offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false
var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
if (this.affixed === affix) return
if (this.unpin != null) this.$element.css('top', '')
if (this.affixed != affix) {
if (this.unpin != null) this.$element.css('top', '')
var affixType = 'affix' + (affix ? '-' + affix : '')
var e = $.Event(affixType + '.bs.affix')
var affixType = 'affix' + (affix ? '-' + affix : '')
var e = $.Event(affixType + '.bs.affix')
this.$element.trigger(e)
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
if (e.isDefaultPrevented()) return
this.affixed = affix
this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
this.affixed = affix
this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
this.$element
.removeClass(Affix.RESET)
.addClass(affixType)
.trigger($.Event(affixType.replace('affix', 'affixed')))
this.$element
.removeClass(Affix.RESET)
.addClass(affixType)
.trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
}
if (affix == 'bottom') {
this.$element.offset({
top: scrollHeight - this.$element.height() - offsetBottom
top: scrollHeight - height - offsetBottom
})
}
}
@@ -132,8 +152,8 @@
data.offset = data.offset || {}
if (data.offsetBottom) data.offset.bottom = data.offsetBottom
if (data.offsetTop) data.offset.top = data.offsetTop
if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
if (data.offsetTop != null) data.offset.top = data.offsetTop
Plugin.call($spy, data)
})
+6 -4
View File
@@ -1,5 +1,5 @@
/* ========================================================================
* Bootstrap: alert.js v3.2.0
* Bootstrap: alert.js v3.3.1
* http://getbootstrap.com/javascript/#alerts
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -18,7 +18,9 @@
$(el).on('click', dismiss, this.close)
}
Alert.VERSION = '3.2.0'
Alert.VERSION = '3.3.1'
Alert.TRANSITION_DURATION = 150
Alert.prototype.close = function (e) {
var $this = $(this)
@@ -34,7 +36,7 @@
if (e) e.preventDefault()
if (!$parent.length) {
$parent = $this.hasClass('alert') ? $this : $this.parent()
$parent = $this.closest('.alert')
}
$parent.trigger(e = $.Event('close.bs.alert'))
@@ -51,7 +53,7 @@
$.support.transition && $parent.hasClass('fade') ?
$parent
.one('bsTransitionEnd', removeElement)
.emulateTransitionEnd(150) :
.emulateTransitionEnd(Alert.TRANSITION_DURATION) :
removeElement()
}
+16 -10
View File
@@ -1,5 +1,5 @@
/* ========================================================================
* Bootstrap: button.js v3.2.0
* Bootstrap: button.js v3.3.1
* http://getbootstrap.com/javascript/#buttons
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -19,7 +19,7 @@
this.isLoading = false
}
Button.VERSION = '3.2.0'
Button.VERSION = '3.3.1'
Button.DEFAULTS = {
loadingText: 'loading...'
@@ -35,10 +35,10 @@
if (data.resetText == null) $el.data('resetText', $el[val]())
$el[val](data[state] == null ? this.options[state] : data[state])
// push to event loop to allow forms to submit
setTimeout($.proxy(function () {
$el[val](data[state] == null ? this.options[state] : data[state])
if (state == 'loadingText') {
this.isLoading = true
$el.addClass(d).attr(d, d)
@@ -60,6 +60,8 @@
else $parent.find('.active').removeClass('active')
}
if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
} else {
this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
}
if (changed) this.$element.toggleClass('active')
@@ -100,11 +102,15 @@
// BUTTON DATA-API
// ===============
$(document).on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
var $btn = $(e.target)
if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
Plugin.call($btn, 'toggle')
e.preventDefault()
})
$(document)
.on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
var $btn = $(e.target)
if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
Plugin.call($btn, 'toggle')
e.preventDefault()
})
.on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
$(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
})
}(jQuery);
+27 -10
View File
@@ -1,5 +1,5 @@
/* ========================================================================
* Bootstrap: carousel.js v3.2.0
* Bootstrap: carousel.js v3.3.1
* http://getbootstrap.com/javascript/#carousel
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -14,7 +14,7 @@
// =========================
var Carousel = function (element, options) {
this.$element = $(element).on('keydown.bs.carousel', $.proxy(this.keydown, this))
this.$element = $(element)
this.$indicators = this.$element.find('.carousel-indicators')
this.options = options
this.paused =
@@ -23,20 +23,26 @@
this.$active =
this.$items = null
this.options.pause == 'hover' && this.$element
this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
.on('mouseenter.bs.carousel', $.proxy(this.pause, this))
.on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
}
Carousel.VERSION = '3.2.0'
Carousel.VERSION = '3.3.1'
Carousel.TRANSITION_DURATION = 600
Carousel.DEFAULTS = {
interval: 5000,
pause: 'hover',
wrap: true
wrap: true,
keyboard: true
}
Carousel.prototype.keydown = function (e) {
if (/input|textarea/i.test(e.target.tagName)) return
switch (e.which) {
case 37: this.prev(); break
case 39: this.next(); break
@@ -63,6 +69,13 @@
return this.$items.index(item || this.$active)
}
Carousel.prototype.getItemForDirection = function (direction, active) {
var delta = direction == 'prev' ? -1 : 1
var activeIndex = this.getItemIndex(active)
var itemIndex = (activeIndex + delta) % this.$items.length
return this.$items.eq(itemIndex)
}
Carousel.prototype.to = function (pos) {
var that = this
var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
@@ -72,7 +85,7 @@
if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
if (activeIndex == pos) return this.pause().cycle()
return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
}
Carousel.prototype.pause = function (e) {
@@ -100,7 +113,7 @@
Carousel.prototype.slide = function (type, next) {
var $active = this.$element.find('.item.active')
var $next = next || $active[type]()
var $next = next || this.getItemForDirection(type, $active)
var isCycling = this.interval
var direction = type == 'next' ? 'left' : 'right'
var fallback = type == 'next' ? 'first' : 'last'
@@ -146,7 +159,7 @@
that.$element.trigger(slidEvent)
}, 0)
})
.emulateTransitionEnd($active.css('transition-duration').slice(0, -1) * 1000)
.emulateTransitionEnd(Carousel.TRANSITION_DURATION)
} else {
$active.removeClass('active')
$next.addClass('active')
@@ -195,7 +208,7 @@
// CAROUSEL DATA-API
// =================
$(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
var clickHandler = function (e) {
var href
var $this = $(this)
var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
@@ -211,7 +224,11 @@
}
e.preventDefault()
})
}
$(document)
.on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
.on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
$(window).on('load', function () {
$('[data-ride="carousel"]').each(function () {
+69 -28
View File
@@ -1,5 +1,5 @@
/* ========================================================================
* Bootstrap: collapse.js v3.2.0
* Bootstrap: collapse.js v3.3.1
* http://getbootstrap.com/javascript/#collapse
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -16,16 +16,25 @@
var Collapse = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, Collapse.DEFAULTS, options)
this.$trigger = $(this.options.trigger).filter('[href="#' + element.id + '"], [data-target="#' + element.id + '"]')
this.transitioning = null
if (this.options.parent) this.$parent = $(this.options.parent)
if (this.options.parent) {
this.$parent = this.getParent()
} else {
this.addAriaAndCollapsedClass(this.$element, this.$trigger)
}
if (this.options.toggle) this.toggle()
}
Collapse.VERSION = '3.2.0'
Collapse.VERSION = '3.3.1'
Collapse.TRANSITION_DURATION = 350
Collapse.DEFAULTS = {
toggle: true
toggle: true,
trigger: '[data-toggle="collapse"]'
}
Collapse.prototype.dimension = function () {
@@ -36,17 +45,21 @@
Collapse.prototype.show = function () {
if (this.transitioning || this.$element.hasClass('in')) return
var activesData
var actives = this.$parent && this.$parent.find('> .panel').children('.in, .collapsing')
if (actives && actives.length) {
activesData = actives.data('bs.collapse')
if (activesData && activesData.transitioning) return
}
var startEvent = $.Event('show.bs.collapse')
this.$element.trigger(startEvent)
if (startEvent.isDefaultPrevented()) return
var actives = this.$parent && this.$parent.find('> .panel > .in')
if (actives && actives.length) {
var hasData = actives.data('bs.collapse')
if (hasData && hasData.transitioning) return
Plugin.call(actives, 'hide')
hasData || actives.data('bs.collapse', null)
activesData || actives.data('bs.collapse', null)
}
var dimension = this.dimension()
@@ -54,6 +67,11 @@
this.$element
.removeClass('collapse')
.addClass('collapsing')[dimension](0)
.attr('aria-expanded', true)
this.$trigger
.removeClass('collapsed')
.attr('aria-expanded', true)
this.transitioning = 1
@@ -72,7 +90,7 @@
this.$element
.one('bsTransitionEnd', $.proxy(complete, this))
.emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize])
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
}
Collapse.prototype.hide = function () {
@@ -88,17 +106,21 @@
this.$element
.addClass('collapsing')
.removeClass('collapse')
.removeClass('in')
.removeClass('collapse in')
.attr('aria-expanded', false)
this.$trigger
.addClass('collapsed')
.attr('aria-expanded', false)
this.transitioning = 1
var complete = function () {
this.transitioning = 0
this.$element
.trigger('hidden.bs.collapse')
.removeClass('collapsing')
.addClass('collapse')
.trigger('hidden.bs.collapse')
}
if (!$.support.transition) return complete.call(this)
@@ -106,13 +128,40 @@
this.$element
[dimension](0)
.one('bsTransitionEnd', $.proxy(complete, this))
.emulateTransitionEnd(350)
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)
}
Collapse.prototype.toggle = function () {
this[this.$element.hasClass('in') ? 'hide' : 'show']()
}
Collapse.prototype.getParent = function () {
return $(this.options.parent)
.find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
.each($.proxy(function (i, element) {
var $element = $(element)
this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
}, this))
.end()
}
Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
var isOpen = $element.hasClass('in')
$element.attr('aria-expanded', isOpen)
$trigger
.toggleClass('collapsed', !isOpen)
.attr('aria-expanded', isOpen)
}
function getTargetFromTrigger($trigger) {
var href
var target = $trigger.attr('data-target')
|| (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
return $(target)
}
// COLLAPSE PLUGIN DEFINITION
// ==========================
@@ -123,7 +172,7 @@
var data = $this.data('bs.collapse')
var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
if (!data && options.toggle && option == 'show') option = !option
if (!data && options.toggle && option == 'show') options.toggle = false
if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
if (typeof option == 'string') data[option]()
})
@@ -148,21 +197,13 @@
// =================
$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
var href
var $this = $(this)
var target = $this.attr('data-target')
|| e.preventDefault()
|| (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
var $target = $(target)
var data = $target.data('bs.collapse')
var option = data ? 'toggle' : $this.data()
var parent = $this.attr('data-parent')
var $parent = parent && $(parent)
if (!data || !data.transitioning) {
if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed')
$this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
}
if (!$this.attr('data-target')) e.preventDefault()
var $target = getTargetFromTrigger($this)
var data = $target.data('bs.collapse')
var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this })
Plugin.call($target, option)
})
+20 -10
View File
@@ -1,5 +1,5 @@
/* ========================================================================
* Bootstrap: dropdown.js v3.2.0
* Bootstrap: dropdown.js v3.3.1
* http://getbootstrap.com/javascript/#dropdowns
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -19,7 +19,7 @@
$(element).on('click.bs.dropdown', this.toggle)
}
Dropdown.VERSION = '3.2.0'
Dropdown.VERSION = '3.3.1'
Dropdown.prototype.toggle = function (e) {
var $this = $(this)
@@ -42,7 +42,9 @@
if (e.isDefaultPrevented()) return
$this.trigger('focus')
$this
.trigger('focus')
.attr('aria-expanded', 'true')
$parent
.toggleClass('open')
@@ -53,7 +55,7 @@
}
Dropdown.prototype.keydown = function (e) {
if (!/(38|40|27)/.test(e.keyCode)) return
if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
var $this = $(this)
@@ -65,7 +67,7 @@
var $parent = getParent($this)
var isActive = $parent.hasClass('open')
if (!isActive || (isActive && e.keyCode == 27)) {
if ((!isActive && e.which != 27) || (isActive && e.which == 27)) {
if (e.which == 27) $parent.find(toggle).trigger('focus')
return $this.trigger('click')
}
@@ -75,10 +77,10 @@
if (!$items.length) return
var index = $items.index($items.filter(':focus'))
var index = $items.index(e.target)
if (e.keyCode == 38 && index > 0) index-- // up
if (e.keyCode == 40 && index < $items.length - 1) index++ // down
if (e.which == 38 && index > 0) index-- // up
if (e.which == 40 && index < $items.length - 1) index++ // down
if (!~index) index = 0
$items.eq(index).trigger('focus')
@@ -88,11 +90,17 @@
if (e && e.which === 3) return
$(backdrop).remove()
$(toggle).each(function () {
var $parent = getParent($(this))
var $this = $(this)
var $parent = getParent($this)
var relatedTarget = { relatedTarget: this }
if (!$parent.hasClass('open')) return
$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
if (e.isDefaultPrevented()) return
$this.attr('aria-expanded', 'false')
$parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
})
}
@@ -146,6 +154,8 @@
.on('click.bs.dropdown.data-api', clearMenus)
.on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
.on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
.on('keydown.bs.dropdown.data-api', toggle + ', [role="menu"], [role="listbox"]', Dropdown.prototype.keydown)
.on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
.on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown)
.on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown)
}(jQuery);
+67 -23
View File
@@ -1,5 +1,5 @@
/* ========================================================================
* Bootstrap: modal.js v3.2.0
* Bootstrap: modal.js v3.3.1
* http://getbootstrap.com/javascript/#modals
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -30,7 +30,10 @@
}
}
Modal.VERSION = '3.2.0'
Modal.VERSION = '3.3.1'
Modal.TRANSITION_DURATION = 300
Modal.BACKDROP_TRANSITION_DURATION = 150
Modal.DEFAULTS = {
backdrop: true,
@@ -53,10 +56,11 @@
this.isShown = true
this.checkScrollbar()
this.setScrollbar()
this.$body.addClass('modal-open')
this.setScrollbar()
this.escape()
this.resize()
this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
@@ -71,6 +75,9 @@
.show()
.scrollTop(0)
if (that.options.backdrop) that.adjustBackdrop()
that.adjustDialog()
if (transition) {
that.$element[0].offsetWidth // force reflow
}
@@ -88,7 +95,7 @@
.one('bsTransitionEnd', function () {
that.$element.trigger('focus').trigger(e)
})
.emulateTransitionEnd(300) :
.emulateTransitionEnd(Modal.TRANSITION_DURATION) :
that.$element.trigger('focus').trigger(e)
})
}
@@ -104,10 +111,8 @@
this.isShown = false
this.$body.removeClass('modal-open')
this.resetScrollbar()
this.escape()
this.resize()
$(document).off('focusin.bs.modal')
@@ -119,7 +124,7 @@
$.support.transition && this.$element.hasClass('fade') ?
this.$element
.one('bsTransitionEnd', $.proxy(this.hideModal, this))
.emulateTransitionEnd(300) :
.emulateTransitionEnd(Modal.TRANSITION_DURATION) :
this.hideModal()
}
@@ -135,11 +140,19 @@
Modal.prototype.escape = function () {
if (this.isShown && this.options.keyboard) {
this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {
this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
e.which == 27 && this.hide()
}, this))
} else if (!this.isShown) {
this.$element.off('keyup.dismiss.bs.modal')
this.$element.off('keydown.dismiss.bs.modal')
}
}
Modal.prototype.resize = function () {
if (this.isShown) {
$(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
} else {
$(window).off('resize.bs.modal')
}
}
@@ -147,6 +160,9 @@
var that = this
this.$element.hide()
this.backdrop(function () {
that.$body.removeClass('modal-open')
that.resetAdjustments()
that.resetScrollbar()
that.$element.trigger('hidden.bs.modal')
})
}
@@ -164,14 +180,13 @@
var doAnimate = $.support.transition && animate
this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
.appendTo(this.$body)
this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
if (e.target !== e.currentTarget) return
this.options.backdrop == 'static'
? this.$element[0].focus.call(this.$element[0])
: this.hide.call(this)
}, this))
.prependTo(this.$element)
.on('click.dismiss.bs.modal', $.proxy(function (e) {
if (e.target !== e.currentTarget) return
this.options.backdrop == 'static'
? this.$element[0].focus.call(this.$element[0])
: this.hide.call(this)
}, this))
if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
@@ -182,7 +197,7 @@
doAnimate ?
this.$backdrop
.one('bsTransitionEnd', callback)
.emulateTransitionEnd(150) :
.emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
callback()
} else if (!this.isShown && this.$backdrop) {
@@ -195,7 +210,7 @@
$.support.transition && this.$element.hasClass('fade') ?
this.$backdrop
.one('bsTransitionEnd', callbackRemove)
.emulateTransitionEnd(150) :
.emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
callbackRemove()
} else if (callback) {
@@ -203,14 +218,43 @@
}
}
// these following methods are used to handle overflowing modals
Modal.prototype.handleUpdate = function () {
if (this.options.backdrop) this.adjustBackdrop()
this.adjustDialog()
}
Modal.prototype.adjustBackdrop = function () {
this.$backdrop
.css('height', 0)
.css('height', this.$element[0].scrollHeight)
}
Modal.prototype.adjustDialog = function () {
var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
this.$element.css({
paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
})
}
Modal.prototype.resetAdjustments = function () {
this.$element.css({
paddingLeft: '',
paddingRight: ''
})
}
Modal.prototype.checkScrollbar = function () {
if (document.body.clientWidth >= window.innerWidth) return
this.scrollbarWidth = this.scrollbarWidth || this.measureScrollbar()
this.bodyIsOverflowing = document.body.scrollHeight > document.documentElement.clientHeight
this.scrollbarWidth = this.measureScrollbar()
}
Modal.prototype.setScrollbar = function () {
var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
if (this.scrollbarWidth) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
}
Modal.prototype.resetScrollbar = function () {
+13 -7
View File
@@ -1,5 +1,5 @@
/* ========================================================================
* Bootstrap: popover.js v3.2.0
* Bootstrap: popover.js v3.3.1
* http://getbootstrap.com/javascript/#popovers
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -19,7 +19,7 @@
if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
Popover.VERSION = '3.2.0'
Popover.VERSION = '3.3.1'
Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
placement: 'right',
@@ -46,7 +46,7 @@
var content = this.getContent()
$tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
$tip.find('.popover-content').empty()[ // we use append for html objects to maintain js events
$tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
](content)
@@ -86,12 +86,18 @@
function Plugin(option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.popover')
var options = typeof option == 'object' && option
var $this = $(this)
var data = $this.data('bs.popover')
var options = typeof option == 'object' && option
var selector = options && options.selector
if (!data && option == 'destroy') return
if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
if (selector) {
if (!data) $this.data('bs.popover', (data = {}))
if (!data[selector]) data[selector] = new Popover(this, options)
} else {
if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
}
if (typeof option == 'string') data[option]()
})
}
+12 -7
View File
@@ -1,5 +1,5 @@
/* ========================================================================
* Bootstrap: scrollspy.js v3.2.0
* Bootstrap: scrollspy.js v3.3.1
* http://getbootstrap.com/javascript/#scrollspy
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -30,7 +30,7 @@
this.process()
}
ScrollSpy.VERSION = '3.2.0'
ScrollSpy.VERSION = '3.3.1'
ScrollSpy.DEFAULTS = {
offset: 10
@@ -91,8 +91,9 @@
return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
}
if (activeTarget && scrollTop <= offsets[0]) {
return activeTarget != (i = targets[0]) && this.activate(i)
if (activeTarget && scrollTop < offsets[0]) {
this.activeTarget = null
return this.clear()
}
for (i = offsets.length; i--;) {
@@ -106,9 +107,7 @@
ScrollSpy.prototype.activate = function (target) {
this.activeTarget = target
$(this.selector)
.parentsUntil(this.options.target, '.active')
.removeClass('active')
this.clear()
var selector = this.selector +
'[data-target="' + target + '"],' +
@@ -127,6 +126,12 @@
active.trigger('activate.bs.scrollspy')
}
ScrollSpy.prototype.clear = function () {
$(this.selector)
.parentsUntil(this.options.target, '.active')
.removeClass('active')
}
// SCROLLSPY PLUGIN DEFINITION
// ===========================
+41 -16
View File
@@ -1,5 +1,5 @@
/* ========================================================================
* Bootstrap: tab.js v3.2.0
* Bootstrap: tab.js v3.3.1
* http://getbootstrap.com/javascript/#tabs
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
@@ -17,7 +17,9 @@
this.element = $(element)
}
Tab.VERSION = '3.2.0'
Tab.VERSION = '3.3.1'
Tab.TRANSITION_DURATION = 150
Tab.prototype.show = function () {
var $this = this.element
@@ -31,22 +33,30 @@
if ($this.parent('li').hasClass('active')) return
var previous = $ul.find('.active:last a')[0]
var e = $.Event('show.bs.tab', {
relatedTarget: previous
var $previous = $ul.find('.active:last a')
var hideEvent = $.Event('hide.bs.tab', {
relatedTarget: $this[0]
})
var showEvent = $.Event('show.bs.tab', {
relatedTarget: $previous[0]
})
$this.trigger(e)
$previous.trigger(hideEvent)
$this.trigger(showEvent)
if (e.isDefaultPrevented()) return
if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
var $target = $(selector)
this.activate($this.closest('li'), $ul)
this.activate($target, $target.parent(), function () {
$previous.trigger({
type: 'hidden.bs.tab',
relatedTarget: $this[0]
})
$this.trigger({
type: 'shown.bs.tab',
relatedTarget: previous
relatedTarget: $previous[0]
})
})
}
@@ -55,15 +65,21 @@
var $active = container.find('> .active')
var transition = callback
&& $.support.transition
&& $active.hasClass('fade')
&& (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length)
function next() {
$active
.removeClass('active')
.find('> .dropdown-menu > .active')
.removeClass('active')
.removeClass('active')
.end()
.find('[data-toggle="tab"]')
.attr('aria-expanded', false)
element.addClass('active')
element
.addClass('active')
.find('[data-toggle="tab"]')
.attr('aria-expanded', true)
if (transition) {
element[0].offsetWidth // reflow for transition
@@ -73,16 +89,21 @@
}
if (element.parent('.dropdown-menu')) {
element.closest('li.dropdown').addClass('active')
element
.closest('li.dropdown')
.addClass('active')
.end()
.find('[data-toggle="tab"]')
.attr('aria-expanded', true)
}
callback && callback()
}
transition ?
$active.length && transition ?
$active
.one('bsTransitionEnd', next)
.emulateTransitionEnd(150) :
.emulateTransitionEnd(Tab.TRANSITION_DURATION) :
next()
$active.removeClass('in')
@@ -120,9 +141,13 @@
// TAB DATA-API
// ============
$(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
var clickHandler = function (e) {
e.preventDefault()
Plugin.call($(this), 'show')
})
}
$(document)
.on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
.on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
}(jQuery);
+60 -39
View File
@@ -1,5 +1,5 @@
/* ========================================================================
* Bootstrap: tooltip.js v3.2.0
* Bootstrap: tooltip.js v3.3.1
* http://getbootstrap.com/javascript/#tooltip
* Inspired by the original jQuery.tipsy by Jason Frame
* ========================================================================
@@ -25,7 +25,9 @@
this.init('tooltip', element, options)
}
Tooltip.VERSION = '3.2.0'
Tooltip.VERSION = '3.3.1'
Tooltip.TRANSITION_DURATION = 150
Tooltip.DEFAULTS = {
animation: true,
@@ -103,6 +105,11 @@
var self = obj instanceof this.constructor ?
obj : $(obj.currentTarget).data('bs.' + this.type)
if (self && self.$tip && self.$tip.is(':visible')) {
self.hoverState = 'in'
return
}
if (!self) {
self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
$(obj.currentTarget).data('bs.' + this.type, self)
@@ -145,7 +152,7 @@
if (this.hasContent() && this.enabled) {
this.$element.trigger(e)
var inDom = $.contains(document.documentElement, this.$element[0])
var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
if (e.isDefaultPrevented() || !inDom) return
var that = this
@@ -181,13 +188,13 @@
if (autoPlace) {
var orgPlacement = placement
var $parent = this.$element.parent()
var parentDim = this.getPosition($parent)
var $container = this.options.container ? $(this.options.container) : this.$element.parent()
var containerDim = this.getPosition($container)
placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' :
placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' :
placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' :
placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' :
placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' :
placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' :
placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' :
placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' :
placement
$tip
@@ -200,14 +207,17 @@
this.applyPlacement(calculatedOffset, placement)
var complete = function () {
var prevHoverState = that.hoverState
that.$element.trigger('shown.bs.' + that.type)
that.hoverState = null
if (prevHoverState == 'out') that.leave(that)
}
$.support.transition && this.$tip.hasClass('fade') ?
$tip
.one('bsTransitionEnd', complete)
.emulateTransitionEnd(150) :
.emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
complete()
}
}
@@ -254,16 +264,18 @@
if (delta.left) offset.left += delta.left
else offset.top += delta.top
var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
var arrowPosition = delta.left ? 'left' : 'top'
var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight'
var isVertical = /top|bottom/.test(placement)
var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
$tip.offset(offset)
this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition)
this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
}
Tooltip.prototype.replaceArrow = function (delta, dimension, position) {
this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '')
Tooltip.prototype.replaceArrow = function (delta, dimension, isHorizontal) {
this.arrow()
.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
.css(isHorizontal ? 'top' : 'left', '')
}
Tooltip.prototype.setContent = function () {
@@ -274,16 +286,17 @@
$tip.removeClass('fade in top bottom left right')
}
Tooltip.prototype.hide = function () {
Tooltip.prototype.hide = function (callback) {
var that = this
var $tip = this.tip()
var e = $.Event('hide.bs.' + this.type)
this.$element.removeAttr('aria-describedby')
function complete() {
if (that.hoverState != 'in') $tip.detach()
that.$element.trigger('hidden.bs.' + that.type)
that.$element
.removeAttr('aria-describedby')
.trigger('hidden.bs.' + that.type)
callback && callback()
}
this.$element.trigger(e)
@@ -295,7 +308,7 @@
$.support.transition && this.$tip.hasClass('fade') ?
$tip
.one('bsTransitionEnd', complete)
.emulateTransitionEnd(150) :
.emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
complete()
this.hoverState = null
@@ -316,13 +329,20 @@
Tooltip.prototype.getPosition = function ($element) {
$element = $element || this.$element
var el = $element[0]
var isBody = el.tagName == 'BODY'
return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, {
scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(),
width: isBody ? $(window).width() : $element.outerWidth(),
height: isBody ? $(window).height() : $element.outerHeight()
}, isBody ? { top: 0, left: 0 } : $element.offset())
var elRect = el.getBoundingClientRect()
if (elRect.width == null) {
// width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
}
var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()
var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
return $.extend({}, elRect, scroll, outerDims, elOffset)
}
Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
@@ -386,14 +406,6 @@
return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
}
Tooltip.prototype.validate = function () {
if (!this.$element[0].parentNode) {
this.hide()
this.$element = null
this.options = null
}
}
Tooltip.prototype.enable = function () {
this.enabled = true
}
@@ -420,8 +432,11 @@
}
Tooltip.prototype.destroy = function () {
var that = this
clearTimeout(this.timeout)
this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
this.hide(function () {
that.$element.off('.' + that.type).removeData('bs.' + that.type)
})
}
@@ -430,12 +445,18 @@
function Plugin(option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.tooltip')
var options = typeof option == 'object' && option
var $this = $(this)
var data = $this.data('bs.tooltip')
var options = typeof option == 'object' && option
var selector = options && options.selector
if (!data && option == 'destroy') return
if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
if (selector) {
if (!data) $this.data('bs.tooltip', (data = {}))
if (!data[selector]) data[selector] = new Tooltip(this, options)
} else {
if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
}
if (typeof option == 'string') data[option]()
})
}
+1 -1
View File
@@ -1,5 +1,5 @@
/* ========================================================================
* Bootstrap: transition.js v3.2.0
* Bootstrap: transition.js v3.3.1
* http://getbootstrap.com/javascript/#transitions
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
+304
View File
@@ -0,0 +1,304 @@
{
"always-semicolon": true,
"block-indent": 2,
"color-case": "lower",
"color-shorthand": true,
"element-case": "lower",
"eof-newline": true,
"leading-zero": false,
"remove-empty-rulesets": true,
"space-after-colon": 1,
"space-after-combinator": 1,
"space-before-selector-delimiter": 0,
"space-between-declarations": "\n",
"space-after-opening-brace": "\n",
"space-before-closing-brace": "\n",
"space-before-colon": 0,
"space-before-combinator": 1,
"space-before-opening-brace": 1,
"strip-spaces": true,
"unitless-zero": true,
"vendor-prefix-align": true,
"sort-order": [
[
"position",
"top",
"right",
"bottom",
"left",
"z-index",
"display",
"float",
"width",
"min-width",
"max-width",
"height",
"min-height",
"max-height",
"-webkit-box-sizing",
"-moz-box-sizing",
"box-sizing",
"-webkit-appearance",
"padding",
"padding-top",
"padding-right",
"padding-bottom",
"padding-left",
"margin",
"margin-top",
"margin-right",
"margin-bottom",
"margin-left",
"overflow",
"overflow-x",
"overflow-y",
"-webkit-overflow-scrolling",
"-ms-overflow-x",
"-ms-overflow-y",
"-ms-overflow-style",
"clip",
"clear",
"font",
"font-family",
"font-size",
"font-style",
"font-weight",
"font-variant",
"font-size-adjust",
"font-stretch",
"font-effect",
"font-emphasize",
"font-emphasize-position",
"font-emphasize-style",
"font-smooth",
"-webkit-hyphens",
"-moz-hyphens",
"hyphens",
"line-height",
"color",
"text-align",
"-webkit-text-align-last",
"-moz-text-align-last",
"-ms-text-align-last",
"text-align-last",
"text-emphasis",
"text-emphasis-color",
"text-emphasis-style",
"text-emphasis-position",
"text-decoration",
"text-indent",
"text-justify",
"text-outline",
"-ms-text-overflow",
"text-overflow",
"text-overflow-ellipsis",
"text-overflow-mode",
"text-shadow",
"text-transform",
"text-wrap",
"-webkit-text-size-adjust",
"-ms-text-size-adjust",
"letter-spacing",
"-ms-word-break",
"word-break",
"word-spacing",
"-ms-word-wrap",
"word-wrap",
"-moz-tab-size",
"-o-tab-size",
"tab-size",
"white-space",
"vertical-align",
"list-style",
"list-style-position",
"list-style-type",
"list-style-image",
"pointer-events",
"-ms-touch-action",
"touch-action",
"cursor",
"visibility",
"zoom",
"flex-direction",
"flex-order",
"flex-pack",
"flex-align",
"table-layout",
"empty-cells",
"caption-side",
"border-spacing",
"border-collapse",
"content",
"quotes",
"counter-reset",
"counter-increment",
"resize",
"-webkit-user-select",
"-moz-user-select",
"-ms-user-select",
"-o-user-select",
"user-select",
"nav-index",
"nav-up",
"nav-right",
"nav-down",
"nav-left",
"background",
"background-color",
"background-image",
"-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
"filter:progid:DXImageTransform.Microsoft.gradient",
"filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
"filter",
"background-repeat",
"background-attachment",
"background-position",
"background-position-x",
"background-position-y",
"-webkit-background-clip",
"-moz-background-clip",
"background-clip",
"background-origin",
"-webkit-background-size",
"-moz-background-size",
"-o-background-size",
"background-size",
"border",
"border-color",
"border-style",
"border-width",
"border-top",
"border-top-color",
"border-top-style",
"border-top-width",
"border-right",
"border-right-color",
"border-right-style",
"border-right-width",
"border-bottom",
"border-bottom-color",
"border-bottom-style",
"border-bottom-width",
"border-left",
"border-left-color",
"border-left-style",
"border-left-width",
"border-radius",
"border-top-left-radius",
"border-top-right-radius",
"border-bottom-right-radius",
"border-bottom-left-radius",
"-webkit-border-image",
"-moz-border-image",
"-o-border-image",
"border-image",
"-webkit-border-image-source",
"-moz-border-image-source",
"-o-border-image-source",
"border-image-source",
"-webkit-border-image-slice",
"-moz-border-image-slice",
"-o-border-image-slice",
"border-image-slice",
"-webkit-border-image-width",
"-moz-border-image-width",
"-o-border-image-width",
"border-image-width",
"-webkit-border-image-outset",
"-moz-border-image-outset",
"-o-border-image-outset",
"border-image-outset",
"-webkit-border-image-repeat",
"-moz-border-image-repeat",
"-o-border-image-repeat",
"border-image-repeat",
"outline",
"outline-width",
"outline-style",
"outline-color",
"outline-offset",
"-webkit-box-shadow",
"-moz-box-shadow",
"box-shadow",
"filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
"-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
"opacity",
"-ms-interpolation-mode",
"-webkit-transition",
"-moz-transition",
"-ms-transition",
"-o-transition",
"transition",
"-webkit-transition-delay",
"-moz-transition-delay",
"-ms-transition-delay",
"-o-transition-delay",
"transition-delay",
"-webkit-transition-timing-function",
"-moz-transition-timing-function",
"-ms-transition-timing-function",
"-o-transition-timing-function",
"transition-timing-function",
"-webkit-transition-duration",
"-moz-transition-duration",
"-ms-transition-duration",
"-o-transition-duration",
"transition-duration",
"-webkit-transition-property",
"-moz-transition-property",
"-ms-transition-property",
"-o-transition-property",
"transition-property",
"-webkit-transform",
"-moz-transform",
"-ms-transform",
"-o-transform",
"transform",
"-webkit-transform-origin",
"-moz-transform-origin",
"-ms-transform-origin",
"-o-transform-origin",
"transform-origin",
"-webkit-animation",
"-moz-animation",
"-ms-animation",
"-o-animation",
"animation",
"-webkit-animation-name",
"-moz-animation-name",
"-ms-animation-name",
"-o-animation-name",
"animation-name",
"-webkit-animation-duration",
"-moz-animation-duration",
"-ms-animation-duration",
"-o-animation-duration",
"animation-duration",
"-webkit-animation-play-state",
"-moz-animation-play-state",
"-ms-animation-play-state",
"-o-animation-play-state",
"animation-play-state",
"-webkit-animation-timing-function",
"-moz-animation-timing-function",
"-ms-animation-timing-function",
"-o-animation-timing-function",
"animation-timing-function",
"-webkit-animation-delay",
"-moz-animation-delay",
"-ms-animation-delay",
"-o-animation-delay",
"animation-delay",
"-webkit-animation-iteration-count",
"-moz-animation-iteration-count",
"-ms-animation-iteration-count",
"-o-animation-iteration-count",
"animation-iteration-count",
"-webkit-animation-direction",
"-moz-animation-direction",
"-ms-animation-direction",
"-o-animation-direction",
"animation-direction"
]
]
}
+19
View File
@@ -0,0 +1,19 @@
{
"adjoining-classes": false,
"box-sizing": false,
"box-model": false,
"compatible-vendor-prefixes": false,
"floats": false,
"font-sizes": false,
"gradients": false,
"important": false,
"known-properties": false,
"outline-none": false,
"qualified-headings": false,
"regex-selectors": false,
"shorthand": false,
"text-indent": false,
"unique-headings": false,
"universal-selector": false,
"unqualified-attributes": false
}
+7 -1
View File
@@ -44,11 +44,17 @@
}
// Account for badges in navs
a.list-group-item.active > &,
.list-group-item.active > &,
.nav-pills > .active > a > & {
color: @badge-active-color;
background-color: @badge-active-bg;
}
.list-group-item > & {
float: right;
}
.list-group-item > & + & {
margin-right: 5px;
}
.nav-pills > li > a > & {
margin-left: 3px;
}
+16 -13
View File
@@ -18,10 +18,6 @@
&.active {
z-index: 2;
}
&:focus {
// Remove focus outline when dropdown JS adds it after closing the menu
outline: 0;
}
}
}
@@ -198,7 +194,6 @@
}
// Justified button groups
// ----------------------
@@ -226,15 +221,23 @@
// Checkbox and radio options
//
// In order to support the browser's form validation feedback, powered by the
// `required` attribute, we have to "hide" the inputs via `opacity`. We cannot
// use `display: none;` or `visibility: hidden;` as that also hides the popover.
// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
// `display: none;` or `visibility: hidden;` as that also hides the popover.
// Simply visually hiding the inputs via `opacity` would leave them clickable in
// certain cases which is prevented by using `clip` and `pointer-events`.
// This way, we ensure a DOM element is visible to position the popover from.
//
// See https://github.com/twbs/bootstrap/pull/12794 for more.
// See https://github.com/twbs/bootstrap/pull/12794 and
// https://github.com/twbs/bootstrap/pull/14559 for more information.
[data-toggle="buttons"] > .btn > input[type="radio"],
[data-toggle="buttons"] > .btn > input[type="checkbox"] {
position: absolute;
z-index: -1;
.opacity(0);
[data-toggle="buttons"] {
> .btn,
> .btn-group > .btn {
input[type="radio"],
input[type="checkbox"] {
position: absolute;
clip: rect(0,0,0,0);
pointer-events: none;
}
}
}
+7 -4
View File
@@ -12,6 +12,7 @@
font-weight: @btn-font-weight;
text-align: center;
vertical-align: middle;
touch-action: manipulation;
cursor: pointer;
background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
border: 1px solid transparent;
@@ -22,13 +23,15 @@
&,
&:active,
&.active {
&:focus {
&:focus,
&.focus {
.tab-focus();
}
}
&:hover,
&:focus {
&:focus,
&.focus {
color: @btn-default-color;
text-decoration: none;
}
@@ -43,7 +46,7 @@
&.disabled,
&[disabled],
fieldset[disabled] & {
cursor: not-allowed;
cursor: @cursor-disabled;
pointer-events: none; // Future-proof disabling of clicks
.opacity(.65);
.box-shadow(none);
@@ -85,11 +88,11 @@
.btn-link {
color: @link-color;
font-weight: normal;
cursor: pointer;
border-radius: 0;
&,
&:active,
&.active,
&[disabled],
fieldset[disabled] & {
background-color: transparent;
+24
View File
@@ -24,6 +24,30 @@
&:extend(.img-responsive);
line-height: 1;
}
// WebKit CSS3 transforms for supported devices
@media all and (transform-3d), (-webkit-transform-3d) {
transition: transform .6s ease-in-out;
backface-visibility: hidden;
perspective: 1000;
&.next,
&.active.right {
transform: translate3d(100%, 0, 0);
left: 0;
}
&.prev,
&.active.left {
transform: translate3d(-100%, 0, 0);
left: 0;
}
&.next.left,
&.prev.right,
&.active {
transform: translate3d(0, 0, 0);
left: 0;
}
}
}
> .active,
+1
View File
@@ -32,6 +32,7 @@ kbd {
kbd {
padding: 0;
font-size: 100%;
font-weight: bold;
box-shadow: none;
}
}
@@ -17,8 +17,9 @@
.collapse {
display: none;
visibility: hidden;
&.in { display: block; }
&.in { display: block; visibility: visible; }
tr&.in { display: table-row; }
tbody&.in { display: table-row-group; }
}
@@ -27,5 +28,7 @@
position: relative;
height: 0;
overflow: hidden;
.transition(height .35s ease);
.transition-property(~"height, visibility");
.transition-duration(.35s);
.transition-timing-function(ease);
}
+3 -5
View File
@@ -103,16 +103,15 @@
&:focus {
color: @dropdown-link-disabled-color;
}
}
// Nuke hover/focus effects
.dropdown-menu > .disabled > a {
// Nuke hover/focus effects
&:hover,
&:focus {
text-decoration: none;
background-color: transparent;
background-image: none; // Remove CSS gradient
.reset-filter();
cursor: not-allowed;
cursor: @cursor-disabled;
}
}
@@ -212,4 +211,3 @@
}
}
}
+45 -39
View File
@@ -141,7 +141,7 @@ output {
&[disabled],
&[readonly],
fieldset[disabled] & {
cursor: not-allowed;
cursor: @cursor-disabled;
background-color: @input-bg-disabled;
opacity: 1; // iOS fix for unreadable disabled content
}
@@ -168,23 +168,27 @@ input[type="search"] {
// Special styles for iOS temporal inputs
//
// In Mobile Safari, setting `display: block` on temporal inputs causes the
// text within the input to become vertically misaligned.
// As a workaround, we set a pixel line-height that matches the
// given height of the input. Since this fucks up everything else, we have to
// appropriately reset it for Internet Explorer and the size variations.
// text within the input to become vertically misaligned. As a workaround, we
// set a pixel line-height that matches the given height of the input, but only
// for Safari.
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
line-height: @input-height-base;
// IE8+ misaligns the text within date inputs, so we reset
line-height: @line-height-base ~"\0";
&.input-sm {
@media screen and (-webkit-min-device-pixel-ratio: 0) {
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
line-height: @input-height-base;
}
input[type="date"].input-sm,
input[type="time"].input-sm,
input[type="datetime-local"].input-sm,
input[type="month"].input-sm {
line-height: @input-height-small;
}
&.input-lg {
input[type="date"].input-lg,
input[type="time"].input-lg,
input[type="datetime-local"].input-lg,
input[type="month"].input-lg {
line-height: @input-height-large;
}
}
@@ -208,11 +212,11 @@ input[type="month"] {
.checkbox {
position: relative;
display: block;
min-height: @line-height-computed; // clear the floating input if there is no label text
margin-top: 10px;
margin-bottom: 10px;
label {
min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text
padding-left: 20px;
margin-bottom: 0;
font-weight: normal;
@@ -258,7 +262,7 @@ input[type="checkbox"] {
&[disabled],
&.disabled,
fieldset[disabled] & {
cursor: not-allowed;
cursor: @cursor-disabled;
}
}
// These classes are used directly on <label>s
@@ -266,7 +270,7 @@ input[type="checkbox"] {
.checkbox-inline {
&.disabled,
fieldset[disabled] & {
cursor: not-allowed;
cursor: @cursor-disabled;
}
}
// These classes are used on elements with <label> descendants
@@ -275,7 +279,7 @@ input[type="checkbox"] {
&.disabled,
fieldset[disabled] & {
label {
cursor: not-allowed;
cursor: @cursor-disabled;
}
}
}
@@ -306,12 +310,14 @@ input[type="checkbox"] {
// Build on `.form-control` with modifier classes to decrease or increase the
// height and font-size of form controls.
.input-sm {
.input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);
.input-sm,
.form-group-sm .form-control {
.input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @input-border-radius-small);
}
.input-lg {
.input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);
.input-lg,
.form-group-lg .form-control {
.input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @input-border-radius-large);
}
@@ -331,7 +337,7 @@ input[type="checkbox"] {
// Feedback icon (requires .glyphicon classes)
.form-control-feedback {
position: absolute;
top: (@line-height-computed + 5); // Height of the `label` and its margin
top: 0;
right: 0;
z-index: 2; // Ensure icon is above input groups
display: block;
@@ -339,6 +345,7 @@ input[type="checkbox"] {
height: @input-height-base;
line-height: @input-height-base;
text-align: center;
pointer-events: none;
}
.input-lg + .form-control-feedback {
width: @input-height-large;
@@ -362,10 +369,15 @@ input[type="checkbox"] {
.form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);
}
// Reposition feedback icon if input has visible label above
.has-feedback label {
// Reposition feedback icon if label is hidden with "screenreader only" state
.has-feedback label.sr-only ~ .form-control-feedback {
top: 0;
& ~ .form-control-feedback {
top: (@line-height-computed + 5); // Height of the `label` and its margin
}
&.sr-only ~ .form-control-feedback {
top: 0;
}
}
@@ -382,7 +394,6 @@ input[type="checkbox"] {
}
// Inline forms
//
// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
@@ -412,6 +423,11 @@ input[type="checkbox"] {
vertical-align: middle;
}
// Make static controls behave like regular ones
.form-control-static {
display: inline-block;
}
.input-group {
display: inline-table;
vertical-align: middle;
@@ -453,10 +469,7 @@ input[type="checkbox"] {
margin-left: 0;
}
// Validation states
//
// Reposition the icon because it's now within a grid column and columns have
// `position: relative;` on them. Also accounts for the grid gutter padding.
// Re-override the feedback icon.
.has-feedback .form-control-feedback {
top: 0;
}
@@ -509,7 +522,6 @@ input[type="checkbox"] {
// Reposition the icon because it's now within a grid column and columns have
// `position: relative;` on them. Also accounts for the grid gutter padding.
.has-feedback .form-control-feedback {
top: 0;
right: (@grid-gutter-width / 2);
}
@@ -523,9 +535,6 @@ input[type="checkbox"] {
padding-top: ((@padding-large-vertical * @line-height-large) + 1);
}
}
.form-control {
&:extend(.input-lg);
}
}
.form-group-sm {
@media (min-width: @screen-sm-min) {
@@ -533,8 +542,5 @@ input[type="checkbox"] {
padding-top: (@padding-small-vertical + 1);
}
}
.form-control {
&:extend(.input-sm);
}
}
}

Some files were not shown because too many files have changed in this diff Show More