diff options
author | nod_ <nod_@598310.no-reply.drupal.org> | 2024-04-17 17:12:06 +0200 |
---|---|---|
committer | nod_ <nod_@598310.no-reply.drupal.org> | 2024-04-17 17:12:06 +0200 |
commit | 66c3914d39bf24d828ec8516389d7cadad52294e (patch) | |
tree | 6baa47ed9c00ea6ea9dfe4d798ec366c084d867a /core/misc/dialog/dialog.jquery-ui.js | |
parent | 244a7eeb7a94e08913e56f315f8e901438114476 (diff) | |
download | drupal-66c3914d39bf24d828ec8516389d7cadad52294e.tar.gz drupal-66c3914d39bf24d828ec8516389d7cadad52294e.zip |
Issue #3296098 by catch, finnsky, smustgrave: Removal :tabbable usage in dialog.js
Diffstat (limited to 'core/misc/dialog/dialog.jquery-ui.js')
-rw-r--r-- | core/misc/dialog/dialog.jquery-ui.js | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/core/misc/dialog/dialog.jquery-ui.js b/core/misc/dialog/dialog.jquery-ui.js index 783797d1a148..32367977d8c8 100644 --- a/core/misc/dialog/dialog.jquery-ui.js +++ b/core/misc/dialog/dialog.jquery-ui.js @@ -30,6 +30,82 @@ $buttons.eq(index).addClass(opts.buttonPrimaryClass); } }, + _createWrapper() { + this.uiDialog = $('<div>') + .hide() + .attr({ + // Setting tabIndex makes the div focusable + tabIndex: -1, + role: 'dialog', + }) + .appendTo(this._appendTo()); + + this._addClass( + this.uiDialog, + 'ui-dialog', + 'ui-widget ui-widget-content ui-front', + ); + this._on(this.uiDialog, { + keydown(event) { + if ( + this.options.closeOnEscape && + !event.isDefaultPrevented() && + event.keyCode && + event.keyCode === $.ui.keyCode.ESCAPE + ) { + event.preventDefault(); + this.close(event); + return; + } + + // Prevent tabbing out of dialogs + if ( + event.keyCode !== $.ui.keyCode.TAB || + event.isDefaultPrevented() + ) { + return; + } + + const tabbableElements = tabbable(this.uiDialog[0]); + if (tabbableElements.length) { + const first = tabbableElements[0]; + const last = tabbableElements[tabbableElements.length - 1]; + + if ( + (event.target === last || event.target === this.uiDialog[0]) && + !event.shiftKey + ) { + this._delay(function () { + $(first).trigger('focus'); + }); + event.preventDefault(); + } else if ( + (event.target === first || event.target === this.uiDialog[0]) && + event.shiftKey + ) { + this._delay(function () { + $(last).trigger('focus'); + }); + event.preventDefault(); + } + } + }, + mousedown(event) { + if (this._moveToTop(event)) { + this._focusTabbable(); + } + }, + }); + + // We assume that any existing aria-describedby attribute means + // that the dialog content is marked up properly + // otherwise we brute force the content as the description + if (!this.element.find('[aria-describedby]').length) { + this.uiDialog.attr({ + 'aria-describedby': this.element.uniqueId().attr('id'), + }); + } + }, // Override jQuery UI's `_focusTabbable()` so finding tabbable elements uses // the core/tabbable library instead of jQuery UI's `:tabbable` selector. _focusTabbable() { |