~canonical-sysadmins/wordpress/4.7.2

« back to all changes in this revision

Viewing changes to wp-includes/js/customize-loader.js

  • Committer: Jacek Nykis
  • Date: 2015-01-05 16:17:05 UTC
  • Revision ID: jacek.nykis@canonical.com-20150105161705-w544l1h5mcg7u4w9
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* global _wpCustomizeLoaderSettings, confirm */
 
2
window.wp = window.wp || {};
 
3
 
 
4
(function( exports, $ ){
 
5
        var api = wp.customize,
 
6
                Loader;
 
7
 
 
8
        $.extend( $.support, {
 
9
                history: !! ( window.history && history.pushState ),
 
10
                hashchange: ('onhashchange' in window) && (document.documentMode === undefined || document.documentMode > 7)
 
11
        });
 
12
 
 
13
        /**
 
14
         * Allows the Customizer to be overlayed on any page.
 
15
         *
 
16
         * By default, any element in the body with the load-customize class will open
 
17
         * the Customizer overlay with the URL specified.
 
18
         *
 
19
         *     e.g. <a class="load-customize" href="http://siteurl.com/2014/01/02/post">Open customizer</a>
 
20
         *
 
21
         * @augments wp.customize.Events
 
22
         */
 
23
        Loader = $.extend( {}, api.Events, {
 
24
                /**
 
25
                 * Setup the Loader; triggered on document#ready.
 
26
                 */
 
27
                initialize: function() {
 
28
                        this.body = $( document.body );
 
29
 
 
30
                        // Ensure the loader is supported.
 
31
                        // Check for settings, postMessage support, and whether we require CORS support.
 
32
                        if ( ! Loader.settings || ! $.support.postMessage || ( ! $.support.cors && Loader.settings.isCrossDomain ) ) {
 
33
                                return;
 
34
                        }
 
35
 
 
36
                        this.window  = $( window );
 
37
                        this.element = $( '<div id="customize-container" />' ).appendTo( this.body );
 
38
 
 
39
                        // Bind events for opening and closing the overlay.
 
40
                        this.bind( 'open', this.overlay.show );
 
41
                        this.bind( 'close', this.overlay.hide );
 
42
 
 
43
                        // Any element in the body with the `load-customize` class opens
 
44
                        // the Customizer.
 
45
                        $('#wpbody').on( 'click', '.load-customize', function( event ) {
 
46
                                event.preventDefault();
 
47
 
 
48
                                // Store a reference to the link that opened the customizer.
 
49
                                Loader.link = $(this);
 
50
                                // Load the theme.
 
51
                                Loader.open( Loader.link.attr('href') );
 
52
                        });
 
53
 
 
54
                        // Add navigation listeners.
 
55
                        if ( $.support.history ) {
 
56
                                this.window.on( 'popstate', Loader.popstate );
 
57
                        }
 
58
 
 
59
                        if ( $.support.hashchange ) {
 
60
                                this.window.on( 'hashchange', Loader.hashchange );
 
61
                                this.window.triggerHandler( 'hashchange' );
 
62
                        }
 
63
                },
 
64
 
 
65
                popstate: function( e ) {
 
66
                        var state = e.originalEvent.state;
 
67
                        if ( state && state.customize ) {
 
68
                                Loader.open( state.customize );
 
69
                        } else if ( Loader.active ) {
 
70
                                Loader.close();
 
71
                        }
 
72
                },
 
73
 
 
74
                hashchange: function() {
 
75
                        var hash = window.location.toString().split('#')[1];
 
76
 
 
77
                        if ( hash && 0 === hash.indexOf( 'wp_customize=on' ) ) {
 
78
                                Loader.open( Loader.settings.url + '?' + hash );
 
79
                        }
 
80
 
 
81
                        if ( ! hash && ! $.support.history ){
 
82
                                Loader.close();
 
83
                        }
 
84
                },
 
85
 
 
86
                beforeunload: function () {
 
87
                        if ( ! Loader.saved() ) {
 
88
                                return Loader.settings.l10n.saveAlert;
 
89
                        }
 
90
                },
 
91
 
 
92
                /**
 
93
                 * Open the customizer overlay for a specific URL.
 
94
                 *
 
95
                 * @param  string src URL to load in the Customizer.
 
96
                 */
 
97
                open: function( src ) {
 
98
 
 
99
                        if ( this.active ) {
 
100
                                return;
 
101
                        }
 
102
 
 
103
                        // Load the full page on mobile devices.
 
104
                        if ( Loader.settings.browser.mobile ) {
 
105
                                return window.location = src;
 
106
                        }
 
107
 
 
108
                        this.active = true;
 
109
                        this.body.addClass('customize-loading');
 
110
 
 
111
                        // Dirty state of customizer in iframe
 
112
                        this.saved = new api.Value( true );
 
113
 
 
114
                        this.iframe = $( '<iframe />', { src: src }).appendTo( this.element );
 
115
                        this.iframe.one( 'load', this.loaded );
 
116
 
 
117
                        // Create a postMessage connection with the iframe.
 
118
                        this.messenger = new api.Messenger({
 
119
                                url: src,
 
120
                                channel: 'loader',
 
121
                                targetWindow: this.iframe[0].contentWindow
 
122
                        });
 
123
 
 
124
                        // Wait for the connection from the iframe before sending any postMessage events.
 
125
                        this.messenger.bind( 'ready', function() {
 
126
                                Loader.messenger.send( 'back' );
 
127
                        });
 
128
 
 
129
                        this.messenger.bind( 'close', function() {
 
130
                                if ( $.support.history ) {
 
131
                                        history.back();
 
132
                                } else if ( $.support.hashchange ) {
 
133
                                        window.location.hash = '';
 
134
                                } else {
 
135
                                        Loader.close();
 
136
                                }
 
137
                        } );
 
138
 
 
139
                        // Prompt AYS dialog when navigating away
 
140
                        $( window ).on( 'beforeunload', this.beforeunload );
 
141
 
 
142
                        this.messenger.bind( 'activated', function( location ) {
 
143
                                if ( location ) {
 
144
                                        window.location = location;
 
145
                                }
 
146
                        });
 
147
 
 
148
                        this.messenger.bind( 'saved', function () {
 
149
                                Loader.saved( true );
 
150
                        } );
 
151
                        this.messenger.bind( 'change', function () {
 
152
                                Loader.saved( false );
 
153
                        } );
 
154
 
 
155
                        this.pushState( src );
 
156
 
 
157
                        this.trigger( 'open' );
 
158
                },
 
159
 
 
160
                pushState: function ( src ) {
 
161
                        var hash;
 
162
 
 
163
                        // Ensure we don't call pushState if the user hit the forward button.
 
164
                        if ( $.support.history && window.location.href !== src ) {
 
165
                                history.pushState( { customize: src }, '', src );
 
166
                        } else if ( ! $.support.history && $.support.hashchange && hash ) {
 
167
                                hash = src.split( '?' )[1];
 
168
                                window.location.hash = 'wp_customize=on&' + hash;
 
169
                        }
 
170
                },
 
171
 
 
172
                /**
 
173
                 * Callback after the customizer has been opened.
 
174
                 */
 
175
                opened: function() {
 
176
                        Loader.body.addClass( 'customize-active full-overlay-active' );
 
177
                },
 
178
 
 
179
                /**
 
180
                 * Close the Customizer overlay and return focus to the link that opened it.
 
181
                 */
 
182
                close: function() {
 
183
                        if ( ! this.active ) {
 
184
                                return;
 
185
                        }
 
186
 
 
187
                        // Display AYS dialog if customizer is dirty
 
188
                        if ( ! this.saved() && ! confirm( Loader.settings.l10n.saveAlert ) ) {
 
189
                                // Go forward since Customizer is exited by history.back()
 
190
                                history.forward();
 
191
                                return;
 
192
                        }
 
193
 
 
194
                        this.active = false;
 
195
 
 
196
                        this.trigger( 'close' );
 
197
 
 
198
                        // Return focus to link that was originally clicked.
 
199
                        if ( this.link ) {
 
200
                                this.link.focus();
 
201
                        }
 
202
                },
 
203
 
 
204
                /**
 
205
                 * Callback after the customizer has been closed.
 
206
                 */
 
207
                closed: function() {
 
208
                        Loader.iframe.remove();
 
209
                        Loader.messenger.destroy();
 
210
                        Loader.iframe    = null;
 
211
                        Loader.messenger = null;
 
212
                        Loader.saved     = null;
 
213
                        Loader.body.removeClass( 'customize-active full-overlay-active' ).removeClass( 'customize-loading' );
 
214
                        $( window ).off( 'beforeunload', Loader.beforeunload );
 
215
                },
 
216
 
 
217
                /**
 
218
                 * Callback for the `load` event on the Customizer iframe.
 
219
                 */
 
220
                loaded: function() {
 
221
                        Loader.body.removeClass('customize-loading');
 
222
                },
 
223
 
 
224
                /**
 
225
                 * Overlay hide/show utility methods.
 
226
                 */
 
227
                overlay: {
 
228
                        show: function() {
 
229
                                this.element.fadeIn( 200, Loader.opened );
 
230
                        },
 
231
 
 
232
                        hide: function() {
 
233
                                this.element.fadeOut( 200, Loader.closed );
 
234
                        }
 
235
                }
 
236
        });
 
237
 
 
238
        // Bootstrap the Loader on document#ready.
 
239
        $( function() {
 
240
                Loader.settings = _wpCustomizeLoaderSettings;
 
241
                Loader.initialize();
 
242
        });
 
243
 
 
244
        // Expose the API publicly on window.wp.customize.Loader
 
245
        api.Loader = Loader;
 
246
})( wp, jQuery );