/** * jwplayer.html5 namespace * * @author pablo */ (function(jwplayer) { jwplayer.html5 = {}; jwplayer.html5.version = '6.12.0'; // These 'reset' styles must be included before any others var _css = jwplayer.utils.css; var JW_CLASS = '.jwplayer '; var helperString = [JW_CLASS, 'div', 'span', 'a', 'img', 'ul', 'li', 'video'].join(', ' + JW_CLASS); _css(helperString + ', .jwclick', { margin: 0, padding: 0, border: 0, color: '#000000', 'font-size': '100%', font: 'inherit', 'vertical-align': 'baseline', 'background-color': 'transparent', 'text-align': 'left', 'direction': 'ltr', 'line-height': 20, '-webkit-tap-highlight-color': 'rgba(255, 255, 255, 0)' }); // Reset box-sizing to default for player and all sub-elements // Note: If we use pseudo elements we will need to add *:before and *:after _css(JW_CLASS + ',' + JW_CLASS + '*', { 'box-sizing': 'content-box'}); // Browsers use border-box as a the default box-sizing for many form elements _css(JW_CLASS + '* button,' + JW_CLASS + '* input,' + JW_CLASS + '* select,' + JW_CLASS + '* textarea', { 'box-sizing': 'border-box'}); _css(JW_CLASS + 'ul', { 'list-style': 'none' }); // These rules allow click and hover events to reach the provider, instead // of being blocked by the controller element // ** Note : pointer-events will not work on IE < 11 _css('.jwplayer .jwcontrols', { 'pointer-events': 'none' }); _css('.jwplayer.jw-user-inactive .jwcontrols', { 'pointer-events': 'all' }); var acceptClicks = [ '.jwplayer .jwcontrols .jwdockbuttons', '.jwplayer .jwcontrols .jwcontrolbar', '.jwplayer .jwcontrols .jwskip', '.jwplayer .jwcontrols .jwdisplayIcon', // play and replay button '.jwplayer .jwcontrols .jwpreview', // poster image '.jwplayer .jwcontrols .jwlogo' ]; _css(acceptClicks.join(', '), { 'pointer-events' : 'all' }); })(jwplayer); /** * HTML5-only utilities for the JW Player. * * @author pablo * @version 6.0 */ (function(utils) { var DOCUMENT = document; /** * Cleans up a css dimension (e.g. '420px') and returns an integer. */ utils.parseDimension = function(dimension) { if (typeof dimension === 'string') { if (dimension === '') { return 0; } else if (dimension.lastIndexOf('%') > -1) { return dimension; } return parseInt(dimension.replace('px', ''), 10); } return dimension; }; /** Format the elapsed / remaining text. **/ utils.timeFormat = function(sec) { if (sec > 0) { var hrs = Math.floor(sec / 3600), mins = Math.floor((sec - hrs * 3600) / 60), secs = Math.floor(sec % 60); return (hrs ? hrs + ':' : '') + (mins < 10 ? '0' : '') + mins + ':' + (secs < 10 ? '0' : '') + secs; } else { return '00:00'; } }; utils.bounds = function(element) { var bounds = { left: 0, right: 0, width: 0, height: 0, top: 0, bottom: 0 }; if (!element || !DOCUMENT.body.contains(element)) { return bounds; } if (element.getBoundingClientRect) { var rect = element.getBoundingClientRect(element), scrollOffsetY = window.pageYOffset, scrollOffsetX = window.pageXOffset; if (!rect.width && !rect.height && !rect.left && !rect.top) { //element is not visible / no layout return bounds; } bounds.left = rect.left + scrollOffsetX; bounds.right = rect.right + scrollOffsetX; bounds.top = rect.top + scrollOffsetY; bounds.bottom = rect.bottom + scrollOffsetY; bounds.width = rect.right - rect.left; bounds.height = rect.bottom - rect.top; } else { /*jshint -W084 */ // For the while loop assignment bounds.width = element.offsetWidth | 0; bounds.height = element.offsetHeight | 0; do { bounds.left += element.offsetLeft | 0; bounds.top += element.offsetTop | 0; } while (element = element.offsetParent); bounds.right = bounds.left + bounds.width; bounds.bottom = bounds.top + bounds.height; } return bounds; }; utils.empty = function(element) { if (!element) { return; } while (element.childElementCount > 0) { element.removeChild(element.children[0]); } }; })(jwplayer.utils); (function(utils) { /*jshint maxparams:6*/ /** Stretching options **/ var _stretching = utils.stretching = { NONE: 'none', FILL: 'fill', UNIFORM: 'uniform', EXACTFIT: 'exactfit' }; utils.scale = function(domelement, xscale, yscale, xoffset, yoffset) { var value = ''; // Set defaults xscale = xscale || 1; yscale = yscale || 1; xoffset = xoffset | 0; yoffset = yoffset | 0; if (xscale !== 1 || yscale !== 1) { value = 'scale(' + xscale + ', ' + yscale + ')'; } if (xoffset || yoffset) { if (value) { value += ' '; } value = 'translate(' + xoffset + 'px, ' + yoffset + 'px)'; } utils.transform(domelement, value); }; /** * Stretches domelement based on stretching. parentWidth, parentHeight, * elementWidth, and elementHeight are required as the elements dimensions * change as a result of the stretching. Hence, the original dimensions must * always be supplied. * * @param {String} * stretching * @param {DOMElement} * domelement * @param {Number} * parentWidth * @param {Number} * parentHeight * @param {Number} * elementWidth * @param {Number} * elementHeight */ utils.stretch = function(stretching, domelement, parentWidth, parentHeight, elementWidth, elementHeight) { if (!domelement) { return false; } if (!parentWidth || !parentHeight || !elementWidth || !elementHeight) { return false; } stretching = stretching || _stretching.UNIFORM; var xscale = Math.ceil(parentWidth / 2) * 2 / elementWidth, yscale = Math.ceil(parentHeight / 2) * 2 / elementHeight, video = (domelement.tagName.toLowerCase() === 'video'), scale = false, stretchClass = 'jw' + stretching.toLowerCase(); switch (stretching.toLowerCase()) { case _stretching.FILL: if (xscale > yscale) { yscale = xscale; } else { xscale = yscale; } scale = true; break; case _stretching.NONE: xscale = yscale = 1; /* falls through */ case _stretching.EXACTFIT: scale = true; break; case _stretching.UNIFORM: /* falls through */ default: if (xscale > yscale) { if (elementWidth * yscale / parentWidth > 0.95) { scale = true; stretchClass = 'jwexactfit'; } else { elementWidth = elementWidth * yscale; elementHeight = elementHeight * yscale; } } else { if (elementHeight * xscale / parentHeight > 0.95) { scale = true; stretchClass = 'jwexactfit'; } else { elementWidth = elementWidth * xscale; elementHeight = elementHeight * xscale; } } if (scale) { xscale = Math.ceil(parentWidth / 2) * 2 / elementWidth; yscale = Math.ceil(parentHeight / 2) * 2 / elementHeight; } } if (video) { var style = { left: '', right: '', width: '', height: '' }; if (scale) { if (parentWidth < elementWidth) { style.left = style.right = Math.ceil((parentWidth - elementWidth) / 2); } if (parentHeight < elementHeight) { style.top = style.bottom = Math.ceil((parentHeight - elementHeight) / 2); } style.width = elementWidth; style.height = elementHeight; utils.scale(domelement, xscale, yscale, 0, 0); } else { scale = false; utils.transform(domelement); } utils.css.style(domelement, style); } else { domelement.className = domelement.className.replace(/\s*jw(none|exactfit|uniform|fill)/g, '') + ' ' + stretchClass; } return scale; }; })(jwplayer.utils); (function(parsers) { /** Component that loads and parses an DFXP file. **/ parsers.dfxp = function() { var _seconds = jwplayer.utils.seconds; this.parse = function(data) { var _captions = [{ begin: 0, text: '' }]; data = data.replace(/^\s+/, '').replace(/\s+$/, ''); var list = data.split('

'); var list2 = data.split(''); var newlist = []; var i; for (i = 0; i < list.length; i++) { if (list[i].indexOf('= 0) { list[i] = list[i].substr(list[i].indexOf('= 0) { list2[i] = list2[i].substr(list2[i].indexOf(' 1) { return _captions; } else { throw { message: 'Invalid DFXP file:' }; } }; /** Parse a single captions entry. **/ function _entry(data) { var entry = {}; try { var idx = data.indexOf('begin=\"'); data = data.substr(idx + 7); idx = data.indexOf('\" end=\"'); entry.begin = _seconds(data.substr(0, idx)); data = data.substr(idx + 7); idx = data.indexOf('\"'); entry.end = _seconds(data.substr(0, idx)); idx = data.indexOf('\">'); data = data.substr(idx + 2); entry.text = data; } catch (error) {} return entry; } }; })(jwplayer.parsers); (function(parsers) { /** Component that loads and parses an SRT file. **/ parsers.srt = function() { /** XMLHTTP Object. **/ var _utils = jwplayer.utils, _seconds = _utils.seconds; this.parse = function(data, mergeBeginEnd) { // Trim whitespace and split the list by returns. var _captions = mergeBeginEnd ? [] : [{ begin: 0, text: '' }]; data = _utils.trim(data); var list = data.split('\r\n\r\n'); if (list.length === 1) { list = data.split('\n\n'); } for (var i = 0; i < list.length; i++) { if (list[i] === 'WEBVTT') { continue; } // Parse each entry var entry = _entry(list[i]); if (entry.text) { _captions.push(entry); // Insert empty caption at the end. if (entry.end && !mergeBeginEnd) { _captions.push({ begin: entry.end, text: '' }); delete entry.end; } } } if (_captions.length > 1) { return _captions; } else { throw { message: 'Invalid SRT file' }; } }; /** Parse a single captions entry. **/ function _entry(data) { var entry = {}; var array = data.split('\r\n'); if (array.length === 1) { array = data.split('\n'); } try { // Second line contains the start and end. var idx = 1; if (array[0].indexOf(' --> ') > 0) { idx = 0; } var index = array[idx].indexOf(' --> '); if (index > 0) { entry.begin = _seconds(array[idx].substr(0, index)); entry.end = _seconds(array[idx].substr(index + 5)); } // Third line starts the text. if (array[idx + 1]) { entry.text = array[idx + 1]; // Arbitrary number of additional lines. for (var i = idx + 2; i < array.length; i++) { entry.text += '
' + array[i]; } } } catch (error) {} return entry; } }; })(jwplayer.parsers); (function(jwplayer) { var noop = jwplayer.utils.noop, _ = jwplayer._, events = jwplayer.events, returnFalse = _.constant(false); var defaultProvider = { // This function is required to determine if a provider can work on a given source supports : returnFalse, // Basic playback features play : noop, load : noop, stop : noop, volume : noop, mute : noop, seek : noop, seekDrag : noop, // only for html5 ? resize : noop, remove : noop, // removes from page destroy : noop, // frees memory setVisibility : noop, setFullscreen : returnFalse, getFullscreen : noop, // If setContainer has been set, this returns the element. // It's value is used to determine if we should remove the