Skip to content

Commit c377e17

Browse files
committed
feat: global hotkey support
1 parent 5b9795d commit c377e17

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

src/js/player.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,8 @@ class Player extends Component {
374374

375375
this.boundUpdatePlayerHeightOnAudioOnlyMode_ = (e) => this.updatePlayerHeightOnAudioOnlyMode_(e);
376376

377+
this.boundGlobalKeydown_ = (e) => this.handleGlobalKeydown_(e);
378+
377379
// default isFullscreen_ to false
378380
this.isFullscreen_ = false;
379381

@@ -615,6 +617,10 @@ class Player extends Component {
615617
this.on('keydown', (e) => this.handleKeyDown(e));
616618
this.on('languagechange', (e) => this.handleLanguagechange(e));
617619

620+
if (this.isGlobalHotKeysEnabled()) {
621+
Events.on(document.body, 'keydown', this.boundGlobalKeydown_);
622+
}
623+
618624
this.breakpoints(this.options_.breakpoints);
619625
this.responsive(this.options_.responsive);
620626

@@ -650,6 +656,7 @@ class Player extends Component {
650656
// Make sure all player-specific document listeners are unbound. This is
651657
Events.off(document, this.fsApi_.fullscreenchange, this.boundDocumentFullscreenChange_);
652658
Events.off(document, 'keydown', this.boundFullWindowOnEscKey_);
659+
Events.off(document.body, 'keydown', this.boundGlobalKeydown_);
653660

654661
if (this.styleEl_ && this.styleEl_.parentNode) {
655662
this.styleEl_.parentNode.removeChild(this.styleEl_);
@@ -2251,6 +2258,12 @@ class Player extends Component {
22512258
this.trigger('textdata', data);
22522259
}
22532260

2261+
handleGlobalKeydown_(event) {
2262+
if (event.target === document.body) {
2263+
this.handleKeyDown(event);
2264+
}
2265+
}
2266+
22542267
/**
22552268
* Get object for cached values.
22562269
*
@@ -4574,6 +4587,10 @@ class Player extends Component {
45744587
this.height(this.audioOnlyCache_.controlBarHeight);
45754588
}
45764589

4590+
isGlobalHotKeysEnabled() {
4591+
return !!(this.options_ && this.options_.userActions && this.options_.userActions.globalHotkeys);
4592+
}
4593+
45774594
enableAudioOnlyUI_() {
45784595
// Update styling immediately to show the control bar so we can get its height
45794596
this.addClass('vjs-audio-only-mode');

test/unit/player-user-actions.test.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,3 +639,58 @@ QUnit.test('hotkeys are NOT ignored when focus is on a button input', function(a
639639
defaultKeyTests.mute(this.player, assert, true);
640640
defaultKeyTests.playPause(this.player, assert, true);
641641
});
642+
643+
QUnit.module('Player: User Actions: Global Hotkeys', {
644+
645+
beforeEach() {
646+
this.clock = sinon.useFakeTimers();
647+
this.player = TestHelpers.makePlayer();
648+
},
649+
650+
afterEach() {
651+
this.player.dispose();
652+
this.clock.restore();
653+
}
654+
});
655+
656+
QUnit.test('when userActions.globalHotkeys is true, hotkeys are enabled at document.body level', function(assert) {
657+
this.player.dispose();
658+
this.player = TestHelpers.makePlayer({
659+
controls: true,
660+
userActions: {
661+
globalHotkeys: true,
662+
hotkeys: true
663+
}
664+
});
665+
666+
this.player.requestFullscreen = sinon.spy();
667+
668+
const event = new KeyboardEvent('keydown', { // eslint-disable-line no-undef
669+
key: 'f'
670+
});
671+
672+
document.body.dispatchEvent(event);
673+
674+
assert.strictEqual(this.player.requestFullscreen.callCount, 1, 'has gone fullscreen');
675+
});
676+
677+
QUnit.test('when userActions.globalHotkeys is NOT true, hotkeys are NOT enabled at document.body level', function(assert) {
678+
this.player.dispose();
679+
this.player = TestHelpers.makePlayer({
680+
controls: true,
681+
userActions: {
682+
globalHotkeys: false,
683+
hotkeys: true
684+
}
685+
});
686+
687+
this.player.requestFullscreen = sinon.spy();
688+
689+
const event = new KeyboardEvent('keydown', { // eslint-disable-line no-undef
690+
key: 'f'
691+
});
692+
693+
document.body.dispatchEvent(event);
694+
695+
assert.strictEqual(this.player.requestFullscreen.callCount, 0, 'has not gone fullscreen');
696+
});

0 commit comments

Comments
 (0)