1 /** The minplayer namespace. */ 2 minplayer = minplayer || {}; 3 4 /** 5 * @constructor 6 * @extends minplayer.plugin 7 * @class Base class used to provide the display and options for any component 8 * deriving from this class. Components who derive are expected to provide 9 * the elements that they define by implementing the getElements method. 10 * 11 * @param {string} name The name of this plugin. 12 * @param {object} context The jQuery context this component resides. 13 * @param {object} options The options for this component. 14 * @param {object} queue The event queue to pass events around. 15 */ 16 minplayer.display = function(name, context, options, queue) { 17 18 // Derive from plugin 19 minplayer.plugin.call(this, name, context, options, queue); 20 }; 21 22 /** Derive from minplayer.plugin. */ 23 minplayer.display.prototype = new minplayer.plugin(); 24 25 /** Reset the constructor. */ 26 minplayer.display.prototype.constructor = minplayer.display; 27 28 /** 29 * Returns the display for this component. 30 * 31 * @return {object} The jQuery context for this display. 32 */ 33 minplayer.display.prototype.getDisplay = function() { 34 return this.context; 35 }; 36 37 /** 38 * @see minplayer.plugin.construct 39 */ 40 minplayer.display.prototype.construct = function() { 41 42 // Set the display. 43 this.display = this.getDisplay(this.context, this.options); 44 45 // Call the plugin constructor. 46 minplayer.plugin.prototype.construct.call(this); 47 48 // Set the plugin name within the options. 49 this.options.pluginName = 'display'; 50 51 // Get the display elements. 52 this.elements = this.getElements(); 53 54 // Only do this if they allow resize for this display. 55 if (this.onResize) { 56 57 // Set the resize timeout and this pointer. 58 var resizeTimeout = 0; 59 60 // Add a handler to trigger a resize event. 61 jQuery(window).resize((function(display) { 62 return function() { 63 clearTimeout(resizeTimeout); 64 resizeTimeout = setTimeout(function() { 65 display.onResize(); 66 }, 200); 67 }; 68 })(this)); 69 } 70 }; 71 72 /** 73 * Called when the window resizes. 74 */ 75 minplayer.display.prototype.onResize = false; 76 77 /** 78 * Wrapper around hide that will always not show. 79 * 80 * @param {object} element The element you wish to hide. 81 */ 82 minplayer.display.prototype.hide = function(element) { 83 element = element || this.display; 84 if (element) { 85 element.forceHide = true; 86 element.unbind().hide(); 87 } 88 }; 89 90 /** 91 * Gets the full screen element. 92 * 93 * @return {object} The display to be used for full screen support. 94 */ 95 minplayer.display.prototype.fullScreenElement = function() { 96 return this.display; 97 }; 98 99 /** 100 * Fix for the click function in jQuery to be cross platform. 101 * 102 * @param {object} element The element that will be clicked. 103 * @param {function} fn Called when the element is clicked. 104 * @return {object} The element that is to be clicked. 105 */ 106 minplayer.click = function(element, fn) { 107 var flag = false; 108 element = jQuery(element); 109 element.bind('touchstart click', function(event) { 110 if (!flag) { 111 flag = true; 112 setTimeout(function() { 113 flag = false; 114 }, 100); 115 fn.call(this, event); 116 } 117 }); 118 return element; 119 }; 120 121 /** 122 * Determines if the player is in focus or not. 123 * 124 * @param {boolean} focus If the player is in focus. 125 */ 126 minplayer.display.prototype.onFocus = function(focus) { 127 this.hasFocus = this.focus = focus; 128 }; 129 130 /** Keep track of all the show hide elements. */ 131 minplayer.showHideElements = []; 132 133 /** 134 * Show all the show hide elements. 135 */ 136 minplayer.showAll = function() { 137 var i = minplayer.showHideElements.length; 138 var obj = null; 139 while (i--) { 140 obj = minplayer.showHideElements[i]; 141 minplayer.showThenHide(obj.element, obj.timeout, obj.callback); 142 } 143 }; 144 145 /** 146 * Stops the whole show then hide from happening. 147 * 148 * @param {object} element The element you want the showThenHide to stop. 149 */ 150 minplayer.stopShowThenHide = function(element) { 151 element = jQuery(element); 152 if (element.showTimer) { 153 clearTimeout(element.showTimer); 154 } 155 element.stopShowThenHide = true; 156 element.shown = true; 157 element.show(); 158 }; 159 160 /** 161 * Called if you would like for your display item to show then hide. 162 * 163 * @param {object} element The element you would like to hide or show. 164 * @param {number} timeout The timeout to hide and show. 165 * @param {function} callback Called when something happens. 166 */ 167 minplayer.showThenHide = function(element, timeout, callback) { 168 169 // If no element exists, then just return. 170 if (!element) { 171 return; 172 } 173 174 // Ensure we have a timeout. 175 timeout = timeout || 5000; 176 177 // If this has not yet been configured. 178 if (!element.showTimer) { 179 element.shown = true; 180 element.stopShowThenHide = false; 181 182 // Add this to our showHideElements. 183 minplayer.showHideElements.push({ 184 element: element, 185 timeout: timeout, 186 callback: callback 187 }); 188 189 // Bind to a click event. 190 minplayer.click(document, function() { 191 if (!element.stopShowThenHide) { 192 minplayer.showThenHide(element, timeout, callback); 193 } 194 }); 195 196 // Bind to the mousemove event. 197 jQuery(document).bind('mousemove', function() { 198 if (!element.stopShowThenHide) { 199 minplayer.showThenHide(element, timeout, callback); 200 } 201 }); 202 } 203 204 // Clear the timeout, and then setup the show then hide functionality. 205 clearTimeout(element.showTimer); 206 207 // Show the display. 208 if (!element.shown && !element.forceHide) { 209 element.shown = true; 210 element.show(); 211 if (callback) { 212 callback(true); 213 } 214 } 215 216 // Set a timer to hide it after the timeout. 217 element.showTimer = setTimeout(function() { 218 element.hide('slow', function() { 219 element.shown = false; 220 if (callback) { 221 callback(false); 222 } 223 }); 224 }, timeout); 225 }; 226 227 /** 228 * Make this display element go fullscreen. 229 * 230 * @param {boolean} full Tell the player to go into fullscreen or not. 231 */ 232 minplayer.display.prototype.fullscreen = function(full) { 233 var isFull = this.isFullScreen(); 234 var element = this.fullScreenElement(); 235 if (isFull && !full) { 236 element.removeClass('fullscreen'); 237 if (screenfull) { 238 screenfull.exit(); 239 } 240 this.trigger('fullscreen', false); 241 } 242 else if (!isFull && full) { 243 element.addClass('fullscreen'); 244 if (screenfull) { 245 screenfull.request(element[0]); 246 screenfull.onchange = (function(display) { 247 return function(e) { 248 if (!screenfull.isFullscreen) { 249 display.fullscreen(false); 250 } 251 }; 252 })(this); 253 } 254 this.trigger('fullscreen', true); 255 } 256 }; 257 258 /** 259 * Toggle fullscreen. 260 */ 261 minplayer.display.prototype.toggleFullScreen = function() { 262 this.fullscreen(!this.isFullScreen()); 263 }; 264 265 /** 266 * Checks to see if we are in fullscreen mode. 267 * 268 * @return {boolean} TRUE - fullscreen, FALSE - otherwise. 269 */ 270 minplayer.display.prototype.isFullScreen = function() { 271 return this.fullScreenElement().hasClass('fullscreen'); 272 }; 273 274 /** 275 * Returns a scaled rectangle provided a ratio and the container rect. 276 * 277 * @param {number} ratio The width/height ratio of what is being scaled. 278 * @param {object} rect The bounding rectangle for scaling. 279 * @return {object} The Rectangle object of the scaled rectangle. 280 */ 281 minplayer.display.prototype.getScaledRect = function(ratio, rect) { 282 var scaledRect = {}; 283 scaledRect.x = rect.x ? rect.x : 0; 284 scaledRect.y = rect.y ? rect.y : 0; 285 scaledRect.width = rect.width ? rect.width : 0; 286 scaledRect.height = rect.height ? rect.height : 0; 287 if (ratio) { 288 if ((rect.width / rect.height) > ratio) { 289 scaledRect.height = rect.height; 290 scaledRect.width = Math.floor(rect.height * ratio); 291 } 292 else { 293 scaledRect.height = Math.floor(rect.width / ratio); 294 scaledRect.width = rect.width; 295 } 296 scaledRect.x = Math.floor((rect.width - scaledRect.width) / 2); 297 scaledRect.y = Math.floor((rect.height - scaledRect.height) / 2); 298 } 299 return scaledRect; 300 }; 301 302 /** 303 * Returns all the jQuery elements that this component uses. 304 * 305 * @return {object} An object which defines all the jQuery elements that 306 * this component uses. 307 */ 308 minplayer.display.prototype.getElements = function() { 309 return {}; 310 }; 311 312 /** 313 * From https://github.com/sindresorhus/screenfull.js 314 */ 315 /*global Element:true*/ 316 (function(window, document) { 317 'use strict'; 318 var methods = (function() { 319 var methodMap = [ 320 [ 321 'requestFullscreen', 322 'exitFullscreen', 323 'fullscreenchange', 324 'fullscreen', 325 'fullscreenElement' 326 ], 327 [ 328 'webkitRequestFullScreen', 329 'webkitCancelFullScreen', 330 'webkitfullscreenchange', 331 'webkitIsFullScreen', 332 'webkitCurrentFullScreenElement' 333 ], 334 [ 335 'mozRequestFullScreen', 336 'mozCancelFullScreen', 337 'mozfullscreenchange', 338 'mozFullScreen', 339 'mozFullScreenElement' 340 ] 341 ]; 342 for (var i = 0, l = methodMap.length; i < l; i++) { 343 if (methodMap.hasOwnProperty(i)) { 344 var val = methodMap[i]; 345 if (val[1] in document) { 346 return val; 347 } 348 } 349 } 350 })(); 351 352 if (!methods) { 353 return window.screenfull = false; 354 } 355 356 var keyboardAllowed = 'ALLOW_KEYBOARD_INPUT' in Element; 357 358 var screenfull = { 359 init: function() { 360 document.addEventListener(methods[2], function(e) { 361 screenfull.isFullscreen = document[methods[3]]; 362 screenfull.element = document[methods[4]]; 363 screenfull.onchange(e); 364 }); 365 return this; 366 }, 367 isFullscreen: document[methods[3]], 368 element: document[methods[4]], 369 request: function(elem) { 370 elem = elem || document.documentElement; 371 elem[methods[0]](keyboardAllowed && Element.ALLOW_KEYBOARD_INPUT); 372 // Work around Safari 5.1 bug: reports support for keyboard in fullscreen 373 // even though it doesn't. 374 if (!document.isFullscreen) { 375 elem[methods[0]](); 376 } 377 }, 378 exit: function() { 379 document[methods[1]](); 380 }, 381 toggle: function(elem) { 382 if (this.isFullscreen) { 383 this.exit(); 384 } else { 385 this.request(elem); 386 } 387 }, 388 onchange: function() {} 389 }; 390 391 window.screenfull = screenfull.init(); 392 })(window, document); 393