(function ($) { // Set default variable values. AblePlayer.prototype.setDefaults = function () { // this.playing will change to true after 'playing' event is triggered this.playing = false; this.getUserAgent(); this.setIconColor(); this.setButtonImages(); }; AblePlayer.prototype.getRootPath = function() { // returns Able Player root path (assumes ableplayer.js is in /build, one directory removed from root) var scripts, i, scriptSrc, scriptFile, fullPath, ablePath, parentFolderIndex, rootPath; scripts= document.getElementsByTagName('script'); for (i=0; i < scripts.length; i++) { scriptSrc = scripts[i].src; scriptFile = scriptSrc.substr(scriptSrc.lastIndexOf('/')); if (scriptFile.indexOf('ableplayer') !== -1) { // this is the ableplayerscript fullPath = scriptSrc.split('?')[0]; // remove any ? params break; } } ablePath= fullPath.split('/').slice(0, -1).join('/'); // remove last filename part of path parentFolderIndex = ablePath.lastIndexOf('/'); rootPath = ablePath.substring(0, parentFolderIndex) + '/'; return rootPath; } AblePlayer.prototype.setIconColor = function() { // determine the best color choice (white or black) for icons, // given the background-color of their container elements // Source for relative luminance formula: // https://en.wikipedia.org/wiki/Relative_luminance // We need to know the color *before* creating the element // so the element doesn't exist yet when this function is called // therefore, need to create a temporary element then remove it after color is determined // Temp element must be added to the DOM or WebKit can't retrieve its CSS properties var $elements, i, $el, bgColor, rgb, red, green, blue, luminance, iconColor; $elements = ['controller', 'toolbar']; for (i=0; i<$elements.length; i++) { if ($elements[i] == 'controller') { $el = $('
', { 'class': 'able-controller' }).hide(); } else if ($elements[i] === 'toolbar') { $el = $('
', { 'class': 'able-window-toolbar' }).hide(); } $('body').append($el); bgColor = $el.css('background-color'); // bgColor is a string in the form 'rgb(R, G, B)', perhaps with a 4th item for alpha; // split the 3 or 4 channels into an array rgb = bgColor.replace(/[^\d,]/g, '').split(','); red = rgb[0]; green = rgb[1]; blue = rgb[2]; luminance = (0.2126 * red) + (0.7152 * green) + (0.0722 * blue); // range is 1 - 255; therefore 125 is the tipping point if (luminance < 125) { // background is dark iconColor = 'white'; } else { // background is light iconColor = 'black'; } if ($elements[i] === 'controller') { this.iconColor = iconColor; } else if ($elements[i] === 'toolbar') { this.toolbarIconColor = iconColor; } $el.remove(); } }; AblePlayer.prototype.setButtonImages = function() { // NOTE: volume button images are now set dynamically within volume.js this.imgPath = this.rootPath + 'button-icons/' + this.iconColor + '/'; this.playButtonImg = this.imgPath + 'play.png'; this.pauseButtonImg = this.imgPath + 'pause.png'; this.restartButtonImg = this.imgPath + 'restart.png'; this.rewindButtonImg = this.imgPath + 'rewind.png'; this.forwardButtonImg = this.imgPath + 'forward.png'; this.previousButtonImg = this.imgPath + 'previous.png'; this.nextButtonImg = this.imgPath + 'next.png'; if (this.speedIcons === 'arrows') { this.fasterButtonImg = this.imgPath + 'slower.png'; this.slowerButtonImg = this.imgPath + 'faster.png'; } else if (this.speedIcons === 'animals') { this.fasterButtonImg = this.imgPath + 'rabbit.png'; this.slowerButtonImg = this.imgPath + 'turtle.png'; } this.captionsButtonImg = this.imgPath + 'captions.png'; this.chaptersButtonImg = this.imgPath + 'chapters.png'; this.signButtonImg = this.imgPath + 'sign.png'; this.transcriptButtonImg = this.imgPath + 'transcript.png'; this.descriptionsButtonImg = this.imgPath + 'descriptions.png'; this.fullscreenExpandButtonImg = this.imgPath + 'fullscreen-expand.png'; this.fullscreenCollapseButtonImg = this.imgPath + 'fullscreen-collapse.png'; this.prefsButtonImg = this.imgPath + 'preferences.png'; this.helpButtonImg = this.imgPath + 'help.png'; }; // Initialize player based on data on page. // This sets some variables, but does not modify anything. Safe to call multiple times. // Can call again after updating this.media so long as new media element has the same ID. AblePlayer.prototype.reinitialize = function () { var deferred, promise, thisObj, errorMsg, srcFile; deferred = new $.Deferred(); promise = deferred.promise(); thisObj = this; // if F12 Developer Tools aren't open in IE (through 9, no longer a problen in IE10) // console.log causes an error - can't use debug without a console to log messages to if (! window.console) { this.debug = false; } this.startedPlaying = false; // TODO: Move this setting to cookie. this.autoScrollTranscript = true; //this.autoScrollTranscript = this.getCookie(autoScrollTranscript); // (doesn't work) // Bootstrap from this.media possibly being an ID or other selector. this.$media = $(this.media).first(); this.media = this.$media[0]; // Set media type to 'audio' or 'video'; this determines some of the behavior of player creation. if (this.$media.is('audio')) { this.mediaType = 'audio'; } else if (this.$media.is('video')) { this.mediaType = 'video'; } else { this.mediaType = this.$media.get(0).tagName; errorMsg = 'Media player initialized with ' + this.mediaType + '#' + this.mediaId + '. '; errorMsg += 'Expecting an HTML5 audio or video element.'; this.provideFallback(errorMsg); deferred.fail(); return promise; } this.$sources = this.$media.find('source'); this.player = this.getPlayer(); if (!this.player) { // an error was generated in getPlayer() this.provideFallback(this.error); } this.setIconType(); this.setDimensions(); deferred.resolve(); return promise; }; AblePlayer.prototype.setDimensions = function() { // if