Keyboard accessibility improvements (Fixes #66)
- Enter now works on checkboxes within the controls
This commit is contained in:
parent
9feffb2972
commit
388cb4df39
2
dist/plyr.css
vendored
2
dist/plyr.css
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.js
vendored
2
dist/plyr.js
vendored
File diff suppressed because one or more lines are too long
@ -6,7 +6,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<!-- Docs styles -->
|
<!-- Docs styles -->
|
||||||
<link rel="stylesheet" href="//cdn.plyr.io/1.0.26/docs.css">
|
<link rel="stylesheet" href="//cdn.plyr.io/1.0.27/docs.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<!-- Styles -->
|
<!-- Styles -->
|
||||||
<link rel="stylesheet" href="//cdn.plyr.io/1.0.26/plyr.css">
|
<link rel="stylesheet" href="//cdn.plyr.io/1.0.27/plyr.css">
|
||||||
|
|
||||||
<!-- Docs styles -->
|
<!-- Docs styles -->
|
||||||
<link rel="stylesheet" href="//cdn.plyr.io/1.0.26/docs.css">
|
<link rel="stylesheet" href="//cdn.plyr.io/1.0.27/docs.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
@ -67,13 +67,13 @@
|
|||||||
<!-- Load SVG defs -->
|
<!-- Load SVG defs -->
|
||||||
<!-- You should bundle all SVG/Icons into one file using a build tool such as gulp and svg store -->
|
<!-- You should bundle all SVG/Icons into one file using a build tool such as gulp and svg store -->
|
||||||
<script>
|
<script>
|
||||||
(function(d,p){var a=new XMLHttpRequest(),b=d.body;a.open("GET",p,!0);a.send();a.onload=function(){var c=d.createElement("div");c.style.display="none";c.innerHTML=a.responseText;b.insertBefore(c,b.childNodes[0])}})(document,"//cdn.plyr.io/1.0.26/sprite.svg");
|
(function(d,p){var a=new XMLHttpRequest(),b=d.body;a.open("GET",p,!0);a.send();a.onload=function(){var c=d.createElement("div");c.style.display="none";c.innerHTML=a.responseText;b.insertBefore(c,b.childNodes[0])}})(document,"//cdn.plyr.io/1.0.27/sprite.svg");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Plyr core script -->
|
<!-- Plyr core script -->
|
||||||
<script src="//cdn.plyr.io/1.0.26/plyr.js"></script>
|
<script src="//cdn.plyr.io/1.0.27/plyr.js"></script>
|
||||||
|
|
||||||
<!-- Docs script -->
|
<!-- Docs script -->
|
||||||
<script src="//cdn.plyr.io/1.0.26/docs.js"></script>
|
<script src="//cdn.plyr.io/1.0.27/docs.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
12
gulpfile.js
12
gulpfile.js
@ -22,7 +22,8 @@ var fs = require("fs"),
|
|||||||
s3 = require("gulp-s3"),
|
s3 = require("gulp-s3"),
|
||||||
gzip = require("gulp-gzip"),
|
gzip = require("gulp-gzip"),
|
||||||
replace = require("gulp-replace"),
|
replace = require("gulp-replace"),
|
||||||
open = require("gulp-open");
|
open = require("gulp-open"),
|
||||||
|
size = require("gulp-size");
|
||||||
|
|
||||||
var root = __dirname,
|
var root = __dirname,
|
||||||
paths = {
|
paths = {
|
||||||
@ -223,6 +224,10 @@ gulp.task("cdn", function () {
|
|||||||
|
|
||||||
// Upload to CDN
|
// Upload to CDN
|
||||||
gulp.src(paths.upload)
|
gulp.src(paths.upload)
|
||||||
|
.pipe(size({
|
||||||
|
showFiles: true,
|
||||||
|
gzip: true
|
||||||
|
}))
|
||||||
.pipe(rename(function (path) {
|
.pipe(rename(function (path) {
|
||||||
path.dirname = path.dirname.replace(".", version);
|
path.dirname = path.dirname.replace(".", version);
|
||||||
}))
|
}))
|
||||||
@ -234,6 +239,11 @@ gulp.task("cdn", function () {
|
|||||||
gulp.task("docs", function () {
|
gulp.task("docs", function () {
|
||||||
console.log("Uploading " + version + " docs to " + aws.docs.bucket);
|
console.log("Uploading " + version + " docs to " + aws.docs.bucket);
|
||||||
|
|
||||||
|
// Replace versioned files in readme.md
|
||||||
|
gulp.src([root + "/readme.md"])
|
||||||
|
.pipe(replace(cdnpath, aws.cdn.bucket + "/" + version))
|
||||||
|
.pipe(gulp.dest(root));
|
||||||
|
|
||||||
// Replace versioned files in *.html
|
// Replace versioned files in *.html
|
||||||
gulp.src([paths.docs.root + "*.html"])
|
gulp.src([paths.docs.root + "*.html"])
|
||||||
.pipe(replace(cdnpath, aws.cdn.bucket + "/" + version))
|
.pipe(replace(cdnpath, aws.cdn.bucket + "/" + version))
|
||||||
|
83
package.json
83
package.json
@ -1,43 +1,44 @@
|
|||||||
{
|
{
|
||||||
"name": "plyr",
|
"name": "plyr",
|
||||||
"version": "1.0.26",
|
"version": "1.0.27",
|
||||||
"description": "A simple HTML5 media player using custom controls",
|
"description": "A simple HTML5 media player using custom controls",
|
||||||
"homepage": "http://plyr.io",
|
"homepage": "http://plyr.io",
|
||||||
"main": "gulpfile.js",
|
"main": "gulpfile.js",
|
||||||
"dependencies": {},
|
"dependencies": {},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"gulp": "~3.8.6",
|
"gulp": "~3.8.6",
|
||||||
"gulp-autoprefixer": "^0.0.8",
|
"gulp-autoprefixer": "^0.0.8",
|
||||||
"gulp-concat": "~2.3.3",
|
"gulp-concat": "~2.3.3",
|
||||||
"gulp-gzip": "^1.0.0",
|
"gulp-gzip": "^1.0.0",
|
||||||
"gulp-hogan-compile": "^0.4.1",
|
"gulp-hogan-compile": "^0.4.1",
|
||||||
"gulp-less": "~1.3.1",
|
"gulp-less": "~1.3.1",
|
||||||
"gulp-minify-css": "~0.3.6",
|
"gulp-minify-css": "~0.3.6",
|
||||||
"gulp-open": "^0.3.2",
|
"gulp-open": "^0.3.2",
|
||||||
"gulp-rename": "^1.2.0",
|
"gulp-rename": "^1.2.0",
|
||||||
"gulp-replace": "^0.5.3",
|
"gulp-replace": "^0.5.3",
|
||||||
"gulp-s3": "^0.3.0",
|
"gulp-s3": "^0.3.0",
|
||||||
"gulp-sass": "^1.3.3",
|
"gulp-sass": "^1.3.3",
|
||||||
"gulp-svgmin": "^1.0.0",
|
"gulp-size": "^1.2.1",
|
||||||
"gulp-svgstore": "^5.0.0",
|
"gulp-svgmin": "^1.0.0",
|
||||||
"gulp-uglify": "~0.3.1",
|
"gulp-svgstore": "^5.0.0",
|
||||||
"gulp-util": "~2.2.20",
|
"gulp-uglify": "~0.3.1",
|
||||||
"run-sequence": "^0.3.6"
|
"gulp-util": "~2.2.20",
|
||||||
},
|
"run-sequence": "^0.3.6"
|
||||||
"scripts": {
|
},
|
||||||
"preinstall": "npm install -g gulp"
|
"scripts": {
|
||||||
},
|
"preinstall": "npm install -g gulp"
|
||||||
"keywords": [
|
},
|
||||||
"HTML5 Video",
|
"keywords": [
|
||||||
"HTML5 Audio",
|
"HTML5 Video",
|
||||||
"Media Player"
|
"HTML5 Audio",
|
||||||
],
|
"Media Player"
|
||||||
"repository": {
|
],
|
||||||
"type": "git",
|
"repository": {
|
||||||
"url": "git://github.com/selz/plyr.git"
|
"type": "git",
|
||||||
},
|
"url": "git://github.com/selz/plyr.git"
|
||||||
"authors": [
|
},
|
||||||
"Sam Potts <me@sampotts.me>"
|
"authors": [
|
||||||
],
|
"Sam Potts <me@sampotts.me>"
|
||||||
"license": "MIT"
|
],
|
||||||
|
"license": "MIT"
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ If you have any cool ideas or features, please let me know by [creating an issue
|
|||||||
|
|
||||||
Check `docs/index.html` and `docs/dist/docs.js` for an example setup.
|
Check `docs/index.html` and `docs/dist/docs.js` for an example setup.
|
||||||
|
|
||||||
**Heads up**, the example `index.html` file needs to be served from a webserver (such as Apache, Nginx, IIS or similar) unless you change the file sources to include http or https. e.g. change `//cdn.plyr.io/1.0.26/plyr.js` to `https://cdn.plyr.io/1.0.26/plyr.js`
|
**Heads up**, the example `index.html` file needs to be served from a webserver (such as Apache, Nginx, IIS or similar) unless you change the file sources to include http or https. e.g. change `//cdn.plyr.io/1.0.27/plyr.js` to `https://cdn.plyr.io/1.0.27/plyr.js`
|
||||||
|
|
||||||
### Bower
|
### Bower
|
||||||
If bower is your thang, you can grab Plyr using:
|
If bower is your thang, you can grab Plyr using:
|
||||||
@ -51,11 +51,11 @@ More info on setting up dependencies can be found in the [Bower Docs](http://bow
|
|||||||
If you want to use our CDN, you can use the following. HTTPS (SSL) is supported.
|
If you want to use our CDN, you can use the following. HTTPS (SSL) is supported.
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<link rel="stylesheet" href="//cdn.plyr.io/1.0.26/plyr.css">
|
<link rel="stylesheet" href="//cdn.plyr.io/1.0.27/plyr.css">
|
||||||
<script src="//cdn.plyr.io/1.0.26/plyr.js"></script>
|
<script src="//cdn.plyr.io/1.0.27/plyr.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also access the `sprite.svg` file at `//cdn.plyr.io/1.0.26/sprite.svg`.
|
You can also access the `sprite.svg` file at `//cdn.plyr.io/1.0.27/sprite.svg`.
|
||||||
|
|
||||||
### CSS
|
### CSS
|
||||||
If you want to use the default css, add the `plyr.css` file from /dist into your head, or even better use `plyr.less` or `plyr.sass` file included in `/src` in your build to save a request.
|
If you want to use the default css, add the `plyr.css` file from /dist into your head, or even better use `plyr.less` or `plyr.sass` file included in `/src` in your build to save a request.
|
||||||
|
113
src/js/plyr.js
113
src/js/plyr.js
@ -1,6 +1,6 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Plyr
|
// Plyr
|
||||||
// plyr.js v1.0.25
|
// plyr.js v1.0.27
|
||||||
// https://github.com/selz/plyr
|
// https://github.com/selz/plyr
|
||||||
// License: The MIT License (MIT)
|
// License: The MIT License (MIT)
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
@ -317,6 +317,17 @@
|
|||||||
function _toggleHandler(element, events, callback, toggle) {
|
function _toggleHandler(element, events, callback, toggle) {
|
||||||
events = events.split(" ");
|
events = events.split(" ");
|
||||||
|
|
||||||
|
// If a nodelist is passed, call itself on each node
|
||||||
|
if(element instanceof NodeList) {
|
||||||
|
for (var x = 0; x < element.length; x++) {
|
||||||
|
if (element[x] instanceof Node) {
|
||||||
|
_toggleHandler(element[x], arguments[1], arguments[2], arguments[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a single node is passed, bind the event listener
|
||||||
for (var i = 0; i < events.length; i++) {
|
for (var i = 0; i < events.length; i++) {
|
||||||
element[toggle ? "addEventListener" : "removeEventListener"](events[i], callback, false);
|
element[toggle ? "addEventListener" : "removeEventListener"](events[i], callback, false);
|
||||||
}
|
}
|
||||||
@ -332,6 +343,35 @@
|
|||||||
_toggleHandler(element, events, callback, false);
|
_toggleHandler(element, events, callback, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Trigger event
|
||||||
|
function _triggerEvent(element, event) {
|
||||||
|
// Create faux event
|
||||||
|
var fauxEvent = document.createEvent("MouseEvents");
|
||||||
|
|
||||||
|
// Set the event type
|
||||||
|
fauxEvent.initEvent(event, true, true);
|
||||||
|
|
||||||
|
// Dispatch the event
|
||||||
|
element.dispatchEvent(fauxEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle checkbox
|
||||||
|
function _toggleCheckbox(event) {
|
||||||
|
// Only listen for return key
|
||||||
|
if(event.keyCode && event.keyCode != 13) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle the checkbox
|
||||||
|
event.target.checked = !event.target.checked;
|
||||||
|
|
||||||
|
// Set the attribute for CSS hooks
|
||||||
|
event.target[event.target.checked ? "setAttribute" : "removeAttribute"]("checked", "");
|
||||||
|
|
||||||
|
// Trigger change event
|
||||||
|
_triggerEvent(event.target, "change");
|
||||||
|
}
|
||||||
|
|
||||||
// Get percentage
|
// Get percentage
|
||||||
function _getPercentage(current, max) {
|
function _getPercentage(current, max) {
|
||||||
if(current === 0 || max === 0 || isNaN(current) || isNaN(max)) {
|
if(current === 0 || max === 0 || isNaN(current) || isNaN(max)) {
|
||||||
@ -496,7 +536,7 @@
|
|||||||
|
|
||||||
if (config.captions.defaultActive) {
|
if (config.captions.defaultActive) {
|
||||||
_toggleClass(player.container, config.classes.captions.active, true);
|
_toggleClass(player.container, config.classes.captions.active, true);
|
||||||
player.buttons.captions.setAttribute("checked", "checked");
|
player.buttons.captions.setAttribute("checked", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -590,9 +630,12 @@
|
|||||||
player.buttons.restart = _getElement(config.selectors.buttons.restart);
|
player.buttons.restart = _getElement(config.selectors.buttons.restart);
|
||||||
player.buttons.rewind = _getElement(config.selectors.buttons.rewind);
|
player.buttons.rewind = _getElement(config.selectors.buttons.rewind);
|
||||||
player.buttons.forward = _getElement(config.selectors.buttons.forward);
|
player.buttons.forward = _getElement(config.selectors.buttons.forward);
|
||||||
|
player.buttons.fullscreen = _getElement(config.selectors.buttons.fullscreen);
|
||||||
|
|
||||||
|
// Inputs
|
||||||
player.buttons.mute = _getElement(config.selectors.buttons.mute);
|
player.buttons.mute = _getElement(config.selectors.buttons.mute);
|
||||||
player.buttons.captions = _getElement(config.selectors.buttons.captions);
|
player.buttons.captions = _getElement(config.selectors.buttons.captions);
|
||||||
player.buttons.fullscreen = _getElement(config.selectors.buttons.fullscreen);
|
player.checkboxes = _getElements("[type='checkbox']");
|
||||||
|
|
||||||
// Progress
|
// Progress
|
||||||
player.progress = {};
|
player.progress = {};
|
||||||
@ -899,7 +942,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the current time
|
// Set the current time
|
||||||
player.media.currentTime = targetTime.toFixed(1);
|
// Try/catch incase the media isn't set and we're calling seek() from source() and IE moans
|
||||||
|
try {
|
||||||
|
player.media.currentTime = targetTime.toFixed(1);
|
||||||
|
}
|
||||||
|
catch(e) {}
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
_log("Seeking to " + player.media.currentTime + " seconds");
|
_log("Seeking to " + player.media.currentTime + " seconds");
|
||||||
@ -1225,22 +1272,6 @@
|
|||||||
// Handle user exiting fullscreen by escaping etc
|
// Handle user exiting fullscreen by escaping etc
|
||||||
_on(document, fullscreen.fullScreenEventName, _toggleFullscreen);
|
_on(document, fullscreen.fullScreenEventName, _toggleFullscreen);
|
||||||
|
|
||||||
// Click video
|
|
||||||
if(player.type === "video" && config.click) {
|
|
||||||
_on(player.videoContainer, "click", function() {
|
|
||||||
if(player.media.paused) {
|
|
||||||
_play();
|
|
||||||
}
|
|
||||||
else if(player.media.ended) {
|
|
||||||
_seek();
|
|
||||||
_play();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_pause();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Time change on media
|
// Time change on media
|
||||||
_on(player.media, "timeupdate seeking", _timeUpdate);
|
_on(player.media, "timeupdate seeking", _timeUpdate);
|
||||||
|
|
||||||
@ -1251,15 +1282,18 @@
|
|||||||
_on(player.buttons.seek, "change input", _seek);
|
_on(player.buttons.seek, "change input", _seek);
|
||||||
|
|
||||||
// Captions
|
// Captions
|
||||||
_on(player.buttons.captions, "click", function() {
|
_on(player.buttons.captions, "change", function() {
|
||||||
_toggleCaptions(this.checked);
|
_toggleCaptions(this.checked);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Clear captions at end of video
|
// Handle the media finishing
|
||||||
_on(player.media, "ended", function() {
|
_on(player.media, "ended", function() {
|
||||||
|
// Clear
|
||||||
if(player.type === "video") {
|
if(player.type === "video") {
|
||||||
player.captionsContainer.innerHTML = "";
|
player.captionsContainer.innerHTML = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset UI
|
||||||
_checkPlaying();
|
_checkPlaying();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1277,6 +1311,25 @@
|
|||||||
|
|
||||||
// Loading
|
// Loading
|
||||||
_on(player.media, "waiting canplay seeked", _checkLoading);
|
_on(player.media, "waiting canplay seeked", _checkLoading);
|
||||||
|
|
||||||
|
// Toggle checkboxes on return key (as they look like buttons)
|
||||||
|
_on(player.checkboxes, "keyup", _toggleCheckbox);
|
||||||
|
|
||||||
|
// Click video
|
||||||
|
if(player.type === "video" && config.click) {
|
||||||
|
_on(player.videoContainer, "click", function() {
|
||||||
|
if(player.media.paused) {
|
||||||
|
_play();
|
||||||
|
}
|
||||||
|
else if(player.media.ended) {
|
||||||
|
_seek();
|
||||||
|
_play();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_pause();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _init() {
|
function _init() {
|
||||||
@ -1324,9 +1377,14 @@
|
|||||||
|
|
||||||
// Listeners
|
// Listeners
|
||||||
_listeners();
|
_listeners();
|
||||||
|
|
||||||
|
// Successful setup
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_init();
|
if(!_init()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
media: player.media,
|
media: player.media,
|
||||||
@ -1357,7 +1415,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the players
|
// Get the players
|
||||||
var elements = document.querySelectorAll(config.selectors.container), players = [];
|
var elements = document.querySelectorAll(config.selectors.container),
|
||||||
|
players = [];
|
||||||
|
|
||||||
// Create a player instance for each element
|
// Create a player instance for each element
|
||||||
for (var i = elements.length - 1; i >= 0; i--) {
|
for (var i = elements.length - 1; i >= 0; i--) {
|
||||||
@ -1373,7 +1432,11 @@
|
|||||||
|
|
||||||
// Setup a player instance and add to the element
|
// Setup a player instance and add to the element
|
||||||
if(typeof element.plyr === "undefined") {
|
if(typeof element.plyr === "undefined") {
|
||||||
element.plyr = new Plyr(element);
|
// Create new instance
|
||||||
|
var instance = new Plyr(element);
|
||||||
|
|
||||||
|
// Set plyr to false if setup failed
|
||||||
|
element.plyr = (Object.keys(instance).length ? instance : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add to return array
|
// Add to return array
|
||||||
|
@ -524,13 +524,13 @@
|
|||||||
z-index: 10000000;
|
z-index: 10000000;
|
||||||
background: #000;
|
background: #000;
|
||||||
|
|
||||||
|
video {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
.player-video-wrapper {
|
.player-video-wrapper {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
video {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.player-captions {
|
.player-captions {
|
||||||
top: auto;
|
top: auto;
|
||||||
bottom: 90px;
|
bottom: 90px;
|
||||||
|
@ -532,13 +532,13 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
|
|||||||
z-index: 10000000;
|
z-index: 10000000;
|
||||||
background: #000;
|
background: #000;
|
||||||
|
|
||||||
|
video {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
.player-video-wrapper {
|
.player-video-wrapper {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
video {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.player-captions {
|
.player-captions {
|
||||||
top: auto;
|
top: auto;
|
||||||
bottom: 90px;
|
bottom: 90px;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user