Diff: STRATO-apps/wordpress_03/app/wp-includes/js/customize-base.js
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
/**
2
+
* @output wp-includes/js/customize-base.js
3
+
*/
4
+
5
+
/** @namespace wp */
6
+
window.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 );
995
+