WordPress.org

Make WordPress Core

Changeset 39332


Ignore:
Timestamp:
11/21/16 16:55:20 (10 months 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.