video_embed_field_overlay.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. (function($) {
  2. var console = window.console || false;
  3. /**
  4. * Finds the links to the videos and attaches the overlay behavior
  5. */
  6. Drupal.behaviors.videoEmbedFieldOverlay = {
  7. ready: [],
  8. timer: null,
  9. players: {},
  10. playOnPopUp: undefined,
  11. /**
  12. * Initial load function, preps videos for popup, sets up initial event chain.
  13. */
  14. attach: function (context, settings) {
  15. Drupal.behaviors.videoEmbedFieldOverlay.players = $('.video-overlay-source iframe', context);
  16. if ($.isFunction($.openDOMWindow)) {
  17. Drupal.behaviors.videoEmbedFieldOverlay.players.each(function(i, element) {
  18. if ($(element).attr('src').indexOf('vimeo.com') !== -1) {
  19. Drupal.behaviors.videoEmbedFieldOverlay.vimeoProcessElement(element);
  20. }
  21. });
  22. // Setup message handlers
  23. if (window.addEventListener) { // all browsers except IE before version 9
  24. window.addEventListener('message', Drupal.behaviors.videoEmbedFieldOverlay.onMessageReceived, false);
  25. }
  26. else if (window.attachEvent) { // IE before version 9
  27. var attached = window.attachEvent('onmessage', Drupal.behaviors.videoEmbedFieldOverlay.onMessageReceived, false);
  28. if (attached === false) {
  29. if (console) {console.log('Failed to attach the listener');}
  30. }
  31. }
  32. // Find all the trigger links
  33. $('.video-overlay-thumbnail a.overlay', context).bind('click', function(e) {
  34. // Prevent going to the URL
  35. e.preventDefault();
  36. // Get the id of the video
  37. // @TODO: Find cleaner way to get this.
  38. var id = $(this).parent().parent().find('.video-overlay-source iframe').attr('id').replace('overlay-video-', '');
  39. Drupal.behaviors.videoEmbedFieldOverlay.videoOnClick(id);
  40. });
  41. } else {
  42. if (console) {console.log('Cannot create DOMWindow');}
  43. }
  44. },
  45. /**
  46. * Triggers the DOM Windwow and the autoplay
  47. */
  48. videoOnClick: function (id) {
  49. var f = $('iframe#overlay-video-' + id).parent().get(0) || $('iframe').parent().get(0);
  50. var iframe = $('iframe#overlay-video-' + id).get(0) || $('iframe').get(0);
  51. // Setup the DOM Window
  52. $.openDOMWindow({
  53. loader:0,
  54. width:iframe.width || 640,
  55. height:iframe.height || 360,
  56. windowSourceID:f
  57. });
  58. // Play: Will not work on IE and some older versions of players.
  59. if (Drupal.behaviors.videoEmbedFieldOverlay.browserSupported() === true) {
  60. // Since we're moving the video from the page to the popup, we need to let the video know to
  61. // start playing AFTER it's been loaded in the new place, instead of sending the command directly.
  62. // We do this by telling this script which video to play once it's been loaded and ready to go.
  63. Drupal.behaviors.videoEmbedFieldOverlay.playOnPopUp = 'overlay-video-' + id;
  64. }
  65. },
  66. setupListeners: function (id) {
  67. var f = $('iframe#' + id).get(0) || $('iframe').get(0),
  68. url = '*';
  69. if (f.contentWindow.postMessage) {
  70. f.contentWindow.postMessage({
  71. method: 'addEventListener',
  72. value: 'play'
  73. }, url);
  74. f.contentWindow.postMessage({
  75. method: 'addEventListener',
  76. value: 'pause'
  77. }, url);
  78. f.contentWindow.postMessage({
  79. method: 'addEventListener',
  80. value: 'finish'
  81. }, url);
  82. Drupal.behaviors.videoEmbedFieldOverlay.setStatus(id, 'listening');
  83. if (console) {console.log('Listeners setup for ' + id);}
  84. } else {
  85. if (console) {console.log('Browser does not support postMessage');}
  86. }
  87. },
  88. /**
  89. * Notes:
  90. * The postMessage method is synchronous in Internet Explorer and
  91. * asynchronous in other browsers.
  92. */
  93. play: function (id) {
  94. var f = $('iframe#' + id).get(0) || $('iframe').get(0),
  95. url = '*';
  96. if (Drupal.behaviors.videoEmbedFieldOverlay.getStatus(id) !== 'play') {
  97. if (f.contentWindow.postMessage) {
  98. // Trigger video play
  99. var messageData = JSON.stringify({method: 'play', player_id: id});
  100. f.contentWindow.postMessage(messageData, url);
  101. }
  102. else {
  103. if (console) {console.log('Your browser does not support the postMessage method!');}
  104. }
  105. }
  106. },
  107. /**
  108. * Assigns a status to an array of player ids
  109. */
  110. setStatus: function (id, status) {
  111. Drupal.behaviors.videoEmbedFieldOverlay.ready[id] = status;
  112. if (console) {
  113. console.log('Video: ' + id + ' is ' + status);
  114. }
  115. // react to certain events.
  116. var eventHandler = 'onStatus' + status.charAt(0).toUpperCase() + status.slice(1);
  117. if (Drupal.behaviors.videoEmbedFieldOverlay[eventHandler] !== undefined) {
  118. Drupal.behaviors.videoEmbedFieldOverlay[eventHandler](id);
  119. }
  120. },
  121. /**
  122. * Retrieves the status for a given player id
  123. */
  124. getStatus: function (id) {
  125. return Drupal.behaviors.videoEmbedFieldOverlay.ready[id];
  126. },
  127. /**
  128. * Handles the messages received by the listener
  129. */
  130. onMessageReceived: function(e) {
  131. var data = jQuery.parseJSON(e.data);
  132. Drupal.behaviors.videoEmbedFieldOverlay.setStatus(data.player_id, data.event);
  133. },
  134. // Status event callbacks.
  135. /**
  136. * onStatusReady: Called when the video is ready to be interacted with.
  137. */
  138. onStatusReady: function(id) {
  139. Drupal.behaviors.videoEmbedFieldOverlay.setupListeners(id);
  140. if (Drupal.behaviors.videoEmbedFieldOverlay.playOnPopUp === id) {
  141. Drupal.behaviors.videoEmbedFieldOverlay.playOnPopUp = undefined;
  142. Drupal.behaviors.videoEmbedFieldOverlay.play(id);
  143. }
  144. },
  145. /**
  146. * onStatusFinish: Called when video playback is complete.
  147. */
  148. onStatusFinish: function(id) {
  149. $.closeDOMWindow();
  150. },
  151. /**
  152. * Checks to see if the current browser supports autoPlayback. Should be rewritten to use feature
  153. * detection instead of browser sniffing.
  154. */
  155. browserSupported: function () {
  156. if ($.browser.msie === true ) {
  157. if (window.console) {window.console.log('IE does not support the autoplay feature');}
  158. return false;
  159. }
  160. if ($.browser.mozilla === true && $.browser.version.slice(0,3) == '1.9') {
  161. if (window.console) {window.console.log('Older versions of Mozilla do not support the autoplay feature');}
  162. return false;
  163. }
  164. if ($.browser.opera === true) {
  165. if (window.console) {window.console.log('Opera does not support the autoplay feature');}
  166. return false;
  167. }
  168. return true;
  169. },
  170. /**
  171. * Handles Vimeo-specific code on the embed element.
  172. *
  173. * For Vimeo popup, we need to drop in an #id if there isn't one already, and we need to also let
  174. * Vimeo know what the id is via a URL parameter. Also, we need to ensure that we let Vimeo know
  175. * that we want to use their JS API via another URL parameter. Written in a way that ensures we
  176. * don't lose any other url parameters passed in.
  177. */
  178. vimeoProcessElement: function(element) {
  179. var src = $(element).attr('src');
  180. var href = src.split('?')[0];
  181. var videoID = href.split('/video/')[1];
  182. $(element).attr('id', 'overlay-video-' + videoID);
  183. var urlAttributes = src.split('?')[1];
  184. var urlAttributesObject = urlAttributes.split('&');
  185. var urlKeyedAttributes = {};
  186. for (var i in urlAttributesObject) {
  187. var components = urlAttributesObject[i].split('=');
  188. urlKeyedAttributes[components[0]] = components[1];
  189. }
  190. urlKeyedAttributes['api'] = 1;
  191. urlKeyedAttributes['player_id'] = 'overlay-video-' + videoID;
  192. var newURLAttributes = [];
  193. for (i in urlKeyedAttributes) {
  194. newURLAttributes.push(i + "=" + urlKeyedAttributes[i]);
  195. }
  196. $(element).attr('src', href + '?' + newURLAttributes.join('&'));
  197. }
  198. };
  199. })(jQuery);