diff --git a/src/components/focusManager.js b/src/components/focusManager.js index 48ccd6b92c0..8dd0f6dd518 100644 --- a/src/components/focusManager.js +++ b/src/components/focusManager.js @@ -93,22 +93,24 @@ function isCurrentlyFocusableInternal(elem) { // Determines if a focusable element can be focused at a given point in time function isCurrentlyFocusable(elem) { - if (elem.disabled) { - return false; - } - - if (elem.getAttribute('tabindex') === '-1') { - return false; - } - - if (elem.tagName === 'INPUT') { - const type = elem.type; - if (type === 'range') { + if (!elem.classList?.contains('focusable')) { + if (elem.disabled) { return false; } - if (type === 'file') { + + if (elem.getAttribute('tabindex') === '-1') { return false; } + + if (elem.tagName === 'INPUT') { + const type = elem.type; + if (type === 'range') { + return false; + } + if (type === 'file') { + return false; + } + } } return isCurrentlyFocusableInternal(elem); diff --git a/src/components/playback/skipsegment.ts b/src/components/playback/skipsegment.ts index 523a16c49e3..b73576c721f 100644 --- a/src/components/playback/skipsegment.ts +++ b/src/components/playback/skipsegment.ts @@ -20,6 +20,15 @@ interface ShowOptions { function onHideComplete(this: HTMLButtonElement) { if (this) { + // Handle focus after the hide transition completes + if (document.activeElement === this) { + this.blur(); + const pauseButton = document.querySelector('.btnPause'); + if (pauseButton && focusManager.isCurrentlyFocusable(pauseButton)) { + focusManager.focus(pauseButton); + } + } + this.classList.add('hide'); } } diff --git a/src/controllers/playback/video/index.js b/src/controllers/playback/video/index.js index 09af84fc53f..b95183deaea 100644 --- a/src/controllers/playback/video/index.js +++ b/src/controllers/playback/video/index.js @@ -304,11 +304,15 @@ export default function (view) { } function slideDownToShow(elem) { + clearHideAnimationEventListeners(elem); + elem.classList.remove('hide'); elem.classList.remove('osdHeader-hidden'); } function slideUpToHide(elem) { + clearHideAnimationEventListeners(elem); elem.classList.add('osdHeader-hidden'); + elem.addEventListener(transitionEndEventName, onHideAnimationComplete); } function clearHideAnimationEventListeners(elem) { @@ -317,7 +321,7 @@ export default function (view) { function onHideAnimationComplete(e) { const elem = e.target; - if (elem != osdBottomElement) return; + if (elem !== osdBottomElement && elem !== headerElement) return; elem.classList.add('hide'); elem.removeEventListener(transitionEndEventName, onHideAnimationComplete); } @@ -338,8 +342,17 @@ export default function (view) { _focus(focusElement); } toggleSubtitleSync(); - } else if (currentVisibleMenu === 'osd' && focusElement && !layoutManager.mobile) { - _focus(focusElement); + } else if (currentVisibleMenu === 'osd' && !layoutManager.mobile) { + // If no focus element is provided, try to keep current focus if it's valid, + // otherwise default to pause button + if (!focusElement) { + const currentFocus = document.activeElement; + if (!currentFocus || !focusManager.isCurrentlyFocusable(currentFocus)) { + focusElement = osdBottomElement.querySelector('.btnPause'); + } + } + + if (focusElement) _focus(focusElement); } } @@ -354,7 +367,8 @@ export default function (view) { toggleSubtitleSync('hide'); // Firefox does not blur by itself - if (document.activeElement) { + if (osdBottomElement.contains(document.activeElement) + || headerElement.contains(document.activeElement)) { document.activeElement.blur(); } }