| | |
| | |
| | |
| |
|
| | |
| | window.wp = window.wp || {}; |
| |
|
| | (function( exports, $ ){ |
| | var api = {}, ctor, inherits, |
| | slice = Array.prototype.slice; |
| |
|
| | |
| | ctor = function() {}; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | inherits = function( parent, protoProps, staticProps ) { |
| | var child; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | if ( protoProps && protoProps.hasOwnProperty( 'constructor' ) ) { |
| | child = protoProps.constructor; |
| | } else { |
| | child = function() { |
| | |
| | |
| | |
| | |
| | |
| | |
| | var result = parent.apply( this, arguments ); |
| | return result; |
| | }; |
| | } |
| |
|
| | |
| | $.extend( child, parent ); |
| |
|
| | |
| | |
| | ctor.prototype = parent.prototype; |
| | child.prototype = new ctor(); |
| |
|
| | |
| | |
| | if ( protoProps ) { |
| | $.extend( child.prototype, protoProps ); |
| | } |
| |
|
| | |
| | if ( staticProps ) { |
| | $.extend( child, staticProps ); |
| | } |
| |
|
| | |
| | child.prototype.constructor = child; |
| |
|
| | |
| | child.__super__ = parent.prototype; |
| |
|
| | return child; |
| | }; |
| |
|
| | |
| | |
| | |
| | api.Class = function( applicator, argsArray, options ) { |
| | var magic, args = arguments; |
| |
|
| | if ( applicator && argsArray && api.Class.applicator === applicator ) { |
| | args = argsArray; |
| | $.extend( this, options || {} ); |
| | } |
| |
|
| | magic = this; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | if ( this.instance ) { |
| | magic = function() { |
| | return magic.instance.apply( magic, arguments ); |
| | }; |
| |
|
| | $.extend( magic, this ); |
| | } |
| |
|
| | magic.initialize.apply( magic, args ); |
| | return magic; |
| | }; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | api.Class.extend = function( protoProps, staticProps ) { |
| | var child = inherits( this, protoProps, staticProps ); |
| | child.extend = this.extend; |
| | return child; |
| | }; |
| |
|
| | api.Class.applicator = {}; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | api.Class.prototype.initialize = 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; |
| | }; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | api.Events = { |
| | trigger: function( id ) { |
| | if ( this.topics && this.topics[ id ] ) { |
| | this.topics[ id ].fireWith( this, slice.call( arguments, 1 ) ); |
| | } |
| | return this; |
| | }, |
| |
|
| | bind: function( id ) { |
| | this.topics = this.topics || {}; |
| | this.topics[ id ] = this.topics[ id ] || $.Callbacks(); |
| | this.topics[ id ].add.apply( this.topics[ id ], slice.call( arguments, 1 ) ); |
| | return this; |
| | }, |
| |
|
| | unbind: function( id ) { |
| | if ( this.topics && this.topics[ id ] ) { |
| | this.topics[ id ].remove.apply( this.topics[ id ], slice.call( arguments, 1 ) ); |
| | } |
| | return this; |
| | } |
| | }; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | api.Value = api.Class.extend({ |
| | |
| | |
| | |
| | |
| | initialize: function( initial, options ) { |
| | this._value = initial; |
| | this.callbacks = $.Callbacks(); |
| | this._dirty = false; |
| |
|
| | $.extend( this, options || {} ); |
| |
|
| | this.set = this.set.bind( this ); |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | instance: function() { |
| | return arguments.length ? this.set.apply( this, arguments ) : this.get(); |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | get: function() { |
| | return this._value; |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | set: function( to ) { |
| | var from = this._value; |
| |
|
| | to = this._setter.apply( this, arguments ); |
| | to = this.validate( to ); |
| |
|
| | |
| | if ( null === to || _.isEqual( from, to ) ) { |
| | return this; |
| | } |
| |
|
| | this._value = to; |
| | this._dirty = true; |
| |
|
| | this.callbacks.fireWith( this, [ to, from ] ); |
| |
|
| | return this; |
| | }, |
| |
|
| | _setter: function( to ) { |
| | return to; |
| | }, |
| |
|
| | setter: function( callback ) { |
| | var from = this.get(); |
| | this._setter = callback; |
| | |
| | this._value = null; |
| | this.set( from ); |
| | return this; |
| | }, |
| |
|
| | resetSetter: function() { |
| | this._setter = this.constructor.prototype._setter; |
| | this.set( this.get() ); |
| | return this; |
| | }, |
| |
|
| | validate: function( value ) { |
| | return value; |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | bind: function() { |
| | this.callbacks.add.apply( this.callbacks, arguments ); |
| | return this; |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | unbind: function() { |
| | this.callbacks.remove.apply( this.callbacks, arguments ); |
| | return this; |
| | }, |
| |
|
| | link: function() { |
| | var set = this.set; |
| | $.each( arguments, function() { |
| | this.bind( set ); |
| | }); |
| | return this; |
| | }, |
| |
|
| | unlink: function() { |
| | var set = this.set; |
| | $.each( arguments, function() { |
| | this.unbind( set ); |
| | }); |
| | return this; |
| | }, |
| |
|
| | sync: function() { |
| | var that = this; |
| | $.each( arguments, function() { |
| | that.link( this ); |
| | this.link( that ); |
| | }); |
| | return this; |
| | }, |
| |
|
| | unsync: function() { |
| | var that = this; |
| | $.each( arguments, function() { |
| | that.unlink( this ); |
| | this.unlink( that ); |
| | }); |
| | return this; |
| | } |
| | }); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | api.Values = api.Class.extend({ |
| |
|
| | |
| | |
| | |
| | |
| | |
| | defaultConstructor: api.Value, |
| |
|
| | initialize: function( options ) { |
| | $.extend( this, options || {} ); |
| |
|
| | this._value = {}; |
| | this._deferreds = {}; |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | instance: function( id ) { |
| | if ( arguments.length === 1 ) { |
| | return this.value( id ); |
| | } |
| |
|
| | return this.when.apply( this, arguments ); |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | value: function( id ) { |
| | return this._value[ id ]; |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | has: function( id ) { |
| | return typeof this._value[ id ] !== 'undefined'; |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | add: function( item, itemObject ) { |
| | var collection = this, id, instance; |
| | if ( 'string' === typeof item ) { |
| | id = item; |
| | instance = itemObject; |
| | } else { |
| | if ( 'string' !== typeof item.id ) { |
| | throw new Error( 'Unknown key' ); |
| | } |
| | id = item.id; |
| | instance = item; |
| | } |
| |
|
| | if ( collection.has( id ) ) { |
| | return collection.value( id ); |
| | } |
| |
|
| | collection._value[ id ] = instance; |
| | instance.parent = collection; |
| |
|
| | |
| | if ( instance.extended( api.Value ) ) { |
| | instance.bind( collection._change ); |
| | } |
| |
|
| | collection.trigger( 'add', instance ); |
| |
|
| | |
| | |
| | if ( collection._deferreds[ id ] ) { |
| | collection._deferreds[ id ].resolve(); |
| | } |
| |
|
| | return collection._value[ id ]; |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | create: function( id ) { |
| | return this.add( id, new this.defaultConstructor( api.Class.applicator, slice.call( arguments, 1 ) ) ); |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | each: function( callback, context ) { |
| | context = typeof context === 'undefined' ? this : context; |
| |
|
| | $.each( this._value, function( key, obj ) { |
| | callback.call( context, obj, key ); |
| | }); |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | remove: function( id ) { |
| | var value = this.value( id ); |
| |
|
| | if ( value ) { |
| |
|
| | |
| | this.trigger( 'remove', value ); |
| |
|
| | if ( value.extended( api.Value ) ) { |
| | value.unbind( this._change ); |
| | } |
| | delete value.parent; |
| | } |
| |
|
| | delete this._value[ id ]; |
| | delete this._deferreds[ id ]; |
| |
|
| | |
| | if ( value ) { |
| | this.trigger( 'removed', value ); |
| | } |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | when: function() { |
| | var self = this, |
| | ids = slice.call( arguments ), |
| | dfd = $.Deferred(); |
| |
|
| | |
| | if ( typeof ids[ ids.length - 1 ] === 'function' ) { |
| | dfd.done( ids.pop() ); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | $.when.apply( $, $.map( ids, function( id ) { |
| | if ( self.has( id ) ) { |
| | return; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | return self._deferreds[ id ] = self._deferreds[ id ] || $.Deferred(); |
| | })).done( function() { |
| | var values = $.map( ids, function( id ) { |
| | return self( id ); |
| | }); |
| |
|
| | |
| | |
| | if ( values.length !== ids.length ) { |
| | |
| | self.when.apply( self, ids ).done( function() { |
| | dfd.resolveWith( self, values ); |
| | }); |
| | return; |
| | } |
| |
|
| | dfd.resolveWith( self, values ); |
| | }); |
| |
|
| | return dfd.promise(); |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | _change: function() { |
| | this.parent.trigger( 'change', this ); |
| | } |
| | }); |
| |
|
| | |
| | $.extend( api.Values.prototype, api.Events ); |
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | api.ensure = function( element ) { |
| | return typeof element === 'string' ? $( element ) : element; |
| | }; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | api.Element = api.Value.extend({ |
| | initialize: function( element, options ) { |
| | var self = this, |
| | synchronizer = api.Element.synchronizer.html, |
| | type, update, refresh; |
| |
|
| | this.element = api.ensure( element ); |
| | this.events = ''; |
| |
|
| | if ( this.element.is( 'input, select, textarea' ) ) { |
| | type = this.element.prop( 'type' ); |
| | this.events += ' change input'; |
| | synchronizer = api.Element.synchronizer.val; |
| |
|
| | if ( this.element.is( 'input' ) && api.Element.synchronizer[ type ] ) { |
| | synchronizer = api.Element.synchronizer[ type ]; |
| | } |
| | } |
| |
|
| | api.Value.prototype.initialize.call( this, null, $.extend( options || {}, synchronizer ) ); |
| | this._value = this.get(); |
| |
|
| | update = this.update; |
| | refresh = this.refresh; |
| |
|
| | this.update = function( to ) { |
| | if ( to !== refresh.call( self ) ) { |
| | update.apply( this, arguments ); |
| | } |
| | }; |
| | this.refresh = function() { |
| | self.set( refresh.call( self ) ); |
| | }; |
| |
|
| | this.bind( this.update ); |
| | this.element.on( this.events, this.refresh ); |
| | }, |
| |
|
| | find: function( selector ) { |
| | return $( selector, this.element ); |
| | }, |
| |
|
| | refresh: function() {}, |
| |
|
| | update: function() {} |
| | }); |
| |
|
| | api.Element.synchronizer = {}; |
| |
|
| | $.each( [ 'html', 'val' ], function( index, method ) { |
| | api.Element.synchronizer[ method ] = { |
| | update: function( to ) { |
| | this.element[ method ]( to ); |
| | }, |
| | refresh: function() { |
| | return this.element[ method ](); |
| | } |
| | }; |
| | }); |
| |
|
| | 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; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | api.Messenger = api.Class.extend({ |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | add: function( key, initial, options ) { |
| | return this[ key ] = new api.Value( initial, options ); |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | initialize: function( params, options ) { |
| | |
| | var defaultTarget = window.parent === window ? null : window.parent; |
| |
|
| | $.extend( this, options || {} ); |
| |
|
| | this.add( 'channel', params.channel ); |
| | this.add( 'url', params.url || '' ); |
| | this.add( 'origin', this.url() ).link( this.url ).setter( function( to ) { |
| | var urlParser = document.createElement( 'a' ); |
| | urlParser.href = to; |
| | |
| | return urlParser.protocol + '//' + urlParser.host.replace( /:(80|443)$/, '' ); |
| | }); |
| |
|
| | |
| | this.add( 'targetWindow', null ); |
| | |
| | this.targetWindow.set = function( to ) { |
| | var from = this._value; |
| |
|
| | to = this._setter.apply( this, arguments ); |
| | to = this.validate( to ); |
| |
|
| | if ( null === to || from === to ) { |
| | return this; |
| | } |
| |
|
| | this._value = to; |
| | this._dirty = true; |
| |
|
| | this.callbacks.fireWith( this, [ to, from ] ); |
| |
|
| | return this; |
| | }; |
| | |
| | this.targetWindow( params.targetWindow || defaultTarget ); |
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | this.receive = this.receive.bind( this ); |
| | 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 || ! this.targetWindow() ) { |
| | return; |
| | } |
| |
|
| | |
| | if ( this.origin() && event.origin !== this.origin() ) { |
| | return; |
| | } |
| |
|
| | |
| | if ( typeof event.data !== 'string' || event.data[0] !== '{' ) { |
| | return; |
| | } |
| |
|
| | message = JSON.parse( event.data ); |
| |
|
| | |
| | if ( ! message || ! message.id || typeof message.data === 'undefined' ) { |
| | return; |
| | } |
| |
|
| | |
| | if ( ( message.channel || this.channel() ) && this.channel() !== message.channel ) { |
| | return; |
| | } |
| |
|
| | this.trigger( message.id, message.data ); |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | send: function( id, data ) { |
| | var message; |
| |
|
| | data = typeof data === 'undefined' ? null : data; |
| |
|
| | if ( ! this.url() || ! this.targetWindow() ) { |
| | return; |
| | } |
| |
|
| | message = { id: id, data: data }; |
| | if ( this.channel() ) { |
| | message.channel = this.channel(); |
| | } |
| |
|
| | this.targetWindow().postMessage( JSON.stringify( message ), this.origin() ); |
| | } |
| | }); |
| |
|
| | |
| | $.extend( api.Messenger.prototype, api.Events ); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | api.Notification = api.Class.extend({ |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template: null, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | templateId: 'customize-notification', |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | containerClasses: '', |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | initialize: function( code, params ) { |
| | var _params; |
| | this.code = code; |
| | _params = _.extend( |
| | { |
| | message: null, |
| | type: 'error', |
| | fromServer: false, |
| | data: null, |
| | setting: null, |
| | template: null, |
| | dismissible: false, |
| | containerClasses: '' |
| | }, |
| | params |
| | ); |
| | delete _params.code; |
| | _.extend( this, _params ); |
| | }, |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | render: function() { |
| | var notification = this, container, data; |
| | if ( ! notification.template ) { |
| | notification.template = wp.template( notification.templateId ); |
| | } |
| | data = _.extend( {}, notification, { |
| | alt: notification.parent && notification.parent.alt |
| | } ); |
| | container = $( notification.template( data ) ); |
| |
|
| | if ( notification.dismissible ) { |
| | container.find( '.notice-dismiss' ).on( 'click keydown', function( event ) { |
| | if ( 'keydown' === event.type && 13 !== event.which ) { |
| | return; |
| | } |
| |
|
| | if ( notification.parent ) { |
| | notification.parent.remove( notification.code ); |
| | } else { |
| | container.remove(); |
| | } |
| | }); |
| | } |
| |
|
| | return container; |
| | } |
| | }); |
| |
|
| | |
| | api = $.extend( new api.Values(), api ); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | api.get = function() { |
| | var result = {}; |
| |
|
| | this.each( function( obj, key ) { |
| | result[ key ] = obj.get(); |
| | }); |
| |
|
| | return result; |
| | }; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | api.utils = {}; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | api.utils.parseQueryString = function parseQueryString( queryString ) { |
| | var queryParams = {}; |
| | _.each( queryString.split( '&' ), function( pair ) { |
| | var parts, key, value; |
| | parts = pair.split( '=', 2 ); |
| | if ( ! parts[0] ) { |
| | return; |
| | } |
| | key = decodeURIComponent( parts[0].replace( /\+/g, ' ' ) ); |
| | key = key.replace( / /g, '_' ); |
| | if ( _.isUndefined( parts[1] ) ) { |
| | value = null; |
| | } else { |
| | value = decodeURIComponent( parts[1].replace( /\+/g, ' ' ) ); |
| | } |
| | queryParams[ key ] = value; |
| | } ); |
| | return queryParams; |
| | }; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | exports.customize = api; |
| | })( wp, jQuery ); |
| |
|