Refinements for asynchronous rendering in `wp.mce.media.PlaylistView`:

* Add `visibility: hidden` as an inline style to `<audio>` tags, there is a race with the stylesheet which can get enqueued in the body and loaded in the footer.
* When creating new instances of `MediaElementPlayer`, always push them onto a stack. Lone views can be responsible for multiple instances of the same shortcode on render.
* Rename `wp.media.mixin.unsetPlayer()` to `wp.media.mixin.unsetPlayers()` to reflect the above.
* Call `wp.media.mixin.unsetPlayers()` on the view's `unbind()` method, instead of inline in the `render()` method
* Make sure `WPPlaylistView` is instantiated for each editor instance
* Ensure that the `No Items Found` view state is not rendered when attachments actually do exist.

Props gcorne, wonderboymusic.
See #27899.



Built from https://develop.svn.wordpress.org/trunk@28182


git-svn-id: http://core.svn.wordpress.org/trunk@28013 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Scott Taylor 2014-04-22 17:53:16 +00:00
parent a6eedd18b2
commit 55becc0dfd
6 changed files with 41 additions and 58 deletions

View File

@ -451,10 +451,6 @@ window.wp = window.wp || {};
firefox = this.ua.is( 'ff' ),
className = '.wp-' + this.shortcode.tag + '-shortcode';
if ( this.player ) {
this.unsetPlayer();
}
media = $( node ).find( className );
if ( ! this.isCompatible( media ) ) {
@ -495,12 +491,7 @@ window.wp = window.wp || {};
},
unbind: function() {
var self = this;
this.pauseAllPlayers();
_.each( this.players, function (player) {
self.removePlayer( player );
} );
this.players = [];
this.unsetPlayers();
}
});
_.extend( wp.mce.media.View.prototype, wp.media.mixin );
@ -547,22 +538,10 @@ window.wp = window.wp || {};
template: media.template('editor-playlist'),
initialize: function( options ) {
this.players = [];
this.data = {};
this.attachments = [];
this.shortcode = options.shortcode;
_.bindAll( this, 'setPlayer' );
$(this).on('ready', this.setNode);
},
/**
* Set the element context for the view, and then fetch the playlist's
* associated attachments.
*
* @param {Event} e
* @param {HTMLElement} node
*/
setNode: function(e, node) {
this.node = node;
this.fetch();
},
@ -571,7 +550,7 @@ window.wp = window.wp || {};
*/
fetch: function() {
this.attachments = wp.media.playlist.attachments( this.shortcode );
this.attachments.more().done( this.setPlayer );
this.dfd = this.attachments.more().done( _.bind( this.render, this ) );
},
/**
@ -582,36 +561,31 @@ window.wp = window.wp || {};
* @global WPPlaylistView
* @global tinymce.editors
*/
setPlayer: function() {
var p,
html = this.getHtml(),
t = this.encodedText,
self = this;
this.unsetPlayer();
render: function() {
var html = this.getHtml(), self = this;
_.each( tinymce.editors, function( editor ) {
var doc;
if ( editor.plugins.wpview ) {
doc = editor.getDoc();
$( doc ).find( '[data-wpview-text="' + t + '"]' ).each(function(i, elem) {
$( doc ).find( '[data-wpview-text="' + this.encodedText + '"]' ).each(function (i, elem) {
var node = $( elem );
node.html( html );
self.node = elem;
// The <ins> is used to mark the end of the wrapper div. Needed when comparing
// the content as string for preventing extra undo levels.
node.html( html ).append( '<ins data-wpview-end="1"></ins>' );
if ( ! self.data.tracks ) {
return;
}
self.players.push( new WPPlaylistView({
el: $( elem ).find( '.wp-playlist' ).get(0),
metadata: self.data
}).player );
});
}
}, this );
if ( ! this.data.tracks ) {
return;
}
p = new WPPlaylistView({
el: $( self.node ).find( '.wp-playlist' ).get(0),
metadata: this.data
});
this.player = p.player;
},
/**
@ -695,6 +669,10 @@ window.wp = window.wp || {};
this.data = options;
return this.template( options );
},
unbind: function() {
this.unsetPlayers();
}
});
_.extend( wp.mce.media.PlaylistView.prototype, wp.media.mixin );

File diff suppressed because one or more lines are too long

View File

@ -162,11 +162,13 @@
*
* Examples: modal closes, shortcode properties are removed, etc.
*/
unsetPlayer : function() {
if ( this.player ) {
unsetPlayers : function() {
if ( this.players && this.players.length ) {
wp.media.mixin.pauseAllPlayers();
wp.media.mixin.removePlayer( this.player );
this.player = false;
_.each( this.players, function (player) {
wp.media.mixin.removePlayer( player );
} );
this.players = [];
}
}
};
@ -705,10 +707,10 @@
media.view.MediaDetails = media.view.Settings.AttachmentDisplay.extend({
initialize: function() {
_.bindAll(this, 'success');
this.listenTo( this.controller, 'close', media.mixin.unsetPlayer );
this.players = [];
this.listenTo( this.controller, 'close', media.mixin.unsetPlayers );
this.on( 'ready', this.setPlayer );
this.on( 'media:setting:remove', media.mixin.unsetPlayer, this );
this.on( 'media:setting:remove', media.mixin.unsetPlayers, this );
this.on( 'media:setting:remove', this.render );
this.on( 'media:setting:remove', this.setPlayer );
this.events = _.extend( this.events, {
@ -764,8 +766,8 @@
* @global MediaElementPlayer
*/
setPlayer : function() {
if ( ! this.player && this.media ) {
this.player = new MediaElementPlayer( this.media, this.settings );
if ( ! this.players.length && this.media ) {
this.players.push( new MediaElementPlayer( this.media, this.settings ) );
}
},

File diff suppressed because one or more lines are too long

View File

@ -16,7 +16,8 @@
function wp_underscore_audio_template() {
$audio_types = wp_get_audio_extensions();
?>
<audio controls
<audio style="visibility: hidden"
controls
class="wp-audio-shortcode"
width="{{ _.isUndefined( data.model.width ) ? 400 : data.model.width }}"
preload="{{ _.isUndefined( data.model.preload ) ? 'none' : data.model.preload }}"

View File

@ -1353,6 +1353,8 @@ function wp_playlist_shortcode( $attr ) {
echo (int) $theme_width;
?>"<?php if ( 'video' === $safe_type ):
echo ' height="', (int) $theme_height, '"';
else:
echo ' style="visibility: hidden"';
endif; ?>></<?php echo $safe_type ?>>
<div class="wp-playlist-next"></div>
<div class="wp-playlist-prev"></div>
@ -1555,7 +1557,7 @@ function wp_audio_shortcode( $attr, $content = '' ) {
'loop' => $loop,
'autoplay' => $autoplay,
'preload' => $preload,
'style' => 'width: 100%',
'style' => 'width: 100%; visibility: hidden;',
);
// These ones should just be omitted altogether if they are blank