Skip to content

Commit 6718bd3

Browse files
committed
Admin: Add screen option to turn off moving meta boxes.
In most cases, changing the order and position of dashboard or post meta boxes is an occasional need. When it's not needed, the extra two controls for every meta box create a high number of extra tab stops and a busy design. The drag and drop can result in accidental moves and difficulty scrolling on mobile devices due to accidental touch effects. Add a screen option that allows users to disable moving meta boxes, disabling mover buttons and drag and drop behavior. The setting is defaulted to enable moving meta boxes, so there is no change in the default experience for users. Developed in #12627. Props azaozz, pbiron, afercia, johnbillion, hellofromtonya, helen, knutsp, johnjamesjacoby, garrett-eclipse, margaretschneider, johnstonphilip, hedgefield, sanketparmar, poligilad, sabernhardt, tyxla, jillq, sarahricker, ryokuhi, poena, abrain, SergeyBiryukov, joedolson. Fixes #50699, #51419. git-svn-id: https://develop.svn.wordpress.org/trunk@64301 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 4b712b2 commit 6718bd3

12 files changed

Lines changed: 357 additions & 5 deletions

File tree

‎src/js/_enqueues/admin/common.js‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1858,7 +1858,7 @@ $( function() {
18581858
$document.on( 'postbox-toggled', this.maybeDisableSortables );
18591859

18601860
// When the screen columns are changed, potentially disable sortables.
1861-
$( '#screen-options-wrap input' ).on( 'click', this.maybeDisableSortables );
1861+
$( '#screen-options-wrap input:not(.meta-box-reordering-toggle)' ).on( 'click', this.maybeDisableSortables );
18621862
},
18631863

18641864
/**
@@ -1872,6 +1872,7 @@ $( function() {
18721872
var width = navigator.userAgent.indexOf('AppleWebKit/') > -1 ? $window.width() : window.innerWidth;
18731873

18741874
if (
1875+
$body.hasClass( 'meta-box-reordering-disabled' ) ||
18751876
( width <= 782 ) ||
18761877
( 1 >= $sortables.find( '.ui-sortable-handle:visible' ).length && jQuery( '.columns-prefs-1 input' ).prop( 'checked' ) )
18771878
) {

‎src/js/_enqueues/admin/postbox.js‎

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@
104104
postboxWithinSortablesIndex = postboxesWithinSortables.index( postbox ),
105105
firstOrLastPositionMessage;
106106

107+
if ( ! postboxes.metaBoxReorderingEnabled ) {
108+
return;
109+
}
110+
107111
if ( 'dashboard_browser_nag' === postboxId ) {
108112
return;
109113
}
@@ -344,6 +348,13 @@
344348
postboxes.save_order( page );
345349
}
346350
});
351+
352+
$( '.meta-box-reordering-toggle' ).on( 'click.postboxes', function() {
353+
var enabled = $( this ).prop( 'checked' );
354+
355+
postboxes.setMetaBoxReordering( enabled );
356+
postboxes.save_meta_box_reordering_state( enabled );
357+
} );
347358
},
348359

349360
/**
@@ -419,6 +430,8 @@
419430
}
420431
});
421432

433+
this.setMetaBoxReordering( this.isMetaBoxReorderingEnabled() );
434+
422435
if ( isMobile ) {
423436
$(document.body).on('orientationchange.postboxes', function(){ postboxes._pb_change(); });
424437
this._pb_change();
@@ -437,6 +450,51 @@
437450
});
438451
},
439452

453+
/**
454+
* Checks whether meta box reordering is enabled.
455+
*
456+
* @since 7.2.0
457+
*
458+
* @return {boolean} Whether meta box reordering is enabled.
459+
*/
460+
isMetaBoxReorderingEnabled: function() {
461+
var $toggle = $( '#meta-box-reordering' );
462+
463+
if ( $toggle.length ) {
464+
return $toggle.prop( 'checked' );
465+
}
466+
467+
return ! $( document.body ).hasClass( 'meta-box-reordering-disabled' );
468+
},
469+
470+
/**
471+
* Enables or disables the meta box reordering UI.
472+
*
473+
* @since 7.2.0
474+
*
475+
* @param {boolean} enabled Whether reordering should be enabled.
476+
* @return {void}
477+
*/
478+
setMetaBoxReordering: function( enabled ) {
479+
var $sortables = $( '.meta-box-sortables' );
480+
481+
this.metaBoxReorderingEnabled = enabled;
482+
483+
$( document.body ).toggleClass( 'meta-box-reordering-disabled', ! this.metaBoxReorderingEnabled );
484+
485+
if ( window.wpResponsive && window.wpResponsive.maybeDisableSortables ) {
486+
window.wpResponsive.maybeDisableSortables();
487+
return;
488+
}
489+
490+
if ( $sortables.hasClass( 'ui-sortable' ) ) {
491+
$sortables
492+
.sortable( this.metaBoxReorderingEnabled ? 'enable' : 'disable' )
493+
.find( '.ui-sortable-handle' )
494+
.toggleClass( 'is-non-sortable', ! this.metaBoxReorderingEnabled );
495+
}
496+
},
497+
440498
/**
441499
* Saves the state of the postboxes to the server.
442500
*
@@ -476,6 +534,32 @@
476534
);
477535
},
478536

537+
/**
538+
* Saves the meta box reordering setting to the server.
539+
*
540+
* @since 7.2.0
541+
*
542+
* @param {boolean} enabled Whether meta box reordering is enabled.
543+
* @return {void}
544+
*/
545+
save_meta_box_reordering_state: function( enabled ) {
546+
$.post(
547+
ajaxurl,
548+
{
549+
action: 'meta-box-reordering',
550+
enabled: enabled ? 1 : 0,
551+
screenoptionnonce: $( '#screenoptionnonce' ).val()
552+
},
553+
function() {
554+
wp.a11y.speak(
555+
enabled ?
556+
__( 'Rearranging screen elements enabled.' ) :
557+
__( 'Rearranging screen elements disabled.' )
558+
);
559+
}
560+
);
561+
},
562+
479563
/**
480564
* Saves the order of the postboxes to the server.
481565
*

‎src/wp-admin/admin-ajax.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
'add-user',
8080
'closed-postboxes',
8181
'hidden-columns',
82+
'meta-box-reordering',
8283
'update-welcome-panel',
8384
'menu-get-metabox',
8485
'wp-link-ajax',

‎src/wp-admin/admin-header.php‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,10 @@ function addLoadEvent( func ) {
245245
$admin_body_class .= ' block-editor-page wp-embed-responsive';
246246
}
247247

248+
if ( ! wp_is_meta_box_reordering_enabled() ) {
249+
$admin_body_class .= ' meta-box-reordering-disabled';
250+
}
251+
248252
$admin_body_class .= ' wp-theme-' . sanitize_html_class( get_template() );
249253
if ( is_child_theme() ) {
250254
$admin_body_class .= ' wp-child-theme-' . sanitize_html_class( get_stylesheet() );

‎src/wp-admin/css/common.css‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,6 +1990,10 @@ p.auto-update-status {
19901990
line-height: 2.35;
19911991
}
19921992

1993+
.additional-settings-prefs {
1994+
margin-top: 14px;
1995+
}
1996+
19931997
/* This ID appears to be unused in Core. */
19941998
#number-of-columns {
19951999
display: inline-block;
@@ -2286,6 +2290,11 @@ html.wp-toolbar {
22862290
width: 1.62rem;
22872291
}
22882292

2293+
.js.meta-box-reordering-disabled .postbox .handle-order-higher,
2294+
.js.meta-box-reordering-disabled .postbox .handle-order-lower {
2295+
display: none;
2296+
}
2297+
22892298
/* Post box order buttons in the block editor meta boxes area. */
22902299
.edit-post-meta-boxes-area .postbox .handle-order-higher,
22912300
.edit-post-meta-boxes-area .postbox .handle-order-lower {

‎src/wp-admin/css/dashboard.css‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,10 @@ a.rsswidget {
13791379
}
13801380
}
13811381

1382+
.js.meta-box-reordering-disabled #dashboard-widgets .postbox-container .empty-container {
1383+
display: none;
1384+
}
1385+
13821386
@media screen and (max-width: 870px) {
13831387
/* @deprecated 5.9.0 -- Lists removed from welcome panel. */
13841388
.welcome-panel .welcome-panel-column li {

‎src/wp-admin/includes/ajax-actions.php‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1874,6 +1874,20 @@ function wp_ajax_hidden_columns() {
18741874
wp_die( 1 );
18751875
}
18761876

1877+
/**
1878+
* Handles the meta box reordering setting via Ajax.
1879+
*
1880+
* @since 7.2.0
1881+
*/
1882+
function wp_ajax_meta_box_reordering() {
1883+
check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' );
1884+
1885+
$enabled = isset( $_POST['enabled'] ) && '1' === (string) $_POST['enabled'];
1886+
update_user_option( get_current_user_id(), 'meta_box_reordering', $enabled ? 'enabled' : 'disabled' );
1887+
1888+
wp_die( 1 );
1889+
}
1890+
18771891
/**
18781892
* Handles updating whether to display the welcome panel via AJAX.
18791893
*

‎src/wp-admin/includes/class-wp-screen.php‎

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,11 +1006,32 @@ public function show_screen_options() {
10061006

10071007
$this->_screen_settings = '';
10081008

1009+
$additional_settings = '';
1010+
$has_meta_boxes = $this->has_meta_boxes();
1011+
1012+
if ( $has_meta_boxes ) {
1013+
$additional_settings .= $this->get_meta_box_reordering_option();
1014+
}
1015+
10091016
if ( 'post' === $this->base ) {
1010-
$expand = '<fieldset class="editor-expand hidden"><legend>' . __( 'Additional settings' ) . '</legend><label for="editor-expand-toggle">';
1011-
$expand .= '<input type="checkbox" id="editor-expand-toggle"' . checked( get_user_setting( 'editor_expand', 'on' ), 'on', false ) . ' />';
1012-
$expand .= __( 'Enable full-height editor and distraction-free functionality.' ) . '</label></fieldset>';
1013-
$this->_screen_settings = $expand;
1017+
$additional_settings .= '<span class="editor-expand hidden">';
1018+
$additional_settings .= '<input type="checkbox" id="editor-expand-toggle"' . checked( get_user_setting( 'editor_expand', 'on' ), 'on', false ) . ' />';
1019+
$additional_settings .= '<label for="editor-expand-toggle">' . __( 'Enable full-height editor and distraction-free functionality.' ) . '</label>';
1020+
$additional_settings .= '</span>';
1021+
}
1022+
1023+
if ( $additional_settings ) {
1024+
$fieldset_class = 'metabox-prefs additional-settings-prefs';
1025+
1026+
// The editor expand setting is revealed by JavaScript, so keep the fieldset hidden when it is the only setting.
1027+
if ( ! $has_meta_boxes ) {
1028+
$fieldset_class .= ' editor-expand hidden';
1029+
}
1030+
1031+
$this->_screen_settings = '<fieldset class="' . $fieldset_class . '">';
1032+
$this->_screen_settings .= '<legend>' . __( 'Additional settings' ) . '</legend>';
1033+
$this->_screen_settings .= $additional_settings;
1034+
$this->_screen_settings .= '</fieldset>';
10141035
}
10151036

10161037
/**
@@ -1122,6 +1143,9 @@ public function render_meta_boxes_preferences() {
11221143
<p>
11231144
<?php _e( 'Some screen elements can be shown or hidden by using the checkboxes.' ); ?>
11241145
<?php _e( 'Expand or collapse the elements by clicking on their headings, and arrange them by dragging their headings or by clicking on the up and down arrows.' ); ?>
1146+
<?php if ( $this->has_meta_boxes() ) : ?>
1147+
<?php _e( 'Use the setting below to control whether screen elements can be rearranged.' ); ?>
1148+
<?php endif; ?>
11251149
</p>
11261150
<div class="metabox-prefs-container">
11271151
<?php
@@ -1148,6 +1172,33 @@ public function render_meta_boxes_preferences() {
11481172
<?php
11491173
}
11501174

1175+
/**
1176+
* Gets the option to enable or disable meta box reordering.
1177+
*
1178+
* @since 7.2.0
1179+
*
1180+
* @return string Meta box reordering option markup.
1181+
*/
1182+
private function get_meta_box_reordering_option() {
1183+
return '<input class="meta-box-reordering-toggle" name="meta-box-reordering" type="checkbox" id="meta-box-reordering" value="enabled"' . checked( wp_is_meta_box_reordering_enabled(), true, false ) . ' />'
1184+
. '<label for="meta-box-reordering">' . __( 'Allow screen elements to be rearranged' ) . '</label>';
1185+
}
1186+
1187+
/**
1188+
* Checks whether the screen has meta boxes.
1189+
*
1190+
* @since 7.2.0
1191+
*
1192+
* @global array $wp_meta_boxes Global meta box state.
1193+
*
1194+
* @return bool Whether the screen has meta boxes.
1195+
*/
1196+
private function has_meta_boxes() {
1197+
global $wp_meta_boxes;
1198+
1199+
return ! empty( $wp_meta_boxes[ $this->id ] );
1200+
}
1201+
11511202
/**
11521203
* Renders the list table columns preferences.
11531204
*

‎src/wp-admin/includes/screen.php‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,19 @@ function get_hidden_meta_boxes( $screen ) {
194194
return apply_filters( 'hidden_meta_boxes', $hidden, $screen, $use_defaults );
195195
}
196196

197+
/**
198+
* Determines whether meta box reordering is enabled.
199+
*
200+
* @since 7.2.0
201+
*
202+
* @return bool Whether meta box reordering is enabled.
203+
*/
204+
function wp_is_meta_box_reordering_enabled() {
205+
$setting = get_user_option( 'meta_box_reordering' );
206+
207+
return false === $setting ? true : 'disabled' !== $setting;
208+
}
209+
197210
/**
198211
* Register and configure an admin screen option
199212
*

‎tests/phpunit/includes/testcase-ajax.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ abstract class WP_Ajax_UnitTestCase extends WP_UnitTestCase {
6666
'add-user',
6767
'closed-postboxes',
6868
'hidden-columns',
69+
'meta-box-reordering',
6970
'update-welcome-panel',
7071
'menu-get-metabox',
7172
'wp-link-ajax',

0 commit comments

Comments
 (0)