WordPress.org

Make WordPress Core

Ticket #24716: 24716.17.diff

File 24716.17.diff, 33.6 KB (added by wonderboymusic, 3 years ago)
  • src/wp-admin/upload.php

     
    2424        wp_enqueue_media(); 
    2525        wp_enqueue_script( 'media-grid' ); 
    2626        wp_enqueue_script( 'media' ); 
    27          
     27 
    2828        require_once( ABSPATH . 'wp-admin/admin-header.php' ); 
    29         ?><div class="view-switch media-grid-view-switch"> 
    30                 <a href="<?php echo esc_url( add_query_arg( 'mode', 'list', $_SERVER['REQUEST_URI'] ) ) ?>" class="view-list"> 
    31                         <img id="view-switch-list" src="<?php echo includes_url( 'images/blank.gif' ) ?>" width="20" height="20" title="List View" alt="List View"/> 
    32                 </a> 
    33                 <a href="<?php echo esc_url( add_query_arg( 'mode', 'grid', $_SERVER['REQUEST_URI'] ) ) ?>" class="view-grid current"> 
    34                         <img id="view-switch-excerpt" src="<?php echo includes_url( 'images/blank.gif' ) ?>" width="20" height="20" title="Grid View" alt="Grid View"/> 
    35                 </a> 
    36         </div><?php 
    3729        include( ABSPATH . 'wp-admin/admin-footer.php' ); 
    3830        exit; 
    3931} 
  • src/wp-includes/css/media-views.css

     
    750750        max-height: 100%; 
    751751} 
    752752 
     753.attachment-preview.type-audio .thumbnail, 
     754.attachment-preview.type-video .thumbnail { 
     755        z-index: 1; 
     756        margin: 5%; 
     757        max-width: 90%; 
     758        max-height: 90%; 
     759} 
     760 
     761.media-frame-content .attachment-preview.type-audio .icon, 
     762.media-frame-content .attachment-preview.type-video .icon { 
     763        z-index: 2; 
     764        background: #f1f1f1; 
     765        position: relative; 
     766        padding: 0; 
     767        top: 15%; 
     768        left: auto; 
     769        right: auto; 
     770} 
     771 
     772.attachment-preview.type-audio .filename, 
     773.attachment-preview.type-video .filename { 
     774        z-index: 3; 
     775} 
     776 
    753777.attachment-preview .thumbnail:after { 
    754778        content: ''; 
    755779        display: block; 
     
    909933        border-radius: 0; 
    910934} 
    911935 
     936.attachment .data-fields { 
     937        margin: 5px 0 0; 
     938} 
     939 
     940.attachment .data-field { 
     941        white-space: nowrap; 
     942        text-overflow: ellipsis; 
     943        overflow: hidden; 
     944        display: block; 
     945        line-height: 19px; 
     946        height: 19px; 
     947        text-align: left; 
     948        width: 90%; 
     949        margin: 0 5%; 
     950} 
     951 
    912952/** 
    913953 * Attachments Browser 
    914954 */ 
     
    924964        height: 50px; 
    925965} 
    926966 
     967.attachments-browser.hide-sidebar .media-toolbar { 
     968        right: 0; 
     969} 
     970 
    927971.attachments-browser .media-toolbar-primary > .media-button, 
    928972.attachments-browser .media-toolbar-primary > .media-button-group, 
    929973.attachments-browser .media-toolbar-secondary > .media-button, 
     
    942986        outline: none; 
    943987} 
    944988 
     989.inline-toolbar { 
     990        position: absolute; 
     991        top: 0; 
     992        left: 0; 
     993        display: none; 
     994        z-index: 100; 
     995} 
     996 
     997.inline-toolbar .remove { 
     998        display: none; 
     999} 
     1000 
     1001.active-video .inline-toolbar .remove { 
     1002        display: inline-block; 
     1003} 
     1004 
     1005.attachment:hover .inline-toolbar { 
     1006        display: block; 
     1007} 
     1008 
     1009.inline-toolbar div, 
     1010.inline-toolbar .inline-media-control { 
     1011        display: inline-block; 
     1012        margin-top: 4px; 
     1013        margin-left: 4px; 
     1014        padding: 2px; 
     1015        width: 20px; 
     1016        height: 20px; 
     1017        box-shadow: 0 1px 3px rgba(0,0,0,0.5); 
     1018        background-color: #000; 
     1019        background-color: rgba(0,0,0,0.9); 
     1020        cursor: pointer; 
     1021        color: white; 
     1022        font-size: 20px; 
     1023} 
     1024 
     1025.ie8 .inline-toolbar div, 
     1026.ie7 .inline-toolbar div { 
     1027        display: inline; 
     1028        padding: 0; 
     1029} 
     1030 
     1031.inline-media-control span { 
     1032        display: block; 
     1033        width: 16px; 
     1034        height: 16px; 
     1035        margin: 2px; 
     1036        background: url(/wp-includes/js/mediaelement/controls.png) 0 0 no-repeat; 
     1037} 
     1038 
     1039.inline-media-control.active span { 
     1040        margin: 2px; 
     1041        background-position: 0 -16px; 
     1042} 
     1043 
     1044.inline-media-control.paused span { 
     1045        margin: 2px; 
     1046        background-position: 0 0; 
     1047} 
     1048 
     1049audio#inline-media-node { 
     1050        display: none; 
     1051} 
     1052 
     1053video#inline-media-node { 
     1054        position: relative; 
     1055        z-index: 5; 
     1056        top: 0; 
     1057        left: 0; 
     1058} 
     1059 
     1060.inline-video-wrap { 
     1061        width: 100%; 
     1062        height: auto; 
     1063        position: absolute; 
     1064        z-index: 5; 
     1065        background: #000; 
     1066        padding: 10px 0 5px; 
     1067        top: 0; 
     1068        left: 0; 
     1069} 
     1070 
     1071.attachments-browser.hide-sidebar .attachments { 
     1072        right: 0; 
     1073} 
     1074 
    9451075.attachments-browser .instructions { 
    9461076        display: inline-block; 
    9471077        margin-top: 16px; 
     
    23882518        line-height: 29px; 
    23892519} 
    23902520 
    2391 .media-grid-view-switch { 
    2392         position: fixed; 
    2393         right: 10px; 
    2394         top: 44px; 
    2395         z-index: 300; 
     2521.media-grid-view .view-switch { 
     2522        display: inline-block; 
     2523        float: none; 
     2524        margin-top: 13px; 
     2525        vertical-align: middle; 
    23962526} 
    23972527 
    23982528/** 
     
    24272557        display: none; 
    24282558} 
    24292559 
     2560/** 
     2561 * Copied styles from the Add theme toolbar. 
     2562 * 
     2563 * This should be OOCSS'd so both use a shared selector. 
     2564 */ 
     2565.media-grid-view .media-toolbar { 
     2566        background: #fff; 
     2567        -webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.1); 
     2568        box-shadow: 0 1px 1px 0 rgba(0,0,0,.1); 
     2569        -webkit-box-sizing: border-box; 
     2570        -moz-box-sizing: border-box; 
     2571        box-sizing: border-box; 
     2572        color: #555; 
     2573        display: inline-block; 
     2574        font-size: 13px; 
     2575        padding: 0 20px; 
     2576        position: relative; 
     2577        width: 100%; 
     2578} 
     2579 
     2580/** 
     2581 * The left and right buttons are copied from the expanded theme details modal. 
     2582 * 
     2583 * This should be OOCSS'd so both use a shared selector. 
     2584 */ 
     2585.edit-attachment-frame .edit-media-header .left, 
     2586.edit-attachment-frame .edit-media-header .right { 
     2587        cursor: pointer; 
     2588        color: #777; 
     2589        background-color: transparent; 
     2590        height: 48px; 
     2591        width: 54px; 
     2592        float: left; 
     2593        text-align: center; 
     2594        border: 0; 
     2595        border-right: 1px solid #ddd; 
     2596} 
     2597 
     2598.edit-attachment-frame .edit-media-header .right:before, 
     2599.edit-attachment-frame .edit-media-header .left:before { 
     2600        font: normal 20px/50px 'dashicons' !important; 
     2601        display: inline; 
     2602        font-weight: 300; 
     2603} 
     2604 
     2605 
     2606.edit-attachment-frame .edit-media-header .left:before { 
     2607        content: '\f340'; 
     2608} 
     2609 
     2610.edit-attachment-frame .edit-media-header .right:before { 
     2611        content: '\f344'; 
     2612} 
     2613 
     2614.edit-attachment-frame .edit-media-header .left.disabled, 
     2615.edit-attachment-frame .edit-media-header .right.disabled, 
     2616.edit-attachment-frame .edit-media-header .left.disabled:hover, 
     2617.edit-attachment-frame .edit-media-header .right.disabled:hover { 
     2618        color: #ccc; 
     2619        background: inherit; 
     2620        cursor: inherit; 
     2621} 
     2622 
     2623.edit-attachment-frame .edit-media-header .close:hover, 
     2624.edit-attachment-frame .edit-media-header .right:hover, 
     2625.edit-attachment-frame .edit-media-header .left:hover, 
     2626.edit-attachment-frame .edit-media-header .close:focus, 
     2627.edit-attachment-frame .edit-media-header .right:focus, 
     2628.edit-attachment-frame .edit-media-header .left:focus { 
     2629        background: #0074a2; 
     2630        color: #fff; 
     2631} 
     2632 
     2633.edit-attachment-frame .media-frame-content, 
     2634.edit-attachment-frame .media-frame-router { 
     2635        left: 0; 
     2636} 
     2637 
     2638/* Hiding this for the moment instead of removing it from the template. */ 
     2639.edit-attachment-frame h3 { 
     2640        display: none; 
     2641} 
     2642 
     2643.edit-attachment-frame .attachment-details { 
     2644        position: absolute; 
     2645        overflow: auto; 
     2646        top: 0; 
     2647        bottom: 0; 
     2648        right: 0; 
     2649        left: 0; 
     2650} 
     2651 
     2652.edit-attachment-frame .attachment-info { 
     2653        border-bottom: 0; 
     2654        border-right: 1px solid #ddd; 
     2655        bottom: 0; 
     2656        position: absolute; 
     2657        top: 0; 
     2658        left: 0; 
     2659        margin-bottom: 0; 
     2660        padding: 2% 4%; 
     2661        right: 50%; 
     2662} 
     2663 
     2664.edit-attachment-frame .attachment-info .thumbnail { 
     2665        max-width: none; 
     2666        max-height: none; 
     2667} 
     2668 
     2669.edit-attachment-frame .attachment-info .thumbnail-image img { 
     2670        margin: 0; 
     2671} 
     2672 
     2673.edit-attachment-frame .attachment-info .thumbnail-image:after { 
     2674        -webkit-box-shadow: none; 
     2675                box-shadow: none; 
     2676} 
     2677 
     2678.edit-attachment-frame .attachment-info .thumbnail img { 
     2679        max-width: none; 
     2680        max-height: 50%; 
     2681} 
     2682 
     2683.edit-attachment-frame .attachment-info .details { 
     2684        float: none; 
     2685} 
     2686 
     2687.edit-attachment-frame .wp-media-wrapper { 
     2688        margin-top: 20px; 
     2689} 
     2690 
     2691.edit-attachment-frame .attachment-fields { 
     2692        bottom: 0; 
     2693        padding: 2% 4%; 
     2694        position: absolute; 
     2695        top: 0; 
     2696        left: 50%; 
     2697        right: 0; 
     2698} 
     2699 
     2700.edit-attachment-frame .attachment-fields .setting { 
     2701        display: block; 
     2702        float: left; 
     2703        width: 100%; 
     2704        margin: 1px 0; 
     2705} 
     2706 
     2707.edit-attachment-frame .attachment-fields .setting label { 
     2708        display: block; 
     2709} 
     2710 
     2711.edit-attachment-frame .attachment-fields .setting .link-to-custom { 
     2712        margin: 3px 0; 
     2713} 
     2714 
     2715.edit-attachment-frame .attachment-fields .setting .name { 
     2716        min-width: 30%; 
     2717        margin-right: 4%; 
     2718        font-size: 12px; 
     2719        text-align: right; 
     2720} 
     2721 
     2722.edit-attachment-frame .attachment-fields .setting select { 
     2723        max-width: 65%; 
     2724} 
     2725 
     2726.edit-attachment-frame .attachment-fields .setting input[type="checkbox"], 
     2727.edit-attachment-frame .attachment-fields .field input[type="checkbox"] { 
     2728        width: 16px; 
     2729        float: none; 
     2730        margin: 8px 3px 0; 
     2731        padding: 0; 
     2732} 
     2733 
     2734.edit-attachment-frame .attachment-fields .setting span { 
     2735        float: left; 
     2736        min-height: 22px; 
     2737        padding-top: 8px; 
     2738        line-height: 16px; 
     2739        font-weight: normal; 
     2740        color: #666; 
     2741} 
     2742 
     2743.edit-attachment-frame .attachment-fields .setting input[type="text"], 
     2744.edit-attachment-frame .attachment-fields .setting input[type="password"], 
     2745.edit-attachment-frame .attachment-fields .setting input[type="number"], 
     2746.edit-attachment-frame .attachment-fields .setting input[type="search"], 
     2747.edit-attachment-frame .attachment-fields .setting input[type="email"], 
     2748.edit-attachment-frame .attachment-fields .setting input[type="url"], 
     2749.edit-attachment-frame .attachment-fields .setting textarea, 
     2750.edit-attachment-frame .attachment-fields .setting .value { 
     2751        margin: 1px; 
     2752        width: 65%; 
     2753        float: right; 
     2754        padding: 6px 8px; 
     2755        -webkit-box-sizing: border-box; 
     2756        -moz-box-sizing: border-box; 
     2757        box-sizing: border-box; 
     2758} 
     2759 
     2760.edit-attachment-frame .attachment-fields .setting textarea { 
     2761        height: 62px; 
     2762        resize: vertical; 
     2763} 
     2764 
     2765.edit-attachment-frame .attachment-fields select { 
     2766        margin-top: 3px; 
     2767} 
     2768 
     2769.media-grid-view.hide-router .media-frame-title { 
     2770        box-shadow: none; 
     2771} 
     2772 
    24302773.media-grid-view .media-frame-content { 
     2774        background-color: transparent; 
    24312775        bottom: 40px; 
    24322776} 
    24332777@media screen and (max-width: 782px) { 
  • src/wp-includes/js/media-audiovideo.js

     
    2626                        } 
    2727                }, 
    2828 
     29                removeAllPlayers: function() { 
     30                        var p; 
     31 
     32                        if ( window.mejs && window.mejs.players ) { 
     33                                for ( p in window.mejs.players ) { 
     34                                        window.mejs.players[p].pause(); 
     35                                        this.removePlayer( window.mejs.players[p] ); 
     36                                } 
     37                        } 
     38                }, 
     39 
    2940                /** 
    3041                 * Pauses the current object's instances of MediaElementPlayer 
    3142                 */ 
  • src/wp-includes/js/media-grid.js

     
    1 (function( $, _, Backbone, wp ) { 
     1(function($, _, Backbone, wp) { 
    22        var media = wp.media, l10n; 
    33 
    44        // Link any localized strings. 
     
    1010        } 
    1111 
    1212        /** 
     13         * A more abstracted state, because media.controller.State expects 
     14         * specific regions (menu, title, etc.) to exist on the frame, which do not 
     15         * exist in media.view.Frame.EditAttachment. 
     16         */ 
     17        media.controller._State = Backbone.Model.extend({ 
     18                constructor: function() { 
     19                        this.on( 'activate', this._preActivate, this ); 
     20                        this.on( 'activate', this.activate, this ); 
     21                        this.on( 'activate', this._postActivate, this ); 
     22                        this.on( 'deactivate', this._deactivate, this ); 
     23                        this.on( 'deactivate', this.deactivate, this ); 
     24                        this.on( 'reset', this.reset, this ); 
     25                        this.on( 'ready', this.ready, this ); 
     26                        /** 
     27                         * Call parent constructor with passed arguments 
     28                         */ 
     29                        Backbone.Model.apply( this, arguments ); 
     30                }, 
     31 
     32                /** 
     33                 * @abstract 
     34                 */ 
     35                ready: function() {}, 
     36                /** 
     37                 * @abstract 
     38                 */ 
     39                activate: function() {}, 
     40                /** 
     41                 * @abstract 
     42                 */ 
     43                deactivate: function() {}, 
     44                /** 
     45                 * @abstract 
     46                 */ 
     47                reset: function() {}, 
     48                /** 
     49                 * @access private 
     50                 */ 
     51                _preActivate: function() { 
     52                        this.active = true; 
     53                }, 
     54                /** 
     55                 * @access private 
     56                 */ 
     57                _postActivate: function() {}, 
     58                /** 
     59                 * @access private 
     60                 */ 
     61                _deactivate: function() { 
     62                        this.active = false; 
     63                } 
     64        }); 
     65 
     66        /** 
     67         * A state for editing (cropping, etc.) an image. 
     68         * 
     69         * @constructor 
     70         * @augments wp.media.controller.State 
     71         * @augments Backbone.Model 
     72         */ 
     73        media.controller.EditImageNoFrame = media.controller._State.extend({ 
     74                defaults: { 
     75                        id:      'edit-attachment', 
     76                        title:   l10n.editImage, 
     77                        // Region mode defaults. 
     78                        menu:    false, 
     79                        router:  'edit-metadata', 
     80                        content: 'edit-metadata', 
     81                        toolbar: 'toolbar', 
     82 
     83                        url:     '' 
     84                }, 
     85 
     86                initialize: function() { 
     87                        media.controller._State.prototype.initialize.apply( this, arguments ); 
     88                }, 
     89 
     90                activate: function() { 
     91                        this.listenTo( this.frame, 'toolbar:render:edit-image', this.toolbar ); 
     92                }, 
     93 
     94                _postActivate: function() { 
     95                        this._content(); 
     96                        this._router(); 
     97                }, 
     98 
     99                deactivate: function() { 
     100                        this.stopListening( this.frame ); 
     101                }, 
     102 
     103                toolbar: function() { 
     104                        var frame = this.frame, 
     105                                lastState = frame.lastState(), 
     106                                previous = lastState && lastState.id; 
     107 
     108                        frame.toolbar.set( new media.view.Toolbar({ 
     109                                controller: frame, 
     110                                items: { 
     111                                        back: { 
     112                                                style: 'primary', 
     113                                                text:     l10n.back, 
     114                                                priority: 20, 
     115                                                click:    function() { 
     116                                                        if ( previous ) { 
     117                                                                frame.setState( previous ); 
     118                                                        } else { 
     119                                                                frame.close(); 
     120                                                        } 
     121                                                } 
     122                                        } 
     123                                } 
     124                        }) ); 
     125                }, 
     126 
     127                /** 
     128                 * @access private 
     129                 */ 
     130                _router: function() { 
     131                        var router = this.frame.router, 
     132                                mode = this.get('router'), 
     133                                view; 
     134 
     135                        this.frame.$el.toggleClass( 'hide-router', ! mode ); 
     136                        if ( ! mode ) { 
     137                                return; 
     138                        } 
     139 
     140                        this.frame.router.render( mode ); 
     141 
     142                        view = router.get(); 
     143                        if ( view && view.select ) { 
     144                                view.select( this.frame.content.mode() ); 
     145                        } 
     146                }, 
     147 
     148                _content: function() { 
     149                        var mode = this.get( 'content' ); 
     150                        if ( mode ) { 
     151                                this.frame[ 'content' ].render( mode ); 
     152                        } 
     153                } 
     154        }); 
     155 
     156        /** 
    13157         * wp.media.view.MediaFrame.Manage 
    14158         * 
    15159         * A generic management frame workflow. 
     
    36180                                library:   {}, 
    37181                                multiple:  false, 
    38182                                state:     'library', 
    39                                 uploader:  true 
     183                                uploader:  true, 
     184                                mode:      [ 'grid', 'edit' ] 
    40185                        }); 
    41186 
    42187                        // Ensure core and media grid view UI is enabled. 
     
    111256                                        router:     false, 
    112257                                        content:    'browse', 
    113258                                        filterable: 'mime-types' 
    114                                 }), 
    115  
    116                                 new media.controller.EditImage( { model: options.editImage } ) 
     259                                }) 
    117260                        ]); 
    118261                }, 
    119262 
     
    120263                bindHandlers: function() { 
    121264                        this.on( 'content:create:browse', this.browseContent, this ); 
    122265                        this.on( 'content:render:edit-image', this.editImageContent, this ); 
     266 
     267                        // Handle a frame-level event for editing an attachment. 
     268                        this.on( 'edit:attachment', this.editAttachment, this ); 
     269                        this.on( 'edit:attachment:next', this.editNextAttachment, this ); 
     270                        this.on( 'edit:attachment:previous', this.editPreviousAttachment, this ); 
    123271                }, 
    124272 
     273                editPreviousAttachment: function( currentModel ) { 
     274                        var library = this.state().get('library'), 
     275                            currentModelIndex = library.indexOf( currentModel ); 
     276                        this.trigger( 'edit:attachment', library.at( currentModelIndex - 1 ) ); 
     277                }, 
     278 
     279                editNextAttachment: function( currentModel ) { 
     280                        var library = this.state().get('library'), 
     281                            currentModelIndex = library.indexOf( currentModel ); 
     282                        this.trigger( 'edit:attachment', library.at( currentModelIndex + 1 ) ); 
     283                }, 
     284 
    125285                /** 
     286                 * Open the Edit Attachment modal. 
     287                 */ 
     288                editAttachment: function( model ) { 
     289                        var library = this.state().get('library'), hasPrevious, hasNext; 
     290                        if ( library.indexOf( model ) > 0 ) { 
     291                                hasPrevious = true; 
     292                        } 
     293                        else { 
     294                                hasPrevious = false; 
     295                        } 
     296                        if ( library.indexOf( model ) < library.length - 1 ) { 
     297                                hasNext = true; 
     298                        } 
     299                        else { 
     300                                hasNext = false; 
     301                        } 
     302 
     303                        new media.view.Frame.EditAttachment({ 
     304                                hasPrevious:    hasPrevious, 
     305                                hasNext:        hasNext, 
     306                                model:          model, 
     307                                gridController: this 
     308                        }); 
     309                }, 
     310 
     311                /** 
    126312                 * Content 
    127313                 * 
    128314                 * @param {Object} content 
     
    143329                                display:    state.get('displaySettings'), 
    144330                                dragInfo:   state.get('dragInfo'), 
    145331                                bulkEdit:   true, 
     332                                sidebar:    false, 
    146333 
    147334                                suggestedWidth:  state.get('suggestedWidth'), 
    148335                                suggestedHeight: state.get('suggestedHeight'), 
     
    162349 
    163350                } 
    164351        }); 
    165          
    166 }( jQuery, _, Backbone, wp )); 
    167  No newline at end of file 
     352 
     353        media.view.Attachment.Details.TwoColumn = media.view.Attachment.Details.extend({ 
     354                template: wp.template( 'attachment-details-two-column' ), 
     355 
     356                initialize: function() { 
     357                        this.$el.attr('aria-label', this.model.attributes.title).attr('aria-checked', false); 
     358                        this.model.on( 'change:sizes change:uploading', this.render, this ); 
     359                        this.model.on( 'change:title', this._syncTitle, this ); 
     360                        this.model.on( 'change:caption', this._syncCaption, this ); 
     361                        this.model.on( 'change:percent', this.progress, this ); 
     362 
     363                        // Update the selection. 
     364                        this.model.on( 'add', this.select, this ); 
     365                        this.model.on( 'remove', this.deselect, this ); 
     366                }, 
     367 
     368                render: function() { 
     369                        media.view.Attachment.Details.prototype.render.apply( this, arguments ); 
     370 
     371                        media.mixin.removeAllPlayers(); 
     372                        $( 'audio, video', this.$el ).each( function (i, elem) { 
     373                                var el = media.view.MediaDetails.prepareSrc( elem ); 
     374                                new MediaElementPlayer( el, media.mixin.mejsSettings ); 
     375                        } ); 
     376                } 
     377        }); 
     378 
     379        /** 
     380         * A frame for editing the details of a specific media item. 
     381         * 
     382         * Opens in a modal by default. 
     383         * 
     384         * Requires an attachment model to be passed in the options hash under `model`. 
     385         */ 
     386        media.view.Frame.EditAttachment = media.view.Frame.extend({ 
     387 
     388                className: 'edit-attachment-frame', 
     389                template: media.template( 'edit-attachment-frame' ), 
     390                regions:   [ 'router', 'content' ], 
     391 
     392                events: { 
     393                        'click':                    'collapse', 
     394                        'click .delete-media-item': 'deleteMediaItem', 
     395                        'click .left':              'previousMediaItem', 
     396                        'click .right':             'nextMediaItem' 
     397                }, 
     398 
     399                initialize: function( options ) { 
     400                        var self = this; 
     401                        media.view.Frame.prototype.initialize.apply( this, arguments ); 
     402 
     403                        _.defaults( this.options, { 
     404                                modal: true, 
     405                                state: 'edit-attachment' 
     406                        }); 
     407 
     408                        this.createStates(); 
     409 
     410                        this.on( 'content:render:edit-metadata', this.editMetadataContent, this ); 
     411                        this.on( 'content:render:edit-image', this.editImageContentUgh, this ); 
     412 
     413                        // Only need a tab to Edit Image for images. 
     414                        if ( this.model.get( 'type' ) === 'image' ) { 
     415                                this.on( 'router:create', this.createRouter, this ); 
     416                                this.on( 'router:render', this.browseRouter, this ); 
     417                        } 
     418 
     419                        // Initialize modal container view. 
     420                        if ( this.options.modal ) { 
     421                                this.modal = new media.view.Modal({ 
     422                                        controller: this, 
     423                                        title:      this.options.title 
     424                                }); 
     425 
     426                                // Completely destroy the modal DOM element when closing it. 
     427                                this.modal.close = function() { 
     428                                        self.modal.remove(); 
     429                                }; 
     430 
     431                                this.modal.content( this ); 
     432                                this.modal.open(); 
     433                        } 
     434                }, 
     435 
     436                /** 
     437                 * Add the default states to the frame. 
     438                 */ 
     439                createStates: function() { 
     440                        this.states.add([ 
     441                                new media.controller.EditImageNoFrame( { model: this.model } ) 
     442                        ]); 
     443                }, 
     444 
     445                /** 
     446                 * @returns {wp.media.view.MediaFrame} Returns itself to allow chaining 
     447                 */ 
     448                render: function() { 
     449                        // Activate the default state if no active state exists. 
     450                        if ( ! this.state() && this.options.state ) { 
     451                                this.setState( this.options.state ); 
     452                        } 
     453                        /** 
     454                         * call 'render' directly on the parent class 
     455                         */ 
     456                        return media.view.Frame.prototype.render.apply( this, arguments ); 
     457                }, 
     458 
     459                /** 
     460                 * Content region rendering callback for the `edit-metadata` mode. 
     461                 */ 
     462                editMetadataContent: function() { 
     463                        var view = new media.view.Attachment.Details.TwoColumn({ 
     464                                controller: this, 
     465                                model:      this.model 
     466                        }); 
     467                        this.content.set( view ); 
     468                }, 
     469 
     470                /** 
     471                 * For some reason the view doesn't exist in the DOM yet, don't have the 
     472                 * patience to track this down right now. 
     473                 */ 
     474                editImageContentUgh: function() { 
     475                        _.defer( _.bind( this.editImageContent, this ) ); 
     476                }, 
     477 
     478                /** 
     479                 * Render the EditImage view into the frame's content region. 
     480                 */ 
     481                editImageContent: function() { 
     482                        var view = new media.view.EditImage( { model: this.model, controller: this } ).render(); 
     483 
     484                        this.content.set( view ); 
     485 
     486                        // after creating the wrapper view, load the actual editor via an ajax call 
     487                        view.loadEditor(); 
     488                }, 
     489 
     490                /** 
     491                 * Create the router view. 
     492                 * 
     493                 * @param {Object} router 
     494                 * @this wp.media.controller.Region 
     495                 */ 
     496                createRouter: function( router ) { 
     497                        router.view = new media.view.Router({ 
     498                                controller: this 
     499                        }); 
     500                }, 
     501 
     502                /** 
     503                 * Router rendering callback. 
     504                 * 
     505                 * @param  media.view.Router view Instantiated in this.createRouter() 
     506                 */ 
     507                browseRouter: function( view ) { 
     508                        view.set({ 
     509                                'edit-metadata': { 
     510                                        text:     'Edit Metadata', 
     511                                        priority: 20 
     512                                }, 
     513                                'edit-image': { 
     514                                        text:     'Edit Image', 
     515                                        priority: 40 
     516                                } 
     517                        }); 
     518                }, 
     519 
     520                /** 
     521                 * Click handler to switch to the previous media item. 
     522                 */ 
     523                previousMediaItem: function() { 
     524                        if ( ! this.options.hasPrevious ) 
     525                                return; 
     526                        this.modal.close(); 
     527                        this.options.gridController.trigger( 'edit:attachment:previous', this.model ); 
     528                }, 
     529 
     530                /** 
     531                 * Click handler to switch to the next media item. 
     532                 */ 
     533                nextMediaItem: function() { 
     534                        if ( ! this.options.hasNext ) 
     535                                return; 
     536                        this.modal.close(); 
     537                        this.options.gridController.trigger( 'edit:attachment:next', this.model ); 
     538                } 
     539 
     540        }); 
     541 
     542}(jQuery, _, Backbone, wp)); 
     543 No newline at end of file 
  • src/wp-includes/js/media-views.js

     
    17581758                        _.defaults( this.options, { 
    17591759                                title:    '', 
    17601760                                modal:    true, 
    1761                                 uploader: true 
     1761                                uploader: true, 
     1762                                mode:     ['select'] 
    17621763                        }); 
    17631764 
    17641765                        // Ensure core UI is enabled. 
     
    45304531                        var selection = this.options.selection; 
    45314532 
    45324533                        this.$el.attr('aria-label', this.model.attributes.title).attr('aria-checked', false); 
    4533                         this.model.on( 'change:sizes change:uploading', this.render, this ); 
     4534                        this.model.on( 'change', this.render, this ); 
    45344535                        this.model.on( 'change:title', this._syncTitle, this ); 
    45354536                        this.model.on( 'change:caption', this._syncCaption, this ); 
    45364537                        this.model.on( 'change:percent', this.progress, this ); 
     
    45834584                                        compat:        false, 
    45844585                                        alt:           '', 
    45854586                                        description:   '' 
    4586                                 }); 
     4587                                }, this.options ); 
    45874588 
    45884589                        options.buttons  = this.buttons; 
    45894590                        options.describe = this.controller.state().get('describe'); 
     
    46334634                 */ 
    46344635                toggleSelectionHandler: function( event ) { 
    46354636                        var method; 
    4636  
    46374637                        // Catch enter and space events 
    46384638                        if ( 'keydown' === event.type && 13 !== event.keyCode && 32 !== event.keyCode ) { 
    46394639                                return; 
    46404640                        } 
     4641 
     4642                        // In the grid view, bubble up an edit:attachment event to the controller. 
     4643                        if ( _.contains( this.controller.options.mode, 'grid' ) ) { 
     4644                                this.controller.trigger( 'edit:attachment', this.model ); 
     4645                                return; 
     4646                        } 
     4647 
    46414648                        if ( event.shiftKey ) { 
    46424649                                method = 'between'; 
    46434650                        } else if ( event.ctrlKey || event.metaKey ) { 
     
    51685175                 */ 
    51695176                createAttachmentView: function( attachment ) { 
    51705177                        var view = new this.options.AttachmentView({ 
    5171                                 controller: this.controller, 
    5172                                 model:      attachment, 
    5173                                 collection: this.collection, 
    5174                                 selection:  this.options.selection 
     5178                                controller:           this.controller, 
     5179                                model:                attachment, 
     5180                                collection:           this.collection, 
     5181                                selection:            this.options.selection, 
     5182                                showAttachmentFields: this.options.showAttachmentFields 
    51755183                        }); 
    51765184 
    51775185                        return this._viewsByCid[ attachment.cid ] = view; 
     
    54685476                } 
    54695477        }); 
    54705478 
    5471  
    54725479        /** 
    54735480         * wp.media.view.AttachmentsBrowser 
    54745481         * 
     
    54865493                                filters: false, 
    54875494                                search:  true, 
    54885495                                display: false, 
    5489  
     5496                                sidebar: true, 
     5497                                showAttachmentFields: getUserSetting( 'showAttachmentFields', [ 'title', 'uploadedTo', 'dateFormatted', 'mime' ] ), 
    54905498                                AttachmentView: media.view.Attachment.Library 
    54915499                        }); 
    54925500 
    54935501                        this.createToolbar(); 
    54945502                        this.updateContent(); 
    5495                         this.createSidebar(); 
     5503                        if ( this.options.sidebar ) { 
     5504                                this.createSidebar(); 
     5505                        } else { 
     5506                                this.$el.addClass( 'hide-sidebar' ); 
     5507                        } 
    54965508 
    54975509                        this.collection.on( 'add remove reset', this.updateContent, this ); 
    54985510                }, 
     
    55175529 
    55185530                        this.views.add( this.toolbar ); 
    55195531 
     5532                        // Feels odd to bring the global media library switcher into the Attachment 
     5533                        // browser view. Is this a use case for doAction( 'add:toolbar-items:attachments-browser', this.toolbar ); 
     5534                        // which the controller can tap into and add this view? 
     5535                        if ( _.contains( this.controller.options.mode, 'grid' ) ) { 
     5536                                var libraryViewSwitcherConstructor = media.View.extend({ 
     5537                                        className: 'view-switch media-grid-view-switch', 
     5538                                        template: media.template( 'media-library-view-switcher') 
     5539                                }); 
     5540                                this.toolbar.set( 'libraryViewSwitcher', new libraryViewSwitcherConstructor({ 
     5541                                        controller: this.controller, 
     5542                                        priority: -90 
     5543                                }).render() ); 
     5544                        } 
     5545 
    55205546                        filters = this.options.filters; 
    55215547                        if ( 'uploaded' === filters ) { 
    55225548                                FiltersConstructor = media.view.AttachmentFilters.Uploaded; 
     
    56115637                        this.removeContent(); 
    56125638 
    56135639                        this.attachments = new media.view.Attachments({ 
    5614                                 controller: this.controller, 
    5615                                 collection: this.collection, 
    5616                                 selection:  this.options.selection, 
    5617                                 model:      this.model, 
    5618                                 sortable:   this.options.sortable, 
     5640                                controller:           this.controller, 
     5641                                collection:           this.collection, 
     5642                                selection:            this.options.selection, 
     5643                                model:                this.model, 
     5644                                sortable:             this.options.sortable, 
     5645                                showAttachmentFields: this.options.showAttachmentFields, 
    56195646 
    56205647                                // The single `Attachment` view to be used in the `Attachments` view. 
    56215648                                AttachmentView: this.options.AttachmentView 
  • src/wp-includes/media-template.php

     
    220220                </div> 
    221221        </script> 
    222222 
     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 
    223232        <script type="text/html" id="tmpl-uploader-status"> 
    224233                <h3><?php _e( 'Uploading' ); ?></h3> 
    225234                <a class="upload-dismiss-errors" href="#"><?php _e('Dismiss Errors'); ?></a> 
     
    241250                <span class="upload-error-message">{{ data.message }}</span> 
    242251        </script> 
    243252 
     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 }} &times; {{ data.height }}</div> 
     290                                        <# } #> 
     291 
     292                                        <# if ( data.can.save ) { #> 
     293                                                <a class="edit-attachment" href="{{ data.editLink }}&amp;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                        <# if ( 'audio' === data.type ) { #> 
     317                        <div class="wp-media-wrapper"> 
     318                                <audio style="visibility: hidden" controls class="wp-audio-shortcode" width="100%" preload="none"> 
     319                                        <source type="{{ data.mime }}" src="{{ data.url }}"/> 
     320                                </audio> 
     321                        </div> 
     322                        <# } else if ( 'video' === data.type ) { #> 
     323                        <div style="max-width: 100%; width: {{ data.width }}px" class="wp-media-wrapper"> 
     324                                <video controls class="wp-video-shortcode" preload="metadata" 
     325                                        width="{{ data.width }}" height="{{ data.height }}" 
     326                                        <# if ( data.image.url !== data.icon ) { #>poster="{{ data.image.url }}"<# } #>> 
     327                                        <source type="{{ data.mime }}" src="{{ data.url }}"/> 
     328                                </video> 
     329                        </div> 
     330                        <# } #> 
     331                </div> 
     332                <div class="attachment-fields"> 
     333                        <label class="setting" data-setting="url"> 
     334                                <span class="name"><?php _e('URL'); ?></span> 
     335                                <input type="text" value="{{ data.url }}" readonly /> 
     336                        </label> 
     337                        <# var maybeReadOnly = data.can.save || data.allowLocalEdits ? '' : 'readonly'; #> 
     338                        <label class="setting" data-setting="title"> 
     339                                <span class="name"><?php _e('Title'); ?></span> 
     340                                <input type="text" value="{{ data.title }}" {{ maybeReadOnly }} /> 
     341                        </label> 
     342                        <label class="setting" data-setting="caption"> 
     343                                <span class="name"><?php _e('Caption'); ?></span> 
     344                                <textarea {{ maybeReadOnly }}>{{ data.caption }}</textarea> 
     345                        </label> 
     346                        <# if ( 'image' === data.type ) { #> 
     347                                <label class="setting" data-setting="alt"> 
     348                                        <span class="name"><?php _e('Alt Text'); ?></span> 
     349                                        <input type="text" value="{{ data.alt }}" {{ maybeReadOnly }} /> 
     350                                </label> 
     351                        <# } #> 
     352                        <label class="setting" data-setting="description"> 
     353                                <span class="name"><?php _e('Description'); ?></span> 
     354                                <textarea {{ maybeReadOnly }}>{{ data.description }}</textarea> 
     355                        </label> 
     356                        <label class="setting"> 
     357                                        <span class="name"><?php _e( 'Uploaded By' ); ?></span> 
     358                                        <span class="value">{{ data.authorName }}</span> 
     359                                </label> 
     360                        <# if ( data.uploadedTo ) { #> 
     361                                <label class="setting"> 
     362                                        <span class="name"><?php _e('Uploaded To'); ?></span> 
     363                                        <span class="value"><a href="{{ data.uploadedToLink }}">{{ data.uploadedToTitle }}</a></span> 
     364                                </label> 
     365                        <# } #> 
     366                </div> 
     367        </script> 
     368 
    244369        <script type="text/html" id="tmpl-attachment"> 
     370                <# if ( _.contains( data.controller.options.mode, 'grid' ) ) { #> 
     371                <div class="inline-toolbar"> 
     372                        <div class="dashicons dashicons-edit edit edit-media"></div> 
     373                </div> 
     374                <# } #> 
    245375                <div class="attachment-preview type-{{ data.type }} subtype-{{ data.subtype }} {{ data.orientation }}"> 
    246376                        <# if ( data.uploading ) { #> 
    247377                                <div class="media-progress-bar"><div></div></div> 
     
    251381                                                <img src="{{ data.size.url }}" draggable="false" alt="" /> 
    252382                                        </div> 
    253383                                </div> 
    254                         <# } else { #> 
     384                        <# } else { 
     385                                if ( data.thumb && data.thumb.src && data.thumb.src !== data.icon ) { 
     386                                #><img src="{{ data.thumb.src }}" class="thumbnail" draggable="false" /><# 
     387                                } #> 
    255388                                <img src="{{ data.icon }}" class="icon" draggable="false" /> 
    256389                                <div class="filename"> 
    257390                                        <div>{{ data.filename }}</div> 
    258391                                </div> 
    259392                        <# } #> 
    260  
    261393                        <# if ( data.buttons.close ) { #> 
    262394                                <a class="close media-modal-icon" href="#" title="<?php esc_attr_e('Remove'); ?>"></a> 
    263395                        <# } #> 
     
    268400                </div> 
    269401                <# 
    270402                var maybeReadOnly = data.can.save || data.allowLocalEdits ? '' : 'readonly'; 
    271                 if ( data.describe ) { #> 
    272                         <# if ( 'image' === data.type ) { #> 
     403                if ( data.describe ) { 
     404                        if ( 'image' === data.type ) { #> 
    273405                                <input type="text" value="{{ data.caption }}" class="describe" data-setting="caption" 
    274406                                        placeholder="<?php esc_attr_e('Caption this image&hellip;'); ?>" {{ maybeReadOnly }} /> 
    275407                        <# } else { #> 
     
    281413                                        <# } else { #> 
    282414                                                placeholder="<?php esc_attr_e('Describe this media file&hellip;'); ?>" 
    283415                                        <# } #> {{ maybeReadOnly }} /> 
    284                         <# } #> 
     416                        <# } 
     417                } 
     418 
     419                if ( _.contains( data.controller.options.mode, 'grid' ) ) { #> 
     420                <div class="data-fields"> 
     421                <# _.each( data.showAttachmentFields, function( field ) { #> 
     422                        <div class="data-field data-{{ field }}"><# 
     423                                if ( 'uploadedTo' === field ) { 
     424                                        if ( data[field] ) { 
     425                                        #><?php _e( 'Uploaded To:' ) ?><# 
     426                                        } else { 
     427                                        #><?php _e( 'Unattached' ) ?><# 
     428                                        } 
     429                                } else if ( 'title' === field && ! data[ field ] ) { 
     430                                #><?php _e( '(No title)' ) ?><# 
     431                                } 
     432 
     433                                if ( data[ field ] ) { 
     434                                        #>{{ data[ field ] }}<# 
     435                                } 
     436                        #></div> 
     437                <# }); #> 
     438                </div> 
    285439                <# } #> 
     440 
    286441        </script> 
    287442 
    288443        <script type="text/html" id="tmpl-attachment-details">