diff options
author | Sam Potts <me@sampotts.me> | 2016-11-27 20:15:15 +1100 |
---|---|---|
committer | Sam Potts <me@sampotts.me> | 2016-11-27 20:15:15 +1100 |
commit | a44c7ecc3a077b11fc586bba8aa2df25b01f209f (patch) | |
tree | 73560a7146bfa99ba5f7c0fd8e45328641678180 /src | |
parent | 73a1391f2fbe3e986fc09ec82b433674128b1160 (diff) | |
download | plyr-a44c7ecc3a077b11fc586bba8aa2df25b01f209f.tar.lz plyr-a44c7ecc3a077b11fc586bba8aa2df25b01f209f.tar.xz plyr-a44c7ecc3a077b11fc586bba8aa2df25b01f209f.zip |
Fix for iPad and YouTube issues
Diffstat (limited to 'src')
-rw-r--r-- | src/js/plyr.js | 133 | ||||
-rw-r--r-- | src/less/plyr.less | 37 | ||||
-rw-r--r-- | src/scss/plyr.scss | 34 |
3 files changed, 117 insertions, 87 deletions
diff --git a/src/js/plyr.js b/src/js/plyr.js index 4c02b8fd..d65c4f7a 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -25,7 +25,7 @@ 'use strict'; // Globals - var fullscreen, + var fullscreen, scroll = { x: 0, y: 0 }, // Default config @@ -36,8 +36,8 @@ loop: false, seekTime: 10, volume: 10, - volumeMin: 0, - volumeMax: 10, + volumeMin: 0, + volumeMax: 10, volumeStep: 1, duration: null, displayDuration: true, @@ -257,6 +257,7 @@ isChrome: isChrome, isSafari: isSafari, isIos: /(iPad|iPhone|iPod)/g.test(navigator.platform), + isIphone: /(iPhone|iPod)/g.test(navigator.userAgent), isTouch: 'ontouchstart' in document.documentElement }; } @@ -493,9 +494,9 @@ } // Create and dispatch the event - var event = new CustomEvent(type, { + var event = new CustomEvent(type, { bubbles: bubbles, - detail: properties + detail: properties }); // Dispatch the event @@ -568,7 +569,7 @@ // Check variable types var _is = { object: function(input) { - return input !== null && typeof(input) === 'object'; + return input !== null && typeof(input) === 'object'; }, array: function(input) { return input !== null && (typeof(input) === 'object' && input.constructor === Array); @@ -713,7 +714,7 @@ timers = {}, api; - // Set media + // Set media plyr.media = media; var original = media.cloneNode(true); @@ -732,7 +733,7 @@ if (_is.string(config.logPrefix) && config.logPrefix.length) { args.unshift(config.logPrefix); } - + console[type].apply(console, args); } } @@ -1037,7 +1038,7 @@ var captions = [], caption, req = xhr.responseText; - + //According to webvtt spec, line terminator consists of one of the following // CRLF (U+000D U+000A), LF (U+000A) or CR (U+000D) var lineSeparator = '\r\n'; @@ -1048,7 +1049,7 @@ lineSeparator = '\n'; } } - + captions = req.split(lineSeparator+lineSeparator); for (var r = 0; r < captions.length; r++) { @@ -1530,7 +1531,7 @@ mediaId = _parseVimeoId(plyr.embedId); break; - default: + default: mediaId = plyr.embedId; } @@ -1819,7 +1820,7 @@ plyr.embed.stop(); plyr.media.paused = true; }; - + plyr.media.paused = true; plyr.media.currentTime = 0; @@ -1835,7 +1836,7 @@ plyr.embed.getDuration().then(function(value) { plyr.media.duration = value; - + // Trigger timeupdate _triggerEvent(plyr.media, 'durationchange'); }); @@ -1898,7 +1899,7 @@ plyr.embed = window.SC.Widget(this); // Setup on ready - plyr.embed.bind(window.SC.Widget.Events.READY, function() { + plyr.embed.bind(window.SC.Widget.Events.READY, function() { // Create a faux HTML5 API using the Soundcloud API plyr.media.play = function() { plyr.embed.play(); @@ -2035,7 +2036,7 @@ targetTime = duration; } - // Update seek range and progress + // Update seek range and progress _updateSeekDisplay(targetTime); // Set the current time @@ -2126,7 +2127,7 @@ function _toggleFullscreen(event) { // Check for native support var nativeSupport = fullscreen.supportsFullScreen; - + if (nativeSupport) { // If it's a fullscreen change event, update the UI if (event && event.type === fullscreen.fullScreenEventName) { @@ -2424,7 +2425,7 @@ if (!plyr.supported.full) { return; } - + // Default to 0 if (_is.undefined(value)) { value = 0; @@ -2516,7 +2517,7 @@ _updateProgress(event); } - // Update seek range and progress + // Update seek range and progress function _updateSeekDisplay(time) { // Default to 0 if (!_is.number(time)) { @@ -2526,7 +2527,7 @@ var duration = _getDuration(), value = _getPercentage(time, duration); - // Update progress + // Update progress if (plyr.progress && plyr.progress.played) { plyr.progress.played.value = value; } @@ -2635,15 +2636,15 @@ } } - // If toggle is false or if we're playing (regardless of toggle), - // then set the timer to hide the controls + // If toggle is false or if we're playing (regardless of toggle), + // then set the timer to hide the controls if (!show || !plyr.media.paused) { timers.hover = window.setTimeout(function() { // If the mouse is over the controls (and not entering fullscreen), bail if ((plyr.controls.pressed || plyr.controls.hover) && !isEnterFullscreen) { return; } - + _toggleClass(plyr.container, config.classes.hideControls, true); }, delay); } @@ -2720,7 +2721,7 @@ _remove(plyr.videoContainer); } - // Reset class name + // Reset class name if (plyr.container) { plyr.container.removeAttribute('class'); } @@ -2915,7 +2916,7 @@ count = get().length; // Only handle global key press if there's only one player - // and the key is in the allowed keys + // and the key is in the allowed keys // and if the focused element is not editable (e.g. text input) // and any that accept key input http://webaim.org/techniques/keyboard/ if (count === 1 && _inArray(allowed, code) && (!_is.htmlElement(focused) || !_matches(focused, config.selectors.editable))) { @@ -2949,7 +2950,7 @@ return; } - // Divide the max duration into 10th's and times by the number value + // Divide the max duration into 10th's and times by the number value _seek((duration / 10) * (code - 48)); } @@ -2967,18 +2968,18 @@ switch(code) { // 0-9 - case 48: - case 49: - case 50: - case 51: - case 52: - case 53: - case 54: - case 55: + case 48: + case 49: + case 50: + case 51: + case 52: + case 53: + case 54: + case 55: case 56: case 57: if (!held) { seekByKey(); } break; // Space and K key - case 32: + case 32: case 75: if (!held) { _togglePlay(); } break; // Arrow up case 38: _increaseVolume(); break; @@ -2996,7 +2997,7 @@ case 67: if (!held) { _toggleCaptions(); } break; } - // Escape is handle natively when in full screen + // Escape is handle natively when in full screen // So we only need to worry about non native if (!fullscreen.supportsFullScreen && plyr.isFullscreen && code === 27) { _toggleFullscreen(); @@ -3075,12 +3076,12 @@ _on(plyr.container, 'mouseenter mouseleave mousemove touchstart touchend touchcancel touchmove enterfullscreen', _toggleControls); // Watch for cursor over controls so they don't hide when trying to interact - _on(plyr.controls, 'mouseenter mouseleave', function(event) { + _on(plyr.controls, 'mouseenter mouseleave', function(event) { plyr.controls.hover = event.type === 'mouseenter'; }); // Watch for cursor over controls so they don't hide when trying to interact - _on(plyr.controls, 'mousedown mouseup touchstart touchend touchcancel', function(event) { + _on(plyr.controls, 'mousedown mouseup touchstart touchend touchcancel', function(event) { plyr.controls.pressed = _inArray(['mousedown', 'touchstart'], event.type); }); @@ -3136,7 +3137,7 @@ if (plyr.type === 'video') { _setCaption(); } - + // Restart _seek(); @@ -3238,7 +3239,7 @@ // Type specific stuff switch (plyr.type) { - case 'youtube': + case 'youtube': // Clear timers window.clearInterval(timers.buffering); window.clearInterval(timers.playing); @@ -3248,11 +3249,11 @@ // Clean up cleanUp(); - + break; case 'vimeo': - // Destroy Vimeo API + // Destroy Vimeo API // then clean up (wait, to prevent postmessage errors) plyr.embed.unload().then(cleanUp); @@ -3294,6 +3295,9 @@ // Replace the container with the original element provided plyr.container.parentNode.replaceChild(original, plyr.container); + // Allow overflow (set on fullscreen) + document.body.style.overflow = ''; + // Event _triggerEvent(original, 'destroyed', true); } @@ -3448,7 +3452,7 @@ isMuted: function() { return plyr.media.muted; }, isReady: function() { return _hasClass(plyr.container, config.classes.ready); }, isLoading: function() { return _hasClass(plyr.container, config.classes.loading); }, - isPaused: function() { return plyr.media.paused; }, + isPaused: function() { return plyr.media.paused; }, on: function(event, callback) { _on(plyr.container, event, callback); return this; }, play: _play, pause: _pause, @@ -3473,7 +3477,7 @@ // Everything done function _ready() { // Ready event at end of execution stack - window.setTimeout(function() { + window.setTimeout(function() { _triggerEvent(plyr.media, 'ready'); }, 0); @@ -3540,31 +3544,48 @@ var browser = _browserSniff(), isOldIE = (browser.isIE && browser.version <= 9), isIos = browser.isIos, - isIphone = /iPhone|iPod/i.test(navigator.userAgent), - audio = !!document.createElement('audio').canPlayType, - video = !!document.createElement('video').canPlayType, - basic, full; + isIphone = browser.isIphone, + audioSupport = !!document.createElement('audio').canPlayType, + videoSupport = !!document.createElement('video').canPlayType, + basic = false, + full = false; switch (type) { case 'video': - basic = video; + basic = videoSupport; full = (basic && (!isOldIE && !isIphone)); break; case 'audio': - basic = audio; + basic = audioSupport; full = (basic && !isOldIE); break; + // Vimeo does not seem to be supported on iOS via API + // Issue raised https://github.com/vimeo/player.js/issues/87 case 'vimeo': + basic = true; + full = (!isOldIE && !isIos); + break; + case 'youtube': + basic = true; + full = (!isOldIE && !isIos); + + // YouTube seems to work on iOS 10+ on iPad + if (isIos && !isIphone && browser.version >= 10) { + full = true; + } + + break; + case 'soundcloud': basic = true; - full = (!isOldIE && !isIos); + full = (!isOldIE && !isIphone); break; default: - basic = (audio && video); + basic = (audioSupport && videoSupport); full = (basic && !isOldIE); } @@ -3679,15 +3700,15 @@ // Listen for events if debugging if (config.debug) { var events = config.events.concat(['setup', 'statechange', 'enterfullscreen', 'exitfullscreen', 'captionsenabled', 'captionsdisabled']); - - _on(instance.getContainer(), events.join(' '), function(event) { + + _on(instance.getContainer(), events.join(' '), function(event) { console.log([config.logPrefix, 'event:', event.type].join(' '), event.detail.plyr); }); } // Callback - _event(instance.getContainer(), 'setup', true, { - plyr: instance + _event(instance.getContainer(), 'setup', true, { + plyr: instance }); // Add to return array even if it's already setup @@ -3718,7 +3739,7 @@ } }); - return instances; + return instances; } return []; diff --git a/src/less/plyr.less b/src/less/plyr.less index 143e7f06..c9e3d7c3 100644 --- a/src/less/plyr.less +++ b/src/less/plyr.less @@ -61,14 +61,14 @@ height: (@plyr-range-thumb-height * @plyr-range-thumb-active-scale); width: 100%; margin: 0; - padding: 0; + padding: 0; vertical-align: middle; - + appearance: none; cursor: pointer; border: none; background: transparent; - + // WebKit &::-webkit-slider-runnable-track { .plyr-range-track(); @@ -86,7 +86,7 @@ &::-moz-range-thumb { .plyr-range-thumb(); } - + // Microsoft &::-ms-track { height: @plyr-range-track-height; @@ -104,7 +104,7 @@ &::-ms-thumb { .plyr-range-thumb(); // For some reason, Edge uses the -webkit margin above - margin-top: 0; + margin-top: 0; } &::-ms-tooltip { display: none; @@ -116,11 +116,11 @@ } &::-moz-focus-outer { border: 0; - } + } &.tab-focus:focus { outline-offset: 3px; } - + // Pressed styles &:active { &::-webkit-slider-thumb { @@ -179,9 +179,10 @@ .plyr__video-embed { padding-bottom: 56.25%; /* 16:9 */ height: 0; - overflow: hidden; + border-radius: inherit; - // Require z-index to force border-radius + // Require overflow and z-index to force border-radius + overflow: hidden; z-index: 0; iframe { @@ -192,7 +193,6 @@ height: 100%; border: 0; user-select: none; - z-index: 1; } // Vimeo hack @@ -265,7 +265,7 @@ // Playback controls .plyr__controls { display: flex; - align-items: center; + align-items: center; line-height: 1; text-align: center; @@ -329,7 +329,7 @@ } } } -// Hide controls +// Hide controls .plyr--hide-controls .plyr__controls { opacity: 0; pointer-events: none; @@ -341,6 +341,7 @@ left: 0; right: 0; bottom: 0; + z-index: 2; padding: (@plyr-control-spacing * 5) @plyr-control-spacing @plyr-control-spacing; background: linear-gradient(fade(@plyr-video-controls-bg, 0%), fade(@plyr-video-controls-bg, 50%)); border-bottom-left-radius: inherit; @@ -476,7 +477,7 @@ height: 0; left: 50%; transform: translateX(-50%); - + // The background triangle bottom: -@plyr-tooltip-arrow-size; border-right: @plyr-tooltip-arrow-size solid transparent; @@ -624,16 +625,16 @@ } &::-moz-progress-bar { transition: width .2s ease; - } + } &::-ms-fill { transition: width .2s ease; - } + } } .plyr--video .plyr__progress--buffer, .plyr--video .plyr__volume--display { background: @plyr-video-range-track-bg; } -.plyr--video .plyr__progress--buffer { +.plyr--video .plyr__progress--buffer { color: @plyr-video-progress-buffered-bg; } .plyr--audio .plyr__progress--buffer, @@ -740,6 +741,10 @@ height: 100%; width: 100%; } + .plyr__video-embed { + // Revert overflow change + overflow: visible; + } .plyr__controls { position: absolute; bottom: 0; diff --git a/src/scss/plyr.scss b/src/scss/plyr.scss index 70518591..91a5d1b2 100644 --- a/src/scss/plyr.scss +++ b/src/scss/plyr.scss @@ -61,14 +61,14 @@ height: ($plyr-range-thumb-height * $plyr-range-thumb-active-scale); width: 100%; margin: 0; - padding: 0; + padding: 0; vertical-align: middle; - + appearance: none; cursor: pointer; border: none; background: transparent; - + // WebKit &::-webkit-slider-runnable-track { @include plyr-range-track(); @@ -86,7 +86,7 @@ &::-moz-range-thumb { @include plyr-range-thumb(); } - + // Microsoft &::-ms-track { height: $plyr-range-track-height; @@ -104,7 +104,7 @@ &::-ms-thumb { @include plyr-range-thumb(); // For some reason, Edge uses the -webkit margin above - margin-top: 0; + margin-top: 0; } &::-ms-tooltip { display: none; @@ -116,11 +116,11 @@ } &::-moz-focus-outer { border: 0; - } + } &.tab-focus:focus { outline-offset: 3px; } - + // Pressed styles &:active { &::-webkit-slider-thumb { @@ -178,10 +178,10 @@ .plyr__video-embed { padding-bottom: 56.25%; /* 16:9 */ height: 0; - overflow: hidden; border-radius: inherit; - // Require z-index to force border-radius + // Require overflow and z-index to force border-radius + overflow: hidden; z-index: 0; iframe { @@ -264,7 +264,7 @@ // Playback controls .plyr__controls { display: flex; - align-items: center; + align-items: center; line-height: 1; text-align: center; @@ -328,7 +328,7 @@ } } } -// Hide controls +// Hide controls .plyr--hide-controls .plyr__controls { opacity: 0; pointer-events: none; @@ -475,7 +475,7 @@ height: 0; left: 50%; transform: translateX(-50%); - + // The background triangle bottom: -$plyr-tooltip-arrow-size; border-right: $plyr-tooltip-arrow-size solid transparent; @@ -622,16 +622,16 @@ } &::-moz-progress-bar { transition: width .2s ease; - } + } &::-ms-fill { transition: width .2s ease; - } + } } .plyr--video .plyr__progress--buffer, .plyr--video .plyr__volume--display { background: $plyr-video-range-track-bg; } -.plyr--video .plyr__progress--buffer { +.plyr--video .plyr__progress--buffer { color: $plyr-video-progress-buffered-bg; } .plyr--audio .plyr__progress--buffer, @@ -738,6 +738,10 @@ height: 100%; width: 100%; } + .plyr__video-embed { + // Revert overflow change + overflow: visible; + } .plyr__controls { position: absolute; bottom: 0; |