200 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			200 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | /* global _wpmejsSettings, MediaElementPlayer */ | ||
|  | 
 | ||
|  | (function ($, _, Backbone) { | ||
|  | 	'use strict'; | ||
|  | 
 | ||
|  | 	/** @namespace wp */ | ||
|  | 	window.wp = window.wp || {}; | ||
|  | 
 | ||
|  | 	var WPPlaylistView = Backbone.View.extend({ | ||
|  | 		initialize : function (options) { | ||
|  | 			this.index = 0; | ||
|  | 			this.settings = {}; | ||
|  | 			this.data = options.metadata || $.parseJSON( this.$('script.wp-playlist-script').html() ); | ||
|  | 			this.playerNode = this.$( this.data.type ); | ||
|  | 
 | ||
|  | 			this.tracks = new Backbone.Collection( this.data.tracks ); | ||
|  | 			this.current = this.tracks.first(); | ||
|  | 
 | ||
|  | 			if ( 'audio' === this.data.type ) { | ||
|  | 				this.currentTemplate = wp.template( 'wp-playlist-current-item' ); | ||
|  | 				this.currentNode = this.$( '.wp-playlist-current-item' ); | ||
|  | 			} | ||
|  | 
 | ||
|  | 			this.renderCurrent(); | ||
|  | 
 | ||
|  | 			if ( this.data.tracklist ) { | ||
|  | 				this.itemTemplate = wp.template( 'wp-playlist-item' ); | ||
|  | 				this.playingClass = 'wp-playlist-playing'; | ||
|  | 				this.renderTracks(); | ||
|  | 			} | ||
|  | 
 | ||
|  | 			this.playerNode.attr( 'src', this.current.get( 'src' ) ); | ||
|  | 
 | ||
|  | 			_.bindAll( this, 'bindPlayer', 'bindResetPlayer', 'setPlayer', 'ended', 'clickTrack' ); | ||
|  | 
 | ||
|  | 			if ( ! _.isUndefined( window._wpmejsSettings ) ) { | ||
|  | 				this.settings = _.clone( _wpmejsSettings ); | ||
|  | 			} | ||
|  | 			this.settings.success = this.bindPlayer; | ||
|  | 			this.setPlayer(); | ||
|  | 		}, | ||
|  | 
 | ||
|  | 		bindPlayer : function (mejs) { | ||
|  | 			this.mejs = mejs; | ||
|  | 			this.mejs.addEventListener( 'ended', this.ended ); | ||
|  | 		}, | ||
|  | 
 | ||
|  | 		bindResetPlayer : function (mejs) { | ||
|  | 			this.bindPlayer( mejs ); | ||
|  | 			this.playCurrentSrc(); | ||
|  | 		}, | ||
|  | 
 | ||
|  | 		setPlayer: function (force) { | ||
|  | 			if ( this.player ) { | ||
|  | 				this.player.pause(); | ||
|  | 				this.player.remove(); | ||
|  | 				this.playerNode = this.$( this.data.type ); | ||
|  | 			} | ||
|  | 
 | ||
|  | 			if (force) { | ||
|  | 				this.playerNode.attr( 'src', this.current.get( 'src' ) ); | ||
|  | 				this.settings.success = this.bindResetPlayer; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			/** | ||
|  | 			 * This is also our bridge to the outside world | ||
|  | 			 */ | ||
|  | 			this.player = new MediaElementPlayer( this.playerNode.get(0), this.settings ); | ||
|  | 		}, | ||
|  | 
 | ||
|  | 		playCurrentSrc : function () { | ||
|  | 			this.renderCurrent(); | ||
|  | 			this.mejs.setSrc( this.playerNode.attr( 'src' ) ); | ||
|  | 			this.mejs.load(); | ||
|  | 			this.mejs.play(); | ||
|  | 		}, | ||
|  | 
 | ||
|  | 		renderCurrent : function () { | ||
|  | 			var dimensions, defaultImage = 'wp-includes/images/media/video.png'; | ||
|  | 			if ( 'video' === this.data.type ) { | ||
|  | 				if ( this.data.images && this.current.get( 'image' ) && -1 === this.current.get( 'image' ).src.indexOf( defaultImage ) ) { | ||
|  | 					this.playerNode.attr( 'poster', this.current.get( 'image' ).src ); | ||
|  | 				} | ||
|  | 				dimensions = this.current.get( 'dimensions' ).resized; | ||
|  | 				this.playerNode.attr( dimensions ); | ||
|  | 			} else { | ||
|  | 				if ( ! this.data.images ) { | ||
|  | 					this.current.set( 'image', false ); | ||
|  | 				} | ||
|  | 				this.currentNode.html( this.currentTemplate( this.current.toJSON() ) ); | ||
|  | 			} | ||
|  | 		}, | ||
|  | 
 | ||
|  | 		renderTracks : function () { | ||
|  | 			var self = this, i = 1, tracklist = $( '<div class="wp-playlist-tracks"></div>' ); | ||
|  | 			this.tracks.each(function (model) { | ||
|  | 				if ( ! self.data.images ) { | ||
|  | 					model.set( 'image', false ); | ||
|  | 				} | ||
|  | 				model.set( 'artists', self.data.artists ); | ||
|  | 				model.set( 'index', self.data.tracknumbers ? i : false ); | ||
|  | 				tracklist.append( self.itemTemplate( model.toJSON() ) ); | ||
|  | 				i += 1; | ||
|  | 			}); | ||
|  | 			this.$el.append( tracklist ); | ||
|  | 
 | ||
|  | 			this.$( '.wp-playlist-item' ).eq(0).addClass( this.playingClass ); | ||
|  | 		}, | ||
|  | 
 | ||
|  | 		events : { | ||
|  | 			'click .wp-playlist-item' : 'clickTrack', | ||
|  | 			'click .wp-playlist-next' : 'next', | ||
|  | 			'click .wp-playlist-prev' : 'prev' | ||
|  | 		}, | ||
|  | 
 | ||
|  | 		clickTrack : function (e) { | ||
|  | 			e.preventDefault(); | ||
|  | 
 | ||
|  | 			this.index = this.$( '.wp-playlist-item' ).index( e.currentTarget ); | ||
|  | 			this.setCurrent(); | ||
|  | 		}, | ||
|  | 
 | ||
|  | 		ended : function () { | ||
|  | 			if ( this.index + 1 < this.tracks.length ) { | ||
|  | 				this.next(); | ||
|  | 			} else { | ||
|  | 				this.index = 0; | ||
|  | 				this.setCurrent(); | ||
|  | 			} | ||
|  | 		}, | ||
|  | 
 | ||
|  | 		next : function () { | ||
|  | 			this.index = this.index + 1 >= this.tracks.length ? 0 : this.index + 1; | ||
|  | 			this.setCurrent(); | ||
|  | 		}, | ||
|  | 
 | ||
|  | 		prev : function () { | ||
|  | 			this.index = this.index - 1 < 0 ? this.tracks.length - 1 : this.index - 1; | ||
|  | 			this.setCurrent(); | ||
|  | 		}, | ||
|  | 
 | ||
|  | 		loadCurrent : function () { | ||
|  | 			var last = this.playerNode.attr( 'src' ) && this.playerNode.attr( 'src' ).split('.').pop(), | ||
|  | 				current = this.current.get( 'src' ).split('.').pop(); | ||
|  | 
 | ||
|  | 			this.mejs && this.mejs.pause(); | ||
|  | 
 | ||
|  | 			if ( last !== current ) { | ||
|  | 				this.setPlayer( true ); | ||
|  | 			} else { | ||
|  | 				this.playerNode.attr( 'src', this.current.get( 'src' ) ); | ||
|  | 				this.playCurrentSrc(); | ||
|  | 			} | ||
|  | 		}, | ||
|  | 
 | ||
|  | 		setCurrent : function () { | ||
|  | 			this.current = this.tracks.at( this.index ); | ||
|  | 
 | ||
|  | 			if ( this.data.tracklist ) { | ||
|  | 				this.$( '.wp-playlist-item' ) | ||
|  | 					.removeClass( this.playingClass ) | ||
|  | 					.eq( this.index ) | ||
|  | 						.addClass( this.playingClass ); | ||
|  | 			} | ||
|  | 
 | ||
|  | 			this.loadCurrent(); | ||
|  | 		} | ||
|  | 	}); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Initialize media playlists in the document. | ||
|  | 	 * | ||
|  | 	 * Only initializes new playlists not previously-initialized. | ||
|  | 	 * | ||
|  | 	 * @since 4.9.3 | ||
|  | 	 * @returns {void} | ||
|  | 	 */ | ||
|  | 	function initialize() { | ||
|  | 		$( '.wp-playlist:not(:has(.mejs-container))' ).each( function() { | ||
|  | 			new WPPlaylistView( { el: this } ); | ||
|  | 		} ); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Expose the API publicly on window.wp.playlist. | ||
|  | 	 * | ||
|  | 	 * @namespace wp.playlist | ||
|  | 	 * @since 4.9.3 | ||
|  | 	 * @type {object} | ||
|  | 	 */ | ||
|  | 	window.wp.playlist = { | ||
|  | 		initialize: initialize | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	$( document ).ready( initialize ); | ||
|  | 
 | ||
|  | 	window.WPPlaylistView = WPPlaylistView; | ||
|  | 
 | ||
|  | }(jQuery, _, Backbone)); |