From c7cb694732b60c2c149cea66b9c971d509639c92 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 3 Nov 2017 00:58:25 +0000 Subject: [PATCH] Customize: Make sure theme switch blocking in the Customizer is consistently applied when changeset is drafted/scheduled. * Consider both `selectedChangesetStatus` and `changesetStatus` states when deciding to disable. * Factor out common logic into `canSwitchTheme` function on `ThemesPanel`. * Keep Live Preview and Install buttons disabled in Themes controls and detail overlays when appropriate. Props westonruter, dlh. Amends [41788]. See #42126, #37661, #39896. Fixes #42406. git-svn-id: https://develop.svn.wordpress.org/trunk@42113 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/js/customize-controls.js | 56 ++++++++++++++++++++------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js index 7fb87bc88e..fbb8f42959 100644 --- a/src/wp-admin/js/customize-controls.js +++ b/src/wp-admin/js/customize-controls.js @@ -2549,11 +2549,24 @@ * @returns {void} */ showDetails: function ( theme, callback ) { - var section = this; + var section = this, panel = api.panel( 'themes' ); section.currentTheme = theme.id; section.overlay.html( section.template( theme ) ) .fadeIn( 'fast' ) .focus(); + + function disableSwitchButtons() { + return ! panel.canSwitchTheme( theme.id ); + } + + // Temporary special function since supplying SFTP credentials does not work yet. See #42184. + function disableInstallButtons() { + return disableSwitchButtons() || true === api.settings.theme._filesystemCredentialsNeeded; + } + + section.overlay.find( 'button.preview, button.preview-theme' ).toggleClass( 'disabled', disableSwitchButtons() ); + section.overlay.find( 'button.theme-install' ).toggleClass( 'disabled', disableInstallButtons() ); + section.$body.addClass( 'modal-open' ); section.containFocus( section.overlay ); section.updateLimits(); @@ -3030,6 +3043,21 @@ api.Panel.prototype.initialize.call( panel, id, options ); }, + /** + * Determine whether a given theme can be switched to, or in general. + * + * @since 4.9.0 + * + * @param {string} [slug] - Theme slug. + * @returns {boolean} Whether the theme can be switched to. + */ + canSwitchTheme: function canSwitchTheme( slug ) { + if ( slug && slug === api.settings.theme.stylesheet ) { + return true; + } + return 'publish' === api.state( 'selectedChangesetStatus' ).get() && ( '' === api.state( 'changesetStatus' ).get() || 'auto-draft' === api.state( 'changesetStatus' ).get() ); + }, + /** * Attach events. * @@ -3052,7 +3080,7 @@ } function toggleDisabledNotifications() { - if ( 'publish' === api.state( 'selectedChangesetStatus' ).get() ) { + if ( panel.canSwitchTheme() ) { panel.notifications.remove( 'theme_switch_unavailable' ); } else { panel.notifications.add( new api.Notification( 'theme_switch_unavailable', { @@ -3063,6 +3091,7 @@ } toggleDisabledNotifications(); api.state( 'selectedChangesetStatus' ).bind( toggleDisabledNotifications ); + api.state( 'changesetStatus' ).bind( toggleDisabledNotifications ); // Collapse panel to customize the current theme. panel.contentContainer.on( 'click', '.customize-theme', function() { @@ -3173,7 +3202,7 @@ } // Prevent loading a non-active theme preview when there is a drafted/scheduled changeset. - if ( 'publish' !== api.state( 'selectedChangesetStatus' ).get() && slug !== api.settings.theme.stylesheet ) { + if ( panel.canSwitchTheme( slug ) ) { deferred.reject({ errorCode: 'theme_switch_unavailable' }); @@ -3266,10 +3295,10 @@ * @returns {jQuery.promise} Promise. */ loadThemePreview: function( themeId ) { - var deferred = $.Deferred(), onceProcessingComplete, urlParser, queryParams; + var panel = this, deferred = $.Deferred(), onceProcessingComplete, urlParser, queryParams; // Prevent loading a non-active theme preview when there is a drafted/scheduled changeset. - if ( 'publish' !== api.state( 'selectedChangesetStatus' ).get() && themeId !== api.settings.theme.stylesheet ) { + if ( ! panel.canSwitchTheme( themeId ) ) { return deferred.reject().promise(); } @@ -5089,25 +5118,23 @@ * @since 4.2.0 */ ready: function() { - var control = this; + var control = this, panel = api.panel( 'themes' ); function disableSwitchButtons() { - return 'publish' !== api.state( 'selectedChangesetStatus' ).get() && control.params.theme.id !== api.settings.theme.stylesheet; + return ! panel.canSwitchTheme( control.params.theme.id ); } // Temporary special function since supplying SFTP credentials does not work yet. See #42184. function disableInstallButtons() { return disableSwitchButtons() || true === api.settings.theme._filesystemCredentialsNeeded; } - function updateButtons( container ) { - var _container = container || control.container; - _container.find( 'button.preview, button.preview-theme' ).toggleClass( 'disabled', disableSwitchButtons() ); - _container.find( 'button.theme-install' ).toggleClass( 'disabled', disableInstallButtons() ); + function updateButtons() { + control.container.find( 'button.preview, button.preview-theme' ).toggleClass( 'disabled', disableSwitchButtons() ); + control.container.find( 'button.theme-install' ).toggleClass( 'disabled', disableInstallButtons() ); } - api.state( 'selectedChangesetStatus' ).bind( function() { - updateButtons(); - }); + api.state( 'selectedChangesetStatus' ).bind( updateButtons ); + api.state( 'changesetStatus' ).bind( updateButtons ); updateButtons(); control.container.on( 'touchmove', '.theme', function() { @@ -5134,7 +5161,6 @@ event.preventDefault(); // Keep this AFTER the key filter above section = api.section( control.section() ); section.showDetails( control.params.theme, function() { - updateButtons( section.overlay.find( '.theme-actions' ) ); // Temporary special function since supplying SFTP credentials does not work yet. See #42184. if ( api.settings.theme._filesystemCredentialsNeeded ) {