Compare commits

...

123 Commits

Author SHA1 Message Date
Sam Potts ba236c4753 v3.6.8 2021-05-12 23:40:37 +10:00
Sam Potts a204f7c1dd Merge branch 'develop' 2021-05-12 23:37:34 +10:00
Sam Potts bacf9122de chore: update nvmrc to 14 2021-05-12 23:37:05 +10:00
Sam Potts 2fdc1eac94 chore: lock file 2021-05-12 23:37:05 +10:00
Sam Potts 5fd4391cd9 fix: fullscreen issues with Vimeo (fixes #2175) 2021-05-12 23:37:05 +10:00
megumin 6991358428 Add container to FullscreenOptions (#2161) 2021-05-12 23:35:01 +10:00
Benny739 b050fde276 added iPad to isIos (#2191) 2021-05-12 23:33:48 +10:00
Sam Potts 32444c9851 v3.6.7
- Fix: remove regression caused by optional chaining and nullish coalescing in check for `window.CSS` check for aspect-ratio (fixes #2174)
2021-04-20 08:28:23 +10:00
Sam Potts b93dcc43ad fix: minor syntax tweak 2021-04-19 21:16:30 +10:00
Sam Potts 6ff6ff1673 fix: syntax fix (#2176) 2021-04-19 21:13:06 +10:00
Sam Potts e1ff86820c v3.6.6
- Improvements to how aspect ratio is handled. Use `aspect-ratio` CSS property instead of the legacy method (still used as fallback). Also automatically determined aspect ratios are rounded to the nearast standard ratio. This fixes issues with the YouTube embeds showing a 1-2px black bar.
- Hide the YouTube poster image container when paused so that the controls underneath can be used.
2021-04-18 17:49:23 +10:00
Sam Potts 7d22c361d1 chore: remove fastly purging logic (#2173) 2021-04-18 17:41:58 +10:00
Sam Potts 951cccb6b0 fix: youtube poster allow clickthrough while paused (#2172) 2021-04-18 16:59:00 +10:00
Sam Potts 438e425838 fix: aspect ratio improvements (#2171)
- Use CSS aspect-ratio (retain fallback for legacy browsers)
- Round aspect ratios (fixes YouTube black border issue)
2021-04-18 16:58:44 +10:00
Sam Potts ddb5ad071e chore: deploy 2021-04-17 00:30:30 +10:00
Sam Potts 38060d986c chore: release 2021-04-17 00:27:07 +10:00
Sam Potts 8c74396459 chore: linting 2021-04-17 00:27:07 +10:00
dependabot[bot] a09d63e8f8 chore(deps): bump is-svg from 4.2.1 to 4.3.1 (#2148)
Bumps [is-svg](https://github.com/sindresorhus/is-svg) from 4.2.1 to 4.3.1.
- [Release notes](https://github.com/sindresorhus/is-svg/releases)
- [Commits](https://github.com/sindresorhus/is-svg/compare/v4.2.1...v4.3.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-17 00:23:18 +10:00
Sam Potts d74af9a73d fix: regression regarding poster image 2021-04-17 00:19:57 +10:00
Sam Potts 60310693d3 chore: packge updates, switch to cssnano 2021-04-17 00:19:41 +10:00
Sam Potts 5d08821c9b fix: missing styles for embeds 2021-04-17 00:19:05 +10:00
Sam Potts 3316e40e7b fix: issue with IE detection 2021-04-17 00:17:53 +10:00
Jürgen Genser dfe5985326 added Runway360 to list of sites using plyr (#2117) 2021-03-27 19:48:11 +11:00
Jorge Bucaran b27ad17c59 Migrate color formatting to colorette (#2124) 2021-03-27 19:46:41 +11:00
Sam Potts 14b8b24e14 Merge pull request #2152 from didrip/fix-vimeo-video-play-chrome-89
add all required props to vimeo iframe allow attribute - fixes #2151
2021-03-26 20:50:53 +11:00
didrip 711fc5835f add all required props to vimeo iframe allow attribute - fixes #2151 2021-03-24 14:06:50 +01:00
Sam Potts 028be22dec chore: removed dist directories from git 2021-01-30 00:06:48 +11:00
Sam Potts 3b5dc09285 Merge pull request #2093 from sampotts/develop
Develop
2021-01-29 23:54:46 +11:00
Sam Potts 8596e05df3 Merge branch 'master' into develop
# Conflicts:
#	src/js/utils/is.js
2021-01-29 23:43:10 +11:00
Sam Potts 1aee8f53a7 chore: publish 3.6.4 2021-01-29 23:40:34 +11:00
Sam Potts a187d07807 chore: linting fix 2021-01-29 23:28:02 +11:00
Sam Potts 3096dd9513 Update pull_request_template.md 2021-01-29 23:18:47 +11:00
Sam Potts 150b07f3ef Update .travis.yml 2021-01-29 23:17:08 +11:00
Sam Potts ad7778e78d Delete .travis directory 2021-01-29 23:16:52 +11:00
Sam Potts c8e776bbea Delete prevent-base-master.sh 2021-01-29 23:16:33 +11:00
Sam Potts c66dc8bf95 Update .travis.yml 2021-01-29 23:16:15 +11:00
Sam Potts ea87b9c788 Update CONTRIBUTING.md 2021-01-29 23:15:44 +11:00
Sam Potts aa3378fd73 v3.6.4 (#2089)
* force fullscreen events to trigger on plyr element (media element in iOS) and not fullscreen container

* Fixing "missing code in detail" for PlyrEvent type

When using typescript and listening for youtube statechange event, it is missing the code property definition inside the event (even though it is provided in the code).
By making events a map of key-value, we can add easily custom event type for specific event name. Since YouTube "statechange" event differs from the basic PlyrEvent, I added a new Event Type "PlyrStateChangeEvent" having a code property corresponding to a YoutubeState enum defined by the YouTube API documentation.
This pattern follows how addEventListener in the lib.dom.d.ts is defined.

* Update link to working dash.js demo (was broken)

* Fix PreviewThumbnailsOptions type

According to the docs, the `src` should also accept an array of strings.

* fix issue #1872

* Check if key is a string before attempt --plyr checking

* Fix for Slow loading videos not autoplaying

* Fix for Slow loading videos not autoplaying

* Network requests are not cancelled after the player is destroyed

* Fix for apect ratio problem when using Vimeo player on mobile devices (issue #1940)

* chore: update packages and linting

* Invoke custom listener on triggering fullscreen via double-click

* Fix volume when unmuting from volume 0

* adding a nice Svelte plugin that I found

* Add missing unit to calc in media query

* Assigning player's lastSeekTime on rewind/fast forward to prevent immediate controls hide on mobile

* Fix youtube not working when player is inside shadow dom

* v3.6.2

* ESLint to use common config

* add BitChute to users list

* Fix aspect ratio issue

* Revert noCookie change

* feat: demo radius tweaks

* fix: poster image shouldn’t receive click events

* chore: package updates

* chore: linting

* feat: custom controls option for embedded players

* Package upgrades

* ESLint to use common config

* Linting changes

* Update README.md

* chore: formatting

* fix: revert pointer events change for poster

* fix: hack for Safari 14 not repainting Vimeo embed on entering fullscreen

* fix: demo using custom controls for YouTube

* doc: Add STROLLÿN among the list of Plyr users

* Fixes #2005

* fix: overflowing volume slider

* chore: clean up CSS

* fix: hide poster when not using custom controls

* Package upgrades

* ESLint to use common config

* Linting changes

* chore: revert customControls default option (to prevent breaking change)

* docs: changelog for v3.6.3

* Remove unnecessary calc from media query (#2049)

* Enhance types (#1841)

* 🏷️(type) enhance QualityOptions type

Some optional properties in the QualityOptions were missing. The forced
and onChange property allwoing to use an external handler.

* ♻️(type) use Plyr.Provider for the readonly provider property

A type exists to define all available providers. This type isn't used in
the Plyr class definition and the same provider list is also defined.
This code is refactored to use the Plyr.Provider type

* 🏷️(type) add missing elements property in Plyr class

In Plyr class, you can access elements set in cache. This property is
missing in the class definition. The Plyr.Elements is for now
incomplete.

* FIX - object values for the providers must be used (#2053)

To make use of the provider configuration, the objects values must be used.

* Fix to work inside iframes. (#2069)

* Fix to work inside iframes.

Right now Plyr fails to load inside iframes because the selectors are not instances of Element (iframes have their own, separate globals). This is an alternative method to check isElement that will work inside iframes. This is battle-tested fallback code used before browsers supported HTMLElement.

* Update is.js

* Added --plyr-video-background for having control over the background of a video with alpha channel (webm) or a poster image with alpha channel. (#2076)

* Fix issue with not entering iosfullscreen of vimeo videos with playsi… (#2038)

* Fix issue with not entering iosfullscreen of vimeo videos with playsinline=true

* Use isVimeo-function instead of hardcoded value

Co-authored-by: Julian Frosch <julian.frosch@gmail.com>

* fix: use new syntax for iframe allow attribute

* Bump ini from 1.3.5 to 1.3.7 (#2044)

Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.7.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.7)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore: package updates

* chore: add @babel/plugin-proposal-class-properties

* fix: use bound arrow functions in classes

* chore: cleanup commented out code

* chore: release

Co-authored-by: Som Meaden <som@theprojectsomething.com>
Co-authored-by: akuma06 <demon.akuma06@gmail.com>
Co-authored-by: Jonathan Arbely <dev@jonathanarbely.de>
Co-authored-by: Takeshi <iwatakeshi@users.noreply.github.com>
Co-authored-by: Hex <hex@codeigniter.org.cn>
Co-authored-by: Syed Husain <syed.husain@appspace.com>
Co-authored-by: Danielh112 <Daniel@sbgsportssoftware.com>
Co-authored-by: Danil Stoyanov <d.stoyanov@corp.mail.ru>
Co-authored-by: Guru Prasad Srinivasa <gurupras@buffalo.edu>
Co-authored-by: Stephane Fortin Bouchard <stephane.f.bouchard@gmail.com>
Co-authored-by: Zev Averbach <zev@averba.ch>
Co-authored-by: Vincent Orback <hello@vincentorback.se>
Co-authored-by: trafium <trafium@gmail.com>
Co-authored-by: xansen <27698939+xansen@users.noreply.github.com>
Co-authored-by: zoomerdev <59863739+zoomerdev@users.noreply.github.com>
Co-authored-by: Mikaël Castellani <mikael.castellani@gmail.com>
Co-authored-by: dirkjf <d.j.faber@outlook.com>
Co-authored-by: Naomi <naomizuiverloon@gmail.com>
Co-authored-by: Manuel Raynaud <manu@raynaud.io>
Co-authored-by: syteknet-core <github.core@sytek.net>
Co-authored-by: Andre Gagnon <ajgagnon@uwalumni.com>
Co-authored-by: Nepomuk Leutschacher <864660+nepomuc@users.noreply.github.com>
Co-authored-by: Elias Saalmann <lordon@users.noreply.github.com>
Co-authored-by: Julian Frosch <julian.frosch@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-29 23:14:02 +11:00
Sam Potts 2cebf9b8a3 chore: release 2021-01-29 23:07:14 +11:00
Sam Potts 572aeacf5b chore: cleanup commented out code 2021-01-29 23:06:57 +11:00
Sam Potts b5592b0fb5 fix: use bound arrow functions in classes 2021-01-29 22:47:27 +11:00
Sam Potts 9adf35a444 chore: add @babel/plugin-proposal-class-properties 2021-01-29 22:47:27 +11:00
Sam Potts 39ff31e3e3 chore: package updates 2021-01-29 22:47:27 +11:00
dependabot[bot] 7e82ec6d70 Bump ini from 1.3.5 to 1.3.7 (#2044)
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.7.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.7)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-29 22:47:27 +11:00
Sam Potts f4d6a243cd fix: use new syntax for iframe allow attribute 2021-01-29 22:47:27 +11:00
Elias Saalmann 31b5027b1e Fix issue with not entering iosfullscreen of vimeo videos with playsi… (#2038)
* Fix issue with not entering iosfullscreen of vimeo videos with playsinline=true

* Use isVimeo-function instead of hardcoded value

Co-authored-by: Julian Frosch <julian.frosch@gmail.com>
2021-01-29 22:38:26 +11:00
Nepomuk Leutschacher 7750314058 Added --plyr-video-background for having control over the background of a video with alpha channel (webm) or a poster image with alpha channel. (#2076) 2021-01-24 16:43:36 +11:00
Andre Gagnon 16c134fc1e Fix to work inside iframes. (#2069)
* Fix to work inside iframes.

Right now Plyr fails to load inside iframes because the selectors are not instances of Element (iframes have their own, separate globals). This is an alternative method to check isElement that will work inside iframes. This is battle-tested fallback code used before browsers supported HTMLElement.

* Update is.js
2021-01-24 10:32:45 +11:00
syteknet-core f00e81a976 FIX - object values for the providers must be used (#2053)
To make use of the provider configuration, the objects values must be used.
2020-12-23 09:30:23 +11:00
Manuel Raynaud 32a4039f7c Enhance types (#1841)
* 🏷️(type) enhance QualityOptions type

Some optional properties in the QualityOptions were missing. The forced
and onChange property allwoing to use an external handler.

* ♻️(type) use Plyr.Provider for the readonly provider property

A type exists to define all available providers. This type isn't used in
the Plyr class definition and the same provider list is also defined.
This code is refactored to use the Plyr.Provider type

* 🏷️(type) add missing elements property in Plyr class

In Plyr class, you can access elements set in cache. This property is
missing in the class definition. The Plyr.Elements is for now
incomplete.
2020-12-20 20:18:53 +11:00
Sam Potts ba09bc32d3 fix: use bound arrow functions in classes 2020-12-20 20:12:21 +11:00
Sam Potts d7195d5276 chore: add @babel/plugin-proposal-class-properties 2020-12-20 20:12:21 +11:00
Sam Potts 6a6fb8d41a chore: package updates 2020-12-20 20:12:21 +11:00
Naomi c853adc760 Remove unnecessary calc from media query (#2049) 2020-12-20 19:10:50 +11:00
dependabot[bot] ca041f2e0d Bump ini from 1.3.5 to 1.3.7 (#2044)
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.7.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.7)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-20 19:05:31 +11:00
Sam Potts 87078d7a44 Merge branch 'master' into develop
# Conflicts:
#	demo/dist/demo.min.js
#	demo/dist/demo.min.js.map
#	dist/plyr.min.js
#	dist/plyr.min.js.map
#	dist/plyr.min.mjs
#	dist/plyr.min.mjs.map
#	dist/plyr.polyfilled.min.js
#	dist/plyr.polyfilled.min.js.map
#	dist/plyr.polyfilled.min.mjs
#	dist/plyr.polyfilled.min.mjs.map
#	yarn.lock
2020-11-14 13:35:22 +11:00
Sam Potts c300df5742 chore: fix node version 2020-11-14 13:34:29 +11:00
dependabot[bot] 2ba56fda15 Bump bl from 1.2.2 to 1.2.3 (#2017)
Bumps [bl](https://github.com/rvagg/bl) from 1.2.2 to 1.2.3.
- [Release notes](https://github.com/rvagg/bl/releases)
- [Commits](https://github.com/rvagg/bl/compare/v1.2.2...v1.2.3)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-14 13:34:04 +11:00
Sam Potts 36b53d2cf0 docs: changelog for v3.6.3 2020-11-14 13:22:24 +11:00
Sam Potts 2d4686a5f3 chore: revert customControls default option (to prevent breaking change) 2020-11-14 13:22:05 +11:00
Sam Potts 31861bd475 Merge branch 'master' into develop
# Conflicts:
#	package.json
#	src/js/plugins/vimeo.js
#	src/js/plugins/youtube.js
#	src/js/ui.js
#	yarn.lock
2020-11-14 13:11:24 +11:00
Sam Potts c3e163741f Linting changes 2020-11-14 13:01:36 +11:00
Sam Potts 1c715bc889 ESLint to use common config 2020-11-14 12:55:06 +11:00
Sam Potts 35ef42246b Package upgrades 2020-11-14 12:55:06 +11:00
Sam Potts cd3962ca32 fix: hide poster when not using custom controls 2020-11-14 12:50:49 +11:00
Sam Potts da16c55427 chore: clean up CSS 2020-11-14 12:50:35 +11:00
Sam Potts bd8bacb6d5 fix: overflowing volume slider 2020-11-14 00:22:40 +11:00
Sam Potts 0d393a5c92 Merge pull request #2008 from dirkjf/firefox-volume-fix
Fixes #2005
2020-11-14 00:22:18 +11:00
dirkjf 136bb525a5 Fixes #2005 2020-11-09 16:33:28 +01:00
Sam Potts e85737d855 Merge pull request #1992 from micaste/patch-2
doc: Add STROLLÿN among the list of Plyr users
2020-11-05 10:03:34 +11:00
Mikaël Castellani 8882317080 doc: Add STROLLÿN among the list of Plyr users 2020-10-25 07:39:43 +01:00
Sam Potts 5c02205a4f fix: demo using custom controls for YouTube 2020-10-19 23:10:00 +11:00
Sam Potts 45f7e20233 fix: hack for Safari 14 not repainting Vimeo embed on entering fullscreen 2020-10-19 23:09:46 +11:00
Sam Potts b116e62f37 fix: revert pointer events change for poster 2020-10-19 23:09:18 +11:00
Sam Potts fa6282d0e2 chore: formatting 2020-10-19 22:43:53 +11:00
Sam Potts 80bdf04fde Merge pull request #1963 from gurupras/dblclick-fullscreen-custom-listener
Invoke custom listener on double-clicking on video (fullscreen)
2020-10-19 22:41:34 +11:00
Sam Potts 3caa37fdf2 Merge pull request #1867 from jonathanarbely/patch-1
Update link to working dash.js demo (was broken)
2020-10-19 22:39:42 +11:00
Sam Potts 807efcbc46 Update README.md 2020-10-19 22:39:31 +11:00
Sam Potts 03d1e3d3e8 Merge pull request #1972 from zevaverbach/patch-2
adding a nice Svelte plugin that I found
2020-10-19 22:36:06 +11:00
Sam Potts 664e2b4893 Merge pull request #1974 from vincentorback/patch-1
Add missing unit to calc in media query
2020-10-19 22:35:51 +11:00
Sam Potts 4cf36bf203 Merge pull request #1967 from airtimemedia/1934-Youtube-unmute-volume-0
Fix volume when unmuting from volume 0
2020-10-19 22:35:12 +11:00
Sam Potts 92f3728d80 Merge pull request #1977 from trafium/prevent-mobile-control-hiding-on-rewind-and-fast-forward
Prevent immediate hiding of controls on mobile when using rewind and fast forward
2020-10-19 22:34:30 +11:00
Sam Potts 29d3ae0b67 Merge pull request #1984 from xansen/develop
Fix youtube not working when player is inside shadow dom
2020-10-19 22:33:52 +11:00
Sam Potts df91f7faac Merge branch 'master' into develop
# Conflicts:
#	README.md
#	demo/dist/demo.min.js
#	demo/dist/demo.min.js.map
#	dist/plyr.min.js
#	dist/plyr.min.js.map
#	dist/plyr.min.mjs
#	dist/plyr.min.mjs.map
#	dist/plyr.polyfilled.min.js
#	dist/plyr.polyfilled.min.js.map
#	dist/plyr.polyfilled.min.mjs
#	dist/plyr.polyfilled.min.mjs.map
#	package.json
#	src/js/plugins/vimeo.js
#	src/js/plugins/youtube.js
#	src/js/ui.js
#	yarn.lock
2020-10-19 22:31:31 +11:00
Sam Potts 9a69ae2599 Linting changes 2020-10-19 22:27:16 +11:00
Sam Potts 02321c35bc ESLint to use common config 2020-10-19 22:27:16 +11:00
Sam Potts 7c6316d824 Package upgrades 2020-10-19 22:27:16 +11:00
Sam Potts 776b0c4036 feat: custom controls option for embedded players 2020-10-19 22:26:33 +11:00
Sam Potts fa653a8859 chore: linting 2020-10-19 22:25:46 +11:00
Sam Potts b6b7db7327 chore: package updates 2020-10-19 22:25:10 +11:00
Sam Potts d4b4303b8e fix: poster image shouldn’t receive click events 2020-10-19 21:43:20 +11:00
Sam Potts 102fb1a32f feat: demo radius tweaks 2020-10-19 21:43:20 +11:00
Sam Potts c77ba3ecf0 Revert noCookie change 2020-10-19 21:43:20 +11:00
Sam Potts 760f5f9469 Fix aspect ratio issue 2020-10-19 21:43:20 +11:00
zoomerdev 0135e9c7f4 add BitChute to users list 2020-10-19 21:43:20 +11:00
Sam Potts 2426c256cc ESLint to use common config 2020-10-19 21:43:05 +11:00
Sam Potts 93eed08d14 v3.6.2 2020-10-19 21:42:19 +11:00
xansen 5a164780d8 Fix youtube not working when player is inside shadow dom 2020-10-19 01:38:42 +06:00
trafium 272d39c1d1 Assigning player's lastSeekTime on rewind/fast forward to prevent immediate controls hide on mobile 2020-10-12 10:28:57 +03:00
Vincent Orback 828abc8308 Add missing unit to calc in media query 2020-10-08 12:03:25 +02:00
Zev Averbach 6455a6acc0 adding a nice Svelte plugin that I found 2020-10-02 10:35:29 +02:00
Stephane Fortin Bouchard 51cb03dc32 Fix volume when unmuting from volume 0 2020-09-28 21:39:02 -04:00
Guru Prasad Srinivasa 4d25a33cb0 Invoke custom listener on triggering fullscreen via double-click 2020-09-23 18:24:53 -04:00
Sam Potts 18b3f23c69 chore: update packages and linting 2020-08-30 16:10:25 +10:00
Sam Potts 11e48b0181 Merge pull request #1824 from akuma06/patch-2
Fixing "missing code in detail" for PlyrEvent type
2020-08-30 15:48:50 +10:00
Sam Potts 3a07669e30 Merge pull request #1916 from syedhusain-appspace/develop
Check if key is a string before attempt --plyr checking
2020-08-30 15:47:25 +10:00
Sam Potts b3d390076b Merge pull request #1914 from hex-ci/develop
fix issue #1872
2020-08-30 15:46:35 +10:00
Sam Potts f75820fbd3 Merge pull request #1931 from SBGSports/Autoplay-issue
Fix for Slow loading videos not autoplaying
2020-08-30 15:45:24 +10:00
Sam Potts 8b0d84a9a4 Merge pull request #1935 from SBGSports/Cancel-network-requests-once-player-is-destroyed
Network requests are not cancelled after the player is destroyed
2020-08-30 15:44:55 +10:00
Sam Potts d582e43413 Merge pull request #1941 from danilstoyanov/vimeo-aspect-ratio-mobile
Fix for apect ratio problem when using Vimeo player on mobile devices…
2020-08-30 15:44:19 +10:00
Danil Stoyanov 75082bc73f Fix for apect ratio problem when using Vimeo player on mobile devices (issue #1940) 2020-08-28 23:07:12 +03:00
Danielh112 f7e9ee56d2 Fix merge conflicts 2020-08-18 11:29:25 +01:00
Danielh112 22af7f16ea Network requests are not cancelled after the player is destroyed 2020-08-18 11:15:58 +01:00
Danielh112 9076d054b9 Fix for Slow loading videos not autoplaying 2020-08-14 10:34:48 +01:00
Danielh112 4eaa1a72b5 Fix for Slow loading videos not autoplaying 2020-08-14 10:29:46 +01:00
Syed Husain 4c1ae8f3ce Check if key is a string before attempt --plyr checking 2020-07-30 19:43:04 +08:00
Hex 0733133510 fix issue #1872 2020-07-29 17:01:21 +08:00
Sam Potts 423b7b276f Merge pull request #1900 from iwatakeshi/patch-1
Fix PreviewThumbnailsOptions type
2020-07-14 09:03:36 +10:00
Takeshi cbd4a7cef4 Fix PreviewThumbnailsOptions type
According to the docs, the `src` should also accept an array of strings.
2020-07-13 13:00:16 -06:00
Jonathan Arbely 8ce7425f73 Update link to working dash.js demo (was broken) 2020-06-09 20:13:41 +02:00
akuma06 1f63806c3f Fixing "missing code in detail" for PlyrEvent type
When using typescript and listening for youtube statechange event, it is missing the code property definition inside the event (even though it is provided in the code).
By making events a map of key-value, we can add easily custom event type for specific event name. Since YouTube "statechange" event differs from the basic PlyrEvent, I added a new Event Type "PlyrStateChangeEvent" having a code property corresponding to a YoutubeState enum defined by the YouTube API documentation.
This pattern follows how addEventListener in the lib.dom.d.ts is defined.
2020-05-05 15:34:41 +02:00
Sam Potts 6cb822d56f Merge pull request #1823 from theprojectsomething/features/fullscreen-container
force fullscreen events to trigger on plyr element
2020-05-05 17:07:00 +10:00
Som Meaden 9dee5acec6 force fullscreen events to trigger on plyr element (media element in iOS) and not fullscreen container 2020-05-05 16:35:36 +10:00
56 changed files with 3194 additions and 83222 deletions
-5
View File
@@ -1,8 +1,3 @@
### Link to related issue (if applicable)
### Summary of proposed changes
### Checklist
- [ ] Use `develop` as the base branch
- [ ] Exclude the gulp build (`/dist` changes) from the PR
- [ ] Test on [supported browsers](https://github.com/sampotts/plyr#browser-support)
+1 -1
View File
@@ -2,8 +2,8 @@ node_modules
.DS_Store
credentials.json
*.mp4
!dist/blank.mp4
npm-debug.log
yarn-error.log
*.webm
.idea/
dist/
+1 -1
View File
@@ -7,6 +7,6 @@ credentials.json
deploy.json
yarn.lock
package-lock.json
*.mp4
*.webm
*.mp4
!dist/blank.mp4
+1 -1
View File
@@ -1 +1 @@
v13.8.0
14
-2
View File
@@ -2,7 +2,5 @@ language: node_js
node_js: lts/*
script:
- bash .travis/prevent-base-master.sh
- bash .travis/omit-dist.sh
- npm run lint
- npm run build
-5
View File
@@ -1,5 +0,0 @@
#!/bin/bash
if [ $TRAVIS_BRANCH == "develop" ] && $(git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qE "^(demo/)?dist/"); then
echo 'Build output ("dist" and "demo/dist") not permitted in develop' >&2
exit 1
fi
-5
View File
@@ -1,5 +0,0 @@
#!/bin/bash
if [ "$TRAVIS_PULL_REQUEST" != "false" ] && [ $TRAVIS_BRANCH == "master" ] && $(git diff --name-only $TRAVIS_COMMIT_RANGE | grep -q "^src/"); then
echo 'The base branch for pull requests must be "develop"' >&2
exit 1
fi
+36
View File
@@ -1,3 +1,39 @@
### 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
- Fix: remove regression caused by optional chaining and nullish coalescing in check for `window.CSS` check for aspect-ratio (fixes #2174)
### v3.6.6
- Improvements to how aspect ratio is handled. Use `aspect-ratio` CSS property instead of the legacy method (still used as fallback). Also automatically determined aspect ratios are rounded to the nearast standard ratio. This fixes issues with the YouTube embeds showing a 1-2px black bar.
- Hide the YouTube poster image container when paused so that the controls underneath can be used.
### v3.6.5
- Migrate color formatting to colorette (thanks @jorgebucaran)
- Fix: issue with IE detection
- Fix: missing styles for embeds
- Fix: regression regarding poster image
- Add all required props to vimeo iframe allow attribute - fixes #2151 (thanks @didrip)
### v3.6.4
- Remove unnecessary calc from media query (thanks @naomiaz)
- Enhance types (thanks @lunika)
- Fix: Object.values for the providers must be used (thanks @syteknet-core)
- Fix: Improve support inside iframes (thanks @ajgagnon)
- Added --plyr-video-background for having control over the background of a video with alpha channel (webm) or a poster image with alpha channel (thanks @nepomuc)
- Fix issue with not entering iosfullscreen of vimeo videos with playsinline=true (thanks @lordon and @Frosch)
- fix: use new syntax for iframe allow attribute
- chore: package updates
- chore: add @babel/plugin-proposal-class-properties
- fix: use bound arrow functions in classes
### v3.6.3
- Fix volume when unmuting from volume 0 using YouTube (thanks @stephanefbouchard)
+3 -3
View File
@@ -36,8 +36,8 @@ Please follow the instructions in our issue templates. Don't use github issues t
You can use Gitpod (a free online VS Code-like IDE) for contributing. With a single click it will launch a workspace and automatically:
- clone the plyr repo.
- install the dependencies.
- run `gulp` to the start the server.
- install the dependencies with `yarn install` in root directory and "demo" directory.
- run `gulp` in root directory to start the dev server.
So that you can start straight away.
@@ -49,6 +49,6 @@ So that you can start straight away.
- If your modifications changes the documented behavior or add new features, document these changes in [README.md](README.md).
- When finished, push the changes to your GitHub repository and send a pull request to **develop**. Describe what your PR does.
- When finished, push the changes to your GitHub repository and send a pull request. Describe what your PR does.
- If the Travis build fails, or if you get a code review with change requests, you can fix these by pushing new or rebased commits to the branch.
+6 -4
View File
@@ -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.
```html
<script src="https://cdn.plyr.io/3.6.3/plyr.js"></script>
<script src="https://cdn.plyr.io/3.6.8/plyr.js"></script>
```
...or...
```html
<script src="https://cdn.plyr.io/3.6.3/plyr.polyfilled.js"></script>
<script src="https://cdn.plyr.io/3.6.8/plyr.polyfilled.js"></script>
```
## 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:
```html
<link rel="stylesheet" href="https://cdn.plyr.io/3.6.3/plyr.css" />
<link rel="stylesheet" href="https://cdn.plyr.io/3.6.8/plyr.css" />
```
## 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
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.6.3/plyr.svg`.
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.6.8/plyr.svg`.
# Ads
@@ -185,6 +185,7 @@ Here's a list of the properties and what they are used for:
| Name | Description | Default / Fallback |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| `--plyr-color-main` | The primary UI color. | ![#f03c15](https://placehold.it/15/00b3ff/000000?text=+) `#00b3ff` |
| `--plyr-video-background` | The background color of video and poster wrappers for using alpha channel videos and poster images. | `rgba(0, 0, 0, 1)` |
| `--plyr-tab-focus-color` | The color used for the dotted outline when an element is `:focus-visible` (equivalent) keyboard focus. | `--plyr-color-main` |
| `--plyr-badge-background` | The background color for badges in the menu. | ![#4a5464](https://placehold.it/15/4a5464/000000?text=+) `#4a5464` |
| `--plyr-badge-text-color` | The text color for badges. | ![#ffffff](https://placehold.it/15/ffffff/000000?text=+) `#ffffff` |
@@ -838,6 +839,7 @@ Plyr costs money to run, not only my time. I donate my time for free as I enjoy
- [Rutheneum-Bote](https://gymnasium-rutheneum.de/content/newspaper/kreativwettbewerb.php)
- [pressakey.com | Blog-Magazin für Videospiele](https://pressakey.com)
- [STROLLÿN: Work with a View](https://strollyn.com)
- [CFDA Runway360](https://runway360.cfda.com/)
If you want to be added to the list, open a pull request. It'd be awesome to see how you're using Plyr 😎
-1
View File
File diff suppressed because one or more lines are too long
-29688
View File
File diff suppressed because it is too large Load Diff
-19
View File
File diff suppressed because one or more lines are too long
-1
View File
File diff suppressed because one or more lines are too long
-1
View File
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.6 KiB

-1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -2,4 +2,4 @@
// Layout
// ==========================================================================
$container-max-width: 1260px;
$container-max-width: 1240px;
BIN
View File
Binary file not shown.
-1
View File
File diff suppressed because one or more lines are too long
-9349
View File
File diff suppressed because it is too large Load Diff
-4
View File
File diff suppressed because one or more lines are too long
-1
View File
File diff suppressed because one or more lines are too long
-3
View File
File diff suppressed because one or more lines are too long
-1
View File
File diff suppressed because one or more lines are too long
-9341
View File
File diff suppressed because it is too large Load Diff
-15829
View File
File diff suppressed because it is too large Load Diff
-4
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-3
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-15821
View File
File diff suppressed because it is too large Load Diff
-1
View File
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.6 KiB

+23 -24
View File
@@ -1,6 +1,6 @@
{
"name": "plyr",
"version": "3.6.3",
"version": "3.6.8",
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
"homepage": "https://plyr.io",
"author": "Sam Potts <sam@potts.es>",
@@ -39,18 +39,19 @@
"start": "gulp"
},
"devDependencies": {
"@sampotts/eslint-config": "1.1.5",
"ansi-colors": "^4.1.1",
"autoprefixer": "^10.0.2",
"aws-sdk": "^2.773.0",
"@babel/core": "^7.12.3",
"@babel/preset-env": "^7.12.1",
"@sampotts/eslint-config": "1.1.7",
"autoprefixer": "^10.2.5",
"aws-sdk": "^2.888.0",
"@babel/core": "^7.13.15",
"@babel/preset-env": "^7.13.15",
"@babel/plugin-proposal-class-properties": "^7.13.0",
"babel-eslint": "^10.1.0",
"browser-sync": "^2.26.13",
"browser-sync": "^2.26.14",
"colorette": "1.2.2",
"cssnano": "^5.0.1",
"del": "^6.0.0",
"eslint": "^7.3.1",
"eslint": "^7.23.0",
"fancy-log": "^1.3.3",
"fastly-purge": "^1.0.1",
"git-branch": "^2.0.1",
"gulp": "^4.0.2",
"gulp-awspublish": "^4.1.2",
@@ -69,29 +70,27 @@
"gulp-size": "^3.0.0",
"gulp-sourcemaps": "^3.0.0",
"gulp-svgstore": "^7.0.1",
"gulp-terser": "^1.4.1",
"postcss": "^8.1.7",
"postcss-clean": "^1.1.0",
"postcss-custom-properties": "^10.0.0",
"prettier-eslint": "^11.0.0",
"gulp-terser": "^2.0.1",
"postcss": "^8.2.10",
"postcss-custom-properties": "^11.0.0",
"prettier-eslint": "^12.0.0",
"prettier-stylelint": "^0.4.2",
"remark-cli": "^9.0.0",
"remark-validate-links": "^10.0.2",
"rollup": "^2.33.1",
"remark-validate-links": "^10.0.4",
"rollup": "^2.45.2",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0",
"stylelint": "^13.7.2",
"stylelint": "^13.12.0",
"stylelint-config-prettier": "^8.0.2",
"stylelint-config-recommended": "^3.0.0",
"stylelint-config-sass-guidelines": "^7.1.0",
"stylelint-config-recommended": "^4.0.0",
"stylelint-config-sass-guidelines": "^8.0.0",
"stylelint-order": "^4.1.0",
"stylelint-scss": "^3.18.0",
"stylelint-selector-bem-pattern": "^2.1.0",
"through2": "^4.0.2"
"stylelint-scss": "^3.19.0",
"stylelint-selector-bem-pattern": "^2.1.0"
},
"dependencies": {
"core-js": "^3.7.0",
"core-js": "^3.10.1",
"custom-event-polyfill": "^1.0.7",
"loadjs": "^4.2.0",
"rangetouch": "^2.0.1",
+1 -1
View File
@@ -61,7 +61,7 @@ const defaults = {
// Sprite (for icons)
loadSprite: true,
iconPrefix: 'plyr',
iconUrl: 'https://cdn.plyr.io/3.6.3/plyr.svg',
iconUrl: 'https://cdn.plyr.io/3.6.8/plyr.svg',
// Blank video (used to prevent errors on source change)
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
+21 -15
View File
@@ -57,6 +57,8 @@ class Fullscreen {
// Update the UI
this.update();
// this.toggle = this.toggle.bind(this);
}
// Determine if native supported
@@ -134,7 +136,7 @@ class Fullscreen {
: this.player.elements.fullscreen || this.player.elements.container;
}
onChange() {
onChange = () => {
if (!this.enabled) {
return;
}
@@ -149,9 +151,9 @@ class Fullscreen {
const target = this.target === this.player.media ? this.target : this.player.elements.container;
// Trigger an event
triggerEvent.call(this.player, target, this.active ? 'enterfullscreen' : 'exitfullscreen', true);
}
};
toggleFallback(toggle = false) {
toggleFallback = (toggle = false) => {
// Store or restore scroll position
if (toggle) {
this.scrollPosition = {
@@ -198,10 +200,10 @@ class Fullscreen {
// Toggle button and fire events
this.onChange();
}
};
// Trap focus inside container
trapFocus(event) {
trapFocus = (event) => {
// Bail if iOS, not active, not the tab key
if (browser.isIos || !this.active || event.key !== 'Tab' || event.keyCode !== 9) {
return;
@@ -222,10 +224,10 @@ class Fullscreen {
last.focus();
event.preventDefault();
}
}
};
// Update UI
update() {
update = () => {
if (this.enabled) {
let mode;
@@ -244,17 +246,21 @@ class Fullscreen {
// Add styling hook to show button
toggleClass(this.player.elements.container, this.player.config.classNames.fullscreen.enabled, this.enabled);
}
};
// Make an element fullscreen
enter() {
enter = () => {
if (!this.enabled) {
return;
}
// iOS native fullscreen doesn't need the request step
if (browser.isIos && this.player.config.fullscreen.iosNative) {
this.target.webkitEnterFullscreen();
if (this.player.isVimeo) {
this.player.embed.requestFullscreen();
} else {
this.target.webkitEnterFullscreen();
}
} else if (!Fullscreen.native || this.forceFallback) {
this.toggleFallback(true);
} else if (!this.prefix) {
@@ -262,10 +268,10 @@ class Fullscreen {
} else if (!is.empty(this.prefix)) {
this.target[`${this.prefix}Request${this.property}`]();
}
}
};
// Bail from fullscreen
exit() {
exit = () => {
if (!this.enabled) {
return;
}
@@ -282,16 +288,16 @@ class Fullscreen {
const action = this.prefix === 'moz' ? 'Cancel' : 'Exit';
document[`${this.prefix}${action}${this.property}`]();
}
}
};
// Toggle state
toggle() {
toggle = () => {
if (!this.active) {
this.enter();
} else {
this.exit();
}
}
};
}
export default Fullscreen;
+57 -61
View File
@@ -10,7 +10,7 @@ import { getElement, getElements, matches, toggleClass } from './utils/elements'
import { off, on, once, toggleListener, triggerEvent } from './utils/events';
import is from './utils/is';
import { silencePromise } from './utils/promise';
import { getAspectRatio, setAspectRatio } from './utils/style';
import { getAspectRatio, getViewportSize, supportsCSS } from './utils/style';
class Listeners {
constructor(player) {
@@ -149,16 +149,16 @@ class Listeners {
break;
/* case 73:
this.setLoop('start');
break;
this.setLoop('start');
break;
case 76:
this.setLoop();
break;
case 76:
this.setLoop();
break;
case 79:
this.setLoop('end');
break; */
case 79:
this.setLoop('end');
break; */
default:
break;
@@ -183,7 +183,7 @@ class Listeners {
}
// Device is touch enabled
firstTouch() {
firstTouch = () => {
const { player } = this;
const { elements } = player;
@@ -191,9 +191,9 @@ class Listeners {
// Add touch class
toggleClass(elements.container, player.config.classNames.isTouch, true);
}
};
setTabFocus(event) {
setTabFocus = (event) => {
const { player } = this;
const { elements } = player;
@@ -241,10 +241,10 @@ class Listeners {
toggleClass(document.activeElement, player.config.classNames.tabFocus, true);
}, 10);
}
}
};
// Global window & document listeners
global(toggle = true) {
global = (toggle = true) => {
const { player } = this;
// Keyboard shortcuts
@@ -260,10 +260,10 @@ class Listeners {
// Tab focus detection
toggleListener.call(player, document.body, 'keydown focus blur focusout', this.setTabFocus, toggle, false, true);
}
};
// Container listeners
container() {
container = () => {
const { player } = this;
const { config, elements, timers } = player;
@@ -305,39 +305,49 @@ class Listeners {
);
// Set a gutter for Vimeo
const setGutter = (ratio, padding, toggle) => {
const setGutter = () => {
if (!player.isVimeo || player.config.vimeo.premium) {
return;
}
const target = player.elements.wrapper.firstChild;
const [, y] = ratio;
const [videoX, videoY] = getAspectRatio.call(player);
const target = elements.wrapper;
const { active } = player.fullscreen;
const [videoWidth, videoHeight] = getAspectRatio.call(player);
const useNativeAspectRatio = supportsCSS(`aspect-ratio: ${videoWidth} / ${videoHeight}`);
target.style.maxWidth = toggle ? `${(y / videoY) * videoX}px` : null;
target.style.margin = toggle ? '0 auto' : null;
};
// Resize on fullscreen change
const setPlayerSize = (measure) => {
// If we don't need to measure the viewport
if (!measure) {
return setAspectRatio.call(player);
// If not active, remove styles
if (!active) {
if (useNativeAspectRatio) {
target.style.width = null;
target.style.height = null;
} else {
target.style.maxWidth = null;
target.style.margin = null;
}
return;
}
const rect = elements.container.getBoundingClientRect();
const { width, height } = rect;
// Determine which dimension will overflow and constrain view
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 = () => {
clearTimeout(timers.resized);
timers.resized = setTimeout(setPlayerSize, 50);
timers.resized = setTimeout(setGutter, 50);
};
on.call(player, elements.container, 'enterfullscreen exitfullscreen', (event) => {
const { target, usingNative } = player.fullscreen;
const { target } = player.fullscreen;
// Ignore events not from target
if (target !== elements.container) {
@@ -349,31 +359,17 @@ class Listeners {
return;
}
const isEnter = event.type === 'enterfullscreen';
// Set the player size when entering fullscreen to viewport size
const { padding, ratio } = setPlayerSize(isEnter);
// Set Vimeo gutter
setGutter(ratio, padding, isEnter);
setGutter();
// Horrible hack for Safari 14 not repainting properly on entering fullscreen
if (isEnter) {
setTimeout(() => repaint(elements.container), 100);
}
// 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);
}
}
// Watch for resizes
const method = event.type === 'enterfullscreen' ? on : off;
method.call(player, window, 'resize', resized);
});
}
};
// Listen for media events
media() {
media = () => {
const { player } = this;
const { elements } = player;
@@ -514,10 +510,10 @@ class Listeners {
triggerEvent.call(player, elements.container, event.type, true, detail);
});
}
};
// Run default and custom handlers
proxy(event, defaultHandler, customHandlerKey) {
proxy = (event, defaultHandler, customHandlerKey) => {
const { player } = this;
const customHandler = player.config.listeners[customHandlerKey];
const hasCustomHandler = is.function(customHandler);
@@ -532,10 +528,10 @@ class Listeners {
if (returned !== false && is.function(defaultHandler)) {
defaultHandler.call(player, event);
}
}
};
// Trigger custom and default handlers
bind(element, type, defaultHandler, customHandlerKey, passive = true) {
bind = (element, type, defaultHandler, customHandlerKey, passive = true) => {
const { player } = this;
const customHandler = player.config.listeners[customHandlerKey];
const hasCustomHandler = is.function(customHandler);
@@ -547,10 +543,10 @@ class Listeners {
(event) => this.proxy(event, defaultHandler, customHandlerKey),
passive && !hasCustomHandler,
);
}
};
// Listen for control events
controls() {
controls = () => {
const { player } = this;
const { elements } = player;
// IE doesn't support input event, so we fallback to change
@@ -905,7 +901,7 @@ class Listeners {
'volume',
false,
);
}
};
}
export default Listeners;
-1
View File
@@ -41,7 +41,6 @@ const media = {
// Poster image container
this.elements.poster = createElement('div', {
class: this.config.classNames.poster,
hidden: '',
});
this.elements.wrapper.appendChild(this.elements.poster);
+38 -38
View File
@@ -77,7 +77,7 @@ class Ads {
/**
* Load the IMA SDK
*/
load() {
load = () => {
if (!this.enabled) {
return;
}
@@ -95,12 +95,12 @@ class Ads {
} else {
this.ready();
}
}
};
/**
* Get the ads instance ready
*/
ready() {
ready = () => {
// Double check we're enabled
if (!this.enabled) {
destroy(this);
@@ -120,7 +120,7 @@ class Ads {
// Setup the IMA SDK
this.setupIMA();
}
};
// Build the tag URL
get tagUrl() {
@@ -153,7 +153,7 @@ class Ads {
* properly place mid-rolls. After we create the ad display container, we initialize it. On
* mobile devices, this initialization is done as the result of a user action.
*/
setupIMA() {
setupIMA = () => {
// Create the container for our advertisements
this.elements.container = createElement('div', {
class: this.player.config.classNames.ads,
@@ -186,12 +186,12 @@ class Ads {
// Request video ads to be pre-loaded
this.requestAds();
}
};
/**
* Request advertisements
*/
requestAds() {
requestAds = () => {
const { container } = this.player.elements;
try {
@@ -216,13 +216,13 @@ class Ads {
} catch (e) {
this.onAdError(e);
}
}
};
/**
* Update the ad countdown
* @param {Boolean} start
*/
pollCountdown(start = false) {
pollCountdown = (start = false) => {
if (!start) {
clearInterval(this.countdownTimer);
this.elements.container.removeAttribute('data-badge-text');
@@ -236,13 +236,13 @@ class Ads {
};
this.countdownTimer = setInterval(update, 100);
}
};
/**
* This method is called whenever the ads are ready inside the AdDisplayContainer
* @param {Event} adsManagerLoadedEvent
*/
onAdsManagerLoaded(event) {
onAdsManagerLoaded = (event) => {
// Load could occur after a source change (race condition)
if (!this.enabled) {
return;
@@ -273,9 +273,9 @@ class Ads {
// Resolve our adsManager
this.trigger('loaded');
}
};
addCuePoints() {
addCuePoints = () => {
// Add advertisement cue's within the time line if available
if (!is.empty(this.cuePoints)) {
this.cuePoints.forEach((cuePoint) => {
@@ -294,7 +294,7 @@ class Ads {
}
});
}
}
};
/**
* This is where all the event handling takes place. Retrieve the ad from the event. Some
@@ -302,7 +302,7 @@ class Ads {
* https://developers.google.com/interactive-media-ads/docs/sdks/html5/v3/apis#ima.AdEvent.Type
* @param {Event} event
*/
onAdEvent(event) {
onAdEvent = (event) => {
const { container } = this.player.elements;
// Retrieve the ad from the event. Some events (e.g. ALL_ADS_COMPLETED)
// don't have ad object associated
@@ -410,23 +410,23 @@ class Ads {
default:
break;
}
}
};
/**
* Any ad error handling comes through here
* @param {Event} event
*/
onAdError(event) {
onAdError = (event) => {
this.cancel();
this.player.debug.warn('Ads error', event);
}
};
/**
* Setup hooks for Plyr and window events. This ensures
* the mid- and post-roll launch at the correct time. And
* resize the advertisement when the player resizes
*/
listeners() {
listeners = () => {
const { container } = this.player.elements;
let time;
@@ -464,12 +464,12 @@ class Ads {
this.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);
}
});
}
};
/**
* Initialize the adsManager and start playing advertisements
*/
play() {
play = () => {
const { container } = this.player.elements;
if (!this.managerPromise) {
@@ -503,12 +503,12 @@ class Ads {
}
})
.catch(() => {});
}
};
/**
* Resume our video
*/
resumeContent() {
resumeContent = () => {
// Hide the advertisement container
this.elements.container.style.zIndex = '';
@@ -517,12 +517,12 @@ class Ads {
// Play video
silencePromise(this.player.media.play());
}
};
/**
* Pause our video
*/
pauseContent() {
pauseContent = () => {
// Show the advertisement container
this.elements.container.style.zIndex = 3;
@@ -531,7 +531,7 @@ class Ads {
// Pause our video.
this.player.media.pause();
}
};
/**
* Destroy the adsManager so we can grab new ads after this. If we don't then we're not
@@ -539,7 +539,7 @@ class Ads {
* video requests. https://developers.google.com/interactive-
* media-ads/docs/sdks/android/faq#8
*/
cancel() {
cancel = () => {
// Pause our video
if (this.initialized) {
this.resumeContent();
@@ -550,12 +550,12 @@ class Ads {
// Re-create our adsManager
this.loadAds();
}
};
/**
* Re-create our adsManager
*/
loadAds() {
loadAds = () => {
// Tell our adsManager to go bye bye
this.managerPromise
.then(() => {
@@ -576,13 +576,13 @@ class Ads {
this.requestAds();
})
.catch(() => {});
}
};
/**
* Handles callbacks after an ad event was invoked
* @param {String} event - Event type
*/
trigger(event, ...args) {
trigger = (event, ...args) => {
const handlers = this.events[event];
if (is.array(handlers)) {
@@ -592,7 +592,7 @@ class Ads {
}
});
}
}
};
/**
* Add event listeners
@@ -600,7 +600,7 @@ class Ads {
* @param {Function} callback - Callback for when event occurs
* @return {Ads}
*/
on(event, callback) {
on = (event, callback) => {
if (!is.array(this.events[event])) {
this.events[event] = [];
}
@@ -608,7 +608,7 @@ class Ads {
this.events[event].push(callback);
return this;
}
};
/**
* Setup a safety timer for when the ad network doesn't respond for whatever reason.
@@ -618,27 +618,27 @@ class Ads {
* @param {Number} time
* @param {String} from
*/
startSafetyTimer(time, from) {
startSafetyTimer = (time, from) => {
this.player.debug.log(`Safety timer invoked from: ${from}`);
this.safetyTimer = setTimeout(() => {
this.cancel();
this.clearSafetyTimer('startSafetyTimer()');
}, time);
}
};
/**
* Clear our safety timer(s)
* @param {String} from
*/
clearSafetyTimer(from) {
clearSafetyTimer = (from) => {
if (!is.nullOrUndefined(this.safetyTimer)) {
this.player.debug.log(`Safety timer cleared from: ${from}`);
clearTimeout(this.safetyTimer);
this.safetyTimer = null;
}
}
};
}
export default Ads;
+46 -46
View File
@@ -103,7 +103,7 @@ class PreviewThumbnails {
return this.player.isHTML5 && this.player.isVideo && this.player.config.previewThumbnails.enabled;
}
load() {
load = () => {
// Toggle the regular seek tooltip
if (this.player.elements.display.seekTooltip) {
this.player.elements.display.seekTooltip.hidden = this.enabled;
@@ -126,10 +126,10 @@ class PreviewThumbnails {
this.loaded = true;
});
}
};
// Download VTT files and parse them
getThumbnails() {
getThumbnails = () => {
return new Promise((resolve) => {
const { src } = this.player.config.previewThumbnails;
@@ -164,10 +164,10 @@ class PreviewThumbnails {
Promise.all(promises).then(sortAndResolve);
}
});
}
};
// Process individual VTT file
getThumbnail(url) {
getThumbnail = (url) => {
return new Promise((resolve) => {
fetch(url).then((response) => {
const thumbnail = {
@@ -202,9 +202,9 @@ class PreviewThumbnails {
tempImage.src = thumbnail.urlPrefix + thumbnail.frames[0].text;
});
});
}
};
startMove(event) {
startMove = (event) => {
if (!this.loaded) {
return;
}
@@ -245,13 +245,13 @@ class PreviewThumbnails {
// Download and show image
this.showImageAtCurrentTime();
}
};
endMove() {
endMove = () => {
this.toggleThumbContainer(false, true);
}
};
startScrubbing(event) {
startScrubbing = (event) => {
// Only act on left mouse button (0), or touch device (event.button does not exist or is false)
if (is.nullOrUndefined(event.button) || event.button === false || event.button === 0) {
this.mouseDown = true;
@@ -265,9 +265,9 @@ class PreviewThumbnails {
this.showImageAtCurrentTime();
}
}
}
};
endScrubbing() {
endScrubbing = () => {
this.mouseDown = false;
// Hide scrubbing preview. But wait until the video has successfully seeked before hiding the scrubbing preview
@@ -283,12 +283,12 @@ class PreviewThumbnails {
}
});
}
}
};
/**
* Setup hooks for Plyr and window events
*/
listeners() {
listeners = () => {
// Hide thumbnail preview - on mouse click, mouse leave (in listeners.js for now), and video play/seek. All four are required, e.g., for buffering
this.player.on('play', () => {
this.toggleThumbContainer(false, true);
@@ -301,12 +301,12 @@ class PreviewThumbnails {
this.player.on('timeupdate', () => {
this.lastTime = this.player.media.currentTime;
});
}
};
/**
* Create HTML elements for image containers
*/
render() {
render = () => {
// Create HTML element: plyr__preview-thumbnail-container
this.elements.thumb.container = createElement('div', {
class: this.player.config.classNames.previewThumbnails.thumbContainer,
@@ -339,18 +339,18 @@ class PreviewThumbnails {
});
this.player.elements.wrapper.appendChild(this.elements.scrubbing.container);
}
};
destroy() {
destroy = () => {
if (this.elements.thumb.container) {
this.elements.thumb.container.remove();
}
if (this.elements.scrubbing.container) {
this.elements.scrubbing.container.remove();
}
}
};
showImageAtCurrentTime() {
showImageAtCurrentTime = () => {
if (this.mouseDown) {
this.setScrubbingContainerSize();
} else {
@@ -387,10 +387,10 @@ class PreviewThumbnails {
this.showingThumb = thumbNum;
this.loadImage(qualityIndex);
}
}
};
// Show the image that's currently specified in this.showingThumb
loadImage(qualityIndex = 0) {
loadImage = (qualityIndex = 0) => {
const thumbNum = this.showingThumb;
const thumbnail = this.thumbnails[qualityIndex];
const { urlPrefix } = thumbnail;
@@ -426,9 +426,9 @@ class PreviewThumbnails {
this.currentImageElement.dataset.index = thumbNum;
this.removeOldImages(this.currentImageElement);
}
}
};
showImage(previewImage, frame, qualityIndex, thumbNum, thumbFilename, newImage = true) {
showImage = (previewImage, frame, qualityIndex, thumbNum, thumbFilename, newImage = true) => {
this.player.debug.log(
`Showing thumb: ${thumbFilename}. num: ${thumbNum}. qual: ${qualityIndex}. newimg: ${newImage}`,
);
@@ -449,10 +449,10 @@ class PreviewThumbnails {
this.preloadNearby(thumbNum, true)
.then(this.preloadNearby(thumbNum, false))
.then(this.getHigherQuality(qualityIndex, previewImage, frame, thumbFilename));
}
};
// Remove all preview images that aren't the designated current image
removeOldImages(currentImage) {
removeOldImages = (currentImage) => {
// Get a list of all images, convert it from a DOM list to an array
Array.from(this.currentImageContainer.children).forEach((image) => {
if (image.tagName.toLowerCase() !== 'img') {
@@ -476,11 +476,11 @@ class PreviewThumbnails {
}, removeDelay);
}
});
}
};
// Preload images before and after the current one. Only if the user is still hovering/seeking the same frame
// This will only preload the lowest quality
preloadNearby(thumbNum, forward = true) {
preloadNearby = (thumbNum, forward = true) => {
return new Promise((resolve) => {
setTimeout(() => {
const oldThumbFilename = this.thumbnails[0].frames[thumbNum].text;
@@ -527,10 +527,10 @@ class PreviewThumbnails {
}
}, 300);
});
}
};
// If user has been hovering current image for half a second, look for a higher quality one
getHigherQuality(currentQualityIndex, previewImage, frame, thumbFilename) {
getHigherQuality = (currentQualityIndex, previewImage, frame, thumbFilename) => {
if (currentQualityIndex < this.thumbnails.length - 1) {
// Only use the higher quality version if it's going to look any better - if the current thumb is of a lower pixel density than the thumbnail container
let previewImageHeight = previewImage.naturalHeight;
@@ -550,7 +550,7 @@ class PreviewThumbnails {
}, 300);
}
}
}
};
get currentImageContainer() {
if (this.mouseDown) {
@@ -605,7 +605,7 @@ class PreviewThumbnails {
}
}
toggleThumbContainer(toggle = false, clearShowing = false) {
toggleThumbContainer = (toggle = false, clearShowing = false) => {
const className = this.player.config.classNames.previewThumbnails.thumbContainerShown;
this.elements.thumb.container.classList.toggle(className, toggle);
@@ -613,9 +613,9 @@ class PreviewThumbnails {
this.showingThumb = null;
this.showingThumbFilename = null;
}
}
};
toggleScrubbingContainer(toggle = false) {
toggleScrubbingContainer = (toggle = false) => {
const className = this.player.config.classNames.previewThumbnails.scrubbingContainerShown;
this.elements.scrubbing.container.classList.toggle(className, toggle);
@@ -623,17 +623,17 @@ class PreviewThumbnails {
this.showingThumb = null;
this.showingThumbFilename = null;
}
}
};
determineContainerAutoSizing() {
determineContainerAutoSizing = () => {
if (this.elements.thumb.imageContainer.clientHeight > 20 || this.elements.thumb.imageContainer.clientWidth > 20) {
// This will prevent auto sizing in this.setThumbContainerSizeAndPos()
this.sizeSpecifiedInCSS = true;
}
}
};
// Set the size to be about a quarter of the size of video. Unless option dynamicSize === false, in which case it needs to be set in CSS
setThumbContainerSizeAndPos() {
setThumbContainerSizeAndPos = () => {
if (!this.sizeSpecifiedInCSS) {
const thumbWidth = Math.floor(this.thumbContainerHeight * this.thumbAspectRatio);
this.elements.thumb.imageContainer.style.height = `${this.thumbContainerHeight}px`;
@@ -653,9 +653,9 @@ class PreviewThumbnails {
}
this.setThumbContainerPos();
}
};
setThumbContainerPos() {
setThumbContainerPos = () => {
const seekbarRect = this.player.elements.progress.getBoundingClientRect();
const plyrRect = this.player.elements.container.getBoundingClientRect();
const { container } = this.elements.thumb;
@@ -674,20 +674,20 @@ class PreviewThumbnails {
}
container.style.left = `${previewPos}px`;
}
};
// Can't use 100% width, in case the video is a different aspect ratio to the video container
setScrubbingContainerSize() {
setScrubbingContainerSize = () => {
const { width, height } = fitRatio(this.thumbAspectRatio, {
width: this.player.media.clientWidth,
height: this.player.media.clientHeight,
});
this.elements.scrubbing.container.style.width = `${width}px`;
this.elements.scrubbing.container.style.height = `${height}px`;
}
};
// Sprites need to be offset to the correct location
setImageSizeAndOffset(previewImage, frame) {
setImageSizeAndOffset = (previewImage, frame) => {
if (!this.usingSprites) {
return;
}
@@ -703,7 +703,7 @@ class PreviewThumbnails {
previewImage.style.left = `-${frame.x * multiplier}px`;
// eslint-disable-next-line no-param-reassign
previewImage.style.top = `-${frame.y * multiplier}px`;
}
};
}
export default PreviewThumbnails;
+6 -3
View File
@@ -11,7 +11,7 @@ import fetch from '../utils/fetch';
import is from '../utils/is';
import loadScript from '../utils/load-script';
import { format, stripHTML } from '../utils/strings';
import { setAspectRatio } from '../utils/style';
import { roundAspectRatio, setAspectRatio } from '../utils/style';
import { buildUrlParams } from '../utils/urls';
// Parse Vimeo ID from URL
@@ -104,7 +104,10 @@ const vimeo = {
const src = format(player.config.urls.vimeo.iframe, id, params);
iframe.setAttribute('src', src);
iframe.setAttribute('allowfullscreen', '');
iframe.setAttribute('allow', 'autoplay,fullscreen,picture-in-picture');
iframe.setAttribute(
'allow',
['autoplay', 'fullscreen', 'picture-in-picture', 'encrypted-media', 'accelerometer', 'gyroscope'].join('; '),
);
// Set the referrer policy if required
if (!is.empty(referrerPolicy)) {
@@ -291,7 +294,7 @@ const vimeo = {
// Set aspect ratio based on video size
Promise.all([player.embed.getVideoWidth(), player.embed.getVideoHeight()]).then((dimensions) => {
const [width, height] = dimensions;
player.embed.ratio = [width, height];
player.embed.ratio = roundAspectRatio(width, height);
setAspectRatio.call(this);
});
+2 -2
View File
@@ -11,7 +11,7 @@ import loadImage from '../utils/load-image';
import loadScript from '../utils/load-script';
import { extend } from '../utils/objects';
import { format, generateId } from '../utils/strings';
import { setAspectRatio } from '../utils/style';
import { roundAspectRatio, setAspectRatio } from '../utils/style';
// Parse YouTube ID from URL
function parseId(url) {
@@ -90,7 +90,7 @@ const youtube = {
ui.setTitle.call(this);
// Set aspect ratio
this.embed.ratio = [width, height];
this.embed.ratio = roundAspectRatio(width, height);
}
setAspectRatio.call(this);
+30 -1
View File
@@ -138,10 +138,15 @@ declare class Plyr {
*/
ratio?: string;
/**
* Access Elements cache
*/
elements: Plyr.Elements;
/**
* Returns the current video Provider
*/
readonly provider: 'html5' | 'vimeo' | 'youtube';
readonly provider: Plyr.Provider;
/**
* Returns the native API for Vimeo or Youtube players
@@ -510,6 +515,8 @@ declare namespace Plyr {
interface QualityOptions {
default: number;
forced?: boolean;
onChange?: (quality: number) => void;
options: number[];
}
@@ -542,6 +549,7 @@ declare namespace Plyr {
fallback?: boolean | 'force';
allowAudio?: boolean;
iosNative?: boolean;
container?: string;
}
interface CaptionOptions {
@@ -560,6 +568,27 @@ declare namespace Plyr {
src?: string | string[];
}
export interface Elements {
buttons: {
airplay?: HTMLButtonElement;
captions?: HTMLButtonElement;
download?: HTMLButtonElement;
fastForward?: HTMLButtonElement;
fullscreen?: HTMLButtonElement;
mute?: HTMLButtonElement;
pip?: HTMLButtonElement;
play?: HTMLButtonElement | HTMLButtonElement[];
restart?: HTMLButtonElement;
rewind?: HTMLButtonElement;
settings?: HTMLButtonElement;
};
captions: HTMLElement | null;
container: HTMLElement | null;
controls: HTMLElement | null;
fullscreen: HTMLElement | null;
wrapper: HTMLElement | null;
}
interface SourceInfo {
/**
* Note: YouTube and Vimeo are currently not supported as audio sources.
+36 -38
View File
@@ -1,6 +1,6 @@
// ==========================================================================
// Plyr
// plyr.js v3.6.3
// plyr.js v3.6.8
// https://github.com/sampotts/plyr
// License: The MIT License (MIT)
// ==========================================================================
@@ -29,7 +29,7 @@ import loadSprite from './utils/load-sprite';
import { clamp } from './utils/numbers';
import { cloneDeep, extend } from './utils/objects';
import { silencePromise } from './utils/promise';
import { getAspectRatio, reduceAspectRatio, setAspectRatio, validateRatio } from './utils/style';
import { getAspectRatio, reduceAspectRatio, setAspectRatio, validateAspectRatio } from './utils/style';
import { parseUrl } from './utils/urls';
// Private properties
@@ -206,7 +206,7 @@ class Plyr {
}
// Unsupported or missing provider
if (is.empty(this.provider) || !Object.keys(providers).includes(this.provider)) {
if (is.empty(this.provider) || !Object.values(providers).includes(this.provider)) {
this.debug.error('Setup failed: Invalid provider');
return;
}
@@ -355,7 +355,7 @@ class Plyr {
/**
* Play the media, or play the advertisement (if they are not blocked)
*/
play() {
play = () => {
if (!is.function(this.media.play)) {
return null;
}
@@ -367,18 +367,18 @@ class Plyr {
// Return the promise (for HTML5)
return this.media.play();
}
};
/**
* Pause the media
*/
pause() {
pause = () => {
if (!this.playing || !is.function(this.media.pause)) {
return null;
}
return this.media.pause();
}
};
/**
* Get playing state
@@ -412,7 +412,7 @@ class Plyr {
* Toggle playback based on current status
* @param {Boolean} input
*/
togglePlay(input) {
togglePlay = (input) => {
// Toggle based on current state if nothing passed
const toggle = is.boolean(input) ? input : !this.playing;
@@ -421,42 +421,42 @@ class Plyr {
}
return this.pause();
}
};
/**
* Stop playback
*/
stop() {
stop = () => {
if (this.isHTML5) {
this.pause();
this.restart();
} else if (is.function(this.media.stop)) {
this.media.stop();
}
}
};
/**
* Restart playback
*/
restart() {
restart = () => {
this.currentTime = 0;
}
};
/**
* Rewind
* @param {Number} seekTime - how far to rewind in seconds. Defaults to the config.seekTime
*/
rewind(seekTime) {
rewind = (seekTime) => {
this.currentTime -= is.number(seekTime) ? seekTime : this.config.seekTime;
}
};
/**
* Fast forward
* @param {Number} seekTime - how far to fast forward in seconds. Defaults to the config.seekTime
*/
forward(seekTime) {
forward = (seekTime) => {
this.currentTime += is.number(seekTime) ? seekTime : this.config.seekTime;
}
};
/**
* Seek to a time
@@ -582,18 +582,18 @@ class Plyr {
* Increase volume
* @param {Boolean} step - How much to decrease by (between 0 and 1)
*/
increaseVolume(step) {
increaseVolume = (step) => {
const volume = this.media.muted ? 0 : this.volume;
this.volume = volume + (is.number(step) ? step : 0);
}
};
/**
* Decrease volume
* @param {Boolean} step - How much to decrease by (between 0 and 1)
*/
decreaseVolume(step) {
decreaseVolume = (step) => {
this.increaseVolume(-step);
}
};
/**
* Set muted state
@@ -916,12 +916,12 @@ class Plyr {
return;
}
if (!is.string(input) || !validateRatio(input)) {
if (!is.string(input) || !validateAspectRatio(input)) {
this.debug.error(`Invalid aspect ratio specified (${input})`);
return;
}
this.config.ratio = input;
this.config.ratio = reduceAspectRatio(input);
setAspectRatio.call(this);
}
@@ -1033,18 +1033,18 @@ class Plyr {
* Trigger the airplay dialog
* TODO: update player with state, support, enabled
*/
airplay() {
airplay = () => {
// Show dialog if supported
if (support.airplay) {
this.media.webkitShowPlaybackTargetPicker();
}
}
};
/**
* Toggle the player controls
* @param {Boolean} [toggle] - Whether to show the controls
*/
toggleControls(toggle) {
toggleControls = (toggle) => {
// Don't toggle if missing UI support or if it's audio
if (this.supported.ui && !this.isAudio) {
// Get state before change
@@ -1074,34 +1074,34 @@ class Plyr {
}
return false;
}
};
/**
* Add event listeners
* @param {String} event - Event type
* @param {Function} callback - Callback for when event occurs
*/
on(event, callback) {
on = (event, callback) => {
on.call(this, this.elements.container, event, callback);
}
};
/**
* Add event listeners once
* @param {String} event - Event type
* @param {Function} callback - Callback for when event occurs
*/
once(event, callback) {
once = (event, callback) => {
once.call(this, this.elements.container, event, callback);
}
};
/**
* Remove event listeners
* @param {String} event - Event type
* @param {Function} callback - Callback for when event occurs
*/
off(event, callback) {
off = (event, callback) => {
off(this.elements.container, event, callback);
}
};
/**
* Destroy an instance
@@ -1110,7 +1110,7 @@ class Plyr {
* @param {Function} callback - Callback for when destroy is complete
* @param {Boolean} soft - Whether it's a soft destroy (for source changes etc)
*/
destroy(callback, soft = false) {
destroy = (callback, soft = false) => {
if (!this.ready) {
return;
}
@@ -1208,15 +1208,13 @@ class Plyr {
// Vimeo does not always return
setTimeout(done, 200);
}
}
};
/**
* Check for support for a mime type (HTML5 only)
* @param {String} type - Mime type
*/
supports(type) {
return support.mime.call(this, type);
}
supports = (type) => support.mime.call(this, type);
/**
* Check for support
+1 -1
View File
@@ -1,6 +1,6 @@
// ==========================================================================
// Plyr Polyfilled Build
// plyr.js v3.6.3
// plyr.js v3.6.8
// https://github.com/sampotts/plyr
// License: The MIT License (MIT)
// ==========================================================================
+4 -4
View File
@@ -31,7 +31,7 @@ class Storage {
}
}
get(key) {
get = (key) => {
if (!Storage.supported || !this.enabled) {
return null;
}
@@ -45,9 +45,9 @@ class Storage {
const json = JSON.parse(store);
return is.string(key) && key.length ? json[key] : json;
}
};
set(object) {
set = (object) => {
// Bail if we don't have localStorage support or it's disabled
if (!Storage.supported || !this.enabled) {
return;
@@ -71,7 +71,7 @@ class Storage {
// Update storage
window.localStorage.setItem(this.key, JSON.stringify(storage));
}
};
}
export default Storage;
+4 -2
View File
@@ -4,11 +4,13 @@
// ==========================================================================
const browser = {
isIE: /* @cc_on!@ */ false || !!document.documentMode,
isIE: Boolean(window.document.documentMode),
isEdge: window.navigator.userAgent.includes('Edge'),
isWebkit: 'WebkitAppearance' in document.documentElement.style && !/Edge/.test(navigator.userAgent),
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;
+7 -1
View File
@@ -13,7 +13,6 @@ const isFunction = (input) => getConstructor(input) === Function;
const isArray = (input) => Array.isArray(input);
const isWeakMap = (input) => instanceOf(input, WeakMap);
const isNodeList = (input) => instanceOf(input, NodeList);
const isElement = (input) => instanceOf(input, Element);
const isTextNode = (input) => getConstructor(input) === Text;
const isEvent = (input) => instanceOf(input, Event);
const isKeyboardEvent = (input) => instanceOf(input, KeyboardEvent);
@@ -21,6 +20,13 @@ const isCue = (input) => instanceOf(input, window.TextTrackCue) || instanceOf(in
const isTrack = (input) => instanceOf(input, TextTrack) || (!isNullOrUndefined(input) && isString(input.kind));
const isPromise = (input) => instanceOf(input, Promise) && isFunction(input.then);
const isElement = (input) =>
input !== null &&
typeof input === 'object' &&
input.nodeType === 1 &&
typeof input.style === 'object' &&
typeof input.ownerDocument === 'object';
const isEmpty = (input) =>
isNullOrUndefined(input) ||
((isString(input) || isArray(input) || isNodeList(input)) && !input.length) ||
+71 -9
View File
@@ -2,9 +2,39 @@
// Style utils
// ==========================================================================
import { closest } from './arrays';
import is from './is';
export function validateRatio(input) {
// 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
const standardRatios = [
[1, 1],
[4, 3],
[3, 4],
[5, 4],
[4, 5],
[3, 2],
[2, 3],
[16, 10],
[10, 16],
[16, 9],
[9, 16],
[21, 9],
[9, 21],
[32, 9],
[9, 32],
].reduce((out, [x, y]) => ({ ...out, [x / y]: [x, y] }), {});
// Validate an aspect ratio
export function validateAspectRatio(input) {
if (!is.array(input) && (!is.string(input) || !input.includes(':'))) {
return false;
}
@@ -14,6 +44,7 @@ export function validateRatio(input) {
return ratio.map(Number).every(is.number);
}
// Reduce an aspect ratio to it's lowest form
export function reduceAspectRatio(ratio) {
if (!is.array(ratio) || !ratio.every(is.number)) {
return null;
@@ -26,8 +57,9 @@ export function reduceAspectRatio(ratio) {
return [width / divider, height / divider];
}
// Calculate an aspect ratio
export function getAspectRatio(input) {
const parse = (ratio) => (validateRatio(ratio) ? ratio.split(':').map(Number) : null);
const parse = (ratio) => (validateAspectRatio(ratio) ? ratio.split(':').map(Number) : null);
// Try provided ratio
let ratio = parse(input);
@@ -44,10 +76,10 @@ export function getAspectRatio(input) {
// Get from HTML5 video
if (ratio === null && this.isHTML5) {
const { videoWidth, videoHeight } = this.media;
ratio = reduceAspectRatio([videoWidth, videoHeight]);
ratio = [videoWidth, videoHeight];
}
return ratio;
return reduceAspectRatio(ratio);
}
// Set aspect ratio for responsive container
@@ -58,10 +90,20 @@ export function setAspectRatio(input) {
const { wrapper } = this.elements;
const ratio = getAspectRatio.call(this, input);
const [w, h] = is.array(ratio) ? ratio : [0, 0];
const padding = (100 / w) * h;
wrapper.style.paddingBottom = `${padding}%`;
if (!is.array(ratio)) {
return {};
}
const [x, y] = reduceAspectRatio(ratio);
const useNative = supportsCSS(`aspect-ratio: ${x}/${y}`);
const padding = (100 / x) * y;
if (useNative) {
wrapper.style.aspectRatio = `${x}/${y}`;
} else {
wrapper.style.paddingBottom = `${padding}%`;
}
// For Vimeo we have an extra <div> to hide the standard controls and UI
if (this.isVimeo && !this.config.vimeo.premium && this.supported.ui) {
@@ -74,10 +116,30 @@ export function setAspectRatio(input) {
this.media.style.transform = `translateY(-${offset}%)`;
}
} else if (this.isHTML5) {
wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null);
wrapper.classList.add(this.config.classNames.videoFixedRatio);
}
return { padding, ratio };
}
export default { setAspectRatio };
// Round an aspect ratio to closest standard ratio
export function roundAspectRatio(x, y, tolerance = 0.05) {
const ratio = x / y;
const closestRatio = closest(Object.keys(standardRatios), ratio);
// Check match is within tolerance
if (Math.abs(closestRatio - ratio) <= tolerance) {
return standardRatios[closestRatio];
}
// No match
return [x, y];
}
// 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];
}
+6 -1
View File
@@ -3,7 +3,7 @@
// --------------------------------------------------------------
.plyr__poster {
background-color: #000;
background-color: var(--plyr-video-background, $plyr-video-background);
background-position: 50% 50%;
background-repeat: no-repeat;
background-size: contain;
@@ -20,3 +20,8 @@
.plyr--stopped.plyr__poster-enabled .plyr__poster {
opacity: 1;
}
// Allow interaction with YouTube controls while paused
.plyr--youtube.plyr--paused.plyr__poster-enabled:not(.plyr--stopped) .plyr__poster {
display: none;
}
+1 -1
View File
@@ -14,7 +14,7 @@
margin-right: $plyr-control-spacing;
}
@media (max-width: calc(#{$plyr-bp-md} - 1px)) {
@media (max-width: ($plyr-bp-md - 1px)) {
display: none;
}
}
-11
View File
@@ -59,17 +59,6 @@
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
.plyr__control .icon--exit-fullscreen {
display: block;
+1
View File
@@ -3,6 +3,7 @@
// ==========================================================================
$plyr-color-main: var(--plyr-color-main, hsl(198, 100%, 50%)) !default;
$plyr-video-background: var(--plyr-video-background, rgba(0,0,0,1)) !default;
// Grayscale
$plyr-color-gray-900: hsl(216, 15%, 16%) !default;
+16 -14
View File
@@ -4,7 +4,7 @@
// Container
.plyr--video {
background: #000;
background: var(--plyr-video-background, $plyr-video-background);
overflow: hidden;
&.plyr--menu-open {
@@ -13,8 +13,7 @@
}
.plyr__video-wrapper {
background: #000;
height: 100%;
background: var(--plyr-video-background, $plyr-video-background);
margin: auto;
overflow: hidden;
position: relative;
@@ -26,29 +25,32 @@ $embed-padding: ((100 / 16) * 9);
.plyr__video-embed,
.plyr__video-wrapper--fixed-ratio {
height: 0;
padding-bottom: to-percentage($embed-padding);
@supports not (aspect-ratio: 16 / 9) {
height: 0;
padding-bottom: to-percentage($embed-padding);
position: relative;
}
aspect-ratio: 16 / 9;
}
.plyr__video-embed iframe,
.plyr__video-wrapper--fixed-ratio video {
border: 0;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
// If the full custom UI is supported
.plyr--full-ui .plyr__video-embed {
// For Vimeo, if the full custom UI is supported
.plyr--full-ui .plyr__video-embed > .plyr__video-embed__container {
$height: 240;
$offset: to-percentage(($height - $embed-padding) / ($height / 50));
// Only used for Vimeo
> .plyr__video-embed__container {
padding-bottom: to-percentage($height);
position: relative;
transform: translateY(-$offset);
}
padding-bottom: to-percentage($height);
position: relative;
transform: translateY(-$offset);
}
// Controls container
+11 -2
View File
@@ -16,7 +16,7 @@ const resolve = require('rollup-plugin-node-resolve');
const sass = require('gulp-sass');
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
const clean = require('postcss-clean');
const cssnano = require('cssnano');
const customprops = require('postcss-custom-properties');
// Images
const svgstore = require('gulp-svgstore');
@@ -118,6 +118,7 @@ Object.entries(build.js).forEach(([filename, entry]) => {
},
],
],
plugins: ['@babel/plugin-proposal-class-properties'],
babelrc: false,
exclude: [/\/core-js\//],
}),
@@ -157,7 +158,15 @@ Object.entries(build.css).forEach(([filename, entry]) => {
.src(src)
.pipe(plumber())
.pipe(sass())
.pipe(postcss([customprops(), autoprefixer(), clean()]))
.pipe(
postcss([
customprops(),
autoprefixer(),
cssnano({
preset: 'default',
}),
]),
)
.pipe(size(sizeOptions))
.pipe(gulp.dest(dist)),
);
+5 -50
View File
@@ -10,15 +10,13 @@ const gulp = require('gulp');
const gitbranch = require('git-branch');
const rename = require('gulp-rename');
const replace = require('gulp-replace');
const ansi = require('ansi-colors');
const { green, cyan, bold } = require('colorette');
const log = require('fancy-log');
const open = require('gulp-open');
const size = require('gulp-size');
const through = require('through2');
// Deployment
const aws = require('aws-sdk');
const publish = require('gulp-awspublish');
const FastlyPurge = require('fastly-purge');
// Configs
const pkg = require('../package.json');
const deploy = require('../deploy.json');
@@ -53,14 +51,6 @@ const paths = {
],
};
// Get credentials
let credentials = {};
try {
credentials = require('../credentials.json'); //eslint-disable-line
} catch (e) {
// Do nothing
}
// Get branch info
const branch = {
current: gitbranch.sync(),
@@ -128,7 +118,7 @@ gulp.task('version', (done) => {
const { domain } = deploy.cdn;
log(`Updating version in files to ${ansi.green.bold(version)}...`);
log(`Updating version in files to ${green(bold(version))}...`);
// Replace versioned URLs in source
const files = ['plyr.js', 'plyr.polyfilled.js', 'config/defaults.js'];
@@ -156,7 +146,7 @@ gulp.task('cdn', (done) => {
throw new Error('No publisher instance. Check AWS configuration.');
}
log(`Uploading ${ansi.green.bold(pkg.version)} to ${ansi.cyan(domain)}...`);
log(`Uploading ${green(bold(pkg.version))} to ${cyan(domain)}...`);
// Upload to CDN
return (
@@ -177,41 +167,6 @@ gulp.task('cdn', (done) => {
);
});
// Purge the fastly cache incase any 403/404 are cached
gulp.task('purge', () => {
if (!Object.keys(credentials).includes('fastly')) {
throw new Error('Fastly credentials required to purge cache.');
}
const { fastly } = credentials;
const list = [];
return gulp
.src(paths.upload)
.pipe(
through.obj((file, enc, cb) => {
const filename = file.path.split('/').pop();
list.push(`${versionPath}${filename.replace(minSuffix, '')}`);
cb(null);
}),
)
.on('end', () => {
const purge = new FastlyPurge(fastly.token);
list.forEach((url) => {
log(`Purging ${ansi.cyan(url)}...`);
purge.url(url, (error, result) => {
if (error) {
log.error(error);
} else if (result) {
log(result);
}
});
});
});
});
// Publish to demo bucket
gulp.task('demo', (done) => {
if (!canDeploy()) {
@@ -226,7 +181,7 @@ gulp.task('demo', (done) => {
throw new Error('No publisher instance. Check AWS configuration.');
}
log(`Uploading ${ansi.green.bold(pkg.version)} to ${ansi.cyan(domain)}...`);
log(`Uploading ${green(bold(pkg.version))} to ${cyan(domain)}...`);
// Replace versioned files in README.md
gulp
@@ -271,4 +226,4 @@ gulp.task('open', () => {
});
// Do everything
gulp.task('deploy', gulp.series('cdn', 'demo', 'purge', 'open'));
gulp.task('deploy', gulp.series('cdn', 'demo', 'open'));
+2758 -2797
View File
File diff suppressed because it is too large Load Diff