diff --git a/package.json b/package.json
index bd2605372c..520e9c59e2 100644
--- a/package.json
+++ b/package.json
@@ -163,6 +163,8 @@
"src/components/search/searchresults.js",
"src/components/settingshelper.js",
"src/components/shortcuts.js",
+ "src/components/subtitleeditor/subtitleeditor.js",
+ "src/components/subtitlesync/subtitlesync.js",
"src/components/subtitlesettings/subtitleappearancehelper.js",
"src/components/subtitlesettings/subtitlesettings.js",
"src/components/syncPlay/groupSelectionMenu.js",
diff --git a/src/components/subtitleeditor/subtitleeditor.js b/src/components/subtitleeditor/subtitleeditor.js
index b52b911cb9..dfd7f9446c 100644
--- a/src/components/subtitleeditor/subtitleeditor.js
+++ b/src/components/subtitleeditor/subtitleeditor.js
@@ -1,428 +1,437 @@
-define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', 'connectionManager', 'loading', 'focusManager', 'dom', 'apphost', 'emby-select', 'listViewStyle', 'paper-icon-button-light', 'css!./../formdialog', 'material-icons', 'css!./subtitleeditor', 'emby-button', 'flexStyles'], function (dialogHelper, require, layoutManager, globalize, userSettings, connectionManager, loading, focusManager, dom, appHost) {
- 'use strict';
+import dialogHelper from 'dialogHelper';
+import layoutManager from 'layoutManager';
+import globalize from 'globalize';
+import * as userSettings from 'userSettings';
+import connectionManager from 'connectionManager';
+import loading from 'loading';
+import focusManager from 'focusManager';
+import dom from 'dom';
+import 'emby-select';
+import 'listViewStyle';
+import 'paper-icon-button-light';
+import 'css!./../formdialog';
+import 'material-icons';
+import 'css!./subtitleeditor';
+import 'emby-button';
+import 'flexStyles';
- loading = loading.default || loading;
- focusManager = focusManager.default || focusManager;
+let currentItem;
+let hasChanges;
- var currentItem;
- var hasChanges;
+function downloadRemoteSubtitles(context, id) {
+ let url = 'Items/' + currentItem.Id + '/RemoteSearch/Subtitles/' + id;
- function downloadRemoteSubtitles(context, id) {
- var url = 'Items/' + currentItem.Id + '/RemoteSearch/Subtitles/' + id;
+ let apiClient = connectionManager.getApiClient(currentItem.ServerId);
+ apiClient.ajax({
- var apiClient = connectionManager.getApiClient(currentItem.ServerId);
- apiClient.ajax({
+ type: 'POST',
+ url: apiClient.getUrl(url)
- type: 'POST',
- url: apiClient.getUrl(url)
+ }).then(function () {
+ hasChanges = true;
+
+ import('toast').then(({default: toast}) => {
+ toast(globalize.translate('MessageDownloadQueued'));
+ });
+
+ focusManager.autoFocus(context);
+ });
+}
+
+function deleteLocalSubtitle(context, index) {
+ let msg = globalize.translate('MessageAreYouSureDeleteSubtitles');
+
+ import('confirm').then(({default: confirm}) => {
+ confirm({
+
+ title: globalize.translate('ConfirmDeletion'),
+ text: msg,
+ confirmText: globalize.translate('Delete'),
+ primary: 'delete'
}).then(function () {
- hasChanges = true;
+ loading.show();
- require(['toast'], function (toast) {
- toast(globalize.translate('MessageDownloadQueued'));
- });
+ let itemId = currentItem.Id;
+ let url = 'Videos/' + itemId + '/Subtitles/' + index;
- focusManager.autoFocus(context);
- });
- }
+ let apiClient = connectionManager.getApiClient(currentItem.ServerId);
- function deleteLocalSubtitle(context, index) {
- var msg = globalize.translate('MessageAreYouSureDeleteSubtitles');
+ apiClient.ajax({
- require(['confirm'], function (confirm) {
- confirm.default({
-
- title: globalize.translate('ConfirmDeletion'),
- text: msg,
- confirmText: globalize.translate('Delete'),
- primary: 'delete'
+ type: 'DELETE',
+ url: apiClient.getUrl(url)
}).then(function () {
- loading.show();
-
- var itemId = currentItem.Id;
- var url = 'Videos/' + itemId + '/Subtitles/' + index;
-
- var apiClient = connectionManager.getApiClient(currentItem.ServerId);
-
- apiClient.ajax({
-
- type: 'DELETE',
- url: apiClient.getUrl(url)
-
- }).then(function () {
- hasChanges = true;
- reload(context, apiClient, itemId);
- });
+ hasChanges = true;
+ reload(context, apiClient, itemId);
});
});
- }
+ });
+}
- function fillSubtitleList(context, item) {
- var streams = item.MediaStreams || [];
+function fillSubtitleList(context, item) {
+ let streams = item.MediaStreams || [];
- var subs = streams.filter(function (s) {
- return s.Type === 'Subtitle';
- });
+ let subs = streams.filter(function (s) {
+ return s.Type === 'Subtitle';
+ });
- var html = '';
+ let html = '';
- if (subs.length) {
- html += '
' + globalize.translate('MySubtitles') + '
';
+ if (subs.length) {
+ html += '' + globalize.translate('MySubtitles') + '
';
- html += '';
+ html += '
';
- html += subs.map(function (s) {
- var itemHtml = '';
+ html += subs.map(function (s) {
+ let itemHtml = '';
- var tagName = layoutManager.tv ? 'button' : 'div';
- var className = layoutManager.tv && s.Path ? 'listItem listItem-border btnDelete' : 'listItem listItem-border';
+ let tagName = layoutManager.tv ? 'button' : 'div';
+ let className = layoutManager.tv && s.Path ? 'listItem listItem-border btnDelete' : 'listItem listItem-border';
- if (layoutManager.tv) {
- className += ' listItem-focusscale listItem-button';
- }
-
- className += ' listItem-noborder';
-
- itemHtml += '<' + tagName + ' class="' + className + '" data-index="' + s.Index + '">';
-
- itemHtml += '
';
-
- itemHtml += '
';
-
- itemHtml += '
';
- itemHtml += s.DisplayTitle || '';
- itemHtml += '
';
-
- if (s.Path) {
- itemHtml += '
' + (s.Path) + '
';
- }
-
- itemHtml += '';
- itemHtml += '
';
-
- if (!layoutManager.tv) {
- if (s.Path) {
- itemHtml += '
';
- }
- }
-
- itemHtml += '' + tagName + '>';
-
- return itemHtml;
- }).join('');
-
- html += '
';
- }
-
- var elem = context.querySelector('.subtitleList');
-
- if (subs.length) {
- elem.classList.remove('hide');
- } else {
- elem.classList.add('hide');
- }
- elem.innerHTML = html;
- }
-
- function fillLanguages(context, apiClient, languages) {
- var selectLanguage = context.querySelector('#selectLanguage');
-
- selectLanguage.innerHTML = languages.map(function (l) {
- return '
';
- });
-
- var lastLanguage = userSettings.get('subtitleeditor-language');
- if (lastLanguage) {
- selectLanguage.value = lastLanguage;
- } else {
- apiClient.getCurrentUser().then(function (user) {
- var lang = user.Configuration.SubtitleLanguagePreference;
-
- if (lang) {
- selectLanguage.value = lang;
- }
- });
- }
- }
-
- function renderSearchResults(context, results) {
- var lastProvider = '';
- var html = '';
-
- if (!results.length) {
- context.querySelector('.noSearchResults').classList.remove('hide');
- context.querySelector('.subtitleResults').innerHTML = '';
- loading.hide();
- return;
- }
-
- context.querySelector('.noSearchResults').classList.add('hide');
-
- for (var i = 0, length = results.length; i < length; i++) {
- var result = results[i];
-
- var provider = result.ProviderName;
-
- if (provider !== lastProvider) {
- if (i > 0) {
- html += '
';
- }
- html += '' + provider + '
';
- html += '';
- lastProvider = provider;
- }
-
- var tagName = layoutManager.tv ? 'button' : 'div';
- var className = layoutManager.tv ? 'listItem listItem-border btnOptions' : 'listItem listItem-border';
if (layoutManager.tv) {
className += ' listItem-focusscale listItem-button';
}
- html += '<' + tagName + ' class="' + className + '" data-subid="' + result.Id + '">';
+ className += ' listItem-noborder';
- html += '
';
+ itemHtml += '<' + tagName + ' class="' + className + '" data-index="' + s.Index + '">';
- var bodyClass = result.Comment || result.IsHashMatch ? 'three-line' : 'two-line';
+ itemHtml += '
';
- html += '
';
+ itemHtml += '
';
- html += '
' + (result.Name) + '
';
- html += '
';
+ itemHtml += '
';
+ itemHtml += s.DisplayTitle || '';
+ itemHtml += '
';
- if (result.Format) {
- html += '
' + globalize.translate('FormatValue', result.Format) + '';
+ if (s.Path) {
+ itemHtml += '
' + (s.Path) + '
';
}
- if (result.DownloadCount != null) {
- html += '
' + globalize.translate('DownloadsValue', result.DownloadCount) + '';
- }
- html += '
';
-
- if (result.Comment) {
- html += '
' + (result.Comment) + '
';
- }
-
- if (result.IsHashMatch) {
- html += '
' + globalize.translate('PerfectMatch') + '
';
- }
-
- html += '
';
+ itemHtml += '';
+ itemHtml += '
';
if (!layoutManager.tv) {
- html += '
';
+ if (s.Path) {
+ itemHtml += '
';
+ }
}
- html += '' + tagName + '>';
+ itemHtml += '' + tagName + '>';
+
+ return itemHtml;
+ }).join('');
+
+ html += '
';
+ }
+
+ let elem = context.querySelector('.subtitleList');
+
+ if (subs.length) {
+ elem.classList.remove('hide');
+ } else {
+ elem.classList.add('hide');
+ }
+ elem.innerHTML = html;
+}
+
+function fillLanguages(context, apiClient, languages) {
+ let selectLanguage = context.querySelector('#selectLanguage');
+
+ selectLanguage.innerHTML = languages.map(function (l) {
+ return '';
+ });
+
+ let lastLanguage = userSettings.get('subtitleeditor-language');
+ if (lastLanguage) {
+ selectLanguage.value = lastLanguage;
+ } else {
+ apiClient.getCurrentUser().then(function (user) {
+ let lang = user.Configuration.SubtitleLanguagePreference;
+
+ if (lang) {
+ selectLanguage.value = lang;
+ }
+ });
+ }
+}
+
+function renderSearchResults(context, results) {
+ let lastProvider = '';
+ let html = '';
+
+ if (!results.length) {
+ context.querySelector('.noSearchResults').classList.remove('hide');
+ context.querySelector('.subtitleResults').innerHTML = '';
+ loading.hide();
+ return;
+ }
+
+ context.querySelector('.noSearchResults').classList.add('hide');
+
+ for (let i = 0, length = results.length; i < length; i++) {
+ let result = results[i];
+
+ let provider = result.ProviderName;
+
+ if (provider !== lastProvider) {
+ if (i > 0) {
+ html += '';
+ }
+ html += '' + provider + '
';
+ html += '';
+ lastProvider = provider;
}
- if (results.length) {
- html += '
';
+ let tagName = layoutManager.tv ? 'button' : 'div';
+ let className = layoutManager.tv ? 'listItem listItem-border btnOptions' : 'listItem listItem-border';
+ if (layoutManager.tv) {
+ className += ' listItem-focusscale listItem-button';
}
- var elem = context.querySelector('.subtitleResults');
- elem.innerHTML = html;
+ html += '<' + tagName + ' class="' + className + '" data-subid="' + result.Id + '">';
+
+ html += '';
+
+ let bodyClass = result.Comment || result.IsHashMatch ? 'three-line' : 'two-line';
+
+ html += '';
+
+ html += '
' + (result.Name) + '
';
+ html += '
';
+
+ if (result.Format) {
+ html += '' + globalize.translate('FormatValue', result.Format) + '';
+ }
+
+ if (result.DownloadCount != null) {
+ html += '' + globalize.translate('DownloadsValue', result.DownloadCount) + '';
+ }
+ html += '
';
+
+ if (result.Comment) {
+ html += '
' + (result.Comment) + '
';
+ }
+
+ if (result.IsHashMatch) {
+ html += '
' + globalize.translate('PerfectMatch') + '
';
+ }
+
+ html += '
';
+
+ if (!layoutManager.tv) {
+ html += '';
+ }
+
+ html += '' + tagName + '>';
+ }
+
+ if (results.length) {
+ html += '';
+ }
+
+ let elem = context.querySelector('.subtitleResults');
+ elem.innerHTML = html;
+
+ loading.hide();
+}
+
+function searchForSubtitles(context, language) {
+ userSettings.set('subtitleeditor-language', language);
+
+ loading.show();
+
+ let apiClient = connectionManager.getApiClient(currentItem.ServerId);
+ let url = apiClient.getUrl('Items/' + currentItem.Id + '/RemoteSearch/Subtitles/' + language);
+
+ apiClient.getJSON(url).then(function (results) {
+ renderSearchResults(context, results);
+ });
+}
+
+function reload(context, apiClient, itemId) {
+ context.querySelector('.noSearchResults').classList.add('hide');
+
+ function onGetItem(item) {
+ currentItem = item;
+
+ fillSubtitleList(context, item);
+ let file = item.Path || '';
+ let index = Math.max(file.lastIndexOf('/'), file.lastIndexOf('\\'));
+ if (index > -1) {
+ file = file.substring(index + 1);
+ }
+
+ if (file) {
+ context.querySelector('.pathValue').innerHTML = file;
+ context.querySelector('.originalFile').classList.remove('hide');
+ } else {
+ context.querySelector('.pathValue').innerHTML = '';
+ context.querySelector('.originalFile').classList.add('hide');
+ }
loading.hide();
}
- function searchForSubtitles(context, language) {
- userSettings.set('subtitleeditor-language', language);
+ if (typeof itemId === 'string') {
+ apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(onGetItem);
+ } else {
+ onGetItem(itemId);
+ }
+}
- loading.show();
+function onSearchSubmit(e) {
+ let form = this;
- var apiClient = connectionManager.getApiClient(currentItem.ServerId);
- var url = apiClient.getUrl('Items/' + currentItem.Id + '/RemoteSearch/Subtitles/' + language);
+ let lang = form.querySelector('#selectLanguage', form).value;
- apiClient.getJSON(url).then(function (results) {
- renderSearchResults(context, results);
- });
+ searchForSubtitles(dom.parentWithClass(form, 'formDialogContent'), lang);
+
+ e.preventDefault();
+ return false;
+}
+
+function onSubtitleListClick(e) {
+ let btnDelete = dom.parentWithClass(e.target, 'btnDelete');
+ if (btnDelete) {
+ let index = btnDelete.getAttribute('data-index');
+ let context = dom.parentWithClass(btnDelete, 'subtitleEditorDialog');
+ deleteLocalSubtitle(context, index);
+ }
+}
+
+function onSubtitleResultsClick(e) {
+ let subtitleId;
+ let context;
+
+ let btnOptions = dom.parentWithClass(e.target, 'btnOptions');
+ if (btnOptions) {
+ subtitleId = btnOptions.getAttribute('data-subid');
+ context = dom.parentWithClass(btnOptions, 'subtitleEditorDialog');
+ showDownloadOptions(btnOptions, context, subtitleId);
}
- function reload(context, apiClient, itemId) {
- context.querySelector('.noSearchResults').classList.add('hide');
+ let btnDownload = dom.parentWithClass(e.target, 'btnDownload');
+ if (btnDownload) {
+ subtitleId = btnDownload.getAttribute('data-subid');
+ context = dom.parentWithClass(btnDownload, 'subtitleEditorDialog');
+ downloadRemoteSubtitles(context, subtitleId);
+ }
+}
- function onGetItem(item) {
- currentItem = item;
+function showDownloadOptions(button, context, subtitleId) {
+ let items = [];
- fillSubtitleList(context, item);
- var file = item.Path || '';
- var index = Math.max(file.lastIndexOf('/'), file.lastIndexOf('\\'));
- if (index > -1) {
- file = file.substring(index + 1);
+ items.push({
+ name: globalize.translate('Download'),
+ id: 'download'
+ });
+
+ import('actionsheet').then(({default: actionsheet}) => {
+ actionsheet.show({
+ items: items,
+ positionTo: button
+
+ }).then(function (id) {
+ switch (id) {
+ case 'download':
+ downloadRemoteSubtitles(context, subtitleId);
+ break;
+ default:
+ break;
}
+ });
+ });
+}
- if (file) {
- context.querySelector('.pathValue').innerHTML = file;
- context.querySelector('.originalFile').classList.remove('hide');
- } else {
- context.querySelector('.pathValue').innerHTML = '';
- context.querySelector('.originalFile').classList.add('hide');
- }
+function centerFocus(elem, horiz, on) {
+ import('scrollHelper').then(({default: scrollHelper}) => {
+ let fn = on ? 'on' : 'off';
+ scrollHelper.centerFocus[fn](elem, horiz);
+ });
+}
- loading.hide();
- }
+function showEditorInternal(itemId, serverId, template) {
+ hasChanges = false;
- if (typeof itemId === 'string') {
- apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(onGetItem);
+ let apiClient = connectionManager.getApiClient(serverId);
+ return apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(function (item) {
+ let dialogOptions = {
+ removeOnClose: true,
+ scrollY: false
+ };
+
+ if (layoutManager.tv) {
+ dialogOptions.size = 'fullscreen';
} else {
- onGetItem(itemId);
- }
- }
-
- function onSearchSubmit(e) {
- var form = this;
-
- var lang = form.querySelector('#selectLanguage', form).value;
-
- searchForSubtitles(dom.parentWithClass(form, 'formDialogContent'), lang);
-
- e.preventDefault();
- return false;
- }
-
- function onSubtitleListClick(e) {
- var btnDelete = dom.parentWithClass(e.target, 'btnDelete');
- if (btnDelete) {
- var index = btnDelete.getAttribute('data-index');
- var context = dom.parentWithClass(btnDelete, 'subtitleEditorDialog');
- deleteLocalSubtitle(context, index);
- }
- }
-
- function onSubtitleResultsClick(e) {
- var subtitleId;
- var context;
-
- var btnOptions = dom.parentWithClass(e.target, 'btnOptions');
- if (btnOptions) {
- subtitleId = btnOptions.getAttribute('data-subid');
- context = dom.parentWithClass(btnOptions, 'subtitleEditorDialog');
- showDownloadOptions(btnOptions, context, subtitleId);
+ dialogOptions.size = 'small';
}
- var btnDownload = dom.parentWithClass(e.target, 'btnDownload');
- if (btnDownload) {
- subtitleId = btnDownload.getAttribute('data-subid');
- context = dom.parentWithClass(btnDownload, 'subtitleEditorDialog');
- downloadRemoteSubtitles(context, subtitleId);
+ let dlg = dialogHelper.createDialog(dialogOptions);
+
+ dlg.classList.add('formDialog');
+ dlg.classList.add('subtitleEditorDialog');
+
+ dlg.innerHTML = globalize.translateHtml(template, 'core');
+
+ dlg.querySelector('.originalSubtitleFileLabel').innerHTML = globalize.translate('File');
+
+ dlg.querySelector('.subtitleSearchForm').addEventListener('submit', onSearchSubmit);
+
+ let btnSubmit = dlg.querySelector('.btnSubmit');
+
+ if (layoutManager.tv) {
+ centerFocus(dlg.querySelector('.formDialogContent'), false, true);
+ dlg.querySelector('.btnSearchSubtitles').classList.add('hide');
+ } else {
+ btnSubmit.classList.add('hide');
}
- }
- function showDownloadOptions(button, context, subtitleId) {
- var items = [];
+ let editorContent = dlg.querySelector('.formDialogContent');
- items.push({
- name: globalize.translate('Download'),
- id: 'download'
+ dlg.querySelector('.subtitleList').addEventListener('click', onSubtitleListClick);
+ dlg.querySelector('.subtitleResults').addEventListener('click', onSubtitleResultsClick);
+
+ apiClient.getCultures().then(function (languages) {
+ fillLanguages(editorContent, apiClient, languages);
});
- require(['actionsheet'], function (actionsheet) {
- actionsheet.show({
- items: items,
- positionTo: button
-
- }).then(function (id) {
- switch (id) {
- case 'download':
- downloadRemoteSubtitles(context, subtitleId);
- break;
- default:
- break;
- }
- });
+ dlg.querySelector('.btnCancel').addEventListener('click', function () {
+ dialogHelper.close(dlg);
});
- }
-
- function centerFocus(elem, horiz, on) {
- require(['scrollHelper'], function (scrollHelper) {
- scrollHelper = scrollHelper.default || scrollHelper;
- var fn = on ? 'on' : 'off';
- scrollHelper.centerFocus[fn](elem, horiz);
- });
- }
-
- function showEditorInternal(itemId, serverId, template) {
- hasChanges = false;
-
- var apiClient = connectionManager.getApiClient(serverId);
- return apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(function (item) {
- var dialogOptions = {
- removeOnClose: true,
- scrollY: false
- };
-
- if (layoutManager.tv) {
- dialogOptions.size = 'fullscreen';
- } else {
- dialogOptions.size = 'small';
- }
-
- var dlg = dialogHelper.createDialog(dialogOptions);
-
- dlg.classList.add('formDialog');
- dlg.classList.add('subtitleEditorDialog');
-
- dlg.innerHTML = globalize.translateHtml(template, 'core');
-
- dlg.querySelector('.originalSubtitleFileLabel').innerHTML = globalize.translate('File');
-
- dlg.querySelector('.subtitleSearchForm').addEventListener('submit', onSearchSubmit);
-
- var btnSubmit = dlg.querySelector('.btnSubmit');
-
- if (layoutManager.tv) {
- centerFocus(dlg.querySelector('.formDialogContent'), false, true);
- dlg.querySelector('.btnSearchSubtitles').classList.add('hide');
- } else {
- btnSubmit.classList.add('hide');
- }
-
- var editorContent = dlg.querySelector('.formDialogContent');
-
- dlg.querySelector('.subtitleList').addEventListener('click', onSubtitleListClick);
- dlg.querySelector('.subtitleResults').addEventListener('click', onSubtitleResultsClick);
-
- apiClient.getCultures().then(function (languages) {
- fillLanguages(editorContent, apiClient, languages);
- });
-
- dlg.querySelector('.btnCancel').addEventListener('click', function () {
- dialogHelper.close(dlg);
- });
-
- return new Promise(function (resolve, reject) {
- dlg.addEventListener('close', function () {
- if (layoutManager.tv) {
- centerFocus(dlg.querySelector('.formDialogContent'), false, false);
- }
-
- if (hasChanges) {
- resolve();
- } else {
- reject();
- }
- });
-
- dialogHelper.open(dlg);
-
- reload(editorContent, apiClient, item);
- });
- });
- }
-
- function showEditor(itemId, serverId) {
- loading.show();
return new Promise(function (resolve, reject) {
- require(['text!./subtitleeditor.template.html'], function (template) {
- showEditorInternal(itemId, serverId, template).then(resolve, reject);
- });
- });
- }
+ dlg.addEventListener('close', function () {
+ if (layoutManager.tv) {
+ centerFocus(dlg.querySelector('.formDialogContent'), false, false);
+ }
- return {
- show: showEditor
- };
-});
+ if (hasChanges) {
+ resolve();
+ } else {
+ reject();
+ }
+ });
+
+ dialogHelper.open(dlg);
+
+ reload(editorContent, apiClient, item);
+ });
+ });
+}
+
+function showEditor(itemId, serverId) {
+ loading.show();
+
+ return new Promise(function (resolve, reject) {
+ import('text!./subtitleeditor.template.html').then(({default: template}) => {
+ showEditorInternal(itemId, serverId, template).then(resolve, reject);
+ });
+ });
+}
+
+export default {
+ show: showEditor
+};
diff --git a/src/components/subtitlesync/subtitlesync.js b/src/components/subtitlesync/subtitlesync.js
index 203d88535f..efb2087a1b 100644
--- a/src/components/subtitlesync/subtitlesync.js
+++ b/src/components/subtitlesync/subtitlesync.js
@@ -1,147 +1,148 @@
-define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html', 'css!./subtitlesync'], function (playbackManager, layoutManager, template, css) {
- 'use strict';
+import playbackManager from 'playbackManager';
+import layoutManager from 'layoutManager';
+import template from 'text!./subtitlesync.template.html';
+import 'css!./subtitlesync';
- playbackManager = playbackManager.default || playbackManager;
+let player;
+let subtitleSyncSlider;
+let subtitleSyncTextField;
+let subtitleSyncCloseButton;
+let subtitleSyncContainer;
- var player;
- var subtitleSyncSlider;
- var subtitleSyncTextField;
- var subtitleSyncCloseButton;
- var subtitleSyncContainer;
+function init(instance) {
+ const parent = document.createElement('div');
+ document.body.appendChild(parent);
+ parent.innerHTML = template;
- function init(instance) {
- var parent = document.createElement('div');
- document.body.appendChild(parent);
- parent.innerHTML = template;
+ subtitleSyncSlider = parent.querySelector('.subtitleSyncSlider');
+ subtitleSyncTextField = parent.querySelector('.subtitleSyncTextField');
+ subtitleSyncCloseButton = parent.querySelector('.subtitleSync-closeButton');
+ subtitleSyncContainer = parent.querySelector('.subtitleSyncContainer');
- subtitleSyncSlider = parent.querySelector('.subtitleSyncSlider');
- subtitleSyncTextField = parent.querySelector('.subtitleSyncTextField');
- subtitleSyncCloseButton = parent.querySelector('.subtitleSync-closeButton');
- subtitleSyncContainer = parent.querySelector('.subtitleSyncContainer');
+ if (layoutManager.tv) {
+ subtitleSyncSlider.classList.add('focusable');
+ // HACK: Delay to give time for registered element attach (Firefox)
+ setTimeout(function () {
+ subtitleSyncSlider.enableKeyboardDragging();
+ }, 0);
+ }
- if (layoutManager.tv) {
- subtitleSyncSlider.classList.add('focusable');
- // HACK: Delay to give time for registered element attach (Firefox)
- setTimeout(function () {
- subtitleSyncSlider.enableKeyboardDragging();
- }, 0);
- }
+ subtitleSyncContainer.classList.add('hide');
- subtitleSyncContainer.classList.add('hide');
+ subtitleSyncTextField.updateOffset = function (offset) {
+ this.textContent = offset + 's';
+ };
- subtitleSyncTextField.updateOffset = function(offset) {
- this.textContent = offset + 's';
- };
+ subtitleSyncTextField.addEventListener('click', function () {
+ // keep focus to prevent fade with osd
+ this.hasFocus = true;
+ });
- subtitleSyncTextField.addEventListener('click', function () {
+ subtitleSyncTextField.addEventListener('keydown', function (event) {
+ if (event.key === 'Enter') {
+ // if input key is enter search for float pattern
+ let inputOffset = /[-+]?\d+\.?\d*/g.exec(this.textContent);
+ if (inputOffset) {
+ inputOffset = inputOffset[0];
+
+ // replace current text by considered offset
+ this.textContent = inputOffset + 's';
+
+ inputOffset = parseFloat(inputOffset);
+ // set new offset
+ playbackManager.setSubtitleOffset(inputOffset, player);
+ // synchronize with slider value
+ subtitleSyncSlider.updateOffset(
+ getPercentageFromOffset(inputOffset));
+ } else {
+ this.textContent = (playbackManager.getPlayerSubtitleOffset(player) || 0) + 's';
+ }
+ this.hasFocus = false;
+ event.preventDefault();
+ } else {
// keep focus to prevent fade with osd
this.hasFocus = true;
- });
-
- subtitleSyncTextField.addEventListener('keydown', function(event) {
- if (event.key === 'Enter') {
- // if input key is enter search for float pattern
- var inputOffset = /[-+]?\d+\.?\d*/g.exec(this.textContent);
- if (inputOffset) {
- inputOffset = inputOffset[0];
-
- // replace current text by considered offset
- this.textContent = inputOffset + 's';
-
- inputOffset = parseFloat(inputOffset);
- // set new offset
- playbackManager.setSubtitleOffset(inputOffset, player);
- // synchronize with slider value
- subtitleSyncSlider.updateOffset(
- getPercentageFromOffset(inputOffset));
- } else {
- this.textContent = (playbackManager.getPlayerSubtitleOffset(player) || 0) + 's';
- }
- this.hasFocus = false;
+ if (event.key.match(/[+-\d.s]/) === null) {
event.preventDefault();
- } else {
- // keep focus to prevent fade with osd
- this.hasFocus = true;
- if (event.key.match(/[+-\d.s]/) === null) {
- event.preventDefault();
- }
}
+ }
- // FIXME: TV layout will require special handling for navigation keys. But now field is not focusable
- event.stopPropagation();
- });
+ // FIXME: TV layout will require special handling for navigation keys. But now field is not focusable
+ event.stopPropagation();
+ });
- subtitleSyncTextField.blur = function() {
- // prevent textfield to blur while element has focus
- if (!this.hasFocus && this.prototype) {
- this.prototype.blur();
- }
- };
+ subtitleSyncTextField.blur = function () {
+ // prevent textfield to blur while element has focus
+ if (!this.hasFocus && this.prototype) {
+ this.prototype.blur();
+ }
+ };
- subtitleSyncSlider.updateOffset = function(percent) {
- // default value is 0s = 50%
- this.value = percent === undefined ? 50 : percent;
- };
+ subtitleSyncSlider.updateOffset = function (percent) {
+ // default value is 0s = 50%
+ this.value = percent === undefined ? 50 : percent;
+ };
- subtitleSyncSlider.addEventListener('change', function () {
- // set new offset
- playbackManager.setSubtitleOffset(getOffsetFromPercentage(this.value), player);
- // synchronize with textField value
- subtitleSyncTextField.updateOffset(
- getOffsetFromPercentage(this.value));
- });
+ subtitleSyncSlider.addEventListener('change', function () {
+ // set new offset
+ playbackManager.setSubtitleOffset(getOffsetFromPercentage(this.value), player);
+ // synchronize with textField value
+ subtitleSyncTextField.updateOffset(
+ getOffsetFromPercentage(this.value));
+ });
- subtitleSyncSlider.getBubbleHtml = function (value) {
- var newOffset = getOffsetFromPercentage(value);
- return '' +
+ subtitleSyncSlider.getBubbleHtml = function (value) {
+ const newOffset = getOffsetFromPercentage(value);
+ return '' +
(newOffset > 0 ? '+' : '') + parseFloat(newOffset) + 's' +
'
';
- };
+ };
- subtitleSyncCloseButton.addEventListener('click', function() {
- playbackManager.disableShowingSubtitleOffset(player);
- SubtitleSync.prototype.toggle('forceToHide');
- });
+ subtitleSyncCloseButton.addEventListener('click', function () {
+ playbackManager.disableShowingSubtitleOffset(player);
+ SubtitleSync.prototype.toggle('forceToHide');
+ });
- instance.element = parent;
- }
+ instance.element = parent;
+}
- function getOffsetFromPercentage(value) {
- // convert percent to fraction
- var offset = (value - 50) / 50;
- // multiply by offset min/max range value (-x to +x) :
- offset *= 30;
- return offset.toFixed(1);
- }
+function getOffsetFromPercentage(value) {
+ // convert percent to fraction
+ let offset = (value - 50) / 50;
+ // multiply by offset min/max range value (-x to +x) :
+ offset *= 30;
+ return offset.toFixed(1);
+}
- function getPercentageFromOffset(value) {
- // divide by offset min/max range value (-x to +x) :
- var percentValue = value / 30;
- // convert fraction to percent
- percentValue *= 50;
- percentValue += 50;
- return Math.min(100, Math.max(0, percentValue.toFixed()));
- }
+function getPercentageFromOffset(value) {
+ // divide by offset min/max range value (-x to +x) :
+ let percentValue = value / 30;
+ // convert fraction to percent
+ percentValue *= 50;
+ percentValue += 50;
+ return Math.min(100, Math.max(0, percentValue.toFixed()));
+}
- function SubtitleSync(currentPlayer) {
+class SubtitleSync {
+ constructor(currentPlayer) {
player = currentPlayer;
init(this);
}
- SubtitleSync.prototype.destroy = function() {
+ destroy() {
SubtitleSync.prototype.toggle('forceToHide');
if (player) {
playbackManager.disableShowingSubtitleOffset(player);
playbackManager.setSubtitleOffset(0, player);
}
- var elem = this.element;
+ const elem = this.element;
if (elem) {
elem.parentNode.removeChild(elem);
this.element = null;
}
- };
+ }
- SubtitleSync.prototype.toggle = function(action) {
+ toggle(action) {
if (player && playbackManager.supportSubtitleOffset(player)) {
/* eslint-disable no-fallthrough */
switch (action) {
@@ -170,7 +171,7 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html',
}
/* eslint-enable no-fallthrough */
}
- };
+ }
+}
- return SubtitleSync;
-});
+export default SubtitleSync;