Ticket #24716: 24716.12.diff
File 24716.12.diff, 28.8 KB (added by , 10 years ago) |
---|
-
src/wp-admin/upload.php
diff --git a/src/wp-admin/upload.php b/src/wp-admin/upload.php index 11175f9..de099c7 100644
a b if ( 'grid' === $mode ) { 24 24 wp_enqueue_media(); 25 25 wp_enqueue_script( 'media' ); 26 26 require_once( ABSPATH . 'wp-admin/admin-header.php' ); 27 ?><div class="view-switch media-grid-view-switch">28 <a href="<?php echo esc_url( add_query_arg( 'mode', 'list', $_SERVER['REQUEST_URI'] ) ) ?>" class="view-list">29 <img id="view-switch-list" src="<?php echo includes_url( 'images/blank.gif' ) ?>" width="20" height="20" title="List View" alt="List View"/>30 </a>31 <a href="<?php echo esc_url( add_query_arg( 'mode', 'grid', $_SERVER['REQUEST_URI'] ) ) ?>" class="view-grid current">32 <img id="view-switch-excerpt" src="<?php echo includes_url( 'images/blank.gif' ) ?>" width="20" height="20" title="Grid View" alt="Grid View"/>33 </a>34 </div><?php35 27 include( ABSPATH . 'wp-admin/admin-footer.php' ); 36 28 exit; 37 29 } -
src/wp-includes/css/media-views.css
diff --git a/src/wp-includes/css/media-views.css b/src/wp-includes/css/media-views.css index c768479..d1c023d 100644
a b 909 909 border-radius: 0; 910 910 } 911 911 912 .attachment .data-field { 913 white-space: nowrap; 914 text-overflow: ellipsis; 915 overflow: hidden; 916 display: block; 917 line-height: 19px; 918 height: 19px; 919 text-align: left; 920 } 921 912 922 /** 913 923 * Attachments Browser 914 924 */ … … 924 934 height: 50px; 925 935 } 926 936 937 .attachments-browser.hide-sidebar .media-toolbar { 938 right: 0; 939 } 940 927 941 .attachments-browser .media-toolbar-primary > .media-button, 928 942 .attachments-browser .media-toolbar-primary > .media-button-group, 929 943 .attachments-browser .media-toolbar-secondary > .media-button, … … 942 956 outline: none; 943 957 } 944 958 959 /** 960 * Copied styles from the theme browser view. 961 * 962 * This should be OOCSS'd so both use a shared selector. 963 */ 964 .attachment .edit-media { 965 -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; 966 opacity: 0; 967 position: absolute; 968 top: 25%; 969 right: 25%; 970 left: 25%; 971 background: #222; 972 background: rgba(0,0,0,0.7); 973 color: #fff; 974 font-size: 15px; 975 text-shadow: 0 1px 0 rgba(0,0,0,0.6); 976 -webkit-font-smoothing: antialiased; 977 font-weight: 600; 978 padding: 10px 0; 979 text-align: center; 980 -webkit-border-radius: 3px; 981 border-radius: 3px; 982 -webkit-transition: opacity 0.1s ease-in-out; 983 transition: opacity 0.1s ease-in-out; 984 } 985 986 .attachment:hover .edit-media { 987 -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; 988 opacity: 1; 989 } 990 991 .attachments-browser.hide-sidebar .attachments { 992 right: 0; 993 } 994 945 995 .attachments-browser .instructions { 946 996 display: inline-block; 947 997 margin-top: 16px; … … 2388 2438 line-height: 29px; 2389 2439 } 2390 2440 2391 .media-grid-view -switch {2392 position: fixed;2393 right: 10px;2394 top: 44px;2395 z-index: 300;2441 .media-grid-view .view-switch { 2442 display: inline-block; 2443 float: none; 2444 margin-top: 13px; 2445 vertical-align: middle; 2396 2446 } 2397 2447 2398 2448 /** … … 2427 2477 display: none; 2428 2478 } 2429 2479 2480 /** 2481 * Copied styles from the Add theme toolbar. 2482 * 2483 * This should be OOCSS'd so both use a shared selector. 2484 */ 2485 .media-grid-view .media-toolbar { 2486 background: #fff; 2487 -webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.1); 2488 box-shadow: 0 1px 1px 0 rgba(0,0,0,.1); 2489 -webkit-box-sizing: border-box; 2490 -moz-box-sizing: border-box; 2491 box-sizing: border-box; 2492 color: #555; 2493 display: inline-block; 2494 font-size: 13px; 2495 padding: 0 20px; 2496 position: relative; 2497 width: 100%; 2498 } 2499 2500 /** 2501 * The left and right buttons are copied from the expanded theme details modal. 2502 * 2503 * This should be OOCSS'd so both use a shared selector. 2504 */ 2505 .edit-attachment-frame .edit-media-header .left, 2506 .edit-attachment-frame .edit-media-header .right { 2507 cursor: pointer; 2508 color: #777; 2509 background-color: transparent; 2510 height: 48px; 2511 width: 54px; 2512 float: left; 2513 text-align: center; 2514 border: 0; 2515 border-right: 1px solid #ddd; 2516 } 2517 2518 .edit-attachment-frame .edit-media-header .right:before, 2519 .edit-attachment-frame .edit-media-header .left:before { 2520 font: normal 20px/50px 'dashicons' !important; 2521 display: inline; 2522 font-weight: 300; 2523 } 2524 2525 2526 .edit-attachment-frame .edit-media-header .left:before { 2527 content: '\f340'; 2528 } 2529 2530 .edit-attachment-frame .edit-media-header .right:before { 2531 content: '\f344'; 2532 } 2533 2534 .edit-attachment-frame .edit-media-header .left.disabled, 2535 .edit-attachment-frame .edit-media-header .right.disabled, 2536 .edit-attachment-frame .edit-media-header .left.disabled:hover, 2537 .edit-attachment-frame .edit-media-header .right.disabled:hover { 2538 color: #ccc; 2539 background: inherit; 2540 cursor: inherit; 2541 } 2542 2543 .edit-attachment-frame .edit-media-header .close:hover, 2544 .edit-attachment-frame .edit-media-header .right:hover, 2545 .edit-attachment-frame .edit-media-header .left:hover, 2546 .edit-attachment-frame .edit-media-header .close:focus, 2547 .edit-attachment-frame .edit-media-header .right:focus, 2548 .edit-attachment-frame .edit-media-header .left:focus { 2549 background: #0074a2; 2550 color: #fff; 2551 } 2552 2553 .edit-attachment-frame .media-frame-content, 2554 .edit-attachment-frame .media-frame-router { 2555 left: 0; 2556 } 2557 2558 /* Hiding this for the moment instead of removing it from the template. */ 2559 .edit-attachment-frame h3 { 2560 display: none; 2561 } 2562 2563 .edit-attachment-frame .attachment-details { 2564 position: absolute; 2565 overflow: auto; 2566 top: 0; 2567 bottom: 0; 2568 right: 0; 2569 left: 0; 2570 } 2571 2572 .edit-attachment-frame .attachment-info { 2573 border-bottom: 0; 2574 border-right: 1px solid #ddd; 2575 bottom: 0; 2576 position: absolute; 2577 top: 0; 2578 left: 0; 2579 margin-bottom: 0; 2580 padding: 2% 4%; 2581 right: 50%; 2582 } 2583 2584 .edit-attachment-frame .attachment-info .thumbnail { 2585 float: none; 2586 max-width: none; 2587 max-height: none; 2588 } 2589 2590 .edit-attachment-frame .attachment-info .thumbnail-image:after { 2591 -webkit-box-shadow: none; 2592 box-shadow: none; 2593 } 2594 2595 .edit-attachment-frame .attachment-info .thumbnail img { 2596 max-width: none; 2597 max-height: 300px; 2598 } 2599 2600 .edit-attachment-frame .attachment-info .details { 2601 float: none; 2602 } 2603 2604 .edit-attachment-frame .attachment-fields { 2605 bottom: 0; 2606 padding: 2% 4%; 2607 position: absolute; 2608 top: 0; 2609 left: 50%; 2610 right: 0; 2611 } 2612 2613 .edit-attachment-frame .attachment-fields .setting { 2614 display: block; 2615 float: left; 2616 width: 100%; 2617 margin: 1px 0; 2618 } 2619 2620 .edit-attachment-frame .attachment-fields .setting label { 2621 display: block; 2622 } 2623 2624 .edit-attachment-frame .attachment-fields .setting .link-to-custom { 2625 margin: 3px 0; 2626 } 2627 2628 .edit-attachment-frame .attachment-fields .setting .name { 2629 min-width: 30%; 2630 margin-right: 4%; 2631 font-size: 12px; 2632 text-align: right; 2633 } 2634 2635 .edit-attachment-frame .attachment-fields .setting select { 2636 max-width: 65%; 2637 } 2638 2639 .edit-attachment-frame .attachment-fields .setting input[type="checkbox"], 2640 .edit-attachment-frame .attachment-fields .field input[type="checkbox"] { 2641 width: 16px; 2642 float: none; 2643 margin: 8px 3px 0; 2644 padding: 0; 2645 } 2646 2647 .edit-attachment-frame .attachment-fields .setting span { 2648 float: left; 2649 min-height: 22px; 2650 padding-top: 8px; 2651 line-height: 16px; 2652 font-weight: normal; 2653 color: #666; 2654 } 2655 2656 .edit-attachment-frame .attachment-fields .setting input, 2657 .edit-attachment-frame .attachment-fields .setting textarea, 2658 .edit-attachment-frame .attachment-fields .setting .value { 2659 margin: 1px; 2660 width: 65%; 2661 float: right; 2662 } 2663 2664 .edit-attachment-frame .attachment-fields .setting textarea { 2665 height: 62px; 2666 resize: vertical; 2667 } 2668 2669 .edit-attachment-frame .attachment-fields select { 2670 margin-top: 3px; 2671 } 2672 2673 .media-grid-view.hide-router .media-frame-title { 2674 box-shadow: none; 2675 } 2676 2430 2677 .media-grid-view .media-frame-content { 2678 background-color: transparent; 2431 2679 bottom: 40px; 2432 2680 } 2433 2681 @media screen and (max-width: 782px) { -
src/wp-includes/js/media-views.js
diff --git a/src/wp-includes/js/media-views.js b/src/wp-includes/js/media-views.js index c1407d3..01e850c 100644
a b 337 337 }); 338 338 339 339 /** 340 * A more abstracted state, because media.controller.State expects 341 * specific regions (menu, title, etc.) to exist on the frame, which do not 342 * exist in media.view.Frame.EditAttachment. 343 */ 344 media.controller._State = Backbone.Model.extend({ 345 constructor: function() { 346 this.on( 'activate', this._preActivate, this ); 347 this.on( 'activate', this.activate, this ); 348 this.on( 'activate', this._postActivate, this ); 349 this.on( 'deactivate', this._deactivate, this ); 350 this.on( 'deactivate', this.deactivate, this ); 351 this.on( 'reset', this.reset, this ); 352 this.on( 'ready', this.ready, this ); 353 /** 354 * Call parent constructor with passed arguments 355 */ 356 Backbone.Model.apply( this, arguments ); 357 }, 358 359 /** 360 * @abstract 361 */ 362 ready: function() {}, 363 /** 364 * @abstract 365 */ 366 activate: function() {}, 367 /** 368 * @abstract 369 */ 370 deactivate: function() {}, 371 /** 372 * @abstract 373 */ 374 reset: function() {}, 375 /** 376 * @access private 377 */ 378 _preActivate: function() { 379 this.active = true; 380 }, 381 /** 382 * @access private 383 */ 384 _postActivate: function() {}, 385 /** 386 * @access private 387 */ 388 _deactivate: function() { 389 this.active = false; 390 } 391 }); 392 393 /** 340 394 * wp.media.controller.State 341 395 * 342 396 * A state is a step in a workflow that when set will trigger the controllers … … 1350 1404 }); 1351 1405 1352 1406 /** 1407 * A state for editing (cropping, etc.) an image. 1408 * 1409 * @constructor 1410 * @augments wp.media.controller.State 1411 * @augments Backbone.Model 1412 */ 1413 media.controller.EditImageNoFrame = media.controller._State.extend({ 1414 defaults: { 1415 id: 'edit-attachment', 1416 title: l10n.editImage, 1417 // Region mode defaults. 1418 menu: false, 1419 router: 'edit-metadata', 1420 content: 'edit-metadata', 1421 toolbar: 'toolbar', 1422 1423 url: '' 1424 }, 1425 1426 initialize: function() { 1427 media.controller._State.prototype.initialize.apply( this, arguments ); 1428 }, 1429 1430 activate: function() { 1431 this.listenTo( this.frame, 'toolbar:render:edit-image', this.toolbar ); 1432 }, 1433 1434 _postActivate: function() { 1435 this._content(); 1436 this._router(); 1437 }, 1438 1439 deactivate: function() { 1440 this.stopListening( this.frame ); 1441 }, 1442 1443 toolbar: function() { 1444 var frame = this.frame, 1445 lastState = frame.lastState(), 1446 previous = lastState && lastState.id; 1447 1448 frame.toolbar.set( new media.view.Toolbar({ 1449 controller: frame, 1450 items: { 1451 back: { 1452 style: 'primary', 1453 text: l10n.back, 1454 priority: 20, 1455 click: function() { 1456 if ( previous ) { 1457 frame.setState( previous ); 1458 } else { 1459 frame.close(); 1460 } 1461 } 1462 } 1463 } 1464 }) ); 1465 }, 1466 1467 /** 1468 * @access private 1469 */ 1470 _router: function() { 1471 var router = this.frame.router, 1472 mode = this.get('router'), 1473 view; 1474 1475 this.frame.$el.toggleClass( 'hide-router', ! mode ); 1476 if ( ! mode ) { 1477 return; 1478 } 1479 1480 this.frame.router.render( mode ); 1481 1482 view = router.get(); 1483 if ( view && view.select ) { 1484 view.select( this.frame.content.mode() ); 1485 } 1486 }, 1487 1488 _content: function() { 1489 var mode = this.get( 'content' ); 1490 if ( mode ) { 1491 this.frame[ 'content' ].render( mode ); 1492 } 1493 } 1494 }); 1495 1496 /** 1353 1497 * wp.media.controller.MediaLibrary 1354 1498 * 1355 1499 * @constructor … … 1758 1902 _.defaults( this.options, { 1759 1903 title: '', 1760 1904 modal: true, 1761 uploader: true 1905 uploader: true, 1906 mode: ['select'] 1762 1907 }); 1763 1908 1764 1909 // Ensure core UI is enabled. … … 1981 2126 library: {}, 1982 2127 multiple: false, 1983 2128 state: 'library', 1984 uploader: true 2129 uploader: true, 2130 mode: [ 'grid', 'edit' ] 1985 2131 }); 1986 2132 1987 2133 // Ensure core and media grid view UI is enabled. … … 2056 2202 router: false, 2057 2203 content: 'browse', 2058 2204 filterable: 'mime-types' 2059 }), 2060 2061 new media.controller.EditImage( { model: options.editImage } ) 2205 }) 2062 2206 ]); 2063 2207 }, 2064 2208 2065 2209 bindHandlers: function() { 2066 2210 this.on( 'content:create:browse', this.browseContent, this ); 2067 2211 this.on( 'content:render:edit-image', this.editImageContent, this ); 2212 2213 // Handle a frame-level event for editing an attachment. 2214 this.on( 'edit:attachment', this.editAttachment, this ); 2215 this.on( 'edit:attachment:next', this.editNextAttachment, this ); 2216 this.on( 'edit:attachment:previous', this.editPreviousAttachment, this ); 2217 }, 2218 2219 editPreviousAttachment: function( currentModel ) { 2220 var library = this.state().get('library'), 2221 currentModelIndex = library.indexOf( currentModel ); 2222 this.trigger( 'edit:attachment', library.at( currentModelIndex - 1 ) ); 2223 }, 2224 2225 editNextAttachment: function( currentModel ) { 2226 var library = this.state().get('library'), 2227 currentModelIndex = library.indexOf( currentModel ); 2228 this.trigger( 'edit:attachment', library.at( currentModelIndex + 1 ) ); 2229 }, 2230 2231 /** 2232 * Open the Edit Attachment modal. 2233 */ 2234 editAttachment: function( model ) { 2235 var library = this.state().get('library'), hasPrevious, hasNext; 2236 if ( library.indexOf( model ) > 0 ) { 2237 hasPrevious = true; 2238 } 2239 else { 2240 hasPrevious = false; 2241 } 2242 if ( library.indexOf( model ) < library.length - 1 ) { 2243 hasNext = true; 2244 } 2245 else { 2246 hasNext = false; 2247 } 2248 2249 new media.view.Frame.EditAttachment({ 2250 hasPrevious: hasPrevious, 2251 hasNext: hasNext, 2252 model: model, 2253 gridController: this 2254 }); 2068 2255 }, 2069 2256 2070 2257 /** … … 2088 2275 display: state.get('displaySettings'), 2089 2276 dragInfo: state.get('dragInfo'), 2090 2277 bulkEdit: true, 2278 sidebar: false, 2091 2279 2092 2280 suggestedWidth: state.get('suggestedWidth'), 2093 2281 suggestedHeight: state.get('suggestedHeight'), … … 4665 4853 var selection = this.options.selection; 4666 4854 4667 4855 this.$el.attr('aria-label', this.model.attributes.title).attr('aria-checked', false); 4668 this.model.on( 'change :sizes change:uploading', this.render, this );4856 this.model.on( 'change', this.render, this ); 4669 4857 this.model.on( 'change:title', this._syncTitle, this ); 4670 4858 this.model.on( 'change:caption', this._syncCaption, this ); 4671 4859 this.model.on( 'change:percent', this.progress, this ); … … 4718 4906 compat: false, 4719 4907 alt: '', 4720 4908 description: '' 4721 } );4909 }, this.options ); 4722 4910 4723 4911 options.buttons = this.buttons; 4724 4912 options.describe = this.controller.state().get('describe'); … … 4768 4956 */ 4769 4957 toggleSelectionHandler: function( event ) { 4770 4958 var method; 4771 4772 4959 // Catch enter and space events 4773 4960 if ( 'keydown' === event.type && 13 !== event.keyCode && 32 !== event.keyCode ) { 4774 4961 return; 4775 4962 } 4963 4964 // In the grid view, bubble up an edit:attachment event to the controller. 4965 if ( _.contains( this.controller.options.mode, 'grid' ) ) { 4966 this.controller.trigger( 'edit:attachment', this.model ); 4967 return; 4968 } 4969 4776 4970 if ( event.shiftKey ) { 4777 4971 method = 'between'; 4778 4972 } else if ( event.ctrlKey || event.metaKey ) { … … 5303 5497 */ 5304 5498 createAttachmentView: function( attachment ) { 5305 5499 var view = new this.options.AttachmentView({ 5306 controller: this.controller, 5307 model: attachment, 5308 collection: this.collection, 5309 selection: this.options.selection 5500 controller: this.controller, 5501 model: attachment, 5502 collection: this.collection, 5503 selection: this.options.selection, 5504 showAttachmentFields: this.options.showAttachmentFields 5310 5505 }); 5311 5506 5312 5507 return this._viewsByCid[ attachment.cid ] = view; … … 5603 5798 } 5604 5799 }); 5605 5800 5606 5607 5801 /** 5608 5802 * wp.media.view.AttachmentsBrowser 5609 5803 * … … 5621 5815 filters: false, 5622 5816 search: true, 5623 5817 display: false, 5624 5818 sidebar: true, 5819 showAttachmentFields: getUserSetting( 'showAttachmentFields', [ 'title', 'uploadedTo', 'dateFormatted', 'mime' ] ), 5625 5820 AttachmentView: media.view.Attachment.Library 5626 5821 }); 5627 5822 5628 5823 this.createToolbar(); 5629 5824 this.updateContent(); 5630 this.createSidebar(); 5825 if ( this.options.sidebar ) { 5826 this.createSidebar(); 5827 } else { 5828 this.$el.addClass( 'hide-sidebar' ); 5829 } 5631 5830 5632 5831 this.collection.on( 'add remove reset', this.updateContent, this ); 5633 5832 }, … … 5652 5851 5653 5852 this.views.add( this.toolbar ); 5654 5853 5854 // Feels odd to bring the global media library switcher into the Attachment 5855 // browser view. Is this a use case for doAction( 'add:toolbar-items:attachments-browser', this.toolbar ); 5856 // which the controller can tap into and add this view? 5857 if ( _.contains( this.controller.options.mode, 'grid' ) ) { 5858 var libraryViewSwitcherConstructor = media.View.extend({ 5859 className: 'view-switch media-grid-view-switch', 5860 template: media.template( 'media-library-view-switcher') 5861 }); 5862 this.toolbar.set( 'libraryViewSwitcher', new libraryViewSwitcherConstructor({ 5863 controller: this.controller, 5864 priority: -90 5865 }).render() ); 5866 } 5867 5655 5868 filters = this.options.filters; 5656 5869 if ( 'uploaded' === filters ) { 5657 5870 FiltersConstructor = media.view.AttachmentFilters.Uploaded; … … 5746 5959 this.removeContent(); 5747 5960 5748 5961 this.attachments = new media.view.Attachments({ 5749 controller: this.controller, 5750 collection: this.collection, 5751 selection: this.options.selection, 5752 model: this.model, 5753 sortable: this.options.sortable, 5962 controller: this.controller, 5963 collection: this.collection, 5964 selection: this.options.selection, 5965 model: this.model, 5966 sortable: this.options.sortable, 5967 showAttachmentFields: this.options.showAttachmentFields, 5754 5968 5755 5969 // The single `Attachment` view to be used in the `Attachments` view. 5756 5970 AttachmentView: this.options.AttachmentView … … 6814 7028 } 6815 7029 }); 6816 7030 7031 media.view.Attachment.Details.TwoColumn = media.view.Attachment.Details.extend({ 7032 template: wp.template( 'attachment-details-two-column' ), 7033 7034 initialize: function() { 7035 var selection = this.options.selection; 7036 7037 this.$el.attr('aria-label', this.model.attributes.title).attr('aria-checked', false); 7038 this.model.on( 'change:sizes change:uploading', this.render, this ); 7039 this.model.on( 'change:title', this._syncTitle, this ); 7040 this.model.on( 'change:caption', this._syncCaption, this ); 7041 this.model.on( 'change:percent', this.progress, this ); 7042 7043 // Update the selection. 7044 this.model.on( 'add', this.select, this ); 7045 this.model.on( 'remove', this.deselect, this ); 7046 }, 7047 }); 7048 7049 /** 7050 * A frame for editing the details of a specific media item. 7051 * 7052 * Opens in a modal by default. 7053 * 7054 * Requires an attachment model to be passed in the options hash under `model`. 7055 */ 7056 media.view.Frame.EditAttachment = media.view.Frame.extend({ 7057 7058 className: 'edit-attachment-frame', 7059 template: media.template( 'edit-attachment-frame' ), 7060 regions: [ 'router', 'content' ], 7061 7062 events: { 7063 'click': 'collapse', 7064 'click .delete-media-item': 'deleteMediaItem', 7065 'click .left': 'previousMediaItem', 7066 'click .right': 'nextMediaItem' 7067 }, 7068 7069 initialize: function( options ) { 7070 var self = this; 7071 media.view.Frame.prototype.initialize.apply( this, arguments ); 7072 7073 _.defaults( this.options, { 7074 modal: true, 7075 state: 'edit-attachment' 7076 }); 7077 7078 this.createStates(); 7079 7080 this.on( 'content:render:edit-metadata', this.editMetadataContent, this ); 7081 this.on( 'content:render:edit-image', this.editImageContentUgh, this ); 7082 7083 // Only need a tab to Edit Image for images. 7084 if ( this.model.get( 'type' ) === 'image' ) { 7085 this.on( 'router:create', this.createRouter, this ); 7086 this.on( 'router:render', this.browseRouter, this ); 7087 } 7088 7089 // Initialize modal container view. 7090 if ( this.options.modal ) { 7091 this.modal = new media.view.Modal({ 7092 controller: this, 7093 title: this.options.title 7094 }); 7095 7096 // Completely destroy the modal DOM element when closing it. 7097 this.modal.close = function() { 7098 self.modal.remove(); 7099 }; 7100 7101 this.modal.content( this ); 7102 this.modal.open(); 7103 } 7104 }, 7105 7106 /** 7107 * Add the default states to the frame. 7108 */ 7109 createStates: function() { 7110 this.states.add([ 7111 new media.controller.EditImageNoFrame( { model: this.model } ) 7112 ]); 7113 }, 7114 7115 /** 7116 * @returns {wp.media.view.MediaFrame} Returns itself to allow chaining 7117 */ 7118 render: function() { 7119 // Activate the default state if no active state exists. 7120 if ( ! this.state() && this.options.state ) { 7121 this.setState( this.options.state ); 7122 } 7123 /** 7124 * call 'render' directly on the parent class 7125 */ 7126 return media.view.Frame.prototype.render.apply( this, arguments ); 7127 }, 7128 7129 /** 7130 * Content region rendering callback for the `edit-metadata` mode. 7131 */ 7132 editMetadataContent: function() { 7133 var view = new media.view.Attachment.Details.TwoColumn({ 7134 controller: this, 7135 model: this.model 7136 }); 7137 this.content.set( view ); 7138 }, 7139 7140 /** 7141 * For some reason the view doesn't exist in the DOM yet, don't have the 7142 * patience to track this down right now. 7143 */ 7144 editImageContentUgh: function() { 7145 _.defer( _.bind( this.editImageContent, this ) ); 7146 }, 7147 7148 /** 7149 * Render the EditImage view into the frame's content region. 7150 */ 7151 editImageContent: function() { 7152 var view = new media.view.EditImage( { model: this.model, controller: this } ).render(); 7153 7154 this.content.set( view ); 7155 7156 // after creating the wrapper view, load the actual editor via an ajax call 7157 view.loadEditor(); 7158 }, 7159 7160 /** 7161 * Create the router view. 7162 * 7163 * @param {Object} router 7164 * @this wp.media.controller.Region 7165 */ 7166 createRouter: function( router ) { 7167 router.view = new media.view.Router({ 7168 controller: this 7169 }); 7170 }, 7171 7172 /** 7173 * Router rendering callback. 7174 * 7175 * @param media.view.Router view Instantiated in this.createRouter() 7176 */ 7177 browseRouter: function( view ) { 7178 view.set({ 7179 'edit-metadata': { 7180 text: 'Edit Metadata', 7181 priority: 20 7182 }, 7183 'edit-image': { 7184 text: 'Edit Image', 7185 priority: 40 7186 } 7187 }); 7188 }, 7189 7190 /** 7191 * Click handler to switch to the previous media item. 7192 */ 7193 previousMediaItem: function() { 7194 if ( ! this.options.hasPrevious ) 7195 return; 7196 this.modal.close(); 7197 this.options.gridController.trigger( 'edit:attachment:previous', this.model ); 7198 }, 7199 7200 /** 7201 * Click handler to switch to the next media item. 7202 */ 7203 nextMediaItem: function() { 7204 if ( ! this.options.hasNext ) 7205 return; 7206 this.modal.close(); 7207 this.options.gridController.trigger( 'edit:attachment:next', this.model ); 7208 } 7209 7210 }); 7211 6817 7212 media.view.EditImage = media.View.extend({ 6818 7213 6819 7214 className: 'image-editor', -
src/wp-includes/media-template.php
diff --git a/src/wp-includes/media-template.php b/src/wp-includes/media-template.php index 2c0ff80..9a1f5d8 100644
a b function wp_print_media_templates() { 220 220 </div> 221 221 </script> 222 222 223 <script type="text/html" id="tmpl-media-library-view-switcher"> 224 <a href="<?php echo esc_url( add_query_arg( 'mode', 'list', $_SERVER['REQUEST_URI'] ) ) ?>" class="view-list"> 225 <img id="view-switch-list" src="<?php echo includes_url( 'images/blank.gif' ) ?>" width="20" height="20" title="List View" alt="List View"/> 226 </a> 227 <a href="<?php echo esc_url( add_query_arg( 'mode', 'grid', $_SERVER['REQUEST_URI'] ) ) ?>" class="view-grid current"> 228 <img id="view-switch-excerpt" src="<?php echo includes_url( 'images/blank.gif' ) ?>" width="20" height="20" title="Grid View" alt="Grid View"/> 229 </a> 230 </script> 231 223 232 <script type="text/html" id="tmpl-uploader-status"> 224 233 <h3><?php _e( 'Uploading' ); ?></h3> 225 234 <a class="upload-dismiss-errors" href="#"><?php _e('Dismiss Errors'); ?></a> … … function wp_print_media_templates() { 241 250 <span class="upload-error-message">{{ data.message }}</span> 242 251 </script> 243 252 253 <script type="text/html" id="tmpl-edit-attachment-frame"> 254 <div class="edit-media-header"> 255 <button class="left dashicons dashicons-no<# if ( ! data.hasPrevious ) { #> disabled <# } #>"><span class="screen-reader-text"><?php _e( 'Edit previous media item' ); ?></span></button> 256 <button class="right dashicons dashicons-no<# if ( ! data.hasNext ) { #> disabled <# } #>"><span class="screen-reader-text"><?php _e( 'Edit next media item' ); ?></span></button> 257 </div> 258 <div class="media-frame-router"></div> 259 <div class="media-frame-content"></div> 260 <div class="media-frame-toolbar"></div> 261 </script> 262 263 <script type="text/html" id="tmpl-attachment-details-two-column"> 264 <h3> 265 <?php _e('Attachment Details'); ?> 266 267 <span class="settings-save-status"> 268 <span class="spinner"></span> 269 <span class="saved"><?php esc_html_e('Saved.'); ?></span> 270 </span> 271 </h3> 272 <div class="attachment-info"> 273 <div class="thumbnail thumbnail-{{ data.type }}"> 274 <# if ( data.uploading ) { #> 275 <div class="media-progress-bar"><div></div></div> 276 <# } else if ( 'image' === data.type ) { #> 277 <img src="{{ data.sizes.full.url }}" draggable="false" /> 278 <# } else { #> 279 <img src="{{ data.icon }}" class="icon" draggable="false" /> 280 <# } #> 281 </div> 282 <div class="details"> 283 <div class="filename">{{ data.filename }}</div> 284 <div class="uploaded">{{ data.dateFormatted }}</div> 285 286 <div class="file-size">{{ data.filesizeHumanReadable }}</div> 287 <# if ( 'image' === data.type && ! data.uploading ) { #> 288 <# if ( data.width && data.height ) { #> 289 <div class="dimensions">{{ data.width }} × {{ data.height }}</div> 290 <# } #> 291 292 <# if ( data.can.save ) { #> 293 <a class="edit-attachment" href="{{ data.editLink }}&image-editor" target="_blank"><?php _e( 'Edit Image' ); ?></a> 294 <a class="refresh-attachment" href="#"><?php _e( 'Refresh' ); ?></a> 295 <# } #> 296 <# } #> 297 298 <# if ( data.fileLength ) { #> 299 <div class="file-length"><?php _e( 'Length:' ); ?> {{ data.fileLength }}</div> 300 <# } #> 301 302 <# if ( ! data.uploading && data.can.remove ) { #> 303 <?php if ( MEDIA_TRASH ): ?> 304 <a class="trash-attachment" href="#"><?php _e( 'Trash' ); ?></a> 305 <?php else: ?> 306 <a class="delete-attachment" href="#"><?php _e( 'Delete Permanently' ); ?></a> 307 <?php endif; ?> 308 <# } #> 309 310 <div class="compat-meta"> 311 <# if ( data.compat && data.compat.meta ) { #> 312 {{{ data.compat.meta }}} 313 <# } #> 314 </div> 315 </div> 316 </div> 317 <div class="attachment-fields"> 318 <label class="setting" data-setting="url"> 319 <span class="name"><?php _e('URL'); ?></span> 320 <input type="text" value="{{ data.url }}" readonly /> 321 </label> 322 <# var maybeReadOnly = data.can.save || data.allowLocalEdits ? '' : 'readonly'; #> 323 <label class="setting" data-setting="title"> 324 <span class="name"><?php _e('Title'); ?></span> 325 <input type="text" value="{{ data.title }}" {{ maybeReadOnly }} /> 326 </label> 327 <label class="setting" data-setting="caption"> 328 <span class="name"><?php _e('Caption'); ?></span> 329 <textarea {{ maybeReadOnly }}>{{ data.caption }}</textarea> 330 </label> 331 <# if ( 'image' === data.type ) { #> 332 <label class="setting" data-setting="alt"> 333 <span class="name"><?php _e('Alt Text'); ?></span> 334 <input type="text" value="{{ data.alt }}" {{ maybeReadOnly }} /> 335 </label> 336 <# } #> 337 <label class="setting" data-setting="description"> 338 <span class="name"><?php _e('Description'); ?></span> 339 <textarea {{ maybeReadOnly }}>{{ data.description }}</textarea> 340 </label> 341 <label class="setting"> 342 <span class="name"><?php _e( 'Uploaded By' ); ?></span> 343 <span class="value">{{ data.authorName }}</span> 344 </label> 345 <# if ( data.uploadedTo ) { #> 346 <label class="setting"> 347 <span class="name"><?php _e('Uploaded To'); ?></span> 348 <span class="value"><a href="{{ data.uploadedToLink }}">{{ data.uploadedToTitle }}</a></span> 349 </label> 350 <# } #> 351 </div> 352 </script> 353 244 354 <script type="text/html" id="tmpl-attachment"> 245 355 <div class="attachment-preview type-{{ data.type }} subtype-{{ data.subtype }} {{ data.orientation }}"> 246 356 <# if ( data.uploading ) { #> … … function wp_print_media_templates() { 257 367 <div>{{ data.filename }}</div> 258 368 </div> 259 369 <# } #> 260 370 <# if ( _.contains( data.controller.options.mode, 'grid' ) ) { #> 371 <span class="edit-media">Edit Media</span> 372 <# } #> 261 373 <# if ( data.buttons.close ) { #> 262 374 <a class="close media-modal-icon" href="#" title="<?php esc_attr_e('Remove'); ?>"></a> 263 375 <# } #> … … function wp_print_media_templates() { 283 395 <# } #> {{ maybeReadOnly }} /> 284 396 <# } #> 285 397 <# } #> 398 <# if ( _.contains( data.controller.options.mode, 'grid' ) ) { #> 399 <# _.each( data.showAttachmentFields, function( field ) { #> 400 <div class="data-field data-{{ field }}"> 401 <# if ( 'uploadedTo' === field ) { #> 402 403 <# if ( data[field] ) { #> 404 <?php _e( 'Uploaded To:' ) ?> 405 <# } else { #> 406 <?php _e( 'Unattached' ) ?> 407 <# } #> 408 409 <# } #> 410 <# if ( data[field] ) { #> 411 {{ data[field] }} 412 <# } #> 413 </div> 414 <# }); #> 415 <# } #> 416 286 417 </script> 287 418 288 419 <script type="text/html" id="tmpl-attachment-details">