wp-playlist.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /* global _wpmejsSettings, MediaElementPlayer */
  2. (function ($, _, Backbone) {
  3. 'use strict';
  4. /** @namespace wp */
  5. window.wp = window.wp || {};
  6. var WPPlaylistView = Backbone.View.extend(/** @lends WPPlaylistView.prototype */{
  7. /**
  8. * @constructs
  9. *
  10. * @param {Object} options The options to create this playlist view with.
  11. * @param {Object} options.metadata The metadata
  12. */
  13. initialize : function (options) {
  14. this.index = 0;
  15. this.settings = {};
  16. this.data = options.metadata || $.parseJSON( this.$('script.wp-playlist-script').html() );
  17. this.playerNode = this.$( this.data.type );
  18. this.tracks = new Backbone.Collection( this.data.tracks );
  19. this.current = this.tracks.first();
  20. if ( 'audio' === this.data.type ) {
  21. this.currentTemplate = wp.template( 'wp-playlist-current-item' );
  22. this.currentNode = this.$( '.wp-playlist-current-item' );
  23. }
  24. this.renderCurrent();
  25. if ( this.data.tracklist ) {
  26. this.itemTemplate = wp.template( 'wp-playlist-item' );
  27. this.playingClass = 'wp-playlist-playing';
  28. this.renderTracks();
  29. }
  30. this.playerNode.attr( 'src', this.current.get( 'src' ) );
  31. _.bindAll( this, 'bindPlayer', 'bindResetPlayer', 'setPlayer', 'ended', 'clickTrack' );
  32. if ( ! _.isUndefined( window._wpmejsSettings ) ) {
  33. this.settings = _.clone( _wpmejsSettings );
  34. }
  35. this.settings.success = this.bindPlayer;
  36. this.setPlayer();
  37. },
  38. bindPlayer : function (mejs) {
  39. this.mejs = mejs;
  40. this.mejs.addEventListener( 'ended', this.ended );
  41. },
  42. bindResetPlayer : function (mejs) {
  43. this.bindPlayer( mejs );
  44. this.playCurrentSrc();
  45. },
  46. setPlayer: function (force) {
  47. if ( this.player ) {
  48. this.player.pause();
  49. this.player.remove();
  50. this.playerNode = this.$( this.data.type );
  51. }
  52. if (force) {
  53. this.playerNode.attr( 'src', this.current.get( 'src' ) );
  54. this.settings.success = this.bindResetPlayer;
  55. }
  56. // This is also our bridge to the outside world.
  57. this.player = new MediaElementPlayer( this.playerNode.get(0), this.settings );
  58. },
  59. playCurrentSrc : function () {
  60. this.renderCurrent();
  61. this.mejs.setSrc( this.playerNode.attr( 'src' ) );
  62. this.mejs.load();
  63. this.mejs.play();
  64. },
  65. renderCurrent : function () {
  66. var dimensions, defaultImage = 'wp-includes/images/media/video.png';
  67. if ( 'video' === this.data.type ) {
  68. if ( this.data.images && this.current.get( 'image' ) && -1 === this.current.get( 'image' ).src.indexOf( defaultImage ) ) {
  69. this.playerNode.attr( 'poster', this.current.get( 'image' ).src );
  70. }
  71. dimensions = this.current.get( 'dimensions' ).resized;
  72. this.playerNode.attr( dimensions );
  73. } else {
  74. if ( ! this.data.images ) {
  75. this.current.set( 'image', false );
  76. }
  77. this.currentNode.html( this.currentTemplate( this.current.toJSON() ) );
  78. }
  79. },
  80. renderTracks : function () {
  81. var self = this, i = 1, tracklist = $( '<div class="wp-playlist-tracks"></div>' );
  82. this.tracks.each(function (model) {
  83. if ( ! self.data.images ) {
  84. model.set( 'image', false );
  85. }
  86. model.set( 'artists', self.data.artists );
  87. model.set( 'index', self.data.tracknumbers ? i : false );
  88. tracklist.append( self.itemTemplate( model.toJSON() ) );
  89. i += 1;
  90. });
  91. this.$el.append( tracklist );
  92. this.$( '.wp-playlist-item' ).eq(0).addClass( this.playingClass );
  93. },
  94. events : {
  95. 'click .wp-playlist-item' : 'clickTrack',
  96. 'click .wp-playlist-next' : 'next',
  97. 'click .wp-playlist-prev' : 'prev'
  98. },
  99. clickTrack : function (e) {
  100. e.preventDefault();
  101. this.index = this.$( '.wp-playlist-item' ).index( e.currentTarget );
  102. this.setCurrent();
  103. },
  104. ended : function () {
  105. if ( this.index + 1 < this.tracks.length ) {
  106. this.next();
  107. } else {
  108. this.index = 0;
  109. this.setCurrent();
  110. }
  111. },
  112. next : function () {
  113. this.index = this.index + 1 >= this.tracks.length ? 0 : this.index + 1;
  114. this.setCurrent();
  115. },
  116. prev : function () {
  117. this.index = this.index - 1 < 0 ? this.tracks.length - 1 : this.index - 1;
  118. this.setCurrent();
  119. },
  120. loadCurrent : function () {
  121. var last = this.playerNode.attr( 'src' ) && this.playerNode.attr( 'src' ).split('.').pop(),
  122. current = this.current.get( 'src' ).split('.').pop();
  123. this.mejs && this.mejs.pause();
  124. if ( last !== current ) {
  125. this.setPlayer( true );
  126. } else {
  127. this.playerNode.attr( 'src', this.current.get( 'src' ) );
  128. this.playCurrentSrc();
  129. }
  130. },
  131. setCurrent : function () {
  132. this.current = this.tracks.at( this.index );
  133. if ( this.data.tracklist ) {
  134. this.$( '.wp-playlist-item' )
  135. .removeClass( this.playingClass )
  136. .eq( this.index )
  137. .addClass( this.playingClass );
  138. }
  139. this.loadCurrent();
  140. }
  141. });
  142. /**
  143. * Initialize media playlists in the document.
  144. *
  145. * Only initializes new playlists not previously-initialized.
  146. *
  147. * @since 4.9.3
  148. * @returns {void}
  149. */
  150. function initialize() {
  151. $( '.wp-playlist:not(:has(.mejs-container))' ).each( function() {
  152. new WPPlaylistView( { el: this } );
  153. } );
  154. }
  155. /**
  156. * Expose the API publicly on window.wp.playlist.
  157. *
  158. * @namespace wp.playlist
  159. * @since 4.9.3
  160. * @type {object}
  161. */
  162. window.wp.playlist = {
  163. initialize: initialize
  164. };
  165. $( document ).ready( initialize );
  166. window.WPPlaylistView = WPPlaylistView;
  167. }(jQuery, _, Backbone));