From 2c66a7db75dc8899b9e0a7e7ca75c3ba5f7537d6 Mon Sep 17 00:00:00 2001 From: Anton Timmermans Date: Thu, 21 Dec 2017 14:26:17 +0000 Subject: [PATCH] Docs: Improve JSDoc for `media/views/attachments.js`. Props maartenleenders, herregroen, jipmoors, ireneyoast. Fixes #42832. git-svn-id: https://develop.svn.wordpress.org/trunk@42415 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/js/media-views.js | 210 +++++++++++++++--- src/wp-includes/js/media/views/attachments.js | 210 +++++++++++++++--- 2 files changed, 346 insertions(+), 74 deletions(-) diff --git a/src/wp-includes/js/media-views.js b/src/wp-includes/js/media-views.js index 32bdcbd455..c9c3a8af3e 100644 --- a/src/wp-includes/js/media-views.js +++ b/src/wp-includes/js/media-views.js @@ -6620,16 +6620,6 @@ var View = wp.media.View, $ = jQuery, Attachments; -/** - * wp.media.view.Attachments - * - * @memberOf wp.media.view - * - * @class - * @augments wp.media.View - * @augments wp.Backbone.View - * @augments Backbone.View - */ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ tagName: 'ul', className: 'attachments', @@ -6638,9 +6628,44 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ tabIndex: -1 }, + /** + * Represents the overview of attachments in the Media Library. + * + * The constructor binds events to the collection this view represents when + * adding or removing attachments or resetting the entire collection. + * + * @since 3.5.0 + * + * @constructs + * @memberof wp.media.view + * + * @augments wp.media.View + * + * @listens collection:add + * @listens collection:remove + * @listens collection:reset + * @listens controller:library:selection:add + * @listens scrollElement:scroll + * @listens this:ready + * @listens controller:open + */ initialize: function() { this.el.id = _.uniqueId('__attachments-view-'); + /** + * @param refreshSensitivity The time in milliseconds to throttle the scroll + * handler. + * @param refreshThreshold The amount of pixels that should be scrolled before + * loading more attachments from the server. + * @param AttachmentView The view class to be used for models in the + * collection. + * @param sortable A jQuery sortable options object + * ( http://api.jqueryui.com/sortable/ ). + * @param resize A boolean indicating whether or not to listen to + * resize events. + * @param idealColumnWidth The width in pixels which a column should have when + * calculating the total number of columns. + */ _.defaults( this.options, { refreshSensitivity: wp.media.isTouchDevice ? 300 : 200, refreshThreshold: 3, @@ -6660,6 +6685,10 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ }); }, this ); + /* + * Find the view to be removed, delete it and call the remove function to clear + * any set event handlers. + */ this.collection.on( 'remove', function( attachment ) { var view = this._viewsByCid[ attachment.cid ]; delete this._viewsByCid[ attachment.cid ]; @@ -6687,24 +6716,63 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ this.on( 'ready', this.bindEvents ); this.controller.on( 'open', this.setColumns ); - // Call this.setColumns() after this view has been rendered in the DOM so - // attachments get proper width applied. + /* + * Call this.setColumns() after this view has been rendered in the + * DOM so attachments get proper width applied. + */ _.defer( this.setColumns, this ); } }, + /** + * Listens to the resizeEvent on the window. + * + * Adjusts the amount of columns accordingly. First removes any existing event + * handlers to prevent duplicate listeners. + * + * @since 4.0.0 + * + * @listens window:resize + * + * @returns {void} + */ bindEvents: function() { this.$window.off( this.resizeEvent ).on( this.resizeEvent, _.debounce( this.setColumns, 50 ) ); }, + /** + * Focuses the first item in the collection. + * + * @since 4.0.0 + * + * @returns {void} + */ attachmentFocus: function() { this.$( 'li:first' ).focus(); }, + /** + * Restores focus to the selected item in the collection. + * + * @since 4.0.0 + * + * @returns {void} + */ restoreFocus: function() { this.$( 'li.selected:first' ).focus(); }, + /** + * Handles events for arrow key presses. + * + * Focuses the attachment in the direction of the used arrow key if it exists. + * + * @since 4.0.0 + * + * @param {KeyboardEvent} event The keyboard event that triggered this function. + * + * @returns {void} + */ arrowEvent: function( event ) { var attachments = this.$el.children( 'li' ), perRow = this.columns, @@ -6715,7 +6783,7 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ return; } - // Left arrow + // Left arrow = 37. if ( 37 === event.keyCode ) { if ( 0 === index ) { return; @@ -6723,7 +6791,7 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ attachments.eq( index - 1 ).focus(); } - // Up arrow + // Up arrow = 38. if ( 38 === event.keyCode ) { if ( 1 === row ) { return; @@ -6731,7 +6799,7 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ attachments.eq( index - perRow ).focus(); } - // Right arrow + // Right arrow = 39. if ( 39 === event.keyCode ) { if ( attachments.length === index ) { return; @@ -6739,7 +6807,7 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ attachments.eq( index + 1 ).focus(); } - // Down arrow + // Down arrow = 40. if ( 40 === event.keyCode ) { if ( Math.ceil( attachments.length / perRow ) === row ) { return; @@ -6748,18 +6816,33 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ } }, + /** + * Clears any set event handlers. + * + * @since 3.5.0 + * + * @returns {void} + */ dispose: function() { this.collection.props.off( null, null, this ); if ( this.options.resize ) { this.$window.off( this.resizeEvent ); } - /** - * call 'dispose' directly on the parent class - */ + // Call 'dispose' directly on the parent class. View.prototype.dispose.apply( this, arguments ); }, + /** + * Calculates the amount of columns. + * + * Calculates the amount of columns and sets it on the data-columns attribute + * of .media-frame-content. + * + * @since 4.0.0 + * + * @returns {void} + */ setColumns: function() { var prev = this.columns, width = this.$el.width(); @@ -6773,6 +6856,18 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ } }, + /** + * Initializes jQuery sortable on the attachment list. + * + * Fails gracefully if jQuery sortable doesn't exist or isn't passed in the + * options. + * + * @since 3.5.0 + * + * @fires collection:reset + * + * @returns {void} + */ initSortable: function() { var collection = this.collection; @@ -6784,8 +6879,10 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ // If the `collection` has a `comparator`, disable sorting. disabled: !! collection.comparator, - // Change the position of the attachment as soon as the - // mouse pointer overlaps a thumbnail. + /* + * Change the position of the attachment as soon as the mouse pointer overlaps a + * thumbnail. + */ tolerance: 'pointer', // Record the initial `index` of the dragged model. @@ -6793,8 +6890,10 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ ui.item.data('sortableIndexStart', ui.item.index()); }, - // Update the model's index in the collection. - // Do so silently, as the view is already accurate. + /* + * Update the model's index in the collection. Do so silently, as the view + * is already accurate. + */ update: function( event, ui ) { var model = collection.at( ui.item.data('sortableIndexStart') ), comparator = collection.comparator; @@ -6818,14 +6917,15 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ // Fire the `reset` event to ensure other collections sync. collection.trigger( 'reset', collection ); - // If the collection is sorted by menu order, - // update the menu order. + // If the collection is sorted by menu order, update the menu order. collection.saveMenuOrder(); } }, this.options.sortable ) ); - // If the `orderby` property is changed on the `collection`, - // check to see if we have a `comparator`. If so, disable sorting. + /* + * If the `orderby` property is changed on the `collection`, check to see if we + * have a `comparator`. If so, disable sorting. + */ collection.props.on( 'change:orderby', function() { this.$el.sortable( 'option', 'disabled', !! collection.comparator ); }, this ); @@ -6834,12 +6934,19 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ this.refreshSortable(); }, + /** + * Disables jQuery sortable if collection has a comparator or collection.orderby + * equals menuOrder. + * + * @since 3.5.0 + * + * @returns {void} + */ refreshSortable: function() { if ( ! this.options.sortable || ! $.fn.sortable ) { return; } - // If the `collection` has a `comparator`, disable sorting. var collection = this.collection, orderby = collection.props.get('orderby'), enabled = 'menuOrder' === orderby || ! collection.comparator; @@ -6848,8 +6955,13 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ }, /** + * Creates a new view for an attachment and adds it to _viewsByCid. + * + * @since 3.5.0 + * * @param {wp.media.model.Attachment} attachment - * @returns {wp.media.View} + * + * @returns {wp.media.View} The created view. */ createAttachmentView: function( attachment ) { var view = new this.options.AttachmentView({ @@ -6862,33 +6974,57 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ return this._viewsByCid[ attachment.cid ] = view; }, + /** + * Prepares view for display. + * + * Creates views for every attachment in collection if the collection is not + * empty, otherwise clears all views and loads more attachments. + * + * @since 3.5.0 + * + * @returns {void} + */ prepare: function() { - // Create all of the Attachment views, and replace - // the list in a single DOM operation. if ( this.collection.length ) { this.views.set( this.collection.map( this.createAttachmentView, this ) ); - - // If there are no elements, clear the views and load some. } else { this.views.unset(); this.collection.more().done( this.scroll ); } }, + /** + * Triggers the scroll function to check if we should query for additional + * attachments right away. + * + * @since 3.5.0 + * + * @returns {void} + */ ready: function() { - // Trigger the scroll event to check if we're within the - // threshold to query for additional attachments. this.scroll(); }, + /** + * Handles scroll events. + * + * Shows the spinner if we're close to the bottom. Loads more attachments from + * server if we're {refreshThreshold} times away from the bottom. + * + * @since 3.5.0 + * + * @returns {void} + */ scroll: function() { var view = this, el = this.options.scrollElement, scrollTop = el.scrollTop, toolbar; - // The scroll event occurs on the document, but the element - // that should be checked is the document body. + /* + * The scroll event occurs on the document, but the element that should be + * checked is the document body. + */ if ( el === document ) { el = document.body; scrollTop = $(document).scrollTop(); diff --git a/src/wp-includes/js/media/views/attachments.js b/src/wp-includes/js/media/views/attachments.js index 73edcec8f4..90a5e116fd 100644 --- a/src/wp-includes/js/media/views/attachments.js +++ b/src/wp-includes/js/media/views/attachments.js @@ -2,16 +2,6 @@ var View = wp.media.View, $ = jQuery, Attachments; -/** - * wp.media.view.Attachments - * - * @memberOf wp.media.view - * - * @class - * @augments wp.media.View - * @augments wp.Backbone.View - * @augments Backbone.View - */ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ tagName: 'ul', className: 'attachments', @@ -20,9 +10,44 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ tabIndex: -1 }, + /** + * Represents the overview of attachments in the Media Library. + * + * The constructor binds events to the collection this view represents when + * adding or removing attachments or resetting the entire collection. + * + * @since 3.5.0 + * + * @constructs + * @memberof wp.media.view + * + * @augments wp.media.View + * + * @listens collection:add + * @listens collection:remove + * @listens collection:reset + * @listens controller:library:selection:add + * @listens scrollElement:scroll + * @listens this:ready + * @listens controller:open + */ initialize: function() { this.el.id = _.uniqueId('__attachments-view-'); + /** + * @param refreshSensitivity The time in milliseconds to throttle the scroll + * handler. + * @param refreshThreshold The amount of pixels that should be scrolled before + * loading more attachments from the server. + * @param AttachmentView The view class to be used for models in the + * collection. + * @param sortable A jQuery sortable options object + * ( http://api.jqueryui.com/sortable/ ). + * @param resize A boolean indicating whether or not to listen to + * resize events. + * @param idealColumnWidth The width in pixels which a column should have when + * calculating the total number of columns. + */ _.defaults( this.options, { refreshSensitivity: wp.media.isTouchDevice ? 300 : 200, refreshThreshold: 3, @@ -42,6 +67,10 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ }); }, this ); + /* + * Find the view to be removed, delete it and call the remove function to clear + * any set event handlers. + */ this.collection.on( 'remove', function( attachment ) { var view = this._viewsByCid[ attachment.cid ]; delete this._viewsByCid[ attachment.cid ]; @@ -69,24 +98,63 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ this.on( 'ready', this.bindEvents ); this.controller.on( 'open', this.setColumns ); - // Call this.setColumns() after this view has been rendered in the DOM so - // attachments get proper width applied. + /* + * Call this.setColumns() after this view has been rendered in the + * DOM so attachments get proper width applied. + */ _.defer( this.setColumns, this ); } }, + /** + * Listens to the resizeEvent on the window. + * + * Adjusts the amount of columns accordingly. First removes any existing event + * handlers to prevent duplicate listeners. + * + * @since 4.0.0 + * + * @listens window:resize + * + * @returns {void} + */ bindEvents: function() { this.$window.off( this.resizeEvent ).on( this.resizeEvent, _.debounce( this.setColumns, 50 ) ); }, + /** + * Focuses the first item in the collection. + * + * @since 4.0.0 + * + * @returns {void} + */ attachmentFocus: function() { this.$( 'li:first' ).focus(); }, + /** + * Restores focus to the selected item in the collection. + * + * @since 4.0.0 + * + * @returns {void} + */ restoreFocus: function() { this.$( 'li.selected:first' ).focus(); }, + /** + * Handles events for arrow key presses. + * + * Focuses the attachment in the direction of the used arrow key if it exists. + * + * @since 4.0.0 + * + * @param {KeyboardEvent} event The keyboard event that triggered this function. + * + * @returns {void} + */ arrowEvent: function( event ) { var attachments = this.$el.children( 'li' ), perRow = this.columns, @@ -97,7 +165,7 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ return; } - // Left arrow + // Left arrow = 37. if ( 37 === event.keyCode ) { if ( 0 === index ) { return; @@ -105,7 +173,7 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ attachments.eq( index - 1 ).focus(); } - // Up arrow + // Up arrow = 38. if ( 38 === event.keyCode ) { if ( 1 === row ) { return; @@ -113,7 +181,7 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ attachments.eq( index - perRow ).focus(); } - // Right arrow + // Right arrow = 39. if ( 39 === event.keyCode ) { if ( attachments.length === index ) { return; @@ -121,7 +189,7 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ attachments.eq( index + 1 ).focus(); } - // Down arrow + // Down arrow = 40. if ( 40 === event.keyCode ) { if ( Math.ceil( attachments.length / perRow ) === row ) { return; @@ -130,18 +198,33 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ } }, + /** + * Clears any set event handlers. + * + * @since 3.5.0 + * + * @returns {void} + */ dispose: function() { this.collection.props.off( null, null, this ); if ( this.options.resize ) { this.$window.off( this.resizeEvent ); } - /** - * call 'dispose' directly on the parent class - */ + // Call 'dispose' directly on the parent class. View.prototype.dispose.apply( this, arguments ); }, + /** + * Calculates the amount of columns. + * + * Calculates the amount of columns and sets it on the data-columns attribute + * of .media-frame-content. + * + * @since 4.0.0 + * + * @returns {void} + */ setColumns: function() { var prev = this.columns, width = this.$el.width(); @@ -155,6 +238,18 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ } }, + /** + * Initializes jQuery sortable on the attachment list. + * + * Fails gracefully if jQuery sortable doesn't exist or isn't passed in the + * options. + * + * @since 3.5.0 + * + * @fires collection:reset + * + * @returns {void} + */ initSortable: function() { var collection = this.collection; @@ -166,8 +261,10 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ // If the `collection` has a `comparator`, disable sorting. disabled: !! collection.comparator, - // Change the position of the attachment as soon as the - // mouse pointer overlaps a thumbnail. + /* + * Change the position of the attachment as soon as the mouse pointer overlaps a + * thumbnail. + */ tolerance: 'pointer', // Record the initial `index` of the dragged model. @@ -175,8 +272,10 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ ui.item.data('sortableIndexStart', ui.item.index()); }, - // Update the model's index in the collection. - // Do so silently, as the view is already accurate. + /* + * Update the model's index in the collection. Do so silently, as the view + * is already accurate. + */ update: function( event, ui ) { var model = collection.at( ui.item.data('sortableIndexStart') ), comparator = collection.comparator; @@ -200,14 +299,15 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ // Fire the `reset` event to ensure other collections sync. collection.trigger( 'reset', collection ); - // If the collection is sorted by menu order, - // update the menu order. + // If the collection is sorted by menu order, update the menu order. collection.saveMenuOrder(); } }, this.options.sortable ) ); - // If the `orderby` property is changed on the `collection`, - // check to see if we have a `comparator`. If so, disable sorting. + /* + * If the `orderby` property is changed on the `collection`, check to see if we + * have a `comparator`. If so, disable sorting. + */ collection.props.on( 'change:orderby', function() { this.$el.sortable( 'option', 'disabled', !! collection.comparator ); }, this ); @@ -216,12 +316,19 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ this.refreshSortable(); }, + /** + * Disables jQuery sortable if collection has a comparator or collection.orderby + * equals menuOrder. + * + * @since 3.5.0 + * + * @returns {void} + */ refreshSortable: function() { if ( ! this.options.sortable || ! $.fn.sortable ) { return; } - // If the `collection` has a `comparator`, disable sorting. var collection = this.collection, orderby = collection.props.get('orderby'), enabled = 'menuOrder' === orderby || ! collection.comparator; @@ -230,8 +337,13 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ }, /** + * Creates a new view for an attachment and adds it to _viewsByCid. + * + * @since 3.5.0 + * * @param {wp.media.model.Attachment} attachment - * @returns {wp.media.View} + * + * @returns {wp.media.View} The created view. */ createAttachmentView: function( attachment ) { var view = new this.options.AttachmentView({ @@ -244,33 +356,57 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ return this._viewsByCid[ attachment.cid ] = view; }, + /** + * Prepares view for display. + * + * Creates views for every attachment in collection if the collection is not + * empty, otherwise clears all views and loads more attachments. + * + * @since 3.5.0 + * + * @returns {void} + */ prepare: function() { - // Create all of the Attachment views, and replace - // the list in a single DOM operation. if ( this.collection.length ) { this.views.set( this.collection.map( this.createAttachmentView, this ) ); - - // If there are no elements, clear the views and load some. } else { this.views.unset(); this.collection.more().done( this.scroll ); } }, + /** + * Triggers the scroll function to check if we should query for additional + * attachments right away. + * + * @since 3.5.0 + * + * @returns {void} + */ ready: function() { - // Trigger the scroll event to check if we're within the - // threshold to query for additional attachments. this.scroll(); }, + /** + * Handles scroll events. + * + * Shows the spinner if we're close to the bottom. Loads more attachments from + * server if we're {refreshThreshold} times away from the bottom. + * + * @since 3.5.0 + * + * @returns {void} + */ scroll: function() { var view = this, el = this.options.scrollElement, scrollTop = el.scrollTop, toolbar; - // The scroll event occurs on the document, but the element - // that should be checked is the document body. + /* + * The scroll event occurs on the document, but the element that should be + * checked is the document body. + */ if ( el === document ) { el = document.body; scrollTop = $(document).scrollTop();