Make WordPress Core

Changeset 27608


Ignore:
Timestamp:
03/19/2014 05:30:27 AM (12 years ago)
Author:
wonderboymusic
Message:

Create a new file, media-audiovideo.js, to house all of the audio and video JS code in core.

UX Changes:

  • Don't add a menu item for "Add Audio|Video Source"
  • In the Audio|Video Details modal, add buttons and some suggestive text for adding alternate playback sources
  • Don't show "Create Audio|Video Playlist" menu items until the user has uploaded audio or video files

See #27437.

Location:
trunk/src/wp-includes
Files:
1 added
7 edited

Legend:

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

    r27542 r27608  
    1212
    1313        /**
     14         * A helper mixin function to avoid truthy and falsey values being
     15         *   passed as an input that expects booleans. If key is undefined in the map,
     16         *   but has a default value, set it.
     17         *
     18         * @param {object} attrs Map of props from a shortcode or settings.
     19         * @param {string} key The key within the passed map to check for a value.
     20         * @returns {mixed|undefined} The original or coerced value of key within attrs
     21         */
     22        wp.media.coerce = function ( attrs, key ) {
     23                if ( _.isUndefined( attrs[ key ] ) && ! _.isUndefined( this.defaults[ key ] ) ) {
     24                        attrs[ key ] = this.defaults[ key ];
     25                } else if ( 'true' === attrs[ key ] ) {
     26                        attrs[ key ] = true;
     27                } else if ( 'false' === attrs[ key ] ) {
     28                        attrs[ key ] = false;
     29                }
     30                return attrs[ key ];
     31        };
     32
     33        /**
    1434         * wp.media.string
    1535         * @namespace
     
    275295        };
    276296
    277         /**
    278          * @mixin
    279          */
    280         wp.media.mixin = {
    281                 /**
    282                  * A helper function to avoid truthy and falsey values being
    283                  *   passed as an input that expects booleans. If key is undefined in the map,
    284                  *   but has a default value, set it.
    285                  *
    286                  * @param {object} attrs Map of props from a shortcode or settings.
    287                  * @param {string} key The key within the passed map to check for a value.
    288                  * @returns {mixed|undefined} The original or coerced value of key within attrs
    289                  */
    290                 coerce: function ( attrs, key ) {
    291                         if ( _.isUndefined( attrs[ key ] ) && ! _.isUndefined( this.defaults[ key ] ) ) {
    292                                 attrs[ key ] = this.defaults[ key ];
    293                         } else if ( 'true' === attrs[ key ] ) {
    294                                 attrs[ key ] = true;
    295                         } else if ( 'false' === attrs[ key ] ) {
    296                                 attrs[ key ] = false;
    297                         }
    298                         return attrs[ key ];
    299                 },
    300 
    301                 pauseAllPlayers: function () {
    302                         var p;
    303                         if ( window.mejs && window.mejs.players ) {
    304                                 for ( p in window.mejs.players ) {
    305                                         window.mejs.players[p].pause();
    306                                 }
    307                         }
    308                 },
    309 
    310                 ua: {
    311                         is : function (browser) {
    312                                 var passes = false, ua = window.navigator.userAgent;
    313 
    314                                 switch ( browser ) {
    315                                         case 'oldie':
    316                                                 passes = ua.match(/MSIE [6-8]/gi) !== null;
    317                                         break;
    318                                         case 'ie':
    319                                                 passes = ua.match(/MSIE/gi) !== null;
    320                                         break;
    321                                         case 'ff':
    322                                                 passes = ua.match(/firefox/gi) !== null;
    323                                         break;
    324                                         case 'opera':
    325                                                 passes = ua.match(/OPR/) !== null;
    326                                         break;
    327                                         case 'safari':
    328                                                 passes = ua.match(/safari/gi) !== null && ua.match(/chrome/gi) === null;
    329                                         break;
    330                                         case 'chrome':
    331                                                 passes = ua.match(/safari/gi) && ua.match(/chrome/gi) !== null;
    332                                         break;
    333                                 }
    334 
    335                                 return passes;
    336                         }
    337                 },
    338 
    339                 compat :{
    340                         'opera' : {
    341                                 audio: ['ogg', 'wav'],
    342                                 video: ['ogg', 'webm']
    343                         },
    344                         'chrome' : {
    345                                 audio: ['ogg', 'mpeg', 'x-ms-wma'],
    346                                 video: ['ogg', 'webm', 'mp4', 'm4v', 'mpeg']
    347                         },
    348                         'ff' : {
    349                                 audio: ['ogg', 'mpeg'],
    350                                 video: ['ogg', 'webm']
    351                         },
    352                         'safari' : {
    353                                 audio: ['mpeg', 'wav'],
    354                                 video: ['mp4', 'm4v', 'mpeg', 'x-ms-wmv', 'quicktime']
    355                         },
    356                         'ie' : {
    357                                 audio: ['mpeg'],
    358                                 video: ['mp4', 'm4v', 'mpeg']
    359                         }
    360                 },
    361 
    362                 isCompatible: function ( media ) {
    363                         if ( ! media.find( 'source' ).length ) {
    364                                 return false;
    365                         }
    366 
    367                         var ua = this.ua, test = false, found = false, sources;
    368 
    369                         if ( ua.is( 'oldIE' ) ) {
    370                                 return false;
    371                         }
    372 
    373                         sources = media.find( 'source' );
    374 
    375                         _.find( this.compat, function (supports, browser) {
    376                                 if ( ua.is( browser ) ) {
    377                                         found = true;
    378                                         _.each( sources, function (elem) {
    379                                                 var audio = new RegExp( 'audio\/(' + supports.audio.join('|') + ')', 'gi' ),
    380                                                         video = new RegExp( 'video\/(' + supports.video.join('|') + ')', 'gi' );
    381 
    382                                                 if ( elem.type.match( video ) !== null || elem.type.match( audio ) !== null ) {
    383                                                         test = true;
    384                                                 }
    385                                         } );
    386                                 }
    387 
    388                                 return test || found;
    389                         } );
    390 
    391                         return test;
    392                 },
    393 
    394                 /**
    395                  * Override the MediaElement method for removing a player.
    396                  *      MediaElement tries to pull the audio/video tag out of
    397                  *      its container and re-add it to the DOM.
    398                  */
    399                 removePlayer: function() {
    400                         var t = this.player, featureIndex, feature;
    401 
    402                         // invoke features cleanup
    403                         for ( featureIndex in t.options.features ) {
    404                                 feature = t.options.features[featureIndex];
    405                                 if ( t['clean' + feature] ) {
    406                                         try {
    407                                                 t['clean' + feature](t);
    408                                         } catch (e) {}
    409                                 }
    410                         }
    411 
    412                         if ( ! t.isDynamic ) {
    413                                 t.$node.remove();
    414                         }
    415 
    416                         if ( 'native' !== t.media.pluginType ) {
    417                                 t.media.remove();
    418                         }
    419 
    420                         delete window.mejs.players[t.id];
    421 
    422                         t.container.remove();
    423                         t.globalUnbind();
    424                         delete t.node.player;
    425                 },
    426 
    427                 /**
    428                  * Allows any class that has set 'player' to a MediaElementPlayer
    429                  *  instance to remove the player when listening to events.
    430                  *
    431                  *  Examples: modal closes, shortcode properties are removed, etc.
    432                  */
    433                 unsetPlayer : function() {
    434                         if ( this.player ) {
    435                                 wp.media.mixin.pauseAllPlayers();
    436                                 wp.media.mixin.removePlayer.apply( this );
    437                                 this.player = false;
    438                         }
    439                 }
    440         };
    441 
    442297        wp.media.collection = function(attributes) {
    443298                var collections = {};
    444299
    445300                return _.extend( attributes, {
    446                         coerce : wp.media.mixin.coerce,
     301                        coerce : wp.media.coerce,
    447302                        /**
    448303                         * Retrieve attachments based on the properties of the passed shortcode
     
    670525        });
    671526
    672         wp.media.playlist = new wp.media.collection({
    673                 tag: 'playlist',
    674                 type : 'audio',
    675                 editTitle : wp.media.view.l10n.editPlaylistTitle,
    676                 defaults : {
    677                         id: wp.media.view.settings.post.id,
    678                         style: 'light',
    679                         tracklist: true,
    680                         tracknumbers: true,
    681                         images: true,
    682                         artists: true
    683                 }
    684         });
    685 
    686         wp.media['video-playlist'] = new wp.media.collection({
    687                 tag: 'video-playlist',
    688                 type : 'video',
    689                 editTitle : wp.media.view.l10n.editVideoPlaylistTitle,
    690                 defaults : {
    691                         id: wp.media.view.settings.post.id,
    692                         style: 'light',
    693                         tracklist: false,
    694                         tracknumbers: false,
    695                         images: true
    696                 }
    697         });
    698 
    699         /**
    700          * @namespace
    701          */
    702         wp.media.audio = {
    703                 coerce : wp.media.mixin.coerce,
    704 
    705                 defaults : {
    706                         id : wp.media.view.settings.post.id,
    707                         src      : '',
    708                         loop     : false,
    709                         autoplay : false,
    710                         preload  : 'none'
    711                 },
    712 
    713                 edit : function (data) {
    714                         var frame, shortcode = wp.shortcode.next( 'audio', data ).shortcode;
    715                         frame = wp.media({
    716                                 frame: 'audio',
    717                                 state: 'audio-details',
    718                                 metadata: _.defaults(
    719                                         shortcode.attrs.named,
    720                                         wp.media.audio.defaults
    721                                 )
    722                         });
    723 
    724                         return frame;
    725                 },
    726 
    727                 shortcode : function (shortcode) {
    728                         var self = this;
    729 
    730                         _.each( wp.media.audio.defaults, function( value, key ) {
    731                                 shortcode[ key ] = self.coerce( shortcode, key );
    732 
    733                                 if ( value === shortcode[ key ] ) {
    734                                         delete shortcode[ key ];
    735                                 }
    736                         });
    737 
    738                         return wp.shortcode.string({
    739                                 tag:     'audio',
    740                                 attrs:   shortcode
    741                         });
    742                 }
    743         };
    744 
    745         /**
    746          * @namespace
    747          */
    748         wp.media.video = {
    749                 coerce : wp.media.mixin.coerce,
    750 
    751                 defaults : {
    752                         id : wp.media.view.settings.post.id,
    753                         src : '',
    754                         poster : '',
    755                         loop : false,
    756                         autoplay : false,
    757                         preload : 'metadata',
    758                         content : ''
    759                 },
    760 
    761                 edit : function (data) {
    762                         var frame,
    763                                 defaults = this.defaults,
    764                                 shortcode = wp.shortcode.next( 'video', data ).shortcode,
    765                                 attrs;
    766 
    767                         attrs = shortcode.attrs.named;
    768                         attrs.content = shortcode.content;
    769 
    770                         frame = wp.media({
    771                                 frame: 'video',
    772                                 state: 'video-details',
    773                                 metadata: _.defaults( attrs, defaults )
    774                         });
    775 
    776                         return frame;
    777                 },
    778 
    779                 shortcode : function (shortcode) {
    780                         var self = this, content = shortcode.content;
    781                         delete shortcode.content;
    782 
    783                         _.each( this.defaults, function( value, key ) {
    784                                 shortcode[ key ] = self.coerce( shortcode, key );
    785 
    786                                 if ( value === shortcode[ key ] ) {
    787                                         delete shortcode[ key ];
    788                                 }
    789                         });
    790 
    791                         return wp.shortcode.string({
    792                                 tag:     'video',
    793                                 attrs:   shortcode,
    794                                 content: content
    795                         });
    796                 }
    797         };
    798 
    799527        /**
    800528         * wp.media.featuredImage
     
    12801008                                                options.state = 'gallery';
    12811009                                                options.title = wp.media.view.l10n.createGalleryTitle;
    1282                                         } else if ( elem.hasClass( 'playlist' ) ) {
    1283                                                 options.state = 'playlist';
    1284                                                 options.title = wp.media.view.l10n.createPlaylistTitle;
    1285                                         } else if ( elem.hasClass( 'video-playlist' ) ) {
    1286                                                 options.state = 'video-playlist';
    1287                                                 options.title = wp.media.view.l10n.createVideoPlaylistTitle;
    12881010                                        }
    12891011
    12901012                                        wp.media.editor.open( editor, options );
    1291                                 })
    1292                                 .on( 'click', '.wp-switch-editor', wp.media.mixin.pauseAllPlayers );
     1013                                });
    12931014
    12941015                        // Initialize and render the Editor drag-and-drop uploader.
  • trunk/src/wp-includes/js/media-models.js

    r27536 r27608  
    4040
    4141                delete attributes.frame;
     42
     43                media.frame = frame;
    4244
    4345                return frame;
     
    450452                        this.set( 'width', size.width );
    451453                        this.set( 'height', size.height );
    452                 }
    453         });
    454 
    455         /**
    456          * wp.media.model.PostMedia
    457          *
    458          * @constructor
    459          * @augments Backbone.Model
    460          **/
    461         media.model.PostMedia = Backbone.Model.extend({
    462                 initialize: function() {
    463                         this.attachment = false;
    464                 },
    465 
    466                 setSource: function ( attachment ) {
    467                         this.attachment = attachment;
    468                         this.extension = attachment.get('filename' ).split('.').pop();
    469 
    470                         if ( this.get( 'src' ) && this.extension === this.get( 'src' ).split('.').pop() ) {
    471                                 this.unset( 'src' );
    472                         }
    473 
    474                         if ( _.contains( wp.media.view.settings.embedExts, this.extension ) ) {
    475                                 this.set( this.extension, this.attachment.get( 'url' ) );
    476                         } else {
    477                                 this.unset( this.extension );
    478                         }
    479                 },
    480 
    481                 changeAttachment: function( attachment ) {
    482                         var self = this;
    483 
    484                         this.setSource( attachment );
    485 
    486                         this.unset( 'src' );
    487                         _.each( _.without( wp.media.view.settings.embedExts, this.extension ), function (ext) {
    488                                 self.unset( ext );
    489                         } );
    490454                }
    491455        });
  • trunk/src/wp-includes/js/media-views.js

    r27538 r27608  
    762762                initialize: function( options ) {
    763763                        this.image = options.image;
    764                         media.controller.State.prototype.initialize.apply( this, arguments );
    765                 }
    766         });
    767 
    768         /**
    769          * wp.media.controller.AudioDetails
    770          *
    771          * @constructor
    772          * @augments wp.media.controller.State
    773          * @augments Backbone.Model
    774          */
    775         media.controller.AudioDetails = media.controller.State.extend({
    776                 defaults: _.defaults({
    777                         id: 'audio-details',
    778                         toolbar: 'audio-details',
    779                         title: l10n.audioDetailsTitle,
    780                         content: 'audio-details',
    781                         menu: 'audio-details',
    782                         router: false,
    783                         attachment: false,
    784                         priority: 60,
    785                         editing: false
    786                 }, media.controller.Library.prototype.defaults ),
    787 
    788                 initialize: function( options ) {
    789                         this.media = options.media;
    790                         media.controller.State.prototype.initialize.apply( this, arguments );
    791                 }
    792         });
    793 
    794         /**
    795          * wp.media.controller.VideoDetails
    796          *
    797          * @constructor
    798          * @augments wp.media.controller.State
    799          * @augments Backbone.Model
    800          */
    801         media.controller.VideoDetails = media.controller.State.extend({
    802                 defaults: _.defaults({
    803                         id: 'video-details',
    804                         toolbar: 'video-details',
    805                         title: l10n.videoDetailsTitle,
    806                         content: 'video-details',
    807                         menu: 'video-details',
    808                         router: false,
    809                         attachment: false,
    810                         priority: 60,
    811                         editing: false
    812                 }, media.controller.Library.prototype.defaults ),
    813 
    814                 initialize: function( options ) {
    815                         this.media = options.media;
    816764                        media.controller.State.prototype.initialize.apply( this, arguments );
    817765                }
     
    19311879
    19321880                createStates: function() {
    1933                         var options = this.options;
     1881                        var options = this.options, counts;
    19341882
    19351883                        // Add the default states.
     
    19911939                                        collectionType: 'gallery',
    19921940                                        title:          l10n.addToGalleryTitle
    1993                                 }),
    1994 
    1995                                 new media.controller.Library({
    1996                                         id:         'playlist',
    1997                                         title:      l10n.createPlaylistTitle,
    1998                                         priority:   60,
    1999                                         toolbar:    'main-playlist',
    2000                                         filterable: 'uploaded',
    2001                                         multiple:   'add',
    2002                                         editable:   false,
    2003 
    2004                                         library:  media.query( _.defaults({
    2005                                                 type: 'audio'
    2006                                         }, options.library ) )
    2007                                 }),
    2008 
    2009                                 // Playlist states.
    2010                                 new media.controller.CollectionEdit({
    2011                                         type:           'audio',
    2012                                         collectionType: 'playlist',
    2013                                         title:          l10n.editPlaylistTitle,
    2014                                         SettingsView:   media.view.Settings.Playlist,
    2015                                         library:        options.selection,
    2016                                         editing:        options.editing,
    2017                                         menu:           'playlist',
    2018                                         dragInfoText:   l10n.playlistDragInfo,
    2019                                         dragInfo:       false
    2020                                 }),
    2021 
    2022                                 new media.controller.CollectionAdd({
    2023                                         type: 'audio',
    2024                                         collectionType: 'playlist',
    2025                                         title: l10n.addToPlaylistTitle
    2026                                 }),
    2027 
    2028                                 new media.controller.Library({
    2029                                         id:         'video-playlist',
    2030                                         title:      l10n.createVideoPlaylistTitle,
    2031                                         priority:   60,
    2032                                         toolbar:    'main-video-playlist',
    2033                                         filterable: 'uploaded',
    2034                                         multiple:   'add',
    2035                                         editable:   false,
    2036 
    2037                                         library:  media.query( _.defaults({
    2038                                                 type: 'video'
    2039                                         }, options.library ) )
    2040                                 }),
    2041 
    2042                                 // Video Playlist states.
    2043                                 new media.controller.CollectionEdit({
    2044                                         type:           'video',
    2045                                         collectionType: 'video-playlist',
    2046                                         title:          l10n.editVideoPlaylistTitle,
    2047                                         SettingsView:   media.view.Settings.Playlist,
    2048                                         library:        options.selection,
    2049                                         editing:        options.editing,
    2050                                         menu:           'video-playlist',
    2051                                         dragInfoText:   l10n.videoPlaylistDragInfo,
    2052                                         dragInfo:       false
    2053                                 }),
    2054 
    2055                                 new media.controller.CollectionAdd({
    2056                                         type:           'video',
    2057                                         collectionType: 'video-playlist',
    2058                                         title:          l10n.addToVideoPlaylistTitle
    20591941                                })
    20601942                        ]);
    20611943
     1944                        counts = media.playlist.counts();
     1945
     1946                        if ( counts.audio ) {
     1947                                this.states.add( media.playlist.states(options) );
     1948                        }
     1949
     1950                        if ( counts.video ) {
     1951                                this.states.add( media.playlist.videoStates(options) );
     1952                        }
    20621953
    20631954                        if ( media.view.settings.post.featuredImageId ) {
     
    27472638
    27482639        /**
    2749          * wp.media.view.MediaFrame.MediaDetails
    2750          *
    2751          * @constructor
    2752          * @augments wp.media.view.MediaFrame.Select
    2753          * @augments wp.media.view.MediaFrame
    2754          * @augments wp.media.view.Frame
    2755          * @augments wp.media.View
    2756          * @augments wp.Backbone.View
    2757          * @augments Backbone.View
    2758          * @mixes wp.media.controller.StateMachine
    2759          */
    2760         media.view.MediaFrame.MediaDetails = media.view.MediaFrame.Select.extend({
    2761                 defaults: {
    2762                         id:      'media',
    2763                         url:     '',
    2764                         menu:    'media-details',
    2765                         content: 'media-details',
    2766                         toolbar: 'media-details',
    2767                         type:    'link',
    2768                         priority: 120
    2769                 },
    2770 
    2771                 initialize: function( options ) {
    2772                         this.DetailsView = options.DetailsView;
    2773                         this.cancelText = options.cancelText;
    2774                         this.addText = options.addText;
    2775 
    2776                         this.media = new media.model.PostMedia( options.metadata );
    2777                         this.options.selection = new media.model.Selection( this.media.attachment, { multiple: false } );
    2778                         media.view.MediaFrame.Select.prototype.initialize.apply( this, arguments );
    2779                 },
    2780 
    2781                 bindHandlers: function() {
    2782                         var menu = this.defaults.menu;
    2783 
    2784                         media.view.MediaFrame.Select.prototype.bindHandlers.apply( this, arguments );
    2785 
    2786                         this.on( 'menu:create:' + menu, this.createMenu, this );
    2787                         this.on( 'content:render:' + menu, this.renderDetailsContent, this );
    2788                         this.on( 'menu:render:' + menu, this.renderMenu, this );
    2789                         this.on( 'toolbar:render:' + menu, this.renderDetailsToolbar, this );
    2790                 },
    2791 
    2792                 renderDetailsContent: function() {
    2793                         var view = new this.DetailsView({
    2794                                 controller: this,
    2795                                 model: this.state().media,
    2796                                 attachment: this.state().media.attachment
    2797                         }).render();
    2798 
    2799                         this.content.set( view );
    2800                 },
    2801 
    2802                 renderMenu: function( view ) {
    2803                         var lastState = this.lastState(),
    2804                                 previous = lastState && lastState.id,
    2805                                 frame = this;
    2806 
    2807                         view.set({
    2808                                 cancel: {
    2809                                         text:     this.cancelText,
    2810                                         priority: 20,
    2811                                         click:    function() {
    2812                                                 if ( previous ) {
    2813                                                         frame.setState( previous );
    2814                                                 } else {
    2815                                                         frame.close();
    2816                                                 }
    2817                                         }
    2818                                 },
    2819                                 separateCancel: new media.View({
    2820                                         className: 'separator',
    2821                                         priority: 40
    2822                                 })
    2823                         });
    2824 
    2825                 },
    2826 
    2827                 renderDetailsToolbar: function() {
    2828                         this.toolbar.set( new media.view.Toolbar({
    2829                                 controller: this,
    2830                                 items: {
    2831                                         select: {
    2832                                                 style:    'primary',
    2833                                                 text:     l10n.update,
    2834                                                 priority: 80,
    2835 
    2836                                                 click: function() {
    2837                                                         var controller = this.controller,
    2838                                                                 state = controller.state();
    2839 
    2840                                                         controller.close();
    2841 
    2842                                                         state.trigger( 'update', controller.media.toJSON() );
    2843 
    2844                                                         // Restore and reset the default state.
    2845                                                         controller.setState( controller.options.state );
    2846                                                         controller.reset();
    2847                                                 }
    2848                                         }
    2849                                 }
    2850                         }) );
    2851                 },
    2852 
    2853                 renderReplaceToolbar: function() {
    2854                         this.toolbar.set( new media.view.Toolbar({
    2855                                 controller: this,
    2856                                 items: {
    2857                                         replace: {
    2858                                                 style:    'primary',
    2859                                                 text:     l10n.replace,
    2860                                                 priority: 80,
    2861 
    2862                                                 click: function() {
    2863                                                         var controller = this.controller,
    2864                                                                 state = controller.state(),
    2865                                                                 selection = state.get( 'selection' ),
    2866                                                                 attachment = selection.single();
    2867 
    2868                                                         controller.media.changeAttachment( attachment );
    2869 
    2870                                                         state.trigger( 'replace', controller.media.toJSON() );
    2871 
    2872                                                         // Restore and reset the default state.
    2873                                                         controller.setState( controller.options.state );
    2874                                                         controller.reset();
    2875                                                 }
    2876                                         }
    2877                                 }
    2878                         }) );
    2879                 },
    2880 
    2881                 renderAddSourceToolbar: function() {
    2882                         this.toolbar.set( new media.view.Toolbar({
    2883                                 controller: this,
    2884                                 items: {
    2885                                         replace: {
    2886                                                 style:    'primary',
    2887                                                 text:     this.addText,
    2888                                                 priority: 80,
    2889 
    2890                                                 click: function() {
    2891                                                         var controller = this.controller,
    2892                                                                 state = controller.state(),
    2893                                                                 selection = state.get( 'selection' ),
    2894                                                                 attachment = selection.single();
    2895 
    2896                                                         controller.media.setSource( attachment );
    2897 
    2898                                                         state.trigger( 'add-source', controller.media.toJSON() );
    2899 
    2900                                                         // Restore and reset the default state.
    2901                                                         controller.setState( controller.options.state );
    2902                                                         controller.reset();
    2903                                                 }
    2904                                         }
    2905                                 }
    2906                         }) );
    2907                 }
    2908         });
    2909 
    2910         /**
    2911          * wp.media.view.MediaFrame.AudioDetails
    2912          *
    2913          * @constructor
    2914          * @augments wp.media.view.MediaFrame.MediaDetails
    2915          * @augments wp.media.view.MediaFrame.Select
    2916          * @augments wp.media.view.MediaFrame
    2917          * @augments wp.media.view.Frame
    2918          * @augments wp.media.View
    2919          * @augments wp.Backbone.View
    2920          * @augments Backbone.View
    2921          * @mixes wp.media.controller.StateMachine
    2922          */
    2923         media.view.MediaFrame.AudioDetails = media.view.MediaFrame.MediaDetails.extend({
    2924                 defaults: {
    2925                         id:      'audio',
    2926                         url:     '',
    2927                         menu:    'audio-details',
    2928                         content: 'audio-details',
    2929                         toolbar: 'audio-details',
    2930                         type:    'link',
    2931                         title:    l10n.audioDetailsTitle,
    2932                         priority: 120
    2933                 },
    2934 
    2935                 initialize: function( options ) {
    2936                         options.DetailsView = media.view.AudioDetails;
    2937                         options.cancelText = l10n.audioDetailsCancel;
    2938                         options.addText = l10n.audioAddSourceTitle;
    2939 
    2940                         media.view.MediaFrame.MediaDetails.prototype.initialize.call( this, options );
    2941                 },
    2942 
    2943                 bindHandlers: function() {
    2944                         media.view.MediaFrame.MediaDetails.prototype.bindHandlers.apply( this, arguments );
    2945 
    2946                         this.on( 'toolbar:render:replace-audio', this.renderReplaceToolbar, this );
    2947                         this.on( 'toolbar:render:add-audio-source', this.renderAddSourceToolbar, this );
    2948                 },
    2949 
    2950                 createStates: function() {
    2951                         this.states.add([
    2952                                 new media.controller.AudioDetails( {
    2953                                         media: this.media,
    2954                                         editable: false,
    2955                                         menu: 'audio-details'
    2956                                 } ),
    2957 
    2958                                 new media.controller.MediaLibrary( {
    2959                                         type: 'audio',
    2960                                         id: 'replace-audio',
    2961                                         title: l10n.audioReplaceTitle,
    2962                                         toolbar: 'replace-audio',
    2963                                         media: this.media,
    2964                                         menu: 'audio-details'
    2965                                 } ),
    2966 
    2967                                 new media.controller.MediaLibrary( {
    2968                                         type: 'audio',
    2969                                         id: 'add-audio-source',
    2970                                         title: l10n.audioAddSourceTitle,
    2971                                         toolbar: 'add-audio-source',
    2972                                         media: this.media,
    2973                                         menu: 'audio-details'
    2974                                 } )
    2975                         ]);
    2976                 }
    2977         });
    2978 
    2979         /**
    2980          * wp.media.view.MediaFrame.VideoDetails
    2981          *
    2982          * @constructor
    2983          * @augments wp.media.view.MediaFrame.MediaDetails
    2984          * @augments wp.media.view.MediaFrame.Select
    2985          * @augments wp.media.view.MediaFrame
    2986          * @augments wp.media.view.Frame
    2987          * @augments wp.media.View
    2988          * @augments wp.Backbone.View
    2989          * @augments Backbone.View
    2990          * @mixes wp.media.controller.StateMachine
    2991          */
    2992         media.view.MediaFrame.VideoDetails = media.view.MediaFrame.MediaDetails.extend({
    2993                 defaults: {
    2994                         id:      'video',
    2995                         url:     '',
    2996                         menu:    'video-details',
    2997                         content: 'video-details',
    2998                         toolbar: 'video-details',
    2999                         type:    'link',
    3000                         title:    l10n.videoDetailsTitle,
    3001                         priority: 120
    3002                 },
    3003 
    3004                 initialize: function( options ) {
    3005                         options.DetailsView = media.view.VideoDetails;
    3006                         options.cancelText = l10n.videoDetailsCancel;
    3007                         options.addText = l10n.videoAddSourceTitle;
    3008 
    3009                         media.view.MediaFrame.MediaDetails.prototype.initialize.call( this, options );
    3010                 },
    3011 
    3012                 bindHandlers: function() {
    3013                         media.view.MediaFrame.MediaDetails.prototype.bindHandlers.apply( this, arguments );
    3014 
    3015                         this.on( 'toolbar:render:replace-video', this.renderReplaceToolbar, this );
    3016                         this.on( 'toolbar:render:add-video-source', this.renderAddSourceToolbar, this );
    3017                         this.on( 'toolbar:render:select-poster-image', this.renderSelectPosterImageToolbar, this );
    3018                         this.on( 'toolbar:render:add-track', this.renderAddTrackToolbar, this );
    3019                 },
    3020 
    3021                 createStates: function() {
    3022                         this.states.add([
    3023                                 new media.controller.VideoDetails({
    3024                                         media: this.media,
    3025                                         editable: false,
    3026                                         menu: 'video-details'
    3027                                 }),
    3028 
    3029                                 new media.controller.MediaLibrary( {
    3030                                         type: 'video',
    3031                                         id: 'replace-video',
    3032                                         title: l10n.videoReplaceTitle,
    3033                                         toolbar: 'replace-video',
    3034                                         media: this.media,
    3035                                         menu: 'video-details'
    3036                                 } ),
    3037 
    3038                                 new media.controller.MediaLibrary( {
    3039                                         type: 'video',
    3040                                         id: 'add-video-source',
    3041                                         title: l10n.videoAddSourceTitle,
    3042                                         toolbar: 'add-video-source',
    3043                                         media: this.media,
    3044                                         menu: 'video-details'
    3045                                 } ),
    3046 
    3047                                 new media.controller.MediaLibrary( {
    3048                                         type: 'image',
    3049                                         id: 'select-poster-image',
    3050                                         title: l10n.videoSelectPosterImageTitle,
    3051                                         toolbar: 'select-poster-image',
    3052                                         media: this.media,
    3053                                         menu: 'video-details'
    3054                                 } ),
    3055 
    3056                                 new media.controller.MediaLibrary( {
    3057                                         type: 'text',
    3058                                         id: 'add-track',
    3059                                         title: l10n.videoAddTrackTitle,
    3060                                         toolbar: 'add-track',
    3061                                         media: this.media,
    3062                                         menu: 'video-details'
    3063                                 } )
    3064                         ]);
    3065                 },
    3066 
    3067                 renderSelectPosterImageToolbar: function() {
    3068                         this.toolbar.set( new media.view.Toolbar({
    3069                                 controller: this,
    3070                                 items: {
    3071                                         replace: {
    3072                                                 style:    'primary',
    3073                                                 text:     l10n.videoSelectPosterImageTitle,
    3074                                                 priority: 80,
    3075 
    3076                                                 click: function() {
    3077                                                         var controller = this.controller,
    3078                                                                 state = controller.state(),
    3079                                                                 selection = state.get( 'selection' ),
    3080                                                                 attachment = selection.single();
    3081 
    3082                                                         controller.media.set( 'poster', attachment.get( 'url' ) );
    3083 
    3084                                                         state.trigger( 'set-poster-image', controller.media.toJSON() );
    3085 
    3086                                                         // Restore and reset the default state.
    3087                                                         controller.setState( controller.options.state );
    3088                                                         controller.reset();
    3089                                                 }
    3090                                         }
    3091                                 }
    3092                         }) );
    3093                 },
    3094 
    3095                 renderAddTrackToolbar: function() {
    3096                         this.toolbar.set( new media.view.Toolbar({
    3097                                 controller: this,
    3098                                 items: {
    3099                                         replace: {
    3100                                                 style:    'primary',
    3101                                                 text:     l10n.videoAddTrackTitle,
    3102                                                 priority: 80,
    3103 
    3104                                                 click: function() {
    3105                                                         var controller = this.controller,
    3106                                                                 state = controller.state(),
    3107                                                                 selection = state.get( 'selection' ),
    3108                                                                 attachment = selection.single(),
    3109                                                                 content = controller.media.get( 'content' );
    3110 
    3111                                                         if ( -1 === content.indexOf( attachment.get( 'url' ) ) ) {
    3112                                                                 content += [
    3113                                                                         '<track srclang="en" label="English"kind="subtitles" src="',
    3114                                                                         attachment.get( 'url' ),
    3115                                                                         '" />'
    3116                                                                 ].join('');
    3117 
    3118                                                                 controller.media.set( 'content', content );
    3119                                                         }
    3120 
    3121                                                         state.trigger( 'add-track', controller.media.toJSON() );
    3122 
    3123                                                         // Restore and reset the default state.
    3124                                                         controller.setState( controller.options.state );
    3125                                                         controller.reset();
    3126                                                 }
    3127                                         }
    3128                                 }
    3129                         }) );
    3130                 }
    3131         });
    3132 
    3133         /**
    31342640         * wp.media.view.Modal
    31352641         *
     
    66646170
    66656171        /**
    6666          * wp.media.view.AudioDetails
    6667          *
    6668          * @contructor
    6669          * @augments wp.media.view.MediaDetails
    6670          * @augments wp.media.view.Settings.AttachmentDisplay
    6671          * @augments wp.media.view.Settings
    6672          * @augments wp.media.View
    6673          * @augments wp.Backbone.View
    6674          * @augments Backbone.View
    6675          */
    6676         media.view.AudioDetails = media.view.MediaDetails.extend({
    6677                 className: 'audio-details',
    6678                 template:  media.template('audio-details'),
    6679 
    6680                 setMedia: function() {
    6681                         var audio = this.$('.wp-audio-shortcode');
    6682 
    6683                         if ( audio.find( 'source' ).length ) {
    6684                                 if ( audio.is(':hidden') ) {
    6685                                         audio.show();
    6686                                 }
    6687                                 this.media = media.view.MediaDetails.prepareSrc( audio.get(0) );
    6688                         } else {
    6689                                 audio.hide();
    6690                                 this.media = false;
    6691                         }
    6692 
    6693                         return this;
    6694                 }
    6695         });
    6696 
    6697         /**
    6698          * wp.media.view.VideoDetails
    6699          *
    6700          * @contructor
    6701          * @augments wp.media.view.MediaDetails
    6702          * @augments wp.media.view.Settings.AttachmentDisplay
    6703          * @augments wp.media.view.Settings
    6704          * @augments wp.media.View
    6705          * @augments wp.Backbone.View
    6706          * @augments Backbone.View
    6707          */
    6708         media.view.VideoDetails = media.view.MediaDetails.extend({
    6709                 className: 'video-details',
    6710                 template:  media.template('video-details'),
    6711 
    6712                 setMedia: function() {
    6713                         var video = this.$('.wp-video-shortcode');
    6714 
    6715                         if ( video.find( 'source' ).length ) {
    6716                                 if ( video.is(':hidden') ) {
    6717                                         video.show();
    6718                                 }
    6719 
    6720                                 if ( ! video.hasClass('youtube-video') ) {
    6721                                         this.media = media.view.MediaDetails.prepareSrc( video.get(0) );
    6722                                 } else {
    6723                                         this.media = video.get(0);
    6724                                 }
    6725                         } else {
    6726                                 video.hide();
    6727                                 this.media = false;
    6728                         }
    6729 
    6730                         return this;
    6731                 }
    6732         });
    6733 
    6734         /**
    67356172         * wp.media.view.Spinner
    67366173         *
  • trunk/src/wp-includes/js/mediaelement/wp-mediaelement.css

    r27534 r27608  
    2727.media-embed-details .embed-media-settings {
    2828        padding-top: 0;
     29        top: 28px;
    2930}
    3031
     
    4344.media-embed-details .setting a:hover {
    4445        color: #f00;
    45 }
    46 
    47 .media-embed-details .embed-media-settings {
    48         top: 0;
    4946}
    5047
  • trunk/src/wp-includes/media-template.php

    r27580 r27608  
    766766
    767767        <script type="text/html" id="tmpl-audio-details">
     768                <# var ext, html5types = { mp3: true, ogg: true }; #>
     769
    768770                <?php $audio_types = wp_get_audio_extensions(); ?>
    769771                <div class="media-embed media-embed-details">
    770772                        <div class="embed-media-settings embed-audio-settings">
    771                                 <div class="instructions media-instructions">{{{ wp.media.view.l10n.audioDetailsText }}}</div>
    772 
    773773                                <?php wp_underscore_audio_template() ?>
    774774
    775                                 <# if ( ! _.isEmpty( data.model.src ) ) { #>
     775                                <# if ( ! _.isEmpty( data.model.src ) ) {
     776                                        ext = data.model.src.split('.').pop();
     777                                        if ( html5types[ ext ] ) {
     778                                                delete html5types[ ext ];
     779                                        }
     780                                #>
    776781                                <label class="setting">
    777782                                        <span>SRC</span>
     
    783788
    784789                                foreach ( $audio_types as $type ):
    785                                 ?><# if ( ! _.isEmpty( data.model.<?php echo $type ?> ) ) { #>
     790                                ?><# if ( ! _.isEmpty( data.model.<?php echo $type ?> ) ) {
     791                                        if ( ! _.isUndefined( html5types.<?php echo $type ?> ) ) {
     792                                                delete html5types.<?php echo $type ?>;
     793                                        }
     794                                #>
    786795                                <label class="setting">
    787796                                        <span><?php echo strtoupper( $type ) ?></span>
     
    791800                                <# } #>
    792801                                <?php endforeach ?>
     802
     803                                <# if ( ! _.isEmpty( html5types ) ) { #>
     804                                <div class="setting">
     805                                        <span>{{{ wp.media.view.l10n.mediaHTML5Text }}}</span>
     806                                        <div class="button-large">
     807                                        <# _.each( html5types, function (value, type) { #>
     808                                        <button class="button add-media-source">{{ type }}</button>
     809                                        <# } ) #>
     810                                        </div>
     811                                </div>
     812                                <# } #>
    793813
    794814                                <div class="setting preload">
     
    816836
    817837        <script type="text/html" id="tmpl-video-details">
     838                <# var ext, html5types = { mp4: true, ogv: true, webm: true }; #>
     839
    818840                <?php $video_types = wp_get_video_extensions(); ?>
    819841                <div class="media-embed media-embed-details">
    820842                        <div class="embed-media-settings embed-video-settings">
    821                                 <div class="instructions media-instructions">{{{ wp.media.view.l10n.videoDetailsText }}}</div>
    822843                                <div class="wp-video-holder">
    823844                                <#
     
    833854                                <?php wp_underscore_video_template() ?>
    834855
    835                                 <# if ( ! _.isEmpty( data.model.src ) ) { #>
     856                                <# if ( ! _.isEmpty( data.model.src ) ) {
     857                                        ext = data.model.src.split('.').pop();
     858                                        if ( html5types[ ext ] ) {
     859                                                delete html5types[ ext ];
     860                                        }
     861                                #>
    836862                                <label class="setting">
    837863                                        <span>SRC</span>
     
    841867                                <# } #>
    842868                                <?php foreach ( $video_types as $type ):
    843                                 ?><# if ( ! _.isEmpty( data.model.<?php echo $type ?> ) ) { #>
     869                                ?><# if ( ! _.isEmpty( data.model.<?php echo $type ?> ) ) {
     870                                        if ( ! _.isUndefined( html5types.<?php echo $type ?> ) ) {
     871                                                delete html5types.<?php echo $type ?>;
     872                                        }
     873                                #>
    844874                                <label class="setting">
    845875                                        <span><?php echo strtoupper( $type ) ?></span>
     
    850880                                <?php endforeach ?>
    851881                                </div>
     882
     883                                <# if ( ! _.isEmpty( html5types ) ) { #>
     884                                <div class="setting">
     885                                        <span>{{{ wp.media.view.l10n.mediaHTML5Text }}}</span>
     886                                        <div class="button-large">
     887                                        <# _.each( html5types, function (value, type) { #>
     888                                        <button class="button add-media-source">{{ type }}</button>
     889                                        <# } ) #>
     890                                        </div>
     891                                </div>
     892                                <# } #>
     893
    852894                                <# if ( ! _.isEmpty( data.model.poster ) ) { #>
    853895                                <label class="setting">
  • trunk/src/wp-includes/media.php

    r27519 r27608  
    24012401                ),
    24022402                'defaultProps' => $props,
     2403                'attachmentCounts' => wp_count_attachments(),
    24032404                'embedExts'    => $exts,
    24042405                'embedMimes'   => $ext_mimes
     
    24962497                'suggestedHeight' => __( 'Suggested height is %d pixels.' ),
    24972498
     2499                'mediaHTML5Text'        => __( 'Add alternate sources for maximum HTML5 playback:' ),
     2500
    24982501                // Edit Audio
    24992502                'audioDetailsTitle'     => __( 'Audio Details' ),
     
    25012504                'audioAddSourceTitle'   => __( 'Add Audio Source' ),
    25022505                'audioDetailsCancel'    => __( 'Cancel Edit' ),
    2503                 'audioDetailsText'      => __( '"Replace Audio" will remove all associated source files when you update. ' .
    2504                         '"Add Audio Source" allows you to specify alternate sources for maximum native HTML5 audio playback.' ),
    25052506
    25062507                // Edit Video
     
    25092510                'videoAddSourceTitle'   => __( 'Add Video Source' ),
    25102511                'videoDetailsCancel'    => __( 'Cancel Edit' ),
    2511                 'videoDetailsText'      => __( '"Replace Video" will remove all associated source files when you update. ' .
    2512                         '"Add Video Source" allows you to specify alternate sources for maximum native HTML5 video playback.' ),
    25132512                'videoSelectPosterImageTitle' => _( 'Select Poster Image' ),
    25142513                'videoAddTrackTitle'    => __( 'Add Subtitles' ),
     
    25432542
    25442543        wp_enqueue_script( 'media-editor' );
     2544        wp_enqueue_script( 'media-audiovideo' );
    25452545        wp_enqueue_style( 'media-views' );
    25462546        wp_enqueue_style( 'imgareaselect' );
  • trunk/src/wp-includes/script-loader.php

    r27585 r27608  
    397397        $scripts->add( 'media-views',  "/wp-includes/js/media-views$suffix.js",  array( 'utils', 'media-models', 'wp-plupload', 'jquery-ui-sortable', 'wp-mediaelement', 'image-edit' ), false, 1 );
    398398        $scripts->add( 'media-editor', "/wp-includes/js/media-editor$suffix.js", array( 'shortcode', 'media-views' ), false, 1 );
     399        $scripts->add( 'media-audiovideo', "/wp-includes/js/media-audiovideo$suffix.js", array( 'media-editor' ), false, 1 );
    399400        $scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'shortcode', 'media-models' ), false, 1 );
    400401
Note: See TracChangeset for help on using the changeset viewer.