Ticket #22714: 22714.diff
| File 22714.diff, 18.1 KB (added by , 13 years ago) |
|---|
-
wp-admin/js/custom-background.js
25 25 26 26 event.preventDefault(); 27 27 28 // If the media frame already exists, reopen it. 28 29 if ( frame ) { 29 30 frame.open(); 30 31 return; 31 32 } 32 33 34 // Create the media frame. 33 35 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: { 36 41 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 37 51 } 38 52 }); 39 53 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(); 45 58 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(); 57 67 }); 58 68 }); 59 69 60 frame.setState('library').open(); 70 // Finally, open the modal. 71 frame.open(); 61 72 }); 62 73 }); 63 74 })(jQuery); 75 No newline at end of file -
wp-admin/js/custom-header.js
18 18 var $el = $(this); 19 19 event.preventDefault(); 20 20 21 // Create the media frame. 21 22 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: { 24 28 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 25 38 } 26 39 }); 27 40 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'); 33 46 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; 42 49 }); 43 50 44 frame. setState('library').open();51 frame.open(); 45 52 }); 46 53 }); 47 54 }(jQuery)); -
wp-includes/css/media-views.css
1170 1170 background: red; 1171 1171 } 1172 1172 1173 .media-selection .selection-view { 1174 display: inline-block; 1175 } 1176 1173 1177 .media-selection .attachments { 1174 1178 display: inline-block; 1175 1179 height: 48px; -
wp-includes/js/media-views.js
389 389 }, 390 390 391 391 activate: function() { 392 var library = this.get('library'),393 selection = this.get('selection'),394 mode;395 396 392 if ( this.get('syncLastSelection') ) { 397 393 this.getLastSelection(); 398 394 } … … 404 400 405 401 wp.Uploader.queue.on( 'add', this.uploading, this ); 406 402 407 selection.on( 'add remove reset', this.refreshSelection, this );403 this.get('selection').on( 'add remove reset', this.refreshContent, this ); 408 404 409 405 this.on( 'insert', this._insertDisplaySettings, this ); 410 406 … … 490 486 selection.reset( lastSelection.toArray() ).single( lastSelection.single() ); 491 487 }, 492 488 493 refreshSelection: function() {494 this.frame.toolbar.get().refresh();495 this.trigger( 'refresh:selection', this, this.get('selection') );496 this.refreshContent();497 },498 499 489 refreshContent: function() { 500 490 var selection = this.get('selection'), 501 491 frame = this.frame, … … 1317 1307 }, 1318 1308 1319 1309 createToolbar: function( toolbar ) { 1320 menu.view = new media.view.Toolbar({1310 toolbar.view = new media.view.Toolbar({ 1321 1311 controller: this 1322 1312 }); 1323 1313 }, … … 1425 1415 _.defaults( this.options, { 1426 1416 selection: [], 1427 1417 library: {}, 1428 multiple: false 1418 multiple: false, 1419 state: 'library' 1429 1420 }); 1430 1421 1431 1422 this.createSelection(); … … 1468 1459 this.on( 'content:create:browse', this.browseContent, this ); 1469 1460 this.on( 'content:render:upload', this.uploadContent, this ); 1470 1461 this.on( 'toolbar:create:select', this.createSelectToolbar, this ); 1471 1472 this.on( 'refresh:selection', this.refreshSelectToolbar, this );1473 1462 }, 1474 1463 1475 1464 // Routers … … 1517 1506 1518 1507 // Toolbars 1519 1508 createSelectToolbar: function( toolbar, options ) { 1520 options = _.defaults( options || {}, { 1521 event: 'select', 1522 silent: false, 1523 state: false 1524 }); 1509 options = options || this.options.button || {}; 1510 options.controller = this; 1525 1511 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 ); 1512 toolbar.view = new media.view.Toolbar.Select( options ); 1557 1513 } 1558 1514 }); 1559 1515 … … 1564 1520 initialize: function() { 1565 1521 _.defaults( this.options, { 1566 1522 multiple: true, 1567 editing: false 1523 editing: false, 1524 state: 'insert' 1568 1525 }); 1569 1526 1570 1527 media.view.MediaFrame.Select.prototype.initialize.apply( this, arguments ); … … 1651 1608 bindHandlers: function() { 1652 1609 media.view.MediaFrame.Select.prototype.bindHandlers.apply( this, arguments ); 1653 1610 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 ); 1656 1615 1657 1616 var handlers = { 1658 1617 menu: { … … 1668 1627 toolbar: { 1669 1628 'main-insert': 'mainInsertToolbar', 1670 1629 'main-gallery': 'mainGalleryToolbar', 1671 'main-embed': 'mainEmbedToolbar',1672 'featured-image': 'featuredImageToolbar',1673 1630 'gallery-edit': 'galleryEditToolbar', 1674 1631 'gallery-add': 'galleryAddToolbar' 1675 1632 } … … 1757 1714 }, 1758 1715 1759 1716 // 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({ 1762 1721 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() ); 1765 1731 }, 1766 1732 1767 1733 mainInsertToolbar: function( view ) { 1768 1734 var controller = this; 1769 1735 1770 view.button = 'insert'; 1736 this.selectionStatusToolbar( view ); 1737 1771 1738 view.set( 'insert', { 1772 1739 style: 'primary', 1773 1740 priority: 80, 1774 1741 text: l10n.insertIntoPost, 1742 requires: { selection: true }, 1775 1743 1776 1744 click: function() { 1777 1745 var state = controller.state(), … … 1786 1754 mainGalleryToolbar: function( view ) { 1787 1755 var controller = this; 1788 1756 1789 view.button = 'gallery'; 1757 this.selectionStatusToolbar( view ); 1758 1790 1759 view.set( 'gallery', { 1791 1760 style: 'primary', 1792 1761 text: l10n.createNewGallery, 1793 1762 priority: 60, 1763 requires: { selection: true }, 1794 1764 1795 1765 click: function() { 1796 1766 var selection = controller.state().get('selection'), … … 1807 1777 }); 1808 1778 }, 1809 1779 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 }) ); 1780 featuredImageToolbar: function( toolbar ) { 1781 this.createSelectToolbar( toolbar, { 1782 text: l10n.setFeaturedImage, 1783 state: this.options.state || 'upload' 1784 }); 1816 1785 }, 1817 1786 1818 mainEmbedToolbar: function( ) {1819 t his.toolbar.set(new media.view.Toolbar.Embed({1787 mainEmbedToolbar: function( toolbar ) { 1788 toolbar.view = new media.view.Toolbar.Embed({ 1820 1789 controller: this 1821 }) ); 1822 1823 this.$el.removeClass('hide-toolbar'); 1790 }); 1824 1791 }, 1825 1792 1826 1793 galleryEditToolbar: function() { … … 1832 1799 style: 'primary', 1833 1800 text: editing ? l10n.updateGallery : l10n.insertGallery, 1834 1801 priority: 80, 1802 requires: { library: true }, 1835 1803 1836 1804 click: function() { 1837 1805 var controller = this.controller, … … 2220 2188 className: 'media-toolbar', 2221 2189 2222 2190 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'); 2226 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 ]); 2204 2227 2205 if ( this.options.items ) 2228 2206 this.set( this.options.items, { silent: true }); 2229 2207 2230 2208 if ( ! this.options.silent ) 2231 2209 this.render(); 2210 2211 selection.on( 'add remove reset', this.refresh, this ); 2212 library.on( 'add remove reset', this.refresh, this ); 2232 2213 }, 2233 2214 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 }); 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 ); 2249 2219 }, 2250 2220 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 2221 ready: function() { 2264 2222 this.refresh(); 2265 2266 return this;2267 2223 }, 2268 2224 2269 2225 set: function( id, view, options ) { 2226 var list; 2270 2227 options = options || {}; 2271 2228 2272 2229 // Accept an object with an `id` : `view` mapping. … … 2284 2241 view.controller = view.controller || this.controller; 2285 2242 2286 2243 this._views[ id ] = view; 2244 2245 list = view.options.priority < 0 ? 'secondary' : 'primary'; 2246 this[ list ].set( id, view, options ); 2287 2247 } 2288 2248 2289 2249 if ( ! options.silent ) 2290 this.render(); 2250 this.refresh(); 2251 2291 2252 return this; 2292 2253 }, 2293 2254 … … 2297 2258 2298 2259 unset: function( id, options ) { 2299 2260 delete this._views[ id ]; 2261 this.primary.unset( id, options ); 2262 this.secondary.unset( id, options ); 2263 2300 2264 if ( ! options || ! options.silent ) 2301 this.re nder();2265 this.refresh(); 2302 2266 return this; 2303 2267 }, 2304 2268 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 } 2306 2289 }); 2307 2290 2308 2291 // wp.media.view.Toolbar.Select … … 2320 2303 state: false, 2321 2304 reset: true, 2322 2305 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 } 2324 2312 }); 2325 2313 2326 2314 options.items = _.defaults( options.items || {}, { … … 2328 2316 style: 'primary', 2329 2317 text: options.text, 2330 2318 priority: 80, 2331 click: this.clickSelect 2319 click: this.clickSelect, 2320 requires: options.requires 2332 2321 } 2333 2322 }); 2334 2323 … … 2365 2354 this.controller.state().props.on( 'change:url', this.refresh, this ); 2366 2355 }, 2367 2356 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 2368 2362 refresh: function() { 2369 2363 var url = this.controller.state().props.get('url'); 2370 2364 this.get('select').model.set( 'disabled', ! url || /^https?:\/\/$/.test(url) ); 2371 }2372 });2373 2365 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 ); 2366 media.view.Toolbar.Select.prototype.refresh.apply( this, arguments ); 2407 2367 } 2408 2368 }); 2409 2369 … … 2516 2476 this.render(); 2517 2477 }, 2518 2478 2519 destroy: this.dispose,2520 2521 2479 set: function( id, view, options ) { 2522 2480 var priority, views, index; 2523 2481 … … 3649 3607 AttachmentView: media.view.Attachment.Selection 3650 3608 }); 3651 3609 3610 this.views.set( '.selection-view', this.attachments ); 3652 3611 this.collection.on( 'add remove reset', this.refresh, this ); 3653 3612 }, 3654 3613 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() { 3668 3615 this.refresh(); 3669 return this;3670 3616 }, 3671 3617 3672 3618 refresh: function() { … … 3728 3674 this.model.on( 'change', this.updateChanges, this ); 3729 3675 }, 3730 3676 3731 destroy: function() {3732 this.model.off( null, null, this );3733 },3734 3735 3677 render: function() { 3736 3678 this.$el.html( this.template( _.defaults({ 3737 3679 model: this.model.toJSON() … … 3934 3876 this.model.on( 'change:compat', this.render, this ); 3935 3877 }, 3936 3878 3937 destroy: function() {3938 this.model.off( null, null, this );3939 },3940 3941 3879 render: function() { 3942 3880 var compat = this.model.get('compat'); 3943 3881 if ( ! compat || ! compat.item ) … … 4005 3943 settings: function( view ) { 4006 3944 view.render(); 4007 3945 this._settings.$el.replaceWith( view.$el ); 4008 if ( this._settings.destroy )4009 this._settings.destroy();4010 3946 this._settings.remove(); 4011 3947 this._settings = view; 4012 3948 }, … … 4055 3991 this.model.on( 'change:url', this.render, this ); 4056 3992 }, 4057 3993 4058 destroy: function() {4059 this.model.off( null, null, this );4060 },4061 4062 3994 render: function() { 4063 3995 var $input = this.$input; 4064 3996 … … 4101 4033 this.model.on( 'change:url', this.updateImage, this ); 4102 4034 }, 4103 4035 4104 destroy: function() {4105 this.model.off( null, null, this );4106 media.view.Settings.AttachmentDisplay.prototype.destroy.apply( this, arguments );4107 },4108 4109 4036 updateImage: function() { 4110 4037 this.$('img').attr( 'src', this.model.get('url') ); 4111 4038 }