aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Otto <[email protected]>2017-05-01 21:54:50 -0700
committerGitHub <[email protected]>2017-05-01 21:54:50 -0700
commit8c7fe6cf147e98fb5d8096f6e6536bcb4e207586 (patch)
treed33635083f70814945e92cb17957b6c522073379
parentca44f5b03a9707dda74e1aa3f92a1b54de3ec6d5 (diff)
parente00de46540818fa11feb6d1f0e8b0089ba56f082 (diff)
downloadbootstrap-8c7fe6cf147e98fb5d8096f6e6536bcb4e207586.tar.xz
bootstrap-8c7fe6cf147e98fb5d8096f6e6536bcb4e207586.zip
Merge branch 'v4-dev' into form-tweaks
-rw-r--r--docs/.htmllintrc1
-rw-r--r--docs/components/carousel.md98
-rw-r--r--docs/components/collapse.md78
-rw-r--r--docs/components/forms.md14
-rw-r--r--docs/components/list-group.md12
-rw-r--r--docs/components/modal.md100
-rw-r--r--docs/components/navs.md12
-rw-r--r--docs/components/popovers.md10
-rw-r--r--docs/components/scrollspy.md40
-rw-r--r--docs/components/tooltips.md8
-rw-r--r--docs/examples/jumbotron/index.html2
-rw-r--r--docs/examples/justified-nav/index.html2
-rw-r--r--docs/getting-started/build-tools.md2
-rw-r--r--docs/getting-started/introduction.md4
-rw-r--r--js/src/button.js6
-rw-r--r--js/src/collapse.js16
-rw-r--r--js/src/tab.js2
-rw-r--r--js/tests/unit/button.js17
-rw-r--r--js/tests/unit/collapse.js76
-rw-r--r--package.json14
20 files changed, 294 insertions, 220 deletions
diff --git a/docs/.htmllintrc b/docs/.htmllintrc
index e15284536..d88560faa 100644
--- a/docs/.htmllintrc
+++ b/docs/.htmllintrc
@@ -9,6 +9,7 @@
"html-valid-content-model": false,
"id-class-ignore-regex": "(onclick|content|[a-z]+([A-Z][a-z])+)",
"id-class-style": "dash",
+ "img-req-src": false,
"img-req-alt": false,
"indent-style": "spaces",
"indent-width": 2,
diff --git a/docs/components/carousel.md b/docs/components/carousel.md
index ab84bf460..af00dc526 100644
--- a/docs/components/carousel.md
+++ b/docs/components/carousel.md
@@ -186,45 +186,45 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
<table class="table table-bordered table-striped table-responsive">
<thead>
- <tr>
- <th style="width: 100px;">Name</th>
- <th style="width: 50px;">Type</th>
- <th style="width: 50px;">Default</th>
- <th>Description</th>
- </tr>
+ <tr>
+ <th style="width: 100px;">Name</th>
+ <th style="width: 50px;">Type</th>
+ <th style="width: 50px;">Default</th>
+ <th>Description</th>
+ </tr>
</thead>
<tbody>
- <tr>
- <td>interval</td>
- <td>number</td>
- <td>5000</td>
- <td>The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle.</td>
- </tr>
- <tr>
- <td>keyboard</td>
- <td>boolean</td>
- <td>true</td>
- <td>Whether the carousel should react to keyboard events.</td>
- </tr>
- <tr>
- <td>pause</td>
- <td>string | boolean</td>
- <td>"hover"</td>
- <td><p>If set to <code>"hover"</code>, pauses the cycling of the carousel on <code>mouseenter</code> and resumes the cycling of the carousel on <code>mouseleave</code>. If set to <code>false</code>, hovering over the carousel won't pause it.</p>
- <p>On touch-enabled devices, when set to <code>"hover"</code>, cycling will pause on <code>touchend</code> (once the user finished interacting with the carousel) for two intervals, before automatically resuming. Note that this is in addition to the above mouse behavior.</p></td>
- </tr>
- <tr>
- <td>ride</td>
- <td>string</td>
- <td>false</td>
- <td>Autoplays the carousel after the user manually cycles the first item. If "carousel", autoplays the carousel on load.</td>
- </tr>
- <tr>
- <td>wrap</td>
- <td>boolean</td>
- <td>true</td>
- <td>Whether the carousel should cycle continuously or have hard stops.</td>
- </tr>
+ <tr>
+ <td>interval</td>
+ <td>number</td>
+ <td>5000</td>
+ <td>The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle.</td>
+ </tr>
+ <tr>
+ <td>keyboard</td>
+ <td>boolean</td>
+ <td>true</td>
+ <td>Whether the carousel should react to keyboard events.</td>
+ </tr>
+ <tr>
+ <td>pause</td>
+ <td>string | boolean</td>
+ <td>"hover"</td>
+ <td><p>If set to <code>"hover"</code>, pauses the cycling of the carousel on <code>mouseenter</code> and resumes the cycling of the carousel on <code>mouseleave</code>. If set to <code>false</code>, hovering over the carousel won't pause it.</p>
+ <p>On touch-enabled devices, when set to <code>"hover"</code>, cycling will pause on <code>touchend</code> (once the user finished interacting with the carousel) for two intervals, before automatically resuming. Note that this is in addition to the above mouse behavior.</p></td>
+ </tr>
+ <tr>
+ <td>ride</td>
+ <td>string</td>
+ <td>false</td>
+ <td>Autoplays the carousel after the user manually cycles the first item. If "carousel", autoplays the carousel on load.</td>
+ </tr>
+ <tr>
+ <td>wrap</td>
+ <td>boolean</td>
+ <td>true</td>
+ <td>Whether the carousel should cycle continuously or have hard stops.</td>
+ </tr>
</tbody>
</table>
@@ -276,20 +276,20 @@ All carousel events are fired at the carousel itself (i.e. at the `<div class="c
<table class="table table-bordered table-striped table-responsive">
<thead>
- <tr>
- <th style="width: 150px;">Event Type</th>
- <th>Description</th>
- </tr>
+ <tr>
+ <th style="width: 150px;">Event Type</th>
+ <th>Description</th>
+ </tr>
</thead>
<tbody>
- <tr>
- <td>slide.bs.carousel</td>
- <td>This event fires immediately when the <code>slide</code> instance method is invoked.</td>
- </tr>
- <tr>
- <td>slid.bs.carousel</td>
- <td>This event is fired when the carousel has completed its slide transition.</td>
- </tr>
+ <tr>
+ <td>slide.bs.carousel</td>
+ <td>This event fires immediately when the <code>slide</code> instance method is invoked.</td>
+ </tr>
+ <tr>
+ <td>slid.bs.carousel</td>
+ <td>This event is fired when the carousel has completed its slide transition.</td>
+ </tr>
</tbody>
</table>
diff --git a/docs/components/collapse.md b/docs/components/collapse.md
index a86678ad1..65b8171bd 100644
--- a/docs/components/collapse.md
+++ b/docs/components/collapse.md
@@ -153,26 +153,26 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
<table class="table table-bordered table-striped table-responsive">
<thead>
- <tr>
- <th style="width: 100px;">Name</th>
- <th style="width: 50px;">Type</th>
- <th style="width: 50px;">Default</th>
- <th>Description</th>
- </tr>
+ <tr>
+ <th style="width: 100px;">Name</th>
+ <th style="width: 50px;">Type</th>
+ <th style="width: 50px;">Default</th>
+ <th>Description</th>
+ </tr>
</thead>
<tbody>
- <tr>
- <td>parent</td>
- <td>selector</td>
- <td>false</td>
- <td>If a selector is provided, then all collapsible elements under the specified parent will be closed when this collapsible item is shown. (similar to traditional accordion behavior - this is dependent on the <code>card</code> class). The attribute has to be set on the target collapsible area.</td>
- </tr>
- <tr>
- <td>toggle</td>
- <td>boolean</td>
- <td>true</td>
- <td>Toggles the collapsible element on invocation</td>
- </tr>
+ <tr>
+ <td>parent</td>
+ <td>selector</td>
+ <td>false</td>
+ <td>If a selector is provided, then all collapsible elements under the specified parent will be closed when this collapsible item is shown. (similar to traditional accordion behavior - this is dependent on the <code>card</code> class). The attribute has to be set on the target collapsible area.</td>
+ </tr>
+ <tr>
+ <td>toggle</td>
+ <td>boolean</td>
+ <td>true</td>
+ <td>Toggles the collapsible element on invocation</td>
+ </tr>
</tbody>
</table>
@@ -209,30 +209,28 @@ Bootstrap's collapse class exposes a few events for hooking into collapse functi
<table class="table table-bordered table-striped table-responsive">
<thead>
- <tr>
- <th style="width: 150px;">Event Type</th>
- <th>Description</th>
- </tr>
+ <tr>
+ <th style="width: 150px;">Event Type</th>
+ <th>Description</th>
+ </tr>
</thead>
<tbody>
- <tr>
- <td>show.bs.collapse</td>
- <td>This event fires immediately when the <code>show</code> instance method is called.</td>
- </tr>
- <tr>
- <td>shown.bs.collapse</td>
- <td>This event is fired when a collapse element has been made visible to the user (will wait for CSS transitions to complete).</td>
- </tr>
- <tr>
- <td>hide.bs.collapse</td>
- <td>
- This event is fired immediately when the <code>hide</code> method has been called.
- </td>
- </tr>
- <tr>
- <td>hidden.bs.collapse</td>
- <td>This event is fired when a collapse element has been hidden from the user (will wait for CSS transitions to complete).</td>
- </tr>
+ <tr>
+ <td>show.bs.collapse</td>
+ <td>This event fires immediately when the <code>show</code> instance method is called.</td>
+ </tr>
+ <tr>
+ <td>shown.bs.collapse</td>
+ <td>This event is fired when a collapse element has been made visible to the user (will wait for CSS transitions to complete).</td>
+ </tr>
+ <tr>
+ <td>hide.bs.collapse</td>
+ <td>This event is fired immediately when the <code>hide</code> method has been called.</td>
+ </tr>
+ <tr>
+ <td>hidden.bs.collapse</td>
+ <td>This event is fired when a collapse element has been hidden from the user (will wait for CSS transitions to complete).</td>
+ </tr>
</tbody>
</table>
diff --git a/docs/components/forms.md b/docs/components/forms.md
index 53654fac2..fd87dec7a 100644
--- a/docs/components/forms.md
+++ b/docs/components/forms.md
@@ -376,7 +376,7 @@ Be sure to add `.col-form-label` to your `<label>`s as well so they're verticall
</div>
</fieldset>
<div class="form-group row">
- <label class="col-sm-2">Checkbox</label>
+ <div class="col-sm-2">Checkbox</div>
<div class="col-sm-10">
<div class="form-check">
<label class="form-check-label">
@@ -569,14 +569,14 @@ Should you have no text within the `<label>`, the input is positioned as you'd e
## Static controls
-When you need to place plain text next to a form label within a form, use the `.form-control-static` class on an element of your choice.
+If you want to have read-only fields in your form styled as plain text, use the `.form-control-static` class to remove the default form field styling and preserve the correct margin and padding.
{% example html %}
<form>
<div class="form-group row">
- <label class="col-sm-2 col-form-label">Email</label>
+ <label for="staticEmail" class="col-sm-2 col-form-label">Email</label>
<div class="col-sm-10">
- <p class="form-control-static">[email protected]</p>
+ <input type="text" readonly class="form-control-static" id="staticEmail" value="[email protected]">
</div>
</div>
<div class="form-group row">
@@ -591,8 +591,8 @@ When you need to place plain text next to a form label within a form, use the `.
{% example html %}
<form class="form-inline">
<div class="form-group">
- <label class="sr-only">Email</label>
- <p class="form-control-static">[email protected]</p>
+ <label for="staticEmail2" class="sr-only">Email</label>
+ <input type="text" readonly class="form-control-static" id="staticEmail2" value="[email protected]">
</div>
<div class="form-group mx-sm-3">
<label for="inputPassword2" class="sr-only">Password</label>
@@ -604,7 +604,7 @@ When you need to place plain text next to a form label within a form, use the `.
## Disabled states
-Add the `disabled` boolean attribute on an input to prevent user interactions. Disabled inputs appear lighter and add a `not-allowed` cursor.
+Add the `disabled` boolean attribute on an input to prevent user interactions and make it appear lighter.
{% highlight html %}
<input class="form-control" id="disabledInput" type="text" placeholder="Disabled input here..." disabled>
diff --git a/docs/components/list-group.md b/docs/components/list-group.md
index fcaa364fb..dcf605aee 100644
--- a/docs/components/list-group.md
+++ b/docs/components/list-group.md
@@ -328,17 +328,17 @@ If no tab was already active, the `hide.bs.tab` and `hidden.bs.tab` events will
<table class="table table-bordered table-striped table-responsive">
<thead>
- <tr>
- <th style="width: 150px;">Event type</th>
- <th>Description</th>
- </tr>
+ <tr>
+ <th style="width: 150px;">Event type</th>
+ <th>Description</th>
+ </tr>
</thead>
<tbody>
<tr>
<td>show.bs.tab</td>
<td>This event fires on tab show, but before the new tab has been shown. Use <code>event.target</code> and <code>event.relatedTarget</code> to target the active tab and the previous active tab (if available) respectively.</td>
- </tr>
- <tr>
+ </tr>
+ <tr>
<td>shown.bs.tab</td>
<td>This event fires on tab show after a tab has been shown. Use <code>event.target</code> and <code>event.relatedTarget</code> to target the active tab and the previous active tab (if available) respectively.</td>
</tr>
diff --git a/docs/components/modal.md b/docs/components/modal.md
index 19254b880..a2f4471d3 100644
--- a/docs/components/modal.md
+++ b/docs/components/modal.md
@@ -510,38 +510,38 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
<table class="table table-bordered table-striped table-responsive">
<thead>
- <tr>
- <th style="width: 100px;">Name</th>
- <th style="width: 50px;">Type</th>
- <th style="width: 50px;">Default</th>
- <th>Description</th>
- </tr>
+ <tr>
+ <th style="width: 100px;">Name</th>
+ <th style="width: 50px;">Type</th>
+ <th style="width: 50px;">Default</th>
+ <th>Description</th>
+ </tr>
</thead>
<tbody>
- <tr>
- <td>backdrop</td>
- <td>boolean or the string <code>'static'</code></td>
- <td>true</td>
- <td>Includes a modal-backdrop element. Alternatively, specify <code>static</code> for a backdrop which doesn't close the modal on click.</td>
- </tr>
- <tr>
- <td>keyboard</td>
- <td>boolean</td>
- <td>true</td>
- <td>Closes the modal when escape key is pressed</td>
- </tr>
- <tr>
- <td>focus</td>
- <td>boolean</td>
- <td>true</td>
- <td>Puts the focus on the modal when initialized.</td>
- </tr>
- <tr>
- <td>show</td>
- <td>boolean</td>
- <td>true</td>
- <td>Shows the modal when initialized.</td>
- </tr>
+ <tr>
+ <td>backdrop</td>
+ <td>boolean or the string <code>'static'</code></td>
+ <td>true</td>
+ <td>Includes a modal-backdrop element. Alternatively, specify <code>static</code> for a backdrop which doesn't close the modal on click.</td>
+ </tr>
+ <tr>
+ <td>keyboard</td>
+ <td>boolean</td>
+ <td>true</td>
+ <td>Closes the modal when escape key is pressed</td>
+ </tr>
+ <tr>
+ <td>focus</td>
+ <td>boolean</td>
+ <td>true</td>
+ <td>Puts the focus on the modal when initialized.</td>
+ </tr>
+ <tr>
+ <td>show</td>
+ <td>boolean</td>
+ <td>true</td>
+ <td>Shows the modal when initialized.</td>
+ </tr>
</tbody>
</table>
@@ -590,28 +590,28 @@ Bootstrap's modal class exposes a few events for hooking into modal functionalit
<table class="table table-bordered table-striped table-responsive">
<thead>
- <tr>
- <th style="width: 150px;">Event Type</th>
- <th>Description</th>
- </tr>
+ <tr>
+ <th style="width: 150px;">Event Type</th>
+ <th>Description</th>
+ </tr>
</thead>
<tbody>
- <tr>
- <td>show.bs.modal</td>
- <td>This event fires immediately when the <code>show</code> instance method is called. If caused by a click, the clicked element is available as the <code>relatedTarget</code> property of the event.</td>
- </tr>
- <tr>
- <td>shown.bs.modal</td>
- <td>This event is fired when the modal has been made visible to the user (will wait for CSS transitions to complete). If caused by a click, the clicked element is available as the <code>relatedTarget</code> property of the event.</td>
- </tr>
- <tr>
- <td>hide.bs.modal</td>
- <td>This event is fired immediately when the <code>hide</code> instance method has been called.</td>
- </tr>
- <tr>
- <td>hidden.bs.modal</td>
- <td>This event is fired when the modal has finished being hidden from the user (will wait for CSS transitions to complete).</td>
- </tr>
+ <tr>
+ <td>show.bs.modal</td>
+ <td>This event fires immediately when the <code>show</code> instance method is called. If caused by a click, the clicked element is available as the <code>relatedTarget</code> property of the event.</td>
+ </tr>
+ <tr>
+ <td>shown.bs.modal</td>
+ <td>This event is fired when the modal has been made visible to the user (will wait for CSS transitions to complete). If caused by a click, the clicked element is available as the <code>relatedTarget</code> property of the event.</td>
+ </tr>
+ <tr>
+ <td>hide.bs.modal</td>
+ <td>This event is fired immediately when the <code>hide</code> instance method has been called.</td>
+ </tr>
+ <tr>
+ <td>hidden.bs.modal</td>
+ <td>This event is fired when the modal has finished being hidden from the user (will wait for CSS transitions to complete).</td>
+ </tr>
</tbody>
</table>
diff --git a/docs/components/navs.md b/docs/components/navs.md
index 9ab2535ed..e92906229 100644
--- a/docs/components/navs.md
+++ b/docs/components/navs.md
@@ -636,17 +636,17 @@ If no tab was already active, then the `hide.bs.tab` and `hidden.bs.tab` events
<table class="table table-bordered table-striped table-responsive">
<thead>
- <tr>
- <th style="width: 150px;">Event Type</th>
- <th>Description</th>
- </tr>
+ <tr>
+ <th style="width: 150px;">Event Type</th>
+ <th>Description</th>
+ </tr>
</thead>
<tbody>
<tr>
<td>show.bs.tab</td>
<td>This event fires on tab show, but before the new tab has been shown. Use <code>event.target</code> and <code>event.relatedTarget</code> to target the active tab and the previous active tab (if available) respectively.</td>
- </tr>
- <tr>
+ </tr>
+ <tr>
<td>shown.bs.tab</td>
<td>This event fires on tab show after a tab has been shown. Use <code>event.target</code> and <code>event.relatedTarget</code> to target the active tab and the previous active tab (if available) respectively.</td>
</tr>
diff --git a/docs/components/popovers.md b/docs/components/popovers.md
index cc1b0fe2e..307b4cb6d 100644
--- a/docs/components/popovers.md
+++ b/docs/components/popovers.md
@@ -201,9 +201,9 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
<td>number | object</td>
<td>0</td>
<td>
- <p>Delay showing and hiding the popover (ms) - does not apply to manual trigger type</p>
- <p>If a number is supplied, delay is applied to both hide/show</p>
- <p>Object structure is: <code>delay: { "show": 500, "hide": 100 }</code></p>
+ <p>Delay showing and hiding the popover (ms) - does not apply to manual trigger type</p>
+ <p>If a number is supplied, delay is applied to both hide/show</p>
+ <p>Object structure is: <code>delay: { "show": 500, "hide": 100 }</code></p>
</td>
</tr>
<tr>
@@ -331,10 +331,10 @@ Toggles the ability for an element's popover to be shown or hidden.
<table class="table table-bordered table-striped table-responsive">
<thead>
- <tr>
+ <tr>
<th style="width: 150px;">Event Type</th>
<th>Description</th>
- </tr>
+ </tr>
</thead>
<tbody>
<tr>
diff --git a/docs/components/scrollspy.md b/docs/components/scrollspy.md
index ecabd51c5..80c057161 100644
--- a/docs/components/scrollspy.md
+++ b/docs/components/scrollspy.md
@@ -292,20 +292,20 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
<table class="table table-bordered table-striped table-responsive">
<thead>
- <tr>
- <th style="width: 100px;">Name</th>
- <th style="width: 100px;">Type</th>
- <th style="width: 50px;">Default</th>
- <th>Description</th>
- </tr>
+ <tr>
+ <th style="width: 100px;">Name</th>
+ <th style="width: 100px;">Type</th>
+ <th style="width: 50px;">Default</th>
+ <th>Description</th>
+ </tr>
</thead>
<tbody>
- <tr>
- <td>offset</td>
- <td>number</td>
- <td>10</td>
- <td>Pixels to offset from top when calculating position of scroll.</td>
- </tr>
+ <tr>
+ <td>offset</td>
+ <td>number</td>
+ <td>10</td>
+ <td>Pixels to offset from top when calculating position of scroll.</td>
+ </tr>
</tbody>
</table>
@@ -313,16 +313,16 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
<table class="table table-bordered table-striped table-responsive">
<thead>
- <tr>
- <th style="width: 150px;">Event Type</th>
- <th>Description</th>
- </tr>
+ <tr>
+ <th style="width: 150px;">Event Type</th>
+ <th>Description</th>
+ </tr>
</thead>
<tbody>
- <tr>
- <td>activate.bs.scrollspy</td>
- <td>This event fires whenever a new item becomes activated by the scrollspy.</td>
- </tr>
+ <tr>
+ <td>activate.bs.scrollspy</td>
+ <td>This event fires whenever a new item becomes activated by the scrollspy.</td>
+ </tr>
</tbody>
</table>
diff --git a/docs/components/tooltips.md b/docs/components/tooltips.md
index 7c7f9af8b..55de9a886 100644
--- a/docs/components/tooltips.md
+++ b/docs/components/tooltips.md
@@ -168,16 +168,16 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
<td>false</td>
<td>
<p>Appends the tooltip to a specific element. Example: <code>container: 'body'</code>. This option is particularly useful in that it allows you to position the tooltip in the flow of the document near the triggering element - which will prevent the tooltip from floating away from the triggering element during a window resize.</p>
- </td>
+ </td>
</tr>
<tr>
<td>delay</td>
<td>number | object</td>
<td>0</td>
<td>
- <p>Delay showing and hiding the tooltip (ms) - does not apply to manual trigger type</p>
- <p>If a number is supplied, delay is applied to both hide/show</p>
- <p>Object structure is: <code>delay: { "show": 500, "hide": 100 }</code></p>
+ <p>Delay showing and hiding the tooltip (ms) - does not apply to manual trigger type</p>
+ <p>If a number is supplied, delay is applied to both hide/show</p>
+ <p>Object structure is: <code>delay: { "show": 500, "hide": 100 }</code></p>
</td>
</tr>
<tr>
diff --git a/docs/examples/jumbotron/index.html b/docs/examples/jumbotron/index.html
index 8ac227e23..35c308d14 100644
--- a/docs/examples/jumbotron/index.html
+++ b/docs/examples/jumbotron/index.html
@@ -72,7 +72,7 @@
<h2>Heading</h2>
<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
<p><a class="btn btn-secondary" href="#" role="button">View details &raquo;</a></p>
- </div>
+ </div>
<div class="col-md-4">
<h2>Heading</h2>
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
diff --git a/docs/examples/justified-nav/index.html b/docs/examples/justified-nav/index.html
index 0fcbf0856..23615bd60 100644
--- a/docs/examples/justified-nav/index.html
+++ b/docs/examples/justified-nav/index.html
@@ -75,7 +75,7 @@
<h2>Heading</h2>
<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
<p><a class="btn btn-primary" href="#" role="button">View details &raquo;</a></p>
- </div>
+ </div>
<div class="col-lg-4">
<h2>Heading</h2>
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa.</p>
diff --git a/docs/getting-started/build-tools.md b/docs/getting-started/build-tools.md
index 8c5b635b3..3482bb617 100644
--- a/docs/getting-started/build-tools.md
+++ b/docs/getting-started/build-tools.md
@@ -5,7 +5,7 @@ description: Details on how to use Bootstrap's included build tools to compile s
group: getting-started
---
-Bootstrap uses [NPM scripts](https://docs.npmjs.com/misc/scripts) for its build system. Our [package.json](https://github.com/twbs/bootstrap/blob/master/package.json) includes convenient methods for working with the framework, including compiling code, running tests, and more.
+Bootstrap uses [NPM scripts](https://docs.npmjs.com/misc/scripts) for its build system. Our [package.json](https://github.com/twbs/bootstrap/blob/v4-dev/package.json) includes convenient methods for working with the framework, including compiling code, running tests, and more.
## Contents
diff --git a/docs/getting-started/introduction.md b/docs/getting-started/introduction.md
index d70a42627..0ca845a8a 100644
--- a/docs/getting-started/introduction.md
+++ b/docs/getting-started/introduction.md
@@ -96,9 +96,7 @@ On the rare occasion you need to override it, use something like the following:
{% highlight scss %}
.selector-for-some-widget {
- -webkit-box-sizing: content-box;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
+ box-sizing: content-box;
}
{% endhighlight %}
diff --git a/js/src/button.js b/js/src/button.js
index 6295d0db0..722fd489d 100644
--- a/js/src/button.js
+++ b/js/src/button.js
@@ -90,6 +90,12 @@ const Button = (($) => {
}
if (triggerChangeEvent) {
+ if (input.hasAttribute('disabled') ||
+ rootElement.hasAttribute('disabled') ||
+ input.classList.contains('disabled') ||
+ rootElement.classList.contains('disabled')) {
+ return
+ }
input.checked = !$(this._element).hasClass(ClassName.ACTIVE)
$(input).trigger('change')
}
diff --git a/js/src/collapse.js b/js/src/collapse.js
index dec272297..bf1c738f5 100644
--- a/js/src/collapse.js
+++ b/js/src/collapse.js
@@ -56,9 +56,8 @@ const Collapse = (($) => {
}
const Selector = {
- ACTIVES : '.card > .show, .card > .collapsing',
- DATA_TOGGLE : '[data-toggle="collapse"]',
- DATA_CHILDREN : 'data-children'
+ ACTIVES : '.show, .collapsing',
+ DATA_TOGGLE : '[data-toggle="collapse"]'
}
@@ -78,20 +77,13 @@ const Collapse = (($) => {
`[data-toggle="collapse"][href="#${element.id}"],` +
`[data-toggle="collapse"][data-target="#${element.id}"]`
))
+
this._parent = this._config.parent ? this._getParent() : null
if (!this._config.parent) {
this._addAriaAndCollapsedClass(this._element, this._triggerArray)
}
- this._selectorActives = Selector.ACTIVES
- if (this._parent) {
- const childrenSelector = this._parent.hasAttribute(Selector.DATA_CHILDREN) ? this._parent.getAttribute(Selector.DATA_CHILDREN) : null
- if (childrenSelector !== null) {
- this._selectorActives = `${childrenSelector} > .show, ${childrenSelector} > .collapsing`
- }
- }
-
if (this._config.toggle) {
this.toggle()
}
@@ -129,7 +121,7 @@ const Collapse = (($) => {
let activesData
if (this._parent) {
- actives = $.makeArray($(this._parent).find(this._selectorActives))
+ actives = $.makeArray($(this._parent).children().children(Selector.ACTIVES))
if (!actives.length) {
actives = null
}
diff --git a/js/src/tab.js b/js/src/tab.js
index 6f8187d17..c7bc520df 100644
--- a/js/src/tab.js
+++ b/js/src/tab.js
@@ -140,7 +140,7 @@ const Tab = (($) => {
}
dispose() {
- $.removeClass(this._element, DATA_KEY)
+ $.removeData(this._element, DATA_KEY)
this._element = null
}
diff --git a/js/tests/unit/button.js b/js/tests/unit/button.js
index abc04e10a..489d400a6 100644
--- a/js/tests/unit/button.js
+++ b/js/tests/unit/button.js
@@ -156,4 +156,21 @@ $(function () {
assert.ok($btn2.is(':not([aria-pressed])'), 'label for nested radio input has not been given an aria-pressed attribute')
})
+ QUnit.test('should handle disabled attribute on non-button elements', function (assert) {
+ assert.expect(2)
+ var groupHTML = ' <div class="btn-group disabled" data-toggle="buttons" aria-disabled="true" disabled>'
+ + '<label class="btn btn-danger disabled" aria-disabled="true" disabled>'
+ + '<input type="checkbox" aria-disabled="true" autocomplete="off" disabled class="disabled"/>'
+ + '</label>'
+ + '</div>'
+ var $group = $(groupHTML).appendTo('#qunit-fixture')
+
+ var $btn = $group.children().eq(0)
+ var $input = $btn.children().eq(0)
+
+ $btn.trigger('click')
+ assert.ok($btn.is(':not(.active)'), 'button did not become active')
+ assert.ok(!$input.is(':checked'), 'checkbox did not get checked')
+ })
+
})
diff --git a/js/tests/unit/collapse.js b/js/tests/unit/collapse.js
index 35fcf2108..2b9d0e58f 100644
--- a/js/tests/unit/collapse.js
+++ b/js/tests/unit/collapse.js
@@ -491,27 +491,85 @@ $(function () {
})
QUnit.test('should allow accordion to use children other than card', function (assert) {
- assert.expect(2)
+ assert.expect(4)
var done = assert.async()
- var accordionHTML = '<div id="accordion" data-children=".item">'
+ var accordionHTML = '<div id="accordion">'
+ '<div class="item">'
+ '<a id="linkTrigger" data-parent="#accordion" data-toggle="collapse" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>'
+ '<div id="collapseOne" class="collapse" role="tabpanel" aria-labelledby="headingThree"></div>'
+ '</div>'
+ '<div class="item">'
- + '<a data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>'
+ + '<a id="linkTriggerTwo" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>'
+ '<div id="collapseTwo" class="collapse show" role="tabpanel" aria-labelledby="headingTwo"></div>'
+ '</div>'
+ '</div>'
$(accordionHTML).appendTo('#qunit-fixture')
- var $target = $('#linkTrigger')
- $('#collapseOne').on('shown.bs.collapse', function () {
- assert.ok($(this).hasClass('show'))
- assert.ok(!$('#collapseTwo').hasClass('show'))
- done()
+ var $trigger = $('#linkTrigger')
+ var $triggerTwo = $('#linkTriggerTwo')
+ var $collapseOne = $('#collapseOne')
+ var $collapseTwo = $('#collapseTwo')
+ $collapseOne.on('shown.bs.collapse', function () {
+ assert.ok($collapseOne.hasClass('show'), '#collapseOne is shown')
+ assert.ok(!$collapseTwo.hasClass('show'), '#collapseTwo is not shown')
+ $collapseTwo.on('shown.bs.collapse', function () {
+ assert.ok(!$collapseOne.hasClass('show'), '#collapseOne is not shown')
+ assert.ok($collapseTwo.hasClass('show'), '#collapseTwo is shown')
+ done()
+ })
+ $triggerTwo.trigger($.Event('click'))
})
- $target.trigger($.Event('click'))
+ $trigger.trigger($.Event('click'))
+ })
+
+ QUnit.test('should collapse accordion children but not nested accordion children', function (assert) {
+ assert.expect(9)
+ var done = assert.async()
+ $('<div id="accordion">'
+ + '<div class="item">'
+ + '<a id="linkTrigger" data-parent="#accordion" data-toggle="collapse" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>'
+ + '<div id="collapseOne" class="collapse" role="tabpanel" aria-labelledby="headingThree">'
+ + '<div id="nestedAccordion">'
+ + '<div class="item">'
+ + '<a id="nestedLinkTrigger" data-parent="#nestedAccordion" data-toggle="collapse" href="#nestedCollapseOne" aria-expanded="false" aria-controls="nestedCollapseOne"></a>'
+ + '<div id="nestedCollapseOne" class="collapse" role="tabpanel" aria-labelledby="headingThree">'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ + '<div class="item">'
+ + '<a id="linkTriggerTwo" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>'
+ + '<div id="collapseTwo" class="collapse show" role="tabpanel" aria-labelledby="headingTwo"></div>'
+ + '</div>'
+ + '</div>').appendTo('#qunit-fixture')
+ var $trigger = $('#linkTrigger')
+ var $triggerTwo = $('#linkTriggerTwo')
+ var $nestedTrigger = $('#nestedLinkTrigger')
+ var $collapseOne = $('#collapseOne')
+ var $collapseTwo = $('#collapseTwo')
+ var $nestedCollapseOne = $('#nestedCollapseOne')
+
+
+ $collapseOne.one('shown.bs.collapse', function () {
+ assert.ok($collapseOne.hasClass('show'), '#collapseOne is shown')
+ assert.ok(!$collapseTwo.hasClass('show'), '#collapseTwo is not shown')
+ assert.ok(!$('#nestedCollapseOne').hasClass('show'), '#nestedCollapseOne is not shown')
+ $nestedCollapseOne.one('shown.bs.collapse', function () {
+ assert.ok($collapseOne.hasClass('show'), '#collapseOne is shown')
+ assert.ok(!$collapseTwo.hasClass('show'), '#collapseTwo is not shown')
+ assert.ok($nestedCollapseOne.hasClass('show'), '#nestedCollapseOne is shown')
+ $collapseTwo.one('shown.bs.collapse', function () {
+ assert.ok(!$collapseOne.hasClass('show'), '#collapseOne is not shown')
+ assert.ok($collapseTwo.hasClass('show'), '#collapseTwo is shown')
+ assert.ok($nestedCollapseOne.hasClass('show'), '#nestedCollapseOne is shown')
+ done()
+ })
+ $triggerTwo.trigger($.Event('click'))
+ })
+ $nestedTrigger.trigger($.Event('click'))
+ })
+ $trigger.trigger($.Event('click'))
})
QUnit.test('should not prevent event for input', function (assert) {
diff --git a/package.json b/package.json
index ab1185bd7..7e9ee3c75 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,7 @@
"css-compile": "node-sass --output-style expanded --source-map true --precision 6 scss/bootstrap.scss dist/css/bootstrap.css && node-sass --output-style expanded --source-map true --precision 6 scss/bootstrap-grid.scss dist/css/bootstrap-grid.css && node-sass --output-style expanded --source-map true --precision 6 scss/bootstrap-reboot.scss dist/css/bootstrap-reboot.css",
"css-compile-docs": "node-sass --output-style expanded --source-map true --precision 6 docs/assets/scss/docs.scss docs/assets/css/docs.min.css",
"css-prefix": "postcss --config build/ --replace dist/css/*.css",
- "css-prefix-docs": "postcss --config build/ --no-map --replace docs/assets/css/docs.min.css docs/examples/**/*.css",
+ "css-prefix-docs": "postcss --config build/ --no-map --replace docs/assets/css/docs.min.css",
"css-minify": "cleancss --level 1 --source-map --output dist/css/bootstrap.min.css dist/css/bootstrap.css && cleancss --level 1 --source-map --output dist/css/bootstrap-grid.min.css dist/css/bootstrap-grid.css && cleancss --level 1 --source-map --output dist/css/bootstrap-reboot.min.css dist/css/bootstrap-reboot.css",
"css-minify-docs": "cleancss --level 1 --source-map --output docs/assets/css/docs.min.css docs/assets/css/docs.min.css",
"js": "npm-run-all js-compile js-minify",
@@ -38,7 +38,9 @@
"js-minify": "uglifyjs --compress warnings=false --mangle --comments '/^!/' --output dist/js/bootstrap.min.js dist/js/bootstrap.js",
"js-minify-docs": "uglifyjs --compress warnings=false --mangle --comments '/^!/' --output docs/assets/js/docs.min.js docs/assets/js/vendor/anchor.min.js docs/assets/js/vendor/clipboard.min.js docs/assets/js/vendor/holder.min.js docs/assets/js/src/application.js",
"js-test": "phantomjs ./node_modules/qunit-phantomjs-runner/runner.js js/tests/index.html 60",
- "js-test-cloud": "ruby -run -ehttpd . -p3000 > /dev/null & grunt saucelabs-qunit",
+ "js-test-dep": "npm install grunt && npm install grunt-saucelabs",
+ "js-launch-cloud": "ruby -run -ehttpd . -p3000 > /dev/null & grunt saucelabs-qunit",
+ "js-test-cloud": "npm-run-all js-test-dep js-launch-cloud",
"docs": "npm-run-all docs-compile docs-lint",
"docs-lint": "htmlhint --config docs/.htmlhintrc _gh_pages/ js/tests/visual/ && htmllint --rc docs/.htmllintrc _gh_pages/*.html _gh_pages/**/*.html js/tests/visual/*.html",
"docs-clean": "shx rm -r docs/dist/* && shx cp -r dist/* docs/dist/",
@@ -51,7 +53,10 @@
"release-version": "node build/change-version.js",
"release-zip": "cd dist/ && zip -r9 bootstrap-$npm_package_version-dist.zip * && shx mv bootstrap-$npm_package_version-dist.zip ..",
"dist": "npm-run-all --parallel css js",
- "test": "npm-run-all dist docs"
+ "test": "npm-run-all dist js-test docs",
+ "watch-css": "nodemon --ignore js/ --ignore dist/ -e scss -x \"npm run css && npm run css-docs\"",
+ "watch-js": "nodemon --ignore scss/ --ignore js/dist/ --ignore dist/ -e js -x \"npm run js-compile\"",
+ "watch": "npm-run-all --parallel watch-css watch-js"
},
"style": "dist/css/bootstrap.css",
"sass": "scss/bootstrap.scss",
@@ -76,11 +81,10 @@
"babel-preset-es2015": "^7.0.0-alpha.7",
"clean-css-cli": "^4.0.12",
"eslint": "^3.19.0",
- "grunt": "^1.0.1",
- "grunt-saucelabs": "^9.0.0",
"htmlhint": "^0.9.13",
"htmllint-cli": "^0.0.6",
"node-sass": "^4.5.2",
+ "nodemon": "^1.11.0",
"npm-run-all": "^4.0.2",
"phantomjs-prebuilt": "^2.1.14",
"postcss-cli": "^3.1.1",