Make WordPress Core

Changeset 41788


Ignore:
Timestamp:
10/07/2017 05:59:45 AM (7 years ago)
Author:
westonruter
Message:

Customize: Fix confusion related to visibility of Themes panel with drafted/scheduled changesets.

  • Prevent autoloading an existing draft/future changeset when theme not active.
  • Add missing notifications container to Themes panel.
  • Remove deactivation of themes panel when selected status is not publish.
  • Show notification in Themes panel when themes cannot be previewed and disable preview buttons.
  • Reject installTheme call when theme preview not available.
  • Return promise from installTheme and eliminate use of global events in favor of promises.

Props westonruter, melchoyce, zoonini.
See #37661, #39896.
Fixes #42126.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/js/customize-controls.js

    r41778 r41788  
    28022802         */
    28032803        attachEvents: function() {
    2804             var panel = this;
     2804            var panel = this, toggleDisabledNotification;
    28052805
    28062806            // Attach regular panel events.
    28072807            api.Panel.prototype.attachEvents.apply( panel );
     2808
     2809            toggleDisabledNotification = function() {
     2810                if ( 'publish' === api.state( 'selectedChangesetStatus' ).get() ) {
     2811                    panel.notifications.remove( 'theme_switch_unavailable' );
     2812                } else {
     2813                    panel.notifications.add( new api.Notification( 'theme_switch_unavailable', {
     2814                        message: api.l10n.themePreviewUnavailable,
     2815                        type: 'warning'
     2816                    } ) );
     2817                }
     2818            };
     2819            toggleDisabledNotification();
     2820            api.state( 'selectedChangesetStatus' ).bind( toggleDisabledNotification );
    28082821
    28092822            // Collapse panel to customize the current theme.
     
    28882901         * @since 4.9.0
    28892902         *
    2890          * @returns {void}
     2903         * @param {jQuery.Event} event - Event.
     2904         * @returns {jQuery.promise} Promise.
    28912905         */
    28922906        installTheme: function( event ) {
    2893             var panel = this, preview = false, slug = $( event.target ).data( 'slug' );
    2894 
     2907            var panel = this, preview, onInstallSuccess, slug = $( event.target ).data( 'slug' ), deferred = $.Deferred(), request;
     2908            preview = $( event.target ).hasClass( 'preview' );
     2909
     2910            // Prevent loading a non-active theme preview when there is a drafted/scheduled changeset.
     2911            if ( 'publish' !== api.state( 'selectedChangesetStatus' ).get() && slug !== api.settings.theme.stylesheet ) {
     2912                deferred.reject({
     2913                    errorCode: 'theme_switch_unavailable'
     2914                });
     2915                return deferred.promise();
     2916            }
     2917
     2918            // Theme is already being installed.
    28952919            if ( _.contains( panel.installingThemes, slug ) ) {
    2896                 return; // Theme is already being installed.
     2920                deferred.reject({
     2921                    errorCode: 'theme_already_installing'
     2922                });
     2923                return deferred.promise();
    28972924            }
    28982925
    28992926            wp.updates.maybeRequestFilesystemCredentials( event );
    29002927
    2901             $( document ).one( 'wp-theme-install-success', function( event, response ) {
     2928            onInstallSuccess = function( response ) {
    29022929                var theme = false, themeControl;
    29032930                if ( preview ) {
     
    29162943                    // Don't add the same theme more than once.
    29172944                    if ( ! theme || api.control.has( 'installed_theme_' + theme.id ) ) {
     2945                        deferred.resolve( response );
    29182946                        return;
    29192947                    }
     
    29402968                    });
    29412969                }
    2942             } );
    2943 
    2944             panel.installingThemes.push( $( event.target ).data( 'slug' ) ); // Note: we don't remove elements from installingThemes, since they shouldn't be installed again.
    2945             wp.updates.installTheme( {
     2970                deferred.resolve( response );
     2971            };
     2972
     2973            panel.installingThemes.push( slug ); // Note: we don't remove elements from installingThemes, since they shouldn't be installed again.
     2974            request = wp.updates.installTheme( {
    29462975                slug: slug
    29472976            } );
    29482977
    29492978            // Also preview the theme as the event is triggered on Install & Preview.
    2950             if ( $( event.target ).hasClass( 'preview' ) ) {
    2951                 preview = true;
    2952 
     2979            if ( preview ) {
    29532980                api.notifications.add( new api.OverlayNotification( 'theme_installing', {
    29542981                    message: api.l10n.themeDownloading,
     
    29572984                } ) );
    29582985            }
     2986
     2987            request.done( onInstallSuccess );
     2988            request.fail( function() {
     2989                api.notifications.remove( 'theme_installing' );
     2990            } );
     2991
     2992            return deferred.promise();
    29592993        },
    29602994
     
    29693003        loadThemePreview: function( themeId ) {
    29703004            var deferred = $.Deferred(), onceProcessingComplete, urlParser, queryParams;
     3005
     3006            // Prevent loading a non-active theme preview when there is a drafted/scheduled changeset.
     3007            if ( 'publish' !== api.state( 'selectedChangesetStatus' ).get() && themeId !== api.settings.theme.stylesheet ) {
     3008                return deferred.reject().promise();
     3009            }
    29713010
    29723011            urlParser = document.createElement( 'a' );
     
    47424781         */
    47434782        ready: function() {
    4744             var control = this;
     4783            var control = this, disableSwitchButtons, updateButtons;
     4784
     4785            disableSwitchButtons = function() {
     4786                return 'publish' !== api.state( 'selectedChangesetStatus' ).get() && control.params.theme.id !== api.settings.theme.stylesheet;
     4787            };
     4788            updateButtons = function() {
     4789                control.container.find( 'button' ).toggleClass( 'disabled', disableSwitchButtons() );
     4790            };
     4791
     4792            api.state( 'selectedChangesetStatus' ).bind( updateButtons );
     4793            updateButtons();
    47454794
    47464795            control.container.on( 'touchmove', '.theme', function() {
     
    47504799            // Bind details view trigger.
    47514800            control.container.on( 'click keydown touchend', '.theme', function( event ) {
     4801                var section;
    47524802                if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
    47534803                    return;
     
    47654815
    47664816                event.preventDefault(); // Keep this AFTER the key filter above
    4767                 api.section( control.section() ).showDetails( control.params.theme );
     4817                section = api.section( control.section() );
     4818                section.showDetails( control.params.theme, function() {
     4819                    section.overlay.find( '.theme-actions button' ).toggleClass( 'disabled', disableSwitchButtons() );
     4820                } );
    47684821            });
    47694822
     
    73407393            };
    73417394
    7342             // Deactivate themes panel if changeset status is not auto-draft.
    7343             api.panel( 'themes', function( themesPanel ) {
    7344                 var isPanelActive, updatePanelActive;
    7345 
    7346                 isPanelActive = function() {
    7347                     return 'publish' === selectedChangesetStatus.get() && ( ! changesetStatus() || 'auto-draft' === changesetStatus() );
    7348                 };
    7349                 themesPanel.active.validate = isPanelActive;
    7350 
    7351                 updatePanelActive = function() {
    7352                     themesPanel.active.set( isPanelActive() );
    7353                 };
    7354 
    7355                 updatePanelActive();
    7356                 changesetStatus.bind( updatePanelActive );
    7357                 selectedChangesetStatus.bind( updatePanelActive );
    7358             } );
    7359 
    73607395            // Show changeset UUID in URL when in branching mode and there is a saved changeset.
    73617396            if ( api.settings.changeset.branching ) {
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r41771 r41788  
    608608            $changeset_uuid = null;
    609609
    610             if ( ! $this->branching() ) {
     610            if ( ! $this->branching() && $this->is_theme_active() ) {
    611611                $unpublished_changeset_posts = $this->get_changeset_posts( array(
    612612                    'post_status' => array_diff( get_post_stati(), array( 'auto-draft', 'publish', 'trash', 'inherit', 'private' ) ),
  • trunk/src/wp-includes/customize/class-wp-customize-themes-panel.php

    r41709 r41788  
    8989                <# } #>
    9090            <?php endif; ?>
     91
     92            <div class="customize-control-notifications-container"></div>
    9193        </li>
    9294        <li class="customize-themes-full-container-container">
  • trunk/src/wp-includes/script-loader.php

    r41771 r41788  
    581581        /* translators: %s: URL to the Customizer to load the autosaved version */
    582582        'autosaveNotice'     => __( 'There is a more recent autosave of your changes than the one you are previewing. <a href="%s">Restore the autosave</a>' ),
    583         'videoHeaderNotice'  => __( 'This theme doesn\'t support video headers on this page. Navigate to the front page or another page that supports video headers.' ),
     583        'videoHeaderNotice'  => __( 'This theme doesn&#8217;t support video headers on this page. Navigate to the front page or another page that supports video headers.' ),
    584584        // Used for overriding the file types allowed in plupload.
    585585        'allowedFiles'       => __( 'Allowed Files' ),
     
    596596        ),
    597597        'scheduleDescription' => __( 'Schedule your customization changes to publish ("go live") at a future date.' ),
     598        'themePreviewUnavailable' => __( 'Sorry, you can&#8217;t preview new themes when you have changes scheduled or saved as a draft. Please publish your changes, or wait until they publish to preview new themes.' ),
    598599    ) );
    599600    $scripts->add( 'customize-selective-refresh', "/wp-includes/js/customize-selective-refresh$suffix.js", array( 'jquery', 'wp-util', 'customize-preview' ), false, 1 );
  • trunk/tests/phpunit/tests/customize/manager.php

    r41750 r41788  
    197197        ) );
    198198        $this->assertNotContains( $wp_customize->changeset_uuid(), array( $uuid1, $uuid2 ) );
     199        $this->assertEmpty( $wp_customize->changeset_post_id() );
     200
     201        // Make sure existing changeset is not autoloaded in the case of previewing a theme switch.
     202        switch_theme( 'twentyseventeen' );
     203        $wp_customize = new WP_Customize_Manager( array(
     204            'changeset_uuid' => false, // Cause UUID to be deferred.
     205            'branching' => false,
     206            'theme' => 'twentyfifteen',
     207        ) );
    199208        $this->assertEmpty( $wp_customize->changeset_post_id() );
    200209    }
Note: See TracChangeset for help on using the changeset viewer.