diff --git src/wp-includes/js/media/views/attachments.js src/wp-includes/js/media/views/attachments.js
index 73edcec8f..32798ed5d 100644
|
|
|
var View = wp.media.View,
|
| 5 | 5 | /** |
| 6 | 6 | * wp.media.view.Attachments |
| 7 | 7 | * |
| | 8 | * Represents the overview of attachments in the Media Library. |
| | 9 | * |
| 8 | 10 | * @memberOf wp.media.view |
| 9 | 11 | * |
| 10 | 12 | * @class |
| 11 | 13 | * @augments wp.media.View |
| 12 | 14 | * @augments wp.Backbone.View |
| 13 | 15 | * @augments Backbone.View |
| | 16 | * |
| | 17 | * @access private |
| 14 | 18 | */ |
| 15 | 19 | Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ |
| 16 | 20 | tagName: 'ul', |
| … |
… |
Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{
|
| 20 | 24 | tabIndex: -1 |
| 21 | 25 | }, |
| 22 | 26 | |
| | 27 | /** |
| | 28 | * Binds events to the collection this view represents when adding or removing attachments |
| | 29 | * or resetting the entire collection. |
| | 30 | * |
| | 31 | * @summary Binds events to scrolling to trigger the scroll function. |
| | 32 | * |
| | 33 | * @constructs |
| | 34 | * @memberof wp.media.view |
| | 35 | * |
| | 36 | * @augments wp.media.View |
| | 37 | * @augments wp.Backbone.View |
| | 38 | * @augments Backbone.View |
| | 39 | * |
| | 40 | * @listens collection:add |
| | 41 | * @listens collection:remove |
| | 42 | * @listens collection:reset |
| | 43 | * @listens controller:library:selection:add |
| | 44 | * @listens scrollElement:scroll |
| | 45 | * @listens this:ready |
| | 46 | * @listens controller:open |
| | 47 | */ |
| 23 | 48 | initialize: function() { |
| 24 | 49 | this.el.id = _.uniqueId('__attachments-view-'); |
| 25 | 50 | |
| | 51 | /** |
| | 52 | * @param refreshSensitivity The time in milliseconds to throttle the scroll handler. |
| | 53 | * @param refreshThreshold The amount of pixels that should be scrolled before loading more attachments |
| | 54 | * from the server. |
| | 55 | * @param AttachmentView The view class to be used for models in the collection. |
| | 56 | * @param sortable A jQuery sortable options object ( http://api.jqueryui.com/sortable/ ). |
| | 57 | * @param resize A boolean indicating whether or not to listen to resize events. |
| | 58 | * @param idealColumnWidth The width in pixels which a column should have when calculating the |
| | 59 | * total number of columns. |
| | 60 | */ |
| 26 | 61 | _.defaults( this.options, { |
| 27 | 62 | refreshSensitivity: wp.media.isTouchDevice ? 300 : 200, |
| 28 | 63 | refreshThreshold: 3, |
| … |
… |
Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{
|
| 42 | 77 | }); |
| 43 | 78 | }, this ); |
| 44 | 79 | |
| | 80 | /* |
| | 81 | * Find the view to be removed, delete it and call the remove function to clear |
| | 82 | * any set event handlers. |
| | 83 | */ |
| 45 | 84 | this.collection.on( 'remove', function( attachment ) { |
| 46 | 85 | var view = this._viewsByCid[ attachment.cid ]; |
| 47 | 86 | delete this._viewsByCid[ attachment.cid ]; |
| … |
… |
Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{
|
| 69 | 108 | this.on( 'ready', this.bindEvents ); |
| 70 | 109 | this.controller.on( 'open', this.setColumns ); |
| 71 | 110 | |
| 72 | | // Call this.setColumns() after this view has been rendered in the DOM so |
| 73 | | // attachments get proper width applied. |
| | 111 | /* |
| | 112 | * Call this.setColumns() after this view has been rendered in the |
| | 113 | * DOM so attachments get proper width applied. |
| | 114 | */ |
| 74 | 115 | _.defer( this.setColumns, this ); |
| 75 | 116 | } |
| 76 | 117 | }, |
| 77 | 118 | |
| | 119 | /** |
| | 120 | * Listens to the resizeEvent on the window and adjusts the amount of columns accordingly. |
| | 121 | * First removes any existing event handlers to prevent duplicate listeners. |
| | 122 | * |
| | 123 | * @summary Listens to the resizeEvent on the window |
| | 124 | * |
| | 125 | * @listens window:resize |
| | 126 | * |
| | 127 | * @returns {void} |
| | 128 | */ |
| 78 | 129 | bindEvents: function() { |
| 79 | 130 | this.$window.off( this.resizeEvent ).on( this.resizeEvent, _.debounce( this.setColumns, 50 ) ); |
| 80 | 131 | }, |
| 81 | 132 | |
| | 133 | /** |
| | 134 | * Focuses the first item in the collection. |
| | 135 | * |
| | 136 | * @returns {void} |
| | 137 | */ |
| 82 | 138 | attachmentFocus: function() { |
| 83 | 139 | this.$( 'li:first' ).focus(); |
| 84 | 140 | }, |
| 85 | 141 | |
| | 142 | /** |
| | 143 | * Restores focus to the selected item in the collection. |
| | 144 | * |
| | 145 | * @returns {void} |
| | 146 | */ |
| 86 | 147 | restoreFocus: function() { |
| 87 | 148 | this.$( 'li.selected:first' ).focus(); |
| 88 | 149 | }, |
| 89 | 150 | |
| | 151 | /** |
| | 152 | * Event handler for arrow key presses. |
| | 153 | * Focuses the attachment in the direction of the used arrow key if it exists. |
| | 154 | * |
| | 155 | * @param {KeyboardEvent} event The keyboard event that triggered this function. |
| | 156 | * |
| | 157 | * @returns {void} |
| | 158 | */ |
| 90 | 159 | arrowEvent: function( event ) { |
| 91 | 160 | var attachments = this.$el.children( 'li' ), |
| 92 | 161 | perRow = this.columns, |
| … |
… |
Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{
|
| 97 | 166 | return; |
| 98 | 167 | } |
| 99 | 168 | |
| 100 | | // Left arrow |
| | 169 | // Left arrow = 37. |
| 101 | 170 | if ( 37 === event.keyCode ) { |
| 102 | 171 | if ( 0 === index ) { |
| 103 | 172 | return; |
| … |
… |
Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{
|
| 105 | 174 | attachments.eq( index - 1 ).focus(); |
| 106 | 175 | } |
| 107 | 176 | |
| 108 | | // Up arrow |
| | 177 | // Up arrow = 38. |
| 109 | 178 | if ( 38 === event.keyCode ) { |
| 110 | 179 | if ( 1 === row ) { |
| 111 | 180 | return; |
| … |
… |
Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{
|
| 113 | 182 | attachments.eq( index - perRow ).focus(); |
| 114 | 183 | } |
| 115 | 184 | |
| 116 | | // Right arrow |
| | 185 | // Right arrow = 39. |
| 117 | 186 | if ( 39 === event.keyCode ) { |
| 118 | 187 | if ( attachments.length === index ) { |
| 119 | 188 | return; |
| … |
… |
Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{
|
| 121 | 190 | attachments.eq( index + 1 ).focus(); |
| 122 | 191 | } |
| 123 | 192 | |
| 124 | | // Down arrow |
| | 193 | // Down arrow = 40. |
| 125 | 194 | if ( 40 === event.keyCode ) { |
| 126 | 195 | if ( Math.ceil( attachments.length / perRow ) === row ) { |
| 127 | 196 | return; |
| … |
… |
Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{
|
| 130 | 199 | } |
| 131 | 200 | }, |
| 132 | 201 | |
| | 202 | /** |
| | 203 | * Clears any set event handlers. |
| | 204 | * |
| | 205 | * @returns {void} |
| | 206 | */ |
| 133 | 207 | dispose: function() { |
| 134 | 208 | this.collection.props.off( null, null, this ); |
| 135 | 209 | if ( this.options.resize ) { |
| 136 | 210 | this.$window.off( this.resizeEvent ); |
| 137 | 211 | } |
| 138 | 212 | |
| 139 | | /** |
| 140 | | * call 'dispose' directly on the parent class |
| 141 | | */ |
| | 213 | // Call 'dispose' directly on the parent class. |
| 142 | 214 | View.prototype.dispose.apply( this, arguments ); |
| 143 | 215 | }, |
| 144 | 216 | |
| | 217 | /** |
| | 218 | * Calculates the amount of columns and sets it on the data-columns attribute |
| | 219 | * of .media-frame-content. |
| | 220 | * |
| | 221 | * @summary Calculates the amount of columns. |
| | 222 | * |
| | 223 | * @returns {void} |
| | 224 | */ |
| 145 | 225 | setColumns: function() { |
| 146 | 226 | var prev = this.columns, |
| 147 | 227 | width = this.$el.width(); |
| … |
… |
Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{
|
| 155 | 235 | } |
| 156 | 236 | }, |
| 157 | 237 | |
| | 238 | /** |
| | 239 | * Initializes jQuery sortable on the list if jQuery sortable exists and sortable has |
| | 240 | * been passed to the options. |
| | 241 | * |
| | 242 | * @summary Initializes jQuery sortable on the list. |
| | 243 | * |
| | 244 | * @fires collection:reset |
| | 245 | * |
| | 246 | * @returns {void} |
| | 247 | */ |
| 158 | 248 | initSortable: function() { |
| 159 | 249 | var collection = this.collection; |
| 160 | 250 | |
| … |
… |
Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{
|
| 166 | 256 | // If the `collection` has a `comparator`, disable sorting. |
| 167 | 257 | disabled: !! collection.comparator, |
| 168 | 258 | |
| 169 | | // Change the position of the attachment as soon as the |
| 170 | | // mouse pointer overlaps a thumbnail. |
| | 259 | // Change the position of the attachment as soon as the mouse pointer overlaps a thumbnail. |
| 171 | 260 | tolerance: 'pointer', |
| 172 | 261 | |
| 173 | 262 | // Record the initial `index` of the dragged model. |
| … |
… |
Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{
|
| 175 | 264 | ui.item.data('sortableIndexStart', ui.item.index()); |
| 176 | 265 | }, |
| 177 | 266 | |
| 178 | | // Update the model's index in the collection. |
| 179 | | // Do so silently, as the view is already accurate. |
| | 267 | /* |
| | 268 | * Update the model's index in the collection. |
| | 269 | * Do so silently, as the view is already accurate. |
| | 270 | */ |
| 180 | 271 | update: function( event, ui ) { |
| 181 | 272 | var model = collection.at( ui.item.data('sortableIndexStart') ), |
| 182 | 273 | comparator = collection.comparator; |
| … |
… |
Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{
|
| 200 | 291 | // Fire the `reset` event to ensure other collections sync. |
| 201 | 292 | collection.trigger( 'reset', collection ); |
| 202 | 293 | |
| 203 | | // If the collection is sorted by menu order, |
| 204 | | // update the menu order. |
| | 294 | // If the collection is sorted by menu order, update the menu order. |
| 205 | 295 | collection.saveMenuOrder(); |
| 206 | 296 | } |
| 207 | 297 | }, this.options.sortable ) ); |
| 208 | 298 | |
| 209 | | // If the `orderby` property is changed on the `collection`, |
| 210 | | // check to see if we have a `comparator`. If so, disable sorting. |
| | 299 | /* |
| | 300 | * If the `orderby` property is changed on the `collection`, |
| | 301 | * check to see if we have a `comparator`. If so, disable sorting. |
| | 302 | */ |
| 211 | 303 | collection.props.on( 'change:orderby', function() { |
| 212 | 304 | this.$el.sortable( 'option', 'disabled', !! collection.comparator ); |
| 213 | 305 | }, this ); |
| … |
… |
Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{
|
| 216 | 308 | this.refreshSortable(); |
| 217 | 309 | }, |
| 218 | 310 | |
| | 311 | /** |
| | 312 | * Disables jQuery sortable if collection has a comparator or collection.orderby equals menuOrder. |
| | 313 | * |
| | 314 | * @returns {void} |
| | 315 | */ |
| 219 | 316 | refreshSortable: function() { |
| 220 | 317 | if ( ! this.options.sortable || ! $.fn.sortable ) { |
| 221 | 318 | return; |
| 222 | 319 | } |
| 223 | 320 | |
| 224 | | // If the `collection` has a `comparator`, disable sorting. |
| 225 | 321 | var collection = this.collection, |
| 226 | 322 | orderby = collection.props.get('orderby'), |
| 227 | 323 | enabled = 'menuOrder' === orderby || ! collection.comparator; |
| … |
… |
Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{
|
| 230 | 326 | }, |
| 231 | 327 | |
| 232 | 328 | /** |
| | 329 | * Creates a new view for an attachment and adds it to _viewsByCid. |
| | 330 | * |
| 233 | 331 | * @param {wp.media.model.Attachment} attachment |
| 234 | | * @returns {wp.media.View} |
| | 332 | * |
| | 333 | * @returns {wp.media.View} The created view. |
| 235 | 334 | */ |
| 236 | 335 | createAttachmentView: function( attachment ) { |
| 237 | 336 | var view = new this.options.AttachmentView({ |
| … |
… |
Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{
|
| 244 | 343 | return this._viewsByCid[ attachment.cid ] = view; |
| 245 | 344 | }, |
| 246 | 345 | |
| | 346 | /** |
| | 347 | * Creates views for every attachment in collection if the collection is not empty, |
| | 348 | * otherwise clears all views and loads more attachments. |
| | 349 | * |
| | 350 | * @summary Creates views for every attachment in collection. |
| | 351 | * |
| | 352 | * @returns {void} |
| | 353 | */ |
| 247 | 354 | prepare: function() { |
| 248 | | // Create all of the Attachment views, and replace |
| 249 | | // the list in a single DOM operation. |
| 250 | 355 | if ( this.collection.length ) { |
| 251 | 356 | this.views.set( this.collection.map( this.createAttachmentView, this ) ); |
| 252 | | |
| 253 | | // If there are no elements, clear the views and load some. |
| 254 | 357 | } else { |
| 255 | 358 | this.views.unset(); |
| 256 | 359 | this.collection.more().done( this.scroll ); |
| 257 | 360 | } |
| 258 | 361 | }, |
| 259 | 362 | |
| | 363 | /** |
| | 364 | * Triggers the scroll function to check if we should query for additional attachments right away. |
| | 365 | * |
| | 366 | * @returns {void} |
| | 367 | */ |
| 260 | 368 | ready: function() { |
| 261 | | // Trigger the scroll event to check if we're within the |
| 262 | | // threshold to query for additional attachments. |
| 263 | 369 | this.scroll(); |
| 264 | 370 | }, |
| 265 | 371 | |
| | 372 | /** |
| | 373 | * Event handler for scroll events. |
| | 374 | * Shows the spinner if we're close to the bottom. |
| | 375 | * Loads more attachments from server if we're {refreshThreshold} times away from the bottom. |
| | 376 | * |
| | 377 | * @summary Event handler for scroll events. |
| | 378 | * |
| | 379 | * @returns {void} |
| | 380 | */ |
| 266 | 381 | scroll: function() { |
| 267 | 382 | var view = this, |
| 268 | 383 | el = this.options.scrollElement, |
| 269 | 384 | scrollTop = el.scrollTop, |
| 270 | 385 | toolbar; |
| 271 | 386 | |
| 272 | | // The scroll event occurs on the document, but the element |
| 273 | | // that should be checked is the document body. |
| | 387 | /* |
| | 388 | * The scroll event occurs on the document, but the element |
| | 389 | * that should be checked is the document body. |
| | 390 | */ |
| 274 | 391 | if ( el === document ) { |
| 275 | 392 | el = document.body; |
| 276 | 393 | scrollTop = $(document).scrollTop(); |