diff -r 2f6f6f7551ca -r 32102edaa81b web/wp-admin/js/customize-controls.dev.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/wp-admin/js/customize-controls.dev.js Mon Nov 19 18:26:13 2012 +0100 @@ -0,0 +1,963 @@ +(function( exports, $ ){ + var api = wp.customize; + + /* + * @param options + * - previewer - The Previewer instance to sync with. + * - transport - The transport to use for previewing. Supports 'refresh' and 'postMessage'. + */ + api.Setting = api.Value.extend({ + initialize: function( id, value, options ) { + var element; + + api.Value.prototype.initialize.call( this, value, options ); + + this.id = id; + this.transport = this.transport || 'refresh'; + + this.bind( this.preview ); + }, + preview: function() { + switch ( this.transport ) { + case 'refresh': + return this.previewer.refresh(); + case 'postMessage': + return this.previewer.send( 'setting', [ this.id, this() ] ); + } + } + }); + + api.Control = api.Class.extend({ + initialize: function( id, options ) { + var control = this, + nodes, radios, settings; + + this.params = {}; + $.extend( this, options || {} ); + + this.id = id; + this.selector = '#customize-control-' + id.replace( ']', '' ).replace( '[', '-' ); + this.container = $( this.selector ); + + settings = $.map( this.params.settings, function( value ) { + return value; + }); + + api.apply( api, settings.concat( function() { + var key; + + control.settings = {}; + for ( key in control.params.settings ) { + control.settings[ key ] = api( control.params.settings[ key ] ); + } + + control.setting = control.settings['default'] || null; + control.ready(); + }) ); + + control.elements = []; + + nodes = this.container.find('[data-customize-setting-link]'); + radios = {}; + + nodes.each( function() { + var node = $(this), + name; + + if ( node.is(':radio') ) { + name = node.prop('name'); + if ( radios[ name ] ) + return; + + radios[ name ] = true; + node = nodes.filter( '[name="' + name + '"]' ); + } + + api( node.data('customizeSettingLink'), function( setting ) { + var element = new api.Element( node ); + control.elements.push( element ); + element.sync( setting ); + element.set( setting() ); + }); + }); + }, + + ready: function() {}, + + dropdownInit: function() { + var control = this, + statuses = this.container.find('.dropdown-status'), + params = this.params, + update = function( to ) { + if ( typeof to === 'string' && params.statuses && params.statuses[ to ] ) + statuses.html( params.statuses[ to ] ).show(); + else + statuses.hide(); + }; + + // Support the .dropdown class to open/close complex elements + this.container.on( 'click', '.dropdown', function( event ) { + event.preventDefault(); + control.container.toggleClass('open'); + }); + + this.setting.bind( update ); + update( this.setting() ); + } + }); + + api.ColorControl = api.Control.extend({ + ready: function() { + var control = this, + rhex, spot, input, text, update; + + rhex = /^#([A-Fa-f0-9]{3}){0,2}$/; + spot = this.container.find('.dropdown-content'); + input = new api.Element( this.container.find('.color-picker-hex') ); + update = function( color ) { + spot.css( 'background', color ); + control.farbtastic.setColor( color ); + }; + + this.farbtastic = $.farbtastic( this.container.find('.farbtastic-placeholder'), control.setting.set ); + + // Only pass through values that are valid hexes/empty. + input.sync( this.setting ).validate = function( to ) { + return rhex.test( to ) ? to : null; + }; + + this.setting.bind( update ); + update( this.setting() ); + + this.dropdownInit(); + } + }); + + api.UploadControl = api.Control.extend({ + ready: function() { + var control = this; + + this.params.removed = this.params.removed || ''; + + this.success = $.proxy( this.success, this ); + + this.uploader = $.extend({ + container: this.container, + browser: this.container.find('.upload'), + dropzone: this.container.find('.upload-dropzone'), + success: this.success + }, this.uploader || {} ); + + if ( this.uploader.supported ) { + if ( control.params.context ) + control.uploader.param( 'post_data[context]', this.params.context ); + + control.uploader.param( 'post_data[theme]', api.settings.theme.stylesheet ); + } + + this.uploader = new wp.Uploader( this.uploader ); + + this.remover = this.container.find('.remove'); + this.remover.click( function( event ) { + control.setting.set( control.params.removed ); + event.preventDefault(); + }); + + this.removerVisibility = $.proxy( this.removerVisibility, this ); + this.setting.bind( this.removerVisibility ); + this.removerVisibility( this.setting.get() ); + }, + success: function( attachment ) { + this.setting.set( attachment.url ); + }, + removerVisibility: function( to ) { + this.remover.toggle( to != this.params.removed ); + } + }); + + api.ImageControl = api.UploadControl.extend({ + ready: function() { + var control = this, + panels; + + this.uploader = { + init: function( up ) { + var fallback, button; + + if ( this.supports.dragdrop ) + return; + + // Maintain references while wrapping the fallback button. + fallback = control.container.find( '.upload-fallback' ); + button = fallback.children().detach(); + + this.browser.detach().empty().append( button ); + fallback.append( this.browser ).show(); + } + }; + + api.UploadControl.prototype.ready.call( this ); + + this.thumbnail = this.container.find('.preview-thumbnail img'); + this.thumbnailSrc = $.proxy( this.thumbnailSrc, this ); + this.setting.bind( this.thumbnailSrc ); + + this.library = this.container.find('.library'); + + // Generate tab objects + this.tabs = {}; + panels = this.library.find('.library-content'); + + this.library.children('ul').children('li').each( function() { + var link = $(this), + id = link.data('customizeTab'), + panel = panels.filter('[data-customize-tab="' + id + '"]'); + + control.tabs[ id ] = { + both: link.add( panel ), + link: link, + panel: panel + }; + }); + + // Bind tab switch events + this.library.children('ul').on( 'click', 'li', function( event ) { + var id = $(this).data('customizeTab'), + tab = control.tabs[ id ]; + + event.preventDefault(); + + if ( tab.link.hasClass('library-selected') ) + return; + + control.selected.both.removeClass('library-selected'); + control.selected = tab; + control.selected.both.addClass('library-selected'); + }); + + // Bind events to switch image urls. + this.library.on( 'click', 'a', function( event ) { + var value = $(this).data('customizeImageValue'); + + if ( value ) { + control.setting.set( value ); + event.preventDefault(); + } + }); + + if ( this.tabs.uploaded ) { + this.tabs.uploaded.target = this.library.find('.uploaded-target'); + if ( ! this.tabs.uploaded.panel.find('.thumbnail').length ) + this.tabs.uploaded.both.addClass('hidden'); + } + + // Select a tab + panels.each( function() { + var tab = control.tabs[ $(this).data('customizeTab') ]; + + // Select the first visible tab. + if ( ! tab.link.hasClass('hidden') ) { + control.selected = tab; + tab.both.addClass('library-selected'); + return false; + } + }); + + this.dropdownInit(); + }, + success: function( attachment ) { + api.UploadControl.prototype.success.call( this, attachment ); + + // Add the uploaded image to the uploaded tab. + if ( this.tabs.uploaded && this.tabs.uploaded.target.length ) { + this.tabs.uploaded.both.removeClass('hidden'); + + attachment.element = $( '' ) + .data( 'customizeImageValue', attachment.url ) + .append( '' ) + .appendTo( this.tabs.uploaded.target ); + } + }, + thumbnailSrc: function( to ) { + if ( /^(https?:)?\/\//.test( to ) ) + this.thumbnail.prop( 'src', to ).show(); + else + this.thumbnail.hide(); + } + }); + + // Change objects contained within the main customize object to Settings. + api.defaultConstructor = api.Setting; + + // Create the collection of Control objects. + api.control = new api.Values({ defaultConstructor: api.Control }); + + api.PreviewFrame = api.Messenger.extend({ + sensitivity: 2000, + + initialize: function( params, options ) { + var deferred = $.Deferred(), + self = this; + + // This is the promise object. + deferred.promise( this ); + + this.container = params.container; + this.signature = params.signature; + + $.extend( params, { channel: api.PreviewFrame.uuid() }); + + api.Messenger.prototype.initialize.call( this, params, options ); + + this.add( 'previewUrl', params.previewUrl ); + + this.query = $.extend( params.query || {}, { customize_messenger_channel: this.channel() }); + + this.run( deferred ); + }, + + run: function( deferred ) { + var self = this, + loaded = false, + ready = false; + + if ( this._ready ) + this.unbind( 'ready', this._ready ); + + this._ready = function() { + ready = true; + + if ( loaded ) + deferred.resolveWith( self ); + }; + + this.bind( 'ready', this._ready ); + + this.request = $.ajax( this.previewUrl(), { + type: 'POST', + data: this.query, + xhrFields: { + withCredentials: true + } + } ); + + this.request.fail( function() { + deferred.rejectWith( self, [ 'request failure' ] ); + }); + + this.request.done( function( response ) { + var location = self.request.getResponseHeader('Location'), + signature = self.signature, + index; + + // Check if the location response header differs from the current URL. + // If so, the request was redirected; try loading the requested page. + if ( location && location != self.previewUrl() ) { + deferred.rejectWith( self, [ 'redirect', location ] ); + return; + } + + // Check if the user is not logged in. + if ( '0' === response ) { + self.login( deferred ); + return; + } + + // Check for cheaters. + if ( '-1' === response ) { + deferred.rejectWith( self, [ 'cheatin' ] ); + return; + } + + // Check for a signature in the request. + index = response.lastIndexOf( signature ); + if ( -1 === index || index < response.lastIndexOf('') ) { + deferred.rejectWith( self, [ 'unsigned' ] ); + return; + } + + // Strip the signature from the request. + response = response.slice( 0, index ) + response.slice( index + signature.length ); + + // Create the iframe and inject the html content. + self.iframe = $('