Вход Регистрация
Файл: wordpress/wp-includes/js/customize-base.js
Строк: 734
<?php
window
.wp window.wp || {};

(function( 
exports, $ ){
    var 
api = {}, ctorinherits,
        
slice = Array.prototype.slice;

    
// Shared empty constructor function to aid in prototype-chain creation.
    
ctor = function() {};

    
/**
     * 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( parentprotoPropsstaticProps ) {
        var 
child;

        
// 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;
        } else {
            
child = function() {
                
// 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.applythisarguments );
                return 
result;
            };
        }

        
// Inherit class (static) properties from parent.
        
$.extendchildparent );

        
// 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,
        // if supplied.
        
if ( protoProps )
            $.
extendchild.prototypeprotoProps );

        
// Add static properties to the constructor function, if supplied.
        
if ( staticProps )
            $.
extendchildstaticProps );

        
// 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;

        return 
child;
    };

    
/**
     * Base class for object inheritance.
     */
    
api.Class = function( applicatorargsArrayoptions ) {
        var 
magicargs arguments;

        if ( 
applicator && argsArray && api.Class.applicator === applicator ) {
            
args argsArray;
            $.
extendthisoptions || {} );
        }

        
magic this;
        if ( 
this.instance ) {
            
magic = function() {
                return 
magic.instance.applymagicarguments );
            };

            $.
extendmagicthis );
        }

        
magic.initialize.applymagicargs );
        return 
magic;
    };

    
/**
     * 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( protoPropsclassProps ) {
        var 
child inheritsthisprotoPropsclassProps );
        
child.extend this.extend;
        return 
child;
    };

    
api.Class.applicator = {};

    
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 ) {
        var 
proto this;

        while ( 
typeof proto.constructor !== 'undefined' ) {
            if ( 
proto.constructor === constructor )
                return 
true;
            if ( 
typeof proto.constructor.__super__ === 'undefined' )
                return 
false;
            
proto proto.constructor.__super__;
        }
        return 
false;
    };

    
/**
     * An events manager object, offering the ability to bind to and trigger events.
     *
     * Used as a mixin.
     */
    
api.Events = {
        
trigger: function( id ) {
            if ( 
this.topics && this.topicsid ] )
                
this.topicsid ].fireWiththisslice.callarguments) );
            return 
this;
        },

        
bind: function( id ) {
            
this.topics this.topics || {};
            
this.topicsid ] = this.topicsid ] || $.Callbacks();
            
this.topicsid ].add.applythis.topicsid ], slice.callarguments) );
            return 
this;
        },

        
unbind: function( id ) {
            if ( 
this.topics && this.topicsid ] )
                
this.topicsid ].remove.applythis.topicsid ], slice.callarguments) );
            return 
this;
        }
    };

    
/**
     * Observable values that support two-way binding.
     *
     * @constuctor
     */
    
api.Value api.Class.extend({
        
initialize: function( initialoptions ) {
            
this._value initial// @todo: potentially change this to a this.set() call.
            
this.callbacks = $.Callbacks();
            
this._dirty false;

            $.
extendthisoptions || {} );

            
this.set = $.proxythis.setthis );
        },

        
/*
         * Magic. Returns a function that will become the instance.
         * Set to null to prevent the instance from extending a function.
         */
        
instance: function() {
            return 
arguments.length this.set.applythisarguments ) : this.get();
        },

        
get: function() {
            return 
this._value;
        },

        
set: function( to ) {
            var 
from this._value;

            
to this._setter.applythisarguments );
            
to this.validateto );

            
// Bail if the sanitized value is null or unchanged.
            
if ( null === to || _.isEqualfromto ) ) {
                return 
this;
            }

            
this._value to;
            
this._dirty true;

            
this.callbacks.fireWiththis, [ tofrom ] );

            return 
this;
        },

        
_setter: function( to ) {
            return 
to;
        },

        
setter: function( callback ) {
            var 
from this.get();
            
this._setter callback;
            
// Temporarily clear value so setter can decide if it's valid.
            
this._value null;
            
this.setfrom );
            return 
this;
        },

        
resetSetter: function() {
            
this._setter this.constructor.prototype._setter;
            
this.setthis.get() );
            return 
this;
        },

        
validate: function( value ) {
            return 
value;
        },

        
bind: function() {
            
this.callbacks.add.applythis.callbacksarguments );
            return 
this;
        },

        
unbind: function() {
            
this.callbacks.remove.applythis.callbacksarguments );
            return 
this;
        },

        
link: function() { // values*
            
var set this.set;
            $.
eacharguments, function() {
                
this.bindset );
            });
            return 
this;
        },

        
unlink: function() { // values*
            
var set this.set;
            $.
eacharguments, function() {
                
this.unbindset );
            });
            return 
this;
        },

        
sync: function() { // values*
            
var that this;
            $.
eacharguments, function() {
                
that.linkthis );
                
this.linkthat );
            });
            return 
this;
        },

        
unsync: function() { // values*
            
var that this;
            $.
eacharguments, function() {
                
that.unlinkthis );
                
this.unlinkthat );
            });
            return 
this;
        }
    });

    
/**
     * A collection of observable values.
     *
     * @constuctor
     * @augments wp.customize.Class
     * @mixes wp.customize.Events
     */
    
api.Values api.Class.extend({
        
defaultConstructorapi.Value,

        
initialize: function( options ) {
            $.
extendthisoptions || {} );

            
this._value = {};
            
this._deferreds = {};
        },

        
instance: function( id ) {
            if ( 
arguments.length === )
                return 
this.valueid );

            return 
this.when.applythisarguments );
        },

        
value: function( id ) {
            return 
this._valueid ];
        },

        
has: function( id ) {
            return 
typeof this._valueid ] !== 'undefined';
        },

        
add: function( idvalue ) {
            if ( 
this.hasid ) )
                return 
this.valueid );

            
this._valueid ] = value;
            
value.parent this;
            if ( 
value.extendedapi.Value ) )
                
value.bindthis._change );

            
this.trigger'add'value );

            if ( 
this._deferredsid ] )
                
this._deferredsid ].resolve();

            return 
this._valueid ];
        },

        
create: function( id ) {
            return 
this.addid, new this.defaultConstructorapi.Class.applicatorslice.callarguments) ) );
        },

        
each: function( callbackcontext ) {
            
context typeof context === 'undefined' this context;

            $.
eachthis._value, function( keyobj ) {
                
callback.callcontextobjkey );
            });
        },

        
remove: function( id ) {
            var 
value;

            if ( 
this.hasid ) ) {
                
value this.valueid );
                
this.trigger'remove'value );
                if ( 
value.extendedapi.Value ) )
                    
value.unbindthis._change );
                
delete value.parent;
            }

            
delete this._valueid ];
            
delete this._deferredsid ];
        },

        
/**
         * Runs a callback once all requested values exist.
         *
         * when( ids*, [callback] );
         *
         * For example:
         *     when( id1, id2, id3, function( value1, value2, value3 ) {} );
         *
         * @returns $.Deferred.promise();
         */
        
when: function() {
            var 
self this,
                
ids  slice.callarguments ),
                
dfd  = $.Deferred();

            
// If the last argument is a callback, bind it to .done()
            
if ( $.isFunctionidsids.length ] ) )
                
dfd.doneids.pop() );

            $.
when.apply( $, $.mapids, function( id ) {
                if ( 
self.hasid ) )
                    return;

                return 
self._deferredsid ] = self._deferredsid ] || $.Deferred();
            })).
done( function() {
                var 
values = $.mapids, function( id ) {
                        return 
selfid );
                    });

                
// If a value is missing, we've used at least one expired deferred.
                // Call Values.when again to generate a new deferred.
                
if ( values.length !== ids.length ) {
                    
// ids.push( callback );
                    
self.when.applyselfids ).done( function() {
                        
dfd.resolveWithselfvalues );
                    });
                    return;
                }

                
dfd.resolveWithselfvalues );
            });

            return 
dfd.promise();
        },

        
_change: function() {
            
this.parent.trigger'change'this );
        }
    });

    $.
extendapi.Values.prototypeapi.Events );


    
/**
     * Cast a string to a jQuery collection if it isn't already.
     *
     * @param {string|jQuery collection} element
     */
    
api.ensure = function( element ) {
        return 
typeof element == 'string' ? $( element ) : element;
    };

    
/**
     * An observable value that syncs with an element.
     *
     * Handles inputs, selects, and textareas by default.
     *
     * @constuctor
     * @augments wp.customize.Value
     * @augments wp.customize.Class
     */
    
api.Element api.Value.extend({
        
initialize: function( elementoptions ) {
            var 
self this,
                
synchronizer api.Element.synchronizer.html,
                
typeupdaterefresh;

            
this.element api.ensureelement );
            
this.events '';

            if ( 
this.element.is('input, select, textarea') ) {
                
this.events += 'change';
                
synchronizer api.Element.synchronizer.val;

                if ( 
this.element.is('input') ) {
                    
type this.element.prop('type');
                    if ( 
api.Element.synchronizertype ] ) {
                        
synchronizer api.Element.synchronizertype ];
                    }
                    if ( 
'text' === type || 'password' === type ) {
                        
this.events += ' keyup';
                    } else if ( 
'range' === type ) {
                        
this.events += ' input propertychange';
                    }
                } else if ( 
this.element.is('textarea') ) {
                    
this.events += ' keyup';
                }
            }

            
api.Value.prototype.initialize.callthisnull, $.extendoptions || {}, synchronizer ) );
            
this._value this.get();

            
update  this.update;
            
refresh this.refresh;

            
this.update = function( to ) {
                if ( 
to !== refresh.callself ) )
                    
update.applythisarguments );
            };
            
this.refresh = function() {
                
self.setrefresh.callself ) );
            };

            
this.bindthis.update );
            
this.element.bindthis.eventsthis.refresh );
        },

        
find: function( selector ) {
            return $( 
selectorthis.element );
        },

        
refresh: function() {},

        
update: function() {}
    });

    
api.Element.synchronizer = {};

    $.
each( [ 'html''val' ], function( indexmethod ) {
        
api.Element.synchronizermethod ] = {
            
update: function( to ) {
                
this.elementmethod ]( to );
            },
            
refresh: function() {
                return 
this.elementmethod ]();
            }
        };
    });

    
api.Element.synchronizer.checkbox = {
        
update: function( to ) {
            
this.element.prop'checked'to );
        },
        
refresh: function() {
            return 
this.element.prop'checked' );
        }
    };

    
api.Element.synchronizer.radio = {
        
update: function( to ) {
            
this.element.filter( function() {
                return 
this.value === to;
            }).
prop'checked'true );
        },
        
refresh: function() {
            return 
this.element.filter':checked' ).val();
        }
    };

    $.
support.postMessage = !! window.postMessage;

    
/**
     * Messenger for postMessage.
     *
     * @constuctor
     * @augments wp.customize.Class
     * @mixes wp.customize.Events
     */
    
api.Messenger api.Class.extend({
        
/**
         * Create a new Value.
         *
         * @param  {string} key     Unique identifier.
         * @param  {mixed}  initial Initial value.
         * @param  {mixed}  options Options hash. Optional.
         * @return {Value}          Class instance of the Value.
         */
        
add: function( keyinitialoptions ) {
            return 
thiskey ] = new api.Valueinitialoptions );
        },

        
/**
         * Initialize Messenger.
         *
         * @param  {object} params        Parameters to configure the messenger.
         *         {string} .url          The URL to communicate with.
         *         {window} .targetWindow The window instance to communicate with. Default window.parent.
         *         {string} .channel      If provided, will send the channel with each message and only accept messages a matching channel.
         * @param  {object} options       Extend any instance parameter or method with this object.
         */
        
initialize: function( paramsoptions ) {
            
// Target the parent frame by default, but only if a parent frame exists.
            
var defaultTarget window.parent == window null window.parent;

            $.
extendthisoptions || {} );

            
this.add'channel'params.channel );
            
this.add'url'params.url || '' );
            
this.add'origin'this.url() ).linkthis.url ).setter( function( to ) {
                return 
to.replace( /([^:]+://[^/]+).*/, '$1' );
            
});

            
// first add with no value
            
this.add'targetWindow'null );
            
// This avoids SecurityErrors when setting a window object in x-origin iframe'd scenarios.
            
this.targetWindow.set = function( to ) {
                var 
from this._value;

                
to this._setter.applythisarguments );
                
to this.validateto );

                if ( 
null === to || from === to ) {
                    return 
this;
                }

                
this._value to;
                
this._dirty true;

                
this.callbacks.fireWiththis, [ tofrom ] );

                return 
this;
            };
            
// now set it
            
this.targetWindowparams.targetWindow || defaultTarget );


            
// Since we want jQuery to treat the receive function as unique
            // to this instance, we give the function a new guid.
            //
            // This will prevent every Messenger's receive function from being
            // unbound when calling $.off( 'message', this.receive );
            
this.receive = $.proxythis.receivethis );
            
this.receive.guid = $.guid++;

            $( 
window ).on'message'this.receive );
        },

        
destroy: function() {
            $( 
window ).off'message'this.receive );
        },

        
receive: function( event ) {
            var 
message;

            
event event.originalEvent;

            if ( ! 
this.targetWindow() )
                return;

            
// Check to make sure the origin is valid.
            
if ( this.origin() && event.origin !== this.origin() )
                return;

            
// Ensure we have a string that's JSON.parse-able
            
if ( typeof event.data !== 'string' || event.data[0] !== '{' ) {
                return;
            }

            
message JSON.parseevent.data );

            
// Check required message properties.
            
if ( ! message || ! message.id || typeof message.data === 'undefined' )
                return;

            
// Check if channel names match.
            
if ( ( message.channel || this.channel() ) && this.channel() !== message.channel )
                return;

            
this.triggermessage.idmessage.data );
        },

        
send: function( iddata ) {
            var 
message;

            
data typeof data === 'undefined' null data;

            if ( ! 
this.url() || ! this.targetWindow() )
                return;

            
message = { ididdatadata };
            if ( 
this.channel() )
                
message.channel this.channel();

            
this.targetWindow().postMessageJSON.stringifymessage ), this.origin() );
        }
    });

    
// Add the Events mixin to api.Messenger.
    
$.extendapi.Messenger.prototypeapi.Events );

    
// Core customize object.
    
api = $.extend( new api.Values(), api );
    
api.get = function() {
        var 
result = {};

        
this.each( function( objkey ) {
            
resultkey ] = obj.get();
        });

        return 
result;
    };

    
// Expose the API publicly on window.wp.customize
    
exports.customize api;
})( 
wpjQuery );
?>
Онлайн: 0
Реклама