Make WordPress Core

Changeset 27988


Ignore:
Timestamp:
04/07/2014 04:31:52 PM (12 years ago)
Author:
ocean90
Message:

Widget Customizer: Cleanup wp.customize.Widgets.WidgetControl.

see #27690.

Location:
trunk/src/wp-admin
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/css/customize-widgets.css

    r27985 r27988  
    9696}
    9797
    98 .control-section.accordion-section.widget-customizer-highlighted > .accordion-section-title,
    99 .customize-control-widget_form.widget-customizer-highlighted {
     98.control-section.accordion-section.highlighted > .accordion-section-title,
     99.customize-control-widget_form.highlighted {
    100100        outline: none;
    101101        -webkit-box-shadow: 0 0 2px rgba(30,140,190,0.8);
  • trunk/src/wp-admin/js/customize-widgets.js

    r27986 r27988  
    178178
    179179                        this.listenTo( this.collection, 'update', this.updateList );
     180                        this.listenTo( this.collection, 'change', this.updateList );
    180181
    181182                        this.updateList();
     
    411412                 */
    412413                ready: function() {
    413                         var control = this;
    414                         control._setupModel();
    415                         control._setupWideWidget();
    416                         control._setupControlToggle();
    417                         control._setupWidgetTitle();
    418                         control._setupReorderUI();
    419                         control._setupHighlightEffects();
    420                         control._setupUpdateUI();
    421                         control._setupRemoveUI();
     414                        this._setupModel();
     415                        this._setupWideWidget();
     416                        this._setupControlToggle();
     417                        this._setupWidgetTitle();
     418                        this._setupReorderUI();
     419                        this._setupHighlightEffects();
     420                        this._setupUpdateUI();
     421                        this._setupRemoveUI();
    422422                },
    423423
     
    426426                 */
    427427                _setupModel: function() {
    428                         var control = this, remember_saved_widget_id;
     428                        var self = this, rememberSavedWidgetId;
    429429
    430430                        api.Widgets.savedWidgetIds = api.Widgets.savedWidgetIds || [];
    431431
    432432                        // Remember saved widgets so we know which to trash (move to inactive widgets sidebar)
    433                         remember_saved_widget_id = function() {
    434                                 api.Widgets.savedWidgetIds[control.params.widget_id] = true;
     433                        rememberSavedWidgetId = function() {
     434                                api.Widgets.savedWidgetIds[self.params.widget_id] = true;
    435435                        };
    436                         api.bind( 'ready', remember_saved_widget_id );
    437                         api.bind( 'saved', remember_saved_widget_id );
    438 
    439                         control._update_count = 0;
    440                         control.is_widget_updating = false;
    441                         control.live_update_mode = true;
     436                        api.bind( 'ready', rememberSavedWidgetId );
     437                        api.bind( 'saved', rememberSavedWidgetId );
     438
     439                        this._updateCount = 0;
     440                        this.isWidgetUpdating = false;
     441                        this.liveUpdateMode = true;
    442442
    443443                        // Update widget whenever model changes
    444                         control.setting.bind( function( to, from ) {
    445                                 if ( ! _( from ).isEqual( to ) && ! control.is_widget_updating ) {
    446                                         control.updateWidget( { instance: to } );
     444                        this.setting.bind( function( to, from ) {
     445                                if ( ! _( from ).isEqual( to ) && ! self.isWidgetUpdating ) {
     446                                        self.updateWidget( { instance: to } );
    447447                                }
    448448                        } );
     
    453453                 */
    454454                _setupWideWidget: function() {
    455                         var control = this,
    456                                 widget_inside,
    457                                 widget_form,
    458                                 customize_sidebar,
    459                                 position_widget,
    460                                 theme_controls_container;
    461 
    462                         if ( ! control.params.is_wide ) {
     455                        var self = this, $widgetInside, $widgetForm, $customizeSidebar,
     456                                $themeControlsContainer, positionWidget;
     457
     458                        if ( ! this.params.is_wide ) {
    463459                                return;
    464460                        }
    465461
    466                         widget_inside = control.container.find( '.widget-inside' );
    467                         widget_form = widget_inside.find( '> .form' );
    468                         customize_sidebar = $( '.wp-full-overlay-sidebar-content:first' );
    469                         control.container.addClass( 'wide-widget-control' );
    470 
    471                         control.container.find( '.widget-content:first' ).css( {
    472                                 'max-width': control.params.width,
    473                                 'min-height': control.params.height
     462                        $widgetInside = this.container.find( '.widget-inside' );
     463                        $widgetForm = $widgetInside.find( '> .form' );
     464                        $customizeSidebar = $( '.wp-full-overlay-sidebar-content:first' );
     465                        this.container.addClass( 'wide-widget-control' );
     466
     467                        this.container.find( '.widget-content:first' ).css( {
     468                                'max-width': this.params.width,
     469                                'min-height': this.params.height
    474470                        } );
    475471
     
    483479                         * will become scrollable (overflow:auto).
    484480                         */
    485                         position_widget = function() {
    486                                 var offset_top = control.container.offset().top,
    487                                         window_height = $( window ).height(),
    488                                         form_height = widget_form.outerHeight(),
     481                        positionWidget = function() {
     482                                var offsetTop = self.container.offset().top,
     483                                        windowHeight = $( window ).height(),
     484                                        formHeight = $widgetForm.outerHeight(),
    489485                                        top;
    490                                 widget_inside.css( 'max-height', window_height );
     486                                $widgetInside.css( 'max-height', windowHeight );
    491487                                top = Math.max(
    492488                                        0, // prevent top from going off screen
    493489                                        Math.min(
    494                                                 Math.max( offset_top, 0 ), // distance widget in panel is from top of screen
    495                                                 window_height - form_height // flush up against bottom of screen
     490                                                Math.max( offsetTop, 0 ), // distance widget in panel is from top of screen
     491                                                windowHeight - formHeight // flush up against bottom of screen
    496492                                        )
    497493                                );
    498                                 widget_inside.css( 'top', top );
     494                                $widgetInside.css( 'top', top );
    499495                        };
    500496
    501                         theme_controls_container = $( '#customize-theme-controls' );
    502                         control.container.on( 'expand', function() {
    503                                 position_widget();
    504                                 customize_sidebar.on( 'scroll', position_widget );
    505                                 $( window ).on( 'resize', position_widget );
    506                                 theme_controls_container.on( 'expanded collapsed', position_widget );
    507                         } );
    508                         control.container.on( 'collapsed', function() {
    509                                 customize_sidebar.off( 'scroll', position_widget );
    510                                 $( window ).off( 'resize', position_widget );
    511                                 theme_controls_container.off( 'expanded collapsed', position_widget );
     497                        $themeControlsContainer = $( '#customize-theme-controls' );
     498                        this.container.on( 'expand', function() {
     499                                positionWidget();
     500                                $customizeSidebar.on( 'scroll', positionWidget );
     501                                $( window ).on( 'resize', positionWidget );
     502                                $themeControlsContainer.on( 'expanded collapsed', positionWidget );
     503                        } );
     504                        this.container.on( 'collapsed', function() {
     505                                $customizeSidebar.off( 'scroll', positionWidget );
     506                                $( window ).off( 'resize', positionWidget );
     507                                $themeControlsContainer.off( 'expanded collapsed', positionWidget );
    512508                        } );
    513509
     
    516512                                if ( 0 === setting.id.indexOf( 'sidebars_widgets[' ) ) {
    517513                                        setting.bind( function() {
    518                                                 if ( control.container.hasClass( 'expanded' ) ) {
    519                                                         position_widget();
     514                                                if ( self.container.hasClass( 'expanded' ) ) {
     515                                                        positionWidget();
    520516                                                }
    521517                                        } );
     
    529525                 */
    530526                _setupControlToggle: function() {
    531                         var control = this, close_btn;
    532 
    533                         control.container.find( '.widget-top' ).on( 'click', function( e ) {
     527                        var self = this, $closeBtn;
     528
     529                        this.container.find( '.widget-top' ).on( 'click', function( e ) {
    534530                                e.preventDefault();
    535                                 var sidebar_widgets_control = control.getSidebarWidgetsControl();
    536                                 if ( sidebar_widgets_control.is_reordering ) {
     531                                var sidebarWidgetsControl = self.getSidebarWidgetsControl();
     532                                if ( sidebarWidgetsControl.is_reordering ) {
    537533                                        return;
    538534                                }
    539                                 control.toggleForm();
    540                         } );
    541 
    542                         close_btn = control.container.find( '.widget-control-close' );
    543                         // @todo Hitting Enter on this link does nothing; will be resolved in core with <http://core.trac.wordpress.org/ticket/26633>
    544                         close_btn.on( 'click', function( e ) {
     535                                self.toggleForm();
     536                        } );
     537
     538                        $closeBtn = this.container.find( '.widget-control-close' );
     539                        $closeBtn.on( 'click', function( e ) {
    545540                                e.preventDefault();
    546                                 control.collapseForm();
    547                                 control.container.find( '.widget-top .widget-action:first' ).focus(); // keyboard accessibility
     541                                self.collapseForm();
     542                                self.container.find( '.widget-top .widget-action:first' ).focus(); // keyboard accessibility
    548543                        } );
    549544                },
     
    553548                 */
    554549                _setupWidgetTitle: function() {
    555                         var control = this, update_title;
    556 
    557                         update_title = function() {
    558                                 var title = control.setting().title,
    559                                         in_widget_title = control.container.find( '.in-widget-title' );
     550                        var self = this, updateTitle;
     551
     552                        updateTitle = function() {
     553                                var title = self.setting().title,
     554                                        inWidgetTitle = self.container.find( '.in-widget-title' );
    560555
    561556                                if ( title ) {
    562                                         in_widget_title.text( ': ' + title );
     557                                        inWidgetTitle.text( ': ' + title );
    563558                                } else {
    564                                         in_widget_title.text( '' );
     559                                        inWidgetTitle.text( '' );
    565560                                }
    566561                        };
    567                         control.setting.bind( update_title );
    568                         update_title();
     562                        this.setting.bind( updateTitle );
     563                        updateTitle();
    569564                },
    570565
     
    573568                 */
    574569                _setupReorderUI: function() {
    575                         var control = this,
    576                                 select_sidebar_item,
    577                                 move_widget_area,
    578                                 reorder_nav,
    579                                 update_available_sidebars;
     570                        var self = this, selectSidebarItem, $moveWidgetArea,
     571                                $reorderNav, updateAvailableSidebars;
    580572
    581573                        /**
     
    584576                         * @param {jQuery} li
    585577                         */
    586                         select_sidebar_item = function( li ) {
     578                        selectSidebarItem = function( li ) {
    587579                                li.siblings( '.selected' ).removeClass( 'selected' );
    588580                                li.addClass( 'selected' );
    589                                 var is_self_sidebar = ( li.data( 'id' ) === control.params.sidebar_id );
    590                                 control.container.find( '.move-widget-btn' ).prop( 'disabled', is_self_sidebar );
     581                                var isSelfSidebar = ( li.data( 'id' ) === self.params.sidebar_id );
     582                                self.container.find( '.move-widget-btn' ).prop( 'disabled', isSelfSidebar );
    591583                        };
    592584
     
    594586                         * Add the widget reordering elements to the widget control
    595587                         */
    596                         control.container.find( '.widget-title-action' ).after( $( api.Widgets.data.tpl.widgetReorderNav ) );
    597                         move_widget_area = $(
     588                        this.container.find( '.widget-title-action' ).after( $( api.Widgets.data.tpl.widgetReorderNav ) );
     589                        $moveWidgetArea = $(
    598590                                _.template( api.Widgets.data.tpl.moveWidgetArea, {
    599591                                        sidebars: _( api.Widgets.registeredSidebars.toArray() ).pluck( 'attributes' )
    600592                                } )
    601593                        );
    602                         control.container.find( '.widget-top' ).after( move_widget_area );
     594                        this.container.find( '.widget-top' ).after( $moveWidgetArea );
    603595
    604596                        /**
    605597                         * Update available sidebars when their rendered state changes
    606598                         */
    607                         update_available_sidebars = function() {
    608                                 var sidebar_items = move_widget_area.find( 'li' ), self_sidebar_item;
    609                                 self_sidebar_item = sidebar_items.filter( function(){
    610                                         return $( this ).data( 'id' ) === control.params.sidebar_id;
     599                        updateAvailableSidebars = function() {
     600                                var $sidebarItems = $moveWidgetArea.find( 'li' ), selfSidebarItem;
     601
     602                                selfSidebarItem = $sidebarItems.filter( function(){
     603                                        return $( this ).data( 'id' ) === self.params.sidebar_id;
    611604                                } );
    612                                 sidebar_items.each( function() {
     605
     606                                $sidebarItems.each( function() {
    613607                                        var li = $( this ),
    614                                                 sidebar_id,
     608                                                sidebarId,
    615609                                                sidebar_model;
    616610
    617                                         sidebar_id = li.data( 'id' );
    618                                         sidebar_model = api.Widgets.registeredSidebars.get( sidebar_id );
     611                                        sidebarId = li.data( 'id' );
     612                                        sidebar_model = api.Widgets.registeredSidebars.get( sidebarId );
     613
    619614                                        li.toggle( sidebar_model.get( 'is_rendered' ) );
     615
    620616                                        if ( li.hasClass( 'selected' ) && ! sidebar_model.get( 'is_rendered' ) ) {
    621                                                 select_sidebar_item( self_sidebar_item );
     617                                                selectSidebarItem( selfSidebarItem );
    622618                                        }
    623619                                } );
    624620                        };
    625                         update_available_sidebars();
    626                         api.Widgets.registeredSidebars.on( 'change:is_rendered', update_available_sidebars );
     621
     622                        updateAvailableSidebars();
     623                        api.Widgets.registeredSidebars.on( 'change:is_rendered', updateAvailableSidebars );
    627624
    628625                        /**
    629626                         * Handle clicks for up/down/move on the reorder nav
    630627                         */
    631                         reorder_nav = control.container.find( '.widget-reorder-nav' );
    632                         reorder_nav.find( '.move-widget, .move-widget-down, .move-widget-up' ).on( 'click keypress', function( event ) {
     628                        $reorderNav = this.container.find( '.widget-reorder-nav' );
     629                        $reorderNav.find( '.move-widget, .move-widget-down, .move-widget-up' ).on( 'click keypress', function( event ) {
    633630                                if ( event.type === 'keypress' && ( event.which !== 13 && event.which !== 32 ) ) {
    634631                                        return;
     
    637634
    638635                                if ( $( this ).is( '.move-widget' ) ) {
    639                                         control.toggleWidgetMoveArea();
     636                                        self.toggleWidgetMoveArea();
    640637                                } else {
    641                                         var is_move_down = $( this ).is( '.move-widget-down' ),
    642                                                 is_move_up = $( this ).is( '.move-widget-up' ),
    643                                                 i = control.getWidgetSidebarPosition();
    644 
    645                                         if ( ( is_move_up && i === 0 ) || ( is_move_down && i === control.getSidebarWidgetsControl().setting().length - 1 ) ) {
     638                                        var isMoveDown = $( this ).is( '.move-widget-down' ),
     639                                                isMoveUp = $( this ).is( '.move-widget-up' ),
     640                                                i = self.getWidgetSidebarPosition();
     641
     642                                        if ( ( isMoveUp && i === 0 ) || ( isMoveDown && i === self.getSidebarWidgetsControl().setting().length - 1 ) ) {
    646643                                                return;
    647644                                        }
    648645
    649                                         if ( is_move_up ) {
    650                                                 control.moveUp();
     646                                        if ( isMoveUp ) {
     647                                                self.moveUp();
    651648                                        } else {
    652                                                 control.moveDown();
     649                                                self.moveDown();
    653650                                        }
    654651
     
    660657                         * Handle selecting a sidebar to move to
    661658                         */
    662                         control.container.find( '.widget-area-select' ).on( 'click keypress', 'li', function( e ) {
     659                        this.container.find( '.widget-area-select' ).on( 'click keypress', 'li', function( e ) {
    663660                                if ( event.type === 'keypress' && ( event.which !== 13 && event.which !== 32 ) ) {
    664661                                        return;
    665662                                }
    666663                                e.preventDefault();
    667                                 select_sidebar_item( $( this ) );
     664                                selectSidebarItem( $( this ) );
    668665                        } );
    669666
     
    671668                         * Move widget to another sidebar
    672669                         */
    673                         control.container.find( '.move-widget-btn' ).click( function() {
    674                                 control.getSidebarWidgetsControl().toggleReordering( false );
    675 
    676                                 var old_sidebar_id = control.params.sidebar_id,
    677                                         new_sidebar_id = control.container.find( '.widget-area-select li.selected' ).data( 'id' ),
    678                                         old_sidebar_widgets_setting,
    679                                         new_sidebar_widgets_setting,
    680                                         old_sidebar_widget_ids,
    681                                         new_sidebar_widget_ids,
    682                                         i;
    683 
    684                                 old_sidebar_widgets_setting = api( 'sidebars_widgets[' + old_sidebar_id + ']' );
    685                                 new_sidebar_widgets_setting = api( 'sidebars_widgets[' + new_sidebar_id + ']' );
    686                                 old_sidebar_widget_ids = Array.prototype.slice.call( old_sidebar_widgets_setting() );
    687                                 new_sidebar_widget_ids = Array.prototype.slice.call( new_sidebar_widgets_setting() );
    688 
    689                                 i = control.getWidgetSidebarPosition();
    690                                 old_sidebar_widget_ids.splice( i, 1 );
    691                                 new_sidebar_widget_ids.push( control.params.widget_id );
    692 
    693                                 old_sidebar_widgets_setting( old_sidebar_widget_ids );
    694                                 new_sidebar_widgets_setting( new_sidebar_widget_ids );
    695 
    696                                 control.focus();
     670                        this.container.find( '.move-widget-btn' ).click( function() {
     671                                self.getSidebarWidgetsControl().toggleReordering( false );
     672
     673                                var oldSidebarId = self.params.sidebar_id,
     674                                        newSidebarId = self.container.find( '.widget-area-select li.selected' ).data( 'id' ),
     675                                        oldSidebarWidgetsSetting, newSidebarWidgetsSetting,
     676                                        oldSidebarWidgetIds, newSidebarWidgetIds, i;
     677
     678                                oldSidebarWidgetsSetting = api( 'sidebars_widgets[' + oldSidebarId + ']' );
     679                                newSidebarWidgetsSetting = api( 'sidebars_widgets[' + newSidebarId + ']' );
     680                                oldSidebarWidgetIds = Array.prototype.slice.call( oldSidebarWidgetsSetting() );
     681                                newSidebarWidgetIds = Array.prototype.slice.call( newSidebarWidgetsSetting() );
     682
     683                                i = self.getWidgetSidebarPosition();
     684                                oldSidebarWidgetIds.splice( i, 1 );
     685                                newSidebarWidgetIds.push( self.params.widget_id );
     686
     687                                oldSidebarWidgetsSetting( oldSidebarWidgetIds );
     688                                newSidebarWidgetsSetting( newSidebarWidgetIds );
     689
     690                                self.focus();
    697691                        } );
    698692                },
     
    702696                 */
    703697                _setupHighlightEffects: function() {
    704                         var control = this;
     698                        var self = this;
    705699
    706700                        // Highlight whenever hovering or clicking over the form
    707                         control.container.on( 'mouseenter click', function() {
    708                                 control.setting.previewer.send( 'highlight-widget', control.params.widget_id );
     701                        this.container.on( 'mouseenter click', function() {
     702                                self.setting.previewer.send( 'highlight-widget', self.params.widget_id );
    709703                        } );
    710704
    711705                        // Highlight when the setting is updated
    712                         control.setting.bind( function() {
    713                                 control.setting.previewer.send( 'highlight-widget', control.params.widget_id );
    714                         } );
    715 
    716                         // Highlight when the widget form is expanded
    717                         control.container.on( 'expand', function() {
    718                                 control.scrollPreviewWidgetIntoView();
     706                        this.setting.bind( function() {
     707                                self.setting.previewer.send( 'highlight-widget', self.params.widget_id );
    719708                        } );
    720709                },
     
    724713                 */
    725714                _setupUpdateUI: function() {
    726                         var control = this,
    727                                 widget_root,
    728                                 widget_content,
    729                                 save_btn,
    730                                 update_widget_debounced,
    731                                 form_update_event_handler;
    732 
    733                         widget_root = control.container.find( '.widget:first' );
    734                         widget_content = widget_root.find( '.widget-content:first' );
     715                        var self = this, $widgetRoot, $widgetContent,
     716                                $saveBtn, updateWidgetDebounced, formSyncHandler;
     717
     718                        $widgetRoot = this.container.find( '.widget:first' );
     719                        $widgetContent = $widgetRoot.find( '.widget-content:first' );
    735720
    736721                        // Configure update button
    737                         save_btn = control.container.find( '.widget-control-save' );
    738                         save_btn.val( l10n.saveBtnLabel );
    739                         save_btn.attr( 'title', l10n.saveBtnTooltip );
    740                         save_btn.removeClass( 'button-primary' ).addClass( 'button-secondary' );
    741                         save_btn.on( 'click', function( e ) {
     722                        $saveBtn = this.container.find( '.widget-control-save' );
     723                        $saveBtn.val( l10n.saveBtnLabel );
     724                        $saveBtn.attr( 'title', l10n.saveBtnTooltip );
     725                        $saveBtn.removeClass( 'button-primary' ).addClass( 'button-secondary' );
     726                        $saveBtn.on( 'click', function( e ) {
    742727                                e.preventDefault();
    743                                 control.updateWidget( { disable_form: true } );
    744                         } );
    745 
    746                         update_widget_debounced = _.debounce( function() {
    747                                 // @todo For compatibility with other plugins, should we trigger a click event? What about form submit event?
    748                                 control.updateWidget();
     728                                self.updateWidget( { disable_form: true } );
     729                        } );
     730
     731                        updateWidgetDebounced = _.debounce( function() {
     732                                self.updateWidget();
    749733                        }, 250 );
    750734
    751735                        // Trigger widget form update when hitting Enter within an input
    752                         control.container.find( '.widget-content' ).on( 'keydown', 'input', function( e ) {
     736                        this.container.find( '.widget-content' ).on( 'keydown', 'input', function( e ) {
    753737                                if ( 13 === e.which ) { // Enter
    754738                                        e.preventDefault();
    755                                         control.updateWidget( { ignore_active_element: true } );
     739                                        self.updateWidget( { ignore_active_element: true } );
    756740                                }
    757741                        } );
    758742
    759743                        // Handle widgets that support live previews
    760                         widget_content.on( 'change input propertychange', ':input', function( e ) {
    761                                 if ( control.live_update_mode ) {
     744                        $widgetContent.on( 'change input propertychange', ':input', function( e ) {
     745                                if ( self.liveUpdateMode ) {
    762746                                        if ( e.type === 'change' ) {
    763                                                 control.updateWidget();
     747                                                self.updateWidget();
    764748                                        } else if ( this.checkValidity && this.checkValidity() ) {
    765                                                 update_widget_debounced();
     749                                                updateWidgetDebounced();
    766750                                        }
    767751                                }
     
    769753
    770754                        // Remove loading indicators when the setting is saved and the preview updates
    771                         control.setting.previewer.channel.bind( 'synced', function() {
    772                                 control.container.removeClass( 'previewer-loading' );
    773                         } );
    774                         api.Widgets.Previewer.bind( 'widget-updated', function( updated_widget_id ) {
    775                                 if ( updated_widget_id === control.params.widget_id ) {
    776                                         control.container.removeClass( 'previewer-loading' );
    777                                 }
    778                         } );
    779 
    780                         // Update widget control to indicate whether it is currently rendered (cf. Widget Visibility)
     755                        this.setting.previewer.channel.bind( 'synced', function() {
     756                                self.container.removeClass( 'previewer-loading' );
     757                        } );
     758
     759                        api.Widgets.Previewer.bind( 'widget-updated', function( updatedWidgetId ) {
     760                                if ( updatedWidgetId === self.params.widget_id ) {
     761                                        self.container.removeClass( 'previewer-loading' );
     762                                }
     763                        } );
     764
     765                        // Update widget control to indicate whether it is currently rendered
    781766                        api.Widgets.Previewer.bind( 'rendered-widgets', function( rendered_widgets ) {
    782                                 var is_rendered = !! rendered_widgets[control.params.widget_id];
    783                                 control.container.toggleClass( 'widget-rendered', is_rendered );
    784                         } );
    785 
    786                         form_update_event_handler = api.Widgets.formSyncHandlers[ control.params.widget_id_base ];
    787                         if ( form_update_event_handler ) {
    788                                 $( document ).on( 'widget-synced', function( e, widget_el ) {
    789                                         if ( widget_root.is( widget_el ) ) {
    790                                                 form_update_event_handler.apply( document, arguments );
     767                                var is_rendered = !! rendered_widgets[self.params.widget_id];
     768                                self.container.toggleClass( 'widget-rendered', is_rendered );
     769                        } );
     770
     771                        formSyncHandler = api.Widgets.formSyncHandlers[ this.params.widget_id_base ];
     772                        if ( formSyncHandler ) {
     773                                $( document ).on( 'widget-synced', function( e, widget ) {
     774                                        if ( $widgetRoot.is( widget ) ) {
     775                                                formSyncHandler.apply( document, arguments );
    791776                                        }
    792777                                } );
     
    798783                 */
    799784                _setupRemoveUI: function() {
    800                         var control = this,
    801                                 remove_btn,
    802                                 replace_delete_with_remove;
     785                        var self = this, $removeBtn, replaceDeleteWithRemove;
    803786
    804787                        // Configure remove button
    805                         remove_btn = control.container.find( 'a.widget-control-remove' );
    806                         // @todo Hitting Enter on this link does nothing; will be resolved in core with <http://core.trac.wordpress.org/ticket/26633>
    807                         remove_btn.on( 'click', function( e ) {
     788                        $removeBtn = this.container.find( 'a.widget-control-remove' );
     789                        $removeBtn.on( 'click', function( e ) {
    808790                                e.preventDefault();
    809791
    810792                                // Find an adjacent element to add focus to when this widget goes away
    811                                 var adjacent_focus_target;
    812                                 if ( control.container.next().is( '.customize-control-widget_form' ) ) {
    813                                         adjacent_focus_target = control.container.next().find( '.widget-action:first' );
    814                                 } else if ( control.container.prev().is( '.customize-control-widget_form' ) ) {
    815                                         adjacent_focus_target = control.container.prev().find( '.widget-action:first' );
     793                                var $adjacentFocusTarget;
     794                                if ( self.container.next().is( '.customize-control-widget_form' ) ) {
     795                                        $adjacentFocusTarget = self.container.next().find( '.widget-action:first' );
     796                                } else if ( self.container.prev().is( '.customize-control-widget_form' ) ) {
     797                                        $adjacentFocusTarget = self.container.prev().find( '.widget-action:first' );
    816798                                } else {
    817                                         adjacent_focus_target = control.container.next( '.customize-control-sidebar_widgets' ).find( '.add-new-widget:first' );
    818                                 }
    819 
    820                                 control.container.slideUp( function() {
    821                                         var sidebars_widgets_control = api.Widgets.getSidebarWidgetControlContainingWidget( control.params.widget_id ),
     799                                        $adjacentFocusTarget = self.container.next( '.customize-control-sidebar_widgets' ).find( '.add-new-widget:first' );
     800                                }
     801
     802                                self.container.slideUp( function() {
     803                                        var sidebars_widgets_control = api.Widgets.getSidebarWidgetControlContainingWidget( self.params.widget_id ),
    822804                                                sidebar_widget_ids,
    823805                                                i;
    824806
    825807                                        if ( ! sidebars_widgets_control ) {
    826                                                 throw new Error( 'Unable to find sidebars_widgets_control' );
     808                                                return;
    827809                                        }
    828810                                        sidebar_widget_ids = sidebars_widgets_control.setting().slice();
    829                                         i = _.indexOf( sidebar_widget_ids, control.params.widget_id );
     811                                        i = _.indexOf( sidebar_widget_ids, self.params.widget_id );
    830812                                        if ( -1 === i ) {
    831                                                 throw new Error( 'Widget is not in sidebar' );
     813                                                return;
    832814                                        }
    833815                                        sidebar_widget_ids.splice( i, 1 );
    834816                                        sidebars_widgets_control.setting( sidebar_widget_ids );
    835                                         adjacent_focus_target.focus(); // keyboard accessibility
     817                                        $adjacentFocusTarget.focus(); // keyboard accessibility
    836818                                } );
    837819                        } );
    838820
    839                         replace_delete_with_remove = function() {
    840                                 remove_btn.text( l10n.removeBtnLabel ); // wp_widget_control() outputs the link as "Delete"
    841                                 remove_btn.attr( 'title', l10n.removeBtnTooltip );
     821                        replaceDeleteWithRemove = function() {
     822                                $removeBtn.text( l10n.removeBtnLabel ); // wp_widget_control() outputs the link as "Delete"
     823                                $removeBtn.attr( 'title', l10n.removeBtnTooltip );
    842824                        };
    843                         if ( control.params.is_new ) {
    844                                 api.bind( 'saved', replace_delete_with_remove );
     825
     826                        if ( this.params.is_new ) {
     827                                api.bind( 'saved', replaceDeleteWithRemove );
    845828                        } else {
    846                                 replace_delete_with_remove();
     829                                replaceDeleteWithRemove();
    847830                        }
    848831                },
     
    872855                 */
    873856                _getInputsSignature: function( inputs ) {
    874                         var inputs_signatures = _( inputs ).map( function( input ) {
    875                                 input = $( input );
    876                                 var signature_parts;
    877                                 if ( input.is( ':checkbox, :radio' ) ) {
    878                                         signature_parts = [ input.attr( 'id' ), input.attr( 'name' ), input.prop( 'value' ) ];
     857                        var inputsSignatures = _( inputs ).map( function( input ) {
     858                                var $input = $( input ), signatureParts;
     859
     860                                if ( $input.is( ':checkbox, :radio' ) ) {
     861                                        signatureParts = [ $input.attr( 'id' ), $input.attr( 'name' ), $input.prop( 'value' ) ];
    879862                                } else {
    880                                         signature_parts = [ input.attr( 'id' ), input.attr( 'name' ) ];
    881                                 }
    882                                 return signature_parts.join( ',' );
    883                         } );
    884                         return inputs_signatures.join( ';' );
     863                                        signatureParts = [ $input.attr( 'id' ), $input.attr( 'name' ) ];
     864                                }
     865
     866                                return signatureParts.join( ',' );
     867                        } );
     868
     869                        return inputsSignatures.join( ';' );
    885870                },
    886871
     
    893878                 */
    894879                _getInputStatePropertyName: function( input ) {
    895                         input = $( input );
    896                         if ( input.is( ':radio, :checkbox' ) ) {
     880                        var $input = $( input );
     881
     882                        if ( $input.is( ':radio, :checkbox' ) ) {
    897883                                return 'checked';
    898884                        } else {
     
    909895                 */
    910896                getSidebarWidgetsControl: function() {
    911                         var control = this, setting_id, sidebar_widgets_control;
    912 
    913                         setting_id = 'sidebars_widgets[' + control.params.sidebar_id + ']';
    914                         sidebar_widgets_control = api.control( setting_id );
    915                         if ( ! sidebar_widgets_control ) {
    916                                 throw new Error( 'Unable to locate sidebar_widgets control for ' + control.params.sidebar_id );
    917                         }
    918                         return sidebar_widgets_control;
     897                        var settingId, sidebarWidgetsControl;
     898
     899                        settingId = 'sidebars_widgets[' + this.params.sidebar_id + ']';
     900                        sidebarWidgetsControl = api.control( settingId );
     901
     902                        if ( ! sidebarWidgetsControl ) {
     903                                return;
     904                        }
     905
     906                        return sidebarWidgetsControl;
    919907                },
    920908
     
    929917                 */
    930918                updateWidget: function( args ) {
    931                         var control = this,
    932                                 instance_override,
    933                                 complete_callback,
    934                                 widget_root,
    935                                 update_number,
    936                                 widget_content,
    937                                 params,
    938                                 data,
    939                                 inputs,
    940                                 processing,
    941                                 jqxhr,
    942                                 is_changed;
     919                        var self = this, instanceOverride, completeCallback, $widgetRoot, $widgetContent,
     920                                updateNumber, params, data, $inputs, processing, jqxhr, isChanged;
    943921
    944922                        args = $.extend( {
     
    948926                        }, args );
    949927
    950                         instance_override = args.instance;
    951                         complete_callback = args.complete;
    952 
    953                         control._update_count += 1;
    954                         update_number = control._update_count;
    955 
    956                         widget_root = control.container.find( '.widget:first' );
    957                         widget_content = widget_root.find( '.widget-content:first' );
     928                        instanceOverride = args.instance;
     929                        completeCallback = args.complete;
     930
     931                        this._updateCount += 1;
     932                        updateNumber = this._updateCount;
     933
     934                        $widgetRoot = this.container.find( '.widget:first' );
     935                        $widgetContent = $widgetRoot.find( '.widget-content:first' );
    958936
    959937                        // Remove a previous error message
    960                         widget_content.find( '.widget-error' ).remove();
    961 
    962                         control.container.addClass( 'widget-form-loading' );
    963                         control.container.addClass( 'previewer-loading' );
     938                        $widgetContent.find( '.widget-error' ).remove();
     939
     940                        this.container.addClass( 'widget-form-loading' );
     941                        this.container.addClass( 'previewer-loading' );
    964942                        processing = api.state( 'processing' );
    965943                        processing( processing() + 1 );
    966944
    967                         if ( ! control.live_update_mode ) {
    968                                 control.container.addClass( 'widget-form-disabled' );
     945                        if ( ! this.liveUpdateMode ) {
     946                                this.container.addClass( 'widget-form-disabled' );
    969947                        }
    970948
     
    975953
    976954                        data = $.param( params );
    977                         inputs = control._getInputs( widget_content );
     955                        $inputs = this._getInputs( $widgetContent );
    978956
    979957                        // Store the value we're submitting in data so that when the response comes back,
    980958                        // we know if it got sanitized; if there is no difference in the sanitized value,
    981959                        // then we do not need to touch the UI and mess up the user's ongoing editing.
    982                         inputs.each( function() {
     960                        $inputs.each( function() {
    983961                                var input = $( this ),
    984                                         property = control._getInputStatePropertyName( this );
    985                                 input.data( 'state' + update_number, input.prop( property ) );
    986                         } );
    987 
    988                         if ( instance_override ) {
    989                                 data += '&' + $.param( { 'sanitized_widget_setting': JSON.stringify( instance_override ) } );
     962                                        property = self._getInputStatePropertyName( this );
     963                                input.data( 'state' + updateNumber, input.prop( property ) );
     964                        } );
     965
     966                        if ( instanceOverride ) {
     967                                data += '&' + $.param( { 'sanitized_widget_setting': JSON.stringify( instanceOverride ) } );
    990968                        } else {
    991                                 data += '&' + inputs.serialize();
    992                         }
    993                         data += '&' + widget_content.find( '~ :input' ).serialize();
    994 
    995                         jqxhr = $.post( wp.ajax.settings.url, data, function( r ) {
    996                                 var message,
    997                                         sanitized_form,
    998                                         sanitized_inputs,
    999                                         has_same_inputs_in_response,
    1000                                         is_live_update_aborted = false;
     969                                data += '&' + $inputs.serialize();
     970                        }
     971                        data += '&' + $widgetContent.find( '~ :input' ).serialize();
     972
     973                        jqxhr = $.post( wp.ajax.settings.url, data );
     974
     975                        jqxhr.done( function( r ) {
     976                                var message, sanitizedForm,     $sanitizedInputs, hasSameInputsInResponse,
     977                                        isLiveUpdateAborted = false;
    1001978
    1002979                                // Check if the user is logged out.
     
    1004981                                        api.Widgets.Previewer.preview.iframe.hide();
    1005982                                        api.Widgets.Previewer.login().done( function() {
    1006                                                 control.updateWidget( args );
     983                                                self.updateWidget( args );
    1007984                                                api.Widgets.Previewer.preview.iframe.show();
    1008985                                        } );
     
    1017994
    1018995                                if ( r.success ) {
    1019                                         sanitized_form = $( '<div>' + r.data.form + '</div>' );
    1020                                         sanitized_inputs = control._getInputs( sanitized_form );
    1021                                         has_same_inputs_in_response = control._getInputsSignature( inputs ) === control._getInputsSignature( sanitized_inputs );
     996                                        sanitizedForm = $( '<div>' + r.data.form + '</div>' );
     997                                        $sanitizedInputs = self._getInputs( sanitizedForm );
     998                                        hasSameInputsInResponse = self._getInputsSignature( $inputs ) === self._getInputsSignature( $sanitizedInputs );
    1022999
    10231000                                        // Restore live update mode if sanitized fields are now aligned with the existing fields
    1024                                         if ( has_same_inputs_in_response && ! control.live_update_mode ) {
    1025                                                 control.live_update_mode = true;
    1026                                                 control.container.removeClass( 'widget-form-disabled' );
    1027                                                 control.container.find( 'input[name="savewidget"]' ).hide();
     1001                                        if ( hasSameInputsInResponse && ! self.liveUpdateMode ) {
     1002                                                self.liveUpdateMode = true;
     1003                                                self.container.removeClass( 'widget-form-disabled' );
     1004                                                self.container.find( 'input[name="savewidget"]' ).hide();
    10281005                                        }
    10291006
    10301007                                        // Sync sanitized field states to existing fields if they are aligned
    1031                                         if ( has_same_inputs_in_response && control.live_update_mode ) {
    1032                                                 inputs.each( function( i ) {
    1033                                                         var input = $( this ),
    1034                                                                 sanitized_input = $( sanitized_inputs[i] ),
    1035                                                                 property = control._getInputStatePropertyName( this ),
    1036                                                                 submitted_state,
    1037                                                                 sanitized_state,
    1038                                                                 can_update_state;
    1039 
    1040                                                         submitted_state = input.data( 'state' + update_number );
    1041                                                         sanitized_state = sanitized_input.prop( property );
    1042                                                         input.data( 'sanitized', sanitized_state );
    1043 
    1044                                                         can_update_state = (
    1045                                                                 submitted_state !== sanitized_state &&
    1046                                                                 ( args.ignore_active_element || ! input.is( document.activeElement ) )
    1047                                                         );
    1048                                                         if ( can_update_state ) {
    1049                                                                 input.prop( property, sanitized_state );
     1008                                        if ( hasSameInputsInResponse && self.liveUpdateMode ) {
     1009                                                $inputs.each( function( i ) {
     1010                                                        var $input = $( this ),
     1011                                                                $sanitizedInput = $( $sanitizedInputs[i] ),
     1012                                                                property = self._getInputStatePropertyName( this ),
     1013                                                                submittedState, sanitizedState, canUpdateState;
     1014
     1015                                                        submittedState = $input.data( 'state' + updateNumber );
     1016                                                        sanitizedState = $sanitizedInput.prop( property );
     1017                                                        $input.data( 'sanitized', sanitizedState );
     1018
     1019                                                        canUpdateState = ( submittedState !== sanitizedState && ( args.ignore_active_element || ! $input.is( document.activeElement ) ) );
     1020                                                        if ( canUpdateState ) {
     1021                                                                $input.prop( property, sanitizedState );
    10501022                                                        }
    10511023                                                } );
    1052                                                 $( document ).trigger( 'widget-synced', [ widget_root, r.data.form ] );
     1024
     1025                                                $( document ).trigger( 'widget-synced', [ $widgetRoot, r.data.form ] );
    10531026
    10541027                                        // Otherwise, if sanitized fields are not aligned with existing fields, disable live update mode if enabled
    1055                                         } else if ( control.live_update_mode ) {
    1056                                                 control.live_update_mode = false;
    1057                                                 control.container.find( 'input[name="savewidget"]' ).show();
    1058                                                 is_live_update_aborted = true;
     1028                                        } else if ( self.liveUpdateMode ) {
     1029                                                self.liveUpdateMode = false;
     1030                                                self.container.find( 'input[name="savewidget"]' ).show();
     1031                                                isLiveUpdateAborted = true;
     1032
    10591033                                        // Otherwise, replace existing form with the sanitized form
    10601034                                        } else {
    1061                                                 widget_content.html( r.data.form );
    1062                                                 control.container.removeClass( 'widget-form-disabled' );
    1063                                                 $( document ).trigger( 'widget-updated', [ widget_root ] );
     1035                                                $widgetContent.html( r.data.form );
     1036
     1037                                                self.container.removeClass( 'widget-form-disabled' );
     1038
     1039                                                $( document ).trigger( 'widget-updated', [ $widgetRoot ] );
    10641040                                        }
    10651041
     
    10691045                                         * preview finishing loading.
    10701046                                         */
    1071                                         is_changed = ! is_live_update_aborted && ! _( control.setting() ).isEqual( r.data.instance );
    1072                                         if ( is_changed ) {
    1073                                                 control.is_widget_updating = true; // suppress triggering another updateWidget
    1074                                                 control.setting( r.data.instance );
    1075                                                 control.is_widget_updating = false;
     1047                                        isChanged = ! isLiveUpdateAborted && ! _( self.setting() ).isEqual( r.data.instance );
     1048                                        if ( isChanged ) {
     1049                                                self.isWidgetUpdating = true; // suppress triggering another updateWidget
     1050                                                self.setting( r.data.instance );
     1051                                                self.isWidgetUpdating = false;
    10761052                                        } else {
    10771053                                                // no change was made, so stop the spinner now instead of when the preview would updates
    1078                                                 control.container.removeClass( 'previewer-loading' );
    1079                                         }
    1080 
    1081                                         if ( complete_callback ) {
    1082                                                 complete_callback.call( control, null, { no_change: ! is_changed, ajax_finished: true } );
     1054                                                self.container.removeClass( 'previewer-loading' );
     1055                                        }
     1056
     1057                                        if ( completeCallback ) {
     1058                                                completeCallback.call( self, null, { no_change: ! isChanged, ajax_finished: true } );
    10831059                                        }
    10841060                                } else {
     1061                                        // General error message
    10851062                                        message = l10n.error;
     1063
    10861064                                        if ( r.data && r.data.message ) {
    10871065                                                message = r.data.message;
    10881066                                        }
    1089                                         if ( complete_callback ) {
    1090                                                 complete_callback.call( control, message );
     1067
     1068                                        if ( completeCallback ) {
     1069                                                completeCallback.call( self, message );
    10911070                                        } else {
    1092                                                 widget_content.prepend( '<p class="widget-error"><strong>' + message + '</strong></p>' );
    1093                                         }
    1094                                 }
    1095                         } );
     1071                                                $widgetContent.prepend( '<p class="widget-error"><strong>' + message + '</strong></p>' );
     1072                                        }
     1073                                }
     1074                        } );
     1075
    10961076                        jqxhr.fail( function( jqXHR, textStatus ) {
    1097                                 if ( complete_callback ) {
    1098                                         complete_callback.call( control, textStatus );
    1099                                 }
    1100                         } );
     1077                                if ( completeCallback ) {
     1078                                        completeCallback.call( self, textStatus );
     1079                                }
     1080                        } );
     1081
    11011082                        jqxhr.always( function() {
    1102                                 control.container.removeClass( 'widget-form-loading' );
    1103                                 inputs.each( function() {
    1104                                         $( this ).removeData( 'state' + update_number );
     1083                                self.container.removeClass( 'widget-form-loading' );
     1084
     1085                                $inputs.each( function() {
     1086                                        $( this ).removeData( 'state' + updateNumber );
    11051087                                } );
    11061088
     
    11111093                /**
    11121094                 * Expand the accordion section containing a control
    1113                  * @todo it would be nice if accordion had a proper API instead of having to trigger UI events on its elements
    11141095                 */
    11151096                expandControlSection: function() {
    1116                         var section = this.container.closest( '.accordion-section' );
    1117                         if ( ! section.hasClass( 'open' ) ) {
    1118                                 section.find( '.accordion-section-title:first' ).trigger( 'click' );
     1097                        var $section = this.container.closest( '.accordion-section' );
     1098
     1099                        if ( ! $section.hasClass( 'open' ) ) {
     1100                                $section.find( '.accordion-section-title:first' ).trigger( 'click' );
    11191101                        }
    11201102                },
     
    11371119                 * Expand or collapse the widget control
    11381120                 *
    1139                  * @param {boolean|undefined} [do_expand] If not supplied, will be inverse of current visibility
    1140                  */
    1141                 toggleForm: function( do_expand ) {
    1142                         var control = this, widget, inside, complete;
    1143 
    1144                         widget = control.container.find( 'div.widget:first' );
    1145                         inside = widget.find( '.widget-inside:first' );
    1146                         if ( typeof do_expand === 'undefined' ) {
    1147                                 do_expand = ! inside.is( ':visible' );
     1121                 * @param {boolean|undefined} [showOrHide] If not supplied, will be inverse of current visibility
     1122                 */
     1123                toggleForm: function( showOrHide ) {
     1124                        var self = this, $widget, $inside, complete;
     1125
     1126                        $widget = this.container.find( 'div.widget:first' );
     1127                        $inside = $widget.find( '.widget-inside:first' );
     1128                        if ( typeof showOrHide === 'undefined' ) {
     1129                                showOrHide = ! $inside.is( ':visible' );
    11481130                        }
    11491131
    11501132                        // Already expanded or collapsed, so noop
    1151                         if ( inside.is( ':visible' ) === do_expand ) {
     1133                        if ( $inside.is( ':visible' ) === showOrHide ) {
    11521134                                return;
    11531135                        }
    11541136
    1155                         if ( do_expand ) {
     1137                        if ( showOrHide ) {
    11561138                                // Close all other widget controls before expanding this one
    1157                                 api.control.each( function( other_control ) {
    1158                                         if ( control.params.type === other_control.params.type && control !== other_control ) {
    1159                                                 other_control.collapseForm();
     1139                                api.control.each( function( otherControl ) {
     1140                                        if ( self.params.type === otherControl.params.type && self !== otherControl ) {
     1141                                                otherControl.collapseForm();
    11601142                                        }
    11611143                                } );
    11621144
    11631145                                complete = function() {
    1164                                         control.container.removeClass( 'expanding' );
    1165                                         control.container.addClass( 'expanded' );
    1166                                         control.container.trigger( 'expanded' );
     1146                                        self.container.removeClass( 'expanding' );
     1147                                        self.container.addClass( 'expanded' );
     1148                                        self.container.trigger( 'expanded' );
    11671149                                };
    1168                                 if ( control.params.is_wide ) {
    1169                                         inside.fadeIn( 'fast', complete );
     1150
     1151                                if ( self.params.is_wide ) {
     1152                                        $inside.fadeIn( 'fast', complete );
    11701153                                } else {
    1171                                         inside.slideDown( 'fast', complete );
    1172                                 }
    1173                                 control.container.trigger( 'expand' );
    1174                                 control.container.addClass( 'expanding' );
     1154                                        $inside.slideDown( 'fast', complete );
     1155                                }
     1156
     1157                                self.container.trigger( 'expand' );
     1158                                self.container.addClass( 'expanding' );
    11751159                        } else {
    1176                                 control.container.trigger( 'collapse' );
    1177                                 control.container.addClass( 'collapsing' );
    11781160                                complete = function() {
    1179                                         control.container.removeClass( 'collapsing' );
    1180                                         control.container.removeClass( 'expanded' );
    1181                                         control.container.trigger( 'collapsed' );
     1161                                        self.container.removeClass( 'collapsing' );
     1162                                        self.container.removeClass( 'expanded' );
     1163                                        self.container.trigger( 'collapsed' );
    11821164                                };
    1183                                 if ( control.params.is_wide ) {
    1184                                         inside.fadeOut( 'fast', complete );
     1165
     1166                                self.container.trigger( 'collapse' );
     1167                                self.container.addClass( 'collapsing' );
     1168
     1169                                if ( self.params.is_wide ) {
     1170                                        $inside.fadeOut( 'fast', complete );
    11851171                                } else {
    1186                                         inside.slideUp( 'fast', function() {
    1187                                                 widget.css( { width:'', margin:'' } );
     1172                                        $inside.slideUp( 'fast', function() {
     1173                                                $widget.css( { width:'', margin:'' } );
    11881174                                                complete();
    11891175                                        } );
     
    11971183                 */
    11981184                focus: function() {
    1199                         var control = this;
    1200                         control.expandControlSection();
    1201                         control.expandForm();
    1202                         control.container.find( '.widget-content :focusable:first' ).focus();
     1185                        this.expandControlSection();
     1186                        this.expandForm();
     1187                        this.container.find( '.widget-content :focusable:first' ).focus();
    12031188                },
    12041189
     
    12061191                 * Get the position (index) of the widget in the containing sidebar
    12071192                 *
    1208                  * @throws Error
    12091193                 * @returns {Number}
    12101194                 */
    12111195                getWidgetSidebarPosition: function() {
    1212                         var control = this,
    1213                                 sidebar_widget_ids,
    1214                                 position;
    1215 
    1216                         sidebar_widget_ids = control.getSidebarWidgetsControl().setting();
    1217                         position = _.indexOf( sidebar_widget_ids, control.params.widget_id );
     1196                        var sidebarWidgetIds, position;
     1197
     1198                        sidebarWidgetIds = this.getSidebarWidgetsControl().setting();
     1199                        position = _.indexOf( sidebarWidgetIds, this.params.widget_id );
     1200
    12181201                        if ( position === -1 ) {
    1219                                 throw new Error( 'Widget was unexpectedly not present in the sidebar.' );
    1220                         }
     1202                                return;
     1203                        }
     1204
    12211205                        return position;
    12221206                },
     
    12421226                 */
    12431227                _moveWidgetByOne: function( offset ) {
    1244                         var control = this,
    1245                                 i,
    1246                                 sidebar_widgets_setting,
    1247                                 sidebar_widget_ids,
    1248                                 adjacent_widget_id;
    1249 
    1250                         i = control.getWidgetSidebarPosition();
    1251 
    1252                         sidebar_widgets_setting = control.getSidebarWidgetsControl().setting;
    1253                         sidebar_widget_ids = Array.prototype.slice.call( sidebar_widgets_setting() ); // clone
    1254                         adjacent_widget_id = sidebar_widget_ids[i + offset];
    1255                         sidebar_widget_ids[i + offset] = control.params.widget_id;
    1256                         sidebar_widget_ids[i] = adjacent_widget_id;
    1257 
    1258                         sidebar_widgets_setting( sidebar_widget_ids );
     1228                        var i, sidebarWidgetsSetting, sidebarWidgetIds, adjacentWidgetId;
     1229
     1230                        i = this.getWidgetSidebarPosition();
     1231
     1232                        sidebarWidgetsSetting = this.getSidebarWidgetsControl().setting;
     1233                        sidebarWidgetIds = Array.prototype.slice.call( sidebarWidgetsSetting() ); // clone
     1234                        adjacentWidgetId = sidebarWidgetIds[i + offset];
     1235                        sidebarWidgetIds[i + offset] = this.params.widget_id;
     1236                        sidebarWidgetIds[i] = adjacentWidgetId;
     1237
     1238                        sidebarWidgetsSetting( sidebarWidgetIds );
    12591239                },
    12601240
     
    12621242                 * Toggle visibility of the widget move area
    12631243                 *
    1264                  * @param {Boolean} [toggle]
    1265                  */
    1266                 toggleWidgetMoveArea: function( toggle ) {
    1267                         var control = this, move_widget_area;
    1268                         move_widget_area = control.container.find( '.move-widget-area' );
    1269                         if ( typeof toggle === 'undefined' ) {
    1270                                 toggle = ! move_widget_area.hasClass( 'active' );
    1271                         }
    1272                         if ( toggle ) {
     1244                 * @param {Boolean} [showOrHide]
     1245                 */
     1246                toggleWidgetMoveArea: function( showOrHide ) {
     1247                        var self = this, $moveWidgetArea;
     1248
     1249                        $moveWidgetArea = this.container.find( '.move-widget-area' );
     1250
     1251                        if ( typeof showOrHide === 'undefined' ) {
     1252                                showOrHide = ! $moveWidgetArea.hasClass( 'active' );
     1253                        }
     1254
     1255                        if ( showOrHide ) {
    12731256                                // reset the selected sidebar
    1274                                 move_widget_area.find( '.selected' ).removeClass( 'selected' );
    1275                                 move_widget_area.find( 'li' ).filter( function() {
    1276                                         return $( this ).data( 'id' ) === control.params.sidebar_id;
     1257                                $moveWidgetArea.find( '.selected' ).removeClass( 'selected' );
     1258
     1259                                $moveWidgetArea.find( 'li' ).filter( function() {
     1260                                        return $( this ).data( 'id' ) === self.params.sidebar_id;
    12771261                                } ).addClass( 'selected' );
    1278                                 control.container.find( '.move-widget-btn' ).prop( 'disabled', true );
    1279                         }
    1280                         move_widget_area.toggleClass( 'active', toggle );
    1281                 },
    1282 
    1283                 /**
    1284                  * Inside of the customizer preview, scroll the widget into view
    1285                  */
    1286                 scrollPreviewWidgetIntoView: function() {
    1287                         // @todo scrollIntoView() provides a robust but very poor experience. Animation is needed. See https://github.com/x-team/wp-widget-customizer/issues/16
     1262
     1263                                this.container.find( '.move-widget-btn' ).prop( 'disabled', true );
     1264                        }
     1265
     1266                        $moveWidgetArea.toggleClass( 'active', showOrHide );
    12881267                },
    12891268
     
    12921271                 */
    12931272                highlightSectionAndControl: function() {
    1294                         var control = this, target_element;
    1295 
    1296                         if ( control.container.is( ':hidden' ) ) {
    1297                                 target_element = control.container.closest( '.control-section' );
     1273                        var $target;
     1274
     1275                        if ( this.container.is( ':hidden' ) ) {
     1276                                $target = this.container.closest( '.control-section' );
    12981277                        } else {
    1299                                 target_element = control.container;
    1300                         }
    1301 
    1302                         $( '.widget-customizer-highlighted' ).removeClass( 'widget-customizer-highlighted' );
    1303                         target_element.addClass( 'widget-customizer-highlighted' );
     1278                                $target = this.container;
     1279                        }
     1280
     1281                        $( '.highlighted' ).removeClass( 'highlighted' );
     1282                        $target.addClass( 'highlighted' );
     1283
    13041284                        setTimeout( function() {
    1305                                 target_element.removeClass( 'widget-customizer-highlighted' );
     1285                                $target.removeClass( 'highlighted' );
    13061286                        }, 500 );
    13071287                }
    1308 
    13091288        } );
    13101289
     
    16021581
    16031582                        form_controls = _( control.setting() ).map( function( widget_id ) {
    1604                                 var setting_id = widget_id_to_setting_id( widget_id ),
     1583                                var setting_id = widgetIdToSettingId( widget_id ),
    16051584                                        form_control = api.control( setting_id );
    16061585
     
    18161795        api.Widgets.getSidebarWidgetControlContainingWidget = function( widget_id ) {
    18171796                var found_control = null;
    1818                 // @todo this can use widget_id_to_setting_id(), then pass into wp.customize.control( x ).getSidebarWidgetsControl()
     1797                // @todo this can use widgetIdToSettingId(), then pass into wp.customize.control( x ).getSidebarWidgetsControl()
    18191798                api.control.each( function( control ) {
    18201799                        if ( control.params.type === 'sidebar_widgets' && -1 !== _.indexOf( control.setting(), widget_id ) ) {
     
    18331812        api.Widgets.getWidgetFormControlForWidget = function( widget_id ) {
    18341813                var found_control = null;
    1835                 // @todo We can just use widget_id_to_setting_id() here
     1814                // @todo We can just use widgetIdToSettingId() here
    18361815                api.control.each( function( control ) {
    18371816                        if ( control.params.type === 'widget_form' && control.params.widget_id === widget_id ) {
     
    18651844        /**
    18661845         * @param {String} widget_id
    1867          * @returns {String} setting_id
     1846         * @returns {String} settingId
    18681847         */
    1869         function widget_id_to_setting_id( widget_id ) {
    1870                 var parsed = parse_widget_id( widget_id ), setting_id;
    1871 
    1872                 setting_id = 'widget_' + parsed.id_base;
     1848        function widgetIdToSettingId( widget_id ) {
     1849                var parsed = parse_widget_id( widget_id ), settingId;
     1850
     1851                settingId = 'widget_' + parsed.id_base;
    18731852                if ( parsed.number ) {
    1874                         setting_id += '[' + parsed.number + ']';
     1853                        settingId += '[' + parsed.number + ']';
    18751854                }
    1876                 return setting_id;
     1855                return settingId;
    18771856        }
    18781857
Note: See TracChangeset for help on using the changeset viewer.