Make WordPress Core

Ticket #27298: 27298.diff

File 27298.diff, 41.1 KB (added by wonderboymusic, 11 years ago)
  • src/wp-admin/js/customize-widgets.js

     
    33var WidgetCustomizer = ( function ($) {
    44        'use strict';
    55
    6         var customize = wp.customize;
    7         var self = {
     6        var Widget,
     7                WidgetCollection,
     8                Sidebar,
     9                SidebarCollection,
     10                OldPreviewer,
     11                customize = wp.customize, self = {
    812                update_widget_ajax_action: null,
    913                update_widget_nonce_value: null,
    1014                update_widget_nonce_post_key: null,
     
    3943        /**
    4044         * Set up model
    4145         */
    42         var Widget = self.Widget = Backbone.Model.extend( {
     46        Widget = self.Widget = Backbone.Model.extend( {
    4347                id: null,
    4448                temp_id: null,
    4549                classname: null,
     
    5559                width: null,
    5660                height: null
    5761        } );
    58         var WidgetCollection = self.WidgetCollection = Backbone.Collection.extend( {
     62
     63        WidgetCollection = self.WidgetCollection = Backbone.Collection.extend( {
    5964                model: Widget
    6065        } );
    6166        self.available_widgets = new WidgetCollection( self.available_widgets );
    6267
    63         var Sidebar = self.Sidebar = Backbone.Model.extend( {
     68        Sidebar = self.Sidebar = Backbone.Model.extend( {
    6469                after_title: null,
    6570                after_widget: null,
    6671                before_title: null,
     
    7176                name: null,
    7277                is_rendered: false
    7378        } );
    74         var SidebarCollection = self.SidebarCollection = Backbone.Collection.extend( {
     79
     80        SidebarCollection = self.SidebarCollection = Backbone.Collection.extend( {
    7581                model: Sidebar
    7682        } );
    7783        self.registered_sidebars = new SidebarCollection( self.registered_sidebars );
     
    99105
    100106                var show_first_visible_sidebar = function () {
    101107                        self.registered_sidebars.off( 'change:is_rendered', show_first_visible_sidebar );
    102                         var first_rendered_sidebar = self.registered_sidebars.find( function ( sidebar ) {
     108                        var section, first_rendered_sidebar = self.registered_sidebars.find( function ( sidebar ) {
    103109                                return sidebar.get( 'is_rendered' );
    104110                        } );
    105111                        if ( ! first_rendered_sidebar ) {
    106112                                return;
    107113                        }
    108                         var section = $( '#accordion-section-sidebar-widgets-' + first_rendered_sidebar.get( 'id' ) );
     114                        section = $( '#accordion-section-sidebar-widgets-' + first_rendered_sidebar.get( 'id' ) );
    109115                        if ( ! section.hasClass( 'open' ) ) {
    110116                                section.find( '.accordion-section-title' ).trigger( 'click' );
    111117                        }
     
    138144                 * Update ordering of widget control forms when the setting is updated
    139145                 */
    140146                _setupModel: function() {
    141                         var control = this;
    142                         var registered_sidebar = self.registered_sidebars.get( control.params.sidebar_id );
     147                        var control = this,
     148                                registered_sidebar = self.registered_sidebars.get( control.params.sidebar_id );
    143149
    144150                        control.setting.bind( function( new_widget_ids, old_widget_ids ) {
    145                                 var removed_widget_ids = _( old_widget_ids ).difference( new_widget_ids );
     151                                var widget_form_controls,
     152                                        sidebar_widgets_add_control,
     153                                        final_control_containers,
     154                                        removed_widget_ids = _( old_widget_ids ).difference( new_widget_ids );
    146155
    147156                                // Filter out any persistent widget_ids for widgets which have been deactivated
    148157                                new_widget_ids = _( new_widget_ids ).filter( function ( new_widget_id ) {
     
    150159                                        return !! self.available_widgets.findWhere( { id_base: parsed_widget_id.id_base } );
    151160                                } );
    152161
    153                                 var widget_form_controls = _( new_widget_ids ).map( function ( widget_id ) {
     162                                widget_form_controls = _( new_widget_ids ).map( function ( widget_id ) {
    154163                                        var widget_form_control = self.getWidgetFormControlForWidget( widget_id );
    155164                                        if ( ! widget_form_control ) {
    156165                                                widget_form_control = control.addWidget( widget_id );
     
    160169
    161170                                // Sort widget controls to their new positions
    162171                                widget_form_controls.sort( function ( a, b ) {
    163                                         var a_index = new_widget_ids.indexOf( a.params.widget_id );
    164                                         var b_index = new_widget_ids.indexOf( b.params.widget_id );
     172                                        var a_index = new_widget_ids.indexOf( a.params.widget_id ),
     173                                                b_index = new_widget_ids.indexOf( b.params.widget_id );
    165174                                        if ( a_index === b_index ) {
    166175                                                return 0;
    167176                                        }
     
    168177                                        return a_index < b_index ? -1 : 1;
    169178                                } );
    170179
    171                                 var sidebar_widgets_add_control = control.section_content.find( '.customize-control-sidebar_widgets' );
     180                                sidebar_widgets_add_control = control.section_content.find( '.customize-control-sidebar_widgets' );
    172181
    173182                                // Append the controls to put them in the right order
    174                                 var final_control_containers = _( widget_form_controls ).map( function( widget_form_controls ) {
     183                                final_control_containers = _( widget_form_controls ).map( function( widget_form_controls ) {
    175184                                        return widget_form_controls.container[0];
    176185                                } );
    177186
     
    189198
    190199                                        // Using setTimeout so that when moving a widget to another sidebar, the other sidebars_widgets settings get a chance to update
    191200                                        setTimeout( function () {
    192                                                 var is_present_in_another_sidebar = false;
     201                                                var is_present_in_another_sidebar = false,
     202                                                        removed_control,
     203                                                        was_dragged_to_another_sidebar,
     204                                                        inactive_widgets,
     205                                                        removed_id_base,
     206                                                        widget;
    193207
    194208                                                // Check if the widget is in another sidebar
    195209                                                wp.customize.each( function ( other_setting ) {
     
    196210                                                        if ( other_setting.id === control.setting.id || 0 !== other_setting.id.indexOf( 'sidebars_widgets[' ) || other_setting.id === 'sidebars_widgets[wp_inactive_widgets]' ) {
    197211                                                                return;
    198212                                                        }
    199                                                         var other_sidebar_widgets = other_setting();
    200                                                         var i = other_sidebar_widgets.indexOf( removed_widget_id );
     213                                                        var other_sidebar_widgets = other_setting(), i;
     214
     215                                                        i = other_sidebar_widgets.indexOf( removed_widget_id );
    201216                                                        if ( -1 !== i ) {
    202217                                                                is_present_in_another_sidebar = true;
    203218                                                        }
     
    208223                                                        return;
    209224                                                }
    210225
    211                                                 var removed_control = self.getWidgetFormControlForWidget( removed_widget_id );
     226                                                removed_control = self.getWidgetFormControlForWidget( removed_widget_id );
    212227
    213228                                                // Detect if widget control was dragged to another sidebar
    214                                                 var was_dragged_to_another_sidebar = (
     229                                                was_dragged_to_another_sidebar = (
    215230                                                        removed_control &&
    216231                                                        $.contains( document, removed_control.container[0] ) &&
    217232                                                        ! $.contains( control.section_content[0], removed_control.container[0] )
     
    226241                                                // Move widget to inactive widgets sidebar (move it to trash) if has been previously saved
    227242                                                // This prevents the inactive widgets sidebar from overflowing with throwaway widgets
    228243                                                if ( self.saved_widget_ids[removed_widget_id] ) {
    229                                                         var inactive_widgets = wp.customize.value( 'sidebars_widgets[wp_inactive_widgets]' )().slice();
     244                                                        inactive_widgets = wp.customize.value( 'sidebars_widgets[wp_inactive_widgets]' )().slice();
    230245                                                        inactive_widgets.push( removed_widget_id );
    231246                                                        wp.customize.value( 'sidebars_widgets[wp_inactive_widgets]' )( _( inactive_widgets ).unique() );
    232247                                                }
    233248
    234249                                                // Make old single widget available for adding again
    235                                                 var removed_id_base = parse_widget_id( removed_widget_id ).id_base;
    236                                                 var widget = self.available_widgets.findWhere( { id_base: removed_id_base } );
     250                                                removed_id_base = parse_widget_id( removed_widget_id ).id_base;
     251                                                widget = self.available_widgets.findWhere( { id_base: removed_id_base } );
    237252                                                if ( widget && ! widget.get( 'is_multi' ) ) {
    238253                                                        widget.set( 'is_disabled', false );
    239254                                                }
     
    250265
    251266                        // Show the sidebar section when it becomes visible
    252267                        registered_sidebar.on( 'change:is_rendered', function ( ) {
    253                                 var section_selector = '#accordion-section-sidebar-widgets-' + this.get( 'id' );
    254                                 var section = $( section_selector );
     268                                var section_selector = '#accordion-section-sidebar-widgets-' + this.get( 'id' ), section;
     269                                section = $( section_selector );
    255270                                if ( this.get( 'is_rendered' ) ) {
    256271                                        section.stop().slideDown( function () {
    257272                                                $( this ).css( 'height', 'auto' ); // so that the .accordion-section-content won't overflow
     
    283298                                axis: 'y',
    284299                                connectWith: '.accordion-section-content:has(.customize-control-sidebar_widgets)',
    285300                                update: function () {
    286                                         var widget_container_ids = control.section_content.sortable( 'toArray' );
    287                                         var widget_ids = $.map( widget_container_ids, function ( widget_container_id ) {
     301                                        var widget_container_ids = control.section_content.sortable( 'toArray' ), widget_ids;
     302                                        widget_ids = $.map( widget_container_ids, function ( widget_container_id ) {
    288303                                                return $( '#' + widget_container_id ).find( ':input[name=widget-id]' ).val();
    289304                                        } );
    290305                                        control.setting( widget_ids );
     
    392407                 * @return {wp.customize.controlConstructor.widget_form[]}
    393408                 */
    394409                getWidgetFormControls: function () {
    395                         var control = this;
    396                         var form_controls = _( control.setting() ).map( function ( widget_id ) {
    397                                 var setting_id = widget_id_to_setting_id( widget_id );
    398                                 var form_control = customize.control( setting_id );
     410                        var control = this, form_controls;
     411
     412                        form_controls = _( control.setting() ).map( function ( widget_id ) {
     413                                var setting_id = widget_id_to_setting_id( widget_id ),
     414                                        form_control = customize.control( setting_id );
     415
    399416                                if ( ! form_control ) {
    400417                                        throw new Error( 'Unable to find widget_form control for ' + widget_id );
    401418                                }
     
    409426                 * @returns {object} widget_form control instance
    410427                 */
    411428                addWidget: function ( widget_id ) {
    412                         var control = this;
    413                         var parsed_widget_id = parse_widget_id( widget_id );
    414                         var widget_number = parsed_widget_id.number;
    415                         var widget_id_base = parsed_widget_id.id_base;
    416                         var widget = self.available_widgets.findWhere( {id_base: widget_id_base} );
     429                        var control = this,
     430                                control_html,
     431                                customize_control_type = 'widget_form',
     432                                customize_control,
     433                                parsed_widget_id = parse_widget_id( widget_id ),
     434                                widget_number = parsed_widget_id.number,
     435                                widget_id_base = parsed_widget_id.id_base,
     436                                widget = self.available_widgets.findWhere( {id_base: widget_id_base} ),
     437                                setting_id,
     438                                is_existing_widget,
     439                                Constructor,
     440                                widget_form_control,
     441                                sidebar_widgets,
     442                                setting_args;
     443
    417444                        if ( ! widget ) {
    418445                                throw new Error( 'Widget unexpectedly not found.' );
    419446                        }
     
    427454                                widget_number = widget.get( 'multi_number' );
    428455                        }
    429456
    430                         var control_html = $( '#widget-tpl-' + widget.get( 'id' ) ).html();
     457                        control_html = $( '#widget-tpl-' + widget.get( 'id' ) ).html();
    431458                        if ( widget.get( 'is_multi' ) ) {
    432459                                control_html = control_html.replace( /<[^<>]+>/g, function ( m ) {
    433460                                        return m.replace( /__i__|%i%/g, widget_number );
     
    436463                                widget.set( 'is_disabled', true ); // Prevent single widget from being added again now
    437464                        }
    438465
    439                         var customize_control_type = 'widget_form';
    440                         var customize_control = $( '<li></li>' );
     466                        customize_control = $( '<li></li>' );
    441467                        customize_control.addClass( 'customize-control' );
    442468                        customize_control.addClass( 'customize-control-' + customize_control_type );
    443469                        customize_control.append( $( control_html ) );
     
    449475                        widget_id = customize_control.find( '[name="widget-id"]' ).val();
    450476                        customize_control.hide(); // to be slid-down below
    451477
    452                         var setting_id = 'widget_' + widget.get( 'id_base' );
     478                        setting_id = 'widget_' + widget.get( 'id_base' );
    453479                        if ( widget.get( 'is_multi' ) ) {
    454480                                setting_id += '[' + widget_number + ']';
    455481                        }
     
    458484                        control.container.after( customize_control );
    459485
    460486                        // Only create setting if it doesn't already exist (if we're adding a pre-existing inactive widget)
    461                         var is_existing_widget = wp.customize.has( setting_id );
     487                        is_existing_widget = wp.customize.has( setting_id );
    462488                        if ( ! is_existing_widget ) {
    463                                 var setting_args = {
     489                                setting_args = {
    464490                                        transport: 'refresh',
    465491                                        previewer: control.setting.previewer
    466492                                };
     
    467493                                wp.customize.create( setting_id, setting_id, {}, setting_args );
    468494                        }
    469495
    470                         var Constructor = wp.customize.controlConstructor[customize_control_type];
    471                         var widget_form_control = new Constructor( setting_id, {
     496                        Constructor = wp.customize.controlConstructor[customize_control_type];
     497                        widget_form_control = new Constructor( setting_id, {
    472498                                params: {
    473499                                        settings: {
    474500                                                'default': setting_id
     
    494520                                if ( 0 !== other_setting.id.indexOf( 'sidebars_widgets[' ) ) {
    495521                                        return;
    496522                                }
    497                                 var other_sidebar_widgets = other_setting().slice();
    498                                 var i = other_sidebar_widgets.indexOf( widget_id );
     523                                var other_sidebar_widgets = other_setting().slice(), i;
     524                                i = other_sidebar_widgets.indexOf( widget_id );
    499525                                if ( -1 !== i ) {
    500526                                        other_sidebar_widgets.splice( i );
    501527                                        other_setting( other_sidebar_widgets );
     
    503529                        } );
    504530
    505531                        // Add widget to this sidebar
    506                         var sidebar_widgets = control.setting().slice();
     532                        sidebar_widgets = control.setting().slice();
    507533                        if ( -1 === sidebar_widgets.indexOf( widget_id ) ) {
    508534                                sidebar_widgets.push( widget_id );
    509535                                control.setting( sidebar_widgets );
     
    560586                        _default: {},
    561587                        rss: {
    562588                                formUpdated: function ( serialized_form ) {
    563                                         var control = this;
    564                                         var old_widget_error = control.container.find( '.widget-error:first' );
    565                                         var new_widget_error = serialized_form.find( '.widget-error:first' );
     589                                        var control = this,
     590                                                old_widget_error = control.container.find( '.widget-error:first' ),
     591                                                new_widget_error = serialized_form.find( '.widget-error:first' );
     592
    566593                                        if ( old_widget_error.length && new_widget_error.length ) {
    567594                                                old_widget_error.replaceWith( new_widget_error );
    568595                                        } else if ( old_widget_error.length ) {
     
    580607                 * @param name
    581608                 */
    582609                hook: function ( name ) {
    583                         var args = Array.prototype.slice.call( arguments, 1 );
    584                         var handler;
     610                        var args = Array.prototype.slice.call( arguments, 1 ), handler;
     611
    585612                        if ( this.hooks[this.params.widget_id_base] && this.hooks[this.params.widget_id_base][name] ) {
    586613                                handler = this.hooks[this.params.widget_id_base][name];
    587614                        } else if ( this.hooks._default[name] ) {
     
    596623                 * Handle changes to the setting
    597624                 */
    598625                _setupModel: function () {
    599                         var control = this;
     626                        var control = this, remember_saved_widget_id;
    600627
    601628                        // Remember saved widgets so we know which to trash (move to inactive widgets sidebar)
    602                         var remember_saved_widget_id = function () {
     629                        remember_saved_widget_id = function () {
    603630                                self.saved_widget_ids[control.params.widget_id] = true;
    604631                        };
    605632                        wp.customize.bind( 'ready', remember_saved_widget_id );
     
    620647                 * Add special behaviors for wide widget controls
    621648                 */
    622649                _setupWideWidget: function () {
    623                         var control = this;
     650                        var control = this,
     651                                widget_inside,
     652                                customize_sidebar,
     653                                position_widget,
     654                                theme_controls_container;
     655
    624656                        if ( ! control.params.is_wide ) {
    625657                                return;
    626658                        }
    627                         var widget_inside = control.container.find( '.widget-inside' );
    628                         var customize_sidebar = $( '.wp-full-overlay-sidebar-content:first' );
     659
     660                        widget_inside = control.container.find( '.widget-inside' );
     661                        customize_sidebar = $( '.wp-full-overlay-sidebar-content:first' );
    629662                        control.container.addClass( 'wide-widget-control' );
    630663
    631664                        control.container.find( '.widget-content:first' ).css( {
     
    639672                         * widget-top is scrolled out of view, keep the widget-top in view;
    640673                         * likewise, don't allow the widget to drop off the bottom of the window.
    641674                         */
    642                         var position_widget = function () {
    643                                 var offset_top = control.container.offset().top;
    644                                 var height = widget_inside.outerHeight();
    645                                 var top = Math.max( offset_top, 0 );
    646                                 var max_top = $( window ).height() - height;
     675                        position_widget = function () {
     676                                var offset_top = control.container.offset().top,
     677                                        height,
     678                                        top,
     679                                        max_top;
     680
     681                                height = widget_inside.outerHeight();
     682                                top = Math.max( offset_top, 0 );
     683                                max_top = $( window ).height() - height;
    647684                                top = Math.min( top, max_top );
    648685                                widget_inside.css( 'top', top );
    649686                        };
    650687
    651                         var theme_controls_container = $( '#customize-theme-controls' );
     688                        theme_controls_container = $( '#customize-theme-controls' );
    652689                        control.container.on( 'expand', function () {
    653690                                customize_sidebar.on( 'scroll', position_widget );
    654691                                $( window ).on( 'resize', position_widget );
     
    678715                 * the close button
    679716                 */
    680717                _setupControlToggle: function() {
    681                         var control = this;
     718                        var control = this, close_btn;
     719
    682720                        control.container.find( '.widget-top' ).on( 'click', function ( e ) {
    683721                                e.preventDefault();
    684722                                var sidebar_widgets_control = control.getSidebarWidgetsControl();
     
    688726                                control.toggleForm();
    689727                        } );
    690728
    691                         var close_btn = control.container.find( '.widget-control-close' );
     729                        close_btn = control.container.find( '.widget-control-close' );
    692730                        // @todo Hitting Enter on this link does nothing; will be resolved in core with <http://core.trac.wordpress.org/ticket/26633>
    693731                        close_btn.on( 'click', function ( e ) {
    694732                                e.preventDefault();
     
    701739                 * Update the title of the form if a title field is entered
    702740                 */
    703741                _setupWidgetTitle: function () {
    704                         var control = this;
    705                         var update_title = function () {
    706                                 var title = control.setting().title;
    707                                 var in_widget_title = control.container.find( '.in-widget-title' );
     742                        var control = this, update_title;
     743
     744                        update_title = function () {
     745                                var title = control.setting().title,
     746                                        in_widget_title = control.container.find( '.in-widget-title' );
     747
    708748                                if ( title ) {
    709749                                        in_widget_title.text( ': ' + title );
    710750                                } else {
     
    719759                 * Set up the widget-reorder-nav
    720760                 */
    721761                _setupReorderUI: function () {
    722                         var control = this;
     762                        var control = this,
     763                                select_sidebar_item,
     764                                move_widget_area,
     765                                reorder_nav,
     766                                update_available_sidebars;
    723767
    724768                        /**
    725769                         * select the provided sidebar list item in the move widget area
     
    726770                         *
    727771                         * @param {jQuery} li
    728772                         */
    729                         var select_sidebar_item = function ( li ) {
     773                        select_sidebar_item = function ( li ) {
    730774                                li.siblings( '.selected' ).removeClass( 'selected' );
    731775                                li.addClass( 'selected' );
    732776                                var is_self_sidebar = ( li.data( 'id' ) === control.params.sidebar_id );
     
    737781                         * Add the widget reordering elements to the widget control
    738782                         */
    739783                        control.container.find( '.widget-title-action' ).after( $( self.tpl.widget_reorder_nav ) );
    740                         var move_widget_area = $(
     784                        move_widget_area = $(
    741785                                _.template( self.tpl.move_widget_area, {
    742786                                        sidebars: _( self.registered_sidebars.toArray() ).pluck( 'attributes' )
    743787                                } )
     
    747791                        /**
    748792                         * Update available sidebars when their rendered state changes
    749793                         */
    750                         var update_available_sidebars = function () {
    751                                 var sidebar_items = move_widget_area.find( 'li' );
    752                                 var self_sidebar_item = sidebar_items.filter( function(){
     794                        update_available_sidebars = function () {
     795                                var sidebar_items = move_widget_area.find( 'li' ), self_sidebar_item;
     796                                self_sidebar_item = sidebar_items.filter( function(){
    753797                                        return $( this ).data( 'id' ) === control.params.sidebar_id;
    754798                                } );
    755799                                sidebar_items.each( function () {
    756                                         var li = $( this );
    757                                         var sidebar_id = li.data( 'id' );
    758                                         var sidebar_model = self.registered_sidebars.get( sidebar_id );
     800                                        var li = $( this ),
     801                                                sidebar_id,
     802                                                sidebar_model;
     803
     804                                        sidebar_id = li.data( 'id' );
     805                                        sidebar_model = self.registered_sidebars.get( sidebar_id );
    759806                                        li.toggle( sidebar_model.get( 'is_rendered' ) );
    760807                                        if ( li.hasClass( 'selected' ) && ! sidebar_model.get( 'is_rendered' ) ) {
    761808                                                select_sidebar_item( self_sidebar_item );
     
    768815                        /**
    769816                         * Handle clicks for up/down/move on the reorder nav
    770817                         */
    771                         var reorder_nav = control.container.find( '.widget-reorder-nav' );
     818                        reorder_nav = control.container.find( '.widget-reorder-nav' );
    772819                        reorder_nav.find( '.move-widget, .move-widget-down, .move-widget-up' ).on( 'click keypress', function ( event ) {
    773820                                if ( event.type === 'keypress' && ( event.which !== 13 && event.which !== 32 ) ) {
    774821                                        return;
     
    778825                                if ( $( this ).is( '.move-widget' ) ) {
    779826                                        control.toggleWidgetMoveArea();
    780827                                } else {
    781                                         var is_move_down = $( this ).is( '.move-widget-down' );
    782                                         var is_move_up = $( this ).is( '.move-widget-up' );
    783                                         var i = control.getWidgetSidebarPosition();
     828                                        var is_move_down = $( this ).is( '.move-widget-down' ),
     829                                                is_move_up = $( this ).is( '.move-widget-up' ),
     830                                                i = control.getWidgetSidebarPosition();
     831
    784832                                        if ( ( is_move_up && i === 0 ) || ( is_move_down && i === control.getSidebarWidgetsControl().setting().length - 1 ) ) {
    785833                                                return;
    786834                                        }
     
    812860                        control.container.find( '.move-widget-btn' ).click( function () {
    813861                                control.getSidebarWidgetsControl().toggleReordering( false );
    814862
    815                                 var old_sidebar_id = control.params.sidebar_id;
    816                                 var new_sidebar_id = control.container.find( '.widget-area-select li.selected' ).data( 'id' );
    817                                 var old_sidebar_widgets_setting = customize( 'sidebars_widgets[' + old_sidebar_id + ']' );
    818                                 var new_sidebar_widgets_setting = customize( 'sidebars_widgets[' + new_sidebar_id + ']' );
    819                                 var old_sidebar_widget_ids = Array.prototype.slice.call( old_sidebar_widgets_setting() );
    820                                 var new_sidebar_widget_ids = Array.prototype.slice.call( new_sidebar_widgets_setting() );
     863                                var old_sidebar_id = control.params.sidebar_id,
     864                                        new_sidebar_id = control.container.find( '.widget-area-select li.selected' ).data( 'id' ),
     865                                        old_sidebar_widgets_setting,
     866                                        new_sidebar_widgets_setting,
     867                                        old_sidebar_widget_ids,
     868                                        new_sidebar_widget_ids,
     869                                        i;
    821870
    822                                 var i = control.getWidgetSidebarPosition();
     871                                old_sidebar_widgets_setting = customize( 'sidebars_widgets[' + old_sidebar_id + ']' );
     872                                new_sidebar_widgets_setting = customize( 'sidebars_widgets[' + new_sidebar_id + ']' );
     873                                old_sidebar_widget_ids = Array.prototype.slice.call( old_sidebar_widgets_setting() );
     874                                new_sidebar_widget_ids = Array.prototype.slice.call( new_sidebar_widgets_setting() );
     875
     876                                i = control.getWidgetSidebarPosition();
    823877                                old_sidebar_widget_ids.splice( i, 1 );
    824878                                new_sidebar_widget_ids.push( control.params.widget_id );
    825879
     
    857911                 * Set up event handlers for widget updating
    858912                 */
    859913                _setupUpdateUI: function () {
    860                         var control = this;
     914                        var control = this,
     915                                widget_content,
     916                                save_btn,
     917                                trigger_save;
    861918
    862                         var widget_content = control.container.find( '.widget-content' );
     919                        widget_content = control.container.find( '.widget-content' );
    863920
    864921                        // Configure update button
    865                         var save_btn = control.container.find( '.widget-control-save' );
     922                        save_btn = control.container.find( '.widget-control-save' );
    866923                        save_btn.val( self.i18n.save_btn_label );
    867924                        save_btn.attr( 'title', self.i18n.save_btn_tooltip );
    868925                        save_btn.removeClass( 'button-primary' ).addClass( 'button-secondary' );
     
    871928                                control.updateWidget();
    872929                        } );
    873930
    874                         var trigger_save = _.debounce( function () {
     931                        trigger_save = _.debounce( function () {
    875932                                // @todo For compatibility with other plugins, should we trigger a click event? What about form submit event?
    876933                                control.updateWidget();
    877934                        }, 250 );
     
    912969                 * Set up event handlers for widget removal
    913970                 */
    914971                _setupRemoveUI: function () {
    915                         var control = this;
     972                        var control = this,
     973                                remove_btn,
     974                                replace_delete_with_remove;
    916975
    917976                        // Configure remove button
    918                         var remove_btn = control.container.find( 'a.widget-control-remove' );
     977                        remove_btn = control.container.find( 'a.widget-control-remove' );
    919978                        // @todo Hitting Enter on this link does nothing; will be resolved in core with <http://core.trac.wordpress.org/ticket/26633>
    920979                        remove_btn.on( 'click', function ( e ) {
    921980                                e.preventDefault();
     
    931990                                }
    932991
    933992                                control.container.slideUp( function() {
    934                                         var sidebars_widgets_control = self.getSidebarWidgetControlContainingWidget( control.params.widget_id );
     993                                        var sidebars_widgets_control = self.getSidebarWidgetControlContainingWidget( control.params.widget_id ),
     994                                                sidebar_widget_ids,
     995                                                i;
     996
    935997                                        if ( ! sidebars_widgets_control ) {
    936998                                                throw new Error( 'Unable to find sidebars_widgets_control' );
    937999                                        }
    938                                         var sidebar_widget_ids = sidebars_widgets_control.setting().slice();
    939                                         var i = sidebar_widget_ids.indexOf( control.params.widget_id );
     1000                                        sidebar_widget_ids = sidebars_widgets_control.setting().slice();
     1001                                        i = sidebar_widget_ids.indexOf( control.params.widget_id );
    9401002                                        if ( -1 === i ) {
    9411003                                                throw new Error( 'Widget is not in sidebar' );
    9421004                                        }
     
    9461008                                } );
    9471009                        } );
    9481010
    949                         var replace_delete_with_remove = function () {
     1011                        replace_delete_with_remove = function () {
    9501012                                remove_btn.text( self.i18n.remove_btn_label ); // wp_widget_control() outputs the link as "Delete"
    9511013                                remove_btn.attr( 'title', self.i18n.remove_btn_tooltip );
    9521014                        };
     
    10071069                 * @return {wp.customize.controlConstructor.sidebar_widgets[]}
    10081070                 */
    10091071                getSidebarWidgetsControl: function () {
    1010                         var control = this;
    1011                         var setting_id = 'sidebars_widgets[' + control.params.sidebar_id + ']';
    1012                         var sidebar_widgets_control = customize.control( setting_id );
     1072                        var control = this, setting_id, sidebar_widgets_control;
     1073
     1074                        setting_id = 'sidebars_widgets[' + control.params.sidebar_id + ']';
     1075                        sidebar_widgets_control = customize.control( setting_id );
    10131076                        if ( ! sidebar_widgets_control ) {
    10141077                                throw new Error( 'Unable to locate sidebar_widgets control for ' + control.params.sidebar_id );
    10151078                        }
     
    10261089                 * @param {Boolean} [args.ignore_active_element=false] Whether or not updating a field will be deferred if focus is still on the element.
    10271090                 */
    10281091                updateWidget: function ( args ) {
    1029                         var control = this;
     1092                        var control = this,
     1093                                instance_override,
     1094                                complete_callback,
     1095                                update_number,
     1096                                widget_content,
     1097                                element_id_to_refocus = null,
     1098                                active_input_selection_start = null,
     1099                                active_input_selection_end = null,
     1100                                params = {},
     1101                                data,
     1102                                inputs,
     1103                                jqxhr;
     1104
    10301105                        args = $.extend( {
    10311106                                instance: null,
    10321107                                complete: null,
    10331108                                ignore_active_element: false
    10341109                        }, args );
    1035                         var instance_override = args.instance;
    1036                         var complete_callback = args.complete;
    10371110
     1111                        instance_override = args.instance;
     1112                        complete_callback = args.complete;
     1113
    10381114                        control._update_count += 1;
    1039                         var update_number = control._update_count;
     1115                        update_number = control._update_count;
    10401116
    1041                         var widget_content = control.container.find( '.widget-content' );
     1117                        widget_content = control.container.find( '.widget-content' );
    10421118
    1043                         var element_id_to_refocus = null;
    1044                         var active_input_selection_start = null;
    1045                         var active_input_selection_end = null;
    10461119                        // @todo Support more selectors than IDs?
    10471120                        if ( $.contains( control.container[0], document.activeElement ) && $( document.activeElement ).is( '[id]' ) ) {
    10481121                                element_id_to_refocus = $( document.activeElement ).prop( 'id' );
     
    10571130                        control.container.addClass( 'widget-form-loading' );
    10581131                        control.container.addClass( 'previewer-loading' );
    10591132
    1060                         var params = {};
     1133                        params = {};
    10611134                        params.action = self.update_widget_ajax_action;
    10621135                        params[self.update_widget_nonce_post_key] = self.update_widget_nonce_value;
    10631136
    1064                         var data = $.param( params );
    1065                         var inputs = widget_content.find( ':input, option' );
     1137                        data = $.param( params );
     1138                        inputs = widget_content.find( ':input, option' );
    10661139
    10671140                        // Store the value we're submitting in data so that when the response comes back,
    10681141                        // we know if it got sanitized; if there is no difference in the sanitized value,
    10691142                        // then we do not need to touch the UI and mess up the user's ongoing editing.
    10701143                        inputs.each( function () {
    1071                                 var input = $( this );
    1072                                 var property = control._getInputStatePropertyName( this );
     1144                                var input = $( this ),
     1145                                        property = control._getInputStatePropertyName( this );
    10731146                                input.data( 'state' + update_number, input.prop( property ) );
    10741147                        } );
    10751148
     
    10801153                        }
    10811154                        data += '&' + widget_content.find( '~ :input' ).serialize();
    10821155
    1083                         console.log( wp.ajax.settings.url, data );
    1084                         var jqxhr = $.post( wp.ajax.settings.url, data, function ( r ) {
     1156                        window.console && window.console.log( wp.ajax.settings.url, data );
     1157                        jqxhr = $.post( wp.ajax.settings.url, data, function ( r ) {
     1158                                var message,
     1159                                        sanitized_form,
     1160                                        sanitized_inputs,
     1161                                        has_same_inputs_in_response,
     1162                                        is_instance_identical;
     1163
    10851164                                if ( r.success ) {
    1086                                         var sanitized_form = $( '<div>' + r.data.form + '</div>' );
     1165                                        sanitized_form = $( '<div>' + r.data.form + '</div>' );
     1166
    10871167                                        control.hook( 'formUpdate', sanitized_form );
    10881168
    1089                                         var sanitized_inputs = sanitized_form.find( ':input, option' );
    1090                                         var has_same_inputs_in_response = control._getInputsSignature( inputs ) === control._getInputsSignature( sanitized_inputs );
     1169                                        sanitized_inputs = sanitized_form.find( ':input, option' );
     1170                                        has_same_inputs_in_response = control._getInputsSignature( inputs ) === control._getInputsSignature( sanitized_inputs );
    10911171
    10921172                                        if ( has_same_inputs_in_response ) {
    10931173                                                inputs.each( function ( i ) {
    1094                                                         var input = $( this );
    1095                                                         var sanitized_input = $( sanitized_inputs[i] );
    1096                                                         var property = control._getInputStatePropertyName( this );
    1097                                                         var state = input.data( 'state' + update_number );
    1098                                                         var sanitized_state = sanitized_input.prop( property );
     1174                                                        var input = $( this ),
     1175                                                                sanitized_input = $( sanitized_inputs[i] ),
     1176                                                                property = control._getInputStatePropertyName( this ),
     1177                                                                state,
     1178                                                                sanitized_state;
     1179
     1180                                                        state = input.data( 'state' + update_number );
     1181                                                        sanitized_state = sanitized_input.prop( property );
    10991182                                                        input.data( 'sanitized', sanitized_state );
    11001183
    11011184                                                        if ( state !== sanitized_state ) {
     
    11321215                                         * needing to be rendered, and so we can preempt the event for the
    11331216                                         * preview finishing loading.
    11341217                                         */
    1135                                         var is_instance_identical = _( control.setting() ).isEqual( r.data.instance );
     1218                                        is_instance_identical = _( control.setting() ).isEqual( r.data.instance );
    11361219                                        if ( is_instance_identical ) {
    11371220                                                control.container.removeClass( 'previewer-loading' );
    11381221                                        } else {
     
    11451228                                                complete_callback.call( control, null, { no_change: is_instance_identical, ajax_finished: true } );
    11461229                                        }
    11471230                                } else {
    1148                                         console.log( r );
    1149                                         var message = 'FAIL';
     1231                                        window.console && window.console.log( r );
     1232                                        message = 'FAIL';
    11501233                                        if ( r.data && r.data.message ) {
    11511234                                                message = r.data.message;
    11521235                                        }
     
    12031286                 * @param {boolean|undefined} [do_expand] If not supplied, will be inverse of current visibility
    12041287                 */
    12051288                toggleForm: function ( do_expand ) {
    1206                         var control = this;
    1207                         var widget = control.container.find( 'div.widget:first' );
    1208                         var inside = widget.find( '.widget-inside:first' );
     1289                        var control = this, widget, inside, complete;
     1290
     1291                        widget = control.container.find( 'div.widget:first' );
     1292                        inside = widget.find( '.widget-inside:first' );
    12091293                        if ( typeof do_expand === 'undefined' ) {
    12101294                                do_expand = ! inside.is( ':visible' );
    12111295                        }
     
    12151299                                return;
    12161300                        }
    12171301
    1218                         var complete;
     1302                        complete;
    12191303                        if ( do_expand ) {
    12201304                                // Close all other widget controls before expanding this one
    12211305                                wp.customize.control.each( function ( other_control ) {
     
    12731357                 * @returns {Number}
    12741358                 */
    12751359                getWidgetSidebarPosition: function () {
    1276                         var control = this;
    1277                         var sidebar_widget_ids = control.getSidebarWidgetsControl().setting();
    1278                         var position = sidebar_widget_ids.indexOf( control.params.widget_id );
     1360                        var control = this,
     1361                                sidebar_widget_ids,
     1362                                position;
     1363
     1364                        sidebar_widget_ids = control.getSidebarWidgetsControl().setting();
     1365                        position = sidebar_widget_ids.indexOf( control.params.widget_id );
    12791366                        if ( position === -1 ) {
    12801367                                throw new Error( 'Widget was unexpectedly not present in the sidebar.' );
    12811368                        }
     
    13021389                 * @param {Number} offset 1|-1
    13031390                 */
    13041391                _moveWidgetByOne: function ( offset ) {
    1305                         var control = this;
    1306                         var i = control.getWidgetSidebarPosition();
     1392                        var control = this,
     1393                                i,
     1394                                sidebar_widgets_setting,
     1395                                sidebar_widget_ids,
     1396                                adjacent_widget_id;
    13071397
    1308                         var sidebar_widgets_setting = control.getSidebarWidgetsControl().setting;
    1309                         var sidebar_widget_ids = Array.prototype.slice.call( sidebar_widgets_setting() ); // clone
    1310                         var adjacent_widget_id = sidebar_widget_ids[i + offset];
     1398                        i = control.getWidgetSidebarPosition();
     1399
     1400                        sidebar_widgets_setting = control.getSidebarWidgetsControl().setting;
     1401                        sidebar_widget_ids = Array.prototype.slice.call( sidebar_widgets_setting() ); // clone
     1402                        adjacent_widget_id = sidebar_widget_ids[i + offset];
    13111403                        sidebar_widget_ids[i + offset] = control.params.widget_id;
    13121404                        sidebar_widget_ids[i] = adjacent_widget_id;
    13131405
     
    13201412                 * @param {Boolean} [toggle]
    13211413                 */
    13221414                toggleWidgetMoveArea: function ( toggle ) {
    1323                         var control = this;
    1324                         var move_widget_area = control.container.find( '.move-widget-area' );
     1415                        var control = this, move_widget_area;
     1416                        move_widget_area = control.container.find( '.move-widget-area' );
    13251417                        if ( typeof toggle === 'undefined' ) {
    13261418                                toggle = ! move_widget_area.hasClass( 'active' );
    13271419                        }
     
    13411433                 * @return {jQuery}
    13421434                 */
    13431435                getPreviewWidgetElement: function () {
    1344                         var control = this;
    1345                         var widget_customizer_preview = self.getPreviewWindow().WidgetCustomizerPreview;
     1436                        var control = this,
     1437                                widget_customizer_preview = self.getPreviewWindow().WidgetCustomizerPreview;
    13461438                        return widget_customizer_preview.getSidebarWidgetElement( control.params.sidebar_id, control.params.widget_id );
    13471439                },
    13481440
     
    13571449                 * Highlight the widget control and section
    13581450                 */
    13591451                highlightSectionAndControl: function() {
    1360                         var control = this;
    1361                         var target_element;
     1452                        var control = this, target_element;
     1453
    13621454                        if ( control.container.is( ':hidden' ) ) {
    13631455                                target_element = control.container.closest( '.control-section' );
    13641456                        } else {
     
    13761468                 * Add the widget-customizer-highlighted-widget class to the widget for 500ms
    13771469                 */
    13781470                highlightPreviewWidget: function () {
    1379                         var control = this;
    1380                         var widget_el = control.getPreviewWidgetElement();
    1381                         var root_el = widget_el.closest( 'html' );
     1471                        var control = this, widget_el, root_el;
     1472
     1473                        widget_el = control.getPreviewWidgetElement();
     1474                        root_el = widget_el.closest( 'html' );
    13821475                        root_el.find( '.widget-customizer-highlighted-widget' ).removeClass( 'widget-customizer-highlighted-widget' );
    13831476                        widget_el.addClass( 'widget-customizer-highlighted-widget' );
    13841477                        setTimeout( function () {
     
    13911484        /**
    13921485         * Capture the instance of the Previewer since it is private
    13931486         */
    1394         var OldPreviewer = wp.customize.Previewer;
     1487        OldPreviewer = wp.customize.Previewer;
    13951488        wp.customize.Previewer = OldPreviewer.extend( {
    13961489                initialize: function( params, options ) {
    13971490                        self.previewer = this;
     
    14521545                 * Set up event listeners
    14531546                 */
    14541547                setup: function () {
    1455                         var panel = this;
     1548                        var panel = this, update_available_widgets_list;
     1549
    14561550                        panel.container = $( '#available-widgets' );
    14571551                        panel.filter_input = $( '#available-widgets-filter' ).find( 'input' );
    14581552
    1459                         var update_available_widgets_list = function () {
     1553                        update_available_widgets_list = function () {
    14601554                                self.available_widgets.each( function ( widget ) {
    14611555                                        var widget_tpl = $( '#widget-tpl-' + widget.id );
    14621556                                        widget_tpl.toggle( ! widget.get( 'is_disabled' ) );
     
    15011595                                {
    15021596                                        filterChildSelector: '.widget-title h4',
    15031597                                        after: function () {
    1504                                                 var filter_val = panel.filter_input.val();
     1598                                                var filter_val = panel.filter_input.val(),
     1599                                                        first_visible_widget;
    15051600
    15061601                                                // Remove a widget from being selected if it is no longer visible
    15071602                                                if ( panel.selected_widget_tpl && ! panel.selected_widget_tpl.is( ':visible' ) ) {
     
    15171612
    15181613                                                // If a filter has been entered and a widget hasn't been selected, select the first one shown
    15191614                                                if ( ! panel.selected_widget_tpl && filter_val ) {
    1520                                                         var first_visible_widget = panel.container.find( '> .widget-tpl:visible:first' );
     1615                                                        first_visible_widget = panel.container.find( '> .widget-tpl:visible:first' );
    15211616                                                        if ( first_visible_widget.length ) {
    15221617                                                                panel.select( first_visible_widget );
    15231618                                                        }
     
    15331628                        } );
    15341629
    15351630                        panel.container.on( 'keydown', function ( event ) {
    1536                                 var is_enter = ( event.which === 13 );
    1537                                 var is_esc = ( event.which === 27 );
    1538                                 var is_down = ( event.which === 40 );
    1539                                 var is_up = ( event.which === 38 );
    1540                                 var selected_widget_tpl = null;
    1541                                 var first_visible_widget = panel.container.find( '> .widget-tpl:visible:first' );
    1542                                 var last_visible_widget = panel.container.find( '> .widget-tpl:visible:last' );
    1543                                 var is_input_focused = $( event.target ).is( panel.filter_input );
     1631                                var is_enter = ( event.which === 13 ),
     1632                                        is_esc = ( event.which === 27 ),
     1633                                        is_down = ( event.which === 40 ),
     1634                                        is_up = ( event.which === 38 ),
     1635                                        selected_widget_tpl = null,
     1636                                        first_visible_widget = panel.container.find( '> .widget-tpl:visible:first' ),
     1637                                        last_visible_widget = panel.container.find( '> .widget-tpl:visible:last' ),
     1638                                        is_input_focused = $( event.target ).is( panel.filter_input );
    15441639
    15451640                                if ( is_down || is_up ) {
    15461641                                        if ( is_down ) {
     
    15891684                },
    15901685
    15911686                submit: function ( widget_tpl ) {
    1592                         var panel = this;
     1687                        var panel = this, widget_id, widget;
    15931688                        if ( ! widget_tpl ) {
    15941689                                widget_tpl = panel.selected_widget_tpl;
    15951690                        }
     
    15981693                        }
    15991694                        panel.select( widget_tpl );
    16001695
    1601                         var widget_id = $( panel.selected_widget_tpl ).data( 'widget-id' );
    1602                         var widget = self.available_widgets.findWhere( {id: widget_id} );
     1696                        widget_id = $( panel.selected_widget_tpl ).data( 'widget-id' );
     1697                        widget = self.available_widgets.findWhere( {id: widget_id} );
    16031698                        if ( ! widget ) {
    16041699                                throw new Error( 'Widget unexpectedly not found.' );
    16051700                        }
     
    16471742         * @returns {Object}
    16481743         */
    16491744        function parse_widget_id( widget_id ) {
    1650                 var parsed = {
     1745                var matches, parsed = {
    16511746                        number: null,
    16521747                        id_base: null
    16531748                };
    1654                 var matches = widget_id.match( /^(.+)-(\d+)$/ );
     1749                matches = widget_id.match( /^(.+)-(\d+)$/ );
    16551750                if ( matches ) {
    16561751                        parsed.id_base = matches[1];
    16571752                        parsed.number = parseInt( matches[2], 10 );
     
    16671762         * @returns {String} setting_id
    16681763         */
    16691764        function widget_id_to_setting_id( widget_id ) {
    1670                 var parsed = parse_widget_id( widget_id );
    1671                 var setting_id = 'widget_' + parsed.id_base;
     1765                var parsed = parse_widget_id( widget_id ), setting_id;
     1766
     1767                setting_id = 'widget_' + parsed.id_base;
    16721768                if ( parsed.number ) {
    16731769                        setting_id += '[' + parsed.number + ']';
    16741770                }
     
    16901786
    16911787(function($){
    16921788        $.fn.liveFilter = function(inputEl, filterEl, options){
    1693                 var defaults = {
     1789                var el, filter, defaults = {
    16941790                        filterChildSelector: null,
    16951791                        filter: function(el, val){
    16961792                                return $(el).text().toUpperCase().indexOf(val.toUpperCase()) >= 0;
     
    17001796                };
    17011797                options = $.extend(defaults, options);
    17021798
    1703                 var el = $(this).find(filterEl);
     1799                el = $(this).find(filterEl);
    17041800                if (options.filterChildSelector) {
    17051801                        el = el.find(options.filterChildSelector);
    17061802                }
    17071803
    1708                 var filter = options.filter;
     1804                filter = options.filter;
    17091805                $(inputEl).keyup(function(){
    1710                         var val = $(this).val();
    1711                         var contains = el.filter(function(){
     1806                        var val = $(this).val(), contains, containsNot;
     1807
     1808                        contains = el.filter(function(){
    17121809                                return filter(this, val);
    17131810                        });
    1714                         var containsNot = el.not(contains);
     1811                        containsNot = el.not(contains);
    17151812                        if (options.filterChildSelector){
    17161813                                contains = contains.parents(filterEl);
    17171814                                containsNot = containsNot.parents(filterEl).hide();
  • src/wp-includes/js/customize-preview-widgets.js

     
    33var WidgetCustomizerPreview = (function ($) {
    44        'use strict';
    55
    6         var self = {
     6        var OldPreview, self = {
    77                rendered_sidebars: {}, // @todo Make rendered a property of the Backbone model
    88                rendered_widgets: {}, // @todo Make rendered a property of the Backbone model
    99                registered_sidebars: [], // @todo Make a Backbone collection
     
    3131                buildWidgetSelectors: function () {
    3232                        $.each( self.registered_sidebars, function ( i, sidebar ) {
    3333                                var widget_tpl = [
    34                                         sidebar.before_widget.replace('%1$s', '').replace('%2$s', ''),
    35                                         sidebar.before_title,
    36                                         sidebar.after_title,
    37                                         sidebar.after_widget
    38                                 ].join('');
    39                                 var empty_widget = $(widget_tpl);
    40                                 var widget_selector = empty_widget.prop('tagName');
    41                                 var widget_classes = empty_widget.prop('className').replace(/^\s+|\s+$/g, '');
     34                                                sidebar.before_widget.replace('%1$s', '').replace('%2$s', ''),
     35                                                sidebar.before_title,
     36                                                sidebar.after_title,
     37                                                sidebar.after_widget
     38                                        ].join(''),
     39                                        empty_widget,
     40                                        widget_selector,
     41                                        widget_classes;
     42
     43                                empty_widget = $(widget_tpl);
     44                                widget_selector = empty_widget.prop('tagName');
     45                                widget_classes = empty_widget.prop('className').replace(/^\s+|\s+$/g, '');
     46
    4247                                if ( widget_classes ) {
    4348                                        widget_selector += '.' + widget_classes.split(/\s+/).join('.');
    4449                                }
     
    98103        /**
    99104         * Capture the instance of the Preview since it is private
    100105         */
    101         var OldPreview = wp.customize.Preview;
     106        OldPreview = wp.customize.Preview;
    102107        wp.customize.Preview = OldPreview.extend( {
    103108                initialize: function( params, options ) {
    104109                        self.preview = this;