Make WordPress Core

Ticket #28536: 28536.4.diff

File 28536.4.diff, 11.4 KB (added by westonruter, 10 years ago)

Fix issue with messenger variable. https://github.com/x-team/wordpress-develop/commit/15bee01361ed3ab54e9f4ca8eaeaef68688fa50f https://github.com/x-team/wordpress-develop/pull/16

  • src/wp-admin/customize.php

    diff --git src/wp-admin/customize.php src/wp-admin/customize.php
    index 3cfa0c7..2a3fb57 100644
    if ( ! current_user_can( 'customize' ) ) { 
    1616        wp_die( __( 'Cheatin’ uh?' ) );
    1717}
    1818
     19global $wp_scripts, $wp_customize;
     20
    1921wp_reset_vars( array( 'url', 'return' ) );
    2022$url = wp_unslash( $url );
    2123$url = wp_validate_redirect( $url, home_url( '/' ) );
     24
    2225if ( $return ) {
    2326        $return = wp_unslash( $return );
    2427        $return = wp_validate_redirect( $return );
    2528}
    2629if ( ! $return ) {
    27         if ( $url ) {
     30        if ( ! $wp_customize->is_theme_active() ) {
     31                $return = admin_url( 'themes.php' );
     32        } elseif ( $url ) {
    2833                $return = $url;
    2934        } elseif ( current_user_can( 'edit_theme_options' ) || current_user_can( 'switch_themes' ) ) {
    3035                $return = admin_url( 'themes.php' );
    if ( ! $return ) { 
    3338        }
    3439}
    3540
    36 global $wp_scripts, $wp_customize;
    37 
    3841$registered = $wp_scripts->registered;
    3942$wp_scripts = new WP_Scripts;
    4043$wp_scripts->registered = $registered;
  • src/wp-admin/js/customize-controls.js

    diff --git src/wp-admin/js/customize-controls.js src/wp-admin/js/customize-controls.js
    index 85b171d..af082c5 100644
     
    811811                                                }
    812812                                        }
    813813
    814                                         clearTimeout( timeout );
    815                                         timeout = setTimeout( callback, self.refreshBuffer );
     814                                        try {
     815                                                clearTimeout( timeout );
     816                                                timeout = setTimeout( callback, self.refreshBuffer );
     817                                        } catch ( e ) {
     818                                                // Handle Uncaught InvalidAccessError: Failed to execute 'setTimeout' on 'Window': No script context is available in which to execute the script.
     819                                                return callback();
     820                                        }
    816821                                };
    817822                        })( this );
    818823
     
    877882
    878883                        // Update the URL when the iframe sends a URL message.
    879884                        this.bind( 'url', this.previewUrl );
     885
     886                        this.addHistory();
     887                },
     888
     889                /**
     890                 * Given a URL query string, return the query vars contained within it
     891                 *
     892                 * @param {String} queryString
     893                 * @returns {Object}
     894                 */
     895                parseQueryVars: function ( queryString ) {
     896                        var queryVars = {};
     897                        if ( queryString ) {
     898                                $.each( queryString.split( '&' ), function () {
     899                                        var key, value, pair;
     900                                        pair = this.split( '=', 2 );
     901                                        key = decodeURIComponent( pair[0] );
     902                                        value = pair[1] ? decodeURIComponent( pair[1] ) : null;
     903                                        queryVars[ key ] = value;
     904                                } );
     905                        }
     906                        return queryVars;
     907                },
     908
     909                /**
     910                 * Add support for history for navigation in Customize preview
     911                 */
     912                addHistory: function () {
     913                        var self, backLink, pushStatePreviewUrl, popState;
     914                        if ( ! history.pushState ) {
     915                                return;
     916                        }
     917                        self = this;
     918                        backLink = $( '.back.button:first' );
     919
     920                        // Push state
     921                        pushStatePreviewUrl = function ( url ) {
     922                                var state, parentLocation, queryVars;
     923                                state = { customizePreviewUrl: url };
     924                                parentLocation = location.pathname;
     925                                queryVars = self.parseQueryVars( location.search.substr( 1 ) );
     926                                queryVars.url = url;
     927                                parentLocation += '?' + $.param( queryVars );
     928                                parentLocation += location.hash;
     929
     930                                // parent frame is for the sake of customizer loaded into iframe for Live Preview
     931                                if ( api.parent.targetWindow() ) {
     932                                        api.parent.send( 'pushstate', [ state, '', parentLocation ] );
     933                                } else {
     934                                        window.history.pushState( state, '', parentLocation );
     935                                }
     936
     937                                if ( api.settings.theme.active ) {
     938                                        backLink.prop( 'href', url );
     939                                }
     940                        };
     941                        this.previewUrl.bind( pushStatePreviewUrl );
     942
     943                        // Pop state
     944                        popState = function ( state, windowLocation ) {
     945                                var url, queryVars;
     946
     947                                queryVars = self.parseQueryVars( windowLocation.search.substr( 1 ) );
     948
     949                                // Handle hitting back to themes page after having reloaded on a page in the Customizer
     950                                if ( ! state && /themes\.php$/.test( windowLocation.pathname ) ) {
     951                                        location.replace( windowLocation.href );
     952                                        return;
     953                                }
     954
     955                                if ( state && state.customizePreviewUrl ) {
     956                                        url = state.customizePreviewUrl;
     957                                } else if ( queryVars.url ) {
     958                                        /*
     959                                         * When popped to initial state, then state is null and so
     960                                         * we don't have customizePreviewUrl, so we can grab it from
     961                                         * the URL query parameter. Note that the previewUrl value
     962                                         * has a validator in place which will prevent illegal
     963                                         * or malicious URLs from being injected into the preview.
     964                                         */
     965                                        url = queryVars.url;
     966                                } else {
     967                                        // Use the homepage as the preview URL as default
     968                                        url = api.settings.url.home;
     969                                }
     970                                self.previewUrl.unbind( pushStatePreviewUrl );
     971                                self.previewUrl( url );
     972                                self.previewUrl.bind( pushStatePreviewUrl );
     973
     974                                if ( api.settings.theme.active ) {
     975                                        backLink.prop( 'href', url );
     976                                }
     977                        };
     978
     979                        if ( api.parent.targetWindow() ) {
     980                                api.parent.bind( 'popstate', function ( args ) {
     981                                        popState.apply( null, args );
     982                                } );
     983                        } else {
     984                                $( window ).on( 'popstate', function ( e ) {
     985                                        popState( e.originalEvent.state, window.location );
     986                                } );
     987                        }
    880988                },
    881989
    882990                query: function() {},
     
    9921100                if ( ! $.support.postMessage || ( ! $.support.cors && api.settings.isCrossDomain ) )
    9931101                        return window.location = api.settings.url.fallback;
    9941102
    995                 var parent, topFocus,
     1103                var topFocus,
    9961104                        body = $( document.body ),
    9971105                        overlay = body.children( '.wp-full-overlay' ),
    9981106                        title = $( '#customize-info .theme-name.site-title' ),
     
    10091117                        }
    10101118                });
    10111119
     1120                // Create a potential postMessage connection with the parent frame.
     1121                api.parent = new api.Messenger( {
     1122                        url: api.settings.url.parent,
     1123                        channel: 'loader'
     1124                } );
     1125
    10121126                // Initialize Previewer
    10131127                api.previewer = new api.Previewer({
    10141128                        container:   '#customize-preview',
     
    12001314                        } );
    12011315                }
    12021316
    1203                 // Create a potential postMessage connection with the parent frame.
    1204                 parent = new api.Messenger({
    1205                         url: api.settings.url.parent,
    1206                         channel: 'loader'
    1207                 });
    1208 
    12091317                // If we receive a 'back' event, we're inside an iframe.
    12101318                // Send any clicks to the 'Return' link to the parent page.
    1211                 parent.bind( 'back', function() {
     1319                api.parent.bind( 'back', function() {
    12121320                        closeBtn.on( 'click.customize-controls-close', function( event ) {
    12131321                                event.preventDefault();
    1214                                 parent.send( 'close' );
     1322                                api.parent.send( 'close' );
    12151323                        });
    12161324                });
    12171325
     
    12251333                // Pass events through to the parent.
    12261334                $.each( [ 'saved', 'change' ], function ( i, event ) {
    12271335                        api.bind( event, function() {
    1228                                 parent.send( event );
     1336                                api.parent.send( 'saved' );
    12291337                        });
    12301338                } );
    12311339
    12321340                // When activated, let the loader handle redirecting the page.
    12331341                // If no loader exists, redirect the page ourselves (if a url exists).
    12341342                api.bind( 'activated', function() {
    1235                         if ( parent.targetWindow() )
    1236                                 parent.send( 'activated', api.settings.url.activated );
    1237                         else if ( api.settings.url.activated )
     1343                        if ( api.parent.targetWindow() ) {
     1344                                api.parent.send( 'activated', api.settings.url.activated );
     1345                        } else if ( api.settings.url.activated ) {
    12381346                                window.location = api.settings.url.activated;
     1347                        }
    12391348                });
    12401349
    12411350                // Initialize the connection with the parent frame.
    1242                 parent.send( 'ready' );
     1351                api.parent.send( 'ready' );
    12431352
    12441353                // Control visibility for default controls
    12451354                $.each({
  • src/wp-includes/js/customize-base.js

    diff --git src/wp-includes/js/customize-base.js src/wp-includes/js/customize-base.js
    index 6c41b40..a4ddc11 100644
    window.wp = window.wp || {}; 
    524524                 * @param  {object} options       Extend any instance parameter or method with this object.
    525525                 */
    526526                initialize: function( params, options ) {
    527                         // Target the parent frame by default, but only if a parent frame exists.
    528                         var defaultTarget = window.parent == window ? null : window.parent;
     527                        var defaultTarget;
     528                        try {
     529                                // Target the parent frame by default, but only if a parent frame exists.
     530                                defaultTarget = window.parent === window ? null : window.parent;
     531                        } catch ( e ) {
     532                                // Handle case where window goes away in race condition. Uncaught TypeError: Cannot read property 'parent' of null
     533                                defaultTarget = null;
     534                        }
    529535
    530536                        $.extend( this, options || {} );
    531537
  • src/wp-includes/js/customize-loader.js

    diff --git src/wp-includes/js/customize-loader.js src/wp-includes/js/customize-loader.js
    index 2ee0c0f..14d6661 100644
    window.wp = window.wp || {}; 
    6666                        var state = e.originalEvent.state;
    6767                        if ( state && state.customize ) {
    6868                                Loader.open( state.customize );
    69                         } else if ( Loader.active ) {
     69                        } else if ( Loader.active && ( ! state || ! state.customizePreviewUrl ) ) {
    7070                                Loader.close();
    7171                        }
    7272                },
    window.wp = window.wp || {}; 
    7575                        var hash = window.location.toString().split('#')[1];
    7676
    7777                        if ( hash && 0 === hash.indexOf( 'wp_customize=on' ) ) {
    78                                 Loader.open( Loader.settings.url + '?' + hash );
     78                                Loader.open( Loader.settings.url.customize + '?' + hash );
    7979                        }
    8080
    8181                        if ( ! hash && ! $.support.history ){
    window.wp = window.wp || {}; 
    9595                 * @param  string src URL to load in the Customizer.
    9696                 */
    9797                open: function( src ) {
    98 
    9998                        if ( this.active ) {
    10099                                return;
    101100                        }
    window.wp = window.wp || {}; 
    124123                        // Wait for the connection from the iframe before sending any postMessage events.
    125124                        this.messenger.bind( 'ready', function() {
    126125                                Loader.messenger.send( 'back' );
    127                         });
     126                        } );
    128127
    129128                        this.messenger.bind( 'close', function() {
     129                                var goBackToThemesPage;
    130130                                if ( $.support.history ) {
     131                                        goBackToThemesPage = function ( e ) {
     132                                                var state;
     133                                                state = e.originalEvent.state;
     134                                                if ( state && ( state.customize || state.customizePreviewUrl ) ) {
     135                                                        history.back();
     136                                                } else {
     137                                                        $( window ).off( 'popstate', goBackToThemesPage );
     138                                                }
     139                                        };
     140                                        $( window ).on( 'popstate', goBackToThemesPage );
    131141                                        history.back();
    132142                                } else if ( $.support.hashchange ) {
    133143                                        window.location.hash = '';
    window.wp = window.wp || {}; 
    160170                pushState: function ( src ) {
    161171                        var hash;
    162172
    163                         // Ensure we don't call pushState if the user hit the forward button.
    164                         if ( $.support.history && window.location.href !== src ) {
    165                                 history.pushState( { customize: src }, '', src );
    166                         } else if ( ! $.support.history && $.support.hashchange && hash ) {
     173                        if ( $.support.history ) {
     174                                // Ensure we don't call pushState if the user hit the forward button.
     175                                if ( window.location.href !== src ) {
     176                                        history.pushState( { customize: src }, '', src );
     177                                }
     178
     179                                // Allow customizer to control history of parent
     180                                this.messenger.bind( 'pushstate', function( args ) {
     181                                        history.pushState.apply( history, args );
     182                                } );
     183
     184                                // Forward popstate events to customizer
     185                                $( window ).on( 'popstate', function ( e ) {
     186                                        Loader.messenger.send( 'popstate', [ e.originalEvent.state, window.location ] );
     187                                } );
     188
     189                        } else if ( $.support.hashchange && hash ) {
    167190                                hash = src.split( '?' )[1];
    168191                                window.location.hash = 'wp_customize=on&' + hash;
    169192                        }
  • src/wp-includes/theme.php

    diff --git src/wp-includes/theme.php src/wp-includes/theme.php
    index 85119ed..1c9b3c0 100644
    function _wp_customize_loader_settings() { 
    19271927        );
    19281928
    19291929        $settings = array(
    1930                 'url'           => esc_url( admin_url( 'customize.php' ) ),
     1930                'url'           => array(
     1931                        'customize' => esc_url_raw( admin_url( 'customize.php' ) ),
     1932                        'home'      => esc_url_raw( home_url( '/' ) ),
     1933                ),
    19311934                'isCrossDomain' => $cross_domain,
    19321935                'browser'       => $browser,
    19331936                'l10n'          => array(