Make WordPress Core

Changeset 22466


Ignore:
Timestamp:
11/08/2012 02:15:09 PM (11 years ago)
Author:
koopersmith
Message:

Media: Improve sidebar handling and make attachment display properties attachment-specific.

wp.mce.media

  • Watch all workflows for the insert event and attempt to insert the current state's selection if it exists.
  • Fetch and pass attachment display properties through to wp.media.string.image().

wp.media.controller.Region

  • Separate the concept of events and modes.
  • All events triggered on a Region trigger both event and event:mode callbacks.
  • When a mode is deactivated, deactivate and deactivate:mode events are fired.
  • When a mode is activated, activate and activate:mode events are fired.

wp.media.controller.Library

  • Remove the details(), buildDetails(), and clearDetails() methods that juggled sidebar views. Instead, handle the sidebar views using modes.

wp.media.controller.Gallery

  • Shift the overloaded sidebar() method to use modes.

wp.media.view.MediaFrame.Post

  • Declare activate:mode event bindings using an nested object to reduce repetition.
  • Update sidebar activation callbacks.

wp.media.view.Settings

  • Refactor to leverage HTML data attributes and implicit values (instead of setting the fallback whenever an object was created). This has the additional benefit that gallery shortcode parameters are not output when the user has left them set to the default.

see #21390.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/js/media-upload.js

    r22437 r22466  
    108108            } ) );
    109109
    110             workflow.get('library').on( 'insert', function( selection ) {
     110            workflow.on( 'insert', function() {
     111                var state = workflow.state(),
     112                    selection = state.get('selection'),
     113                    details = state.get('details');
     114
     115                if ( ! selection || ! details )
     116                    return;
     117
    111118                this.insert( selection.map( function( attachment ) {
     119                    var detail = details[ attachment.cid ];
     120
     121                    if ( detail )
     122                        detail = detail.toJSON();
     123
    112124                    if ( 'image' === attachment.get('type') )
    113                         return wp.media.string.image( attachment ) + ' ';
     125                        return wp.media.string.image( attachment, detail ) + ' ';
    114126                    else
    115127                        return wp.media.string.link( attachment ) + ' ';
  • trunk/wp-includes/css/media-views.css

    r22437 r22466  
    760760 */
    761761
     762.attachment-details {
     763    overflow: auto;
     764}
     765
    762766.attachment-details-preview {
    763767    cursor: default;
  • trunk/wp-includes/js/media-views.js

    r22454 r22466  
    5959        _.extend( this, _.pick( options || {}, 'id', 'controller' ) );
    6060
    61         this.on( 'empty', this.empty, this );
     61        this.on( 'activate:empty', this.empty, this );
    6262        this.mode('empty');
    6363    };
     
    6767
    6868    _.extend( media.controller.Region.prototype, Backbone.Events, {
    69         trigger: function( id ) {
    70             this._mode = id;
    71             return Backbone.Events.trigger.apply( this, arguments );
    72         },
     69        trigger: (function() {
     70            var eventSplitter = /\s+/,
     71                trigger = Backbone.Events.trigger;
     72
     73            return function( events ) {
     74                var mode = ':' + this._mode,
     75                    modeEvents = events.split( eventSplitter ).join( mode ) + mode;
     76
     77                trigger.apply( this, arguments );
     78                trigger.apply( this, [ modeEvents ].concat( _.rest( arguments ) ) );
     79                return this;
     80            };
     81        }()),
    7382
    7483        mode: function( mode ) {
    75             if ( mode )
    76                 return this.trigger( mode );
     84            if ( mode ) {
     85                this.trigger('deactivate');
     86                this._mode = mode;
     87                return this.trigger('activate');
     88            }
    7789            return this._mode;
    7890        },
     
    271283                this.set( 'gutter', 8 );
    272284
     285            if ( ! this.get('details') )
     286                this.set( 'details', [] );
     287
    273288            media.controller.State.prototype.initialize.apply( this, arguments );
    274289        },
     
    282297                wp.Uploader.queue.on( 'add', this.selectUpload, this );
    283298
    284             selection.on( 'selection:single', this.buildDetails, this );
    285             selection.on( 'selection:unsingle', this.clearDetails, this );
     299            selection.on( 'selection:single selection:unsingle', this.sidebar, this );
    286300            selection.on( 'add remove reset', this.refreshToolbar, this );
    287301
     
    307321
    308322        sidebar: function() {
    309             media.controller.State.prototype.sidebar.apply( this, arguments );
    310             this.details();
     323            var sidebar = this.frame.sidebar;
     324
     325            if ( this.get('selection').single() )
     326                sidebar.mode( this.get('sidebar') );
     327            else
     328                sidebar.mode('clear');
    311329        },
    312330
     
    343361        selectUpload: function( attachment ) {
    344362            this.get('selection').add( attachment );
    345         },
    346 
    347         details: function() {
    348             var single = this.get('selection').single();
    349             this[ single ? 'buildDetails' : 'clearDetails' ]( single );
    350         },
    351 
    352         buildDetails: function( model ) {
    353             var frame = this.frame;
    354             frame.sidebar.view().add( 'details', new media.view.Attachment.Details({
    355                 controller: frame,
    356                 model:      model,
    357                 priority:   80
    358             }).render() );
    359             return this;
    360         },
    361 
    362         clearDetails: function( model ) {
    363             if ( this.get('selection').single() )
    364                 return this;
    365 
    366             this.frame.sidebar.view().add( 'details', new Backbone.View({
    367                 priority: 80
    368             }).render() );
    369             return this;
    370363        },
    371364
     
    437430
    438431        sidebar: function() {
    439             var frame = this.frame;
    440 
    441             media.controller.State.prototype.sidebar.apply( this, arguments );
    442             this.details();
    443 
    444             frame.sidebar.view().add({
    445                 settings: new media.view.Settings.Gallery({
    446                     controller: frame,
    447                     model:      this.get('library').props,
    448                     priority:   40
    449                 }).render()
    450             });
     432            media.controller.Library.prototype.sidebar.apply( this, arguments );
     433            this.frame.sidebar.trigger('gallery-settings');
     434            return this;
    451435        }
    452436    });
     
    591575
    592576        bindHandlers: function() {
    593             this.menu.on( 'main', this.mainMenu, this );
    594             this.menu.on( 'batch', this.batchMenu, this );
    595             this.menu.on( 'gallery', this.galleryMenu, this );
    596 
    597             this.content.on( 'browse', this.browseContent, this );
    598             this.content.on( 'upload', this.uploadContent, this );
    599             this.content.on( 'embed', this.embedContent, this );
    600 
    601             this.sidebar.on( 'settings', this.settingsSidebar, this );
    602             this.sidebar.on( 'attachment-settings', this.attachmentSettingsSidebar, this );
    603 
    604             this.toolbar.on( 'main-attachments', this.mainAttachmentsToolbar, this );
    605             this.toolbar.on( 'main-embed', this.mainEmbedToolbar, this );
    606             this.toolbar.on( 'batch-edit', this.batchEditToolbar, this );
    607             this.toolbar.on( 'batch-add', this.batchAddToolbar, this );
    608             this.toolbar.on( 'gallery-edit', this.galleryEditToolbar, this );
    609             this.toolbar.on( 'gallery-add', this.galleryAddToolbar, this );
     577            var handlers = {
     578                    menu: {
     579                        main:    'mainMenu',
     580                        batch:   'batchMenu',
     581                        gallery: 'galleryMenu'
     582                    },
     583
     584                    content: {
     585                        browse: 'browseContent',
     586                        upload: 'uploadContent',
     587                        embed:  'embedContent'
     588                    },
     589
     590                    sidebar: {
     591                        'clear':               'clearSidebar',
     592                        'settings':            'settingsSidebar',
     593                        'attachment-settings': 'attachmentSettingsSidebar'
     594                    },
     595
     596                    toolbar: {
     597                        'main-attachments': 'mainAttachmentsToolbar',
     598                        'main-embed':       'mainEmbedToolbar',
     599                        'batch-edit':       'batchEditToolbar',
     600                        'batch-add':        'batchAddToolbar',
     601                        'gallery-edit':     'galleryEditToolbar',
     602                        'gallery-add':      'galleryAddToolbar'
     603                    }
     604                };
     605
     606            _.each( handlers, function( regionHandlers, region ) {
     607                _.each( regionHandlers, function( callback, handler ) {
     608                    this[ region ].on( 'activate:' + handler, this[ callback ], this );
     609                }, this );
     610            }, this );
     611
     612            this.sidebar.on( 'gallery-settings', this.onSidebarGallerySettings, this );
    610613        },
    611614
     
    622625
    623626        createStates: function() {
    624             var options = this.options;
     627            var options = this.options,
     628                main, gallery;
     629
     630            main = {
     631                multiple: this.options.multiple,
     632                menu:      'main',
     633                sidebar:   'attachment-settings',
     634
     635                // Update user settings when users adjust the
     636                // attachment display settings.
     637                displayUserSettings: true
     638            };
     639
     640            gallery = {
     641                multiple: true,
     642                menu:     'gallery',
     643                toolbar:  'gallery-add'
     644            };
    625645
    626646            // Add the default states.
    627647            this.states.add([
    628                 new media.controller.Library({
     648                new media.controller.Library( _.defaults({
    629649                    selection: options.selection,
    630                     library:   media.query( options.library ),
    631                     multiple:  this.options.multiple,
    632                     menu:      'main',
    633                     sidebar:   'attachment-settings'
    634                 }),
    635 
    636                 new media.controller.Upload({
    637                     multiple: this.options.multiple,
    638                     menu:      'main',
    639                     sidebar:   'attachment-settings'
    640                 }),
     650                    library:   media.query( options.library )
     651                }, main ) ),
     652
     653                new media.controller.Upload( main ),
    641654
    642655                new media.controller.Gallery({
     
    645658                }),
    646659
    647                 new media.controller.Library({
    648                     id:        'gallery-library',
    649                     library:   media.query({ type: 'image' }),
    650                     multiple:  true,
    651                     menu:      'gallery',
    652                     toolbar:   'gallery-add'
    653                 }),
    654 
    655                 new media.controller.Upload({
    656                     id:        'gallery-upload',
    657                     multiple:  true,
    658                     menu:      'gallery',
    659                     toolbar:   'gallery-add'
    660                 })
     660                new media.controller.Library( _.defaults({
     661                    id:      'gallery-library',
     662                    library: media.query({ type: 'image' })
     663                }, gallery ) ),
     664
     665                new media.controller.Upload( _.defaults({
     666                    id: 'gallery-upload'
     667                }, gallery ) )
    661668            ]);
    662669
     
    814821
    815822        // Sidebars
    816         settingsSidebar: function() {
     823        clearSidebar: function() {
    817824            this.sidebar.view( new media.view.Sidebar({
    818825                controller: this
     
    820827        },
    821828
    822         attachmentSettingsSidebar: function() {
     829        settingsSidebar: function( options ) {
    823830            this.sidebar.view( new media.view.Sidebar({
    824831                controller: this,
     832                silent:     options && options.silent,
     833
    825834                views: {
    826                     settings: new media.view.Settings.AttachmentDisplay({
     835                    details: new media.view.Attachment.Details({
    827836                        controller: this,
    828                         priority:   20
     837                        model:      this.state().get('selection').single(),
     838                        priority:   80
    829839                    }).render()
    830840                }
    831841            }) );
     842        },
     843
     844        onSidebarGallerySettings: function( options ) {
     845            this.sidebar.view().add({
     846                gallery: new media.view.Settings.Gallery({
     847                    controller: this,
     848                    model:      this.state().get('library').props,
     849                    priority:   40
     850                }).render()
     851            }, options );
     852        },
     853
     854        attachmentSettingsSidebar: function( options ) {
     855            var state = this.state(),
     856                display = state.get('details'),
     857                single = state.get('selection').single().cid;
     858
     859            this.settingsSidebar({ silent: true });
     860
     861            display[ single ] = display[ single ] || new Backbone.Model({
     862                align: getUserSetting( 'align', 'none' ),
     863                size:  getUserSetting( 'imgsize', 'medium' ),
     864                link:  getUserSetting( 'urlbutton', 'post' )
     865            });
     866
     867            this.sidebar.view().add({
     868                display: new media.view.Settings.AttachmentDisplay({
     869                    controller:   this,
     870                    model:        display[ single ],
     871                    priority:     100,
     872                    userSettings: state.get('displayUserSettings')
     873                }).render()
     874            }, options );
    832875        },
    833876
     
    21262169        },
    21272170
    2128         settings: {},
    2129 
    21302171        initialize: function() {
    2131             var settings = this.settings;
    2132 
    21332172            this.model = this.model || new Backbone.Model();
    2134 
    2135             _.each( settings, function( setting, key ) {
    2136                 if ( setting.name )
    2137                     this.model.set( key, getUserSetting( setting.name, setting.fallback ) );
    2138                 else
    2139                     this.model.set( key, this.model.get( key ) || setting.fallback );
    2140             }, this );
    2141 
    2142             this.model.validate = function( attrs ) {
    2143                 return _.any( attrs, function( value, key ) {
    2144                     // If we don't have a `setting` for the `key`, assume the
    2145                     // `value` is valid. Otherwise, check if the `value` exists
    2146                     // in the `setting.accepts` array.
    2147                     return settings[ key ] && ! _.contains( settings[ key ].accepts, value );
    2148                 });
    2149             };
    2150 
    2151             this.model.on( 'change', function( model, options ) {
    2152                 if ( ! options.changes )
    2153                     return;
    2154 
    2155                 _.each( _.keys( options.changes ), function( key ) {
    2156                     if ( settings[ key ] && settings[ key ].name )
    2157                         setUserSetting( settings[ key ].name, model.get( key ) );
    2158                 });
    2159             }, this );
    2160 
    21612173            this.model.on( 'change', this.updateChanges, this );
    21622174        },
    21632175
    21642176        render: function() {
    2165             this.$el.html( this.template( this.model.toJSON() ) );
     2177            this.$el.html( this.template( _.defaults({
     2178                model: this.model.toJSON()
     2179            }, this.options ) ) );
    21662180
    21672181            // Select the correct values.
     
    21712185
    21722186        update: function( key ) {
    2173             var setting = this.settings[ key ],
     2187            var value = this.model.get( key ),
    21742188                $setting = this.$('[data-setting="' + key + '"]'),
    21752189                $buttons;
    21762190
    2177             if ( ! setting )
     2191            // Bail if we didn't find a matching setting.
     2192            if ( ! $setting.length )
    21782193                return;
    21792194
    2180             if ( 'select' === setting.type ) {
    2181                 $setting.find('[value="' + this.model.get( key ) + '"]').attr( 'selected', true );
    2182             } else {
     2195            // Attempt to determine how the setting is rendered and update
     2196            // the selected value.
     2197
     2198            // Handle dropdowns.
     2199            if ( $setting.is('select') ) {
     2200                $setting.find('[value="' + value + '"]').attr( 'selected', true );
     2201
     2202            // Handle button groups.
     2203            } else if ( $setting.hasClass('button-group') ) {
    21832204                $buttons = $setting.find('button').removeClass('active');
    2184                 $buttons.filter( '[value="' + this.model.get( key ) + '"]' ).addClass('active');
     2205                $buttons.filter( '[value="' + value + '"]' ).addClass('active');
    21852206            }
    21862207        },
    21872208
    21882209        updateHandler: function( event ) {
    2189             var $setting = $( event.target ).closest('[data-setting]');
     2210            var $setting = $( event.target ).closest('[data-setting]'),
     2211                value = event.target.value,
     2212                userSetting;
    21902213
    21912214            event.preventDefault();
    21922215
    2193             if ( $setting.length )
    2194                 this.model.set( $setting.data('setting'), event.target.value );
     2216            if ( ! $setting.length )
     2217                return;
     2218
     2219            this.model.set( $setting.data('setting'), value );
     2220
     2221            // If the setting has a corresponding user setting,
     2222            // update that as well.
     2223            if ( userSetting = $setting.data('userSetting') )
     2224                setUserSetting( userSetting, value );
    21952225        },
    21962226
     
    22082238        template:  media.template('attachment-display-settings'),
    22092239
    2210         settings: {
    2211             align: {
    2212                 accepts:  ['left','center','right','none'],
    2213                 name:     'align',
    2214                 fallback: 'none'
    2215             },
    2216             link: {
    2217                 accepts:  ['post','file','none'],
    2218                 name:     'urlbutton',
    2219                 fallback: 'post'
    2220             },
    2221             size: {
    2222                 // @todo: Dynamically generate these.
    2223                 accepts:  ['thumbnail','medium','large','full'],
    2224                 name:     'imgsize',
    2225                 fallback: 'medium'
    2226             }
     2240        initialize: function() {
     2241            _.defaults( this.options, {
     2242                userSettings: false
     2243            });
     2244            media.view.Settings.prototype.initialize.apply( this, arguments );
    22272245        }
    22282246    });
     
    22332251    media.view.Settings.Gallery = media.view.Settings.extend({
    22342252        className: 'gallery-settings',
    2235         template:  media.template('gallery-settings'),
    2236 
    2237         settings: {
    2238             columns: {
    2239                 accepts:  _.invoke( _.range( 1, 10 ), 'toString' ),
    2240                 fallback: '3',
    2241                 type:     'select'
    2242             },
    2243             link: {
    2244                 accepts:  ['post','file'],
    2245                 fallback: 'post'
    2246             }
    2247         }
     2253        template:  media.template('gallery-settings')
    22482254    });
    22492255
  • trunk/wp-includes/media.php

    r22437 r22466  
    14181418
    14191419        <h4><?php _e('Alignment'); ?></h4>
    1420         <div class="alignment button-group button-large" data-setting="align">
     1420        <div class="alignment button-group button-large"
     1421            data-setting="align"
     1422            <# if ( userSettings ) { #>
     1423                data-user-setting="align"
     1424            <# } #>>
     1425
    14211426            <button class="button" value="left">
    14221427                <?php esc_attr_e('Left'); ?>
     
    14281433                <?php esc_attr_e('Right'); ?>
    14291434            </button>
    1430             <button class="button" value="none">
     1435            <button class="button active" value="none">
    14311436                <?php esc_attr_e('None'); ?>
    14321437            </button>
     
    14341439
    14351440        <h4><?php _e('Link To'); ?></h4>
    1436         <div class="link-to button-group button-large" data-setting="link">
    1437             <button class="button" value="post">
     1441        <div class="link-to button-group button-large"
     1442            data-setting="link"
     1443            <# if ( userSettings ) { #>
     1444                data-user-setting="urlbutton"
     1445            <# } #>>
     1446
     1447            <button class="button active" value="post">
    14381448                <?php esc_attr_e('Attachment Page'); ?>
    14391449            </button>
     
    14511461
    14521462        <h4><?php _e('Link To'); ?></h4>
    1453         <div class="link-to button-group" data-setting="link">
    1454             <button class="button" value="post">
     1463        <div class="link-to button-group"
     1464            data-setting="link">
     1465
     1466            <button class="button active" value="post">
    14551467                <?php esc_attr_e('Attachment Page'); ?>
    14561468            </button>
     
    14621474        <h4><?php _e('Gallery Columns'); ?></h4>
    14631475
    1464         <select class="columns" name="columns" data-setting="columns">
     1476        <select class="columns" name="columns"
     1477            data-setting="columns">
    14651478            <?php for ( $i = 1; $i <= 9; $i++ ) : ?>
    1466                 <option value="<?php echo esc_attr( $i ); ?>">
     1479                <option value="<?php echo esc_attr( $i ); ?>" <?php selected( $i, 3 ); ?>>
    14671480                    <?php echo esc_html( $i ); ?>
    14681481                </option>
Note: See TracChangeset for help on using the changeset viewer.