diff options
| author | XhmikosR <[email protected]> | 2020-06-04 10:41:47 +0300 |
|---|---|---|
| committer | XhmikosR <[email protected]> | 2020-06-04 17:53:16 +0300 |
| commit | 8bc6dcd280f096189214561b1f87f015cd2dcba1 (patch) | |
| tree | fcda9b0cad8c9bd49f46a4b8d2e9119d5e7167bd /js | |
| parent | 288b9b82b5a5cb64ec3aaadef13ac934a957e5d2 (diff) | |
| download | bootstrap-8bc6dcd280f096189214561b1f87f015cd2dcba1.tar.xz bootstrap-8bc6dcd280f096189214561b1f87f015cd2dcba1.zip | |
Backport #30936
Add role="dialog" in modals via JavaScript
Diffstat (limited to 'js')
| -rw-r--r-- | js/src/modal.js | 2 | ||||
| -rw-r--r-- | js/tests/unit/modal.js | 17 | ||||
| -rw-r--r-- | js/tests/visual/modal.html | 8 |
3 files changed, 23 insertions, 4 deletions
diff --git a/js/src/modal.js b/js/src/modal.js index 7338ffd37..f898d0c46 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -265,6 +265,7 @@ class Modal { this._element.style.display = 'block' this._element.removeAttribute('aria-hidden') this._element.setAttribute('aria-modal', true) + this._element.setAttribute('role', 'dialog') if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) { modalBody.scrollTop = 0 @@ -344,6 +345,7 @@ class Modal { this._element.style.display = 'none' this._element.setAttribute('aria-hidden', true) this._element.removeAttribute('aria-modal') + this._element.removeAttribute('role') this._isTransitioning = false this._showBackdrop(() => { $(document.body).removeClass(CLASS_NAME_OPEN) diff --git a/js/tests/unit/modal.js b/js/tests/unit/modal.js index fefd84fce..5434987d8 100644 --- a/js/tests/unit/modal.js +++ b/js/tests/unit/modal.js @@ -297,6 +297,23 @@ $(function () { .bootstrapModal('show') }) + QUnit.test('should add role="dialog" attribute when shown, remove it again when hidden', function (assert) { + assert.expect(3) + var done = assert.async() + + $('<div id="modal-test"/>') + .on('shown.bs.modal', function () { + assert.ok($('#modal-test').is('[role]'), 'role attribute added') + assert.strictEqual($('#modal-test').attr('role'), 'dialog', 'correct role="dialog" added') + $(this).bootstrapModal('hide') + }) + .on('hidden.bs.modal', function () { + assert.notOk($('#modal-test').is('[role]'), 'role attribute removed') + done() + }) + .bootstrapModal('show') + }) + QUnit.test('should close reopened modal with [data-dismiss="modal"] click', function (assert) { assert.expect(2) var done = assert.async() diff --git a/js/tests/visual/modal.html b/js/tests/visual/modal.html index 872c8d402..4ec8214f5 100644 --- a/js/tests/visual/modal.html +++ b/js/tests/visual/modal.html @@ -34,7 +34,7 @@ <div class="container mt-3"> <h1>Modal <small>Bootstrap Visual Test</small></h1> - <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> + <div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> @@ -121,7 +121,7 @@ </div> </div> - <div class="modal fade" id="firefoxModal" tabindex="-1" role="dialog" aria-labelledby="firefoxModalLabel" aria-hidden="true"> + <div class="modal fade" id="firefoxModal" tabindex="-1" aria-labelledby="firefoxModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> @@ -147,7 +147,7 @@ </div> </div> - <div class="modal fade" id="slowModal" tabindex="-1" role="dialog" aria-labelledby="slowModalLabel" aria-hidden="true" style="transition-duration: 5s;"> + <div class="modal fade" id="slowModal" tabindex="-1" aria-labelledby="slowModalLabel" aria-hidden="true" style="transition-duration: 5s;"> <div class="modal-dialog" style="transition-duration: inherit;"> <div class="modal-content"> <div class="modal-header"> @@ -194,7 +194,7 @@ Tall body content to force the page to have a scrollbar. </div> - <button type="button" class="btn btn-secondary btn-lg" data-toggle="modal" data-target="<div class="modal fade the-bad" tabindex="-1" role="dialog"><div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button><h4 class="modal-title">The Bad Modal</h4></div><div class="modal-body">This modal's HTTML source code is declared inline, inside the data-target attribute of it's show-button</div></div></div></div>"> + <button type="button" class="btn btn-secondary btn-lg" data-toggle="modal" data-target="<div class="modal fade the-bad" tabindex="-1"><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button><h4 class="modal-title">The Bad Modal</h4></div><div class="modal-body">This modal's HTTML source code is declared inline, inside the data-target attribute of it's show-button</div></div></div></div>"> Modal with an XSS inside the data-target </button> |
