Make WordPress Core

Changeset 41797


Ignore:
Timestamp:
10/09/2017 04:03:35 PM (9 years ago)
Author:
westonruter
Message:

Customize: Eliminate use of customize-loader in core so Customizer is opened consistently in top window.

  • Open the door for future browser history feature in #28536, which is currently not feasible when customize-loader is used.
  • Remove customizer-loader from being used on admin screens for Dashboard, Themes, non-shiny theme install/update.
  • Keep the customize-loader functionality available for plugins, for the time being. It may become deprecated.
  • Ensure return param in customizer links in Themes screen update to reflect search updated by pushState.
  • Persist return when reloading Customizer due to theme switch, autosave restoration, or changeset trashing.
  • Use location.replace() instead of changing location.href when trashing.
  • Hide theme browser while Themes screen is loading when there is a search to prevent flash of unfiltered themes.
  • Use throttling instead of debouncing when searching themes to ensure that screen is updated immediately on page load.
  • Fix encoding and decoding of search param between URL and search field.
  • Add support for dismissing autosaves when closing customize-loader, when it is used by plugins.
  • Skip sending changeset UUID to customize-loader for population in browser location if changeset branching is not enabled.

See #28536.
Fixes #40254.

Location:
trunk/src
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/css/themes.css

    r41667 r41797  
    77  16.1 - Manage Themes
    88------------------------------------------------------------------------------*/
     9
     10body.js .theme-browser.search-loading {
     11        display: none;
     12}
    913
    1014.theme-browser .themes {
  • trunk/src/wp-admin/includes/class-theme-installer-skin.php

    r41161 r41797  
    6565
    6666                if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    67                         $install_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
     67                        $customize_url = add_query_arg(
     68                                array(
     69                                        'theme' => urlencode( $stylesheet ),
     70                                        'return' => urlencode( admin_url( 'web' === $this->type ? 'theme-install.php' : 'themes.php' ) ),
     71                                ),
     72                                admin_url( 'customize.php' )
     73                        );
     74                        $install_actions['preview'] = '<a href="' . esc_url( $customize_url ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
    6875                }
    6976                $install_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate &#8220;%s&#8221;' ), $name ) . '</span></a>';
  • trunk/src/wp-admin/includes/class-theme-upgrader-skin.php

    r41161 r41797  
    5050                        $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
    5151
     52                        $customize_url = add_query_arg(
     53                                array(
     54                                        'theme' => urlencode( $stylesheet ),
     55                                        'return' => urlencode( admin_url( 'themes.php' ) ),
     56                                ),
     57                                admin_url( 'customize.php' )
     58                        );
    5259                        if ( get_stylesheet() == $stylesheet ) {
    5360                                if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    54                                         $update_actions['preview']  = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Customize' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Customize &#8220;%s&#8221;' ), $name ) . '</span></a>';
     61                                        $update_actions['preview']  = '<a href="' . esc_url( $customize_url ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Customize' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Customize &#8220;%s&#8221;' ), $name ) . '</span></a>';
    5562                                }
    5663                        } elseif ( current_user_can( 'switch_themes' ) ) {
    5764                                if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    58                                         $update_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
     65                                        $update_actions['preview'] = '<a href="' . esc_url( $customize_url ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
    5966                                }
    6067                                $update_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate &#8220;%s&#8221;' ), $name ) . '</span></a>';
  • trunk/src/wp-admin/index.php

    r40776 r41797  
    1717wp_enqueue_script( 'dashboard' );
    1818
    19 if ( current_user_can( 'edit_theme_options' ) )
    20         wp_enqueue_script( 'customize-loader' );
    2119if ( current_user_can( 'install_plugins' ) ) {
    2220        wp_enqueue_script( 'plugin-install' );
  • trunk/src/wp-admin/js/customize-controls.js

    r41788 r41797  
    107107                 * @since 4.9.0
    108108                 *
    109                  * @param {string|wp.customize.Notification} - Notification object to add. Alternatively code may be supplied, and in that case the second notificationObject argument must be supplied.
     109                 * @param {string|wp.customize.Notification} notification - Notification object to add. Alternatively code may be supplied, and in that case the second notificationObject argument must be supplied.
    110110                 * @param {wp.customize.Notification} [notificationObject] - Notification to add when first argument is the code string.
    111111                 * @returns {wp.customize.Notification} Added notification (or existing instance if it was already added).
     
    30153015                                {
    30163016                                        theme: themeId,
    3017                                         changeset_uuid: api.settings.changeset.uuid
     3017                                        changeset_uuid: api.settings.changeset.uuid,
     3018                                        'return': api.settings.url['return']
    30183019                                }
    30193020                        );
     
    30453046                                        deferred.resolve();
    30463047                                        $( window ).off( 'beforeunload.customize-confirm' );
    3047                                         window.location.href = urlParser.href; // @todo Use location.replace()?
     3048                                        location.replace( urlParser.href );
    30483049                                } );
    30493050                                request.fail( function() {
     
    69596960                                                        api.settings.changeset.uuid = response.next_changeset_uuid;
    69606961                                                        api.state( 'changesetStatus' ).set( '' );
    6961                                                         parent.send( 'changeset-uuid', api.settings.changeset.uuid );
     6962                                                        if ( api.settings.changeset.branching ) {
     6963                                                                parent.send( 'changeset-uuid', api.settings.changeset.uuid );
     6964                                                        }
    69626965                                                        api.previewer.send( 'changeset-uuid', api.settings.changeset.uuid );
    69636966                                                }
     
    69906993                                                        api.state( 'changesetStatus' ).set( '' );
    69916994                                                        api.settings.changeset.uuid = response.next_changeset_uuid;
    6992                                                         parent.send( 'changeset-uuid', api.settings.changeset.uuid );
     6995                                                        if ( api.settings.changeset.branching ) {
     6996                                                                parent.send( 'changeset-uuid', api.settings.changeset.uuid );
     6997                                                        }
    69936998                                                }
    69946999
     
    70667071                                        queryParams = api.utils.parseQueryString( urlParser.search.substr( 1 ) );
    70677072                                        delete queryParams.changeset_uuid;
     7073                                        queryParams['return'] = api.settings.url['return'];
    70687074                                        urlParser.search = $.param( queryParams );
    70697075                                        location.replace( urlParser.href );
     
    74197425                                        queryParams.customize_autosaved = 'on';
    74207426                                }
     7427                                queryParams['return'] = api.settings.url['return'];
    74217428                                urlParser.search = $.param( queryParams );
    74227429                                return urlParser.href;
     
    79167923                        api.bind( 'change', startPromptingBeforeUnload );
    79177924
    7918                         closeBtn.on( 'click.customize-controls-close', function( event ) {
     7925                        function requestClose() {
    79197926                                var clearedToClose = $.Deferred();
    7920                                 event.preventDefault();
    7921 
    7922                                 /*
    7923                                  * The isInsideIframe condition is because Customizer is not able to use a confirm()
    7924                                  * since customize-loader.js will also use one. So autosave restorations are disabled
    7925                                  * when customize-loader.js is used.
    7926                                  */
    7927                                 if ( isInsideIframe || isCleanState() ) {
     7927                                if ( isCleanState() ) {
    79287928                                        clearedToClose.resolve();
    79297929                                } else if ( confirm( api.l10n.saveAlert ) ) {
     
    79557955                                        clearedToClose.reject();
    79567956                                }
    7957 
    7958                                 clearedToClose.done( function() {
    7959                                         $( window ).off( 'beforeunload.customize-confirm' );
    7960                                         if ( isInsideIframe ) {
    7961                                                 parent.send( 'close' );
    7962                                         } else {
     7957                                return clearedToClose.promise();
     7958                        }
     7959
     7960                        parent.bind( 'confirm-close', function() {
     7961                                requestClose().done( function() {
     7962                                        parent.send( 'confirmed-close', true );
     7963                                } ).fail( function() {
     7964                                        parent.send( 'confirmed-close', false );
     7965                                } );
     7966                        } );
     7967
     7968                        closeBtn.on( 'click.customize-controls-close', function( event ) {
     7969                                event.preventDefault();
     7970                                if ( isInsideIframe ) {
     7971                                        parent.send( 'close' ); // See confirm-close logic above.
     7972                                } else {
     7973                                        requestClose().done( function() {
     7974                                                $( window ).off( 'beforeunload.customize-confirm' );
    79637975                                                window.location.href = closeBtn.prop( 'href' );
    7964                                         }
    7965                                 } );
     7976                                        } );
     7977                                }
    79667978                        });
    79677979                })();
     
    79797991                });
    79807992
    7981                 parent.send( 'changeset-uuid', api.settings.changeset.uuid );
     7993                if ( api.settings.changeset.branching ) {
     7994                        parent.send( 'changeset-uuid', api.settings.changeset.uuid );
     7995                }
    79827996
    79837997                // Initialize the connection with the parent frame.
  • trunk/src/wp-admin/js/theme.js

    r41683 r41797  
    7777                // Render search form.
    7878                this.search();
     79
     80                this.$el.removeClass( 'search-loading' );
    7981
    8082                // Render and append
     
    13461348                }
    13471349
    1348                 /**
    1349                  * Since doSearch is debounced, it will only run when user input comes to a rest
    1350                  */
     1350                // Note that doSearch is throttled.
    13511351                this.doSearch( event );
    13521352        },
    13531353
    13541354        // Runs a search on the theme collection.
    1355         doSearch: _.debounce( function( event ) {
     1355        doSearch: _.throttle( function( event ) {
    13561356                var options = {};
    13571357
    1358                 this.collection.doSearch( event.target.value );
     1358                this.collection.doSearch( event.target.value.replace( /\+/g, ' ' ) );
    13591359
    13601360                // if search is initiated and key is not return
     
    13771377
    13781378                if ( event.target.value ) {
    1379                         url = themes.router.baseUrl( themes.router.searchPath + event.target.value );
     1379                        url = themes.router.baseUrl( themes.router.searchPath + encodeURIComponent( event.target.value ) );
    13801380                }
    13811381
     
    13851385        }
    13861386});
     1387
     1388/**
     1389 * Navigate router.
     1390 *
     1391 * @since 4.9.0
     1392 *
     1393 * @param {string} url - URL to navigate to.
     1394 * @param {object} state - State.
     1395 * @returns {void}
     1396 */
     1397function navigateRouter( url, state ) {
     1398        var router = this;
     1399        if ( Backbone.history._hasPushState ) {
     1400                Backbone.Router.prototype.navigate.call( router, url, state );
     1401        }
     1402}
    13871403
    13881404// Sets up the routes events for relevant url queries
     
    14061422
    14071423        search: function( query ) {
    1408                 $( '.wp-filter-search' ).val( query );
     1424                $( '.wp-filter-search' ).val( query.replace( /\+/g, ' ' ) );
    14091425        },
    14101426
     
    14131429        },
    14141430
    1415         navigate: function() {
    1416                 if ( Backbone.history._hasPushState ) {
    1417                         Backbone.Router.prototype.navigate.apply( this, arguments );
    1418                 }
    1419         }
     1431        navigate: navigateRouter
    14201432
    14211433});
     
    15091521        },
    15101522
    1511         doSearch: _.debounce( function( value ) {
     1523        doSearch: _.throttle( function( value ) {
    15121524                var request = {};
    15131525
     
    15521564
    15531565                // Set route
    1554                 themes.router.navigate( themes.router.baseUrl( themes.router.searchPath + value ), { replace: true } );
     1566                themes.router.navigate( themes.router.baseUrl( themes.router.searchPath + encodeURIComponent( value ) ), { replace: true } );
    15551567        }, 500 )
    15561568});
     
    18881900
    18891901        search: function( query ) {
    1890                 $( '.wp-filter-search' ).val( query );
    1891         },
    1892 
    1893         navigate: function() {
    1894                 if ( Backbone.history._hasPushState ) {
    1895                         Backbone.Router.prototype.navigate.apply( this, arguments );
    1896                 }
    1897         }
     1902                $( '.wp-filter-search' ).val( query.replace( /\+/g, ' ' ) );
     1903        },
     1904
     1905        navigate: navigateRouter
    18981906});
    18991907
     
    20032011                themes.Run.init();
    20042012        }
     2013
     2014        // Update the return param just in time.
     2015        $( document.body ).on( 'click', '.load-customize', function() {
     2016                var link = $( this ), urlParser = document.createElement( 'a' );
     2017                urlParser.href = link.prop( 'href' );
     2018                urlParser.search = $.param( _.extend(
     2019                        wp.customize.utils.parseQueryString( urlParser.search.substr( 1 ) ),
     2020                        {
     2021                                'return': window.location.href
     2022                        }
     2023                ) );
     2024                link.prop( 'href', urlParser.href );
     2025        });
    20052026
    20062027        $( '.broken-themes .delete-theme' ).on( 'click', function() {
  • trunk/src/wp-admin/themes.php

    r41658 r41797  
    147147wp_enqueue_script( 'theme' );
    148148wp_enqueue_script( 'updates' );
    149 wp_enqueue_script( 'customize-loader' );
    150149
    151150require_once( ABSPATH . 'wp-admin/admin-header.php' );
     
    154153<div class="wrap">
    155154        <h1 class="wp-heading-inline"><?php esc_html_e( 'Themes' ); ?>
    156                 <span class="title-count theme-count"><?php echo count( $themes ); ?></span>
     155                <span class="title-count theme-count"><?php echo ! empty( $_GET['search'] ) ? __( '&hellip;' ) : count( $themes ); ?></span>
    157156        </h1>
    158157
     
    235234?>
    236235
    237 <div class="theme-browser">
     236<?php
     237$class_name = 'theme-browser';
     238if ( ! empty( $_GET['search'] ) ) {
     239        $class_name .= ' search-loading';
     240}
     241?>
     242<div class="<?php echo esc_attr( $class_name ); ?>">
    238243        <div class="themes wp-clearfix">
    239244
  • trunk/src/wp-admin/update.php

    r41289 r41797  
    174174                check_admin_referer('upgrade-theme_' . $theme);
    175175
    176                 wp_enqueue_script( 'customize-loader' );
    177176                wp_enqueue_script( 'updates' );
    178177
     
    224223                $api = themes_api('theme_information', array('slug' => $theme, 'fields' => array('sections' => false, 'tags' => false) ) ); //Save on a bit of bandwidth.
    225224
    226                 if ( is_wp_error($api) )
    227                         wp_die($api);
    228 
    229                 wp_enqueue_script( 'customize-loader' );
     225                if ( is_wp_error( $api ) ) {
     226                        wp_die( $api );
     227                }
    230228
    231229                $title = __('Install Themes');
     
    253251
    254252                $file_upload = new File_Upload_Upgrader('themezip', 'package');
    255 
    256                 wp_enqueue_script( 'customize-loader' );
    257253
    258254                $title = __('Upload Theme');
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r41793 r41797  
    42374237                        'url'      => array(
    42384238                                'preview'       => esc_url_raw( $this->get_preview_url() ),
     4239                                'return'        => esc_url_raw( $this->get_return_url() ),
    42394240                                'parent'        => esc_url_raw( admin_url() ),
    42404241                                'activated'     => esc_url_raw( home_url( '/' ) ),
  • trunk/src/wp-includes/js/customize-loader.js

    r41351 r41797  
    1 /* global _wpCustomizeLoaderSettings, confirm */
     1/* global _wpCustomizeLoaderSettings */
    22/**
    33 * Expose a public API that allows the customizer to be
     
    209209                 */
    210210                close: function() {
    211                         if ( ! this.active ) {
     211                        var self = this, onConfirmClose;
     212                        if ( ! self.active ) {
    212213                                return;
    213214                        }
    214215
    215                         // Display AYS dialog if Customizer is dirty
    216                         if ( ! this.saved() && ! confirm( Loader.settings.l10n.saveAlert ) ) {
    217                                 // Go forward since Customizer is exited by history.back()
    218                                 history.forward();
    219                                 return;
    220                         }
    221 
    222                         this.active = false;
    223 
    224                         this.trigger( 'close' );
    225 
    226                         // Restore document title prior to opening the Live Preview
    227                         if ( this.originalDocumentTitle ) {
    228                                 document.title = this.originalDocumentTitle;
    229                         }
     216                        onConfirmClose = function( confirmed ) {
     217                                if ( confirmed ) {
     218                                        self.active = false;
     219                                        self.trigger( 'close' );
     220
     221                                        // Restore document title prior to opening the Live Preview
     222                                        if ( self.originalDocumentTitle ) {
     223                                                document.title = self.originalDocumentTitle;
     224                                        }
     225                                } else {
     226
     227                                        // Go forward since Customizer is exited by history.back()
     228                                        history.forward();
     229                                }
     230                                self.messenger.unbind( 'confirmed-close', onConfirmClose );
     231                        };
     232                        self.messenger.bind( 'confirmed-close', onConfirmClose );
     233
     234                        Loader.messenger.send( 'confirm-close' );
    230235                },
    231236
  • trunk/src/wp-includes/script-loader.php

    r41791 r41797  
    726726                $scripts->add( 'custom-html-widgets', "/wp-admin/js/widgets/custom-html-widgets$suffix.js", array( 'code-editor', 'jquery', 'backbone', 'wp-util', 'jquery-ui-core', 'wp-a11y' ) );
    727727
    728                 $scripts->add( 'theme', "/wp-admin/js/theme$suffix.js", array( 'wp-backbone', 'wp-a11y' ), false, 1 );
     728                $scripts->add( 'theme', "/wp-admin/js/theme$suffix.js", array( 'wp-backbone', 'wp-a11y', 'customize-base' ), false, 1 );
    729729
    730730                $scripts->add( 'inline-edit-post', "/wp-admin/js/inline-edit-post$suffix.js", array( 'jquery', 'tags-suggest', 'wp-a11y' ), false, 1 );
Note: See TracChangeset for help on using the changeset viewer.