aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSam Potts <me@sampotts.me>2017-05-07 19:03:48 +1000
committerSam Potts <me@sampotts.me>2017-05-07 19:03:48 +1000
commitaba5a9dc0e421a9f8a6098847fe3927f565c3241 (patch)
treef4498cb22459737fe6651ab05f4e8c42ff0d4d0e /src
parent97157efcfa51297324046087ad787ed346a39f06 (diff)
downloadplyr-aba5a9dc0e421a9f8a6098847fe3927f565c3241.tar.lz
plyr-aba5a9dc0e421a9f8a6098847fe3927f565c3241.tar.xz
plyr-aba5a9dc0e421a9f8a6098847fe3927f565c3241.zip
Utils object, work on Vimeo captions
Diffstat (limited to 'src')
-rw-r--r--src/js/plyr.js1255
-rw-r--r--src/less/plyr.less4
2 files changed, 638 insertions, 621 deletions
diff --git a/src/js/plyr.js b/src/js/plyr.js
index fd823bbc..6e2ec27f 100644
--- a/src/js/plyr.js
+++ b/src/js/plyr.js
@@ -309,7 +309,7 @@
return input !== null && typeof(input) === 'object' && input.constructor === Object;
},
array: function(input) {
- return input !== null && typeof(input) === 'object' && input.constructor === Array;
+ return input !== null && Array.isArray(input);
},
number: function(input) {
return input !== null && (typeof(input) === 'number' && !isNaN(input - 0) || (typeof input === 'object' && input.constructor === Number));
@@ -346,470 +346,473 @@
}
};
- // Credits: http://paypal.github.io/accessible-html5-video-player/
- // Unfortunately, due to mixed support, UA sniffing is required
- function getBrowser() {
- var ua = navigator.userAgent;
- var name = navigator.appName;
- var fullVersion = '' + parseFloat(navigator.appVersion);
- var majorVersion = parseInt(navigator.appVersion, 10);
- var nameOffset;
- var verOffset;
- var ix;
- var isIE = false;
- var isFirefox = false;
- var isChrome = false;
- var isSafari = false;
-
- if ((navigator.appVersion.indexOf('Windows NT') !== -1) && (navigator.appVersion.indexOf('rv:11') !== -1)) {
- // MSIE 11
- isIE = true;
- name = 'IE';
- fullVersion = '11';
- } else if ((verOffset = ua.indexOf('MSIE')) !== -1) {
- // MSIE
- isIE = true;
- name = 'IE';
- fullVersion = ua.substring(verOffset + 5);
- } else if ((verOffset = ua.indexOf('Chrome')) !== -1) {
- // Chrome
- isChrome = true;
- name = 'Chrome';
- fullVersion = ua.substring(verOffset + 7);
- } else if ((verOffset = ua.indexOf('Safari')) !== -1) {
- // Safari
- isSafari = true;
- name = 'Safari';
- fullVersion = ua.substring(verOffset + 7);
-
- if ((verOffset = ua.indexOf('Version')) !== -1) {
+ var utils = {
+ // Credits: http://paypal.github.io/accessible-html5-video-player/
+ // Unfortunately, due to mixed support, UA sniffing is required
+ getBrowser: function() {
+ var ua = navigator.userAgent;
+ var name = navigator.appName;
+ var fullVersion = '' + parseFloat(navigator.appVersion);
+ var majorVersion = parseInt(navigator.appVersion, 10);
+ var nameOffset;
+ var verOffset;
+ var ix;
+ var isIE = false;
+ var isFirefox = false;
+ var isChrome = false;
+ var isSafari = false;
+
+ if ((navigator.appVersion.indexOf('Windows NT') !== -1) && (navigator.appVersion.indexOf('rv:11') !== -1)) {
+ // MSIE 11
+ isIE = true;
+ name = 'IE';
+ fullVersion = '11';
+ } else if ((verOffset = ua.indexOf('MSIE')) !== -1) {
+ // MSIE
+ isIE = true;
+ name = 'IE';
+ fullVersion = ua.substring(verOffset + 5);
+ } else if ((verOffset = ua.indexOf('Chrome')) !== -1) {
+ // Chrome
+ isChrome = true;
+ name = 'Chrome';
+ fullVersion = ua.substring(verOffset + 7);
+ } else if ((verOffset = ua.indexOf('Safari')) !== -1) {
+ // Safari
+ isSafari = true;
+ name = 'Safari';
+ fullVersion = ua.substring(verOffset + 7);
+
+ if ((verOffset = ua.indexOf('Version')) !== -1) {
+ fullVersion = ua.substring(verOffset + 8);
+ }
+ } else if ((verOffset = ua.indexOf('Firefox')) !== -1) {
+ // Firefox
+ isFirefox = true;
+ name = 'Firefox';
fullVersion = ua.substring(verOffset + 8);
+ } else if ((nameOffset = ua.lastIndexOf(' ') + 1) < (verOffset = ua.lastIndexOf('/'))) {
+ // In most other browsers, 'name/version' is at the end of userAgent
+ name = ua.substring(nameOffset, verOffset);
+ fullVersion = ua.substring(verOffset + 1);
+
+ if (name.toLowerCase() === name.toUpperCase()) {
+ name = navigator.appName;
+ }
}
- } else if ((verOffset = ua.indexOf('Firefox')) !== -1) {
- // Firefox
- isFirefox = true;
- name = 'Firefox';
- fullVersion = ua.substring(verOffset + 8);
- } else if ((nameOffset = ua.lastIndexOf(' ') + 1) < (verOffset = ua.lastIndexOf('/'))) {
- // In most other browsers, 'name/version' is at the end of userAgent
- name = ua.substring(nameOffset, verOffset);
- fullVersion = ua.substring(verOffset + 1);
- if (name.toLowerCase() === name.toUpperCase()) {
- name = navigator.appName;
+ // Trim the fullVersion string at semicolon/space if present
+ if ((ix = fullVersion.indexOf(';')) !== -1) {
+ fullVersion = fullVersion.substring(0, ix);
+ }
+ if ((ix = fullVersion.indexOf(' ')) !== -1) {
+ fullVersion = fullVersion.substring(0, ix);
}
- }
- // Trim the fullVersion string at semicolon/space if present
- if ((ix = fullVersion.indexOf(';')) !== -1) {
- fullVersion = fullVersion.substring(0, ix);
- }
- if ((ix = fullVersion.indexOf(' ')) !== -1) {
- fullVersion = fullVersion.substring(0, ix);
- }
+ // Get major version
+ majorVersion = parseInt('' + fullVersion, 10);
+ if (isNaN(majorVersion)) {
+ fullVersion = '' + parseFloat(navigator.appVersion);
+ majorVersion = parseInt(navigator.appVersion, 10);
+ }
- // Get major version
- majorVersion = parseInt('' + fullVersion, 10);
- if (isNaN(majorVersion)) {
- fullVersion = '' + parseFloat(navigator.appVersion);
- majorVersion = parseInt(navigator.appVersion, 10);
- }
+ // Return data
+ return {
+ name: name,
+ version: majorVersion,
+ isIE: isIE,
+ isFirefox: isFirefox,
+ isChrome: isChrome,
+ isSafari: isSafari,
+ isIos: /(iPad|iPhone|iPod)/g.test(navigator.platform),
+ isTouch: 'ontouchstart' in document.documentElement
+ };
+ },
- // Return data
- return {
- name: name,
- version: majorVersion,
- isIE: isIE,
- isFirefox: isFirefox,
- isChrome: isChrome,
- isSafari: isSafari,
- isIos: /(iPad|iPhone|iPod)/g.test(navigator.platform),
- isTouch: 'ontouchstart' in document.documentElement
- };
- }
+ // Inject a script
+ injectScript: function(url) {
+ // Check script is not already referenced
+ if (document.querySelectorAll('script[src="' + url + '"]').length) {
+ return;
+ }
- // Inject a script
- function injectScript(url) {
- // Check script is not already referenced
- if (document.querySelectorAll('script[src="' + url + '"]').length) {
- return;
- }
+ var tag = document.createElement('script');
+ tag.src = url;
- var tag = document.createElement('script');
- tag.src = url;
+ var firstScriptTag = document.getElementsByTagName('script')[0];
+ firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
+ },
- var firstScriptTag = document.getElementsByTagName('script')[0];
- firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
- }
+ // Determine if we're in an iframe
+ inFrame: function() {
+ try {
+ return window.self !== window.top;
+ } catch (e) {
+ return true;
+ }
+ },
- // Determine if we're in an iframe
- function inFrame() {
- try {
- return window.self !== window.top;
- } catch (e) {
- return true;
- }
- }
+ // Element exists in an array
+ inArray: function(haystack, needle) {
+ return is.array(haystack) && haystack.indexOf(needle) !== -1;
+ },
- // Element exists in an array
- function inArray(haystack, needle) {
- return Array.prototype.indexOf && (haystack.indexOf(needle) !== -1);
- }
+ // Replace all
+ replaceAll: function(string, find, replace) {
+ return string.replace(new RegExp(find.replace(/([.*+?\^=!:${}()|\[\]\/\\])/g, '\\$1'), 'g'), replace);
+ },
- // Replace all
- function replaceAll(string, find, replace) {
- return string.replace(new RegExp(find.replace(/([.*+?\^=!:${}()|\[\]\/\\])/g, '\\$1'), 'g'), replace);
- }
+ // Wrap an element
+ wrap: function(elements, wrapper) {
+ // Convert `elements` to an array, if necessary.
+ if (!elements.length) {
+ elements = [elements];
+ }
- // Wrap an element
- function wrap(elements, wrapper) {
- // Convert `elements` to an array, if necessary.
- if (!elements.length) {
- elements = [elements];
- }
+ // Loops backwards to prevent having to clone the wrapper on the
+ // first element (see `child` below).
+ for (var i = elements.length - 1; i >= 0; i--) {
+ var child = (i > 0) ? wrapper.cloneNode(true) : wrapper;
+ var element = elements[i];
- // Loops backwards to prevent having to clone the wrapper on the
- // first element (see `child` below).
- for (var i = elements.length - 1; i >= 0; i--) {
- var child = (i > 0) ? wrapper.cloneNode(true) : wrapper;
- var element = elements[i];
-
- // Cache the current parent and sibling.
- var parent = element.parentNode;
- var sibling = element.nextSibling;
-
- // Wrap the element (is automatically removed from its current
- // parent).
- child.appendChild(element);
-
- // If the element had a sibling, insert the wrapper before
- // the sibling to maintain the HTML structure; otherwise, just
- // append it to the parent.
- if (sibling) {
- parent.insertBefore(child, sibling);
- } else {
- parent.appendChild(child);
+ // Cache the current parent and sibling.
+ var parent = element.parentNode;
+ var sibling = element.nextSibling;
+
+ // Wrap the element (is automatically removed from its current
+ // parent).
+ child.appendChild(element);
+
+ // If the element had a sibling, insert the wrapper before
+ // the sibling to maintain the HTML structure; otherwise, just
+ // append it to the parent.
+ if (sibling) {
+ parent.insertBefore(child, sibling);
+ } else {
+ parent.appendChild(child);
+ }
+
+ return child;
}
+ },
- return child;
- }
- }
+ // Remove an element
+ removeElement: function(element) {
+ if (!is.htmlElement(element)) {
+ return;
+ }
- // Remove an element
- function remove(element) {
- if (!element) {
- return;
- }
- element.parentNode.removeChild(element);
- }
+ element.parentNode.removeChild(element);
+ },
- // Prepend child
- function prependChild(parent, element) {
- parent.insertBefore(element, parent.firstChild);
- }
+ // Prepend child
+ prependChild: function(parent, element) {
+ parent.insertBefore(element, parent.firstChild);
+ },
- // Set attributes
- function setAttributes(element, attributes) {
- for (var key in attributes) {
- element.setAttribute(key, attributes[key]);
- }
- }
+ // Set attributes
+ setAttributes: function(element, attributes) {
+ for (var key in attributes) {
+ element.setAttribute(key, attributes[key]);
+ }
+ },
- // Get an attribute object from a string selector
- function getAttributesFromSelector(selector, existingAttributes) {
- // For example:
- // '.test' to { class: 'test' }
- // '#test' to { id: 'test' }
- // '[data-test="test"]' to { 'data-test': 'test' }
+ // Get an attribute object from a string selector
+ getAttributesFromSelector: function(selector, existingAttributes) {
+ // For example:
+ // '.test' to { class: 'test' }
+ // '#test' to { id: 'test' }
+ // '[data-test="test"]' to { 'data-test': 'test' }
- if (!is.string(selector) || is.empty(selector)) {
- return {};
- }
+ if (!is.string(selector) || is.empty(selector)) {
+ return {};
+ }
- var attributes = {};
+ var attributes = {};
- selector.split(',').forEach(function(selector) {
- // Remove whitespace
- selector = selector.trim();
+ selector.split(',').forEach(function(selector) {
+ // Remove whitespace
+ selector = selector.trim();
- // Get the first character
- var start = selector.charAt(0);
+ // Get the first character
+ var start = selector.charAt(0);
- switch (start) {
- case '.':
- // Classname selector
- var className = selector.replace('.', '');
+ switch (start) {
+ case '.':
+ // Classname selector
+ var className = selector.replace('.', '');
- // Add to existing classname
- if (is.object(existingAttributes) && is.string(existingAttributes.class)) {
- existingAttributes.class += ' ' + className;
- }
+ // Add to existing classname
+ if (is.object(existingAttributes) && is.string(existingAttributes.class)) {
+ existingAttributes.class += ' ' + className;
+ }
- attributes.class = className;
- break;
+ attributes.class = className;
+ break;
- case '#':
- // ID selector
- attributes.id = selector.replace('#', '');
- break;
+ case '#':
+ // ID selector
+ attributes.id = selector.replace('#', '');
+ break;
- case '[':
- // Strip the []
- selector = selector.replace(/[\[\]]/g, '');
+ case '[':
+ // Strip the []
+ selector = selector.replace(/[\[\]]/g, '');
- // Get the parts if
- var parts = selector.split('=');
- var key = parts[0];
+ // Get the parts if
+ var parts = selector.split('=');
+ var key = parts[0];
- // Get the value if provided
- var value = parts.length > 1 ? parts[1].replace(/[\"\']/g, '') : '';
+ // Get the value if provided
+ var value = parts.length > 1 ? parts[1].replace(/[\"\']/g, '') : '';
- // Attribute selector
- attributes[key] = value;
+ // Attribute selector
+ attributes[key] = value;
- break;
- }
- });
+ break;
+ }
+ });
- return attributes;
- }
+ return attributes;
+ },
- // Create a DocumentFragment
- function createElement(type, attributes, text) {
- // Create a new <element>
- var element = document.createElement(type);
+ // Create a DocumentFragment
+ createElement: function(type, attributes, text) {
+ // Create a new <element>
+ var element = document.createElement(type);
- // Set all passed attributes
- if (is.object(attributes)) {
- setAttributes(element, attributes);
- }
+ // Set all passed attributes
+ if (is.object(attributes)) {
+ utils.setAttributes(element, attributes);
+ }
- // Add text node
- if (is.string(text)) {
- element.textContent = text;
- }
+ // Add text node
+ if (is.string(text)) {
+ element.textContent = text;
+ }
- // Return built element
- return element;
- }
+ // Return built element
+ return element;
+ },
- // Insert a DocumentFragment
- function insertElement(type, parent, attributes, text) {
- // Create a new <element>
- var element = createElement(type, attributes, text);
+ // Insert a DocumentFragment
+ insertElement: function(type, parent, attributes, text) {
+ // Create a new <element>
+ var element = utils.createElement(type, attributes, text);
- // Inject the new element
- prependChild(parent, element);
- }
+ // Inject the new element
+ utils.prependChild(parent, element);
+ },
- // Remove all child elements
- function emptyElement(element) {
- var length = element.childNodes.length;
- while (length--) {
- element.removeChild(element.lastChild);
- }
- }
+ // Remove all child elements
+ emptyElement: function(element) {
+ var length = element.childNodes.length;
+ while (length--) {
+ element.removeChild(element.lastChild);
+ }
+ },
- // Toggle class on an element
- function toggleClass(element, className, state) {
- if (element) {
- if (element.classList) {
- element.classList[state ? 'add' : 'remove'](className);
- } else {
- var name = (' ' + element.className + ' ').replace(/\s+/g, ' ').replace(' ' + className + ' ', '');
- element.className = name + (state ? ' ' + className : '');
+ // Toggle class on an element
+ toggleClass: function(element, className, state) {
+ if (element) {
+ if (element.classList) {
+ element.classList[state ? 'add' : 'remove'](className);
+ } else {
+ var name = (' ' + element.className + ' ').replace(/\s+/g, ' ').replace(' ' + className + ' ', '');
+ element.className = name + (state ? ' ' + className : '');
+ }
}
- }
- }
+ },
- // Has class name
- function hasClass(element, className) {
- if (element) {
- if (element.classList) {
- return element.classList.contains(className);
- } else {
- return new RegExp('(\\s|^)' + className + '(\\s|$)').test(element.className);
+ // Has class name
+ hasClass: function(element, className) {
+ if (element) {
+ if (element.classList) {
+ return element.classList.contains(className);
+ } else {
+ return new RegExp('(\\s|^)' + className + '(\\s|$)').test(element.className);
+ }
}
- }
- return false;
- }
+ return false;
+ },
- // Element matches selector
- function matches(element, selector) {
- var prototype = Element.prototype;
+ // Element matches selector
+ matches: function(element, selector) {
+ var prototype = Element.prototype;
- var matches = prototype.matches ||
- prototype.webkitMatchesSelector ||
- prototype.mozMatchesSelector ||
- prototype.msMatchesSelector ||
- function(s) {
- return [].indexOf.call(document.querySelectorAll(s), this) !== -1;
- };
+ var matches = prototype.matches ||
+ prototype.webkitMatchesSelector ||
+ prototype.mozMatchesSelector ||
+ prototype.msMatchesSelector ||
+ function(s) {
+ return [].indexOf.call(document.querySelectorAll(s), this) !== -1;
+ };
- return matches.call(element, selector);
- }
+ return matches.call(element, selector);
+ },
- // Get the focused element
- function getFocusElement() {
- var focused = document.activeElement;
+ // Get the focused element
+ getFocusElement: function() {
+ var focused = document.activeElement;
- if (!focused || focused === document.body) {
- focused = null;
- } else {
- focused = document.querySelector(':focus');
- }
+ if (!focused || focused === document.body) {
+ focused = null;
+ } else {
+ focused = document.querySelector(':focus');
+ }
- return focused;
- }
+ return focused;
+ },
- // Bind along with custom handler
- function proxy(element, eventName, customListener, defaultListener, useCapture) {
- on(element, eventName, function(event) {
- if (customListener) {
- customListener.apply(element, [event]);
- }
- defaultListener.apply(element, [event]);
- }, useCapture);
- }
+ // Bind along with custom handler
+ proxy: function(element, eventName, customListener, defaultListener, useCapture) {
+ utils.on(element, eventName, function(event) {
+ if (customListener) {
+ customListener.apply(element, [event]);
+ }
+ defaultListener.apply(element, [event]);
+ }, useCapture);
+ },
- // Toggle event listener
- function toggleListener(elements, events, callback, toggle, useCapture) {
- var eventList = events.split(' ');
+ // Toggle event listener
+ toggleListener: function(elements, events, callback, toggle, useCapture) {
+ var eventList = events.split(' ');
- // Whether the listener is a capturing listener or not
- // Default to false
- if (!is.boolean(useCapture)) {
- useCapture = false;
- }
+ // Whether the listener is a capturing listener or not
+ // Default to false
+ if (!is.boolean(useCapture)) {
+ useCapture = false;
+ }
- // If a nodelist is passed, call itself on each node
- if (elements instanceof NodeList) {
- for (var x = 0; x < elements.length; x++) {
- if (elements[x] instanceof Node) {
- toggleListener(elements[x], arguments[1], arguments[2], arguments[3]);
+ // If a nodelist is passed, call itself on each node
+ if (elements instanceof NodeList) {
+ for (var x = 0; x < elements.length; x++) {
+ if (elements[x] instanceof Node) {
+ utils.toggleListener(elements[x], arguments[1], arguments[2], arguments[3]);
+ }
}
+ return;
}
- return;
- }
- // If a single node is passed, bind the event listener
- for (var i = 0; i < eventList.length; i++) {
- elements[toggle ? 'addEventListener' : 'removeEventListener'](eventList[i], callback, useCapture);
- }
- }
+ // If a single node is passed, bind the event listener
+ for (var i = 0; i < eventList.length; i++) {
+ elements[toggle ? 'addEventListener' : 'removeEventListener'](eventList[i], callback, useCapture);
+ }
+ },
- // Bind event handler
- function on(element, events, callback, useCapture) {
- if (!is.undefined(element)) {
- toggleListener(element, events, callback, true, useCapture);
- }
- }
+ // Bind event handler
+ on: function(element, events, callback, useCapture) {
+ if (!is.undefined(element)) {
+ utils.toggleListener(element, events, callback, true, useCapture);
+ }
+ },
- // Unbind event handler
- function off(element, events, callback, useCapture) {
- if (!is.undefined(element)) {
- toggleListener(element, events, callback, false, useCapture);
- }
- }
+ // Unbind event handler
+ off: function(element, events, callback, useCapture) {
+ if (!is.undefined(element)) {
+ utils.toggleListener(element, events, callback, false, useCapture);
+ }
+ },
- // Trigger event
- function event(element, type, bubbles, properties) {
- // Bail if no element
- if (!element || !type) {
- return;
- }
+ // Trigger event
+ event: function(element, type, bubbles, properties) {
+ // Bail if no element
+ if (!element || !type) {
+ return;
+ }
- // Default bubbles to false
- if (!is.boolean(bubbles)) {
- bubbles = false;
- }
+ // Default bubbles to false
+ if (!is.boolean(bubbles)) {
+ bubbles = false;
+ }
- // Create and dispatch the event
- var event = new CustomEvent(type, {
- bubbles: bubbles,
- detail: properties
- });
+ // Create and dispatch the event
+ var event = new CustomEvent(type, {
+ bubbles: bubbles,
+ detail: properties
+ });
- // Dispatch the event
- element.dispatchEvent(event);
- }
+ // Dispatch the event
+ element.dispatchEvent(event);
+ },
- // 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) {
- return;
- }
+ // Toggle aria-pressed state on a toggle button
+ // http://www.ssbbartgroup.com/blog/how-not-to-misuse-aria-states-properties-and-roles
+ toggleState: function(target, state) {
+ // Bail if no target
+ if (!target) {
+ return;
+ }
- // Get state
- state = (is.boolean(state) ? state : !target.getAttribute('aria-pressed'));
+ // Get state
+ state = (is.boolean(state) ? state : !target.getAttribute('aria-pressed'));
- // Set the attribute on target
- target.setAttribute('aria-pressed', state);
+ // Set the attribute on target
+ target.setAttribute('aria-pressed', state);
- return state;
- }
+ return state;
+ },
- // Get percentage
- function getPercentage(current, max) {
- if (current === 0 || max === 0 || isNaN(current) || isNaN(max)) {
- return 0;
- }
- return ((current / max) * 100).toFixed(2);
- }
+ // Get percentage
+ getPercentage: function(current, max) {
+ if (current === 0 || max === 0 || isNaN(current) || isNaN(max)) {
+ return 0;
+ }
+ return ((current / max) * 100).toFixed(2);
+ },
- // 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() {
- // Get arguments
- var objects = arguments;
+ // 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)
+ extend: function() {
+ // Get arguments
+ var objects = arguments;
- // Bail if nothing to merge
- if (!objects.length) {
- return;
- }
+ // Bail if nothing to merge
+ if (!objects.length) {
+ return;
+ }
- // Return first if specified but nothing to merge
- if (objects.length === 1) {
- return objects[0];
- }
+ // Return first if specified but nothing to merge
+ if (objects.length === 1) {
+ return objects[0];
+ }
- // First object is the destination
- var destination = Array.prototype.shift.call(objects);
- if (!is.object(destination)) {
- destination = {};
- }
+ // First object is the destination
+ var destination = Array.prototype.shift.call(objects);
+ if (!is.object(destination)) {
+ destination = {};
+ }
- var length = objects.length;
+ var length = objects.length;
- // Loop through all objects to merge
- for (var i = 0; i < length; i++) {
- var source = objects[i];
+ // Loop through all objects to merge
+ for (var i = 0; i < length; i++) {
+ var source = objects[i];
- if (!is.object(source)) {
- source = {};
- }
+ if (!is.object(source)) {
+ 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];
+ for (var property in source) {
+ if (source[property] && source[property].constructor && source[property].constructor === Object) {
+ destination[property] = destination[property] || {};
+ utils.extend(destination[property], source[property]);
+ } else {
+ destination[property] = source[property];
+ }
}
}
- }
- return destination;
- }
+ return destination;
+ },
- // Parse YouTube ID from url
- function parseYouTubeId(url) {
- var regex = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
- return url.match(regex) ? RegExp.$2 : url;
- }
+ // Parse YouTube ID from url
+ parseYouTubeId: function(url) {
+ var regex = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
+ return url.match(regex) ? RegExp.$2 : url;
+ }
+ };
// Fullscreen API
var fullscreen = (function() {
@@ -866,9 +869,6 @@
if (!is.htmlElement(element)) {
element = document.body;
}
-
- console.log(prefix);
-
return (prefix === '') ? element.requestFullScreen() : element[prefix + (prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen')]();
},
cancelFullScreen: function() {
@@ -922,7 +922,7 @@
// Picture-in-picture support
// Safari only currently
pip: (function() {
- return is.function(createElement('video').webkitSetPresentationMode);
+ return is.function(utils.createElement('video').webkitSetPresentationMode);
})(),
// Airplay support
@@ -1028,7 +1028,7 @@
// Trigger events, with plyr instance passed
function trigger(element, type, bubbles, properties) {
- event(element, type, bubbles, extend({}, properties, {
+ utils.event(element, type, bubbles, utils.extend({}, properties, {
plyr: api
}));
}
@@ -1043,6 +1043,16 @@
return getElements(selector)[0];
}
+ function removeElement(element) {
+ // Remove reference from player.elements cache
+ if (is.string(element)) {
+ utils.removeElement(player.elements[element]);
+ player.elements[element] = null;
+ } else {
+ utils.removeElement(element);
+ }
+ }
+
// Trap focus inside container
function focusTrap() {
var tabbables = getElements('input:not([disabled]), button:not([disabled])');
@@ -1065,18 +1075,18 @@
}
// Bind the handler
- on(player.elements.container, 'keydown', checkFocus);
+ utils.on(player.elements.container, 'keydown', checkFocus);
}
// Add elements to HTML5 media (source, tracks, etc)
function insertElements(type, attributes) {
if (is.string(attributes)) {
- insertElement(type, player.elements.media, {
+ utils.insertElement(type, player.elements.media, {
src: attributes
});
} else if (is.array(attributes)) {
attributes.forEach(function(attribute) {
- insertElement(type, player.elements.media, attribute);
+ utils.insertElement(type, player.elements.media, attribute);
});
}
}
@@ -1097,7 +1107,7 @@
// Create <svg>
var icon = document.createElementNS(namespace, 'svg');
- setAttributes(icon, extend(attributes, {
+ utils.setAttributes(icon, utils.extend(attributes, {
role: 'presentation'
}));
@@ -1125,18 +1135,18 @@
break;
}
- return createElement('span', {
+ return utils.createElement('span', {
class: config.classes.hidden
}, text);
}
// Create a badge
function createBadge(text) {
- var badge = createElement('span', {
+ var badge = utils.createElement('span', {
class: config.classes.menu.value
});
- badge.appendChild(createElement('span', {
+ badge.appendChild(utils.createElement('span', {
class: config.classes.menu.badge
}, text));
@@ -1145,7 +1155,7 @@
// Create a <button>
function createButton(type, attributes) {
- var button = createElement('button');
+ var button = utils.createElement('button');
var iconDefault;
var iconToggled;
var labelKey;
@@ -1195,7 +1205,7 @@
}
// Merge attributes
- extend(attributes, getAttributesFromSelector(config.selectors.buttons[type], attributes));
+ utils.extend(attributes, utils.getAttributesFromSelector(config.selectors.buttons[type], attributes));
// Add toggle icon if needed
if (is.string(iconToggled)) {
@@ -1211,7 +1221,7 @@
button.appendChild(createLabel(labelKey));
// Set element attributes
- setAttributes(button, attributes);
+ utils.setAttributes(button, attributes);
player.elements.buttons[type] = button;
@@ -1221,13 +1231,13 @@
// Create an <input type='range'>
function createRange(type, attributes) {
// Seek label
- var label = createElement('label', {
+ var label = utils.createElement('label', {
for: attributes.id,
class: config.classes.hidden
}, config.i18n[type]);
// Seek input
- var input = createElement('input', extend(getAttributesFromSelector(config.selectors.inputs[type]), {
+ var input = utils.createElement('input', utils.extend(utils.getAttributesFromSelector(config.selectors.inputs[type]), {
type: 'range',
min: 0,
max: 100,
@@ -1246,7 +1256,7 @@
// Create a <progress>
function createProgress(type, attributes) {
- var progress = createElement('progress', extend(getAttributesFromSelector(config.selectors.display[type]), {
+ var progress = utils.createElement('progress', utils.extend(utils.getAttributesFromSelector(config.selectors.display[type]), {
min: 0,
max: 100,
value: 0
@@ -1254,7 +1264,7 @@
// Create the label inside
if (type !== 'volume') {
- progress.appendChild(createElement('span', null, '0'));
+ progress.appendChild(utils.createElement('span', null, '0'));
var suffix = '';
switch (type) {
@@ -1277,15 +1287,15 @@
// Create time display
function createTime(type) {
- var container = createElement('span', {
+ var container = utils.createElement('span', {
class: 'plyr__time'
});
- container.appendChild(createElement('span', {
+ container.appendChild(utils.createElement('span', {
class: config.classes.hidden
}, config.i18n[type]));
- container.appendChild(createElement('span', getAttributesFromSelector(config.selectors.display[type]), '00:00'));
+ container.appendChild(utils.createElement('span', utils.getAttributesFromSelector(config.selectors.display[type]), '00:00'));
player.elements.display[type] = container;
@@ -1295,33 +1305,33 @@
// Build the default HTML
function createControls(data) {
// Create the container
- var controls = createElement('div', getAttributesFromSelector(config.selectors.controls.wrapper));
+ var controls = utils.createElement('div', utils.getAttributesFromSelector(config.selectors.controls.wrapper));
// Restart button
- if (inArray(config.controls, 'restart')) {
+ if (utils.inArray(config.controls, 'restart')) {
controls.appendChild(createButton('restart'));
}
// Rewind button
- if (inArray(config.controls, 'rewind')) {
+ if (utils.inArray(config.controls, 'rewind')) {
controls.appendChild(createButton('rewind'));
}
// Play Pause button
// TODO: This should be a toggle button really?
- if (inArray(config.controls, 'play')) {
+ if (utils.inArray(config.controls, 'play')) {
controls.appendChild(createButton('play'));
controls.appendChild(createButton('pause'));
}
// Fast forward button
- if (inArray(config.controls, 'fast-forward')) {
+ if (utils.inArray(config.controls, 'fast-forward')) {
controls.appendChild(createButton('fast-forward'));
}
// Progress
- if (inArray(config.controls, 'progress')) {
- var container = createElement('span', getAttributesFromSelector(config.selectors.progress));
+ if (utils.inArray(config.controls, 'progress')) {
+ var container = utils.createElement('span', utils.getAttributesFromSelector(config.selectors.progress));
// Seek range slider
var seek = createRange('seek', {
@@ -1340,7 +1350,7 @@
// Seek tooltip
if (config.tooltips.seek) {
- var tooltip = createElement('span', {
+ var tooltip = utils.createElement('span', {
role: 'tooltip',
class: config.classes.tooltip
}, '00:00');
@@ -1354,23 +1364,23 @@
}
// Media current time display
- if (inArray(config.controls, 'current-time')) {
+ if (utils.inArray(config.controls, 'current-time')) {
controls.appendChild(createTime('currentTime'));
}
// Media duration display
- if (inArray(config.controls, 'duration')) {
+ if (utils.inArray(config.controls, 'duration')) {
controls.appendChild(createTime('duration'));
}
// Toggle mute button
- if (inArray(config.controls, 'mute')) {
+ if (utils.inArray(config.controls, 'mute')) {
controls.appendChild(createButton('mute'));
}
// Volume range control
- if (inArray(config.controls, 'volume')) {
- var volume = createElement('span', {
+ if (utils.inArray(config.controls, 'volume')) {
+ var volume = utils.createElement('span', {
class: 'plyr__volume'
});
@@ -1381,7 +1391,7 @@
};
// Create the volume range slider
- var range = createRange('volume', extend(attributes, {
+ var range = createRange('volume', utils.extend(attributes, {
id: 'plyr-volume-' + data.id
}));
volume.appendChild(range.label);
@@ -1395,13 +1405,13 @@
}
// Toggle captions button
- if (inArray(config.controls, 'captions')) {
+ if (utils.inArray(config.controls, 'captions')) {
controls.appendChild(createButton('captions'));
}
// Settings button / menu
- if (inArray(config.controls, 'settings')) {
- var menu = createElement('span', extend(getAttributesFromSelector(config.selectors.buttons.settings), {
+ if (utils.inArray(config.controls, 'settings')) {
+ var menu = utils.createElement('span', utils.extend(utils.getAttributesFromSelector(config.selectors.buttons.settings), {
class: 'plyr__menu'
}));
@@ -1412,7 +1422,7 @@
'aria-expanded': false
}));
- var form = createElement('form', {
+ var form = utils.createElement('form', {
class: 'plyr__menu__container',
id: 'plyr-settings-' + data.id,
'aria-hidden': true,
@@ -1421,25 +1431,25 @@
tabindex: -1
});
- var inner = createElement('div');
+ var inner = utils.createElement('div');
- var home = createElement('div', {
+ var home = utils.createElement('div', {
id: 'plyr-settings-' + data.id + '-home',
'aria-hidden': false,
'aria-labelled-by': 'plyr-settings-toggle-' + data.id,
role: 'tabpanel'
});
- var tabs = createElement('ul', {
+ var tabs = utils.createElement('ul', {
role: 'tablist'
});
['captions', 'quality', 'speed', 'loop'].forEach(function(type) {
- var tab = createElement('li', {
+ var tab = utils.createElement('li', {
role: 'tab'
});
- var button = createElement('button', extend(getAttributesFromSelector(config.selectors.buttons.settings), {
+ var button = utils.createElement('button', utils.extend(utils.getAttributesFromSelector(config.selectors.buttons.settings), {
type: 'button',
class: config.classes.control + ' ' + config.classes.control + '--forward',
id: 'plyr-settings-' + data.id + '-' + type + '-tab',
@@ -1448,7 +1458,7 @@
'aria-expanded': false
}), config.i18n[type]);
- var value = createElement('span', {
+ var value = utils.createElement('span', {
class: config.classes.menu.value
});
@@ -1469,7 +1479,7 @@
inner.appendChild(home);
['captions', 'quality', 'speed', 'loop'].forEach(function(type) {
- var pane = createElement('div', {
+ var pane = utils.createElement('div', {
id: 'plyr-settings-' + data.id + '-' + type,
'aria-hidden': true,
'aria-labelled-by': 'plyr-settings-' + data.id + '-' + type + '-tab',
@@ -1477,7 +1487,7 @@
tabindex: -1
});
- var back = createElement('button', {
+ var back = utils.createElement('button', {
type: 'button',
class: config.classes.control + ' ' + config.classes.control + '--back',
'aria-haspopup': true,
@@ -1487,7 +1497,7 @@
pane.appendChild(back);
- var options = createElement('ul');
+ var options = utils.createElement('ul');
pane.appendChild(options);
@@ -1506,17 +1516,17 @@
}
// Picture in picture button
- if (inArray(config.controls, 'pip') && support.pip) {
+ if (utils.inArray(config.controls, 'pip') && support.pip) {
controls.appendChild(createButton('pip'));
}
// Airplay button
- if (inArray(config.controls, 'airplay') && support.airplay) {
+ if (utils.inArray(config.controls, 'airplay') && support.airplay) {
controls.appendChild(createButton('airplay'));
}
// Toggle fullscreen button
- if (inArray(config.controls, 'fullscreen')) {
+ if (utils.inArray(config.controls, 'fullscreen')) {
controls.appendChild(createButton('fullscreen'));
}
@@ -1535,7 +1545,7 @@
var list = player.elements.settings.panes.quality.querySelector('ul');
// Empty the menu
- emptyElement(list);
+ utils.emptyElement(list);
// Get the badge HTML for HD, 4K etc
function getBadge(quality) {
@@ -1592,14 +1602,14 @@
});
filtered.forEach(function(quality) {
- var item = createElement('li');
+ var item = utils.createElement('li');
- var label = createElement('label', {
+ var label = utils.createElement('label', {
class: config.classes.control,
for: 'plyr-quality-' + quality
});
- var radio = createElement('input', extend(getAttributesFromSelector(config.selectors.inputs.quality), {
+ var radio = utils.createElement('input', utils.extend(utils.getAttributesFromSelector(config.selectors.inputs.quality), {
type: 'radio',
id: 'plyr-quality-' + quality,
name: 'plyr-quality',
@@ -1631,18 +1641,18 @@
var list = player.elements.settings.panes.loop.querySelector('ul');
// Empty the menu
- emptyElement(list);
+ utils.emptyElement(list);
options.forEach(function(option) {
- var item = createElement('li');
+ var item = utils.createElement('li');
- var button = createElement('button', extend(getAttributesFromSelector(config.selectors.buttons.loop), {
+ var button = utils.createElement('button', utils.extend(utils.getAttributesFromSelector(config.selectors.buttons.loop), {
type: 'button',
class: config.classes.control,
'data-plyr-loop-action': option
}), config.i18n[option]);
- if (inArray(['start', 'end'], option)) {
+ if (utils.inArray(['start', 'end'], option)) {
var badge = createBadge('0:00');
button.appendChild(badge);
}
@@ -1658,7 +1668,7 @@
var list = player.elements.settings.panes.captions.querySelector('ul');
// Empty the menu
- emptyElement(list);
+ utils.emptyElement(list);
// If there's no captions, bail
if (is.empty(player.captions.tracks)) {
@@ -1682,14 +1692,14 @@
// Generate options
tracks.forEach(function(track) {
- var item = createElement('li');
+ var item = utils.createElement('li');
- var label = createElement('label', {
+ var label = utils.createElement('label', {
class: config.classes.control,
for: 'plyr-language-' + track.language
});
- var radio = createElement('input', extend(getAttributesFromSelector(config.selectors.inputs.language), {
+ var radio = utils.createElement('input', utils.extend(utils.getAttributesFromSelector(config.selectors.inputs.language), {
type: 'radio',
id: 'plyr-language-' + track.language,
name: 'plyr-language',
@@ -1718,7 +1728,7 @@
var list = player.elements.settings.panes.speed.querySelector('ul');
// Empty the menu
- emptyElement(list);
+ utils.emptyElement(list);
// If there's no captions, bail
if (!is.array(options)) {
@@ -1726,14 +1736,14 @@
}
options.forEach(function(speed) {
- var item = createElement('li');
+ var item = utils.createElement('li');
- var label = createElement('label', {
+ var label = utils.createElement('label', {
class: config.classes.control,
for: 'plyr-speed-' + speed.toString().replace('.', '-')
});
- var radio = createElement('input', extend(getAttributesFromSelector(config.selectors.inputs.speed), {
+ var radio = utils.createElement('input', utils.extend(utils.getAttributesFromSelector(config.selectors.inputs.speed), {
type: 'radio',
id: 'plyr-speed-' + speed.toString().replace('.', '-'),
name: 'plyr-speed',
@@ -1763,18 +1773,18 @@
// Check for native support
var nativeSupport = support.fullscreen;
- if (nativeSupport || (config.fullscreen.fallback && !inFrame())) {
+ if (nativeSupport || (config.fullscreen.fallback && !utils.inFrame())) {
log((nativeSupport ? 'Native' : 'Fallback') + ' fullscreen enabled');
// Add styling hook
- toggleClass(player.elements.container, config.classes.fullscreen.enabled, true);
+ utils.toggleClass(player.elements.container, config.classes.fullscreen.enabled, true);
} else {
log('Fullscreen not supported and fallback disabled');
}
// Toggle state
if (player.elements.buttons && player.elements.buttons.fullscreen) {
- toggleState(player.elements.buttons.fullscreen, false);
+ utils.toggleState(player.elements.buttons.fullscreen, false);
}
// Setup focus trap
@@ -1785,21 +1795,29 @@
// Setup captions
function setupCaptions(tracks) {
// Only Vimeo and HTML5 video supported at this point
- if (!inArray(['video', 'vimeo'], player.type) || (player.type === 'video' && !support.textTracks)) {
+ if (!utils.inArray(['video', 'vimeo'], player.type) || (player.type === 'video' && !support.textTracks)) {
return;
}
// Inject the container
if (!is.htmlElement(player.elements.captions)) {
- player.elements.captions = createElement('div', getAttributesFromSelector(config.selectors.captions));
- player.elements.wrapper.appendChild(player.elements.captions);
+ player.elements.captions = utils.createElement('div', utils.getAttributesFromSelector(config.selectors.captions));
+
+ console.warn(player.type);
+
+ if (player.type === 'video') {
+ player.elements.wrapper.appendChild(player.elements.captions);
+ } else {
+ console.warn(player.elements.media);
+ player.elements.media.appendChild(player.elements.captions);
+ }
}
// Get tracks
player.captions.tracks = is.array(tracks) ? tracks : player.elements.media.textTracks;
// Set the class hook
- toggleClass(player.elements.container, config.classes.captions.enabled, !is.empty(player.captions.tracks));
+ utils.toggleClass(player.elements.container, config.classes.captions.enabled, !is.empty(player.captions.tracks));
// If no caption file exists, hide container for caption text
if (is.empty(player.captions.tracks)) {
@@ -1815,7 +1833,7 @@
// Turn off native caption rendering to avoid double captions
[].forEach.call(player.captions.tracks, function(track) {
// Remove previous bindings (if we've changed source or language)
- off(track, 'cuechange', setActiveCue);
+ utils.off(track, 'cuechange', setActiveCue);
// Hide captions
track.mode = 'hidden';
@@ -1834,8 +1852,8 @@
// If it's a caption or subtitle, render it
var track = player.captions.currentTrack;
- if (is.track(track) && inArray(['captions', 'subtitles'], track.kind)) {
- on(track, 'cuechange', setActiveCue);
+ if (is.track(track) && utils.inArray(['captions', 'subtitles'], track.kind)) {
+ utils.on(track, 'cuechange', setActiveCue);
// If we change the active track while a cue is already displayed we need to update it
if (track.activeCues && track.activeCues.length > 0) {
@@ -1897,10 +1915,10 @@
// Set the current caption
function setCaption(caption) {
if (is.htmlElement(player.elements.captions)) {
- var content = createElement('span');
+ var content = utils.createElement('span');
// Empty the container
- emptyElement(player.elements.captions);
+ utils.emptyElement(player.elements.captions);
// Default to empty
if (is.undefined(caption)) {
@@ -1942,8 +1960,8 @@
}
if (active) {
- toggleClass(player.elements.container, config.classes.captions.active, true);
- toggleState(player.elements.buttons.captions, true);
+ utils.toggleClass(player.elements.container, config.classes.captions.active, true);
+ utils.toggleState(player.elements.buttons.captions, true);
}
}
@@ -1963,10 +1981,10 @@
player.captions.enabled = show;
// Toggle state
- toggleState(player.elements.buttons.captions, player.captions.enabled);
+ utils.toggleState(player.elements.buttons.captions, player.captions.enabled);
// Add class hook
- toggleClass(player.elements.container, config.classes.captions.active, player.captions.enabled);
+ utils.toggleClass(player.elements.container, config.classes.captions.active, player.captions.enabled);
// Trigger an event
trigger(player.elements.container, player.captions.enabled ? 'captionsenabled' : 'captionsdisabled', true);
@@ -1993,7 +2011,7 @@
}
// Larger overlaid play button
- if (inArray(config.controls, 'play-large')) {
+ if (utils.inArray(config.controls, 'play-large')) {
player.elements.buttons.playLarge = createButton('play-large');
player.elements.container.appendChild(player.elements.buttons.playLarge);
}
@@ -2062,8 +2080,8 @@
for (var i = labels.length - 1; i >= 0; i--) {
var label = labels[i];
- toggleClass(label, config.classes.hidden, false);
- toggleClass(label, config.classes.tooltip, true);
+ utils.toggleClass(label, config.classes.hidden, false);
+ utils.toggleClass(label, config.classes.tooltip, true);
}
}
}
@@ -2126,12 +2144,12 @@
// Toggle style hook
function toggleStyleHook() {
- toggleClass(player.elements.container, config.selectors.container.replace('.', ''), player.supported.full);
+ utils.toggleClass(player.elements.container, config.selectors.container.replace('.', ''), player.supported.full);
}
// Toggle native controls
function toggleNativeControls(toggle) {
- if (toggle && inArray(types.html5, player.type)) {
+ if (toggle && utils.inArray(types.html5, player.type)) {
player.elements.media.setAttribute('controls', '');
} else {
player.elements.media.removeAttribute('controls');
@@ -2210,7 +2228,7 @@
}
// Update the working copy of the values
- extend(player.storage, value);
+ utils.extend(player.storage, value);
// Update storage
window.localStorage.setItem(config.storage.key, JSON.stringify(player.storage));
@@ -2226,57 +2244,57 @@
if (player.supported.full) {
// Add type class
- toggleClass(player.elements.container, config.classes.type.replace('{0}', player.type), true);
+ utils.toggleClass(player.elements.container, config.classes.type.replace('{0}', player.type), true);
// Add video class for embeds
// This will require changes if audio embeds are added
- if (inArray(types.embed, player.type)) {
- toggleClass(player.elements.container, config.classes.type.replace('{0}', 'video'), true);
+ if (utils.inArray(types.embed, player.type)) {
+ utils.toggleClass(player.elements.container, config.classes.type.replace('{0}', 'video'), true);
}
// Check for picture-in-picture support
- toggleClass(player.elements.container, config.classes.pip.enabled, support.pip && player.type === 'video');
+ utils.toggleClass(player.elements.container, config.classes.pip.enabled, support.pip && player.type === 'video');
// Check for airplay support
- toggleClass(player.elements.container, config.classes.airplay.enabled, support.airplay && inArray(types.html5, player.type));
+ utils.toggleClass(player.elements.container, config.classes.airplay.enabled, support.airplay && utils.inArray(types.html5, player.type));
// If there's no autoplay attribute, assume the video is stopped and add state class
- toggleClass(player.elements.container, config.classes.stopped, config.autoplay);
+ utils.toggleClass(player.elements.container, config.classes.stopped, config.autoplay);
// Add iOS class
- toggleClass(player.elements.container, config.classes.isIos, player.browser.isIos);
+ utils.toggleClass(player.elements.container, config.classes.isIos, player.browser.isIos);
// Add touch class
- toggleClass(player.elements.container, config.classes.isTouch, player.browser.isTouch);
+ utils.toggleClass(player.elements.container, config.classes.isTouch, player.browser.isTouch);
// Inject the player wrapper
if (player.type === 'video') {
// Create the wrapper div
- player.elements.wrapper = createElement('div', {
+ player.elements.wrapper = utils.createElement('div', {
class: config.classes.videoWrapper
});
// Wrap the video in a container
- wrap(player.elements.media, player.elements.wrapper);
+ utils.wrap(player.elements.media, player.elements.wrapper);
}
}
// Embeds
- if (inArray(types.embed, player.type)) {
+ if (utils.inArray(types.embed, player.type)) {
setupEmbed();
}
}
// Setup YouTube/Vimeo
function setupEmbed() {
- var container = createElement('div');
+ var container = utils.createElement('div');
var mediaId;
var id = player.type + '-' + Math.floor(Math.random() * (10000));
// Parse IDs from URLs if supplied
switch (player.type) {
case 'youtube':
- mediaId = parseYouTubeId(player.embedId);
+ mediaId = utils.parseYouTubeId(player.embedId);
break;
default:
@@ -2286,12 +2304,12 @@
// Remove old containers
var containers = getElements('[id^="' + player.type + '-"]');
for (var i = containers.length - 1; i >= 0; i--) {
- remove(containers[i]);
+ utils.removeElement(containers[i]);
}
// Add embed class for responsive
- toggleClass(player.elements.media, config.classes.videoWrapper, true);
- toggleClass(player.elements.media, config.classes.embedWrapper, true);
+ utils.toggleClass(player.elements.media, config.classes.videoWrapper, true);
+ utils.toggleClass(player.elements.media, config.classes.embedWrapper, true);
if (player.type === 'youtube') {
// Create the YouTube container
@@ -2305,7 +2323,7 @@
youTubeReady(mediaId, container);
} else {
// Load the API
- injectScript(config.urls.youtube.api);
+ utils.injectScript(config.urls.youtube.api);
// Setup callback for the API
window.onYouTubeReadyCallbacks = window.onYouTubeReadyCallbacks || [];
@@ -2335,7 +2353,7 @@
// Load the API if not already
if (!is.object(window.Vimeo)) {
- injectScript(config.urls.vimeo.api);
+ utils.injectScript(config.urls.vimeo.api);
// Wait for fragaloop load
var vimeoTimer = window.setInterval(function() {
@@ -2350,15 +2368,15 @@
} else if (player.type === 'soundcloud') {
// TODO: Currently unsupported and undocumented
// Inject the iframe
- var soundCloud = createElement('iframe');
+ var soundCloud = utils.createElement('iframe');
// Watch for iframe load
soundCloud.loaded = false;
- on(soundCloud, 'load', function() {
+ utils.on(soundCloud, 'load', function() {
soundCloud.loaded = true;
});
- setAttributes(soundCloud, {
+ utils.setAttributes(soundCloud, {
'src': 'https://w.soundcloud.com/player/?url=https://api.soundcloud.com/tracks/' + mediaId,
'id': id
});
@@ -2368,7 +2386,7 @@
// Load the API if not already
if (!window.SC) {
- injectScript(config.urls.soundcloud.api);
+ utils.injectScript(config.urls.soundcloud.api);
}
// Wait for SC load
@@ -2410,7 +2428,7 @@
wmode: 'transparent',
modestbranding: 1,
disablekb: 1,
- origin: 'https://plyr.io'
+ origin: window.location.href
},
events: {
'onError': function(event) {
@@ -2446,7 +2464,7 @@
instance.stopVideo();
player.elements.media.paused = true;
};
- player.elements.media.duration = instance.getDuration();
+ player.elements.media.duration = instance.getDuratiutils.on();
player.elements.media.paused = true;
player.elements.media.currentTime = 0;
player.elements.media.muted = instance.isMuted();
@@ -2789,7 +2807,7 @@
// TODO: Set the indicator on load as user may pass loop as config
function toggleLoop(type) {
// Set default to be a true toggle
- if (!inArray(['start', 'end', 'all', 'none', 'toggle'], type)) {
+ if (!utils.inArray(['start', 'end', 'all', 'none', 'toggle'], type)) {
type = 'toggle';
}
@@ -2931,7 +2949,7 @@
if (is.number(input)) {
targetTime = input;
- } else if (is.event(input) && inArray(['input', 'change'], input.type)) {
+ } else if (is.event(input) && utils.inArray(['input', 'change'], input.type)) {
// It's the seek slider
// Seek to the selected time
targetTime = ((input.target.value / input.target.max) * duration);
@@ -2954,7 +2972,7 @@
} catch (e) {}
// Embeds
- if (inArray(types.embed, player.type)) {
+ if (utils.inArray(types.embed, player.type)) {
switch (player.type) {
case 'youtube':
player.embed.seekTo(targetTime);
@@ -3007,9 +3025,9 @@
// Check playing state
function checkPlaying() {
- toggleClass(player.elements.container, config.classes.playing, !player.elements.media.paused);
+ utils.toggleClass(player.elements.container, config.classes.playing, !player.elements.media.paused);
- toggleClass(player.elements.container, config.classes.stopped, player.elements.media.paused);
+ utils.toggleClass(player.elements.container, config.classes.stopped, player.elements.media.paused);
toggleControls(player.elements.media.paused);
}
@@ -3063,14 +3081,14 @@
}
// Set class hook
- toggleClass(player.elements.container, config.classes.fullscreen.active, player.fullscreen.active);
+ utils.toggleClass(player.elements.container, config.classes.fullscreen.active, player.fullscreen.active);
// Trap focus
focusTrap(player.fullscreen.active);
// Set button state
if (player.elements.buttons && player.elements.buttons.fullscreen) {
- toggleState(player.elements.buttons.fullscreen, player.fullscreen.active);
+ utils.toggleState(player.elements.buttons.fullscreen, player.fullscreen.active);
}
// Trigger an event
@@ -3124,7 +3142,7 @@
container.appendChild(clone);
targetWidth = clone.scrollWidth;
targetHeight = clone.scrollHeight;
- remove(clone);
+ utils.removeElement(clone);
}
target.setAttribute('aria-hidden', !show);
@@ -3150,7 +3168,7 @@
}
// Set button state
- toggleState(player.elements.buttons.mute, muted);
+ utils.toggleState(player.elements.buttons.mute, muted);
// Set mute on the player
player.elements.media.muted = muted;
@@ -3161,7 +3179,7 @@
}
// Embeds
- if (inArray(types.embed, player.type)) {
+ if (utils.inArray(types.embed, player.type)) {
// YouTube
switch (player.type) {
case 'youtube':
@@ -3217,7 +3235,7 @@
}
// Embeds
- if (inArray(types.embed, player.type)) {
+ if (utils.inArray(types.embed, player.type)) {
switch (player.type) {
case 'youtube':
player.embed.setVolume(player.elements.media.volume * 100);
@@ -3284,11 +3302,11 @@
});
// Toggle class if muted
- toggleClass(player.elements.container, config.classes.muted, (volume === 0));
+ utils.toggleClass(player.elements.container, config.classes.muted, (volume === 0));
// Update checkbox for mute state
if (player.supported.full && player.elements.buttons.mute) {
- toggleState(player.elements.buttons.mute, (volume === 0));
+ utils.toggleState(player.elements.buttons.mute, (volume === 0));
}
}
@@ -3302,7 +3320,7 @@
// Timer to prevent flicker when seeking
timers.loading = setTimeout(function() {
// Toggle container class hook
- toggleClass(player.elements.container, config.classes.loading, loading);
+ utils.toggleClass(player.elements.container, config.classes.loading, loading);
// Show controls if loading, hide if done
toggleControls(loading);
@@ -3328,7 +3346,7 @@
return;
}
- value = getPercentage(player.elements.media.currentTime, duration);
+ value = utils.getPercentage(player.elements.media.currentTime, duration);
// Set seek range value only if it's a 'natural' time event
if (event.type === 'timeupdate' && player.elements.inputs.seek) {
@@ -3346,7 +3364,7 @@
if (buffered && buffered.length) {
// HTML5
- return getPercentage(buffered.end(0), duration);
+ return utils.getPercentage(buffered.end(0), duration);
} else if (is.number(buffered)) {
// YouTube returns between 0 and 1
return (buffered * 100);
@@ -3475,7 +3493,7 @@
}
var duration = getDuration(),
- value = getPercentage(time, duration);
+ value = utils.getPercentage(time, duration);
// Update progress
if (player.elements.progress && player.elements.display.played) {
@@ -3506,7 +3524,7 @@
if (is.event(event)) {
percent = ((100 / clientRect.width) * (event.pageX - clientRect.left));
} else {
- if (hasClass(player.elements.display.seekTooltip, visible)) {
+ if (utils.hasClass(player.elements.display.seekTooltip, visible)) {
percent = player.elements.display.seekTooltip.style.left.replace('%', '');
} else {
return;
@@ -3528,8 +3546,8 @@
// Show/hide the tooltip
// If the event is a moues in/out and percentage is inside bounds
- if (is.event(event) && inArray(['mouseenter', 'mouseleave'], event.type)) {
- toggleClass(player.elements.display.seekTooltip, visible, (event.type === 'mouseenter'));
+ if (is.event(event) && utils.inArray(['mouseenter', 'mouseleave'], event.type)) {
+ utils.toggleClass(player.elements.display.seekTooltip, visible, (event.type === 'mouseenter'));
}
}
@@ -3543,7 +3561,7 @@
var delay = 0;
var isEnterFullscreen = false;
var show = toggle;
- var loading = hasClass(player.elements.container, config.classes.loading);
+ var loading = utils.hasClass(player.elements.container, config.classes.loading);
// Default to false if no boolean
if (!is.boolean(toggle)) {
@@ -3552,10 +3570,10 @@
isEnterFullscreen = (toggle.type === 'enterfullscreen');
// Whether to show controls
- show = inArray(['mousemove', 'touchstart', 'mouseenter', 'focus'], toggle.type);
+ show = utils.inArray(['mousemove', 'touchstart', 'mouseenter', 'focus'], toggle.type);
// Delay hiding on move events
- if (inArray(['mousemove', 'touchmove'], toggle.type)) {
+ if (utils.inArray(['mousemove', 'touchmove'], toggle.type)) {
delay = 2000;
}
@@ -3564,7 +3582,7 @@
delay = 3000;
}
} else {
- show = hasClass(player.elements.container, config.classes.hideControls);
+ show = utils.hasClass(player.elements.container, config.classes.hideControls);
}
}
@@ -3573,7 +3591,7 @@
// If the mouse is not over the controls, set a timeout to hide them
if (show || player.elements.media.paused || loading) {
- toggleClass(player.elements.container, config.classes.hideControls, false);
+ utils.toggleClass(player.elements.container, config.classes.hideControls, false);
// Always show controls when paused or if touch
if (player.elements.media.paused || loading) {
@@ -3595,7 +3613,7 @@
return;
}
- toggleClass(player.elements.container, config.classes.hideControls, true);
+ utils.toggleClass(player.elements.container, config.classes.hideControls, true);
}, delay);
}
}
@@ -3644,7 +3662,7 @@
}
// Remove ready class hook
- toggleClass(player.elements.container, config.classes.ready, false);
+ utils.toggleClass(player.elements.container, config.classes.ready, false);
// Pause playback
pause();
@@ -3664,11 +3682,14 @@
player.embed = null;
// Remove the old media
- remove(player.elements.media);
+ removeElement('media');
+
+ // Remove the old captions
+ removeElement('captions');
// Remove video container
if (player.type === 'video' && player.elements.wrapper) {
- remove(player.elements.wrapper);
+ removeElement('wrapper');
}
// Reset class name
@@ -3684,7 +3705,7 @@
if (player.type === 'video') {
var firstSource = source.sources[0];
- if ('type' in firstSource && inArray(types.embed, firstSource.type)) {
+ if ('type' in firstSource && utils.inArray(types.embed, firstSource.type)) {
player.type = firstSource.type;
}
}
@@ -3696,23 +3717,23 @@
// Create new markup
switch (player.type) {
case 'video':
- player.elements.media = createElement('video');
+ player.elements.media = utils.createElement('video');
break;
case 'audio':
- player.elements.media = createElement('audio');
+ player.elements.media = utils.createElement('audio');
break;
case 'youtube':
case 'vimeo':
case 'soundcloud':
- player.elements.media = createElement('div');
+ player.elements.media = utils.createElement('div');
player.embedId = source.sources[0].src;
break;
}
// Inject the new element
- prependChild(player.elements.container, player.elements.media);
+ utils.prependChild(player.elements.container, player.elements.media);
// Autoplay the new source?
if (is.boolean(source.autoplay)) {
@@ -3720,7 +3741,7 @@
}
// Set attributes for audio and video
- if (inArray(types.html5, player.type)) {
+ if (utils.inArray(types.html5, player.type)) {
if (config.crossorigin) {
player.elements.media.setAttribute('crossorigin', '');
}
@@ -3736,12 +3757,12 @@
}
// Restore class hooks
- toggleClass(player.elements.container, config.classes.fullscreen.active, player.fullscreen.active);
- toggleClass(player.elements.container, config.classes.captions.active, player.captions.enabled);
+ utils.toggleClass(player.elements.container, config.classes.fullscreen.active, player.fullscreen.active);
+ utils.toggleClass(player.elements.container, config.classes.captions.active, player.captions.enabled);
toggleStyleHook();
// Set new sources for html5
- if (inArray(types.html5, player.type)) {
+ if (utils.inArray(types.html5, player.type)) {
insertElements('source', source.sources);
}
@@ -3749,7 +3770,7 @@
setupMedia();
// HTML5 stuff
- if (inArray(types.html5, player.type)) {
+ if (utils.inArray(types.html5, player.type)) {
// Setup captions
if ('tracks' in source) {
insertElements('track', source.tracks);
@@ -3760,7 +3781,7 @@
}
// If HTML5 or embed but not fully supported, setupInterface and call ready now
- if (inArray(types.html5, player.type) || (inArray(types.embed, player.type) && !player.supported.full)) {
+ if (utils.inArray(types.html5, player.type) || (utils.inArray(types.embed, player.type) && !player.supported.full)) {
// Setup interface
setupInterface();
@@ -3800,14 +3821,14 @@
// Setup focus and tab focus
if (target) {
- var hadTabFocus = hasClass(trigger, config.classes.tabFocus);
+ var hadTabFocus = utils.hasClass(trigger, config.classes.tabFocus);
setTimeout(function() {
target.focus();
if (hadTabFocus) {
- toggleClass(trigger, config.classes.tabFocus, false);
- toggleClass(target, config.classes.tabFocus, true);
+ utils.toggleClass(trigger, config.classes.tabFocus, false);
+ utils.toggleClass(target, config.classes.tabFocus, true);
}
}, 100);
}
@@ -3820,10 +3841,10 @@
// Detect tab focus
function checkTabFocus(focused) {
- toggleClass(getElements('.' + config.classes.tabFocus), config.classes.tabFocus, false);
+ utils.toggleClass(getElements('.' + config.classes.tabFocus), config.classes.tabFocus, false);
if (player.elements.container.contains(focused)) {
- toggleClass(focused, config.classes.tabFocus, true);
+ utils.toggleClass(focused, config.classes.tabFocus, true);
}
}
@@ -3833,9 +3854,9 @@
// Handle global presses
if (config.keyboardShortcuts.global) {
- on(window, 'keydown keyup', function(event) {
+ utils.on(window, 'keydown keyup', function(event) {
var code = getKeyCode(event);
- var focused = getFocusElement();
+ var focused = utils.getFocusElement();
var allowed = [48, 49, 50, 51, 52, 53, 54, 56, 57, 75, 77, 70, 67, 73, 76, 79];
var count = get().length;
@@ -3843,14 +3864,14 @@
// 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))) {
+ if (count === 1 && utils.inArray(allowed, code) && (!is.htmlElement(focused) || !utils.matches(focused, config.selectors.editable))) {
handleKey(event);
}
});
}
// Handle presses on focused
- on(player.elements.container, 'keydown keyup', handleKey);
+ utils.on(player.elements.container, 'keydown keyup', handleKey);
}
function handleKey(event) {
@@ -3885,16 +3906,16 @@
var preventDefault = [48, 49, 50, 51, 52, 53, 54, 56, 57, 32, 75, 38, 40, 77, 39, 37, 70, 67, 73, 76, 79];
var checkFocus = [38, 40];
- if (inArray(checkFocus, code)) {
- var focused = getFocusElement();
+ if (utils.inArray(checkFocus, code)) {
+ var focused = utils.getFocusElement();
- if (is.htmlElement(focused) && getFocusElement().type === "radio") {
+ if (is.htmlElement(focused) && utils.getFocusElement().type === "radio") {
return;
}
}
// If the code is found prevent default (e.g. prevent scrolling for arrows)
- if (inArray(preventDefault, code)) {
+ if (utils.inArray(preventDefault, code)) {
event.preventDefault();
event.stopPropagation();
}
@@ -3990,22 +4011,22 @@
}
// Focus/tab management
- on(window, 'keyup', function(event) {
+ utils.on(window, 'keyup', function(event) {
var code = getKeyCode(event);
- var focused = getFocusElement();
+ var focused = utils.getFocusElement();
if (code === 9) {
checkTabFocus(focused);
}
});
- on(document.body, 'click', function() {
- toggleClass(getElement('.' + config.classes.tabFocus), config.classes.tabFocus, false);
+ utils.on(document.body, 'click', function() {
+ utils.toggleClass(getElement('.' + config.classes.tabFocus), config.classes.tabFocus, false);
});
for (var button in player.elements.buttons) {
var element = player.elements.buttons[button];
- on(element, 'blur', function() {
- toggleClass(element, 'tab-focus', false);
+ utils.on(element, 'blur', function() {
+ utils.toggleClass(element, 'tab-focus', false);
});
}
@@ -4020,32 +4041,32 @@
}
// Play
- proxy(player.elements.buttons.play, 'click', config.listeners.play, _togglePlay);
- proxy(player.elements.buttons.playLarge, 'click', config.listeners.play, _togglePlay);
+ utils.proxy(player.elements.buttons.play, 'click', config.listeners.play, _togglePlay);
+ utils.proxy(player.elements.buttons.playLarge, 'click', config.listeners.play, _togglePlay);
// Pause
- proxy(player.elements.buttons.pause, 'click', config.listeners.pause, _togglePlay);
+ utils.proxy(player.elements.buttons.pause, 'click', config.listeners.pause, _togglePlay);
// Pause
- proxy(player.elements.buttons.restart, 'click', config.listeners.restart, seek);
+ utils.proxy(player.elements.buttons.restart, 'click', config.listeners.restart, seek);
// Rewind
- proxy(player.elements.buttons.rewind, 'click', config.listeners.rewind, rewind);
+ utils.proxy(player.elements.buttons.rewind, 'click', config.listeners.rewind, rewind);
// Rewind
- proxy(player.elements.buttons.forward, 'click', config.listeners.forward, forward);
+ utils.proxy(player.elements.buttons.forward, 'click', config.listeners.forward, forward);
// Mute
- proxy(player.elements.buttons.mute, 'click', config.listeners.mute, toggleMute);
+ utils.proxy(player.elements.buttons.mute, 'click', config.listeners.mute, toggleMute);
// Captions
- proxy(player.elements.buttons.captions, 'click', config.listeners.captions, toggleCaptions);
+ utils.proxy(player.elements.buttons.captions, 'click', config.listeners.captions, toggleCaptions);
// Fullscreen
- proxy(player.elements.buttons.fullscreen, 'click', config.listeners.fullscreen, toggleFullscreen);
+ utils.proxy(player.elements.buttons.fullscreen, 'click', config.listeners.fullscreen, toggleFullscreen);
// Picture-in-Picture
- proxy(player.elements.buttons.pip, 'click', config.listeners.pip, function(event) {
+ utils.proxy(player.elements.buttons.pip, 'click', config.listeners.pip, function(event) {
if (!support.pip) {
return;
}
@@ -4053,7 +4074,7 @@
});
// Airplay
- proxy(player.elements.buttons.airplay, 'click', config.listeners.airplay, function(event) {
+ utils.proxy(player.elements.buttons.airplay, 'click', config.listeners.airplay, function(event) {
if (!support.airplay) {
return;
}
@@ -4061,10 +4082,10 @@
});
// Settings menu
- on(player.elements.settings.menu, 'click', toggleMenu);
+ utils.on(player.elements.settings.menu, 'click', toggleMenu);
// Click anywhere closes menu
- on(document.body, 'click', function(event) {
+ utils.on(document.body, 'click', function(event) {
var menu = player.elements.settings.menu;
var form = menu.querySelector('form');
@@ -4077,32 +4098,32 @@
});
// Settings menu items - use event delegation as items are added/removed
- on(player.elements.settings.menu, 'click', function(event) {
+ utils.on(player.elements.settings.menu, 'click', function(event) {
// Settings - Language
- if (matches(event.target, config.selectors.inputs.language)) {
+ if (utils.matches(event.target, config.selectors.inputs.language)) {
handlerProxy.call(this, event, config.listeners.language, setLanguage);
}
// Settings - Quality
- else if (matches(event.target, config.selectors.inputs.quality)) {
+ else if (utils.matches(event.target, config.selectors.inputs.quality)) {
handlerProxy.call(this, event, config.listeners.quality, function() {
warn("Set quality");
});
}
// Settings - Speed
- else if (matches(event.target, config.selectors.inputs.speed)) {
+ else if (utils.matches(event.target, config.selectors.inputs.speed)) {
handlerProxy.call(this, event, config.listeners.speed, setSpeed);
}
// Settings - Looping
// TODO: use toggle buttons
- else if (matches(event.target, config.selectors.buttons.loop)) {
+ else if (utils.matches(event.target, config.selectors.buttons.loop)) {
handlerProxy.call(this, event, config.listeners.loop, function() {
// TODO: This should be done in the method itself I think
var value = event.target.getAttribute('data-loop__value') || event.target.getAttribute('data-loop__type');
- if (inArray(['start', 'end', 'all', 'none'], value)) {
+ if (utils.inArray(['start', 'end', 'all', 'none'], value)) {
toggleLoop(value);
}
});
@@ -4110,35 +4131,35 @@
});
// Seek
- proxy(player.elements.inputs.seek, inputEvent, config.listeners.seek, seek);
+ utils.proxy(player.elements.inputs.seek, inputEvent, config.listeners.seek, seek);
// Seek
- proxy(player.elements.inputs.volume, inputEvent, config.listeners.volume, setVolume);
+ utils.proxy(player.elements.inputs.volume, inputEvent, config.listeners.volume, setVolume);
// Seek tooltip
- on(player.elements.progress, 'mouseenter mouseleave mousemove', updateSeekTooltip);
+ utils.on(player.elements.progress, 'mouseenter mouseleave mousemove', updateSeekTooltip);
// Toggle controls visibility based on mouse movement
if (config.hideControls) {
// Toggle controls on mouse events and entering fullscreen
- on(player.elements.container, 'mouseenter mouseleave mousemove touchstart touchend touchcancel touchmove enterfullscreen', toggleControls);
+ utils.on(player.elements.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(player.elements.controls, 'mouseenter mouseleave', function(event) {
+ utils.on(player.elements.controls, 'mouseenter mouseleave', function(event) {
player.elements.controls.hover = event.type === 'mouseenter';
});
// Watch for cursor over controls so they don't hide when trying to interact
- on(player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', function(event) {
- player.elements.controls.pressed = inArray(['mousedown', 'touchstart'], event.type);
+ utils.on(player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', function(event) {
+ player.elements.controls.pressed = utils.inArray(['mousedown', 'touchstart'], event.type);
});
// Focus in/out on controls
- on(player.elements.controls, 'focus blur', toggleControls, true);
+ utils.on(player.elements.controls, 'focus blur', toggleControls, true);
}
// Mouse wheel for volume
- proxy(player.elements.inputs.volume, 'wheel', config.listeners.volume, function(event) {
+ utils.proxy(player.elements.inputs.volume, 'wheel', config.listeners.volume, function(event) {
// Detect "natural" scroll - suppored on OS X Safari only
// Other browsers on OS X will be inverted until support improves
var inverted = event.webkitDirectionInvertedFromDevice;
@@ -4176,20 +4197,20 @@
// Handle user exiting fullscreen by escaping etc
if (support.fullscreen) {
- on(document, fullscreen.eventType, toggleFullscreen);
+ utils.on(document, fullscreen.eventType, toggleFullscreen);
}
}
// Listen for media events
function mediaListeners() {
// Time change on media
- on(player.elements.media, 'timeupdate seeking', timeUpdate);
+ utils.on(player.elements.media, 'timeupdate seeking', timeUpdate);
// Display duration
- on(player.elements.media, 'durationchange loadedmetadata', displayDuration);
+ utils.on(player.elements.media, 'durationchange loadedmetadata', displayDuration);
// Handle the media finishing
- on(player.elements.media, 'ended', function() {
+ utils.on(player.elements.media, 'ended', function() {
// Show poster on end
if (player.type === 'video' && config.showPosterOnEnd) {
// Clear
@@ -4206,16 +4227,16 @@
});
// Check for buffer progress
- on(player.elements.media, 'progress playing', updateProgress);
+ utils.on(player.elements.media, 'progress playing', updateProgress);
// Handle native mute
- on(player.elements.media, 'volumechange', updateVolume);
+ utils.on(player.elements.media, 'volumechange', updateVolume);
// Handle native play/pause
- on(player.elements.media, 'play pause ended', checkPlaying);
+ utils.on(player.elements.media, 'play pause ended', checkPlaying);
// Loading
- on(player.elements.media, 'waiting canplay seeked', checkLoading);
+ utils.on(player.elements.media, 'waiting canplay seeked', checkLoading);
// Click video
if (config.clickToPlay && player.type !== 'audio') {
@@ -4231,7 +4252,7 @@
wrapper.style.cursor = "pointer";
// On click play, pause ore restart
- on(wrapper, 'click', function() {
+ utils.on(wrapper, 'click', function() {
// Touch devices will just show controls (if we're hiding controls)
if (config.hideControls && player.browser.isTouch && !player.elements.media.paused) {
return;
@@ -4250,14 +4271,14 @@
// Disable right click
if (config.disableContextMenu) {
- on(player.elements.media, 'contextmenu', function(event) {
+ utils.on(player.elements.media, 'contextmenu', function(event) {
event.preventDefault();
});
}
// Proxy events to container
// Bubble up key events for Edge
- on(player.elements.media, config.events.concat(['keyup', 'keydown']).join(' '), function(event) {
+ utils.on(player.elements.media, config.events.concat(['keyup', 'keydown']).join(' '), function(event) {
trigger(player.elements.container, event.type, true);
});
}
@@ -4265,14 +4286,14 @@
// Cancel current network requests
// See https://github.com/Selz/plyr/issues/174
function cancelRequests() {
- if (!inArray(types.html5, player.type)) {
+ if (!utils.inArray(types.html5, player.type)) {
return;
}
// Remove child sources
var sources = player.elements.media.querySelectorAll('source');
for (var i = 0; i < sources.length; i++) {
- remove(sources[i]);
+ utils.removeElement(sources[i]);
}
// Set blank video src attribute
@@ -4372,7 +4393,7 @@
}
// Sniff out the browser
- player.browser = getBrowser();
+ player.browser = utils.getBrowser();
// Bail if nothing to setup
if (!is.htmlElement(player.elements.media)) {
@@ -4408,7 +4429,7 @@
}
// Wrap media
- player.elements.container = wrap(media, createElement('div'));
+ player.elements.container = utils.wrap(media, utils.createElement('div'));
// Allow focus to be captured
player.elements.container.setAttribute('tabindex', 0);
@@ -4424,7 +4445,7 @@
// Setup interface
// If embed but not fully supported, setupInterface (to avoid flash of controls) and call ready now
- if (inArray(types.html5, player.type) || (inArray(types.embed, player.type) && !player.supported.full)) {
+ if (utils.inArray(types.html5, player.type) || (utils.inArray(types.embed, player.type) && !player.supported.full)) {
// Setup UI
setupInterface();
@@ -4446,10 +4467,10 @@
warn('Basic support only', player.type);
// Remove controls
- remove(getElement(config.selectors.controls.wrapper));
+ removeElement('controls');
// Remove large play
- remove(getElement(config.selectors.buttons.play));
+ removeElement('buttons.play');
// Restore native controls
toggleNativeControls(true);
@@ -4528,10 +4549,10 @@
return player.elements.media.muted;
},
isReady: function() {
- return hasClass(player.elements.container, config.classes.ready);
+ return utils.hasClass(player.elements.container, config.classes.ready);
},
isLoading: function() {
- return hasClass(player.elements.container, config.classes.loading);
+ return utils.hasClass(player.elements.container, config.classes.loading);
},
isPaused: function() {
return player.elements.media.paused;
@@ -4540,7 +4561,7 @@
return config.loop.active;
},
on: function(event, callback) {
- on(player.elements.container, event, callback);
+ utils.on(player.elements.container, event, callback);
return this;
},
play: play,
@@ -4581,10 +4602,10 @@
}, 0);
// Set class hook on media element
- toggleClass(player.elements.media, defaults.classes.setup, true);
+ utils.toggleClass(player.elements.media, defaults.classes.setup, true);
// Set container class for ready
- toggleClass(player.elements.container, config.classes.ready, true);
+ utils.toggleClass(player.elements.container, config.classes.ready, true);
// Store a refernce to instance
player.elements.media.plyr = api;
@@ -4616,7 +4637,7 @@
}
// Create placeholder (to prevent loading twice)
- var container = createElement('div');
+ var container = utils.createElement('div');
container.setAttribute('hidden', '');
if (is.string(id)) {
container.setAttribute('id', id);
@@ -4640,12 +4661,12 @@
// Check for support
function checkSupport(type) {
- var browser = getBrowser();
+ var browser = utils.getBrowser();
var isOldIE = (browser.isIE && browser.version <= 9);
var isIos = browser.isIos;
var isIphone = /iPhone|iPod/i.test(navigator.userAgent);
- var audio = !!createElement('audio').canPlayType;
- var video = !!createElement('video').canPlayType;
+ var audio = !!utils.createElement('audio').canPlayType;
+ var video = !!utils.createElement('video').canPlayType;
var basic;
var full;
@@ -4716,10 +4737,10 @@
// Add to container list
function add(target, media) {
- if (!hasClass(media, defaults.classes.hook)) {
+ if (!utils.hasClass(media, defaults.classes.hook)) {
players.push({
// Always wrap in a <div> for styling
- // container: wrap(media, document.createElement('div')),
+ // container: utils.wrap(media, document.createElement('div')),
// Could be a container or the media itself
target: target,
// This should be the <video>, <audio> or <div> (YouTube/Vimeo)
@@ -4740,7 +4761,7 @@
for (var x = 0; x < children.length; x++) {
add(target, children[x]);
}
- } else if (matches(target, selector)) {
+ } else if (utils.matches(target, selector)) {
// Target is media element
add(target, target);
}
@@ -4766,7 +4787,7 @@
data = JSON.parse(element.getAttribute('data-plyr'));
} catch (e) {}
- var config = extend({}, defaults, options, data);
+ var config = utils.extend({}, defaults, options, data);
// Bail if not enabled
if (!config.enabled) {
@@ -4785,13 +4806,13 @@
if (config.debug) {
var events = config.events.concat(['setup', 'statechange', 'enterfullscreen', 'exitfullscreen', 'captionsenabled', 'captionsdisabled']);
- on(instance.getContainer(), events.join(' '), function(event) {
+ utils.on(instance.getContainer(), events.join(' '), function(event) {
console.log([config.logPrefix, 'event:', event.type].join(' '), event.detail.plyr);
});
}
// Callback
- event(instance.getContainer(), 'setup', true, {
+ utils.event(instance.getContainer(), 'setup', true, {
plyr: instance
});
diff --git a/src/less/plyr.less b/src/less/plyr.less
index 744f07cf..3ffa95fe 100644
--- a/src/less/plyr.less
+++ b/src/less/plyr.less
@@ -198,10 +198,6 @@
.plyr__video-embed {
padding-bottom: 56.25%; /* 16:9 */
height: 0;
- border-radius: inherit;
- // Require overflow and z-index to force border-radius
- overflow: hidden;
- z-index: 0;
iframe {
position: absolute;