From f87a10ae0b59df0f30d017fe85975c757487a198 Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 17 Jan 2016 01:25:11 +1100 Subject: Fix for event listeners being duplicated on source change --- src/js/plyr.js | 75 +++++++++++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 52f4b9d9..ca160ac6 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -2196,13 +2196,15 @@ } } - // Listen for events - function _listeners() { + // Listen for control events + function _controlListeners() { // IE doesn't support input event, so we fallback to change var inputEvent = (plyr.browser.name == 'IE' ? 'change' : 'input'); // Click play/pause helper - function _togglePlay(play) { + function _togglePlay() { + var play = plyr.media.paused; + // Toggle playback if (play) { _play(); @@ -2264,10 +2266,10 @@ } // Play - _proxyHandler(plyr.buttons.play, 'click', config.handlers.play, function() { _togglePlay(true); }); + _proxyHandler(plyr.buttons.play, 'click', config.handlers.play, _togglePlay); // Pause - _proxyHandler(plyr.buttons.pause, 'click', config.handlers.pause, function() { _togglePlay(); }); + _proxyHandler(plyr.buttons.pause, 'click', config.handlers.pause, _togglePlay); // Restart _proxyHandler(plyr.buttons.restart, 'click', config.handlers.restart, _seek); @@ -2297,6 +2299,28 @@ _on(document, fullscreen.fullScreenEventName, _toggleFullscreen); } + // Captions + _on(plyr.buttons.captions, 'click', _toggleCaptions); + + // Click video + if (plyr.type === 'video' && config.click) { + _on(plyr.videoContainer, 'click', function() { + if (plyr.media.paused) { + _play(); + } + else if (plyr.media.ended) { + _seek(); + _play(); + } + else { + _pause(); + } + }); + } + } + + // Listen for media events + function _mediaListeners() { // Time change on media _on(plyr.media, 'timeupdate seeking', _timeUpdate); @@ -2306,9 +2330,6 @@ // Display duration _on(plyr.media, 'loadedmetadata', _displayDuration); - // Captions - _on(plyr.buttons.captions, 'click', _toggleCaptions); - // Handle the media finishing _on(plyr.media, 'ended', function() { // Clear @@ -2331,22 +2352,6 @@ // Loading _on(plyr.media, 'waiting canplay seeked', _checkLoading); - - // Click video - if (plyr.type === 'video' && config.click) { - _on(plyr.videoContainer, 'click', function() { - if (plyr.media.paused) { - _play(); - } - else if (plyr.media.ended) { - _seek(); - _play(); - } - else { - _pause(); - } - }); - } } // Destroy an instance @@ -2482,26 +2487,32 @@ return; } - // Inject custom controls - if (!_getElements(config.selectors.controls.wrapper).length) { + // Inject custom controls if not present + var controlsMissing = !_getElements(config.selectors.controls.wrapper).length; + if (controlsMissing) { // Inject custom controls _injectControls(); } - // Remove native controls - _toggleControls(); - // Find the elements if (!_findElements()) { return; } + // If the controls are injected, re-bind listeners for controls + if (controlsMissing) { + _controlListeners(); + } + + // Media element listeners + _mediaListeners(); + + // Remove native controls + _toggleControls(); + // Setup fullscreen _setupFullscreen(); - // Listeners - _listeners(); - // Captions _setupCaptions(); -- cgit v1.2.3 From dbe152a4c104906ab872f1ecd80ba3929db809af Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 17 Jan 2016 19:22:43 +1100 Subject: LESS/SASS variable name spacing and clean up --- src/less/plyr.less | 254 ++++++++++++++++++++++++++--------------------------- src/sass/plyr.scss | 251 +++++++++++++++++++++++++--------------------------- 2 files changed, 246 insertions(+), 259 deletions(-) (limited to 'src') diff --git a/src/less/plyr.less b/src/less/plyr.less index fde725d7..955bd824 100644 --- a/src/less/plyr.less +++ b/src/less/plyr.less @@ -7,78 +7,78 @@ // ------------------------------- // Colors -@blue: #3498DB; -@gray-dark: #343F4A; -@gray: #565D64; -@gray-light: #6B7D86; -@gray-lighter: #CBD0D3; -@off-white: #D6DADD; +@plyr-blue: #3498DB; +@plyr-gray-dark: #343F4A; +@plyr-gray: #565D64; +@plyr-gray-light: #6B7D86; +@plyr-gray-lighter: #CBD0D3; +@plyr-off-white: #D6DADD; // Font sizes -@font-size-small: 14px; -@font-size-base: 16px; +@plyr-font-size-small: 14px; +@plyr-font-size-base: 16px; // Captions -@font-size-captions-base: ceil(@font-size-base * 1.25); -@font-size-captions-medium: ceil(@font-size-base * 1.5); -@font-size-captions-large: (@font-size-base * 2); +@plyr-font-size-captions-base: ceil(@plyr-font-size-base * 1.25); +@plyr-font-size-captions-medium: ceil(@plyr-font-size-base * 1.5); +@plyr-font-size-captions-large: (@plyr-font-size-base * 2); // Controls -@control-spacing: 10px; -@controls-bg: #fff; -@control-bg-hover: @blue; -.contrast-control-color(@controls-bg); -.contrast-control-color-hover(@control-bg-hover); +@plyr-control-spacing: 10px; +@plyr-controls-bg: #fff; +@plyr-control-bg-hover: @plyr-blue; +.contrast-control-color(@plyr-controls-bg); +.contrast-control-color-hover(@plyr-control-bg-hover); // Tooltips -@tooltip-bg: @controls-bg; -@tooltip-border-color: fade(@gray-dark, 10%); -@tooltip-border-width: 1px; -@tooltip-shadow: 0 0 5px @tooltip-border-color, 0 0 0 @tooltip-border-width @tooltip-border-color; -@tooltip-color: @control-color; -@tooltip-padding: @control-spacing; -@tooltip-arrow-size: 6px; -@tooltip-radius: 3px; +@plyr-tooltip-bg: @plyr-controls-bg; +@plyr-tooltip-border-color: fade(@plyr-gray-dark, 10%); +@plyr-tooltip-border-width: 1px; +@plyr-tooltip-shadow: 0 0 5px @plyr-tooltip-border-color, 0 0 0 @plyr-tooltip-border-width @plyr-tooltip-border-color; +@plyr-tooltip-color: @plyr-control-color; +@plyr-tooltip-padding: @plyr-control-spacing; +@plyr-tooltip-arrow-size: 6px; +@plyr-tooltip-radius: 3px; // Progress -@progress-bg: fade(@gray, 20%); -@progress-playing-bg: @blue; -@progress-buffered-bg: fade(@gray, 25%); -@progress-loading-size: 40px; -@progress-loading-bg: rgba(0,0,0, .15); +@plyr-progress-bg: fade(@plyr-gray, 20%); +@plyr-progress-playing-bg: @plyr-blue; +@plyr-progress-buffered-bg: fade(@plyr-gray, 25%); +@plyr-progress-loading-size: 40px; +@plyr-progress-loading-bg: fade(#000, 15%); // Volume -@volume-track-height: 6px; -@volume-track-bg: darken(@controls-bg, 10%); -@volume-thumb-height: (@volume-track-height * 2); -@volume-thumb-width: (@volume-track-height * 2); -@volume-thumb-bg: @control-color; -@volume-thumb-bg-focus: @control-bg-hover; +@plyr-volume-track-height: 6px; +@plyr-volume-track-bg: darken(@plyr-controls-bg, 10%); +@plyr-volume-thumb-height: (@plyr-volume-track-height * 2); +@plyr-volume-thumb-width: (@plyr-volume-track-height * 2); +@plyr-volume-thumb-bg: @plyr-control-color; +@plyr-volume-thumb-bg-focus: @plyr-control-bg-hover; // Breakpoints -@bp-control-split: 560px; // When controls split into left/right -@bp-captions-large: 768px; // When captions jump to the larger font size +@plyr-bp-control-split: 560px; // When controls split into left/right +@plyr-bp-captions-large: 768px; // When captions jump to the larger font size // Animation // --------------------------------------- -@keyframes progress { - to { background-position: @progress-loading-size 0; } +@keyframes plyr-progress { + to { background-position: @plyr-progress-loading-size 0; } } // Mixins // ------------------------------- // Contrast -.contrast-control-color(@color: "") when (lightness(@color) >= 65%) { - @control-color: @gray-light; +.contrast-control-color(@plyr-color: "") when (lightness(@plyr-color) >= 65%) { + @plyr-control-color: @plyr-gray-light; } -.contrast-control-color(@color: "") when (lightness(@color) < 65%) { - @control-color: @gray-lighter; +.contrast-control-color(@plyr-color: "") when (lightness(@plyr-color) < 65%) { + @plyr-control-color: @plyr-gray-lighter; } -.contrast-control-color-hover(@color: "") when (lightness(@color) >= 65%) { - @control-color-hover: @gray; +.contrast-control-color-hover(@plyr-color: "") when (lightness(@plyr-color) >= 65%) { + @plyr-control-color-hover: @plyr-gray; } -.contrast-control-color-hover(@color: "") when (lightness(@color) < 65%) { - @control-color-hover: #fff; +.contrast-control-color-hover(@plyr-color: "") when (lightness(@plyr-color) < 65%) { + @plyr-control-color-hover: #fff; } // Font smoothing @@ -91,40 +91,27 @@ -webkit-font-smoothing: subpixel-antialiased; } -// Contain floats: nicolasgallagher.com/micro-clearfix-hack/ -.clearfix() { - zoom: 1; - &:before, - &:after { content: ""; display: table; } - &:after { clear: both; } -} -// Tab focus styles -.tab-focus() { - outline: 1px dotted fade(@gray-dark, 80%); - outline-offset: 3px; -} - // styling .volume-thumb() { - height: @volume-thumb-height; - width: @volume-thumb-width; - background: @volume-thumb-bg; + height: @plyr-volume-thumb-height; + width: @plyr-volume-thumb-width; + background: @plyr-volume-thumb-bg; border: 0; border-radius: 100%; transition: background .3s ease; cursor: ew-resize; } .volume-track() { - height: @volume-track-height; - background: @volume-track-bg; + height: @plyr-volume-track-height; + background: @plyr-volume-track-bg; border: 0; - border-radius: (@volume-track-height / 2); + border-radius: (@plyr-volume-track-height / 2); } .seek-thumb() { background: transparent; border: 0; - width: (@control-spacing * 4); - height: @control-spacing; + width: (@plyr-control-spacing * 4); + height: @plyr-control-spacing; transform: translateX(-50%); } .seek-track() { @@ -208,49 +195,55 @@ bottom: 0; left: 0; width: 100%; - padding: (@control-spacing * 2) (@control-spacing * 2) (@control-spacing * 3); + padding: (@plyr-control-spacing * 2) (@plyr-control-spacing * 2) (@plyr-control-spacing * 3); color: #fff; - font-size: @font-size-captions-base; + font-size: @plyr-font-size-captions-base; text-align: center; .font-smoothing(); span { border-radius: 2px; padding: 3px 10px; - background: rgba(0,0,0, .9); + background: fade(#000, 90%); } span:empty { display: none; } - @media (min-width: @bp-captions-large) { - font-size: @font-size-captions-medium; + @media (min-width: @plyr-bp-captions-large) { + font-size: @plyr-font-size-captions-medium; } } &--captions-active &__captions { display: block; } &--fullscreen-active &__captions { - font-size: @font-size-captions-large; + font-size: @plyr-font-size-captions-large; } // Playback controls &__controls { - .clearfix(); .font-smoothing(); position: relative; - padding: @control-spacing; - background: @controls-bg; + padding: @plyr-control-spacing; + background: @plyr-controls-bg; line-height: 1; text-align: center; - box-shadow: 0 1px 1px fade(@gray-dark, 20%); + box-shadow: 0 1px 1px fade(@plyr-gray-dark, 20%); + + // Clear floats + &::after { + content: ''; + display: table; + clear: both; + } // Layout &--right { display: block; - margin: @control-spacing auto 0; + margin: @plyr-control-spacing auto 0; } - @media (min-width: @bp-control-split) { + @media (min-width: @plyr-bp-control-split) { &--left { float: left; } @@ -265,13 +258,13 @@ display: inline-block; vertical-align: middle; margin: 0 2px; - padding: (@control-spacing / 2) @control-spacing; + padding: (@plyr-control-spacing / 2) @plyr-control-spacing; overflow: hidden; border: 0; background: transparent; border-radius: 3px; cursor: pointer; - color: @control-color; + color: @plyr-control-color; transition: background .3s ease, color .3s ease, opacity .3s ease; svg { @@ -285,8 +278,8 @@ // Hover and tab focus &.tab-focus:focus, &:hover { - background: @control-bg-hover; - color: @control-color-hover; + background: @plyr-control-bg-hover; + color: @plyr-control-color-hover; } // Default focus &:focus { @@ -305,24 +298,24 @@ .plyr__time { display: inline-block; vertical-align: middle; - margin-left: @control-spacing; - color: @control-color; + margin-left: @plyr-control-spacing; + color: @plyr-control-color; font-weight: 600; - font-size: @font-size-small; + font-size: @plyr-font-size-small; } // Media duration hidden on small screens .plyr__time + .plyr__time { display: none; - @media (min-width: @bp-control-split) { + @media (min-width: @plyr-bp-control-split) { display: inline-block; } // Add a slash in before &::before { content: '\2044'; - margin-right: @control-spacing; + margin-right: @plyr-control-spacing; } } } @@ -332,19 +325,19 @@ position: absolute; z-index: 2; bottom: 100%; - margin-bottom: @tooltip-padding; - padding: @tooltip-padding (@tooltip-padding * 1.5); + margin-bottom: @plyr-tooltip-padding; + padding: @plyr-tooltip-padding (@plyr-tooltip-padding * 1.5); opacity: 0; - background: @tooltip-bg; - box-shadow: @tooltip-shadow; - border-radius: @tooltip-radius; - color: @tooltip-color; - font-size: @font-size-small; + background: @plyr-tooltip-bg; + box-shadow: @plyr-tooltip-shadow; + border-radius: @plyr-tooltip-radius; + color: @plyr-tooltip-color; + font-size: @plyr-font-size-small; line-height: 1.5; font-weight: 600; - transform: translate(-50%, (@tooltip-padding * 3)) scale(.8); + transform: translate(-50%, (@plyr-tooltip-padding * 3)) scale(.8); transform-origin: 50% 100%; transition: transform .2s .1s ease, opacity .2s .1s ease; @@ -361,19 +354,19 @@ } // The border triangle &::after { - @border-arrow-size: (@tooltip-arrow-size + (@tooltip-border-width * 1)); - bottom: -(@border-arrow-size + @tooltip-border-width); - border-right: @border-arrow-size solid transparent; - border-top: @border-arrow-size solid @tooltip-border-color; - border-left: @border-arrow-size solid transparent; + @plyr-border-arrow-size: (@plyr-tooltip-arrow-size + (@plyr-tooltip-border-width * 1)); + bottom: -(@plyr-border-arrow-size + @plyr-tooltip-border-width); + border-right: @plyr-border-arrow-size solid transparent; + border-top: @plyr-border-arrow-size solid @plyr-tooltip-border-color; + border-left: @plyr-border-arrow-size solid transparent; z-index: 1; } // The background triangle &::before { - bottom: -@tooltip-arrow-size; - border-right: @tooltip-arrow-size solid transparent; - border-top: @tooltip-arrow-size solid @tooltip-bg; - border-left: @tooltip-arrow-size solid transparent; + bottom: -@plyr-tooltip-arrow-size; + border-right: @plyr-tooltip-arrow-size solid transparent; + border-top: @plyr-tooltip-arrow-size solid @plyr-tooltip-bg; + border-left: @plyr-tooltip-arrow-size solid transparent; z-index: 2; } } @@ -388,7 +381,8 @@ // Common range styles input[type='range'].tab-focus:focus { - .tab-focus(); + outline: 1px dotted fade(@plyr-gray-dark, 80%); + outline-offset: 3px; } // Playback progress @@ -399,8 +393,8 @@ left: 0; right: 0; width: 100%; - height: @control-spacing; - background: @progress-bg; + height: @plyr-control-spacing; + background: @plyr-progress-bg; &--buffer[value], &--played[value], @@ -409,7 +403,7 @@ left: 0; top: 0; width: 100%; - height: @control-spacing; + height: @plyr-control-spacing; margin: 0; padding: 0; vertical-align: top; @@ -435,10 +429,10 @@ } &--played[value] { z-index: 2; - color: @progress-playing-bg; + color: @plyr-progress-playing-bg; } &--buffer[value] { - color: @progress-buffered-bg; + color: @plyr-progress-buffered-bg; } // Seek control @@ -491,17 +485,17 @@ // Loading state &--loading .plyr__progress--buffer { - animation: progress 1s linear infinite; - background-size: @progress-loading-size @progress-loading-size; + animation: plyr-progress 1s linear infinite; + background-size: @plyr-progress-loading-size @plyr-progress-loading-size; background-repeat: repeat-x; - background-color: @progress-buffered-bg; + background-color: @plyr-progress-buffered-bg; background-image: linear-gradient( -45deg, - @progress-loading-bg 25%, + @plyr-progress-loading-bg 25%, transparent 25%, transparent 50%, - @progress-loading-bg 50%, - @progress-loading-bg 75%, + @plyr-progress-loading-bg 50%, + @plyr-progress-loading-bg 75%, transparent 75%, transparent); color: transparent; @@ -525,7 +519,7 @@ -webkit-appearance: none; -moz-appearance: none; width: 100px; - margin: 0 @control-spacing 0 0; + margin: 0 @plyr-control-spacing 0 0; padding: 0; cursor: pointer; background: transparent; @@ -537,7 +531,7 @@ } &::-webkit-slider-thumb { -webkit-appearance: none; - margin-top: -((@volume-thumb-height - @volume-track-height) / 2); + margin-top: -((@plyr-volume-thumb-height - @plyr-volume-track-height) / 2); .volume-thumb(); } @@ -551,10 +545,10 @@ // Microsoft &::-ms-track { - height: @volume-track-height; + height: @plyr-volume-track-height; background: transparent; border-color: transparent; - border-width: ((@volume-thumb-height - @volume-track-height) / 2) 0; + border-width: ((@plyr-volume-thumb-height - @plyr-volume-track-height) / 2) 0; color: transparent; } &::-ms-fill-lower, @@ -569,13 +563,13 @@ outline: 0; &::-webkit-slider-thumb { - background: @volume-thumb-bg-focus; + background: @plyr-volume-thumb-bg-focus; } &::-moz-range-thumb { - background: @volume-thumb-bg-focus; + background: @plyr-volume-thumb-bg-focus; } &::-ms-thumb { - background: @volume-thumb-bg-focus; + background: @plyr-volume-thumb-bg-focus; } } } @@ -596,12 +590,12 @@ // Audio specific styles // Position the progress within the container &--audio .plyr__controls { - padding-top: (@control-spacing * 2); + padding-top: (@plyr-control-spacing * 2); } &--audio .plyr__progress { bottom: auto; top: 0; - background: @off-white; + background: @plyr-off-white; } // Full screen mode @@ -635,14 +629,14 @@ // Hide controls when playing in full screen &--fullscreen--hide-controls&--fullscreen-active&--playing { .plyr__controls { - transform: translateY(100%) translateY(@control-spacing / 2); + transform: translateY(100%) translateY(@plyr-control-spacing / 2); transition: transform .3s .2s ease; } &.plyr--hover .plyr__controls { transform: translateY(0); } .plyr__captions { - bottom: (@control-spacing / 2); + bottom: (@plyr-control-spacing / 2); transition: bottom .3s .2s ease; } } @@ -654,7 +648,7 @@ top: auto; bottom: 90px; - @media (min-width: @bp-control-split) { + @media (min-width: @plyr-bp-control-split) { bottom: 60px; } } diff --git a/src/sass/plyr.scss b/src/sass/plyr.scss index 8bf481db..bbd52579 100644 --- a/src/sass/plyr.scss +++ b/src/sass/plyr.scss @@ -7,76 +7,76 @@ // ------------------------------- // Colors -$blue: #3498DB !default; -$gray-dark: #343F4A !default; -$gray: #565D64 !default; -$gray-light: #6B7D86 !default; -$gray-lighter: #CBD0D3 !default; -$off-white: #D6DADD !default; +$plyr-blue: #3498DB !default; +$plyr-gray-dark: #343F4A !default; +$plyr-gray: #565D64 !default; +$plyr-gray-light: #6B7D86 !default; +$plyr-gray-lighter: #CBD0D3 !default; +$plyr-off-white: #D6DADD !default; // Font sizes -$font-size-small: 14px !default; -$font-size-base: 16px !default; +$plyr-font-size-small: 14px !default; +$plyr-font-size-base: 16px !default; // Captions -$font-size-captions-base: ceil($font-size-base * 1.25) !default; -$font-size-captions-medium: ceil($font-size-base * 1.5) !default; -$font-size-captions-large: ($font-size-base * 2) !default; +$plyr-font-size-captions-base: ceil($plyr-font-size-base * 1.25) !default; +$plyr-font-size-captions-medium: ceil($plyr-font-size-base * 1.5) !default; +$plyr-font-size-captions-large: ($plyr-font-size-base * 2) !default; // Controls -$control-spacing: 10px !default; -$controls-bg: #fff !default; -$control-bg-hover: $blue !default; -$control-color: null !default; -$control-color-hover: null !default; +$plyr-control-spacing: 10px !default; +$plyr-controls-bg: #fff !default; +$plyr-control-bg-hover: $plyr-blue !default; +$plyr-control-color: null !default; +$plyr-control-color-hover: null !default; // Contrast -@if lightness($controls-bg) >= 65% { - $control-color: $gray-light; +@if lightness($plyr-controls-bg) >= 65% { + $plyr-control-color: $plyr-gray-light; } @else { - $control-color: $gray-lighter; + $plyr-control-color: $plyr-gray-lighter; } -@if lightness($control-bg-hover) >= 65% { - $control-color-hover: $gray; +@if lightness($plyr-control-bg-hover) >= 65% { + $plyr-control-color-hover: $plyr-gray; } @else { - $control-color-hover: #fff; + $plyr-control-color-hover: #fff; } // Tooltips -$tooltip-bg: $controls-bg !default; -$tooltip-border-color: transparentize(@gray-dark, .1) !default; -$tooltip-border-width: 1px; -$tooltip-shadow: 0 0 5px $tooltip-border-color, 0 0 0 $tooltip-border-width $tooltip-border-color; -$tooltip-color: $control-color !default; -$tooltip-padding: $control-spacing !default; -$tooltip-arrow-size: 6px !default; -$tooltip-radius: 3px !default; +$plyr-tooltip-bg: $plyr-controls-bg !default; +$plyr-tooltip-border-color: transparentize(@gray-dark, .1) !default; +$plyr-tooltip-border-width: 1px; +$plyr-tooltip-shadow: 0 0 5px $plyr-tooltip-border-color, 0 0 0 $plyr-tooltip-border-width $plyr-tooltip-border-color; +$plyr-tooltip-color: $plyr-control-color !default; +$plyr-tooltip-padding: $plyr-control-spacing !default; +$plyr-tooltip-arrow-size: 6px !default; +$plyr-tooltip-radius: 3px !default; // Progress -$progress-bg: transparentize($gray, .2) !default; -$progress-playing-bg: $blue !default; -$progress-buffered-bg: transparentize($gray, .25) !default; -$progress-loading-size: 40px !default; -$progress-loading-bg: rgba(0,0,0, .15) !default; +$plyr-progress-bg: transparentize($plyr-gray, .2) !default; +$plyr-progress-playing-bg: $plyr-blue !default; +$plyr-progress-buffered-bg: transparentize($plyr-gray, .25) !default; +$plyr-progress-loading-size: 40px !default; +$plyr-progress-loading-bg: transparentize(#000, .15); !default; // Volume -$volume-track-height: 6px !default; -$volume-track-bg: darken($controls-bg, 10%) !default; -$volume-thumb-height: ($volume-track-height * 2) !default; -$volume-thumb-width: ($volume-track-height * 2) !default; -$volume-thumb-bg: $control-color !default; -$volume-thumb-bg-focus: $control-bg-hover !default; +$plyr-volume-track-height: 6px !default; +$plyr-volume-track-bg: darken($plyr-controls-bg, 10%) !default; +$plyr-volume-thumb-height: ($plyr-volume-track-height * 2) !default; +$plyr-volume-thumb-width: ($plyr-volume-track-height * 2) !default; +$plyr-volume-thumb-bg: $plyr-control-color !default; +$plyr-volume-thumb-bg-focus: $plyr-control-bg-hover !default; // Breakpoints -$bp-control-split: 560px !default; // When controls split into left/right -$bp-captions-large: 768px !default; // When captions jump to the larger font size +$plyr-bp-control-split: 560px !default; // When controls split into left/right +$plyr-bp-captions-large: 768px !default; // When captions jump to the larger font size // Animation // --------------------------------------- -@keyframes progress { - to { background-position: $progress-loading-size 0; } +@keyframes plyr-progress { + to { background-position: $plyr-progress-loading-size 0; } } // Font smoothing @@ -92,41 +92,27 @@ $bp-captions-large: 768px !default; // When captions jump to the larger } } -// Contain floats: nicolasgallagher.com/micro-clearfix-hack/ -@mixin clearfix() -{ - zoom: 1; - &:before, - &:after { content: ''; display: table; } - &:after { clear: both; } -} -// Tab focus styles -@mixin tab-focus() { - outline: thin dotted transparentize($gray-dark, .8); - outline-offset: 3px; -} - // styling @mixin volume-thumb() { - height: $volume-thumb-height; - width: $volume-thumb-width; - background: $volume-thumb-bg; + height: $plyr-volume-thumb-height; + width: $plyr-volume-thumb-width; + background: $plyr-volume-thumb-bg; border: 0; border-radius: 100%; transition: background .3s ease; cursor: ew-resize; } @mixin volume-track() { - height: $volume-track-height; - background: $volume-track-bg; + height: $plyr-volume-track-height; + background: $plyr-volume-track-bg; border: 0; - border-radius: ($volume-track-height / 2); + border-radius: ($plyr-volume-track-height / 2); } @mixin seek-thumb() { background: transparent; border: 0; - width: ($control-spacing * 4); - height: $control-spacing; + width: ($plyr-control-spacing * 4); + height: $plyr-control-spacing; transform: translateX(-50%); } @mixin seek-track() { @@ -209,49 +195,55 @@ $bp-captions-large: 768px !default; // When captions jump to the larger bottom: 0; left: 0; width: 100%; - padding: ($control-spacing * 2) ($control-spacing * 2) ($control-spacing * 3); + padding: ($plyr-control-spacing * 2) ($plyr-control-spacing * 2) ($plyr-control-spacing * 3); color: #fff; - font-size: $font-size-captions-base; + font-size: $plyr-font-size-captions-base; text-align: center; @include font-smoothing(); span { border-radius: 2px; padding: 3px 10px; - background: rgba(0,0,0, .9); + background: transparentize(#000, .9); } span:empty { display: none; } - @media (min-width: $bp-captions-large) { - font-size: $font-size-captions-medium; + @media (min-width: $plyr-bp-captions-large) { + font-size: $plyr-font-size-captions-medium; } } &--captions-active &__captions { display: block; } &--fullscreen-active &__captions { - font-size: $font-size-captions-large; + font-size: $plyr-font-size-captions-large; } // Playback controls &__controls { - @include clearfix(); @include font-smoothing(); position: relative; - padding: $control-spacing; - background: $controls-bg; + padding: $plyr-control-spacing; + background: $plyr-controls-bg; line-height: 1; text-align: center; - box-shadow: 0 1px 1px transparentize($gray-dark, .2); + box-shadow: 0 1px 1px transparentize($plyr-gray-dark, .2); + + // Clear floats + &::after { + content: ''; + display: table; + clear: both; + } // Layout &--right { display: block; - margin: $control-spacing auto 0; + margin: $plyr-control-spacing auto 0; } - @media (min-width: $bp-control-split) { + @media (min-width: $plyr-bp-control-split) { &--left { float: left; } @@ -266,13 +258,13 @@ $bp-captions-large: 768px !default; // When captions jump to the larger display: inline-block; vertical-align: middle; margin: 0 2px; - padding: ($control-spacing / 2) $control-spacing; + padding: ($plyr-control-spacing / 2) $plyr-control-spacing; overflow: hidden; border: 0; background: transparent; border-radius: 3px; cursor: pointer; - color: $control-color; + color: $plyr-control-color; transition: background .3s ease, color .3s ease, opacity .3s ease; svg { @@ -286,8 +278,8 @@ $bp-captions-large: 768px !default; // When captions jump to the larger // Hover and tab focus &.tab-focus:hover, &:hover { - background: $control-bg-hover; - color: $control-color-hover; + background: $plyr-control-bg-hover; + color: $plyr-control-color-hover; } // Default focus &:focus { @@ -306,24 +298,24 @@ $bp-captions-large: 768px !default; // When captions jump to the larger .plyr__time { display: inline-block; vertical-align: middle; - margin-left: $control-spacing; - color: $control-color; + margin-left: $plyr-control-spacing; + color: $plyr-control-color; font-weight: 600; - font-size: $font-size-small; + font-size: $plyr-font-size-small; } // Media duration hidden on small screens .plyr__time + .plyr__time { display: none; - @media (min-width: $bp-control-split) { + @media (min-width: $plyr-bp-control-split) { display: inline-block; } // Add a slash in before &::before { content: '\2044'; - margin-right: $control-spacing; + margin-right: $plyr-control-spacing; } } } @@ -333,19 +325,19 @@ $bp-captions-large: 768px !default; // When captions jump to the larger position: absolute; z-index: 2; bottom: 100%; - margin-bottom: $tooltip-padding; - padding: $tooltip-padding ($tooltip-padding * 1.5); + margin-bottom: $plyr-tooltip-padding; + padding: $plyr-tooltip-padding ($plyr-tooltip-padding * 1.5); opacity: 0; - background: $tooltip-bg; - box-shadow: $tooltip-shadow; - border-radius: $tooltip-radius; - color: $tooltip-color; - font-size: $font-size-small; + background: $plyr-tooltip-bg; + box-shadow: $plyr-tooltip-shadow; + border-radius: $plyr-tooltip-radius; + color: $plyr-tooltip-color; + font-size: $plyr-font-size-small; line-height: 1.5; font-weight: 600; - transform: translate(-50%, ($tooltip-padding * 3)) scale(.8); + transform: translate(-50%, ($plyr-tooltip-padding * 3)) scale(.8); transform-origin: 50% 100%; transition: transform .2s .1s ease, opacity .2s .1s ease; @@ -362,19 +354,19 @@ $bp-captions-large: 768px !default; // When captions jump to the larger } // The border triangle &::after { - $border-arrow-size: ($tooltip-arrow-size + ($tooltip-border-width * 1)); - bottom: -($border-arrow-size + $tooltip-border-width); - border-right: $border-arrow-size solid transparent; - border-top: $border-arrow-size solid $tooltip-border-color; - border-left: $border-arrow-size solid transparent; + $plyr-border-arrow-size: ($plyr-tooltip-arrow-size + ($plyr-tooltip-border-width * 1)); + bottom: -($plyr-border-arrow-size + $plyr-tooltip-border-width); + border-right: $plyr-border-arrow-size solid transparent; + border-top: $plyr-border-arrow-size solid $plyr-tooltip-border-color; + border-left: $plyr-border-arrow-size solid transparent; z-index: 1; } // The background triangle &::before { - bottom: -$tooltip-arrow-size; - border-right: $tooltip-arrow-size solid transparent; - border-top: $tooltip-arrow-size solid $tooltip-bg; - border-left: $tooltip-arrow-size solid transparent; + bottom: -$plyr-tooltip-arrow-size; + border-right: $plyr-tooltip-arrow-size solid transparent; + border-top: $plyr-tooltip-arrow-size solid $plyr-tooltip-bg; + border-left: $plyr-tooltip-arrow-size solid transparent; z-index: 2; } } @@ -389,7 +381,8 @@ $bp-captions-large: 768px !default; // When captions jump to the larger // Common range styles input[type='range'].tab-focus:focus { - .tab-focus(); + outline: thin dotted transparentize($plyr-gray-dark, .8); + outline-offset: 3px; } // Playback progress @@ -400,8 +393,8 @@ $bp-captions-large: 768px !default; // When captions jump to the larger left: 0; right: 0; width: 100%; - height: $control-spacing; - background: $progress-bg; + height: $plyr-control-spacing; + background: $plyr-progress-bg; &--buffer[value], &--played[value], @@ -410,7 +403,7 @@ $bp-captions-large: 768px !default; // When captions jump to the larger left: 0; top: 0; width: 100%; - height: $control-spacing; + height: $plyr-control-spacing; margin: 0; padding: 0; vertical-align: top; @@ -436,10 +429,10 @@ $bp-captions-large: 768px !default; // When captions jump to the larger } &--played[value] { z-index: 2; - color: $progress-playing-bg; + color: $plyr-progress-playing-bg; } &--buffer[value] { - color: $progress-buffered-bg; + color: $plyr-progress-buffered-bg; } // Seek control @@ -492,17 +485,17 @@ $bp-captions-large: 768px !default; // When captions jump to the larger // Loading state &--loading .plyr__progress--buffer { - animation: progress 1s linear infinite; - background-size: $progress-loading-size $progress-loading-size; + animation: plyr-progress 1s linear infinite; + background-size: $plyr-progress-loading-size $plyr-progress-loading-size; background-repeat: repeat-x; - background-color: $progress-buffered-bg; + background-color: $plyr-progress-buffered-bg; background-image: linear-gradient( -45deg, - $progress-loading-bg 25%, + $plyr-progress-loading-bg 25%, transparent 25%, transparent 50%, - $progress-loading-bg 50%, - $progress-loading-bg 75%, + $plyr-progress-loading-bg 50%, + $plyr-progress-loading-bg 75%, transparent 75%, transparent); color: transparent; @@ -526,7 +519,7 @@ $bp-captions-large: 768px !default; // When captions jump to the larger -webkit-appearance: none; -moz-appearance: none; width: 100px; - margin: 0 $control-spacing 0 0; + margin: 0 $plyr-control-spacing 0 0; padding: 0; cursor: pointer; background: transparent; @@ -538,7 +531,7 @@ $bp-captions-large: 768px !default; // When captions jump to the larger } &::-webkit-slider-thumb { -webkit-appearance: none; - margin-top: -(($volume-thumb-height - $volume-track-height) / 2); + margin-top: -(($plyr-volume-thumb-height - $plyr-volume-track-height) / 2); @include volume-thumb(); } @@ -552,10 +545,10 @@ $bp-captions-large: 768px !default; // When captions jump to the larger // Microsoft &::-ms-track { - height: $volume-track-height; + height: $plyr-volume-track-height; background: transparent; border-color: transparent; - border-width: (($volume-thumb-height - $volume-track-height) / 2) 0; + border-width: (($plyr-volume-thumb-height - $plyr-volume-track-height) / 2) 0; color: transparent; } &::-ms-fill-lower, @@ -570,13 +563,13 @@ $bp-captions-large: 768px !default; // When captions jump to the larger outline: 0; &::-webkit-slider-thumb { - background: $volume-thumb-bg-focus; + background: $plyr-volume-thumb-bg-focus; } &::-moz-range-thumb { - background: $volume-thumb-bg-focus; + background: $plyr-volume-thumb-bg-focus; } &::-ms-thumb { - background: $volume-thumb-bg-focus; + background: $plyr-volume-thumb-bg-focus; } } } @@ -597,12 +590,12 @@ $bp-captions-large: 768px !default; // When captions jump to the larger // Audio specific styles // Position the progress within the container &--audio .plyr__controls { - padding-top: ($control-spacing * 2); + padding-top: ($plyr-control-spacing * 2); } &--audio .plyr__progress { bottom: auto; top: 0; - background: $off-white; + background: $plyr-off-white; } // Full screen mode @@ -635,14 +628,14 @@ $bp-captions-large: 768px !default; // When captions jump to the larger // Hide controls when playing in full screen &--fullscreen--hide-controls&--fullscreen-active&--playing { .plyr__controls { - transform: translateY(100%) translateY($control-spacing / 2); + transform: translateY(100%) translateY($plyr-control-spacing / 2); transition: transform .3s .2s ease; } &.plyr--hover .plyr__controls { transform: translateY(0); } .plyr__captions { - bottom: ($control-spacing / 2); + bottom: ($plyr-control-spacing / 2); transition: bottom .3s .2s ease; } } @@ -654,7 +647,7 @@ $bp-captions-large: 768px !default; // When captions jump to the larger top: auto; bottom: 90px; - @media (min-width: $bp-control-split) { + @media (min-width: $plyr-bp-control-split) { bottom: 60px; } } -- cgit v1.2.3 From 2e5bdb338eee71f777bc3898cc57875b0e705dfa Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Mon, 18 Jan 2016 17:35:18 +1100 Subject: Tidying up, Vimeo fix --- src/js/plyr.js | 9 +++++---- src/less/plyr.less | 15 ++++++++------- src/sass/plyr.scss | 13 +++++++------ 3 files changed, 20 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index ca160ac6..a1b4de27 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1646,7 +1646,8 @@ break; case 'vimeo': - plyr.embed.api('seekTo', targetTime); + // Round to nearest second for vimeo + plyr.embed.api('seekTo', targetTime.toFixed(0)); break; } @@ -2214,8 +2215,8 @@ } // Determine which buttons - var trigger = plyr.buttons[play ? "play" : "pause"], - target = plyr.buttons[play ? "pause" : "play"]; + var trigger = plyr.buttons[play ? 'play' : 'pause'], + target = plyr.buttons[play ? 'pause' : 'play']; // Setup focus and tab focus if(target) { @@ -2475,7 +2476,7 @@ function _setupInterface() { // Don't setup interface if no support if (!plyr.supported.full) { - _log("No full support for this media type (" + plyr.type + ")", true); + _log('No full support for this media type (' + plyr.type + ')', true); // Remove controls _remove(_getElement(config.selectors.controls.wrapper)); diff --git a/src/less/plyr.less b/src/less/plyr.less index 955bd824..7cb768a8 100644 --- a/src/less/plyr.less +++ b/src/less/plyr.less @@ -599,7 +599,7 @@ } // Full screen mode - &--fullscreen, + &.plyr--fullscreen, &--fullscreen-active { position: fixed; top: 0; @@ -627,24 +627,25 @@ } // Hide controls when playing in full screen - &--fullscreen--hide-controls&--fullscreen-active&--playing { + &--fullscreen-active.plyr--fullscreen--hide-controls.plyr--playing, + &.plyr--fullscreen.plyr--fullscreen--hide-controls.plyr--playing { .plyr__controls { transform: translateY(100%) translateY(@plyr-control-spacing / 2); transition: transform .3s .2s ease; } - &.plyr--hover .plyr__controls { - transform: translateY(0); - } .plyr__captions { bottom: (@plyr-control-spacing / 2); transition: bottom .3s .2s ease; } + &.plyr--hover .plyr__controls { + transform: translateY(0); + } } // Captions - &--fullscreen .plyr__captions, + &.plyr--fullscreen .plyr__captions, &--fullscreen-active .plyr__captions, - &--fullscreen--hide-controls&--fullscreen-active&--playing&--hover &__captions { + &--fullscreen--hide-controls.plyr--fullscreen-active.plyr--playing.plyr--hover .plyr__captions { top: auto; bottom: 90px; diff --git a/src/sass/plyr.scss b/src/sass/plyr.scss index bbd52579..5a94d17d 100644 --- a/src/sass/plyr.scss +++ b/src/sass/plyr.scss @@ -626,24 +626,25 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to the la } // Hide controls when playing in full screen - &--fullscreen--hide-controls&--fullscreen-active&--playing { + &--fullscreen-active.plyr--fullscreen--hide-controls.plyr--playing, + &.plyr--fullscreen.plyr--fullscreen--hide-controls.plyr--playing { .plyr__controls { transform: translateY(100%) translateY($plyr-control-spacing / 2); transition: transform .3s .2s ease; } - &.plyr--hover .plyr__controls { - transform: translateY(0); - } .plyr__captions { bottom: ($plyr-control-spacing / 2); transition: bottom .3s .2s ease; } + &.plyr--hover .plyr__controls { + transform: translateY(0); + } } // Captions - &--fullscreen .plyr__captions, + &.plyr--fullscreen .plyr__captions, &--fullscreen-active .plyr__captions, - &--fullscreen--hide-controls&--fullscreen-active&--playing&--hover &__captions { + &--fullscreen--hide-controls.plyr--fullscreen-active.plyr--playing.plyr--hover .plyr__captions { top: auto; bottom: 90px; -- cgit v1.2.3 From 02d312f2d2764a423279203b0652ab685272a338 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Mon, 18 Jan 2016 18:27:01 +1100 Subject: Style tweaks --- src/less/plyr.less | 3 +++ src/sass/plyr.scss | 3 +++ 2 files changed, 6 insertions(+) (limited to 'src') diff --git a/src/less/plyr.less b/src/less/plyr.less index 7cb768a8..c3240242 100644 --- a/src/less/plyr.less +++ b/src/less/plyr.less @@ -417,14 +417,17 @@ &--played[value] { &::-webkit-progress-bar { background: transparent; + transition: width .2s ease; } // Inherit from currentColor; &::-webkit-progress-value { background: currentColor; + transition: width .2s ease; } &::-moz-progress-bar { background: currentColor; + transition: width .2s ease; } } &--played[value] { diff --git a/src/sass/plyr.scss b/src/sass/plyr.scss index 5a94d17d..a94aeaf5 100644 --- a/src/sass/plyr.scss +++ b/src/sass/plyr.scss @@ -417,14 +417,17 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to the la &--played[value] { &::-webkit-progress-bar { background: transparent; + transition: width .2s ease; } // Inherit from currentColor; &::-webkit-progress-value { background: currentColor; + transition: width .2s ease; } &::-moz-progress-bar { background: currentColor; + transition: width .2s ease; } } &--played[value] { -- cgit v1.2.3 From b81b8c1d31b2e980ab610a4a42e02a22b9832955 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Tue, 19 Jan 2016 00:30:25 +1100 Subject: Event listeners --- src/js/plyr.js | 126 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 82 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index a1b4de27..9d80a9e8 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -92,18 +92,6 @@ }, tabFocus: 'tab-focus' }, - handlers: { - seek: null, - play: null, - pause: null, - restart: null, - rewind: null, - forward: null, - mute: null, - volume: null, - captions: null, - fullscreen: null - }, captions: { defaultActive: false }, @@ -138,6 +126,7 @@ embed: ['youtube', 'vimeo'], html5: ['video', 'audio'] }, + // URLs urls: { vimeo: { api: 'https://cdn.plyr.io/froogaloop/1.0.0/plyr.froogaloop.js', @@ -145,7 +134,22 @@ youtube: { api: 'https://www.youtube.com/iframe_api' } - } + }, + // Custom control listeners + listeners: { + seek: null, + play: null, + pause: null, + restart: null, + rewind: null, + forward: null, + mute: null, + volume: null, + captions: null, + fullscreen: null + }, + // Events to watch on HTML5 media elements + events: ['ended', 'progress', 'stalled', 'playing', 'waiting', 'canplay', 'canplaythrough', 'loadstart', 'loadeddata', 'loadedmetadata', 'timeupdate', 'volumechange', 'play', 'pause', 'error', 'seeking', 'emptied'] }; // Build the default HTML @@ -529,36 +533,36 @@ // Bind event function _on(element, events, callback) { if (element) { - _toggleHandler(element, events, callback, true); + _toggleListener(element, events, callback, true); } } // Unbind event function _off(element, events, callback) { if (element) { - _toggleHandler(element, events, callback, false); + _toggleListener(element, events, callback, false); } } // Bind along with custom handler - function _proxyHandler(element, eventName, userHandler, defaultHandler) { + function _proxyListener(element, eventName, userListener, defaultListener) { _on(element, eventName, function(event) { - if(userHandler) { - userHandler.apply(element, [event]); + if(userListener) { + userListener.apply(element, [event]); } - defaultHandler.apply(element, [event]); + defaultListener.apply(element, [event]); }); } - // Toggle event handler - function _toggleHandler(element, events, callback, toggle) { + // Toggle event listener + function _toggleListener(element, events, callback, toggle) { var eventList = events.split(' '); // If a nodelist is passed, call itself on each node if (element instanceof NodeList) { for (var x = 0; x < element.length; x++) { if (element[x] instanceof Node) { - _toggleHandler(element[x], arguments[1], arguments[2], arguments[3]); + _toggleListener(element[x], arguments[1], arguments[2], arguments[3]); } } return; @@ -571,20 +575,17 @@ } // Trigger event - function _triggerEvent(element, event) { + function _triggerEvent(element, eventName, properties) { // Bail if no element - if(!element || !event) { + if(!element || !eventName) { return; } - // Create faux event - var fauxEvent = document.createEvent('MouseEvents'); - - // Set the event type - fauxEvent.initEvent(event, true, true); + // create and dispatch the event + var event = new CustomEvent(eventName, properties); // Dispatch the event - element.dispatchEvent(fauxEvent); + element.dispatchEvent(event); } // Toggle aria-pressed state on a toggle button @@ -1241,6 +1242,9 @@ // Bail if we're at 100% if (plyr.media.buffered === 1) { window.clearInterval(plyr.timer.buffering); + + // Trigger event + _triggerEvent(plyr.media, 'canplaythrough'); } }, 200); @@ -1274,6 +1278,7 @@ plyr.media.paused = false; plyr.media.seeking = false; _triggerEvent(plyr.media, 'play'); + _triggerEvent(plyr.media, 'playing'); // Poll to get playback progress plyr.timer.playing = window.setInterval(function() { @@ -1289,6 +1294,7 @@ case 2: plyr.media.paused = true; _triggerEvent(plyr.media, 'pause'); + break; } } } @@ -1339,6 +1345,7 @@ plyr.embed.addEvent('play', function() { plyr.media.paused = false; _triggerEvent(plyr.media, 'play'); + _triggerEvent(plyr.media, 'playing'); }); plyr.embed.addEvent('pause', function() { @@ -1355,6 +1362,11 @@ plyr.embed.addEvent('loadProgress', function(data) { plyr.media.buffered = data.percent; _triggerEvent(plyr.media, 'progress'); + + if(parseInt(data.percent) === 1) { + // Trigger event + _triggerEvent(plyr.media, 'canplaythrough'); + } }); plyr.embed.addEvent('finish', function() { @@ -1759,11 +1771,14 @@ _toggleClass(plyr.controls, config.classes.hover, false); // Keep an eye on the mouse location in relation to controls - _toggleHandler(plyr.controls, 'mouseenter mouseleave', _setMouseOver, plyr.isFullscreen); + _toggleListener(plyr.controls, 'mouseenter mouseleave', _setMouseOver, plyr.isFullscreen); // Show the controls on mouse move - _toggleHandler(plyr.container, 'mousemove', _showControls, plyr.isFullscreen); + _toggleListener(plyr.container, 'mousemove', _showControls, plyr.isFullscreen); } + + // Trigger an event + _triggerEvent(plyr.container, plyr.isFullscreen ? 'enterfullscreen' : 'exitfullscreen'); } // Bail from faux-fullscreen @@ -1899,6 +1914,9 @@ // Add class hook _toggleClass(plyr.container, config.classes.captions.active, plyr.captionsEnabled); + + // Trigger an event + _triggerEvent(plyr.container, plyr.captionsEnabled ? 'captionsenabled' : 'captionsdisabled'); } // Check if media is loading @@ -2267,33 +2285,33 @@ } // Play - _proxyHandler(plyr.buttons.play, 'click', config.handlers.play, _togglePlay); + _proxyListener(plyr.buttons.play, 'click', config.listeners.play, _togglePlay); // Pause - _proxyHandler(plyr.buttons.pause, 'click', config.handlers.pause, _togglePlay); + _proxyListener(plyr.buttons.pause, 'click', config.listeners.pause, _togglePlay); // Restart - _proxyHandler(plyr.buttons.restart, 'click', config.handlers.restart, _seek); + _proxyListener(plyr.buttons.restart, 'click', config.listeners.restart, _seek); // Rewind - _proxyHandler(plyr.buttons.rewind, 'click', config.handlers.rewind, _rewind); + _proxyListener(plyr.buttons.rewind, 'click', config.listeners.rewind, _rewind); // Fast forward - _proxyHandler(plyr.buttons.forward, 'click', config.handlers.forward, _forward); + _proxyListener(plyr.buttons.forward, 'click', config.listeners.forward, _forward); // Seek - _proxyHandler(plyr.buttons.seek, inputEvent, config.handlers.seek, _seek); + _proxyListener(plyr.buttons.seek, inputEvent, config.listeners.seek, _seek); // Set volume - _proxyHandler(plyr.volume, inputEvent, config.handlers.volume, function() { + _proxyListener(plyr.volume, inputEvent, config.listeners.volume, function() { _setVolume(plyr.volume.value); }); // Mute - _proxyHandler(plyr.buttons.mute, 'click', config.handlers.mute, _toggleMute); + _proxyListener(plyr.buttons.mute, 'click', config.listeners.mute, _toggleMute); // Fullscreen - _proxyHandler(plyr.buttons.fullscreen, 'click', config.handlers.fullscreen, _toggleFullscreen); + _proxyListener(plyr.buttons.fullscreen, 'click', config.listeners.fullscreen, _toggleFullscreen); // Handle user exiting fullscreen by escaping etc if (fullscreen.supportsFullScreen) { @@ -2353,6 +2371,11 @@ // Loading _on(plyr.media, 'waiting canplay seeked', _checkLoading); + + // Proxy events to container + _on(plyr.media, config.events.join(' '), function(event) { + _triggerEvent(plyr.container, event.type); + }); } // Destroy an instance @@ -2643,9 +2666,7 @@ element.plyr = (Object.keys(instance).length ? instance : false); // Callback - if (typeof config.onSetup === 'function') { - config.onSetup.apply(element.plyr); - } + _triggerEvent(element, 'setup', { plyr: element.plyr }); } // Add to return array even if it's already setup @@ -2657,3 +2678,20 @@ return api; })); + +// Custom event polyfill +// +(function () { + function CustomEvent (event, params) { + params = params || { bubbles: false, cancelable: false, detail: undefined }; + var evt = document.createEvent('CustomEvent'); + evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail ); + return evt; + } + + CustomEvent.prototype = window.Event.prototype; + + if(!('CustomEvent' in window)) { + window.CustomEvent = CustomEvent; + } +})(); -- cgit v1.2.3 From 1b54ff0ad3d25ab5cff9a14d5f86c4f5bb6ac2b5 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Tue, 19 Jan 2016 09:30:37 +1100 Subject: Listen for durationchange --- src/js/plyr.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 9d80a9e8..9657f21e 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -2347,7 +2347,7 @@ _on(plyr.media, 'timeupdate', _seekManualCaptions); // Display duration - _on(plyr.media, 'loadedmetadata', _displayDuration); + _on(plyr.media, 'durationchange loadedmetadata', _displayDuration); // Handle the media finishing _on(plyr.media, 'ended', function() { -- cgit v1.2.3 From a87e87f93ce41cea527265e64d2f38dcfbdc1384 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Tue, 19 Jan 2016 09:32:04 +1100 Subject: Version bump --- src/js/plyr.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 9657f21e..6bf77be3 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1,6 +1,6 @@ // ========================================================================== // Plyr -// plyr.js v1.5.0 +// plyr.js v1.5.3 // https://github.com/selz/plyr // License: The MIT License (MIT) // ========================================================================== -- cgit v1.2.3 From 70c5b24678b9c569e3600df632f94973aa1d07c0 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Tue, 19 Jan 2016 09:35:10 +1100 Subject: Added reference --- src/js/plyr.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 6bf77be3..280d5f19 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -2680,7 +2680,7 @@ })); // Custom event polyfill -// +// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent (function () { function CustomEvent (event, params) { params = params || { bubbles: false, cancelable: false, detail: undefined }; -- cgit v1.2.3 From fd12247a62f2493b176d77d2b80fcde114589a4f Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Tue, 19 Jan 2016 11:34:04 +1100 Subject: Fix for video click --- src/js/plyr.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 280d5f19..2a86c003 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -2320,22 +2320,6 @@ // Captions _on(plyr.buttons.captions, 'click', _toggleCaptions); - - // Click video - if (plyr.type === 'video' && config.click) { - _on(plyr.videoContainer, 'click', function() { - if (plyr.media.paused) { - _play(); - } - else if (plyr.media.ended) { - _seek(); - _play(); - } - else { - _pause(); - } - }); - } } // Listen for media events @@ -2372,6 +2356,22 @@ // Loading _on(plyr.media, 'waiting canplay seeked', _checkLoading); + // Click video + if (plyr.type === 'video' && config.click) { + _on(plyr.videoContainer, 'click', function() { + if (plyr.media.paused) { + _play(); + } + else if (plyr.media.ended) { + _seek(); + _play(); + } + else { + _pause(); + } + }); + } + // Proxy events to container _on(plyr.media, config.events.join(' '), function(event) { _triggerEvent(plyr.container, event.type); -- cgit v1.2.3 From 76917751e38c942c5ae66a2db1dde6625f0ad208 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Thu, 21 Jan 2016 09:43:27 +1100 Subject: Small bug fixes --- src/js/plyr.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 2a86c003..0b5bab14 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -46,7 +46,7 @@ container: null, wrapper: '.plyr__controls' }, - labels: '[data-plyr] .sr-only, label .sr-only', + labels: '[data-plyr]', buttons: { seek: '[data-plyr="seek"]', play: '[data-plyr="play"]', @@ -787,6 +787,9 @@ else { plyr.captionsContainer.innerHTML = ''; } + + // Force redraw + // var redraw = plyr.captionsContainer.offsetHeight; } // Display captions container and button (for initialization) @@ -929,7 +932,7 @@ // Setup tooltips if (config.tooltips) { - var labels = _getElements(config.selectors.labels); + var labels = _getElements(config.selectors.labels + ' .' + config.classes.hidden); for (var i = labels.length - 1; i >= 0; i--) { var label = labels[i]; @@ -1472,6 +1475,9 @@ // Display a cue, if there is one if (this.activeCues[0] && this.activeCues[0].hasOwnProperty('text')) { plyr.captionsContainer.appendChild(this.activeCues[0].getCueAsHTML().trim()); + + // Force redraw + // var redraw = plyr.captionsContainer.offsetHeight; } }); } -- cgit v1.2.3 From 173e651e3f4549b7a337e30854d1e4467940b489 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sat, 23 Jan 2016 12:24:58 +1100 Subject: Comment --- src/js/plyr.js | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 0b5bab14..afa9b6b8 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -589,6 +589,7 @@ } // Toggle aria-pressed state on a toggle button + // http://www.ssbbartgroup.com/blog/how-not-to-misuse-aria-states-properties-and-roles function _toggleState(target, state) { // Bail if no target if(!target) { -- cgit v1.2.3 From a965d8a893a6885848c5c4cceab9f96265c7fa21 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sun, 24 Jan 2016 11:25:31 +1100 Subject: Seek tooltip, bug fixes for SASS, fullscreen and icons --- src/js/plyr.js | 156 ++++++++++++++++++++++++++--------- src/less/plyr.less | 15 +++- src/sass/plyr.scss | 22 +++-- src/sprite/icon-captions-off.svg | 3 +- src/sprite/icon-captions-on.svg | 3 +- src/sprite/icon-enter-fullscreen.svg | 11 +-- src/sprite/icon-exit-fullscreen.svg | 11 +-- src/sprite/icon-fast-forward.svg | 1 - src/sprite/icon-muted.svg | 3 +- src/sprite/icon-pause.svg | 3 +- src/sprite/icon-play.svg | 1 - src/sprite/icon-restart.svg | 5 +- src/sprite/icon-rewind.svg | 3 +- src/sprite/icon-volume.svg | 1 - 14 files changed, 157 insertions(+), 81 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index afa9b6b8..8204ada6 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -37,7 +37,10 @@ seekTime: 10, volume: 5, click: true, - tooltips: false, + tooltips: { + controls: false, + seek: true + }, displayDuration: true, iconPrefix: 'icon', selectors: { @@ -165,9 +168,16 @@ '', '', '0% ' + config.i18n.buffered, - '', - '', - '']; + '']; + + // Seek tooltip + if (config.tooltips.seek) { + html.push('0:00'); + } + + // Close progress + html.push('', + ''); // Restart button if (_inArray(config.controls, 'restart')) { @@ -736,7 +746,8 @@ // Player instance function Plyr(container) { var plyr = this; - plyr.container = container; + plyr.container = container, + plyr.timers = {}; // Captions functions // Seek the manual caption time and update UI @@ -979,6 +990,9 @@ plyr.progress.played.bar = _getElement(config.selectors.progress.played); plyr.progress.played.text = plyr.progress.played.bar && plyr.progress.played.bar.getElementsByTagName('span')[0]; + // Seek tooltip + plyr.progress.tooltip = plyr.progress.container && plyr.progress.container.querySelector('.' + config.classes.tooltip); + // Volume plyr.volume = _getElement(config.selectors.buttons.volume); @@ -1749,39 +1763,10 @@ // Set button state _toggleState(plyr.buttons.fullscreen, plyr.isFullscreen); - // Toggle controls visibility based on mouse movement and location - var hoverTimer, isMouseOver = false; - - // Show the player controls - function _showControls() { - // Set shown class - _toggleClass(plyr.container, config.classes.hover, true); - - // Clear timer every movement - window.clearTimeout(hoverTimer); - - // If the mouse is not over the controls, set a timeout to hide them - if (!isMouseOver) { - hoverTimer = window.setTimeout(function() { - _toggleClass(plyr.container, config.classes.hover, false); - }, 2000); - } - } - - // Check mouse is over the controls - function _setMouseOver (event) { - isMouseOver = (event.type === 'mouseenter'); - } - + // Hide on entering full screen if (config.fullscreen.hideControls) { - // Hide on entering full screen - _toggleClass(plyr.controls, config.classes.hover, false); - - // Keep an eye on the mouse location in relation to controls - _toggleListener(plyr.controls, 'mouseenter mouseleave', _setMouseOver, plyr.isFullscreen); - - // Show the controls on mouse move - _toggleListener(plyr.container, 'mousemove', _showControls, plyr.isFullscreen); + //_toggleClass(plyr.controls, config.classes.hover, false); + _showControls(true); } // Trigger an event @@ -1931,10 +1916,10 @@ var loading = (event.type === 'waiting'); // Clear timer - clearTimeout(plyr.loadingTimer); + clearTimeout(plyr.timers.loading); // Timer to prevent flicker when seeking - plyr.loadingTimer = setTimeout(function() { + plyr.timers.loading = setTimeout(function() { _toggleClass(plyr.container, config.classes.loading, loading); }, (loading ? 250 : 0)); } @@ -2041,6 +2026,9 @@ if (plyr.duration) { _updateTimeDisplay(duration, plyr.duration); } + + // Update the tooltip (if visible) + _updateSeekTooltip(); } // Handle time change event @@ -2057,6 +2045,73 @@ _updateProgress(event); } + // Update hover tooltip for seeking + function _updateSeekTooltip(event) { + // Bail if setting not true + if (!config.tooltips.seek) { + return; + } + + // Calculate percentage + var clientRect = plyr.progress.container.getBoundingClientRect(), + percent = 0, + visible = config.classes.tooltip + '--visible'; + + // Determine percentage, if already visible + if (!event) { + if(_hasClass(plyr.progress.tooltip, visible)) { + percent = plyr.progress.tooltip.style.left.replace('%', ''); + } + else { + return; + } + } + else { + percent = ((100 / clientRect.width) * (event.pageX - clientRect.left)); + } + + // Set bounds + if (percent < 0) { + percent = 0; + } + else if (percent > 100) { + percent = 100; + } + + // Display the time a click would seek to + _updateTimeDisplay(((plyr.media.duration / 100) * percent), plyr.progress.tooltip); + + // Set position + plyr.progress.tooltip.style.left = percent + "%"; + + // Show/hide the tooltip + // If the event is a moues in/out and percentage is inside bounds + if(_inArray(['mouseenter', 'mouseleave'], event.type)) { + _toggleClass(plyr.progress.tooltip, visible, (event.type === 'mouseenter')); + } + } + + // Show the player controls in fullscreen mode + function _showControls(force) { + // We're only worried about fullscreen + if (!plyr.isFullscreen) { + return; + } + + // Set shown class + _toggleClass(plyr.container, config.classes.hover, true); + + // Clear timer every movement + window.clearTimeout(plyr.timers.hover); + + // If the mouse is not over the controls, set a timeout to hide them + plyr.timers.hover = window.setTimeout(function() { + if (!plyr.controls.mouseover || (force === true)) { + _toggleClass(plyr.container, config.classes.hover, false); + } + }, 2000); + } + // Add common function to retrieve media source function _source(source) { // If not null or undefined, parse it @@ -2327,6 +2382,19 @@ // Captions _on(plyr.buttons.captions, 'click', _toggleCaptions); + + // Seek tooltip + _on(plyr.progress.container, 'mouseenter mouseleave mousemove', _updateSeekTooltip); + + // Toggle controls visibility based on mouse movement and location + var hoverTimer, isMouseOver = false; + + if (config.fullscreen.hideControls) { + // Keep an eye on the mouse location in relation to controls + _on(plyr.controls, 'mouseenter mouseleave', function() { + plyr.controls.mouseover = (event.type === 'mouseenter'); + }); + } } // Listen for media events @@ -2364,8 +2432,8 @@ _on(plyr.media, 'waiting canplay seeked', _checkLoading); // Click video - if (plyr.type === 'video' && config.click) { - _on(plyr.videoContainer, 'click', function() { + if (config.click) { + _on(plyr.media, 'click', function() { if (plyr.media.paused) { _play(); } @@ -2379,6 +2447,12 @@ }); } + // Listen for mouse move to show controls + if (config.fullscreen.hideControls) { + // Show the controls on mouse move + _on(plyr.media, 'mousemove', _showControls); + } + // Proxy events to container _on(plyr.media, config.events.join(' '), function(event) { _triggerEvent(plyr.container, event.type); diff --git a/src/less/plyr.less b/src/less/plyr.less index c3240242..8a8364e7 100644 --- a/src/less/plyr.less +++ b/src/less/plyr.less @@ -178,6 +178,7 @@ height: 100%; border: 0; user-select: none; + pointer-events: none; // To allow mouse events to be captured } // Vimeo hack @@ -322,6 +323,7 @@ // Tooltips &__tooltip { + visibility: hidden; position: absolute; z-index: 2; bottom: 100%; @@ -337,9 +339,9 @@ line-height: 1.5; font-weight: 600; - transform: translate(-50%, (@plyr-tooltip-padding * 3)) scale(.8); + transform: translate(-50%, 10px) scale(.8); transform-origin: 50% 100%; - transition: transform .2s .1s ease, opacity .2s .1s ease; + transition: transform .2s .1s ease, opacity .2s .1s ease, visibility .3s ease; // Arrows &::after, @@ -371,7 +373,9 @@ } } button:hover .plyr__tooltip, - button.tab-focus:focus .plyr__tooltip { + button.tab-focus:focus .plyr__tooltip, + &__tooltip--visible { + visibility: visible; opacity: 1; transform: translate(-50%, 0) scale(1); } @@ -484,6 +488,11 @@ border: 0; } } + + // Seek tooltip to show time + .plyr__tooltip { + left: 0; + } } // Loading state diff --git a/src/sass/plyr.scss b/src/sass/plyr.scss index a94aeaf5..36c157e4 100644 --- a/src/sass/plyr.scss +++ b/src/sass/plyr.scss @@ -46,7 +46,7 @@ $plyr-control-color-hover: null !default; // Tooltips $plyr-tooltip-bg: $plyr-controls-bg !default; -$plyr-tooltip-border-color: transparentize(@gray-dark, .1) !default; +$plyr-tooltip-border-color: transparentize($plyr-gray-dark, .1) !default; $plyr-tooltip-border-width: 1px; $plyr-tooltip-shadow: 0 0 5px $plyr-tooltip-border-color, 0 0 0 $plyr-tooltip-border-width $plyr-tooltip-border-color; $plyr-tooltip-color: $plyr-control-color !default; @@ -59,7 +59,7 @@ $plyr-progress-bg: transparentize($plyr-gray, .2) !default; $plyr-progress-playing-bg: $plyr-blue !default; $plyr-progress-buffered-bg: transparentize($plyr-gray, .25) !default; $plyr-progress-loading-size: 40px !default; -$plyr-progress-loading-bg: transparentize(#000, .15); !default; +$plyr-progress-loading-bg: transparentize(#000, .15) !default; // Volume $plyr-volume-track-height: 6px !default; @@ -178,6 +178,8 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to the la width: 100%; height: 100%; border: 0; + user-select: none; + pointer-events: none; // To allow mouse events to be captured } // Vimeo hack @@ -322,6 +324,7 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to the la // Tooltips &__tooltip { + visibility: hidden; position: absolute; z-index: 2; bottom: 100%; @@ -337,9 +340,9 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to the la line-height: 1.5; font-weight: 600; - transform: translate(-50%, ($plyr-tooltip-padding * 3)) scale(.8); + transform: translate(-50%, 10px) scale(.8); transform-origin: 50% 100%; - transition: transform .2s .1s ease, opacity .2s .1s ease; + transition: transform .2s .1s ease, opacity .2s .1s ease, visibility .3s ease; // Arrows &::after, @@ -371,7 +374,9 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to the la } } button:hover .plyr__tooltip, - button.tab-focus:focus .plyr__tooltip { + button.tab-focus:focus .plyr__tooltip, + &__tooltip--visible { + visibility: visible; opacity: 1; transform: translate(-50%, 0) scale(1); } @@ -387,7 +392,7 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to the la // Playback progress // element - &-progress { + &__progress { position: absolute; bottom: 100%; left: 0; @@ -484,6 +489,11 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to the la border: 0; } } + + // Seek tooltip to show time + .plyr__tooltip { + left: 0; + } } // Loading state diff --git a/src/sprite/icon-captions-off.svg b/src/sprite/icon-captions-off.svg index d9c2c444..788e4de4 100644 --- a/src/sprite/icon-captions-off.svg +++ b/src/sprite/icon-captions-off.svg @@ -1,7 +1,6 @@ - Captions Off - \ No newline at end of file + diff --git a/src/sprite/icon-captions-on.svg b/src/sprite/icon-captions-on.svg index 9053a31c..c02dfcb1 100644 --- a/src/sprite/icon-captions-on.svg +++ b/src/sprite/icon-captions-on.svg @@ -1,10 +1,9 @@ - Captions On - \ No newline at end of file + diff --git a/src/sprite/icon-enter-fullscreen.svg b/src/sprite/icon-enter-fullscreen.svg index 200e44e0..e8d1ab1a 100644 --- a/src/sprite/icon-enter-fullscreen.svg +++ b/src/sprite/icon-enter-fullscreen.svg @@ -1,10 +1,7 @@ - Enter Fullscreen - - - - - + + + - \ No newline at end of file + diff --git a/src/sprite/icon-exit-fullscreen.svg b/src/sprite/icon-exit-fullscreen.svg index 3c6f31e7..0fdd6b45 100644 --- a/src/sprite/icon-exit-fullscreen.svg +++ b/src/sprite/icon-exit-fullscreen.svg @@ -1,10 +1,7 @@ - Exit Fullscreen - - - - - + + + - \ No newline at end of file + diff --git a/src/sprite/icon-fast-forward.svg b/src/sprite/icon-fast-forward.svg index 71d5d138..1cc67199 100755 --- a/src/sprite/icon-fast-forward.svg +++ b/src/sprite/icon-fast-forward.svg @@ -1,5 +1,4 @@ - Fast Forward diff --git a/src/sprite/icon-muted.svg b/src/sprite/icon-muted.svg index 6d017d02..8a0014f1 100644 --- a/src/sprite/icon-muted.svg +++ b/src/sprite/icon-muted.svg @@ -1,9 +1,8 @@ - Muted - \ No newline at end of file + diff --git a/src/sprite/icon-pause.svg b/src/sprite/icon-pause.svg index b4ba82e2..7fb41105 100644 --- a/src/sprite/icon-pause.svg +++ b/src/sprite/icon-pause.svg @@ -1,8 +1,7 @@ - Pause - \ No newline at end of file + diff --git a/src/sprite/icon-play.svg b/src/sprite/icon-play.svg index f564b80f..056b9f79 100755 --- a/src/sprite/icon-play.svg +++ b/src/sprite/icon-play.svg @@ -1,5 +1,4 @@ - Play diff --git a/src/sprite/icon-restart.svg b/src/sprite/icon-restart.svg index 6cf89d8d..2a889021 100755 --- a/src/sprite/icon-restart.svg +++ b/src/sprite/icon-restart.svg @@ -1,8 +1,5 @@ - - - + diff --git a/src/sprite/icon-rewind.svg b/src/sprite/icon-rewind.svg index b7beaa34..661df0fd 100644 --- a/src/sprite/icon-rewind.svg +++ b/src/sprite/icon-rewind.svg @@ -1,5 +1,4 @@ - Rewind - \ No newline at end of file + diff --git a/src/sprite/icon-volume.svg b/src/sprite/icon-volume.svg index 27d6d809..9de20690 100755 --- a/src/sprite/icon-volume.svg +++ b/src/sprite/icon-volume.svg @@ -1,6 +1,5 @@ - Volume -- cgit v1.2.3 From 3127cea1b238bcb20d316943ee81448c45c4cc9a Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Mon, 25 Jan 2016 08:36:53 +1100 Subject: SASS fix (fixes #149) --- src/sass/plyr.scss | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/sass/plyr.scss b/src/sass/plyr.scss index 36c157e4..fd905af0 100644 --- a/src/sass/plyr.scss +++ b/src/sass/plyr.scss @@ -637,33 +637,33 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to the la left: 0; right: 0; } + } - // Hide controls when playing in full screen - &--fullscreen-active.plyr--fullscreen--hide-controls.plyr--playing, - &.plyr--fullscreen.plyr--fullscreen--hide-controls.plyr--playing { - .plyr__controls { - transform: translateY(100%) translateY($plyr-control-spacing / 2); - transition: transform .3s .2s ease; - } - .plyr__captions { - bottom: ($plyr-control-spacing / 2); - transition: bottom .3s .2s ease; - } - &.plyr--hover .plyr__controls { - transform: translateY(0); - } + // Hide controls when playing in full screen + &--fullscreen-active.plyr--fullscreen--hide-controls.plyr--playing, + &.plyr--fullscreen.plyr--fullscreen--hide-controls.plyr--playing { + .plyr__controls { + transform: translateY(100%) translateY($plyr-control-spacing / 2); + transition: transform .3s .2s ease; + } + .plyr__captions { + bottom: ($plyr-control-spacing / 2); + transition: bottom .3s .2s ease; } + &.plyr--hover .plyr__controls { + transform: translateY(0); + } + } - // Captions - &.plyr--fullscreen .plyr__captions, - &--fullscreen-active .plyr__captions, - &--fullscreen--hide-controls.plyr--fullscreen-active.plyr--playing.plyr--hover .plyr__captions { - top: auto; - bottom: 90px; + // Captions + &.plyr--fullscreen .plyr__captions, + &--fullscreen-active .plyr__captions, + &--fullscreen--hide-controls.plyr--fullscreen-active.plyr--playing.plyr--hover .plyr__captions { + top: auto; + bottom: 90px; - @media (min-width: $plyr-bp-control-split) { - bottom: 60px; - } + @media (min-width: $plyr-bp-control-split) { + bottom: 60px; } } -- cgit v1.2.3 From b006b73c698a6a681e3f634ad755de1d24ccc0f5 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Mon, 25 Jan 2016 11:02:35 +1100 Subject: Fix for control tooltips always showing --- src/js/plyr.js | 4 ++-- src/less/plyr.less | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 8204ada6..0749b716 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -162,7 +162,7 @@ '
', '
', '', - '', + '', '', '0% ' + config.i18n.played, '', @@ -943,7 +943,7 @@ container.insertAdjacentHTML('beforeend', html); // Setup tooltips - if (config.tooltips) { + if (config.tooltips.controls) { var labels = _getElements(config.selectors.labels + ' .' + config.classes.hidden); for (var i = labels.length - 1; i >= 0; i--) { diff --git a/src/less/plyr.less b/src/less/plyr.less index 8a8364e7..65918665 100644 --- a/src/less/plyr.less +++ b/src/less/plyr.less @@ -32,7 +32,7 @@ // Tooltips @plyr-tooltip-bg: @plyr-controls-bg; -@plyr-tooltip-border-color: fade(@plyr-gray-dark, 10%); +@plyr-tooltip-border-color: fade(darken(@plyr-controls-bg, 5%), 10%); @plyr-tooltip-border-width: 1px; @plyr-tooltip-shadow: 0 0 5px @plyr-tooltip-border-color, 0 0 0 @plyr-tooltip-border-width @plyr-tooltip-border-color; @plyr-tooltip-color: @plyr-control-color; -- cgit v1.2.3 From a327056789603a025ecd5ec546e65914cd7c5bba Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Mon, 25 Jan 2016 11:25:32 +1100 Subject: Seek fixes for touch --- src/js/plyr.js | 8 ++++---- src/less/plyr.less | 20 +++++++++++++++++++- src/sass/plyr.scss | 20 +++++++++++++++++++- 3 files changed, 42 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 0749b716..ac6c7d20 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -2048,7 +2048,7 @@ // Update hover tooltip for seeking function _updateSeekTooltip(event) { // Bail if setting not true - if (!config.tooltips.seek) { + if (!config.tooltips.seek || plyr.browser.touch) { return; } @@ -2251,11 +2251,11 @@ // Load HTML5 sources plyr.media.load(); - // Display duration if available - _displayDuration(); - // Setup interface _setupInterface(); + + // Display duration if available + _displayDuration(); } // Play if autoplay attribute is present diff --git a/src/less/plyr.less b/src/less/plyr.less index 65918665..f480ed3f 100644 --- a/src/less/plyr.less +++ b/src/less/plyr.less @@ -110,8 +110,11 @@ .seek-thumb() { background: transparent; border: 0; - width: (@plyr-control-spacing * 4); + width: 1px; height: @plyr-control-spacing; +} +.seek-thumb-touch() { + width: (@plyr-control-spacing * 4); transform: translateX(-50%); } .seek-track() { @@ -495,6 +498,21 @@ } } + // Touch seek wider handle + &--is-touch &--seek[type='range'] { + &::-webkit-slider-thumb { + .seek-thumb-touch(); + } + // Mozilla + &::-moz-range-thumb { + .seek-thumb-touch(); + } + // Microsoft + &::-ms-thumb { + .seek-thumb-touch(); + } + } + // Loading state &--loading .plyr__progress--buffer { animation: plyr-progress 1s linear infinite; diff --git a/src/sass/plyr.scss b/src/sass/plyr.scss index fd905af0..dd118602 100644 --- a/src/sass/plyr.scss +++ b/src/sass/plyr.scss @@ -111,8 +111,11 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to the la @mixin seek-thumb() { background: transparent; border: 0; - width: ($plyr-control-spacing * 4); + width: 1px; height: $plyr-control-spacing; +} +@mixin seek-thumb-touch() { + width: ($plyr-control-spacing * 4); transform: translateX(-50%); } @mixin seek-track() { @@ -496,6 +499,21 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to the la } } + // Touch seek wider handle + &--is-touch &--seek[type='range'] { + &::-webkit-slider-thumb { + @include seek-thumb-touch(); + } + // Mozilla + &::-moz-range-thumb { + @include seek-thumb-touch(); + } + // Microsoft + &::-ms-thumb { + @include seek-thumb-touch(); + } + } + // Loading state &--loading .plyr__progress--buffer { animation: plyr-progress 1s linear infinite; -- cgit v1.2.3 From 4fda65c8622f7b91d9ba0a1b2c5ac578b9a44d3b Mon Sep 17 00:00:00 2001 From: Marvin Hagemeister Date: Tue, 26 Jan 2016 16:53:15 +0100 Subject: Swap CommonJS and AMD module check so that CommonJS is checked first. Fixes Webpack module bundling --- src/js/plyr.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index ac6c7d20..8c281d93 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -11,12 +11,12 @@ 'use strict'; /*global define,module*/ - if (typeof define === 'function' && define.amd) { - // AMD - define(null, function() { factory(root, document) }); - } else if (typeof module === 'object') { + if (typeof module === 'object') { // Node, CommonJS-like module.exports = factory(root, document); + } else if (typeof define === 'function' && define.amd) { + // AMD + define(null, function() { factory(root, document) }); } else { // Browser globals (root is window) root.plyr = factory(root, document); -- cgit v1.2.3 From a285fcc4ec45816d43fa3bfe35c23dd21e7bfc63 Mon Sep 17 00:00:00 2001 From: Marvin Hagemeister Date: Tue, 26 Jan 2016 17:05:57 +0100 Subject: Check for module.exports as well for CommonJS Modules --- src/js/plyr.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 8c281d93..76623068 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -11,7 +11,7 @@ 'use strict'; /*global define,module*/ - if (typeof module === 'object') { + if (typeof module === 'object' && typeof module.exports === 'object') { // Node, CommonJS-like module.exports = factory(root, document); } else if (typeof define === 'function' && define.amd) { -- cgit v1.2.3 From 31a0eb8d1472ff792fe64cb75e81de16b7a5ea0b Mon Sep 17 00:00:00 2001 From: Marvin Hagemeister Date: Wed, 27 Jan 2016 21:27:58 +0100 Subject: Get the proper window reference on initialization. The previous code assumed that `this` points to the browsers window object, which is not the case when using a module bundler. So we check for the variable `window` first, before falling back to `this`. (taken from jQuery's codebase) --- src/js/plyr.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 76623068..2cee1210 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -21,7 +21,7 @@ // Browser globals (root is window) root.plyr = factory(root, document); } -}(this, function(window, document) { +}(typeof window !== 'undefined' ? window : this, function(window, document) { 'use strict'; /*global YT,$f*/ -- cgit v1.2.3 From ce513442699f4b3c964adf06d9baa49821351ce3 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sat, 13 Feb 2016 22:18:42 +1100 Subject: iOS fix (Fixes #166), Edge Progress Tip (Fixes #160), SASS fix (Fixes #158) --- src/js/plyr.js | 21 +++++++++++++-------- src/less/plyr.less | 17 +++++++++++++---- src/sass/plyr.scss | 16 +++++++++------- 3 files changed, 35 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index ac6c7d20..6725478a 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -172,7 +172,7 @@ // Seek tooltip if (config.tooltips.seek) { - html.push('0:00'); + html.push('--:--'); } // Close progress @@ -238,7 +238,7 @@ html.push( '', '' + config.i18n.duration + '', - '00:00', + '--:--', '' ); } @@ -746,7 +746,7 @@ // Player instance function Plyr(container) { var plyr = this; - plyr.container = container, + plyr.container = container; plyr.timers = {}; // Captions functions @@ -1816,14 +1816,18 @@ function _setVolume(volume) { // Use default if no value specified if (typeof volume === 'undefined') { + volume = config.volume; + if (config.storage.enabled && _storage().supported) { - volume = window.localStorage[config.storage.key] || config.volume; - } - else { - volume = config.volume; + volume = window.localStorage.getItem(config.storage.key); } } + // Use config if all else fails + if(isNaN(volume)) { + volume = config.volume; + } + // Maximum is 10 if (volume > 10) { volume = 10; @@ -1873,7 +1877,7 @@ } // Store the volume in storage - if (config.storage.enabled && _storage().supported) { + if (config.storage.enabled && _storage().supported && !isNaN(volume)) { window.localStorage.setItem(config.storage.key, volume); } @@ -2015,6 +2019,7 @@ return; } + // Determine duration var duration = plyr.media.duration || 0; // If there's only one time display, display duration there diff --git a/src/less/plyr.less b/src/less/plyr.less index f480ed3f..73e14c56 100644 --- a/src/less/plyr.less +++ b/src/less/plyr.less @@ -181,7 +181,6 @@ height: 100%; border: 0; user-select: none; - pointer-events: none; // To allow mouse events to be captured } // Vimeo hack @@ -190,6 +189,11 @@ padding-bottom: 200%; transform: translateY(-35.95%); } + + // To allow mouse events to be captured if full support + &.plyr iframe { + pointer-events: none; + } } // Captions @@ -387,9 +391,14 @@ } // Common range styles - input[type='range'].tab-focus:focus { - outline: 1px dotted fade(@plyr-gray-dark, 80%); - outline-offset: 3px; + input[type='range'] { + &::-ms-tooltip { + display: none; + } + &.tab-focus:focus { + outline: 1px dotted fade(@plyr-gray-dark, 80%); + outline-offset: 3px; + } } // Playback progress diff --git a/src/sass/plyr.scss b/src/sass/plyr.scss index dd118602..f0d1df6f 100644 --- a/src/sass/plyr.scss +++ b/src/sass/plyr.scss @@ -27,21 +27,19 @@ $plyr-font-size-captions-large: ($plyr-font-size-base * 2) !default; $plyr-control-spacing: 10px !default; $plyr-controls-bg: #fff !default; $plyr-control-bg-hover: $plyr-blue !default; -$plyr-control-color: null !default; -$plyr-control-color-hover: null !default; // Contrast @if lightness($plyr-controls-bg) >= 65% { - $plyr-control-color: $plyr-gray-light; + $plyr-control-color: $plyr-gray-light !default; } @else { - $plyr-control-color: $plyr-gray-lighter; + $plyr-control-color: $plyr-gray-lighter !default; } @if lightness($plyr-control-bg-hover) >= 65% { - $plyr-control-color-hover: $plyr-gray; + $plyr-control-color-hover: $plyr-gray !default; } @else { - $plyr-control-color-hover: #fff; + $plyr-control-color-hover: #fff !default; } // Tooltips @@ -182,7 +180,6 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to the la height: 100%; border: 0; user-select: none; - pointer-events: none; // To allow mouse events to be captured } // Vimeo hack @@ -191,6 +188,11 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to the la padding-bottom: 200%; transform: translateY(-35.95%); } + + // To allow mouse events to be captured if full support + &.plyr iframe { + pointer-events: none; + } } // Captions -- cgit v1.2.3 From 67f19166ac92d5adc03c9421300149260a6424ac Mon Sep 17 00:00:00 2001 From: Guru Prasad Srinivasa Date: Tue, 16 Feb 2016 19:52:08 -0500 Subject: Some WebVTT fixes to allow manual captions WebVTT allows additional parameters along with the line that contains the start and end times. These were not being filtered out while attempting to manually display captions. --- src/js/plyr.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index fce746db..2f50bb69 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -820,15 +820,21 @@ } // Utilities for caption time codes - function _timecodeMin(tc) { + function _timecodeCommon(tc, pos) { var tcpair = []; tcpair = tc.split(' --> '); - return _subTcSecs(tcpair[0]); + for(var i = 0; i < tcpair.length; i++) { + // WebVTT allows for extra meta data after the timestamp line + // So get rid of this if it exists + tcpair[i] = tcpair[i].replace(/(\d+:\d+:\d+\.\d+).*/, "$1"); + } + return _subTcSecs(tcpair[pos]); + } + function _timecodeMin(tc) { + return _timecodeCommon(tc, 0); } function _timecodeMax(tc) { - var tcpair = []; - tcpair = tc.split(' --> '); - return _subTcSecs(tcpair[1]); + return _timecodeCommon(tc, 1); } function _subTcSecs(tc) { if (tc === null || tc === undefined) { -- cgit v1.2.3 From 402c45ee2bf1d528ea1c3ea333dfa7fcb7dd79af Mon Sep 17 00:00:00 2001 From: Guru Prasad Srinivasa Date: Tue, 16 Feb 2016 19:53:07 -0500 Subject: Updated manual caption split pattern Previously, Plyr was using a fixed pattern of '\n\n' to split contents into captions. This does not always work as some VTT files contain '\r\n'. This commit checks for both. --- src/js/plyr.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 2f50bb69..b2b9c964 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1523,12 +1523,18 @@ record, req = xhr.responseText; - records = req.split('\n\n'); - + var pattern = '\n'; + records = req.split(pattern + pattern); + if(records.length === 1) { + // The '\n' pattern didn't work + // Try '\r\n' + pattern = '\r\n'; + records = req.split(pattern + pattern); + } for (var r = 0; r < records.length; r++) { record = records[r]; plyr.captions[r] = []; - plyr.captions[r] = record.split('\n'); + plyr.captions[r] = record.split(pattern); } // Remove first element ('VTT') -- cgit v1.2.3 From b18ed0338477059b0c8bace92fc96cf5ef0bbc6f Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sun, 21 Feb 2016 13:17:30 +1100 Subject: WIP on captions bug, manual duration option, reset media object --- src/js/plyr.js | 792 ++++++++++++++++++++++++++++------------------------- src/less/plyr.less | 73 ++--- src/sass/plyr.scss | 82 +++--- 3 files changed, 503 insertions(+), 444 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index fce746db..d04972a8 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -26,7 +26,7 @@ /*global YT,$f*/ // Globals - var fullscreen, config, api = {}; + var fullscreen, api = {}; // Default config var defaults = { @@ -36,13 +36,14 @@ loop: false, seekTime: 10, volume: 5, + duration: null, + displayDuration: true, + iconPrefix: 'icon', click: true, tooltips: { controls: false, seek: true }, - displayDuration: true, - iconPrefix: 'icon', selectors: { container: '.plyr', controls: { @@ -155,157 +156,6 @@ events: ['ended', 'progress', 'stalled', 'playing', 'waiting', 'canplay', 'canplaythrough', 'loadstart', 'loadeddata', 'loadedmetadata', 'timeupdate', 'volumechange', 'play', 'pause', 'error', 'seeking', 'emptied'] }; - // Build the default HTML - function _buildControls() { - // Open and add the progress and seek elements - var html = [ - '
', - '
', - '', - '', - '', - '0% ' + config.i18n.played, - '', - '', - '0% ' + config.i18n.buffered, - '']; - - // Seek tooltip - if (config.tooltips.seek) { - html.push('--:--'); - } - - // Close progress - html.push('
', - ''); - - // Restart button - if (_inArray(config.controls, 'restart')) { - html.push( - '' - ); - } - - // Rewind button - if (_inArray(config.controls, 'rewind')) { - html.push( - '' - ); - } - - // Play/pause button - if (_inArray(config.controls, 'play')) { - html.push( - '', - '' - ); - } - - // Fast forward button - if (_inArray(config.controls, 'fast-forward')) { - html.push( - '' - ); - } - - // Media current time display - if (_inArray(config.controls, 'current-time')) { - html.push( - '', - '' + config.i18n.currentTime + '', - '00:00', - '' - ); - } - - // Media duration display - if (_inArray(config.controls, 'duration')) { - html.push( - '', - '' + config.i18n.duration + '', - '--:--', - '' - ); - } - - // Close left controls - html.push( - '', - '' - ); - - // Toggle mute button - if (_inArray(config.controls, 'mute')) { - html.push( - '' - ); - } - - // Volume range control - if (_inArray(config.controls, 'volume')) { - html.push( - '', - '' - ); - } - - // Toggle captions button - if (_inArray(config.controls, 'captions')) { - html.push( - '' - ); - } - - // Toggle fullscreen button - if (_inArray(config.controls, 'fullscreen')) { - html.push( - '' - ); - } - - // Close everything - html.push( - '', - '
' - ); - - return html.join(''); - } - - // Debugging - function _log(text, warn) { - if (config.debug && window.console) { - console[(warn ? 'warn' : 'log')](text); - } - } - // Credits: http://paypal.github.io/accessible-html5-video-player/ // Unfortunately, due to mixed support, UA sniffing is required function _browserSniff() { @@ -623,19 +473,42 @@ return ((current / max) * 100).toFixed(2); } - // Deep extend/merge two Objects + // Deep extend/merge destination object with N more objects // http://andrewdupont.net/2009/08/28/deep-extending-objects-in-javascript/ // Removed call to arguments.callee (used explicit function name instead) - function _extend(destination, source) { - for (var property in source) { - if (source[property] && source[property].constructor && source[property].constructor === Object) { - destination[property] = destination[property] || {}; - _extend(destination[property], source[property]); - } - else { - destination[property] = source[property]; + function _extend() { + // Get arguments + var objects = arguments; + + // Bail if nothing to merge + if(!objects.length) { + return; + } + + // Return first if specified but nothing to merge + if(objects.lenth == 1) { + return objects[0]; + } + + // First object is the destination + var destination = Array.prototype.shift.call(objects), + length = objects.length; + + // Loop through all objects to merge + for (var i = 0; i < length; i++) { + var source = objects[i]; + + for (var property in source) { + if (source[property] && source[property].constructor && source[property].constructor === Object) { + destination[property] = destination[property] || {}; + _extend(destination[property], source[property]); + } + else { + destination[property] = source[property]; + } } } + return destination; } @@ -744,11 +617,360 @@ } // Player instance - function Plyr(container) { + function Plyr(container, config) { var plyr = this; plyr.container = container; plyr.timers = {}; + // Log config options + _log(config); + + // Debugging + function _log(text, warn) { + if (config.debug && window.console) { + console[(warn ? 'warn' : 'log')](text); + } + } + + // Build the default HTML + function _buildControls() { + // Open and add the progress and seek elements + var html = [ + '
', + '
', + '', + '', + '', + '0% ' + config.i18n.played, + '', + '', + '0% ' + config.i18n.buffered, + '']; + + // Seek tooltip + if (config.tooltips.seek) { + html.push('00:00'); + } + + // Close progress + html.push('
', + ''); + + // Restart button + if (_inArray(config.controls, 'restart')) { + html.push( + '' + ); + } + + // Rewind button + if (_inArray(config.controls, 'rewind')) { + html.push( + '' + ); + } + + // Play/pause button + if (_inArray(config.controls, 'play')) { + html.push( + '', + '' + ); + } + + // Fast forward button + if (_inArray(config.controls, 'fast-forward')) { + html.push( + '' + ); + } + + // Media current time display + if (_inArray(config.controls, 'current-time')) { + html.push( + '', + '' + config.i18n.currentTime + '', + '00:00', + '' + ); + } + + // Media duration display + if (_inArray(config.controls, 'duration')) { + html.push( + '', + '' + config.i18n.duration + '', + '00:00', + '' + ); + } + + // Close left controls + html.push( + '', + '' + ); + + // Toggle mute button + if (_inArray(config.controls, 'mute')) { + html.push( + '' + ); + } + + // Volume range control + if (_inArray(config.controls, 'volume')) { + html.push( + '', + '' + ); + } + + // Toggle captions button + if (_inArray(config.controls, 'captions')) { + html.push( + '' + ); + } + + // Toggle fullscreen button + if (_inArray(config.controls, 'fullscreen')) { + html.push( + '' + ); + } + + // Close everything + html.push( + '', + '
' + ); + + return html.join(''); + } + + // Setup fullscreen + function _setupFullscreen() { + if (!plyr.supported.full) { + return; + } + + if ((plyr.type != 'audio' || config.fullscreen.allowAudio) && config.fullscreen.enabled) { + // Check for native support + var nativeSupport = fullscreen.supportsFullScreen; + + if (nativeSupport || (config.fullscreen.fallback && !_inFrame())) { + _log((nativeSupport ? 'Native' : 'Fallback') + ' fullscreen enabled'); + + // Add styling hook + _toggleClass(plyr.container, config.classes.fullscreen.enabled, true); + } + else { + _log('Fullscreen not supported and fallback disabled'); + } + + // Toggle state + _toggleState(plyr.buttons.fullscreen, false); + + // Setup focus trap + _focusTrap(); + + // Set control hide class hook + if (config.fullscreen.hideControls) { + _toggleClass(plyr.container, config.classes.fullscreen.hideControls, true); + } + } + } + + // Setup captions + function _setupCaptions() { + if (plyr.type !== 'video') { + return; + } + + // Inject the container + if (!_getElement(config.selectors.captions)) { + plyr.videoContainer.insertAdjacentHTML('afterbegin', '
'); + } + + // Cache selector + plyr.captionsContainer = _getElement(config.selectors.captions).querySelector('span'); + + // Determine if HTML5 textTracks is supported + plyr.usingTextTracks = false; + if (plyr.media.textTracks) { + plyr.usingTextTracks = true; + } + + // Get URL of caption file if exists + var captionSrc = '', + kind, + children = plyr.media.childNodes; + + for (var i = 0; i < children.length; i++) { + if (children[i].nodeName.toLowerCase() === 'track') { + kind = children[i].kind; + if (kind === 'captions' || kind === 'subtitles') { + captionSrc = children[i].getAttribute('src'); + } + } + } + + // Record if caption file exists or not + plyr.captionExists = true; + if (captionSrc === '') { + plyr.captionExists = false; + _log('No caption track found'); + } + else { + _log('Caption track found; URI: ' + captionSrc); + } + + // If no caption file exists, hide container for caption text + if (!plyr.captionExists) { + _toggleClass(plyr.container, config.classes.captions.enabled); + } + // If caption file exists, process captions + else { + // Turn off native caption rendering to avoid double captions + // This doesn't seem to work in Safari 7+, so the elements are removed from the dom below + var tracks = plyr.media.textTracks; + for (var x = 0; x < tracks.length; x++) { + tracks[x].mode = 'hidden'; + } + + // Enable UI + _showCaptions(plyr); + + // Disable unsupported browsers than report false positive + if ((plyr.browser.name === 'IE' && plyr.browser.version >= 10) || + (plyr.browser.name === 'Firefox' && plyr.browser.version >= 31)) { + // || + //(plyr.browser.name === 'Chrome' && plyr.browser.version >= 43) || + //(plyr.browser.name === 'Safari' && plyr.browser.version >= 7)) { + + // Debugging + _log('Detected unsupported browser for HTML5 captions - using fallback'); + + // Set to false so skips to 'manual' captioning + plyr.usingTextTracks = false; + } + + // Rendering caption tracks + // Native support required - http://caniuse.com/webvtt + if (plyr.usingTextTracks) { + _log('TextTracks supported'); + + for (var y = 0; y < tracks.length; y++) { + var track = tracks[y]; + + if (track.kind === 'captions' || track.kind === 'subtitles') { + _on(track, 'cuechange', function() { + console.log('cuechange'); + console.log(this); + + // Clear container + plyr.captionsContainer.innerHTML = ''; + + // Display a cue, if there is one + if (this.activeCues[0] && 'text' in this.activeCues[0]) { + console.log(this.activeCues[0].getCueAsHTML()); + + plyr.captionsContainer.appendChild(this.activeCues[0].getCueAsHTML()); + + // Force redraw + var redraw = plyr.captionsContainer.offsetHeight; + } + }); + } + } + } + // Caption tracks not natively supported + else { + _log('TextTracks not supported so rendering captions manually'); + + // Render captions from array at appropriate time + plyr.currentCaption = ''; + plyr.captions = []; + + if (captionSrc !== '') { + // Create XMLHttpRequest Object + var xhr = new XMLHttpRequest(); + + xhr.onreadystatechange = function() { + if (xhr.readyState === 4) { + if (xhr.status === 200) { + var records = [], + record, + req = xhr.responseText; + + records = req.split('\n\n'); + + for (var r = 0; r < records.length; r++) { + record = records[r]; + plyr.captions[r] = []; + plyr.captions[r] = record.split('\n'); + } + + // Remove first element ('VTT') + plyr.captions.shift(); + + _log('Successfully loaded the caption file via AJAX'); + } + else { + _log('There was a problem loading the caption file via AJAX', true); + } + } + }; + + xhr.open('get', captionSrc, true); + + xhr.send(); + } + } + + // If Safari 7+, removing track from DOM [see 'turn off native caption rendering' above] + /*if (plyr.browser.name === 'Safari' && plyr.browser.version >= 7) { + _log('Safari 7+ detected; removing track from DOM'); + + // Find all elements + tracks = plyr.media.getElementsByTagName('track'); + + // Loop through and remove one by one + for (var t = 0; t < tracks.length; t++) { + plyr.media.removeChild(tracks[t]); + } + }*/ + } + } + // Captions functions // Seek the manual caption time and update UI function _seekManualCaptions(time) { @@ -1402,194 +1624,6 @@ }); } - // Setup captions - function _setupCaptions() { - if (plyr.type !== 'video') { - return; - } - - // Inject the container - if (!_getElement(config.selectors.captions)) { - plyr.videoContainer.insertAdjacentHTML('afterbegin', '
'); - } - - // Cache selector - plyr.captionsContainer = _getElement(config.selectors.captions).querySelector('span'); - - // Determine if HTML5 textTracks is supported - plyr.usingTextTracks = false; - if (plyr.media.textTracks) { - plyr.usingTextTracks = true; - } - - // Get URL of caption file if exists - var captionSrc = '', - kind, - children = plyr.media.childNodes; - - for (var i = 0; i < children.length; i++) { - if (children[i].nodeName.toLowerCase() === 'track') { - kind = children[i].kind; - if (kind === 'captions' || kind === 'subtitles') { - captionSrc = children[i].getAttribute('src'); - } - } - } - - // Record if caption file exists or not - plyr.captionExists = true; - if (captionSrc === '') { - plyr.captionExists = false; - _log('No caption track found'); - } - else { - _log('Caption track found; URI: ' + captionSrc); - } - - // If no caption file exists, hide container for caption text - if (!plyr.captionExists) { - _toggleClass(plyr.container, config.classes.captions.enabled); - } - // If caption file exists, process captions - else { - // Turn off native caption rendering to avoid double captions - // This doesn't seem to work in Safari 7+, so the elements are removed from the dom below - var tracks = plyr.media.textTracks; - for (var x = 0; x < tracks.length; x++) { - tracks[x].mode = 'hidden'; - } - - // Enable UI - _showCaptions(plyr); - - // Disable unsupported browsers than report false positive - if ((plyr.browser.name === 'IE' && plyr.browser.version >= 10) || - (plyr.browser.name === 'Firefox' && plyr.browser.version >= 31) || - (plyr.browser.name === 'Chrome' && plyr.browser.version >= 43) || - (plyr.browser.name === 'Safari' && plyr.browser.version >= 7)) { - // Debugging - _log('Detected unsupported browser for HTML5 captions - using fallback'); - - // Set to false so skips to 'manual' captioning - plyr.usingTextTracks = false; - } - - // Rendering caption tracks - // Native support required - http://caniuse.com/webvtt - if (plyr.usingTextTracks) { - _log('TextTracks supported'); - - for (var y = 0; y < tracks.length; y++) { - var track = tracks[y]; - - if (track.kind === 'captions' || track.kind === 'subtitles') { - _on(track, 'cuechange', function() { - // Clear container - plyr.captionsContainer.innerHTML = ''; - - // Display a cue, if there is one - if (this.activeCues[0] && this.activeCues[0].hasOwnProperty('text')) { - plyr.captionsContainer.appendChild(this.activeCues[0].getCueAsHTML().trim()); - - // Force redraw - // var redraw = plyr.captionsContainer.offsetHeight; - } - }); - } - } - } - // Caption tracks not natively supported - else { - _log('TextTracks not supported so rendering captions manually'); - - // Render captions from array at appropriate time - plyr.currentCaption = ''; - plyr.captions = []; - - if (captionSrc !== '') { - // Create XMLHttpRequest Object - var xhr = new XMLHttpRequest(); - - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - if (xhr.status === 200) { - var records = [], - record, - req = xhr.responseText; - - records = req.split('\n\n'); - - for (var r = 0; r < records.length; r++) { - record = records[r]; - plyr.captions[r] = []; - plyr.captions[r] = record.split('\n'); - } - - // Remove first element ('VTT') - plyr.captions.shift(); - - _log('Successfully loaded the caption file via AJAX'); - } - else { - _log('There was a problem loading the caption file via AJAX', true); - } - } - }; - - xhr.open('get', captionSrc, true); - - xhr.send(); - } - } - - // If Safari 7+, removing track from DOM [see 'turn off native caption rendering' above] - if (plyr.browser.name === 'Safari' && plyr.browser.version >= 7) { - _log('Safari 7+ detected; removing track from DOM'); - - // Find all elements - tracks = plyr.media.getElementsByTagName('track'); - - // Loop through and remove one by one - for (var t = 0; t < tracks.length; t++) { - plyr.media.removeChild(tracks[t]); - } - } - } - } - - // Setup fullscreen - function _setupFullscreen() { - if (!plyr.supported.full) { - return; - } - - if ((plyr.type != 'audio' || config.fullscreen.allowAudio) && config.fullscreen.enabled) { - // Check for native support - var nativeSupport = fullscreen.supportsFullScreen; - - if (nativeSupport || (config.fullscreen.fallback && !_inFrame())) { - _log((nativeSupport ? 'Native' : 'Fallback') + ' fullscreen enabled'); - - // Add styling hook - _toggleClass(plyr.container, config.classes.fullscreen.enabled, true); - } - else { - _log('Fullscreen not supported and fallback disabled'); - } - - // Toggle state - _toggleState(plyr.buttons.fullscreen, false); - - // Setup focus trap - _focusTrap(); - - // Set control hide class hook - if (config.fullscreen.hideControls) { - _toggleClass(plyr.container, config.classes.fullscreen.hideControls, true); - } - } - } - // Play media function _play() { if('play' in plyr.media) { @@ -1642,7 +1676,8 @@ // The input parameter can be an event or a number function _seek(input) { var targetTime = 0, - paused = plyr.media.paused; + paused = plyr.media.paused, + duration = _getDuration(); // Explicit position if (typeof input === 'number') { @@ -1652,15 +1687,15 @@ else if (typeof input === 'object' && (input.type === 'input' || input.type === 'change')) { // It's the seek slider // Seek to the selected time - targetTime = ((input.target.value / input.target.max) * plyr.media.duration); + targetTime = ((input.target.value / input.target.max) * duration); } // Normalise targetTime if (targetTime < 0) { targetTime = 0; } - else if (targetTime > plyr.media.duration) { - targetTime = plyr.media.duration; + else if (targetTime > duration) { + targetTime = duration; } // Set the current time @@ -1702,6 +1737,15 @@ _seekManualCaptions(targetTime); } + // Get the duration (or custom if set) + function _getDuration() { + // It should be a number, but parse it just incase + var duration = parseInt(config.duration); + + // If custom duration is funky, use regular duration + return (isNaN(duration) ? plyr.media.duration : duration); + } + // Check playing state function _checkPlaying() { _toggleClass(plyr.container, config.classes.playing, !plyr.media.paused); @@ -1932,14 +1976,15 @@ function _updateProgress(event) { var progress = plyr.progress.played.bar, text = plyr.progress.played.text, - value = 0; + value = 0, + duration = _getDuration(); if (event) { switch (event.type) { // Video playing case 'timeupdate': case 'seeking': - value = _getPercentage(plyr.media.currentTime, plyr.media.duration); + value = _getPercentage(plyr.media.currentTime, duration); // Set seek range value only if it's a 'natural' time event if (event.type == 'timeupdate' && plyr.buttons.seek) { @@ -1965,7 +2010,7 @@ // HTML5 if (buffered && buffered.length) { - return _getPercentage(buffered.end(0), plyr.media.duration); + return _getPercentage(buffered.end(0), duration); } // YouTube returns between 0 and 1 else if (typeof buffered === 'number') { @@ -2003,7 +2048,7 @@ plyr.hours = parseInt(((time / 60) / 60) % 60); // Do we need to display hours? - var displayHours = (parseInt(((plyr.media.duration / 60) / 60) % 60) > 0); + var displayHours = (parseInt(((_getDuration() / 60) / 60) % 60) > 0); // Ensure it's two digits. For example, 03 rather than 3. plyr.secs = ('0' + plyr.secs).slice(-2); @@ -2020,7 +2065,7 @@ } // Determine duration - var duration = plyr.media.duration || 0; + var duration = _getDuration() || 0; // If there's only one time display, display duration there if (!plyr.duration && config.displayDuration && plyr.media.paused) { @@ -2084,14 +2129,14 @@ } // Display the time a click would seek to - _updateTimeDisplay(((plyr.media.duration / 100) * percent), plyr.progress.tooltip); + _updateTimeDisplay(((_getDuration() / 100) * percent), plyr.progress.tooltip); // Set position plyr.progress.tooltip.style.left = percent + "%"; // Show/hide the tooltip // If the event is a moues in/out and percentage is inside bounds - if(_inArray(['mouseenter', 'mouseleave'], event.type)) { + if(event && _inArray(['mouseenter', 'mouseleave'], event.type)) { _toggleClass(plyr.progress.tooltip, visible, (event.type === 'mouseenter')); } } @@ -2273,6 +2318,9 @@ config.title = source.title; _setTitle(); } + + // Reset media object + plyr.container.plyr.media = plyr.media; } // Update poster @@ -2635,6 +2683,9 @@ // Update the UI _checkPlaying(); + + // Display duration + _displayDuration(); } // Initialize instance @@ -2729,12 +2780,9 @@ elements = document.querySelectorAll(defaults.selectors.container); } - // Extend the default options with user specified - config = _extend(defaults, options); - // Bail if disabled or no basic support // You may want to disable certain UAs etc - if (!config.enabled || !api.supported().basic || !elements.length) { + if (!api.supported().basic || !elements.length) { return false; } @@ -2745,8 +2793,16 @@ // Setup a player instance and add to the element if (typeof element.plyr === 'undefined') { + // Create instance-specific config + var config = _extend(defaults, options, JSON.parse(element.getAttribute("data-plyr"))); + + // Bail if not enabled + if(!config.enabled) { + return; + } + // Create new instance - var instance = new Plyr(element); + var instance = new Plyr(element, config); // Set plyr to false if setup failed element.plyr = (Object.keys(instance).length ? instance : false); diff --git a/src/less/plyr.less b/src/less/plyr.less index 73e14c56..156ac5f9 100644 --- a/src/less/plyr.less +++ b/src/less/plyr.less @@ -7,57 +7,58 @@ // ------------------------------- // Colors -@plyr-blue: #3498DB; -@plyr-gray-dark: #343F4A; -@plyr-gray: #565D64; -@plyr-gray-light: #6B7D86; -@plyr-gray-lighter: #CBD0D3; -@plyr-off-white: #D6DADD; +@plyr-blue: #3498DB; +@plyr-gray-dark: #343F4A; +@plyr-gray: #565D64; +@plyr-gray-light: #6B7D86; +@plyr-gray-lighter: #CBD0D3; +@plyr-off-white: #D6DADD; // Font sizes -@plyr-font-size-small: 14px; -@plyr-font-size-base: 16px; +@plyr-font-size-small: 14px; +@plyr-font-size-base: 16px; // Captions -@plyr-font-size-captions-base: ceil(@plyr-font-size-base * 1.25); -@plyr-font-size-captions-medium: ceil(@plyr-font-size-base * 1.5); -@plyr-font-size-captions-large: (@plyr-font-size-base * 2); +@plyr-font-size-captions-base: ceil(@plyr-font-size-base * 1.25); +@plyr-font-size-captions-medium: ceil(@plyr-font-size-base * 1.5); +@plyr-font-size-captions-large: (@plyr-font-size-base * 2); // Controls -@plyr-control-spacing: 10px; -@plyr-controls-bg: #fff; -@plyr-control-bg-hover: @plyr-blue; +@plyr-control-spacing: 10px; +@plyr-controls-bg: #fff; +@plyr-control-bg-hover: @plyr-blue; .contrast-control-color(@plyr-controls-bg); .contrast-control-color-hover(@plyr-control-bg-hover); // Tooltips -@plyr-tooltip-bg: @plyr-controls-bg; -@plyr-tooltip-border-color: fade(darken(@plyr-controls-bg, 5%), 10%); -@plyr-tooltip-border-width: 1px; -@plyr-tooltip-shadow: 0 0 5px @plyr-tooltip-border-color, 0 0 0 @plyr-tooltip-border-width @plyr-tooltip-border-color; -@plyr-tooltip-color: @plyr-control-color; -@plyr-tooltip-padding: @plyr-control-spacing; -@plyr-tooltip-arrow-size: 6px; -@plyr-tooltip-radius: 3px; +@plyr-tooltip-bg: @plyr-controls-bg; +@plyr-tooltip-border-color: fade(darken(@plyr-controls-bg, 75%), 10%); +@plyr-tooltip-arrow-border-color: fade(darken(@plyr-controls-bg, 75%), 20%); +@plyr-tooltip-border-width: 1px; +@plyr-tooltip-shadow: 0 0 5px @plyr-tooltip-border-color, 0 0 0 @plyr-tooltip-border-width @plyr-tooltip-border-color; +@plyr-tooltip-color: @plyr-control-color; +@plyr-tooltip-padding: @plyr-control-spacing; +@plyr-tooltip-arrow-size: 6px; +@plyr-tooltip-radius: 3px; // Progress -@plyr-progress-bg: fade(@plyr-gray, 20%); -@plyr-progress-playing-bg: @plyr-blue; -@plyr-progress-buffered-bg: fade(@plyr-gray, 25%); -@plyr-progress-loading-size: 40px; -@plyr-progress-loading-bg: fade(#000, 15%); +@plyr-progress-bg: fade(@plyr-gray, 20%); +@plyr-progress-playing-bg: @plyr-blue; +@plyr-progress-buffered-bg: fade(@plyr-gray, 25%); +@plyr-progress-loading-size: 40px; +@plyr-progress-loading-bg: fade(#000, 15%); // Volume -@plyr-volume-track-height: 6px; -@plyr-volume-track-bg: darken(@plyr-controls-bg, 10%); -@plyr-volume-thumb-height: (@plyr-volume-track-height * 2); -@plyr-volume-thumb-width: (@plyr-volume-track-height * 2); -@plyr-volume-thumb-bg: @plyr-control-color; -@plyr-volume-thumb-bg-focus: @plyr-control-bg-hover; +@plyr-volume-track-height: 6px; +@plyr-volume-track-bg: darken(@plyr-controls-bg, 10%); +@plyr-volume-thumb-height: (@plyr-volume-track-height * 2); +@plyr-volume-thumb-width: (@plyr-volume-track-height * 2); +@plyr-volume-thumb-bg: @plyr-control-color; +@plyr-volume-thumb-bg-focus: @plyr-control-bg-hover; // Breakpoints -@plyr-bp-control-split: 560px; // When controls split into left/right -@plyr-bp-captions-large: 768px; // When captions jump to the larger font size +@plyr-bp-control-split: 560px; // When controls split into left/right +@plyr-bp-captions-large: 768px; // When captions jump to the larger font size // Animation // --------------------------------------- @@ -366,7 +367,7 @@ @plyr-border-arrow-size: (@plyr-tooltip-arrow-size + (@plyr-tooltip-border-width * 1)); bottom: -(@plyr-border-arrow-size + @plyr-tooltip-border-width); border-right: @plyr-border-arrow-size solid transparent; - border-top: @plyr-border-arrow-size solid @plyr-tooltip-border-color; + border-top: @plyr-border-arrow-size solid @plyr-tooltip-arrow-border-color; border-left: @plyr-border-arrow-size solid transparent; z-index: 1; } diff --git a/src/sass/plyr.scss b/src/sass/plyr.scss index f0d1df6f..966a7966 100644 --- a/src/sass/plyr.scss +++ b/src/sass/plyr.scss @@ -7,69 +7,71 @@ // ------------------------------- // Colors -$plyr-blue: #3498DB !default; -$plyr-gray-dark: #343F4A !default; -$plyr-gray: #565D64 !default; -$plyr-gray-light: #6B7D86 !default; -$plyr-gray-lighter: #CBD0D3 !default; -$plyr-off-white: #D6DADD !default; +$plyr-blue: #3498DB !default; +$plyr-gray-dark: #343F4A !default; +$plyr-gray: #565D64 !default; +$plyr-gray-light: #6B7D86 !default; +$plyr-gray-lighter: #CBD0D3 !default; +$plyr-off-white: #D6DADD !default; // Font sizes -$plyr-font-size-small: 14px !default; -$plyr-font-size-base: 16px !default; +$plyr-font-size-small: 14px !default; +$plyr-font-size-base: 16px !default; // Captions -$plyr-font-size-captions-base: ceil($plyr-font-size-base * 1.25) !default; -$plyr-font-size-captions-medium: ceil($plyr-font-size-base * 1.5) !default; -$plyr-font-size-captions-large: ($plyr-font-size-base * 2) !default; +$plyr-font-size-captions-base: ceil($plyr-font-size-base * 1.25) !default; +$plyr-font-size-captions-medium: ceil($plyr-font-size-base * 1.5) !default; +$plyr-font-size-captions-large: ($plyr-font-size-base * 2) !default; // Controls -$plyr-control-spacing: 10px !default; -$plyr-controls-bg: #fff !default; -$plyr-control-bg-hover: $plyr-blue !default; +$plyr-control-spacing: 10px !default; +$plyr-controls-bg: #fff !default; +$plyr-control-bg-hover: $plyr-blue !default; // Contrast @if lightness($plyr-controls-bg) >= 65% { - $plyr-control-color: $plyr-gray-light !default; + $plyr-control-color: $plyr-gray-light !default; } @else { - $plyr-control-color: $plyr-gray-lighter !default; + $plyr-control-color: $plyr-gray-lighter !default; } @if lightness($plyr-control-bg-hover) >= 65% { - $plyr-control-color-hover: $plyr-gray !default; + $plyr-control-color-hover: $plyr-gray !default; } @else { - $plyr-control-color-hover: #fff !default; + $plyr-control-color-hover: #fff !default; } // Tooltips -$plyr-tooltip-bg: $plyr-controls-bg !default; -$plyr-tooltip-border-color: transparentize($plyr-gray-dark, .1) !default; -$plyr-tooltip-border-width: 1px; -$plyr-tooltip-shadow: 0 0 5px $plyr-tooltip-border-color, 0 0 0 $plyr-tooltip-border-width $plyr-tooltip-border-color; -$plyr-tooltip-color: $plyr-control-color !default; -$plyr-tooltip-padding: $plyr-control-spacing !default; -$plyr-tooltip-arrow-size: 6px !default; -$plyr-tooltip-radius: 3px !default; +$plyr-tooltip-bg: $plyr-controls-bg !default; +$plyr-tooltip-border-color: transparentize(darken($plyr-controls-bg, 75%), .1) !default; +$plyr-tooltip-arrow-border-color: transparentize(darken($plyr-controls-bg, 75%), .2) !default; + +$plyr-tooltip-border-width: 1px; +$plyr-tooltip-shadow: 0 0 5px $plyr-tooltip-border-color, 0 0 0 $plyr-tooltip-border-width $plyr-tooltip-border-color; +$plyr-tooltip-color: $plyr-control-color !default; +$plyr-tooltip-padding: $plyr-control-spacing !default; +$plyr-tooltip-arrow-size: 6px !default; +$plyr-tooltip-radius: 3px !default; // Progress -$plyr-progress-bg: transparentize($plyr-gray, .2) !default; -$plyr-progress-playing-bg: $plyr-blue !default; -$plyr-progress-buffered-bg: transparentize($plyr-gray, .25) !default; -$plyr-progress-loading-size: 40px !default; -$plyr-progress-loading-bg: transparentize(#000, .15) !default; +$plyr-progress-bg: transparentize($plyr-gray, .2) !default; +$plyr-progress-playing-bg: $plyr-blue !default; +$plyr-progress-buffered-bg: transparentize($plyr-gray, .25) !default; +$plyr-progress-loading-size: 40px !default; +$plyr-progress-loading-bg: transparentize(#000, .15) !default; // Volume -$plyr-volume-track-height: 6px !default; -$plyr-volume-track-bg: darken($plyr-controls-bg, 10%) !default; -$plyr-volume-thumb-height: ($plyr-volume-track-height * 2) !default; -$plyr-volume-thumb-width: ($plyr-volume-track-height * 2) !default; -$plyr-volume-thumb-bg: $plyr-control-color !default; -$plyr-volume-thumb-bg-focus: $plyr-control-bg-hover !default; +$plyr-volume-track-height: 6px !default; +$plyr-volume-track-bg: darken($plyr-controls-bg, 10%) !default; +$plyr-volume-thumb-height: ($plyr-volume-track-height * 2) !default; +$plyr-volume-thumb-width: ($plyr-volume-track-height * 2) !default; +$plyr-volume-thumb-bg: $plyr-control-color !default; +$plyr-volume-thumb-bg-focus: $plyr-control-bg-hover !default; // Breakpoints -$plyr-bp-control-split: 560px !default; // When controls split into left/right -$plyr-bp-captions-large: 768px !default; // When captions jump to the larger font size +$plyr-bp-control-split: 560px !default; // When controls split into left/right +$plyr-bp-captions-large: 768px !default; // When captions jump to the larger font size // Animation // --------------------------------------- @@ -365,7 +367,7 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to the la $plyr-border-arrow-size: ($plyr-tooltip-arrow-size + ($plyr-tooltip-border-width * 1)); bottom: -($plyr-border-arrow-size + $plyr-tooltip-border-width); border-right: $plyr-border-arrow-size solid transparent; - border-top: $plyr-border-arrow-size solid $plyr-tooltip-border-color; + border-top: $plyr-border-arrow-size solid $plyr-tooltip-arrow-border-color; border-left: $plyr-border-arrow-size solid transparent; z-index: 1; } -- cgit v1.2.3 From 5b968c97f4a0a35fde5f3c338ec79274b32ebb9a Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sun, 21 Feb 2016 14:07:17 +1100 Subject: v1.5.12 --- src/js/plyr.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 81cd6f15..066392dd 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1043,7 +1043,7 @@ _setCaption(plyr.currentCaption); } else { - _setCaption(''); + _setCaption(); } } @@ -2460,7 +2460,7 @@ _on(plyr.media, 'ended', function() { // Clear if (plyr.type === 'video') { - _setCaption(''); + _setCaption(); } // Reset UI -- cgit v1.2.3 From c99f20d5d854bf579851fced0cd39550e81b91bc Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sun, 21 Feb 2016 14:28:01 +1100 Subject: Fix for manual captions --- src/js/plyr.js | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 066392dd..637a267c 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -914,16 +914,26 @@ xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 200) { - var records = [], - record, + var captions = [], + caption, req = xhr.responseText; - records = req.split('\n\n'); + captions = req.split('\n\n'); - for (var r = 0; r < records.length; r++) { - record = records[r]; + for (var r = 0; r < captions.length; r++) { + caption = captions[r]; plyr.captions[r] = []; - plyr.captions[r] = record.split('\n'); + + // Get the parts of the captions + var parts = caption.split('\n'), + index = 0; + + // Incase caption numbers are added + if(parts[index].indexOf(":") === -1) { + index = 1; + } + + plyr.captions[r] = [parts[index], parts[index + 1]]; } // Remove first element ('VTT') -- cgit v1.2.3 From 1ecbec40444e1d36f1cf70a97805fd54021cb577 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Thu, 25 Feb 2016 19:35:03 +1100 Subject: Volume storage fix (Fixes #171) --- src/js/plyr.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 637a267c..6066fcff 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -107,7 +107,7 @@ }, storage: { enabled: true, - key: 'plyr_volume' + key: 'plyr' }, controls: ['restart', 'rewind', 'play', 'fast-forward', 'current-time', 'duration', 'mute', 'volume', 'captions', 'fullscreen'], i18n: { @@ -1869,11 +1869,15 @@ if (config.storage.enabled && _storage().supported) { volume = window.localStorage.getItem(config.storage.key); + + // Clean up old volume + // https://github.com/Selz/plyr/issues/171 + window.localStorage.removeItem('plyr-volume'); } } // Use config if all else fails - if(isNaN(volume)) { + if(volume === null || isNaN(volume)) { volume = config.volume; } -- cgit v1.2.3 From 7a1a5830aae174f3a01f3c3ee01c6e9569687fad Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Thu, 25 Feb 2016 19:36:14 +1100 Subject: Remove version from source --- src/js/plyr.js | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 6066fcff..57544997 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1,6 +1,5 @@ // ========================================================================== // Plyr -// plyr.js v1.5.3 // https://github.com/selz/plyr // License: The MIT License (MIT) // ========================================================================== -- cgit v1.2.3 From 1bbc47c64f6ad9dfbe58ab05ce65ec6ed9366c4c Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sun, 28 Feb 2016 11:22:11 +1100 Subject: CustomEvent polyfill (Fixes #172) --- src/js/plyr.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 57544997..24c6d76d 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1,5 +1,6 @@ // ========================================================================== // Plyr +// plyr.js v1.5.15 // https://github.com/selz/plyr // License: The MIT License (MIT) // ========================================================================== @@ -2832,16 +2833,18 @@ // Custom event polyfill // https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent (function () { + if (typeof window.CustomEvent === 'function') { + return false; + } + function CustomEvent (event, params) { params = params || { bubbles: false, cancelable: false, detail: undefined }; var evt = document.createEvent('CustomEvent'); - evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail ); + evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); return evt; } CustomEvent.prototype = window.Event.prototype; - if(!('CustomEvent' in window)) { - window.CustomEvent = CustomEvent; - } + window.CustomEvent = CustomEvent; })(); -- cgit v1.2.3 From cd83a2670b322aa03a3659ec554875fa2805b593 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sun, 28 Feb 2016 12:50:34 +1100 Subject: Cancel requests on source change (Fixes #174) --- src/js/plyr.js | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 24c6d76d..edac1118 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1,6 +1,6 @@ // ========================================================================== // Plyr -// plyr.js v1.5.15 +// plyr.js v1.5.16 // https://github.com/selz/plyr // License: The MIT License (MIT) // ========================================================================== @@ -2225,6 +2225,9 @@ _remove(plyr.videoContainer); } + // Cancel current network requests + _cancelRequests(); + // Remove the old media _remove(plyr.media); @@ -2521,6 +2524,31 @@ }); } + // Cancel current network requests + // See https://github.com/Selz/plyr/issues/174 + function _cancelRequests() { + if(!_inArray(config.types.html5, plyr.type)) { + return; + } + + // Set empty src attribute + plyr.media.setAttribute('src', ''); + + // Remove child sources + var sources = plyr.media.querySelectorAll('source'); + for (var i = 0; i < sources.length; i++) { + _remove(sources[i]); + } + + // Load the new empty source + // This will cancel existing requests + // See https://github.com/Selz/plyr/issues/174 + plyr.media.load(); + + // Debugging + _log("Cancelled network requests for old media"); + } + // Destroy an instance // Event listeners are removed when elements are removed // http://stackoverflow.com/questions/12528049/if-a-dom-element-is-removed-are-its-listeners-also-removed-from-memory @@ -2547,7 +2575,7 @@ // If video, we need to remove some more if (plyr.type === 'video') { - // Remove captions + // Remove captions container _remove(_getElement(config.selectors.captions)); // Remove video wrapper -- cgit v1.2.3 From 87d174ac2c3c07f9b022d7ed5d0542cff5edae86 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Mon, 7 Mar 2016 22:28:30 +1100 Subject: Bug fixes and native APIs exposed for embeds --- src/js/plyr.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index edac1118..8722b62f 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1,6 +1,6 @@ // ========================================================================== // Plyr -// plyr.js v1.5.16 +// plyr.js v1.5.17 // https://github.com/selz/plyr // License: The MIT License (MIT) // ========================================================================== @@ -133,7 +133,7 @@ // URLs urls: { vimeo: { - api: 'https://cdn.plyr.io/froogaloop/1.0.0/plyr.froogaloop.js', + api: 'https://cdn.plyr.io/froogaloop/1.0.1/plyr.froogaloop.js', }, youtube: { api: 'https://www.youtube.com/iframe_api' @@ -1420,6 +1420,9 @@ // Set title _setTitle(_getElement('iframe')); + + // Store reference to API + plyr.container.plyr.embed = plyr.embed; } // Handle YouTube API ready @@ -1470,6 +1473,9 @@ plyr.media.currentTime = instance.getCurrentTime(); plyr.media.muted = instance.isMuted(); + // Set title + config.title = instance.getVideoData().title; + // Trigger timeupdate _triggerEvent(plyr.media, 'timeupdate'); @@ -2225,6 +2231,9 @@ _remove(plyr.videoContainer); } + // Remove embed object + plyr.embed = null; + // Cancel current network requests _cancelRequests(); @@ -2326,12 +2335,10 @@ } // Set aria title and iframe title - if ('title' in source) { - config.title = source.title; - _setTitle(); - } + config.title = source.title; + _setTitle(); - // Reset media object + // Reset media objects plyr.container.plyr.media = plyr.media; } -- cgit v1.2.3 From c636f0e69e7db7f2aa38df882f10dfc4ad15a2a3 Mon Sep 17 00:00:00 2001 From: Shakeel Mohamed Date: Sat, 12 Mar 2016 14:05:33 -0800 Subject: Dynamically set YouTube autoplay from config The YouTube autoplay doesn't work without this change. --- src/js/plyr.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 8722b62f..ec1064e8 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1438,7 +1438,7 @@ plyr.embed = new YT.Player(container.id, { videoId: videoId, playerVars: { - autoplay: 0, + autoplay: plyr.autoplay ? 1 : 0, controls: (plyr.supported.full ? 0 : 1), rel: 0, showinfo: 0, -- cgit v1.2.3 From c41e5320c837a68276293bbffe345eac61f48169 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sun, 13 Mar 2016 21:22:51 +1100 Subject: SASS fixes, Default font stack added --- src/less/plyr.less | 3 ++- src/sass/plyr.scss | 15 ++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/less/plyr.less b/src/less/plyr.less index c5caeb65..61b5e2ae 100644 --- a/src/less/plyr.less +++ b/src/less/plyr.less @@ -11,7 +11,7 @@ @plyr-gray-dark: #343F4A; @plyr-gray: #565D64; @plyr-gray-light: #6B7D86; -@plyr-gray-lighter: #CBD0D3; +@plyr-gray-lighter: #CBD0D3; @plyr-off-white: #D6DADD; // Font sizes @@ -130,6 +130,7 @@ position: relative; max-width: 100%; min-width: 290px; + font-family: Avenir, "Avenir Next", "Helvetica Neue", "Segoe UI", Helvetica, Arial, sans-serif; // border-box everything // http://paulirish.com/2012/box-sizing-border-box-ftw/ diff --git a/src/sass/plyr.scss b/src/sass/plyr.scss index 0a6d653f..0e30eb4f 100644 --- a/src/sass/plyr.scss +++ b/src/sass/plyr.scss @@ -44,8 +44,8 @@ $plyr-control-bg-hover: $plyr-blue !default; // Tooltips $plyr-tooltip-bg: $plyr-controls-bg !default; -$plyr-tooltip-border-color: transparentize(darken($plyr-controls-bg, 75%), .1) !default; -$plyr-tooltip-arrow-border-color: transparentize(darken($plyr-controls-bg, 75%), .2) !default; +$plyr-tooltip-border-color: transparentize(darken($plyr-controls-bg, 75%), .9) !default; +$plyr-tooltip-arrow-border-color: transparentize(darken($plyr-controls-bg, 75%), .8) !default; $plyr-tooltip-border-width: 1px; $plyr-tooltip-shadow: 0 0 5px $plyr-tooltip-border-color, 0 0 0 $plyr-tooltip-border-width $plyr-tooltip-border-color; @@ -55,11 +55,11 @@ $plyr-tooltip-arrow-size: 6px !default; $plyr-tooltip-radius: 3px !default; // Progress -$plyr-progress-bg: transparentize($plyr-gray, .2) !default; +$plyr-progress-bg: transparentize($plyr-gray, .8) !default; $plyr-progress-playing-bg: $plyr-blue !default; -$plyr-progress-buffered-bg: transparentize($plyr-gray, .25) !default; +$plyr-progress-buffered-bg: transparentize($plyr-gray, .75) !default; $plyr-progress-loading-size: 40px !default; -$plyr-progress-loading-bg: transparentize(#000, .15) !default; +$plyr-progress-loading-bg: transparentize(#000, .85) !default; // Volume $plyr-volume-track-height: 6px !default; @@ -130,6 +130,7 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to th position: relative; max-width: 100%; min-width: 290px; + font-family: Avenir, "Avenir Next", "Helvetica Neue", "Segoe UI", Helvetica, Arial, sans-serif; // border-box everything // http://paulirish.com/2012/box-sizing-border-box-ftw/ @@ -218,7 +219,7 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to th span { border-radius: 2px; padding: 3px 10px; - background: transparentize(#000, .9); + background: transparentize(#000, .1); } span:empty { display: none; @@ -243,7 +244,7 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to th background: $plyr-controls-bg; line-height: 1; text-align: center; - box-shadow: 0 1px 1px transparentize($plyr-gray-dark, .2); + box-shadow: 0 1px 1px transparentize($plyr-gray-dark, .8); // Clear floats &::after { -- cgit v1.2.3 From 5ea9e59d71b462ab5d651c1f8189e48d89205d63 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sun, 13 Mar 2016 21:45:57 +1100 Subject: SASS fixes, docs changes (fixes #180), 'ready' event --- src/js/plyr.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index ec1064e8..1ad338e9 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1,6 +1,6 @@ // ========================================================================== // Plyr -// plyr.js v1.5.17 +// plyr.js v1.5.18 // https://github.com/selz/plyr // License: The MIT License (MIT) // ========================================================================== @@ -1242,7 +1242,7 @@ // Toggle style hook function _toggleStyleHook() { - _toggleClass(plyr.container, defaults.selectors.container.replace('.', ''), plyr.supported.full); + _toggleClass(plyr.container, config.selectors.container.replace('.', ''), plyr.supported.full); } // Toggle native controls @@ -2730,6 +2730,9 @@ // Display duration _displayDuration(); + + // Ready event + _triggerEvent(plyr.container, 'ready'); } // Initialize instance -- cgit v1.2.3 From b51a1684dc624a9fda18a93c83f8b5ab790146ba Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Mon, 14 Mar 2016 22:34:28 +1100 Subject: Fix for embed property not being set --- src/js/plyr.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 1ad338e9..0c877a7d 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1,6 +1,6 @@ // ========================================================================== // Plyr -// plyr.js v1.5.18 +// plyr.js v1.5.19 // https://github.com/selz/plyr // License: The MIT License (MIT) // ========================================================================== @@ -1415,14 +1415,14 @@ // When embeds are ready function _embedReady() { - // Setup the UI - _setupInterface(); - // Set title _setTitle(_getElement('iframe')); // Store reference to API plyr.container.plyr.embed = plyr.embed; + + // Setup the UI + _setupInterface(); } // Handle YouTube API ready -- cgit v1.2.3 From 815100cff8ba4241ebf636ee9aac56a96a82851d Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Mon, 14 Mar 2016 22:50:34 +1100 Subject: Autoplay bug fixes --- src/js/plyr.js | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 0c877a7d..5615f511 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1319,12 +1319,6 @@ // Clean up plyr.embedId = null; } - else { - // Autoplay - if (config.autoplay) { - _play(); - } - } } // Setup YouTube/Vimeo @@ -1438,7 +1432,7 @@ plyr.embed = new YT.Player(container.id, { videoId: videoId, playerVars: { - autoplay: plyr.autoplay ? 1 : 0, + autoplay: (config.autoplay ? 1 : 0), controls: (plyr.supported.full ? 0 : 1), rel: 0, showinfo: 0, @@ -1626,12 +1620,12 @@ }); // Always seek to 0 - //plyr.embed.api('seekTo', 0); + // plyr.embed.api('seekTo', 0); - // Prevent autoplay if needed (seek will play) - //if (!config.autoplay) { - // plyr.embed.api('pause'); - //} + // Autoplay + if (config.autoplay) { + plyr.embed.api('play'); + } }); } @@ -2277,6 +2271,11 @@ // Inject the new element _prependChild(plyr.container, plyr.media); + // Autoplay the new source? + if (typeof source.autoplay !== 'undefined') { + config.autoplay = source.autoplay; + } + // Set attributes for audio video if (_inArray(config.types.html5, plyr.type)) { if (config.crossorigin) { @@ -2301,9 +2300,6 @@ _toggleClass(plyr.container, config.classes.captions.active, plyr.captionsEnabled); _toggleStyleHook(); - // Autoplay the new source? - config.autoplay = (source.autoplay || config.autoplay); - // Set new sources for html5 if (_inArray(config.types.html5, plyr.type)) { _insertChildElements('source', source.sources); @@ -2329,11 +2325,6 @@ _displayDuration(); } - // Play if autoplay attribute is present - if (config.autoplay) { - _play(); - } - // Set aria title and iframe title config.title = source.title; _setTitle(); @@ -2668,6 +2659,11 @@ // Set title on button and frame _setTitle(); + + // Autoplay + if (config.autoplay) { + _play(); + } } // Successful setup -- cgit v1.2.3 From 6ae2655923b3f4a74ddf06e99b54a9b7f450c9e8 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Mon, 14 Mar 2016 22:53:11 +1100 Subject: Version bump --- src/js/plyr.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index 5615f511..e39665e8 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1,6 +1,6 @@ // ========================================================================== // Plyr -// plyr.js v1.5.19 +// plyr.js v1.5.20 // https://github.com/selz/plyr // License: The MIT License (MIT) // ========================================================================== -- cgit v1.2.3 From 67b2f2510bed1223cd137f3d0f2f9151f6d12d12 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sun, 27 Mar 2016 18:29:58 +1100 Subject: Bug fix for embeds: `play` not being defined (fixes #185 and #186) --- src/js/plyr.js | 12 ++++++------ src/less/plyr.less | 1 + src/sass/plyr.scss | 1 + 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/js/plyr.js b/src/js/plyr.js index e39665e8..3d78c58c 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1,13 +1,13 @@ // ========================================================================== // Plyr -// plyr.js v1.5.20 +// plyr.js v1.5.21 // https://github.com/selz/plyr // License: The MIT License (MIT) // ========================================================================== // Credits: http://paypal.github.io/accessible-html5-video-player/ // ========================================================================== -(function(root, factory) { +;(function(root, factory) { 'use strict'; /*global define,module*/ @@ -1409,14 +1409,14 @@ // When embeds are ready function _embedReady() { - // Set title - _setTitle(_getElement('iframe')); - // Store reference to API plyr.container.plyr.embed = plyr.embed; // Setup the UI _setupInterface(); + + // Set title + _setTitle(_getElement('iframe')); } // Handle YouTube API ready @@ -2830,7 +2830,7 @@ } // Create a player instance for each element - for (var i = elements.length - 1; i >= 0; i--) { + for (var i = 0; i < elements.length; i++) { // Get the current element var element = elements[i]; diff --git a/src/less/plyr.less b/src/less/plyr.less index 61b5e2ae..f27023bc 100644 --- a/src/less/plyr.less +++ b/src/less/plyr.less @@ -343,6 +343,7 @@ bottom: 100%; margin-bottom: @plyr-tooltip-padding; padding: @plyr-tooltip-padding (@plyr-tooltip-padding * 1.5); + pointer-events: none; opacity: 0; background: @plyr-tooltip-bg; diff --git a/src/sass/plyr.scss b/src/sass/plyr.scss index 0e30eb4f..8de9af6e 100644 --- a/src/sass/plyr.scss +++ b/src/sass/plyr.scss @@ -343,6 +343,7 @@ $plyr-bp-captions-large: 768px !default; // When captions jump to th bottom: 100%; margin-bottom: $plyr-tooltip-padding; padding: $plyr-tooltip-padding ($plyr-tooltip-padding * 1.5); + pointer-events: none; opacity: 0; background: $plyr-tooltip-bg; -- cgit v1.2.3