mirror of
https://github.com/Hopiu/bootstrap.git
synced 2026-04-10 07:50:57 +00:00
Merge branch 'v4-dev' into rip-custom
This commit is contained in:
commit
5818374fdf
49 changed files with 1523 additions and 1120 deletions
|
|
@ -114,7 +114,7 @@ linters:
|
|||
|
||||
NestingDepth:
|
||||
enabled: true
|
||||
max_depth: 4
|
||||
max_depth: 5
|
||||
ignore_parent_selectors: false
|
||||
|
||||
PlaceholderInExtend:
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ module.exports = function (grunt) {
|
|||
concurrency: 10,
|
||||
maxRetries: 3,
|
||||
maxPollRetries: 4,
|
||||
urls: ['http://127.0.0.1:3000/js/tests/index.html?hidepassed'],
|
||||
urls: ['http://localhost:3000/js/tests/index.html?hidepassed'],
|
||||
browsers: grunt.file.readYAML('build/sauce_browsers.yml')
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,5 +53,5 @@ cdn:
|
|||
js_hash: "sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn"
|
||||
jquery: https://code.jquery.com/jquery-3.2.1.slim.min.js
|
||||
jquery_hash: "sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
|
||||
popper: https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js
|
||||
popper_hash: "sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc="
|
||||
popper: https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.10.1/umd/popper.min.js
|
||||
popper_hash: "sha256-nxD3NU7Wocq19nG7DTQAx9troUwVoxjUhYrAhFSO3HM="
|
||||
|
|
|
|||
2
assets/css/docs.min.css
vendored
2
assets/css/docs.min.css
vendored
File diff suppressed because one or more lines are too long
Binary file not shown.
2
assets/js/vendor/popper.min.js
vendored
2
assets/js/vendor/popper.min.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -1,7 +1,7 @@
|
|||
// scss-lint:disable VendorPrefix
|
||||
|
||||
//
|
||||
// Side navigation
|
||||
// Right side table of contents
|
||||
//
|
||||
|
||||
.bd-toc {
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
a {
|
||||
display: block;
|
||||
padding: .25rem 1.5rem;
|
||||
padding: .125rem 1.5rem;
|
||||
color: #99979c;
|
||||
|
||||
&:hover {
|
||||
|
|
@ -44,6 +44,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Left side navigation
|
||||
//
|
||||
|
||||
.bd-sidebar {
|
||||
background-color: #f5f2f9;
|
||||
border-bottom: 1px solid rgba(0,0,0,.1);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,6 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"jquery": ">=1.9.1",
|
||||
"popper.js": "^1.9.9"
|
||||
"popper.js": "^1.10.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
6
build/npm-shrinkwrap.json
generated
6
build/npm-shrinkwrap.json
generated
|
|
@ -3390,9 +3390,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"popper.js": {
|
||||
"version": "1.9.9",
|
||||
"from": "popper.js@>=1.9.9 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.9.9.tgz"
|
||||
"version": "1.10.1",
|
||||
"from": "popper.js@>=1.10.1 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.10.1.tgz"
|
||||
},
|
||||
"postcss": {
|
||||
"version": "5.2.17",
|
||||
|
|
|
|||
BIN
dist/css/bootstrap-grid.css.map
vendored
BIN
dist/css/bootstrap-grid.css.map
vendored
Binary file not shown.
BIN
dist/css/bootstrap-reboot.css.map
vendored
BIN
dist/css/bootstrap-reboot.css.map
vendored
Binary file not shown.
|
|
@ -2156,7 +2156,7 @@ pre code {
|
|||
.form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.5rem 1rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
font-size: 1rem;
|
||||
line-height: 1.25;
|
||||
color: #464a4c;
|
||||
|
|
@ -2249,7 +2249,7 @@ select.form-control:focus::-ms-value {
|
|||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.form-control-static {
|
||||
.form-control-plaintext {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
margin-bottom: 0;
|
||||
|
|
@ -2258,11 +2258,11 @@ select.form-control:focus::-ms-value {
|
|||
border-width: 1px 0;
|
||||
}
|
||||
|
||||
.form-control-static.form-control-sm, .input-group-sm > .form-control-static.form-control,
|
||||
.input-group-sm > .form-control-static.input-group-addon,
|
||||
.input-group-sm > .input-group-btn > .form-control-static.btn, .form-control-static.form-control-lg, .input-group-lg > .form-control-static.form-control,
|
||||
.input-group-lg > .form-control-static.input-group-addon,
|
||||
.input-group-lg > .input-group-btn > .form-control-static.btn {
|
||||
.form-control-plaintext.form-control-sm, .input-group-sm > .form-control-plaintext.form-control,
|
||||
.input-group-sm > .form-control-plaintext.input-group-addon,
|
||||
.input-group-sm > .input-group-btn > .form-control-plaintext.btn, .form-control-plaintext.form-control-lg, .input-group-lg > .form-control-plaintext.form-control,
|
||||
.input-group-lg > .form-control-plaintext.input-group-addon,
|
||||
.input-group-lg > .input-group-btn > .form-control-plaintext.btn {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
|
@ -2294,7 +2294,7 @@ select.form-control-sm:not([size]):not([multiple]), .input-group-sm > select.for
|
|||
select.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.form-control:not([size]):not([multiple]),
|
||||
.input-group-lg > select.input-group-addon:not([size]):not([multiple]),
|
||||
.input-group-lg > .input-group-btn > select.btn:not([size]):not([multiple]) {
|
||||
height: calc(2.875rem + 2px);
|
||||
height: calc(2.3125rem + 2px);
|
||||
}
|
||||
|
||||
.form-group {
|
||||
|
|
@ -2306,6 +2306,24 @@ select.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.for
|
|||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
.form-row {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-wrap: wrap;
|
||||
-ms-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
margin-right: -5px;
|
||||
margin-left: -5px;
|
||||
}
|
||||
|
||||
.form-row > .col,
|
||||
.form-row > [class*="col-"] {
|
||||
padding-right: 5px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.form-check {
|
||||
position: relative;
|
||||
display: block;
|
||||
|
|
@ -2343,90 +2361,124 @@ select.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.for
|
|||
margin-left: 0.75rem;
|
||||
}
|
||||
|
||||
.form-control-feedback {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
.form-control-success,
|
||||
.form-control-warning,
|
||||
.form-control-danger {
|
||||
padding-right: 3rem;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center right 0.5625rem;
|
||||
-webkit-background-size: 1.125rem 1.125rem;
|
||||
background-size: 1.125rem 1.125rem;
|
||||
}
|
||||
|
||||
.has-success .form-control-feedback,
|
||||
.has-success .form-control-label,
|
||||
.has-success .col-form-label,
|
||||
.has-success .form-check-label,
|
||||
.has-success .custom-control {
|
||||
color: #5cb85c;
|
||||
}
|
||||
|
||||
.has-success .form-control,
|
||||
.has-success .custom-select,
|
||||
.has-success .custom-file-control {
|
||||
border-color: #5cb85c;
|
||||
}
|
||||
|
||||
.has-success .input-group-addon {
|
||||
color: #5cb85c;
|
||||
background-color: #eaf6ea;
|
||||
border-color: #5cb85c;
|
||||
}
|
||||
|
||||
.has-success .form-control-success {
|
||||
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%235cb85c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.has-warning .form-control-feedback,
|
||||
.has-warning .form-control-label,
|
||||
.has-warning .col-form-label,
|
||||
.has-warning .form-check-label,
|
||||
.has-warning .custom-control {
|
||||
color: #f0ad4e;
|
||||
}
|
||||
|
||||
.has-warning .form-control,
|
||||
.has-warning .custom-select,
|
||||
.has-warning .custom-file-control {
|
||||
border-color: #f0ad4e;
|
||||
}
|
||||
|
||||
.has-warning .input-group-addon {
|
||||
color: #f0ad4e;
|
||||
background-color: white;
|
||||
border-color: #f0ad4e;
|
||||
}
|
||||
|
||||
.has-warning .form-control-warning {
|
||||
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23f0ad4e' d='M4.4 5.324h-.8v-2.46h.8zm0 1.42h-.8V5.89h.8zM3.76.63L.04 7.075c-.115.2.016.425.26.426h7.397c.242 0 .372-.226.258-.426C6.726 4.924 5.47 2.79 4.253.63c-.113-.174-.39-.174-.494 0z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.has-danger .form-control-feedback,
|
||||
.has-danger .form-control-label,
|
||||
.has-danger .col-form-label,
|
||||
.has-danger .form-check-label,
|
||||
.has-danger .custom-control {
|
||||
.invalid-feedback {
|
||||
display: none;
|
||||
margin-top: .25rem;
|
||||
font-size: .875rem;
|
||||
color: #d9534f;
|
||||
}
|
||||
|
||||
.has-danger .form-control,
|
||||
.has-danger .custom-select,
|
||||
.has-danger .custom-file-control {
|
||||
.invalid-tooltip {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
z-index: 5;
|
||||
display: none;
|
||||
width: 250px;
|
||||
padding: .5rem;
|
||||
margin-top: .1rem;
|
||||
font-size: .875rem;
|
||||
line-height: 1;
|
||||
color: #fff;
|
||||
background-color: rgba(217, 83, 79, 0.8);
|
||||
border-radius: .2rem;
|
||||
}
|
||||
|
||||
.was-validated .form-control:valid, .form-control.is-valid, .was-validated
|
||||
.custom-select:valid,
|
||||
.custom-select.is-valid {
|
||||
border-color: #5cb85c;
|
||||
}
|
||||
|
||||
.was-validated .form-control:valid:focus, .form-control.is-valid:focus, .was-validated
|
||||
.custom-select:valid:focus,
|
||||
.custom-select.is-valid:focus {
|
||||
-webkit-box-shadow: 0 0 0 0.2rem rgba(92, 184, 92, 0.25);
|
||||
box-shadow: 0 0 0 0.2rem rgba(92, 184, 92, 0.25);
|
||||
}
|
||||
|
||||
.was-validated .form-control:valid ~ .invalid-feedback,
|
||||
.was-validated .form-control:valid ~ .invalid-tooltip, .form-control.is-valid ~ .invalid-feedback,
|
||||
.form-control.is-valid ~ .invalid-tooltip, .was-validated
|
||||
.custom-select:valid ~ .invalid-feedback,
|
||||
.was-validated
|
||||
.custom-select:valid ~ .invalid-tooltip,
|
||||
.custom-select.is-valid ~ .invalid-feedback,
|
||||
.custom-select.is-valid ~ .invalid-tooltip {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.was-validated .form-check-input:valid + .form-check-label, .form-check-input.is-valid + .form-check-label {
|
||||
color: #5cb85c;
|
||||
}
|
||||
|
||||
.was-validated .custom-control-input:valid ~ .custom-control-indicator, .custom-control-input.is-valid ~ .custom-control-indicator {
|
||||
background-color: rgba(92, 184, 92, 0.25);
|
||||
}
|
||||
|
||||
.was-validated .custom-control-input:valid ~ .custom-control-description, .custom-control-input.is-valid ~ .custom-control-description {
|
||||
color: #5cb85c;
|
||||
}
|
||||
|
||||
.was-validated .custom-file-input:valid ~ .custom-file-control, .custom-file-input.is-valid ~ .custom-file-control {
|
||||
border-color: #5cb85c;
|
||||
}
|
||||
|
||||
.was-validated .custom-file-input:valid ~ .custom-file-control::before, .custom-file-input.is-valid ~ .custom-file-control::before {
|
||||
border-color: inherit;
|
||||
}
|
||||
|
||||
.was-validated .custom-file-input:valid:focus, .custom-file-input.is-valid:focus {
|
||||
-webkit-box-shadow: 0 0 0 0.2rem rgba(92, 184, 92, 0.25);
|
||||
box-shadow: 0 0 0 0.2rem rgba(92, 184, 92, 0.25);
|
||||
}
|
||||
|
||||
.was-validated .form-control:invalid, .form-control.is-invalid, .was-validated
|
||||
.custom-select:invalid,
|
||||
.custom-select.is-invalid {
|
||||
border-color: #d9534f;
|
||||
}
|
||||
|
||||
.has-danger .input-group-addon {
|
||||
.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus, .was-validated
|
||||
.custom-select:invalid:focus,
|
||||
.custom-select.is-invalid:focus {
|
||||
-webkit-box-shadow: 0 0 0 0.2rem rgba(217, 83, 79, 0.25);
|
||||
box-shadow: 0 0 0 0.2rem rgba(217, 83, 79, 0.25);
|
||||
}
|
||||
|
||||
.was-validated .form-control:invalid ~ .invalid-feedback,
|
||||
.was-validated .form-control:invalid ~ .invalid-tooltip, .form-control.is-invalid ~ .invalid-feedback,
|
||||
.form-control.is-invalid ~ .invalid-tooltip, .was-validated
|
||||
.custom-select:invalid ~ .invalid-feedback,
|
||||
.was-validated
|
||||
.custom-select:invalid ~ .invalid-tooltip,
|
||||
.custom-select.is-invalid ~ .invalid-feedback,
|
||||
.custom-select.is-invalid ~ .invalid-tooltip {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.was-validated .form-check-input:invalid + .form-check-label, .form-check-input.is-invalid + .form-check-label {
|
||||
color: #d9534f;
|
||||
background-color: #fdf7f7;
|
||||
}
|
||||
|
||||
.was-validated .custom-control-input:invalid ~ .custom-control-indicator, .custom-control-input.is-invalid ~ .custom-control-indicator {
|
||||
background-color: rgba(217, 83, 79, 0.25);
|
||||
}
|
||||
|
||||
.was-validated .custom-control-input:invalid ~ .custom-control-description, .custom-control-input.is-invalid ~ .custom-control-description {
|
||||
color: #d9534f;
|
||||
}
|
||||
|
||||
.was-validated .custom-file-input:invalid ~ .custom-file-control, .custom-file-input.is-invalid ~ .custom-file-control {
|
||||
border-color: #d9534f;
|
||||
}
|
||||
|
||||
.has-danger .form-control-danger {
|
||||
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23d9534f' viewBox='-2 -2 7 7'%3E%3Cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3E%3Ccircle r='.5'/%3E%3Ccircle cx='3' r='.5'/%3E%3Ccircle cy='3' r='.5'/%3E%3Ccircle cx='3' cy='3' r='.5'/%3E%3C/svg%3E");
|
||||
.was-validated .custom-file-input:invalid ~ .custom-file-control::before, .custom-file-input.is-invalid ~ .custom-file-control::before {
|
||||
border-color: inherit;
|
||||
}
|
||||
|
||||
.was-validated .custom-file-input:invalid:focus, .custom-file-input.is-invalid:focus {
|
||||
-webkit-box-shadow: 0 0 0 0.2rem rgba(217, 83, 79, 0.25);
|
||||
box-shadow: 0 0 0 0.2rem rgba(217, 83, 79, 0.25);
|
||||
}
|
||||
|
||||
.form-inline {
|
||||
|
|
@ -2563,7 +2615,7 @@ select.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.for
|
|||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.5rem 1rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
font-size: 1rem;
|
||||
line-height: 1.25;
|
||||
border-radius: 0.25rem;
|
||||
|
|
@ -2578,8 +2630,8 @@ select.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.for
|
|||
|
||||
.btn:focus, .btn.focus {
|
||||
outline: 0;
|
||||
-webkit-box-shadow: 0 0 0 2px rgba(2, 117, 216, 0.25);
|
||||
box-shadow: 0 0 0 2px rgba(2, 117, 216, 0.25);
|
||||
-webkit-box-shadow: 0 0 0 3px rgba(2, 117, 216, 0.25);
|
||||
box-shadow: 0 0 0 3px rgba(2, 117, 216, 0.25);
|
||||
}
|
||||
|
||||
.btn.disabled, .btn:disabled {
|
||||
|
|
@ -2608,8 +2660,8 @@ fieldset[disabled] a.btn {
|
|||
}
|
||||
|
||||
.btn-primary:focus, .btn-primary.focus {
|
||||
-webkit-box-shadow: 0 0 0 2px rgba(2, 117, 216, 0.5);
|
||||
box-shadow: 0 0 0 2px rgba(2, 117, 216, 0.5);
|
||||
-webkit-box-shadow: 0 0 0 3px rgba(2, 117, 216, 0.5);
|
||||
box-shadow: 0 0 0 3px rgba(2, 117, 216, 0.5);
|
||||
}
|
||||
|
||||
.btn-primary.disabled, .btn-primary:disabled {
|
||||
|
|
@ -2638,8 +2690,8 @@ fieldset[disabled] a.btn {
|
|||
}
|
||||
|
||||
.btn-secondary:focus, .btn-secondary.focus {
|
||||
-webkit-box-shadow: 0 0 0 2px rgba(204, 204, 204, 0.5);
|
||||
box-shadow: 0 0 0 2px rgba(204, 204, 204, 0.5);
|
||||
-webkit-box-shadow: 0 0 0 3px rgba(204, 204, 204, 0.5);
|
||||
box-shadow: 0 0 0 3px rgba(204, 204, 204, 0.5);
|
||||
}
|
||||
|
||||
.btn-secondary.disabled, .btn-secondary:disabled {
|
||||
|
|
@ -2668,8 +2720,8 @@ fieldset[disabled] a.btn {
|
|||
}
|
||||
|
||||
.btn-info:focus, .btn-info.focus {
|
||||
-webkit-box-shadow: 0 0 0 2px rgba(91, 192, 222, 0.5);
|
||||
box-shadow: 0 0 0 2px rgba(91, 192, 222, 0.5);
|
||||
-webkit-box-shadow: 0 0 0 3px rgba(91, 192, 222, 0.5);
|
||||
box-shadow: 0 0 0 3px rgba(91, 192, 222, 0.5);
|
||||
}
|
||||
|
||||
.btn-info.disabled, .btn-info:disabled {
|
||||
|
|
@ -2698,8 +2750,8 @@ fieldset[disabled] a.btn {
|
|||
}
|
||||
|
||||
.btn-success:focus, .btn-success.focus {
|
||||
-webkit-box-shadow: 0 0 0 2px rgba(92, 184, 92, 0.5);
|
||||
box-shadow: 0 0 0 2px rgba(92, 184, 92, 0.5);
|
||||
-webkit-box-shadow: 0 0 0 3px rgba(92, 184, 92, 0.5);
|
||||
box-shadow: 0 0 0 3px rgba(92, 184, 92, 0.5);
|
||||
}
|
||||
|
||||
.btn-success.disabled, .btn-success:disabled {
|
||||
|
|
@ -2728,8 +2780,8 @@ fieldset[disabled] a.btn {
|
|||
}
|
||||
|
||||
.btn-warning:focus, .btn-warning.focus {
|
||||
-webkit-box-shadow: 0 0 0 2px rgba(240, 173, 78, 0.5);
|
||||
box-shadow: 0 0 0 2px rgba(240, 173, 78, 0.5);
|
||||
-webkit-box-shadow: 0 0 0 3px rgba(240, 173, 78, 0.5);
|
||||
box-shadow: 0 0 0 3px rgba(240, 173, 78, 0.5);
|
||||
}
|
||||
|
||||
.btn-warning.disabled, .btn-warning:disabled {
|
||||
|
|
@ -2758,8 +2810,8 @@ fieldset[disabled] a.btn {
|
|||
}
|
||||
|
||||
.btn-danger:focus, .btn-danger.focus {
|
||||
-webkit-box-shadow: 0 0 0 2px rgba(217, 83, 79, 0.5);
|
||||
box-shadow: 0 0 0 2px rgba(217, 83, 79, 0.5);
|
||||
-webkit-box-shadow: 0 0 0 3px rgba(217, 83, 79, 0.5);
|
||||
box-shadow: 0 0 0 3px rgba(217, 83, 79, 0.5);
|
||||
}
|
||||
|
||||
.btn-danger.disabled, .btn-danger:disabled {
|
||||
|
|
@ -2789,8 +2841,8 @@ fieldset[disabled] a.btn {
|
|||
}
|
||||
|
||||
.btn-outline-primary:focus, .btn-outline-primary.focus {
|
||||
-webkit-box-shadow: 0 0 0 2px rgba(2, 117, 216, 0.5);
|
||||
box-shadow: 0 0 0 2px rgba(2, 117, 216, 0.5);
|
||||
-webkit-box-shadow: 0 0 0 3px rgba(2, 117, 216, 0.5);
|
||||
box-shadow: 0 0 0 3px rgba(2, 117, 216, 0.5);
|
||||
}
|
||||
|
||||
.btn-outline-primary.disabled, .btn-outline-primary:disabled {
|
||||
|
|
@ -2819,8 +2871,8 @@ fieldset[disabled] a.btn {
|
|||
}
|
||||
|
||||
.btn-outline-secondary:focus, .btn-outline-secondary.focus {
|
||||
-webkit-box-shadow: 0 0 0 2px rgba(204, 204, 204, 0.5);
|
||||
box-shadow: 0 0 0 2px rgba(204, 204, 204, 0.5);
|
||||
-webkit-box-shadow: 0 0 0 3px rgba(204, 204, 204, 0.5);
|
||||
box-shadow: 0 0 0 3px rgba(204, 204, 204, 0.5);
|
||||
}
|
||||
|
||||
.btn-outline-secondary.disabled, .btn-outline-secondary:disabled {
|
||||
|
|
@ -2849,8 +2901,8 @@ fieldset[disabled] a.btn {
|
|||
}
|
||||
|
||||
.btn-outline-info:focus, .btn-outline-info.focus {
|
||||
-webkit-box-shadow: 0 0 0 2px rgba(91, 192, 222, 0.5);
|
||||
box-shadow: 0 0 0 2px rgba(91, 192, 222, 0.5);
|
||||
-webkit-box-shadow: 0 0 0 3px rgba(91, 192, 222, 0.5);
|
||||
box-shadow: 0 0 0 3px rgba(91, 192, 222, 0.5);
|
||||
}
|
||||
|
||||
.btn-outline-info.disabled, .btn-outline-info:disabled {
|
||||
|
|
@ -2879,8 +2931,8 @@ fieldset[disabled] a.btn {
|
|||
}
|
||||
|
||||
.btn-outline-success:focus, .btn-outline-success.focus {
|
||||
-webkit-box-shadow: 0 0 0 2px rgba(92, 184, 92, 0.5);
|
||||
box-shadow: 0 0 0 2px rgba(92, 184, 92, 0.5);
|
||||
-webkit-box-shadow: 0 0 0 3px rgba(92, 184, 92, 0.5);
|
||||
box-shadow: 0 0 0 3px rgba(92, 184, 92, 0.5);
|
||||
}
|
||||
|
||||
.btn-outline-success.disabled, .btn-outline-success:disabled {
|
||||
|
|
@ -2909,8 +2961,8 @@ fieldset[disabled] a.btn {
|
|||
}
|
||||
|
||||
.btn-outline-warning:focus, .btn-outline-warning.focus {
|
||||
-webkit-box-shadow: 0 0 0 2px rgba(240, 173, 78, 0.5);
|
||||
box-shadow: 0 0 0 2px rgba(240, 173, 78, 0.5);
|
||||
-webkit-box-shadow: 0 0 0 3px rgba(240, 173, 78, 0.5);
|
||||
box-shadow: 0 0 0 3px rgba(240, 173, 78, 0.5);
|
||||
}
|
||||
|
||||
.btn-outline-warning.disabled, .btn-outline-warning:disabled {
|
||||
|
|
@ -2939,8 +2991,8 @@ fieldset[disabled] a.btn {
|
|||
}
|
||||
|
||||
.btn-outline-danger:focus, .btn-outline-danger.focus {
|
||||
-webkit-box-shadow: 0 0 0 2px rgba(217, 83, 79, 0.5);
|
||||
box-shadow: 0 0 0 2px rgba(217, 83, 79, 0.5);
|
||||
-webkit-box-shadow: 0 0 0 3px rgba(217, 83, 79, 0.5);
|
||||
box-shadow: 0 0 0 3px rgba(217, 83, 79, 0.5);
|
||||
}
|
||||
|
||||
.btn-outline-danger.disabled, .btn-outline-danger:disabled {
|
||||
|
|
@ -3253,8 +3305,8 @@ tbody.collapse.show {
|
|||
}
|
||||
|
||||
.btn + .dropdown-toggle-split {
|
||||
padding-right: 0.75rem;
|
||||
padding-left: 0.75rem;
|
||||
padding-right: 0.5625rem;
|
||||
padding-left: 0.5625rem;
|
||||
}
|
||||
|
||||
.btn + .dropdown-toggle-split::after {
|
||||
|
|
@ -3392,7 +3444,7 @@ tbody.collapse.show {
|
|||
}
|
||||
|
||||
.input-group-addon {
|
||||
padding: 0.5rem 1rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
margin-bottom: 0;
|
||||
font-size: 1rem;
|
||||
font-weight: normal;
|
||||
|
|
@ -3629,6 +3681,7 @@ tbody.collapse.show {
|
|||
}
|
||||
|
||||
.custom-select-sm {
|
||||
height: calc(1.8125rem + 2px);
|
||||
padding-top: 0.375rem;
|
||||
padding-bottom: 0.375rem;
|
||||
font-size: 75%;
|
||||
|
|
@ -4288,6 +4341,8 @@ tbody.collapse.show {
|
|||
-webkit-flex-direction: column;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
word-wrap: break-word;
|
||||
background-color: #fff;
|
||||
border: 1px solid rgba(0, 0, 0, 0.125);
|
||||
border-radius: 0.25rem;
|
||||
|
|
@ -4303,7 +4358,6 @@ tbody.collapse.show {
|
|||
|
||||
.card-title {
|
||||
margin-bottom: 0.75rem;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.card-subtitle {
|
||||
|
|
|
|||
BIN
dist/css/bootstrap.css.map
vendored
BIN
dist/css/bootstrap.css.map
vendored
Binary file not shown.
2
dist/css/bootstrap.min.css
vendored
2
dist/css/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
BIN
dist/css/bootstrap.min.css.map
vendored
BIN
dist/css/bootstrap.min.css.map
vendored
Binary file not shown.
|
|
@ -1107,6 +1107,14 @@ var Collapse = function ($) {
|
|||
this._element = element;
|
||||
this._config = this._getConfig(config);
|
||||
this._triggerArray = $.makeArray($('[data-toggle="collapse"][href="#' + element.id + '"],' + ('[data-toggle="collapse"][data-target="#' + element.id + '"]')));
|
||||
var tabToggles = $(Selector.DATA_TOGGLE);
|
||||
for (var i = 0; i < tabToggles.length; i++) {
|
||||
var elem = tabToggles[i];
|
||||
var selector = Util.getSelectorFromElement(elem);
|
||||
if (selector !== null && $(selector).filter(element).length > 0) {
|
||||
this._triggerArray.push(elem);
|
||||
}
|
||||
}
|
||||
|
||||
this._parent = this._config.parent ? this._getParent() : null;
|
||||
|
||||
|
|
@ -1225,7 +1233,16 @@ var Collapse = function ($) {
|
|||
$(this._element).addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.SHOW);
|
||||
|
||||
if (this._triggerArray.length) {
|
||||
$(this._triggerArray).addClass(ClassName.COLLAPSED).attr('aria-expanded', false);
|
||||
for (var i = 0; i < this._triggerArray.length; i++) {
|
||||
var trigger = this._triggerArray[i];
|
||||
var selector = Util.getSelectorFromElement(trigger);
|
||||
if (selector !== null) {
|
||||
var $elem = $(selector);
|
||||
if (!$elem.hasClass(ClassName.SHOW)) {
|
||||
$(trigger).addClass(ClassName.COLLAPSED).attr('aria-expanded', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.setTransitioning(true);
|
||||
|
|
@ -1353,11 +1370,14 @@ var Collapse = function ($) {
|
|||
event.preventDefault();
|
||||
}
|
||||
|
||||
var target = Collapse._getTargetFromElement(this);
|
||||
var data = $(target).data(DATA_KEY);
|
||||
var config = data ? 'toggle' : $(this).data();
|
||||
|
||||
Collapse._jQueryInterface.call($(target), config);
|
||||
var $trigger = $(this);
|
||||
var selector = Util.getSelectorFromElement(this);
|
||||
$(selector).each(function () {
|
||||
var $target = $(this);
|
||||
var data = $target.data(DATA_KEY);
|
||||
var config = data ? 'toggle' : $trigger.data();
|
||||
Collapse._jQueryInterface.call($target, config);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -32,6 +32,35 @@ You can use a link with the `href` attribute, or a button with the `data-target`
|
|||
</div>
|
||||
{% endexample %}
|
||||
|
||||
## Multiple triggers / targets
|
||||
|
||||
A `<button>` or `<a>` can show and hide multiple elements by referencing them with a JQuery selector in its `href` or `data-target` attribute.
|
||||
Multiple `<button>` or `<a>` can show and hide an element if they each reference it with their `href` or `data-target` attribute
|
||||
|
||||
{% example html %}
|
||||
<p>
|
||||
<a class="btn btn-primary" data-toggle="collapse" href="#multiCollapseExample1" aria-expanded="false" aria-controls="multiCollapseExample1">Toggle first element</a>
|
||||
<button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#multiCollapseExample2" aria-expanded="false" aria-controls="multiCollapseExample1">Toggle second element</button>
|
||||
<button class="btn btn-primary" type="button" data-toggle="collapse" data-target=".multi-collapse" aria-expanded="false" aria-controls="multiCollapseExample1 multiCollapseExample2">Toggle both elements</button>
|
||||
</p>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="collapse multi-collapse" id="multiCollapseExample1">
|
||||
<div class="card card-block">
|
||||
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="collapse multi-collapse" id="multiCollapseExample2">
|
||||
<div class="card card-block">
|
||||
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endexample %}
|
||||
|
||||
## Accordion example
|
||||
|
||||
Using the [card]({{ site.baseurl }}/docs/{{ site.docs_version }}/components/card/) component, you can extend the default collapse behavior to create an accordion.
|
||||
|
|
@ -129,7 +158,7 @@ These classes can be found in `_transitions.scss`.
|
|||
|
||||
### Via data attributes
|
||||
|
||||
Just add `data-toggle="collapse"` and a `data-target` to the element to automatically assign control of a collapsible element. The `data-target` attribute accepts a CSS selector to apply the collapse to. Be sure to add the class `collapse` to the collapsible element. If you'd like it to default open, add the additional class `show`.
|
||||
Just add `data-toggle="collapse"` and a `data-target` to the element to automatically assign control of one or more collapsible elements. The `data-target` attribute accepts a CSS selector to apply the collapse to. Be sure to add the class `collapse` to the collapsible element. If you'd like it to default open, add the additional class `show`.
|
||||
|
||||
To add accordion-like group management to a collapsible area, add the data attribute `data-parent="#selector"`. Refer to the demo to see this in action.
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ toc: true
|
|||
|
||||
Dropdowns are toggleable, contextual overlays for displaying lists of links and more. They're made interactive with the included Bootstrap dropdown JavaScript plugin. They're toggled by clicking, not by hovering; this is [an intentional design decision.](http://markdotto.com/2012/02/27/bootstrap-explained-dropdowns/)
|
||||
|
||||
Dropdowns are built on a third party library, [Popper.js](https://popper.js.org), which provides dynamic positioning and viewport detection. Be sure to include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js) before Bootstrap's JavaScript.
|
||||
Dropdowns are built on a third party library, [Popper.js](https://popper.js.org), which provides dynamic positioning and viewport detection. Be sure to include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.10.1/umd/popper.min.js) before Bootstrap's JavaScript.
|
||||
|
||||
## Accessibility
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -11,7 +11,7 @@ toc: true
|
|||
Things to know when using the popover plugin:
|
||||
|
||||
|
||||
- Popovers rely on the 3rd party library [Popper.js](https://popper.js.org) for positioning. You must include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js) before bootstrap.js in order for popovers to work!
|
||||
- Popovers rely on the 3rd party library [Popper.js](https://popper.js.org) for positioning. You must include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.10.1/umd/popper.min.js) before bootstrap.js in order for popovers to work!
|
||||
- Popovers require the [tooltip plugin]({{ site.baseurl }}/docs/{{ site.docs_version }}/components/tooltips/) as a dependency.
|
||||
- Popovers are opt-in for performance reasons, so **you must initialize them yourself**.
|
||||
- Zero-length `title` and `content` values will never show a popover.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ toc: true
|
|||
|
||||
Things to know when using the tooltip plugin:
|
||||
|
||||
- Tooltips rely on the 3rd party library [Popper.js](https://popper.js.org) for positioning. You must include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js) before bootstrap.js in order for tooltips to work!
|
||||
- Tooltips rely on the 3rd party library [Popper.js](https://popper.js.org) for positioning. You must include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.10.1/umd/popper.min.js) before bootstrap.js in order for tooltips to work!
|
||||
- Tooltips are opt-in for performance reasons, so **you must initialize them yourself**.
|
||||
- Tooltips with zero-length titles are never displayed.
|
||||
- Specify `container: 'body'` to avoid rendering problems in more complex components (like our input groups, button groups, etc).
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@
|
|||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
|
||||
<script src="../../../../assets/js/vendor/popper.min.js"></script>
|
||||
<script src="../../../../assets/js/vendor/holder.min.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@
|
|||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
|
||||
<script src="../../../../assets/js/vendor/popper.min.js"></script>
|
||||
<script src="../../../../dist/js/bootstrap.min.js"></script>
|
||||
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
|
||||
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@
|
|||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
|
||||
<script src="../../../../assets/js/vendor/popper.min.js"></script>
|
||||
<script src="../../../../dist/js/bootstrap.min.js"></script>
|
||||
<!-- Just to make our placeholder images work. Don't actually copy the next line! -->
|
||||
<script src="../../../../assets/js/vendor/holder.min.js"></script>
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@
|
|||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
|
||||
<script src="../../../../assets/js/vendor/popper.min.js"></script>
|
||||
<script src="../../../../dist/js/bootstrap.min.js"></script>
|
||||
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
|
||||
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@
|
|||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
|
||||
<script src="../../../../assets/js/vendor/popper.min.js"></script>
|
||||
<script src="../../../../dist/js/bootstrap.min.js"></script>
|
||||
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
|
||||
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@
|
|||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
|
||||
<script src="../../../../assets/js/vendor/popper.min.js"></script>
|
||||
<script src="../../../../dist/js/bootstrap.min.js"></script>
|
||||
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
|
||||
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@
|
|||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
|
||||
<script src="../../../../assets/js/vendor/popper.min.js"></script>
|
||||
<script src="../../../../dist/js/bootstrap.min.js"></script>
|
||||
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
|
||||
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
|
||||
<script src="../../../../assets/js/vendor/popper.min.js"></script>
|
||||
<script src="../../../../dist/js/bootstrap.min.js"></script>
|
||||
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
|
||||
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
|
||||
<script src="../../../../assets/js/vendor/popper.min.js"></script>
|
||||
<script src="../../../../dist/js/bootstrap.min.js"></script>
|
||||
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
|
||||
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
|
||||
|
|
|
|||
|
|
@ -351,7 +351,7 @@
|
|||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
|
||||
<script src="../../../../assets/js/vendor/popper.min.js"></script>
|
||||
<script src="../../../../dist/js/bootstrap.min.js"></script>
|
||||
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
|
||||
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@
|
|||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
|
||||
<script src="../../../../assets/js/vendor/popper.min.js"></script>
|
||||
<script src="../../../../dist/js/bootstrap.min.js"></script>
|
||||
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
|
||||
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@
|
|||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
|
||||
<script src="../../../../assets/js/vendor/popper.min.js"></script>
|
||||
<script src="../../../../dist/js/bootstrap.min.js"></script>
|
||||
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
|
||||
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@
|
|||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
|
||||
<script src="../../../../assets/js/vendor/popper.min.js"></script>
|
||||
<script src="../../../../dist/js/bootstrap.min.js"></script>
|
||||
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
|
||||
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
|
||||
<script src="../../../../assets/js/vendor/popper.min.js"></script>
|
||||
<script src="../../../../dist/js/bootstrap.min.js"></script>
|
||||
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
|
||||
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
|
||||
|
|
|
|||
|
|
@ -103,8 +103,11 @@ New to Bootstrap 4 is the [Reboot]({{ site.baseurl }}/docs/{{ site.docs_version
|
|||
- Dropped the `.form-horizontal` class requirement.
|
||||
- `.form-group` no longer applies styles from the `.row` via mixin, so `.row` is now required for horizontal grid layouts (e.g., `<div class="form-group row">`).
|
||||
- Added new `.form-control-label` class to vertically center labels with `.form-control`s.
|
||||
- Added new `.form-row` for compact form layouts with the grid classes (swap your `.row` for a `.form-row` and go).
|
||||
- Added custom forms support (for checkboxes, radios, selects, and file inputs).
|
||||
- Added HTML5 form validation support via CSS's `:invalid` and `:valid` pseudo-classes.
|
||||
- Renamed `.has-error` to `.has-danger`.
|
||||
- Renamed `.form-control-static` to `.form-control-plaintext`.
|
||||
|
||||
### Buttons
|
||||
|
||||
|
|
|
|||
32
js/dist/collapse.js
vendored
32
js/dist/collapse.js
vendored
|
|
@ -76,6 +76,14 @@ var Collapse = function ($) {
|
|||
this._element = element;
|
||||
this._config = this._getConfig(config);
|
||||
this._triggerArray = $.makeArray($('[data-toggle="collapse"][href="#' + element.id + '"],' + ('[data-toggle="collapse"][data-target="#' + element.id + '"]')));
|
||||
var tabToggles = $(Selector.DATA_TOGGLE);
|
||||
for (var i = 0; i < tabToggles.length; i++) {
|
||||
var elem = tabToggles[i];
|
||||
var selector = Util.getSelectorFromElement(elem);
|
||||
if (selector !== null && $(selector).filter(element).length > 0) {
|
||||
this._triggerArray.push(elem);
|
||||
}
|
||||
}
|
||||
|
||||
this._parent = this._config.parent ? this._getParent() : null;
|
||||
|
||||
|
|
@ -194,7 +202,16 @@ var Collapse = function ($) {
|
|||
$(this._element).addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.SHOW);
|
||||
|
||||
if (this._triggerArray.length) {
|
||||
$(this._triggerArray).addClass(ClassName.COLLAPSED).attr('aria-expanded', false);
|
||||
for (var i = 0; i < this._triggerArray.length; i++) {
|
||||
var trigger = this._triggerArray[i];
|
||||
var selector = Util.getSelectorFromElement(trigger);
|
||||
if (selector !== null) {
|
||||
var $elem = $(selector);
|
||||
if (!$elem.hasClass(ClassName.SHOW)) {
|
||||
$(trigger).addClass(ClassName.COLLAPSED).attr('aria-expanded', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.setTransitioning(true);
|
||||
|
|
@ -322,11 +339,14 @@ var Collapse = function ($) {
|
|||
event.preventDefault();
|
||||
}
|
||||
|
||||
var target = Collapse._getTargetFromElement(this);
|
||||
var data = $(target).data(DATA_KEY);
|
||||
var config = data ? 'toggle' : $(this).data();
|
||||
|
||||
Collapse._jQueryInterface.call($(target), config);
|
||||
var $trigger = $(this);
|
||||
var selector = Util.getSelectorFromElement(this);
|
||||
$(selector).each(function () {
|
||||
var $target = $(this);
|
||||
var data = $target.data(DATA_KEY);
|
||||
var config = data ? 'toggle' : $trigger.data();
|
||||
Collapse._jQueryInterface.call($target, config);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
|||
BIN
js/dist/collapse.js.map
vendored
BIN
js/dist/collapse.js.map
vendored
Binary file not shown.
|
|
@ -77,6 +77,14 @@ const Collapse = (($) => {
|
|||
`[data-toggle="collapse"][href="#${element.id}"],` +
|
||||
`[data-toggle="collapse"][data-target="#${element.id}"]`
|
||||
))
|
||||
const tabToggles = $(Selector.DATA_TOGGLE)
|
||||
for (let i = 0; i < tabToggles.length; i++) {
|
||||
const elem = tabToggles[i]
|
||||
const selector = Util.getSelectorFromElement(elem)
|
||||
if (selector !== null && $(selector).filter(element).length > 0) {
|
||||
this._triggerArray.push(elem)
|
||||
}
|
||||
}
|
||||
|
||||
this._parent = this._config.parent ? this._getParent() : null
|
||||
|
||||
|
|
@ -215,9 +223,17 @@ const Collapse = (($) => {
|
|||
.removeClass(ClassName.SHOW)
|
||||
|
||||
if (this._triggerArray.length) {
|
||||
$(this._triggerArray)
|
||||
.addClass(ClassName.COLLAPSED)
|
||||
.attr('aria-expanded', false)
|
||||
for (let i = 0; i < this._triggerArray.length; i++) {
|
||||
const trigger = this._triggerArray[i]
|
||||
const selector = Util.getSelectorFromElement(trigger)
|
||||
if (selector !== null) {
|
||||
const $elem = $(selector)
|
||||
if (!$elem.hasClass(ClassName.SHOW)) {
|
||||
$(trigger).addClass(ClassName.COLLAPSED)
|
||||
.attr('aria-expanded', false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.setTransitioning(true)
|
||||
|
|
@ -349,11 +365,14 @@ const Collapse = (($) => {
|
|||
event.preventDefault()
|
||||
}
|
||||
|
||||
const target = Collapse._getTargetFromElement(this)
|
||||
const data = $(target).data(DATA_KEY)
|
||||
const config = data ? 'toggle' : $(this).data()
|
||||
|
||||
Collapse._jQueryInterface.call($(target), config)
|
||||
const $trigger = $(this)
|
||||
const selector = Util.getSelectorFromElement(this)
|
||||
$(selector).each(function () {
|
||||
const $target = $(this)
|
||||
const data = $target.data(DATA_KEY)
|
||||
const config = data ? 'toggle' : $trigger.data()
|
||||
Collapse._jQueryInterface.call($target, config)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -52,8 +52,28 @@ $(function () {
|
|||
assert.ok(!/height/i.test($el.attr('style')), 'has height reset')
|
||||
})
|
||||
|
||||
|
||||
QUnit.test('should show multiple collapsed elements', function (assert) {
|
||||
assert.expect(4)
|
||||
var done = assert.async()
|
||||
var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href=".multi"/>').appendTo('#qunit-fixture')
|
||||
var $el = $('<div class="collapse multi"/>').appendTo('#qunit-fixture')
|
||||
var $el2 = $('<div class="collapse multi"/>').appendTo('#qunit-fixture')
|
||||
$el.one('shown.bs.collapse', function () {
|
||||
assert.ok($el.hasClass('show'), 'has class "show"')
|
||||
assert.ok(!/height/i.test($el.attr('style')), 'has height reset')
|
||||
})
|
||||
$el2.one('shown.bs.collapse', function () {
|
||||
assert.ok($el2.hasClass('show'), 'has class "show"')
|
||||
assert.ok(!/height/i.test($el2.attr('style')), 'has height reset')
|
||||
done()
|
||||
})
|
||||
$target.trigger('click')
|
||||
})
|
||||
|
||||
QUnit.test('should collapse only the first collapse', function (assert) {
|
||||
assert.expect(2)
|
||||
var done = assert.async()
|
||||
var html = [
|
||||
'<div class="panel-group" id="accordion1">',
|
||||
'<div class="panel">',
|
||||
|
|
@ -69,10 +89,11 @@ $(function () {
|
|||
$(html).appendTo('#qunit-fixture')
|
||||
var $el1 = $('#collapse1')
|
||||
var $el2 = $('#collapse2')
|
||||
$el1.bootstrapCollapse('show')
|
||||
|
||||
assert.ok($el1.hasClass('show'))
|
||||
assert.ok($el2.hasClass('show'))
|
||||
$el1.one('shown.bs.collapse', function () {
|
||||
assert.ok($el1.hasClass('show'))
|
||||
assert.ok($el2.hasClass('show'))
|
||||
done()
|
||||
}).bootstrapCollapse('show')
|
||||
})
|
||||
|
||||
QUnit.test('should hide a collapsed element', function (assert) {
|
||||
|
|
@ -588,4 +609,68 @@ $(function () {
|
|||
|
||||
$target.trigger($.Event('click'))
|
||||
})
|
||||
|
||||
QUnit.test('should add "collapsed" class to triggers only when all the targeted collapse are hidden', function (assert) {
|
||||
assert.expect(9)
|
||||
var done = assert.async()
|
||||
|
||||
var $trigger1 = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
|
||||
var $trigger2 = $('<a role="button" data-toggle="collapse" href="#test2"/>').appendTo('#qunit-fixture')
|
||||
var $trigger3 = $('<a role="button" data-toggle="collapse" href=".multi"/>').appendTo('#qunit-fixture')
|
||||
|
||||
var $target1 = $('<div id="test1" class="multi"/>').appendTo('#qunit-fixture')
|
||||
var $target2 = $('<div id="test2" class="multi"/>').appendTo('#qunit-fixture')
|
||||
|
||||
$target2.one('shown.bs.collapse', function () {
|
||||
assert.ok(!$trigger1.hasClass('collapsed'), 'trigger1 does not have collapsed class')
|
||||
assert.ok(!$trigger2.hasClass('collapsed'), 'trigger2 does not have collapsed class')
|
||||
assert.ok(!$trigger3.hasClass('collapsed'), 'trigger3 does not have collapsed class')
|
||||
$target2.one('hidden.bs.collapse', function () {
|
||||
assert.ok(!$trigger1.hasClass('collapsed'), 'trigger1 does not have collapsed class')
|
||||
assert.ok($trigger2.hasClass('collapsed'), 'trigger2 has collapsed class')
|
||||
assert.ok(!$trigger3.hasClass('collapsed'), 'trigger3 does not have collapsed class')
|
||||
$target1.one('hidden.bs.collapse', function () {
|
||||
assert.ok($trigger1.hasClass('collapsed'), 'trigger1 has collapsed class')
|
||||
assert.ok($trigger2.hasClass('collapsed'), 'trigger2 has collapsed class')
|
||||
assert.ok($trigger3.hasClass('collapsed'), 'trigger3 has collapsed class')
|
||||
done()
|
||||
})
|
||||
$trigger1.trigger('click')
|
||||
})
|
||||
$trigger2.trigger('click')
|
||||
})
|
||||
$trigger3.trigger('click')
|
||||
})
|
||||
|
||||
QUnit.test('should set aria-expanded="true" to triggers targetting shown collaspe and aria-expanded="false" only when all the targeted collapses are shown', function (assert) {
|
||||
assert.expect(9)
|
||||
var done = assert.async()
|
||||
|
||||
var $trigger1 = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
|
||||
var $trigger2 = $('<a role="button" data-toggle="collapse" href="#test2"/>').appendTo('#qunit-fixture')
|
||||
var $trigger3 = $('<a role="button" data-toggle="collapse" href=".multi"/>').appendTo('#qunit-fixture')
|
||||
|
||||
var $target1 = $('<div id="test1" class="multi collapse"/>').appendTo('#qunit-fixture')
|
||||
var $target2 = $('<div id="test2" class="multi collapse"/>').appendTo('#qunit-fixture')
|
||||
|
||||
$target2.one('shown.bs.collapse', function () {
|
||||
assert.strictEqual($trigger1.attr('aria-expanded'), 'true', 'aria-expanded on trigger1 is "true"')
|
||||
assert.strictEqual($trigger2.attr('aria-expanded'), 'true', 'aria-expanded on trigger2 is "true"')
|
||||
assert.strictEqual($trigger3.attr('aria-expanded'), 'true', 'aria-expanded on trigger3 is "true"')
|
||||
$target2.one('hidden.bs.collapse', function () {
|
||||
assert.strictEqual($trigger1.attr('aria-expanded'), 'true', 'aria-expanded on trigger1 is "true"')
|
||||
assert.strictEqual($trigger2.attr('aria-expanded'), 'false', 'aria-expanded on trigger2 is "false"')
|
||||
assert.strictEqual($trigger3.attr('aria-expanded'), 'true', 'aria-expanded on trigger3 is "true"')
|
||||
$target1.one('hidden.bs.collapse', function () {
|
||||
assert.strictEqual($trigger1.attr('aria-expanded'), 'false', 'aria-expanded on trigger1 is "fasle"')
|
||||
assert.strictEqual($trigger2.attr('aria-expanded'), 'false', 'aria-expanded on trigger2 is "false"')
|
||||
assert.strictEqual($trigger3.attr('aria-expanded'), 'false', 'aria-expanded on trigger3 is "false"')
|
||||
done()
|
||||
})
|
||||
$trigger1.trigger('click')
|
||||
})
|
||||
$trigger2.trigger('click')
|
||||
})
|
||||
$trigger3.trigger('click')
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ $(function () {
|
|||
})
|
||||
|
||||
QUnit.test('should not open dropdown if target is disabled via attribute', function (assert) {
|
||||
assert.expect(0)
|
||||
assert.expect(1)
|
||||
var done = assert.async()
|
||||
var dropdownHTML = '<div class="tabs">'
|
||||
+ '<div class="dropdown">'
|
||||
+ '<button disabled href="#" class="btn dropdown-toggle" data-toggle="dropdown">Dropdown</button>'
|
||||
|
|
@ -57,10 +58,13 @@ $(function () {
|
|||
+ '</div>'
|
||||
+ '</div>'
|
||||
+ '</div>'
|
||||
var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown()
|
||||
setTimeout(function () {
|
||||
assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
|
||||
}, 300)
|
||||
$(dropdownHTML).appendTo('#qunit-fixture')
|
||||
var $dropdown = $('#qunit-fixture').find('[data-toggle="dropdown"]').bootstrapDropdown()
|
||||
$dropdown.on('click', function () {
|
||||
assert.ok(!$dropdown.parent('.dropdown').hasClass('show'))
|
||||
done()
|
||||
})
|
||||
$dropdown.trigger($.Event('click'))
|
||||
})
|
||||
|
||||
QUnit.test('should set aria-expanded="true" on target when dropdown menu is shown', function (assert) {
|
||||
|
|
@ -77,7 +81,10 @@ $(function () {
|
|||
+ '</div>'
|
||||
+ '</div>'
|
||||
+ '</div>'
|
||||
var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown()
|
||||
var $dropdown = $(dropdownHTML)
|
||||
.appendTo('#qunit-fixture')
|
||||
.find('[data-toggle="dropdown"]')
|
||||
.bootstrapDropdown()
|
||||
$dropdown
|
||||
.parent('.dropdown')
|
||||
.on('shown.bs.dropdown', function () {
|
||||
|
|
@ -118,7 +125,8 @@ $(function () {
|
|||
})
|
||||
|
||||
QUnit.test('should not open dropdown if target is disabled via class', function (assert) {
|
||||
assert.expect(0)
|
||||
assert.expect(1)
|
||||
var done = assert.async()
|
||||
var dropdownHTML = '<div class="tabs">'
|
||||
+ '<div class="dropdown">'
|
||||
+ '<button href="#" class="btn dropdown-toggle disabled" data-toggle="dropdown">Dropdown</button>'
|
||||
|
|
@ -130,10 +138,14 @@ $(function () {
|
|||
+ '</div>'
|
||||
+ '</div>'
|
||||
+ '</div>'
|
||||
var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().trigger('click')
|
||||
setTimeout(function () {
|
||||
assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
|
||||
}, 300)
|
||||
|
||||
$(dropdownHTML).appendTo('#qunit-fixture')
|
||||
var $dropdown = $('#qunit-fixture').find('[data-toggle="dropdown"]').bootstrapDropdown()
|
||||
$dropdown.on('click', function () {
|
||||
assert.ok(!$dropdown.parent('.dropdown').hasClass('show'))
|
||||
done()
|
||||
})
|
||||
$dropdown.trigger($.Event('click'))
|
||||
})
|
||||
|
||||
QUnit.test('should add class show to menu if clicked', function (assert) {
|
||||
|
|
|
|||
4
js/tests/vendor/qunit.css
vendored
4
js/tests/vendor/qunit.css
vendored
|
|
@ -1,12 +1,12 @@
|
|||
/*!
|
||||
* QUnit 2.3.2
|
||||
* QUnit 2.3.3
|
||||
* https://qunitjs.com/
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
* Released under the MIT license
|
||||
* https://jquery.org/license
|
||||
*
|
||||
* Date: 2017-04-18T02:19Z
|
||||
* Date: 2017-06-02T14:07Z
|
||||
*/
|
||||
|
||||
/** Font Family and Sizes */
|
||||
|
|
|
|||
563
js/tests/vendor/qunit.js
vendored
563
js/tests/vendor/qunit.js
vendored
|
|
@ -1,12 +1,12 @@
|
|||
/*!
|
||||
* QUnit 2.3.2
|
||||
* QUnit 2.3.3
|
||||
* https://qunitjs.com/
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
* Released under the MIT license
|
||||
* https://jquery.org/license
|
||||
*
|
||||
* Date: 2017-04-18T02:19Z
|
||||
* Date: 2017-06-02T14:07Z
|
||||
*/
|
||||
(function (global$1) {
|
||||
'use strict';
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
global$1 = 'default' in global$1 ? global$1['default'] : global$1;
|
||||
|
||||
var window = global$1.window;
|
||||
var self$1 = global$1.self;
|
||||
var console = global$1.console;
|
||||
var setTimeout = global$1.setTimeout;
|
||||
var clearTimeout = global$1.clearTimeout;
|
||||
|
|
@ -238,6 +239,27 @@
|
|||
return objectType(obj) === type;
|
||||
}
|
||||
|
||||
// Based on Java's String.hashCode, a simple but not
|
||||
// rigorously collision resistant hashing function
|
||||
function generateHash(module, testName) {
|
||||
var str = module + "\x1C" + testName;
|
||||
var hash = 0;
|
||||
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
hash = (hash << 5) - hash + str.charCodeAt(i);
|
||||
hash |= 0;
|
||||
}
|
||||
|
||||
// Convert the possibly negative integer hash code into an 8 character hex string, which isn't
|
||||
// strictly necessary but increases user understanding that the id is a SHA-like hash
|
||||
var hex = (0x100000000 + hash).toString(16);
|
||||
if (hex.length < 8) {
|
||||
hex = "0000000" + hex;
|
||||
}
|
||||
|
||||
return hex.slice(-8);
|
||||
}
|
||||
|
||||
// Test for equality any JavaScript type.
|
||||
// Authors: Philippe Rathé <prathe@gmail.com>, David Chan <david@troi.org>
|
||||
var equiv = (function () {
|
||||
|
|
@ -608,21 +630,19 @@
|
|||
// Set of all modules.
|
||||
modules: [],
|
||||
|
||||
// Stack of nested modules
|
||||
moduleStack: [],
|
||||
|
||||
// The first unnamed module
|
||||
currentModule: {
|
||||
name: "",
|
||||
tests: [],
|
||||
childModules: [],
|
||||
testsRun: 0
|
||||
testsRun: 0,
|
||||
unskippedTestsRun: 0
|
||||
},
|
||||
|
||||
callbacks: {},
|
||||
|
||||
// The storage module to use for reordering tests
|
||||
storage: sessionStorage
|
||||
storage: localSessionStorage
|
||||
};
|
||||
|
||||
// take a predefined QUnit.config and extend the defaults
|
||||
|
|
@ -1064,6 +1084,135 @@
|
|||
return extractStacktrace(error, offset);
|
||||
}
|
||||
|
||||
var priorityCount = 0;
|
||||
var unitSampler = void 0;
|
||||
|
||||
/**
|
||||
* Advances the ProcessingQueue to the next item if it is ready.
|
||||
* @param {Boolean} last
|
||||
*/
|
||||
function advance() {
|
||||
var start = now();
|
||||
config.depth = (config.depth || 0) + 1;
|
||||
|
||||
while (config.queue.length && !config.blocking) {
|
||||
var elapsedTime = now() - start;
|
||||
|
||||
if (!defined.setTimeout || config.updateRate <= 0 || elapsedTime < config.updateRate) {
|
||||
if (priorityCount > 0) {
|
||||
priorityCount--;
|
||||
}
|
||||
|
||||
config.queue.shift()();
|
||||
} else {
|
||||
setTimeout(advance, 13);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
config.depth--;
|
||||
|
||||
if (!config.blocking && !config.queue.length && config.depth === 0) {
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
function addToQueueImmediate(callback) {
|
||||
if (objectType(callback) === "array") {
|
||||
while (callback.length) {
|
||||
addToQueueImmediate(callback.pop());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
config.queue.unshift(callback);
|
||||
priorityCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a function to the ProcessingQueue for execution.
|
||||
* @param {Function|Array} callback
|
||||
* @param {Boolean} priority
|
||||
* @param {String} seed
|
||||
*/
|
||||
function addToQueue(callback, prioritize, seed) {
|
||||
if (prioritize) {
|
||||
config.queue.splice(priorityCount++, 0, callback);
|
||||
} else if (seed) {
|
||||
if (!unitSampler) {
|
||||
unitSampler = unitSamplerGenerator(seed);
|
||||
}
|
||||
|
||||
// Insert into a random position after all prioritized items
|
||||
var index = Math.floor(unitSampler() * (config.queue.length - priorityCount + 1));
|
||||
config.queue.splice(priorityCount + index, 0, callback);
|
||||
} else {
|
||||
config.queue.push(callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a seeded "sample" generator which is used for randomizing tests.
|
||||
*/
|
||||
function unitSamplerGenerator(seed) {
|
||||
|
||||
// 32-bit xorshift, requires only a nonzero seed
|
||||
// http://excamera.com/sphinx/article-xorshift.html
|
||||
var sample = parseInt(generateHash(seed), 16) || -1;
|
||||
return function () {
|
||||
sample ^= sample << 13;
|
||||
sample ^= sample >>> 17;
|
||||
sample ^= sample << 5;
|
||||
|
||||
// ECMAScript has no unsigned number type
|
||||
if (sample < 0) {
|
||||
sample += 0x100000000;
|
||||
}
|
||||
|
||||
return sample / 0x100000000;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when the ProcessingQueue is done processing all
|
||||
* items. It handles emitting the final run events.
|
||||
*/
|
||||
function done() {
|
||||
var storage = config.storage;
|
||||
|
||||
ProcessingQueue.finished = true;
|
||||
|
||||
var runtime = now() - config.started;
|
||||
var passed = config.stats.all - config.stats.bad;
|
||||
|
||||
emit("runEnd", globalSuite.end(true));
|
||||
runLoggingCallbacks("done", {
|
||||
passed: passed,
|
||||
failed: config.stats.bad,
|
||||
total: config.stats.all,
|
||||
runtime: runtime
|
||||
});
|
||||
|
||||
// Clear own storage items if all tests passed
|
||||
if (storage && config.stats.bad === 0) {
|
||||
for (var i = storage.length - 1; i >= 0; i--) {
|
||||
var key = storage.key(i);
|
||||
|
||||
if (key.indexOf("qunit-test-") === 0) {
|
||||
storage.removeItem(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ProcessingQueue = {
|
||||
finished: false,
|
||||
add: addToQueue,
|
||||
addImmediate: addToQueueImmediate,
|
||||
advance: advance
|
||||
};
|
||||
|
||||
var TestReport = function () {
|
||||
function TestReport(name, suite, options) {
|
||||
classCallCheck(this, TestReport);
|
||||
|
|
@ -1077,6 +1226,8 @@
|
|||
this.skipped = !!options.skip;
|
||||
this.todo = !!options.todo;
|
||||
|
||||
this.valid = options.valid;
|
||||
|
||||
this._startTime = 0;
|
||||
this._endTime = 0;
|
||||
|
||||
|
|
@ -1149,13 +1300,24 @@
|
|||
value: function getAssertions() {
|
||||
return this.assertions.slice();
|
||||
}
|
||||
|
||||
// Remove actual and expected values from assertions. This is to prevent
|
||||
// leaking memory throughout a test suite.
|
||||
|
||||
}, {
|
||||
key: "slimAssertions",
|
||||
value: function slimAssertions() {
|
||||
this.assertions = this.assertions.map(function (assertion) {
|
||||
delete assertion.actual;
|
||||
delete assertion.expected;
|
||||
return assertion;
|
||||
});
|
||||
}
|
||||
}]);
|
||||
return TestReport;
|
||||
}();
|
||||
|
||||
var unitSampler;
|
||||
var focused = false;
|
||||
var priorityCount = 0;
|
||||
|
||||
function Test(settings) {
|
||||
var i, l;
|
||||
|
|
@ -1166,14 +1328,14 @@
|
|||
extend(this, settings);
|
||||
this.assertions = [];
|
||||
this.semaphore = 0;
|
||||
this.usedAsync = false;
|
||||
this.module = config.currentModule;
|
||||
this.stack = sourceFromStacktrace(3);
|
||||
this.steps = [];
|
||||
|
||||
this.testReport = new TestReport(settings.testName, this.module.suiteReport, {
|
||||
todo: settings.todo,
|
||||
skip: settings.skip
|
||||
skip: settings.skip,
|
||||
valid: this.valid()
|
||||
});
|
||||
|
||||
// Register unique strings
|
||||
|
|
@ -1187,7 +1349,8 @@
|
|||
|
||||
this.module.tests.push({
|
||||
name: this.testName,
|
||||
testId: this.testId
|
||||
testId: this.testId,
|
||||
skip: !!settings.skip
|
||||
});
|
||||
|
||||
if (settings.skip) {
|
||||
|
|
@ -1234,12 +1397,6 @@
|
|||
|
||||
config.current = this;
|
||||
|
||||
if (module.testEnvironment) {
|
||||
delete module.testEnvironment.before;
|
||||
delete module.testEnvironment.beforeEach;
|
||||
delete module.testEnvironment.afterEach;
|
||||
delete module.testEnvironment.after;
|
||||
}
|
||||
this.testEnvironment = extend({}, module.testEnvironment);
|
||||
|
||||
this.started = now();
|
||||
|
|
@ -1297,14 +1454,14 @@
|
|||
test = this;
|
||||
return function runHook() {
|
||||
if (hookName === "before") {
|
||||
if (hookOwner.testsRun !== 0) {
|
||||
if (hookOwner.unskippedTestsRun !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
test.preserveEnvironment = true;
|
||||
}
|
||||
|
||||
if (hookName === "after" && hookOwner.testsRun !== numberOfTests(hookOwner) - 1) {
|
||||
if (hookName === "after" && hookOwner.unskippedTestsRun !== numberOfUnskippedTests(hookOwner) - 1 && config.queue.length > 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1334,8 +1491,8 @@
|
|||
if (module.parentModule) {
|
||||
processHooks(test, module.parentModule);
|
||||
}
|
||||
if (module.testEnvironment && objectType(module.testEnvironment[handler]) === "function") {
|
||||
hooks.push(test.queueHook(module.testEnvironment[handler], handler, module));
|
||||
if (module.hooks && objectType(module.hooks[handler]) === "function") {
|
||||
hooks.push(test.queueHook(module.hooks[handler], handler, module));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1378,7 +1535,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
notifyTestsRan(module);
|
||||
notifyTestsRan(module, skipped);
|
||||
|
||||
// Store result when possible
|
||||
if (storage) {
|
||||
|
|
@ -1389,7 +1546,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
// After emitting the js-reporters event we cleanup the assertion data to
|
||||
// avoid leaking it. It is not used by the legacy testDone callbacks.
|
||||
emit("testEnd", this.testReport.end(true));
|
||||
this.testReport.slimAssertions();
|
||||
|
||||
runLoggingCallbacks("testDone", {
|
||||
name: testName,
|
||||
module: moduleName,
|
||||
|
|
@ -1409,6 +1570,20 @@
|
|||
});
|
||||
|
||||
if (module.testsRun === numberOfTests(module)) {
|
||||
logSuiteEnd(module);
|
||||
|
||||
// Check if the parent modules, iteratively, are done. If that the case,
|
||||
// we emit the `suiteEnd` event and trigger `moduleDone` callback.
|
||||
var parent = module.parentModule;
|
||||
while (parent && parent.testsRun === numberOfTests(parent)) {
|
||||
logSuiteEnd(parent);
|
||||
parent = parent.parentModule;
|
||||
}
|
||||
}
|
||||
|
||||
config.current = undefined;
|
||||
|
||||
function logSuiteEnd(module) {
|
||||
emit("suiteEnd", module.suiteReport.end(true));
|
||||
runLoggingCallbacks("moduleDone", {
|
||||
name: module.name,
|
||||
|
|
@ -1419,8 +1594,6 @@
|
|||
runtime: now() - module.stats.started
|
||||
});
|
||||
}
|
||||
|
||||
config.current = undefined;
|
||||
},
|
||||
|
||||
preserveTestEnvironment: function preserveTestEnvironment() {
|
||||
|
|
@ -1431,18 +1604,16 @@
|
|||
},
|
||||
|
||||
queue: function queue() {
|
||||
var priority,
|
||||
previousFailCount,
|
||||
test = this;
|
||||
var test = this;
|
||||
|
||||
if (!this.valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
function run() {
|
||||
function runTest() {
|
||||
|
||||
// Each of these can by async
|
||||
synchronize([function () {
|
||||
ProcessingQueue.addImmediate([function () {
|
||||
test.before();
|
||||
}, test.hooks("before"), function () {
|
||||
test.preserveTestEnvironment();
|
||||
|
|
@ -1455,17 +1626,26 @@
|
|||
}]);
|
||||
}
|
||||
|
||||
previousFailCount = config.storage && +config.storage.getItem("qunit-test-" + this.module.name + "-" + this.testName);
|
||||
var previousFailCount = config.storage && +config.storage.getItem("qunit-test-" + this.module.name + "-" + this.testName);
|
||||
|
||||
// Prioritize previously failed tests, detected from storage
|
||||
priority = config.reorder && previousFailCount;
|
||||
var prioritize = config.reorder && !!previousFailCount;
|
||||
|
||||
this.previousFailure = !!previousFailCount;
|
||||
|
||||
return synchronize(run, priority, config.seed);
|
||||
ProcessingQueue.add(runTest, prioritize, config.seed);
|
||||
|
||||
// If the queue has already finished, we manually process the new test
|
||||
if (ProcessingQueue.finished) {
|
||||
ProcessingQueue.advance();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
pushResult: function pushResult(resultInfo) {
|
||||
if (this !== config.current) {
|
||||
throw new Error("Assertion occured after test had finished.");
|
||||
}
|
||||
|
||||
// Destructure of resultInfo = { result, actual, expected, message, negative }
|
||||
var source,
|
||||
|
|
@ -1503,7 +1683,7 @@
|
|||
throw new Error("pushFailure() assertion outside test context, was " + sourceFromStacktrace(2));
|
||||
}
|
||||
|
||||
this.assert.pushResult({
|
||||
this.pushResult({
|
||||
result: false,
|
||||
message: message || "error",
|
||||
actual: actual || null,
|
||||
|
|
@ -1643,79 +1823,6 @@
|
|||
return currentTest.pushFailure.apply(currentTest, arguments);
|
||||
}
|
||||
|
||||
// Based on Java's String.hashCode, a simple but not
|
||||
// rigorously collision resistant hashing function
|
||||
function generateHash(module, testName) {
|
||||
var hex,
|
||||
i = 0,
|
||||
hash = 0,
|
||||
str = module + "\x1C" + testName,
|
||||
len = str.length;
|
||||
|
||||
for (; i < len; i++) {
|
||||
hash = (hash << 5) - hash + str.charCodeAt(i);
|
||||
hash |= 0;
|
||||
}
|
||||
|
||||
// Convert the possibly negative integer hash code into an 8 character hex string, which isn't
|
||||
// strictly necessary but increases user understanding that the id is a SHA-like hash
|
||||
hex = (0x100000000 + hash).toString(16);
|
||||
if (hex.length < 8) {
|
||||
hex = "0000000" + hex;
|
||||
}
|
||||
|
||||
return hex.slice(-8);
|
||||
}
|
||||
|
||||
function synchronize(callback, priority, seed) {
|
||||
var last = !priority,
|
||||
index;
|
||||
|
||||
if (objectType(callback) === "array") {
|
||||
while (callback.length) {
|
||||
synchronize(callback.shift());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (priority) {
|
||||
config.queue.splice(priorityCount++, 0, callback);
|
||||
} else if (seed) {
|
||||
if (!unitSampler) {
|
||||
unitSampler = unitSamplerGenerator(seed);
|
||||
}
|
||||
|
||||
// Insert into a random position after all priority items
|
||||
index = Math.floor(unitSampler() * (config.queue.length - priorityCount + 1));
|
||||
config.queue.splice(priorityCount + index, 0, callback);
|
||||
} else {
|
||||
config.queue.push(callback);
|
||||
}
|
||||
|
||||
if (internalState.autorun && !config.blocking) {
|
||||
process(last);
|
||||
}
|
||||
}
|
||||
|
||||
function unitSamplerGenerator(seed) {
|
||||
|
||||
// 32-bit xorshift, requires only a nonzero seed
|
||||
// http://excamera.com/sphinx/article-xorshift.html
|
||||
var sample = parseInt(generateHash(seed), 16) || -1;
|
||||
return function () {
|
||||
sample ^= sample << 13;
|
||||
sample ^= sample >>> 17;
|
||||
sample ^= sample << 5;
|
||||
|
||||
// ECMAScript has no unsigned number type
|
||||
if (sample < 0) {
|
||||
sample += 0x100000000;
|
||||
}
|
||||
|
||||
return sample / 0x100000000;
|
||||
};
|
||||
}
|
||||
|
||||
function saveGlobal() {
|
||||
config.pollution = [];
|
||||
|
||||
|
|
@ -1888,24 +1995,40 @@
|
|||
}
|
||||
}
|
||||
|
||||
function numberOfTests(module) {
|
||||
var count = module.tests.length,
|
||||
modules = [].concat(toConsumableArray(module.childModules));
|
||||
function collectTests(module) {
|
||||
var tests = [].concat(module.tests);
|
||||
var modules = [].concat(toConsumableArray(module.childModules));
|
||||
|
||||
// Do a breadth-first traversal of the child modules
|
||||
while (modules.length) {
|
||||
var nextModule = modules.shift();
|
||||
count += nextModule.tests.length;
|
||||
tests.push.apply(tests, nextModule.tests);
|
||||
modules.push.apply(modules, toConsumableArray(nextModule.childModules));
|
||||
}
|
||||
|
||||
return count;
|
||||
return tests;
|
||||
}
|
||||
|
||||
function notifyTestsRan(module) {
|
||||
function numberOfTests(module) {
|
||||
return collectTests(module).length;
|
||||
}
|
||||
|
||||
function numberOfUnskippedTests(module) {
|
||||
return collectTests(module).filter(function (test) {
|
||||
return !test.skip;
|
||||
}).length;
|
||||
}
|
||||
|
||||
function notifyTestsRan(module, skipped) {
|
||||
module.testsRun++;
|
||||
if (!skipped) {
|
||||
module.unskippedTestsRun++;
|
||||
}
|
||||
while (module = module.parentModule) {
|
||||
module.testsRun++;
|
||||
if (!skipped) {
|
||||
module.unskippedTestsRun++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1978,18 +2101,22 @@
|
|||
}, {
|
||||
key: "async",
|
||||
value: function async(count) {
|
||||
var test$$1 = this.test,
|
||||
popped = false,
|
||||
var test$$1 = this.test;
|
||||
|
||||
var popped = false,
|
||||
acceptCallCount = count;
|
||||
|
||||
if (typeof acceptCallCount === "undefined") {
|
||||
acceptCallCount = 1;
|
||||
}
|
||||
|
||||
test$$1.usedAsync = true;
|
||||
var resume = internalStop(test$$1);
|
||||
|
||||
return function done() {
|
||||
if (config.current !== test$$1) {
|
||||
throw Error("assert.async callback called after test finished.");
|
||||
}
|
||||
|
||||
if (popped) {
|
||||
test$$1.pushFailure("Too many calls to the `assert.async` callback", sourceFromStacktrace(2));
|
||||
return;
|
||||
|
|
@ -2027,8 +2154,8 @@
|
|||
value: function pushResult(resultInfo) {
|
||||
|
||||
// Destructure of resultInfo = { result, actual, expected, message, negative }
|
||||
var assert = this,
|
||||
currentTest = assert instanceof Assert && assert.test || config.current;
|
||||
var assert = this;
|
||||
var currentTest = assert instanceof Assert && assert.test || config.current;
|
||||
|
||||
// Backwards compatibility fix.
|
||||
// Allows the direct use of global exported assertions and QUnit.assert.*
|
||||
|
|
@ -2039,12 +2166,6 @@
|
|||
throw new Error("assertion outside test context, in " + sourceFromStacktrace(2));
|
||||
}
|
||||
|
||||
if (currentTest.usedAsync === true && currentTest.semaphore === 0) {
|
||||
currentTest.pushFailure("Assertion after the final `assert.async` was resolved", sourceFromStacktrace(2));
|
||||
|
||||
// Allow this assertion to continue running anyway...
|
||||
}
|
||||
|
||||
if (!(assert instanceof Assert)) {
|
||||
assert = currentTest.assert;
|
||||
}
|
||||
|
|
@ -2181,8 +2302,9 @@
|
|||
key: "throws",
|
||||
value: function throws(block, expected, message) {
|
||||
var actual = void 0,
|
||||
result = false,
|
||||
currentTest = this instanceof Assert && this.test || config.current;
|
||||
result = false;
|
||||
|
||||
var currentTest = this instanceof Assert && this.test || config.current;
|
||||
|
||||
// 'expected' is optional unless doing string comparison
|
||||
if (objectType(expected) === "string") {
|
||||
|
|
@ -2306,6 +2428,11 @@
|
|||
});
|
||||
QUnit.config.autostart = false;
|
||||
}
|
||||
|
||||
// For Web/Service Workers
|
||||
if (self$1 && self$1.WorkerGlobalScope && self$1 instanceof self$1.WorkerGlobalScope) {
|
||||
self$1.QUnit = QUnit;
|
||||
}
|
||||
}
|
||||
|
||||
var SuiteReport = function () {
|
||||
|
|
@ -2386,8 +2513,11 @@
|
|||
var counts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { passed: 0, failed: 0, skipped: 0, todo: 0, total: 0 };
|
||||
|
||||
counts = this.tests.reduce(function (counts, test) {
|
||||
counts[test.getStatus()]++;
|
||||
counts.total++;
|
||||
if (test.valid) {
|
||||
counts[test.getStatus()]++;
|
||||
counts.total++;
|
||||
}
|
||||
|
||||
return counts;
|
||||
}, counts);
|
||||
|
||||
|
|
@ -2451,27 +2581,49 @@
|
|||
// it since each module has a suiteReport associated with it.
|
||||
config.currentModule.suiteReport = globalSuite;
|
||||
|
||||
var moduleStack = [];
|
||||
var globalStartCalled = false;
|
||||
var runStarted = false;
|
||||
|
||||
var internalState = {
|
||||
autorun: false
|
||||
};
|
||||
|
||||
// Figure out if we're running the tests from a server or not
|
||||
QUnit.isLocal = !(defined.document && window.location.protocol !== "file:");
|
||||
|
||||
// Expose the current QUnit version
|
||||
QUnit.version = "2.2.0";
|
||||
QUnit.version = "2.3.3";
|
||||
|
||||
function createModule(name, testEnvironment) {
|
||||
var parentModule = moduleStack.length ? moduleStack.slice(-1)[0] : null;
|
||||
var moduleName = parentModule !== null ? [parentModule.name, name].join(" > ") : name;
|
||||
var parentSuite = parentModule ? parentModule.suiteReport : globalSuite;
|
||||
|
||||
var module = {
|
||||
name: moduleName,
|
||||
parentModule: parentModule,
|
||||
tests: [],
|
||||
moduleId: generateHash(moduleName),
|
||||
testsRun: 0,
|
||||
unskippedTestsRun: 0,
|
||||
childModules: [],
|
||||
suiteReport: new SuiteReport(name, parentSuite)
|
||||
};
|
||||
|
||||
var env = {};
|
||||
if (parentModule) {
|
||||
parentModule.childModules.push(module);
|
||||
extend(env, parentModule.testEnvironment);
|
||||
}
|
||||
extend(env, testEnvironment);
|
||||
module.testEnvironment = env;
|
||||
|
||||
config.modules.push(module);
|
||||
return module;
|
||||
}
|
||||
|
||||
extend(QUnit, {
|
||||
on: on,
|
||||
|
||||
// Call on start of module test to prepend name to all tests
|
||||
module: function module(name, testEnvironment, executeNow) {
|
||||
var module, moduleFns;
|
||||
var currentModule = config.currentModule;
|
||||
|
||||
if (arguments.length === 2) {
|
||||
if (objectType(testEnvironment) === "function") {
|
||||
executeNow = testEnvironment;
|
||||
|
|
@ -2479,57 +2631,40 @@
|
|||
}
|
||||
}
|
||||
|
||||
module = createModule();
|
||||
var module = createModule(name, testEnvironment);
|
||||
|
||||
moduleFns = {
|
||||
// Move any hooks to a 'hooks' object
|
||||
if (module.testEnvironment) {
|
||||
module.hooks = {
|
||||
before: module.testEnvironment.before,
|
||||
beforeEach: module.testEnvironment.beforeEach,
|
||||
afterEach: module.testEnvironment.afterEach,
|
||||
after: module.testEnvironment.after
|
||||
};
|
||||
|
||||
delete module.testEnvironment.before;
|
||||
delete module.testEnvironment.beforeEach;
|
||||
delete module.testEnvironment.afterEach;
|
||||
delete module.testEnvironment.after;
|
||||
}
|
||||
|
||||
var moduleFns = {
|
||||
before: setHook(module, "before"),
|
||||
beforeEach: setHook(module, "beforeEach"),
|
||||
afterEach: setHook(module, "afterEach"),
|
||||
after: setHook(module, "after")
|
||||
};
|
||||
|
||||
var currentModule = config.currentModule;
|
||||
if (objectType(executeNow) === "function") {
|
||||
config.moduleStack.push(module);
|
||||
setCurrentModule(module);
|
||||
moduleStack.push(module);
|
||||
config.currentModule = module;
|
||||
executeNow.call(module.testEnvironment, moduleFns);
|
||||
config.moduleStack.pop();
|
||||
moduleStack.pop();
|
||||
module = module.parentModule || currentModule;
|
||||
}
|
||||
|
||||
setCurrentModule(module);
|
||||
|
||||
function createModule() {
|
||||
var parentModule = config.moduleStack.length ? config.moduleStack.slice(-1)[0] : null;
|
||||
var moduleName = parentModule !== null ? [parentModule.name, name].join(" > ") : name;
|
||||
var parentSuite = parentModule ? parentModule.suiteReport : globalSuite;
|
||||
|
||||
var module = {
|
||||
name: moduleName,
|
||||
parentModule: parentModule,
|
||||
tests: [],
|
||||
moduleId: generateHash(moduleName),
|
||||
testsRun: 0,
|
||||
childModules: [],
|
||||
suiteReport: new SuiteReport(name, parentSuite)
|
||||
};
|
||||
|
||||
var env = {};
|
||||
if (parentModule) {
|
||||
parentModule.childModules.push(module);
|
||||
extend(env, parentModule.testEnvironment);
|
||||
delete env.beforeEach;
|
||||
delete env.afterEach;
|
||||
}
|
||||
extend(env, testEnvironment);
|
||||
module.testEnvironment = env;
|
||||
|
||||
config.modules.push(module);
|
||||
return module;
|
||||
}
|
||||
|
||||
function setCurrentModule(module) {
|
||||
config.currentModule = module;
|
||||
}
|
||||
config.currentModule = module;
|
||||
},
|
||||
|
||||
test: test,
|
||||
|
|
@ -2664,73 +2799,16 @@
|
|||
}
|
||||
|
||||
config.blocking = false;
|
||||
process(true);
|
||||
}
|
||||
|
||||
function process(last) {
|
||||
function next() {
|
||||
process(last);
|
||||
}
|
||||
var start = now();
|
||||
config.depth = (config.depth || 0) + 1;
|
||||
|
||||
while (config.queue.length && !config.blocking) {
|
||||
if (!defined.setTimeout || config.updateRate <= 0 || now() - start < config.updateRate) {
|
||||
if (config.current) {
|
||||
|
||||
// Reset async tracking for each phase of the Test lifecycle
|
||||
config.current.usedAsync = false;
|
||||
}
|
||||
config.queue.shift()();
|
||||
} else {
|
||||
setTimeout(next, 13);
|
||||
break;
|
||||
}
|
||||
}
|
||||
config.depth--;
|
||||
if (last && !config.blocking && !config.queue.length && config.depth === 0) {
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
function done() {
|
||||
var runtime,
|
||||
passed,
|
||||
i,
|
||||
key,
|
||||
storage = config.storage;
|
||||
|
||||
internalState.autorun = true;
|
||||
|
||||
runtime = now() - config.started;
|
||||
passed = config.stats.all - config.stats.bad;
|
||||
|
||||
emit("runEnd", globalSuite.end(true));
|
||||
runLoggingCallbacks("done", {
|
||||
failed: config.stats.bad,
|
||||
passed: passed,
|
||||
total: config.stats.all,
|
||||
runtime: runtime
|
||||
});
|
||||
|
||||
// Clear own storage items if all tests passed
|
||||
if (storage && config.stats.bad === 0) {
|
||||
for (i = storage.length - 1; i >= 0; i--) {
|
||||
key = storage.key(i);
|
||||
if (key.indexOf("qunit-test-") === 0) {
|
||||
storage.removeItem(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
ProcessingQueue.advance();
|
||||
}
|
||||
|
||||
function setHook(module, hookName) {
|
||||
if (module.testEnvironment === undefined) {
|
||||
module.testEnvironment = {};
|
||||
if (!module.hooks) {
|
||||
module.hooks = {};
|
||||
}
|
||||
|
||||
return function (callback) {
|
||||
module.testEnvironment[hookName] = callback;
|
||||
module.hooks[hookName] = callback;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -3588,13 +3666,19 @@
|
|||
|
||||
message += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText(actual) + "</pre></td></tr>";
|
||||
|
||||
// Don't show diff if actual or expected are booleans
|
||||
if (!/^(true|false)$/.test(actual) && !/^(true|false)$/.test(expected)) {
|
||||
if (typeof details.actual === "number" && typeof details.expected === "number") {
|
||||
if (!isNaN(details.actual) && !isNaN(details.expected)) {
|
||||
showDiff = true;
|
||||
diff = details.actual - details.expected;
|
||||
diff = (diff > 0 ? "+" : "") + diff;
|
||||
}
|
||||
} else if (typeof details.actual !== "boolean" && typeof details.expected !== "boolean") {
|
||||
diff = QUnit.diff(expected, actual);
|
||||
|
||||
// don't show diff if there is zero overlap
|
||||
showDiff = stripHtml(diff).length !== stripHtml(expected).length + stripHtml(actual).length;
|
||||
}
|
||||
|
||||
// Don't show diff if expected and actual are totally different
|
||||
if (showDiff) {
|
||||
message += "<tr class='test-diff'><th>Diff: </th><td><pre>" + diff + "</pre></td></tr>";
|
||||
}
|
||||
|
|
@ -3691,6 +3775,7 @@
|
|||
var todoLabel = document$$1.createElement("em");
|
||||
todoLabel.className = "qunit-todo-label";
|
||||
todoLabel.innerHTML = "todo";
|
||||
testItem.className += " todo";
|
||||
testItem.insertBefore(todoLabel, testTitle);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@
|
|||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jquery": ">=1.9.1",
|
||||
"popper.js": "^1.9.9"
|
||||
"popper.js": "^1.10.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^7.1.1",
|
||||
|
|
|
|||
|
|
@ -133,8 +133,7 @@
|
|||
.custom-select {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
$select-border-width: ($custom-select-border-width * 2);
|
||||
height: calc(#{$input-height} + #{$select-border-width});
|
||||
height: $input-height;
|
||||
padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x;
|
||||
line-height: $custom-select-line-height;
|
||||
color: $custom-select-color;
|
||||
|
|
@ -142,7 +141,11 @@
|
|||
background: $custom-select-bg $custom-select-indicator no-repeat right $custom-select-padding-x center;
|
||||
background-size: $custom-select-bg-size;
|
||||
border: $custom-select-border-width solid $custom-select-border-color;
|
||||
@include border-radius($custom-select-border-radius);
|
||||
@if $enable-rounded {
|
||||
border-radius: $custom-select-border-radius;
|
||||
} @else {
|
||||
border-radius: 0;
|
||||
}
|
||||
appearance: none;
|
||||
|
||||
&:focus {
|
||||
|
|
@ -173,14 +176,10 @@
|
|||
}
|
||||
|
||||
.custom-select-sm {
|
||||
height: $custom-select-height-sm;
|
||||
padding-top: $custom-select-padding-y;
|
||||
padding-bottom: $custom-select-padding-y;
|
||||
font-size: $custom-select-font-size-sm;
|
||||
|
||||
// &:not([multiple]) {
|
||||
// height: 26px;
|
||||
// min-height: 26px;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -62,8 +62,7 @@
|
|||
|
||||
select.form-control {
|
||||
&:not([size]):not([multiple]) {
|
||||
$select-border-width: ($border-width * 2);
|
||||
height: calc(#{$input-height} + #{$select-border-width});
|
||||
height: $input-height;
|
||||
}
|
||||
|
||||
&:focus::-ms-value {
|
||||
|
|
@ -123,12 +122,12 @@ select.form-control {
|
|||
}
|
||||
|
||||
|
||||
// Static form control text
|
||||
// Readonly controls as plain text
|
||||
//
|
||||
// Apply class to an element to make any string of text align with labels in a
|
||||
// horizontal form layout.
|
||||
// Apply class to a readonly input to make it appear like regular plain
|
||||
// text (without any border, background color, focus indicator)
|
||||
|
||||
.form-control-static {
|
||||
.form-control-plaintext {
|
||||
padding-top: $input-btn-padding-y;
|
||||
padding-bottom: $input-btn-padding-y;
|
||||
margin-bottom: 0; // match inputs if this class comes on inputs with default margins
|
||||
|
|
@ -161,8 +160,7 @@ select.form-control {
|
|||
|
||||
select.form-control-sm {
|
||||
&:not([size]):not([multiple]) {
|
||||
$select-border-width: ($border-width * 2);
|
||||
height: calc(#{$input-height-sm} + #{$select-border-width});
|
||||
height: $input-height-sm;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -175,8 +173,7 @@ select.form-control-sm {
|
|||
|
||||
select.form-control-lg {
|
||||
&:not([size]):not([multiple]) {
|
||||
$select-border-width: ($border-width * 2);
|
||||
height: calc(#{$input-height-lg} + #{$select-border-width});
|
||||
height: $input-height-lg;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -196,6 +193,24 @@ select.form-control-lg {
|
|||
}
|
||||
|
||||
|
||||
// Form grid
|
||||
//
|
||||
// Special replacement for our grid system's `.row` for tighter form layouts.
|
||||
|
||||
.form-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-right: -5px;
|
||||
margin-left: -5px;
|
||||
|
||||
> .col,
|
||||
> [class*="col-"] {
|
||||
padding-right: 5px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Checkboxes and radios
|
||||
//
|
||||
// Indent the labels to position radios/checkboxes as hanging controls.
|
||||
|
|
@ -241,48 +256,37 @@ select.form-control-lg {
|
|||
}
|
||||
|
||||
|
||||
// Form control feedback states
|
||||
// Form validation
|
||||
//
|
||||
// Apply contextual and semantic states to individual form controls.
|
||||
// Provide feedback to users when form field values are valid or invalid. Works
|
||||
// primarily for client-side validation via scoped `:invalid` and `:valid`
|
||||
// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for
|
||||
// server side validation.
|
||||
|
||||
.form-control-feedback {
|
||||
margin-top: $form-feedback-margin-top;
|
||||
.invalid-feedback {
|
||||
display: none;
|
||||
margin-top: .25rem;
|
||||
font-size: .875rem;
|
||||
color: $form-feedback-invalid-color;
|
||||
}
|
||||
|
||||
.form-control-success,
|
||||
.form-control-warning,
|
||||
.form-control-danger {
|
||||
padding-right: ($input-btn-padding-x * 3);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center right ($input-height / 4);
|
||||
background-size: ($input-height / 2) ($input-height / 2);
|
||||
}
|
||||
|
||||
// Form validation states
|
||||
.has-success {
|
||||
@include form-control-validation($brand-success);
|
||||
|
||||
.form-control-success {
|
||||
background-image: $form-icon-success;
|
||||
}
|
||||
}
|
||||
|
||||
.has-warning {
|
||||
@include form-control-validation($brand-warning);
|
||||
|
||||
.form-control-warning {
|
||||
background-image: $form-icon-warning;
|
||||
}
|
||||
}
|
||||
|
||||
.has-danger {
|
||||
@include form-control-validation($brand-danger);
|
||||
|
||||
.form-control-danger {
|
||||
background-image: $form-icon-danger;
|
||||
}
|
||||
.invalid-tooltip {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
z-index: 5;
|
||||
display: none;
|
||||
width: 250px;
|
||||
padding: .5rem;
|
||||
margin-top: .1rem;
|
||||
font-size: .875rem;
|
||||
line-height: 1;
|
||||
color: #fff;
|
||||
background-color: rgba($form-feedback-invalid-color,.8);
|
||||
border-radius: .2rem;
|
||||
}
|
||||
|
||||
@include form-validation-state("valid", $form-feedback-valid-color);
|
||||
@include form-validation-state("invalid", $form-feedback-invalid-color);
|
||||
|
||||
// Inline forms
|
||||
//
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@ $table-inverse-color: $body-bg !default;
|
|||
// For each of Bootstrap's buttons, define text, background and border color.
|
||||
|
||||
$input-btn-padding-y: .5rem !default;
|
||||
$input-btn-padding-x: 1rem !default;
|
||||
$input-btn-padding-x: .75rem !default;
|
||||
$input-btn-line-height: 1.25 !default;
|
||||
|
||||
$input-btn-padding-y-sm: .25rem !default;
|
||||
|
|
@ -354,7 +354,7 @@ $input-btn-line-height-lg: 1.5 !default;
|
|||
|
||||
$btn-font-weight: $font-weight-normal !default;
|
||||
$btn-box-shadow: inset 0 1px 0 rgba($white,.15), 0 1px 1px rgba($black,.075) !default;
|
||||
$btn-focus-box-shadow: 0 0 0 2px rgba($brand-primary, .25) !default;
|
||||
$btn-focus-box-shadow: 0 0 0 3px rgba($brand-primary, .25) !default;
|
||||
$btn-active-box-shadow: inset 0 3px 5px rgba($black,.125) !default;
|
||||
|
||||
$btn-primary-color: $white !default;
|
||||
|
|
@ -409,14 +409,21 @@ $input-border-radius-sm: $border-radius-sm !default;
|
|||
|
||||
$input-focus-bg: $input-bg !default;
|
||||
$input-focus-border-color: lighten($brand-primary, 25%) !default;
|
||||
$input-focus-box-shadow: $input-box-shadow, rgba($input-focus-border-color, .6) !default;
|
||||
$input-focus-box-shadow: $input-box-shadow, $btn-focus-box-shadow !default;
|
||||
$input-focus-color: $input-color !default;
|
||||
|
||||
$input-placeholder-color: $gray-light !default;
|
||||
|
||||
$input-height: (($font-size-base * $input-btn-line-height) + ($input-btn-padding-y * 2)) !default;
|
||||
$input-height-lg: (($font-size-lg * $input-btn-line-height-lg) + ($input-btn-padding-y-lg * 2)) !default;
|
||||
$input-height-sm: (($font-size-sm * $input-btn-line-height-sm) + ($input-btn-padding-y-sm * 2)) !default;
|
||||
$input-height-border: $input-btn-border-width * 2 !default;
|
||||
|
||||
$input-height-inner: ($font-size-base * $input-btn-line-height) + ($input-btn-padding-y * 2) !default;
|
||||
$input-height: calc(#{$input-height-inner} + #{$input-height-border}) !default;
|
||||
|
||||
$input-height-inner-sm: ($font-size-sm * $input-btn-line-height-sm) + ($input-btn-padding-y-sm * 2) !default;
|
||||
$input-height-sm: calc(#{$input-height-inner-sm} + #{$input-height-border}) !default;
|
||||
|
||||
$input-height-inner-lg: ($font-size-sm * $input-btn-line-height-lg) + ($input-btn-padding-y-lg * 2) !default;
|
||||
$input-height-lg: calc(#{$input-height-inner-lg} + #{$input-height-border}) !default;
|
||||
|
||||
$input-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s !default;
|
||||
|
||||
|
|
@ -470,6 +477,7 @@ $custom-radio-icon-checked: str-replace(url("data:image/svg+xml;charset=utf8,%3C
|
|||
|
||||
$custom-select-padding-y: .375rem !default;
|
||||
$custom-select-padding-x: .75rem !default;
|
||||
$custom-select-height: $input-height !default;
|
||||
$custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator
|
||||
$custom-select-line-height: $input-btn-line-height !default;
|
||||
$custom-select-color: $input-color !default;
|
||||
|
|
@ -487,6 +495,7 @@ $custom-select-focus-border-color: lighten($brand-primary, 25%) !default;
|
|||
$custom-select-focus-box-shadow: inset 0 1px 2px rgba($black, .075), 0 0 5px rgba($custom-select-focus-border-color, .5) !default;
|
||||
|
||||
$custom-select-font-size-sm: 75% !default;
|
||||
$custom-select-height-sm: $input-height-sm !default;
|
||||
|
||||
$custom-file-height: 2.5rem !default;
|
||||
$custom-file-width: 14rem !default;
|
||||
|
|
@ -513,15 +522,9 @@ $custom-file-text: (
|
|||
) !default;
|
||||
|
||||
|
||||
// Form validation icons
|
||||
$form-icon-success-color: $brand-success !default;
|
||||
$form-icon-success: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#{$form-icon-success-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E"), "#", "%23") !default;
|
||||
|
||||
$form-icon-warning-color: $brand-warning !default;
|
||||
$form-icon-warning: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#{$form-icon-warning-color}' d='M4.4 5.324h-.8v-2.46h.8zm0 1.42h-.8V5.89h.8zM3.76.63L.04 7.075c-.115.2.016.425.26.426h7.397c.242 0 .372-.226.258-.426C6.726 4.924 5.47 2.79 4.253.63c-.113-.174-.39-.174-.494 0z'/%3E%3C/svg%3E"), "#", "%23") !default;
|
||||
|
||||
$form-icon-danger-color: $brand-danger !default;
|
||||
$form-icon-danger: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$form-icon-danger-color}' viewBox='-2 -2 7 7'%3E%3Cpath stroke='#{$form-icon-danger-color}' d='M0 0l3 3m0-3L0 3'/%3E%3Ccircle r='.5'/%3E%3Ccircle cx='3' r='.5'/%3E%3Ccircle cy='3' r='.5'/%3E%3Ccircle cx='3' cy='3' r='.5'/%3E%3C/svg%3E"), "#", "%23") !default;
|
||||
// Form validation
|
||||
$form-feedback-valid-color: $brand-success !default;
|
||||
$form-feedback-invalid-color: $brand-danger !default;
|
||||
|
||||
|
||||
// Dropdowns
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@
|
|||
&.focus {
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
@if $enable-shadows {
|
||||
box-shadow: $btn-box-shadow, 0 0 0 2px rgba($border, .5);
|
||||
box-shadow: $btn-box-shadow, 0 0 0 3px rgba($border, .5);
|
||||
} @else {
|
||||
box-shadow: 0 0 0 2px rgba($border, .5);
|
||||
box-shadow: 0 0 0 3px rgba($border, .5);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
|
||||
&:focus,
|
||||
&.focus {
|
||||
box-shadow: 0 0 0 2px rgba($color, .5);
|
||||
box-shadow: 0 0 0 3px rgba($color, .5);
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
|
|
|
|||
|
|
@ -1,37 +1,3 @@
|
|||
// Form validation states
|
||||
//
|
||||
// Used in _forms.scss to generate the form validation CSS for warnings, errors,
|
||||
// and successes.
|
||||
|
||||
@mixin form-control-validation($color) {
|
||||
// Color the label and help text
|
||||
.form-control-feedback,
|
||||
.form-control-label,
|
||||
.col-form-label,
|
||||
.form-check-label,
|
||||
.custom-control {
|
||||
color: $color;
|
||||
}
|
||||
|
||||
// Set the border and box shadow on specific inputs to match
|
||||
.form-control,
|
||||
.custom-select,
|
||||
.custom-file-control {
|
||||
border-color: $color;
|
||||
|
||||
&:focus {
|
||||
@include box-shadow($input-box-shadow, 0 0 6px lighten($color, 20%));
|
||||
}
|
||||
}
|
||||
|
||||
// Set validation states also for addons
|
||||
.input-group-addon {
|
||||
color: $color;
|
||||
background-color: lighten($color, 40%);
|
||||
border-color: $color;
|
||||
}
|
||||
}
|
||||
|
||||
// Form control focus state
|
||||
//
|
||||
// Generate a customized focus state and for any input with the specified color,
|
||||
|
|
@ -53,3 +19,63 @@
|
|||
@include box-shadow($input-focus-box-shadow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@mixin form-validation-state($state, $color) {
|
||||
|
||||
.form-control,
|
||||
.custom-select {
|
||||
.was-validated &:#{$state},
|
||||
&.is-#{$state} {
|
||||
border-color: $color;
|
||||
|
||||
&:focus {
|
||||
box-shadow: 0 0 0 .2rem rgba($color,.25);
|
||||
}
|
||||
|
||||
~ .invalid-feedback,
|
||||
~ .invalid-tooltip {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: redo check markup lol crap
|
||||
.form-check-input {
|
||||
.was-validated &:#{$state},
|
||||
&.is-#{$state} {
|
||||
+ .form-check-label {
|
||||
color: $color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// custom radios and checks
|
||||
.custom-control-input {
|
||||
.was-validated &:#{$state},
|
||||
&.is-#{$state} {
|
||||
~ .custom-control-indicator {
|
||||
background-color: rgba($color, .25);
|
||||
}
|
||||
~ .custom-control-description {
|
||||
color: $color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// custom file
|
||||
.custom-file-input {
|
||||
.was-validated &:#{$state},
|
||||
&.is-#{$state} {
|
||||
~ .custom-file-control {
|
||||
border-color: $color;
|
||||
|
||||
&::before { border-color: inherit; }
|
||||
}
|
||||
&:focus {
|
||||
box-shadow: 0 0 0 .2rem rgba($color,.25);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue