From adc6017db3ee88c72c726f43b45d6716f72dbbe3 Mon Sep 17 00:00:00 2001 From: Khokan Sardar Date: Fri, 31 Jul 2026 22:51:51 +0530 Subject: [PATCH 1/3] Media: Add a checkbox to toggle infinite scrolling in the media modal. Infinite scrolling of the attachments list can now be turned on and off at the point of use, from a checkbox rendered before the list of media items in both the media modal and the Media Library grid view. The checkbox reflects the value resolved by `wp_enqueue_media()` and overrides it for the current view only, so the `media_library_infinite_scrolling` filter and the "Infinite Scrolling" user profile option still determine the initial state. Turning the checkbox off reveals the "Load more" button and stops the scroll handler from requesting more attachments; turning it back on hides the button and resumes loading on scroll. To make room for the checkbox before the list, the attachments wrapper is now the positioned, scrolling region in both modes, rather than only when the "Load more" button is present. Fixes #65775. --- src/js/media/views/attachments.js | 15 ++-- src/js/media/views/attachments/browser.js | 90 ++++++++++++++++++++--- src/wp-admin/css/media.css | 6 +- src/wp-includes/css/media-views.css | 21 +++++- 4 files changed, 110 insertions(+), 22 deletions(-) diff --git a/src/js/media/views/attachments.js b/src/js/media/views/attachments.js index b2e91624cb159..6ca793c51e904 100644 --- a/src/js/media/views/attachments.js +++ b/src/js/media/views/attachments.js @@ -90,13 +90,11 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ this.controller.on( 'library:selection:add', this.attachmentFocus, this ); - if ( this.options.infiniteScrolling ) { - // Throttle the scroll handler and bind this. - this.scroll = _.chain( this.scroll ).bind( this ).throttle( this.options.refreshSensitivity ).value(); + // Throttle the scroll handler and bind this. + this.scroll = _.chain( this.scroll ).bind( this ).throttle( this.options.refreshSensitivity ).value(); - this.options.scrollElement = this.options.scrollElement || this.el; - $( this.options.scrollElement ).on( 'scroll', this.scroll ); - } + this.options.scrollElement = this.options.scrollElement || this.el; + $( this.options.scrollElement ).on( 'scroll', this.scroll ); this.initSortable(); @@ -422,6 +420,7 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ * server if we're {refreshThreshold} times away from the bottom. * * @since 3.5.0 + * @since 7.1.0 Bails out when infinite scrolling is disabled. * * @return {void} */ @@ -431,6 +430,10 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ scrollTop = el.scrollTop, toolbar; + if ( ! this.options.infiniteScrolling ) { + return; + } + /* * The scroll event occurs on the document, but the element that should be * checked is the document body. diff --git a/src/js/media/views/attachments/browser.js b/src/js/media/views/attachments/browser.js index 5533110d815f9..c75eab20e73f9 100644 --- a/src/js/media/views/attachments/browser.js +++ b/src/js/media/views/attachments/browser.js @@ -43,6 +43,8 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro AttachmentView: wp.media.view.Attachment.Library }); + this.infiniteScrolling = !! infiniteScrolling; + this.controller.on( 'toggle:upload:attachment', this.toggleUploader, this ); this.controller.on( 'edit:selection', this.editSelection ); @@ -77,7 +79,7 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro // Create the attachments wrapper view. this.createAttachmentsWrapperView(); - if ( ! infiniteScrolling ) { + if ( ! this.infiniteScrolling ) { this.$el.addClass( 'has-load-more' ); this.createLoadMoreView(); } @@ -89,7 +91,7 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro this.updateContent(); - if ( ! infiniteScrolling ) { + if ( ! this.infiniteScrolling ) { this.updateLoadMoreView(); } @@ -102,10 +104,7 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro } this.collection.on( 'add remove reset', this.updateContent, this ); - - if ( ! infiniteScrolling ) { - this.collection.on( 'add remove reset', this.updateLoadMoreView, this ); - } + this.collection.on( 'add remove reset', this.updateLoadMoreView, this ); // The non-cached or cached attachments query has completed. this.collection.on( 'attachments:received', this.announceSearchResults, this ); @@ -125,7 +124,7 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro /* translators: Accessibility text. %d: Number of attachments found in a search. */ mediaFoundHasMoreResultsMessage = __( 'Number of media items displayed: %d. Click load more for more results.' ); - if ( infiniteScrolling ) { + if ( this.infiniteScrolling ) { /* translators: Accessibility text. %d: Number of attachments found in a search. */ mediaFoundHasMoreResultsMessage = __( 'Number of media items displayed: %d. Scroll the page for more results.' ); } @@ -472,11 +471,78 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro className: 'attachments-wrapper' } ); - // Create the list of attachments. this.views.add( this.attachmentsWrapper ); + + // Place the infinite scrolling toggle before the list of attachments. + this.createInfiniteScrollingToggle(); + + // Create the list of attachments. this.createAttachments(); }, + /** + * Creates the checkbox that turns infinite scrolling on and off. + * + * @since 7.1.0 + * + * @return {void} + */ + createInfiniteScrollingToggle: function() { + var view = this, + id = _.uniqueId( 'media-infinite-scrolling-' ), + checkbox = $( '', { + type: 'checkbox', + id: id, + checked: this.infiniteScrolling + } ), + label = $( '