Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions src/wp-includes/admin-bar.php
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,20 @@ function wp_admin_bar_command_palette_menu( WP_Admin_Bar $wp_admin_bar ): void {
),
)
);

// Duplicate into top-secondary for mobile viewport.
$wp_admin_bar->add_node(
array(
'parent' => 'top-secondary',
'id' => 'mobile-command-palette',
'title' => $title,
'href' => '#',
'meta' => array(
'class' => 'hide-if-no-js',
'onclick' => 'wp.data.dispatch( "core/commands" ).open(); return false;',
),
)
);
}

/**
Expand Down Expand Up @@ -1121,6 +1135,15 @@ function wp_admin_bar_comments_menu( $wp_admin_bar ) {
'id' => 'comments',
'title' => $icon . $title,
'href' => admin_url( 'edit-comments.php' ),
'meta' => array(
'menu_title' => $awaiting_mod > 0
? sprintf(
/* translators: %s: Number of comments awaiting moderation. */
__( 'Comments %s' ),
number_format_i18n( $awaiting_mod )
)
: __( 'Comments' ),
),
)
);
}
Expand Down Expand Up @@ -1236,6 +1259,13 @@ function wp_admin_bar_updates_menu( $wp_admin_bar ) {
'id' => 'updates',
'title' => $icon . $title,
'href' => network_admin_url( 'update-core.php' ),
'meta' => array(
'menu_title' => sprintf(
/* translators: %s: Number of updates available. */
__( 'Updates %s' ),
number_format_i18n( $update_data['counts']['total'] )
),
),
)
);
}
Expand Down Expand Up @@ -1300,6 +1330,91 @@ function wp_admin_bar_recovery_mode_menu( $wp_admin_bar ) {
);
}

/**
* Duplicate site and content-related shortcut menus (such as Updates and New)
* under the `site-name` menu and show them on mobile viewport, where
* the original shortcut menus are hidden to make room for the site title.
*
* @since 7.1.0
*
* @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
*/
function wp_admin_bar_duplicate_shortcut_menus( $wp_admin_bar ) {
if ( ! $wp_admin_bar->get_node( 'site-name' ) ) {
return;
}

$shortcut_node_ids = array(
'site-editor',
'customize',
'updates',
'comments',
'new-content',
'edit',
);

$nodes = $wp_admin_bar->get_nodes();

$shortcut_nodes = array();
foreach ( $shortcut_node_ids as $node_id ) {
if ( isset( $nodes[ $node_id ] ) ) {
$shortcut_nodes[] = $nodes[ $node_id ];
}
}

if ( empty( $shortcut_nodes ) ) {
return;
}

$children_by_parent = array();
foreach ( $nodes as $node ) {
if ( ! empty( $node->parent ) ) {
$children_by_parent[ $node->parent ][] = $node;
}
}

$wp_admin_bar->add_group(
array(
'parent' => 'site-name',
'id' => 'mobile-site-shortcuts',
'meta' => array(
'class' => 'ab-sub-secondary',
),
)
);

foreach ( $shortcut_nodes as $node ) {
// Swap potentially icon-only markup for a plain text label
if ( ! empty( $node->meta['menu_title'] ) ) {
$node->title = $node->meta['menu_title'];
}
_wp_admin_bar_clone_subtree( $wp_admin_bar, $node, 'mobile-site-shortcuts', $children_by_parent );
}
}

/**
* Recursively clones a node and its descendants under a new parent.
*
* @since 7.1.0
* @access private
*
* @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
* @param object $node The original node to clone.
* @param string $new_parent The ID of the new parent node.
* @param array $children_by_parent Map of parent id => array of child node objects.
*/
function _wp_admin_bar_clone_subtree( $wp_admin_bar, $node, $new_parent, $children_by_parent ) {
$new_id = 'mobile-site-shortcut-' . $node->id;
$clone = clone $node;
$clone->id = $new_id;
$clone->parent = $new_parent;
$wp_admin_bar->add_node( $clone );

foreach ( $children_by_parent[ $node->id ] ?? array() as $child ) {
_wp_admin_bar_clone_subtree( $wp_admin_bar, $child, $new_id, $children_by_parent );
}
}

/**
* Adds secondary menus.
*
Expand Down
3 changes: 3 additions & 0 deletions src/wp-includes/class-wp-admin-bar.php
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,9 @@ public function add_menus() {
}
add_action( 'admin_bar_menu', 'wp_admin_bar_edit_menu', 80 );

// Duplicate site and content-related shortcut menus under site menu for mobile viewport.
add_action( 'admin_bar_menu', 'wp_admin_bar_duplicate_shortcut_menus', 90 );

add_action( 'admin_bar_menu', 'wp_admin_bar_add_secondary_groups', 200 );

/**
Expand Down
93 changes: 69 additions & 24 deletions src/wp-includes/css/admin-bar.css
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,11 @@ html:lang(he-il) .rtl #wpadminbar * {
content: "\f102" / '';
}


/* Hide the duplicated mobile-only menus on desktop viewport */
#wpadminbar #wp-admin-bar-mobile-site-shortcuts,
#wpadminbar #wp-admin-bar-mobile-command-palette {
display: none;
}

/**
* Comments
Expand Down Expand Up @@ -697,7 +701,8 @@ html:lang(he-il) .rtl #wpadminbar * {
/**
* Command Palette
*/
#wpadminbar #wp-admin-bar-command-palette .ab-icon:before {
#wpadminbar #wp-admin-bar-command-palette .ab-icon:before,
#wpadminbar #wp-admin-bar-mobile-command-palette .ab-icon:before {
content: "\f179";
content: "\f179" / '';
top: 3px;
Expand Down Expand Up @@ -840,7 +845,8 @@ html:lang(he-il) .rtl #wpadminbar * {
padding-right: 30px;
}

#wpadminbar .menupop .menupop > .ab-item:before {
#wpadminbar .menupop .menupop > .ab-item:before,
#wpadminbar .menupop .menupop > .ab-item .wp-admin-bar-arrow:before {
top: 10px;
right: 6px;
}
Expand Down Expand Up @@ -877,9 +883,8 @@ html:lang(he-il) .rtl #wpadminbar * {
padding: 0;
}

/* My Sites and "Site Title" menu */
/* My Sites menu */
#wpadminbar #wp-admin-bar-my-sites > .ab-item,
#wpadminbar #wp-admin-bar-site-name > .ab-item,
#wpadminbar #wp-admin-bar-site-editor > .ab-item,
#wpadminbar #wp-admin-bar-customize > .ab-item,
#wpadminbar #wp-admin-bar-edit > .ab-item,
Expand Down Expand Up @@ -951,12 +956,14 @@ html:lang(he-il) .rtl #wpadminbar * {

/* Comments and Command Palette */
#wpadminbar #wp-admin-bar-comments .ab-icon,
#wpadminbar #wp-admin-bar-command-palette .ab-icon {
#wpadminbar #wp-admin-bar-command-palette .ab-icon,
#wpadminbar #wp-admin-bar-mobile-command-palette .ab-icon {
margin: 0;
}

#wpadminbar #wp-admin-bar-comments .ab-icon:before,
#wpadminbar #wp-admin-bar-command-palette .ab-icon:before {
#wpadminbar #wp-admin-bar-command-palette .ab-icon:before,
#wpadminbar #wp-admin-bar-mobile-command-palette .ab-icon:before {
display: block;
font-size: 34px;
height: 46px;
Expand Down Expand Up @@ -1018,18 +1025,64 @@ html:lang(he-il) .rtl #wpadminbar * {
#wpadminbar li#wp-admin-bar-menu-toggle,
#wpadminbar li#wp-admin-bar-wp-logo,
#wpadminbar li#wp-admin-bar-my-sites,
#wpadminbar li#wp-admin-bar-updates,
#wpadminbar li#wp-admin-bar-site-name,
#wpadminbar li#wp-admin-bar-site-editor,
#wpadminbar li#wp-admin-bar-customize,
#wpadminbar li#wp-admin-bar-new-content,
#wpadminbar li#wp-admin-bar-edit,
#wpadminbar li#wp-admin-bar-comments,
#wpadminbar li#wp-admin-bar-my-account,
#wpadminbar li#wp-admin-bar-command-palette {
#wpadminbar li#wp-admin-bar-my-account {
display: block;
}

#wpadminbar li#wp-admin-bar-site-name > .ab-item {
position: relative;
padding: 0 12px 0 52px;
}

#wpadminbar li#wp-admin-bar-site-name > .ab-item:before {
position: absolute;
left: 0;
top: 7px;
}

/* Show the duplicated mobile-only menus on mobile viewport */
#wpadminbar #wp-admin-bar-mobile-site-shortcuts,
#wpadminbar #wp-admin-bar-mobile-command-palette {
display: block;
}

/* Allow the root left nodes to overflow past the viewport */
#wpadminbar .ab-top-menu {
min-width: max-content;
}

#wpadminbar {
overflow-x: clip;
}

/* Pin the secondary group to the right edge instead of letting it float,
* covering the root left nodes when they overflow */
#wpadminbar #wp-admin-bar-top-secondary {
float: none;
position: absolute;
right: 0;
}

/* Add a fade-out effect to the left edge of the right-pinned secondary group */
#wpadminbar .quicklinks,
#wpadminbar .quicklinks #wp-admin-bar-top-secondary {
background-color: inherit;
}

#wpadminbar #wp-admin-bar-top-secondary::before {
content: '';
position: absolute;
right: 100%;
top: 0;
bottom: 0;
width: 24px;
background-color: inherit;
-webkit-mask-image: linear-gradient(to left, black, transparent);
mask-image: linear-gradient(to left, black, transparent);
pointer-events: none;
}

/* Allow dropdown list items to appear normally */
#wpadminbar li:hover ul li,
#wpadminbar li.hover ul li,
Expand Down Expand Up @@ -1119,8 +1172,7 @@ html:lang(he-il) .rtl #wpadminbar * {
display: list-item;
}

#wpadminbar li#wp-admin-bar-wp-logo,
#wpadminbar li#wp-admin-bar-updates {
#wpadminbar li#wp-admin-bar-wp-logo {
display: none;
}

Expand All @@ -1131,10 +1183,3 @@ html:lang(he-il) .rtl #wpadminbar * {
box-shadow: none;
}
}

/* Very narrow screens */
@media screen and (max-width: 400px) {
#wpadminbar li#wp-admin-bar-comments {
display: none;
}
}
19 changes: 19 additions & 0 deletions tests/phpunit/tests/adminbar.php
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,25 @@ public function data_my_sites_network_menu_items() {
);
}

/**
* @covers ::wp_admin_bar_duplicate_shortcut_menus
*/
public function test_site_name_menu_contains_duplicated_shortcut_menus() {
wp_set_current_user( self::$admin_id );

$wp_admin_bar = $this->get_standard_admin_bar();

$shortcuts = $wp_admin_bar->get_node( 'mobile-site-shortcuts' );
$this->assertNotNull( $shortcuts );
$this->assertSame( 'site-name', $shortcuts->parent );

foreach ( array( 'comments', 'new-content' ) as $node_id ) {
$clone = $wp_admin_bar->get_node( 'mobile-site-shortcut-' . $node_id );
$this->assertNotNull( $clone );
$this->assertSame( 'mobile-site-shortcuts', $clone->parent );
}
}

/**
* This test ensures that WP_Admin_Bar::$proto is not defined (including magic methods).
*
Expand Down
Loading