* @output wp-includes/js/customize-base.js
window.wp = window.wp || {};
var api = {}, ctor, inherits,
slice = Array.prototype.slice;
// Shared empty constructor function to aid in prototype-chain creation.
* Helper function to correctly set up the prototype chain, for subclasses.
* Similar to `goog.inherits`, but uses a hash of prototype properties and
* class properties to be extended.
* @param object parent Parent class constructor to inherit from.
* @param object protoProps Properties to apply to the prototype for use as class instance properties.
* @param object staticProps Properties to apply directly to the class constructor.
* @return child The subclassed constructor.
inherits = function( parent, protoProps, staticProps ) {
* The constructor function for the new subclass is either defined by you
* (the "constructor" property in your `extend` definition), or defaulted
* by us to simply call `super()`.
if ( protoProps && protoProps.hasOwnProperty( 'constructor' ) ) {
child = protoProps.constructor;
* Storing the result `super()` before returning the value
* prevents a bug in Opera where, if the constructor returns
* a function, Opera will reject the return value in favor of
* the original object. This causes all sorts of trouble.
var result = parent.apply( this, arguments );
// Inherit class (static) properties from parent.
$.extend( child, parent );
// Set the prototype chain to inherit from `parent`,
// without calling `parent`'s constructor function.
ctor.prototype = parent.prototype;
child.prototype = new ctor();
// Add prototype properties (instance properties) to the subclass,
$.extend( child.prototype, protoProps );
// Add static properties to the constructor function, if supplied.
$.extend( child, staticProps );
// Correctly set child's `prototype.constructor`.
child.prototype.constructor = child;
// Set a convenience property in case the parent's prototype is needed later.
child.__super__ = parent.prototype;
* Base class for object inheritance.
api.Class = function( applicator, argsArray, options ) {
var magic, args = arguments;
if ( applicator && argsArray && api.Class.applicator === applicator ) {
$.extend( this, options || {} );
* If the class has a method called "instance",
* the return value from the class' constructor will be a function that
* calls the "instance" method.
* It is also an object that has properties and methods inside it.
return magic.instance.apply( magic, arguments );
magic.initialize.apply( magic, args );
* Creates a subclass of the class.
* @param object protoProps Properties to apply to the prototype.
* @param object staticProps Properties to apply directly to the class.
* @return child The subclass.
api.Class.extend = function( protoProps, staticProps ) {
var child = inherits( this, protoProps, staticProps );
child.extend = this.extend;
api.Class.applicator = {};
* Initialize a class instance.
* Override this function in a subclass as needed.
api.Class.prototype.initialize = function() {};
* Checks whether a given instance extended a constructor.
* The magic surrounding the instance parameter causes the instanceof
* keyword to return inaccurate results; it defaults to the function's
* prototype instead of the constructor chain. Hence this function.
api.Class.prototype.extended = function( constructor ) {
while ( typeof proto.constructor !== 'undefined' ) {
if ( proto.constructor === constructor ) {
if ( typeof proto.constructor.__super__ === 'undefined' ) {
proto = proto.constructor.__super__;
* An events manager object, offering the ability to bind to and trigger events.
trigger: function( id ) {
if ( this.topics && this.topics[ id ] ) {
this.topics[ id ].fireWith( this, slice.call( arguments, 1 ) );
this.topics = this.topics || {};
this.topics[ id ] = this.topics[ id ] || $.Callbacks();
this.topics[ id ].add.apply( this.topics[ id ], slice.call( arguments, 1 ) );
if ( this.topics && this.topics[ id ] ) {
this.topics[ id ].remove.apply( this.topics[ id ], slice.call( arguments, 1 ) );
* Observable values that support two-way binding.
* @alias wp.customize.Value
api.Value = api.Class.extend(/** @lends wp.customize.Value.prototype */{
* @param {mixed} initial The initial value.
* @param {Object} options
initialize: function( initial, options ) {
this._value = initial; // @todo Potentially change this to a this.set() call.
this.callbacks = $.Callbacks();
$.extend( this, options || {} );
this.set = $.proxy( this.set, this );
* Magic. Returns a function that will become the instance.
* Set to null to prevent the instance from extending a function.
return arguments.length ? this.set.apply( this, arguments ) : this.get();
* Set the value and trigger all bound callbacks.
* @param {Object} to New value.
to = this._setter.apply( this, arguments );
to = this.validate( to );
// Bail if the sanitized value is null or unchanged.
if ( null === to || _.isEqual( from, to ) ) {
this.callbacks.fireWith( this, [ to, from ] );
_setter: function( to ) {
setter: function( callback ) {
// Temporarily clear value so setter can decide if it's valid.
resetSetter: function() {
this._setter = this.constructor.prototype._setter;
validate: function( value ) {
* Bind a function to be invoked whenever the value changes.
* @param {...Function} A function, or multiple functions, to add to the callback stack.
this.callbacks.add.apply( this.callbacks, arguments );
* Unbind a previously bound function.
* @param {...Function} A function, or multiple functions, to remove from the callback stack.
this.callbacks.remove.apply( this.callbacks, arguments );
link: function() { // values*
$.each( arguments, function() {
unlink: function() { // values*
$.each( arguments, function() {
sync: function() { // values*
$.each( arguments, function() {
unsync: function() { // values*
$.each( arguments, function() {
* A collection of observable values.
* @alias wp.customize.Values
* @augments wp.customize.Class
* @mixes wp.customize.Events
api.Values = api.Class.extend(/** @lends wp.customize.Values.prototype */{
* The default constructor for items of the collection.
defaultConstructor: api.Value,
initialize: function( options ) {
$.extend( this, options || {} );
* Get the instance of an item from the collection if only ID is specified.
* If more than one argument is supplied, all are expected to be IDs and
* the last to be a function callback that will be invoked when the requested
* @param {string} id ID of the item.
* @param {...} Zero or more IDs of items to wait for and a callback
* function to invoke when they're available. Optional.
* @return {mixed} The item instance if only one ID was supplied.
* A Deferred Promise object if a callback function is supplied.
instance: function( id ) {
if ( arguments.length === 1 ) {
return this.when.apply( this, arguments );
* Get the instance of an item.
* @param {string} id The ID of the item.
* @return {[type]} [description]
return this._value[ id ];
* Whether the collection has an item with the given ID.
* @param {string} id The ID of the item to look for.
return typeof this._value[ id ] !== 'undefined';
* Add an item to the collection.
* @param {string|wp.customize.Class} item - The item instance to add, or the ID for the instance to add. When an ID string is supplied, then itemObject must be provided.
* @param {wp.customize.Class} [itemObject] - The item instance when the first argument is a ID string.
* @return {wp.customize.Class} The new item's instance, or an existing instance if already added.
add: function( item, itemObject ) {
var collection = this, id, instance;
if ( 'string' === typeof item ) {
if ( 'string' !== typeof item.id ) {
throw new Error( 'Unknown key' );
if ( collection.has( id ) ) {
return collection.value( id );
collection._value[ id ] = instance;
instance.parent = collection;
// Propagate a 'change' event on an item up to the collection.
if ( instance.extended( api.Value ) ) {
instance.bind( collection._change );
collection.trigger( 'add', instance );
// If a deferred object exists for this item,
if ( collection._deferreds[ id ] ) {
collection._deferreds[ id ].resolve();
return collection._value[ id ];
* Create a new item of the collection using the collection's default constructor
* and store it in the collection.
* @param {string} id The ID of the item.
* @param {mixed} value Any extra arguments are passed into the item's initialize method.
* @return {mixed} The new item's instance.
return this.add( id, new this.defaultConstructor( api.Class.applicator, slice.call( arguments, 1 ) ) );
* Iterate over all items in the collection invoking the provided callback.
* @param {Function} callback Function to invoke.
* @param {Object} context Object context to invoke the function with. Optional.
each: function( callback, context ) {
context = typeof context === 'undefined' ? this : context;
$.each( this._value, function( key, obj ) {
callback.call( context, obj, key );
* Remove an item from the collection.
* @param {string} id The ID of the item to remove.
var value = this.value( id );
// Trigger event right before the element is removed from the collection.
this.trigger( 'remove', value );
if ( value.extended( api.Value ) ) {
value.unbind( this._change );
delete this._value[ id ];
delete this._deferreds[ id ];
// Trigger removed event after the item has been eliminated from the collection.
this.trigger( 'removed', value );
* Runs a callback once all requested values exist.
* when( ids*, [callback] );
* when( id1, id2, id3, function( value1, value2, value3 ) {} );
* @return $.Deferred.promise();
ids = slice.call( arguments ),