Ticket #21390: 21390.8.diff
File 21390.8.diff, 65.5 KB (added by , 12 years ago) |
---|
-
wp-admin/js/custom-background.js
37 37 } 38 38 }); 39 39 40 frame. toolbar.on( 'activate:select', function() {41 frame.toolbar.view().set({40 frame.on( 'toolbar:render:select', function( view ) { 41 view.set({ 42 42 select: { 43 43 style: 'primary', 44 44 text: $el.data('update'), -
wp-admin/js/custom-header.js
24 24 } 25 25 }); 26 26 27 frame. toolbar.on( 'activate:select', function() {28 frame.toolbar.view().set({27 frame.on( 'toolbar:render:select', function( view ) { 28 view.set({ 29 29 select: { 30 30 style: 'primary', 31 31 text: $el.data('update'), -
wp-includes/css/media-views-rtl.css
1 1 /** 2 2 * Modal 3 3 */ 4 .media-modal-title {5 left: auto;6 right: 0;7 }8 9 4 .media-modal-close { 10 5 right: auto; 11 left: 0;6 left: 7px; 12 7 } 13 8 14 9 /** 15 10 * Toolbar 16 11 */ 17 .media-frame-toolbar > .media-toolbar {18 left: 0;19 right: 200px;20 }21 22 23 12 .media-toolbar-primary { 24 13 float: left; 25 14 } … … 93 82 * Menu 94 83 */ 95 84 .media-menu { 96 left: auto;97 right: 0;98 85 border-right: 0; 99 86 border-left: 1px solid #d9d9d9; 100 87 box-shadow: inset 6px 0 6px -6px rgba( 0, 0, 0, 0.2 ) 101 88 } 102 89 103 90 /** 91 * Router 92 */ 93 .media-router > a { 94 float: right; 95 border-right: 0; 96 border-left: 1px solid #dfdfdf; 97 } 98 .media-router > a:last-child { 99 border-left: 0; 100 } 101 102 /** 104 103 * Frame 105 104 */ 106 .media-frame .region-content { 105 .media-frame-menu { 106 left: auto; 107 right: 0; 108 } 109 110 .media-frame-title, 111 .media-frame-router, 112 .media-frame-content, 113 .media-frame-toolbar { 107 114 left: 0; 108 115 right: 200px; 109 116 } 110 117 118 .media-frame.hide-menu .media-frame-title, 119 .media-frame.hide-menu .media-frame-router, 120 .media-frame.hide-menu .media-frame-toolbar, 121 .media-frame.hide-menu .media-frame-content { 122 right: 0; 123 } 124 125 .media-frame.hide-menu .media-frame-menu { 126 left: auto; 127 right: -200px; 128 } 129 111 130 /** 112 131 * Attachment Browser Filters 113 132 */ … … 226 245 } 227 246 228 247 /** 229 * Selection Preview230 */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 /**253 248 * Attachment Details 254 249 */ 255 250 .attachment-info .thumbnail { … … 289 284 * Responsive layout 290 285 */ 291 286 @media only screen and (max-width: 900px) { 292 .media-frame .region-content, 293 .media-frame-toolbar > .media-toolbar { 287 .media-frame-title, 288 .media-frame-router, 289 .media-frame-content, 290 .media-frame-toolbar { 294 291 left: 0; 295 292 right: 140px; 296 293 } -
wp-includes/css/media-views.css
80 80 */ 81 81 .media-modal { 82 82 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; 87 87 z-index: 160000; 88 88 } 89 89 … … 94 94 right: 0; 95 95 bottom: 0; 96 96 background: #000; 97 opacity: 0. 8;97 opacity: 0.7; 98 98 z-index: 159900; 99 99 } 100 100 101 .media-modal-backdrop div, 102 .uploader-window-content { 101 .media-modal-close { 103 102 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; 109 108 } 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; 130 113 height: 15px; 131 width: 15px; 132 background-position: -80px 0; 114 background-position: -100px 0; 133 115 } 134 116 135 117 .media-modal-close:active { … … 165 147 border: 0 solid #dfdfdf; 166 148 } 167 149 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 180 150 .media-toolbar-primary { 181 151 float: right; 182 152 } … … 238 208 width: 100%; 239 209 } 240 210 241 .media-sidebar .selection-preview {242 display: block;243 padding-top: 5px;244 }245 246 211 .media-sidebar h3 { 247 212 position: relative; 248 213 font-weight: bold; … … 361 326 position: absolute; 362 327 top: 0; 363 328 left: 0; 329 right: 0; 364 330 bottom: 0; 365 width: 199px;366 331 margin: 0; 367 332 padding: 16px 0; 368 z-index: 200;369 333 border-right: 1px solid #d9d9d9; 370 334 box-shadow: inset -6px 0 6px -6px rgba( 0, 0, 0, 0.2 ); 371 335 -webkit-user-select: none; … … 374 338 user-select: none; 375 339 } 376 340 377 .media-menu li { 341 .media-menu > a { 342 display: block; 378 343 position: relative; 379 344 padding: 4px 20px; 380 345 margin: 0; … … 382 347 font-size: 14px; 383 348 color: #21759B; 384 349 text-shadow: 0 1px 0 #fff; 350 text-decoration: none; 385 351 } 386 352 387 .media-menu-item { 388 cursor: pointer; 353 .media-menu > a:hover { 354 color: #21759B; 355 background: rgba( 0, 0, 0, 0.04 ); 389 356 } 390 357 391 .media-menu li:hover{392 background: rgba( 0, 0, 0, 0.04 );358 .media-menu > a:active { 359 outline: none; 393 360 } 394 361 395 362 .media-menu .active, … … 407 374 } 408 375 409 376 /** 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 /** 410 434 * Frame 411 435 */ 412 436 .media-frame { … … 418 442 bottom: 0; 419 443 } 420 444 421 .media-frame .region-content{445 .media-frame-menu { 422 446 position: absolute; 423 447 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; 424 457 left: 200px; 425 458 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; 426 479 bottom: 61px; 427 480 height: auto; 428 481 width: auto; … … 430 483 overflow: auto; 431 484 } 432 485 433 .media-frame.hide-toolbar .region-content { 486 .media-frame-toolbar { 487 position: absolute; 488 left: 200px; 489 right: 0; 434 490 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 ); 435 496 } 436 497 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 437 530 .media-frame .media-toolbar .add-to-gallery { 438 531 display: none; 439 532 } 440 533 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 441 542 /** 442 543 * Iframes 443 544 */ … … 721 822 * Attachments Browser 722 823 */ 723 824 .media-frame .attachments-browser { 825 position: relative; 826 width: 100%; 827 height: 100%; 724 828 overflow: hidden; 725 829 } 726 830 … … 903 1007 } 904 1008 905 1009 .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; 907 1016 } 908 1017 909 1018 .uploader-window h3 { … … 956 1065 margin: 4em 0; 957 1066 } 958 1067 1068 .uploader-inline .has-upload-message .upload-ui { 1069 margin: 0 0 4em; 1070 } 1071 959 1072 .uploader-inline h3 { 960 1073 font-size: 20px; 961 1074 line-height: 28px; … … 963 1076 margin-bottom: 1.6em; 964 1077 } 965 1078 1079 .uploader-inline .has-upload-message .upload-instructions { 1080 font-size: 14px; 1081 color: #464646; 1082 font-weight: normal; 1083 } 1084 966 1085 .uploader-inline .drop-instructions { 967 1086 display: none; 968 1087 } … … 1058 1177 vertical-align: top; 1059 1178 } 1060 1179 1061 .media-selection .attachment img{1180 .media-selection .attachment .icon { 1062 1181 width: 50%; 1063 1182 } 1064 1183 … … 1098 1217 } 1099 1218 1100 1219 /** 1101 * Selection Preview1102 */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 /**1164 1220 * Spinner 1165 1221 */ 1166 1222 .media-sidebar .settings-save-status { … … 1297 1353 .embed-url { 1298 1354 display: block; 1299 1355 position: relative; 1300 height: 75px;1301 padding: 16px 16px;1356 height: 40px; 1357 padding: 0 16px 16px; 1302 1358 margin: 0; 1303 z-index: 50; 1359 z-index: 250; 1360 background: #fff; 1304 1361 border-bottom: 1px solid #dfdfdf; 1305 1362 box-shadow: 0 4px 4px -4px rgba( 0, 0, 0, 0.1 ); 1306 1363 font-size: 18px; 1307 1364 font-weight: 200; 1308 1365 } 1309 1366 1310 .embed-url span {1311 display: block;1312 padding: 4px 0 6px 2px;1313 }1314 1315 1367 .media-frame .embed-url input { 1316 1368 font-size: 18px; 1317 1369 padding: 12px 14px; … … 1324 1376 .embed-image-settings { 1325 1377 position: absolute; 1326 1378 background: #f5f5f5; 1327 top: 108px;1379 top: 57px; 1328 1380 left: 0; 1329 1381 right: 0; 1330 1382 bottom: 0; … … 1388 1440 * Responsive layout 1389 1441 */ 1390 1442 @media only screen and (max-width: 900px) { 1391 .media-modal { 1392 bottom: 20px; 1393 left: 20px; 1394 right: 20px; 1395 top: 40px; 1396 } 1397 1398 .media-modal-title { 1399 height: 30px; 1400 line-height: 30px; 1401 top: -30px; 1402 } 1403 1404 .media-modal-close { 1405 top: -23px; 1406 } 1407 1408 .media-modal-backdrop div, 1409 .uploader-window-content { 1410 top: 5px; 1411 left: 5px; 1412 right: 5px; 1413 bottom: 5px; 1414 } 1415 1416 .media-menu { 1443 .media-frame-menu { 1417 1444 width: 139px; 1418 1445 } 1419 1446 … … 1421 1448 padding: 4px 10px; 1422 1449 } 1423 1450 1424 .media-frame .region-content, 1425 .media-frame-toolbar > .media-toolbar { 1451 .media-frame-title, 1452 .media-frame-router, 1453 .media-frame-content, 1454 .media-frame-toolbar { 1426 1455 left: 140px; 1427 1456 } 1428 1457 -
wp-includes/js/media-editor.js
384 384 385 385 workflow = workflows[ id ] = wp.media( _.defaults( options || {}, { 386 386 frame: 'post', 387 state: ' upload',387 state: 'insert', 388 388 title: wp.media.view.l10n.addMedia, 389 389 multiple: true 390 390 } ) ); … … 408 408 }, this ); 409 409 410 410 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(); 412 414 413 415 embed.url = embed.url || ''; 414 416 415 if ( 'link' === embed.type ) {417 if ( 'link' === type ) { 416 418 _.defaults( embed, { 417 419 title: embed.url, 418 420 linkUrl: embed.url … … 420 422 421 423 this.send.link( embed ); 422 424 423 } else if ( 'image' === embed.type ) {425 } else if ( 'image' === type ) { 424 426 _.defaults( embed, { 425 427 title: embed.url, 426 428 linkUrl: '', -
wp-includes/js/media-views.js
68 68 * wp.media.controller.Region 69 69 */ 70 70 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' ) ); 75 72 }; 76 73 77 74 // Use Backbone's self-propagating `extend` inheritance method. 78 75 media.controller.Region.extend = Backbone.Model.extend; 79 76 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; 84 81 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 ) 91 84 return this; 92 };93 }()),94 85 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; 102 91 }, 103 92 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 ); 108 98 109 // If no argument is provided, return the current view. 110 if ( ! view ) 111 return previous; 99 var set = { view: null }, 100 view; 112 101 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 ) 115 123 return; 116 124 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; 120 127 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 ); 123 131 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; 130 136 } 131 137 }); 132 138 … … 208 214 // wp.media.controller.State 209 215 // --------------------------- 210 216 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 ); 213 219 this.on( 'activate', this.activate, this ); 220 this.on( 'activate', this._postActivate, this ); 214 221 this.on( 'deactivate', this._deactivate, this ); 215 222 this.on( 'deactivate', this.deactivate, this ); 216 223 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 ); 217 230 }, 218 231 232 ready: function() {}, 219 233 activate: function() {}, 220 _activate: function() { 234 deactivate: function() {}, 235 reset: function() {}, 236 237 _ready: function() { 238 this._updateMenu(); 239 }, 240 241 _preActivate: function() { 221 242 this.active = true; 243 }, 222 244 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(); 226 258 }, 227 259 228 deactivate: function() {}, 260 229 261 _deactivate: function() { 230 262 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 ); 231 270 }, 232 271 233 reset: function() {}, 272 _title: function() { 273 this.frame.title.render( this.get('titleMode') || 'default' ); 274 }, 234 275 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() { 236 297 var menu = this.frame.menu, 237 298 mode = this.get('menu'), 238 299 view; … … 240 301 if ( ! mode ) 241 302 return; 242 303 243 if ( menu.mode() !== mode ) 244 menu.mode( mode ); 304 menu.mode( mode ); 245 305 246 view = menu. view();306 view = menu.get(); 247 307 if ( view.select ) 248 308 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 ); 249 338 } 250 339 }); 251 340 252 341 _.each(['toolbar','content'], function( region ) { 253 media.controller.State.prototype[ region ] = function() {342 media.controller.State.prototype[ '_' + region ] = function() { 254 343 var mode = this.get( region ); 255 344 if ( mode ) 256 this.frame[ region ]. mode( mode );345 this.frame[ region ].render( mode ); 257 346 }; 258 347 }); 259 348 … … 262 351 media.controller.Library = media.controller.State.extend({ 263 352 defaults: { 264 353 id: 'library', 265 multiple: false, 354 multiple: false, // false, 'add', 'reset' 266 355 describe: false, 267 toolbar: ' main-attachments',356 toolbar: 'select', 268 357 sidebar: 'settings', 269 content: 'browse', 358 content: 'upload', 359 router: 'browse', 270 360 searchable: true, 271 361 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, 367 368 // Sync the selection from the last state when 'multiple' matches. 369 syncLastSelection: true 274 370 }, 275 371 276 372 initialize: function() { … … 290 386 this.set( 'gutter', 8 ); 291 387 292 388 this.resetDisplays(); 293 294 media.controller.State.prototype.initialize.apply( this, arguments );295 389 }, 296 390 297 391 activate: function() { 298 392 var library = this.get('library'), 299 selection = this.get('selection'); 393 selection = this.get('selection'), 394 mode; 300 395 396 if ( this.get('syncLastSelection') ) { 397 this.getLastSelection(); 398 } 399 301 400 this._excludeStateLibrary(); 302 401 this.buildComposite(); 303 402 this.on( 'change:library change:exclude', this.buildComposite, this ); 304 403 this.on( 'change:excludeState', this._excludeState, this ); 305 404 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 ); 405 wp.Uploader.queue.on( 'add', this.uploading, this ); 310 406 311 407 selection.on( 'add remove reset', this.refreshSelection, this ); 312 408 313 this.refresh();314 409 this.on( 'insert', this._insertDisplaySettings, this ); 410 411 if ( this.get('contentUserSetting') ) { 412 this.frame.on( 'content:activate', this.saveContentMode, this ); 413 this.set( 'content', getUserSetting( 'libraryContent', this.get('content') ) ); 414 } 315 415 }, 316 416 317 417 deactivate: function() { 418 this.frame.off( 'content:activate', this.saveContentMode, this ); 419 318 420 // Unbind all event handlers that use this state as the context 319 421 // from the selection. 320 422 this.get('selection').off( null, null, this ); … … 330 432 reset: function() { 331 433 this.get('selection').reset(); 332 434 this.resetDisplays(); 435 this.refreshContent(); 333 436 }, 334 437 335 refresh: function() {336 this.content();337 this.refreshSelection();338 },339 340 438 resetDisplays: function() { 341 439 this._displays = []; 342 440 this._defaultDisplaySettings = { … … 371 469 setUserSetting( 'urlbutton', display.link ); 372 470 }, 373 471 472 getLastSelection: function() { 473 var selection = this.get('selection'), 474 lastState = this.frame.lastState(), 475 lastSelection = lastState && lastState.get('selection'), 476 lastMultiple, thisMultiple; 477 478 if ( ! lastSelection ) 479 return; 480 481 // We don't care about the method of multiple selection the 482 // selections use, just that they both support (or don't support) 483 // multiple selection. 484 lastMultiple = !! lastSelection.multiple; 485 thisMultiple = !! selection.multiple; 486 487 if ( lastMultiple !== thisMultiple ) 488 return; 489 490 selection.reset( lastSelection.toArray() ).single( lastSelection.single() ); 491 }, 492 374 493 refreshSelection: function() { 494 this.frame.toolbar.get().refresh(); 495 this.trigger( 'refresh:selection', this, this.get('selection') ); 496 this.refreshContent(); 497 }, 498 499 refreshContent: function() { 375 500 var selection = this.get('selection'), 376 mode = this.frame.content.mode(); 501 frame = this.frame, 502 router = frame.router.get(), 503 mode = frame.content.mode(); 377 504 378 this.frame.toolbar.view().refresh(); 379 this.trigger( 'refresh:selection', this, selection ); 505 if ( this.active&& ! selection.length && ! router.get( mode ) ) 506 this.frame.content.render( this.get('content') ); 507 }, 380 508 381 if ( ! selection.length && 'browse' !== mode && 'upload' !== mode ) 382 this.content(); 509 uploading: function( attachment ) { 510 var content = this.frame.content; 511 512 // If the uploader was selected, navigate to the browser. 513 if ( 'upload' === content.mode() ) 514 this.frame.content.mode('browse'); 515 516 // If we're in a workflow that supports multiple attachments, 517 // automatically select any uploading attachments. 518 if ( this.get('multiple') ) 519 this.get('selection').add( attachment ); 383 520 }, 384 521 385 selectUpload: function( attachment ) { 386 this.get('selection').add( attachment ); 522 saveContentMode: function() { 523 // Only track the browse router on library states. 524 if ( 'browse' !== this.get('router') ) 525 return; 526 527 var mode = this.frame.content.mode(), 528 view = this.frame.router.get(); 529 530 if ( view && view.get( mode ) ) 531 setUserSetting( 'libraryContent', mode ); 387 532 }, 388 533 389 534 buildComposite: function() { … … 448 593 } 449 594 }); 450 595 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 487 // wp.media.controller.Gallery 488 // --------------------------- 489 media.controller.Gallery = media.controller.Library.extend({ 596 // wp.media.controller.GalleryEdit 597 // ------------------------------- 598 media.controller.GalleryEdit = media.controller.Library.extend({ 490 599 defaults: { 491 600 id: 'gallery-edit', 492 601 multiple: false, … … 496 605 sortable: true, 497 606 searchable: false, 498 607 toolbar: 'gallery-edit', 499 content: 'browse' 608 content: 'browse', 609 title: l10n.editGalleryTitle, 610 priority: 60 500 611 }, 501 612 502 613 initialize: function() { … … 519 630 // Watch for uploaded attachments. 520 631 this.get('library').observe( wp.Uploader.queue ); 521 632 522 this.frame. content.on( 'activate:browse', this.gallerySettings, this );633 this.frame.on( 'content:render:browse', this.gallerySettings, this ); 523 634 524 635 media.controller.Library.prototype.activate.apply( this, arguments ); 525 636 }, … … 528 639 // Stop watching for uploaded attachments. 529 640 this.get('library').unobserve( wp.Uploader.queue ); 530 641 531 this.frame.content.off( null, null, this ); 642 this.frame.off( 'content:render:browse', this.gallerySettings, this ); 643 532 644 media.controller.Library.prototype.deactivate.apply( this, arguments ); 533 645 }, 534 646 535 gallerySettings: function() { 536 var library = this.get('library'), 537 browser; 647 gallerySettings: function( browser ) { 648 var library = this.get('library'); 538 649 539 if ( ! library )650 if ( ! library || ! browser ) 540 651 return; 541 652 542 653 library.gallery = library.gallery || new Backbone.Model(); 543 654 544 browser = this.frame.content.view();545 546 655 browser.sidebar.set({ 547 656 gallery: new media.view.Settings.Gallery({ 548 657 controller: this, … … 570 679 filterable: 'uploaded', 571 680 multiple: false, 572 681 menu: 'main', 573 toolbar: 'featured-image' 682 toolbar: 'featured-image', 683 title: l10n.featuredImageTitle, 684 priority: 60 574 685 }, media.controller.Library.prototype.defaults ), 575 686 576 687 initialize: function() { … … 629 740 menu: 'main', 630 741 content: 'embed', 631 742 toolbar: 'main-embed', 632 type: 'link' 743 type: 'link', 744 745 title: l10n.fromUrlTitle, 746 priority: 120 633 747 }, 634 748 635 749 // The amount of time used when debouncing the scan. … … 637 751 638 752 initialize: function() { 639 753 this.debouncedScan = _.debounce( _.bind( this.scan, this ), this.sensitivity ); 640 this.on( 'change:url', this.debouncedScan, this ); 754 this.props = new Backbone.Model({ url: '' }); 755 this.props.on( 'change:url', this.debouncedScan, this ); 641 756 this.on( 'scan', this.scanImage, this ); 642 media.controller.State.prototype.initialize.apply( this, arguments );643 757 }, 644 758 645 759 scan: function() { … … 652 766 scanImage: function( attributes ) { 653 767 var frame = this.frame, 654 768 state = this, 655 url = this. get('url'),769 url = this.props.get('url'), 656 770 image = new Image(); 657 771 658 772 image.onload = function() { 659 if ( state !== frame.state() || url !== state. get('url') )773 if ( state !== frame.state() || url !== state.props.get('url') ) 660 774 return; 661 775 662 776 state.set({ … … 670 784 }, 671 785 672 786 reset: function() { 673 _.each( _.difference( _.keys( this.attributes ), _.keys( this.defaults ) ), function( key ) { 674 this.unset( key ); 675 }, this ); 787 this.props = new Backbone.Model({ url: '' }); 676 788 677 this.set( 'url', '' );678 679 789 if ( this.id === this.frame.state().id ) 680 this.frame.toolbar. view().refresh();790 this.frame.toolbar.get().refresh(); 681 791 } 682 792 }); 683 793 … … 1022 1132 // The constructor for the `Views` manager. 1023 1133 Views: media.Views, 1024 1134 1025 constructor: function( ) {1135 constructor: function( options ) { 1026 1136 this.views = new this.Views( this, this.views ); 1027 1137 this.on( 'ready', this.ready, this ); 1138 1139 if ( options && options.controller ) 1140 this.controller = options.controller; 1141 1028 1142 Backbone.View.apply( this, arguments ); 1029 1143 }, 1030 1144 … … 1097 1211 // Initialize regions. 1098 1212 _.each( this.regions, function( region ) { 1099 1213 this[ region ] = new media.controller.Region({ 1100 controller:this,1101 id: 1102 selector: 1214 view: this, 1215 id: region, 1216 selector: '.media-frame-' + region 1103 1217 }); 1104 1218 }, this ); 1105 1219 }, … … 1113 1227 // Ensure states have a reference to the frame. 1114 1228 this.states.on( 'add', function( model ) { 1115 1229 model.frame = this; 1230 model.trigger('ready'); 1116 1231 }, this ); 1117 1232 }, 1118 1233 … … 1131 1246 media.view.MediaFrame = media.view.Frame.extend({ 1132 1247 className: 'media-frame', 1133 1248 template: media.template('media-frame'), 1134 regions: ['menu',' content','toolbar'],1249 regions: ['menu','title','content','toolbar','router'], 1135 1250 1136 1251 initialize: function() { 1137 1252 media.view.Frame.prototype.initialize.apply( this, arguments ); … … 1173 1288 } 1174 1289 1175 1290 this.on( 'attach', _.bind( this.views.ready, this.views ), this ); 1291 1292 // Bind default title creation. 1293 this.on( 'title:create:default', this.createTitle, this ); 1294 this.title.mode('default'); 1176 1295 }, 1177 1296 1178 1297 render: function() { … … 1183 1302 return media.view.Frame.prototype.render.apply( this, arguments ); 1184 1303 }, 1185 1304 1305 createTitle: function( title ) { 1306 title.view = new media.View({ 1307 controller: this, 1308 tagName: 'h1' 1309 }); 1310 }, 1311 1312 createMenu: function( menu ) { 1313 menu.view = new media.view.Menu({ 1314 controller: this 1315 }); 1316 }, 1317 1318 createToolbar: function( toolbar ) { 1319 menu.view = new media.view.Toolbar({ 1320 controller: this 1321 }); 1322 }, 1323 1324 createRouter: function( router ) { 1325 router.view = new media.view.Router({ 1326 controller: this 1327 }); 1328 }, 1329 1186 1330 createIframeStates: function( options ) { 1187 1331 var settings = media.view.settings, 1188 1332 tabs = settings.tabs, … … 1208 1352 }, options ) ); 1209 1353 }, this ); 1210 1354 1211 this. content.on( 'activate:iframe', this.iframeContent, this );1212 this. menu.on( 'activate:main', this.iframeMenu, this );1355 this.on( 'content:create:iframe', this.iframeContent, this ); 1356 this.on( 'menu:render:main', this.iframeMenu, this ); 1213 1357 this.on( 'open', this.hijackThickbox, this ); 1214 1358 this.on( 'close', this.restoreThickbox, this ); 1215 1359 }, 1216 1360 1217 iframeContent: function( ) {1361 iframeContent: function( content ) { 1218 1362 this.$el.addClass('hide-toolbar'); 1219 this.content.view(new media.view.Iframe({1363 content.view = new media.view.Iframe({ 1220 1364 controller: this 1221 }) .render() );1365 }); 1222 1366 }, 1223 1367 1224 iframeMenu: function( ) {1368 iframeMenu: function( view ) { 1225 1369 var views = {}; 1226 1370 1371 if ( ! view ) 1372 return; 1373 1227 1374 _.each( media.view.settings.tabs, function( title, id ) { 1228 1375 views[ 'iframe:' + id ] = { 1229 1376 text: this.state( 'iframe:' + id ).get('title'), … … 1231 1378 }; 1232 1379 }, this ); 1233 1380 1234 this.menu.view().set( views );1381 view.set( views ); 1235 1382 }, 1236 1383 1237 1384 hijackThickbox: function() { … … 1305 1452 new media.controller.Library({ 1306 1453 selection: options.selection, 1307 1454 library: media.query( options.library ), 1308 multiple: this.options.multiple,1455 multiple: options.multiple, 1309 1456 menu: 'main', 1310 toolbar: 'select' 1311 }), 1312 1313 new media.controller.Upload({ 1314 menu: 'main' 1457 title: options.title, 1458 priority: 20 1315 1459 }) 1316 1460 ]); 1317 1461 }, 1318 1462 1319 1463 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 ); 1464 this.on( 'menu:create:main', this.createMenu, this ); 1465 this.on( 'router:create:browse', this.createRouter, this ); 1466 this.on( 'router:render:browse', this.browseRouter, this ); 1467 this.on( 'content:create:browse', this.browseContent, this ); 1468 this.on( 'content:render:upload', this.uploadContent, this ); 1469 this.on( 'toolbar:create:select', this.createSelectToolbar, this ); 1324 1470 1325 1471 this.on( 'refresh:selection', this.refreshSelectToolbar, this ); 1326 1472 }, 1327 1473 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 } 1474 // Routers 1475 browseRouter: function( view ) { 1476 view.set({ 1477 upload: { 1478 text: l10n.uploadFilesTitle, 1479 priority: 20 1480 }, 1481 browse: { 1482 text: l10n.mediaLibraryTitle, 1483 priority: 40 1342 1484 } 1343 }) );1485 }); 1344 1486 }, 1345 1487 1346 1488 // Content 1347 browseContent: function( ) {1489 browseContent: function( content ) { 1348 1490 var state = this.state(); 1349 1491 1350 1492 this.$el.removeClass('hide-toolbar'); 1351 1493 1352 1494 // Browse our library of attachments. 1353 this.content.view(new media.view.AttachmentsBrowser({1495 content.view = new media.view.AttachmentsBrowser({ 1354 1496 controller: this, 1355 1497 collection: state.get('library'), 1356 1498 selection: state.get('selection'), 1357 1499 model: state, 1358 1500 sortable: state.get('sortable'), 1359 1501 search: state.get('searchable'), 1360 uploads: state.get('uploads'),1361 1502 filters: state.get('filterable'), 1362 1503 display: state.get('displaySettings'), 1363 1504 1364 1505 AttachmentView: state.get('AttachmentView') 1365 }) );1506 }); 1366 1507 }, 1367 1508 1368 1509 uploadContent: function() { 1369 this.$el.addClass('hide-toolbar'); 1370 1371 this.content.view( new media.view.UploaderInline({ 1510 this.$el.removeClass('hide-toolbar'); 1511 this.content.set( new media.view.UploaderInline({ 1372 1512 controller: this 1373 1513 }) ); 1374 1514 }, 1375 1515 1376 1516 // Toolbars 1377 selectToolbar: function(options ) {1517 createSelectToolbar: function( toolbar, options ) { 1378 1518 options = _.defaults( options || {}, { 1379 1519 event: 'select', 1380 1520 silent: false, 1381 1521 state: false 1382 1522 }); 1383 1523 1384 t his.toolbar.view(new media.view.Toolbar({1524 toolbar.view = new media.view.Toolbar({ 1385 1525 controller: this, 1386 1526 silent: options.silent, 1387 1527 … … 1402 1542 } 1403 1543 } 1404 1544 } 1405 }) );1545 }); 1406 1546 }, 1407 1547 1408 1548 refreshSelectToolbar: function() { … … 1411 1551 if ( ! selection || 'select' !== this.toolbar.mode() ) 1412 1552 return; 1413 1553 1414 this.toolbar. view().get('select').model.set( 'disabled', ! selection.length );1554 this.toolbar.get().get('select').model.set( 'disabled', ! selection.length ); 1415 1555 } 1416 1556 }); 1417 1557 … … 1430 1570 }, 1431 1571 1432 1572 createStates: function() { 1433 var options = this.options; 1573 var options = this.options, 1574 selection = options.selection; 1434 1575 1435 1576 // Add the default states. 1436 1577 this.states.add([ 1437 1578 // Main states. 1438 1579 new media.controller.Library({ 1439 selection: options.selection, 1580 id: 'insert', 1581 title: l10n.insertMediaTitle, 1582 priority: 20, 1583 menu: 'main', 1584 toolbar: 'main-insert', 1585 filterable: 'all', 1440 1586 library: media.query( options.library ), 1587 selection: selection, 1588 multiple: options.multiple ? 'reset' : false, 1441 1589 editable: true, 1442 filterable: 'all',1443 multiple: this.options.multiple,1444 menu: 'main',1445 1590 1446 1591 // Show the attachment display settings. 1447 1592 displaySettings: true, … … 1450 1595 displayUserSettings: true 1451 1596 }), 1452 1597 1453 new media.controller.Upload({ 1454 menu: 'main' 1598 new media.controller.Library({ 1599 id: 'gallery', 1600 title: l10n.createGalleryTitle, 1601 priority: 40, 1602 menu: 'main', 1603 toolbar: 'main-gallery', 1604 filterable: 'uploaded', 1605 multiple: 'add', 1606 editable: true, 1607 1608 library: media.query( _.defaults({ 1609 type: 'image' 1610 }, options.library ) ), 1611 1612 selection: new media.model.Selection( selection.models, { 1613 multiple: 'add' 1614 }) 1455 1615 }), 1456 1616 1457 1617 // Embed states. 1458 1618 new media.controller.Embed(), 1459 1619 1460 1620 // Gallery states. 1461 new media.controller.Gallery ({1621 new media.controller.GalleryEdit({ 1462 1622 library: options.selection, 1463 1623 editing: options.editing, 1464 1624 menu: 'gallery' … … 1468 1628 id: 'gallery-library', 1469 1629 library: media.query({ type: 'image' }), 1470 1630 filterable: 'uploaded', 1471 multiple: true,1631 multiple: 'add', 1472 1632 menu: 'gallery', 1473 1633 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' 1634 excludeState: 'gallery-edit', 1635 title: l10n.addToGalleryTitle, 1636 priority: 100 1481 1637 }) 1482 1638 ]); 1483 1639 … … 1492 1648 1493 1649 bindHandlers: function() { 1494 1650 media.view.MediaFrame.Select.prototype.bindHandlers.apply( this, arguments ); 1651 this.on( 'menu:create:gallery', this.createMenu, this ); 1652 this.on( 'toolbar:create:main-insert', this.createSelectionToolbar, this ); 1653 this.on( 'toolbar:create:main-gallery', this.createSelectionToolbar, this ); 1495 1654 1496 1655 var handlers = { 1497 1656 menu: { 1657 'main': 'mainMenu', 1498 1658 'gallery': 'galleryMenu' 1499 1659 }, 1500 1660 … … 1504 1664 }, 1505 1665 1506 1666 toolbar: { 1507 'main-attachments': 'mainAttachmentsToolbar', 1667 'main-insert': 'mainInsertToolbar', 1668 'main-gallery': 'mainGalleryToolbar', 1508 1669 'main-embed': 'mainEmbedToolbar', 1509 1670 'featured-image': 'featuredImageToolbar', 1510 1671 'gallery-edit': 'galleryEditToolbar', … … 1514 1675 1515 1676 _.each( handlers, function( regionHandlers, region ) { 1516 1677 _.each( regionHandlers, function( callback, handler ) { 1517 this [ region ].on( 'activate:' + handler, this[ callback ], this );1678 this.on( region + ':render:' + handler, this[ callback ], this ); 1518 1679 }, this ); 1519 1680 }, this ); 1520 1681 }, 1521 1682 1522 1683 // Menus 1523 mainMenu: function() { 1524 media.view.MediaFrame.Select.prototype.mainMenu.call( this, { silent: true }); 1525 1526 this.menu.view().set({ 1684 mainMenu: function( view ) { 1685 view.set({ 1527 1686 'library-separator': new media.View({ 1528 1687 className: 'separator', 1529 priority: 60 1530 }), 1531 'embed': { 1532 text: l10n.fromUrlTitle, 1533 priority: 80 1534 } 1688 priority: 100 1689 }) 1535 1690 }); 1536 1537 if ( media.view.settings.post.featuredImageId ) {1538 this.menu.view().set( 'featured-image', {1539 text: l10n.featuredImageTitle,1540 priority: 1001541 });1542 }1543 1691 }, 1544 1692 1545 galleryMenu: function( ) {1693 galleryMenu: function( view ) { 1546 1694 var lastState = this.lastState(), 1547 1695 previous = lastState && lastState.id, 1548 1696 frame = this; 1549 1697 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 1698 view.set({ 1699 cancel: { 1700 text: l10n.cancelGalleryTitle, 1701 priority: 20, 1702 click: function() { 1703 if ( previous ) 1704 frame.setState( previous ); 1705 else 1706 frame.close(); 1578 1707 } 1579 } 1580 }) ); 1708 }, 1709 separateCancel: new media.View({ 1710 className: 'separator', 1711 priority: 40 1712 }) 1713 }); 1581 1714 }, 1582 1715 1583 1716 // Content … … 1587 1720 model: this.state() 1588 1721 }).render(); 1589 1722 1590 this.content. view( view );1723 this.content.set( view ); 1591 1724 view.url.focus(); 1592 1725 }, 1593 1726 … … 1617 1750 }); 1618 1751 1619 1752 // Browse our library of attachments. 1620 this.content. view( view );1753 this.content.set( view ); 1621 1754 }, 1622 1755 1623 // Sidebars 1624 onSidebarGallerySettings: function( options ) { 1625 var library = this.state().get('library'); 1756 // Toolbars 1757 createSelectionToolbar: function( toolbar ) { 1758 toolbar.view = new media.view.Toolbar.Selection({ 1759 controller: this, 1760 editable: this.state().get('editable') 1761 }); 1762 }, 1626 1763 1627 if ( ! library )1628 return;1764 mainInsertToolbar: function( view ) { 1765 var controller = this; 1629 1766 1630 library.gallery = library.gallery || new Backbone.Model(); 1767 view.button = 'insert'; 1768 view.set( 'insert', { 1769 style: 'primary', 1770 priority: 80, 1771 text: l10n.insertIntoPost, 1631 1772 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 ); 1773 click: function() { 1774 var state = controller.state(), 1775 selection = state.get('selection'); 1776 1777 controller.close(); 1778 state.trigger( 'insert', selection ).reset(); 1779 } 1780 }); 1639 1781 }, 1640 1782 1641 // Toolbars 1642 mainAttachmentsToolbar: function() { 1643 this.toolbar.view( new media.view.Toolbar.Insert({ 1644 controller: this, 1645 editable: this.state().get('editable') 1646 }) ); 1783 mainGalleryToolbar: function( view ) { 1784 var controller = this; 1785 1786 view.button = 'gallery'; 1787 view.set( 'gallery', { 1788 style: 'primary', 1789 text: l10n.createNewGallery, 1790 priority: 60, 1791 1792 click: function() { 1793 var selection = controller.state().get('selection'), 1794 edit = controller.state('gallery-edit'), 1795 models = selection.where({ type: 'image' }); 1796 1797 edit.set( 'library', new media.model.Selection( models, { 1798 props: selection.props.toJSON(), 1799 multiple: true 1800 }) ); 1801 1802 this.controller.setState('gallery-edit'); 1803 } 1804 }); 1647 1805 }, 1648 1806 1649 1807 featuredImageToolbar: function() { 1650 this.toolbar. view( new media.view.Toolbar.Select({1808 this.toolbar.set( new media.view.Toolbar.Select({ 1651 1809 controller: this, 1652 1810 text: l10n.setFeaturedImage, 1653 1811 state: this.options.state || 'upload' … … 1655 1813 }, 1656 1814 1657 1815 mainEmbedToolbar: function() { 1658 this.toolbar. view( new media.view.Toolbar.Embed({1816 this.toolbar.set( new media.view.Toolbar.Embed({ 1659 1817 controller: this 1660 1818 }) ); 1661 1819 … … 1664 1822 1665 1823 galleryEditToolbar: function() { 1666 1824 var editing = this.state().get('editing'); 1667 this.toolbar. view( new media.view.Toolbar({1825 this.toolbar.set( new media.view.Toolbar({ 1668 1826 controller: this, 1669 1827 items: { 1670 1828 insert: { … … 1689 1847 }, 1690 1848 1691 1849 galleryAddToolbar: function() { 1692 this.toolbar. view( new media.view.Toolbar({1850 this.toolbar.set( new media.view.Toolbar({ 1693 1851 controller: this, 1694 1852 items: { 1695 1853 insert: { … … 1704 1862 1705 1863 edit.get('library').add( state.get('selection').models ); 1706 1864 state.trigger('reset'); 1707 controller.s tate('gallery-edit');1865 controller.setState('gallery-edit'); 1708 1866 } 1709 1867 } 1710 1868 } … … 1729 1887 }, 1730 1888 1731 1889 initialize: function() { 1732 this.controller = this.options.controller;1733 1734 1890 _.defaults( this.options, { 1735 1891 container: document.body, 1736 1892 title: '', … … 1838 1994 initialize: function() { 1839 1995 var uploader; 1840 1996 1841 this.controller = this.options.controller;1842 1843 1997 this.$browser = $('<a href="#" class="browser" />').hide().appendTo('body'); 1844 1998 1845 1999 uploader = this.options.uploader = _.defaults( this.options.uploader || {}, { … … 1906 2060 template: media.template('uploader-inline'), 1907 2061 1908 2062 initialize: function() { 1909 this.controller = this.options.controller; 2063 _.defaults( this.options, { 2064 message: '', 2065 status: true 2066 }); 1910 2067 1911 2068 if ( ! this.options.$browser && this.controller.uploader ) 1912 2069 this.options.$browser = this.controller.uploader.$browser; … … 1914 2071 if ( _.isUndefined( this.options.postId ) ) 1915 2072 this.options.postId = media.view.settings.post.id; 1916 2073 1917 this.views.set( '.upload-inline-status', new media.view.UploaderStatus({ 1918 controller: this.controller 1919 }) ); 2074 if ( this.options.status ) { 2075 this.views.set( '.upload-inline-status', new media.view.UploaderStatus({ 2076 controller: this.controller 2077 }) ); 2078 } 1920 2079 }, 1921 2080 1922 2081 ready: function() { … … 1951 2110 }, 1952 2111 1953 2112 initialize: function() { 1954 this.controller = this.options.controller;1955 1956 2113 this.queue = wp.Uploader.queue; 1957 2114 this.queue.on( 'add remove reset', this.visibility, this ); 1958 2115 this.queue.on( 'add remove reset change:percent', this.progress, this ); … … 2060 2217 className: 'media-toolbar', 2061 2218 2062 2219 initialize: function() { 2063 this.controller = this.options.controller;2064 2065 2220 this._views = {}; 2066 2221 this.$primary = $('<div class="media-toolbar-primary" />').prependTo( this.$el ); 2067 2222 this.$secondary = $('<div class="media-toolbar-secondary" />').prependTo( this.$el ); … … 2199 2354 // --------------------------- 2200 2355 media.view.Toolbar.Embed = media.view.Toolbar.Select.extend({ 2201 2356 initialize: function() { 2202 var controller = this.options.controller;2203 2204 2357 _.defaults( this.options, { 2205 2358 text: l10n.insertIntoPost 2206 2359 }); 2207 2360 2208 2361 media.view.Toolbar.Select.prototype.initialize.apply( this, arguments ); 2209 controller.on( 'change:url', this.refresh, this );2362 this.controller.state().props.on( 'change:url', this.refresh, this ); 2210 2363 }, 2211 2364 2212 2365 refresh: function() { 2213 var url = this.controller.state(). get('url');2366 var url = this.controller.state().props.get('url'); 2214 2367 this.get('select').model.set( 'disabled', ! url || /^https?:\/\/$/.test(url) ); 2215 2368 } 2216 2369 }); 2217 2370 2218 // wp.media.view.Toolbar.Insert 2219 // ---------------------------- 2220 media.view.Toolbar.Insert = media.view.Toolbar.extend({ 2371 // wp.media.view.Toolbar.Selection 2372 // ------------------------------- 2373 media.view.Toolbar.Selection = media.view.Toolbar.extend({ 2374 button: 'insert', 2375 2221 2376 initialize: function() { 2222 var controller = this.options.controller, 2223 selection = controller.state().get('selection'), 2224 selectionToLibrary; 2377 var controller = this.controller; 2225 2378 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: true2236 }) );2237 2238 this.controller.setState( state );2239 };2240 };2241 2242 2379 this.options.items = _.defaults( this.options.items || {}, { 2243 2380 selection: new media.view.Selection({ 2244 2381 controller: controller, 2245 collection: selection,2382 collection: controller.state().get('selection'), 2246 2383 priority: -40, 2247 2384 2248 2385 // If the selection is editable, pass the callback to … … 2250 2387 editable: this.options.editable && function() { 2251 2388 this.controller.content.mode('edit-selection'); 2252 2389 } 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 } 2390 }).render() 2273 2391 }); 2274 2392 2275 2393 media.view.Toolbar.prototype.initialize.apply( this, arguments ); … … 2277 2395 2278 2396 refresh: function() { 2279 2397 var selection = this.controller.state().get('selection'), 2280 count = selection.length;2398 button = this.get( this.button ); 2281 2399 2282 this.get('insert').model.set( 'disabled', ! selection.length ); 2400 if ( ! button ) 2401 return; 2283 2402 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 }) ); 2403 button.model.set( 'disabled', ! selection.length ); 2288 2404 } 2289 2405 }); 2290 2406 … … 2388 2504 tagName: 'div', 2389 2505 2390 2506 initialize: function() { 2391 this.controller = this.options.controller; 2392 this._views = {}; 2507 this._views = {}; 2393 2508 2394 2509 this.set( _.extend( {}, this._views, this.options.views ), { silent: true }); 2395 2510 delete this.options.views; … … 2457 2572 } 2458 2573 }); 2459 2574 2575 /** 2576 * wp.media.view.MenuItem 2577 */ 2578 media.view.MenuItem = media.View.extend({ 2579 tagName: 'a', 2580 className: 'media-menu-item', 2460 2581 2582 attributes: { 2583 href: '#' 2584 }, 2585 2586 events: { 2587 'click': '_click' 2588 }, 2589 2590 _click: function( event ) { 2591 var clickOverride = this.options.click; 2592 2593 if ( event ) 2594 event.preventDefault(); 2595 2596 if ( clickOverride ) 2597 clickOverride.call( this ); 2598 else 2599 this.click(); 2600 }, 2601 2602 click: function() { 2603 var state = this.options.state; 2604 if ( state ) 2605 this.controller.setState( state ); 2606 }, 2607 2608 render: function() { 2609 var options = this.options; 2610 2611 if ( options.text ) 2612 this.$el.text( options.text ); 2613 else if ( options.html ) 2614 this.$el.html( options.html ); 2615 2616 return this; 2617 } 2618 }); 2619 2461 2620 /** 2462 2621 * wp.media.view.Menu 2463 2622 */ 2464 2623 media.view.Menu = media.view.PriorityList.extend({ 2465 tagName: ' ul',2624 tagName: 'div', 2466 2625 className: 'media-menu', 2626 property: 'state', 2627 ItemView: media.view.MenuItem, 2628 region: 'menu', 2467 2629 2468 toView: function( options, state) {2630 toView: function( options, id ) { 2469 2631 options = options || {}; 2470 options .state = options.state || state;2471 return new media.view.MenuItem( options ).render();2632 options[ this.property ] = options[ this.property ] || id; 2633 return new this.ItemView( options ).render(); 2472 2634 }, 2473 2635 2474 select: function( state ) { 2475 var view = this.get( state ); 2636 ready: function() { 2637 media.view.PriorityList.prototype.ready.apply( this, arguments ); 2638 this.visibility(); 2639 }, 2476 2640 2641 set: function() { 2642 media.view.PriorityList.prototype.set.apply( this, arguments ); 2643 this.visibility(); 2644 }, 2645 2646 unset: function() { 2647 media.view.PriorityList.prototype.unset.apply( this, arguments ); 2648 this.visibility(); 2649 }, 2650 2651 visibility: function() { 2652 var region = this.region, 2653 view = this.controller[ region ].get(), 2654 views = this.views.get(), 2655 hide = ! views || views.length < 2; 2656 2657 if ( this === view ) 2658 this.controller.$el.toggleClass( 'hide-' + region, hide ); 2659 }, 2660 2661 select: function( id ) { 2662 var view = this.get( id ); 2663 2477 2664 if ( ! view ) 2478 2665 return; 2479 2666 … … 2486 2673 } 2487 2674 }); 2488 2675 2489 media.view.MenuItem = media.View.extend({ 2490 tagName: 'li', 2491 className: 'media-menu-item', 2676 /** 2677 * wp.media.view.RouterItem 2678 */ 2679 media.view.RouterItem = media.view.MenuItem.extend({ 2680 click: function() { 2681 var contentMode = this.options.contentMode; 2682 if ( contentMode ) 2683 this.controller.content.mode( contentMode ); 2684 } 2685 }); 2492 2686 2493 events: { 2494 'click': 'click' 2495 }, 2687 /** 2688 * wp.media.view.Router 2689 */ 2690 media.view.Router = media.view.Menu.extend({ 2691 tagName: 'div', 2692 className: 'media-router', 2693 property: 'contentMode', 2694 ItemView: media.view.RouterItem, 2695 region: 'router', 2496 2696 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 ); 2697 initialize: function() { 2698 this.controller.on( 'content:render', this.update, this ); 2699 media.view.Menu.prototype.initialize.apply( this, arguments ); 2504 2700 }, 2505 2701 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; 2702 update: function() { 2703 var mode = this.controller.content.mode(); 2704 if ( mode ) 2705 this.select( mode ); 2515 2706 } 2516 2707 }); 2517 2708 2709 2518 2710 /** 2519 2711 * wp.media.view.Sidebar 2520 2712 */ … … 2531 2723 template: media.template('attachment'), 2532 2724 2533 2725 events: { 2534 'click .attachment-preview': 'toggleSelection ',2726 'click .attachment-preview': 'toggleSelectionHandler', 2535 2727 'change [data-setting]': 'updateSetting', 2536 2728 'change [data-setting] input': 'updateSetting', 2537 2729 'change [data-setting] select': 'updateSetting', … … 2546 2738 initialize: function() { 2547 2739 var selection = this.options.selection; 2548 2740 2549 this.controller = this.options.controller;2550 2551 2741 this.model.on( 'change:sizes change:uploading change:caption change:title', this.render, this ); 2552 2742 this.model.on( 'change:percent', this.progress, this ); 2553 2743 … … 2623 2813 this.$bar.width( this.model.get('percent') + '%' ); 2624 2814 }, 2625 2815 2626 toggleSelection: function( event ) { 2627 var selection = this.options.selection, 2628 model = this.model; 2816 toggleSelectionHandler: function( event ) { 2817 var method; 2629 2818 2819 if ( event.shiftKey ) 2820 method = 'between'; 2821 else if ( event.ctrlKey || event.metaKey ) 2822 method = 'toggle'; 2823 2824 this.toggleSelection({ 2825 method: method 2826 }); 2827 }, 2828 2829 toggleSelection: function( options ) { 2830 var collection = this.collection, 2831 selection = this.options.selection, 2832 model = this.model, 2833 method = options && options.method, 2834 single, between, models, singleIndex, modelIndex; 2835 2630 2836 if ( ! selection ) 2631 2837 return; 2632 2838 2839 single = selection.single(); 2840 method = _.isUndefined( method ) ? selection.multiple : method; 2841 2842 // If the `method` is set to `between`, select all models that 2843 // exist between the current and the selected model. 2844 if ( 'between' === method && single && selection.multiple ) { 2845 // If the models are the same, short-circuit. 2846 if ( single === model ) 2847 return; 2848 2849 singleIndex = collection.indexOf( single ); 2850 modelIndex = collection.indexOf( this.model ); 2851 2852 if ( singleIndex < modelIndex ) 2853 models = collection.models.slice( singleIndex, modelIndex + 1 ); 2854 else 2855 models = collection.models.slice( modelIndex, singleIndex + 1 ); 2856 2857 selection.add( models ).single( model ); 2858 return; 2859 2860 // If the `method` is set to `toggle`, just flip the selection 2861 // status, regardless of whether the model is the single model. 2862 } else if ( 'toggle' === method ) { 2863 selection[ this.selected() ? 'remove' : 'add' ]( model ).single( model ); 2864 return; 2865 } 2866 2867 if ( method !== 'add' ) 2868 method = 'reset'; 2869 2633 2870 if ( this.selected() ) { 2634 2871 // If the model is the single model, remove it. 2635 2872 // If it is not the same as the single model, 2636 2873 // it now becomes the single model. 2637 selection[ s election.single()=== model ? 'remove' : 'single' ]( model );2874 selection[ single === model ? 'remove' : 'single' ]( model ); 2638 2875 } else { 2639 selection.add( model ).single( model ); 2876 // If the model is not selected, run the `method` on the 2877 // selection. By default, we `reset` the selection, but the 2878 // `method` can be set to `add` the model to the selection. 2879 selection[ method ]( model ).single( model ); 2640 2880 } 2641 2881 }, 2642 2882 … … 2838 3078 }, 2839 3079 2840 3080 initialize: function() { 2841 this.controller = this.options.controller;2842 3081 this.el.id = _.uniqueId('__attachments-view-'); 2843 3082 2844 3083 _.defaults( this.options, { … … 2950 3189 collection.remove( model, { 2951 3190 silent: true 2952 3191 }).add( model, { 2953 at: ui.item.index(),2954 silent: true3192 silent: true, 3193 at: ui.item.index() 2955 3194 }); 2956 3195 2957 3196 // Restore the comparator. 2958 3197 collection.comparator = comparator; 2959 3198 3199 // Fire the `reset` event to ensure other collections sync. 3200 collection.trigger( 'reset', collection ); 3201 2960 3202 // If the collection is sorted by menu order, 2961 3203 // update the menu order. 2962 3204 collection.saveMenuOrder(); … … 3200 3442 className: 'attachments-browser', 3201 3443 3202 3444 initialize: function() { 3203 this.controller = this.options.controller;3204 3205 3445 _.defaults( this.options, { 3206 3446 filters: false, 3207 3447 search: true, 3208 uploads: false,3209 3448 display: false, 3210 3449 3211 3450 AttachmentView: media.view.Attachment.Library … … 3290 3529 this.removeContent(); 3291 3530 3292 3531 this.uploader = new media.view.UploaderInline({ 3293 controller: this.controller 3532 controller: this.controller, 3533 status: false, 3534 message: l10n.noItemsFound 3294 3535 }); 3295 3536 3296 3537 this.views.add( this.uploader ); … … 3322 3563 3323 3564 this.views.add( sidebar ); 3324 3565 3325 if ( options.uploads &&this.controller.uploader ) {3566 if ( this.controller.uploader ) { 3326 3567 sidebar.set( 'uploads', new media.view.UploaderStatus({ 3327 3568 controller: this.controller, 3328 3569 priority: 40 … … 3373 3614 }); 3374 3615 3375 3616 /** 3376 * wp.media.view.SelectionPreview3377 */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: true3390 });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 else3414 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 /**3427 3617 * wp.media.view.Selection 3428 3618 */ 3429 3619 media.view.Selection = media.View.extend({ … … 3442 3632 clearable: true 3443 3633 }); 3444 3634 3445 this.controller = this.options.controller;3446 3635 this.attachments = new media.view.Attachments({ 3447 3636 controller: this.controller, 3448 3637 collection: this.collection, … … 3659 3848 $input = this.$('.link-to-custom'), 3660 3849 attachment = this.options.attachment; 3661 3850 3662 if ( 'none' === linkTo ) {3851 if ( 'none' === linkTo || ( ! attachment && 'custom' !== linkTo ) ) { 3663 3852 $input.hide(); 3664 3853 return; 3665 3854 } 3666 3855 3667 $input.show(); 3856 if ( attachment ) { 3857 if ( 'post' === linkTo ) { 3858 $input.val( attachment.get('link') ); 3859 } else if ( 'file' === linkTo ) { 3860 $input.val( attachment.get('url') ); 3861 } else if ( ! this.model.get('linkUrl') ) { 3862 $input.val('http://'); 3863 } 3668 3864 3669 if ( 'post' === linkTo ) { 3670 $input.val( attachment.get('link') ); 3671 } else if ( 'file' === linkTo ) { 3672 $input.val( attachment.get('url') ); 3673 } else if ( ! this.model.get('linkUrl') ) { 3674 $input.val('http://'); 3865 $input.prop( 'readonly', 'custom' !== linkTo ); 3675 3866 } 3676 3867 3677 $input. prop( 'readonly', 'custom' !== linkTo);3868 $input.show(); 3678 3869 3679 3870 // If the input is visible, focus and select its contents. 3680 3871 if ( $input.is(':visible') ) … … 3768 3959 media.view.Iframe = media.View.extend({ 3769 3960 className: 'media-iframe', 3770 3961 3771 initialize: function() {3772 this.controller = this.options.controller;3773 },3774 3775 3962 render: function() { 3963 this.views.detach(); 3776 3964 this.$el.html( '<iframe src="' + this.controller.state().get('src') + '" />' ); 3965 this.views.render(); 3777 3966 return this; 3778 3967 } 3779 3968 }); … … 3785 3974 className: 'media-embed', 3786 3975 3787 3976 initialize: function() { 3788 this.controller = this.options.controller;3789 3790 3977 this.url = new media.view.EmbedUrl({ 3791 3978 controller: this.controller, 3792 model: this.model 3979 model: this.model.props 3793 3980 }).render(); 3794 3981 3795 3982 this._settings = new media.View(); … … 3826 4013 3827 4014 this.settings( new constructor({ 3828 4015 controller: this.controller, 3829 model: this.model ,4016 model: this.model.props, 3830 4017 priority: 40 3831 4018 }) ); 3832 4019 } … … 3846 4033 }, 3847 4034 3848 4035 initialize: function() { 3849 this.label = this.make( 'span', null, this.options.label || l10n.url );3850 4036 this.input = this.make( 'input', { 3851 4037 type: 'text', 3852 4038 value: this.model.get('url') || '' 3853 4039 }); 3854 4040 3855 this.$label = $( this.label );3856 4041 this.$input = $( this.input ); 3857 this.$el.append( [ this.label, this.input ]);4042 this.$el.append( this.input ); 3858 4043 3859 4044 this.model.on( 'change:url', this.render, this ); 3860 4045 }, -
wp-includes/media.php
1467 1467 1468 1468 // Library 1469 1469 'mediaLibraryTitle' => __( 'Media Library' ), 1470 'insertMediaTitle' => __( 'Insert Media' ), 1470 1471 'createNewGallery' => __( 'Create a new gallery' ), 1471 1472 'returnToLibrary' => __( '← Return to library' ), 1472 1473 'allMediaItems' => __( 'All media items' ), 1474 'noItemsFound' => __( 'No items found.' ), 1473 1475 'insertIntoPost' => $hier ? __( 'Insert into page' ) : __( 'Insert into post' ), 1474 1476 'uploadedToThisPost' => $hier ? __( 'Uploaded to this page' ) : __( 'Uploaded to this post' ), 1475 1477 'warnDelete' => __( "You are about to permanently delete this item.\n 'Cancel' to stop, 'OK' to delete." ), … … 1489 1491 'updateGallery' => __( 'Update gallery' ), 1490 1492 'continueEditing' => __( 'Continue editing' ), 1491 1493 'addToGallery' => __( 'Add to gallery' ), 1494 'addToGalleryTitle' => __( 'Add to Gallery' ), 1492 1495 'reverseOrder' => __( 'Reverse order' ), 1493 1496 ); 1494 1497 … … 1517 1520 ?> 1518 1521 <script type="text/html" id="tmpl-media-frame"> 1519 1522 <div class="media-frame-menu"></div> 1523 <div class="media-frame-title"></div> 1524 <div class="media-frame-router"></div> 1520 1525 <div class="media-frame-content"></div> 1521 1526 <div class="media-frame-toolbar"></div> 1522 1527 <div class="media-frame-uploader"></div> … … 1524 1529 1525 1530 <script type="text/html" id="tmpl-media-modal"> 1526 1531 <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> 1529 1533 <div class="media-modal-content"></div> 1530 1534 </div> 1531 <div class="media-modal-backdrop"> 1532 <div></div> 1533 </div> 1535 <div class="media-modal-backdrop"></div> 1534 1536 </script> 1535 1537 1536 1538 <script type="text/html" id="tmpl-uploader-window"> … … 1540 1542 </script> 1541 1543 1542 1544 <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 <# } #> 1544 1550 <?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> 1546 1552 <?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> 1548 1554 <?php do_action( 'upload_ui_over_quota' ); ?> 1549 1555 1550 1556 <?php else : ?> 1551 1557 <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> 1553 1559 <a href="#" class="browser button button-hero"><?php _e( 'Select Files' ); ?></a> 1554 1560 </div> 1555 1561 … … 1744 1750 <div class="selection-view"></div> 1745 1751 </script> 1746 1752 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 1760 1753 <script type="text/html" id="tmpl-attachment-display-settings"> 1761 1754 <h3><?php _e('Attachment Display Settings'); ?></h3> 1762 1755