WordPress.org

Make WordPress Core

Changeset 29179


Ignore:
Timestamp:
07/15/14 22:17:58 (3 years ago)
Author:
wonderboymusic
Message:

Simplify creation of audio, video, and playlist MCE views by placing them in iframe sandboxes.

Wins:

  • Eliminates duplication of code between PHP and JS
  • Views can load JS without messing with TinyMCE and scope
  • MEjs doesn't break when it loads a file plugin-mode. This allows any file type the MEjs supports to play in MCE views.
  • YouTube now works as the source for video.
  • Users can still style the views, editor stylesheets are included in these sandboxes.
  • Audio and Video URLs and [embed]s are no longer broken.
  • Remove the crazy compat code necessary to determine what file types play in what browser.
  • Remove unneeded Underscore templates.
  • Remove the compat code for playlists.

See #28905.

Location:
trunk/src/wp-includes
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/js/mce-view.js

    r29019 r29179  
    105105            }, this ); 
    106106        }, 
     107 
     108        /* jshint scripturl: true */ 
     109        createIframe: function ( content ) { 
     110            var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver, 
     111                iframe, iframeDoc, i, resize, 
     112                dom = tinymce.DOM; 
     113 
     114            if ( content.indexOf( '<script' ) !== -1 ) { 
     115                iframe = dom.create( 'iframe', { 
     116                    src: tinymce.Env.ie ? 'javascript:""' : '', 
     117                    frameBorder: '0', 
     118                    allowTransparency: 'true', 
     119                    scrolling: 'no', 
     120                    style: { 
     121                        width: '100%', 
     122                        display: 'block' 
     123                    } 
     124                } ); 
     125 
     126                this.setContent( iframe ); 
     127                iframeDoc = iframe.contentWindow.document; 
     128 
     129                iframeDoc.open(); 
     130                iframeDoc.write( 
     131                    '<!DOCTYPE html>' + 
     132                    '<html>' + 
     133                        '<head>' + 
     134                            '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />' + 
     135                        '</head>' + 
     136                        '<body style="padding: 0; margin: 0;" class="' + dom.doc.body.className + '">' + 
     137                            content + 
     138                        '</body>' + 
     139                    '</html>' 
     140                ); 
     141                iframeDoc.close(); 
     142 
     143                resize = function() { 
     144                    $( iframe ).height( $( iframeDoc.body ).height() ); 
     145                }; 
     146 
     147                if ( MutationObserver ) { 
     148                    new MutationObserver( _.debounce( function() { 
     149                        resize(); 
     150                    }, 100 ) ) 
     151                    .observe( iframeDoc.body, { 
     152                        attributes: true, 
     153                        childList: true, 
     154                        subtree: true 
     155                    } ); 
     156                } else { 
     157                    for ( i = 1; i < 6; i++ ) { 
     158                        setTimeout( resize, i * 700 ); 
     159                    } 
     160                } 
     161            } else { 
     162                this.setContent( content ); 
     163            } 
     164        }, 
     165 
    107166        setError: function( message, dashicon ) { 
    108167            this.setContent( 
     
    422481        loaded: false, 
    423482 
    424         View: _.extend( {}, wp.media.mixin, { 
     483        View: { 
    425484            overlay: true, 
    426485 
     486            action: 'parse-media-shortcode', 
     487 
    427488            initialize: function( options ) { 
    428                 this.players = []; 
    429489                this.shortcode = options.shortcode; 
    430                 _.bindAll( this, 'setPlayer', 'pausePlayers' ); 
    431                 $( this ).on( 'ready', this.setPlayer ); 
    432                 $( this ).on( 'ready', function( event, editor ) { 
    433                     editor.on( 'hide', this.pausePlayers ); 
     490                this.fetching = false; 
     491 
     492                _.bindAll( this, 'createIframe', 'setNode', 'fetch' ); 
     493                $( this ).on( 'ready', this.setNode ); 
     494            }, 
     495 
     496            setNode: function () { 
     497                if ( this.parsed ) { 
     498                    this.createIframe( this.parsed ); 
     499                } else if ( ! this.fetching ) { 
     500                    this.fetch(); 
     501                } 
     502            }, 
     503 
     504            fetch: function () { 
     505                var self = this; 
     506                this.fetching = true; 
     507 
     508                wp.ajax.send( this.action, { 
     509                    data: { 
     510                        post_ID: $( '#post_ID' ).val() || 0, 
     511                        type: this.shortcode.tag, 
     512                        shortcode: this.shortcode.string() 
     513                    } 
     514                } ) 
     515                .always( function() { 
     516                    self.fetching = false; 
     517                } ) 
     518                .done( function( response ) { 
     519                    if ( response ) { 
     520                        self.parsed = response; 
     521                        self.createIframe( response ); 
     522                    } 
     523                } ) 
     524                .fail( function( response ) { 
     525                    if ( response && response.message ) { 
     526                        if ( ( response.type === 'not-embeddable' && self.type === 'embed' ) || 
     527                            response.type === 'not-ssl' ) { 
     528 
     529                            self.setError( response.message, 'admin-media' ); 
     530                        } else { 
     531                            self.setContent( '<p>' + self.original + '</p>', null, 'replace' ); 
     532                        } 
     533                    } else if ( response && response.statusText ) { 
     534                        self.setError( response.statusText, 'admin-media' ); 
     535                    } 
    434536                } ); 
    435                 $( document ).on( 'media:edit', this.pausePlayers ); 
    436             }, 
    437  
    438             /** 
    439              * Creates the player instance for the current node 
    440              * 
    441              * @global MediaElementPlayer 
    442              * 
    443              * @param {Event} event 
    444              * @param {Object} editor 
    445              * @param {HTMLElement} node 
    446              */ 
    447             setPlayer: function( event, editor, node ) { 
    448                 var self = this, 
    449                     media; 
    450  
    451                 media = $( node ).find( '.wp-' +  this.shortcode.tag + '-shortcode' ); 
    452  
    453                 if ( ! this.isCompatible( media ) ) { 
    454                     media.closest( '.wpview-wrap' ).addClass( 'wont-play' ); 
    455                     media.replaceWith( '<p>' + media.find( 'source' ).eq(0).prop( 'src' ) + '</p>' ); 
    456                     return; 
    457                 } else { 
    458                     media.closest( '.wpview-wrap' ).removeClass( 'wont-play' ); 
    459                     if ( this.ua.is( 'ff' ) ) { 
    460                         media.prop( 'preload', 'metadata' ); 
    461                     } else { 
    462                         media.prop( 'preload', 'none' ); 
    463                     } 
    464                 } 
    465  
    466                 media = wp.media.view.MediaDetails.prepareSrc( media.get(0) ); 
    467  
    468                 setTimeout( function() { 
    469                     wp.mce.av.loaded = true; 
    470                     self.players.push( new MediaElementPlayer( media, self.mejsSettings ) ); 
    471                 }, wp.mce.av.loaded ? 10 : 500 ); 
    472537            }, 
    473538 
     
    478543             */ 
    479544            getHtml: function() { 
    480                 var attrs = this.shortcode.attrs.named; 
    481                 attrs.content = this.shortcode.content; 
    482  
    483                 return this.template({ model: _.defaults( 
    484                     attrs, 
    485                     wp.media[ this.shortcode.tag ].defaults ) 
    486                 }); 
    487             }, 
    488  
    489             unbind: function() { 
    490                 this.unsetPlayers(); 
    491             } 
    492         } ), 
     545                if ( ! this.parsed ) { 
     546                    return ''; 
     547                } 
     548                return this.parsed; 
     549            } 
     550        }, 
    493551 
    494552        /** 
     
    538596     */ 
    539597    wp.mce.views.register( 'video', _.extend( {}, wp.mce.av, { 
    540         state: 'video-details', 
    541         View: _.extend( {}, wp.mce.av.View, { 
    542             template: media.template( 'editor-video' ) 
    543         } ) 
     598        state: 'video-details' 
    544599    } ) ); 
    545600 
     
    550605     */ 
    551606    wp.mce.views.register( 'audio', _.extend( {}, wp.mce.av, { 
    552         state: 'audio-details', 
    553         View: _.extend( {}, wp.mce.av.View, { 
    554             template: media.template( 'editor-audio' ) 
    555         } ) 
     607        state: 'audio-details' 
    556608    } ) ); 
    557609 
     
    562614     */ 
    563615    wp.mce.views.register( 'playlist', _.extend( {}, wp.mce.av, { 
    564         state: ['playlist-edit', 'video-playlist-edit'], 
    565         View: _.extend( {}, wp.media.mixin, { 
    566             template:  media.template( 'editor-playlist' ), 
    567             overlay: true, 
    568  
    569             initialize: function( options ) { 
    570                 this.players = []; 
    571                 this.data = {}; 
    572                 this.attachments = []; 
    573                 this.shortcode = options.shortcode; 
    574  
    575                 $( this ).on( 'ready', function( event, editor ) { 
    576                     editor.on( 'hide', this.pausePlayers ); 
    577                 } ); 
    578                 $( document ).on( 'media:edit', this.pausePlayers ); 
    579  
    580                 this.fetch(); 
    581  
    582                 $( this ).on( 'ready', this.setPlaylist ); 
    583             }, 
    584  
    585             /** 
    586              * Asynchronously fetch the shortcode's attachments 
    587              */ 
    588             fetch: function() { 
    589                 this.attachments = wp.media.playlist.attachments( this.shortcode ); 
    590                 this.dfd = this.attachments.more().done( _.bind( this.render, this ) ); 
    591             }, 
    592  
    593             setPlaylist: function( event, editor, element ) { 
    594                 if ( ! this.data.tracks ) { 
    595                     return; 
    596                 } 
    597  
    598                 this.players.push( new WPPlaylistView( { 
    599                     el: $( element ).find( '.wp-playlist' ).get( 0 ), 
    600                     metadata: this.data 
    601                 } ).player ); 
    602             }, 
    603  
    604             /** 
    605              * Set the data that will be used to compile the Underscore template, 
    606              *  compile the template, and then return it. 
    607              * 
    608              * @returns {string} 
    609              */ 
    610             getHtml: function() { 
    611                 var data = this.shortcode.attrs.named, 
    612                     model = wp.media.playlist, 
    613                     options, 
    614                     attachments, 
    615                     tracks = []; 
    616  
    617                 // Don't render errors while still fetching attachments 
    618                 if ( this.dfd && 'pending' === this.dfd.state() && ! this.attachments.length ) { 
    619                     return ''; 
    620                 } 
    621  
    622                 _.each( model.defaults, function( value, key ) { 
    623                     data[ key ] = model.coerce( data, key ); 
    624                 }); 
    625  
    626                 options = { 
    627                     type: data.type, 
    628                     style: data.style, 
    629                     tracklist: data.tracklist, 
    630                     tracknumbers: data.tracknumbers, 
    631                     images: data.images, 
    632                     artists: data.artists 
    633                 }; 
    634  
    635                 if ( ! this.attachments.length ) { 
    636                     return this.template( options ); 
    637                 } 
    638  
    639                 attachments = this.attachments.toJSON(); 
    640  
    641                 _.each( attachments, function( attachment ) { 
    642                     var size = {}, resize = {}, track = { 
    643                         src : attachment.url, 
    644                         type : attachment.mime, 
    645                         title : attachment.title, 
    646                         caption : attachment.caption, 
    647                         description : attachment.description, 
    648                         meta : attachment.meta 
    649                     }; 
    650  
    651                     if ( 'video' === data.type ) { 
    652                         size.width = attachment.width; 
    653                         size.height = attachment.height; 
    654                         if ( media.view.settings.contentWidth ) { 
    655                             resize.width = media.view.settings.contentWidth - 22; 
    656                             resize.height = Math.ceil( ( size.height * resize.width ) / size.width ); 
    657                             if ( ! options.width ) { 
    658                                 options.width = resize.width; 
    659                                 options.height = resize.height; 
    660                             } 
    661                         } else { 
    662                             if ( ! options.width ) { 
    663                                 options.width = attachment.width; 
    664                                 options.height = attachment.height; 
    665                             } 
    666                         } 
    667                         track.dimensions = { 
    668                             original : size, 
    669                             resized : _.isEmpty( resize ) ? size : resize 
    670                         }; 
    671                     } else { 
    672                         options.width = 400; 
    673                     } 
    674  
    675                     track.image = attachment.image; 
    676                     track.thumb = attachment.thumb; 
    677  
    678                     tracks.push( track ); 
    679                 } ); 
    680  
    681                 options.tracks = tracks; 
    682                 this.data = options; 
    683  
    684                 return this.template( options ); 
    685             }, 
    686  
    687             unbind: function() { 
    688                 this.unsetPlayers(); 
    689             } 
    690         } ) 
     616        state: [ 'playlist-edit', 'video-playlist-edit' ] 
    691617    } ) ); 
    692618 
     
    694620     * TinyMCE handler for the embed shortcode 
    695621     */ 
    696     wp.mce.embedView = _.extend( {}, wp.media.mixin, { 
    697         overlay: true, 
    698         initialize: function( options ) { 
    699             this.players = []; 
    700             this.content = options.content; 
    701             this.fetching = false; 
    702             this.parsed = false; 
    703             this.original = options.url || options.shortcode.string(); 
    704  
    705             if ( options.url ) { 
    706                 this.shortcode = '[embed]' + options.url + '[/embed]'; 
    707             } else { 
    708                 this.shortcode = options.shortcode.string(); 
    709             } 
    710  
    711             _.bindAll( this, 'setHtml', 'setNode', 'fetch' ); 
    712             $( this ).on( 'ready', this.setNode ); 
    713         }, 
    714         unbind: function() { 
    715             var self = this; 
    716             _.each( this.players, function ( player ) { 
    717                 player.pause(); 
    718                 self.removePlayer( player ); 
    719             } ); 
    720             this.players = []; 
    721         }, 
    722         setNode: function () { 
    723             if ( this.parsed ) { 
    724                 this.setHtml( this.parsed ); 
    725                 this.parseMediaShortcodes(); 
    726             } else if ( ! this.fetching ) { 
    727                 this.fetch(); 
    728             } 
    729         }, 
    730         fetch: function () { 
    731             var self = this; 
    732  
    733             this.fetching = true; 
    734  
    735             wp.ajax.send( 'parse-embed', { 
    736                 data: { 
    737                     post_ID: $( '#post_ID' ).val() || 0, 
    738                     shortcode: this.shortcode 
    739                 } 
    740             } ) 
    741             .always( function() { 
    742                 self.fetching = false; 
    743             } ) 
    744             .done( function( response ) { 
    745                 if ( response ) { 
    746                     self.parsed = response; 
    747                     self.setHtml( response ); 
    748                 } 
    749             } ) 
    750             .fail( function( response ) { 
    751                 if ( response && response.message ) { 
    752                     if ( ( response.type === 'not-embeddable' && self.type === 'embed' ) || 
    753                         response.type === 'not-ssl' ) { 
    754  
    755                         self.setError( response.message, 'admin-media' ); 
    756                     } else { 
    757                         self.setContent( '<p>' + self.original + '</p>', null, 'replace' ); 
    758                     } 
    759                 } else if ( response && response.statusText ) { 
    760                     self.setError( response.statusText, 'admin-media' ); 
    761                 } 
    762             } ); 
    763         }, 
    764         /* jshint scripturl: true */ 
    765         setHtml: function ( content ) { 
    766             var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver, 
    767                 iframe, iframeDoc, i, resize, 
    768                 dom = tinymce.DOM; 
    769  
    770             if ( content.indexOf( '<script' ) !== -1 ) { 
    771                 iframe = dom.create( 'iframe', { 
    772                     src: tinymce.Env.ie ? 'javascript:""' : '', 
    773                     frameBorder: '0', 
    774                     allowTransparency: 'true', 
    775                     style: { 
    776                         width: '100%', 
    777                         display: 'block' 
    778                     } 
    779                 } ); 
    780  
    781                 this.setContent( iframe ); 
    782                 iframeDoc = iframe.contentWindow.document; 
    783  
    784                 iframeDoc.open(); 
    785                 iframeDoc.write( 
    786                     '<!DOCTYPE html>' + 
    787                     '<html>' + 
    788                         '<head>' + 
    789                             '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />' + 
    790                         '</head>' + 
    791                         '<body>' + 
    792                             content + 
    793                         '</body>' + 
    794                     '</html>' 
    795                 ); 
    796                 iframeDoc.close(); 
    797  
    798                 resize = function() { 
    799                     $( iframe ).height( $( iframeDoc ).height() ); 
    800                 }; 
    801  
    802                 if ( MutationObserver ) { 
    803                     new MutationObserver( _.debounce( function() { 
    804                         resize(); 
    805                     }, 100 ) ) 
    806                     .observe( iframeDoc.body, { 
    807                         attributes: true, 
    808                         childList: true, 
    809                         subtree: true 
     622    wp.mce.embedMixin = { 
     623        View: _.extend( {}, wp.mce.av.View, { 
     624            overlay: true, 
     625            action: 'parse-embed', 
     626            initialize: function( options ) { 
     627                this.content = options.content; 
     628                this.fetching = false; 
     629                this.parsed = false; 
     630                this.original = options.url || options.shortcode.string(); 
     631 
     632                if ( options.url ) { 
     633                    this.shortcode = media.embed.shortcode( { 
     634                        url: options.url 
    810635                    } ); 
    811636                } else { 
    812                     for ( i = 1; i < 6; i++ ) { 
    813                         setTimeout( resize, i * 700 ); 
    814                     } 
    815                 } 
    816             } else { 
    817                 this.setContent( content ); 
    818             } 
    819  
    820             this.parseMediaShortcodes(); 
    821         }, 
    822         parseMediaShortcodes: function () { 
    823             var self = this; 
    824             $( '.wp-audio-shortcode, .wp-video-shortcode', this.node ).each( function ( i, element ) { 
    825                 self.players.push( new MediaElementPlayer( element, self.mejsSettings ) ); 
    826             } ); 
    827         } 
    828     } ); 
    829  
    830     wp.mce.embedMixin = { 
    831         View: wp.mce.embedView, 
     637                    this.shortcode = options.shortcode; 
     638                } 
     639 
     640                _.bindAll( this, 'createIframe', 'setNode', 'fetch' ); 
     641                $( this ).on( 'ready', this.setNode ); 
     642            } 
     643        } ), 
    832644        edit: function( node ) { 
    833645            var embed = media.embed, 
  • trunk/src/wp-includes/js/media-audiovideo.js

    r29029 r29179  
    4545                player.pause(); 
    4646            } ); 
    47         }, 
    48  
    49         /** 
    50          * Utility to identify the user's browser 
    51          */ 
    52         ua: { 
    53             is : function( browser ) { 
    54                 var passes = false, ua = window.navigator.userAgent; 
    55  
    56                 switch ( browser ) { 
    57                     case 'oldie': 
    58                         passes = ua.match(/MSIE [6-8]/gi) !== null; 
    59                     break; 
    60                     case 'ie': 
    61                         passes = /MSIE /.test( ua ) || ( /Trident\//.test( ua ) && /rv:\d/.test( ua ) ); // IE11 
    62                     break; 
    63                     case 'ff': 
    64                         passes = ua.match(/firefox/gi) !== null; 
    65                     break; 
    66                     case 'opera': 
    67                         passes = ua.match(/OPR/) !== null; 
    68                     break; 
    69                     case 'safari': 
    70                         passes = ua.match(/safari/gi) !== null && ua.match(/chrome/gi) === null; 
    71                     break; 
    72                     case 'chrome': 
    73                         passes = ua.match(/safari/gi) !== null && ua.match(/chrome/gi) !== null; 
    74                     break; 
    75                 } 
    76  
    77                 return passes; 
    78             } 
    79         }, 
    80  
    81         /** 
    82          * Specify compatibility for native playback by browser 
    83          */ 
    84         compat :{ 
    85             'opera' : { 
    86                 audio: ['ogg', 'wav'], 
    87                 video: ['ogg', 'webm'] 
    88             }, 
    89             'chrome' : { 
    90                 audio: ['ogg', 'mpeg'], 
    91                 video: ['ogg', 'webm', 'mp4', 'm4v', 'mpeg'] 
    92             }, 
    93             'ff' : { 
    94                 audio: ['ogg', 'mpeg'], 
    95                 video: ['ogg', 'webm'] 
    96             }, 
    97             'safari' : { 
    98                 audio: ['mpeg', 'wav'], 
    99                 video: ['mp4', 'm4v', 'mpeg', 'x-ms-wmv', 'quicktime'] 
    100             }, 
    101             'ie' : { 
    102                 audio: ['mpeg'], 
    103                 video: ['mp4', 'm4v', 'mpeg'] 
    104             } 
    105         }, 
    106  
    107         /** 
    108          * Determine if the passed media contains a <source> that provides 
    109          *  native playback in the user's browser 
    110          * 
    111          * @param {jQuery} media 
    112          * @returns {Boolean} 
    113          */ 
    114         isCompatible: function( media ) { 
    115             if ( ! media.find( 'source' ).length ) { 
    116                 return false; 
    117             } 
    118  
    119             var ua = this.ua, test = false, found = false, sources; 
    120  
    121             if ( ua.is( 'oldIE' ) ) { 
    122                 return false; 
    123             } 
    124  
    125             sources = media.find( 'source' ); 
    126  
    127             _.find( this.compat, function( supports, browser ) { 
    128                 if ( ua.is( browser ) ) { 
    129                     found = true; 
    130                     _.each( sources, function( elem ) { 
    131                         var audio = new RegExp( 'audio\/(' + supports.audio.join('|') + ')', 'gi' ), 
    132                             video = new RegExp( 'video\/(' + supports.video.join('|') + ')', 'gi' ); 
    133  
    134                         if ( elem.type.match( video ) !== null || elem.type.match( audio ) !== null ) { 
    135                             test = true; 
    136                         } 
    137                     } ); 
    138                 } 
    139  
    140                 return test || found; 
    141             } ); 
    142  
    143             return test; 
    14447        }, 
    14548 
  • trunk/src/wp-includes/js/mediaelement/wp-mediaelement.css

    r28863 r29179  
    110110    font-size: 14px; 
    111111    line-height: 1.5; 
     112} 
     113 
     114.wp-admin .wp-playlist { 
     115    margin: 0 0 18px; 
    112116} 
    113117 
  • trunk/src/wp-includes/js/mediaelement/wp-playlist.js

    r28649 r29179  
    88            this.index = 0; 
    99            this.settings = {}; 
    10             this.compatMode = $( 'body' ).hasClass( 'wp-admin' ) && $( '#content_ifr' ).length; 
    1110            this.data = options.metadata || $.parseJSON( this.$('script').html() ); 
    1211            this.playerNode = this.$( this.data.type ); 
     
    2827            } 
    2928 
    30             if ( this.isCompatibleSrc() ) { 
    31                 this.playerNode.attr( 'src', this.current.get( 'src' ) ); 
    32             } 
     29            this.playerNode.attr( 'src', this.current.get( 'src' ) ); 
    3330 
    3431            _.bindAll( this, 'bindPlayer', 'bindResetPlayer', 'setPlayer', 'ended', 'clickTrack' ); 
     
    4845        bindResetPlayer : function (mejs) { 
    4946            this.bindPlayer( mejs ); 
    50             if ( this.isCompatibleSrc() ) { 
    51                 this.playCurrentSrc(); 
    52             } 
    53         }, 
    54  
    55         isCompatibleSrc: function () { 
    56             var testNode; 
    57  
    58             if ( this.compatMode ) { 
    59                 testNode = $( '<span><source type="' + this.current.get( 'type' ) + '" /></span>' ); 
    60  
    61                 if ( ! wp.media.mixin.isCompatible( testNode ) ) { 
    62                     this.playerNode.removeAttr( 'src' ); 
    63                     this.playerNode.removeAttr( 'poster' ); 
    64                     return; 
    65                 } 
    66             } 
    67  
    68             return true; 
     47            this.playCurrentSrc(); 
    6948        }, 
    7049 
     
    7756 
    7857            if (force) { 
    79                 if ( this.isCompatibleSrc() ) { 
    80                     this.playerNode.attr( 'src', this.current.get( 'src' ) ); 
    81                 } 
     58                this.playerNode.attr( 'src', this.current.get( 'src' ) ); 
    8259                this.settings.success = this.bindResetPlayer; 
    8360            } 
     
    189166 
    190167    $(document).ready(function () { 
    191         if ( ! $( 'body' ).hasClass( 'wp-admin' ) || $( 'body' ).hasClass( 'about-php' ) ) { 
    192             $('.wp-playlist').each(function () { 
    193                 return new WPPlaylistView({ el: this }); 
    194             }); 
    195         } 
     168        $('.wp-playlist').each( function() { 
     169            return new WPPlaylistView({ el: this }); 
     170        } ); 
    196171    }); 
    197172 
  • trunk/src/wp-includes/media-template.php

    r29133 r29179  
    12171217    </script> 
    12181218 
    1219     <script type="text/html" id="tmpl-editor-audio"> 
    1220         <?php wp_underscore_audio_template() ?> 
    1221     </script> 
    1222  
    1223     <script type="text/html" id="tmpl-editor-video"> 
    1224         <?php wp_underscore_video_template() ?> 
    1225     </script> 
    1226  
    1227     <?php wp_underscore_playlist_templates() ?> 
    1228  
    1229     <script type="text/html" id="tmpl-editor-playlist"> 
    1230         <# if ( data.tracks ) { #> 
    1231             <div class="wp-playlist wp-{{ data.type }}-playlist wp-playlist-{{ data.style }}"> 
    1232                 <# if ( 'audio' === data.type ){ #> 
    1233                 <div class="wp-playlist-current-item"></div> 
    1234                 <# } #> 
    1235                 <{{ data.type }} controls="controls" preload="none" <# 
    1236                     if ( data.width ) { #> width="{{ data.width }}"<# } 
    1237                     #><# if ( data.height ) { #> height="{{ data.height }}"<# } #>></{{ data.type }}> 
    1238                 <div class="wp-playlist-next"></div> 
    1239                 <div class="wp-playlist-prev"></div> 
    1240             </div> 
    1241         <# } else { #> 
    1242             <div class="wpview-error"> 
    1243                 <div class="dashicons dashicons-video-alt3"></div><p><?php _e( 'No items found.' ); ?></p> 
    1244             </div> 
    1245         <# } #> 
    1246     </script> 
    1247  
    12481219    <script type="text/html" id="tmpl-crop-content"> 
    12491220        <img class="crop-image" src="{{ data.url }}"> 
Note: See TracChangeset for help on using the changeset viewer.