Changeset 23006
- Timestamp:
- 12/04/2012 01:26:03 AM (12 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/wp-admin/js/custom-background.js
r22979 r23006 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', -
trunk/wp-admin/js/custom-header.js
r22979 r23006 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', -
trunk/wp-includes/css/media-views-rtl.css
r22983 r23006 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 … … 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; … … 94 83 */ 95 84 .media-menu { 96 left: auto;97 right: 0;98 85 border-right: 0; 99 86 border-left: 1px solid #d9d9d9; … … 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; 116 } 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; 109 128 } 110 129 … … 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 */ … … 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; -
trunk/wp-includes/css/media-views.css
r22998 r23006 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 } … … 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 {103 position: absolute;104 top: 10px;105 left: 10px;106 right: 10px;107 bottom: 10px;108 border: 1px dashed rgba( 255, 255, 255, 0.5 );109 }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 101 .media-modal-close { 127 102 position: absolute; 128 top: -27px; 129 right: 0; 103 top: 7px; 104 right: 7px; 105 width: 30px; 106 height: 30px; 107 z-index: 1000; 108 } 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 … … 164 146 padding: 0 16px; 165 147 border: 0 solid #dfdfdf; 166 }167 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 148 } 179 149 … … 237 207 display: block; 238 208 width: 100%; 239 }240 241 .media-sidebar .selection-preview {242 display: block;243 padding-top: 5px;244 209 } 245 210 … … 362 327 top: 0; 363 328 left: 0; 364 bottom: 0;365 width: 199px;329 right: 0; 330 bottom: 0; 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 ); … … 375 339 } 376 340 377 .media-menu li { 341 .media-menu > a { 342 display: block; 378 343 position: relative; 379 344 padding: 4px 20px; … … 383 348 color: #21759B; 384 349 text-shadow: 0 1px 0 #fff; 385 } 386 387 .media-menu-item { 388 cursor: pointer; 389 } 390 391 .media-menu li:hover { 350 text-decoration: none; 351 } 352 353 .media-menu > a:hover { 354 color: #21759B; 392 355 background: rgba( 0, 0, 0, 0.04 ); 356 } 357 358 .media-menu > a:active { 359 outline: none; 393 360 } 394 361 … … 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 .media-router > a:focus { 409 outline: none; 410 } 411 412 .media-router .active, 413 .media-router .active:hover { 414 color: #333; 415 } 416 417 .media-router .active:after { 418 content: ''; 419 display: block; 420 margin: -100px auto 0; 421 width: 7px; 422 height: 7px; 423 background: #fff; 424 box-shadow: 1px 1px 1px rgba( 0, 0, 0, 0.2 ); 425 z-index: 300; 426 427 -webkit-transform: rotate( 45deg ) translate( 75px, 75px ); 428 -moz-transform: rotate( 45deg ) translate( 75px, 75px ); 429 -ms-transform: rotate( 45deg ) translate( 75px, 75px ); 430 -o-transform: rotate( 45deg ) translate( 75px, 75px ); 431 transform: rotate( 45deg ) translate( 75px, 75px ); 432 } 433 434 /** 410 435 * Frame 411 436 */ … … 419 444 } 420 445 421 .media-frame .region-content { 422 position: absolute; 423 top: 0; 446 .media-frame-menu { 447 position: absolute; 448 top: 0; 449 left: 0; 450 bottom: 0; 451 width: 199px; 452 z-index: 150; 453 } 454 455 .media-frame-title { 456 position: absolute; 457 top: 0; 458 left: 200px; 459 right: 0; 460 height: 45px; 461 z-index: 200; 462 } 463 464 .media-frame-router { 465 position: absolute; 466 top: 45px; 467 left: 200px; 468 right: 0; 469 height: 30px; 470 z-index: 200; 471 border-bottom: 1px solid #dfdfdf; 472 box-shadow: 0 4px 4px -4px rgba( 0, 0, 0, 0.1 ); 473 } 474 475 .media-frame-content { 476 position: absolute; 477 top: 75px; 424 478 left: 200px; 425 479 right: 0; … … 431 485 } 432 486 433 .media-frame.hide-toolbar .region-content { 434 bottom: 0; 487 .media-frame-toolbar { 488 position: absolute; 489 left: 200px; 490 right: 0; 491 bottom: 0; 492 height: 60px; 493 z-index: 100; 494 border: 0 solid #dfdfdf; 495 border-width: 1px 0 0 0; 496 box-shadow: 0 -4px 4px -4px rgba( 0, 0, 0, 0.1 ); 497 } 498 499 .media-frame.hide-menu .media-frame-title, 500 .media-frame.hide-menu .media-frame-router, 501 .media-frame.hide-menu .media-frame-toolbar, 502 .media-frame.hide-menu .media-frame-content { 503 left: 0; 504 } 505 506 .media-frame.hide-menu .media-frame-menu { 507 left: -200px; 508 } 509 510 .media-frame.hide-toolbar .media-frame-content { 511 bottom: 0; 512 } 513 514 .media-frame.hide-toolbar .media-frame-toolbar { 515 bottom: -61px; 516 } 517 518 .media-frame.hide-router .media-frame-content { 519 top: 45px; 520 } 521 522 .media-frame.hide-router .media-frame-router { 523 display: none; 524 } 525 526 .media-frame.hide-router .media-frame-title { 527 border-bottom: 1px solid #dfdfdf; 528 box-shadow: 0 4px 4px -4px rgba( 0, 0, 0, 0.1 ); 435 529 } 436 530 437 531 .media-frame .media-toolbar .add-to-gallery { 438 532 display: none; 533 } 534 535 .media-frame-title h1 { 536 padding: 0 16px; 537 font-size: 22px; 538 font-weight: 200; 539 line-height: 45px; 540 margin: 0; 439 541 } 440 542 … … 722 824 */ 723 825 .media-frame .attachments-browser { 826 position: relative; 827 width: 100%; 828 height: 100%; 724 829 overflow: hidden; 725 830 } … … 904 1009 905 1010 .uploader-window-content { 906 border-color: #fff; 1011 position: absolute; 1012 top: 10px; 1013 left: 10px; 1014 right: 10px; 1015 bottom: 10px; 1016 border: 1px dashed #fff; 907 1017 } 908 1018 … … 957 1067 } 958 1068 1069 .uploader-inline .has-upload-message .upload-ui { 1070 margin: 0 0 4em; 1071 } 1072 959 1073 .uploader-inline h3 { 960 1074 font-size: 20px; … … 962 1076 font-weight: 200; 963 1077 margin-bottom: 1.6em; 1078 } 1079 1080 .uploader-inline .has-upload-message .upload-instructions { 1081 font-size: 14px; 1082 color: #464646; 1083 font-weight: normal; 964 1084 } 965 1085 … … 1059 1179 } 1060 1180 1061 .media-selection .attachment img{1181 .media-selection .attachment .icon { 1062 1182 width: 50%; 1063 1183 } … … 1096 1216 .media-selection .attachment .filename { 1097 1217 display: none; 1098 }1099 1100 /**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 1218 } 1162 1219 … … 1298 1355 display: block; 1299 1356 position: relative; 1300 height: 75px;1301 padding: 16px 16px;1357 height: 40px; 1358 padding: 0 16px 16px; 1302 1359 margin: 0; 1303 z-index: 50; 1360 z-index: 250; 1361 background: #fff; 1304 1362 border-bottom: 1px solid #dfdfdf; 1305 1363 box-shadow: 0 4px 4px -4px rgba( 0, 0, 0, 0.1 ); 1306 1364 font-size: 18px; 1307 1365 font-weight: 200; 1308 }1309 1310 .embed-url span {1311 display: block;1312 padding: 4px 0 6px 2px;1313 1366 } 1314 1367 … … 1325 1378 position: absolute; 1326 1379 background: #f5f5f5; 1327 top: 108px;1380 top: 57px; 1328 1381 left: 0; 1329 1382 right: 0; … … 1389 1442 */ 1390 1443 @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 { 1444 .media-frame-menu { 1417 1445 width: 139px; 1418 1446 } 1419 1447 1420 .media-menu li{1448 .media-menu > a { 1421 1449 padding: 4px 10px; 1422 1450 } 1423 1451 1424 .media-frame .region-content, 1425 .media-frame-toolbar > .media-toolbar { 1452 .media-frame-title, 1453 .media-frame-router, 1454 .media-frame-content, 1455 .media-frame-toolbar { 1426 1456 left: 140px; 1427 1457 } -
trunk/wp-includes/js/media-editor.js
r22994 r23006 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 … … 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, … … 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, -
trunk/wp-includes/js/media-views.js
r22994 r23006 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 … … 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; 84 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 ) ) ); 77 _.extend( media.controller.Region.prototype, { 78 mode: function( mode ) { 79 if ( ! mode ) 80 return this._mode; 81 82 // Bail if we're trying to change to the current mode. 83 if ( mode === this._mode ) 91 84 return this; 92 }; 93 }()), 94 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; 102 }, 103 104 view: function( view ) { 105 var previous = this._view, 106 mode = this._mode, 107 id = this.id; 108 109 // If no argument is provided, return the current view. 110 if ( ! view ) 111 return previous; 112 113 // If we're attempting to switch to the current view, bail. 114 if ( view === previous ) 85 86 this.trigger('deactivate'); 87 this._mode = mode; 88 this.render( mode ); 89 this.trigger('activate'); 90 return this; 91 }, 92 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 ); 98 99 var set = { view: null }, 100 view; 101 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 ); 120 121 if ( mode ) 122 view.$el.addClass( 'mode-' + mode ); 123 124 this.controller.views.set( this.selector, view ); 125 this._view = view; 126 }, 127 128 empty: function() { 129 this.view( new media.View() ); 125 var args = _.toArray( arguments ); 126 base = this.id + ':' + event; 127 128 // Trigger `region:action:mode` event. 129 args[0] = base + ':' + this._mode; 130 this.view.trigger.apply( this.view, args ); 131 132 // Trigger `region:action` event. 133 args[0] = base; 134 this.view.trigger.apply( this.view, args ); 135 return this; 130 136 } 131 137 }); … … 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 ); 217 }, 218 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 ); 230 }, 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; 222 223 this.menu(); 224 this.toolbar(); 225 this.content(); 226 }, 227 228 deactivate: function() {}, 243 }, 244 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(); 258 }, 259 260 229 261 _deactivate: function() { 230 262 this.active = false; 231 }, 232 233 reset: function() {}, 234 235 menu: function() { 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 ); 270 }, 271 272 _title: function() { 273 this.frame.title.render( this.get('titleMode') || 'default' ); 274 }, 275 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'), … … 241 302 return; 242 303 243 if ( menu.mode() !== mode ) 244 menu.mode( mode ); 245 246 view = menu.view(); 304 menu.mode( mode ); 305 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 }); … … 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 … … 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; 395 396 if ( this.get('syncLastSelection') ) { 397 this.getLastSelection(); 398 } 300 399 301 400 this._excludeStateLibrary(); … … 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. … … 331 433 this.get('selection').reset(); 332 434 this.resetDisplays(); 333 }, 334 335 refresh: function() { 336 this.content(); 337 this.refreshSelection(); 435 this.refreshContent(); 338 436 }, 339 437 … … 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(); 377 378 this.frame.toolbar.view().refresh(); 379 this.trigger( 'refresh:selection', this, selection ); 380 381 if ( ! selection.length && 'browse' !== mode && 'upload' !== mode ) 382 this.content(); 383 }, 384 385 selectUpload: function( attachment ) { 386 this.get('selection').add( attachment ); 501 frame = this.frame, 502 router = frame.router.get(), 503 mode = frame.content.mode(); 504 505 if ( this.active&& ! selection.length && ! router.get( mode ) ) 506 this.frame.content.render( this.get('content') ); 507 }, 508 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 ); 520 }, 521 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 … … 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', … … 497 606 searchable: false, 498 607 toolbar: 'gallery-edit', 499 content: 'browse' 608 content: 'browse', 609 title: l10n.editGalleryTitle, 610 priority: 60, 611 dragInfo: true 500 612 }, 501 613 … … 520 632 this.get('library').observe( wp.Uploader.queue ); 521 633 522 this.frame. content.on( 'activate:browse', this.gallerySettings, this );634 this.frame.on( 'content:render:browse', this.gallerySettings, this ); 523 635 524 636 media.controller.Library.prototype.activate.apply( this, arguments ); … … 529 641 this.get('library').unobserve( wp.Uploader.queue ); 530 642 531 this.frame.content.off( null, null, this ); 643 this.frame.off( 'content:render:browse', this.gallerySettings, this ); 644 532 645 media.controller.Library.prototype.deactivate.apply( this, arguments ); 533 646 }, 534 647 535 gallerySettings: function() { 536 var library = this.get('library'), 537 browser; 538 539 if ( ! library ) 648 gallerySettings: function( browser ) { 649 var library = this.get('library'); 650 651 if ( ! library || ! browser ) 540 652 return; 541 653 542 654 library.gallery = library.gallery || new Backbone.Model(); 543 544 browser = this.frame.content.view();545 655 546 656 browser.sidebar.set({ … … 571 681 multiple: false, 572 682 menu: 'main', 573 toolbar: 'featured-image' 683 toolbar: 'featured-image', 684 title: l10n.featuredImageTitle, 685 priority: 60 574 686 }, media.controller.Library.prototype.defaults ), 575 687 … … 630 742 content: 'embed', 631 743 toolbar: 'main-embed', 632 type: 'link' 744 type: 'link', 745 746 title: l10n.fromUrlTitle, 747 priority: 120 633 748 }, 634 749 … … 638 753 initialize: function() { 639 754 this.debouncedScan = _.debounce( _.bind( this.scan, this ), this.sensitivity ); 640 this.on( 'change:url', this.debouncedScan, this ); 755 this.props = new Backbone.Model({ url: '' }); 756 this.props.on( 'change:url', this.debouncedScan, this ); 641 757 this.on( 'scan', this.scanImage, this ); 642 media.controller.State.prototype.initialize.apply( this, arguments );643 758 }, 644 759 … … 653 768 var frame = this.frame, 654 769 state = this, 655 url = this. get('url'),770 url = this.props.get('url'), 656 771 image = new Image(); 657 772 658 773 image.onload = function() { 659 if ( state !== frame.state() || url !== state. get('url') )774 if ( state !== frame.state() || url !== state.props.get('url') ) 660 775 return; 661 776 … … 671 786 672 787 reset: function() { 673 _.each( _.difference( _.keys( this.attributes ), _.keys( this.defaults ) ), function( key ) { 674 this.unset( key ); 675 }, this ); 676 677 this.set( 'url', '' ); 788 this.props = new Backbone.Model({ url: '' }); 678 789 679 790 if ( this.id === this.frame.state().id ) 680 this.frame.toolbar. view().refresh();791 this.frame.toolbar.get().refresh(); 681 792 } 682 793 }); … … 1023 1134 Views: media.Views, 1024 1135 1025 constructor: function( ) {1136 constructor: function( options ) { 1026 1137 this.views = new this.Views( this, this.views ); 1027 1138 this.on( 'ready', this.ready, this ); 1139 1140 if ( options && options.controller ) 1141 this.controller = options.controller; 1142 1028 1143 Backbone.View.apply( this, arguments ); 1029 1144 }, … … 1098 1213 _.each( this.regions, function( region ) { 1099 1214 this[ region ] = new media.controller.Region({ 1100 controller:this,1101 id: 1102 selector: 1215 view: this, 1216 id: region, 1217 selector: '.media-frame-' + region 1103 1218 }); 1104 1219 }, this ); … … 1114 1229 this.states.on( 'add', function( model ) { 1115 1230 model.frame = this; 1231 model.trigger('ready'); 1116 1232 }, this ); 1117 1233 }, … … 1132 1248 className: 'media-frame', 1133 1249 template: media.template('media-frame'), 1134 regions: ['menu',' content','toolbar'],1250 regions: ['menu','title','content','toolbar','router'], 1135 1251 1136 1252 initialize: function() { … … 1174 1290 1175 1291 this.on( 'attach', _.bind( this.views.ready, this.views ), this ); 1292 1293 // Bind default title creation. 1294 this.on( 'title:create:default', this.createTitle, this ); 1295 this.title.mode('default'); 1176 1296 }, 1177 1297 … … 1182 1302 1183 1303 return media.view.Frame.prototype.render.apply( this, arguments ); 1304 }, 1305 1306 createTitle: function( title ) { 1307 title.view = new media.View({ 1308 controller: this, 1309 tagName: 'h1' 1310 }); 1311 }, 1312 1313 createMenu: function( menu ) { 1314 menu.view = new media.view.Menu({ 1315 controller: this 1316 }); 1317 }, 1318 1319 createToolbar: function( toolbar ) { 1320 menu.view = new media.view.Toolbar({ 1321 controller: this 1322 }); 1323 }, 1324 1325 createRouter: function( router ) { 1326 router.view = new media.view.Router({ 1327 controller: this 1328 }); 1184 1329 }, 1185 1330 … … 1209 1354 }, this ); 1210 1355 1211 this. content.on( 'activate:iframe', this.iframeContent, this );1212 this. menu.on( 'activate:main', this.iframeMenu, this );1356 this.on( 'content:create:iframe', this.iframeContent, this ); 1357 this.on( 'menu:render:main', this.iframeMenu, this ); 1213 1358 this.on( 'open', this.hijackThickbox, this ); 1214 1359 this.on( 'close', this.restoreThickbox, this ); 1215 1360 }, 1216 1361 1217 iframeContent: function( ) {1362 iframeContent: function( content ) { 1218 1363 this.$el.addClass('hide-toolbar'); 1219 this.content.view(new media.view.Iframe({1364 content.view = new media.view.Iframe({ 1220 1365 controller: this 1221 }) .render() );1222 }, 1223 1224 iframeMenu: function( ) {1366 }); 1367 }, 1368 1369 iframeMenu: function( view ) { 1225 1370 var views = {}; 1371 1372 if ( ! view ) 1373 return; 1226 1374 1227 1375 _.each( media.view.settings.tabs, function( title, id ) { … … 1232 1380 }, this ); 1233 1381 1234 this.menu.view().set( views );1382 view.set( views ); 1235 1383 }, 1236 1384 … … 1306 1454 selection: options.selection, 1307 1455 library: media.query( options.library ), 1308 multiple: this.options.multiple,1456 multiple: options.multiple, 1309 1457 menu: 'main', 1310 toolbar: 'select' 1311 }), 1312 1313 new media.controller.Upload({ 1314 menu: 'main' 1458 title: options.title, 1459 priority: 20 1315 1460 }) 1316 1461 ]); … … 1318 1463 1319 1464 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 ); 1465 this.on( 'menu:create:main', this.createMenu, this ); 1466 this.on( 'router:create:browse', this.createRouter, this ); 1467 this.on( 'router:render:browse', this.browseRouter, this ); 1468 this.on( 'content:create:browse', this.browseContent, this ); 1469 this.on( 'content:render:upload', this.uploadContent, this ); 1470 this.on( 'toolbar:create:select', this.createSelectToolbar, this ); 1324 1471 1325 1472 this.on( 'refresh:selection', this.refreshSelectToolbar, this ); 1326 1473 }, 1327 1474 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 } 1475 // Routers 1476 browseRouter: function( view ) { 1477 view.set({ 1478 upload: { 1479 text: l10n.uploadFilesTitle, 1480 priority: 20 1481 }, 1482 browse: { 1483 text: l10n.mediaLibraryTitle, 1484 priority: 40 1342 1485 } 1343 }) );1486 }); 1344 1487 }, 1345 1488 1346 1489 // Content 1347 browseContent: function( ) {1490 browseContent: function( content ) { 1348 1491 var state = this.state(); 1349 1492 … … 1351 1494 1352 1495 // Browse our library of attachments. 1353 this.content.view(new media.view.AttachmentsBrowser({1496 content.view = new media.view.AttachmentsBrowser({ 1354 1497 controller: this, 1355 1498 collection: state.get('library'), … … 1358 1501 sortable: state.get('sortable'), 1359 1502 search: state.get('searchable'), 1360 uploads: state.get('uploads'),1361 1503 filters: state.get('filterable'), 1362 1504 display: state.get('displaySettings'), 1505 dragInfo: state.get('dragInfo'), 1363 1506 1364 1507 AttachmentView: state.get('AttachmentView') 1365 }) );1508 }); 1366 1509 }, 1367 1510 1368 1511 uploadContent: function() { 1369 this.$el.addClass('hide-toolbar'); 1370 1371 this.content.view( new media.view.UploaderInline({ 1512 this.$el.removeClass('hide-toolbar'); 1513 this.content.set( new media.view.UploaderInline({ 1372 1514 controller: this 1373 1515 }) ); … … 1375 1517 1376 1518 // Toolbars 1377 selectToolbar: function(options ) {1519 createSelectToolbar: function( toolbar, options ) { 1378 1520 options = _.defaults( options || {}, { 1379 1521 event: 'select', … … 1382 1524 }); 1383 1525 1384 t his.toolbar.view(new media.view.Toolbar({1526 toolbar.view = new media.view.Toolbar({ 1385 1527 controller: this, 1386 1528 silent: options.silent, … … 1403 1545 } 1404 1546 } 1405 }) );1547 }); 1406 1548 }, 1407 1549 … … 1412 1554 return; 1413 1555 1414 this.toolbar. view().get('select').model.set( 'disabled', ! selection.length );1556 this.toolbar.get().get('select').model.set( 'disabled', ! selection.length ); 1415 1557 } 1416 1558 }); … … 1431 1573 1432 1574 createStates: function() { 1433 var options = this.options; 1575 var options = this.options, 1576 selection = options.selection; 1434 1577 1435 1578 // Add the default states. … … 1437 1580 // Main states. 1438 1581 new media.controller.Library({ 1439 selection: options.selection, 1582 id: 'insert', 1583 title: l10n.insertMediaTitle, 1584 priority: 20, 1585 menu: 'main', 1586 toolbar: 'main-insert', 1587 filterable: 'all', 1440 1588 library: media.query( options.library ), 1589 selection: selection, 1590 multiple: options.multiple ? 'reset' : false, 1441 1591 editable: true, 1442 filterable: 'all',1443 multiple: this.options.multiple,1444 menu: 'main',1445 1592 1446 1593 // Show the attachment display settings. … … 1451 1598 }), 1452 1599 1453 new media.controller.Upload({ 1454 menu: 'main' 1600 new media.controller.Library({ 1601 id: 'gallery', 1602 title: l10n.createGalleryTitle, 1603 priority: 40, 1604 menu: 'main', 1605 toolbar: 'main-gallery', 1606 filterable: 'uploaded', 1607 multiple: 'add', 1608 editable: true, 1609 1610 library: media.query( _.defaults({ 1611 type: 'image' 1612 }, options.library ) ), 1613 1614 selection: new media.model.Selection( selection.models, { 1615 multiple: 'add' 1616 }) 1455 1617 }), 1456 1618 … … 1459 1621 1460 1622 // Gallery states. 1461 new media.controller.Gallery ({1623 new media.controller.GalleryEdit({ 1462 1624 library: options.selection, 1463 1625 editing: options.editing, … … 1469 1631 library: media.query({ type: 'image' }), 1470 1632 filterable: 'uploaded', 1471 multiple: true,1633 multiple: 'add', 1472 1634 menu: 'gallery', 1473 1635 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' 1636 excludeState: 'gallery-edit', 1637 title: l10n.addToGalleryTitle, 1638 priority: 100 1481 1639 }) 1482 1640 ]); … … 1493 1651 bindHandlers: function() { 1494 1652 media.view.MediaFrame.Select.prototype.bindHandlers.apply( this, arguments ); 1653 this.on( 'menu:create:gallery', this.createMenu, this ); 1654 this.on( 'toolbar:create:main-insert', this.createSelectionToolbar, this ); 1655 this.on( 'toolbar:create:main-gallery', this.createSelectionToolbar, this ); 1495 1656 1496 1657 var handlers = { 1497 1658 menu: { 1659 'main': 'mainMenu', 1498 1660 'gallery': 'galleryMenu' 1499 1661 }, … … 1505 1667 1506 1668 toolbar: { 1507 'main-attachments': 'mainAttachmentsToolbar', 1669 'main-insert': 'mainInsertToolbar', 1670 'main-gallery': 'mainGalleryToolbar', 1508 1671 'main-embed': 'mainEmbedToolbar', 1509 1672 'featured-image': 'featuredImageToolbar', … … 1515 1678 _.each( handlers, function( regionHandlers, region ) { 1516 1679 _.each( regionHandlers, function( callback, handler ) { 1517 this [ region ].on( 'activate:' + handler, this[ callback ], this );1680 this.on( region + ':render:' + handler, this[ callback ], this ); 1518 1681 }, this ); 1519 1682 }, this ); … … 1521 1684 1522 1685 // Menus 1523 mainMenu: function() { 1524 media.view.MediaFrame.Select.prototype.mainMenu.call( this, { silent: true }); 1525 1526 this.menu.view().set({ 1686 mainMenu: function( view ) { 1687 view.set({ 1527 1688 'library-separator': new media.View({ 1528 1689 className: 'separator', 1529 priority: 601530 }),1531 'embed': {1532 text: l10n.fromUrlTitle,1533 priority: 801534 }1535 });1536 1537 if ( media.view.settings.post.featuredImageId ) {1538 this.menu.view().set( 'featured-image', {1539 text: l10n.featuredImageTitle,1540 1690 priority: 100 1541 }) ;1542 } 1543 }, 1544 1545 galleryMenu: function( ) {1691 }) 1692 }); 1693 }, 1694 1695 galleryMenu: function( view ) { 1546 1696 var lastState = this.lastState(), 1547 1697 previous = lastState && lastState.id, 1548 1698 frame = this; 1549 1699 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 1700 view.set({ 1701 cancel: { 1702 text: l10n.cancelGalleryTitle, 1703 priority: 20, 1704 click: function() { 1705 if ( previous ) 1706 frame.setState( previous ); 1707 else 1708 frame.close(); 1578 1709 } 1579 } 1580 }) ); 1710 }, 1711 separateCancel: new media.View({ 1712 className: 'separator', 1713 priority: 40 1714 }) 1715 }); 1581 1716 }, 1582 1717 … … 1588 1723 }).render(); 1589 1724 1590 this.content. view( view );1725 this.content.set( view ); 1591 1726 view.url.focus(); 1592 1727 }, … … 1604 1739 sortable: true, 1605 1740 search: false, 1741 dragInfo: true, 1606 1742 1607 1743 AttachmentView: media.view.Attachment.EditSelection … … 1618 1754 1619 1755 // Browse our library of attachments. 1620 this.content.view( view ); 1621 }, 1622 1623 // Sidebars 1624 onSidebarGallerySettings: function( options ) { 1625 var library = this.state().get('library'); 1626 1627 if ( ! library ) 1628 return; 1629 1630 library.gallery = library.gallery || new Backbone.Model(); 1631 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 ); 1756 this.content.set( view ); 1639 1757 }, 1640 1758 1641 1759 // Toolbars 1642 mainAttachmentsToolbar: function() {1643 t his.toolbar.view( new media.view.Toolbar.Insert({1760 createSelectionToolbar: function( toolbar ) { 1761 toolbar.view = new media.view.Toolbar.Selection({ 1644 1762 controller: this, 1645 1763 editable: this.state().get('editable') 1646 }) ); 1764 }); 1765 }, 1766 1767 mainInsertToolbar: function( view ) { 1768 var controller = this; 1769 1770 view.button = 'insert'; 1771 view.set( 'insert', { 1772 style: 'primary', 1773 priority: 80, 1774 text: l10n.insertIntoPost, 1775 1776 click: function() { 1777 var state = controller.state(), 1778 selection = state.get('selection'); 1779 1780 controller.close(); 1781 state.trigger( 'insert', selection ).reset(); 1782 } 1783 }); 1784 }, 1785 1786 mainGalleryToolbar: function( view ) { 1787 var controller = this; 1788 1789 view.button = 'gallery'; 1790 view.set( 'gallery', { 1791 style: 'primary', 1792 text: l10n.createNewGallery, 1793 priority: 60, 1794 1795 click: function() { 1796 var selection = controller.state().get('selection'), 1797 edit = controller.state('gallery-edit'), 1798 models = selection.where({ type: 'image' }); 1799 1800 edit.set( 'library', new media.model.Selection( models, { 1801 props: selection.props.toJSON(), 1802 multiple: true 1803 }) ); 1804 1805 this.controller.setState('gallery-edit'); 1806 } 1807 }); 1647 1808 }, 1648 1809 1649 1810 featuredImageToolbar: function() { 1650 this.toolbar. view( new media.view.Toolbar.Select({1811 this.toolbar.set( new media.view.Toolbar.Select({ 1651 1812 controller: this, 1652 1813 text: l10n.setFeaturedImage, … … 1656 1817 1657 1818 mainEmbedToolbar: function() { 1658 this.toolbar. view( new media.view.Toolbar.Embed({1819 this.toolbar.set( new media.view.Toolbar.Embed({ 1659 1820 controller: this 1660 1821 }) ); … … 1665 1826 galleryEditToolbar: function() { 1666 1827 var editing = this.state().get('editing'); 1667 this.toolbar. view( new media.view.Toolbar({1828 this.toolbar.set( new media.view.Toolbar({ 1668 1829 controller: this, 1669 1830 items: { … … 1690 1851 1691 1852 galleryAddToolbar: function() { 1692 this.toolbar. view( new media.view.Toolbar({1853 this.toolbar.set( new media.view.Toolbar({ 1693 1854 controller: this, 1694 1855 items: { … … 1705 1866 edit.get('library').add( state.get('selection').models ); 1706 1867 state.trigger('reset'); 1707 controller.s tate('gallery-edit');1868 controller.setState('gallery-edit'); 1708 1869 } 1709 1870 } … … 1730 1891 1731 1892 initialize: function() { 1732 this.controller = this.options.controller;1733 1734 1893 _.defaults( this.options, { 1735 1894 container: document.body, … … 1839 1998 var uploader; 1840 1999 1841 this.controller = this.options.controller;1842 1843 2000 this.$browser = $('<a href="#" class="browser" />').hide().appendTo('body'); 1844 2001 … … 1907 2064 1908 2065 initialize: function() { 1909 this.controller = this.options.controller; 2066 _.defaults( this.options, { 2067 message: '', 2068 status: true 2069 }); 1910 2070 1911 2071 if ( ! this.options.$browser && this.controller.uploader ) … … 1915 2075 this.options.postId = media.view.settings.post.id; 1916 2076 1917 this.views.set( '.upload-inline-status', new media.view.UploaderStatus({ 1918 controller: this.controller 1919 }) ); 2077 if ( this.options.status ) { 2078 this.views.set( '.upload-inline-status', new media.view.UploaderStatus({ 2079 controller: this.controller 2080 }) ); 2081 } 1920 2082 }, 1921 2083 … … 1952 2114 1953 2115 initialize: function() { 1954 this.controller = this.options.controller;1955 1956 2116 this.queue = wp.Uploader.queue; 1957 2117 this.queue.on( 'add remove reset', this.visibility, this ); … … 2061 2221 2062 2222 initialize: function() { 2063 this.controller = this.options.controller;2064 2065 2223 this._views = {}; 2066 2224 this.$primary = $('<div class="media-toolbar-primary" />').prependTo( this.$el ); … … 2200 2358 media.view.Toolbar.Embed = media.view.Toolbar.Select.extend({ 2201 2359 initialize: function() { 2202 var controller = this.options.controller;2203 2204 2360 _.defaults( this.options, { 2205 2361 text: l10n.insertIntoPost … … 2207 2363 2208 2364 media.view.Toolbar.Select.prototype.initialize.apply( this, arguments ); 2209 controller.on( 'change:url', this.refresh, this );2365 this.controller.state().props.on( 'change:url', this.refresh, this ); 2210 2366 }, 2211 2367 2212 2368 refresh: function() { 2213 var url = this.controller.state(). get('url');2369 var url = this.controller.state().props.get('url'); 2214 2370 this.get('select').model.set( 'disabled', ! url || /^https?:\/\/$/.test(url) ); 2215 2371 } 2216 2372 }); 2217 2373 2218 // wp.media.view.Toolbar.Insert 2219 // ---------------------------- 2220 media.view.Toolbar.Insert = media.view.Toolbar.extend({ 2374 // wp.media.view.Toolbar.Selection 2375 // ------------------------------- 2376 media.view.Toolbar.Selection = media.view.Toolbar.extend({ 2377 button: 'insert', 2378 2221 2379 initialize: function() { 2222 var controller = this.options.controller, 2223 selection = controller.state().get('selection'), 2224 selectionToLibrary; 2225 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 }; 2380 var controller = this.controller; 2241 2381 2242 2382 this.options.items = _.defaults( this.options.items || {}, { 2243 2383 selection: new media.view.Selection({ 2244 2384 controller: controller, 2245 collection: selection,2385 collection: controller.state().get('selection'), 2246 2386 priority: -40, 2247 2387 … … 2251 2391 this.controller.content.mode('edit-selection'); 2252 2392 } 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 } 2393 }).render() 2273 2394 }); 2274 2395 … … 2278 2399 refresh: function() { 2279 2400 var selection = this.controller.state().get('selection'), 2280 count = selection.length; 2281 2282 this.get('insert').model.set( 'disabled', ! selection.length ); 2283 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 }) ); 2401 button = this.get( this.button ); 2402 2403 if ( ! button ) 2404 return; 2405 2406 button.model.set( 'disabled', ! selection.length ); 2288 2407 } 2289 2408 }); … … 2389 2508 2390 2509 initialize: function() { 2391 this.controller = this.options.controller; 2392 this._views = {}; 2510 this._views = {}; 2393 2511 2394 2512 this.set( _.extend( {}, this._views, this.options.views ), { silent: true }); … … 2458 2576 }); 2459 2577 2578 /** 2579 * wp.media.view.MenuItem 2580 */ 2581 media.view.MenuItem = media.View.extend({ 2582 tagName: 'a', 2583 className: 'media-menu-item', 2584 2585 attributes: { 2586 href: '#' 2587 }, 2588 2589 events: { 2590 'click': '_click' 2591 }, 2592 2593 _click: function( event ) { 2594 var clickOverride = this.options.click; 2595 2596 if ( event ) 2597 event.preventDefault(); 2598 2599 if ( clickOverride ) 2600 clickOverride.call( this ); 2601 else 2602 this.click(); 2603 }, 2604 2605 click: function() { 2606 var state = this.options.state; 2607 if ( state ) 2608 this.controller.setState( state ); 2609 }, 2610 2611 render: function() { 2612 var options = this.options; 2613 2614 if ( options.text ) 2615 this.$el.text( options.text ); 2616 else if ( options.html ) 2617 this.$el.html( options.html ); 2618 2619 return this; 2620 } 2621 }); 2460 2622 2461 2623 /** … … 2463 2625 */ 2464 2626 media.view.Menu = media.view.PriorityList.extend({ 2465 tagName: ' ul',2627 tagName: 'div', 2466 2628 className: 'media-menu', 2467 2468 toView: function( options, state ) { 2629 property: 'state', 2630 ItemView: media.view.MenuItem, 2631 region: 'menu', 2632 2633 toView: function( options, id ) { 2469 2634 options = options || {}; 2470 options.state = options.state || state; 2471 return new media.view.MenuItem( options ).render(); 2472 }, 2473 2474 select: function( state ) { 2475 var view = this.get( state ); 2635 options[ this.property ] = options[ this.property ] || id; 2636 return new this.ItemView( options ).render(); 2637 }, 2638 2639 ready: function() { 2640 media.view.PriorityList.prototype.ready.apply( this, arguments ); 2641 this.visibility(); 2642 }, 2643 2644 set: function() { 2645 media.view.PriorityList.prototype.set.apply( this, arguments ); 2646 this.visibility(); 2647 }, 2648 2649 unset: function() { 2650 media.view.PriorityList.prototype.unset.apply( this, arguments ); 2651 this.visibility(); 2652 }, 2653 2654 visibility: function() { 2655 var region = this.region, 2656 view = this.controller[ region ].get(), 2657 views = this.views.get(), 2658 hide = ! views || views.length < 2; 2659 2660 if ( this === view ) 2661 this.controller.$el.toggleClass( 'hide-' + region, hide ); 2662 }, 2663 2664 select: function( id ) { 2665 var view = this.get( id ); 2476 2666 2477 2667 if ( ! view ) … … 2487 2677 }); 2488 2678 2489 media.view.MenuItem = media.View.extend({ 2490 tagName: 'li', 2491 className: 'media-menu-item', 2492 2493 events: { 2494 'click': 'click' 2495 }, 2496 2679 /** 2680 * wp.media.view.RouterItem 2681 */ 2682 media.view.RouterItem = media.view.MenuItem.extend({ 2497 2683 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 ); 2504 }, 2505 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; 2515 } 2516 }); 2684 var contentMode = this.options.contentMode; 2685 if ( contentMode ) 2686 this.controller.content.mode( contentMode ); 2687 } 2688 }); 2689 2690 /** 2691 * wp.media.view.Router 2692 */ 2693 media.view.Router = media.view.Menu.extend({ 2694 tagName: 'div', 2695 className: 'media-router', 2696 property: 'contentMode', 2697 ItemView: media.view.RouterItem, 2698 region: 'router', 2699 2700 initialize: function() { 2701 this.controller.on( 'content:render', this.update, this ); 2702 media.view.Menu.prototype.initialize.apply( this, arguments ); 2703 }, 2704 2705 update: function() { 2706 var mode = this.controller.content.mode(); 2707 if ( mode ) 2708 this.select( mode ); 2709 } 2710 }); 2711 2517 2712 2518 2713 /** … … 2532 2727 2533 2728 events: { 2534 'click .attachment-preview': 'toggleSelection ',2729 'click .attachment-preview': 'toggleSelectionHandler', 2535 2730 'change [data-setting]': 'updateSetting', 2536 2731 'change [data-setting] input': 'updateSetting', … … 2546 2741 initialize: function() { 2547 2742 var selection = this.options.selection; 2548 2549 this.controller = this.options.controller;2550 2743 2551 2744 this.model.on( 'change:sizes change:uploading change:caption change:title', this.render, this ); … … 2624 2817 }, 2625 2818 2626 toggleSelection: function( event ) { 2627 var selection = this.options.selection, 2628 model = this.model; 2819 toggleSelectionHandler: function( event ) { 2820 var method; 2821 2822 if ( event.shiftKey ) 2823 method = 'between'; 2824 else if ( event.ctrlKey || event.metaKey ) 2825 method = 'toggle'; 2826 2827 this.toggleSelection({ 2828 method: method 2829 }); 2830 }, 2831 2832 toggleSelection: function( options ) { 2833 var collection = this.collection, 2834 selection = this.options.selection, 2835 model = this.model, 2836 method = options && options.method, 2837 single, between, models, singleIndex, modelIndex; 2629 2838 2630 2839 if ( ! selection ) 2631 2840 return; 2841 2842 single = selection.single(); 2843 method = _.isUndefined( method ) ? selection.multiple : method; 2844 2845 // If the `method` is set to `between`, select all models that 2846 // exist between the current and the selected model. 2847 if ( 'between' === method && single && selection.multiple ) { 2848 // If the models are the same, short-circuit. 2849 if ( single === model ) 2850 return; 2851 2852 singleIndex = collection.indexOf( single ); 2853 modelIndex = collection.indexOf( this.model ); 2854 2855 if ( singleIndex < modelIndex ) 2856 models = collection.models.slice( singleIndex, modelIndex + 1 ); 2857 else 2858 models = collection.models.slice( modelIndex, singleIndex + 1 ); 2859 2860 selection.add( models ).single( model ); 2861 return; 2862 2863 // If the `method` is set to `toggle`, just flip the selection 2864 // status, regardless of whether the model is the single model. 2865 } else if ( 'toggle' === method ) { 2866 selection[ this.selected() ? 'remove' : 'add' ]( model ).single( model ); 2867 return; 2868 } 2869 2870 if ( method !== 'add' ) 2871 method = 'reset'; 2632 2872 2633 2873 if ( this.selected() ) { … … 2635 2875 // If it is not the same as the single model, 2636 2876 // it now becomes the single model. 2637 selection[ s election.single()=== model ? 'remove' : 'single' ]( model );2877 selection[ single === model ? 'remove' : 'single' ]( model ); 2638 2878 } else { 2639 selection.add( model ).single( model ); 2879 // If the model is not selected, run the `method` on the 2880 // selection. By default, we `reset` the selection, but the 2881 // `method` can be set to `add` the model to the selection. 2882 selection[ method ]( model ).single( model ); 2640 2883 } 2641 2884 }, … … 2839 3082 2840 3083 initialize: function() { 2841 this.controller = this.options.controller;2842 3084 this.el.id = _.uniqueId('__attachments-view-'); 2843 3085 … … 2951 3193 silent: true 2952 3194 }).add( model, { 2953 at: ui.item.index(),2954 silent: true3195 silent: true, 3196 at: ui.item.index() 2955 3197 }); 2956 3198 2957 3199 // Restore the comparator. 2958 3200 collection.comparator = comparator; 3201 3202 // Fire the `reset` event to ensure other collections sync. 3203 collection.trigger( 'reset', collection ); 2959 3204 2960 3205 // If the collection is sorted by menu order, … … 3201 3446 3202 3447 initialize: function() { 3203 this.controller = this.options.controller;3204 3205 3448 _.defaults( this.options, { 3206 3449 filters: false, 3207 3450 search: true, 3208 uploads: false,3209 3451 display: false, 3210 3452 … … 3256 3498 } 3257 3499 3258 if ( this.options. sortable && ! this.options.filters) {3500 if ( this.options.dragInfo ) { 3259 3501 this.toolbar.set( 'dragInfo', new media.View({ 3260 3502 el: $( '<div class="instructions">' + l10n.dragInfo + '</div>' )[0], … … 3291 3533 3292 3534 this.uploader = new media.view.UploaderInline({ 3293 controller: this.controller 3535 controller: this.controller, 3536 status: false, 3537 message: l10n.noItemsFound 3294 3538 }); 3295 3539 … … 3323 3567 this.views.add( sidebar ); 3324 3568 3325 if ( options.uploads &&this.controller.uploader ) {3569 if ( this.controller.uploader ) { 3326 3570 sidebar.set( 'uploads', new media.view.UploaderStatus({ 3327 3571 controller: this.controller, … … 3374 3618 3375 3619 /** 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 3620 * wp.media.view.Selection 3428 3621 */ … … 3443 3636 }); 3444 3637 3445 this.controller = this.options.controller;3446 3638 this.attachments = new media.view.Attachments({ 3447 3639 controller: this.controller, … … 3660 3852 attachment = this.options.attachment; 3661 3853 3662 if ( 'none' === linkTo ) {3854 if ( 'none' === linkTo || ( ! attachment && 'custom' !== linkTo ) ) { 3663 3855 $input.hide(); 3664 3856 return; 3665 3857 } 3666 3858 3859 if ( attachment ) { 3860 if ( 'post' === linkTo ) { 3861 $input.val( attachment.get('link') ); 3862 } else if ( 'file' === linkTo ) { 3863 $input.val( attachment.get('url') ); 3864 } else if ( ! this.model.get('linkUrl') ) { 3865 $input.val('http://'); 3866 } 3867 3868 $input.prop( 'readonly', 'custom' !== linkTo ); 3869 } 3870 3667 3871 $input.show(); 3668 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://');3675 }3676 3677 $input.prop( 'readonly', 'custom' !== linkTo );3678 3872 3679 3873 // If the input is visible, focus and select its contents. … … 3769 3963 className: 'media-iframe', 3770 3964 3771 initialize: function() {3772 this.controller = this.options.controller;3773 },3774 3775 3965 render: function() { 3966 this.views.detach(); 3776 3967 this.$el.html( '<iframe src="' + this.controller.state().get('src') + '" />' ); 3968 this.views.render(); 3777 3969 return this; 3778 3970 } … … 3786 3978 3787 3979 initialize: function() { 3788 this.controller = this.options.controller;3789 3790 3980 this.url = new media.view.EmbedUrl({ 3791 3981 controller: this.controller, 3792 model: this.model 3982 model: this.model.props 3793 3983 }).render(); 3794 3984 … … 3827 4017 this.settings( new constructor({ 3828 4018 controller: this.controller, 3829 model: this.model ,4019 model: this.model.props, 3830 4020 priority: 40 3831 4021 }) ); … … 3847 4037 3848 4038 initialize: function() { 3849 this.label = this.make( 'span', null, this.options.label || l10n.url );3850 4039 this.input = this.make( 'input', { 3851 4040 type: 'text', … … 3853 4042 }); 3854 4043 3855 this.$label = $( this.label );3856 4044 this.$input = $( this.input ); 3857 this.$el.append( [ this.label, this.input ]);4045 this.$el.append( this.input ); 3858 4046 3859 4047 this.model.on( 'change:url', this.render, this ); -
trunk/wp-includes/media.php
r22994 r23006 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' ), … … 1490 1492 'continueEditing' => __( 'Continue editing' ), 1491 1493 'addToGallery' => __( 'Add to gallery' ), 1494 'addToGalleryTitle' => __( 'Add to Gallery' ), 1492 1495 'reverseOrder' => __( 'Reverse order' ), 1493 1496 ); … … 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> … … 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 … … 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> … … 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>
Note: See TracChangeset
for help on using the changeset viewer.