From e69299af5148bb9f773e464d34a7408e294de821 Mon Sep 17 00:00:00 2001 From: ryan Date: Mon, 4 Jun 2012 15:51:46 +0000 Subject: [PATCH] Theme Customizer: Fix race condition in previewer and use message channels. Props koopersmith. fixes #20811 git-svn-id: http://core.svn.wordpress.org/trunk@20988 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/js/customize-controls.dev.js | 205 +++++++++++++++------ wp-includes/class-wp-customize-manager.php | 3 +- wp-includes/js/customize-base.dev.js | 61 ++++-- wp-includes/js/customize-loader.dev.js | 6 +- wp-includes/js/customize-preview.dev.js | 45 +++-- 5 files changed, 235 insertions(+), 85 deletions(-) diff --git a/wp-admin/js/customize-controls.dev.js b/wp-admin/js/customize-controls.dev.js index cea634c25c..76a58e6940 100644 --- a/wp-admin/js/customize-controls.dev.js +++ b/wp-admin/js/customize-controls.dev.js @@ -281,6 +281,116 @@ // Create the collection of Control objects. api.control = new api.Values({ defaultConstructor: api.Control }); + api.PreviewFrame = api.Messenger.extend({ + sensitivity: 2000, + + initialize: function( params, options ) { + var loaded = false, + ready = false, + deferred = $.Deferred(), + self = this; + + // This is the promise object. + deferred.promise( this ); + + this.previewer = params.previewer; + + $.extend( params, { channel: api.PreviewFrame.uuid() }); + + api.Messenger.prototype.initialize.call( this, params, options ); + + this.bind( 'ready', function() { + ready = true; + + if ( loaded ) + deferred.resolveWith( self ); + }); + + params.query = $.extend( params.query || {}, { customize_messenger_channel: this.channel() }); + + this.request = $.ajax( this.url(), { + type: 'POST', + data: params.query, + xhrFields: { + withCredentials: true + } + } ); + + this.request.fail( function() { + deferred.rejectWith( self, [ 'request failure' ] ); + }); + + this.request.done( function( response ) { + var location = self.request.getResponseHeader('Location'), + signature = 'WP_CUSTOMIZER_SIGNATURE', + index; + + // Check if the location response header differs from the current URL. + // If so, the request was redirected; try loading the requested page. + if ( location && location != self.url() ) { + deferred.rejectWith( self, [ 'redirect', location ] ); + return; + } + + // Check for a signature in the request. + index = response.lastIndexOf( signature ); + if ( -1 === index || index < response.lastIndexOf('') ) { + deferred.rejectWith( self, [ 'unsigned' ] ); + return; + } + + // Strip the signature from the request. + response = response.slice( 0, index ) + response.slice( index + signature.length ); + + // Create the iframe and inject the html content. + // Strip the signature from the request. + response = response.slice( 0, index ) + response.slice( index + signature.length ); + + // Create the iframe and inject the html content. + self.iframe = $('