wp-playlist.js 5.0 KB

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