WordPress.org

Make WordPress Core

Changeset 23024


Ignore:
Timestamp:
12/04/12 16:21:57 (17 months ago)
Author:
nacin
Message:

Media: Disable 'Insert gallery' and 'Set featured image' if nothing is queued. Converts selection toolbars to use the newer view manager. props koopersmith, fixes #22714.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/js/custom-background.js

    r23006 r23024  
    2626            event.preventDefault(); 
    2727 
     28            // If the media frame already exists, reopen it. 
    2829            if ( frame ) { 
    2930                frame.open(); 
     
    3132            } 
    3233 
     34            // Create the media frame. 
    3335            frame = wp.media({ 
    34                 title:     $el.data('choose'), 
    35                 library:   { 
     36                // Set the title of the modal. 
     37                title: $el.data('choose'), 
     38 
     39                // Tell the modal to show only images. 
     40                library: { 
    3641                    type: 'image' 
     42                }, 
     43 
     44                // Customize the submit button. 
     45                button: { 
     46                    // Set the text of the button. 
     47                    text: $el.data('update'), 
     48                    // Tell the button not to close the modal, since we're 
     49                    // going to refresh the page when the image is selected. 
     50                    close: false 
    3751                } 
    3852            }); 
    3953 
    40             frame.on( 'toolbar:render:select', function( view ) { 
    41                 view.set({ 
    42                     select: { 
    43                         style: 'primary', 
    44                         text:  $el.data('update'), 
     54            // When an image is selected, run a callback. 
     55            frame.on( 'select', function() { 
     56                // Grab the selected attachment. 
     57                var attachment = frame.state().get('selection').first(); 
    4558 
    46                         click: function() { 
    47                             var attachment = frame.state().get('selection').first(); 
    48                             $.post( ajaxurl, { 
    49                                 action: 'set-background-image', 
    50                                 attachment_id: attachment.id, 
    51                                 size: 'full' 
    52                             }, function() { 
    53                                 window.location.reload(); 
    54                             }); 
    55                         } 
    56                     } 
     59                // Run an AJAX request to set the background image. 
     60                $.post( ajaxurl, { 
     61                    action: 'set-background-image', 
     62                    attachment_id: attachment.id, 
     63                    size: 'full' 
     64                }).done( function() { 
     65                    // When the request completes, reload the window. 
     66                    window.location.reload(); 
    5767                }); 
    5868            }); 
    5969 
    60             frame.setState('library').open(); 
     70            // Finally, open the modal. 
     71            frame.open(); 
    6172        }); 
    6273    }); 
  • trunk/wp-admin/js/custom-header.js

    r23009 r23024  
    1919            event.preventDefault(); 
    2020 
     21            // Create the media frame. 
    2122            frame = wp.media({ 
    22                 title:     $el.data('choose'), 
    23                 library:   { 
     23                // Set the title of the modal. 
     24                title: $el.data('choose'), 
     25 
     26                // Tell the modal to show only images. 
     27                library: { 
    2428                    type: 'image' 
     29                }, 
     30 
     31                // Customize the submit button. 
     32                button: { 
     33                    // Set the text of the button. 
     34                    text: $el.data('update'), 
     35                    // Tell the button not to close the modal, since we're 
     36                    // going to refresh the page when the image is selected. 
     37                    close: false 
    2538                } 
    2639            }); 
    2740 
    28             frame.on( 'toolbar:render:select', function( view ) { 
    29                 view.set({ 
    30                     select: { 
    31                         style: 'primary', 
    32                         text:  $el.data('update'), 
     41            // When an image is selected, run a callback. 
     42            frame.on( 'select', function() { 
     43                // Grab the selected attachment. 
     44                var attachment = frame.state().get('selection').first(), 
     45                    link = $el.data('updateLink'); 
    3346 
    34                         click: function() { 
    35                             var attachment = frame.state().get('selection').first(), 
    36                                 link = $el.data('updateLink'); 
    37  
    38                             window.location = link + '&file=' + attachment.id; 
    39                         } 
    40                     } 
    41                 }); 
     47                // Tell the browser to navigate to the crop step. 
     48                window.location = link + '&file=' + attachment.id; 
    4249            }); 
    4350 
    44             frame.setState('library').open(); 
     51            frame.open(); 
    4552        }); 
    4653    }); 
  • trunk/wp-includes/css/media-views.css

    r23023 r23024  
    11751175} 
    11761176 
     1177.media-selection .selection-view { 
     1178    display: inline-block; 
     1179} 
     1180 
    11771181.media-selection .attachments { 
    11781182    display: inline-block; 
  • trunk/wp-includes/js/media-views.js

    r23015 r23024  
    390390 
    391391        activate: function() { 
    392             var library = this.get('library'), 
    393                 selection = this.get('selection'), 
    394                 mode; 
    395  
    396392            if ( this.get('syncLastSelection') ) { 
    397393                this.getLastSelection(); 
     
    405401            wp.Uploader.queue.on( 'add', this.uploading, this ); 
    406402 
    407             selection.on( 'add remove reset', this.refreshSelection, this ); 
     403            this.get('selection').on( 'add remove reset', this.refreshContent, this ); 
    408404 
    409405            this.on( 'insert', this._insertDisplaySettings, this ); 
     
    489485 
    490486            selection.reset( lastSelection.toArray() ).single( lastSelection.single() ); 
    491         }, 
    492  
    493         refreshSelection: function() { 
    494             this.frame.toolbar.get().refresh(); 
    495             this.trigger( 'refresh:selection', this, this.get('selection') ); 
    496             this.refreshContent(); 
    497487        }, 
    498488 
     
    13181308 
    13191309        createToolbar: function( toolbar ) { 
    1320             menu.view = new media.view.Toolbar({ 
     1310            toolbar.view = new media.view.Toolbar({ 
    13211311                controller: this 
    13221312            }); 
     
    14261416                selection: [], 
    14271417                library:   {}, 
    1428                 multiple:  false 
     1418                multiple:  false, 
     1419                state:    'library' 
    14291420            }); 
    14301421 
     
    14691460            this.on( 'content:render:upload', this.uploadContent, this ); 
    14701461            this.on( 'toolbar:create:select', this.createSelectToolbar, this ); 
    1471  
    1472             this.on( 'refresh:selection', this.refreshSelectToolbar, this ); 
    14731462        }, 
    14741463 
     
    15181507        // Toolbars 
    15191508        createSelectToolbar: function( toolbar, options ) { 
    1520             options = _.defaults( options || {}, { 
    1521                 event:  'select', 
    1522                 silent: false, 
    1523                 state:  false 
    1524             }); 
    1525  
    1526             toolbar.view = new media.view.Toolbar({ 
    1527                 controller: this, 
    1528                 silent:     options.silent, 
    1529  
    1530                 items: { 
    1531                     select: { 
    1532                         style:    'primary', 
    1533                         text:     l10n.select, 
    1534                         priority: 80, 
    1535  
    1536                         click: function() { 
    1537                             var controller = this.controller; 
    1538  
    1539                             controller.close(); 
    1540                             controller.state().trigger( options.event ); 
    1541                             controller.reset(); 
    1542                             if ( options.state ) 
    1543                                 controller.setState( options.state ); 
    1544                         } 
    1545                     } 
    1546                 } 
    1547             }); 
    1548         }, 
    1549  
    1550         refreshSelectToolbar: function() { 
    1551             var selection = this.state().get('selection'); 
    1552  
    1553             if ( ! selection || 'select' !== this.toolbar.mode() ) 
    1554                 return; 
    1555  
    1556             this.toolbar.get().get('select').model.set( 'disabled', ! selection.length ); 
     1509            options = options || this.options.button || {}; 
     1510            options.controller = this; 
     1511 
     1512            toolbar.view = new media.view.Toolbar.Select( options ); 
    15571513        } 
    15581514    }); 
     
    15651521            _.defaults( this.options, { 
    15661522                multiple:  true, 
    1567                 editing:   false 
     1523                editing:   false, 
     1524                state:    'insert' 
    15681525            }); 
    15691526 
     
    16521609            media.view.MediaFrame.Select.prototype.bindHandlers.apply( this, arguments ); 
    16531610            this.on( 'menu:create:gallery', this.createMenu, this ); 
    1654             this.on( 'toolbar:create:main-insert', this.createSelectionToolbar, this ); 
    1655             this.on( 'toolbar:create:main-gallery', this.createSelectionToolbar, this ); 
     1611            this.on( 'toolbar:create:main-insert', this.createToolbar, this ); 
     1612            this.on( 'toolbar:create:main-gallery', this.createToolbar, this ); 
     1613            this.on( 'toolbar:create:featured-image', this.featuredImageToolbar, this ); 
     1614            this.on( 'toolbar:create:main-embed', this.mainEmbedToolbar, this ); 
    16561615 
    16571616            var handlers = { 
     
    16691628                        'main-insert':      'mainInsertToolbar', 
    16701629                        'main-gallery':     'mainGalleryToolbar', 
    1671                         'main-embed':       'mainEmbedToolbar', 
    1672                         'featured-image':   'featuredImageToolbar', 
    16731630                        'gallery-edit':     'galleryEditToolbar', 
    16741631                        'gallery-add':      'galleryAddToolbar' 
     
    17581715 
    17591716        // Toolbars 
    1760         createSelectionToolbar: function( toolbar ) { 
    1761             toolbar.view = new media.view.Toolbar.Selection({ 
     1717        selectionStatusToolbar: function( view ) { 
     1718            var editable = this.state().get('editable'); 
     1719 
     1720            view.set( 'selection', new media.view.Selection({ 
    17621721                controller: this, 
    1763                 editable:   this.state().get('editable') 
    1764             }); 
     1722                collection: this.state().get('selection'), 
     1723                priority:   -40, 
     1724 
     1725                // If the selection is editable, pass the callback to 
     1726                // switch the content mode. 
     1727                editable: editable && function() { 
     1728                    this.controller.content.mode('edit-selection'); 
     1729                } 
     1730            }).render() ); 
    17651731        }, 
    17661732 
     
    17681734            var controller = this; 
    17691735 
    1770             view.button = 'insert'; 
     1736            this.selectionStatusToolbar( view ); 
     1737 
    17711738            view.set( 'insert', { 
    17721739                style:    'primary', 
    17731740                priority: 80, 
    17741741                text:     l10n.insertIntoPost, 
     1742                requires: { selection: true }, 
    17751743 
    17761744                click: function() { 
     
    17871755            var controller = this; 
    17881756 
    1789             view.button = 'gallery'; 
     1757            this.selectionStatusToolbar( view ); 
     1758 
    17901759            view.set( 'gallery', { 
    17911760                style:    'primary', 
    17921761                text:     l10n.createNewGallery, 
    17931762                priority: 60, 
     1763                requires: { selection: true }, 
    17941764 
    17951765                click: function() { 
     
    18081778        }, 
    18091779 
    1810         featuredImageToolbar: function() { 
    1811             this.toolbar.set( new media.view.Toolbar.Select({ 
    1812                 controller: this, 
    1813                 text:       l10n.setFeaturedImage, 
    1814                 state:      this.options.state || 'upload' 
    1815             }) ); 
    1816         }, 
    1817  
    1818         mainEmbedToolbar: function() { 
    1819             this.toolbar.set( new media.view.Toolbar.Embed({ 
     1780        featuredImageToolbar: function( toolbar ) { 
     1781            this.createSelectToolbar( toolbar, { 
     1782                text:  l10n.setFeaturedImage, 
     1783                state: this.options.state || 'upload' 
     1784            }); 
     1785        }, 
     1786 
     1787        mainEmbedToolbar: function( toolbar ) { 
     1788            toolbar.view = new media.view.Toolbar.Embed({ 
    18201789                controller: this 
    1821             }) ); 
    1822  
    1823             this.$el.removeClass('hide-toolbar'); 
     1790            }); 
    18241791        }, 
    18251792 
     
    18331800                        text:     editing ? l10n.updateGallery : l10n.insertGallery, 
    18341801                        priority: 80, 
     1802                        requires: { library: true }, 
    18351803 
    18361804                        click: function() { 
     
    22212189 
    22222190        initialize: function() { 
    2223             this._views     = {}; 
    2224             this.$primary   = $('<div class="media-toolbar-primary" />').prependTo( this.$el ); 
    2225             this.$secondary = $('<div class="media-toolbar-secondary" />').prependTo( this.$el ); 
     2191            var state = this.controller.state(), 
     2192                selection = this.selection = state.get('selection'), 
     2193                library = this.library = state.get('library'); 
     2194 
     2195            this._views = {}; 
     2196 
     2197            // The toolbar is composed of two `PriorityList` views. 
     2198            this.primary   = new media.view.PriorityList(); 
     2199            this.secondary = new media.view.PriorityList(); 
     2200            this.primary.$el.addClass('media-toolbar-primary'); 
     2201            this.secondary.$el.addClass('media-toolbar-secondary'); 
     2202 
     2203            this.views.set([ this.secondary, this.primary ]); 
    22262204 
    22272205            if ( this.options.items ) 
     
    22302208            if ( ! this.options.silent ) 
    22312209                this.render(); 
    2232         }, 
    2233  
    2234         destroy: function() { 
    2235             this.remove(); 
    2236  
    2237             if ( this.model ) 
    2238                 this.model.off( null, null, this ); 
    2239  
    2240             if ( this.collection ) 
    2241                 this.collection.off( null, null, this ); 
    2242  
    2243             this.controller.off( null, null, this ); 
    2244  
    2245             _.each( this._views, function( view ) { 
    2246                 if ( view.destroy ) 
    2247                     view.destroy(); 
    2248             }); 
    2249         }, 
    2250  
    2251         render: function() { 
    2252             var views = _.chain( this._views ).sortBy( function( view ) { 
    2253                 return view.options.priority || 10; 
    2254             }).groupBy( function( view ) { 
    2255                 return ( view.options.priority || 10 ) > 0 ? 'primary' : 'secondary'; 
    2256             }).value(); 
    2257  
    2258             // Make sure to detach the elements we want to reuse. 
    2259             // Otherwise, `jQuery.html()` will unbind their events. 
    2260             $( _.pluck( this._views, 'el' ) ).detach(); 
    2261             this.$primary.html( _.pluck( views.primary || [], 'el' ) ); 
    2262             this.$secondary.html( _.pluck( views.secondary || [], 'el' ) ); 
    2263  
     2210 
     2211            selection.on( 'add remove reset', this.refresh, this ); 
     2212            library.on( 'add remove reset', this.refresh, this ); 
     2213        }, 
     2214 
     2215        dispose: function() { 
     2216            this.selection.off( null, null, this ); 
     2217            this.library.off( null, null, this ); 
     2218            return media.View.prototype.dispose.apply( this, arguments ); 
     2219        }, 
     2220 
     2221        ready: function() { 
    22642222            this.refresh(); 
    2265  
    2266             return this; 
    22672223        }, 
    22682224 
    22692225        set: function( id, view, options ) { 
     2226            var list; 
    22702227            options = options || {}; 
    22712228 
     
    22852242 
    22862243                this._views[ id ] = view; 
     2244 
     2245                list = view.options.priority < 0 ? 'secondary' : 'primary'; 
     2246                this[ list ].set( id, view, options ); 
    22872247            } 
    22882248 
    22892249            if ( ! options.silent ) 
    2290                 this.render(); 
     2250                this.refresh(); 
     2251 
    22912252            return this; 
    22922253        }, 
     
    22982259        unset: function( id, options ) { 
    22992260            delete this._views[ id ]; 
     2261            this.primary.unset( id, options ); 
     2262            this.secondary.unset( id, options ); 
     2263 
    23002264            if ( ! options || ! options.silent ) 
    2301                 this.render(); 
     2265                this.refresh(); 
    23022266            return this; 
    23032267        }, 
    23042268 
    2305         refresh: function() {} 
     2269        refresh: function() { 
     2270            var state = this.controller.state(), 
     2271                library = state.get('library'), 
     2272                selection = state.get('selection'); 
     2273 
     2274            _.each( this._views, function( button ) { 
     2275                if ( ! button.model || ! button.options || ! button.options.requires ) 
     2276                    return; 
     2277 
     2278                var requires = button.options.requires, 
     2279                    disabled = false; 
     2280 
     2281                if ( requires.selection && ! selection.length ) 
     2282                    disabled = true; 
     2283                else if ( requires.library && ! library.length ) 
     2284                    disabled = true; 
     2285 
     2286                button.model.set( 'disabled', disabled ); 
     2287            }); 
     2288        } 
    23062289    }); 
    23072290 
     
    23212304                reset: true, 
    23222305                close: true, 
    2323                 text:  l10n.select 
     2306                text:  l10n.select, 
     2307 
     2308                // Does the button rely on the selection? 
     2309                requires: { 
     2310                    selection: true 
     2311                } 
    23242312            }); 
    23252313 
     
    23292317                    text:     options.text, 
    23302318                    priority: 80, 
    2331                     click:    this.clickSelect 
     2319                    click:    this.clickSelect, 
     2320                    requires: options.requires 
    23322321                } 
    23332322            }); 
     
    23662355        }, 
    23672356 
     2357        dispose: function() { 
     2358            this.controller.state().props.off( 'change:url', this.refresh, this ); 
     2359            media.view.Toolbar.Select.prototype.dispose.apply( this, arguments ); 
     2360        }, 
     2361 
    23682362        refresh: function() { 
    23692363            var url = this.controller.state().props.get('url'); 
    23702364            this.get('select').model.set( 'disabled', ! url || /^https?:\/\/$/.test(url) ); 
    2371         } 
    2372     }); 
    2373  
    2374     // wp.media.view.Toolbar.Selection 
    2375     // ------------------------------- 
    2376     media.view.Toolbar.Selection = media.view.Toolbar.extend({ 
    2377         button: 'insert', 
    2378  
    2379         initialize: function() { 
    2380             var controller = this.controller; 
    2381  
    2382             this.options.items = _.defaults( this.options.items || {}, { 
    2383                 selection: new media.view.Selection({ 
    2384                     controller: controller, 
    2385                     collection: controller.state().get('selection'), 
    2386                     priority:   -40, 
    2387  
    2388                     // If the selection is editable, pass the callback to 
    2389                     // switch the content mode. 
    2390                     editable: this.options.editable && function() { 
    2391                         this.controller.content.mode('edit-selection'); 
    2392                     } 
    2393                 }).render() 
    2394             }); 
    2395  
    2396             media.view.Toolbar.prototype.initialize.apply( this, arguments ); 
    2397         }, 
    2398  
    2399         refresh: function() { 
    2400             var selection = this.controller.state().get('selection'), 
    2401                 button = this.get( this.button ); 
    2402  
    2403             if ( ! button ) 
    2404                 return; 
    2405  
    2406             button.model.set( 'disabled', ! selection.length ); 
     2365 
     2366            media.view.Toolbar.Select.prototype.refresh.apply( this, arguments ); 
    24072367        } 
    24082368    }); 
     
    25162476                this.render(); 
    25172477        }, 
    2518  
    2519         destroy: this.dispose, 
    25202478 
    25212479        set: function( id, view, options ) { 
     
    36503608            }); 
    36513609 
     3610            this.views.set( '.selection-view', this.attachments ); 
    36523611            this.collection.on( 'add remove reset', this.refresh, this ); 
    36533612        }, 
    36543613 
    3655         destroy: function() { 
    3656             this.remove(); 
    3657             this.collection.off( 'add remove reset', this.refresh, this ); 
    3658             this.attachments.destroy(); 
    3659         }, 
    3660  
    3661         render: function() { 
    3662             this.attachments.$el.detach(); 
    3663             this.attachments.render(); 
    3664  
    3665             this.$el.html( this.template( this.options ) ); 
    3666  
    3667             this.$('.selection-view').replaceWith( this.attachments.$el ); 
     3614        ready: function() { 
    36683615            this.refresh(); 
    3669             return this; 
    36703616        }, 
    36713617 
     
    37293675        }, 
    37303676 
    3731         destroy: function() { 
    3732             this.model.off( null, null, this ); 
    3733         }, 
    3734  
    37353677        render: function() { 
    37363678            this.$el.html( this.template( _.defaults({ 
     
    39353877        }, 
    39363878 
    3937         destroy: function() { 
    3938             this.model.off( null, null, this ); 
    3939         }, 
    3940  
    39413879        render: function() { 
    39423880            var compat = this.model.get('compat'); 
     
    40063944            view.render(); 
    40073945            this._settings.$el.replaceWith( view.$el ); 
    4008             if ( this._settings.destroy ) 
    4009                 this._settings.destroy(); 
    40103946            this._settings.remove(); 
    40113947            this._settings = view; 
     
    40563992        }, 
    40573993 
    4058         destroy: function() { 
    4059             this.model.off( null, null, this ); 
    4060         }, 
    4061  
    40623994        render: function() { 
    40633995            var $input = this.$input; 
     
    41024034        }, 
    41034035 
    4104         destroy: function() { 
    4105             this.model.off( null, null, this ); 
    4106             media.view.Settings.AttachmentDisplay.prototype.destroy.apply( this, arguments ); 
    4107         }, 
    4108  
    41094036        updateImage: function() { 
    41104037            this.$('img').attr( 'src', this.model.get('url') ); 
Note: See TracChangeset for help on using the changeset viewer.