Improve/introduce Customizer JavaScript models for Controls, Sections, and Panels.
* Introduce models for panels and sections. * Introduce API to expand and focus a control, section or panel. * Allow deep-linking to panels, sections, and controls inside of the Customizer. * Clean up `accordion.js`, removing all Customizer-specific logic. * Add initial unit tests for `wp.customize.Class` in `customize-base.js`. https://make.wordpress.org/core/2014/10/27/toward-a-complete-javascript-api-for-the-customizer/ provides an overview of how to use the JavaScript API. props westonruter, celloexpressions, ryankienstra. see #28032, #28579, #28580, #28650, #28709, #29758. fixes #29529. Built from https://develop.svn.wordpress.org/trunk@30102 git-svn-id: http://core.svn.wordpress.org/trunk@30102 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
@@ -53,8 +53,6 @@ do_action( 'customize_controls_init' );
|
||||
wp_enqueue_script( 'customize-controls' );
|
||||
wp_enqueue_style( 'customize-controls' );
|
||||
|
||||
wp_enqueue_script( 'accordion' );
|
||||
|
||||
/**
|
||||
* Enqueue Customizer control scripts.
|
||||
*
|
||||
@@ -130,7 +128,7 @@ do_action( 'customize_controls_print_scripts' );
|
||||
?>
|
||||
|
||||
<div id="widgets-right"><!-- For Widget Customizer, many widgets try to look for instances under div#widgets-right, so we have to add that ID to a container div in the Customizer for compat -->
|
||||
<div class="wp-full-overlay-sidebar-content accordion-container" tabindex="-1">
|
||||
<div class="wp-full-overlay-sidebar-content" tabindex="-1">
|
||||
<div id="customize-info" class="accordion-section <?php if ( $cannot_expand ) echo ' cannot-expand'; ?>">
|
||||
<div class="accordion-section-title" aria-label="<?php esc_attr_e( 'Customizer Options' ); ?>" tabindex="0">
|
||||
<span class="preview-notice"><?php
|
||||
@@ -160,13 +158,9 @@ do_action( 'customize_controls_print_scripts' );
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div id="customize-theme-controls"><ul>
|
||||
<?php
|
||||
foreach ( $wp_customize->containers() as $container ) {
|
||||
$container->maybe_render();
|
||||
}
|
||||
?>
|
||||
</ul></div>
|
||||
<div id="customize-theme-controls">
|
||||
<ul><?php // Panels and sections are managed here via JavaScript ?></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -252,10 +246,13 @@ do_action( 'customize_controls_print_scripts' );
|
||||
),
|
||||
'settings' => array(),
|
||||
'controls' => array(),
|
||||
'panels' => array(),
|
||||
'sections' => array(),
|
||||
'nonce' => array(
|
||||
'save' => wp_create_nonce( 'save-customize_' . $wp_customize->get_stylesheet() ),
|
||||
'preview' => wp_create_nonce( 'preview-customize_' . $wp_customize->get_stylesheet() )
|
||||
),
|
||||
'autofocus' => array(),
|
||||
);
|
||||
|
||||
// Prepare Customize Setting objects to pass to Javascript.
|
||||
@@ -266,10 +263,32 @@ do_action( 'customize_controls_print_scripts' );
|
||||
);
|
||||
}
|
||||
|
||||
// Prepare Customize Control objects to pass to Javascript.
|
||||
// Prepare Customize Control objects to pass to JavaScript.
|
||||
foreach ( $wp_customize->controls() as $id => $control ) {
|
||||
$control->to_json();
|
||||
$settings['controls'][ $id ] = $control->json;
|
||||
$settings['controls'][ $id ] = $control->json();
|
||||
}
|
||||
|
||||
// Prepare Customize Section objects to pass to JavaScript.
|
||||
foreach ( $wp_customize->sections() as $id => $section ) {
|
||||
$settings['sections'][ $id ] = $section->json();
|
||||
}
|
||||
|
||||
// Prepare Customize Panel objects to pass to JavaScript.
|
||||
foreach ( $wp_customize->panels() as $id => $panel ) {
|
||||
$settings['panels'][ $id ] = $panel->json();
|
||||
foreach ( $panel->sections as $section_id => $section ) {
|
||||
$settings['sections'][ $section_id ] = $section->json();
|
||||
}
|
||||
}
|
||||
|
||||
// Pass to frontend the Customizer construct being deeplinked
|
||||
if ( isset( $_GET['autofocus'] ) && is_array( $_GET['autofocus'] ) ) {
|
||||
$autofocus = wp_unslash( $_GET['autofocus'] );
|
||||
foreach ( $autofocus as $type => $id ) {
|
||||
if ( isset( $settings[ $type . 's' ][ $id ] ) ) {
|
||||
$settings['autofocus'][ $type ] = $id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -25,9 +25,6 @@
|
||||
*
|
||||
* Note that any appropriate tags may be used, as long as the above classes are present.
|
||||
*
|
||||
* In addition to the standard accordion behavior, this file includes JS for the
|
||||
* Customizer's "Panel" functionality.
|
||||
*
|
||||
* @since 3.6.0.
|
||||
*/
|
||||
|
||||
@@ -46,20 +43,8 @@
|
||||
accordionSwitch( $( this ) );
|
||||
});
|
||||
|
||||
// Go back to the top-level Customizer accordion.
|
||||
$( '#customize-header-actions' ).on( 'click keydown', '.control-panel-back', function( e ) {
|
||||
if ( e.type === 'keydown' && 13 !== e.which ) { // "return" key
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault(); // Keep this AFTER the key filter above
|
||||
|
||||
panelSwitch( $( '.current-panel' ) );
|
||||
});
|
||||
});
|
||||
|
||||
var sectionContent = $( '.accordion-section-content' );
|
||||
|
||||
/**
|
||||
* Close the current accordion section and open a new one.
|
||||
*
|
||||
@@ -69,75 +54,22 @@
|
||||
function accordionSwitch ( el ) {
|
||||
var section = el.closest( '.accordion-section' ),
|
||||
siblings = section.closest( '.accordion-container' ).find( '.open' ),
|
||||
content = section.find( sectionContent );
|
||||
content = section.find( '.accordion-section-content' );
|
||||
|
||||
// This section has no content and cannot be expanded.
|
||||
if ( section.hasClass( 'cannot-expand' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Slide into a sub-panel instead of accordioning (Customizer-specific).
|
||||
if ( section.hasClass( 'control-panel' ) ) {
|
||||
panelSwitch( section );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( section.hasClass( 'open' ) ) {
|
||||
section.toggleClass( 'open' );
|
||||
content.toggle( true ).slideToggle( 150 );
|
||||
} else {
|
||||
siblings.removeClass( 'open' );
|
||||
siblings.find( sectionContent ).show().slideUp( 150 );
|
||||
siblings.find( '.accordion-section-content' ).show().slideUp( 150 );
|
||||
content.toggle( false ).slideToggle( 150 );
|
||||
section.toggleClass( 'open' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Slide into an accordion sub-panel.
|
||||
*
|
||||
* For the Customizer-specific panel functionality
|
||||
*
|
||||
* @param {Object} panel Title element or back button of the accordion panel to toggle.
|
||||
* @since 4.0.0
|
||||
*/
|
||||
function panelSwitch( panel ) {
|
||||
var position, scroll,
|
||||
section = panel.closest( '.accordion-section' ),
|
||||
overlay = section.closest( '.wp-full-overlay' ),
|
||||
container = section.closest( '.accordion-container' ),
|
||||
siblings = container.find( '.open' ),
|
||||
topPanel = overlay.find( '#customize-theme-controls > ul > .accordion-section > .accordion-section-title' ).add( '#customize-info > .accordion-section-title' ),
|
||||
backBtn = overlay.find( '.control-panel-back' ),
|
||||
panelTitle = section.find( '.accordion-section-title' ).first(),
|
||||
content = section.find( '.control-panel-content' );
|
||||
|
||||
if ( section.hasClass( 'current-panel' ) ) {
|
||||
section.toggleClass( 'current-panel' );
|
||||
overlay.toggleClass( 'in-sub-panel' );
|
||||
content.delay( 180 ).hide( 0, function() {
|
||||
content.css( 'margin-top', 'inherit' ); // Reset
|
||||
} );
|
||||
topPanel.attr( 'tabindex', '0' );
|
||||
backBtn.attr( 'tabindex', '-1' );
|
||||
panelTitle.focus();
|
||||
container.scrollTop( 0 );
|
||||
} else {
|
||||
// Close all open sections in any accordion level.
|
||||
siblings.removeClass( 'open' );
|
||||
siblings.find( sectionContent ).show().slideUp( 0 );
|
||||
content.show( 0, function() {
|
||||
position = content.offset().top;
|
||||
scroll = container.scrollTop();
|
||||
content.css( 'margin-top', ( 45 - position - scroll ) );
|
||||
section.toggleClass( 'current-panel' );
|
||||
overlay.toggleClass( 'in-sub-panel' );
|
||||
container.scrollTop( 0 );
|
||||
} );
|
||||
topPanel.attr( 'tabindex', '-1' );
|
||||
backBtn.attr( 'tabindex', '0' );
|
||||
backBtn.focus();
|
||||
}
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
|
||||
2
wp-admin/js/accordion.min.js
vendored
2
wp-admin/js/accordion.min.js
vendored
@@ -1 +1 @@
|
||||
!function(a){function b(a){var b=a.closest(".accordion-section"),e=b.closest(".accordion-container").find(".open"),f=b.find(d);if(!b.hasClass("cannot-expand"))return b.hasClass("control-panel")?void c(b):void(b.hasClass("open")?(b.toggleClass("open"),f.toggle(!0).slideToggle(150)):(e.removeClass("open"),e.find(d).show().slideUp(150),f.toggle(!1).slideToggle(150),b.toggleClass("open")))}function c(a){var b,c,e=a.closest(".accordion-section"),f=e.closest(".wp-full-overlay"),g=e.closest(".accordion-container"),h=g.find(".open"),i=f.find("#customize-theme-controls > ul > .accordion-section > .accordion-section-title").add("#customize-info > .accordion-section-title"),j=f.find(".control-panel-back"),k=e.find(".accordion-section-title").first(),l=e.find(".control-panel-content");e.hasClass("current-panel")?(e.toggleClass("current-panel"),f.toggleClass("in-sub-panel"),l.delay(180).hide(0,function(){l.css("margin-top","inherit")}),i.attr("tabindex","0"),j.attr("tabindex","-1"),k.focus(),g.scrollTop(0)):(h.removeClass("open"),h.find(d).show().slideUp(0),l.show(0,function(){b=l.offset().top,c=g.scrollTop(),l.css("margin-top",45-b-c),e.toggleClass("current-panel"),f.toggleClass("in-sub-panel"),g.scrollTop(0)}),i.attr("tabindex","-1"),j.attr("tabindex","0"),j.focus())}a(document).ready(function(){a(".accordion-container").on("click keydown",".accordion-section-title",function(c){("keydown"!==c.type||13===c.which)&&(c.preventDefault(),b(a(this)))}),a("#customize-header-actions").on("click keydown",".control-panel-back",function(b){("keydown"!==b.type||13===b.which)&&(b.preventDefault(),c(a(".current-panel")))})});var d=a(".accordion-section-content")}(jQuery);
|
||||
!function(a){function b(a){var b=a.closest(".accordion-section"),c=b.closest(".accordion-container").find(".open"),d=b.find(".accordion-section-content");b.hasClass("cannot-expand")||(b.hasClass("open")?(b.toggleClass("open"),d.toggle(!0).slideToggle(150)):(c.removeClass("open"),c.find(".accordion-section-content").show().slideUp(150),d.toggle(!1).slideToggle(150),b.toggleClass("open")))}a(document).ready(function(){a(".accordion-container").on("click keydown",".accordion-section-title",function(c){("keydown"!==c.type||13===c.which)&&(c.preventDefault(),b(a(this)))})})}(jQuery);
|
||||
File diff suppressed because it is too large
Load Diff
2
wp-admin/js/customize-controls.min.js
vendored
2
wp-admin/js/customize-controls.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -404,6 +404,23 @@
|
||||
* @augments wp.customize.Control
|
||||
*/
|
||||
api.Widgets.WidgetControl = api.Control.extend({
|
||||
defaultExpandedArguments: {
|
||||
duration: 'fast'
|
||||
},
|
||||
|
||||
initialize: function ( id, options ) {
|
||||
var control = this;
|
||||
api.Control.prototype.initialize.call( control, id, options );
|
||||
control.expanded = new api.Value();
|
||||
control.expandedArgumentsQueue = [];
|
||||
control.expanded.bind( function ( expanded ) {
|
||||
var args = control.expandedArgumentsQueue.shift();
|
||||
args = $.extend( {}, control.defaultExpandedArguments, args );
|
||||
control.onChangeExpanded( expanded, args );
|
||||
});
|
||||
control.expanded.set( false );
|
||||
},
|
||||
|
||||
/**
|
||||
* Set up the control
|
||||
*/
|
||||
@@ -529,13 +546,13 @@
|
||||
if ( sidebarWidgetsControl.isReordering ) {
|
||||
return;
|
||||
}
|
||||
self.toggleForm();
|
||||
self.expanded( ! self.expanded() );
|
||||
} );
|
||||
|
||||
$closeBtn = this.container.find( '.widget-control-close' );
|
||||
$closeBtn.on( 'click', function( e ) {
|
||||
e.preventDefault();
|
||||
self.collapseForm();
|
||||
self.collapse();
|
||||
self.container.find( '.widget-top .widget-action:first' ).focus(); // keyboard accessibility
|
||||
} );
|
||||
},
|
||||
@@ -777,9 +794,14 @@
|
||||
* Overrides api.Control.toggle()
|
||||
*
|
||||
* @param {Boolean} active
|
||||
* @param {Object} args
|
||||
*/
|
||||
toggle: function ( active ) {
|
||||
onChangeActive: function ( active, args ) {
|
||||
// Note: there is a second 'args' parameter being passed, merged on top of this.defaultActiveArguments
|
||||
this.container.toggleClass( 'widget-rendered', active );
|
||||
if ( args.completeCallback ) {
|
||||
args.completeCallback();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1101,51 +1123,90 @@
|
||||
* Expand the accordion section containing a control
|
||||
*/
|
||||
expandControlSection: function() {
|
||||
var $section = this.container.closest( '.accordion-section' );
|
||||
|
||||
if ( ! $section.hasClass( 'open' ) ) {
|
||||
$section.find( '.accordion-section-title:first' ).trigger( 'click' );
|
||||
}
|
||||
api.Control.prototype.expand.call( this );
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Boolean} expanded
|
||||
* @param {Object} [params]
|
||||
* @returns {Boolean} false if state already applied
|
||||
*/
|
||||
_toggleExpanded: api.Section.prototype._toggleExpanded,
|
||||
|
||||
/**
|
||||
* @param {Object} [params]
|
||||
* @returns {Boolean} false if already expanded
|
||||
*/
|
||||
expand: api.Section.prototype.expand,
|
||||
|
||||
/**
|
||||
* Expand the widget form control
|
||||
*
|
||||
* @deprecated alias of expand()
|
||||
*/
|
||||
expandForm: function() {
|
||||
this.toggleForm( true );
|
||||
this.expand();
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Object} [params]
|
||||
* @returns {Boolean} false if already collapsed
|
||||
*/
|
||||
collapse: api.Section.prototype.collapse,
|
||||
|
||||
/**
|
||||
* Collapse the widget form control
|
||||
*
|
||||
* @deprecated alias of expand()
|
||||
*/
|
||||
collapseForm: function() {
|
||||
this.toggleForm( false );
|
||||
this.collapse();
|
||||
},
|
||||
|
||||
/**
|
||||
* Expand or collapse the widget control
|
||||
*
|
||||
* @deprecated this is poor naming, and it is better to directly set control.expanded( showOrHide )
|
||||
*
|
||||
* @param {boolean|undefined} [showOrHide] If not supplied, will be inverse of current visibility
|
||||
*/
|
||||
toggleForm: function( showOrHide ) {
|
||||
var self = this, $widget, $inside, complete;
|
||||
|
||||
$widget = this.container.find( 'div.widget:first' );
|
||||
$inside = $widget.find( '.widget-inside:first' );
|
||||
if ( typeof showOrHide === 'undefined' ) {
|
||||
showOrHide = ! $inside.is( ':visible' );
|
||||
showOrHide = ! this.expanded();
|
||||
}
|
||||
this.expanded( showOrHide );
|
||||
},
|
||||
|
||||
// Already expanded or collapsed, so noop
|
||||
if ( $inside.is( ':visible' ) === showOrHide ) {
|
||||
/**
|
||||
* Respond to change in the expanded state.
|
||||
*
|
||||
* @param {Boolean} expanded
|
||||
* @param {Object} args merged on top of this.defaultActiveArguments
|
||||
*/
|
||||
onChangeExpanded: function ( expanded, args ) {
|
||||
var self = this, $widget, $inside, complete, prevComplete;
|
||||
|
||||
// If the expanded state is unchanged only manipulate container expanded states
|
||||
if ( args.unchanged ) {
|
||||
if ( expanded ) {
|
||||
api.Control.prototype.expand.call( self, {
|
||||
completeCallback: args.completeCallback
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( showOrHide ) {
|
||||
$widget = this.container.find( 'div.widget:first' );
|
||||
$inside = $widget.find( '.widget-inside:first' );
|
||||
|
||||
if ( expanded ) {
|
||||
|
||||
self.expandControlSection();
|
||||
|
||||
// Close all other widget controls before expanding this one
|
||||
api.control.each( function( otherControl ) {
|
||||
if ( self.params.type === otherControl.params.type && self !== otherControl ) {
|
||||
otherControl.collapseForm();
|
||||
otherControl.collapse();
|
||||
}
|
||||
} );
|
||||
|
||||
@@ -1154,29 +1215,44 @@
|
||||
self.container.addClass( 'expanded' );
|
||||
self.container.trigger( 'expanded' );
|
||||
};
|
||||
if ( args.completeCallback ) {
|
||||
prevComplete = complete;
|
||||
complete = function () {
|
||||
prevComplete();
|
||||
args.completeCallback();
|
||||
};
|
||||
}
|
||||
|
||||
if ( self.params.is_wide ) {
|
||||
$inside.fadeIn( 'fast', complete );
|
||||
$inside.fadeIn( args.duration, complete );
|
||||
} else {
|
||||
$inside.slideDown( 'fast', complete );
|
||||
$inside.slideDown( args.duration, complete );
|
||||
}
|
||||
|
||||
self.container.trigger( 'expand' );
|
||||
self.container.addClass( 'expanding' );
|
||||
} else {
|
||||
|
||||
complete = function() {
|
||||
self.container.removeClass( 'collapsing' );
|
||||
self.container.removeClass( 'expanded' );
|
||||
self.container.trigger( 'collapsed' );
|
||||
};
|
||||
if ( args.completeCallback ) {
|
||||
prevComplete = complete;
|
||||
complete = function () {
|
||||
prevComplete();
|
||||
args.completeCallback();
|
||||
};
|
||||
}
|
||||
|
||||
self.container.trigger( 'collapse' );
|
||||
self.container.addClass( 'collapsing' );
|
||||
|
||||
if ( self.params.is_wide ) {
|
||||
$inside.fadeOut( 'fast', complete );
|
||||
$inside.fadeOut( args.duration, complete );
|
||||
} else {
|
||||
$inside.slideUp( 'fast', function() {
|
||||
$inside.slideUp( args.duration, function() {
|
||||
$widget.css( { width:'', margin:'' } );
|
||||
complete();
|
||||
} );
|
||||
@@ -1184,16 +1260,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Expand the containing sidebar section, expand the form, and focus on
|
||||
* the first input in the control
|
||||
*/
|
||||
focus: function() {
|
||||
this.expandControlSection();
|
||||
this.expandForm();
|
||||
this.container.find( '.widget-content :focusable:first' ).focus();
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the position (index) of the widget in the containing sidebar
|
||||
*
|
||||
@@ -1304,6 +1370,7 @@
|
||||
* @augments wp.customize.Control
|
||||
*/
|
||||
api.Widgets.SidebarControl = api.Control.extend({
|
||||
|
||||
/**
|
||||
* Set up the control
|
||||
*/
|
||||
@@ -1325,7 +1392,7 @@
|
||||
registeredSidebar = api.Widgets.registeredSidebars.get( this.params.sidebar_id );
|
||||
|
||||
this.setting.bind( function( newWidgetIds, oldWidgetIds ) {
|
||||
var widgetFormControls, $sidebarWidgetsAddControl, finalControlContainers, removedWidgetIds;
|
||||
var widgetFormControls, removedWidgetIds, priority;
|
||||
|
||||
removedWidgetIds = _( oldWidgetIds ).difference( newWidgetIds );
|
||||
|
||||
@@ -1350,21 +1417,16 @@
|
||||
widgetFormControls.sort( function( a, b ) {
|
||||
var aIndex = _.indexOf( newWidgetIds, a.params.widget_id ),
|
||||
bIndex = _.indexOf( newWidgetIds, b.params.widget_id );
|
||||
return aIndex - bIndex;
|
||||
});
|
||||
|
||||
if ( aIndex === bIndex ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return aIndex < bIndex ? -1 : 1;
|
||||
} );
|
||||
|
||||
// Append the controls to put them in the right order
|
||||
finalControlContainers = _( widgetFormControls ).map( function( widgetFormControls ) {
|
||||
return widgetFormControls.container[0];
|
||||
} );
|
||||
|
||||
$sidebarWidgetsAddControl = self.$sectionContent.find( '.customize-control-sidebar_widgets' );
|
||||
$sidebarWidgetsAddControl.before( finalControlContainers );
|
||||
priority = 0;
|
||||
_( widgetFormControls ).each( function ( control ) {
|
||||
control.priority( priority );
|
||||
control.section( self.section() );
|
||||
priority += 1;
|
||||
});
|
||||
self.priority( priority ); // Make sure sidebar control remains at end
|
||||
|
||||
// Re-sort widget form controls (including widgets form other sidebars newly moved here)
|
||||
self._applyCardinalOrderClassNames();
|
||||
@@ -1434,36 +1496,9 @@
|
||||
// Update the model with whether or not the sidebar is rendered
|
||||
self.active.bind( function ( active ) {
|
||||
registeredSidebar.set( 'is_rendered', active );
|
||||
api.section( self.section.get() ).active( active );
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the sidebar section when it becomes visible.
|
||||
*
|
||||
* Overrides api.Control.toggle()
|
||||
*
|
||||
* @param {Boolean} active
|
||||
*/
|
||||
toggle: function ( active ) {
|
||||
var $section, sectionSelector;
|
||||
|
||||
sectionSelector = '#accordion-section-sidebar-widgets-' + this.params.sidebar_id;
|
||||
$section = $( sectionSelector );
|
||||
|
||||
if ( active ) {
|
||||
$section.stop().slideDown( function() {
|
||||
$( this ).css( 'height', 'auto' ); // so that the .accordion-section-content won't overflow
|
||||
} );
|
||||
|
||||
} else {
|
||||
// Make sure that hidden sections get closed first
|
||||
if ( $section.hasClass( 'open' ) ) {
|
||||
// it would be nice if accordionSwitch() in accordion.js was public
|
||||
$section.find( '.accordion-section-title' ).trigger( 'click' );
|
||||
}
|
||||
|
||||
$section.stop().slideUp();
|
||||
}
|
||||
api.section( self.section.get() ).active( self.active() );
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1500,12 +1535,18 @@
|
||||
this.$controlSection.find( '.accordion-section-title' ).droppable({
|
||||
accept: '.customize-control-widget_form',
|
||||
over: function() {
|
||||
if ( ! self.$controlSection.hasClass( 'open' ) ) {
|
||||
self.$controlSection.addClass( 'open' );
|
||||
self.$sectionContent.toggle( false ).slideToggle( 150, function() {
|
||||
self.$sectionContent.sortable( 'refreshPositions' );
|
||||
} );
|
||||
}
|
||||
var section = api.section( self.section.get() );
|
||||
section.expand({
|
||||
allowMultiple: true, // Prevent the section being dragged from to be collapsed
|
||||
completeCallback: function () {
|
||||
// @todo It is not clear when refreshPositions should be called on which sections, or if it is even needed
|
||||
api.section.each( function ( otherSection ) {
|
||||
if ( otherSection.container.find( '.customize-control-sidebar_widgets' ).length ) {
|
||||
otherSection.container.find( '.accordion-section-content:first' ).sortable( 'refreshPositions' );
|
||||
}
|
||||
} );
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1548,16 +1589,30 @@
|
||||
* Add classes to the widget_form controls to assist with styling
|
||||
*/
|
||||
_applyCardinalOrderClassNames: function() {
|
||||
this.$sectionContent.find( '.customize-control-widget_form' )
|
||||
.removeClass( 'first-widget' )
|
||||
.removeClass( 'last-widget' )
|
||||
.find( '.move-widget-down, .move-widget-up' ).prop( 'tabIndex', 0 );
|
||||
var widgetControls = [];
|
||||
_.each( this.setting(), function ( widgetId ) {
|
||||
var widgetControl = api.Widgets.getWidgetFormControlForWidget( widgetId );
|
||||
if ( widgetControl ) {
|
||||
widgetControls.push( widgetControl );
|
||||
}
|
||||
});
|
||||
|
||||
this.$sectionContent.find( '.customize-control-widget_form:first' )
|
||||
if ( ! widgetControls.length ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$( widgetControls ).each( function () {
|
||||
$( this.container )
|
||||
.removeClass( 'first-widget' )
|
||||
.removeClass( 'last-widget' )
|
||||
.find( '.move-widget-down, .move-widget-up' ).prop( 'tabIndex', 0 );
|
||||
});
|
||||
|
||||
_.first( widgetControls ).container
|
||||
.addClass( 'first-widget' )
|
||||
.find( '.move-widget-up' ).prop( 'tabIndex', -1 );
|
||||
|
||||
this.$sectionContent.find( '.customize-control-widget_form:last' )
|
||||
_.last( widgetControls ).container
|
||||
.addClass( 'last-widget' )
|
||||
.find( '.move-widget-down' ).prop( 'tabIndex', -1 );
|
||||
},
|
||||
@@ -1571,6 +1626,8 @@
|
||||
* Enable/disable the reordering UI
|
||||
*
|
||||
* @param {Boolean} showOrHide to enable/disable reordering
|
||||
*
|
||||
* @todo We should have a reordering state instead and rename this to onChangeReordering
|
||||
*/
|
||||
toggleReordering: function( showOrHide ) {
|
||||
showOrHide = Boolean( showOrHide );
|
||||
@@ -1584,7 +1641,7 @@
|
||||
|
||||
if ( showOrHide ) {
|
||||
_( this.getWidgetFormControls() ).each( function( formControl ) {
|
||||
formControl.collapseForm();
|
||||
formControl.collapse();
|
||||
} );
|
||||
|
||||
this.$sectionContent.find( '.first-widget .move-widget' ).focus();
|
||||
@@ -1619,7 +1676,7 @@
|
||||
* @returns {object|false} widget_form control instance, or false on error
|
||||
*/
|
||||
addWidget: function( widgetId ) {
|
||||
var self = this, controlHtml, $widget, controlType = 'widget_form', $control, controlConstructor,
|
||||
var self = this, controlHtml, $widget, controlType = 'widget_form', controlContainer, controlConstructor,
|
||||
parsedWidgetId = parseWidgetId( widgetId ),
|
||||
widgetNumber = parsedWidgetId.number,
|
||||
widgetIdBase = parsedWidgetId.id_base,
|
||||
@@ -1651,30 +1708,28 @@
|
||||
|
||||
$widget = $( controlHtml );
|
||||
|
||||
$control = $( '<li/>' )
|
||||
controlContainer = $( '<li/>' )
|
||||
.addClass( 'customize-control' )
|
||||
.addClass( 'customize-control-' + controlType )
|
||||
.append( $widget );
|
||||
|
||||
// Remove icon which is visible inside the panel
|
||||
$control.find( '> .widget-icon' ).remove();
|
||||
controlContainer.find( '> .widget-icon' ).remove();
|
||||
|
||||
if ( widget.get( 'is_multi' ) ) {
|
||||
$control.find( 'input[name="widget_number"]' ).val( widgetNumber );
|
||||
$control.find( 'input[name="multi_number"]' ).val( widgetNumber );
|
||||
controlContainer.find( 'input[name="widget_number"]' ).val( widgetNumber );
|
||||
controlContainer.find( 'input[name="multi_number"]' ).val( widgetNumber );
|
||||
}
|
||||
|
||||
widgetId = $control.find( '[name="widget-id"]' ).val();
|
||||
widgetId = controlContainer.find( '[name="widget-id"]' ).val();
|
||||
|
||||
$control.hide(); // to be slid-down below
|
||||
controlContainer.hide(); // to be slid-down below
|
||||
|
||||
settingId = 'widget_' + widget.get( 'id_base' );
|
||||
if ( widget.get( 'is_multi' ) ) {
|
||||
settingId += '[' + widgetNumber + ']';
|
||||
}
|
||||
$control.attr( 'id', 'customize-control-' + settingId.replace( /\]/g, '' ).replace( /\[/g, '-' ) );
|
||||
|
||||
this.container.after( $control );
|
||||
controlContainer.attr( 'id', 'customize-control-' + settingId.replace( /\]/g, '' ).replace( /\[/g, '-' ) );
|
||||
|
||||
// Only create setting if it doesn't already exist (if we're adding a pre-existing inactive widget)
|
||||
isExistingWidget = api.has( settingId );
|
||||
@@ -1692,6 +1747,7 @@
|
||||
settings: {
|
||||
'default': settingId
|
||||
},
|
||||
content: controlContainer,
|
||||
sidebar_id: self.params.sidebar_id,
|
||||
widget_id: widgetId,
|
||||
widget_id_base: widget.get( 'id_base' ),
|
||||
@@ -1731,9 +1787,9 @@
|
||||
this.setting( sidebarWidgets );
|
||||
}
|
||||
|
||||
$control.slideDown( function() {
|
||||
controlContainer.slideDown( function() {
|
||||
if ( isExistingWidget ) {
|
||||
widgetFormControl.expandForm();
|
||||
widgetFormControl.expand();
|
||||
widgetFormControl.updateWidget( {
|
||||
instance: widgetFormControl.setting(),
|
||||
complete: function( error ) {
|
||||
|
||||
2
wp-admin/js/customize-widgets.min.js
vendored
2
wp-admin/js/customize-widgets.min.js
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user