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