@gcorevideo/player 2.22.0 → 2.22.2
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/bottomgear copy.ejs +10 -0
- package/assets/bottom-gear/bottomgear.ejs +4 -8
- package/assets/bottom-gear/gear-sub-menu.scss +0 -1
- package/assets/bottom-gear/gear.scss +0 -1
- package/assets/clappr-nerd-stats/button.ejs +3 -3
- package/assets/level-selector/button.ejs +2 -4
- package/assets/level-selector/list.ejs +14 -10
- package/assets/level-selector/style.scss +9 -4
- package/assets/media-control/container.scss +1 -1
- package/assets/playback-rate/list.ejs +5 -5
- package/assets/spinner-three-bounce/spinner.scss +1 -1
- package/dist/core.js +1 -2
- package/dist/index.css +885 -884
- package/dist/index.js +3938 -3779
- package/dist/player.d.ts +246 -108
- package/dist/plugins/index.css +1230 -1229
- package/dist/plugins/index.js +4036 -3878
- package/docs/api/player.bottomgear.additem.md +95 -0
- package/docs/api/player.bottomgear.md +63 -19
- package/docs/api/player.bottomgear.refresh.md +5 -1
- package/docs/api/player.clapprnerdstats.md +0 -2
- package/docs/api/player.clicktopause.md +1 -1
- package/docs/api/player.closedcaptions.md +2 -2
- package/docs/api/player.closedcaptionspluginsettings.md +5 -0
- package/docs/api/player.errorscreen.md +18 -4
- package/docs/api/player.errorscreenpluginsettings.md +1 -4
- package/docs/api/player.errorscreensettings.md +15 -0
- package/docs/api/{player.mediacontrolevents.md → player.gearevents.md} +7 -7
- package/docs/api/player.levelselector.events.md +0 -1
- package/docs/api/player.levelselector.md +1 -1
- package/docs/api/player.md +33 -36
- package/docs/api/{player.bottomgear.setcontent.md → player.mediacontrol.handlecustomarea.md} +5 -9
- package/docs/api/player.mediacontrol.md +10 -24
- package/docs/api/player.mediacontrol.putelement.md +2 -2
- package/docs/api/{player.bottomgear.getelement.md → player.mediacontrol.toggleelement.md} +23 -9
- package/docs/api/player.mediacontrolelement.md +1 -1
- package/docs/api/player.playbackrate.md +22 -3
- package/docs/api/{player.gearoptionsitem.md → player.playbackrateoption.md} +6 -4
- package/docs/api/{player.mediacontrol.getcenterpanel.md → player.playbackratesettings.md} +8 -6
- package/docs/api/player.sourcecontroller._constructor_.md +49 -0
- package/docs/api/player.sourcecontroller.md +70 -7
- package/docs/api/player.spinnerevents.md +1 -4
- package/docs/api/player.spinnerthreebounce._constructor_.md +0 -3
- package/docs/api/player.spinnerthreebounce.hide.md +0 -3
- package/docs/api/player.spinnerthreebounce.md +5 -8
- package/docs/api/player.spinnerthreebounce.show.md +2 -5
- package/lib/internal.types.d.ts +5 -0
- package/lib/internal.types.d.ts.map +1 -1
- package/lib/playback/dash-playback/DashPlayback.d.ts.map +1 -1
- package/lib/playback/dash-playback/DashPlayback.js +0 -1
- package/lib/playback.types.d.ts +0 -5
- package/lib/playback.types.d.ts.map +1 -1
- package/lib/plugins/bottom-gear/BottomGear.d.ts +93 -20
- package/lib/plugins/bottom-gear/BottomGear.d.ts.map +1 -1
- package/lib/plugins/bottom-gear/BottomGear.js +145 -37
- package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts +2 -3
- package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts.map +1 -1
- package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.js +18 -15
- package/lib/plugins/click-to-pause/ClickToPause.d.ts +1 -1
- package/lib/plugins/click-to-pause/ClickToPause.d.ts.map +1 -1
- package/lib/plugins/click-to-pause/ClickToPause.js +3 -2
- package/lib/plugins/dvr-controls/DvrControls.js +1 -1
- package/lib/plugins/error-screen/ErrorScreen.d.ts +29 -4
- package/lib/plugins/error-screen/ErrorScreen.d.ts.map +1 -1
- package/lib/plugins/error-screen/ErrorScreen.js +17 -2
- package/lib/plugins/level-selector/LevelSelector.d.ts +8 -11
- package/lib/plugins/level-selector/LevelSelector.d.ts.map +1 -1
- package/lib/plugins/level-selector/LevelSelector.js +66 -102
- package/lib/plugins/media-control/MediaControl.d.ts +6 -15
- package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
- package/lib/plugins/media-control/MediaControl.js +36 -30
- package/lib/plugins/picture-in-picture/PictureInPicture.d.ts.map +1 -1
- package/lib/plugins/picture-in-picture/PictureInPicture.js +7 -2
- package/lib/plugins/playback-rate/PlaybackRate.d.ts +42 -14
- package/lib/plugins/playback-rate/PlaybackRate.d.ts.map +1 -1
- package/lib/plugins/playback-rate/PlaybackRate.js +101 -83
- package/lib/plugins/source-controller/SourceController.d.ts +40 -4
- package/lib/plugins/source-controller/SourceController.d.ts.map +1 -1
- package/lib/plugins/source-controller/SourceController.js +41 -4
- package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.d.ts +8 -6
- package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.d.ts.map +1 -1
- package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.js +10 -6
- package/lib/plugins/subtitles/ClosedCaptions.d.ts +7 -7
- package/lib/plugins/subtitles/ClosedCaptions.d.ts.map +1 -1
- package/lib/plugins/subtitles/ClosedCaptions.js +3 -3
- package/lib/testUtils.d.ts +1 -0
- package/lib/testUtils.d.ts.map +1 -1
- package/lib/testUtils.js +13 -0
- package/package.json +1 -1
- package/src/internal.types.ts +6 -0
- package/src/playback/dash-playback/DashPlayback.ts +0 -1
- package/src/playback.types.ts +0 -5
- package/src/plugins/bottom-gear/BottomGear.ts +186 -77
- package/src/plugins/bottom-gear/__tests__/BottomGear.test.ts +21 -5
- package/src/plugins/bottom-gear/__tests__/__snapshots__/BottomGear.test.ts.snap +5 -12
- package/src/plugins/clappr-nerd-stats/ClapprNerdStats.ts +27 -25
- package/src/plugins/click-to-pause/ClickToPause.ts +3 -2
- package/src/plugins/dvr-controls/DvrControls.ts +1 -1
- package/src/plugins/dvr-controls/__tests__/DvrControls.test.ts +1 -1
- package/src/plugins/error-screen/ErrorScreen.ts +30 -4
- package/src/plugins/level-selector/LevelSelector.ts +80 -120
- package/src/plugins/level-selector/__tests__/LevelSelector.test.ts +69 -79
- package/src/plugins/level-selector/__tests__/__snapshots__/LevelSelector.test.ts.snap +38 -71
- package/src/plugins/media-control/MediaControl.ts +50 -36
- package/src/plugins/media-control/__tests__/MediaControl.test.ts +4 -4
- package/src/plugins/picture-in-picture/PictureInPicture.ts +7 -2
- package/src/plugins/playback-rate/PlaybackRate.ts +136 -108
- package/src/plugins/playback-rate/__tests__/PlaybackRate.test.ts +84 -37
- package/src/plugins/playback-rate/__tests__/__snapshots__/PlaybackRate.test.ts.snap +55 -6
- package/src/plugins/source-controller/SourceController.ts +41 -4
- package/src/plugins/spinner-three-bounce/SpinnerThreeBounce.ts +10 -6
- package/src/plugins/subtitles/ClosedCaptions.ts +9 -10
- package/src/plugins/subtitles/__tests__/ClosedCaptions.test.ts +1 -1
- package/src/testUtils.ts +14 -0
- package/src/typings/vitest.d.ts +1 -0
- package/temp/player.api.json +303 -370
- package/tsconfig.tsbuildinfo +1 -1
- package/docs/api/player.gearitemelement.md +0 -18
- package/docs/api/player.mediacontrol.getleftpanel.md +0 -22
- package/docs/api/player.mediacontrol.getrightpanel.md +0 -22
- package/docs/api/player.subtitlespluginsettings.md +0 -18
- package/docs/api/player.texttrackitem.id.md +0 -11
- package/docs/api/player.texttrackitem.md +0 -87
- package/docs/api/player.texttrackitem.name.md +0 -11
- package/docs/api/player.texttrackitem.track.md +0 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClosedCaptions.d.ts","sourceRoot":"","sources":["../../../src/plugins/subtitles/ClosedCaptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAwB,MAAM,cAAc,CAAA;AAOzE,OAAO,sCAAsC,CAAA;AAe7C,MAAM,MAAM,4BAA4B,GAAG;IACzC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED
|
|
1
|
+
{"version":3,"file":"ClosedCaptions.d.ts","sourceRoot":"","sources":["../../../src/plugins/subtitles/ClosedCaptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAwB,MAAM,cAAc,CAAA;AAOzE,OAAO,sCAAsC,CAAA;AAe7C;;;GAGG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC9C,OAAO,CAAC,oBAAoB,CAAQ;IAEpC,OAAO,CAAC,SAAS,CAAQ;IAEzB,OAAO,CAAC,KAAK,CAA6B;IAE1C,OAAO,CAAC,MAAM,CAAsB;IAEpC,OAAO,CAAC,KAAK,CAA2B;IAExC;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED;;OAEG;IACH,MAAM,KAAK,OAAO,WAEjB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAyB;IAEzD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAuB;IAE7D;;OAEG;IACH,IAAa,UAAU;;MAItB;IAED;;OAEG;IACH,IAAa,MAAM;;;MAKlB;IAED,OAAO,KAAK,mBAAmB,GAE9B;IAED;;OAEG;IACM,UAAU;IAUnB,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,kBAAkB;IAwC1B,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,iBAAiB;IA+BzB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,YAAY;IAqBpB;;OAEG;IACH,IAAI;IAWJ;;OAEG;IACH,IAAI;IAiBJ,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,UAAU;IAUlB;;OAEG;IACM,MAAM;IA0Bf,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,yBAAyB;IAgBjC,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,yBAAyB;IAgBjC,OAAO,CAAC,UAAU;CAKnB"}
|
|
@@ -16,7 +16,7 @@ const T = 'plugins.cc';
|
|
|
16
16
|
* @beta
|
|
17
17
|
*
|
|
18
18
|
* @remarks
|
|
19
|
-
* The plugin is activated when closed captions tracks are
|
|
19
|
+
* The plugin is activated when closed captions tracks are detected in the media source.
|
|
20
20
|
* It shows a familiar "CC" button with a dropdown menu to select the subtitles language.
|
|
21
21
|
*
|
|
22
22
|
* Depends on:
|
|
@@ -33,7 +33,7 @@ const T = 'plugins.cc';
|
|
|
33
33
|
* new Player({
|
|
34
34
|
* ...
|
|
35
35
|
* cc: {
|
|
36
|
-
* language: '
|
|
36
|
+
* language: 'pt-BR',
|
|
37
37
|
* },
|
|
38
38
|
* })
|
|
39
39
|
* ```
|
|
@@ -248,7 +248,7 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
248
248
|
this.$line = $(ClosedCaptions.templateString());
|
|
249
249
|
this.resizeFont();
|
|
250
250
|
this.core.activeContainer.$el.append(this.$line);
|
|
251
|
-
mediaControl.putElement('cc', this
|
|
251
|
+
mediaControl.putElement('cc', this.$el);
|
|
252
252
|
this.updateSelection();
|
|
253
253
|
this.renderIcon();
|
|
254
254
|
return this;
|
package/lib/testUtils.d.ts
CHANGED
|
@@ -108,4 +108,5 @@ export declare function createMockContainer(playback?: any): Events<string | sym
|
|
|
108
108
|
trigger: <T extends string | symbol>(event: T, ...args: any[]) => boolean;
|
|
109
109
|
};
|
|
110
110
|
export declare function createMockMediaControl(core: any): UICorePlugin;
|
|
111
|
+
export declare function createMockBottomGear(core: any): any;
|
|
111
112
|
//# sourceMappingURL=testUtils.d.ts.map
|
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,EAAe,YAAY,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,MAAM,MAAM,eAAe,CAAA;AAElC;;;;GAIG;AACH,qBAAa,aAAc,SAAQ,MAAM;IAErC,SAAS,CAAC,OAAO,EAAE,GAAG;IACtB,QAAQ,CAAC,IAAI,EAAE,GAAG;IAClB,SAAS,CAAC,WAAW,CAAC,EAAE,GAAG;gBAFjB,OAAO,EAAE,GAAG,EACb,IAAI,EAAE,GAAG,EACR,WAAW,CAAC,EAAE,GAAG,YAAA;IAK7B,IAAI,IAAI,WAEP;IAED,OAAO;IAEP,IAAI;IAEJ,KAAK;IAEL,IAAI;IAEJ,OAAO;IAEP,IAAI;IAEJ,cAAc;IAEd,WAAW;IAIX,QAAQ;IAER,OAAO;IAEP,eAAe;IAIf,kBAAkB;IAIlB,cAAc;IAId,qBAAqB;IAIrB,IAAI;IAEJ,MAAM;IAEN,MAAM;IAEN,SAAS;IAET,eAAe;IAIf,WAAW;IAIX,QAAQ;IAIR,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE;CAGtC;AAED,wBAAgB,cAAc,CAC5B,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,SAAS,GAAE,GAA2B;;;;;;;;;;;;;;;;EAqBvC;AAED,wBAAgB,gBAAgB;;;EAK/B;AAED,wBAAgB,mBAAmB;;;;;;EAKlC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiC/C;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,GAAE,GAA0B;;;;;;;;;;;;;EAiBvE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,gBAiB/C"}
|
|
1
|
+
{"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../src/testUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,YAAY,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,MAAM,MAAM,eAAe,CAAA;AAElC;;;;GAIG;AACH,qBAAa,aAAc,SAAQ,MAAM;IAErC,SAAS,CAAC,OAAO,EAAE,GAAG;IACtB,QAAQ,CAAC,IAAI,EAAE,GAAG;IAClB,SAAS,CAAC,WAAW,CAAC,EAAE,GAAG;gBAFjB,OAAO,EAAE,GAAG,EACb,IAAI,EAAE,GAAG,EACR,WAAW,CAAC,EAAE,GAAG,YAAA;IAK7B,IAAI,IAAI,WAEP;IAED,OAAO;IAEP,IAAI;IAEJ,KAAK;IAEL,IAAI;IAEJ,OAAO;IAEP,IAAI;IAEJ,cAAc;IAEd,WAAW;IAIX,QAAQ;IAER,OAAO;IAEP,eAAe;IAIf,kBAAkB;IAIlB,cAAc;IAId,qBAAqB;IAIrB,IAAI;IAEJ,MAAM;IAEN,MAAM;IAEN,SAAS;IAET,eAAe;IAIf,WAAW;IAIX,QAAQ;IAIR,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE;CAGtC;AAED,wBAAgB,cAAc,CAC5B,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,SAAS,GAAE,GAA2B;;;;;;;;;;;;;;;;EAqBvC;AAED,wBAAgB,gBAAgB;;;EAK/B;AAED,wBAAgB,mBAAmB;;;;;;EAKlC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiC/C;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,GAAE,GAA0B;;;;;;;;;;;;;EAiBvE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,gBAiB/C;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,GAAG,OAY7C"}
|
package/lib/testUtils.js
CHANGED
|
@@ -161,3 +161,16 @@ export function createMockMediaControl(core) {
|
|
|
161
161
|
mediaControl.toggleElement = vi.fn();
|
|
162
162
|
return mediaControl;
|
|
163
163
|
}
|
|
164
|
+
export function createMockBottomGear(core) {
|
|
165
|
+
const plugin = new UICorePlugin(core);
|
|
166
|
+
plugin.getItem = vi.fn();
|
|
167
|
+
plugin.addItem = vi.fn().mockImplementation((name, $el) => {
|
|
168
|
+
const existing = plugin.$el.find(`[data-${name}]`);
|
|
169
|
+
if (existing.length) {
|
|
170
|
+
return existing;
|
|
171
|
+
}
|
|
172
|
+
return $('<li></li>').attr(`data-${name}`, '').append($el).appendTo(plugin.$el);
|
|
173
|
+
});
|
|
174
|
+
plugin.refresh = vi.fn();
|
|
175
|
+
return plugin;
|
|
176
|
+
}
|
package/package.json
CHANGED
package/src/internal.types.ts
CHANGED
|
@@ -662,7 +662,6 @@ export default class DashPlayback extends BasePlayback {
|
|
|
662
662
|
get audioTracks(): AudioTrack[] {
|
|
663
663
|
assert.ok(this._dash, 'DASH.js MediaPlayer is not initialized')
|
|
664
664
|
const tracks = this._dash.getTracksFor('audio')
|
|
665
|
-
trace(`${T} get audioTracks`, { tracks })
|
|
666
665
|
return tracks.map(toClapprTrack)
|
|
667
666
|
}
|
|
668
667
|
|
package/src/playback.types.ts
CHANGED
|
@@ -1,66 +1,123 @@
|
|
|
1
|
-
import { UICorePlugin, template, Events as ClapprEvents } from '@clappr/core'
|
|
2
|
-
import { trace } from '@gcorevideo/utils'
|
|
3
|
-
import assert from 'assert'
|
|
1
|
+
import { UICorePlugin, template, Events as ClapprEvents, $ } from '@clappr/core'
|
|
2
|
+
import { trace } from '@gcorevideo/utils'
|
|
3
|
+
import assert from 'assert'
|
|
4
4
|
|
|
5
|
-
import { CLAPPR_VERSION } from '../../build.js'
|
|
5
|
+
import { CLAPPR_VERSION } from '../../build.js'
|
|
6
6
|
|
|
7
|
-
import pluginHtml from '../../../assets/bottom-gear/bottomgear.ejs'
|
|
8
|
-
import '../../../assets/bottom-gear/gear.scss'
|
|
9
|
-
import '../../../assets/bottom-gear/gear-sub-menu.scss'
|
|
10
|
-
import gearIcon from '../../../assets/icons/new/gear.svg'
|
|
11
|
-
import gearHdIcon from '../../../assets/icons/new/gear-hd.svg'
|
|
12
|
-
import { ZeptoResult } from '../../types.js'
|
|
13
|
-
import { MediaControlEvents } from '../media-control/MediaControl';
|
|
7
|
+
import pluginHtml from '../../../assets/bottom-gear/bottomgear.ejs'
|
|
8
|
+
import '../../../assets/bottom-gear/gear.scss'
|
|
9
|
+
import '../../../assets/bottom-gear/gear-sub-menu.scss'
|
|
10
|
+
import gearIcon from '../../../assets/icons/new/gear.svg'
|
|
11
|
+
import gearHdIcon from '../../../assets/icons/new/gear-hd.svg'
|
|
12
|
+
import { ZeptoResult } from '../../types.js'
|
|
14
13
|
|
|
15
|
-
const VERSION = '2.19.12'
|
|
14
|
+
const VERSION = '2.19.12'
|
|
16
15
|
|
|
17
|
-
const T = 'plugins.bottom_gear'
|
|
16
|
+
const T = 'plugins.bottom_gear'
|
|
18
17
|
|
|
19
18
|
/**
|
|
20
|
-
*
|
|
19
|
+
* Events triggered by the plugin
|
|
21
20
|
* @beta
|
|
22
21
|
*/
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
export enum GearEvents {
|
|
23
|
+
/**
|
|
24
|
+
* Use this event to accurately attach an item to the gear menu
|
|
25
|
+
*/
|
|
26
|
+
RENDERED = 'rendered',
|
|
27
|
+
}
|
|
29
28
|
|
|
30
29
|
// TODO disabled if no items added
|
|
31
30
|
|
|
32
31
|
/**
|
|
33
|
-
* `PLUGIN` that adds
|
|
32
|
+
* `PLUGIN` that adds a button to extend the media controls UI with extra options.
|
|
34
33
|
* @beta
|
|
35
34
|
* @remarks
|
|
36
|
-
* The
|
|
37
|
-
*
|
|
35
|
+
* The plugin renders small gear icon to the right of the media controls.
|
|
36
|
+
* It provides a base for attaching custom settings UI in the gear menu
|
|
37
|
+
*
|
|
38
38
|
* Depends on:
|
|
39
39
|
*
|
|
40
40
|
* - {@link MediaControl}
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* You can use bottom gear to add custom settings UI to the gear menu.
|
|
44
|
+
*
|
|
45
|
+
* ```ts
|
|
46
|
+
* import { BottomGear } from '@gcorevideo/player/plugins/bottom-gear';
|
|
47
|
+
*
|
|
48
|
+
* class CustomOptionsPlugin extends UICorePlugin {
|
|
49
|
+
* // ...
|
|
50
|
+
*
|
|
51
|
+
* override get events() {
|
|
52
|
+
* return {
|
|
53
|
+
* 'click #my-button': 'doMyAction',
|
|
54
|
+
* }
|
|
55
|
+
* }
|
|
56
|
+
*
|
|
57
|
+
* private doMyAction() {
|
|
58
|
+
* // ...
|
|
59
|
+
* }
|
|
60
|
+
*
|
|
61
|
+
* override render() {
|
|
62
|
+
* const bottomGear = this.core.getPlugin('bottom_gear');
|
|
63
|
+
* if (!bottomGear) {
|
|
64
|
+
* return this;
|
|
65
|
+
* }
|
|
66
|
+
* this.$el.html('<button class="custom-option">Custom option</button>');
|
|
67
|
+
* // Put rendered element into the gear menu
|
|
68
|
+
* bottomGear.addItem('custom').html(this.$el)
|
|
69
|
+
* return this;
|
|
70
|
+
* }
|
|
71
|
+
*
|
|
72
|
+
* // alternatively, add an option with a submenu
|
|
73
|
+
* override render() {
|
|
74
|
+
* this.$el.html(template(templateHtml)({
|
|
75
|
+
* // ...
|
|
76
|
+
* })));
|
|
77
|
+
* return this;
|
|
78
|
+
* }
|
|
79
|
+
*
|
|
80
|
+
* private addGearOption() {
|
|
81
|
+
* this.core.getPlugin('bottom_gear')
|
|
82
|
+
* .addItem('custom', this.$el)
|
|
83
|
+
* .html($('<button class="custom-option">Custom option</button>'))
|
|
84
|
+
* }
|
|
85
|
+
*
|
|
86
|
+
* override bindEvents() {
|
|
87
|
+
* this.listenToOnce(this.core, ClapprEvents.CORE_READY, () => {
|
|
88
|
+
* const bottomGear = this.core.getPlugin('bottom_gear');
|
|
89
|
+
* assert(bottomGear, 'bottom_gear plugin is required');
|
|
90
|
+
* // simple case
|
|
91
|
+
* this.listenTo(bottomGear, GearEvents.RENDERED, this.render);
|
|
92
|
+
* // or with a submenu
|
|
93
|
+
* this.listenTo(bottomGear, GearEvents.RENDERED, this.addGearOption);
|
|
94
|
+
* });
|
|
95
|
+
* }
|
|
96
|
+
* }
|
|
97
|
+
* ```
|
|
41
98
|
*/
|
|
42
99
|
export class BottomGear extends UICorePlugin {
|
|
43
|
-
private isHd = false
|
|
100
|
+
private isHd = false
|
|
44
101
|
|
|
45
102
|
/**
|
|
46
103
|
* @internal
|
|
47
104
|
*/
|
|
48
105
|
get name() {
|
|
49
|
-
return 'bottom_gear'
|
|
106
|
+
return 'bottom_gear'
|
|
50
107
|
}
|
|
51
108
|
|
|
52
109
|
/**
|
|
53
110
|
* @internal
|
|
54
111
|
*/
|
|
55
112
|
get supportedVersion() {
|
|
56
|
-
return { min: CLAPPR_VERSION }
|
|
113
|
+
return { min: CLAPPR_VERSION }
|
|
57
114
|
}
|
|
58
115
|
|
|
59
116
|
/**
|
|
60
117
|
* @internal
|
|
61
118
|
*/
|
|
62
119
|
static get version() {
|
|
63
|
-
return VERSION
|
|
120
|
+
return VERSION
|
|
64
121
|
}
|
|
65
122
|
|
|
66
123
|
private static readonly template = template(pluginHtml)
|
|
@@ -70,8 +127,8 @@ export class BottomGear extends UICorePlugin {
|
|
|
70
127
|
*/
|
|
71
128
|
override get attributes() {
|
|
72
129
|
return {
|
|
73
|
-
|
|
74
|
-
}
|
|
130
|
+
class: 'media-control-gear',
|
|
131
|
+
}
|
|
75
132
|
}
|
|
76
133
|
|
|
77
134
|
/**
|
|
@@ -79,94 +136,146 @@ export class BottomGear extends UICorePlugin {
|
|
|
79
136
|
*/
|
|
80
137
|
override get events() {
|
|
81
138
|
return {
|
|
82
|
-
'click
|
|
83
|
-
}
|
|
139
|
+
'click #gear-button': 'toggleGearMenu',
|
|
140
|
+
}
|
|
84
141
|
}
|
|
85
142
|
|
|
86
143
|
/**
|
|
87
144
|
* @internal
|
|
88
145
|
*/
|
|
89
146
|
override bindEvents() {
|
|
90
|
-
this.
|
|
91
|
-
this.listenTo(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
* @returns Zepto result of the element
|
|
97
|
-
*/
|
|
98
|
-
getElement(name: GearOptionsItem): ZeptoResult | null {
|
|
99
|
-
return this.$el.find(`.gear-options-list [data-${name}]`);
|
|
147
|
+
this.listenToOnce(this.core, ClapprEvents.CORE_READY, this.onCoreReady)
|
|
148
|
+
this.listenTo(
|
|
149
|
+
this.core,
|
|
150
|
+
ClapprEvents.CORE_ACTIVE_CONTAINER_CHANGED,
|
|
151
|
+
this.onActiveContainerChanged,
|
|
152
|
+
)
|
|
100
153
|
}
|
|
101
154
|
|
|
102
|
-
// TODO implement putElement/addElement method
|
|
103
|
-
|
|
104
155
|
/**
|
|
105
|
-
*
|
|
106
|
-
* @param
|
|
156
|
+
* Adds a custom option to the gear menu
|
|
157
|
+
* @param name - A unique name of the option
|
|
158
|
+
* @param $subMenu - The submenu to attach to the option
|
|
159
|
+
* @returns The added item placeholder to attach custom markup
|
|
160
|
+
* @remarks
|
|
161
|
+
* When called with $submenu param, a click on the added item will toggle the submenu visibility.
|
|
162
|
+
*
|
|
163
|
+
* When added without submenu, it's responsibility of the caller to handle the click event however needed.
|
|
164
|
+
* @example
|
|
165
|
+
* ```ts
|
|
166
|
+
* class MyPlugin extends UICorePlugin {
|
|
167
|
+
* override render() {
|
|
168
|
+
* this.$el.html('<div class="my-awesome-settings">...</div>')
|
|
169
|
+
* this.core.getPlugin('bottom_gear')
|
|
170
|
+
* ?.addItem('custom', this.$el)
|
|
171
|
+
* .html($('<button>Custom settings</button>'))
|
|
172
|
+
* return this
|
|
173
|
+
* }
|
|
174
|
+
* }
|
|
175
|
+
* ```
|
|
107
176
|
*/
|
|
108
|
-
|
|
109
|
-
this.$el.find(
|
|
177
|
+
addItem(name: string, $subMenu?: ZeptoResult): ZeptoResult {
|
|
178
|
+
const $existingItem = this.$el.find(`#gear-options li[data-${name}`)
|
|
179
|
+
if ($existingItem.length) {
|
|
180
|
+
trace(`${T} addItem already exists`, { name })
|
|
181
|
+
return $existingItem
|
|
182
|
+
}
|
|
183
|
+
const $item = $('<li></li>')
|
|
184
|
+
.attr(`data-${name}`, '')
|
|
185
|
+
.appendTo(this.$el.find('#gear-options'))
|
|
186
|
+
if ($subMenu) {
|
|
187
|
+
trace(`${T} addItem adding submenu`, { name })
|
|
188
|
+
$subMenu
|
|
189
|
+
.addClass('gear-sub-menu-wrapper')
|
|
190
|
+
.hide()
|
|
191
|
+
.appendTo(this.$el.find('#gear-options-wrapper'))
|
|
192
|
+
$item.on('click', (e: MouseEvent) => {
|
|
193
|
+
trace(`${T} addItem submenu clicked`, { name })
|
|
194
|
+
e.stopPropagation()
|
|
195
|
+
$subMenu.show()
|
|
196
|
+
this.$el.find('#gear-options').hide()
|
|
197
|
+
})
|
|
198
|
+
}
|
|
199
|
+
return $item
|
|
110
200
|
}
|
|
111
201
|
|
|
112
202
|
private onActiveContainerChanged() {
|
|
113
|
-
trace(`${T} onActiveContainerChanged`)
|
|
114
|
-
this.bindContainerEvents()
|
|
203
|
+
trace(`${T} onActiveContainerChanged`)
|
|
204
|
+
this.bindContainerEvents()
|
|
115
205
|
}
|
|
116
206
|
|
|
117
207
|
private bindContainerEvents() {
|
|
118
|
-
trace(`${T} bindContainerEvents`)
|
|
119
|
-
this.listenTo(
|
|
208
|
+
trace(`${T} bindContainerEvents`)
|
|
209
|
+
this.listenTo(
|
|
210
|
+
this.core.activeContainer,
|
|
211
|
+
ClapprEvents.CONTAINER_HIGHDEFINITIONUPDATE,
|
|
212
|
+
this.highDefinitionUpdate,
|
|
213
|
+
)
|
|
120
214
|
}
|
|
121
215
|
|
|
122
216
|
private highDefinitionUpdate(isHd: boolean) {
|
|
123
|
-
trace(`${T} highDefinitionUpdate`, { isHd })
|
|
124
|
-
this.isHd = isHd
|
|
125
|
-
this.$el.find('.gear-icon').html(isHd ? gearHdIcon : gearIcon)
|
|
217
|
+
trace(`${T} highDefinitionUpdate`, { isHd })
|
|
218
|
+
this.isHd = isHd
|
|
219
|
+
this.$el.find('.gear-icon').html(isHd ? gearHdIcon : gearIcon)
|
|
126
220
|
}
|
|
127
221
|
|
|
128
222
|
/**
|
|
129
223
|
* @internal
|
|
130
224
|
*/
|
|
131
225
|
override render() {
|
|
132
|
-
|
|
226
|
+
trace(`${T} render`)
|
|
227
|
+
const mediaControl = this.core.getPlugin('media_control')
|
|
228
|
+
if (!mediaControl) {
|
|
229
|
+
return this // TODO test
|
|
230
|
+
}
|
|
231
|
+
const icon = this.isHd ? gearHdIcon : gearIcon
|
|
232
|
+
this.$el
|
|
233
|
+
.html(BottomGear.template({ icon }))
|
|
234
|
+
.find('#gear-sub-menu-wrapper')
|
|
235
|
+
.hide()
|
|
133
236
|
|
|
134
|
-
// TODO
|
|
135
|
-
|
|
136
|
-
'quality',
|
|
137
|
-
'rate',
|
|
138
|
-
'nerd',
|
|
139
|
-
];
|
|
140
|
-
const icon = this.isHd ? gearHdIcon : gearIcon;
|
|
141
|
-
this.$el.html(BottomGear.template({ icon, items }));
|
|
237
|
+
// TODO make non-clickable when there are no items
|
|
238
|
+
mediaControl.putElement('gear', this.$el)
|
|
142
239
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
240
|
+
setTimeout(() => {
|
|
241
|
+
this.trigger(GearEvents.RENDERED)
|
|
242
|
+
}, 0)
|
|
243
|
+
|
|
244
|
+
return this
|
|
146
245
|
}
|
|
147
246
|
|
|
148
247
|
/**
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
248
|
+
* Collapses any submenu open back to the gear menu.
|
|
249
|
+
* @remarks
|
|
250
|
+
* Should be called by the UI plugin that added a gear item with a submenu when the latter is closed (e.g., when a "back" button is clicked).
|
|
152
251
|
*/
|
|
153
252
|
refresh() {
|
|
154
|
-
this.
|
|
155
|
-
this.$el.find('
|
|
253
|
+
this.$el.find('.gear-sub-menu-wrapper').hide()
|
|
254
|
+
this.$el.find('#gear-options').show()
|
|
156
255
|
}
|
|
157
256
|
|
|
158
257
|
private toggleGearMenu() {
|
|
159
|
-
this.$el.find('
|
|
258
|
+
this.$el.find('#gear-options-wrapper').toggle()
|
|
160
259
|
}
|
|
161
260
|
|
|
162
261
|
private hide() {
|
|
163
|
-
this.$el.find('
|
|
262
|
+
this.$el.find('#gear-options-wrapper').hide()
|
|
164
263
|
}
|
|
165
264
|
|
|
166
265
|
private onCoreReady() {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
this.listenTo(
|
|
266
|
+
trace(`${T} onCoreReady`)
|
|
267
|
+
const mediaControl = this.core.getPlugin('media_control')
|
|
268
|
+
assert(mediaControl, 'media_control plugin is required')
|
|
269
|
+
this.listenTo(
|
|
270
|
+
mediaControl,
|
|
271
|
+
ClapprEvents.MEDIACONTROL_RENDERED,
|
|
272
|
+
this.onMediaControlRendered,
|
|
273
|
+
)
|
|
274
|
+
this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_HIDE, this.hide)
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
private onMediaControlRendered() {
|
|
278
|
+
trace(`${T} onMediaControlRendered`)
|
|
279
|
+
this.render()
|
|
171
280
|
}
|
|
172
281
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { MockedFunction, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import { BottomGear } from '../BottomGear'
|
|
3
|
+
import { BottomGear, GearEvents } from '../BottomGear'
|
|
4
4
|
import { createMockCore, createMockMediaControl } from '../../../testUtils'
|
|
5
|
-
import { MediaControlEvents } from '../../media-control/MediaControl'
|
|
6
5
|
|
|
7
6
|
describe('BottomGear', () => {
|
|
8
7
|
let mediaControl: any
|
|
@@ -19,16 +18,33 @@ describe('BottomGear', () => {
|
|
|
19
18
|
)
|
|
20
19
|
bottomGear = new BottomGear(core)
|
|
21
20
|
onGearRendered = vi.fn()
|
|
22
|
-
|
|
21
|
+
bottomGear.on(GearEvents.RENDERED, onGearRendered, null)
|
|
23
22
|
bottomGear.render()
|
|
24
23
|
})
|
|
25
24
|
it('should render', () => {
|
|
26
25
|
expect(bottomGear.el.innerHTML).toMatchSnapshot()
|
|
27
26
|
})
|
|
28
27
|
it('should attach to media control', () => {
|
|
29
|
-
expect(mediaControl.putElement).toHaveBeenCalledWith('gear', bottomGear
|
|
28
|
+
expect(mediaControl.putElement).toHaveBeenCalledWith('gear', bottomGear.$el)
|
|
30
29
|
})
|
|
31
|
-
it('should emit event', () => {
|
|
30
|
+
it('should emit event in the next cycle', async () => {
|
|
31
|
+
expect(onGearRendered).not.toHaveBeenCalled()
|
|
32
|
+
await new Promise((resolve) => setTimeout(resolve, 0))
|
|
32
33
|
expect(onGearRendered).toHaveBeenCalled()
|
|
33
34
|
})
|
|
35
|
+
it('should render the gear menu hidden', () => {
|
|
36
|
+
expect(bottomGear.$el.find('#gear-options-wrapper').css('display')).toBe(
|
|
37
|
+
'none',
|
|
38
|
+
)
|
|
39
|
+
})
|
|
40
|
+
describe('when clicked', () => {
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
bottomGear.$el.find('#gear-button').click()
|
|
43
|
+
})
|
|
44
|
+
it('should toggle the gear menu', () => {
|
|
45
|
+
expect(bottomGear.$el.find('#gear-options-wrapper').css('display')).toBe(
|
|
46
|
+
'block',
|
|
47
|
+
)
|
|
48
|
+
})
|
|
49
|
+
})
|
|
34
50
|
})
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
3
|
exports[`BottomGear > should render 1`] = `
|
|
4
|
-
"<button type="button" class="
|
|
4
|
+
"<button type="button" class="media-control-button gplayer-lite-btn gcore-skin-button-color gear-icon" id="gear-button">
|
|
5
5
|
/assets/icons/new/gear.svg
|
|
6
6
|
</button>
|
|
7
|
-
<div class="gear-wrapper gcore-skin-bg-color">
|
|
8
|
-
<ul class="gear-options-list" id="gear-options">
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
<li data-rate=""></li>
|
|
13
|
-
|
|
14
|
-
<li data-nerd=""></li>
|
|
15
|
-
|
|
16
|
-
</ul>
|
|
17
|
-
</div>"
|
|
7
|
+
<div class="gear-wrapper gcore-skin-bg-color" id="gear-options-wrapper" style="display: none;">
|
|
8
|
+
<ul class="gear-options-list" id="gear-options"></ul>
|
|
9
|
+
</div>
|
|
10
|
+
"
|
|
18
11
|
`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { UICorePlugin, Events, template, Core, Container } from '@clappr/core'
|
|
2
|
-
import { reportError } from '@gcorevideo/utils'
|
|
2
|
+
import { reportError, trace } from '@gcorevideo/utils'
|
|
3
3
|
import Mousetrap from 'mousetrap'
|
|
4
4
|
|
|
5
5
|
import { CLAPPR_VERSION } from '../../build.js'
|
|
@@ -24,8 +24,8 @@ import '../../../assets/clappr-nerd-stats/clappr-nerd-stats.scss'
|
|
|
24
24
|
import pluginHtml from '../../../assets/clappr-nerd-stats/clappr-nerd-stats.ejs'
|
|
25
25
|
import buttonHtml from '../../../assets/clappr-nerd-stats/button.ejs'
|
|
26
26
|
import statsIcon from '../../../assets/icons/new/stats.svg'
|
|
27
|
-
import { BottomGear } from '../bottom-gear/BottomGear.js'
|
|
28
|
-
import { MediaControl
|
|
27
|
+
import { BottomGear, GearEvents } from '../bottom-gear/BottomGear.js'
|
|
28
|
+
import { MediaControl } from '../media-control/MediaControl.js'
|
|
29
29
|
import assert from 'assert'
|
|
30
30
|
|
|
31
31
|
const qualityClasses = [
|
|
@@ -114,7 +114,7 @@ type Metrics = BaseMetrics & {
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
const T = 'plugins.clappr_nerd_stats'
|
|
118
118
|
|
|
119
119
|
/**
|
|
120
120
|
* `PLUGIN` that displays useful network-related statistics.
|
|
@@ -123,8 +123,6 @@ type Metrics = BaseMetrics & {
|
|
|
123
123
|
* @remarks
|
|
124
124
|
* Depends on:
|
|
125
125
|
*
|
|
126
|
-
* - {@link MediaControl}
|
|
127
|
-
*
|
|
128
126
|
* - {@link BottomGear}
|
|
129
127
|
*
|
|
130
128
|
* - {@link ClapprStats}
|
|
@@ -151,6 +149,8 @@ export class ClapprNerdStats extends UICorePlugin {
|
|
|
151
149
|
|
|
152
150
|
private iconPosition: IconPosition
|
|
153
151
|
|
|
152
|
+
private static readonly buttonTemplate = template(buttonHtml)
|
|
153
|
+
|
|
154
154
|
/**
|
|
155
155
|
* @internal
|
|
156
156
|
*/
|
|
@@ -224,17 +224,15 @@ export class ClapprNerdStats extends UICorePlugin {
|
|
|
224
224
|
* @internal
|
|
225
225
|
*/
|
|
226
226
|
override bindEvents() {
|
|
227
|
-
|
|
228
|
-
assert(mediaControl, 'media_control plugin is required')
|
|
229
|
-
this.listenToOnce(this.core, Events.CORE_READY, this.init)
|
|
230
|
-
this.listenTo(
|
|
231
|
-
mediaControl,
|
|
232
|
-
MediaControlEvents.MEDIACONTROL_GEAR_RENDERED,
|
|
233
|
-
this.addToBottomGear,
|
|
234
|
-
)
|
|
227
|
+
this.listenToOnce(this.core, Events.CORE_READY, this.onCoreReady)
|
|
235
228
|
}
|
|
236
229
|
|
|
237
|
-
private
|
|
230
|
+
private onCoreReady() {
|
|
231
|
+
const bottomGear = this.core.getPlugin('bottom_gear') as BottomGear
|
|
232
|
+
assert(bottomGear, 'bottom_gear plugin is required')
|
|
233
|
+
|
|
234
|
+
this.listenTo(bottomGear, GearEvents.RENDERED, this.addToBottomGear)
|
|
235
|
+
|
|
238
236
|
this.container = this.core.activeContainer
|
|
239
237
|
const clapprStats = this.container?.getPlugin('clappr_stats')
|
|
240
238
|
|
|
@@ -375,6 +373,7 @@ export class ClapprNerdStats extends UICorePlugin {
|
|
|
375
373
|
* @internal
|
|
376
374
|
*/
|
|
377
375
|
override render() {
|
|
376
|
+
trace(`${T} render`)
|
|
378
377
|
// TODO append to the container
|
|
379
378
|
this.core.$el.append(this.$el[0])
|
|
380
379
|
this.hide()
|
|
@@ -383,17 +382,20 @@ export class ClapprNerdStats extends UICorePlugin {
|
|
|
383
382
|
}
|
|
384
383
|
|
|
385
384
|
private addToBottomGear() {
|
|
385
|
+
trace(`${T} addToBottomGear`)
|
|
386
386
|
const gear = this.core.getPlugin('bottom_gear') as BottomGear
|
|
387
|
-
const $
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
387
|
+
const $button = gear
|
|
388
|
+
.addItem('nerd')
|
|
389
|
+
.html(
|
|
390
|
+
ClapprNerdStats.buttonTemplate({
|
|
391
|
+
icon: statsIcon,
|
|
392
|
+
i18n: this.core.i18n,
|
|
393
|
+
}),
|
|
394
|
+
)
|
|
395
|
+
.on('click', (e: MouseEvent) => {
|
|
396
|
+
e.stopPropagation()
|
|
397
|
+
this.toggle()
|
|
398
|
+
})
|
|
397
399
|
}
|
|
398
400
|
|
|
399
401
|
private clearCustomMetrics() {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
//
|
|
1
|
+
// This work is based on the original work of the following authors:
|
|
2
|
+
// Copyright 2014 Globo.com Player authors. All rights reserved.
|
|
2
3
|
// Use of this source code is governed by a BSD-style
|
|
3
4
|
// license that can be found at https://github.com/clappr/clappr-plugins/blob/master/LICENSE.
|
|
4
5
|
|
|
@@ -12,7 +13,7 @@ type Timer = ReturnType<typeof setTimeout>
|
|
|
12
13
|
const T = 'plugins.click_to_pause_custom'
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
|
-
* `PLUGIN` that
|
|
16
|
+
* A small `PLUGIN` that toggles the playback state on click over the video container
|
|
16
17
|
* @beta
|
|
17
18
|
*/
|
|
18
19
|
export class ClickToPause extends ContainerPlugin {
|