Linting changes
This commit is contained in:
parent
5ddd9e02de
commit
c9055f391b
31
.eslintrc
31
.eslintrc
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"parser": "babel-eslint",
|
"parser": "babel-eslint",
|
||||||
"extends": ["airbnb-base", "prettier"],
|
"extends": ["airbnb-base", "prettier"],
|
||||||
|
"plugins": ["simple-import-sort", "import"],
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"es6": true
|
"es6": true
|
||||||
@ -10,24 +11,18 @@
|
|||||||
"jQuery": false
|
"jQuery": false
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"import/no-cycle": 1,
|
"import/no-cycle": "warn",
|
||||||
"no-const-assign": 1,
|
"padding-line-between-statements": [
|
||||||
"no-shadow": 0,
|
"error",
|
||||||
"no-this-before-super": 1,
|
{
|
||||||
"no-undef": 1,
|
"blankLine": "never",
|
||||||
"no-unreachable": 1,
|
"prev": ["singleline-const", "singleline-let", "singleline-var"],
|
||||||
"no-unused-vars": 1,
|
"next": ["singleline-const", "singleline-let", "singleline-var"]
|
||||||
"constructor-super": 1,
|
}
|
||||||
"valid-typeof": 1,
|
],
|
||||||
"indent": [2, 4, { "SwitchCase": 1 }],
|
"sort-imports": "off",
|
||||||
"quotes": [2, "single", "avoid-escape"],
|
"import/order": "off",
|
||||||
"semi": [2, "always"],
|
"simple-import-sort/sort": "error"
|
||||||
"eqeqeq": [2, "always"],
|
|
||||||
"one-var": [2, "never"],
|
|
||||||
"comma-dangle": [2, "always-multiline"],
|
|
||||||
"spaced-comment": [2, "always"],
|
|
||||||
"no-restricted-globals": 2,
|
|
||||||
"no-param-reassign": [2, { "props": false }]
|
|
||||||
},
|
},
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"sourceType": "module"
|
"sourceType": "module"
|
||||||
|
2
demo/dist/demo.css
vendored
2
demo/dist/demo.css
vendored
File diff suppressed because one or more lines are too long
802
demo/dist/demo.js
vendored
802
demo/dist/demo.js
vendored
File diff suppressed because it is too large
Load Diff
2
demo/dist/demo.min.js
vendored
2
demo/dist/demo.min.js
vendored
File diff suppressed because one or more lines are too long
2
demo/dist/demo.min.js.map
vendored
2
demo/dist/demo.min.js.map
vendored
File diff suppressed because one or more lines are too long
@ -50,6 +50,17 @@
|
|||||||
type="font/woff2"
|
type="font/woff2"
|
||||||
href="https://cdn.plyr.io/static/fonts/gordita-bold.woff2"
|
href="https://cdn.plyr.io/static/fonts/gordita-bold.woff2"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- Google Analytics-->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-132699580-1"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag() {
|
||||||
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
gtag('js', new Date());
|
||||||
|
gtag('config', 'UA-132699580-1');
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
import Raven from 'raven-js';
|
import Raven from 'raven-js';
|
||||||
|
|
||||||
import Plyr from '../../../src/js/plyr';
|
import Plyr from '../../../src/js/plyr';
|
||||||
|
|
||||||
(() => {
|
(() => {
|
||||||
|
2
dist/plyr.css
vendored
2
dist/plyr.css
vendored
File diff suppressed because one or more lines are too long
796
dist/plyr.js
vendored
796
dist/plyr.js
vendored
File diff suppressed because it is too large
Load Diff
2
dist/plyr.min.js
vendored
2
dist/plyr.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.min.js.map
vendored
2
dist/plyr.min.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.min.mjs
vendored
2
dist/plyr.min.mjs
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.min.mjs.map
vendored
2
dist/plyr.min.mjs.map
vendored
File diff suppressed because one or more lines are too long
796
dist/plyr.mjs
vendored
796
dist/plyr.mjs
vendored
File diff suppressed because it is too large
Load Diff
1581
dist/plyr.polyfilled.js
vendored
1581
dist/plyr.polyfilled.js
vendored
File diff suppressed because it is too large
Load Diff
2
dist/plyr.polyfilled.min.js
vendored
2
dist/plyr.polyfilled.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.polyfilled.min.js.map
vendored
2
dist/plyr.polyfilled.min.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.polyfilled.min.mjs
vendored
2
dist/plyr.polyfilled.min.mjs
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.polyfilled.min.mjs.map
vendored
2
dist/plyr.polyfilled.min.mjs.map
vendored
File diff suppressed because one or more lines are too long
1581
dist/plyr.polyfilled.mjs
vendored
1581
dist/plyr.polyfilled.mjs
vendored
File diff suppressed because it is too large
Load Diff
24
gulpfile.js
24
gulpfile.js
@ -6,24 +6,28 @@
|
|||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const gulp = require('gulp');
|
const gulp = require('gulp');
|
||||||
|
// ------------------------------------
|
||||||
// JavaScript
|
// JavaScript
|
||||||
|
// ------------------------------------
|
||||||
const terser = require('gulp-terser');
|
const terser = require('gulp-terser');
|
||||||
const rollup = require('gulp-better-rollup');
|
const rollup = require('gulp-better-rollup');
|
||||||
const babel = require('rollup-plugin-babel');
|
const babel = require('rollup-plugin-babel');
|
||||||
const commonjs = require('rollup-plugin-commonjs');
|
const commonjs = require('rollup-plugin-commonjs');
|
||||||
const resolve = require('rollup-plugin-node-resolve');
|
const resolve = require('rollup-plugin-node-resolve');
|
||||||
|
// ------------------------------------
|
||||||
// CSS
|
// CSS
|
||||||
|
// ------------------------------------
|
||||||
const sass = require('gulp-sass');
|
const sass = require('gulp-sass');
|
||||||
const clean = require('gulp-clean-css');
|
const clean = require('gulp-clean-css');
|
||||||
const prefix = require('gulp-autoprefixer');
|
const prefix = require('gulp-autoprefixer');
|
||||||
|
// ------------------------------------
|
||||||
// Images
|
// Images
|
||||||
|
// ------------------------------------
|
||||||
const svgstore = require('gulp-svgstore');
|
const svgstore = require('gulp-svgstore');
|
||||||
const imagemin = require('gulp-imagemin');
|
const imagemin = require('gulp-imagemin');
|
||||||
|
// ------------------------------------
|
||||||
// Utils
|
// Utils
|
||||||
|
// ------------------------------------
|
||||||
const del = require('del');
|
const del = require('del');
|
||||||
const filter = require('gulp-filter');
|
const filter = require('gulp-filter');
|
||||||
const header = require('gulp-header');
|
const header = require('gulp-header');
|
||||||
@ -37,18 +41,22 @@ const plumber = require('gulp-plumber');
|
|||||||
const size = require('gulp-size');
|
const size = require('gulp-size');
|
||||||
const sourcemaps = require('gulp-sourcemaps');
|
const sourcemaps = require('gulp-sourcemaps');
|
||||||
const through = require('through2');
|
const through = require('through2');
|
||||||
|
// ------------------------------------
|
||||||
// Deployment
|
// Deployment
|
||||||
|
// ------------------------------------
|
||||||
const aws = require('aws-sdk');
|
const aws = require('aws-sdk');
|
||||||
const publish = require('gulp-awspublish');
|
const publish = require('gulp-awspublish');
|
||||||
const FastlyPurge = require('fastly-purge');
|
const FastlyPurge = require('fastly-purge');
|
||||||
|
// ------------------------------------
|
||||||
|
// Configs
|
||||||
|
// ------------------------------------
|
||||||
const pkg = require('./package.json');
|
const pkg = require('./package.json');
|
||||||
const build = require('./build.json');
|
const build = require('./build.json');
|
||||||
const deploy = require('./deploy.json');
|
const deploy = require('./deploy.json');
|
||||||
|
// ------------------------------------
|
||||||
|
// Info from package
|
||||||
|
// ------------------------------------
|
||||||
const { browserslist: browsers, version } = pkg;
|
const { browserslist: browsers, version } = pkg;
|
||||||
|
|
||||||
const minSuffix = '.min';
|
const minSuffix = '.min';
|
||||||
|
|
||||||
// Get AWS config
|
// Get AWS config
|
||||||
|
48
package.json
48
package.json
@ -31,31 +31,33 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "gulp build",
|
"build": "gulp build",
|
||||||
"lint": "eslint src/js && npm run-script remark",
|
"lint": "eslint src/js && npm run-script remark",
|
||||||
|
"lint:fix": "eslint --fix src/js",
|
||||||
"remark": "remark -f --use 'validate-links=repository:\"sampotts/plyr\"' '{,!(node_modules),.?**/}*.md'",
|
"remark": "remark -f --use 'validate-links=repository:\"sampotts/plyr\"' '{,!(node_modules),.?**/}*.md'",
|
||||||
"deploy": "yarn lint && gulp deploy"
|
"deploy": "yarn lint && gulp deploy"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"ansi-colors": "^3.2.4",
|
"ansi-colors": "^3.2.4",
|
||||||
"aws-sdk": "^2.437.0",
|
"aws-sdk": "^2.466.0",
|
||||||
"@babel/core": "^7.4.3",
|
"@babel/core": "^7.4.5",
|
||||||
"@babel/preset-env": "^7.4.3",
|
"@babel/preset-env": "^7.4.5",
|
||||||
"babel-eslint": "^10.0.1",
|
"babel-eslint": "^10.0.1",
|
||||||
"del": "^4.1.0",
|
"del": "^4.1.1",
|
||||||
"eslint": "^5.16.0",
|
"eslint": "^5.16.0",
|
||||||
"eslint-config-airbnb-base": "^13.1.0",
|
"eslint-config-airbnb-base": "^13.1.0",
|
||||||
"eslint-config-prettier": "^4.1.0",
|
"eslint-config-prettier": "^4.3.0",
|
||||||
"eslint-plugin-import": "^2.16.0",
|
"eslint-plugin-import": "^2.17.3",
|
||||||
|
"eslint-plugin-simple-import-sort": "^3.1.1",
|
||||||
"fancy-log": "^1.3.3",
|
"fancy-log": "^1.3.3",
|
||||||
"fastly-purge": "^1.0.1",
|
"fastly-purge": "^1.0.1",
|
||||||
"git-branch": "^2.0.1",
|
"git-branch": "^2.0.1",
|
||||||
"gulp": "^4.0.0",
|
"gulp": "^4.0.2",
|
||||||
"gulp-autoprefixer": "^6.0.0",
|
"gulp-autoprefixer": "^6.1.0",
|
||||||
"gulp-awspublish": "^4.0.0",
|
"gulp-awspublish": "^4.0.0",
|
||||||
"gulp-better-rollup": "^4.0.1",
|
"gulp-better-rollup": "^4.0.1",
|
||||||
"gulp-clean-css": "^4.0.0",
|
"gulp-clean-css": "^4.2.0",
|
||||||
"gulp-filter": "^5.1.0",
|
"gulp-filter": "^6.0.0",
|
||||||
"gulp-header": "^2.0.7",
|
"gulp-header": "^2.0.7",
|
||||||
"gulp-imagemin": "^5.0.3",
|
"gulp-imagemin": "^6.0.0",
|
||||||
"gulp-open": "^3.0.1",
|
"gulp-open": "^3.0.1",
|
||||||
"gulp-plumber": "^1.2.1",
|
"gulp-plumber": "^1.2.1",
|
||||||
"gulp-postcss": "^8.0.0",
|
"gulp-postcss": "^8.0.0",
|
||||||
@ -65,31 +67,31 @@
|
|||||||
"gulp-size": "^3.0.0",
|
"gulp-size": "^3.0.0",
|
||||||
"gulp-sourcemaps": "^2.6.5",
|
"gulp-sourcemaps": "^2.6.5",
|
||||||
"gulp-svgstore": "^7.0.1",
|
"gulp-svgstore": "^7.0.1",
|
||||||
"gulp-terser": "^1.1.7",
|
"gulp-terser": "^1.2.0",
|
||||||
"postcss-custom-properties": "^8.0.10",
|
"postcss-custom-properties": "^8.0.10",
|
||||||
"prettier-eslint": "^8.8.2",
|
"prettier-eslint": "^8.8.2",
|
||||||
"prettier-stylelint": "^0.4.2",
|
"prettier-stylelint": "^0.4.2",
|
||||||
"remark-cli": "^6.0.1",
|
"remark-cli": "^6.0.1",
|
||||||
"remark-validate-links": "^8.0.2",
|
"remark-validate-links": "^8.0.2",
|
||||||
"rollup": "^1.10.0",
|
"rollup": "^1.13.0",
|
||||||
"rollup-plugin-babel": "^4.3.2",
|
"rollup-plugin-babel": "^4.3.2",
|
||||||
"rollup-plugin-commonjs": "^9.3.4",
|
"rollup-plugin-commonjs": "^10.0.0",
|
||||||
"rollup-plugin-node-resolve": "^4.2.3",
|
"rollup-plugin-node-resolve": "^5.0.1",
|
||||||
"stylelint": "^9.10.1",
|
"stylelint": "^10.0.1",
|
||||||
"stylelint-config-prettier": "^5.0.0",
|
"stylelint-config-prettier": "^5.2.0",
|
||||||
"stylelint-config-recommended": "^2.1.0",
|
"stylelint-config-recommended": "^2.2.0",
|
||||||
"stylelint-config-sass-guidelines": "^5.4.0",
|
"stylelint-config-sass-guidelines": "^6.0.0",
|
||||||
"stylelint-order": "^2.2.1",
|
"stylelint-order": "^3.0.0",
|
||||||
"stylelint-scss": "^3.5.4",
|
"stylelint-scss": "^3.8.0",
|
||||||
"stylelint-selector-bem-pattern": "^2.1.0",
|
"stylelint-selector-bem-pattern": "^2.1.0",
|
||||||
"through2": "^3.0.1"
|
"through2": "^3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-js": "^3.0.1",
|
"core-js": "^3.1.3",
|
||||||
"custom-event-polyfill": "^1.0.7",
|
"custom-event-polyfill": "^1.0.7",
|
||||||
"loadjs": "^3.6.1",
|
"loadjs": "^3.6.1",
|
||||||
"rangetouch": "^2.0.0",
|
"rangetouch": "^2.0.0",
|
||||||
"raven-js": "^3.27.0",
|
"raven-js": "^3.27.1",
|
||||||
"url-polyfill": "^1.1.5"
|
"url-polyfill": "^1.1.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,6 @@
|
|||||||
"editor.tabSize": 4,
|
"editor.tabSize": 4,
|
||||||
"editor.insertSpaces": true,
|
"editor.insertSpaces": true,
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"editor.codeActionsOnSave": {
|
|
||||||
"source.organizeImports": true
|
|
||||||
},
|
|
||||||
|
|
||||||
// Trim on save
|
// Trim on save
|
||||||
"files.trimTrailingWhitespace": true
|
"files.trimTrailingWhitespace": true
|
||||||
|
@ -123,13 +123,13 @@ See [initialising](#initialising) for more information on advanced setups.
|
|||||||
You can use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript. There's 2 versions; one with and one without [polyfills](#polyfills). My recommendation would be to manage polyfills seperately as part of your application but to make life easier you can use the polyfilled build.
|
You can use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript. There's 2 versions; one with and one without [polyfills](#polyfills). My recommendation would be to manage polyfills seperately as part of your application but to make life easier you can use the polyfilled build.
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script src="https://cdn.plyr.io/3.5.3/plyr.js"></script>
|
<script src="https://cdn.plyr.io/3.5.4/plyr.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
...or...
|
...or...
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script src="https://cdn.plyr.io/3.5.3/plyr.polyfilled.js"></script>
|
<script src="https://cdn.plyr.io/3.5.4/plyr.polyfilled.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
## CSS
|
## CSS
|
||||||
@ -143,13 +143,13 @@ Include the `plyr.css` stylsheet into your `<head>`
|
|||||||
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the default CSS, you can use the following:
|
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the default CSS, you can use the following:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<link rel="stylesheet" href="https://cdn.plyr.io/3.5.3/plyr.css" />
|
<link rel="stylesheet" href="https://cdn.plyr.io/3.5.4/plyr.css" />
|
||||||
```
|
```
|
||||||
|
|
||||||
## SVG Sprite
|
## SVG Sprite
|
||||||
|
|
||||||
The SVG sprite is loaded automatically from our CDN (provided by [Fastly](https://www.fastly.com/)). To change this, see the [options](#options) below. For
|
The SVG sprite is loaded automatically from our CDN (provided by [Fastly](https://www.fastly.com/)). To change this, see the [options](#options) below. For
|
||||||
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.5.3/plyr.svg`.
|
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.5.4/plyr.svg`.
|
||||||
|
|
||||||
# Ads
|
# Ads
|
||||||
|
|
||||||
|
@ -85,7 +85,6 @@ const captions = {
|
|||||||
|
|
||||||
const browserLanguages = navigator.languages || [navigator.language || navigator.userLanguage || 'en'];
|
const browserLanguages = navigator.languages || [navigator.language || navigator.userLanguage || 'en'];
|
||||||
const languages = dedupe(browserLanguages.map(language => language.split('-')[0]));
|
const languages = dedupe(browserLanguages.map(language => language.split('-')[0]));
|
||||||
|
|
||||||
let language = (this.storage.get('language') || this.config.captions.language || 'auto').toLowerCase();
|
let language = (this.storage.get('language') || this.config.captions.language || 'auto').toLowerCase();
|
||||||
|
|
||||||
// Use first browser language when language is 'auto'
|
// Use first browser language when language is 'auto'
|
||||||
@ -134,7 +133,7 @@ const captions = {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Turn off native caption rendering to avoid double captions
|
// Turn off native caption rendering to avoid double captions
|
||||||
track.mode = 'hidden';
|
Object.assign(track, { mode: 'hidden' });
|
||||||
|
|
||||||
// Add event listener for cue changes
|
// Add event listener for cue changes
|
||||||
on.call(this, track, 'cuechange', () => captions.updateCues.call(this));
|
on.call(this, track, 'cuechange', () => captions.updateCues.call(this));
|
||||||
@ -166,7 +165,6 @@ const captions = {
|
|||||||
|
|
||||||
const { toggled } = this.captions; // Current state
|
const { toggled } = this.captions; // Current state
|
||||||
const activeClass = this.config.classNames.captions.active;
|
const activeClass = this.config.classNames.captions.active;
|
||||||
|
|
||||||
// Get the next state
|
// Get the next state
|
||||||
// If the method is called without parameter, toggle based on current value
|
// If the method is called without parameter, toggle based on current value
|
||||||
const active = is.nullOrUndefined(input) ? !toggled : input;
|
const active = is.nullOrUndefined(input) ? !toggled : input;
|
||||||
@ -304,7 +302,7 @@ const captions = {
|
|||||||
let track;
|
let track;
|
||||||
|
|
||||||
languages.every(language => {
|
languages.every(language => {
|
||||||
track = sorted.find(track => track.language === language);
|
track = sorted.find(t => t.language === language);
|
||||||
return !track; // Break iteration if there is a match
|
return !track; // Break iteration if there is a match
|
||||||
});
|
});
|
||||||
|
|
||||||
|
52
src/js/controls.js
vendored
52
src/js/controls.js
vendored
@ -4,13 +4,27 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
import RangeTouch from 'rangetouch';
|
import RangeTouch from 'rangetouch';
|
||||||
|
|
||||||
import captions from './captions';
|
import captions from './captions';
|
||||||
import html5 from './html5';
|
import html5 from './html5';
|
||||||
import support from './support';
|
import support from './support';
|
||||||
import { repaint, transitionEndEvent } from './utils/animation';
|
import { repaint, transitionEndEvent } from './utils/animation';
|
||||||
import { dedupe } from './utils/arrays';
|
import { dedupe } from './utils/arrays';
|
||||||
import browser from './utils/browser';
|
import browser from './utils/browser';
|
||||||
import { createElement, emptyElement, getAttributesFromSelector, getElement, getElements, hasClass, matches, removeElement, setAttributes, setFocus, toggleClass, toggleHidden } from './utils/elements';
|
import {
|
||||||
|
createElement,
|
||||||
|
emptyElement,
|
||||||
|
getAttributesFromSelector,
|
||||||
|
getElement,
|
||||||
|
getElements,
|
||||||
|
hasClass,
|
||||||
|
matches,
|
||||||
|
removeElement,
|
||||||
|
setAttributes,
|
||||||
|
setFocus,
|
||||||
|
toggleClass,
|
||||||
|
toggleHidden,
|
||||||
|
} from './utils/elements';
|
||||||
import { off, on } from './utils/events';
|
import { off, on } from './utils/events';
|
||||||
import i18n from './utils/i18n';
|
import i18n from './utils/i18n';
|
||||||
import is from './utils/is';
|
import is from './utils/is';
|
||||||
@ -92,7 +106,6 @@ const controls = {
|
|||||||
const namespace = 'http://www.w3.org/2000/svg';
|
const namespace = 'http://www.w3.org/2000/svg';
|
||||||
const iconUrl = controls.getIconUrl.call(this);
|
const iconUrl = controls.getIconUrl.call(this);
|
||||||
const iconPath = `${!iconUrl.cors ? iconUrl.url : ''}#${this.config.iconPrefix}`;
|
const iconPath = `${!iconUrl.cors ? iconUrl.url : ''}#${this.config.iconPrefix}`;
|
||||||
|
|
||||||
// Create <svg>
|
// Create <svg>
|
||||||
const icon = document.createElementNS(namespace, 'svg');
|
const icon = document.createElementNS(namespace, 'svg');
|
||||||
setAttributes(
|
setAttributes(
|
||||||
@ -480,15 +493,15 @@ const controls = {
|
|||||||
get() {
|
get() {
|
||||||
return menuItem.getAttribute('aria-checked') === 'true';
|
return menuItem.getAttribute('aria-checked') === 'true';
|
||||||
},
|
},
|
||||||
set(checked) {
|
set(check) {
|
||||||
// Ensure exclusivity
|
// Ensure exclusivity
|
||||||
if (checked) {
|
if (check) {
|
||||||
Array.from(menuItem.parentNode.children)
|
Array.from(menuItem.parentNode.children)
|
||||||
.filter(node => matches(node, '[role="menuitemradio"]'))
|
.filter(node => matches(node, '[role="menuitemradio"]'))
|
||||||
.forEach(node => node.setAttribute('aria-checked', 'false'));
|
.forEach(node => node.setAttribute('aria-checked', 'false'));
|
||||||
}
|
}
|
||||||
|
|
||||||
menuItem.setAttribute('aria-checked', checked ? 'true' : 'false');
|
menuItem.setAttribute('aria-checked', check ? 'true' : 'false');
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -596,17 +609,17 @@ const controls = {
|
|||||||
let value = 0;
|
let value = 0;
|
||||||
|
|
||||||
const setProgress = (target, input) => {
|
const setProgress = (target, input) => {
|
||||||
const value = is.number(input) ? input : 0;
|
const val = is.number(input) ? input : 0;
|
||||||
const progress = is.element(target) ? target : this.elements.display.buffer;
|
const progress = is.element(target) ? target : this.elements.display.buffer;
|
||||||
|
|
||||||
// Update value and label
|
// Update value and label
|
||||||
if (is.element(progress)) {
|
if (is.element(progress)) {
|
||||||
progress.value = value;
|
progress.value = val;
|
||||||
|
|
||||||
// Update text label inside
|
// Update text label inside
|
||||||
const label = progress.getElementsByTagName('span')[0];
|
const label = progress.getElementsByTagName('span')[0];
|
||||||
if (is.element(label)) {
|
if (is.element(label)) {
|
||||||
label.childNodes[0].nodeValue = value;
|
label.childNodes[0].nodeValue = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -688,14 +701,8 @@ const controls = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate percentage
|
|
||||||
let percent = 0;
|
|
||||||
const clientRect = this.elements.progress.getBoundingClientRect();
|
|
||||||
const visible = `${this.config.classNames.tooltip}--visible`;
|
const visible = `${this.config.classNames.tooltip}--visible`;
|
||||||
|
const toggle = show => toggleClass(this.elements.display.seekTooltip, visible, show);
|
||||||
const toggle = toggle => {
|
|
||||||
toggleClass(this.elements.display.seekTooltip, visible, toggle);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Hide on touch
|
// Hide on touch
|
||||||
if (this.touch) {
|
if (this.touch) {
|
||||||
@ -704,6 +711,9 @@ const controls = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Determine percentage, if already visible
|
// Determine percentage, if already visible
|
||||||
|
let percent = 0;
|
||||||
|
const clientRect = this.elements.progress.getBoundingClientRect();
|
||||||
|
|
||||||
if (is.event(event)) {
|
if (is.event(event)) {
|
||||||
percent = (100 / clientRect.width) * (event.pageX - clientRect.left);
|
percent = (100 / clientRect.width) * (event.pageX - clientRect.left);
|
||||||
} else if (hasClass(this.elements.display.seekTooltip, visible)) {
|
} else if (hasClass(this.elements.display.seekTooltip, visible)) {
|
||||||
@ -1100,7 +1110,7 @@ const controls = {
|
|||||||
let target = pane;
|
let target = pane;
|
||||||
|
|
||||||
if (!is.element(target)) {
|
if (!is.element(target)) {
|
||||||
target = Object.values(this.elements.settings.panels).find(pane => !pane.hidden);
|
target = Object.values(this.elements.settings.panels).find(p => !p.hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
const firstItem = target.querySelector('[role^="menuitem"]');
|
const firstItem = target.querySelector('[role^="menuitem"]');
|
||||||
@ -1398,7 +1408,7 @@ const controls = {
|
|||||||
|
|
||||||
// Settings button / menu
|
// Settings button / menu
|
||||||
if (control === 'settings' && !is.empty(this.config.settings)) {
|
if (control === 'settings' && !is.empty(this.config.settings)) {
|
||||||
const control = createElement(
|
const wrapper = createElement(
|
||||||
'div',
|
'div',
|
||||||
extend({}, defaultAttributes, {
|
extend({}, defaultAttributes, {
|
||||||
class: `${defaultAttributes.class} plyr__menu`.trim(),
|
class: `${defaultAttributes.class} plyr__menu`.trim(),
|
||||||
@ -1406,7 +1416,7 @@ const controls = {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
control.appendChild(
|
wrapper.appendChild(
|
||||||
createButton.call(this, 'settings', {
|
createButton.call(this, 'settings', {
|
||||||
'aria-haspopup': true,
|
'aria-haspopup': true,
|
||||||
'aria-controls': `plyr-settings-${data.id}`,
|
'aria-controls': `plyr-settings-${data.id}`,
|
||||||
@ -1546,11 +1556,11 @@ const controls = {
|
|||||||
});
|
});
|
||||||
|
|
||||||
popup.appendChild(inner);
|
popup.appendChild(inner);
|
||||||
control.appendChild(popup);
|
wrapper.appendChild(popup);
|
||||||
container.appendChild(control);
|
container.appendChild(wrapper);
|
||||||
|
|
||||||
this.elements.settings.popup = popup;
|
this.elements.settings.popup = popup;
|
||||||
this.elements.settings.menu = control;
|
this.elements.settings.menu = wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Picture in picture button
|
// Picture in picture button
|
||||||
|
@ -52,7 +52,7 @@ const html5 = {
|
|||||||
get() {
|
get() {
|
||||||
// Get sources
|
// Get sources
|
||||||
const sources = html5.getSources.call(player);
|
const sources = html5.getSources.call(player);
|
||||||
const source = sources.find(source => source.getAttribute('src') === player.source);
|
const source = sources.find(s => s.getAttribute('src') === player.source);
|
||||||
|
|
||||||
// Return size, if match is found
|
// Return size, if match is found
|
||||||
return source && Number(source.getAttribute('size'));
|
return source && Number(source.getAttribute('size'));
|
||||||
@ -60,9 +60,8 @@ const html5 = {
|
|||||||
set(input) {
|
set(input) {
|
||||||
// Get sources
|
// Get sources
|
||||||
const sources = html5.getSources.call(player);
|
const sources = html5.getSources.call(player);
|
||||||
|
|
||||||
// Get first match for requested size
|
// Get first match for requested size
|
||||||
const source = sources.find(source => Number(source.getAttribute('size')) === input);
|
const source = sources.find(s => Number(s.getAttribute('size')) === input);
|
||||||
|
|
||||||
// No matching source found
|
// No matching source found
|
||||||
if (!source) {
|
if (!source) {
|
||||||
|
@ -275,17 +275,16 @@ class Listeners {
|
|||||||
elements.container,
|
elements.container,
|
||||||
'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen',
|
'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen',
|
||||||
event => {
|
event => {
|
||||||
const { controls } = elements;
|
const { controls: controlsElement } = elements;
|
||||||
|
|
||||||
// Remove button states for fullscreen
|
// Remove button states for fullscreen
|
||||||
if (controls && event.type === 'enterfullscreen') {
|
if (controlsElement && event.type === 'enterfullscreen') {
|
||||||
controls.pressed = false;
|
controlsElement.pressed = false;
|
||||||
controls.hover = false;
|
controlsElement.hover = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show, then hide after a timeout unless another control event occurs
|
// Show, then hide after a timeout unless another control event occurs
|
||||||
const show = ['touchstart', 'touchmove', 'mousemove'].includes(event.type);
|
const show = ['touchstart', 'touchmove', 'mousemove'].includes(event.type);
|
||||||
|
|
||||||
let delay = 0;
|
let delay = 0;
|
||||||
|
|
||||||
if (show) {
|
if (show) {
|
||||||
@ -351,7 +350,6 @@ class Listeners {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const isEnter = event.type === 'enterfullscreen';
|
const isEnter = event.type === 'enterfullscreen';
|
||||||
|
|
||||||
// Set the player size when entering fullscreen to viewport size
|
// Set the player size when entering fullscreen to viewport size
|
||||||
const { padding, ratio } = setPlayerSize(isEnter);
|
const { padding, ratio } = setPlayerSize(isEnter);
|
||||||
|
|
||||||
@ -542,7 +540,6 @@ class Listeners {
|
|||||||
controls() {
|
controls() {
|
||||||
const { player } = this;
|
const { player } = this;
|
||||||
const { elements } = player;
|
const { elements } = player;
|
||||||
|
|
||||||
// IE doesn't support input event, so we fallback to change
|
// IE doesn't support input event, so we fallback to change
|
||||||
const inputEvent = browser.isIE ? 'change' : 'input';
|
const inputEvent = browser.isIE ? 'change' : 'input';
|
||||||
|
|
||||||
@ -678,7 +675,6 @@ class Listeners {
|
|||||||
|
|
||||||
// Was playing before?
|
// Was playing before?
|
||||||
const play = seek.hasAttribute(attribute);
|
const play = seek.hasAttribute(attribute);
|
||||||
|
|
||||||
// Done seeking
|
// Done seeking
|
||||||
const done = ['mouseup', 'touchend', 'keyup'].includes(event.type);
|
const done = ['mouseup', 'touchend', 'keyup'].includes(event.type);
|
||||||
|
|
||||||
@ -706,7 +702,6 @@ class Listeners {
|
|||||||
inputEvent,
|
inputEvent,
|
||||||
event => {
|
event => {
|
||||||
const seek = event.currentTarget;
|
const seek = event.currentTarget;
|
||||||
|
|
||||||
// If it exists, use seek-value instead of "value" for consistency with tooltip time (#954)
|
// If it exists, use seek-value instead of "value" for consistency with tooltip time (#954)
|
||||||
let seekTo = seek.getAttribute('seek-value');
|
let seekTo = seek.getAttribute('seek-value');
|
||||||
|
|
||||||
@ -806,7 +801,7 @@ class Listeners {
|
|||||||
|
|
||||||
// Show controls when they receive focus (e.g., when using keyboard tab key)
|
// Show controls when they receive focus (e.g., when using keyboard tab key)
|
||||||
this.bind(elements.controls, 'focusin', () => {
|
this.bind(elements.controls, 'focusin', () => {
|
||||||
const { config, elements, timers } = player;
|
const { config, timers } = player;
|
||||||
|
|
||||||
// Skip transition to prevent focus from scrolling the parent element
|
// Skip transition to prevent focus from scrolling the parent element
|
||||||
toggleClass(elements.controls, config.classNames.noTransition, true);
|
toggleClass(elements.controls, config.classNames.noTransition, true);
|
||||||
@ -837,10 +832,8 @@ class Listeners {
|
|||||||
// Detect "natural" scroll - suppored on OS X Safari only
|
// Detect "natural" scroll - suppored on OS X Safari only
|
||||||
// Other browsers on OS X will be inverted until support improves
|
// Other browsers on OS X will be inverted until support improves
|
||||||
const inverted = event.webkitDirectionInvertedFromDevice;
|
const inverted = event.webkitDirectionInvertedFromDevice;
|
||||||
|
|
||||||
// Get delta from event. Invert if `inverted` is true
|
// Get delta from event. Invert if `inverted` is true
|
||||||
const [x, y] = [event.deltaX, -event.deltaY].map(value => (inverted ? -value : value));
|
const [x, y] = [event.deltaX, -event.deltaY].map(value => (inverted ? -value : value));
|
||||||
|
|
||||||
// Using the biggest delta, normalize to 1 or -1 (or 0 if no delta)
|
// Using the biggest delta, normalize to 1 or -1 (or 0 if no delta)
|
||||||
const direction = Math.sign(Math.abs(x) > Math.abs(y) ? x : y);
|
const direction = Math.sign(Math.abs(x) > Math.abs(y) ? x : y);
|
||||||
|
|
||||||
|
@ -267,7 +267,7 @@ class Ads {
|
|||||||
|
|
||||||
// Advertisement regular events
|
// Advertisement regular events
|
||||||
Object.keys(google.ima.AdEvent.Type).forEach(type => {
|
Object.keys(google.ima.AdEvent.Type).forEach(type => {
|
||||||
this.manager.addEventListener(google.ima.AdEvent.Type[type], event => this.onAdEvent(event));
|
this.manager.addEventListener(google.ima.AdEvent.Type[type], e => this.onAdEvent(e));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Resolve our adsManager
|
// Resolve our adsManager
|
||||||
@ -303,7 +303,6 @@ class Ads {
|
|||||||
*/
|
*/
|
||||||
onAdEvent(event) {
|
onAdEvent(event) {
|
||||||
const { container } = this.player.elements;
|
const { container } = this.player.elements;
|
||||||
|
|
||||||
// Retrieve the ad from the event. Some events (e.g. ALL_ADS_COMPLETED)
|
// Retrieve the ad from the event. Some events (e.g. ALL_ADS_COMPLETED)
|
||||||
// don't have ad object associated
|
// don't have ad object associated
|
||||||
const ad = event.getAd();
|
const ad = event.getAd();
|
||||||
@ -311,8 +310,7 @@ class Ads {
|
|||||||
|
|
||||||
// Proxy event
|
// Proxy event
|
||||||
const dispatchEvent = type => {
|
const dispatchEvent = type => {
|
||||||
const event = `ads${type.replace(/_/g, '').toLowerCase()}`;
|
triggerEvent.call(this.player, this.player.media, `ads${type.replace(/_/g, '').toLowerCase()}`);
|
||||||
triggerEvent.call(this.player, this.player.media, event);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Bubble the event
|
// Bubble the event
|
||||||
|
@ -2,6 +2,7 @@ import { createElement } from '../utils/elements';
|
|||||||
import { once } from '../utils/events';
|
import { once } from '../utils/events';
|
||||||
import fetch from '../utils/fetch';
|
import fetch from '../utils/fetch';
|
||||||
import is from '../utils/is';
|
import is from '../utils/is';
|
||||||
|
import { extend } from '../utils/objects';
|
||||||
import { formatTime } from '../utils/time';
|
import { formatTime } from '../utils/time';
|
||||||
|
|
||||||
// Arg: vttDataString example: "WEBVTT\n\n1\n00:00:05.000 --> 00:00:10.000\n1080p-00001.jpg"
|
// Arg: vttDataString example: "WEBVTT\n\n1\n00:00:05.000 --> 00:00:10.000\n1080p-00001.jpg"
|
||||||
@ -121,7 +122,6 @@ class PreviewThumbnails {
|
|||||||
|
|
||||||
// If string, convert into single-element list
|
// If string, convert into single-element list
|
||||||
const urls = is.string(src) ? [src] : src;
|
const urls = is.string(src) ? [src] : src;
|
||||||
|
|
||||||
// Loop through each src URL. Download and process the VTT file, storing the resulting data in this.thumbnails
|
// Loop through each src URL. Download and process the VTT file, storing the resulting data in this.thumbnails
|
||||||
const promises = urls.map(u => this.getThumbnail(u));
|
const promises = urls.map(u => this.getThumbnail(u));
|
||||||
|
|
||||||
@ -426,7 +426,7 @@ class PreviewThumbnails {
|
|||||||
if (image.dataset.index !== currentImage.dataset.index && !image.dataset.deleting) {
|
if (image.dataset.index !== currentImage.dataset.index && !image.dataset.deleting) {
|
||||||
// Wait 200ms, as the new image can take some time to show on certain browsers (even though it was downloaded before showing). This will prevent flicker, and show some generosity towards slower clients
|
// Wait 200ms, as the new image can take some time to show on certain browsers (even though it was downloaded before showing). This will prevent flicker, and show some generosity towards slower clients
|
||||||
// First set attribute 'deleting' to prevent multi-handling of this on repeat firing of this function
|
// First set attribute 'deleting' to prevent multi-handling of this on repeat firing of this function
|
||||||
image.dataset.deleting = true;
|
extend(image, { dataset: { deleting: true } });
|
||||||
// This has to be set before the timeout - to prevent issues switching between hover and scrub
|
// This has to be set before the timeout - to prevent issues switching between hover and scrub
|
||||||
const { currentImageContainer } = this;
|
const { currentImageContainer } = this;
|
||||||
|
|
||||||
@ -467,7 +467,6 @@ class PreviewThumbnails {
|
|||||||
|
|
||||||
const { urlPrefix } = this.thumbnails[0];
|
const { urlPrefix } = this.thumbnails[0];
|
||||||
const thumbURL = urlPrefix + newThumbFilename;
|
const thumbURL = urlPrefix + newThumbFilename;
|
||||||
|
|
||||||
const previewImage = new Image();
|
const previewImage = new Image();
|
||||||
previewImage.src = thumbURL;
|
previewImage.src = thumbURL;
|
||||||
previewImage.onload = () => {
|
previewImage.onload = () => {
|
||||||
@ -601,11 +600,9 @@ class PreviewThumbnails {
|
|||||||
const seekbarRect = this.player.elements.progress.getBoundingClientRect();
|
const seekbarRect = this.player.elements.progress.getBoundingClientRect();
|
||||||
const plyrRect = this.player.elements.container.getBoundingClientRect();
|
const plyrRect = this.player.elements.container.getBoundingClientRect();
|
||||||
const { container } = this.elements.thumb;
|
const { container } = this.elements.thumb;
|
||||||
|
|
||||||
// Find the lowest and highest desired left-position, so we don't slide out the side of the video container
|
// Find the lowest and highest desired left-position, so we don't slide out the side of the video container
|
||||||
const minVal = plyrRect.left - seekbarRect.left + 10;
|
const minVal = plyrRect.left - seekbarRect.left + 10;
|
||||||
const maxVal = plyrRect.right - seekbarRect.left - container.clientWidth - 10;
|
const maxVal = plyrRect.right - seekbarRect.left - container.clientWidth - 10;
|
||||||
|
|
||||||
// Set preview container position to: mousepos, minus seekbar.left, minus half of previewContainer.clientWidth
|
// Set preview container position to: mousepos, minus seekbar.left, minus half of previewContainer.clientWidth
|
||||||
let previewPos = this.mousePosX - seekbarRect.left - container.clientWidth / 2;
|
let previewPos = this.mousePosX - seekbarRect.left - container.clientWidth / 2;
|
||||||
|
|
||||||
@ -636,9 +633,13 @@ class PreviewThumbnails {
|
|||||||
// Find difference between height and preview container height
|
// Find difference between height and preview container height
|
||||||
const multiplier = this.thumbContainerHeight / frame.h;
|
const multiplier = this.thumbContainerHeight / frame.h;
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
previewImage.style.height = `${Math.floor(previewImage.naturalHeight * multiplier)}px`;
|
previewImage.style.height = `${Math.floor(previewImage.naturalHeight * multiplier)}px`;
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
previewImage.style.width = `${Math.floor(previewImage.naturalWidth * multiplier)}px`;
|
previewImage.style.width = `${Math.floor(previewImage.naturalWidth * multiplier)}px`;
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
previewImage.style.left = `-${frame.x * multiplier}px`;
|
previewImage.style.left = `-${frame.x * multiplier}px`;
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
previewImage.style.top = `-${frame.y * multiplier}px`;
|
previewImage.style.top = `-${frame.y * multiplier}px`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,6 @@ const vimeo = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const id = parseId(source);
|
const id = parseId(source);
|
||||||
|
|
||||||
// Build an iframe
|
// Build an iframe
|
||||||
const iframe = createElement('iframe');
|
const iframe = createElement('iframe');
|
||||||
const src = format(player.config.urls.vimeo.iframe, id, params);
|
const src = format(player.config.urls.vimeo.iframe, id, params);
|
||||||
@ -102,7 +101,6 @@ const vimeo = {
|
|||||||
|
|
||||||
// Get poster, if already set
|
// Get poster, if already set
|
||||||
const { poster } = player;
|
const { poster } = player;
|
||||||
|
|
||||||
// Inject the package
|
// Inject the package
|
||||||
const wrapper = createElement('div', { poster, class: player.config.classNames.embedContainer });
|
const wrapper = createElement('div', { poster, class: player.config.classNames.embedContainer });
|
||||||
wrapper.appendChild(iframe);
|
wrapper.appendChild(iframe);
|
||||||
|
@ -107,7 +107,6 @@ const youtube = {
|
|||||||
// API ready
|
// API ready
|
||||||
ready() {
|
ready() {
|
||||||
const player = this;
|
const player = this;
|
||||||
|
|
||||||
// Ignore already setup (race condition)
|
// Ignore already setup (race condition)
|
||||||
const currentId = player.media.getAttribute('id');
|
const currentId = player.media.getAttribute('id');
|
||||||
if (!is.empty(currentId) && currentId.startsWith('youtube-')) {
|
if (!is.empty(currentId) && currentId.startsWith('youtube-')) {
|
||||||
@ -125,25 +124,23 @@ const youtube = {
|
|||||||
// Replace the <iframe> with a <div> due to YouTube API issues
|
// Replace the <iframe> with a <div> due to YouTube API issues
|
||||||
const videoId = parseId(source);
|
const videoId = parseId(source);
|
||||||
const id = generateId(player.provider);
|
const id = generateId(player.provider);
|
||||||
|
|
||||||
// Get poster, if already set
|
// Get poster, if already set
|
||||||
const { poster } = player;
|
const { poster } = player;
|
||||||
|
|
||||||
// Replace media element
|
// Replace media element
|
||||||
const container = createElement('div', { id, poster });
|
const container = createElement('div', { id, poster });
|
||||||
player.media = replaceElement(container, player.media);
|
player.media = replaceElement(container, player.media);
|
||||||
|
|
||||||
// Id to poster wrapper
|
// Id to poster wrapper
|
||||||
const posterSrc = format => `https://i.ytimg.com/vi/${videoId}/${format}default.jpg`;
|
const posterSrc = s => `https://i.ytimg.com/vi/${videoId}/${s}default.jpg`;
|
||||||
|
|
||||||
// Check thumbnail images in order of quality, but reject fallback thumbnails (120px wide)
|
// Check thumbnail images in order of quality, but reject fallback thumbnails (120px wide)
|
||||||
loadImage(posterSrc('maxres'), 121) // Higest quality and unpadded
|
loadImage(posterSrc('maxres'), 121) // Higest quality and unpadded
|
||||||
.catch(() => loadImage(posterSrc('sd'), 121)) // 480p padded 4:3
|
.catch(() => loadImage(posterSrc('sd'), 121)) // 480p padded 4:3
|
||||||
.catch(() => loadImage(posterSrc('hq'))) // 360p padded 4:3. Always exists
|
.catch(() => loadImage(posterSrc('hq'))) // 360p padded 4:3. Always exists
|
||||||
.then(image => ui.setPoster.call(player, image.src))
|
.then(image => ui.setPoster.call(player, image.src))
|
||||||
.then(posterSrc => {
|
.then(src => {
|
||||||
// If the image is padded, use background-size "cover" instead (like youtube does too with their posters)
|
// If the image is padded, use background-size "cover" instead (like youtube does too with their posters)
|
||||||
if (!posterSrc.includes('maxres')) {
|
if (!src.includes('maxres')) {
|
||||||
player.elements.poster.style.backgroundSize = 'cover';
|
player.elements.poster.style.backgroundSize = 'cover';
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -151,7 +151,6 @@ class Plyr {
|
|||||||
// Set media type based on tag or data attribute
|
// Set media type based on tag or data attribute
|
||||||
// Supported: video, audio, vimeo, youtube
|
// Supported: video, audio, vimeo, youtube
|
||||||
const type = this.media.tagName.toLowerCase();
|
const type = this.media.tagName.toLowerCase();
|
||||||
|
|
||||||
// Embed properties
|
// Embed properties
|
||||||
let iframe = null;
|
let iframe = null;
|
||||||
let url = null;
|
let url = null;
|
||||||
@ -324,27 +323,27 @@ class Plyr {
|
|||||||
* Types and provider helpers
|
* Types and provider helpers
|
||||||
*/
|
*/
|
||||||
get isHTML5() {
|
get isHTML5() {
|
||||||
return Boolean(this.provider === providers.html5);
|
return this.provider === providers.html5;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isEmbed() {
|
get isEmbed() {
|
||||||
return Boolean(this.isYouTube || this.isVimeo);
|
return this.isYouTube || this.isVimeo;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isYouTube() {
|
get isYouTube() {
|
||||||
return Boolean(this.provider === providers.youtube);
|
return this.provider === providers.youtube;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isVimeo() {
|
get isVimeo() {
|
||||||
return Boolean(this.provider === providers.vimeo);
|
return this.provider === providers.vimeo;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isVideo() {
|
get isVideo() {
|
||||||
return Boolean(this.type === types.video);
|
return this.type === types.video;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isAudio() {
|
get isAudio() {
|
||||||
return Boolean(this.type === types.audio);
|
return this.type === types.audio;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -514,7 +513,6 @@ class Plyr {
|
|||||||
get duration() {
|
get duration() {
|
||||||
// Faux duration set via config
|
// Faux duration set via config
|
||||||
const fauxDuration = parseFloat(this.config.duration);
|
const fauxDuration = parseFloat(this.config.duration);
|
||||||
|
|
||||||
// Media duration can be NaN or Infinity before the media has loaded
|
// Media duration can be NaN or Infinity before the media has loaded
|
||||||
const realDuration = (this.media || {}).duration;
|
const realDuration = (this.media || {}).duration;
|
||||||
const duration = !is.number(realDuration) || realDuration === Infinity ? 0 : realDuration;
|
const duration = !is.number(realDuration) || realDuration === Infinity ? 0 : realDuration;
|
||||||
@ -1045,10 +1043,8 @@ class Plyr {
|
|||||||
if (this.supported.ui && !this.isAudio) {
|
if (this.supported.ui && !this.isAudio) {
|
||||||
// Get state before change
|
// Get state before change
|
||||||
const isHidden = hasClass(this.elements.container, this.config.classNames.hideControls);
|
const isHidden = hasClass(this.elements.container, this.config.classNames.hideControls);
|
||||||
|
|
||||||
// Negate the argument if not undefined since adding the class to hides the controls
|
// Negate the argument if not undefined since adding the class to hides the controls
|
||||||
const force = typeof toggle === 'undefined' ? undefined : !toggle;
|
const force = typeof toggle === 'undefined' ? undefined : !toggle;
|
||||||
|
|
||||||
// Apply and get updated state
|
// Apply and get updated state
|
||||||
const hiding = toggleClass(this.elements.container, this.config.classNames.hideControls, force);
|
const hiding = toggleClass(this.elements.container, this.config.classNames.hideControls, force);
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
import 'custom-event-polyfill';
|
import 'custom-event-polyfill';
|
||||||
import 'url-polyfill';
|
import 'url-polyfill';
|
||||||
|
|
||||||
import Plyr from './plyr';
|
import Plyr from './plyr';
|
||||||
|
|
||||||
export default Plyr;
|
export default Plyr;
|
||||||
|
15
src/js/ui.js
15
src/js/ui.js
@ -213,7 +213,7 @@ const ui = {
|
|||||||
|
|
||||||
// Set state
|
// Set state
|
||||||
Array.from(this.elements.buttons.play || []).forEach(target => {
|
Array.from(this.elements.buttons.play || []).forEach(target => {
|
||||||
target.pressed = this.playing;
|
Object.assign(target, { pressed: this.playing });
|
||||||
});
|
});
|
||||||
|
|
||||||
// Only update controls on non timeupdate events
|
// Only update controls on non timeupdate events
|
||||||
@ -247,15 +247,22 @@ const ui = {
|
|||||||
|
|
||||||
// Toggle controls based on state and `force` argument
|
// Toggle controls based on state and `force` argument
|
||||||
toggleControls(force) {
|
toggleControls(force) {
|
||||||
const { controls } = this.elements;
|
const { controls: controlsElement } = this.elements;
|
||||||
|
|
||||||
if (controls && this.config.hideControls) {
|
if (controlsElement && this.config.hideControls) {
|
||||||
// Don't hide controls if a touch-device user recently seeked. (Must be limited to touch devices, or it occasionally prevents desktop controls from hiding.)
|
// Don't hide controls if a touch-device user recently seeked. (Must be limited to touch devices, or it occasionally prevents desktop controls from hiding.)
|
||||||
const recentTouchSeek = this.touch && this.lastSeekTime + 2000 > Date.now();
|
const recentTouchSeek = this.touch && this.lastSeekTime + 2000 > Date.now();
|
||||||
|
|
||||||
// Show controls if force, loading, paused, button interaction, or recent seek, otherwise hide
|
// Show controls if force, loading, paused, button interaction, or recent seek, otherwise hide
|
||||||
this.toggleControls(
|
this.toggleControls(
|
||||||
Boolean(force || this.loading || this.paused || controls.pressed || controls.hover || recentTouchSeek),
|
Boolean(
|
||||||
|
force ||
|
||||||
|
this.loading ||
|
||||||
|
this.paused ||
|
||||||
|
controlsElement.pressed ||
|
||||||
|
controlsElement.hover ||
|
||||||
|
recentTouchSeek,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -17,7 +17,6 @@ export function wrap(elements, wrapper) {
|
|||||||
.reverse()
|
.reverse()
|
||||||
.forEach((element, index) => {
|
.forEach((element, index) => {
|
||||||
const child = index > 0 ? wrapper.cloneNode(true) : wrapper;
|
const child = index > 0 ? wrapper.cloneNode(true) : wrapper;
|
||||||
|
|
||||||
// Cache the current parent and sibling.
|
// Cache the current parent and sibling.
|
||||||
const parent = element.parentNode;
|
const parent = element.parentNode;
|
||||||
const sibling = element.nextSibling;
|
const sibling = element.nextSibling;
|
||||||
@ -145,12 +144,10 @@ export function getAttributesFromSelector(sel, existingAttributes) {
|
|||||||
const selector = s.trim();
|
const selector = s.trim();
|
||||||
const className = selector.replace('.', '');
|
const className = selector.replace('.', '');
|
||||||
const stripped = selector.replace(/[[\]]/g, '');
|
const stripped = selector.replace(/[[\]]/g, '');
|
||||||
|
|
||||||
// Get the parts and value
|
// Get the parts and value
|
||||||
const parts = stripped.split('=');
|
const parts = stripped.split('=');
|
||||||
const [key] = parts;
|
const [key] = parts;
|
||||||
const value = parts.length > 1 ? parts[1].replace(/["']/g, '') : '';
|
const value = parts.length > 1 ? parts[1].replace(/["']/g, '') : '';
|
||||||
|
|
||||||
// Get the first character
|
// Get the first character
|
||||||
const start = selector.charAt(0);
|
const start = selector.charAt(0);
|
||||||
|
|
||||||
@ -234,14 +231,14 @@ export function matches(element, selector) {
|
|||||||
return Array.from(document.querySelectorAll(selector)).includes(this);
|
return Array.from(document.querySelectorAll(selector)).includes(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
const matches =
|
const method =
|
||||||
prototype.matches ||
|
prototype.matches ||
|
||||||
prototype.webkitMatchesSelector ||
|
prototype.webkitMatchesSelector ||
|
||||||
prototype.mozMatchesSelector ||
|
prototype.mozMatchesSelector ||
|
||||||
prototype.msMatchesSelector ||
|
prototype.msMatchesSelector ||
|
||||||
match;
|
match;
|
||||||
|
|
||||||
return matches.call(element, selector);
|
return method.call(element, selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find all elements
|
// Find all elements
|
||||||
|
@ -35,7 +35,6 @@ export function toggleListener(element, event, callback, toggle = false, passive
|
|||||||
|
|
||||||
// Allow multiple events
|
// Allow multiple events
|
||||||
const events = event.split(' ');
|
const events = event.split(' ');
|
||||||
|
|
||||||
// Build options
|
// Build options
|
||||||
// Default to just the capture boolean for browsers with no passive listener support
|
// Default to just the capture boolean for browsers with no passive listener support
|
||||||
let options = capture;
|
let options = capture;
|
||||||
|
@ -36,8 +36,8 @@ const i18n = {
|
|||||||
'{title}': config.title,
|
'{title}': config.title,
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.entries(replace).forEach(([key, value]) => {
|
Object.entries(replace).forEach(([k, v]) => {
|
||||||
string = replaceAll(string, key, value);
|
string = replaceAll(string, k, v);
|
||||||
});
|
});
|
||||||
|
|
||||||
return string;
|
return string;
|
||||||
|
@ -15,10 +15,10 @@ export default function loadSprite(url, id) {
|
|||||||
const prefix = 'cache';
|
const prefix = 'cache';
|
||||||
const hasId = is.string(id);
|
const hasId = is.string(id);
|
||||||
let isCached = false;
|
let isCached = false;
|
||||||
|
|
||||||
const exists = () => document.getElementById(id) !== null;
|
const exists = () => document.getElementById(id) !== null;
|
||||||
|
|
||||||
const update = (container, data) => {
|
const update = (container, data) => {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
container.innerHTML = data;
|
container.innerHTML = data;
|
||||||
|
|
||||||
// Check again incase of race condition
|
// Check again incase of race condition
|
||||||
@ -33,7 +33,6 @@ export default function loadSprite(url, id) {
|
|||||||
// Only load once if ID set
|
// Only load once if ID set
|
||||||
if (!hasId || !exists()) {
|
if (!hasId || !exists()) {
|
||||||
const useStorage = Storage.supported;
|
const useStorage = Storage.supported;
|
||||||
|
|
||||||
// Create container
|
// Create container
|
||||||
const container = document.createElement('div');
|
const container = document.createElement('div');
|
||||||
container.setAttribute('hidden', '');
|
container.setAttribute('hidden', '');
|
||||||
|
@ -64,7 +64,6 @@ export function setAspectRatio(input) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ratio = getAspectRatio.call(this, input);
|
const ratio = getAspectRatio.call(this, input);
|
||||||
|
|
||||||
const [w, h] = is.array(ratio) ? ratio : [0, 0];
|
const [w, h] = is.array(ratio) ? ratio : [0, 0];
|
||||||
const padding = (100 / w) * h;
|
const padding = (100 / w) * h;
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ export function formatTime(time = 0, displayHours = false, inverted = false) {
|
|||||||
|
|
||||||
// Format time component to add leading zero
|
// Format time component to add leading zero
|
||||||
const format = value => `0${value}`.slice(-2);
|
const format = value => `0${value}`.slice(-2);
|
||||||
|
|
||||||
// Breakdown to hours, mins, secs
|
// Breakdown to hours, mins, secs
|
||||||
let hours = getHours(time);
|
let hours = getHours(time);
|
||||||
const mins = getMinutes(time);
|
const mins = getMinutes(time);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user