Skip to content

Commit 9018201

Browse files
committed
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. git-svn-id: https://develop.svn.wordpress.org/trunk@30102 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 037e00f commit 9018201

12 files changed

Lines changed: 1445 additions & 269 deletions

src/wp-admin/customize.php

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@
5353
wp_enqueue_script( 'customize-controls' );
5454
wp_enqueue_style( 'customize-controls' );
5555

56-
wp_enqueue_script( 'accordion' );
57-
5856
/**
5957
* Enqueue Customizer control scripts.
6058
*
@@ -130,7 +128,7 @@
130128
?>
131129

132130
<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 -->
133-
<div class="wp-full-overlay-sidebar-content accordion-container" tabindex="-1">
131+
<div class="wp-full-overlay-sidebar-content" tabindex="-1">
134132
<div id="customize-info" class="accordion-section <?php if ( $cannot_expand ) echo ' cannot-expand'; ?>">
135133
<div class="accordion-section-title" aria-label="<?php esc_attr_e( 'Customizer Options' ); ?>" tabindex="0">
136134
<span class="preview-notice"><?php
@@ -160,13 +158,9 @@
160158
<?php endif; ?>
161159
</div>
162160

163-
<div id="customize-theme-controls"><ul>
164-
<?php
165-
foreach ( $wp_customize->containers() as $container ) {
166-
$container->maybe_render();
167-
}
168-
?>
169-
</ul></div>
161+
<div id="customize-theme-controls">
162+
<ul><?php // Panels and sections are managed here via JavaScript ?></ul>
163+
</div>
170164
</div>
171165
</div>
172166

@@ -252,10 +246,13 @@
252246
),
253247
'settings' => array(),
254248
'controls' => array(),
249+
'panels' => array(),
250+
'sections' => array(),
255251
'nonce' => array(
256252
'save' => wp_create_nonce( 'save-customize_' . $wp_customize->get_stylesheet() ),
257253
'preview' => wp_create_nonce( 'preview-customize_' . $wp_customize->get_stylesheet() )
258254
),
255+
'autofocus' => array(),
259256
);
260257

261258
// Prepare Customize Setting objects to pass to Javascript.
@@ -266,10 +263,32 @@
266263
);
267264
}
268265

269-
// Prepare Customize Control objects to pass to Javascript.
266+
// Prepare Customize Control objects to pass to JavaScript.
270267
foreach ( $wp_customize->controls() as $id => $control ) {
271-
$control->to_json();
272-
$settings['controls'][ $id ] = $control->json;
268+
$settings['controls'][ $id ] = $control->json();
269+
}
270+
271+
// Prepare Customize Section objects to pass to JavaScript.
272+
foreach ( $wp_customize->sections() as $id => $section ) {
273+
$settings['sections'][ $id ] = $section->json();
274+
}
275+
276+
// Prepare Customize Panel objects to pass to JavaScript.
277+
foreach ( $wp_customize->panels() as $id => $panel ) {
278+
$settings['panels'][ $id ] = $panel->json();
279+
foreach ( $panel->sections as $section_id => $section ) {
280+
$settings['sections'][ $section_id ] = $section->json();
281+
}
282+
}
283+
284+
// Pass to frontend the Customizer construct being deeplinked
285+
if ( isset( $_GET['autofocus'] ) && is_array( $_GET['autofocus'] ) ) {
286+
$autofocus = wp_unslash( $_GET['autofocus'] );
287+
foreach ( $autofocus as $type => $id ) {
288+
if ( isset( $settings[ $type . 's' ][ $id ] ) ) {
289+
$settings['autofocus'][ $type ] = $id;
290+
}
291+
}
273292
}
274293

275294
?>

src/wp-admin/js/accordion.js

Lines changed: 2 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@
2525
*
2626
* Note that any appropriate tags may be used, as long as the above classes are present.
2727
*
28-
* In addition to the standard accordion behavior, this file includes JS for the
29-
* Customizer's "Panel" functionality.
30-
*
3128
* @since 3.6.0.
3229
*/
3330

@@ -46,20 +43,8 @@
4643
accordionSwitch( $( this ) );
4744
});
4845

49-
// Go back to the top-level Customizer accordion.
50-
$( '#customize-header-actions' ).on( 'click keydown', '.control-panel-back', function( e ) {
51-
if ( e.type === 'keydown' && 13 !== e.which ) { // "return" key
52-
return;
53-
}
54-
55-
e.preventDefault(); // Keep this AFTER the key filter above
56-
57-
panelSwitch( $( '.current-panel' ) );
58-
});
5946
});
6047

61-
var sectionContent = $( '.accordion-section-content' );
62-
6348
/**
6449
* Close the current accordion section and open a new one.
6550
*
@@ -69,75 +54,22 @@
6954
function accordionSwitch ( el ) {
7055
var section = el.closest( '.accordion-section' ),
7156
siblings = section.closest( '.accordion-container' ).find( '.open' ),
72-
content = section.find( sectionContent );
57+
content = section.find( '.accordion-section-content' );
7358

7459
// This section has no content and cannot be expanded.
7560
if ( section.hasClass( 'cannot-expand' ) ) {
7661
return;
7762
}
7863

79-
// Slide into a sub-panel instead of accordioning (Customizer-specific).
80-
if ( section.hasClass( 'control-panel' ) ) {
81-
panelSwitch( section );
82-
return;
83-
}
84-
8564
if ( section.hasClass( 'open' ) ) {
8665
section.toggleClass( 'open' );
8766
content.toggle( true ).slideToggle( 150 );
8867
} else {
8968
siblings.removeClass( 'open' );
90-
siblings.find( sectionContent ).show().slideUp( 150 );
69+
siblings.find( '.accordion-section-content' ).show().slideUp( 150 );
9170
content.toggle( false ).slideToggle( 150 );
9271
section.toggleClass( 'open' );
9372
}
9473
}
9574

96-
/**
97-
* Slide into an accordion sub-panel.
98-
*
99-
* For the Customizer-specific panel functionality
100-
*
101-
* @param {Object} panel Title element or back button of the accordion panel to toggle.
102-
* @since 4.0.0
103-
*/
104-
function panelSwitch( panel ) {
105-
var position, scroll,
106-
section = panel.closest( '.accordion-section' ),
107-
overlay = section.closest( '.wp-full-overlay' ),
108-
container = section.closest( '.accordion-container' ),
109-
siblings = container.find( '.open' ),
110-
topPanel = overlay.find( '#customize-theme-controls > ul > .accordion-section > .accordion-section-title' ).add( '#customize-info > .accordion-section-title' ),
111-
backBtn = overlay.find( '.control-panel-back' ),
112-
panelTitle = section.find( '.accordion-section-title' ).first(),
113-
content = section.find( '.control-panel-content' );
114-
115-
if ( section.hasClass( 'current-panel' ) ) {
116-
section.toggleClass( 'current-panel' );
117-
overlay.toggleClass( 'in-sub-panel' );
118-
content.delay( 180 ).hide( 0, function() {
119-
content.css( 'margin-top', 'inherit' ); // Reset
120-
} );
121-
topPanel.attr( 'tabindex', '0' );
122-
backBtn.attr( 'tabindex', '-1' );
123-
panelTitle.focus();
124-
container.scrollTop( 0 );
125-
} else {
126-
// Close all open sections in any accordion level.
127-
siblings.removeClass( 'open' );
128-
siblings.find( sectionContent ).show().slideUp( 0 );
129-
content.show( 0, function() {
130-
position = content.offset().top;
131-
scroll = container.scrollTop();
132-
content.css( 'margin-top', ( 45 - position - scroll ) );
133-
section.toggleClass( 'current-panel' );
134-
overlay.toggleClass( 'in-sub-panel' );
135-
container.scrollTop( 0 );
136-
} );
137-
topPanel.attr( 'tabindex', '-1' );
138-
backBtn.attr( 'tabindex', '0' );
139-
backBtn.focus();
140-
}
141-
}
142-
14375
})(jQuery);

0 commit comments

Comments
 (0)