Make WordPress Core

Changeset 39332


Ignore:
Timestamp:
11/21/2016 04:55:20 PM (9 years ago)
Author:
westonruter
Message:

Customize: Remove iframe-specific behaviors from customize preview when previewing on frontend and not contained inside iframe.

  • Strip out customize_messenger_channel from preview window URL when not contained in iframe.
  • Allow interacting with unpreviewable links and forms when previewing customized state on frontend.

See #30937.
Fixes #38867.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r39320 r39332  
    13541354        wp_enqueue_script( 'customize-preview' );
    13551355        add_action( 'wp_head', array( $this, 'customize_preview_loading_style' ) );
     1356        add_action( 'wp_head', array( $this, 'remove_frameless_preview_messenger_channel' ) );
    13561357        add_action( 'wp_footer', array( $this, 'customize_preview_settings' ), 20 );
    13571358        add_filter( 'get_edit_post_link', '__return_empty_string' );
     
    14861487            }
    14871488        </style><?php
     1489    }
     1490
     1491    /**
     1492     * Remove customize_messenger_channel query parameter from the preview window when it is not in an iframe.
     1493     *
     1494     * This ensures that the admin bar will be shown. It also ensures that link navigation will
     1495     * work as expected since the parent frame is not being sent the URL to navigate to.
     1496     *
     1497     * @since 4.7.0
     1498     * @access public
     1499     */
     1500    public function remove_frameless_preview_messenger_channel() {
     1501        if ( ! $this->messenger_channel ) {
     1502            return;
     1503        }
     1504        ?>
     1505        <script>
     1506        ( function() {
     1507            var urlParser, oldQueryParams, newQueryParams, i;
     1508            if ( parent !== window ) {
     1509                return;
     1510            }
     1511            urlParser = document.createElement( 'a' );
     1512            urlParser.href = location.href;
     1513            oldQueryParams = urlParser.search.substr( 1 ).split( /&/ );
     1514            newQueryParams = [];
     1515            for ( i = 0; i < oldQueryParams.length; i += 1 ) {
     1516                if ( ! /^customize_messenger_channel=/.test( oldQueryParams[ i ] ) ) {
     1517                    newQueryParams.push( oldQueryParams[ i ] );
     1518                }
     1519            }
     1520            urlParser.search = newQueryParams.join( '&' );
     1521            if ( urlParser.search !== location.search ) {
     1522                location.replace( urlParser.href );
     1523            }
     1524        } )();
     1525        </script>
     1526        <?php
    14881527    }
    14891528
  • trunk/src/wp-includes/js/customize-preview.js

    r39209 r39332  
    107107
    108108            preview.body = $( document.body );
    109 
    110             preview.body.on( 'click.preview', 'a', function( event ) {
    111                 preview.handleLinkClick( event );
    112             } );
    113 
    114             preview.body.on( 'submit.preview', 'form', function( event ) {
    115                 preview.handleFormSubmit( event );
    116             } );
    117 
    118109            preview.window = $( window );
    119110
    120111            if ( api.settings.channel ) {
     112
     113                // If in an iframe, then intercept the link clicks and form submissions.
     114                preview.body.on( 'click.preview', 'a', function( event ) {
     115                    preview.handleLinkClick( event );
     116                } );
     117                preview.body.on( 'submit.preview', 'form', function( event ) {
     118                    preview.handleFormSubmit( event );
     119                } );
     120
    121121                preview.window.on( 'scroll.preview', debounce( function() {
    122122                    preview.send( 'scroll', preview.window.scrollTop() );
     
    156156                wp.a11y.speak( api.settings.l10n.linkUnpreviewable );
    157157                event.preventDefault();
    158                 return;
    159             }
    160 
    161             // If not in an iframe, then allow the link click to proceed normally since the state query params are added.
    162             if ( ! api.settings.channel ) {
    163158                return;
    164159            }
     
    197192                wp.a11y.speak( api.settings.l10n.formUnpreviewable );
    198193                event.preventDefault();
    199                 return;
    200             }
    201 
    202             // If not in an iframe, then allow the form submission to proceed normally with the state inputs injected.
    203             if ( ! api.settings.channel ) {
    204194                return;
    205195            }
     
    349339
    350340        // Make sure links in preview use HTTPS if parent frame uses HTTPS.
    351         if ( 'https' === api.preview.scheme.get() && 'http:' === element.protocol && -1 !== api.settings.url.allowedHosts.indexOf( element.host ) ) {
     341        if ( api.settings.channel && 'https' === api.preview.scheme.get() && 'http:' === element.protocol && -1 !== api.settings.url.allowedHosts.indexOf( element.host ) ) {
    352342            element.protocol = 'https:';
    353343        }
    354344
    355345        if ( ! api.isLinkPreviewable( element ) ) {
    356             $( element ).addClass( 'customize-unpreviewable' );
     346
     347            // Style link as unpreviewable only if previewing in iframe; if previewing on frontend, links will be allowed to work normally.
     348            if ( api.settings.channel ) {
     349                $( element ).addClass( 'customize-unpreviewable' );
     350            }
    357351            return;
    358352        }
     
    497491
    498492        // Make sure forms in preview use HTTPS if parent frame uses HTTPS.
    499         if ( 'https' === api.preview.scheme.get() && 'http:' === urlParser.protocol && -1 !== api.settings.url.allowedHosts.indexOf( urlParser.host ) ) {
     493        if ( api.settings.channel && 'https' === api.preview.scheme.get() && 'http:' === urlParser.protocol && -1 !== api.settings.url.allowedHosts.indexOf( urlParser.host ) ) {
    500494            urlParser.protocol = 'https:';
    501495            form.action = urlParser.href;
     
    503497
    504498        if ( 'GET' !== form.method.toUpperCase() || ! api.isLinkPreviewable( urlParser ) ) {
    505             $( form ).addClass( 'customize-unpreviewable' );
     499
     500            // Style form as unpreviewable only if previewing in iframe; if previewing on frontend, all forms will be allowed to work normally.
     501            if ( api.settings.channel ) {
     502                $( form ).addClass( 'customize-unpreviewable' );
     503            }
    506504            return;
    507505        }
  • trunk/tests/phpunit/tests/customize/manager.php

    r39320 r39332  
    461461
    462462        $this->assertEquals( 10, has_action( 'wp_head', 'wp_no_robots' ) );
     463        $this->assertEquals( 10, has_action( 'wp_head', array( $wp_customize, 'remove_frameless_preview_messenger_channel' ) ) );
    463464        $this->assertEquals( 10, has_filter( 'wp_headers', array( $wp_customize, 'filter_iframe_security_headers' ) ) );
    464465        $this->assertEquals( 10, has_filter( 'wp_redirect', array( $wp_customize, 'add_state_query_params' ) ) );
     
    20372038
    20382039    /**
     2040     * Test remove_frameless_preview_messenger_channel.
     2041     *
     2042     * @ticket 38867
     2043     * @covers WP_Customize_Manager::remove_frameless_preview_messenger_channel()
     2044     */
     2045    function test_remove_frameless_preview_messenger_channel() {
     2046        wp_set_current_user( self::$admin_user_id );
     2047        $manager = new WP_Customize_Manager( array( 'messenger_channel' => null ) );
     2048        ob_start();
     2049        $manager->remove_frameless_preview_messenger_channel();
     2050        $output = ob_get_clean();
     2051        $this->assertEmpty( $output );
     2052
     2053        $manager = new WP_Customize_Manager( array( 'messenger_channel' => 'preview-0' ) );
     2054        ob_start();
     2055        $manager->remove_frameless_preview_messenger_channel();
     2056        $output = ob_get_clean();
     2057        $this->assertContains( '<script>', $output );
     2058    }
     2059
     2060    /**
    20392061     * Test customize_preview_settings() method.
    20402062     *
Note: See TracChangeset for help on using the changeset viewer.