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.

Built from https://develop.svn.wordpress.org/trunk@42113


git-svn-id: http://core.svn.wordpress.org/trunk@41942 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Weston Ruter 2017-11-03 00:59:47 +00:00
parent 83c29a4d08
commit d0608c5585
3 changed files with 46 additions and 20 deletions

View File

@ -2549,11 +2549,24 @@
* @returns {void} * @returns {void}
*/ */
showDetails: function ( theme, callback ) { showDetails: function ( theme, callback ) {
var section = this; var section = this, panel = api.panel( 'themes' );
section.currentTheme = theme.id; section.currentTheme = theme.id;
section.overlay.html( section.template( theme ) ) section.overlay.html( section.template( theme ) )
.fadeIn( 'fast' ) .fadeIn( 'fast' )
.focus(); .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.$body.addClass( 'modal-open' );
section.containFocus( section.overlay ); section.containFocus( section.overlay );
section.updateLimits(); section.updateLimits();
@ -3030,6 +3043,21 @@
api.Panel.prototype.initialize.call( panel, id, options ); 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. * Attach events.
* *
@ -3052,7 +3080,7 @@
} }
function toggleDisabledNotifications() { function toggleDisabledNotifications() {
if ( 'publish' === api.state( 'selectedChangesetStatus' ).get() ) { if ( panel.canSwitchTheme() ) {
panel.notifications.remove( 'theme_switch_unavailable' ); panel.notifications.remove( 'theme_switch_unavailable' );
} else { } else {
panel.notifications.add( new api.Notification( 'theme_switch_unavailable', { panel.notifications.add( new api.Notification( 'theme_switch_unavailable', {
@ -3063,6 +3091,7 @@
} }
toggleDisabledNotifications(); toggleDisabledNotifications();
api.state( 'selectedChangesetStatus' ).bind( toggleDisabledNotifications ); api.state( 'selectedChangesetStatus' ).bind( toggleDisabledNotifications );
api.state( 'changesetStatus' ).bind( toggleDisabledNotifications );
// Collapse panel to customize the current theme. // Collapse panel to customize the current theme.
panel.contentContainer.on( 'click', '.customize-theme', function() { 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. // 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({ deferred.reject({
errorCode: 'theme_switch_unavailable' errorCode: 'theme_switch_unavailable'
}); });
@ -3266,10 +3295,10 @@
* @returns {jQuery.promise} Promise. * @returns {jQuery.promise} Promise.
*/ */
loadThemePreview: function( themeId ) { 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. // 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(); return deferred.reject().promise();
} }
@ -5089,25 +5118,23 @@
* @since 4.2.0 * @since 4.2.0
*/ */
ready: function() { ready: function() {
var control = this; var control = this, panel = api.panel( 'themes' );
function disableSwitchButtons() { 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. // Temporary special function since supplying SFTP credentials does not work yet. See #42184.
function disableInstallButtons() { function disableInstallButtons() {
return disableSwitchButtons() || true === api.settings.theme._filesystemCredentialsNeeded; return disableSwitchButtons() || true === api.settings.theme._filesystemCredentialsNeeded;
} }
function updateButtons( container ) { function updateButtons() {
var _container = container || control.container; control.container.find( 'button.preview, button.preview-theme' ).toggleClass( 'disabled', disableSwitchButtons() );
_container.find( 'button.preview, button.preview-theme' ).toggleClass( 'disabled', disableSwitchButtons() ); control.container.find( 'button.theme-install' ).toggleClass( 'disabled', disableInstallButtons() );
_container.find( 'button.theme-install' ).toggleClass( 'disabled', disableInstallButtons() );
} }
api.state( 'selectedChangesetStatus' ).bind( function() { api.state( 'selectedChangesetStatus' ).bind( updateButtons );
updateButtons(); api.state( 'changesetStatus' ).bind( updateButtons );
});
updateButtons(); updateButtons();
control.container.on( 'touchmove', '.theme', function() { control.container.on( 'touchmove', '.theme', function() {
@ -5134,7 +5161,6 @@
event.preventDefault(); // Keep this AFTER the key filter above event.preventDefault(); // Keep this AFTER the key filter above
section = api.section( control.section() ); section = api.section( control.section() );
section.showDetails( control.params.theme, function() { 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. // Temporary special function since supplying SFTP credentials does not work yet. See #42184.
if ( api.settings.theme._filesystemCredentialsNeeded ) { if ( api.settings.theme._filesystemCredentialsNeeded ) {

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,7 @@
* *
* @global string $wp_version * @global string $wp_version
*/ */
$wp_version = '4.9-RC1-42112'; $wp_version = '4.9-RC1-42113';
/** /**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.