From ee7f1e2fbf2dc19439240910b522cb574c325523 Mon Sep 17 00:00:00 2001 From: Tsachi Shlidor Date: Sun, 17 Mar 2024 14:14:13 +0200 Subject: [PATCH] fix: styled subtitles browser compatibility (#576) * fix: styled subtitles browser compatibility * chore: unlazy styled subtitles --- src/assets/styles/components/text-tracks.scss | 9 ++- src/plugins/styled-text-tracks/index.js | 7 +- .../styled-text-tracks/styled-text-tracks.js | 73 +++++++++++-------- .../styled-text-tracks.scss | 62 +++++++--------- 4 files changed, 75 insertions(+), 76 deletions(-) diff --git a/src/assets/styles/components/text-tracks.scss b/src/assets/styles/components/text-tracks.scss index 5b50ad9f..c4d2976b 100644 --- a/src/assets/styles/components/text-tracks.scss +++ b/src/assets/styles/components/text-tracks.scss @@ -7,10 +7,6 @@ > div { margin: 3% !important; } - // Word highlight - &.cld-paced-text-tracks b { - color: var(--color-accent); - } } .vjs-text-track-cue { top: auto !important; @@ -27,6 +23,11 @@ bottom: 1.5rem !important; } + // Word highlight - default style + .cld-paced-text-tracks .vjs-text-track-cue b { + color: var(--color-accent); + } + // Default caption styles, when not configured to `videojs-default` theme .vjs-text-track-display:not(.cld-styled-text-tracks-theme-videojs-default) { .vjs-text-track-cue { diff --git a/src/plugins/styled-text-tracks/index.js b/src/plugins/styled-text-tracks/index.js index 2676495d..57953c54 100644 --- a/src/plugins/styled-text-tracks/index.js +++ b/src/plugins/styled-text-tracks/index.js @@ -1,8 +1,9 @@ -export default async function lazyPlugin(config) { +import styledTextTracks from './styled-text-tracks'; + +export default async function styledTextTracksPlugin(config) { const player = this; try { - const { default: initPlugin } = await import(/* webpackChunkName: "styled-text-tracks" */ './styled-text-tracks'); - player.ready(() => initPlugin(config, player)); + player.ready(() => styledTextTracks(config, player)); } catch (error) { console.error('Failed to load plugin:', error); } diff --git a/src/plugins/styled-text-tracks/styled-text-tracks.js b/src/plugins/styled-text-tracks/styled-text-tracks.js index 549455b7..f016b7a3 100644 --- a/src/plugins/styled-text-tracks/styled-text-tracks.js +++ b/src/plugins/styled-text-tracks/styled-text-tracks.js @@ -14,6 +14,9 @@ const styledTextTracks = (config, player) => { wordHighlightStyle: config.wordHighlightStyle }; + const styleEl = document.createElement('style'); + player.el_.appendChild(styleEl); + // Class Names - Theme/Gravity const classNames = player.textTrackDisplay.el().classList; classNames.forEach(className => { @@ -28,60 +31,66 @@ const styledTextTracks = (config, player) => { classNames.add(`cld-styled-text-tracks-gravity-${gravity}`); }); - // Font - if (options.fontFace) { - fontFace(player.textTrackDisplay.el(), options.fontFace); - } - - const applyImportantStyle = (style, selector) => { - const styleEl = document.createElement('style'); + const applyStyle = (style, selector) => { if (Object.entries(style)) { const css = Object.entries(style).reduce((acc, [key, value]) => { return acc + `${key}: ${value} !important; `; }, ''); - styleEl.innerHTML = ` - .${playerClassPrefix(player)} ${selector} { - ${css} - } - `; - player.el_.appendChild(styleEl); + styleEl.innerHTML += `${selector} { ${css} } `; } }; + const applyWrapperStyle = (style) => { + const selector = ` + .${playerClassPrefix(player)} .vjs-text-track-display.cld-styled-text-tracks, + .${playerClassPrefix(player)} ::-webkit-media-text-track-display + `; + applyStyle(style, selector); + }; + + const applyCueStyle = (style) => { + const selector = ` + .${playerClassPrefix(player)} .vjs-text-track-cue > div, + .${playerClassPrefix(player)} ::cue + `; + applyStyle(style, selector); + }; + + // Font + if (options.fontFace) { + fontFace(player.textTrackDisplay.el(), options.fontFace); + applyCueStyle({ 'font-family': options.fontFace }); + } + // Custom bounding box if (options.box) { const { x, y, width, height } = options.box; - applyImportantStyle( - { - translate: `${x ? x : 0} ${y ? y : 0}`, - ...(width ? { width } : undefined), - ...(height ? { height } : undefined) - }, - '.vjs-text-track-display.cld-styled-text-tracks' - ); + applyWrapperStyle({ + translate: `${x ? x : 0} ${y ? y : 0}`, + ...(width ? { width } : undefined), + ...(height ? { height } : undefined) + }); } // Custom font-size if (options.fontSize) { - applyImportantStyle( - { 'font-size': options.fontSize }, - '.vjs-text-track-display.cld-styled-text-tracks .vjs-text-track-cue > div' - ); + applyCueStyle({ 'font-size': options.fontSize }); } // Custom styles if (options.style) { - applyImportantStyle( - options.style, - '.vjs-text-track-display.cld-styled-text-tracks .vjs-text-track-cue > div' - ); + applyCueStyle(options.style); } - // Custom styles + // Word highlight styles if (options.wordHighlightStyle) { - applyImportantStyle( + applyStyle( + options.wordHighlightStyle, + `.${playerClassPrefix(player)} .cld-paced-text-tracks .vjs-text-track-cue b` + ); + applyStyle( options.wordHighlightStyle, - '.vjs-text-track-display.cld-styled-text-tracks .vjs-text-track-cue b' + 'video::cue(b)' ); } }; diff --git a/src/plugins/styled-text-tracks/styled-text-tracks.scss b/src/plugins/styled-text-tracks/styled-text-tracks.scss index 71ab97a5..49f74496 100644 --- a/src/plugins/styled-text-tracks/styled-text-tracks.scss +++ b/src/plugins/styled-text-tracks/styled-text-tracks.scss @@ -28,44 +28,32 @@ } // Themes - .vjs-text-track-display { - - &.cld-styled-text-tracks-theme-yellow-outlined { - div.vjs-text-track-cue { - & > div { - color: #FEF94A !important; - text-shadow: - -1px -1px 0 #000, - 1px -1px 0 #000, - -1px 1px 0 #000, - 1px 1px 0 #000; - } - } - } + div.vjs-text-track-display.cld-styled-text-tracks-theme-yellow-outlined div.vjs-text-track-cue > div, + &:has(.cld-styled-text-tracks-theme-yellow-outlined) ::cue { + color: #FEF94A !important; + text-shadow: + -1px -1px 0 #000, + 1px -1px 0 #000, + -1px 1px 0 #000, + 1px 1px 0 #000; + } - &.cld-styled-text-tracks-theme-3d { - div.vjs-text-track-cue { - & > div { - $base-size: 0.03em; - $base-color: #ff76ad; - color: lighten($base-color, 40%) !important; - text-shadow: - #{1*$base-size} #{1*$base-size} 0 darken($base-color, 10%), - #{2*$base-size} #{2*$base-size} 0 darken($base-color, 20%), - #{3*$base-size} #{3*$base-size} 0 darken($base-color, 30%), - #{4*$base-size} #{4*$base-size} 0 darken($base-color, 40%); - } - } - } + div.vjs-text-track-display.cld-styled-text-tracks-theme-3d div.vjs-text-track-cue > div, + &:has(.cld-styled-text-tracks-theme-3d) ::cue { + $base-size: 0.03em; + $base-color: #ff76ad; + color: lighten($base-color, 40%) !important; + text-shadow: + #{1*$base-size} #{1*$base-size} 0 darken($base-color, 10%), + #{2*$base-size} #{2*$base-size} 0 darken($base-color, 20%), + #{3*$base-size} #{3*$base-size} 0 darken($base-color, 30%), + #{4*$base-size} #{4*$base-size} 0 darken($base-color, 40%); + } - &.cld-styled-text-tracks-theme-player-colors { - div.vjs-text-track-cue { - & > div { - color: var(--color-text) !important; - background-color: var(--color-accent) !important; - text-shadow: 0 0 4px var(--color-base) !important; - } - } - } + div.vjs-text-track-display.cld-styled-text-tracks-theme-player-colors div.vjs-text-track-cue > div, + &:has(.cld-styled-text-tracks-theme-player-colors) ::cue { + color: var(--color-text) !important; + background-color: var(--color-accent) !important; + text-shadow: 0 0 4px var(--color-base); } }