diff --git a/public/scripts/bulk-edit.js b/public/scripts/bulk-edit.js index 891a6134a..66d95a31a 100644 --- a/public/scripts/bulk-edit.js +++ b/public/scripts/bulk-edit.js @@ -94,6 +94,9 @@ function enableBulkSelect() { }); $(el).prepend(checkbox); }); + $('#rm_print_characters_block.group_overlay_mode_select .bogus_folder_select, #rm_print_characters_block.group_overlay_mode_select .group_select') + .addClass('disabled'); + $('#rm_print_characters_block').addClass('bulk_select'); // We also need to disable the default click event for the character_select divs $(document).on('click', '.bulk_select_checkbox', function (event) { @@ -106,6 +109,8 @@ function enableBulkSelect() { */ function disableBulkSelect() { $('.bulk_select_checkbox').remove(); + $('#rm_print_characters_block.group_overlay_mode_select .bogus_folder_select, #rm_print_characters_block.group_overlay_mode_select .group_select') + .removeClass('disabled'); $('#rm_print_characters_block').removeClass('bulk_select'); } diff --git a/public/scripts/dynamic-styles.js b/public/scripts/dynamic-styles.js index 36e0faa01..3a339776f 100644 --- a/public/scripts/dynamic-styles.js +++ b/public/scripts/dynamic-styles.js @@ -60,7 +60,7 @@ function applyDynamicFocusStyles(styleSheet, { fromExtension = false } = {}) { hoverRules.push({ baseSelector, rule }); } else if (selector.includes(':focus')) { // We need to make sure that we both remember existing :focus and :focus-within rules - const baseSelector = selector.replace(':focus-within', PLACEHOLDER).replace(':focus', PLACEHOLDER).trim(); + const baseSelector = selector.replace(':focus-within', PLACEHOLDER).replace(':focus-visible', PLACEHOLDER).replace(':focus', PLACEHOLDER).trim(); focusRules.add(baseSelector); } }); @@ -92,7 +92,10 @@ function applyDynamicFocusStyles(styleSheet, { fromExtension = false } = {}) { // Only initialize the dynamic stylesheet if needed targetStyleSheet ??= getDynamicStyleSheet({ fromExtension }); - const focusSelector = rule.selectorText.replace(/:hover/g, ':focus'); + // The closest keyboard-equivalent to :hover styling is utilizing the :focus-within for keyboards + // So we take all :hover rules that don't have a manually defined focus rule yet, and create their + // :focus-within counterpart, which will make the styling work the same for keyboard and mouse + const focusSelector = rule.selectorText.replace(/:hover/g, ':focus-within'); const focusRule = `${focusSelector} { ${rule.style.cssText} }`; try { diff --git a/public/scripts/keyboard.js b/public/scripts/keyboard.js index c798508f5..e62733ea0 100644 --- a/public/scripts/keyboard.js +++ b/public/scripts/keyboard.js @@ -109,8 +109,23 @@ export function makeKeyboardInteractable(...interactables) { interactable.classList.add(INTERACTABLE_CONTROL_CLASS); } + /** + * Check if the element or any parent element has 'disabled' or 'not_focusable' class + * @param {Element} el + * @returns {boolean} + */ + const hasDisabledOrNotFocusableAncestor = (el) => { + while (el) { + if (el.classList.contains(NOT_FOCUSABLE_CONTROL_CLASS) || el.classList.contains(DISABLED_CONTROL_CLASS)) { + return true; + } + el = el.parentElement; + } + return false; + }; + // Set/remove the tabindex accordingly to the classes. Remembering if it had a custom value. - if (!interactable.classList.contains(NOT_FOCUSABLE_CONTROL_CLASS) && !interactable.classList.contains(DISABLED_CONTROL_CLASS)) { + if (!hasDisabledOrNotFocusableAncestor(interactable)) { if (!interactable.hasAttribute('tabindex')) { const tabIndex = interactable.getAttribute('data-original-tabindex') ?? '0'; interactable.setAttribute('tabindex', tabIndex); @@ -122,6 +137,7 @@ export function makeKeyboardInteractable(...interactables) { }); } + /** * Initializes the focusability of controls on the given element or the document * diff --git a/public/scripts/tags.js b/public/scripts/tags.js index 7f1385738..e0757eb4f 100644 --- a/public/scripts/tags.js +++ b/public/scripts/tags.js @@ -1547,6 +1547,22 @@ function appendViewTagToList(list, tag, everything) { list.append(template); + // We prevent the popup from auto-close on Escape press on the color pickups. If the user really wants to, he can hit it again + // Not the "cleanest" way, that would be actually using and observer, remembering whether the popup was open just before, but eh + // Not gonna invest too much time into this small control here + let lastHit = 0; + template.on('keydown', (evt) => { + if (evt.key === 'Escape') { + if (evt.target === primaryColorPicker[0] || evt.target === secondaryColorPicker[0]) { + if (Date.now() - lastHit < 5000) // If user hits it twice in five seconds + return; + lastHit = Date.now(); + evt.stopPropagation(); + evt.preventDefault(); + } + } + }); + updateDrawTagFolder(template, tag); } diff --git a/public/style.css b/public/style.css index 85b22cfa6..fccecf3e0 100644 --- a/public/style.css +++ b/public/style.css @@ -212,15 +212,17 @@ table.responsiveTable { } /* Keyboard/focus navigation styling */ -/** Mimic the outline of keyboard navigation for most most focusable controls */ +/* Mimic the outline of keyboard navigation for most most focusable controls */ .interactable { border-radius: 5px; } -.interactable:focus { +/* Outline for "normal" buttons should only be when actual keyboard navigation is used */ +.interactable:focus-visible { outline: 1px solid var(--white100); } +/* The specific input controls can always have a faint outline, even on mouse interaction, to give a better hint */ select:focus, input:focus, textarea:focus { @@ -266,7 +268,7 @@ input[type='checkbox']:focus { .fa-lock.right_menu_button, .fa-unlock.right_menu_button { - padding: 2 4px; + padding: 2px 4px; } .text_muted { @@ -2780,17 +2782,15 @@ input[type=search]:focus::-webkit-search-cancel-button { } .bg_button { - width: 15px; - height: 15px; + padding: 4px; position: absolute; top: 5px; cursor: pointer; opacity: 0.8; - border-radius: 50%; + border-radius: 3px; font-size: 20px; color: var(--black70a); text-shadow: none; - padding: 0; margin: 0; filter: drop-shadow(0px 0px 3px white); transition: opacity 0.2s ease-in-out; @@ -2806,15 +2806,15 @@ input[type=search]:focus::-webkit-search-cancel-button { } .bg_example_cross { - right: 10px; + right: 6px; } .bg_example_edit { - left: 10px; + left: 6px; } .bg_example_copy { - left: 10px; + left: 6px; } .bg_example_lock,