@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
|
@@ -4,9 +4,9 @@ import { ClosedCaptions } from '../ClosedCaptions.js'
|
|
|
4
4
|
import { createMockCore, createMockMediaControl } from '../../../testUtils.js'
|
|
5
5
|
import { ExtendedEvents } from '../../media-control/MediaControl.js'
|
|
6
6
|
|
|
7
|
-
import { LogTracer, Logger, setTracer } from '@gcorevideo/utils'
|
|
8
7
|
import { Events } from '@clappr/core'
|
|
9
|
-
|
|
8
|
+
|
|
9
|
+
// import { LogTracer, Logger, setTracer } from '@gcorevideo/utils'
|
|
10
10
|
|
|
11
11
|
// Logger.enable('*')
|
|
12
12
|
// setTracer(new LogTracer('ClosedCaptions.test'))
|
|
@@ -18,6 +18,7 @@ describe('ClosedCaptions', () => {
|
|
|
18
18
|
beforeEach(() => {
|
|
19
19
|
core = createMockCore()
|
|
20
20
|
mediaControl = createMockMediaControl(core)
|
|
21
|
+
mediaControl.getAvailablePopupHeight = vi.fn().mockReturnValue(211)
|
|
21
22
|
core.getPlugin = vi.fn().mockImplementation((name) => {
|
|
22
23
|
if (name === 'media_control') {
|
|
23
24
|
return mediaControl
|
|
@@ -31,44 +32,60 @@ describe('ClosedCaptions', () => {
|
|
|
31
32
|
core.emit(Events.CORE_READY)
|
|
32
33
|
core.activePlayback.el = document.createElement('video')
|
|
33
34
|
core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
|
|
34
|
-
core.activePlayback.closedCaptionsTracks = [
|
|
35
|
-
{
|
|
36
|
-
id: 1,
|
|
37
|
-
name: 'English',
|
|
38
|
-
track: {
|
|
39
|
-
language: 'en',
|
|
40
|
-
kind: 'subtitles',
|
|
41
|
-
label: 'English',
|
|
42
|
-
mode: 'hidden',
|
|
43
|
-
cues: [],
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
id: 2,
|
|
48
|
-
name: 'Spanish',
|
|
49
|
-
track: {
|
|
50
|
-
language: 'es',
|
|
51
|
-
kind: 'subtitles',
|
|
52
|
-
label: 'Spanish',
|
|
53
|
-
mode: 'hidden',
|
|
54
|
-
cues: [],
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
]
|
|
58
|
-
core.activePlayback.emit(Events.PLAYBACK_SUBTITLE_AVAILABLE)
|
|
59
|
-
core.activeContainer.emit(Events.CONTAINER_SUBTITLE_AVAILABLE)
|
|
60
35
|
})
|
|
61
36
|
it('should render', () => {
|
|
62
37
|
expect(cc.el.innerHTML).toMatchSnapshot()
|
|
63
|
-
expect(cc.$el.find('#cc-button').length).toEqual(1)
|
|
64
|
-
expect(
|
|
38
|
+
expect(cc.$el.find('#gplayer-cc-button').length).toEqual(1)
|
|
39
|
+
expect(cc.$el.find('#gplayer-cc-menu').css('display')).toEqual('none')
|
|
40
|
+
expect(core.activeContainer.$el.find('#gplayer-cc-line').length).toEqual(
|
|
41
|
+
1,
|
|
42
|
+
)
|
|
43
|
+
})
|
|
44
|
+
it('should clamp popup to availableheight', () => {
|
|
45
|
+
expect(cc.$el.find('#gplayer-cc-menu').css('max-height')).toBe('211px')
|
|
46
|
+
})
|
|
47
|
+
describe('until subtitle tracks are available', () => {
|
|
48
|
+
it('should not mount', () => {
|
|
49
|
+
expect(mediaControl.slot).not.toHaveBeenCalledWith(
|
|
50
|
+
'cc',
|
|
51
|
+
expect.anything(),
|
|
52
|
+
)
|
|
53
|
+
emitSubtitleAvailable(core)
|
|
54
|
+
expect(mediaControl.slot).toHaveBeenCalledWith('cc', cc.$el)
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
describe('when viewport is resized', () => {
|
|
58
|
+
beforeEach(() => {
|
|
59
|
+
mediaControl.getAvailablePopupHeight = vi.fn().mockReturnValue(197)
|
|
60
|
+
core.activeContainer.emit(Events.CONTAINER_RESIZE, {
|
|
61
|
+
width: 320,
|
|
62
|
+
height: 260,
|
|
63
|
+
})
|
|
64
|
+
// core.emit(Events.CORE_RESIZE, { width: 320, height: 260 })
|
|
65
|
+
})
|
|
66
|
+
it('should clamp popup height', () => {
|
|
67
|
+
expect(cc.$el.find('#gplayer-cc-menu').css('max-height')).toBe('197px')
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
describe('when media control is rerendered', () => {
|
|
71
|
+
beforeEach(() => {
|
|
72
|
+
emitSubtitleAvailable(core)
|
|
73
|
+
mediaControl.trigger(Events.MEDIACONTROL_RENDERED)
|
|
74
|
+
})
|
|
75
|
+
it('should mount', () => {
|
|
76
|
+
expect(mediaControl.slot).toHaveBeenCalledWith('cc', cc.$el)
|
|
77
|
+
})
|
|
65
78
|
})
|
|
66
79
|
describe('when button is clicked', () => {
|
|
67
80
|
beforeEach(() => {
|
|
68
|
-
|
|
81
|
+
emitSubtitleAvailable(core)
|
|
82
|
+
cc.$el.find('#gplayer-cc-button').click()
|
|
69
83
|
})
|
|
70
84
|
it('should open menu', () => {
|
|
71
|
-
expect(cc.$el.find('#cc-
|
|
85
|
+
expect(cc.$el.find('#gplayer-cc-menu').css('display')).not.toBe('none')
|
|
86
|
+
expect(cc.$el.find('#gplayer-cc-button').attr('aria-expanded')).toBe(
|
|
87
|
+
'true',
|
|
88
|
+
)
|
|
72
89
|
})
|
|
73
90
|
it('should collapse all other menus', () => {
|
|
74
91
|
expect(mediaControl.trigger).toHaveBeenCalledWith(
|
|
@@ -79,20 +96,188 @@ describe('ClosedCaptions', () => {
|
|
|
79
96
|
})
|
|
80
97
|
describe('when clicked twice', () => {
|
|
81
98
|
beforeEach(() => {
|
|
82
|
-
|
|
99
|
+
emitSubtitleAvailable(core)
|
|
100
|
+
cc.$el.find('#gplayer-cc-button').click().click()
|
|
83
101
|
})
|
|
84
102
|
it('should collapse the menu', () => {
|
|
85
|
-
expect(cc.$el.find('#cc-
|
|
103
|
+
expect(cc.$el.find('#gplayer-cc-menu').css('display')).toBe('none')
|
|
104
|
+
expect(cc.$el.find('#gplayer-cc-button').attr('aria-expanded')).toBe(
|
|
105
|
+
'false',
|
|
106
|
+
)
|
|
86
107
|
})
|
|
87
108
|
})
|
|
88
109
|
describe('when media control is hidden', () => {
|
|
89
110
|
beforeEach(() => {
|
|
111
|
+
emitSubtitleAvailable(core)
|
|
90
112
|
cc.$el.find('#cc-button').click()
|
|
91
113
|
mediaControl.trigger(Events.MEDIACONTROL_HIDE)
|
|
92
114
|
})
|
|
93
115
|
it('should hide menu', () => {
|
|
94
|
-
expect(cc.$el.find('#cc-
|
|
116
|
+
expect(cc.$el.find('#gplayer-cc-menu').css('display')).toBe('none')
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
describe('when container is clicked', () => {
|
|
120
|
+
beforeEach(() => {
|
|
121
|
+
emitSubtitleAvailable(core)
|
|
122
|
+
cc.$el.find('#gplayer-cc-button').click()
|
|
123
|
+
core.activeContainer.emit(Events.CONTAINER_CLICK)
|
|
124
|
+
})
|
|
125
|
+
it('should hide menu', () => {
|
|
126
|
+
expect(cc.$el.find('#gplayer-cc-menu').css('display')).toBe('none')
|
|
127
|
+
expect(cc.$el.find('#gplayer-cc-button').attr('aria-expanded')).toBe(
|
|
128
|
+
'false',
|
|
129
|
+
)
|
|
130
|
+
})
|
|
131
|
+
})
|
|
132
|
+
describe('when subtitle is changed', () => {
|
|
133
|
+
beforeEach(async () => {
|
|
134
|
+
emitSubtitleAvailable(core)
|
|
135
|
+
await new Promise((resolve) => setTimeout(resolve, 100))
|
|
136
|
+
core.activePlayback.getCurrentTime = vi.fn().mockReturnValue(7)
|
|
137
|
+
core.activeContainer.getCurrentTime = vi.fn().mockReturnValue(7)
|
|
138
|
+
core.activePlayback.closedCaptionsTracks[1].track.cues = [
|
|
139
|
+
{
|
|
140
|
+
startTime: 0,
|
|
141
|
+
endTime: 5,
|
|
142
|
+
text: 'Alright this is me',
|
|
143
|
+
getCueAsHTML: vi
|
|
144
|
+
.fn()
|
|
145
|
+
.mockImplementation(() =>
|
|
146
|
+
document.createTextNode('Alright this is me'),
|
|
147
|
+
),
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
startTime: 5,
|
|
151
|
+
endTime: 10,
|
|
152
|
+
text: 'Welcome to my channel',
|
|
153
|
+
getCueAsHTML: vi
|
|
154
|
+
.fn()
|
|
155
|
+
.mockImplementation(() =>
|
|
156
|
+
document.createTextNode('Welcome to my channel'),
|
|
157
|
+
),
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
startTime: 10,
|
|
161
|
+
endTime: 15,
|
|
162
|
+
text: 'Thank you for watching',
|
|
163
|
+
getCueAsHTML: vi
|
|
164
|
+
.fn()
|
|
165
|
+
.mockImplementation(() =>
|
|
166
|
+
document.createTextNode('Thank you for watching'),
|
|
167
|
+
),
|
|
168
|
+
},
|
|
169
|
+
]
|
|
170
|
+
core.activePlayback.emit(Events.PLAYBACK_SUBTITLE_CHANGED, { id: 2 })
|
|
171
|
+
})
|
|
172
|
+
it('should activate subtitle track', () => {
|
|
173
|
+
expect(core.activePlayback.closedCaptionsTracks[1].track.mode).toBe(
|
|
174
|
+
'showing',
|
|
175
|
+
)
|
|
176
|
+
expect(core.activePlayback.closedCaptionsTracks[0].track.mode).toBe(
|
|
177
|
+
'hidden',
|
|
178
|
+
)
|
|
179
|
+
})
|
|
180
|
+
it('should show active subtitle text', () => {
|
|
181
|
+
expect(
|
|
182
|
+
core.activeContainer.$el.find('#gplayer-cc-line').text().trim(),
|
|
183
|
+
).toEqual('Welcome to my channel')
|
|
184
|
+
})
|
|
185
|
+
})
|
|
186
|
+
describe('when subtitle is selected from menu', () => {
|
|
187
|
+
beforeEach(() => {
|
|
188
|
+
emitSubtitleAvailable(core)
|
|
189
|
+
cc.$el.find('#gplayer-cc-menu li:nth-child(2) a').click()
|
|
190
|
+
})
|
|
191
|
+
it('should activate subtitle track', () => {
|
|
192
|
+
expect(core.activePlayback.closedCaptionsTrackId).toEqual(2)
|
|
193
|
+
})
|
|
194
|
+
it('should highlight selected menu item', () => {
|
|
195
|
+
expect(
|
|
196
|
+
cc.$el.find('#gplayer-cc-menu li:nth-child(2)').hasClass('current'),
|
|
197
|
+
).toBe(true)
|
|
198
|
+
expect(
|
|
199
|
+
cc.$el
|
|
200
|
+
.find('#gplayer-cc-menu li:nth-child(2) a')
|
|
201
|
+
.attr('aria-checked'),
|
|
202
|
+
).toBe('true')
|
|
203
|
+
expect(cc.$el.find('#gplayer-cc-menu li.current').length).toBe(1)
|
|
204
|
+
expect(
|
|
205
|
+
cc.$el.find('#gplayer-cc-menu li a[aria-checked="true"]').length,
|
|
206
|
+
).toBe(1)
|
|
207
|
+
})
|
|
208
|
+
it('should collapse menu', () => {
|
|
209
|
+
expect(cc.$el.find('#gplayer-cc-menu').css('display')).toBe('none')
|
|
210
|
+
})
|
|
211
|
+
})
|
|
212
|
+
describe('when user turns off subtitles', () => {
|
|
213
|
+
beforeEach(() => {
|
|
214
|
+
emitSubtitleAvailable(core)
|
|
215
|
+
core.activePlayback.closedCaptionsTracks[1].track.mode = 'showing'
|
|
216
|
+
core.activePlayback.closedCaptionsTrackId = 2
|
|
217
|
+
core.activePlayback.emit(Events.PLAYBACK_SUBTITLE_CHANGED, { id: 2 })
|
|
218
|
+
cc.$el.find('#gplayer-cc-button').click()
|
|
219
|
+
cc.$el.find('#gplayer-cc-menu li:nth-child(3) a').click() // off
|
|
220
|
+
})
|
|
221
|
+
it('should hide menu', () => {
|
|
222
|
+
expect(cc.$el.find('#gplayer-cc-menu').css('display')).toBe('none')
|
|
223
|
+
})
|
|
224
|
+
it('should hide subtitle text', () => {
|
|
225
|
+
expect(
|
|
226
|
+
core.activeContainer.$el.find('#gplayer-cc-line').text().trim(),
|
|
227
|
+
).toBe('')
|
|
228
|
+
})
|
|
229
|
+
it('should deactivate subtitle track', () => {
|
|
230
|
+
expect(core.activePlayback.closedCaptionsTrackId).toEqual(-1)
|
|
231
|
+
expect(core.activePlayback.closedCaptionsTracks[0].track.mode).toBe(
|
|
232
|
+
'hidden',
|
|
233
|
+
)
|
|
234
|
+
expect(core.activePlayback.closedCaptionsTracks[1].track.mode).toBe(
|
|
235
|
+
'hidden',
|
|
236
|
+
)
|
|
237
|
+
})
|
|
238
|
+
it('should select menu item', () => {
|
|
239
|
+
expect(
|
|
240
|
+
cc.$el.find('#gplayer-cc-menu li:nth-child(3)').hasClass('current'),
|
|
241
|
+
).toBe(true)
|
|
242
|
+
expect(
|
|
243
|
+
cc.$el
|
|
244
|
+
.find('#gplayer-cc-menu li:nth-child(3) a')
|
|
245
|
+
.attr('aria-checked'),
|
|
246
|
+
).toBe('true')
|
|
247
|
+
expect(cc.$el.find('#gplayer-cc-menu li.current').length).toBe(1)
|
|
248
|
+
expect(
|
|
249
|
+
cc.$el.find('#gplayer-cc-menu li a[aria-checked="true"]').length,
|
|
250
|
+
).toBe(1)
|
|
95
251
|
})
|
|
96
252
|
})
|
|
97
253
|
})
|
|
98
254
|
})
|
|
255
|
+
|
|
256
|
+
function emitSubtitleAvailable(core: any) {
|
|
257
|
+
core.activePlayback.closedCaptionsTracks = [
|
|
258
|
+
{
|
|
259
|
+
id: 1,
|
|
260
|
+
name: 'English',
|
|
261
|
+
track: {
|
|
262
|
+
language: 'en',
|
|
263
|
+
kind: 'subtitles',
|
|
264
|
+
label: 'English',
|
|
265
|
+
mode: 'hidden',
|
|
266
|
+
cues: [],
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
id: 2,
|
|
271
|
+
name: 'Spanish',
|
|
272
|
+
track: {
|
|
273
|
+
language: 'es',
|
|
274
|
+
kind: 'subtitles',
|
|
275
|
+
label: 'Spanish',
|
|
276
|
+
mode: 'hidden',
|
|
277
|
+
cues: [],
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
]
|
|
281
|
+
core.activePlayback.emit(Events.PLAYBACK_SUBTITLE_AVAILABLE)
|
|
282
|
+
core.activeContainer.emit(Events.CONTAINER_SUBTITLE_AVAILABLE)
|
|
283
|
+
}
|
|
@@ -1,25 +1,14 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
3
|
exports[`ClosedCaptions > basically > should render 1`] = `
|
|
4
|
-
"<button
|
|
5
|
-
<span class="cc-text">/assets/icons/new/subtitles-off.svg</span>
|
|
6
|
-
</button>
|
|
4
|
+
"<button class="media-control-button media-control-icon gcore-skin-button-color media-control-dd" id="gplayer-cc-button" aria-haspopup="menu" aria-expanded="false" aria-controls="gplayer-cc-menu">/assets/icons/new/subtitles-off.svg</button>
|
|
7
5
|
|
|
8
|
-
<ul class="gcore-skin-bg-color" id="cc-
|
|
6
|
+
<ul class="gcore-skin-bg-color media-control-dd__popup" id="gplayer-cc-menu" role="menu" style="display: none; max-height: 211px;">
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
<li class="">
|
|
17
|
-
<a href="#" class="gcore-skin-text-color" data-cc-select="2">
|
|
18
|
-
Spanish
|
|
19
|
-
</a>
|
|
20
|
-
</li>
|
|
21
|
-
|
|
22
|
-
<li class="current"><a href="#" class="gcore-skin-text-color gcore-skin-active" data-cc-select="-1">off</a></li>
|
|
23
|
-
</ul>
|
|
24
|
-
"
|
|
8
|
+
<li class="current">
|
|
9
|
+
<a href="#" class="gcore-skin-text-color gcore-skin-active" data-item="-1" role="menuitemradio" aria-checked="true">
|
|
10
|
+
off
|
|
11
|
+
</a>
|
|
12
|
+
</li>
|
|
13
|
+
</ul>"
|
|
25
14
|
`;
|
package/src/testUtils.ts
CHANGED
|
@@ -134,6 +134,8 @@ export function createMockMediaControl(core: any) {
|
|
|
134
134
|
// @ts-ignore
|
|
135
135
|
mediaControl.getAvailableHeight = vi.fn().mockReturnValue(300)
|
|
136
136
|
// @ts-ignore
|
|
137
|
+
mediaControl.getAvailablePopupHeight = vi.fn().mockReturnValue(286)
|
|
138
|
+
// @ts-ignore
|
|
137
139
|
mediaControl.toggleElement = vi.fn()
|
|
138
140
|
vi.spyOn(mediaControl, 'trigger')
|
|
139
141
|
core.$el.append(mediaControl.$el)
|