From c3e7ce5320d957e29987796069f87e6dd14dd196 Mon Sep 17 00:00:00 2001 From: koopersmith Date: Thu, 24 May 2012 21:13:21 +0000 Subject: [PATCH] Theme Customizer: Check for CORS support when the preview and admin urls are cross-domain. Add a fallback to the customize control frame, and check support there as well. see #20582, #19910. git-svn-id: http://core.svn.wordpress.org/trunk@20886 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/customize.php | 21 ++++++++++--- wp-includes/js/customize-base.dev.js | 2 ++ wp-includes/js/customize-controls.dev.js | 3 ++ wp-includes/js/customize-loader.dev.js | 40 +++++++++++++++--------- wp-includes/theme.php | 29 ++++++++++++----- 5 files changed, 68 insertions(+), 27 deletions(-) diff --git a/wp-admin/customize.php b/wp-admin/customize.php index 3b0b10045f..80e14b773c 100644 --- a/wp-admin/customize.php +++ b/wp-admin/customize.php @@ -107,22 +107,33 @@ do_action( 'customize_controls_print_scripts' ); $allowed_urls = array( home_url('/') ); $admin_origin = parse_url( admin_url() ); $home_origin = parse_url( home_url() ); + $cross_domain = ( strtolower( $admin_origin[ 'host' ] ) != strtolower( $home_origin[ 'host' ] ) ); - if ( is_ssl() && ( $admin_origin[ 'host' ] == $home_origin[ 'host' ] ) ) + if ( is_ssl() && ! $cross_domain ) $allowed_urls[] = home_url( '/', 'https' ); $allowed_urls = array_unique( apply_filters( 'customize_allowed_urls', $allowed_urls ) ); + $fallback_url = add_query_arg( array( + 'preview' => 1, + 'template' => $wp_customize->get_template(), + 'stylesheet' => $wp_customize->get_stylesheet(), + 'preview_iframe' => true, + 'TB_iframe' => 'true' + ), home_url( '/' ) ); + $settings = array( 'theme' => array( 'stylesheet' => $wp_customize->get_stylesheet(), 'active' => $wp_customize->is_theme_active(), ), 'url' => array( - 'preview' => esc_url( home_url( '/' ) ), - 'parent' => esc_url( admin_url() ), - 'ajax' => esc_url( admin_url( 'admin-ajax.php', 'relative' ) ), - 'allowed' => array_map( 'esc_url', $allowed_urls ), + 'preview' => esc_url( home_url( '/' ) ), + 'parent' => esc_url( admin_url() ), + 'ajax' => esc_url( admin_url( 'admin-ajax.php', 'relative' ) ), + 'allowed' => array_map( 'esc_url', $allowed_urls ), + 'isCrossDomain' => $cross_domain, + 'fallback' => $fallback_url, ), 'settings' => array(), 'controls' => array(), diff --git a/wp-includes/js/customize-base.dev.js b/wp-includes/js/customize-base.dev.js index 860c307048..bf8a028533 100644 --- a/wp-includes/js/customize-base.dev.js +++ b/wp-includes/js/customize-base.dev.js @@ -474,6 +474,8 @@ if ( typeof wp === 'undefined' ) * Messenger for postMessage. * ===================================================================== */ + $.support.postMessage = !! window.postMessage; + api.Messenger = api.Class.extend({ add: function( key, initial, options ) { return this[ key ] = new api.Value( initial, options ); diff --git a/wp-includes/js/customize-controls.dev.js b/wp-includes/js/customize-controls.dev.js index f6a3a92e39..34fb08995c 100644 --- a/wp-includes/js/customize-controls.dev.js +++ b/wp-includes/js/customize-controls.dev.js @@ -442,6 +442,9 @@ if ( ! api.settings ) return; + if ( ! $.support.postMessage || ( ! $.support.cors && api.settings.isCrossDomain ) ) + return window.location = api.settings.url.fallback; + // Initialize Previewer var body = $( document.body ), query, previewer, parent; diff --git a/wp-includes/js/customize-loader.dev.js b/wp-includes/js/customize-loader.dev.js index c23ed667c3..095d264dce 100644 --- a/wp-includes/js/customize-loader.dev.js +++ b/wp-includes/js/customize-loader.dev.js @@ -5,14 +5,24 @@ if ( typeof wp === 'undefined' ) var api = wp.customize, Loader; - Loader = $.extend( {}, api.Events, { - supports: { - history: !! ( window.history && history.pushState ), - hashchange: ('onhashchange' in window) && (document.documentMode === undefined || document.documentMode > 7) - }, + $.extend( $.support, { + history: !! ( window.history && history.pushState ), + hashchange: ('onhashchange' in window) && (document.documentMode === undefined || document.documentMode > 7) + }); + Loader = $.extend( {}, api.Events, { initialize: function() { - this.body = $( document.body ).addClass('customize-support'); + this.body = $( document.body ); + + // Ensure the loader is supported. + // Check for settings, postMessage support, and whether we require CORS support. + if ( ! Loader.settings || ! $.support.postMessage || ( ! $.support.cors && Loader.settings.isCrossDomain ) ) { + this.body.removeClass( 'customize-support' ).addClass( 'no-customize-support' ); + return; + } + + this.body.removeClass( 'no-customize-support' ).addClass( 'customize-support' ); + this.window = $( window ); this.element = $( '
' ).appendTo( this.body ); @@ -27,10 +37,10 @@ if ( typeof wp === 'undefined' ) }); // Add navigation listeners. - if ( this.supports.history ) + if ( $.support.history ) this.window.on( 'popstate', Loader.popstate ); - if ( this.supports.hashchange ) + if ( $.support.hashchange ) this.window.on( 'hashchange', Loader.hashchange ); }, @@ -48,7 +58,7 @@ if ( typeof wp === 'undefined' ) if ( hash && 0 === hash.indexOf( 'customize=on' ) ) Loader.open( wpCustomizeLoaderL10n.url + '?' + hash ); - if ( ! hash && ! Loader.supports.history ) + if ( ! hash && ! $.support.history ) Loader.close(); }, @@ -73,9 +83,9 @@ if ( typeof wp === 'undefined' ) }); this.messenger.bind( 'close', function() { - if ( Loader.supports.history ) + if ( $.support.history ) history.back(); - else if ( Loader.supports.hashchange ) + else if ( $.support.hashchange ) window.location.hash = ''; else Loader.close(); @@ -84,9 +94,9 @@ if ( typeof wp === 'undefined' ) hash = src.split('?')[1]; // Ensure we don't call pushState if the user hit the forward button. - if ( Loader.supports.history && window.location.href !== src ) + if ( $.support.history && window.location.href !== src ) history.pushState( { customize: src }, '', src ); - else if ( ! Loader.supports.history && Loader.supports.hashchange && hash ) + else if ( ! $.support.history && $.support.hashchange && hash ) window.location.hash = hash; this.trigger( 'open' ); @@ -128,8 +138,8 @@ if ( typeof wp === 'undefined' ) }); $( function() { - if ( window.postMessage ) - Loader.initialize(); + Loader.settings = _wpCustomizeLoaderSettings; + Loader.initialize(); }); // Expose the API to the world. diff --git a/wp-includes/theme.php b/wp-includes/theme.php index f4816efc7d..fc2b4efc2d 100644 --- a/wp-includes/theme.php +++ b/wp-includes/theme.php @@ -1584,16 +1584,31 @@ function _wp_customize_include() { add_action( 'plugins_loaded', '_wp_customize_include' ); /** - * Localizes the customize-loader script. + * Adds settings for the customize-loader script. * * @since 3.4.0 */ -function _wp_customize_loader_localize() { - wp_localize_script( 'customize-loader', 'wpCustomizeLoaderL10n', array( - 'url' => admin_url( 'admin.php' ), - ) ); +function _wp_customize_loader_settings() { + global $wp_scripts; + + $admin_origin = parse_url( admin_url() ); + $home_origin = parse_url( home_url() ); + $cross_domain = ( strtolower( $admin_origin[ 'host' ] ) != strtolower( $home_origin[ 'host' ] ) ); + + $settings = array( + 'url' => esc_url( admin_url( 'admin.php' ) ), + 'isCrossDomain' => $cross_domain, + ); + + $script = 'var _wpCustomizeLoaderSettings = ' . json_encode( $settings ) . ';'; + + $data = $wp_scripts->get_data( 'customize-loader', 'data' ); + if ( $data ) + $script = "$data\n$script"; + + $wp_scripts->add_data( 'customize-loader', 'data', $script ); } -add_action( 'admin_enqueue_scripts', '_wp_customize_loader_localize' ); +add_action( 'admin_enqueue_scripts', '_wp_customize_loader_settings' ); /** * Returns a URL to load the theme customizer. @@ -1602,4 +1617,4 @@ add_action( 'admin_enqueue_scripts', '_wp_customize_loader_localize' ); */ function wp_customize_url( $stylesheet ) { return esc_url( admin_url( 'customize.php' ) . '?theme=' . $stylesheet ); -} \ No newline at end of file +}