Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ba236c4753 | |||
| a204f7c1dd | |||
| bacf9122de | |||
| 2fdc1eac94 | |||
| 5fd4391cd9 | |||
| 6991358428 | |||
| b050fde276 |
@@ -1,3 +1,9 @@
|
|||||||
|
### v3.6.8
|
||||||
|
|
||||||
|
- Typings: add FullscreenOptions.container to typing files (thanks @MeguminSama!)
|
||||||
|
- Fix: added iPadOS detection to isIos util (thanks @Benny739!)
|
||||||
|
- Fix: issues with Vimeo fullscreen
|
||||||
|
|
||||||
### v3.6.7
|
### v3.6.7
|
||||||
|
|
||||||
- Fix: remove regression caused by optional chaining and nullish coalescing in check for `window.CSS` check for aspect-ratio (fixes #2174)
|
- Fix: remove regression caused by optional chaining and nullish coalescing in check for `window.CSS` check for aspect-ratio (fixes #2174)
|
||||||
|
|||||||
@@ -134,13 +134,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.6.7/plyr.js"></script>
|
<script src="https://cdn.plyr.io/3.6.8/plyr.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
...or...
|
...or...
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script src="https://cdn.plyr.io/3.6.7/plyr.polyfilled.js"></script>
|
<script src="https://cdn.plyr.io/3.6.8/plyr.polyfilled.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
## CSS
|
## CSS
|
||||||
@@ -154,13 +154,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.6.7/plyr.css" />
|
<link rel="stylesheet" href="https://cdn.plyr.io/3.6.8/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.6.7/plyr.svg`.
|
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.6.8/plyr.svg`.
|
||||||
|
|
||||||
# Ads
|
# Ads
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "plyr",
|
"name": "plyr",
|
||||||
"version": "3.6.7",
|
"version": "3.6.8",
|
||||||
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
|
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
|
||||||
"homepage": "https://plyr.io",
|
"homepage": "https://plyr.io",
|
||||||
"author": "Sam Potts <sam@potts.es>",
|
"author": "Sam Potts <sam@potts.es>",
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ const defaults = {
|
|||||||
// Sprite (for icons)
|
// Sprite (for icons)
|
||||||
loadSprite: true,
|
loadSprite: true,
|
||||||
iconPrefix: 'plyr',
|
iconPrefix: 'plyr',
|
||||||
iconUrl: 'https://cdn.plyr.io/3.6.7/plyr.svg',
|
iconUrl: 'https://cdn.plyr.io/3.6.8/plyr.svg',
|
||||||
|
|
||||||
// Blank video (used to prevent errors on source change)
|
// Blank video (used to prevent errors on source change)
|
||||||
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
||||||
|
|||||||
+41
-45
@@ -10,7 +10,7 @@ import { getElement, getElements, matches, toggleClass } from './utils/elements'
|
|||||||
import { off, on, once, toggleListener, triggerEvent } from './utils/events';
|
import { off, on, once, toggleListener, triggerEvent } from './utils/events';
|
||||||
import is from './utils/is';
|
import is from './utils/is';
|
||||||
import { silencePromise } from './utils/promise';
|
import { silencePromise } from './utils/promise';
|
||||||
import { getAspectRatio, setAspectRatio } from './utils/style';
|
import { getAspectRatio, getViewportSize, supportsCSS } from './utils/style';
|
||||||
|
|
||||||
class Listeners {
|
class Listeners {
|
||||||
constructor(player) {
|
constructor(player) {
|
||||||
@@ -149,16 +149,16 @@ class Listeners {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* case 73:
|
/* case 73:
|
||||||
this.setLoop('start');
|
this.setLoop('start');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 76:
|
case 76:
|
||||||
this.setLoop();
|
this.setLoop();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 79:
|
case 79:
|
||||||
this.setLoop('end');
|
this.setLoop('end');
|
||||||
break; */
|
break; */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -305,39 +305,49 @@ class Listeners {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Set a gutter for Vimeo
|
// Set a gutter for Vimeo
|
||||||
const setGutter = (ratio, padding, toggle) => {
|
const setGutter = () => {
|
||||||
if (!player.isVimeo || player.config.vimeo.premium) {
|
if (!player.isVimeo || player.config.vimeo.premium) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const target = player.elements.wrapper.firstChild;
|
const target = elements.wrapper;
|
||||||
const [, y] = ratio;
|
const { active } = player.fullscreen;
|
||||||
const [videoX, videoY] = getAspectRatio.call(player);
|
const [videoWidth, videoHeight] = getAspectRatio.call(player);
|
||||||
|
const useNativeAspectRatio = supportsCSS(`aspect-ratio: ${videoWidth} / ${videoHeight}`);
|
||||||
|
|
||||||
target.style.maxWidth = toggle ? `${(y / videoY) * videoX}px` : null;
|
// If not active, remove styles
|
||||||
target.style.margin = toggle ? '0 auto' : null;
|
if (!active) {
|
||||||
};
|
if (useNativeAspectRatio) {
|
||||||
|
target.style.width = null;
|
||||||
// Resize on fullscreen change
|
target.style.height = null;
|
||||||
const setPlayerSize = (measure) => {
|
} else {
|
||||||
// If we don't need to measure the viewport
|
target.style.maxWidth = null;
|
||||||
if (!measure) {
|
target.style.margin = null;
|
||||||
return setAspectRatio.call(player);
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rect = elements.container.getBoundingClientRect();
|
// Determine which dimension will overflow and constrain view
|
||||||
const { width, height } = rect;
|
const [viewportWidth, viewportHeight] = getViewportSize();
|
||||||
|
const overflow = viewportWidth / viewportHeight > videoWidth / videoHeight;
|
||||||
|
|
||||||
return setAspectRatio.call(player, `${width}:${height}`);
|
if (useNativeAspectRatio) {
|
||||||
|
target.style.width = overflow ? 'auto' : '100%';
|
||||||
|
target.style.height = overflow ? '100%' : 'auto';
|
||||||
|
} else {
|
||||||
|
target.style.maxWidth = overflow ? `${(viewportHeight / videoHeight) * videoWidth}px` : null;
|
||||||
|
target.style.margin = overflow ? '0 auto' : null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Handle resizing
|
||||||
const resized = () => {
|
const resized = () => {
|
||||||
clearTimeout(timers.resized);
|
clearTimeout(timers.resized);
|
||||||
timers.resized = setTimeout(setPlayerSize, 50);
|
timers.resized = setTimeout(setGutter, 50);
|
||||||
};
|
};
|
||||||
|
|
||||||
on.call(player, elements.container, 'enterfullscreen exitfullscreen', (event) => {
|
on.call(player, elements.container, 'enterfullscreen exitfullscreen', (event) => {
|
||||||
const { target, usingNative } = player.fullscreen;
|
const { target } = player.fullscreen;
|
||||||
|
|
||||||
// Ignore events not from target
|
// Ignore events not from target
|
||||||
if (target !== elements.container) {
|
if (target !== elements.container) {
|
||||||
@@ -349,26 +359,12 @@ class Listeners {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isEnter = event.type === 'enterfullscreen';
|
|
||||||
// Set the player size when entering fullscreen to viewport size
|
|
||||||
const { padding, ratio } = setPlayerSize(isEnter);
|
|
||||||
|
|
||||||
// Set Vimeo gutter
|
// Set Vimeo gutter
|
||||||
setGutter(ratio, padding, isEnter);
|
setGutter();
|
||||||
|
|
||||||
// Horrible hack for Safari 14 not repainting properly on entering fullscreen
|
// Watch for resizes
|
||||||
if (isEnter) {
|
const method = event.type === 'enterfullscreen' ? on : off;
|
||||||
setTimeout(() => repaint(elements.container), 100);
|
method.call(player, window, 'resize', resized);
|
||||||
}
|
|
||||||
|
|
||||||
// If not using native browser fullscreen API, we need to check for resizes of viewport
|
|
||||||
if (!usingNative) {
|
|
||||||
if (isEnter) {
|
|
||||||
on.call(player, window, 'resize', resized);
|
|
||||||
} else {
|
|
||||||
off.call(player, window, 'resize', resized);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
@@ -549,6 +549,7 @@ declare namespace Plyr {
|
|||||||
fallback?: boolean | 'force';
|
fallback?: boolean | 'force';
|
||||||
allowAudio?: boolean;
|
allowAudio?: boolean;
|
||||||
iosNative?: boolean;
|
iosNative?: boolean;
|
||||||
|
container?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CaptionOptions {
|
interface CaptionOptions {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Plyr
|
// Plyr
|
||||||
// plyr.js v3.6.7
|
// plyr.js v3.6.8
|
||||||
// https://github.com/sampotts/plyr
|
// https://github.com/sampotts/plyr
|
||||||
// License: The MIT License (MIT)
|
// License: The MIT License (MIT)
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Plyr Polyfilled Build
|
// Plyr Polyfilled Build
|
||||||
// plyr.js v3.6.7
|
// plyr.js v3.6.8
|
||||||
// https://github.com/sampotts/plyr
|
// https://github.com/sampotts/plyr
|
||||||
// License: The MIT License (MIT)
|
// License: The MIT License (MIT)
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ const browser = {
|
|||||||
isEdge: window.navigator.userAgent.includes('Edge'),
|
isEdge: window.navigator.userAgent.includes('Edge'),
|
||||||
isWebkit: 'WebkitAppearance' in document.documentElement.style && !/Edge/.test(navigator.userAgent),
|
isWebkit: 'WebkitAppearance' in document.documentElement.style && !/Edge/.test(navigator.userAgent),
|
||||||
isIPhone: /(iPhone|iPod)/gi.test(navigator.platform),
|
isIPhone: /(iPhone|iPod)/gi.test(navigator.platform),
|
||||||
isIos: /(iPad|iPhone|iPod)/gi.test(navigator.platform),
|
isIos:
|
||||||
|
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1) ||
|
||||||
|
/(iPad|iPhone|iPod)/gi.test(navigator.platform),
|
||||||
};
|
};
|
||||||
|
|
||||||
export default browser;
|
export default browser;
|
||||||
|
|||||||
+21
-6
@@ -5,6 +5,15 @@
|
|||||||
import { closest } from './arrays';
|
import { closest } from './arrays';
|
||||||
import is from './is';
|
import is from './is';
|
||||||
|
|
||||||
|
// Check support for a CSS declaration
|
||||||
|
export function supportsCSS(declaration) {
|
||||||
|
if (!window || !window.CSS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return window.CSS.supports(declaration);
|
||||||
|
}
|
||||||
|
|
||||||
// Standard/common aspect ratios
|
// Standard/common aspect ratios
|
||||||
const standardRatios = [
|
const standardRatios = [
|
||||||
[1, 1],
|
[1, 1],
|
||||||
@@ -67,10 +76,10 @@ export function getAspectRatio(input) {
|
|||||||
// Get from HTML5 video
|
// Get from HTML5 video
|
||||||
if (ratio === null && this.isHTML5) {
|
if (ratio === null && this.isHTML5) {
|
||||||
const { videoWidth, videoHeight } = this.media;
|
const { videoWidth, videoHeight } = this.media;
|
||||||
ratio = reduceAspectRatio([videoWidth, videoHeight]);
|
ratio = [videoWidth, videoHeight];
|
||||||
}
|
}
|
||||||
|
|
||||||
return ratio;
|
return reduceAspectRatio(ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set aspect ratio for responsive container
|
// Set aspect ratio for responsive container
|
||||||
@@ -86,8 +95,8 @@ export function setAspectRatio(input) {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const [x, y] = ratio;
|
const [x, y] = reduceAspectRatio(ratio);
|
||||||
const useNative = window.CSS ? window.CSS.supports(`aspect-ratio: ${x}/${y}`) : false;
|
const useNative = supportsCSS(`aspect-ratio: ${x}/${y}`);
|
||||||
const padding = (100 / x) * y;
|
const padding = (100 / x) * y;
|
||||||
|
|
||||||
if (useNative) {
|
if (useNative) {
|
||||||
@@ -107,7 +116,7 @@ export function setAspectRatio(input) {
|
|||||||
this.media.style.transform = `translateY(-${offset}%)`;
|
this.media.style.transform = `translateY(-${offset}%)`;
|
||||||
}
|
}
|
||||||
} else if (this.isHTML5) {
|
} else if (this.isHTML5) {
|
||||||
wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null);
|
wrapper.classList.add(this.config.classNames.videoFixedRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { padding, ratio };
|
return { padding, ratio };
|
||||||
@@ -127,4 +136,10 @@ export function roundAspectRatio(x, y, tolerance = 0.05) {
|
|||||||
return [x, y];
|
return [x, y];
|
||||||
}
|
}
|
||||||
|
|
||||||
export default { setAspectRatio };
|
// Get the size of the viewport
|
||||||
|
// https://stackoverflow.com/questions/1248081/how-to-get-the-browser-viewport-dimensions
|
||||||
|
export function getViewportSize() {
|
||||||
|
const width = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
|
||||||
|
const height = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);
|
||||||
|
return [width, height];
|
||||||
|
}
|
||||||
|
|||||||
@@ -59,17 +59,6 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.plyr__video-wrapper {
|
|
||||||
height: 100%;
|
|
||||||
position: static;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vimeo requires some different styling
|
|
||||||
&.plyr--vimeo .plyr__video-wrapper {
|
|
||||||
height: 0;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display correct icon
|
// Display correct icon
|
||||||
.plyr__control .icon--exit-fullscreen {
|
.plyr__control .icon--exit-fullscreen {
|
||||||
display: block;
|
display: block;
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
.plyr__video-wrapper {
|
.plyr__video-wrapper {
|
||||||
background: var(--plyr-video-background, $plyr-video-background);
|
background: var(--plyr-video-background, $plyr-video-background);
|
||||||
height: 100%;
|
|
||||||
margin: auto;
|
margin: auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -45,17 +44,13 @@ $embed-padding: ((100 / 16) * 9);
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the full custom UI is supported
|
// For Vimeo, if the full custom UI is supported
|
||||||
.plyr--full-ui .plyr__video-embed {
|
.plyr--full-ui .plyr__video-embed > .plyr__video-embed__container {
|
||||||
$height: 240;
|
$height: 240;
|
||||||
$offset: to-percentage(($height - $embed-padding) / ($height / 50));
|
$offset: to-percentage(($height - $embed-padding) / ($height / 50));
|
||||||
|
padding-bottom: to-percentage($height);
|
||||||
// Only used for Vimeo
|
position: relative;
|
||||||
> .plyr__video-embed__container {
|
transform: translateY(-$offset);
|
||||||
padding-bottom: to-percentage($height);
|
|
||||||
position: relative;
|
|
||||||
transform: translateY(-$offset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Controls container
|
// Controls container
|
||||||
|
|||||||
@@ -4434,13 +4434,6 @@ fastest-levenshtein@^1.0.12:
|
|||||||
resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2"
|
resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2"
|
||||||
integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==
|
integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==
|
||||||
|
|
||||||
fastly-purge@^1.0.1:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/fastly-purge/-/fastly-purge-1.0.1.tgz#3bdfe9ea1d0fbf2a65712f2f5fe2eca63fcb5960"
|
|
||||||
integrity sha1-O9/p6h0PvyplcS8vX+Lspj/LWWA=
|
|
||||||
dependencies:
|
|
||||||
request "^2.55.0"
|
|
||||||
|
|
||||||
fastq@^1.6.0:
|
fastq@^1.6.0:
|
||||||
version "1.11.0"
|
version "1.11.0"
|
||||||
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858"
|
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858"
|
||||||
@@ -9447,7 +9440,7 @@ replacestream@^4.0.0:
|
|||||||
object-assign "^4.0.1"
|
object-assign "^4.0.1"
|
||||||
readable-stream "^2.0.2"
|
readable-stream "^2.0.2"
|
||||||
|
|
||||||
request@^2.55.0, request@^2.87.0, request@^2.88.0:
|
request@^2.87.0, request@^2.88.0:
|
||||||
version "2.88.2"
|
version "2.88.2"
|
||||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
||||||
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
|
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
|
||||||
|
|||||||
Reference in New Issue
Block a user