@gcorevideo/player 2.25.7 → 2.25.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/bottom-gear/gear-sub-menu.scss +4 -9
- package/assets/media-control/container.scss +0 -13
- package/assets/media-control/media-control.scss +14 -12
- package/assets/media-control/width270.scss +3 -0
- package/assets/media-control/width370.scss +4 -0
- package/assets/multi-camera/style.scss +0 -5
- package/assets/subtitles/combobox.ejs +27 -6
- package/assets/subtitles/string.ejs +1 -1
- package/assets/subtitles/style.scss +16 -69
- package/dist/core.js +1 -1
- package/dist/index.css +1036 -1090
- package/dist/index.embed.js +139 -101
- package/dist/index.js +80 -46
- package/lib/plugins/bottom-gear/BottomGear.d.ts +1 -1
- package/lib/plugins/bottom-gear/BottomGear.d.ts.map +1 -1
- package/lib/plugins/bottom-gear/BottomGear.js +3 -4
- package/lib/plugins/media-control/MediaControl.d.ts +4 -0
- package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
- package/lib/plugins/media-control/MediaControl.js +7 -0
- package/lib/plugins/subtitles/ClosedCaptions.d.ts +8 -5
- package/lib/plugins/subtitles/ClosedCaptions.d.ts.map +1 -1
- package/lib/plugins/subtitles/ClosedCaptions.js +67 -38
- package/lib/testUtils.d.ts.map +1 -1
- package/lib/testUtils.js +2 -0
- package/package.json +1 -1
- package/src/plugins/bottom-gear/BottomGear.ts +3 -4
- package/src/plugins/bottom-gear/__tests__/BottomGear.test.ts +1 -1
- package/src/plugins/media-control/MediaControl.ts +10 -0
- package/src/plugins/subtitles/ClosedCaptions.ts +73 -39
- package/src/plugins/subtitles/__tests__/ClosedCaptions.test.ts +220 -35
- package/src/plugins/subtitles/__tests__/__snapshots__/ClosedCaptions.test.ts.snap +8 -19
- package/src/testUtils.ts +2 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -42,6 +42,7 @@ const T = 'plugins.cc';
|
|
|
42
42
|
export class ClosedCaptions extends UICorePlugin {
|
|
43
43
|
isPreselectedApplied = false;
|
|
44
44
|
active = false;
|
|
45
|
+
open = false;
|
|
45
46
|
track = null;
|
|
46
47
|
tracks = [];
|
|
47
48
|
$line = null;
|
|
@@ -63,14 +64,14 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
63
64
|
static get version() {
|
|
64
65
|
return VERSION;
|
|
65
66
|
}
|
|
66
|
-
static
|
|
67
|
-
static
|
|
67
|
+
static templateControl = template(comboboxHTML);
|
|
68
|
+
static templateLine = template(stringHTML);
|
|
68
69
|
/**
|
|
69
70
|
* @internal
|
|
70
71
|
*/
|
|
71
72
|
get attributes() {
|
|
72
73
|
return {
|
|
73
|
-
class: 'media-control-cc',
|
|
74
|
+
class: 'media-control-cc media-control-dd__wrap',
|
|
74
75
|
};
|
|
75
76
|
}
|
|
76
77
|
/**
|
|
@@ -78,8 +79,8 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
78
79
|
*/
|
|
79
80
|
get events() {
|
|
80
81
|
return {
|
|
81
|
-
'click #cc-
|
|
82
|
-
'click #cc-button': 'toggleMenu',
|
|
82
|
+
'click #gplayer-cc-menu [data-item]': 'onItemSelect',
|
|
83
|
+
'click #gplayer-cc-button': 'toggleMenu',
|
|
83
84
|
};
|
|
84
85
|
}
|
|
85
86
|
get preselectedLanguage() {
|
|
@@ -92,14 +93,12 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
92
93
|
*/
|
|
93
94
|
bindEvents() {
|
|
94
95
|
this.listenTo(this.core, Events.CORE_READY, this.onCoreReady);
|
|
95
|
-
this.listenTo(this.core, Events.CORE_RESIZE, this.playerResize);
|
|
96
96
|
this.listenTo(this.core, Events.CORE_ACTIVE_CONTAINER_CHANGED, this.onContainerChanged);
|
|
97
97
|
}
|
|
98
98
|
onCoreReady() {
|
|
99
|
-
trace(`${T} onCoreReady`);
|
|
100
99
|
const mediaControl = this.core.getPlugin('media_control');
|
|
101
100
|
assert(mediaControl, 'media_control plugin is required');
|
|
102
|
-
this.listenTo(mediaControl, Events.MEDIACONTROL_RENDERED, this.
|
|
101
|
+
this.listenTo(mediaControl, Events.MEDIACONTROL_RENDERED, this.mount);
|
|
103
102
|
this.listenTo(mediaControl, Events.MEDIACONTROL_HIDE, () => {
|
|
104
103
|
this.hideMenu();
|
|
105
104
|
});
|
|
@@ -110,11 +109,15 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
110
109
|
});
|
|
111
110
|
}
|
|
112
111
|
onContainerChanged() {
|
|
113
|
-
|
|
114
|
-
this.listenTo(this.core.activeContainer, Events.
|
|
112
|
+
this.listenTo(this.core.activeContainer, Events.CONTAINER_FULLSCREEN, this.onContainerResize);
|
|
113
|
+
this.listenTo(this.core.activeContainer, Events.CONTAINER_RESIZE, this.onContainerResize);
|
|
115
114
|
this.listenTo(this.core.activeContainer, 'container:advertisement:start', this.onStartAd);
|
|
116
115
|
this.listenTo(this.core.activePlayback, Events.PLAYBACK_SUBTITLE_AVAILABLE, this.onSubtitleAvailable);
|
|
117
116
|
this.listenTo(this.core.activePlayback, Events.PLAYBACK_SUBTITLE_CHANGED, this.onSubtitleChanged);
|
|
117
|
+
this.listenTo(this.core.activeContainer, Events.CONTAINER_CLICK, () => {
|
|
118
|
+
// TODO test
|
|
119
|
+
this.hideMenu();
|
|
120
|
+
});
|
|
118
121
|
// fix for iOS
|
|
119
122
|
const video = this.core.activePlayback.el;
|
|
120
123
|
assert(video, 'video element is required');
|
|
@@ -132,6 +135,7 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
132
135
|
onSubtitleAvailable() {
|
|
133
136
|
trace(`${T} onSubtitleAvailable`);
|
|
134
137
|
this.applyTracks();
|
|
138
|
+
this.mount();
|
|
135
139
|
}
|
|
136
140
|
onSubtitleChanged({ id }) {
|
|
137
141
|
trace(`${T} onSubtitleChanged`, { id });
|
|
@@ -183,8 +187,7 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
183
187
|
this.show();
|
|
184
188
|
this.stopListening(this.core.activeContainer, 'container:advertisement:finish', this.onFinishAd);
|
|
185
189
|
}
|
|
186
|
-
|
|
187
|
-
trace(`${T} playerResize`);
|
|
190
|
+
onContainerResize() {
|
|
188
191
|
const shouldShow = this.core.activeContainer &&
|
|
189
192
|
isFullscreen(this.core.activeContainer.el) &&
|
|
190
193
|
this.track &&
|
|
@@ -196,6 +199,7 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
196
199
|
}
|
|
197
200
|
try {
|
|
198
201
|
this.resizeFont();
|
|
202
|
+
this.clampPopup();
|
|
199
203
|
}
|
|
200
204
|
catch (error) {
|
|
201
205
|
reportError(error);
|
|
@@ -206,7 +210,10 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
206
210
|
*/
|
|
207
211
|
hide() {
|
|
208
212
|
this.active = false;
|
|
213
|
+
this.open = false;
|
|
209
214
|
this.renderIcon();
|
|
215
|
+
this.$el.find('#gplayer-cc-menu').hide();
|
|
216
|
+
this.$el.find('#gplayer-cc-button').attr('aria-expanded', 'false');
|
|
210
217
|
this.$line.hide();
|
|
211
218
|
if (this.tracks) {
|
|
212
219
|
for (const t of this.tracks) {
|
|
@@ -249,17 +256,18 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
249
256
|
if (!this.core.activeContainer) {
|
|
250
257
|
return this;
|
|
251
258
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
this.$el.find('#cc-
|
|
258
|
-
this.
|
|
259
|
-
this.$line
|
|
259
|
+
this.$el.html(ClosedCaptions.templateControl({
|
|
260
|
+
tracks: this.tracks ?? [],
|
|
261
|
+
i18n: this.core.i18n,
|
|
262
|
+
current: this.track?.id ?? -1,
|
|
263
|
+
}));
|
|
264
|
+
this.$el.find('#gplayer-cc-menu').hide();
|
|
265
|
+
this.open = false;
|
|
266
|
+
this.core.activeContainer.$el.find('#gplayer-cc-line').remove();
|
|
267
|
+
this.$line = $(ClosedCaptions.templateLine());
|
|
260
268
|
this.resizeFont();
|
|
269
|
+
this.clampPopup();
|
|
261
270
|
this.core.activeContainer.$el.append(this.$line);
|
|
262
|
-
mediaControl.slot('cc', this.$el);
|
|
263
271
|
this.updateSelection();
|
|
264
272
|
this.renderIcon();
|
|
265
273
|
return this;
|
|
@@ -273,9 +281,10 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
273
281
|
this.updateSelection();
|
|
274
282
|
}
|
|
275
283
|
onItemSelect(event) {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
284
|
+
// event.target does not exist for some reason in tests
|
|
285
|
+
const id = (event.target ?? event.currentTarget).dataset?.item ??
|
|
286
|
+
'-1';
|
|
287
|
+
localStorage.setItem(LOCAL_STORAGE_CC_ID, id); // TODO store language instead
|
|
279
288
|
this.selectItem(this.findById(Number(id)));
|
|
280
289
|
this.hideMenu();
|
|
281
290
|
return false;
|
|
@@ -292,26 +301,33 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
292
301
|
}
|
|
293
302
|
}
|
|
294
303
|
hideMenu() {
|
|
295
|
-
|
|
296
|
-
this.$el.find('#cc-
|
|
304
|
+
this.open = false;
|
|
305
|
+
this.$el.find('#gplayer-cc-menu').hide();
|
|
306
|
+
this.$el.find('#gplayer-cc-button').attr('aria-expanded', 'false');
|
|
297
307
|
}
|
|
298
308
|
toggleMenu() {
|
|
299
|
-
trace(`${T} toggleMenu`, { display: this.$el.find('#cc-select').css('display') });
|
|
300
309
|
this.core
|
|
301
310
|
.getPlugin('media_control')
|
|
302
311
|
.trigger(ExtendedEvents.MEDIACONTROL_MENU_COLLAPSE, this.name);
|
|
303
|
-
this
|
|
304
|
-
|
|
312
|
+
this.open = !this.open;
|
|
313
|
+
if (this.open) {
|
|
314
|
+
this.$el.find('#gplayer-cc-menu').show();
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
this.$el.find('#gplayer-cc-menu').hide();
|
|
318
|
+
}
|
|
319
|
+
this.$el.find('#gplayer-cc-button').attr('aria-expanded', this.open);
|
|
305
320
|
}
|
|
306
321
|
itemElement(id) {
|
|
307
|
-
|
|
322
|
+
// TODO fix semantically
|
|
323
|
+
return this.$el.find(`#gplayer-cc-menu [data-item="${id}"]`).parent();
|
|
308
324
|
}
|
|
309
325
|
allItemElements() {
|
|
310
|
-
return this.$('#cc-
|
|
326
|
+
return this.$el.find('#gplayer-cc-menu li'); // TODO fix semantically
|
|
311
327
|
}
|
|
312
328
|
selectSubtitles() {
|
|
313
329
|
const trackId = this.track ? this.track.id : -1;
|
|
314
|
-
this.core.activePlayback.closedCaptionsTrackId = trackId;
|
|
330
|
+
this.core.activePlayback.closedCaptionsTrackId = trackId; // TODO test
|
|
315
331
|
}
|
|
316
332
|
getSubtitleText(track) {
|
|
317
333
|
const currentTime = this.core.activePlayback?.getCurrentTime() ?? 0;
|
|
@@ -321,6 +337,7 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
321
337
|
for (const cue of cues) {
|
|
322
338
|
if (currentTime >= cue.startTime && currentTime <= cue.endTime) {
|
|
323
339
|
lines.push(cue.getCueAsHTML().textContent);
|
|
340
|
+
// TODO break?
|
|
324
341
|
}
|
|
325
342
|
}
|
|
326
343
|
}
|
|
@@ -346,18 +363,30 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
346
363
|
this.allItemElements()
|
|
347
364
|
.removeClass('current')
|
|
348
365
|
.find('a')
|
|
349
|
-
.removeClass('gcore-skin-active')
|
|
350
|
-
|
|
351
|
-
track: this.track?.id,
|
|
352
|
-
});
|
|
366
|
+
.removeClass('gcore-skin-active')
|
|
367
|
+
.attr('aria-checked', 'false');
|
|
353
368
|
const currentLevelElement = this.itemElement(this.track ? this.track.id : -1);
|
|
354
369
|
currentLevelElement
|
|
355
370
|
.addClass('current')
|
|
356
371
|
.find('a')
|
|
357
|
-
.addClass('gcore-skin-active')
|
|
372
|
+
.addClass('gcore-skin-active')
|
|
373
|
+
.attr('aria-checked', 'true');
|
|
358
374
|
}
|
|
359
375
|
renderIcon() {
|
|
376
|
+
// render both icons at once
|
|
360
377
|
const icon = this.active ? subtitlesOnIcon : subtitlesOffIcon;
|
|
361
|
-
this.$el.find('
|
|
378
|
+
this.$el.find('#gplayer-cc-button').html(icon);
|
|
379
|
+
}
|
|
380
|
+
clampPopup() {
|
|
381
|
+
const availableHeight = this.core
|
|
382
|
+
.getPlugin('media_control')
|
|
383
|
+
.getAvailablePopupHeight();
|
|
384
|
+
this.$el.find('#gplayer-cc-menu').css('max-height', `${availableHeight}px`);
|
|
385
|
+
}
|
|
386
|
+
mount() {
|
|
387
|
+
if (this.shouldRender()) {
|
|
388
|
+
const mediaControl = this.core.getPlugin('media_control');
|
|
389
|
+
mediaControl.slot('cc', this.$el);
|
|
390
|
+
}
|
|
362
391
|
}
|
|
363
392
|
}
|
package/lib/testUtils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../src/testUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,YAAY,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,MAAM,MAAM,eAAe,CAAA;AAGlC,wBAAgB,cAAc,CAC5B,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,SAAS,GAAE,GAAkC;;;;;;;;;;;;;;;;;EAsB9C;AAED,wBAAgB,gBAAgB;;;EAK/B;AAED,wBAAgB,mBAAmB;;;;;;EAKlC;AAED,wBAAgB,kBAAkB,CAChC,IAAI,SAAS,EACb,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqCtC;AAED,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,QAAQ,GAAE,GAAgD;;;;;;;;;;;;;;;;;;;;;;;;;EA8B3D;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,
|
|
1
|
+
{"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../src/testUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,YAAY,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,MAAM,MAAM,eAAe,CAAA;AAGlC,wBAAgB,cAAc,CAC5B,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,SAAS,GAAE,GAAkC;;;;;;;;;;;;;;;;;EAsB9C;AAED,wBAAgB,gBAAgB;;;EAK/B;AAED,wBAAgB,mBAAmB;;;;;;EAKlC;AAED,wBAAgB,kBAAkB,CAChC,IAAI,SAAS,EACb,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqCtC;AAED,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,QAAQ,GAAE,GAAgD;;;;;;;;;;;;;;;;;;;;;;;;;EA8B3D;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,gBAuB/C;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,GAAG,OAe7C"}
|
package/lib/testUtils.js
CHANGED
|
@@ -117,6 +117,8 @@ export function createMockMediaControl(core) {
|
|
|
117
117
|
// @ts-ignore
|
|
118
118
|
mediaControl.getAvailableHeight = vi.fn().mockReturnValue(300);
|
|
119
119
|
// @ts-ignore
|
|
120
|
+
mediaControl.getAvailablePopupHeight = vi.fn().mockReturnValue(286);
|
|
121
|
+
// @ts-ignore
|
|
120
122
|
mediaControl.toggleElement = vi.fn();
|
|
121
123
|
vi.spyOn(mediaControl, 'trigger');
|
|
122
124
|
core.$el.append(mediaControl.$el);
|
package/package.json
CHANGED
|
@@ -198,7 +198,7 @@ export class BottomGear extends UICorePlugin {
|
|
|
198
198
|
.appendTo(this.$el.find('#gear-options-wrapper'))
|
|
199
199
|
$item.on('click', (e: MouseEvent) => {
|
|
200
200
|
e.stopPropagation()
|
|
201
|
-
this.
|
|
201
|
+
this.clampPopup($subMenu)
|
|
202
202
|
$subMenu.show()
|
|
203
203
|
this.$el.find('#gear-options').hide()
|
|
204
204
|
})
|
|
@@ -323,10 +323,9 @@ export class BottomGear extends UICorePlugin {
|
|
|
323
323
|
mediaControl.slot('gear', this.$el)
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
-
private
|
|
326
|
+
private clampPopup($subMenu: ZeptoResult) {
|
|
327
327
|
const availableHeight =
|
|
328
|
-
this.core.getPlugin('media_control').
|
|
329
|
-
MENU_VMARGIN * 2
|
|
328
|
+
this.core.getPlugin('media_control').getAvailablePopupHeight()
|
|
330
329
|
$subMenu.css('max-height', `${availableHeight}px`)
|
|
331
330
|
$subMenu
|
|
332
331
|
.find('.gear-sub-menu')
|
|
@@ -110,7 +110,7 @@ describe('BottomGear', () => {
|
|
|
110
110
|
})
|
|
111
111
|
describe('when submenu is open', () => {
|
|
112
112
|
beforeEach(async () => {
|
|
113
|
-
mediaControl.
|
|
113
|
+
mediaControl.getAvailablePopupHeight.mockReturnValue(174)
|
|
114
114
|
bottomGear.$el.find('#gear-button').click()
|
|
115
115
|
await new Promise((resolve) => setTimeout(resolve, 0))
|
|
116
116
|
bottomGear.$el.find('#more-button').click()
|
|
@@ -49,6 +49,8 @@ const STANDARD_MEDIA_CONTROL_ELEMENTS: string[] = [
|
|
|
49
49
|
'volume',
|
|
50
50
|
]
|
|
51
51
|
|
|
52
|
+
const MENU_VMARGIN = 12
|
|
53
|
+
|
|
52
54
|
/**
|
|
53
55
|
* Built-in media control elements.
|
|
54
56
|
* @beta
|
|
@@ -562,6 +564,13 @@ export class MediaControl extends UICorePlugin {
|
|
|
562
564
|
)
|
|
563
565
|
}
|
|
564
566
|
|
|
567
|
+
/**
|
|
568
|
+
* @returns Vertical space available to render a popup menu
|
|
569
|
+
*/
|
|
570
|
+
getAvailablePopupHeight() {
|
|
571
|
+
return this.getAvailableHeight() - MENU_VMARGIN * 2
|
|
572
|
+
}
|
|
573
|
+
|
|
565
574
|
/**
|
|
566
575
|
* Set the initial volume, which is preserved when playback is interrupted by an advertisement
|
|
567
576
|
*/
|
|
@@ -681,6 +690,7 @@ export class MediaControl extends UICorePlugin {
|
|
|
681
690
|
const pos = offset
|
|
682
691
|
? Math.min(1, Math.max(offset / this.$seekBarContainer.width(), 0))
|
|
683
692
|
: 0
|
|
693
|
+
|
|
684
694
|
if (this.settings.seekEnabled) {
|
|
685
695
|
// TODO test that it works when the element does not exist
|
|
686
696
|
this.$seekBarHover.css({ left: hoverOffset })
|
|
@@ -64,6 +64,8 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
64
64
|
|
|
65
65
|
private active = false
|
|
66
66
|
|
|
67
|
+
private open = false
|
|
68
|
+
|
|
67
69
|
private track: TextTrackItem | null = null
|
|
68
70
|
|
|
69
71
|
private tracks: TextTrackItem[] = []
|
|
@@ -91,16 +93,16 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
91
93
|
return VERSION
|
|
92
94
|
}
|
|
93
95
|
|
|
94
|
-
private static readonly
|
|
96
|
+
private static readonly templateControl = template(comboboxHTML)
|
|
95
97
|
|
|
96
|
-
private static readonly
|
|
98
|
+
private static readonly templateLine = template(stringHTML)
|
|
97
99
|
|
|
98
100
|
/**
|
|
99
101
|
* @internal
|
|
100
102
|
*/
|
|
101
103
|
override get attributes() {
|
|
102
104
|
return {
|
|
103
|
-
class: 'media-control-cc',
|
|
105
|
+
class: 'media-control-cc media-control-dd__wrap',
|
|
104
106
|
}
|
|
105
107
|
}
|
|
106
108
|
|
|
@@ -109,8 +111,8 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
109
111
|
*/
|
|
110
112
|
override get events() {
|
|
111
113
|
return {
|
|
112
|
-
'click #cc-
|
|
113
|
-
'click #cc-button': 'toggleMenu',
|
|
114
|
+
'click #gplayer-cc-menu [data-item]': 'onItemSelect',
|
|
115
|
+
'click #gplayer-cc-button': 'toggleMenu',
|
|
114
116
|
}
|
|
115
117
|
}
|
|
116
118
|
|
|
@@ -127,7 +129,6 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
127
129
|
*/
|
|
128
130
|
override bindEvents() {
|
|
129
131
|
this.listenTo(this.core, Events.CORE_READY, this.onCoreReady)
|
|
130
|
-
this.listenTo(this.core, Events.CORE_RESIZE, this.playerResize)
|
|
131
132
|
this.listenTo(
|
|
132
133
|
this.core,
|
|
133
134
|
Events.CORE_ACTIVE_CONTAINER_CHANGED,
|
|
@@ -136,10 +137,9 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
private onCoreReady() {
|
|
139
|
-
trace(`${T} onCoreReady`)
|
|
140
140
|
const mediaControl = this.core.getPlugin('media_control')
|
|
141
141
|
assert(mediaControl, 'media_control plugin is required')
|
|
142
|
-
this.listenTo(mediaControl, Events.MEDIACONTROL_RENDERED, this.
|
|
142
|
+
this.listenTo(mediaControl, Events.MEDIACONTROL_RENDERED, this.mount)
|
|
143
143
|
this.listenTo(mediaControl, Events.MEDIACONTROL_HIDE, () => {
|
|
144
144
|
this.hideMenu()
|
|
145
145
|
})
|
|
@@ -155,11 +155,15 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
private onContainerChanged() {
|
|
158
|
-
trace(`${T} onContainerChanged`)
|
|
159
158
|
this.listenTo(
|
|
160
159
|
this.core.activeContainer,
|
|
161
160
|
Events.CONTAINER_FULLSCREEN,
|
|
162
|
-
this.
|
|
161
|
+
this.onContainerResize,
|
|
162
|
+
)
|
|
163
|
+
this.listenTo(
|
|
164
|
+
this.core.activeContainer,
|
|
165
|
+
Events.CONTAINER_RESIZE,
|
|
166
|
+
this.onContainerResize,
|
|
163
167
|
)
|
|
164
168
|
this.listenTo(
|
|
165
169
|
this.core.activeContainer,
|
|
@@ -176,6 +180,10 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
176
180
|
Events.PLAYBACK_SUBTITLE_CHANGED,
|
|
177
181
|
this.onSubtitleChanged,
|
|
178
182
|
)
|
|
183
|
+
this.listenTo(this.core.activeContainer, Events.CONTAINER_CLICK, () => {
|
|
184
|
+
// TODO test
|
|
185
|
+
this.hideMenu()
|
|
186
|
+
})
|
|
179
187
|
|
|
180
188
|
// fix for iOS
|
|
181
189
|
const video = this.core.activePlayback.el
|
|
@@ -197,6 +205,7 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
197
205
|
private onSubtitleAvailable() {
|
|
198
206
|
trace(`${T} onSubtitleAvailable`)
|
|
199
207
|
this.applyTracks()
|
|
208
|
+
this.mount()
|
|
200
209
|
}
|
|
201
210
|
|
|
202
211
|
private onSubtitleChanged({ id }: { id: number }) {
|
|
@@ -260,8 +269,7 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
260
269
|
)
|
|
261
270
|
}
|
|
262
271
|
|
|
263
|
-
private
|
|
264
|
-
trace(`${T} playerResize`)
|
|
272
|
+
private onContainerResize() {
|
|
265
273
|
const shouldShow =
|
|
266
274
|
this.core.activeContainer &&
|
|
267
275
|
isFullscreen(this.core.activeContainer.el) &&
|
|
@@ -276,6 +284,7 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
276
284
|
|
|
277
285
|
try {
|
|
278
286
|
this.resizeFont()
|
|
287
|
+
this.clampPopup()
|
|
279
288
|
} catch (error) {
|
|
280
289
|
reportError(error)
|
|
281
290
|
}
|
|
@@ -286,7 +295,10 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
286
295
|
*/
|
|
287
296
|
hide() {
|
|
288
297
|
this.active = false
|
|
298
|
+
this.open = false
|
|
289
299
|
this.renderIcon()
|
|
300
|
+
this.$el.find('#gplayer-cc-menu').hide()
|
|
301
|
+
this.$el.find('#gplayer-cc-button').attr('aria-expanded', 'false')
|
|
290
302
|
this.$line.hide()
|
|
291
303
|
if (this.tracks) {
|
|
292
304
|
for (const t of this.tracks) {
|
|
@@ -337,20 +349,21 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
337
349
|
return this
|
|
338
350
|
}
|
|
339
351
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
this.$el.find('#cc-
|
|
348
|
-
this.
|
|
349
|
-
this.$line
|
|
352
|
+
this.$el.html(
|
|
353
|
+
ClosedCaptions.templateControl({
|
|
354
|
+
tracks: this.tracks ?? [],
|
|
355
|
+
i18n: this.core.i18n,
|
|
356
|
+
current: this.track?.id ?? -1,
|
|
357
|
+
}),
|
|
358
|
+
)
|
|
359
|
+
this.$el.find('#gplayer-cc-menu').hide()
|
|
360
|
+
this.open = false
|
|
361
|
+
this.core.activeContainer.$el.find('#gplayer-cc-line').remove()
|
|
362
|
+
this.$line = $(ClosedCaptions.templateLine())
|
|
350
363
|
this.resizeFont()
|
|
364
|
+
this.clampPopup()
|
|
351
365
|
|
|
352
366
|
this.core.activeContainer.$el.append(this.$line)
|
|
353
|
-
mediaControl.slot('cc', this.$el)
|
|
354
367
|
|
|
355
368
|
this.updateSelection()
|
|
356
369
|
|
|
@@ -371,11 +384,12 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
371
384
|
}
|
|
372
385
|
|
|
373
386
|
private onItemSelect(event: MouseEvent) {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
387
|
+
// event.target does not exist for some reason in tests
|
|
388
|
+
const id =
|
|
389
|
+
((event.target ?? event.currentTarget) as HTMLElement).dataset?.item ??
|
|
390
|
+
'-1'
|
|
377
391
|
|
|
378
|
-
localStorage.setItem(LOCAL_STORAGE_CC_ID, id)
|
|
392
|
+
localStorage.setItem(LOCAL_STORAGE_CC_ID, id) // TODO store language instead
|
|
379
393
|
this.selectItem(this.findById(Number(id)))
|
|
380
394
|
this.hideMenu()
|
|
381
395
|
return false
|
|
@@ -398,31 +412,37 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
398
412
|
}
|
|
399
413
|
|
|
400
414
|
private hideMenu() {
|
|
401
|
-
|
|
402
|
-
this.$el.find('#cc-
|
|
415
|
+
this.open = false
|
|
416
|
+
this.$el.find('#gplayer-cc-menu').hide()
|
|
417
|
+
this.$el.find('#gplayer-cc-button').attr('aria-expanded', 'false')
|
|
403
418
|
}
|
|
404
419
|
|
|
405
420
|
private toggleMenu() {
|
|
406
|
-
trace(`${T} toggleMenu`, {display: this.$el.find('#cc-select').css('display')})
|
|
407
421
|
this.core
|
|
408
422
|
.getPlugin('media_control')
|
|
409
423
|
.trigger(ExtendedEvents.MEDIACONTROL_MENU_COLLAPSE, this.name)
|
|
410
|
-
this
|
|
411
|
-
|
|
424
|
+
this.open = !this.open
|
|
425
|
+
if (this.open) {
|
|
426
|
+
this.$el.find('#gplayer-cc-menu').show()
|
|
427
|
+
} else {
|
|
428
|
+
this.$el.find('#gplayer-cc-menu').hide()
|
|
429
|
+
}
|
|
430
|
+
this.$el.find('#gplayer-cc-button').attr('aria-expanded', this.open)
|
|
412
431
|
}
|
|
413
432
|
|
|
414
433
|
private itemElement(id: number): ZeptoResult {
|
|
415
|
-
|
|
434
|
+
// TODO fix semantically
|
|
435
|
+
return this.$el.find(`#gplayer-cc-menu [data-item="${id}"]`).parent()
|
|
416
436
|
}
|
|
417
437
|
|
|
418
438
|
private allItemElements(): ZeptoResult {
|
|
419
|
-
return this.$('#cc-
|
|
439
|
+
return this.$el.find('#gplayer-cc-menu li') // TODO fix semantically
|
|
420
440
|
}
|
|
421
441
|
|
|
422
442
|
private selectSubtitles() {
|
|
423
443
|
const trackId = this.track ? this.track.id : -1
|
|
424
444
|
|
|
425
|
-
this.core.activePlayback.closedCaptionsTrackId = trackId
|
|
445
|
+
this.core.activePlayback.closedCaptionsTrackId = trackId // TODO test
|
|
426
446
|
}
|
|
427
447
|
|
|
428
448
|
private getSubtitleText(track: TextTrack) {
|
|
@@ -434,6 +454,7 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
434
454
|
for (const cue of cues) {
|
|
435
455
|
if (currentTime >= cue.startTime && currentTime <= cue.endTime) {
|
|
436
456
|
lines.push((cue as VTTCue).getCueAsHTML().textContent)
|
|
457
|
+
// TODO break?
|
|
437
458
|
}
|
|
438
459
|
}
|
|
439
460
|
}
|
|
@@ -464,10 +485,8 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
464
485
|
.removeClass('current')
|
|
465
486
|
.find('a')
|
|
466
487
|
.removeClass('gcore-skin-active')
|
|
488
|
+
.attr('aria-checked', 'false')
|
|
467
489
|
|
|
468
|
-
trace(`${T} highlightCurrentSubtitles`, {
|
|
469
|
-
track: this.track?.id,
|
|
470
|
-
})
|
|
471
490
|
const currentLevelElement = this.itemElement(
|
|
472
491
|
this.track ? this.track.id : -1,
|
|
473
492
|
)
|
|
@@ -475,11 +494,26 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
475
494
|
.addClass('current')
|
|
476
495
|
.find('a')
|
|
477
496
|
.addClass('gcore-skin-active')
|
|
497
|
+
.attr('aria-checked', 'true')
|
|
478
498
|
}
|
|
479
499
|
|
|
480
500
|
private renderIcon() {
|
|
501
|
+
// render both icons at once
|
|
481
502
|
const icon = this.active ? subtitlesOnIcon : subtitlesOffIcon
|
|
503
|
+
this.$el.find('#gplayer-cc-button').html(icon)
|
|
504
|
+
}
|
|
482
505
|
|
|
483
|
-
|
|
506
|
+
private clampPopup() {
|
|
507
|
+
const availableHeight = this.core
|
|
508
|
+
.getPlugin('media_control')
|
|
509
|
+
.getAvailablePopupHeight()
|
|
510
|
+
this.$el.find('#gplayer-cc-menu').css('max-height', `${availableHeight}px`)
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
private mount() {
|
|
514
|
+
if (this.shouldRender()) {
|
|
515
|
+
const mediaControl = this.core.getPlugin('media_control')
|
|
516
|
+
mediaControl.slot('cc', this.$el)
|
|
517
|
+
}
|
|
484
518
|
}
|
|
485
519
|
}
|