From 90c5735904354f5fde0dcdae9f8894fe9088739c Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Mon, 28 May 2018 10:19:07 +1000 Subject: WIP --- src/js/captions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/js/captions.js') diff --git a/src/js/captions.js b/src/js/captions.js index df717351..fadab43f 100644 --- a/src/js/captions.js +++ b/src/js/captions.js @@ -262,7 +262,7 @@ const captions = { if (active) { utils.toggleClass(this.elements.container, this.config.classNames.captions.active, true); - utils.toggleState(this.elements.buttons.captions, true); + this.elements.buttons.captions.pressed = true; } }, }; -- cgit v1.2.3 From 87170ab46080ae0d82afd1b39ab3fdf2e3ff1e62 Mon Sep 17 00:00:00 2001 From: cky <576779975@qq.com> Date: Tue, 12 Jun 2018 20:55:31 +0800 Subject: remove event listeners in destroy, add once method --- src/js/captions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/js/captions.js') diff --git a/src/js/captions.js b/src/js/captions.js index bafcf87e..18f4cbd3 100644 --- a/src/js/captions.js +++ b/src/js/captions.js @@ -80,7 +80,7 @@ const captions = { // Watch changes to textTracks and update captions menu if (this.isHTML5) { const trackEvents = this.config.captions.update ? 'addtrack removetrack' : 'removetrack'; - utils.on(this.media.textTracks, trackEvents, captions.update.bind(this)); + utils.on.call(this, this.media.textTracks, trackEvents, captions.update.bind(this)); } // Update available languages in list next tick (the event must not be triggered before the listeners) @@ -107,7 +107,7 @@ const captions = { track.mode = 'hidden'; // Add event listener for cue changes - utils.on(track, 'cuechange', () => captions.updateCues.call(this)); + utils.on.call(this, track, 'cuechange', () => captions.updateCues.call(this)); }); } -- cgit v1.2.3 From 392dfd024c505f5ae1bbb2f0d3e0793c251a1f35 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Wed, 13 Jun 2018 00:02:55 +1000 Subject: Utils broken down into seperate files and exports --- src/js/captions.js | 100 ++++++++++++++++++++++++++--------------------------- 1 file changed, 49 insertions(+), 51 deletions(-) (limited to 'src/js/captions.js') diff --git a/src/js/captions.js b/src/js/captions.js index bafcf87e..0506d1e6 100644 --- a/src/js/captions.js +++ b/src/js/captions.js @@ -6,7 +6,13 @@ import controls from './controls'; import i18n from './i18n'; import support from './support'; -import utils from './utils'; +import browser from './utils/browser'; +import { createElement, emptyElement, getAttributesFromSelector, insertAfter, removeElement, toggleClass } from './utils/elements'; +import { on, trigger } from './utils/events'; +import fetch from './utils/fetch'; +import is from './utils/is'; +import { getHTML } from './utils/strings'; +import { parseUrl } from './utils/urls'; const captions = { // Setup captions @@ -19,7 +25,7 @@ const captions = { // Only Vimeo and HTML5 video supported at this point if (!this.isVideo || this.isYouTube || (this.isHTML5 && !support.textTracks)) { // Clear menu and hide - if (utils.is.array(this.config.controls) && this.config.controls.includes('settings') && this.config.settings.includes('captions')) { + if (is.array(this.config.controls) && this.config.controls.includes('settings') && this.config.settings.includes('captions')) { controls.setCaptionsMenu.call(this); } @@ -27,15 +33,12 @@ const captions = { } // Inject the container - if (!utils.is.element(this.elements.captions)) { - this.elements.captions = utils.createElement('div', utils.getAttributesFromSelector(this.config.selectors.captions)); + if (!is.element(this.elements.captions)) { + this.elements.captions = createElement('div', getAttributesFromSelector(this.config.selectors.captions)); - utils.insertAfter(this.elements.captions, this.elements.wrapper); + insertAfter(this.elements.captions, this.elements.wrapper); } - // Get browser info - const browser = utils.getBrowser(); - // Fix IE captions if CORS is used // Fetch captions and inject as blobs instead (data URIs not supported!) if (browser.isIE && window.URL) { @@ -43,19 +46,18 @@ const captions = { Array.from(elements).forEach(track => { const src = track.getAttribute('src'); - const href = utils.parseUrl(src); + const url = parseUrl(src); - if (href.hostname !== window.location.href.hostname && [ + if (url !== null && url.hostname !== window.location.href.hostname && [ 'http:', 'https:', - ].includes(href.protocol)) { - utils - .fetch(src, 'blob') + ].includes(url.protocol)) { + fetch(src, 'blob') .then(blob => { track.setAttribute('src', window.URL.createObjectURL(blob)); }) .catch(() => { - utils.removeElement(track); + removeElement(track); }); } }); @@ -65,14 +67,14 @@ const captions = { let active = this.storage.get('captions'); // Otherwise fall back to the default config - if (!utils.is.boolean(active)) { + if (!is.boolean(active)) { ({ active } = this.config.captions); } // Get language from storage, fallback to config let language = this.storage.get('language') || this.config.captions.language; if (language === 'auto') { - [ language ] = (navigator.language || navigator.userLanguage).split('-'); + [language] = (navigator.language || navigator.userLanguage).split('-'); } // Set language and show if active captions.setLanguage.call(this, language, active); @@ -80,7 +82,7 @@ const captions = { // Watch changes to textTracks and update captions menu if (this.isHTML5) { const trackEvents = this.config.captions.update ? 'addtrack removetrack' : 'removetrack'; - utils.on(this.media.textTracks, trackEvents, captions.update.bind(this)); + on(this.media.textTracks, trackEvents, captions.update.bind(this)); } // Update available languages in list next tick (the event must not be triggered before the listeners) @@ -94,21 +96,19 @@ const captions = { // Handle tracks (add event listener and "pseudo"-default) if (this.isHTML5 && this.isVideo) { - tracks - .filter(track => !meta.get(track)) - .forEach(track => { - this.debug.log('Track added', track); - // Attempt to store if the original dom element was "default" - meta.set(track, { - default: track.mode === 'showing', - }); - - // Turn off native caption rendering to avoid double captions - track.mode = 'hidden'; - - // Add event listener for cue changes - utils.on(track, 'cuechange', () => captions.updateCues.call(this)); + tracks.filter(track => !meta.get(track)).forEach(track => { + this.debug.log('Track added', track); + // Attempt to store if the original dom element was "default" + meta.set(track, { + default: track.mode === 'showing', }); + + // Turn off native caption rendering to avoid double captions + track.mode = 'hidden'; + + // Add event listener for cue changes + on(track, 'cuechange', () => captions.updateCues.call(this)); + }); } const trackRemoved = !tracks.find(track => track === this.captions.currentTrackNode); @@ -120,7 +120,7 @@ const captions = { } // Enable or disable captions based on track length - utils.toggleClass(this.elements.container, this.config.classNames.captions.enabled, !utils.is.empty(tracks)); + toggleClass(this.elements.container, this.config.classNames.captions.enabled, !is.empty(tracks)); // Update available languages in list if ((this.config.controls || []).includes('settings') && this.config.settings.includes('captions')) { @@ -137,7 +137,7 @@ const captions = { return; } - if (!utils.is.number(index)) { + if (!is.number(index)) { this.debug.warn('Invalid caption argument', index); return; } @@ -166,7 +166,7 @@ const captions = { } // Trigger event - utils.dispatchEvent.call(this, this.media, 'languagechange'); + trigger.call(this, this.media, 'languagechange'); } if (this.isHTML5 && this.isVideo) { @@ -181,7 +181,7 @@ const captions = { }, setLanguage(language, show = true) { - if (!utils.is.string(language)) { + if (!is.string(language)) { this.debug.warn('Invalid language argument', language); return; } @@ -202,12 +202,10 @@ const captions = { const tracks = Array.from((this.media || {}).textTracks || []); // For HTML5, use cache instead of current tracks when it exists (if captions.update is false) // Filter out removed tracks and tracks that aren't captions/subtitles (for example metadata) - return tracks - .filter(track => !this.isHTML5 || update || this.captions.meta.has(track)) - .filter(track => [ - 'captions', - 'subtitles', - ].includes(track.kind)); + return tracks.filter(track => !this.isHTML5 || update || this.captions.meta.has(track)).filter(track => [ + 'captions', + 'subtitles', + ].includes(track.kind)); }, // Get the current track for the current language @@ -222,16 +220,16 @@ const captions = { getLabel(track) { let currentTrack = track; - if (!utils.is.track(currentTrack) && support.textTracks && this.captions.active) { + if (!is.track(currentTrack) && support.textTracks && this.captions.active) { currentTrack = captions.getCurrentTrack.call(this); } - if (utils.is.track(currentTrack)) { - if (!utils.is.empty(currentTrack.label)) { + if (is.track(currentTrack)) { + if (!is.empty(currentTrack.label)) { return currentTrack.label; } - if (!utils.is.empty(currentTrack.language)) { + if (!is.empty(currentTrack.language)) { return track.language.toUpperCase(); } @@ -249,13 +247,13 @@ const captions = { return; } - if (!utils.is.element(this.elements.captions)) { + if (!is.element(this.elements.captions)) { this.debug.warn('No captions element to render to'); return; } // Only accept array or empty input - if (!utils.is.nullOrUndefined(input) && !Array.isArray(input)) { + if (!is.nullOrUndefined(input) && !Array.isArray(input)) { this.debug.warn('updateCues: Invalid input', input); return; } @@ -267,7 +265,7 @@ const captions = { const track = captions.getCurrentTrack.call(this); cues = Array.from((track || {}).activeCues || []) .map(cue => cue.getCueAsHTML()) - .map(utils.getHTML); + .map(getHTML); } // Set new caption text @@ -276,13 +274,13 @@ const captions = { if (changed) { // Empty the container and create a new child element - utils.emptyElement(this.elements.captions); - const caption = utils.createElement('span', utils.getAttributesFromSelector(this.config.selectors.caption)); + emptyElement(this.elements.captions); + const caption = createElement('span', getAttributesFromSelector(this.config.selectors.caption)); caption.innerHTML = content; this.elements.captions.appendChild(caption); // Trigger event - utils.dispatchEvent.call(this, this.media, 'cuechange'); + trigger.call(this, this.media, 'cuechange'); } }, }; -- cgit v1.2.3 From 6bff6b317d6adcd9f94c8d4d8ee225d39f784e0f Mon Sep 17 00:00:00 2001 From: Albin Larsson Date: Wed, 13 Jun 2018 22:18:57 +0200 Subject: Remove line breaks in arrays --- src/js/captions.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src/js/captions.js') diff --git a/src/js/captions.js b/src/js/captions.js index 6682d6f0..5f78e636 100644 --- a/src/js/captions.js +++ b/src/js/captions.js @@ -48,10 +48,7 @@ const captions = { const src = track.getAttribute('src'); const url = parseUrl(src); - if (url !== null && url.hostname !== window.location.href.hostname && [ - 'http:', - 'https:', - ].includes(url.protocol)) { + if (url !== null && url.hostname !== window.location.href.hostname && ['http:', 'https:'].includes(url.protocol)) { fetch(src, 'blob') .then(blob => { track.setAttribute('src', window.URL.createObjectURL(blob)); @@ -202,10 +199,9 @@ const captions = { const tracks = Array.from((this.media || {}).textTracks || []); // For HTML5, use cache instead of current tracks when it exists (if captions.update is false) // Filter out removed tracks and tracks that aren't captions/subtitles (for example metadata) - return tracks.filter(track => !this.isHTML5 || update || this.captions.meta.has(track)).filter(track => [ - 'captions', - 'subtitles', - ].includes(track.kind)); + return tracks + .filter(track => !this.isHTML5 || update || this.captions.meta.has(track)) + .filter(track => ['captions', 'subtitles'].includes(track.kind)); }, // Get the current track for the current language -- cgit v1.2.3 From fa5d0ad3162151cb2ecd1737f42d81e18068db5e Mon Sep 17 00:00:00 2001 From: Albin Larsson Date: Thu, 14 Jun 2018 15:58:35 +0200 Subject: Move toggleCaption internals to captions object --- src/js/captions.js | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'src/js/captions.js') diff --git a/src/js/captions.js b/src/js/captions.js index 6682d6f0..24962387 100644 --- a/src/js/captions.js +++ b/src/js/captions.js @@ -7,7 +7,7 @@ import controls from './controls'; import i18n from './i18n'; import support from './support'; import browser from './utils/browser'; -import { createElement, emptyElement, getAttributesFromSelector, insertAfter, removeElement, toggleClass } from './utils/elements'; +import { createElement, emptyElement, getAttributesFromSelector, insertAfter, removeElement, toggleClass, toggleState } from './utils/elements'; import { on, triggerEvent } from './utils/events'; import fetch from './utils/fetch'; import is from './utils/is'; @@ -128,6 +128,28 @@ const captions = { } }, + toggle(input) { + // If there's no full support + if (!this.supported.ui) { + return; + } + + // If the method is called without parameter, toggle based on current value + const active = is.boolean(input) ? input : !this.elements.container.classList.contains(this.config.classNames.captions.active); + + // Toggle state + toggleState(this.elements.buttons.captions, active); + + // Add class hook + toggleClass(this.elements.container, this.config.classNames.captions.active, active); + + // Update state and trigger event + if (active !== this.captions.active) { + this.captions.active = active; + triggerEvent.call(this, this.media, this.captions.active ? 'captionsenabled' : 'captionsdisabled'); + } + }, + set(index, setLanguage = true, show = true) { const tracks = captions.getTracks.call(this); -- cgit v1.2.3 From 6ce9a94932c8cb8e2740bec961c7e2751052e3ab Mon Sep 17 00:00:00 2001 From: Albin Larsson Date: Thu, 14 Jun 2018 16:10:36 +0200 Subject: Move internal event listeners for captions with direct handling in the captions object --- src/js/captions.js | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src/js/captions.js') diff --git a/src/js/captions.js b/src/js/captions.js index 24962387..4103d019 100644 --- a/src/js/captions.js +++ b/src/js/captions.js @@ -128,6 +128,7 @@ const captions = { } }, + // Used internally for toggleCaptions() toggle(input) { // If there's no full support if (!this.supported.ui) { @@ -146,10 +147,19 @@ const captions = { // Update state and trigger event if (active !== this.captions.active) { this.captions.active = active; - triggerEvent.call(this, this.media, this.captions.active ? 'captionsenabled' : 'captionsdisabled'); + + // Update UI + controls.updateSetting.call(this, 'captions'); + + // Save to storage + this.storage.set({ captions: active }); + + // Trigger event (not used internally) + triggerEvent.call(this, this.media, active ? 'captionsenabled' : 'captionsdisabled'); } }, + // Used internally for currentTrack setter set(index, setLanguage = true, show = true) { const tracks = captions.getTracks.call(this); @@ -187,7 +197,13 @@ const captions = { this.embed.enableTextTrack(language); } - // Trigger event + // Update UI + controls.updateSetting.call(this, 'captions'); + + // Save to storage + this.storage.set({ language }); + + // Trigger event (not used internally) triggerEvent.call(this, this.media, 'languagechange'); } @@ -202,6 +218,7 @@ const captions = { } }, + // Used internally for language setter setLanguage(language, show = true) { if (!is.string(language)) { this.debug.warn('Invalid language argument', language); -- cgit v1.2.3 From 19e412a73ac2e3e9f4c6ac9a086557a936109287 Mon Sep 17 00:00:00 2001 From: Albin Larsson Date: Fri, 15 Jun 2018 06:06:16 +0200 Subject: Add 'passive' flag to internal captions methods to avoid overriding user preferences, support multiple browser languages (get first match) and improve comments --- src/js/captions.js | 155 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 101 insertions(+), 54 deletions(-) (limited to 'src/js/captions.js') diff --git a/src/js/captions.js b/src/js/captions.js index 4103d019..63674b95 100644 --- a/src/js/captions.js +++ b/src/js/captions.js @@ -11,6 +11,7 @@ import { createElement, emptyElement, getAttributesFromSelector, insertAfter, re import { on, triggerEvent } from './utils/events'; import fetch from './utils/fetch'; import is from './utils/is'; +import { dedupe } from './utils/arrays'; import { getHTML } from './utils/strings'; import { parseUrl } from './utils/urls'; @@ -63,21 +64,34 @@ const captions = { }); } - // Try to load the value from storage - let active = this.storage.get('captions'); + // Get and set initial data + // The "preferred" options are not realized unless / until the wanted language has a match + // * languages: Array of user's browser languages. + // * language: The language preferred by user settings or config + // * active: The state preferred by user settings or config + // * toggled: The real captions state - // Otherwise fall back to the default config - if (!is.boolean(active)) { - ({ active } = this.config.captions); - } + const languages = dedupe(Array.from(navigator.languages || navigator.userLanguage) + .map(language => language.split('-')[0])); - // Get language from storage, fallback to config let language = this.storage.get('language') || this.config.captions.language; + + // Use first browser language when language is 'auto' if (language === 'auto') { - [language] = (navigator.language || navigator.userLanguage).split('-'); + [language] = languages; } - // Set language and show if active - captions.setLanguage.call(this, language, active); + + let active = this.storage.get('captions'); + if (!is.boolean(active)) { + ({ active } = this.config.captions); + } + + Object.assign(this.captions, { + toggled: false, + active, + language, + languages, + }); // Watch changes to textTracks and update captions menu if (this.isHTML5) { @@ -89,10 +103,12 @@ const captions = { setTimeout(captions.update.bind(this), 0); }, + // Update available language options in settings based on tracks update() { const tracks = captions.getTracks.call(this, true); // Get the wanted language - const { language, meta } = this.captions; + const { active, language, meta, currentTrackNode } = this.captions; + const languageExists = Boolean(tracks.find(track => track.language === language)); // Handle tracks (add event listener and "pseudo"-default) if (this.isHTML5 && this.isVideo) { @@ -111,12 +127,10 @@ const captions = { }); } - const trackRemoved = !tracks.find(track => track === this.captions.currentTrackNode); - const firstMatch = this.language !== language && tracks.find(track => track.language === language); - - // Update language if removed or first matching track added - if (trackRemoved || firstMatch) { - captions.setLanguage.call(this, language, this.config.captions.active); + // Update language first time it matches, or if the previous matching track was removed + if ((languageExists && this.language !== language) || !tracks.includes(currentTrackNode)) { + captions.setLanguage.call(this, language); + captions.toggle.call(this, active && languageExists); } // Enable or disable captions based on track length @@ -128,44 +142,69 @@ const captions = { } }, - // Used internally for toggleCaptions() - toggle(input) { + // Toggle captions display + // Used internally for the toggleCaptions method, with the passive option forced to false + toggle(input, passive = true) { // If there's no full support if (!this.supported.ui) { return; } + const { toggled } = this.captions; // Current state + const activeClass = this.config.classNames.captions.active; + + // Get the next state // If the method is called without parameter, toggle based on current value - const active = is.boolean(input) ? input : !this.elements.container.classList.contains(this.config.classNames.captions.active); + const active = is.nullOrUndefined(input) ? !toggled : input; - // Toggle state - toggleState(this.elements.buttons.captions, active); + // Update state and trigger event + if (active !== toggled) { + // Force language if the call isn't passive and there is no matching language to toggle to + if (!this.language && active && !passive) { + const tracks = captions.getTracks.call(this); + const track = captions.findTrack.call(this, [ + this.captions.language, + ...this.captions.languages, + ], true); + + // Override user preferences to avoid switching languages if a matching track is added + this.captions.language = track.language; + + // Set caption, but don't store in localStorage as user preference + captions.set.call(this, tracks.indexOf(track)); + return; + } - // Add class hook - toggleClass(this.elements.container, this.config.classNames.captions.active, active); + // Toggle state + toggleState(this.elements.buttons.captions, active); - // Update state and trigger event - if (active !== this.captions.active) { - this.captions.active = active; + // Add class hook + toggleClass(this.elements.container, activeClass, active); + + this.captions.toggled = active; - // Update UI + // Update settings menu controls.updateSetting.call(this, 'captions'); - // Save to storage - this.storage.set({ captions: active }); + // When passive, don't override user preferences + if (!passive) { + this.captions.active = active; + this.storage.set({ captions: active }); + } // Trigger event (not used internally) triggerEvent.call(this, this.media, active ? 'captionsenabled' : 'captionsdisabled'); } }, - // Used internally for currentTrack setter - set(index, setLanguage = true, show = true) { + // Set captions by track index + // Used internally for the currentTrack setter with the passive option forced to false + set(index, passive = true) { const tracks = captions.getTracks.call(this); // Disable captions if setting to -1 if (index === -1) { - this.toggleCaptions(false); + captions.toggle.call(this, false, passive); return; } @@ -181,15 +220,19 @@ const captions = { if (this.captions.currentTrack !== index) { this.captions.currentTrack = index; - const track = captions.getCurrentTrack.call(this); + const track = tracks[index]; const { language } = track || {}; // Store reference to node for invalidation on remove this.captions.currentTrackNode = track; - // Prevent setting language in some cases, since it can violate user's intentions - if (setLanguage) { + // Update settings menu + controls.updateSetting.call(this, 'captions'); + + // When passive, don't override user preferences + if (!passive) { this.captions.language = language; + this.storage.set({ language }); } // Handle Vimeo captions @@ -197,13 +240,7 @@ const captions = { this.embed.enableTextTrack(language); } - // Update UI - controls.updateSetting.call(this, 'captions'); - - // Save to storage - this.storage.set({ language }); - - // Trigger event (not used internally) + // Trigger event triggerEvent.call(this, this.media, 'languagechange'); } @@ -213,13 +250,12 @@ const captions = { } // Show captions - if (show) { - this.toggleCaptions(true); - } + captions.toggle.call(this, true, passive); }, - // Used internally for language setter - setLanguage(language, show = true) { + // Set captions by language + // Used internally for the language setter with the passive option forced to false + setLanguage(language, passive = true) { if (!is.string(language)) { this.debug.warn('Invalid language argument', language); return; @@ -229,8 +265,8 @@ const captions = { // Set currentTrack const tracks = captions.getTracks.call(this); - const track = captions.getCurrentTrack.call(this, true); - captions.set.call(this, tracks.indexOf(track), false, show); + const track = captions.findTrack.call(this, [language]); + captions.set.call(this, tracks.indexOf(track), passive); }, // Get current valid caption tracks @@ -247,19 +283,30 @@ const captions = { ].includes(track.kind)); }, - // Get the current track for the current language - getCurrentTrack(fromLanguage = false) { + // Match tracks based on languages and get the first + findTrack(languages, force = false) { const tracks = captions.getTracks.call(this); const sortIsDefault = track => Number((this.captions.meta.get(track) || {}).default); const sorted = Array.from(tracks).sort((a, b) => sortIsDefault(b) - sortIsDefault(a)); - return (!fromLanguage && tracks[this.currentTrack]) || sorted.find(track => track.language === this.captions.language) || sorted[0]; + let track; + languages.every(language => { + track = sorted.find(track => track.language === language); + return !track; // Break iteration if there is a match + }); + // If no match is found but is required, get first + return track || (force ? sorted[0] : undefined); + }, + + // Get the current track + getCurrentTrack() { + return captions.getTracks.call(this)[this.currentTrack]; }, // Get UI label for track getLabel(track) { let currentTrack = track; - if (!is.track(currentTrack) && support.textTracks && this.captions.active) { + if (!is.track(currentTrack) && support.textTracks && this.captions.toggled) { currentTrack = captions.getCurrentTrack.call(this); } -- cgit v1.2.3 From 1f09493ba2253eb234803b5ebe74ad1649253bb9 Mon Sep 17 00:00:00 2001 From: Albin Larsson Date: Sat, 16 Jun 2018 01:07:16 +0200 Subject: Captions: Handle uppercase input (like before) --- src/js/captions.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/js/captions.js') diff --git a/src/js/captions.js b/src/js/captions.js index fd2692f7..d6666cf2 100644 --- a/src/js/captions.js +++ b/src/js/captions.js @@ -71,7 +71,7 @@ const captions = { const languages = dedupe(Array.from(navigator.languages || navigator.userLanguage) .map(language => language.split('-')[0])); - let language = this.storage.get('language') || this.config.captions.language; + let language = (this.storage.get('language') || this.config.captions.language || 'auto').toLowerCase(); // Use first browser language when language is 'auto' if (language === 'auto') { @@ -252,13 +252,14 @@ const captions = { // Set captions by language // Used internally for the language setter with the passive option forced to false - setLanguage(language, passive = true) { - if (!is.string(language)) { - this.debug.warn('Invalid language argument', language); + setLanguage(input, passive = true) { + if (!is.string(input)) { + this.debug.warn('Invalid language argument', input); return; } // Normalize - this.captions.language = language.toLowerCase(); + const language = input.toLowerCase(); + this.captions.language = language; // Set currentTrack const tracks = captions.getTracks.call(this); -- cgit v1.2.3 From 8f359adf9c510a2c4c5a9fc4ecea542c2b782083 Mon Sep 17 00:00:00 2001 From: Albin Larsson Date: Sat, 16 Jun 2018 01:23:47 +0200 Subject: Fix captions.toggle order --- src/js/captions.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/js/captions.js') diff --git a/src/js/captions.js b/src/js/captions.js index d6666cf2..94500290 100644 --- a/src/js/captions.js +++ b/src/js/captions.js @@ -156,6 +156,12 @@ const captions = { // Update state and trigger event if (active !== toggled) { + // When passive, don't override user preferences + if (!passive) { + this.captions.active = active; + this.storage.set({ captions: active }); + } + // Force language if the call isn't passive and there is no matching language to toggle to if (!this.language && active && !passive) { const tracks = captions.getTracks.call(this); @@ -183,12 +189,6 @@ const captions = { // Update settings menu controls.updateSetting.call(this, 'captions'); - // When passive, don't override user preferences - if (!passive) { - this.captions.active = active; - this.storage.set({ captions: active }); - } - // Trigger event (not used internally) triggerEvent.call(this, this.media, active ? 'captionsenabled' : 'captionsdisabled'); } @@ -241,13 +241,13 @@ const captions = { triggerEvent.call(this, this.media, 'languagechange'); } + // Show captions + captions.toggle.call(this, true, passive); + if (this.isHTML5 && this.isVideo) { // If we change the active track while a cue is already displayed we need to update it captions.updateCues.call(this); } - - // Show captions - captions.toggle.call(this, true, passive); }, // Set captions by language -- cgit v1.2.3 From d4abb4b1438cb316aacae480e7b7e9b055a60b24 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sun, 17 Jun 2018 01:04:55 +1000 Subject: 120 line width, package upgrade --- src/js/captions.js | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'src/js/captions.js') diff --git a/src/js/captions.js b/src/js/captions.js index 94500290..28d5cb91 100644 --- a/src/js/captions.js +++ b/src/js/captions.js @@ -6,12 +6,20 @@ import controls from './controls'; import i18n from './i18n'; import support from './support'; +import { dedupe } from './utils/arrays'; import browser from './utils/browser'; -import { createElement, emptyElement, getAttributesFromSelector, insertAfter, removeElement, toggleClass, toggleState } from './utils/elements'; +import { + createElement, + emptyElement, + getAttributesFromSelector, + insertAfter, + removeElement, + toggleClass, + toggleState, +} from './utils/elements'; import { on, triggerEvent } from './utils/events'; import fetch from './utils/fetch'; import is from './utils/is'; -import { dedupe } from './utils/arrays'; import { getHTML } from './utils/strings'; import { parseUrl } from './utils/urls'; @@ -26,7 +34,11 @@ const captions = { // Only Vimeo and HTML5 video supported at this point if (!this.isVideo || this.isYouTube || (this.isHTML5 && !support.textTracks)) { // Clear menu and hide - if (is.array(this.config.controls) && this.config.controls.includes('settings') && this.config.settings.includes('captions')) { + if ( + is.array(this.config.controls) && + this.config.controls.includes('settings') && + this.config.settings.includes('captions') + ) { controls.setCaptionsMenu.call(this); } @@ -49,7 +61,11 @@ const captions = { const src = track.getAttribute('src'); const url = parseUrl(src); - if (url !== null && url.hostname !== window.location.href.hostname && ['http:', 'https:'].includes(url.protocol)) { + if ( + url !== null && + url.hostname !== window.location.href.hostname && + ['http:', 'https:'].includes(url.protocol) + ) { fetch(src, 'blob') .then(blob => { track.setAttribute('src', window.URL.createObjectURL(blob)); @@ -68,8 +84,9 @@ const captions = { // * active: The state preferred by user settings or config // * toggled: The real captions state - const languages = dedupe(Array.from(navigator.languages || navigator.userLanguage) - .map(language => language.split('-')[0])); + const languages = dedupe( + Array.from(navigator.languages || navigator.userLanguage).map(language => language.split('-')[0]), + ); let language = (this.storage.get('language') || this.config.captions.language || 'auto').toLowerCase(); @@ -165,10 +182,7 @@ const captions = { // Force language if the call isn't passive and there is no matching language to toggle to if (!this.language && active && !passive) { const tracks = captions.getTracks.call(this); - const track = captions.findTrack.call(this, [ - this.captions.language, - ...this.captions.languages, - ], true); + const track = captions.findTrack.call(this, [this.captions.language, ...this.captions.languages], true); // Override user preferences to avoid switching languages if a matching track is added this.captions.language = track.language; -- cgit v1.2.3