From 3e9e4e8bebc7f5e2df18ac9defb29f799ae051f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Javier=20Villase=C3=B1or=20Castillo?= Date: Mon, 26 Aug 2024 13:32:20 -0600 Subject: [PATCH] fix: allow captions in devices that use old chrome to be shown (#8826) ## Description In the specific case of using an old chrome version this minor changes will allow the captions to be shown. ## Specific Changes proposed Small fix when using videojs in an old browser that does not support the css 'inset' property. ## Requirements Checklist - [x] Feature implemented / Bug fixed - [ ] If necessary, more likely in a feature request than a bug fix - [ ] Change has been verified in an actual browser (Chrome, Firefox, IE) - [ ] Unit Tests updated or fixed - [ ] Docs/guides updated - [ ] Example created ([starter template on JSBin](https://codepen.io/gkatsev/pen/GwZegv?editors=1000#0)) - [ ] Has no DOM changes which impact accessiblilty or trigger warnings (e.g. Chrome issues tab) - [ ] Has no changes to JSDoc which cause `npm run docs:api` to error - [ ] Reviewed by Two Core Contributors --------- Co-authored-by: Walter Seymour Co-authored-by: Gary Katsevman --- src/css/components/_text-track.scss | 9 +++ src/js/tracks/text-track-display.js | 37 ++++++++++ test/unit/tracks/text-track-display.test.js | 77 +++++++++++++++++++++ 3 files changed, 123 insertions(+) diff --git a/src/css/components/_text-track.scss b/src/css/components/_text-track.scss index 2ebee49b95..e98c5202c9 100644 --- a/src/css/components/_text-track.scss +++ b/src/css/components/_text-track.scss @@ -46,3 +46,12 @@ video::-webkit-media-text-track-display { text-align: center !important; width: 80% !important; } + +@supports (inset: 10px) { + .video-js .vjs-text-track-display > div { + top: 0; + right: 0; + bottom: 0; + left: 0; + } +} diff --git a/src/js/tracks/text-track-display.js b/src/js/tracks/text-track-display.js index c0b05a618f..f9066f366e 100644 --- a/src/js/tracks/text-track-display.js +++ b/src/js/tracks/text-track-display.js @@ -5,6 +5,7 @@ import Component from '../component'; import * as Fn from '../utils/fn.js'; import * as Dom from '../utils/dom.js'; import window from 'global/window'; +import * as browser from '../utils/browser'; /** @import Player from '../player' */ @@ -319,6 +320,42 @@ class TextTrackDisplay extends Component { } this.updateForTrack(descriptionsTrack); } + + if (!window.CSS.supports('inset', '10px')) { + const textTrackDisplay = this.el_; + const vjsTextTrackCues = textTrackDisplay.querySelectorAll('.vjs-text-track-cue'); + const controlBarHeight = this.player_.controlBar.el_.getBoundingClientRect().height; + const playerHeight = this.player_.el_.getBoundingClientRect().height; + + // Clear inline style before getting actual height of textTrackDisplay + textTrackDisplay.style = ''; + + // textrack style updates, this styles are required to be inline + tryUpdateStyle(textTrackDisplay, 'position', 'relative'); + tryUpdateStyle(textTrackDisplay, 'height', (playerHeight - controlBarHeight) + 'px'); + tryUpdateStyle(textTrackDisplay, 'top', 'unset'); + + if (browser.IS_SMART_TV) { + tryUpdateStyle(textTrackDisplay, 'bottom', playerHeight + 'px'); + } else { + tryUpdateStyle(textTrackDisplay, 'bottom', '0px'); + } + + // vjsTextTrackCue style updates + if (vjsTextTrackCues.length > 0) { + vjsTextTrackCues.forEach((vjsTextTrackCue) => { + // verify if inset styles are inline + if (vjsTextTrackCue.style.inset) { + const insetStyles = vjsTextTrackCue.style.inset.split(' '); + + // expected value is always 3 + if (insetStyles.length === 3) { + Object.assign(vjsTextTrackCue.style, { top: insetStyles[0], right: insetStyles[1], bottom: insetStyles[2], left: 'unset' }); + } + } + }); + } + } } /** diff --git a/test/unit/tracks/text-track-display.test.js b/test/unit/tracks/text-track-display.test.js index 9c41926514..f0aa05d586 100644 --- a/test/unit/tracks/text-track-display.test.js +++ b/test/unit/tracks/text-track-display.test.js @@ -500,4 +500,81 @@ if (!Html5.supportsNativeTextTracks()) { player.dispose(); }); + + QUnit.test('should use relative position for vjs-text-track-display element if browser does not support inset property', function(assert) { + // Set conditions for the use of the style modifications + window.CSS.supports = () => false; + browser.IS_SMART_TV = () => true; + + const player = TestHelpers.makePlayer(); + const track1 = { + kind: 'captions', + label: 'English', + language: 'en', + src: 'en.vtt', + default: true + }; + + // Add the text track + player.addRemoteTextTrack(track1, true); + + player.src({type: 'video/mp4', src: 'http://google.com'}); + player.play(); + + // as if metadata was loaded + player.textTrackDisplay.updateDisplayOverlay(); + + // Make sure the ready handler runs + this.clock.tick(1); + + const textTrack = window.document.querySelector('.vjs-text-track-display'); + + assert.ok(textTrack.style.position === 'relative', 'Style of position for vjs-text-track-display element should be relative'); + assert.ok(textTrack.style.top === 'unset', 'Style of position for vjs-text-track-display element should be unset'); + assert.ok(textTrack.style.bottom === '0px', 'Style of bottom for vjs-text-track-display element should be 0px'); + player.dispose(); + }); + + QUnit.test('track cue should use values of top, right, botton, left if browser does not support inset property', function(assert) { + // Set conditions for the use of the style modifications + window.CSS.supports = () => false; + browser.IS_SMART_TV = () => true; + + const player = TestHelpers.makePlayer(); + const track1 = { + kind: 'captions', + label: 'English', + language: 'en', + src: 'en.vtt', + default: true + }; + + // Add the text track + player.addRemoteTextTrack(track1, true); + + player.src({type: 'video/mp4', src: 'http://google.com'}); + player.play(); + + // mock caption + const textTrackDisplay = window.document.querySelector('.vjs-text-track-display').firstChild; + const node = document.createElement('div'); + + node.classList.add('vjs-text-track-cue'); + node.style.inset = '1px 2px 3px'; + const textnode = document.createTextNode('Sample text'); + + node.appendChild(textnode); + textTrackDisplay.appendChild(node); + + // avoid captions clear + player.textTrackDisplay.clearDisplay = () => ''; + + // as if metadata was loaded + player.textTrackDisplay.updateDisplay(); + + assert.ok(player.textTrackDisplay.el_.querySelector('.vjs-text-track-cue').style.left === 'unset', 'Style of left for vjs-text-track-cue element should be unset'); + assert.ok(player.textTrackDisplay.el_.querySelector('.vjs-text-track-cue').style.top === '1px', 'Style of top for vjs-text-track-cue element should be 1px'); + assert.ok(player.textTrackDisplay.el_.querySelector('.vjs-text-track-cue').style.right === '2px', 'Style of right for vjs-text-track-cue element should be 2px'); + player.dispose(); + }); }