[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 /** 2 * @output wp-includes/js/customize-loader.js 3 */ 4 5 /* global _wpCustomizeLoaderSettings */ 6 7 /** 8 * Expose a public API that allows the customizer to be 9 * loaded on any page. 10 * 11 * @namespace wp 12 */ 13 window.wp = window.wp || {}; 14 15 (function( exports, $ ){ 16 var api = wp.customize, 17 Loader; 18 19 $.extend( $.support, { 20 history: !! ( window.history && history.pushState ), 21 hashchange: ('onhashchange' in window) && (document.documentMode === undefined || document.documentMode > 7) 22 }); 23 24 /** 25 * Allows the Customizer to be overlayed on any page. 26 * 27 * By default, any element in the body with the load-customize class will open 28 * an iframe overlay with the URL specified. 29 * 30 * e.g. <a class="load-customize" href="<?php echo wp_customize_url(); ?>">Open Customizer</a> 31 * 32 * @memberOf wp.customize 33 * 34 * @class 35 * @augments wp.customize.Events 36 */ 37 Loader = $.extend( {}, api.Events,/** @lends wp.customize.Loader.prototype */{ 38 /** 39 * Setup the Loader; triggered on document#ready. 40 */ 41 initialize: function() { 42 this.body = $( document.body ); 43 44 // Ensure the loader is supported. 45 // Check for settings, postMessage support, and whether we require CORS support. 46 if ( ! Loader.settings || ! $.support.postMessage || ( ! $.support.cors && Loader.settings.isCrossDomain ) ) { 47 return; 48 } 49 50 this.window = $( window ); 51 this.element = $( '<div id="customize-container" />' ).appendTo( this.body ); 52 53 // Bind events for opening and closing the overlay. 54 this.bind( 'open', this.overlay.show ); 55 this.bind( 'close', this.overlay.hide ); 56 57 // Any element in the body with the `load-customize` class opens 58 // the Customizer. 59 $('#wpbody').on( 'click', '.load-customize', function( event ) { 60 event.preventDefault(); 61 62 // Store a reference to the link that opened the Customizer. 63 Loader.link = $(this); 64 // Load the theme. 65 Loader.open( Loader.link.attr('href') ); 66 }); 67 68 // Add navigation listeners. 69 if ( $.support.history ) { 70 this.window.on( 'popstate', Loader.popstate ); 71 } 72 73 if ( $.support.hashchange ) { 74 this.window.on( 'hashchange', Loader.hashchange ); 75 this.window.triggerHandler( 'hashchange' ); 76 } 77 }, 78 79 popstate: function( e ) { 80 var state = e.originalEvent.state; 81 if ( state && state.customize ) { 82 Loader.open( state.customize ); 83 } else if ( Loader.active ) { 84 Loader.close(); 85 } 86 }, 87 88 hashchange: function() { 89 var hash = window.location.toString().split('#')[1]; 90 91 if ( hash && 0 === hash.indexOf( 'wp_customize=on' ) ) { 92 Loader.open( Loader.settings.url + '?' + hash ); 93 } 94 95 if ( ! hash && ! $.support.history ) { 96 Loader.close(); 97 } 98 }, 99 100 beforeunload: function () { 101 if ( ! Loader.saved() ) { 102 return Loader.settings.l10n.saveAlert; 103 } 104 }, 105 106 /** 107 * Open the Customizer overlay for a specific URL. 108 * 109 * @param string src URL to load in the Customizer. 110 */ 111 open: function( src ) { 112 113 if ( this.active ) { 114 return; 115 } 116 117 // Load the full page on mobile devices. 118 if ( Loader.settings.browser.mobile ) { 119 return window.location = src; 120 } 121 122 // Store the document title prior to opening the Live Preview. 123 this.originalDocumentTitle = document.title; 124 125 this.active = true; 126 this.body.addClass('customize-loading'); 127 128 /* 129 * Track the dirtiness state (whether the drafted changes have been published) 130 * of the Customizer in the iframe. This is used to decide whether to display 131 * an AYS alert if the user tries to close the window before saving changes. 132 */ 133 this.saved = new api.Value( true ); 134 135 this.iframe = $( '<iframe />', { 'src': src, 'title': Loader.settings.l10n.mainIframeTitle } ).appendTo( this.element ); 136 this.iframe.one( 'load', this.loaded ); 137 138 // Create a postMessage connection with the iframe. 139 this.messenger = new api.Messenger({ 140 url: src, 141 channel: 'loader', 142 targetWindow: this.iframe[0].contentWindow 143 }); 144 145 // Expose the changeset UUID on the parent window's URL so that the customized state can survive a refresh. 146 if ( history.replaceState ) { 147 this.messenger.bind( 'changeset-uuid', function( changesetUuid ) { 148 var urlParser = document.createElement( 'a' ); 149 urlParser.href = location.href; 150 urlParser.search = $.param( _.extend( 151 api.utils.parseQueryString( urlParser.search.substr( 1 ) ), 152 { changeset_uuid: changesetUuid } 153 ) ); 154 history.replaceState( { customize: urlParser.href }, '', urlParser.href ); 155 } ); 156 } 157 158 // Wait for the connection from the iframe before sending any postMessage events. 159 this.messenger.bind( 'ready', function() { 160 Loader.messenger.send( 'back' ); 161 }); 162 163 this.messenger.bind( 'close', function() { 164 if ( $.support.history ) { 165 history.back(); 166 } else if ( $.support.hashchange ) { 167 window.location.hash = ''; 168 } else { 169 Loader.close(); 170 } 171 }); 172 173 // Prompt AYS dialog when navigating away. 174 $( window ).on( 'beforeunload', this.beforeunload ); 175 176 this.messenger.bind( 'saved', function () { 177 Loader.saved( true ); 178 } ); 179 this.messenger.bind( 'change', function () { 180 Loader.saved( false ); 181 } ); 182 183 this.messenger.bind( 'title', function( newTitle ){ 184 window.document.title = newTitle; 185 }); 186 187 this.pushState( src ); 188 189 this.trigger( 'open' ); 190 }, 191 192 pushState: function ( src ) { 193 var hash = src.split( '?' )[1]; 194 195 // Ensure we don't call pushState if the user hit the forward button. 196 if ( $.support.history && window.location.href !== src ) { 197 history.pushState( { customize: src }, '', src ); 198 } else if ( ! $.support.history && $.support.hashchange && hash ) { 199 window.location.hash = 'wp_customize=on&' + hash; 200 } 201 202 this.trigger( 'open' ); 203 }, 204 205 /** 206 * Callback after the Customizer has been opened. 207 */ 208 opened: function() { 209 Loader.body.addClass( 'customize-active full-overlay-active' ).attr( 'aria-busy', 'true' ); 210 }, 211 212 /** 213 * Close the Customizer overlay. 214 */ 215 close: function() { 216 var self = this, onConfirmClose; 217 if ( ! self.active ) { 218 return; 219 } 220 221 onConfirmClose = function( confirmed ) { 222 if ( confirmed ) { 223 self.active = false; 224 self.trigger( 'close' ); 225 226 // Restore document title prior to opening the Live Preview. 227 if ( self.originalDocumentTitle ) { 228 document.title = self.originalDocumentTitle; 229 } 230 } else { 231 232 // Go forward since Customizer is exited by history.back(). 233 history.forward(); 234 } 235 self.messenger.unbind( 'confirmed-close', onConfirmClose ); 236 }; 237 self.messenger.bind( 'confirmed-close', onConfirmClose ); 238 239 Loader.messenger.send( 'confirm-close' ); 240 }, 241 242 /** 243 * Callback after the Customizer has been closed. 244 */ 245 closed: function() { 246 Loader.iframe.remove(); 247 Loader.messenger.destroy(); 248 Loader.iframe = null; 249 Loader.messenger = null; 250 Loader.saved = null; 251 Loader.body.removeClass( 'customize-active full-overlay-active' ).removeClass( 'customize-loading' ); 252 $( window ).off( 'beforeunload', Loader.beforeunload ); 253 /* 254 * Return focus to the link that opened the Customizer overlay after 255 * the body element visibility is restored. 256 */ 257 if ( Loader.link ) { 258 Loader.link.focus(); 259 } 260 }, 261 262 /** 263 * Callback for the `load` event on the Customizer iframe. 264 */ 265 loaded: function() { 266 Loader.body.removeClass( 'customize-loading' ).attr( 'aria-busy', 'false' ); 267 }, 268 269 /** 270 * Overlay hide/show utility methods. 271 */ 272 overlay: { 273 show: function() { 274 this.element.fadeIn( 200, Loader.opened ); 275 }, 276 277 hide: function() { 278 this.element.fadeOut( 200, Loader.closed ); 279 } 280 } 281 }); 282 283 // Bootstrap the Loader on document#ready. 284 $( function() { 285 Loader.settings = _wpCustomizeLoaderSettings; 286 Loader.initialize(); 287 }); 288 289 // Expose the API publicly on window.wp.customize.Loader. 290 api.Loader = Loader; 291 })( wp, jQuery );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Dec 22 01:00:02 2024 | Cross-referenced by PHPXref 0.7.1 |