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   // Get the display elements.
 49   this.elements = this.getElements();
 50 
 51   // Only do this if they allow resize for this display.
 52   if (this.onResize) {
 53 
 54     // Set the resize timeout and this pointer.
 55     var resizeTimeout = 0;
 56 
 57     // Add a handler to trigger a resize event.
 58     jQuery(window).resize((function(display) {
 59       return function() {
 60         clearTimeout(resizeTimeout);
 61         resizeTimeout = setTimeout(function() {
 62           display.onResize();
 63         }, 200);
 64       };
 65     })(this));
 66   }
 67 };
 68 
 69 /**
 70  * Called when the window resizes.
 71  */
 72 minplayer.display.prototype.onResize = false;
 73 
 74 /**
 75  * Gets the full screen element.
 76  *
 77  * @return {object} The display to be used for full screen support.
 78  */
 79 minplayer.display.prototype.fullScreenElement = function() {
 80   return this.display;
 81 };
 82 
 83 /**
 84  * Called if you would like for your display item to show then hide.
 85  *
 86  * @param {object} element The element you would like to hide or show.
 87  * @param {number} timeout The timeout to hide and show.
 88  */
 89 minplayer.showThenHide = function(element, timeout) {
 90 
 91   // Ensure we have a timeout.
 92   timeout = timeout || 5000;
 93 
 94   // If this has not yet been configured.
 95   if (!element.showTimer) {
 96 
 97     // Bind when they move the mouse.
 98     jQuery(document).bind('mousemove', function() {
 99       minplayer.showThenHide(element, timeout);
100     });
101   }
102 
103   // Clear the timeout, and then setup the show then hide functionality.
104   clearTimeout(element.showTimer);
105 
106   // Show the display.
107   element.show();
108 
109   // Set a timer to hide it after the timeout.
110   element.showTimer = setTimeout(function() {
111     element.hide('slow');
112   }, timeout);
113 };
114 
115 /**
116  * Make this display element go fullscreen.
117  *
118  * @param {boolean} full Tell the player to go into fullscreen or not.
119  */
120 minplayer.display.prototype.fullscreen = function(full) {
121   var isFull = this.isFullScreen();
122   var element = this.fullScreenElement();
123   if (isFull && !full) {
124     element.removeClass('fullscreen');
125     if (screenfull) {
126       screenfull.exit();
127     }
128     this.trigger('fullscreen', false);
129   }
130   else if (!isFull && full) {
131     element.addClass('fullscreen');
132     if (screenfull) {
133       screenfull.request(element[0]);
134       screenfull.onchange = (function(display) {
135         return function(e) {
136           if (!screenfull.isFullscreen) {
137             display.fullscreen(false);
138           }
139         };
140       })(this);
141     }
142     this.trigger('fullscreen', true);
143   }
144 };
145 
146 /**
147  * Toggle fullscreen.
148  */
149 minplayer.display.prototype.toggleFullScreen = function() {
150   this.fullscreen(!this.isFullScreen());
151 };
152 
153 /**
154  * Checks to see if we are in fullscreen mode.
155  *
156  * @return {boolean} TRUE - fullscreen, FALSE - otherwise.
157  */
158 minplayer.display.prototype.isFullScreen = function() {
159   return this.fullScreenElement().hasClass('fullscreen');
160 };
161 
162 /**
163  * Returns a scaled rectangle provided a ratio and the container rect.
164  *
165  * @param {number} ratio The width/height ratio of what is being scaled.
166  * @param {object} rect The bounding rectangle for scaling.
167  * @return {object} The Rectangle object of the scaled rectangle.
168  */
169 minplayer.display.prototype.getScaledRect = function(ratio, rect) {
170   var scaledRect = {};
171   scaledRect.x = rect.x ? rect.x : 0;
172   scaledRect.y = rect.y ? rect.y : 0;
173   scaledRect.width = rect.width ? rect.width : 0;
174   scaledRect.height = rect.height ? rect.height : 0;
175   if (ratio) {
176     if ((rect.width / rect.height) > ratio) {
177       scaledRect.height = rect.height;
178       scaledRect.width = Math.floor(rect.height * ratio);
179     }
180     else {
181       scaledRect.height = Math.floor(rect.width / ratio);
182       scaledRect.width = rect.width;
183     }
184     scaledRect.x = Math.floor((rect.width - scaledRect.width) / 2);
185     scaledRect.y = Math.floor((rect.height - scaledRect.height) / 2);
186   }
187   return scaledRect;
188 };
189 
190 /**
191  * Returns all the jQuery elements that this component uses.
192  *
193  * @return {object} An object which defines all the jQuery elements that
194  * this component uses.
195  */
196 minplayer.display.prototype.getElements = function() {
197   return {};
198 };
199 
200 /**
201  * Returns if this component is valid and exists within the DOM.
202  *
203  * @return {boolean} TRUE if the plugin display is valid.
204  */
205 minplayer.display.prototype.isValid = function() {
206   return (this.display.length > 0);
207 };
208 
209 /**
210  * From https://github.com/sindresorhus/screenfull.js
211  */
212 /*global Element:true*/
213 (function(window, document) {
214   'use strict';
215   var methods = (function() {
216     var methodMap = [
217       [
218         'requestFullscreen',
219         'exitFullscreen',
220         'fullscreenchange',
221         'fullscreen',
222         'fullscreenElement'
223       ],
224       [
225         'webkitRequestFullScreen',
226         'webkitCancelFullScreen',
227         'webkitfullscreenchange',
228         'webkitIsFullScreen',
229         'webkitCurrentFullScreenElement'
230       ],
231       [
232         'mozRequestFullScreen',
233         'mozCancelFullScreen',
234         'mozfullscreenchange',
235         'mozFullScreen',
236         'mozFullScreenElement'
237       ]
238     ];
239     for (var i = 0, l = methodMap.length; i < l; i++) {
240       var val = methodMap[i];
241       if (val[1] in document) {
242         return val;
243       }
244     }
245   })();
246 
247   if (!methods) {
248     return window.screenfull = false;
249   }
250 
251   var keyboardAllowed = 'ALLOW_KEYBOARD_INPUT' in Element;
252 
253   var screenfull = {
254     init: function() {
255       document.addEventListener(methods[2], function(e) {
256         screenfull.isFullscreen = document[methods[3]];
257         screenfull.element = document[methods[4]];
258         screenfull.onchange(e);
259       });
260       return this;
261     },
262     isFullscreen: document[methods[3]],
263     element: document[methods[4]],
264     request: function(elem) {
265       elem = elem || document.documentElement;
266       elem[methods[0]](keyboardAllowed && Element.ALLOW_KEYBOARD_INPUT);
267       // Work around Safari 5.1 bug: reports support for keyboard in fullscreen
268       // even though it doesn't.
269       if (!document.isFullscreen) {
270         elem[methods[0]]();
271       }
272     },
273     exit: function() {
274       document[methods[1]]();
275     },
276     toggle: function(elem) {
277       if (this.isFullscreen) {
278         this.exit();
279       } else {
280         this.request(elem);
281       }
282     },
283     onchange: function() {}
284   };
285 
286   window.screenfull = screenfull.init();
287 })(window, document);
288