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
This commit is contained in:
koopersmith 2012-05-24 21:13:21 +00:00
parent 92423061e4
commit c3e7ce5320
5 changed files with 68 additions and 27 deletions

View File

@ -107,22 +107,33 @@ do_action( 'customize_controls_print_scripts' );
$allowed_urls = array( home_url('/') ); $allowed_urls = array( home_url('/') );
$admin_origin = parse_url( admin_url() ); $admin_origin = parse_url( admin_url() );
$home_origin = parse_url( home_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[] = home_url( '/', 'https' );
$allowed_urls = array_unique( apply_filters( 'customize_allowed_urls', $allowed_urls ) ); $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( $settings = array(
'theme' => array( 'theme' => array(
'stylesheet' => $wp_customize->get_stylesheet(), 'stylesheet' => $wp_customize->get_stylesheet(),
'active' => $wp_customize->is_theme_active(), 'active' => $wp_customize->is_theme_active(),
), ),
'url' => array( 'url' => array(
'preview' => esc_url( home_url( '/' ) ), 'preview' => esc_url( home_url( '/' ) ),
'parent' => esc_url( admin_url() ), 'parent' => esc_url( admin_url() ),
'ajax' => esc_url( admin_url( 'admin-ajax.php', 'relative' ) ), 'ajax' => esc_url( admin_url( 'admin-ajax.php', 'relative' ) ),
'allowed' => array_map( 'esc_url', $allowed_urls ), 'allowed' => array_map( 'esc_url', $allowed_urls ),
'isCrossDomain' => $cross_domain,
'fallback' => $fallback_url,
), ),
'settings' => array(), 'settings' => array(),
'controls' => array(), 'controls' => array(),

View File

@ -474,6 +474,8 @@ if ( typeof wp === 'undefined' )
* Messenger for postMessage. * Messenger for postMessage.
* ===================================================================== */ * ===================================================================== */
$.support.postMessage = !! window.postMessage;
api.Messenger = api.Class.extend({ api.Messenger = api.Class.extend({
add: function( key, initial, options ) { add: function( key, initial, options ) {
return this[ key ] = new api.Value( initial, options ); return this[ key ] = new api.Value( initial, options );

View File

@ -442,6 +442,9 @@
if ( ! api.settings ) if ( ! api.settings )
return; return;
if ( ! $.support.postMessage || ( ! $.support.cors && api.settings.isCrossDomain ) )
return window.location = api.settings.url.fallback;
// Initialize Previewer // Initialize Previewer
var body = $( document.body ), var body = $( document.body ),
query, previewer, parent; query, previewer, parent;

View File

@ -5,14 +5,24 @@ if ( typeof wp === 'undefined' )
var api = wp.customize, var api = wp.customize,
Loader; Loader;
Loader = $.extend( {}, api.Events, { $.extend( $.support, {
supports: { history: !! ( window.history && history.pushState ),
history: !! ( window.history && history.pushState ), hashchange: ('onhashchange' in window) && (document.documentMode === undefined || document.documentMode > 7)
hashchange: ('onhashchange' in window) && (document.documentMode === undefined || document.documentMode > 7) });
},
Loader = $.extend( {}, api.Events, {
initialize: function() { 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.window = $( window );
this.element = $( '<div id="customize-container" class="wp-full-overlay" />' ).appendTo( this.body ); this.element = $( '<div id="customize-container" class="wp-full-overlay" />' ).appendTo( this.body );
@ -27,10 +37,10 @@ if ( typeof wp === 'undefined' )
}); });
// Add navigation listeners. // Add navigation listeners.
if ( this.supports.history ) if ( $.support.history )
this.window.on( 'popstate', Loader.popstate ); this.window.on( 'popstate', Loader.popstate );
if ( this.supports.hashchange ) if ( $.support.hashchange )
this.window.on( 'hashchange', Loader.hashchange ); this.window.on( 'hashchange', Loader.hashchange );
}, },
@ -48,7 +58,7 @@ if ( typeof wp === 'undefined' )
if ( hash && 0 === hash.indexOf( 'customize=on' ) ) if ( hash && 0 === hash.indexOf( 'customize=on' ) )
Loader.open( wpCustomizeLoaderL10n.url + '?' + hash ); Loader.open( wpCustomizeLoaderL10n.url + '?' + hash );
if ( ! hash && ! Loader.supports.history ) if ( ! hash && ! $.support.history )
Loader.close(); Loader.close();
}, },
@ -73,9 +83,9 @@ if ( typeof wp === 'undefined' )
}); });
this.messenger.bind( 'close', function() { this.messenger.bind( 'close', function() {
if ( Loader.supports.history ) if ( $.support.history )
history.back(); history.back();
else if ( Loader.supports.hashchange ) else if ( $.support.hashchange )
window.location.hash = ''; window.location.hash = '';
else else
Loader.close(); Loader.close();
@ -84,9 +94,9 @@ if ( typeof wp === 'undefined' )
hash = src.split('?')[1]; hash = src.split('?')[1];
// Ensure we don't call pushState if the user hit the forward button. // 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 ); 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; window.location.hash = hash;
this.trigger( 'open' ); this.trigger( 'open' );
@ -128,8 +138,8 @@ if ( typeof wp === 'undefined' )
}); });
$( function() { $( function() {
if ( window.postMessage ) Loader.settings = _wpCustomizeLoaderSettings;
Loader.initialize(); Loader.initialize();
}); });
// Expose the API to the world. // Expose the API to the world.

View File

@ -1584,16 +1584,31 @@ function _wp_customize_include() {
add_action( 'plugins_loaded', '_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 * @since 3.4.0
*/ */
function _wp_customize_loader_localize() { function _wp_customize_loader_settings() {
wp_localize_script( 'customize-loader', 'wpCustomizeLoaderL10n', array( global $wp_scripts;
'url' => admin_url( 'admin.php' ),
) ); $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. * 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 ) { function wp_customize_url( $stylesheet ) {
return esc_url( admin_url( 'customize.php' ) . '?theme=' . $stylesheet ); return esc_url( admin_url( 'customize.php' ) . '?theme=' . $stylesheet );
} }