]> scripts.mit.edu Git - autoinstalls/wordpress.git/blobdiff - wp-admin/js/customize-controls.js
WordPress 4.0
[autoinstalls/wordpress.git] / wp-admin / js / customize-controls.js
index 96f776744fe76732b7990b8b974f9b23a5af78c3..85b171dbe9ae083599937e1e28323b378038c205 100644 (file)
@@ -1,15 +1,18 @@
+/* globals _wpCustomizeHeader, _wpMediaViewsL10n */
 (function( exports, $ ){
        var api = wp.customize;
 
-       /*
+       /**
+        * @constructor
+        * @augments wp.customize.Value
+        * @augments wp.customize.Class
+        *
         * @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;
                }
        });
 
+       /**
+        * @constructor
+        * @augments wp.customize.Class
+        */
        api.Control = api.Class.extend({
                initialize: function( id, options ) {
                        var control = this,
@@ -36,8 +43,9 @@
                        $.extend( this, options || {} );
 
                        this.id = id;
-                       this.selector = '#customize-control-' + id.replace( ']', '' ).replace( '[', '-' );
+                       this.selector = '#customize-control-' + id.replace( /\]/g, '' ).replace( /\[/g, '-' );
                        this.container = $( this.selector );
+                       this.active = new api.Value( this.params.active );
 
                        settings = $.map( this.params.settings, function( value ) {
                                return value;
                                        element.set( setting() );
                                });
                        });
+
+                       control.active.bind( function ( active ) {
+                               control.toggle( active );
+                       } );
+                       control.toggle( control.active() );
                },
 
+               /**
+                * @abstract
+                */
                ready: function() {},
 
+               /**
+                * Callback for change to the control's active state.
+                *
+                * Override function for custom behavior for the control being active/inactive.
+                *
+                * @param {Boolean} active
+                */
+               toggle: function ( active ) {
+                       if ( active ) {
+                               this.container.slideDown();
+                       } else {
+                               this.container.slideUp();
+                       }
+               },
+
                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 ] )
+                       var control      = this,
+                               statuses     = this.container.find('.dropdown-status'),
+                               params       = this.params,
+                               toggleFreeze = false,
+                               update       = function( to ) {
+                                       if ( typeof to === 'string' && params.statuses && params.statuses[ to ] )
                                                statuses.html( params.statuses[ to ] ).show();
                                        else
                                                statuses.hide();
                                };
 
-                       var toggleFreeze = false;
-
                        // Support the .dropdown class to open/close complex elements
                        this.container.on( 'click keydown', '.dropdown', function( event ) {
                                if ( event.type === 'keydown' &&  13 !== event.which ) // enter
                }
        });
 
+       /**
+        * @constructor
+        * @augments wp.customize.Control
+        * @augments wp.customize.Class
+        */
        api.ColorControl = api.Control.extend({
                ready: function() {
                        var control = this,
                                picker = this.container.find('.color-picker-hex');
 
                        picker.val( control.setting() ).wpColorPicker({
-                               change: function( event, options ) {
+                               change: function() {
                                        control.setting.set( picker.wpColorPicker('color') );
-                               },
-                               clear: function() {
-                                       control.setting.set( false );
-                               }
+                               },
+                               clear: function() {
+                                       control.setting.set( false );
+                               }
                        });
                }
        });
 
+       /**
+        * @constructor
+        * @augments wp.customize.Control
+        * @augments wp.customize.Class
+        */
        api.UploadControl = api.Control.extend({
                ready: function() {
                        var control = this;
                }
        });
 
+       /**
+        * @constructor
+        * @augments wp.customize.UploadControl
+        * @augments wp.customize.Control
+        * @augments wp.customize.Class
+        */
        api.ImageControl = api.UploadControl.extend({
                ready: function() {
                        var control = this,
                                panels;
 
                        this.uploader = {
-                               init: function( up ) {
+                               init: function() {
                                        var fallback, button;
 
                                        if ( this.supports.dragdrop )
                }
        });
 
+       /**
+        * @constructor
+        * @augments wp.customize.Control
+        * @augments wp.customize.Class
+        */
+       api.HeaderControl = api.Control.extend({
+               ready: function() {
+                       this.btnRemove        = $('#customize-control-header_image .actions .remove');
+                       this.btnNew           = $('#customize-control-header_image .actions .new');
+
+                       _.bindAll(this, 'openMedia', 'removeImage');
+
+                       this.btnNew.on( 'click', this.openMedia );
+                       this.btnRemove.on( 'click', this.removeImage );
+
+                       api.HeaderTool.currentHeader = new api.HeaderTool.ImageModel();
+
+                       new api.HeaderTool.CurrentView({
+                               model: api.HeaderTool.currentHeader,
+                               el: '.current .container'
+                       });
+
+                       new api.HeaderTool.ChoiceListView({
+                               collection: api.HeaderTool.UploadsList = new api.HeaderTool.ChoiceList(),
+                               el: '.choices .uploaded .list'
+                       });
+
+                       new api.HeaderTool.ChoiceListView({
+                               collection: api.HeaderTool.DefaultsList = new api.HeaderTool.DefaultsList(),
+                               el: '.choices .default .list'
+                       });
+
+                       api.HeaderTool.combinedList = api.HeaderTool.CombinedList = new api.HeaderTool.CombinedList([
+                               api.HeaderTool.UploadsList,
+                               api.HeaderTool.DefaultsList
+                       ]);
+               },
+
+               /**
+                * Returns a set of options, computed from the attached image data and
+                * theme-specific data, to be fed to the imgAreaSelect plugin in
+                * wp.media.view.Cropper.
+                *
+                * @param {wp.media.model.Attachment} attachment
+                * @param {wp.media.controller.Cropper} controller
+                * @returns {Object} Options
+                */
+               calculateImageSelectOptions: function(attachment, controller) {
+                       var xInit = parseInt(_wpCustomizeHeader.data.width, 10),
+                               yInit = parseInt(_wpCustomizeHeader.data.height, 10),
+                               flexWidth = !! parseInt(_wpCustomizeHeader.data['flex-width'], 10),
+                               flexHeight = !! parseInt(_wpCustomizeHeader.data['flex-height'], 10),
+                               ratio, xImg, yImg, realHeight, realWidth,
+                               imgSelectOptions;
+
+                       realWidth = attachment.get('width');
+                       realHeight = attachment.get('height');
+
+                       this.headerImage = new api.HeaderTool.ImageModel();
+                       this.headerImage.set({
+                               themeWidth: xInit,
+                               themeHeight: yInit,
+                               themeFlexWidth: flexWidth,
+                               themeFlexHeight: flexHeight,
+                               imageWidth: realWidth,
+                               imageHeight: realHeight
+                       });
+
+                       controller.set( 'canSkipCrop', ! this.headerImage.shouldBeCropped() );
+
+                       ratio = xInit / yInit;
+                       xImg = realWidth;
+                       yImg = realHeight;
+
+                       if ( xImg / yImg > ratio ) {
+                               yInit = yImg;
+                               xInit = yInit * ratio;
+                       } else {
+                               xInit = xImg;
+                               yInit = xInit / ratio;
+                       }
+
+                       imgSelectOptions = {
+                               handles: true,
+                               keys: true,
+                               instance: true,
+                               persistent: true,
+                               imageWidth: realWidth,
+                               imageHeight: realHeight,
+                               x1: 0,
+                               y1: 0,
+                               x2: xInit,
+                               y2: yInit
+                       };
+
+                       if (flexHeight === false && flexWidth === false) {
+                               imgSelectOptions.aspectRatio = xInit + ':' + yInit;
+                       }
+                       if (flexHeight === false ) {
+                               imgSelectOptions.maxHeight = yInit;
+                       }
+                       if (flexWidth === false ) {
+                               imgSelectOptions.maxWidth = xInit;
+                       }
+
+                       return imgSelectOptions;
+               },
+
+               /**
+                * Sets up and opens the Media Manager in order to select an image.
+                * Depending on both the size of the image and the properties of the
+                * current theme, a cropping step after selection may be required or
+                * skippable.
+                *
+                * @param {event} event
+                */
+               openMedia: function(event) {
+                       var l10n = _wpMediaViewsL10n;
+
+                       event.preventDefault();
+
+                       this.frame = wp.media({
+                               button: {
+                                       text: l10n.selectAndCrop,
+                                       close: false
+                               },
+                               states: [
+                                       new wp.media.controller.Library({
+                                               title:     l10n.chooseImage,
+                                               library:   wp.media.query({ type: 'image' }),
+                                               multiple:  false,
+                                               priority:  20,
+                                               suggestedWidth: _wpCustomizeHeader.data.width,
+                                               suggestedHeight: _wpCustomizeHeader.data.height
+                                       }),
+                                       new wp.media.controller.Cropper({
+                                               imgSelectOptions: this.calculateImageSelectOptions
+                                       })
+                               ]
+                       });
+
+                       this.frame.on('select', this.onSelect, this);
+                       this.frame.on('cropped', this.onCropped, this);
+                       this.frame.on('skippedcrop', this.onSkippedCrop, this);
+
+                       this.frame.open();
+               },
+
+               onSelect: function() {
+                       this.frame.setState('cropper');
+               },
+               onCropped: function(croppedImage) {
+                       var url = croppedImage.post_content,
+                               attachmentId = croppedImage.attachment_id,
+                               w = croppedImage.width,
+                               h = croppedImage.height;
+                       this.setImageFromURL(url, attachmentId, w, h);
+               },
+               onSkippedCrop: function(selection) {
+                       var url = selection.get('url'),
+                               w = selection.get('width'),
+                               h = selection.get('height');
+                       this.setImageFromURL(url, selection.id, w, h);
+               },
+
+               /**
+                * Creates a new wp.customize.HeaderTool.ImageModel from provided
+                * header image data and inserts it into the user-uploaded headers
+                * collection.
+                *
+                * @param {String} url
+                * @param {Number} attachmentId
+                * @param {Number} width
+                * @param {Number} height
+                */
+               setImageFromURL: function(url, attachmentId, width, height) {
+                       var choice, data = {};
+
+                       data.url = url;
+                       data.thumbnail_url = url;
+                       data.timestamp = _.now();
+
+                       if (attachmentId) {
+                               data.attachment_id = attachmentId;
+                       }
+
+                       if (width) {
+                               data.width = width;
+                       }
+
+                       if (height) {
+                               data.height = height;
+                       }
+
+                       choice = new api.HeaderTool.ImageModel({
+                               header: data,
+                               choice: url.split('/').pop()
+                       });
+                       api.HeaderTool.UploadsList.add(choice);
+                       api.HeaderTool.currentHeader.set(choice.toJSON());
+                       choice.save();
+                       choice.importImage();
+               },
+
+               /**
+                * Triggers the necessary events to deselect an image which was set as
+                * the currently selected one.
+                */
+               removeImage: function() {
+                       api.HeaderTool.currentHeader.trigger('hide');
+                       api.HeaderTool.CombinedList.trigger('control:removeImage');
+               }
+
+       });
+
        // 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 });
 
+       /**
+        * @constructor
+        * @augments wp.customize.Messenger
+        * @augments wp.customize.Class
+        * @mixes wp.customize.Events
+        */
        api.PreviewFrame = api.Messenger.extend({
                sensitivity: 2000,
 
                initialize: function( params, options ) {
-                       var deferred = $.Deferred(),
-                               self     = this;
+                       var deferred = $.Deferred();
 
                        // This is the promise object.
                        deferred.promise( this );
 
                        this.bind( 'ready', this._ready );
 
+                       this.bind( 'ready', function ( data ) {
+                               if ( ! data || ! data.activeControls ) {
+                                       return;
+                               }
+
+                               $.each( data.activeControls, function ( id, active ) {
+                                       var control = api.control( id );
+                                       if ( control ) {
+                                               control.active( active );
+                                       }
+                               } );
+                       } );
+
                        this.request = $.ajax( this.previewUrl(), {
                                type: 'POST',
                                data: this.query,
 
        (function(){
                var uuid = 0;
+               /**
+                * Create a universally unique identifier.
+                *
+                * @return {int}
+                */
                api.PreviewFrame.uuid = function() {
                        return 'preview-' + uuid++;
                };
        }());
 
+       /**
+        * @constructor
+        * @augments wp.customize.Messenger
+        * @augments wp.customize.Class
+        * @mixes wp.customize.Events
+        */
        api.Previewer = api.Messenger.extend({
                refreshBuffer: 250,
 
                 */
                initialize: function( params, options ) {
                        var self = this,
-                               rscheme = /^https?/,
-                               url;
+                               rscheme = /^https?/;
 
                        $.extend( this, options || {} );
 
 
                                // Check for URLs that include "/wp-admin/" or end in "/wp-admin".
                                // Strip hashes and query strings before testing.
-                               if ( /\/wp-admin(\/|$)/.test( to.replace(/[#?].*$/, '') ) )
+                               if ( /\/wp-admin(\/|$)/.test( to.replace( /[#?].*$/, '' ) ) )
                                        return null;
 
                                // Attempt to match the URL to the control frame's scheme
                                // and check if it's allowed. If not, try the original URL.
                                $.each([ to.replace( rscheme, self.scheme() ), to ], function( i, url ) {
                                        $.each( self.allowedUrls, function( i, allowed ) {
-                                               if ( 0 === url.indexOf( allowed ) ) {
+                                               var path;
+
+                                               allowed = allowed.replace( /\/+$/, '' );
+                                               path = url.replace( allowed, '' );
+
+                                               if ( 0 === url.indexOf( allowed ) && /^([/#?]|$)/.test( path ) ) {
                                                        result = url;
                                                        return false;
                                                }
                }
        });
 
-       /* =====================================================================
-        * Ready.
-        * ===================================================================== */
-
        api.controlConstructor = {
                color:  api.ColorControl,
                upload: api.UploadControl,
-               image:  api.ImageControl
+               image:  api.ImageControl,
+               header: api.HeaderControl
        };
 
        $( function() {
                if ( ! $.support.postMessage || ( ! $.support.cors && api.settings.isCrossDomain ) )
                        return window.location = api.settings.url.fallback;
 
-               var body = $( document.body ),
-                       overlay = body.children('.wp-full-overlay'),
-                       query, previewer, parent;
+               var parent, topFocus,
+                       body = $( document.body ),
+                       overlay = body.children( '.wp-full-overlay' ),
+                       title = $( '#customize-info .theme-name.site-title' ),
+                       closeBtn = $( '.customize-controls-close' ),
+                       saveBtn = $( '#save' );
 
-               // Prevent the form from saving when enter is pressed.
+               // Prevent the form from saving when enter is pressed on an input or select element.
                $('#customize-controls').on( 'keydown', function( e ) {
-                       if ( $( e.target ).is('textarea') )
-                               return;
+                       var isEnter = ( 13 === e.which ),
+                               $el = $( e.target );
 
-                       if ( 13 === e.which ) // Enter
+                       if ( isEnter && ( $el.is( 'input:not([type=button])' ) || $el.is( 'select' ) ) ) {
                                e.preventDefault();
+                       }
                });
 
                // Initialize Previewer
-               previewer = new api.Previewer({
+               api.previewer = new api.Previewer({
                        container:   '#customize-preview',
                        form:        '#customize-controls',
                        previewUrl:  api.settings.url.preview,
                        query: function() {
                                return {
                                        wp_customize: 'on',
-                                       theme:        api.settings.theme.stylesheet,
-                                       customized:   JSON.stringify( api.get() ),
-                                       nonce:        this.nonce.preview
+                                       theme:      api.settings.theme.stylesheet,
+                                       customized: JSON.stringify( api.get() ),
+                                       nonce:      this.nonce.preview
                                };
                        },
 
                                        query = $.extend( this.query(), {
                                                action: 'customize_save',
                                                nonce:  this.nonce.save
-                                       }),
-                                       request = $.post( api.settings.url.ajax, query );
-
-                               api.trigger( 'save', request );
-
-                               body.addClass('saving');
+                                       } ),
+                                       processing = api.state( 'processing' ),
+                                       submitWhenDoneProcessing,
+                                       submit;
+
+                               body.addClass( 'saving' );
+
+                               submit = function () {
+                                       var request = $.post( api.settings.url.ajax, query );
+
+                                       api.trigger( 'save', request );
+
+                                       request.always( function () {
+                                               body.removeClass( 'saving' );
+                                       } );
+
+                                       request.done( function( response ) {
+                                               // Check if the user is logged out.
+                                               if ( '0' === response ) {
+                                                       self.preview.iframe.hide();
+                                                       self.login().done( function() {
+                                                               self.save();
+                                                               self.preview.iframe.show();
+                                                       } );
+                                                       return;
+                                               }
 
-                               request.always( function() {
-                                       body.removeClass('saving');
-                               });
+                                               // Check for cheaters.
+                                               if ( '-1' === response ) {
+                                                       self.cheatin();
+                                                       return;
+                                               }
 
-                               request.done( function( response ) {
-                                       // Check if the user is logged out.
-                                       if ( '0' === response ) {
-                                               self.preview.iframe.hide();
-                                               self.login().done( function() {
-                                                       self.save();
-                                                       self.preview.iframe.show();
-                                               });
-                                               return;
-                                       }
+                                               api.trigger( 'saved' );
+                                       } );
+                               };
 
-                                       // Check for cheaters.
-                                       if ( '-1' === response ) {
-                                               self.cheatin();
-                                               return;
-                                       }
+                               if ( 0 === processing() ) {
+                                       submit();
+                               } else {
+                                       submitWhenDoneProcessing = function () {
+                                               if ( 0 === processing() ) {
+                                                       api.state.unbind( 'change', submitWhenDoneProcessing );
+                                                       submit();
+                                               }
+                                       };
+                                       api.state.bind( 'change', submitWhenDoneProcessing );
+                               }
 
-                                       api.trigger( 'saved' );
-                               });
                        }
                });
 
                // Refresh the nonces if the preview sends updated nonces over.
-               previewer.bind( 'nonce', function( nonce ) {
-                       $.extend( this.nonce, nonce );
-               });
+               api.previewer.bind( 'nonce', function( nonce ) {
+                       $.extend( this.nonce, nonce );
+               });
 
                $.each( api.settings.settings, function( id, data ) {
                        api.create( id, id, data.value, {
                                transport: data.transport,
-                               previewer: previewer
+                               previewer: api.previewer
                        } );
                });
 
 
                        control = api.control.add( id, new constructor( id, {
                                params: data,
-                               previewer: previewer
+                               previewer: api.previewer
                        } ) );
                });
 
                // Check if preview url is valid and load the preview frame.
-               if ( previewer.previewUrl() )
-                       previewer.refresh();
-               else
-                       previewer.previewUrl( api.settings.url.home );
+               if ( api.previewer.previewUrl() ) {
+                       api.previewer.refresh();
+               } else {
+                       api.previewer.previewUrl( api.settings.url.home );
+               }
 
                // Save and activated states
                (function() {
                        var state = new api.Values(),
-                               saved = state.create('saved'),
-                               activated = state.create('activated');
+                               saved = state.create( 'saved' ),
+                               activated = state.create( 'activated' ),
+                               processing = state.create( 'processing' );
 
                        state.bind( 'change', function() {
-                               var save = $('#save'),
-                                       back = $('.back');
-
                                if ( ! activated() ) {
-                                       save.val( api.l10n.activate ).prop( 'disabled', false );
-                                       back.text( api.l10n.cancel );
+                                       saveBtn.val( api.l10n.activate ).prop( 'disabled', false );
+                                       closeBtn.find( '.screen-reader-text' ).text( api.l10n.cancel );
 
                                } else if ( saved() ) {
-                                       save.val( api.l10n.saved ).prop( 'disabled', true );
-                                       back.text( api.l10n.close );
+                                       saveBtn.val( api.l10n.saved ).prop( 'disabled', true );
+                                       closeBtn.find( '.screen-reader-text' ).text( api.l10n.close );
 
                                } else {
-                                       save.val( api.l10n.save ).prop( 'disabled', false );
-                                       back.text( api.l10n.cancel );
+                                       saveBtn.val( api.l10n.save ).prop( 'disabled', false );
+                                       closeBtn.find( '.screen-reader-text' ).text( api.l10n.cancel );
                                }
                        });
 
                        // Set default states.
                        saved( true );
                        activated( api.settings.theme.active );
+                       processing( 0 );
 
                        api.bind( 'change', function() {
                                state('saved').set( false );
                        api.state = state;
                }());
 
-               // Temporary accordion code.
-               $('.customize-section-title').bind('click keydown', function( event ) {
-
-                       if ( event.type === 'keydown' &&  13 !== event.which ) // enter
-                                       return;
-
-                       var clicked = $( this ).parents( '.customize-section' );
-
-                       if ( clicked.hasClass('cannot-expand') )
-                               return;
-
-                       // Scroll up if on #customize-section-title_tagline
-                       if ('customize-section-title_tagline' === clicked.attr('id'))
-                               $('.wp-full-overlay-sidebar-content').scrollTop(0);
-
-                       $( '.customize-section' ).not( clicked ).removeClass( 'open' );
-                       clicked.toggleClass( 'open' );
-                       event.preventDefault();
-               });
-
                // Button bindings.
-               $('#save').click( function( event ) {
-                       previewer.save();
+               saveBtn.click( function( event ) {
+                       api.previewer.save();
                        event.preventDefault();
                }).keydown( function( event ) {
                        if ( 9 === event.which ) // tab
                                return;
                        if ( 13 === event.which ) // enter
-                               previewer.save();
+                               api.previewer.save();
                        event.preventDefault();
                });
 
-               $('.back').keydown( function( event ) {
+               closeBtn.keydown( function( event ) {
                        if ( 9 === event.which ) // tab
                                return;
                        if ( 13 === event.which ) // enter
-                               parent.send( 'close' );
+                               this.click();
                        event.preventDefault();
                });
 
+               $('.upload-dropzone a.upload').keydown( function( event ) {
+                       if ( 13 === event.which ) // enter
+                               this.click();
+               });
+
                $('.collapse-sidebar').on( 'click keydown', function( event ) {
                        if ( event.type === 'keydown' &&  13 !== event.which ) // enter
                                return;
                        event.preventDefault();
                });
 
+               // Bind site title display to the corresponding field.
+               if ( title.length ) {
+                       $( '#customize-control-blogname input' ).on( 'input', function() {
+                               title.text(  this.value );
+                       } );
+               }
+
                // Create a potential postMessage connection with the parent frame.
                parent = new api.Messenger({
                        url: api.settings.url.parent,
                // If we receive a 'back' event, we're inside an iframe.
                // Send any clicks to the 'Return' link to the parent page.
                parent.bind( 'back', function() {
-                       $('.back').on( 'click.back', function( event ) {
+                       closeBtn.on( 'click.customize-controls-close', function( event ) {
                                event.preventDefault();
                                parent.send( 'close' );
                        });
                });
 
+               // Prompt user with AYS dialog if leaving the Customizer with unsaved changes
+               $( window ).on( 'beforeunload', function () {
+                       if ( ! api.state( 'saved' )() ) {
+                               return api.l10n.saveAlert;
+                       }
+               } );
+
                // Pass events through to the parent.
-               api.bind( 'saved', function() {
-                       parent.send( 'saved' );
-               });
+               $.each( [ 'saved', 'change' ], function ( i, event ) {
+                       api.bind( event, function() {
+                               parent.send( event );
+                       });
+               } );
 
                // When activated, let the loader handle redirecting the page.
                // If no loader exists, redirect the page ourselves (if a url exists).
                $.each({
                        'background_image': {
                                controls: [ 'background_repeat', 'background_position_x', 'background_attachment' ],
-                               callback: function( to ) { return !! to }
+                               callback: function( to ) { return !! to; }
                        },
                        'show_on_front': {
                                controls: [ 'page_on_front', 'page_for_posts' ],
-                               callback: function( to ) { return 'page' === to }
+                               callback: function( to ) { return 'page' === to; }
                        },
                        'header_textcolor': {
                                controls: [ 'header_textcolor' ],
-                               callback: function( to ) { return 'blank' !== to }
+                               callback: function( to ) { return 'blank' !== to; }
                        }
                }, function( settingId, o ) {
                        api( settingId, function( setting ) {
                        });
                });
 
-               // Handle header image data
-               api.control( 'header_image', function( control ) {
-                       control.setting.bind( function( to ) {
-                               if ( to === control.params.removed )
-                                       control.settings.data.set( false );
-                       });
-
-                       control.library.on( 'click', 'a', function( event ) {
-                               control.settings.data.set( $(this).data('customizeHeaderImageData') );
-                       });
-
-                       control.uploader.success = function( attachment ) {
-                               var data;
-
-                               api.ImageControl.prototype.success.call( control, attachment );
-
-                               data = {
-                                       attachment_id: attachment.get('id'),
-                                       url:           attachment.get('url'),
-                                       thumbnail_url: attachment.get('url'),
-                                       height:        attachment.get('height'),
-                                       width:         attachment.get('width')
-                               };
-
-                               attachment.element.data( 'customizeHeaderImageData', data );
-                               control.settings.data.set( data );
-                       };
-               });
-
                api.trigger( 'ready' );
 
                // Make sure left column gets focus
-               var topFocus = $('.back');
+               topFocus = closeBtn;
                topFocus.focus();
                setTimeout(function () {
                        topFocus.focus();