/** * Allows the Customizer to be overlaid on any page. * * By default, any element in the body with the load-customize class will open * an iframe overlay with the URL specified. * * e.g. <a class="load-customize" href="<?php echo wp_customize_url(); ?>">Open Customizer</a> * * @memberOf wp.customize * * @class * @augments wp.customize.Events */ Loader = $.extend( {}, api.Events,/** @lends wp.customize.Loader.prototype */{ /** * Setup the Loader; triggered on document#ready. */ initialize: function() { 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 ) ) { return; }
// Bind events for opening and closing the overlay. this.bind( 'open', this.overlay.show ); this.bind( 'close', this.overlay.hide );
// Any element in the body with the `load-customize` class opens // the Customizer. $('#wpbody').on( 'click', '.load-customize', function( event ) { event.preventDefault();
// Store a reference to the link that opened the Customizer. Loader.link = $(this); // Load the theme. Loader.open( Loader.link.attr('href') ); });
popstate: function( e ) { var state = e.originalEvent.state; if ( state && state.customize ) { Loader.open( state.customize ); } else if ( Loader.active ) { Loader.close(); } },
hashchange: function() { var hash = window.location.toString().split('#')[1];
/* * Track the dirtiness state (whether the drafted changes have been published) * of the Customizer in the iframe. This is used to decide whether to display * an AYS alert if the user tries to close the window before saving changes. */ this.saved = new api.Value( true );
// Create a postMessage connection with the iframe. this.messenger = new api.Messenger({ url: src, channel: 'loader', targetWindow: this.iframe[0].contentWindow });
// Expose the changeset UUID on the parent window's URL so that the customized state can survive a refresh. if ( history.replaceState ) { this.messenger.bind( 'changeset-uuid', function( changesetUuid ) { var urlParser = document.createElement( 'a' ); urlParser.href = location.href; urlParser.search = $.param( _.extend( api.utils.parseQueryString( urlParser.search.substr( 1 ) ), { changeset_uuid: changesetUuid } ) ); history.replaceState( { customize: urlParser.href }, '', urlParser.href ); } ); }
// Wait for the connection from the iframe before sending any postMessage events. this.messenger.bind( 'ready', function() { Loader.messenger.send( 'back' ); });
// Restore document title prior to opening the Live Preview. if ( self.originalDocumentTitle ) { document.title = self.originalDocumentTitle; } } else {
// Go forward since Customizer is exited by history.back(). history.forward(); } self.messenger.unbind( 'confirmed-close', onConfirmClose ); }; self.messenger.bind( 'confirmed-close', onConfirmClose );
Loader.messenger.send( 'confirm-close' ); },
/** * Callback after the Customizer has been closed. */ closed: function() { Loader.iframe.remove(); Loader.messenger.destroy(); Loader.iframe = null; Loader.messenger = null; Loader.saved = null; Loader.body.removeClass( 'customize-active full-overlay-active' ).removeClass( 'customize-loading' ); $( window ).off( 'beforeunload', Loader.beforeunload ); /* * Return focus to the link that opened the Customizer overlay after * the body element visibility is restored. */ if ( Loader.link ) { Loader.link.focus(); } },
/** * Callback for the `load` event on the Customizer iframe. */ loaded: function() { Loader.body.removeClass( 'customize-loading' ).attr( 'aria-busy', 'false' ); },