Skip to content

Commit

Permalink
Added ‘global’ keyboard shortcut option
Browse files Browse the repository at this point in the history
  • Loading branch information
Sam Potts committed Aug 22, 2016
1 parent d5b5faa commit df7f52d
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 85 deletions.
3 changes: 3 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

# v2.0.2
- Added 'global' keyboard shortcut option

# v2.0.1
- Version bump for NPM

Expand Down
4 changes: 2 additions & 2 deletions dist/plyr.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "plyr",
"version": "2.0.1",
"version": "2.0.2",
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
"homepage": "http://plyr.io",
"main": "src/js/plyr.js",
Expand Down
33 changes: 24 additions & 9 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ Include the `plyr.js` script before the closing `</body>` tag and then call `ply
If you want to use our CDN for the JavaScript, you can use the following:

```html
<script src="https://cdn.plyr.io/2.0.1/plyr.js"></script>
<script src="https://cdn.plyr.io/2.0.2/plyr.js"></script>
```

### CSS
Expand All @@ -135,11 +135,11 @@ Include the `plyr.css` stylsheet into your `<head>`
If you want to use our CDN for the default CSS, you can use the following:

```html
<link rel="stylesheet" href="https://cdn.plyr.io/2.0.1/plyr.css">
<link rel="stylesheet" href="https://cdn.plyr.io/2.0.2/plyr.css">
```

### SVG Sprite
The SVG sprite is loaded automatically from our CDN. To change this, see the [options](#Options) below. For reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/2.0.1/plyr.svg`.
The SVG sprite is loaded automatically from our CDN. To change this, see the [options](#Options) below. For reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/2.0.2/plyr.svg`.

## Advanced

Expand Down Expand Up @@ -321,9 +321,9 @@ Note the single quotes encapsulating the JSON and double quotes on the object ke
</tr>
<tr>
<td><code>keyboardShortcuts</code></td>
<td>Boolean</td>
<td><code>true</code></td>
<td>Enable <a href="#shortcuts">keyboard shortcuts</a></td>
<td>Object</td>
<td><code>{ focused: true, global: true }</code></td>
<td>Enable <a href="#shortcuts">keyboard shortcuts</a> for focused players only or global as well (if there's only one player in the document)</td>
</tr>
<tr>
<td><code>tooltips</code></td>
Expand Down Expand Up @@ -873,50 +873,65 @@ More info on the respective API's here:
*Please note*: not all API methods may work 100%. Your mileage may vary. It's better to use the universal plyr API where possible.

## Shortcuts
By default, a focused player will bind the following keyboard shortcuts:
By default, a player will bind the following keyboard shortcuts when it has focus. If you have the `global` option to `true` and there's only one player in the document then the shortcuts will work when any element has focus, apart from an element that requires input (such as an `<input>`, `<select>` or `[contenteditable]`).

<table class="table" width="100%">
<thead>
<tr>
<th width="25%">Key</th>
<th width="75%">Action</th>
<th width="25%">Global</th>
<th width="50%">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>0</code> to <code>9</code></td>
<td>✔</td>
<td>Seek from 0 to 90% respectively</td>
</tr>
<tr>
<td><code>space</code> or <code>K</code></td>
<td><code>space</code></td>
<td></td>
<td>Toggle playback</td>
</tr>
<tr>
<td><code>K</code></td>
<td>✔</td>
<td>Toggle playback</td>
</tr>
<tr>
<td><code>&larr;</code></td>
<td></td>
<td>Seek backward by the <code>seekTime</code> option</td>
</tr>
<tr>
<td><code>&rarr;</code></td>
<td></td>
<td>Seek forward by the <code>seekTime</code> option</td>
</tr>
<tr>
<td><code>&uarr;</code></td>
<td></td>
<td>Increase volume</td>
</tr>
<tr>
<td><code>&darr;</code></td>
<td></td>
<td>Decrease volume</td>
</tr>
<tr>
<td><code>M</code></td>
<td>✔</td>
<td>Toggle mute</td>
</tr>
<tr>
<td><code>F</code></td>
<td>✔</td>
<td>Toggle fullscreen</td>
</tr>
<tr>
<td><code>C</code></td>
<td>✔</td>
<td>Toggle captions</td>
</tr>
</tbody>
Expand Down
173 changes: 100 additions & 73 deletions src/js/plyr.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ==========================================================================
// Plyr
// plyr.js v2.0.1
// plyr.js v2.0.2
// https://github.com/selz/plyr
// License: The MIT License (MIT)
// ==========================================================================
Expand Down Expand Up @@ -43,19 +43,23 @@
displayDuration: true,
loadSprite: true,
iconPrefix: 'plyr',
iconUrl: 'https://cdn.plyr.io/2.0.1/plyr.svg',
iconUrl: 'https://cdn.plyr.io/2.0.2/plyr.svg',
clickToPlay: true,
hideControls: true,
showPosterOnEnd: false,
disableContextMenu: true,
keyboardShorcuts: true,
keyboardShorcuts: {
focused: true,
global: true
},
tooltips: {
controls: false,
seek: true
},
selectors: {
html5: 'video, audio',
embed: '[data-type]',
editable: 'input, select, [contenteditable]',
container: '.plyr',
controls: {
container: null,
Expand Down Expand Up @@ -2896,88 +2900,111 @@
}

// Keyboard shortcuts
if (config.keyboardShorcuts) {
var first = true;
if (config.keyboardShorcuts.focused) {
var last = null;

// Handle global presses
if (config.keyboardShorcuts.global) {
_on(window, 'keydown keyup', function(event) {
var code = getKeyCode(event),
focused = getFocusElement(),
allowed = [48,49,50,51,52,53,54,56,57,75,77,70,67],
count = get().length;

// Only handle global key press if there's only one player
// and the key is in the allowed keys
// and if the focused element is not editable (e.g. text input)
// and any that accept key input http://webaim.org/techniques/keyboard/
if (count === 1 && _inArray(allowed, code) && (!_is.htmlElement(focused) || !_matches(focused, config.selectors.editable))) {
handleKey(event);
}
});
}

_on(plyr.container, 'keydown keyup', function(event) {
var code = getKeyCode(event),
pressed = event.type === 'keydown';
// Handle presses on focused
_on(plyr.container, 'keydown keyup', handleKey);
}

// If the event is bubbled from the media element
// Firefox doesn't get the keycode for whatever reason
if (!_is.number(code)) {
return;
}
function handleKey(event) {
var code = getKeyCode(event),
pressed = event.type === 'keydown',
held = pressed && code === last;

// Seek by the number keys
function seekByKey() {
// Get current duration
var duration = plyr.media.duration;
// If the event is bubbled from the media element
// Firefox doesn't get the keycode for whatever reason
if (!_is.number(code)) {
return;
}

// Bail if we have no duration set
if (!_is.number(duration)) {
return;
}
// Seek by the number keys
function seekByKey() {
// Get current duration
var duration = plyr.media.duration;

// Divide the max duration into 10th's and times by the number value
_seek((duration / 10) * (code - 48));
// Bail if we have no duration set
if (!_is.number(duration)) {
return;
}

// Handle the key on keydown
// Reset on keyup
if (pressed) {
// Which keycodes should we prevent default
var preventDefault = [48,49,50,51,52,53,54,56,57,32,75,38,40,77,39,37,70,67];

// If the code is found prevent default (e.g. prevent scrolling for arrows)
if (_inArray(preventDefault, code)) {
event.preventDefault();
}
// Divide the max duration into 10th's and times by the number value
_seek((duration / 10) * (code - 48));
}

switch(code) {
// 0-9
case 48:
case 49:
case 50:
case 51:
case 52:
case 53:
case 54:
case 55:
case 56:
case 57: if (first) { seekByKey() } break;
// Space and K key
case 32:
case 75: if (first) { _togglePlay(); } break;
// Arrow up
case 38: _increaseVolume(); break;
// Arrow down
case 40: _decreaseVolume(); break;
// M key
case 77: if (first) { _toggleMute() } break;
// Arrow forward
case 39: _forward(); break;
// Arrow back
case 37: _rewind(); break;
// F key
case 70: if (first) { _toggleFullscreen() } break;
// C key
case 67: if (first) { _toggleCaptions() } break;
}
// Handle the key on keydown
// Reset on keyup
if (pressed) {
// Which keycodes should we prevent default
var preventDefault = [48,49,50,51,52,53,54,56,57,32,75,38,40,77,39,37,70,67];

// Escape is handle natively when in full screen
// So we only need to worry about non native
if (!fullscreen.supportsFullScreen && plyr.isFullscreen && code === 27) {
_toggleFullscreen();
}
// If the code is found prevent default (e.g. prevent scrolling for arrows)
if (_inArray(preventDefault, code)) {
event.preventDefault();
event.stopPropagation();
}

// First run completed
first = false;
switch(code) {
// 0-9
case 48:
case 49:
case 50:
case 51:
case 52:
case 53:
case 54:
case 55:
case 56:
case 57: if (!held) { seekByKey(); } break;
// Space and K key
case 32:
case 75: if (!held) { _togglePlay(); } break;
// Arrow up
case 38: _increaseVolume(); break;
// Arrow down
case 40: _decreaseVolume(); break;
// M key
case 77: if (!held) { _toggleMute() } break;
// Arrow forward
case 39: _forward(); break;
// Arrow back
case 37: _rewind(); break;
// F key
case 70: _toggleFullscreen(); break;
// C key
case 67: if (!held) { _toggleCaptions(); } break;
}
else {
first = true;

// Escape is handle natively when in full screen
// So we only need to worry about non native
if (!fullscreen.supportsFullScreen && plyr.isFullscreen && code === 27) {
_toggleFullscreen();
}
});

// Store last code for next cycle
last = code;
}
else {
last = null;
}
}

// Focus/tab management
Expand Down

0 comments on commit df7f52d

Please sign in to comment.