Ticket #21390: 21390.diff

File 21390.diff, 57.6 KB (added by koopersmith, 6 months ago)
  • wp-admin/js/custom-background.js

     
    3737                                } 
    3838                        }); 
    3939 
    40                         frame.toolbar.on( 'activate:select', function() { 
    41                                 frame.toolbar.view().set({ 
     40                        frame.on( 'toolbar:render:select', function( view ) { 
     41                                view.set({ 
    4242                                        select: { 
    4343                                                style: 'primary', 
    4444                                                text:  $el.data('update'), 
  • wp-admin/js/custom-header.js

     
    2424                                } 
    2525                        }); 
    2626 
    27                         frame.toolbar.on( 'activate:select', function() { 
    28                                 frame.toolbar.view().set({ 
     27                        frame.on( 'toolbar:render:select', function( view ) { 
     28                                view.set({ 
    2929                                        select: { 
    3030                                                style: 'primary', 
    3131                                                text:  $el.data('update'), 
  • wp-includes/css/media-views-rtl.css

     
    226226} 
    227227 
    228228/** 
    229  * Selection Preview 
    230  */ 
    231 .selected-img { 
    232         float: right; 
    233         margin-right: 0; 
    234         margin-left: 14px; 
    235 } 
    236  
    237 .selection-preview img { 
    238         float: right; 
    239         margin-left: 0; 
    240         margin-right: 1px; 
    241 } 
    242  
    243 .selection-preview .count { 
    244         right: auto; 
    245         left: 0; 
    246 } 
    247  
    248 .selection-preview .clear-selection { 
    249         float: right; 
    250 } 
    251  
    252 /** 
    253229 * Attachment Details 
    254230 */ 
    255231.attachment-info .thumbnail { 
  • wp-includes/css/media-views.css

     
    8080 */ 
    8181.media-modal { 
    8282        position: fixed; 
    83         top: 60px; 
    84         left: 40px; 
    85         right: 40px; 
    86         bottom: 40px; 
     83        top: 30px; 
     84        left: 30px; 
     85        right: 30px; 
     86        bottom: 30px; 
    8787        z-index: 160000; 
    8888} 
    8989 
     
    9494        right: 0; 
    9595        bottom: 0; 
    9696        background: #000; 
    97         opacity: 0.8; 
     97        opacity: 0.7; 
    9898        z-index: 159900; 
    9999} 
    100100 
    101 .media-modal-backdrop div, 
    102 .uploader-window-content { 
     101.media-modal-close { 
    103102        position: absolute; 
    104         top: 10px; 
    105         left: 10px; 
    106         right: 10px; 
    107         bottom: 10px; 
    108         border: 1px dashed rgba( 255, 255, 255, 0.5 ); 
     103        top: 7px; 
     104        right: 7px; 
     105        width: 30px; 
     106        height: 30px; 
     107        z-index: 1000; 
    109108} 
    110  
    111 .media-modal-title { 
    112         position: absolute; 
    113         top: -40px; 
    114         left: 0; 
    115         height: 40px; 
    116         padding: 0; 
    117         margin: 0; 
    118  
    119         line-height: 40px; 
    120         color: #fff; 
    121         font-size: 16px; 
    122         font-weight: 200; 
    123         text-shadow: 0 0 16px rgba( 0, 0, 0, 0.6 ); 
    124 } 
    125  
    126 .media-modal-close { 
    127         position: absolute; 
    128         top: -27px; 
    129         right: 0; 
     109.media-modal-close span { 
     110        display: block; 
     111        margin: 8px auto 0; 
     112        width: 15px; 
    130113        height: 15px; 
    131         width: 15px; 
    132         background-position: -80px 0; 
     114        background-position: -100px 0; 
    133115} 
    134116 
    135117.media-modal-close:active { 
     
    165147        border: 0 solid #dfdfdf; 
    166148} 
    167149 
    168 .media-frame-toolbar > .media-toolbar { 
    169         top: auto; 
    170         left: 200px; 
    171         bottom: 0; 
    172         border-width: 1px 0 0 0; 
    173         box-shadow: 0 -4px 4px -4px rgba( 0, 0, 0, 0.1 ); 
    174 } 
    175  
    176 .hide-toolbar .media-frame-toolbar > .media-toolbar { 
    177         bottom: -61px; 
    178 } 
    179  
    180150.media-toolbar-primary { 
    181151        float: right; 
    182152} 
     
    238208        width: 100%; 
    239209} 
    240210 
    241 .media-sidebar .selection-preview { 
    242         display: block; 
    243         padding-top: 5px; 
    244 } 
    245  
    246211.media-sidebar h3 { 
    247212        position: relative; 
    248213        font-weight: bold; 
     
    361326        position: absolute; 
    362327        top: 0; 
    363328        left: 0; 
     329        right: 0; 
    364330        bottom: 0; 
    365         width: 199px; 
    366331        margin: 0; 
    367332        padding: 16px 0; 
    368         z-index: 200; 
    369333        border-right: 1px solid #d9d9d9; 
    370334        box-shadow: inset -6px 0 6px -6px rgba( 0, 0, 0, 0.2 ); 
    371335        -webkit-user-select: none; 
     
    374338        user-select: none; 
    375339} 
    376340 
    377 .media-menu li { 
     341.media-menu > a { 
     342        display: block; 
    378343        position: relative; 
    379344        padding: 4px 20px; 
    380345        margin: 0; 
     
    382347        font-size: 14px; 
    383348        color: #21759B; 
    384349        text-shadow: 0 1px 0 #fff; 
     350        text-decoration: none; 
    385351} 
    386352 
    387 .media-menu-item { 
    388         cursor: pointer; 
     353.media-menu > a:hover { 
     354        color: #21759B; 
     355        background: rgba( 0, 0, 0, 0.04 ); 
    389356} 
    390357 
    391 .media-menu li:hover { 
    392         background: rgba( 0, 0, 0, 0.04 ); 
     358.media-menu > a:active { 
     359        outline: none; 
    393360} 
    394361 
    395362.media-menu .active, 
     
    407374} 
    408375 
    409376/** 
     377 * Menu 
     378 */ 
     379.media-router { 
     380        position: relative; 
     381        padding: 0 6px; 
     382        margin: 0; 
     383        clear: both; 
     384        -webkit-user-select: none; 
     385        -moz-user-select: none; 
     386        -ms-user-select: none; 
     387        user-select: none; 
     388} 
     389 
     390.media-router > a { 
     391        position: relative; 
     392        float: left; 
     393        padding: 2px 10px; 
     394        margin: 0; 
     395        height: 18px; 
     396        line-height: 18px; 
     397        font-size: 14px; 
     398        border-right: 1px solid #dfdfdf; 
     399        text-shadow: 0 1px 0 #fff; 
     400        text-decoration: none; 
     401} 
     402 
     403.media-router > a:last-child { 
     404        border-right: 0; 
     405} 
     406 
     407.media-router > a:active { 
     408        outline: none; 
     409} 
     410 
     411.media-router .active, 
     412.media-router .active:hover { 
     413        color: #333; 
     414} 
     415 
     416.media-router .active:after { 
     417        content: ''; 
     418        display: block; 
     419        margin: -100px auto 0; 
     420        width: 7px; 
     421        height: 7px; 
     422        background: #fff; 
     423        box-shadow: 1px 1px 1px rgba( 0, 0, 0, 0.2 ); 
     424        z-index: 300; 
     425 
     426        -webkit-transform: rotate( 45deg ) translate( 75px, 75px ); 
     427        -moz-transform:    rotate( 45deg ) translate( 75px, 75px ); 
     428        -ms-transform:     rotate( 45deg ) translate( 75px, 75px ); 
     429        -o-transform:      rotate( 45deg ) translate( 75px, 75px ); 
     430        transform:         rotate( 45deg ) translate( 75px, 75px ); 
     431} 
     432 
     433/** 
    410434 * Frame 
    411435 */ 
    412436.media-frame { 
     
    418442        bottom: 0; 
    419443} 
    420444 
    421 .media-frame .region-content { 
     445.media-frame-menu { 
    422446        position: absolute; 
    423447        top: 0; 
     448        left: 0; 
     449        bottom: 0; 
     450        width: 199px; 
     451        z-index: 150; 
     452} 
     453 
     454.media-frame-title { 
     455        position: absolute; 
     456        top: 0; 
    424457        left: 200px; 
    425458        right: 0; 
     459        height: 45px; 
     460        z-index: 200; 
     461} 
     462 
     463.media-frame-router { 
     464        position: absolute; 
     465        top: 45px; 
     466        left: 200px; 
     467        right: 0; 
     468        height: 30px; 
     469        z-index: 200; 
     470        border-bottom: 1px solid #dfdfdf; 
     471        box-shadow: 0 4px 4px -4px rgba( 0, 0, 0, 0.1 ); 
     472} 
     473 
     474.media-frame-content { 
     475        position: absolute; 
     476        top: 75px; 
     477        left: 200px; 
     478        right: 0; 
    426479        bottom: 61px; 
    427480        height: auto; 
    428481        width: auto; 
     
    430483        overflow: auto; 
    431484} 
    432485 
    433 .media-frame.hide-toolbar .region-content { 
     486.media-frame-toolbar { 
     487        position: absolute; 
     488        left: 200px; 
     489        right: 0; 
    434490        bottom: 0; 
     491        height: 60px; 
     492        z-index: 100; 
     493        border: 0 solid #dfdfdf; 
     494        border-width: 1px 0 0 0; 
     495        box-shadow: 0 -4px 4px -4px rgba( 0, 0, 0, 0.1 ); 
    435496} 
    436497 
     498.media-frame.hide-menu .media-frame-title, 
     499.media-frame.hide-menu .media-frame-router, 
     500.media-frame.hide-menu .media-frame-toolbar, 
     501.media-frame.hide-menu .media-frame-content { 
     502        left: 0; 
     503} 
     504 
     505.media-frame.hide-menu .media-frame-menu { 
     506        left: -200px; 
     507} 
     508 
     509.media-frame.hide-toolbar .media-frame-content { 
     510        bottom: 0; 
     511} 
     512 
     513.media-frame.hide-toolbar .media-frame-toolbar { 
     514        bottom: -61px; 
     515} 
     516 
     517.media-frame.hide-router .media-frame-content { 
     518        top: 45px; 
     519} 
     520 
     521.media-frame.hide-router .media-frame-router { 
     522        display: none; 
     523} 
     524 
     525.media-frame.hide-router .media-frame-title { 
     526        border-bottom: 1px solid #dfdfdf; 
     527        box-shadow: 0 4px 4px -4px rgba( 0, 0, 0, 0.1 ); 
     528} 
     529 
    437530.media-frame .media-toolbar .add-to-gallery { 
    438531        display: none; 
    439532} 
    440533 
     534.media-frame-title h1 { 
     535        padding: 0 16px; 
     536        font-size: 22px; 
     537        font-weight: 200; 
     538        line-height: 45px; 
     539        margin: 0; 
     540} 
     541 
    441542/** 
    442543 * Iframes 
    443544 */ 
     
    721822 * Attachments Browser 
    722823 */ 
    723824.media-frame .attachments-browser { 
     825        position: relative; 
     826        width: 100%; 
     827        height: 100%; 
    724828        overflow: hidden; 
    725829} 
    726830 
     
    9031007} 
    9041008 
    9051009.uploader-window-content { 
    906         border-color: #fff; 
     1010        position: absolute; 
     1011        top: 10px; 
     1012        left: 10px; 
     1013        right: 10px; 
     1014        bottom: 10px; 
     1015        border: 1px dashed #fff; 
    9071016} 
    9081017 
    9091018.uploader-window h3 { 
     
    9561065        margin: 4em 0; 
    9571066} 
    9581067 
     1068.uploader-inline .has-upload-message .upload-ui { 
     1069        margin: 0 0 4em; 
     1070} 
     1071 
    9591072.uploader-inline h3 { 
    9601073        font-size: 20px; 
    9611074        line-height: 28px; 
     
    9631076        margin-bottom: 1.6em; 
    9641077} 
    9651078 
     1079.uploader-inline .has-upload-message .upload-instructions { 
     1080        font-size: 14px; 
     1081        color: #464646; 
     1082        font-weight: normal; 
     1083} 
     1084 
    9661085.uploader-inline .drop-instructions { 
    9671086        display: none; 
    9681087} 
     
    10581177        vertical-align: top; 
    10591178} 
    10601179 
    1061 .media-selection .attachment img { 
     1180.media-selection .attachment .icon { 
    10621181        width: 50%; 
    10631182} 
    10641183 
     
    10981217} 
    10991218 
    11001219/** 
    1101  * Selection Preview 
    1102  */ 
    1103 .selection-preview { 
    1104         position: relative; 
    1105         height: 60px; 
    1106         overflow: hidden; 
    1107 } 
    1108  
    1109 .selected-img { 
    1110         float: left; 
    1111         position: relative; 
    1112         margin-right: 14px; 
    1113 } 
    1114  
    1115 .selection-preview img { 
    1116         max-width: 40px; 
    1117         max-height: 40px; 
    1118         float: left; 
    1119         margin-top: 6px; 
    1120         margin-left: 1px; 
    1121         border: 2px solid white; 
    1122         box-shadow: 
    1123             0 0 0 1px #ccc, 
    1124             3px 3px 0 0 #fff, 
    1125             3px 3px 0 1px #ccc, 
    1126             6px 6px 0 0 #fff, 
    1127             6px 6px 0 1px #ccc; 
    1128 } 
    1129  
    1130 .selection-preview .selected-count-1 img { 
    1131         margin-top: 8px; 
    1132         box-shadow: 0 0 0 1px #ccc; 
    1133 } 
    1134  
    1135 .selection-preview .selected-count-2 img { 
    1136         margin-top: 7px; 
    1137         box-shadow: 
    1138             0 0 0 1px #ccc, 
    1139             3px 3px 0 0 #fff, 
    1140             3px 3px 0 1px #ccc; 
    1141 } 
    1142  
    1143 .selection-preview .count { 
    1144         position: absolute; 
    1145         bottom: 0; 
    1146         right: 0; 
    1147         height: 16px; 
    1148         min-width: 8px; 
    1149         padding: 0 4px; 
    1150         font-size: 12px; 
    1151         text-align: center; 
    1152         font-weight: bold; 
    1153         color: #999; 
    1154         background: #fff; 
    1155         box-shadow: -1px -1px 2px -1px rgba( 0, 0, 0, 0.2 ); 
    1156 } 
    1157  
    1158 .selection-preview .clear-selection { 
    1159         float: left; 
    1160         line-height: 60px; 
    1161 } 
    1162  
    1163 /** 
    11641220 * Spinner 
    11651221 */ 
    11661222.media-sidebar .settings-save-status { 
     
    12961352.embed-url { 
    12971353        display: block; 
    12981354        position: relative; 
    1299         height: 75px; 
    1300         padding: 16px 16px; 
     1355        height: 40px; 
     1356        padding: 0 16px 16px; 
    13011357        margin: 0; 
    1302         z-index: 50; 
     1358        z-index: 250; 
     1359        background: #fff; 
    13031360        border-bottom: 1px solid #dfdfdf; 
    13041361        box-shadow: 0 4px 4px -4px rgba( 0, 0, 0, 0.1 ); 
    13051362        font-size: 18px; 
    13061363        font-weight: 200; 
    13071364} 
    13081365 
    1309 .embed-url span { 
    1310         display: block; 
    1311         padding: 4px 0 6px 2px; 
    1312 } 
    1313  
    13141366.media-frame .embed-url input { 
    13151367        font-size: 18px; 
    13161368        padding: 12px 14px; 
     
    13231375.embed-image-settings { 
    13241376        position: absolute; 
    13251377        background: #f5f5f5; 
    1326         top: 108px; 
     1378        top: 57px; 
    13271379        left: 0; 
    13281380        right: 0; 
    13291381        bottom: 0; 
     
    13871439 * Responsive layout 
    13881440 */ 
    13891441@media only screen and (max-width: 900px) { 
    1390         .media-modal { 
    1391                 bottom: 20px; 
    1392                 left: 20px; 
    1393                 right: 20px; 
    1394                 top: 40px; 
    1395         } 
    1396  
    1397         .media-modal-title { 
    1398                 height: 30px; 
    1399                 line-height: 30px; 
    1400                 top: -30px; 
    1401         } 
    1402  
    1403         .media-modal-close { 
    1404                 top: -23px; 
    1405         } 
    1406  
    1407         .media-modal-backdrop div, 
    1408         .uploader-window-content { 
    1409                 top: 5px; 
    1410                 left: 5px; 
    1411                 right: 5px; 
    1412                 bottom: 5px; 
    1413         } 
    1414  
    1415         .media-menu { 
     1442        .media-frame-menu { 
    14161443                width: 139px; 
    14171444        } 
    14181445 
     
    14201447                padding: 4px 10px; 
    14211448        } 
    14221449 
    1423         .media-frame .region-content, 
    1424         .media-frame-toolbar > .media-toolbar { 
     1450        .media-frame-content, 
     1451        .media-frame-toolbar { 
    14251452                left: 140px; 
    14261453        } 
    14271454 
  • wp-includes/js/media-editor.js

     
    384384 
    385385                        workflow = workflows[ id ] = wp.media( _.defaults( options || {}, { 
    386386                                frame:    'post', 
    387                                 state:    'upload', 
     387                                state:    'insert', 
    388388                                title:    wp.media.view.l10n.addMedia, 
    389389                                multiple: true 
    390390                        } ) ); 
     
    408408                        }, this ); 
    409409 
    410410                        workflow.state('embed').on( 'select', function() { 
    411                                 var embed = workflow.state().toJSON(); 
     411                                var state = workflow.state(), 
     412                                        type = state.get('type'), 
     413                                        embed = state.props.toJSON(); 
    412414 
    413415                                embed.url = embed.url || ''; 
    414416 
    415                                 if ( 'link' === embed.type ) { 
     417                                if ( 'link' === type ) { 
    416418                                        _.defaults( embed, { 
    417419                                                title:   embed.url, 
    418420                                                linkUrl: embed.url 
     
    420422 
    421423                                        this.send.link( embed ); 
    422424 
    423                                 } else if ( 'image' === embed.type ) { 
     425                                } else if ( 'image' === type ) { 
    424426                                        _.defaults( embed, { 
    425427                                                title:   embed.url, 
    426428                                                linkUrl: '', 
  • wp-includes/js/media-views.js

     
    6868         * wp.media.controller.Region 
    6969         */ 
    7070        media.controller.Region = function( options ) { 
    71                 _.extend( this, _.pick( options || {}, 'id', 'controller', 'selector' ) ); 
    72  
    73                 this.on( 'activate:empty', this.empty, this ); 
    74                 this.mode('empty'); 
     71                _.extend( this, _.pick( options || {}, 'id', 'view', 'selector' ) ); 
    7572        }; 
    7673 
    7774        // Use Backbone's self-propagating `extend` inheritance method. 
    7875        media.controller.Region.extend = Backbone.Model.extend; 
    7976 
    80         _.extend( media.controller.Region.prototype, Backbone.Events, { 
    81                 trigger: (function() { 
    82                         var eventSplitter = /\s+/, 
    83                                 trigger = Backbone.Events.trigger; 
     77        _.extend( media.controller.Region.prototype, { 
     78                mode: function( mode ) { 
     79                        if ( ! mode ) 
     80                                return this._mode; 
    8481 
    85                         return function( events ) { 
    86                                 var mode = ':' + this._mode, 
    87                                         modeEvents = events.split( eventSplitter ).join( mode ) + mode; 
    88  
    89                                 trigger.apply( this, arguments ); 
    90                                 trigger.apply( this, [ modeEvents ].concat( _.rest( arguments ) ) ); 
     82                        // Bail if we're trying to change to the current mode. 
     83                        if ( mode === this._mode ) 
    9184                                return this; 
    92                         }; 
    93                 }()), 
    9485 
    95                 mode: function( mode ) { 
    96                         if ( mode ) { 
    97                                 this.trigger( 'deactivate', this ); 
    98                                 this._mode = mode; 
    99                                 return this.trigger( 'activate', this ); 
    100                         } 
    101                         return this._mode; 
     86                        this.trigger('deactivate'); 
     87                        this._mode = mode; 
     88                        this.render( mode ); 
     89                        this.trigger('activate'); 
     90                        return this; 
    10291                }, 
    10392 
    104                 view: function( view ) { 
    105                         var previous = this._view, 
    106                                 mode = this._mode, 
    107                                 id = this.id; 
     93                render: function( mode ) { 
     94                        // If no mode is provided, just re-render the current mode. 
     95                        // If the provided mode isn't active, perform a full switch. 
     96                        if ( mode && mode !== this._mode ) 
     97                                return this.mode( mode ); 
    10898 
    109                         // If no argument is provided, return the current view. 
    110                         if ( ! view ) 
    111                                 return previous; 
     99                        var set = { view: null }, 
     100                                view; 
    112101 
    113                         // If we're attempting to switch to the current view, bail. 
    114                         if ( view === previous ) 
     102                        this.trigger( 'create', set ); 
     103                        view = set.view; 
     104                        this.trigger( 'render', view ); 
     105                        if ( view ) 
     106                                this.set( view ); 
     107                        return this; 
     108                }, 
     109 
     110                get: function() { 
     111                        return this.view.views.first( this.selector ); 
     112                }, 
     113 
     114                set: function( views, options ) { 
     115                        if ( options ) 
     116                                options.add = false; 
     117                        return this.view.views.set( this.selector, views, options ); 
     118                }, 
     119 
     120                trigger: function( event ) { 
     121                        var base; 
     122                        if ( ! this._mode ) 
    115123                                return; 
    116124 
    117                         // Add classes to the new view. 
    118                         if ( id ) 
    119                                 view.$el.addClass( 'region-' + id ); 
     125                        var args = _.toArray( arguments ); 
     126                        base = this.id + ':' + event; 
    120127 
    121                         if ( mode ) 
    122                                 view.$el.addClass( 'mode-' + mode ); 
     128                        // Trigger `region:action:mode` event. 
     129                        args[0] = base + ':' + this._mode; 
     130                        this.view.trigger.apply( this.view, args ); 
    123131 
    124                         this.controller.views.set( this.selector, view ); 
    125                         this._view = view; 
    126                 }, 
    127  
    128                 empty: function() { 
    129                         this.view( new media.View() ); 
     132                        // Trigger `region:action` event. 
     133                        args[0] = base; 
     134                        this.view.trigger.apply( this.view, args ); 
     135                        return this; 
    130136                } 
    131137        }); 
    132138 
     
    208214        // wp.media.controller.State 
    209215        // --------------------------- 
    210216        media.controller.State = Backbone.Model.extend({ 
    211                 initialize: function() { 
    212                         this.on( 'activate', this._activate, this ); 
     217                constructor: function() { 
     218                        this.on( 'activate', this._preActivate, this ); 
    213219                        this.on( 'activate', this.activate, this ); 
     220                        this.on( 'activate', this._postActivate, this ); 
    214221                        this.on( 'deactivate', this._deactivate, this ); 
    215222                        this.on( 'deactivate', this.deactivate, this ); 
    216223                        this.on( 'reset', this.reset, this ); 
     224                        this.on( 'ready', this._ready, this ); 
     225                        this.on( 'ready', this.ready, this ); 
     226 
     227                        this.on( 'change:menu', this._updateMenu, this ); 
     228 
     229                        Backbone.Model.apply( this, arguments ); 
    217230                }, 
    218231 
     232                ready: function() {}, 
    219233                activate: function() {}, 
    220                 _activate: function() { 
     234                deactivate: function() {}, 
     235                reset: function() {}, 
     236 
     237                _ready: function() { 
     238                        this._updateMenu(); 
     239                }, 
     240 
     241                _preActivate: function() { 
    221242                        this.active = true; 
     243                }, 
    222244 
    223                         this.menu(); 
    224                         this.toolbar(); 
    225                         this.content(); 
     245                _postActivate: function() { 
     246                        this.on( 'change:menu', this._menu, this ); 
     247                        this.on( 'change:titleMode', this._title, this ); 
     248                        this.on( 'change:content', this._content, this ); 
     249                        this.on( 'change:toolbar', this._toolbar, this ); 
     250 
     251                        this.frame.on( 'title:render:default', this._renderTitle, this ); 
     252 
     253                        this._title(); 
     254                        this._menu(); 
     255                        this._toolbar(); 
     256                        this._content(); 
     257                        this._router(); 
    226258                }, 
    227259 
    228                 deactivate: function() {}, 
     260 
    229261                _deactivate: function() { 
    230262                        this.active = false; 
     263 
     264                        this.frame.off( 'title:render:default', this._renderTitle, this ); 
     265 
     266                        this.off( 'change:menu', this._menu, this ); 
     267                        this.off( 'change:titleMode', this._title, this ); 
     268                        this.off( 'change:content', this._content, this ); 
     269                        this.off( 'change:toolbar', this._toolbar, this ); 
    231270                }, 
    232271 
    233                 reset: function() {}, 
     272                _title: function() { 
     273                        this.frame.title.render( this.get('titleMode') || 'default' ); 
     274                }, 
    234275 
    235                 menu: function() { 
     276                _renderTitle: function( view ) { 
     277                        view.$el.text( this.get('title') || '' ); 
     278                }, 
     279 
     280                _router: function() { 
     281                        var router = this.frame.router, 
     282                                mode = this.get('router'), 
     283                                view; 
     284 
     285                        this.frame.$el.toggleClass( 'hide-router', ! mode ); 
     286                        if ( ! mode ) 
     287                                return; 
     288 
     289                        this.frame.router.render( mode ); 
     290 
     291                        view = router.get(); 
     292                        if ( view.select ) 
     293                                view.select( this.frame.content.mode() ); 
     294                }, 
     295 
     296                _menu: function() { 
    236297                        var menu = this.frame.menu, 
    237298                                mode = this.get('menu'), 
    238299                                view; 
     
    240301                        if ( ! mode ) 
    241302                                return; 
    242303 
    243                         if ( menu.mode() !== mode ) 
    244                                 menu.mode( mode ); 
     304                        menu.mode( mode ); 
    245305 
    246                         view = menu.view(); 
     306                        view = menu.get(); 
    247307                        if ( view.select ) 
    248308                                view.select( this.id ); 
     309                }, 
     310 
     311                _updateMenu: function() { 
     312                        var previous = this.previous('menu'), 
     313                                menu = this.get('menu'); 
     314 
     315                        if ( previous ) 
     316                                this.frame.off( 'menu:render:' + previous, this._renderMenu, this ); 
     317 
     318                        if ( menu ) 
     319                                this.frame.on( 'menu:render:' + menu, this._renderMenu, this ); 
     320                }, 
     321 
     322                _renderMenu: function( view ) { 
     323                        var menuItem = this.get('menuItem'), 
     324                                title = this.get('title'), 
     325                                priority = this.get('priority'); 
     326 
     327                        if ( ! menuItem && title ) { 
     328                                menuItem = { text: title }; 
     329 
     330                                if ( priority ) 
     331                                        menuItem.priority = priority; 
     332                        } 
     333 
     334                        if ( ! menuItem ) 
     335                                return; 
     336 
     337                        view.set( this.id, menuItem ); 
    249338                } 
    250339        }); 
    251340 
    252341        _.each(['toolbar','content'], function( region ) { 
    253                 media.controller.State.prototype[ region ] = function() { 
     342                media.controller.State.prototype[ '_' + region ] = function() { 
    254343                        var mode = this.get( region ); 
    255344                        if ( mode ) 
    256                                 this.frame[ region ].mode( mode ); 
     345                                this.frame[ region ].render( mode ); 
    257346                }; 
    258347        }); 
    259348 
     
    264353                        id:         'library', 
    265354                        multiple:   false, 
    266355                        describe:   false, 
    267                         toolbar:    'main-attachments', 
     356                        toolbar:    'select', 
    268357                        sidebar:    'settings', 
    269                         content:    'browse', 
     358                        content:    'upload', 
     359                        router:     'browse', 
    270360                        searchable: true, 
    271361                        filterable: false, 
    272                         uploads:    true, 
    273                         sortable:   true 
     362                        sortable:   true, 
     363                        title:      l10n.mediaLibraryTitle, 
     364 
     365                        // Uses a user setting to override the content mode. 
     366                        contentUserSetting: true 
    274367                }, 
    275368 
    276369                initialize: function() { 
     
    290383                                this.set( 'gutter', 8 ); 
    291384 
    292385                        this.resetDisplays(); 
    293  
    294                         media.controller.State.prototype.initialize.apply( this, arguments ); 
    295386                }, 
    296387 
    297388                activate: function() { 
     
    303394                        this.on( 'change:library change:exclude', this.buildComposite, this ); 
    304395                        this.on( 'change:excludeState', this._excludeState, this ); 
    305396 
    306                         // If we're in a workflow that supports multiple attachments, 
    307                         // automatically select any uploading attachments. 
    308                         if ( this.get('multiple') ) 
    309                                 wp.Uploader.queue.on( 'add', this.selectUpload, this ); 
     397                        wp.Uploader.queue.on( 'add', this.uploading, this ); 
    310398 
    311399                        selection.on( 'add remove reset', this.refreshSelection, this ); 
    312400 
    313                         this.refresh(); 
    314401                        this.on( 'insert', this._insertDisplaySettings, this ); 
     402 
     403                        if ( this.get('contentUserSetting') ) { 
     404                                this.frame.on( 'content:activate', this.saveContentMode, this ); 
     405                                this.set( 'content', getUserSetting( 'libraryContent', this.get('content') ) ); 
     406                        } 
    315407                }, 
    316408 
    317409                deactivate: function() { 
     410                        this.frame.off( 'content:activate', this.saveContentMode, this ); 
     411 
    318412                        // Unbind all event handlers that use this state as the context 
    319413                        // from the selection. 
    320414                        this.get('selection').off( null, null, this ); 
     
    332426                        this.resetDisplays(); 
    333427                }, 
    334428 
    335                 refresh: function() { 
    336                         this.content(); 
    337                         this.refreshSelection(); 
    338                 }, 
    339  
    340429                resetDisplays: function() { 
    341430                        this._displays = []; 
    342431                        this._defaultDisplaySettings = { 
     
    375464                        var selection = this.get('selection'), 
    376465                                mode = this.frame.content.mode(); 
    377466 
    378                         this.frame.toolbar.view().refresh(); 
     467                        this.frame.toolbar.get().refresh(); 
    379468                        this.trigger( 'refresh:selection', this, selection ); 
    380469 
    381470                        if ( ! selection.length && 'browse' !== mode && 'upload' !== mode ) 
    382                                 this.content(); 
     471                                this.frame.content.render(); 
    383472                }, 
    384473 
    385                 selectUpload: function( attachment ) { 
    386                         this.get('selection').add( attachment ); 
     474                uploading: function( attachment ) { 
     475                        var content = this.frame.content; 
     476 
     477                        // If the uploader was selected, navigate to the browser. 
     478                        if ( 'upload' === content.mode() ) 
     479                                this.frame.content.mode('browse'); 
     480 
     481                        // If we're in a workflow that supports multiple attachments, 
     482                        // automatically select any uploading attachments. 
     483                        if ( this.get('multiple') ) 
     484                                this.get('selection').add( attachment ); 
    387485                }, 
    388486 
     487                saveContentMode: function() { 
     488                        // Only track the browse router on library states. 
     489                        if ( 'browse' !== this.get('router') ) 
     490                                return; 
     491 
     492                        setUserSetting( 'libraryContent', this.frame.content.mode() ); 
     493                }, 
     494 
    389495                buildComposite: function() { 
    390496                        var original = this.get('_library'), 
    391497                                exclude = this.get('exclude'), 
     
    448554                } 
    449555        }); 
    450556 
    451  
    452         // wp.media.controller.Upload 
    453         // --------------------------- 
    454         media.controller.Upload = media.controller.State.extend({ 
    455                 defaults: _.defaults({ 
    456                         id:      'upload', 
    457                         content: 'upload', 
    458                         toolbar: 'empty', 
    459                         uploads: true, 
    460  
    461                         // The state to navigate to when files are uploading. 
    462                         libraryState: 'library' 
    463                 }, media.controller.State.prototype.defaults ), 
    464  
    465                 initialize: function() { 
    466                         media.controller.State.prototype.initialize.apply( this, arguments ); 
    467                 }, 
    468  
    469                 activate: function() { 
    470                         wp.Uploader.queue.on( 'add', this.uploading, this ); 
    471                         media.controller.State.prototype.activate.apply( this, arguments ); 
    472                 }, 
    473  
    474                 deactivate: function() { 
    475                         wp.Uploader.queue.off( null, null, this ); 
    476                         media.controller.State.prototype.deactivate.apply( this, arguments ); 
    477                 }, 
    478  
    479                 uploading: function( attachment ) { 
    480                         var library = this.get('libraryState'); 
    481  
    482                         this.frame.state( library ).get('selection').add( attachment ); 
    483                         this.frame.setState( library ); 
    484                 } 
    485         }); 
    486  
    487557        // wp.media.controller.Gallery 
    488558        // --------------------------- 
    489559        media.controller.Gallery = media.controller.Library.extend({ 
     
    496566                        sortable:   true, 
    497567                        searchable: false, 
    498568                        toolbar:    'gallery-edit', 
    499                         content:    'browse' 
     569                        content:    'browse', 
     570                        title:      l10n.editGalleryTitle, 
     571                        priority:   60 
    500572                }, 
    501573 
    502574                initialize: function() { 
     
    519591                        // Watch for uploaded attachments. 
    520592                        this.get('library').observe( wp.Uploader.queue ); 
    521593 
    522                         this.frame.content.on( 'activate:browse', this.gallerySettings, this ); 
     594                        this.frame.on( 'content:render:browse', this.gallerySettings, this ); 
    523595 
    524596                        media.controller.Library.prototype.activate.apply( this, arguments ); 
    525597                }, 
     
    528600                        // Stop watching for uploaded attachments. 
    529601                        this.get('library').unobserve( wp.Uploader.queue ); 
    530602 
    531                         this.frame.content.off( null, null, this ); 
     603                        this.frame.off( 'content:render:browse', this.gallerySettings, this ); 
     604 
    532605                        media.controller.Library.prototype.deactivate.apply( this, arguments ); 
    533606                }, 
    534607 
    535                 gallerySettings: function() { 
    536                         var library = this.get('library'), 
    537                                 browser; 
     608                gallerySettings: function( browser ) { 
     609                        var library = this.get('library'); 
    538610 
    539                         if ( ! library ) 
     611                        if ( ! library || ! browser ) 
    540612                                return; 
    541613 
    542614                        library.gallery = library.gallery || new Backbone.Model(); 
    543615 
    544                         browser = this.frame.content.view(); 
    545  
    546616                        browser.sidebar.set({ 
    547617                                gallery: new media.view.Settings.Gallery({ 
    548618                                        controller: this, 
     
    570640                        filterable: 'uploaded', 
    571641                        multiple:   false, 
    572642                        menu:       'main', 
    573                         toolbar:    'featured-image' 
     643                        toolbar:    'featured-image', 
     644                        title:      l10n.featuredImageTitle, 
     645                        priority:   60 
    574646                }, media.controller.Library.prototype.defaults ), 
    575647 
    576648                initialize: function() { 
     
    629701                        menu:    'main', 
    630702                        content: 'embed', 
    631703                        toolbar: 'main-embed', 
    632                         type:    'link' 
     704                        type:    'link', 
     705 
     706                        title:    l10n.fromUrlTitle, 
     707                        priority: 120 
    633708                }, 
    634709 
    635710                // The amount of time used when debouncing the scan. 
     
    637712 
    638713                initialize: function() { 
    639714                        this.debouncedScan = _.debounce( _.bind( this.scan, this ), this.sensitivity ); 
    640                         this.on( 'change:url', this.debouncedScan, this ); 
     715                        this.props = new Backbone.Model({ url: '' }); 
     716                        this.props.on( 'change:url', this.debouncedScan, this ); 
    641717                        this.on( 'scan', this.scanImage, this ); 
    642                         media.controller.State.prototype.initialize.apply( this, arguments ); 
    643718                }, 
    644719 
    645720                scan: function() { 
     
    652727                scanImage: function( attributes ) { 
    653728                        var frame = this.frame, 
    654729                                state = this, 
    655                                 url = this.get('url'), 
     730                                url = this.props.get('url'), 
    656731                                image = new Image(); 
    657732 
    658733                        image.onload = function() { 
    659                                 if ( state !== frame.state() || url !== state.get('url') ) 
     734                                if ( state !== frame.state() || url !== state.props.get('url') ) 
    660735                                        return; 
    661736 
    662737                                state.set({ 
     
    670745                }, 
    671746 
    672747                reset: function() { 
    673                         _.each( _.difference( _.keys( this.attributes ), _.keys( this.defaults ) ), function( key ) { 
    674                                 this.unset( key ); 
    675                         }, this ); 
     748                        this.props = new Backbone.Model({ url: '' }); 
    676749 
    677                         this.set( 'url', '' ); 
    678  
    679750                        if ( this.id === this.frame.state().id ) 
    680                                 this.frame.toolbar.view().refresh(); 
     751                                this.frame.toolbar.get().refresh(); 
    681752                } 
    682753        }); 
    683754 
     
    10221093                // The constructor for the `Views` manager. 
    10231094                Views: media.Views, 
    10241095 
    1025                 constructor: function() { 
     1096                constructor: function( options ) { 
    10261097                        this.views = new this.Views( this, this.views ); 
    10271098                        this.on( 'ready', this.ready, this ); 
     1099 
     1100                        if ( options && options.controller ) 
     1101                                this.controller = options.controller; 
     1102 
    10281103                        Backbone.View.apply( this, arguments ); 
    10291104                }, 
    10301105 
     
    10971172                        // Initialize regions. 
    10981173                        _.each( this.regions, function( region ) { 
    10991174                                this[ region ] = new media.controller.Region({ 
    1100                                         controller: this, 
    1101                                         id:         region, 
    1102                                         selector:   '.media-frame-' + region 
     1175                                        view:    this, 
     1176                                        id:       region, 
     1177                                        selector: '.media-frame-' + region 
    11031178                                }); 
    11041179                        }, this ); 
    11051180                }, 
     
    11131188                        // Ensure states have a reference to the frame. 
    11141189                        this.states.on( 'add', function( model ) { 
    11151190                                model.frame = this; 
     1191                                model.trigger('ready'); 
    11161192                        }, this ); 
    11171193                }, 
    11181194 
     
    11311207        media.view.MediaFrame = media.view.Frame.extend({ 
    11321208                className: 'media-frame', 
    11331209                template:  media.template('media-frame'), 
    1134                 regions:   ['menu','content','toolbar'], 
     1210                regions:   ['menu','title','content','toolbar','router'], 
    11351211 
    11361212                initialize: function() { 
    11371213                        media.view.Frame.prototype.initialize.apply( this, arguments ); 
     
    11731249                        } 
    11741250 
    11751251                        this.on( 'attach', _.bind( this.views.ready, this.views ), this ); 
     1252 
     1253                        // Bind default title creation. 
     1254                        this.on( 'title:create:default', this.createTitle, this ); 
     1255                        this.title.mode('default'); 
    11761256                }, 
    11771257 
    11781258                render: function() { 
     
    11831263                        return media.view.Frame.prototype.render.apply( this, arguments ); 
    11841264                }, 
    11851265 
     1266                createTitle: function( title ) { 
     1267                        title.view = new media.View({ 
     1268                                controller: this, 
     1269                                tagName: 'h1' 
     1270                        }); 
     1271                }, 
     1272 
     1273                createMenu: function( menu ) { 
     1274                        menu.view = new media.view.Menu({ 
     1275                                controller: this 
     1276                        }); 
     1277                }, 
     1278 
     1279                createToolbar: function( toolbar ) { 
     1280                        menu.view = new media.view.Toolbar({ 
     1281                                controller: this 
     1282                        }); 
     1283                }, 
     1284 
     1285                createRouter: function( router ) { 
     1286                        router.view = new media.view.Router({ 
     1287                                controller: this 
     1288                        }); 
     1289                }, 
     1290 
    11861291                createIframeStates: function( options ) { 
    11871292                        var settings = media.view.settings, 
    11881293                                tabs = settings.tabs, 
     
    12081313                                }, options ) ); 
    12091314                        }, this ); 
    12101315 
    1211                         this.content.on( 'activate:iframe', this.iframeContent, this ); 
    1212                         this.menu.on( 'activate:main', this.iframeMenu, this ); 
     1316                        this.on( 'content:create:iframe', this.iframeContent, this ); 
     1317                        this.on( 'menu:render:main', this.iframeMenu, this ); 
    12131318                        this.on( 'open', this.hijackThickbox, this ); 
    12141319                        this.on( 'close', this.restoreThickbox, this ); 
    12151320                }, 
    12161321 
    1217                 iframeContent: function() { 
     1322                iframeContent: function( content ) { 
    12181323                        this.$el.addClass('hide-toolbar'); 
    1219                         this.content.view( new media.view.Iframe({ 
     1324                        content.view = new media.view.Iframe({ 
    12201325                                controller: this 
    1221                         }).render() ); 
     1326                        }); 
    12221327                }, 
    12231328 
    1224                 iframeMenu: function() { 
     1329                iframeMenu: function( view ) { 
    12251330                        var views = {}; 
    12261331 
     1332                        if ( ! view ) 
     1333                                return; 
     1334 
    12271335                        _.each( media.view.settings.tabs, function( title, id ) { 
    12281336                                views[ 'iframe:' + id ] = { 
    12291337                                        text: this.state( 'iframe:' + id ).get('title'), 
     
    12311339                                }; 
    12321340                        }, this ); 
    12331341 
    1234                         this.menu.view().set( views ); 
     1342                        view.set( views ); 
    12351343                }, 
    12361344 
    12371345                hijackThickbox: function() { 
     
    13051413                                new media.controller.Library({ 
    13061414                                        selection: options.selection, 
    13071415                                        library:   media.query( options.library ), 
    1308                                         multiple:  this.options.multiple, 
     1416                                        multiple:  options.multiple, 
    13091417                                        menu:      'main', 
    1310                                         toolbar:   'select' 
    1311                                 }), 
    1312  
    1313                                 new media.controller.Upload({ 
    1314                                         menu: 'main' 
     1418                                        title:     options.title, 
     1419                                        priority:  20 
    13151420                                }) 
    13161421                        ]); 
    13171422                }, 
    13181423 
    13191424                bindHandlers: function() { 
    1320                         this.menu.on( 'activate:main', this.mainMenu, this ); 
    1321                         this.content.on( 'activate:browse', this.browseContent, this ); 
    1322                         this.content.on( 'activate:upload', this.uploadContent, this ); 
    1323                         this.toolbar.on( 'activate:select', this.selectToolbar, this ); 
     1425                        this.on( 'menu:create:main', this.createMenu, this ); 
     1426                        this.on( 'router:create:browse', this.createRouter, this ); 
     1427                        this.on( 'router:render:browse', this.browseRouter, this ); 
     1428                        this.on( 'content:create:browse', this.browseContent, this ); 
     1429                        this.on( 'content:render:upload', this.uploadContent, this ); 
     1430                        this.on( 'toolbar:create:select', this.createSelectToolbar, this ); 
    13241431 
    13251432                        this.on( 'refresh:selection', this.refreshSelectToolbar, this ); 
    13261433                }, 
    13271434 
    1328                 mainMenu: function( options ) { 
    1329                         this.menu.view( new media.view.Menu({ 
    1330                                 controller: this, 
    1331                                 silent:     options && options.silent, 
    1332  
    1333                                 views: { 
    1334                                         upload: { 
    1335                                                 text: l10n.uploadFilesTitle, 
    1336                                                 priority: 20 
    1337                                         }, 
    1338                                         library: { 
    1339                                                 text: l10n.mediaLibraryTitle, 
    1340                                                 priority: 40 
    1341                                         } 
     1435                // Routers 
     1436                browseRouter: function( view ) { 
     1437                        view.set({ 
     1438                                upload: { 
     1439                                        text:     l10n.uploadFilesTitle, 
     1440                                        priority: 20 
     1441                                }, 
     1442                                browse: { 
     1443                                        text:     l10n.mediaLibraryTitle, 
     1444                                        priority: 40 
    13421445                                } 
    1343                         }) ); 
     1446                        }); 
    13441447                }, 
    13451448 
    13461449                // Content 
    1347                 browseContent: function() { 
     1450                browseContent: function( content ) { 
    13481451                        var state = this.state(); 
    13491452 
    13501453                        this.$el.removeClass('hide-toolbar'); 
    13511454 
    13521455                        // Browse our library of attachments. 
    1353                         this.content.view( new media.view.AttachmentsBrowser({ 
     1456                        content.view = new media.view.AttachmentsBrowser({ 
    13541457                                controller: this, 
    13551458                                collection: state.get('library'), 
    13561459                                selection:  state.get('selection'), 
    13571460                                model:      state, 
    13581461                                sortable:   state.get('sortable'), 
    13591462                                search:     state.get('searchable'), 
    1360                                 uploads:    state.get('uploads'), 
    13611463                                filters:    state.get('filterable'), 
    13621464                                display:    state.get('displaySettings'), 
    13631465 
    13641466                                AttachmentView: state.get('AttachmentView') 
    1365                         }) ); 
     1467                        }); 
    13661468                }, 
    13671469 
    13681470                uploadContent: function() { 
    1369                         this.$el.addClass('hide-toolbar'); 
    1370  
    1371                         this.content.view( new media.view.UploaderInline({ 
     1471                        this.$el.removeClass('hide-toolbar'); 
     1472                        this.content.set( new media.view.UploaderInline({ 
    13721473                                controller: this 
    13731474                        }) ); 
    13741475                }, 
    13751476 
    13761477                // Toolbars 
    1377                 selectToolbar: function( options ) { 
     1478                createSelectToolbar: function( toolbar, options ) { 
    13781479                        options = _.defaults( options || {}, { 
    13791480                                event:  'select', 
    13801481                                silent: false, 
    13811482                                state:  false 
    13821483                        }); 
    13831484 
    1384                         this.toolbar.view( new media.view.Toolbar({ 
     1485                        toolbar.view = new media.view.Toolbar({ 
    13851486                                controller: this, 
    13861487                                silent:     options.silent, 
    13871488 
     
    14021503                                                } 
    14031504                                        } 
    14041505                                } 
    1405                         }) ); 
     1506                        }); 
    14061507                }, 
    14071508 
    14081509                refreshSelectToolbar: function() { 
     
    14111512                        if ( ! selection || 'select' !== this.toolbar.mode() ) 
    14121513                                return; 
    14131514 
    1414                         this.toolbar.view().get('select').model.set( 'disabled', ! selection.length ); 
     1515                        this.toolbar.get().get('select').model.set( 'disabled', ! selection.length ); 
    14151516                } 
    14161517        }); 
    14171518 
     
    14301531                }, 
    14311532 
    14321533                createStates: function() { 
    1433                         var options = this.options; 
    1434  
    1435                         // Add the default states. 
    1436                         this.states.add([ 
    1437                                 // Main states. 
    1438                                 new media.controller.Library({ 
    1439                                         selection:  options.selection, 
    1440                                         library:    media.query( options.library ), 
     1534                        var options = this.options, 
     1535                                selection = options.selection, 
     1536                                library = { 
    14411537                                        editable:   true, 
    1442                                         filterable: 'all', 
    14431538                                        multiple:   this.options.multiple, 
    14441539                                        menu:       'main', 
    14451540 
     
    14481543                                        // Update user settings when users adjust the 
    14491544                                        // attachment display settings. 
    14501545                                        displayUserSettings: true 
    1451                                 }), 
     1546                                }; 
    14521547 
    1453                                 new media.controller.Upload({ 
    1454                                         menu: 'main' 
    1455                                 }), 
     1548                        // Add the default states. 
     1549                        this.states.add([ 
     1550                                // Main states. 
     1551                                new media.controller.Library( _.defaults({ 
     1552                                        id:         'insert', 
     1553                                        title:      l10n.insertMediaTitle, 
     1554                                        priority:   20, 
     1555                                        toolbar:    'main-insert', 
     1556                                        filterable: 'all', 
     1557                                        library:    media.query( options.library ), 
     1558                                        selection:  selection 
     1559                                }, library ) ), 
    14561560 
     1561                                new media.controller.Library( _.defaults({ 
     1562                                        id:         'gallery', 
     1563                                        title:      l10n.createGalleryTitle, 
     1564                                        priority:   40, 
     1565                                        toolbar:    'main-gallery', 
     1566                                        filterable: 'uploaded', 
     1567 
     1568                                        library:  media.query( _.defaults({ 
     1569                                                type: 'image' 
     1570                                        }, options.library ) ), 
     1571 
     1572                                        selection: new media.model.Selection( selection.models, { 
     1573                                                multiple: selection.multiple 
     1574                                        }) 
     1575                                }, library ) ), 
     1576 
    14571577                                // Embed states. 
    14581578                                new media.controller.Embed(), 
    14591579 
     
    14711591                                        multiple:     true, 
    14721592                                        menu:         'gallery', 
    14731593                                        toolbar:      'gallery-add', 
    1474                                         excludeState: 'gallery-edit' 
    1475                                 }), 
    1476  
    1477                                 new media.controller.Upload({ 
    1478                                         id:           'gallery-upload', 
    1479                                         menu:         'gallery', 
    1480                                         libraryState: 'gallery-edit' 
     1594                                        excludeState: 'gallery-edit', 
     1595                                        title:        l10n.addToGalleryTitle, 
     1596                                        priority:     100 
    14811597                                }) 
    14821598                        ]); 
    14831599 
     
    14921608 
    14931609                bindHandlers: function() { 
    14941610                        media.view.MediaFrame.Select.prototype.bindHandlers.apply( this, arguments ); 
     1611                        this.on( 'menu:create:gallery', this.createMenu, this ); 
     1612                        this.on( 'toolbar:create:main-insert', this.createSelectionToolbar, this ); 
     1613                        this.on( 'toolbar:create:main-gallery', this.createSelectionToolbar, this ); 
    14951614 
    14961615                        var handlers = { 
    14971616                                        menu: { 
     1617                                                'main':    'mainMenu', 
    14981618                                                'gallery': 'galleryMenu' 
    14991619                                        }, 
    15001620 
     
    15041624                                        }, 
    15051625 
    15061626                                        toolbar: { 
    1507                                                 'main-attachments': 'mainAttachmentsToolbar', 
     1627                                                'main-insert':      'mainInsertToolbar', 
     1628                                                'main-gallery':     'mainGalleryToolbar', 
    15081629                                                'main-embed':       'mainEmbedToolbar', 
    15091630                                                'featured-image':   'featuredImageToolbar', 
    15101631                                                'gallery-edit':     'galleryEditToolbar', 
     
    15141635 
    15151636                        _.each( handlers, function( regionHandlers, region ) { 
    15161637                                _.each( regionHandlers, function( callback, handler ) { 
    1517                                         this[ region ].on( 'activate:' + handler, this[ callback ], this ); 
     1638                                        this.on( region + ':render:' + handler, this[ callback ], this ); 
    15181639                                }, this ); 
    15191640                        }, this ); 
    15201641                }, 
    15211642 
    15221643                // Menus 
    1523                 mainMenu: function() { 
    1524                         media.view.MediaFrame.Select.prototype.mainMenu.call( this, { silent: true }); 
    1525  
    1526                         this.menu.view().set({ 
     1644                mainMenu: function( view ) { 
     1645                        view.set({ 
    15271646                                'library-separator': new media.View({ 
    15281647                                        className: 'separator', 
    1529                                         priority: 60 
    1530                                 }), 
    1531                                 'embed': { 
    1532                                         text: l10n.fromUrlTitle, 
    1533                                         priority: 80 
    1534                                 } 
     1648                                        priority: 100 
     1649                                }) 
    15351650                        }); 
    1536  
    1537                         if ( media.view.settings.post.featuredImageId ) { 
    1538                                 this.menu.view().set( 'featured-image', { 
    1539                                         text: l10n.featuredImageTitle, 
    1540                                         priority: 100 
    1541                                 }); 
    1542                         } 
    15431651                }, 
    15441652 
    1545                 galleryMenu: function() { 
     1653                galleryMenu: function( view ) { 
    15461654                        var lastState = this.lastState(), 
    15471655                                previous = lastState && lastState.id, 
    15481656                                frame = this; 
    15491657 
    1550                         this.menu.view( new media.view.Menu({ 
    1551                                 controller: this, 
    1552                                 views: { 
    1553                                         cancel: { 
    1554                                                 text:     l10n.cancelGalleryTitle, 
    1555                                                 priority: 20, 
    1556                                                 click:    function() { 
    1557                                                         if ( previous ) 
    1558                                                                 frame.setState( previous ); 
    1559                                                         else 
    1560                                                                 frame.close(); 
    1561                                                 } 
    1562                                         }, 
    1563                                         separateCancel: new media.View({ 
    1564                                                 className: 'separator', 
    1565                                                 priority: 40 
    1566                                         }), 
    1567                                         'gallery-edit': { 
    1568                                                 text: l10n.editGalleryTitle, 
    1569                                                 priority: 60 
    1570                                         }, 
    1571                                         'gallery-upload': { 
    1572                                                 text: l10n.uploadImagesTitle, 
    1573                                                 priority: 80 
    1574                                         }, 
    1575                                         'gallery-library': { 
    1576                                                 text: l10n.mediaLibraryTitle, 
    1577                                                 priority: 100 
     1658                        view.set({ 
     1659                                cancel: { 
     1660                                        text:     l10n.cancelGalleryTitle, 
     1661                                        priority: 20, 
     1662                                        click:    function() { 
     1663                                                if ( previous ) 
     1664                                                        frame.setState( previous ); 
     1665                                                else 
     1666                                                        frame.close(); 
    15781667                                        } 
    1579                                 } 
    1580                         }) ); 
     1668                                }, 
     1669                                separateCancel: new media.View({ 
     1670                                        className: 'separator', 
     1671                                        priority: 40 
     1672                                }) 
     1673                        }); 
    15811674                }, 
    15821675 
    15831676                // Content 
     
    15871680                                model:      this.state() 
    15881681                        }).render(); 
    15891682 
    1590                         this.content.view( view ); 
     1683                        this.content.set( view ); 
    15911684                        view.url.focus(); 
    15921685                }, 
    15931686 
     
    16171710                        }); 
    16181711 
    16191712                        // Browse our library of attachments. 
    1620                         this.content.view( view ); 
     1713                        this.content.set( view ); 
    16211714                }, 
    16221715 
    1623                 // Sidebars 
    1624                 onSidebarGallerySettings: function( options ) { 
    1625                         var library = this.state().get('library'); 
     1716                // Toolbars 
     1717                createSelectionToolbar: function( toolbar ) { 
     1718                        toolbar.view = new media.view.Toolbar.Selection({ 
     1719                                controller: this, 
     1720                                editable:   this.state().get('editable') 
     1721                        }); 
     1722                }, 
    16261723 
    1627                         if ( ! library ) 
    1628                                 return; 
     1724                mainInsertToolbar: function( view ) { 
     1725                        var controller = this; 
    16291726 
    1630                         library.gallery = library.gallery || new Backbone.Model(); 
     1727                        view.button = 'insert'; 
     1728                        view.set( 'insert', { 
     1729                                style:    'primary', 
     1730                                priority: 80, 
     1731                                text:     l10n.insertIntoPost, 
    16311732 
    1632                         this.sidebar.view().set({ 
    1633                                 gallery: new media.view.Settings.Gallery({ 
    1634                                         controller: this, 
    1635                                         model:      library.gallery, 
    1636                                         priority:   40 
    1637                                 }).render() 
    1638                         }, options ); 
     1733                                click: function() { 
     1734                                        var state = controller.state(), 
     1735                                                selection = state.get('selection'); 
     1736 
     1737                                        controller.close(); 
     1738                                        state.trigger( 'insert', selection ).reset(); 
     1739                                } 
     1740                        }); 
    16391741                }, 
    16401742 
    1641                 // Toolbars 
    1642                 mainAttachmentsToolbar: function() { 
    1643                         this.toolbar.view( new media.view.Toolbar.Insert({ 
    1644                                 controller: this, 
    1645                                 editable:   this.state().get('editable') 
    1646                         }) ); 
     1743                mainGalleryToolbar: function( view ) { 
     1744                        var controller = this; 
     1745 
     1746                        view.button = 'gallery'; 
     1747                        view.set( 'gallery', { 
     1748                                style:    'primary', 
     1749                                text:     l10n.createNewGallery, 
     1750                                priority: 60, 
     1751 
     1752                                click: function() { 
     1753                                        var selection = controller.state().get('selection'), 
     1754                                                edit = controller.state('gallery-edit'), 
     1755                                                models = selection.where({ type: 'image' }); 
     1756 
     1757                                        edit.set( 'library', new media.model.Selection( models, { 
     1758                                                props:    selection.props.toJSON(), 
     1759                                                multiple: true 
     1760                                        }) ); 
     1761 
     1762                                        this.controller.setState('gallery-edit'); 
     1763                                } 
     1764                        }); 
    16471765                }, 
    16481766 
    16491767                featuredImageToolbar: function() { 
    1650                         this.toolbar.view( new media.view.Toolbar.Select({ 
     1768                        this.toolbar.set( new media.view.Toolbar.Select({ 
    16511769                                controller: this, 
    16521770                                text:       l10n.setFeaturedImage, 
    16531771                                state:      this.options.state || 'upload' 
     
    16551773                }, 
    16561774 
    16571775                mainEmbedToolbar: function() { 
    1658                         this.toolbar.view( new media.view.Toolbar.Embed({ 
     1776                        this.toolbar.set( new media.view.Toolbar.Embed({ 
    16591777                                controller: this 
    16601778                        }) ); 
    16611779 
     
    16641782 
    16651783                galleryEditToolbar: function() { 
    16661784                        var editing = this.state().get('editing'); 
    1667                         this.toolbar.view( new media.view.Toolbar({ 
     1785                        this.toolbar.set( new media.view.Toolbar({ 
    16681786                                controller: this, 
    16691787                                items: { 
    16701788                                        insert: { 
     
    16891807                }, 
    16901808 
    16911809                galleryAddToolbar: function() { 
    1692                         this.toolbar.view( new media.view.Toolbar({ 
     1810                        this.toolbar.set( new media.view.Toolbar({ 
    16931811                                controller: this, 
    16941812                                items: { 
    16951813                                        insert: { 
     
    17041822 
    17051823                                                        edit.get('library').add( state.get('selection').models ); 
    17061824                                                        state.trigger('reset'); 
    1707                                                         controller.state('gallery-edit'); 
     1825                                                        controller.setState('gallery-edit'); 
    17081826                                                } 
    17091827                                        } 
    17101828                                } 
     
    17291847                }, 
    17301848 
    17311849                initialize: function() { 
    1732                         this.controller = this.options.controller; 
    1733  
    17341850                        _.defaults( this.options, { 
    17351851                                container: document.body, 
    17361852                                title:     '', 
     
    18381954                initialize: function() { 
    18391955                        var uploader; 
    18401956 
    1841                         this.controller = this.options.controller; 
    1842  
    18431957                        this.$browser = $('<a href="#" class="browser" />').hide().appendTo('body'); 
    18441958 
    18451959                        uploader = this.options.uploader = _.defaults( this.options.uploader || {}, { 
     
    19062020                template:  media.template('uploader-inline'), 
    19072021 
    19082022                initialize: function() { 
    1909                         this.controller = this.options.controller; 
     2023                        _.defaults( this.options, { 
     2024                                message: '', 
     2025                                status:  true 
     2026                        }); 
    19102027 
    19112028                        if ( ! this.options.$browser && this.controller.uploader ) 
    19122029                                this.options.$browser = this.controller.uploader.$browser; 
     
    19142031                        if ( _.isUndefined( this.options.postId ) ) 
    19152032                                this.options.postId = media.view.settings.post.id; 
    19162033 
    1917                         this.views.set( '.upload-inline-status', new media.view.UploaderStatus({ 
    1918                                 controller: this.controller 
    1919                         }) ); 
     2034                        if ( this.options.status ) { 
     2035                                this.views.set( '.upload-inline-status', new media.view.UploaderStatus({ 
     2036                                        controller: this.controller 
     2037                                }) ); 
     2038                        } 
    19202039                }, 
    19212040 
    19222041                ready: function() { 
     
    19512070                }, 
    19522071 
    19532072                initialize: function() { 
    1954                         this.controller = this.options.controller; 
    1955  
    19562073                        this.queue = wp.Uploader.queue; 
    19572074                        this.queue.on( 'add remove reset', this.visibility, this ); 
    19582075                        this.queue.on( 'add remove reset change:percent', this.progress, this ); 
     
    20602177                className: 'media-toolbar', 
    20612178 
    20622179                initialize: function() { 
    2063                         this.controller = this.options.controller; 
    2064  
    20652180                        this._views     = {}; 
    20662181                        this.$primary   = $('<div class="media-toolbar-primary" />').prependTo( this.$el ); 
    20672182                        this.$secondary = $('<div class="media-toolbar-secondary" />').prependTo( this.$el ); 
     
    21992314        // --------------------------- 
    22002315        media.view.Toolbar.Embed = media.view.Toolbar.Select.extend({ 
    22012316                initialize: function() { 
    2202                         var controller = this.options.controller; 
    2203  
    22042317                        _.defaults( this.options, { 
    22052318                                text: l10n.insertIntoPost 
    22062319                        }); 
    22072320 
    22082321                        media.view.Toolbar.Select.prototype.initialize.apply( this, arguments ); 
    2209                         controller.on( 'change:url', this.refresh, this ); 
     2322                        this.controller.state().props.on( 'change:url', this.refresh, this ); 
    22102323                }, 
    22112324 
    22122325                refresh: function() { 
    2213                         var url = this.controller.state().get('url'); 
     2326                        var url = this.controller.state().props.get('url'); 
    22142327                        this.get('select').model.set( 'disabled', ! url || /^https?:\/\/$/.test(url) ); 
    22152328                } 
    22162329        }); 
    22172330 
    2218         // wp.media.view.Toolbar.Insert 
     2331        // wp.media.view.Toolbar.Selection 
    22192332        // ---------------------------- 
    2220         media.view.Toolbar.Insert = media.view.Toolbar.extend({ 
     2333        media.view.Toolbar.Selection = media.view.Toolbar.extend({ 
     2334                button: 'insert', 
     2335 
    22212336                initialize: function() { 
    2222                         var controller = this.options.controller, 
    2223                                 selection = controller.state().get('selection'), 
    2224                                 selectionToLibrary; 
     2337                        var controller = this.controller; 
    22252338 
    2226                         selectionToLibrary = function( state, filter ) { 
    2227                                 return function() { 
    2228                                         var controller = this.controller, 
    2229                                                 selection = controller.state().get('selection'), 
    2230                                                 edit = controller.state( state ), 
    2231                                                 models = filter ? filter( selection ) : selection.models; 
    2232  
    2233                                         edit.set( 'library', new media.model.Selection( models, { 
    2234                                                 props:    selection.props.toJSON(), 
    2235                                                 multiple: true 
    2236                                         }) ); 
    2237  
    2238                                         this.controller.setState( state ); 
    2239                                 }; 
    2240                         }; 
    2241  
    22422339                        this.options.items = _.defaults( this.options.items || {}, { 
    22432340                                selection: new media.view.Selection({ 
    22442341                                        controller: controller, 
    2245                                         collection: selection, 
     2342                                        collection: controller.state().get('selection'), 
    22462343                                        priority:   -40, 
    22472344 
    22482345                                        // If the selection is editable, pass the callback to 
     
    22502347                                        editable: this.options.editable && function() { 
    22512348                                                this.controller.content.mode('edit-selection'); 
    22522349                                        } 
    2253                                 }).render(), 
    2254  
    2255                                 insert: { 
    2256                                         style:    'primary', 
    2257                                         priority: 80, 
    2258                                         text:     l10n.insertIntoPost, 
    2259  
    2260                                         click: function() { 
    2261                                                 controller.close(); 
    2262                                                 controller.state().trigger( 'insert', selection ).reset(); 
    2263                                         } 
    2264                                 }, 
    2265  
    2266                                 gallery: { 
    2267                                         text:     l10n.createNewGallery, 
    2268                                         priority: 40, 
    2269                                         click:    selectionToLibrary('gallery-edit', function( selection ) { 
    2270                                                 return selection.where({ type: 'image' }); 
    2271                                         }) 
    2272                                 } 
     2350                                }).render() 
    22732351                        }); 
    22742352 
    22752353                        media.view.Toolbar.prototype.initialize.apply( this, arguments ); 
     
    22772355 
    22782356                refresh: function() { 
    22792357                        var selection = this.controller.state().get('selection'), 
    2280                                 count = selection.length; 
     2358                                button = this.get( this.button ); 
    22812359 
    2282                         this.get('insert').model.set( 'disabled', ! selection.length ); 
     2360                        if ( ! button ) 
     2361                                return; 
    22832362 
    2284                         // Check if any attachment in the selection is an image. 
    2285                         this.get('gallery').$el.toggle( count > 1 && selection.any( function( attachment ) { 
    2286                                 return 'image' === attachment.get('type'); 
    2287                         }) ); 
     2363                        button.model.set( 'disabled', ! selection.length ); 
    22882364                } 
    22892365        }); 
    22902366 
     
    23882464                tagName:   'div', 
    23892465 
    23902466                initialize: function() { 
    2391                         this.controller = this.options.controller; 
    2392                         this._views     = {}; 
     2467                        this._views = {}; 
    23932468 
    23942469                        this.set( _.extend( {}, this._views, this.options.views ), { silent: true }); 
    23952470                        delete this.options.views; 
     
    24572532                } 
    24582533        }); 
    24592534 
     2535        /** 
     2536         * wp.media.view.MenuItem 
     2537         */ 
     2538        media.view.MenuItem = media.View.extend({ 
     2539                tagName:   'a', 
     2540                className: 'media-menu-item', 
    24602541 
     2542                attributes: { 
     2543                        href: '#' 
     2544                }, 
     2545 
     2546                events: { 
     2547                        'click': '_click' 
     2548                }, 
     2549 
     2550                _click: function( event ) { 
     2551                        var clickOverride = this.options.click; 
     2552 
     2553                        event.preventDefault(); 
     2554 
     2555                        if ( clickOverride ) 
     2556                                clickOverride.call( this ); 
     2557                        else 
     2558                                this.click(); 
     2559                }, 
     2560 
     2561                click: function() { 
     2562                        var state = this.options.state; 
     2563                        if ( state ) 
     2564                                this.controller.setState( state ); 
     2565                }, 
     2566 
     2567                render: function() { 
     2568                        var options = this.options; 
     2569 
     2570                        if ( options.text ) 
     2571                                this.$el.text( options.text ); 
     2572                        else if ( options.html ) 
     2573                                this.$el.html( options.html ); 
     2574 
     2575                        return this; 
     2576                } 
     2577        }); 
     2578 
    24612579        /** 
    24622580         * wp.media.view.Menu 
    24632581         */ 
    24642582        media.view.Menu = media.view.PriorityList.extend({ 
    2465                 tagName:   'ul', 
     2583                tagName:   'div', 
    24662584                className: 'media-menu', 
     2585                property:  'state', 
     2586                ItemView:  media.view.MenuItem, 
     2587                region:    'menu', 
    24672588 
    2468                 toView: function( options, state ) { 
     2589                toView: function( options, id ) { 
    24692590                        options = options || {}; 
    2470                         options.state = options.state || state; 
    2471                         return new media.view.MenuItem( options ).render(); 
     2591                        options[ this.property ] = options[ this.property ] || id; 
     2592                        return new this.ItemView( options ).render(); 
    24722593                }, 
    24732594 
    2474                 select: function( state ) { 
    2475                         var view = this.get( state ); 
     2595                ready: function() { 
     2596                        media.view.PriorityList.prototype.ready.apply( this, arguments ); 
     2597                        this.visibility(); 
     2598                }, 
    24762599 
     2600                set: function() { 
     2601                        media.view.PriorityList.prototype.set.apply( this, arguments ); 
     2602                        this.visibility(); 
     2603                }, 
     2604 
     2605                unset: function() { 
     2606                        media.view.PriorityList.prototype.unset.apply( this, arguments ); 
     2607                        this.visibility(); 
     2608                }, 
     2609 
     2610                visibility: function() { 
     2611                        var region = this.region, 
     2612                                view = this.controller[ region ].get(), 
     2613                                views = this.views.get(), 
     2614                                hide = ! views || views.length < 2; 
     2615 
     2616                        if ( this === view ) 
     2617                                this.controller.$el.toggleClass( 'hide-' + region, hide ); 
     2618                }, 
     2619 
     2620                select: function( id ) { 
     2621                        var view = this.get( id ); 
     2622 
    24772623                        if ( ! view ) 
    24782624                                return; 
    24792625 
     
    24862632                } 
    24872633        }); 
    24882634 
    2489         media.view.MenuItem = media.View.extend({ 
    2490                 tagName:   'li', 
    2491                 className: 'media-menu-item', 
     2635        /** 
     2636         * wp.media.view.RouterItem 
     2637         */ 
     2638        media.view.RouterItem = media.view.MenuItem.extend({ 
     2639                click: function() { 
     2640                        var contentMode = this.options.contentMode; 
     2641                        if ( contentMode ) 
     2642                                this.controller.content.mode( contentMode ); 
     2643                } 
     2644        }); 
    24922645 
    2493                 events: { 
    2494                         'click': 'click' 
    2495                 }, 
     2646        /** 
     2647         * wp.media.view.Router 
     2648         */ 
     2649        media.view.Router = media.view.Menu.extend({ 
     2650                tagName:   'div', 
     2651                className: 'media-router', 
     2652                property:  'contentMode', 
     2653                ItemView:  media.view.RouterItem, 
     2654                region:    'router', 
    24962655 
    2497                 click: function() { 
    2498                         var options = this.options; 
    2499  
    2500                         if ( options.click ) 
    2501                                 options.click.call( this ); 
    2502                         else if ( options.state ) 
    2503                                 this.controller.setState( options.state ); 
     2656                initialize: function() { 
     2657                        this.controller.on( 'content:render', this.update, this ); 
     2658                        media.view.Menu.prototype.initialize.apply( this, arguments ); 
    25042659                }, 
    25052660 
    2506                 render: function() { 
    2507                         var options = this.options; 
    2508  
    2509                         if ( options.text ) 
    2510                                 this.$el.text( options.text ); 
    2511                         else if ( options.html ) 
    2512                                 this.$el.html( options.html ); 
    2513  
    2514                         return this; 
     2661                update: function() { 
     2662                        var mode = this.controller.content.mode(); 
     2663                        if ( mode ) 
     2664                                this.select( mode ); 
    25152665                } 
    25162666        }); 
    25172667 
     2668 
    25182669        /** 
    25192670         * wp.media.view.Sidebar 
    25202671         */ 
     
    25462697                initialize: function() { 
    25472698                        var selection = this.options.selection; 
    25482699 
    2549                         this.controller = this.options.controller; 
    2550  
    25512700                        this.model.on( 'change:sizes change:uploading change:caption change:title', this.render, this ); 
    25522701                        this.model.on( 'change:percent', this.progress, this ); 
    25532702 
     
    28382987                }, 
    28392988 
    28402989                initialize: function() { 
    2841                         this.controller = this.options.controller; 
    28422990                        this.el.id = _.uniqueId('__attachments-view-'); 
    28432991 
    28442992                        _.defaults( this.options, { 
     
    32003348                className: 'attachments-browser', 
    32013349 
    32023350                initialize: function() { 
    3203                         this.controller = this.options.controller; 
    3204  
    32053351                        _.defaults( this.options, { 
    32063352                                filters: false, 
    32073353                                search:  true, 
    3208                                 uploads: false, 
    32093354                                display: false, 
    32103355 
    32113356                                AttachmentView: media.view.Attachment.Library 
     
    32903435                        this.removeContent(); 
    32913436 
    32923437                        this.uploader = new media.view.UploaderInline({ 
    3293                                 controller: this.controller 
     3438                                controller: this.controller, 
     3439                                status:     false, 
     3440                                message:    l10n.noItemsFound 
    32943441                        }); 
    32953442 
    32963443                        this.views.add( this.uploader ); 
     
    33223469 
    33233470                        this.views.add( sidebar ); 
    33243471 
    3325                         if ( options.uploads && this.controller.uploader ) { 
     3472                        if ( this.controller.uploader ) { 
    33263473                                sidebar.set( 'uploads', new media.view.UploaderStatus({ 
    33273474                                        controller: this.controller, 
    33283475                                        priority:   40 
     
    33733520        }); 
    33743521 
    33753522        /** 
    3376          * wp.media.view.SelectionPreview 
    3377          */ 
    3378         media.view.SelectionPreview = media.View.extend({ 
    3379                 tagName:   'div', 
    3380                 className: 'selection-preview', 
    3381                 template:  media.template('media-selection-preview'), 
    3382  
    3383                 events: { 
    3384                         'click .clear-selection': 'clear' 
    3385                 }, 
    3386  
    3387                 initialize: function() { 
    3388                         _.defaults( this.options, { 
    3389                                 clearable: true 
    3390                         }); 
    3391  
    3392                         this.controller = this.options.controller; 
    3393                         this.collection.on( 'add change:url remove', this.render, this ); 
    3394                         this.render(); 
    3395                 }, 
    3396  
    3397                 render: function() { 
    3398                         var options = _.clone( this.options ), 
    3399                                 last, sizes, amount; 
    3400  
    3401                         // If nothing is selected, display nothing. 
    3402                         if ( ! this.collection.length ) { 
    3403                                 this.$el.empty(); 
    3404                                 return this; 
    3405                         } 
    3406  
    3407                         options.count = this.collection.length; 
    3408                         last  = this.collection.last(); 
    3409                         sizes = last.get('sizes'); 
    3410  
    3411                         if ( 'image' === last.get('type') ) 
    3412                                 options.thumbnail = ( sizes && sizes.thumbnail ) ? sizes.thumbnail.url : last.get('url'); 
    3413                         else 
    3414                                 options.thumbnail =  last.get('icon'); 
    3415  
    3416                         this.$el.html( this.template( options ) ); 
    3417                         return this; 
    3418                 }, 
    3419  
    3420                 clear: function( event ) { 
    3421                         event.preventDefault(); 
    3422                         this.collection.reset(); 
    3423                 } 
    3424         }); 
    3425  
    3426         /** 
    34273523         * wp.media.view.Selection 
    34283524         */ 
    34293525        media.view.Selection = media.View.extend({ 
     
    34423538                                clearable: true 
    34433539                        }); 
    34443540 
    3445                         this.controller = this.options.controller; 
    34463541                        this.attachments = new media.view.Attachments({ 
    34473542                                controller: this.controller, 
    34483543                                collection: this.collection, 
     
    37683863        media.view.Iframe = media.View.extend({ 
    37693864                className: 'media-iframe', 
    37703865 
    3771                 initialize: function() { 
    3772                         this.controller = this.options.controller; 
    3773                 }, 
    3774  
    37753866                render: function() { 
     3867                        this.views.detach(); 
    37763868                        this.$el.html( '<iframe src="' + this.controller.state().get('src') + '" />' ); 
     3869                        this.views.render(); 
    37773870                        return this; 
    37783871                } 
    37793872        }); 
     
    37853878                className: 'media-embed', 
    37863879 
    37873880                initialize: function() { 
    3788                         this.controller = this.options.controller; 
    3789  
    37903881                        this.url = new media.view.EmbedUrl({ 
    37913882                                controller: this.controller, 
    3792                                 model:      this.model 
     3883                                model:      this.model.props 
    37933884                        }).render(); 
    37943885 
    37953886                        this._settings = new media.View(); 
     
    38263917 
    38273918                        this.settings( new constructor({ 
    38283919                                controller: this.controller, 
    3829                                 model:      this.model, 
     3920                                model:      this.model.props, 
    38303921                                priority:   40 
    38313922                        }) ); 
    38323923                } 
     
    38463937                }, 
    38473938 
    38483939                initialize: function() { 
    3849                         this.label = this.make( 'span', null, this.options.label || l10n.url ); 
    38503940                        this.input = this.make( 'input', { 
    38513941                                type:  'text', 
    38523942                                value: this.model.get('url') || '' 
    38533943                        }); 
    38543944 
    3855                         this.$label = $( this.label ); 
    38563945                        this.$input = $( this.input ); 
    3857                         this.$el.append([ this.label, this.input ]); 
     3946                        this.$el.append( this.input ); 
    38583947 
    38593948                        this.model.on( 'change:url', this.render, this ); 
    38603949                }, 
  • wp-includes/media.php

     
    14671467 
    14681468                // Library 
    14691469                'mediaLibraryTitle'  => __( 'Media Library' ), 
     1470                'insertMediaTitle'   => __( 'Insert Media' ), 
    14701471                'createNewGallery'   => __( 'Create a new gallery' ), 
    14711472                'returnToLibrary'    => __( '&#8592; Return to library' ), 
    14721473                'allMediaItems'      => __( 'All media items' ), 
     1474                'noItemsFound'       => __( 'No items found.' ), 
    14731475                'insertIntoPost'     => $hier ? __( 'Insert into page' ) : __( 'Insert into post' ), 
    14741476                'uploadedToThisPost' => $hier ? __( 'Uploaded to this page' ) : __( 'Uploaded to this post' ), 
    14751477                'warnDelete' =>      __( "You are about to permanently delete this item.\n  'Cancel' to stop, 'OK' to delete." ), 
     
    14891491                'updateGallery'      => __( 'Update gallery' ), 
    14901492                'continueEditing'    => __( 'Continue editing' ), 
    14911493                'addToGallery'       => __( 'Add to gallery' ), 
     1494                'addToGalleryTitle'  => __( 'Add to Gallery' ), 
    14921495                'reverseOrder'       => __( 'Reverse order' ), 
    14931496        ); 
    14941497 
     
    15171520        ?> 
    15181521        <script type="text/html" id="tmpl-media-frame"> 
    15191522                <div class="media-frame-menu"></div> 
     1523                <div class="media-frame-title"></div> 
     1524                <div class="media-frame-router"></div> 
    15201525                <div class="media-frame-content"></div> 
    15211526                <div class="media-frame-toolbar"></div> 
    15221527                <div class="media-frame-uploader"></div> 
     
    15241529 
    15251530        <script type="text/html" id="tmpl-media-modal"> 
    15261531                <div class="media-modal wp-core-ui"> 
    1527                         <h3 class="media-modal-title">{{ data.title }}</h3> 
    1528                         <a class="media-modal-close media-modal-icon" href="#" title="<?php esc_attr_e('Close'); ?>"></a> 
     1532                        <a class="media-modal-close" href="#" title="<?php esc_attr_e('Close'); ?>"><span class="media-modal-icon"></span></a> 
    15291533                        <div class="media-modal-content"></div> 
    15301534                </div> 
    1531                 <div class="media-modal-backdrop"> 
    1532                         <div></div> 
    1533                 </div> 
     1535                <div class="media-modal-backdrop"></div> 
    15341536        </script> 
    15351537 
    15361538        <script type="text/html" id="tmpl-uploader-window"> 
     
    15401542        </script> 
    15411543 
    15421544        <script type="text/html" id="tmpl-uploader-inline"> 
    1543                 <div class="uploader-inline-content"> 
     1545                <# var messageClass = data.message ? 'has-upload-message' : 'no-upload-message'; #> 
     1546                <div class="uploader-inline-content {{ messageClass }}"> 
     1547                <# if ( data.message ) { #> 
     1548                        <h3 class="upload-message">{{ data.message }}</h3> 
     1549                <# } #> 
    15441550                <?php if ( ! _device_can_upload() ) : ?> 
    1545                         <h3><?php _e('The web browser on your device cannot be used to upload files. You may be able to use the <a href="http://wordpress.org/extend/mobile/">native app for your device</a> instead.'); ?></h3> 
     1551                        <h3 class="upload-instructions"><?php _e('The web browser on your device cannot be used to upload files. You may be able to use the <a href="http://wordpress.org/extend/mobile/">native app for your device</a> instead.'); ?></h3> 
    15461552                <?php elseif ( is_multisite() && ! is_upload_space_available() ) : ?> 
    1547                         <h3><?php _e( 'Upload Limit Exceeded' ); ?></h3> 
     1553                        <h3 class="upload-instructions"><?php _e( 'Upload Limit Exceeded' ); ?></h3> 
    15481554                        <?php do_action( 'upload_ui_over_quota' ); ?> 
    15491555 
    15501556                <?php else : ?> 
    15511557                        <div class="upload-ui"> 
    1552                                 <h3 class="drop-instructions"><?php _e( 'Drop files anywhere to upload' ); ?></h3> 
     1558                                <h3 class="upload-instructions drop-instructions"><?php _e( 'Drop files anywhere to upload' ); ?></h3> 
    15531559                                <a href="#" class="browser button button-hero"><?php _e( 'Select Files' ); ?></a> 
    15541560                        </div> 
    15551561 
     
    17441750                <div class="selection-view"></div> 
    17451751        </script> 
    17461752 
    1747         <script type="text/html" id="tmpl-media-selection-preview"> 
    1748                 <div class="selected-img selected-count-{{ data.count }}"> 
    1749                         <# if ( data.thumbnail ) { #> 
    1750                                 <img src="{{ data.thumbnail }}" draggable="false" /> 
    1751                         <# } #> 
    1752  
    1753                         <span class="count">{{ data.count }}</span> 
    1754                 </div> 
    1755                 <# if ( data.clearable ) { #> 
    1756                         <a class="clear-selection" href="#"><?php _e('Clear selection'); ?></a> 
    1757                 <# } #> 
    1758         </script> 
    1759  
    17601753        <script type="text/html" id="tmpl-attachment-display-settings"> 
    17611754                <h3><?php _e('Attachment Display Settings'); ?></h3> 
    17621755