@gcorevideo/player 2.22.5 → 2.22.7

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.
Files changed (40) hide show
  1. package/assets/media-control/media-control.ejs +1 -2
  2. package/dist/core.js +2 -2
  3. package/dist/index.css +1432 -1432
  4. package/dist/index.js +127 -91
  5. package/dist/plugins/index.css +1495 -1495
  6. package/dist/plugins/index.js +123 -86
  7. package/lib/playback/dash-playback/DashPlayback.d.ts.map +1 -1
  8. package/lib/playback/dash-playback/DashPlayback.js +1 -1
  9. package/lib/plugins/bottom-gear/BottomGear.d.ts.map +1 -1
  10. package/lib/plugins/bottom-gear/BottomGear.js +2 -2
  11. package/lib/plugins/media-control/MediaControl.d.ts +37 -6
  12. package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
  13. package/lib/plugins/media-control/MediaControl.js +54 -36
  14. package/lib/plugins/playback-rate/PlaybackRate.d.ts +5 -4
  15. package/lib/plugins/playback-rate/PlaybackRate.d.ts.map +1 -1
  16. package/lib/plugins/playback-rate/PlaybackRate.js +46 -24
  17. package/lib/plugins/subtitles/ClosedCaptions.js +1 -1
  18. package/lib/plugins/utils/fullscreen.d.ts +4 -0
  19. package/lib/plugins/utils/fullscreen.d.ts.map +1 -0
  20. package/lib/plugins/utils/fullscreen.js +30 -0
  21. package/lib/plugins/utils.d.ts +0 -1
  22. package/lib/plugins/utils.d.ts.map +1 -1
  23. package/lib/plugins/utils.js +0 -28
  24. package/lib/utils/fullscreen.d.ts +3 -0
  25. package/lib/utils/fullscreen.d.ts.map +1 -0
  26. package/lib/utils/fullscreen.js +2 -0
  27. package/package.json +1 -1
  28. package/src/playback/dash-playback/DashPlayback.ts +1 -4
  29. package/src/plugins/bottom-gear/BottomGear.ts +2 -2
  30. package/src/plugins/bottom-gear/__tests__/BottomGear.test.ts +15 -3
  31. package/src/plugins/media-control/MediaControl.ts +111 -62
  32. package/src/plugins/media-control/__tests__/MediaControl.test.ts +118 -8
  33. package/src/plugins/media-control/__tests__/__snapshots__/MediaControl.test.ts.snap +149 -5
  34. package/src/plugins/playback-rate/PlaybackRate.ts +48 -26
  35. package/src/plugins/playback-rate/__tests__/PlaybackRate.test.ts +125 -55
  36. package/src/plugins/playback-rate/__tests__/__snapshots__/PlaybackRate.test.ts.snap +1 -1
  37. package/src/plugins/subtitles/ClosedCaptions.ts +1 -1
  38. package/src/plugins/utils/fullscreen.ts +34 -0
  39. package/src/plugins/utils.ts +0 -31
  40. package/tsconfig.tsbuildinfo +1 -1
@@ -1,6 +1,6 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
- exports[`MediaControl > putElement > cc > should put the element in the right panel 1`] = `
3
+ exports[`MediaControl > putElement > audiotracks > should put the element in the right panel 1`] = `
4
4
  "<div class="media-control-background" data-background=""></div>
5
5
 
6
6
  <div class="media-control-layer gcore-skin-bg-color" data-controls="">
@@ -36,7 +36,65 @@ exports[`MediaControl > putElement > cc > should put the element in the right pa
36
36
 
37
37
  </div>
38
38
 
39
+ <div class="media-clip-container gcore-skin-text-color" data-clipstext="">
40
+ <div class="media-clip-point gcore-skin-text-color" data-clipstext="">•</div>
41
+ <div class="media-clip-text gcore-skin-text-color" data-clipstext=""></div>
42
+ </div>
43
+
44
+ </div>
45
+
46
+
47
+
48
+ <div class="media-control-right-panel" data-media-control="">
49
+
50
+ <button type="button" class="media-control-button media-control-icon gcore-skin-button-color" data-fullscreen="" aria-label="fullscreen">/assets/icons/new/fullscreen-off.svg</button>
51
+
52
+ <div class="media-control-multicamera" data-multicamera=""></div>
53
+
54
+ <div class="media-control-vr" data-vr=""></div>
55
+
56
+ <div class="my-media-control" data-audiotracks="">test</div></div>
57
+
58
+ </div>
59
+ <style>:root {}</style>"
60
+ `;
61
+
62
+ exports[`MediaControl > putElement > cc > should put the element in the right panel 1`] = `
63
+ "<div class="media-control-background" data-background=""></div>
64
+
65
+ <div class="media-control-layer gcore-skin-bg-color" data-controls="">
66
+
67
+
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+
39
76
 
77
+
78
+
79
+ <div class="media-control-left-panel" data-media-control="">
80
+
81
+ <div class="drawer-container" data-volume="">
82
+ <div class="drawer-icon-container" data-volume="">
83
+ <div class="drawer-icon media-control-icon gcore-skin-button-color" data-volume="">/assets/icons/new/volume-max.svg</div>
84
+ <span class="drawer-text" data-volume=""></span>
85
+ </div>
86
+
87
+ <div class="bar-container" data-volume="">
88
+ <div class="bar-background" data-volume="">
89
+ <div class="bar-fill-1 gcore-skin-main-color" data-volume="" style=""></div>
90
+ </div>
91
+ <div class="bar-scrubber" data-volume="" style="">
92
+ <div class="bar-scrubber-icon gcore-skin-main-color" data-volume=""></div>
93
+ </div>
94
+ </div>
95
+
96
+ </div>
97
+
40
98
  <div class="media-clip-container gcore-skin-text-color" data-clipstext="">
41
99
  <div class="media-clip-point gcore-skin-text-color" data-clipstext="">•</div>
42
100
  <div class="media-clip-text gcore-skin-text-color" data-clipstext=""></div>
@@ -48,6 +106,8 @@ exports[`MediaControl > putElement > cc > should put the element in the right pa
48
106
 
49
107
  <div class="media-control-right-panel" data-media-control="">
50
108
 
109
+ <button type="button" class="media-control-button media-control-icon gcore-skin-button-color" data-fullscreen="" aria-label="fullscreen">/assets/icons/new/fullscreen-off.svg</button>
110
+
51
111
  <div class="media-control-multicamera" data-multicamera=""></div>
52
112
 
53
113
  <div class="media-control-vr" data-vr=""></div>
@@ -94,7 +154,6 @@ exports[`MediaControl > putElement > gear > should put the element in the right
94
154
 
95
155
  </div>
96
156
 
97
-
98
157
  <div class="media-clip-container gcore-skin-text-color" data-clipstext="">
99
158
  <div class="media-clip-point gcore-skin-text-color" data-clipstext="">•</div>
100
159
  <div class="media-clip-text gcore-skin-text-color" data-clipstext=""></div>
@@ -106,6 +165,8 @@ exports[`MediaControl > putElement > gear > should put the element in the right
106
165
 
107
166
  <div class="media-control-right-panel" data-media-control="">
108
167
 
168
+ <button type="button" class="media-control-button media-control-icon gcore-skin-button-color" data-fullscreen="" aria-label="fullscreen">/assets/icons/new/fullscreen-off.svg</button>
169
+
109
170
  <div class="media-control-multicamera" data-multicamera=""></div>
110
171
 
111
172
  <div class="media-control-vr" data-vr=""></div>
@@ -152,7 +213,6 @@ exports[`MediaControl > putElement > pip > should put the element in the right p
152
213
 
153
214
  </div>
154
215
 
155
-
156
216
  <div class="media-clip-container gcore-skin-text-color" data-clipstext="">
157
217
  <div class="media-clip-point gcore-skin-text-color" data-clipstext="">•</div>
158
218
  <div class="media-clip-text gcore-skin-text-color" data-clipstext=""></div>
@@ -164,6 +224,8 @@ exports[`MediaControl > putElement > pip > should put the element in the right p
164
224
 
165
225
  <div class="media-control-right-panel" data-media-control="">
166
226
 
227
+ <button type="button" class="media-control-button media-control-icon gcore-skin-button-color" data-fullscreen="" aria-label="fullscreen">/assets/icons/new/fullscreen-off.svg</button>
228
+
167
229
  <div class="media-control-multicamera" data-multicamera=""></div>
168
230
 
169
231
  <div class="media-control-vr" data-vr=""></div>
@@ -216,7 +278,6 @@ exports[`MediaControl > updateSettings > dvr > when disabled > should disable DV
216
278
 
217
279
  <div class="media-control-indicator gcore-skin-text-color" data-duration="">00:00</div>
218
280
 
219
-
220
281
  <div class="media-clip-container gcore-skin-text-color" data-clipstext="">
221
282
  <div class="media-clip-point gcore-skin-text-color" data-clipstext="">•</div>
222
283
  <div class="media-clip-text gcore-skin-text-color" data-clipstext=""></div>
@@ -228,6 +289,8 @@ exports[`MediaControl > updateSettings > dvr > when disabled > should disable DV
228
289
 
229
290
  <div class="media-control-right-panel" data-media-control="">
230
291
 
292
+ <button type="button" class="media-control-button media-control-icon gcore-skin-button-color" data-fullscreen="" aria-label="fullscreen">/assets/icons/new/fullscreen-off.svg</button>
293
+
231
294
  <div class="media-control-multicamera" data-multicamera=""></div>
232
295
 
233
296
  <div class="media-control-vr" data-vr=""></div>
@@ -280,7 +343,6 @@ exports[`MediaControl > updateSettings > dvr > when enabled > should enable DVR
280
343
 
281
344
  <div class="media-control-indicator gcore-skin-text-color" data-duration="">00:00</div>
282
345
 
283
-
284
346
  <div class="media-clip-container gcore-skin-text-color" data-clipstext="">
285
347
  <div class="media-clip-point gcore-skin-text-color" data-clipstext="">•</div>
286
348
  <div class="media-clip-text gcore-skin-text-color" data-clipstext=""></div>
@@ -292,6 +354,88 @@ exports[`MediaControl > updateSettings > dvr > when enabled > should enable DVR
292
354
 
293
355
  <div class="media-control-right-panel" data-media-control="">
294
356
 
357
+ <button type="button" class="media-control-button media-control-icon gcore-skin-button-color" data-fullscreen="" aria-label="fullscreen">/assets/icons/new/fullscreen-off.svg</button>
358
+
359
+ <div class="media-control-multicamera" data-multicamera=""></div>
360
+
361
+ <div class="media-control-vr" data-vr=""></div>
362
+
363
+ </div>
364
+
365
+ </div>
366
+ <style>:root {}</style>"
367
+ `;
368
+
369
+ exports[`MediaControl > when container settings update > vod > should render 1`] = `
370
+ "<div class="media-control-background" data-background=""></div>
371
+
372
+ <div class="media-control-layer gcore-skin-bg-color" data-controls="">
373
+
374
+
375
+
376
+
377
+
378
+
379
+
380
+
381
+
382
+
383
+
384
+
385
+
386
+ <div class="media-control-left-panel" data-media-control="">
387
+
388
+ <button type="button" class="media-control-button media-control-icon gcore-skin-button-color paused" data-playpause="" aria-label="playpause">/assets/icons/new/play.svg</button>
389
+
390
+ <div class="drawer-container" data-volume="">
391
+ <div class="drawer-icon-container" data-volume="">
392
+ <div class="drawer-icon media-control-icon gcore-skin-button-color" data-volume="">/assets/icons/new/volume-max.svg</div>
393
+ <span class="drawer-text" data-volume=""></span>
394
+ </div>
395
+
396
+ <div class="bar-container" data-volume="">
397
+ <div class="bar-background" data-volume="">
398
+ <div class="bar-fill-1 gcore-skin-main-color" data-volume="" style=""></div>
399
+ </div>
400
+ <div class="bar-scrubber" data-volume="" style="">
401
+ <div class="bar-scrubber-icon gcore-skin-main-color" data-volume=""></div>
402
+ </div>
403
+ </div>
404
+
405
+ </div>
406
+
407
+ <div class="media-control-indicator gcore-skin-text-color" data-position="">00:00</div>
408
+
409
+ <div class="media-control-indicator gcore-skin-text-color" data-duration="">00:00</div>
410
+
411
+ <div class="media-clip-container gcore-skin-text-color" data-clipstext="">
412
+ <div class="media-clip-point gcore-skin-text-color" data-clipstext="">•</div>
413
+ <div class="media-clip-text gcore-skin-text-color" data-clipstext=""></div>
414
+ </div>
415
+
416
+ </div>
417
+
418
+
419
+ <div class="media-control-center-panel" data-media-control="">
420
+
421
+ <div class="bar-container" data-seekbar="">
422
+ <div class="bar-background" data-seekbar="">
423
+ <div class="bar-fill-1" data-seekbar=""></div>
424
+ <div class="bar-fill-2 gcore-skin-main-color" data-seekbar="" style=""></div>
425
+ <div class="bar-hover" data-seekbar=""></div>
426
+ </div>
427
+ </div>
428
+ <div class="bar-scrubber" data-seekbar="" style="">
429
+ <div class="bar-scrubber-icon gcore-skin-main-color" data-seekbar=""></div>
430
+ </div>
431
+
432
+ </div>
433
+
434
+
435
+ <div class="media-control-right-panel" data-media-control="">
436
+
437
+ <button type="button" class="media-control-button media-control-icon gcore-skin-button-color" data-fullscreen="" aria-label="fullscreen">/assets/icons/new/fullscreen-off.svg</button>
438
+
295
439
  <div class="media-control-multicamera" data-multicamera=""></div>
296
440
 
297
441
  <div class="media-control-vr" data-vr=""></div>
@@ -72,13 +72,11 @@ const T = 'plugins.playback_rate'
72
72
  * { value: 1, label: '1x' },
73
73
  * ],
74
74
  * defaultValue: 1,
75
- * } as PlaybackRateSettings,
75
+ * },
76
76
  * })
77
77
  * ```
78
78
  */
79
79
  export class PlaybackRate extends UICorePlugin {
80
- private playbackRates: PlaybackRateOption[] = DEFAULT_PLAYBACK_RATES
81
-
82
80
  // Saved when an ad starts to restore after it finishes
83
81
  // private prevSelectedRate: string | undefined
84
82
 
@@ -104,10 +102,13 @@ export class PlaybackRate extends UICorePlugin {
104
102
 
105
103
  constructor(core: Core) {
106
104
  super(core)
107
- this.playbackRates =
108
- core.options.playbackRate?.options || DEFAULT_PLAYBACK_RATES
109
- this.selectedRate =
110
- core.options.playbackRate?.defaultValue || DEFAULT_PLAYBACK_RATE
105
+ if (this.core.options.playbackRate?.defaultValue) {
106
+ this.setSelectedRate(this.core.options.playbackRate.defaultValue)
107
+ }
108
+ }
109
+
110
+ private get playbackRates() {
111
+ return this.core.options.playbackRate?.options || DEFAULT_PLAYBACK_RATES
111
112
  }
112
113
 
113
114
  /**
@@ -179,11 +180,16 @@ export class PlaybackRate extends UICorePlugin {
179
180
 
180
181
  private onGearRendered() {
181
182
  trace(`${T} onGearRendered`)
182
- this.addGearItem()
183
+ this.mount()
183
184
  }
184
185
 
185
- private addGearItem() {
186
- trace(`${T} addGearItem`)
186
+ private mount() {
187
+ trace(`${T} mount`, {
188
+ shouldMount: this.shouldMount(),
189
+ })
190
+ if (!this.shouldMount()) {
191
+ return
192
+ }
187
193
  this.core
188
194
  .getPlugin('bottom_gear')
189
195
  ?.addItem('rate', this.$el)
@@ -229,7 +235,7 @@ export class PlaybackRate extends UICorePlugin {
229
235
  }
230
236
  }
231
237
 
232
- private shouldRender() {
238
+ private shouldMount() {
233
239
  if (!this.core.activePlayback) {
234
240
  return false
235
241
  }
@@ -249,13 +255,9 @@ export class PlaybackRate extends UICorePlugin {
249
255
  */
250
256
  override render() {
251
257
  trace(`${T} render`, {
252
- shouldRender: this.shouldRender(),
258
+ shouldMount: this.shouldMount(),
253
259
  })
254
260
 
255
- if (!this.shouldRender()) {
256
- return this
257
- }
258
-
259
261
  this.$el.html(
260
262
  PlaybackRate.listTemplate({
261
263
  arrowLeftIcon,
@@ -266,7 +268,7 @@ export class PlaybackRate extends UICorePlugin {
266
268
  }),
267
269
  )
268
270
 
269
- this.addGearItem()
271
+ this.mount()
270
272
 
271
273
  return this
272
274
  }
@@ -294,12 +296,23 @@ export class PlaybackRate extends UICorePlugin {
294
296
  ) {
295
297
  this.resetPlaybackRate()
296
298
  } else {
297
- this.setSelectedRate(this.selectedRate)
299
+ this.syncRate()
298
300
  }
299
301
  }
300
302
 
303
+ private syncRate() {
304
+ trace(`${T} syncRate`, {
305
+ selectedRate: this.selectedRate,
306
+ })
307
+ this.core.activePlayback?.setPlaybackRate(this.selectedRate)
308
+ }
309
+
301
310
  private resetPlaybackRate() {
302
- this.setSelectedRate(DEFAULT_PLAYBACK_RATE)
311
+ trace(`${T} resetPlaybackRate`, {
312
+ selectedRate: this.selectedRate,
313
+ })
314
+ this.core.activePlayback?.setPlaybackRate(DEFAULT_PLAYBACK_RATE)
315
+ this.selectedRate = DEFAULT_PLAYBACK_RATE
303
316
  }
304
317
 
305
318
  private onStop() {}
@@ -311,8 +324,6 @@ export class PlaybackRate extends UICorePlugin {
311
324
  )
312
325
  if (rate) {
313
326
  this.setSelectedRate(rate)
314
- this.highlightCurrentRate()
315
- this.updateGearOptionLabel()
316
327
  }
317
328
 
318
329
  return false
@@ -325,18 +336,27 @@ export class PlaybackRate extends UICorePlugin {
325
336
  }
326
337
 
327
338
  private setSelectedRate(rate: number) {
328
- this.core.activePlayback?.setPlaybackRate(rate)
339
+ if (rate === this.selectedRate) {
340
+ return
341
+ }
329
342
  this.selectedRate = rate
343
+ this.syncRate()
344
+ this.highlightCurrentRate()
345
+ this.updateGearOptionLabel()
330
346
  }
331
347
 
332
348
  private getTitle() {
349
+ const rate = this.selectedRate
333
350
  return (
334
- this.playbackRates.find((r) => r.value === this.selectedRate)?.label ||
335
- `x${this.selectedRate}`
351
+ this.playbackRates.find((r: PlaybackRateOption) => r.value === rate)?.label ||
352
+ `x${rate}`
336
353
  )
337
354
  }
338
355
 
339
356
  private highlightCurrentRate() {
357
+ trace(`${T} highlightCurrentRate`, {
358
+ selectedRate: this.selectedRate,
359
+ })
340
360
  this.allRateElements().removeClass('current')
341
361
  this.allRateElements().find('a').removeClass('gcore-skin-active')
342
362
 
@@ -347,7 +367,9 @@ export class PlaybackRate extends UICorePlugin {
347
367
  }
348
368
 
349
369
  private updateGearOptionLabel() {
350
- trace(`${T} updateGearOptionLabel`)
351
- this.addGearItem()
370
+ trace(`${T} updateGearOptionLabel`, {
371
+ selectedRate: this.selectedRate,
372
+ })
373
+ this.mount()
352
374
  }
353
375
  }
@@ -30,69 +30,139 @@ describe('PlaybackRate', () => {
30
30
  }
31
31
  return null
32
32
  })
33
- playbackRate = new PlaybackRate(core)
34
- core.emit(Events.CORE_READY)
35
- core.activePlayback.getPlaybackType.mockReturnValue('live')
36
- core.activeContainer.getPlaybackType.mockReturnValue('live')
37
- core.getPlaybackType.mockReturnValue('live')
38
- core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED)
39
- core.activePlayback.dvrEnabled = true
40
- core.activeContainer.isDvrEnabled.mockReturnValue(true)
41
- core.activeContainer.emit(Events.CONTAINER_LOADEDMETADATA)
42
- bottomGear.trigger(GearEvents.RENDERED)
43
33
  })
44
- it('should render', () => {
45
- expect(playbackRate.el.innerHTML).toMatchSnapshot()
46
- expect(bottomGear.addItem).toHaveBeenCalledWith('rate', playbackRate.$el)
47
- expect(
48
- bottomGear.$el.find('li[data-rate]').text(),
49
- // @ts-ignore
50
- ).toMatchPlaybackRateLabel('playback_rate 1x')
51
- })
52
- it('should have normal rate initially', () => {
53
- expect(
54
- playbackRate.$el.find('[data-rate="1"]').parent().hasClass('current'),
55
- ).toBe(true)
56
- expect(
57
- playbackRate.$el.find('[data-rate="1"]').hasClass('gcore-skin-active'),
58
- ).toBe(true)
59
- })
60
- describe('on playback rate select', () => {
61
- describe.each([[2], [1.5], [1.25], [1], [0.75], [0.5]])('%s', (rate) => {
34
+ describe('basically', () => {
35
+ beforeEach(() => {
36
+ playbackRate = new PlaybackRate(core)
37
+ core.emit(Events.CORE_READY)
38
+ mediaControl.trigger(Events.MEDIACONTROL_RENDERED)
39
+ core.activePlayback.getPlaybackType.mockReturnValue('live')
40
+ core.activeContainer.getPlaybackType.mockReturnValue('live')
41
+ core.getPlaybackType.mockReturnValue('live')
42
+ core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED)
43
+ bottomGear.trigger(GearEvents.RENDERED)
44
+ })
45
+ it('should render', () => {
46
+ expect(playbackRate.el.innerHTML).toMatchSnapshot()
47
+ })
48
+ it('should have normal rate initially', () => {
49
+ expect(
50
+ playbackRate.$el.find('[data-rate="1"]').parent().hasClass('current'),
51
+ ).toBe(true)
52
+ expect(
53
+ playbackRate.$el.find('[data-rate="1"]').hasClass('gcore-skin-active'),
54
+ ).toBe(true)
55
+ })
56
+ describe('until media source is loaded', () => {
57
+ it('should not attach to the media control', () => {
58
+ expect(bottomGear.addItem).not.toHaveBeenCalledWith('rate', expect.anything())
59
+ })
60
+ })
61
+ describe('after media source is loaded', () => {
62
+ describe('when DVR is available', () => {
63
+ beforeEach(() => {
64
+ core.activePlayback.dvrEnabled = true
65
+ core.activeContainer.isDvrEnabled.mockReturnValue(true)
66
+ core.activePlayback.emit(Events.PLAYBACK_LOADEDMETADATA)
67
+ core.activeContainer.emit(Events.CONTAINER_LOADEDMETADATA)
68
+ })
69
+ it('should attach to the media control', () => {
70
+ expect(bottomGear.addItem).toHaveBeenCalledWith('rate', playbackRate.$el)
71
+ expect(
72
+ bottomGear.$el.find('li[data-rate]').text(),
73
+ // @ts-ignore
74
+ ).toMatchPlaybackRateLabel('1x')
75
+ })
76
+ })
77
+ describe('when DVR is not available', () => {
78
+ beforeEach(() => {
79
+ core.activePlayback.emit(Events.PLAYBACK_LOADEDMETADATA)
80
+ core.activeContainer.emit(Events.CONTAINER_LOADEDMETADATA)
81
+ })
82
+ it('should not attach to the media control', () => {
83
+ expect(bottomGear.addItem).not.toHaveBeenCalledWith('rate', expect.anything())
84
+ })
85
+ })
86
+ });
87
+ describe('on playback rate select', () => {
62
88
  beforeEach(() => {
63
- playbackRate.$el.find(`[data-rate="${rate}"]`).click()
89
+ core.activePlayback.dvrEnabled = true
90
+ core.activeContainer.isDvrEnabled.mockReturnValue(true)
91
+ core.activePlayback.emit(Events.PLAYBACK_LOADEDMETADATA)
92
+ core.activeContainer.emit(Events.CONTAINER_LOADEDMETADATA)
64
93
  })
65
- it('should set the selected rate', () => {
66
- expect(core.activePlayback.setPlaybackRate).toHaveBeenCalledWith(rate)
94
+ describe.each([[2], [1.5], [1.25], [0.75], [0.5]])('%s', (rate) => {
95
+ beforeEach(() => {
96
+ playbackRate.$el.find(`[data-rate="${rate}"]`).click()
97
+ })
98
+ it('should set the selected rate', () => {
99
+ expect(core.activePlayback.setPlaybackRate).toHaveBeenCalledWith(rate)
100
+ })
101
+ it('should highlight the selected rate', () => {
102
+ expect(
103
+ playbackRate.$el
104
+ .find(`[data-rate="${rate}"]`)
105
+ .parent()
106
+ .hasClass('current'),
107
+ ).toBe(true)
108
+ expect(
109
+ playbackRate.$el
110
+ .find(`[data-rate="${rate}"]`)
111
+ .hasClass('gcore-skin-active'),
112
+ ).toBe(true)
113
+ })
114
+ it('should update the gear box option label', () => {
115
+ expect(
116
+ bottomGear.$el.find('#playback-rate-button').text(),
117
+ // @ts-ignore
118
+ ).toMatchPlaybackRateLabel(`${rate}x`)
119
+ })
67
120
  })
68
- it('should highlight the selected rate', () => {
69
- expect(
70
- playbackRate.$el
71
- .find(`[data-rate="${rate}"]`)
72
- .parent()
73
- .hasClass('current'),
74
- ).toBe(true)
75
- expect(
76
- playbackRate.$el
77
- .find(`[data-rate="${rate}"]`)
78
- .hasClass('gcore-skin-active'),
79
- ).toBe(true)
121
+ })
122
+ describe('on go back', () => {
123
+ beforeEach(async () => {
124
+ playbackRate.$el.find('#playback-rate-back-button').click()
125
+ return new Promise((resolve) => setTimeout(resolve, 0))
80
126
  })
81
- it('should update the gear box option label', () => {
82
- expect(
83
- bottomGear.$el.find('#playback-rate-button').text(),
84
- // @ts-ignore
85
- ).toMatchPlaybackRateLabel(`playback_rate ${rate}x`)
127
+ it('should refresh the bottom gear', () => {
128
+ expect(bottomGear.refresh).toHaveBeenCalled()
86
129
  })
87
130
  })
88
131
  })
89
- describe('on go back', () => {
90
- beforeEach(async () => {
91
- playbackRate.$el.find('#playback-rate-back-button').click()
92
- return new Promise((resolve) => setTimeout(resolve, 0))
132
+ describe('options.defaultValue', () => {
133
+ beforeEach(() => {
134
+ core.options.playbackRate = {
135
+ defaultValue: 1.5,
136
+ }
137
+ playbackRate = new PlaybackRate(core)
138
+ core.emit(Events.CORE_READY)
139
+ mediaControl.trigger(Events.MEDIACONTROL_RENDERED)
140
+ core.activePlayback.getPlaybackType.mockReturnValue('live')
141
+ core.activeContainer.getPlaybackType.mockReturnValue('live')
142
+ core.getPlaybackType.mockReturnValue('live')
143
+ core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED)
144
+ bottomGear.trigger(GearEvents.RENDERED)
145
+ core.activePlayback.dvrEnabled = true
146
+ core.activeContainer.isDvrEnabled.mockReturnValue(true)
147
+ core.activePlayback.emit(Events.PLAYBACK_LOADEDMETADATA)
148
+ core.activeContainer.emit(Events.CONTAINER_LOADEDMETADATA)
149
+ })
150
+ it('should set the selected rate to the defaultValue', () => {
151
+ expect(core.activePlayback.setPlaybackRate).toHaveBeenCalledWith(1.5)
152
+ })
153
+ it('should highlight the selected rate', () => {
154
+ expect(
155
+ playbackRate.$el.find('[data-rate="1.5"]').parent().hasClass('current'),
156
+ ).toBe(true)
157
+ expect(
158
+ playbackRate.$el.find('[data-rate="1.5"]').hasClass('gcore-skin-active'),
159
+ ).toBe(true)
93
160
  })
94
- it('should refresh the bottom gear', () => {
95
- expect(bottomGear.refresh).toHaveBeenCalled()
161
+ it('should render proper gear box option label', () => {
162
+ expect(
163
+ bottomGear.$el.find('#playback-rate-button').text(),
164
+ // @ts-ignore
165
+ ).toMatchPlaybackRateLabel('1.5x')
96
166
  })
97
167
  })
98
168
  })
@@ -105,7 +175,7 @@ expect.extend({
105
175
  received
106
176
  .replace(/\/assets.*\.svg/g, '')
107
177
  .replace(/\s+/g, ' ')
108
- .trim().includes(expected),
178
+ .trim().includes(`playback_rate ${expected}`),
109
179
  message: () => `${received} does${isNot ? '' : ' not'} match ${expected}`,
110
180
  }
111
181
  },
@@ -1,6 +1,6 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
- exports[`PlaybackRate > should render 1`] = `
3
+ exports[`PlaybackRate > basically > should render 1`] = `
4
4
  "<button class="gplayer-lite-btn go-back gcore-skin-text-color" id="playback-rate-back-button">
5
5
  <span class="arrow-left-icon">/assets/icons/new/arrow-left.svg</span>
6
6
  playback_rate
@@ -11,7 +11,7 @@ import subtitlesOnIcon from '../../../assets/icons/new/subtitles-on.svg'
11
11
  import comboboxHTML from '../../../assets/subtitles/combobox.ejs'
12
12
  import stringHTML from '../../../assets/subtitles/string.ejs'
13
13
 
14
- import { isFullscreen } from '../utils.js'
14
+ import { isFullscreen } from '../utils/fullscreen.js'
15
15
  import type { ZeptoResult } from '../../types.js'
16
16
 
17
17
  const VERSION: string = '2.19.14'
@@ -0,0 +1,34 @@
1
+ import { Browser, Utils } from '@clappr/core';
2
+ import { reportError } from '@gcorevideo/utils';
3
+
4
+ export const fullscreenEnabled = Utils.Fullscreen.fullscreenEnabled
5
+
6
+ export function isFullscreen(el: HTMLElement): boolean {
7
+ const video =
8
+ el.nodeName === 'video'
9
+ ? (el as HTMLVideoElement)
10
+ : el.querySelector('video')
11
+ if (!video) {
12
+ return false
13
+ }
14
+ if (Browser.isiOS) {
15
+ return FullscreenIOS.isFullscreen(video)
16
+ }
17
+ return !!document.fullscreenElement
18
+ }
19
+
20
+ const FullscreenIOS = {
21
+ isFullscreen: function (el: HTMLVideoElement): boolean {
22
+ try {
23
+ // @ts-ignore
24
+ if (el.webkitDisplayingFullscreen !== undefined) {
25
+ // @ts-ignore
26
+ return !!el.webkitDisplayingFullscreen
27
+ }
28
+ } catch (e) {
29
+ reportError(e)
30
+ }
31
+
32
+ return false
33
+ },
34
+ }