Make WordPress Core

Changeset 27478


Ignore:
Timestamp:
03/09/2014 05:24:10 AM (11 years ago)
Author:
wonderboymusic
Message:

Audio/Video shortcodes in the media modal:

  • Make a generic model, wp.media.model.PostMedia, which replaces wp.media.model.PostAudio and wp.media.model.PostVideo
  • Make a generic library, wp.media.controller.MediaLibrary, which replaces wp.media.controller.ReplaceVideo and wp.media.controller.ReplaceAudio
  • wp.media.controller.MediaLibrary is used to create new states that want to load a library filtered by type, making it incredibly simple to add states to frames. See wp.media.view.MediaFrame.VideoDetails and wp.media.view.MediaFrame.AudioDetails.

UX changes:

  • Add the ability to manage HTML5 fallbacks - add additional <source>s or remove specific <source>s
  • In the Video Details state, add the ability to select a poster image

See #27016.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/js/media-models.js

    r27477 r27478  
    454454
    455455    /**
    456      * wp.media.model.PostAudio
     456     * wp.media.model.PostMedia
    457457     *
    458458     * @constructor
    459459     * @augments Backbone.Model
    460460     **/
    461     media.model.PostAudio = Backbone.Model.extend({
     461    media.model.PostMedia = Backbone.Model.extend({
    462462        initialize: function() {
    463463            this.attachment = false;
    464464        },
    465465
     466        setSource: function ( attachment ) {
     467            this.attachment = attachment;
     468            this.extension = attachment.get('filename' ).split('.').pop();
     469
     470            if ( _.contains( wp.media.view.settings.embedExts, this.extension ) ) {
     471                this.set( this.extension, this.attachment.get( 'url' ) );
     472            } else {
     473                this.unset( this.extension );
     474            }
     475        },
     476
    466477        changeAttachment: function( attachment ) {
    467478            var self = this;
    468479
    469             this.attachment = attachment;
    470             this.extension = attachment.get('filename' ).split('.').pop();
    471 
    472             if ( _.contains( wp.media.view.settings.embedExts, this.extension ) ) {
    473                 this.set( this.extension, attachment.get( 'url' ) );
    474             } else {
    475                 this.unset( this.extension );
    476             }
    477 
    478             _.each( _.without( wp.media.view.settings.embedExts, this.extension ), function (ext) {
    479                 self.unset( ext );
    480             } );
    481         }
    482     });
    483 
    484     /**
    485      * wp.media.model.PostVideo
    486      *
    487      * @constructor
    488      * @augments Backbone.Model
    489      **/
    490     media.model.PostVideo = Backbone.Model.extend({
    491         initialize: function() {
    492             this.attachment = false;
    493         },
    494 
    495         changeAttachment: function( attachment ) {
    496             var self = this;
    497 
    498             this.attachment = attachment;
    499             this.extension = attachment.get('filename' ).split('.').pop();
    500 
    501             if ( _.contains( wp.media.view.settings.embedExts, this.extension ) ) {
    502                 this.set( this.extension, attachment.get( 'url' ) );
    503             } else {
    504                 this.unset( this.extension );
    505             }
     480            this.setSource( attachment );
    506481
    507482            _.each( _.without( wp.media.view.settings.embedExts, this.extension ), function (ext) {
  • trunk/src/wp-includes/js/media-views.js

    r27476 r27478  
    787787
    788788        initialize: function( options ) {
    789             this.audio = options.audio;
     789            this.media = options.media;
    790790            media.controller.State.prototype.initialize.apply( this, arguments );
    791791        }
     
    813813
    814814        initialize: function( options ) {
    815             this.video = options.video;
     815            this.media = options.media;
    816816            media.controller.State.prototype.initialize.apply( this, arguments );
    817817        }
     
    11841184
    11851185    /**
    1186      * wp.media.controller.ReplaceVideo
    1187      *
    1188      * Replace a selected single video
     1186     * wp.media.controller.MediaLibrary
    11891187     *
    11901188     * @constructor
     
    11931191     * @augments Backbone.Model
    11941192     */
    1195     media.controller.ReplaceVideo = media.controller.Library.extend({
     1193    media.controller.MediaLibrary = media.controller.Library.extend({
    11961194        defaults: _.defaults({
    1197             id:         'replace-video',
    11981195            filterable: 'uploaded',
    11991196            multiple:   false,
    1200             toolbar:    'replace',
    1201             title:      l10n.replaceVideoTitle,
    1202             priority:   60,
    1203             syncSelection: false
     1197            priority:   80,
     1198            syncSelection: false,
     1199            displaySettings: true
    12041200        }, media.controller.Library.prototype.defaults ),
    12051201
     
    12071203            var library, comparator;
    12081204
    1209             this.video = options.video;
    1210             // If we haven't been provided a `library`, create a `Selection`.
    1211             if ( ! this.get('library') ) {
    1212                 this.set( 'library', media.query({ type: 'video' }) );
    1213             }
     1205            this.media = options.media;
     1206            this.set( 'library', media.query({ type: options.type }) );
    12141207
    12151208            media.controller.Library.prototype.initialize.apply( this, arguments );
     
    12451238        updateSelection: function() {
    12461239            var selection = this.get('selection'),
    1247                 attachment = this.video.attachment;
    1248 
    1249             selection.reset( attachment ? [ attachment ] : [] );
    1250         }
    1251     });
    1252 
    1253     /**
    1254      * wp.media.controller.ReplaceAudio
    1255      *
    1256      * Replace a selected single audio file
    1257      *
    1258      * @constructor
    1259      * @augments wp.media.controller.Library
    1260      * @augments wp.media.controller.State
    1261      * @augments Backbone.Model
    1262      */
    1263     media.controller.ReplaceAudio = media.controller.Library.extend({
    1264         defaults: _.defaults({
    1265             id:         'replace-audio',
    1266             filterable: 'uploaded',
    1267             multiple:   false,
    1268             toolbar:    'replace',
    1269             title:      l10n.replaceAudioTitle,
    1270             priority:   60,
    1271             syncSelection: false
    1272         }, media.controller.Library.prototype.defaults ),
    1273 
    1274         initialize: function( options ) {
    1275             var library, comparator;
    1276 
    1277             this.audio = options.audio;
    1278             // If we haven't been provided a `library`, create a `Selection`.
    1279             if ( ! this.get('library') ) {
    1280                 this.set( 'library', media.query({ type: 'audio' }) );
    1281             }
    1282 
    1283             media.controller.Library.prototype.initialize.apply( this, arguments );
    1284 
    1285             library    = this.get('library');
    1286             comparator = library.comparator;
    1287 
    1288             // Overload the library's comparator to push items that are not in
    1289             // the mirrored query to the front of the aggregate collection.
    1290             library.comparator = function( a, b ) {
    1291                 var aInQuery = !! this.mirroring.get( a.cid ),
    1292                     bInQuery = !! this.mirroring.get( b.cid );
    1293 
    1294                 if ( ! aInQuery && bInQuery ) {
    1295                     return -1;
    1296                 } else if ( aInQuery && ! bInQuery ) {
    1297                     return 1;
    1298                 } else {
    1299                     return comparator.apply( this, arguments );
    1300                 }
    1301             };
    1302 
    1303             // Add all items in the selection to the library, so any featured
    1304             // images that are not initially loaded still appear.
    1305             library.observe( this.get('selection') );
    1306         },
    1307 
    1308         activate: function() {
    1309             this.updateSelection();
    1310             media.controller.Library.prototype.activate.apply( this, arguments );
    1311         },
    1312 
    1313         updateSelection: function() {
    1314             var selection = this.get('selection'),
    1315                 attachment = this.audio.attachment;
     1240                attachment;
     1241
     1242            attachment = this.media.attachment;
    13161243
    13171244            selection.reset( attachment ? [ attachment ] : [] );
     
    27952722
    27962723        initialize: function( options ) {
    2797             this.audio = new media.model.PostAudio( options.metadata );
    2798             this.options.selection = new media.model.Selection( this.audio.attachment, { multiple: false } );
     2724            this.media = new media.model.PostMedia( options.metadata );
     2725            this.options.selection = new media.model.Selection( this.media.attachment, { multiple: false } );
    27992726            media.view.MediaFrame.Select.prototype.initialize.apply( this, arguments );
    28002727        },
     
    28072734            this.on( 'toolbar:render:audio-details', this.renderAudioDetailsToolbar, this );
    28082735            // override the select toolbar
    2809             this.on( 'toolbar:render:replace', this.renderReplaceAudioToolbar, this );
     2736            this.on( 'toolbar:render:replace-audio', this.renderReplaceAudioToolbar, this );
     2737            this.on( 'toolbar:render:add-audio-source', this.renderAddAudioSourceToolbar, this );
    28102738        },
    28112739
    28122740        createStates: function() {
    28132741            this.states.add([
    2814                 new media.controller.AudioDetails({
    2815                     audio: this.audio,
     2742                new media.controller.AudioDetails( {
     2743                    media: this.media,
    28162744                    editable: false,
    28172745                    menu: 'audio-details'
    2818                 }),
    2819                 new media.controller.ReplaceAudio({
     2746                } ),
     2747
     2748                new media.controller.MediaLibrary( {
     2749                    type: 'audio',
    28202750                    id: 'replace-audio',
    2821                     library:   media.query( { type: 'audio' } ),
    2822                     audio: this.audio,
    2823                     multiple:  false,
    2824                     title:     l10n.audioReplaceTitle,
    2825                     menu: 'audio-details',
    2826                     toolbar: 'replace',
    2827                     priority:  80,
    2828                     displaySettings: true
    2829                 })
     2751                    title: l10n.audioReplaceTitle,
     2752                    toolbar: 'replace-audio',
     2753                    media: this.media,
     2754                    menu: 'audio-details'
     2755                } ),
     2756
     2757
     2758                new media.controller.MediaLibrary( {
     2759                    type: 'audio',
     2760                    id: 'add-audio-source',
     2761                    title: l10n.audioAddSourceTitle,
     2762                    toolbar: 'add-audio-source',
     2763                    media: this.media,
     2764                    menu: 'audio-details'
     2765                } )
    28302766            ]);
    28312767        },
     
    28342770            var view = new media.view.AudioDetails({
    28352771                controller: this,
    2836                 model: this.state().audio,
    2837                 attachment: this.state().audio.attachment
     2772                model: this.state().media,
     2773                attachment: this.state().media.attachment
    28382774            }).render();
    28392775
     
    28812817                            controller.close();
    28822818
    2883                             // not sure if we want to use wp.media.string.image which will create a shortcode or
    2884                             // perhaps wp.html.string to at least to build the <img />
    2885                             state.trigger( 'update', controller.audio.toJSON() );
     2819                            state.trigger( 'update', controller.media.toJSON() );
    28862820
    28872821                            // Restore and reset the default state.
     
    29092843                                attachment = selection.single();
    29102844
    2911                             controller.audio.changeAttachment( attachment, state.display( attachment ) );
     2845                            controller.media.changeAttachment( attachment, state.display( attachment ) );
    29122846
    29132847                            // not sure if we want to use wp.media.string.image which will create a shortcode or
    29142848                            // perhaps wp.html.string to at least to build the <img />
    2915                             state.trigger( 'replace', controller.audio.toJSON() );
     2849                            state.trigger( 'replace', controller.media.toJSON() );
     2850
     2851                            // Restore and reset the default state.
     2852                            controller.setState( controller.options.state );
     2853                            controller.reset();
     2854                        }
     2855                    }
     2856                }
     2857            }) );
     2858        },
     2859
     2860        renderAddAudioSourceToolbar: function() {
     2861            this.toolbar.set( new media.view.Toolbar({
     2862                controller: this,
     2863                items: {
     2864                    replace: {
     2865                        style:    'primary',
     2866                        text:     l10n.audioAddSourceTitle,
     2867                        priority: 80,
     2868
     2869                        click: function() {
     2870                            var controller = this.controller,
     2871                                state = controller.state(),
     2872                                selection = state.get( 'selection' ),
     2873                                attachment = selection.single();
     2874
     2875                            controller.media.setSource( attachment, state.display( attachment ) );
     2876
     2877                            state.trigger( 'add-source', controller.media.toJSON() );
    29162878
    29172879                            // Restore and reset the default state.
     
    29502912
    29512913        initialize: function( options ) {
    2952             this.video = new media.model.PostVideo( options.metadata );
    2953             this.options.selection = new media.model.Selection( this.video.attachment, { multiple: false } );
     2914            this.media = new media.model.PostMedia( options.metadata );
     2915            this.options.selection = new media.model.Selection( this.media.attachment, { multiple: false } );
    29542916            media.view.MediaFrame.Select.prototype.initialize.apply( this, arguments );
    29552917        },
     
    29622924            this.on( 'toolbar:render:video-details', this.renderVideoDetailsToolbar, this );
    29632925            // override the select toolbar
    2964             this.on( 'toolbar:render:replace', this.renderReplaceVideoToolbar, this );
     2926            this.on( 'toolbar:render:replace-video', this.renderReplaceVideoToolbar, this );
     2927            this.on( 'toolbar:render:add-video-source', this.renderAddVideoSourceToolbar, this );
     2928            this.on( 'toolbar:render:select-poster-image', this.renderSelectPosterImageToolbar, this );
    29652929        },
    29662930
     
    29682932            this.states.add([
    29692933                new media.controller.VideoDetails({
    2970                     video: this.video,
     2934                    media: this.media,
    29712935                    editable: false,
    29722936                    menu: 'video-details'
    29732937                }),
    2974                 new media.controller.ReplaceVideo({
     2938
     2939                new media.controller.MediaLibrary( {
     2940                    type: 'video',
    29752941                    id: 'replace-video',
    2976                     library:   media.query( { type: 'video' } ),
    2977                     video: this.video,
    2978                     multiple:  false,
    2979                     title:     l10n.videoReplaceTitle,
    2980                     menu: 'video-details',
    2981                     toolbar: 'replace',
    2982                     priority:  80,
    2983                     displaySettings: true
    2984                 })
     2942                    title: l10n.videoReplaceTitle,
     2943                    toolbar: 'replace-video',
     2944                    media: this.media,
     2945                    menu: 'video-details'
     2946                } ),
     2947
     2948                new media.controller.MediaLibrary( {
     2949                    type: 'video',
     2950                    id: 'add-video-source',
     2951                    title: l10n.videoAddSourceTitle,
     2952                    toolbar: 'add-video-source',
     2953                    media: this.media,
     2954                    menu: 'video-details'
     2955                } ),
     2956
     2957                new media.controller.MediaLibrary( {
     2958                    type: 'image',
     2959                    id: 'select-poster-image',
     2960                    title: l10n.videoSelectPosterImageTitle,
     2961                    toolbar: 'select-poster-image',
     2962                    media: this.media,
     2963                    menu: 'video-details'
     2964                } )
    29852965            ]);
    29862966        },
     
    29892969            var view = new media.view.VideoDetails({
    29902970                controller: this,
    2991                 model: this.state().video,
    2992                 attachment: this.state().video.attachment
     2971                model: this.state().media,
     2972                attachment: this.state().media.attachment
    29932973            }).render();
    29942974
     
    30383018                            // not sure if we want to use wp.media.string.image which will create a shortcode or
    30393019                            // perhaps wp.html.string to at least to build the <img />
    3040                             state.trigger( 'update', controller.video.toJSON() );
     3020                            state.trigger( 'update', controller.media.toJSON() );
    30413021
    30423022                            // Restore and reset the default state.
     
    30643044                                attachment = selection.single();
    30653045
    3066                             controller.video.changeAttachment( attachment, state.display( attachment ) );
    3067 
    3068                             state.trigger( 'replace', controller.video.toJSON() );
     3046                            controller.media.changeAttachment( attachment, state.display( attachment ) );
     3047
     3048                            state.trigger( 'replace', controller.media.toJSON() );
     3049
     3050                            // Restore and reset the default state.
     3051                            controller.setState( controller.options.state );
     3052                            controller.reset();
     3053                        }
     3054                    }
     3055                }
     3056            }) );
     3057        },
     3058
     3059        renderAddVideoSourceToolbar: function() {
     3060            this.toolbar.set( new media.view.Toolbar({
     3061                controller: this,
     3062                items: {
     3063                    replace: {
     3064                        style:    'primary',
     3065                        text:     l10n.videoAddSourceTitle,
     3066                        priority: 80,
     3067
     3068                        click: function() {
     3069                            var controller = this.controller,
     3070                                state = controller.state(),
     3071                                selection = state.get( 'selection' ),
     3072                                attachment = selection.single();
     3073
     3074                            controller.media.setSource( attachment, state.display( attachment ) );
     3075
     3076                            state.trigger( 'add-source', controller.media.toJSON() );
     3077
     3078                            // Restore and reset the default state.
     3079                            controller.setState( controller.options.state );
     3080                            controller.reset();
     3081                        }
     3082                    }
     3083                }
     3084            }) );
     3085        },
     3086
     3087        renderSelectPosterImageToolbar: function() {
     3088            this.toolbar.set( new media.view.Toolbar({
     3089                controller: this,
     3090                items: {
     3091                    replace: {
     3092                        style:    'primary',
     3093                        text:     l10n.videoSelectPosterImageTitle,
     3094                        priority: 80,
     3095
     3096                        click: function() {
     3097                            var controller = this.controller,
     3098                                state = controller.state(),
     3099                                selection = state.get( 'selection' ),
     3100                                attachment = selection.single();
     3101
     3102                            controller.media.set( 'poster', attachment.get( 'url' ) );
     3103
     3104                            state.trigger( 'set-poster-image', controller.media.toJSON() );
    30693105
    30703106                            // Restore and reset the default state.
     
    64166452    media.view.MediaDetails = media.view.Settings.AttachmentDisplay.extend({
    64176453        initialize: function() {
    6418             _.bindAll(this, 'success', 'close');
    6419 
    6420             this.listenTo( this.controller, 'close', this.close );
     6454            _.bindAll(this, 'success', 'unsetPlayer');
     6455
     6456            this.listenTo( this.controller, 'close', this.unsetPlayer );
    64216457            this.on( 'ready', this.setPlayer );
     6458            this.on( 'media:setting:remove', this.unsetPlayer );
     6459            this.on( 'media:setting:remove', this.render );
     6460            this.on( 'media:setting:remove', this.setPlayer );
     6461            this.events = _.extend( this.events, {
     6462                'click .remove-setting' : 'removeSetting'
     6463            } );
    64226464
    64236465            media.view.Settings.AttachmentDisplay.prototype.initialize.apply( this, arguments );
     
    64556497        },
    64566498
     6499        removeSetting : function (e) {
     6500            var setting = $( e.currentTarget ).parent();
     6501
     6502            this.model.unset( setting.find( 'input' ).data( 'setting' ) );
     6503
     6504            setting.remove();
     6505
     6506            this.trigger( 'media:setting:remove', this );
     6507        },
     6508
    64576509        setPlayer : function () {
    64586510            if ( ! this.player && this.media ) {
     
    64736525         *  its container and re-add it to the DOM.
    64746526         */
    6475         remove: function() {
     6527        removePlayer: function() {
    64766528            var t = this.player, featureIndex, feature;
    64776529
     
    65016553        },
    65026554
    6503         close : function() {
     6555        unsetPlayer : function() {
    65046556            if ( this.player ) {
    65056557                if ( _.isUndefined( this.mejs.pluginType ) ) {
    65066558                    this.mejs.pause();
    65076559                }
    6508                 this.remove();
     6560                this.removePlayer();
    65096561                this.player = false;
    65106562            }
     
    65616613
    65626614        setMedia: function() {
    6563             var audio = this.$('.wp-audio-shortcode').get(0);
    6564 
    6565             this.media = this.prepareSrc( audio );
     6615            var audio = this.$('.wp-audio-shortcode');
     6616
     6617            if ( audio.find( 'source' ).length ) {
     6618                if ( audio.is(':hidden') ) {
     6619                    audio.show();
     6620                }
     6621                this.media = this.prepareSrc( audio.get(0) );
     6622            } else {
     6623                audio.hide();
     6624                this.media = false;
     6625            }
    65666626
    65676627            return this;
     
    65876647            var video = this.$('.wp-video-shortcode');
    65886648
    6589             if ( ! video.hasClass('youtube-video') ) {
    6590                 video = this.prepareSrc( video.get(0) );
     6649            if ( video.find( 'source' ).length ) {
     6650                if ( video.is(':hidden') ) {
     6651                    video.show();
     6652                }
     6653
     6654                if ( ! video.hasClass('youtube-video') ) {
     6655                    this.media = this.prepareSrc( video.get(0) );
     6656                } else {
     6657                    this.media = video.get(0);
     6658                }
    65916659            } else {
    6592                 video = video.get(0);
    6593             }
    6594 
    6595             this.media = video;
     6660                video.hide();
     6661                this.media = false;
     6662            }
    65966663
    65976664            return this;
  • trunk/src/wp-includes/js/mediaelement/wp-mediaelement.css

    r27411 r27478  
    1515}
    1616
    17 .audio-details .wp-audio-shortcode {
     17.media-embed-details .wp-audio-shortcode {
    1818    display: inline-block;
    1919    max-width: 400px;
    2020}
    2121
    22 .video-details .embed-video-settings,
    23 .audio-details .embed-audio-settings {
    24     top: 10px;
     22.media-embed-details .embed-media-settings {
     23    padding-top: 0;
    2524}
    2625
    27 .video-details .embed-video-settings .checkbox-setting,
    28 .audio-details .embed-audio-settings .checkbox-setting {
     26.media-embed-details .instructions {
     27    padding: 16px;
     28    max-width: 600px;
     29}
     30
     31.media-embed-details .setting a {
     32    color: #a00;
     33}
     34
     35.media-embed-details .setting a:hover {
     36    color: #f00;
     37}
     38
     39.media-embed-details .embed-media-settings {
     40    top: 70px;
     41}
     42
     43.media-embed-details .embed-media-settings .checkbox-setting {
    2944    width: 100px;
    3045    clear: none;
  • trunk/src/wp-includes/js/tinymce/plugins/wpgallery/plugin.js

    r27440 r27478  
    9898                frame.detach();
    9999            } );
    100             frame.state( 'video-details' ).on( 'update replace', function ( selection ) {
     100            frame.state( 'video-details' ).on( 'update replace add-source select-poster-image', function ( selection ) {
    101101                var shortcode = wp.media.video.shortcode( selection );
    102102                editor.dom.setAttrib( node, 'data-wp-media', window.encodeURIComponent( shortcode ) );
     
    109109                frame.detach();
    110110            } );
    111             frame.state( 'audio-details' ).on( 'update replace', function ( selection ) {
     111            frame.state( 'audio-details' ).on( 'update replace add-source', function ( selection ) {
    112112                var shortcode = wp.media.audio.shortcode( selection );
    113113                editor.dom.setAttrib( node, 'data-wp-media', window.encodeURIComponent( shortcode ) );
  • trunk/src/wp-includes/media-template.php

    r27476 r27478  
    664664    <script type="text/html" id="tmpl-audio-details">
    665665        <?php $audio_types = wp_get_audio_extensions(); ?>
    666         <div class="media-embed">
     666        <div class="media-embed media-embed-details">
     667            <div class="instructions media-instructions">{{{ wp.media.view.l10n.audioDetailsText }}}</div>
    667668            <div class="embed-media-settings embed-audio-settings">
    668669                <audio controls
     
    690691                    <span>SRC</span>
    691692                    <input type="text" disabled="disabled" data-setting="src" value="{{ data.model.src }}" />
     693                    <a class="remove-setting">{{{ wp.media.view.l10n.audioRemoveSource }}}</a>
    692694                </label>
    693695                <# } #>
     
    699701                    <span><?php echo strtoupper( $type ) ?></span>
    700702                    <input type="text" disabled="disabled" data-setting="<?php echo $type ?>" value="{{ data.model.<?php echo $type ?> }}" />
     703                    <a class="remove-setting">{{{ wp.media.view.l10n.audioRemoveSource }}}</a>
    701704                </label>
    702705                <# } #>
     
    728731    <script type="text/html" id="tmpl-video-details">
    729732        <?php $video_types = wp_get_video_extensions(); ?>
    730         <div class="media-embed">
     733        <div class="media-embed media-embed-details">
     734            <div class="instructions media-instructions">{{{ wp.media.view.l10n.videoDetailsText }}}</div>
    731735            <div class="embed-media-settings embed-video-settings">
    732736                <div class="wp-video-holder">
    733737                <#
    734                 var w = ! data.model.width || data.model.width > 640 ? 640 : data.model.width,
     738                var isYouTube = ! _.isEmpty( data.model.src ) && data.model.src.match(/youtube|youtu\.be/);
     739                    w = ! data.model.width || data.model.width > 640 ? 640 : data.model.width,
    735740                    h = ! data.model.height ? 360 : data.model.height;
    736741
     
    738743                    h = Math.ceil( ( h * w ) / data.model.width );
    739744                }
     745
    740746                #>
    741747                <video controls
    742                     class="wp-video-shortcode youtube-video"
     748                    class="wp-video-shortcode{{ isYouTube ? ' youtube-video' : '' }}"
    743749                    width="{{ w }}"
    744750                    height="{{ h }}"
     
    763769                >
    764770                    <# if ( ! _.isEmpty( data.model.src ) ) {
    765                         if ( data.model.src.match(/youtube|youtu\.be/) ) { #>
     771                        if ( isYouTube ) { #>
    766772                        <source src="{{ data.model.src }}" type="video/youtube" />
    767773                        <# } else { #>
     
    780786                    <span>SRC</span>
    781787                    <input type="text" disabled="disabled" data-setting="src" value="{{ data.model.src }}" />
     788                    <a class="remove-setting">{{{ wp.media.view.l10n.videoRemoveSource }}}</a>
    782789                </label>
    783790                <# } #>
     
    787794                    <span><?php echo strtoupper( $type ) ?></span>
    788795                    <input type="text" disabled="disabled" data-setting="<?php echo $type ?>" value="{{ data.model.<?php echo $type ?> }}" />
     796                    <a class="remove-setting">{{{ wp.media.view.l10n.videoRemoveSource }}}</a>
    789797                </label>
    790798                <# } #>
    791799                <?php endforeach ?>
    792800                </div>
     801                <# if ( ! _.isEmpty( data.model.poster ) ) { #>
    793802                <label class="setting">
    794803                    <span><?php _e( 'Poster Image' ); ?></span>
    795                     <input type="text" data-setting="poster" value="{{ data.model.poster }}" />
    796                 </label>
     804                    <input type="text" disabled="disabled" data-setting="poster" value="{{ data.model.poster }}" />
     805                    <a class="remove-setting">{{{ wp.media.view.l10n.videoRemovePoster }}}</a>
     806                </label>
     807                <# } #>
    797808                <div class="setting preload">
    798809                    <span><?php _e( 'Preload' ); ?></span>
  • trunk/src/wp-includes/media.php

    r27476 r27478  
    24442444        'editImage'             => __( 'Edit Image' ),
    24452445
    2446         // Edit Image
     2446        // Edit Audio
    24472447        'audioDetailsTitle'     => __( 'Audio Details' ),
    24482448        'audioReplaceTitle'     => __( 'Replace Audio' ),
     2449        'audioAddSourceTitle'   => __( 'Add Audio Source' ),
    24492450        'audioDetailsCancel'    => __( 'Cancel Edit' ),
    2450 
    2451         // Edit Image
     2451        'audioDetailsText'      => __( '"Replace Audio" will remove all associated source files when you update. ' .
     2452            '"Add Audio Source" allows you to specify alternate sources for maximum native HTML5 audio playback.' ),
     2453        'audioRemoveSource'     => __( 'Remove Audio Source' ),
     2454
     2455        // Edit Video
    24522456        'videoDetailsTitle'     => __( 'Video Details' ),
    24532457        'videoReplaceTitle'     => __( 'Replace Video' ),
     2458        'videoAddSourceTitle'   => __( 'Add Video Source' ),
    24542459        'videoDetailsCancel'    => __( 'Cancel Edit' ),
     2460        'videoDetailsText'      => __( '"Replace Video" will remove all associated source files when you update. ' .
     2461            '"Add Video Source" allows you to specify alternate sources for maximum native HTML5 video playback.' ),
     2462        'videoRemoveSource'     => __( 'Remove Video Source' ),
     2463        'videoSelectPosterImageTitle' => _( 'Select Poster Image' ),
     2464        'videoRemovePoster'     => __( 'Remove Poster Image' ),
    24552465
    24562466        // Playlist
Note: See TracChangeset for help on using the changeset viewer.