Make WordPress Core

Changeset 23441


Ignore:
Timestamp:
02/16/2013 04:53:59 AM (11 years ago)
Author:
markjaquith
Message:

Improve the UX of the Nav Menus screen. Kill the tabs, and change to a
dropdown, unless you have zero or one menus (which is the most common),
in which case you jump right into editing your sole menu.

Do assignment to location using checkboxes in the main menu editing
section instead of the backwards menu => location assignment in a
random meta box.

More to come, but this gets us started.

props lessbloat, DrewAPicture, jkudish. see #23119

Location:
trunk/wp-admin
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/css/colors-fresh.css

    r23409 r23441  
    401401.submitbox .submitdelete:hover,
    402402#media-items a.delete:hover,
    403 #media-items a.delete-permanently:hover {
     403#media-items a.delete-permanently:hover,
     404#nav-menu-footer .menu-delete:hover {
    404405    color: #fff;
    405406    background-color: #f00;
     
    16821683    background: #21759b;
    16831684    color: #fff;
     1685}
     1686
     1687.manage-menus {
     1688    border: 1px solid #eeeeee;
     1689    background: #fbfbfb;
     1690}
     1691
     1692.menu-settings {
     1693    border-top: 1px solid #eeeeee;
     1694}
     1695
     1696.theme-location-set {
     1697    color: #999999;
     1698}
     1699
     1700.nav-menus-php .delete-action a {
     1701    color: #bc0b0b;
     1702}
     1703
     1704.is-submenu {
     1705    color: #999999;
    16841706}
    16851707/* end added from nav-menu.css */
  • trunk/wp-admin/css/wp-admin-rtl.css

    r23417 r23441  
    454526.0 - Full Overlay w/ Sidebar
    464627.0 - Customize Loader
     4728.0 - Nav Menus
     4829.0 - HiDPI
    4749
    4850
     
    23042306}
    23052307
    2306 .auto-add-pages {
    2307     float: right;
    2308 }
    2309 
    23102308/* Star ratings */
    23112309div.star-holder {
     
    25442542}
    25452543
    2546 /**
    2547  * HiDPI Displays
    2548  */
     2544/*------------------------------------------------------------------------------
     2545  28.0 - Nav Menus
     2546------------------------------------------------------------------------------*/
     2547.nav-menus-php .major-publishing-actions .publishing-action {
     2548    float: left;
     2549}
     2550
     2551.menu-settings dd {
     2552    float: right;
     2553    padding-right: 170px;
     2554}
     2555
     2556.manage-menus span {
     2557    float: right;
     2558}
     2559
     2560.menu-settings dt {
     2561    left: auto;
     2562    right: 0;
     2563}
     2564
     2565.menu-settings dd input,
     2566.menu-settings dd span,
     2567.menu-settings dd label,
     2568.manage-menus select {
     2569    float: right;
     2570    margin-right: 6px;
     2571}
     2572
     2573/*------------------------------------------------------------------------------
     2574  29.0 - HiDPI
     2575------------------------------------------------------------------------------*/
    25492576@media print,
    25502577  (-o-min-device-pixel-ratio: 5/4),
  • trunk/wp-admin/css/wp-admin.css

    r23417 r23441  
    67056705/* nav-menu */
    67066706
     6707.nav-menus-php #message {
     6708    display: none;
     6709}
     6710
     6711.no-js #message {
     6712    display: block;
     6713}
     6714
    67076715#nav-menus-frame {
    67086716    margin-left: 300px;
     6717    margin-top: 28px;
    67096718}
    67106719
     
    67156724    clear: both;
    67166725    float: left;
    6717     padding-top: 24px;
    6718 }
    6719 
    6720 .no-js #wpbody-content #menu-settings-column {
    6721     padding-top: 31px;
     6726    padding-top: 0;
    67226727}
    67236728
     
    67406745}
    67416746
     6747.blank-slate .menu-name {
     6748    height: 2em;
     6749}
     6750
     6751.blank-slate .menu-settings {
     6752    border: none;
     6753    margin-top: 0;
     6754    padding-top: 0;
     6755    overflow: hidden;
     6756}
     6757
     6758.is-submenu {
     6759    font-style: italic;
     6760    font-weight: normal;
     6761    margin-left: 4px;
     6762}
     6763
     6764.manage-menus {
     6765    margin-top: 13px;
     6766    padding: 10px;
     6767    overflow: hidden;
     6768    -webkit-border-radius: 3px;
     6769    border-radius: 3px;
     6770}
     6771
     6772.manage-menus select {
     6773    float: left;
     6774    margin-right: 6px;
     6775}
     6776
     6777.manage-menus .selected-menu {
     6778    float: left;
     6779    margin: 5px 6px 0 0;
     6780}
     6781
     6782.manage-menus .submit-btn {
     6783    float: left;
     6784    margin-top: 1px;
     6785}
     6786
     6787.menu-edit p {
     6788    margin: .3em 0 .6em;
     6789}
     6790
     6791.menu-settings {
     6792    margin-top: 2em;
     6793    padding-top: 16px;
     6794    overflow: hidden;
     6795}
     6796
     6797.menu-settings dl {
     6798    margin: 0 0 10px;
     6799    overflow: hidden;
     6800    position: relative;
     6801}
     6802
     6803.menu-settings dd {
     6804    float: left;
     6805    margin: 0;
     6806    width: 60%;
     6807    padding-left: 170px;
     6808}
     6809
     6810.menu-settings dt {
     6811    clear: both;
     6812    left: 0;
     6813    padding: 3px 0 0;
     6814    position: absolute;
     6815}
     6816
     6817.menu-edit .checkbox-input {
     6818    margin-top: 4px;
     6819}
     6820
     6821.theme-location-set {
     6822    font-size: 11px;
     6823}
     6824
    67426825/* Menu Container */
    67436826#menu-management-liquid {
    67446827    float: left;
    67456828    min-width: 100%;
     6829    margin-top: 3px;
    67466830}
    67476831
     
    67586842
    67596843.nav-menus-php #post-body {
    6760     padding: 10px;
     6844    padding: 0 10px;
    67616845    border-width: 1px 0;
    67626846    border-style: solid;
     
    67706854#nav-menu-header {
    67716855    border-bottom: 1px solid;
     6856    margin-bottom: 13px;
     6857}
     6858
     6859#nav-menu-header .menu-name-label {
     6860    margin-top: 2px;
    67726861}
    67736862
     
    67886877#menu-management .menu-add-new abbr {
    67896878    font-weight:bold;
    6790 }
    6791 
    6792 /* Menu Tabs */
    6793 
    6794 #menu-management .nav-tabs-nav {
    6795     margin: 0 20px;
    6796 }
    6797 
    6798 #menu-management .nav-tabs-arrow {
    6799     width: 10px;
    6800     padding: 0 5px 4px;
    6801     cursor: pointer;
    6802     position: absolute;
    6803     top: 0;
    6804     line-height: 22px;
    6805     font-size: 18px;
    6806 }
    6807 
    6808 #menu-management .nav-tabs-arrow-left {
    6809     left: 0;
    6810 }
    6811 
    6812 #menu-management .nav-tabs-arrow-right {
    6813     right: 0;
    6814     text-align: right;
    6815 }
    6816 
    6817 #menu-management .nav-tabs-wrapper {
    6818     width: 100%;
    6819     height: 28px;
    6820     margin-bottom: -1px;
    6821     overflow: hidden;
    6822 }
    6823 
    6824 #menu-management .nav-tabs {
    6825     padding-left: 20px;
    6826     padding-right: 10px;
    6827 }
    6828 
    6829 .js #menu-management .nav-tabs {
    6830     float: left;
    6831     margin-left: 0px;
    6832     margin-right: -400px;
    6833 }
    6834 
    6835 #menu-management .nav-tab {
    6836     margin-bottom: 0;
    6837     font-size: 14px;
    68386879}
    68396880
     
    70347075
    70357076#menu-to-edit {
    7036     padding: 1em 0;
     7077    margin: 0;
     7078    padding: 0.1em 0;
    70377079}
    70387080
     
    70507092    line-height:1.5em;
    70517093    position:relative;
    7052     margin: 13px 0 0 0;
     7094    margin: 9px 0 0;
    70537095}
    70547096
     
    72707312    float: right;
    72717313    line-height: 23px;
    7272     margin: 5px 0 1px;
    7273 }
    7274 
    7275 .nav-menus-php .major-publishing-actions .delete-action {
    7276     vertical-align: middle;
    7277     text-align: left;
    7278     float: left;
    7279     padding-right: 15px;
    7280     margin-top: 5px;
    7281 }
    7282 
    7283 .menu-name-label span,
    7284 .auto-add-pages label {
    7285     font-size: 12px;
    7286     font-style: normal;
    7287 }
    7288 
    7289 .menu-name-label {
    7290     margin-right: 15px;
    7291 }
    7292 
    7293 .auto-add-pages input {
    7294     margin-top: 0;
    7295 }
    7296 
    7297 .auto-add-pages {
    7298     margin-top: 4px;
    7299     float: left;
     7314    margin: 2px 0 1px;
     7315}
     7316
     7317.nav-menus-php .blank-slate .menu-settings {
     7318    display: none;
     7319}
     7320
     7321.nav-menus-php .delete-action {
     7322    float: left;
     7323    margin-top: 2px;
    73007324}
    73017325
  • trunk/wp-admin/includes/nav-menu.php

    r22396 r23441  
    8282        $title = empty( $item->label ) ? $title : $item->label;
    8383
     84        $submenu_text = '';
     85        if ( 0 == $depth )
     86            $submenu_text = 'style="display: none;"';
     87
    8488        ?>
    8589        <li id="menu-item-<?php echo $item_id; ?>" class="<?php echo implode(' ', $classes ); ?>">
    8690            <dl class="menu-item-bar">
    8791                <dt class="menu-item-handle">
    88                     <span class="item-title"><?php echo esc_html( $title ); ?></span>
     92                    <span class="item-title"><?php echo esc_html( $title ); ?> <span class="is-submenu" <?php echo $submenu_text; ?>><?php _e( 'sub item' ); ?></span></span>
    8993                    <span class="item-controls">
    9094                        <span class="item-type"><?php echo esc_html( $item->type_label ); ?></span>
     
    183187                                'menu-item' => $item_id,
    184188                            ),
    185                             remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
     189                            admin_url( 'nav-menus.php' )
    186190                        ),
    187191                        'delete-menu_item_' . $item_id
    188                     ); ?>"><?php _e('Remove'); ?></a> <span class="meta-sep"> | </span> <a class="item-cancel submitcancel" id="cancel-<?php echo $item_id; ?>" href="<?php echo esc_url( add_query_arg( array('edit-menu-item' => $item_id, 'cancel' => time()), remove_query_arg( $removed_args, admin_url( 'nav-menus.php' ) ) ) );
     192                    ); ?>"><?php _e( 'Remove' ); ?></a> <span class="meta-sep hide-if-no-js"> | </span> <a class="item-cancel submitcancel hide-if-no-js" id="cancel-<?php echo $item_id; ?>" href="<?php echo esc_url( add_query_arg( array( 'edit-menu-item' => $item_id, 'cancel' => time() ), admin_url( 'nav-menus.php' ) ) );
    189193                        ?>#menu-item-settings-<?php echo $item_id; ?>"><?php _e('Cancel'); ?></a>
    190194                </div>
     
    383387function wp_nav_menu_setup() {
    384388    // Register meta boxes
    385     if ( wp_get_nav_menus() )
    386         add_meta_box( 'nav-menu-theme-locations', __( 'Theme Locations' ), 'wp_nav_menu_locations_meta_box' , 'nav-menus', 'side', 'default' );
    387     add_meta_box( 'add-custom-links', __('Custom Links'), 'wp_nav_menu_item_link_meta_box', 'nav-menus', 'side', 'default' );
    388389    wp_nav_menu_post_type_meta_boxes();
     390    add_meta_box( 'add-custom-links', __( 'Add Links' ), 'wp_nav_menu_item_link_meta_box', 'nav-menus', 'side', 'default' );
    389391    wp_nav_menu_taxonomy_meta_boxes();
    390392
     
    412414        return;
    413415
    414     $initial_meta_boxes = array( 'nav-menu-theme-locations', 'add-custom-links', 'add-page', 'add-category' );
     416    $initial_meta_boxes = array( 'nav-menu-theme-locations', 'add-page', 'add-custom-links', 'add-category' );
    415417    $hidden_meta_boxes = array();
    416418
     
    490492    $num_locations = count( array_keys($locations) );
    491493
    492     echo '<p class="howto">' . sprintf( _n('Your theme supports %s menu. Select which menu you would like to use.', 'Your theme supports %s menus. Select which menu appears in each location.', $num_locations ), number_format_i18n($num_locations) ) . '</p>';
     494    echo '<p class="howto">' . _n( 'Select a menu to use within your theme.', 'Select the menus you will use in your theme.', $num_locations ) . '</p>';
    493495
    494496    foreach ( $locations as $location => $description ) {
     
    513515    ?>
    514516    <p class="button-controls">
    515         <?php submit_button( __( 'Save' ), 'primary right', 'nav-menu-locations', false, disabled( $nav_menu_selected_id, 0, false ) ); ?>
     517        <?php submit_button( __( 'Save' ), 'primary right', 'nav-menu-locations', false, wp_nav_menu_disabled_check( $nav_menu_selected_id ) ); ?>
    516518        <span class="spinner"></span>
    517519    </p>
    518520    <?php
     521}
     522
     523/**
     524 * Check whether to disable the Menu Locations meta box submit button
     525 *
     526 * @since 3.6.0
     527 *
     528 * @uses global $one_theme_location_no_menus to determine if no menus exist
     529 * @uses disabled() to output the disabled attribute in $other_attributes param in submit_button()
     530 *
     531 * @param int|string $nav_menu_selected_id (id, name or slug) of the currently-selected menu
     532 * @return string Disabled attribute if at least one menu exists, false if not
     533*/
     534function wp_nav_menu_disabled_check( $nav_menu_selected_id ) {
     535    global $one_theme_location_no_menus;
     536
     537    if ( $one_theme_location_no_menus )
     538        return false;
     539
     540    return disabled( $nav_menu_selected_id, 0 );
    519541}
    520542
     
    555577            <p id="menu-item-name-wrap">
    556578                <label class="howto" for="custom-menu-item-name">
    557                     <span><?php _e('Label'); ?></span>
     579                    <span><?php _e( 'Link Text' ); ?></span>
    558580                    <input id="custom-menu-item-name" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-title]" type="text" class="regular-text menu-item-textbox input-with-default-title" title="<?php esc_attr_e('Menu Item'); ?>" />
    559581                </label>
     
    562584        <p class="button-controls">
    563585            <span class="add-to-menu">
    564                 <input type="submit"<?php disabled( $nav_menu_selected_id, 0 ); ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-custom-menu-item" id="submit-customlinkdiv" />
     586                <input type="submit"<?php wp_nav_menu_disabled_check( $nav_menu_selected_id ); ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-custom-menu-item" id="submit-customlinkdiv" />
    565587                <span class="spinner"></span>
    566588            </span>
     
    769791            <span class="list-controls">
    770792                <a href="<?php
    771                     echo esc_url(add_query_arg(
     793                    echo esc_url( add_query_arg(
    772794                        array(
    773795                            $post_type_name . '-tab' => 'all',
    774796                            'selectall' => 1,
    775797                        ),
    776                         remove_query_arg($removed_args)
     798                        remove_query_arg( $removed_args )
    777799                    ));
    778800                ?>#posttype-<?php echo $post_type_name; ?>" class="select-all"><?php _e('Select All'); ?></a>
     
    780802
    781803            <span class="add-to-menu">
    782                 <input type="submit"<?php disabled( $nav_menu_selected_id, 0 ); ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-post-type-menu-item" id="submit-posttype-<?php echo $post_type_name; ?>" />
     804                <input type="submit"<?php wp_nav_menu_disabled_check( $nav_menu_selected_id ); ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e( __( 'Add to Menu' ) ); ?>" name="add-post-type-menu-item" id="<?php esc_attr_e( 'submit-posttype-' . $post_type_name ); ?>" />
    783805                <span class="spinner"></span>
    784806            </span>
     
    956978
    957979            <span class="add-to-menu">
    958                 <input type="submit"<?php disabled( $nav_menu_selected_id, 0 ); ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-taxonomy-menu-item" id="submit-taxonomy-<?php echo $taxonomy_name; ?>" />
     980                <input type="submit"<?php wp_nav_menu_disabled_check( $nav_menu_selected_id ); ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e( __( 'Add to Menu' ) ); ?>" name="add-taxonomy-menu-item" id="<?php esc_attr_e( 'submit-taxonomy-' . $taxonomy_name ); ?>" />
    959981                <span class="spinner"></span>
    960982            </span>
     
    10871109        $result = '<div id="menu-instructions" class="post-body-plain';
    10881110        $result .= ( ! empty($menu_items) ) ? ' menu-instructions-inactive">' : '">';
    1089         $result .= '<p>' . __('Select menu items (pages, categories, links) from the boxes at left to begin building your custom menu.') . '</p>';
     1111        $result .= '<p>' . __( 'Next, add menu items (i.e. pages, links, categories) from the column on the left.' ) . '</p>';
    10901112        $result .= '</div>';
    10911113
     
    11591181        wp_delete_post( $menu_item_id, true );
    11601182}
    1161 
    11621183add_action('admin_head-nav-menus.php', '_wp_delete_orphaned_draft_menu_items');
     1184
     1185/**
     1186 * Delete nav menus from the nav menu management screen
     1187 *
     1188 * @since 3.6.0
     1189 * @access private
     1190 *
     1191 * @param int|string $nav_menu_id The menu to delete (id, slug, or name)
     1192 * @return false if Error, otherwise true
     1193 */
     1194function _wp_delete_nav_menu( $nav_menu_id ) {
     1195
     1196    if ( ! is_nav_menu( $nav_menu_id ) )
     1197        return;
     1198
     1199    $deleted_nav_menu = wp_get_nav_menu_object( $nav_menu_id );
     1200    $delete_nav_menu = wp_delete_nav_menu( $nav_menu_id );
     1201
     1202    if ( is_wp_error( $delete_nav_menu ) )
     1203        return $delete_nav_menu;
     1204
     1205    // Remove this menu from any locations.
     1206    $locations = get_theme_mod( 'nav_menu_locations' );
     1207    foreach ( (array) $locations as $location => $menu_id ) {
     1208        if ( $menu_id == $nav_menu_id )
     1209            $locations[ $location ] = 0;
     1210    }
     1211    set_theme_mod( 'nav_menu_locations', $locations );
     1212    return true;
     1213}
     1214
     1215/**
     1216 * Saves nav menu items
     1217 *
     1218 * @since 3.6.0
     1219 *
     1220 * @uses wp_get_nav_menu_items() to retrieve the nav menu's menu items
     1221 * @uses wp_defer_term_counter() to enable then disable term counting
     1222 *
     1223 * @param int|string $nav_menu_selected_id (id, slug, or name ) of the currently-selected menu
     1224 * @param string $nav_menu_selected_title Title of the currently-selected menu
     1225 * @return array $messages The menu updated message
     1226 */
     1227function wp_nav_menu_update_menu_items ( $nav_menu_selected_id, $nav_menu_selected_title ) {
     1228    $unsorted_menu_items = wp_get_nav_menu_items( $nav_menu_selected_id, array( 'orderby' => 'ID', 'output' => ARRAY_A, 'output_key' => 'ID', 'post_status' => 'draft,publish' ) );
     1229
     1230    $menu_items = array();
     1231    // Index menu items by db ID
     1232    foreach ( $unsorted_menu_items as $_item )
     1233        $menu_items[$_item->db_id] = $_item;
     1234
     1235    $post_fields = array(
     1236        'menu-item-db-id', 'menu-item-object-id', 'menu-item-object',
     1237        'menu-item-parent-id', 'menu-item-position', 'menu-item-type',
     1238        'menu-item-title', 'menu-item-url', 'menu-item-description',
     1239        'menu-item-attr-title', 'menu-item-target', 'menu-item-classes', 'menu-item-xfn'
     1240    );
     1241
     1242    wp_defer_term_counting( true );
     1243    // Loop through all the menu items' POST variables
     1244    if ( ! empty( $_POST['menu-item-db-id'] ) ) {
     1245        foreach( (array) $_POST['menu-item-db-id'] as $_key => $k ) {
     1246
     1247            // Menu item title can't be blank
     1248            if ( empty( $_POST['menu-item-title'][$_key] ) )
     1249                continue;
     1250
     1251            $args = array();
     1252            foreach ( $post_fields as $field )
     1253                $args[$field] = isset( $_POST[$field][$_key] ) ? $_POST[$field][$_key] : '';
     1254
     1255            $menu_item_db_id = wp_update_nav_menu_item( $nav_menu_selected_id, ( $_POST['menu-item-db-id'][$_key] != $_key ? 0 : $_key ), $args );
     1256
     1257            if ( is_wp_error( $menu_item_db_id ) )
     1258                $messages[] = '<div id="message" class="error"><p>' . $menu_item_db_id->get_error_message() . '</p></div>';
     1259            elseif ( isset( $menu_items[$menu_item_db_id] ) )
     1260                unset( $menu_items[$menu_item_db_id] );
     1261        }
     1262    }
     1263
     1264    // Remove menu items from the menu that weren't in $_POST
     1265    if ( ! empty( $menu_items ) ) {
     1266        foreach ( array_keys( $menu_items ) as $menu_item_id ) {
     1267            if ( is_nav_menu_item( $menu_item_id ) ) {
     1268                wp_delete_post( $menu_item_id );
     1269            }
     1270        }
     1271    }
     1272
     1273    // Store 'auto-add' pages.
     1274    $auto_add = ! empty( $_POST['auto-add-pages'] );
     1275    $nav_menu_option = (array) get_option( 'nav_menu_options' );
     1276    if ( ! isset( $nav_menu_option['auto_add'] ) )
     1277        $nav_menu_option['auto_add'] = array();
     1278    if ( $auto_add ) {
     1279        if ( ! in_array( $nav_menu_selected_id, $nav_menu_option['auto_add'] ) )
     1280            $nav_menu_option['auto_add'][] = $nav_menu_selected_id;
     1281    } else {
     1282        if ( false !== ( $key = array_search( $nav_menu_selected_id, $nav_menu_option['auto_add'] ) ) )
     1283            unset( $nav_menu_option['auto_add'][$key] );
     1284    }
     1285    // Remove nonexistent/deleted menus
     1286    $nav_menu_option['auto_add'] = array_intersect( $nav_menu_option['auto_add'], wp_get_nav_menus( array( 'fields' => 'ids' ) ) );
     1287    update_option( 'nav_menu_options', $nav_menu_option );
     1288
     1289    wp_defer_term_counting( false );
     1290
     1291    do_action( 'wp_update_nav_menu', $nav_menu_selected_id );
     1292
     1293    $messages[] = '<div id="message" class="updated"><p>' . sprintf( __( '<strong>%1$s</strong> has been updated.' ), $nav_menu_selected_title ) . '</p></div>';
     1294    unset( $menu_items, $unsorted_menu_items );
     1295
     1296    return $messages;
     1297}
  • trunk/wp-admin/js/nav-menu.js

    r22019 r23441  
    4646                this.initSortables();
    4747
     48            if( oneThemeLocationNoMenus )
     49                $( '#posttype-page' ).addSelectedToMenu( api.addMenuItemToBottom );
     50
     51            this.messageFadeIn();
     52
     53            this.initAccessibility();
     54
    4855            this.initToggles();
    49 
    50             this.initTabManager();
    5156        },
    5257
     
    8590                    return result;
    8691                },
     92                shiftHorizontally : function( dir ) {
     93                    return this.each(function(){
     94                        var t = $(this),
     95                            depth = t.menuItemDepth(),
     96                            newDepth = depth + dir;
     97
     98                        // Change .menu-item-depth-n class
     99                        t.moveHorizontally( newDepth, depth );
     100                    });
     101                },
     102                moveHorizontally : function( newDepth, depth ) {
     103                    return this.each(function(){
     104                        var t = $(this),
     105                            children = t.childMenuItems(),
     106                            diff = newDepth - depth,
     107                            subItemText = t.find('.is-submenu');
     108
     109                        // Change .menu-item-depth-n class
     110                        t.updateDepthClass( newDepth, depth ).updateParentMenuItemDBId();
     111
     112                        // If it has children, move those too
     113                        if ( children ) {
     114                            children.each(function( index ) {
     115                                var t = $(this),
     116                                    thisDepth = t.menuItemDepth(),
     117                                    newDepth = thisDepth + diff;
     118                                t.updateDepthClass(newDepth, thisDepth).updateParentMenuItemDBId();
     119                            });
     120                        }
     121
     122                        // Show "Sub item" helper text
     123                        if (0 === newDepth)
     124                            subItemText.hide();
     125                        else
     126                            subItemText.show();
     127                    });
     128                },
    87129                updateParentMenuItemDBId : function() {
    88130                    return this.each(function(){
    89131                        var item = $(this),
    90                             input = item.find('.menu-item-data-parent-id'),
    91                             depth = item.menuItemDepth(),
    92                             parent = item.prev();
    93 
    94                         if( depth == 0 ) { // Item is on the top level, has no parent
     132                            input = item.find( '.menu-item-data-parent-id' ),
     133                            depth = parseInt( item.menuItemDepth() ),
     134                            parentDepth = depth - 1,
     135                            parent = item.prevAll( '.menu-item-depth-' + parentDepth ).first();
     136
     137                        if ( 0 == depth ) { // Item is on the top level, has no parent
    95138                            input.val(0);
    96139                        } else { // Find the parent item, and retrieve its object id.
    97                             while( ! parent[0] || ! parent[0].className || -1 == parent[0].className.indexOf('menu-item') || ( parent.menuItemDepth() != depth - 1 ) )
    98                                 parent = parent.prev();
    99                             input.val( parent.find('.menu-item-data-db-id').val() );
     140                            input.val( parent.find( '.menu-item-data-db-id' ).val() );
    100141                        }
    101142                    });
     
    121162                    return this.each(function() {
    122163                        var t = $(this), menuItems = {},
    123                             checkboxes = t.find('.tabs-panel-active .categorychecklist li input:checked'),
     164                            checkboxes = ( oneThemeLocationNoMenus && 0 == t.find('.tabs-panel-active .categorychecklist li input:checked').length ) ? t.find('#page-all li input[type="checkbox"]') : t.find('.tabs-panel-active .categorychecklist li input:checked'),
    124165                            re = new RegExp('menu-item\\[(\[^\\]\]*)');
    125166
     
    224265        },
    225266
     267        initAccessibility : function() {
     268            $( '.item-edit' ).off( 'focus' ).on( 'focus', function(){
     269                $(this).on( 'keydown', function(e){
     270
     271                    var $this = $(this);
     272
     273                    // Bail if it's not an arrow key
     274                    if ( 37 != e.which && 38 != e.which && 39 != e.which && 40 != e.which )
     275                        return;
     276
     277                    // Avoid multiple keydown events
     278                    $this.off('keydown');
     279
     280                    var menuItems = $('#menu-to-edit li');
     281                        menuItemsCount = menuItems.length,
     282                        thisItem = $this.parents( 'li.menu-item' ),
     283                        thisItemChildren = thisItem.childMenuItems(),
     284                        thisItemData = thisItem.getItemData(),
     285                        thisItemDepth = parseInt( thisItem.menuItemDepth() ),
     286                        thisItemPosition = parseInt( thisItem.index() ),
     287                        nextItem = thisItem.next(),
     288                        nextItemChildren = nextItem.childMenuItems(),
     289                        nextItemDepth = parseInt( nextItem.menuItemDepth() ) + 1,
     290                        prevItem = thisItem.prev(),
     291                        prevItemDepth = parseInt( prevItem.menuItemDepth() ),
     292                        prevItemId = prevItem.getItemData()['menu-item-db-id'];
     293
     294                    // Bail if there is only one menu item
     295                    if ( 1 === menuItemsCount )
     296                        return;
     297
     298                    // If RTL, swap left/right arrows
     299                    var arrows = { '38' : 'up', '40' : 'down', '37' : 'left', '39' : 'right' };
     300                    if ( $('body').hasClass('rtl') )
     301                        arrows = { '38' : 'up', '40' : 'down', '39' : 'left', '37' : 'right' };
     302
     303                    switch ( arrows[e.which] ) {
     304                    case 'up':
     305                        var newItemPosition = thisItemPosition - 1;
     306
     307                        // Already at top
     308                        if ( 0 === thisItemPosition )
     309                            break;
     310
     311                        // If a sub item is moved to top, shift it to 0 depth
     312                        if ( 0 === newItemPosition && 0 !== thisItemDepth )
     313                            thisItem.moveHorizontally( 0, thisItemDepth );
     314
     315                        // If prev item is sub item, shift to match depth
     316                        if ( 0 !== prevItemDepth )
     317                            thisItem.moveHorizontally( prevItemDepth, thisItemDepth );
     318
     319                        // Does this item have sub items?
     320                        if ( thisItemChildren ) {
     321                            var items = thisItem.add( thisItemChildren );
     322                            // Move the entire block
     323                            items.detach().insertBefore( menuItems.eq( newItemPosition ) );
     324                        } else {
     325                            thisItem.detach().insertBefore( menuItems.eq( newItemPosition ) );
     326                        }
     327                        break;
     328                    case 'down':
     329                        // Does this item have sub items?
     330                        if ( thisItemChildren ) {
     331                            var items = thisItem.add( thisItemChildren ),
     332                                nextItem = menuItems.eq( items.length + thisItemPosition ),
     333                                nextItemChildren = 0 !== nextItem.childMenuItems().length;
     334
     335                            if ( nextItemChildren ) {
     336                                var newDepth = parseInt( nextItem.menuItemDepth() ) + 1;
     337                                thisItem.moveHorizontally( newDepth, thisItemDepth );
     338                            }
     339
     340                            // Have we reached the bottom?
     341                            if ( menuItemsCount === thisItemPosition + items.length )
     342                                break;
     343
     344                            items.detach().insertAfter( menuItems.eq( thisItemPosition + items.length ) );
     345                        } else {
     346                            // If next item has sub items, shift depth
     347                            if ( 0 !== nextItemChildren.length )
     348                                thisItem.moveHorizontally( nextItemDepth, thisItemDepth );
     349
     350                            // Have we reached the bottom
     351                            if ( menuItemsCount === thisItemPosition + 1 )
     352                                break;
     353                            thisItem.detach().insertAfter( menuItems.eq( thisItemPosition + 1 ) );
     354                        }
     355                        break;
     356                    case 'left':
     357                        // As far left as possible
     358                        if ( 0 === thisItemDepth )
     359                            break;
     360                        thisItem.shiftHorizontally( -1 );
     361                        break;
     362                    case 'right':
     363                        // Can't be sub item at top
     364                        if ( 0 === thisItemPosition )
     365                            break;
     366                        // Already sub item of prevItem
     367                        if ( thisItemData['menu-item-parent-id'] === prevItemId )
     368                            break;
     369                        thisItem.shiftHorizontally( 1 );
     370                        break;
     371                    }
     372                    api.registerChange();
     373                    // Put focus back on same menu item
     374                    $( '#edit-' + thisItemData['menu-item-db-id'] ).focus();
     375                    return false;
     376                });
     377            }).blur(function () {
     378                $(this).off( 'keydown' );
     379            });
     380        },
     381
     382        messageFadeIn : function() {
     383            var messages = $( '#message' );
     384
     385            // Visual change when users save menus multiple times in a row
     386            messages.slideDown( 'slow' );
     387        },
     388
    226389        initToggles : function() {
    227390            // init postboxes
     
    247410                menuMaxDepth = initialMenuMaxDepth();
    248411
     412            if( 0 != $( '#menu-to-edit li' ).length )
     413                $( '.drag-instructions' ).show();
     414
    249415            // Use the right edge if RTL.
    250416            menuEdge += api.isRTL ? api.menuList.width() : 0;
     
    309475                    children = transport.children().insertAfter(ui.item);
    310476
     477                    // Add "sub menu" description
     478                    var subMenuTitle = ui.item.find( '.item-title .is-submenu' );
     479                    if ( 0 < currentDepth )
     480                        subMenuTitle.show();
     481                    else
     482                        subMenuTitle.hide();
     483
    311484                    // Update depth classes
    312485                    if( depthChange != 0 ) {
     
    328501                        ui.item[0].style.right = 0;
    329502                    }
    330 
    331                     // The width of the tab bar might have changed. Just in case.
    332                     api.refreshMenuTabs( true );
    333503                },
    334504                change: function(e, ui) {
     
    462632                    $t.addClass( name ).val( $t.data(name) );
    463633            });
     634
     635            $( '.blank-slate .input-with-default-title' ).focus();
    464636        },
    465637
     
    573745                var ins = $('#menu-instructions');
    574746                processMethod(menuMarkup, params);
    575                 if( ! ins.hasClass('menu-instructions-inactive') && ins.siblings().length )
    576                     ins.addClass('menu-instructions-inactive');
     747                // Make it stand out a bit more visually, by adding a fadeIn
     748                $( 'li.pending' ).hide().fadeIn('slow');
     749                $( '.drag-instructions' ).show();
     750                if( ! ins.hasClass( 'menu-instructions-inactive' ) && ins.siblings().length )
     751                    ins.addClass( 'menu-instructions-inactive' );
    577752                callback();
    578753            });
     
    587762        addMenuItemToBottom : function( menuMarkup, req ) {
    588763            $(menuMarkup).hideAdvancedMenuItemFields().appendTo( api.targetList );
     764            api.initAccessibility();
    589765        },
    590766
    591767        addMenuItemToTop : function( menuMarkup, req ) {
    592768            $(menuMarkup).hideAdvancedMenuItemFields().prependTo( api.targetList );
     769            api.initAccessibility();
    593770        },
    594771
     
    605782            } else {
    606783                // Make the post boxes read-only, as they can't be used yet
    607                 $('#menu-settings-column').find('input,select').prop('disabled', true).end().find('a').attr('href', '#').unbind('click');
     784                $( '#menu-settings-column' ).find( 'input,select' ).end().find( 'a' ).attr( 'href', '#' ).unbind( 'click' );
    608785            }
    609786        },
     
    686863                    return false;
    687864                }
    688             });
    689         },
    690 
    691         initTabManager : function() {
    692             var fixed = $('.nav-tabs-wrapper'),
    693                 fluid = fixed.children('.nav-tabs'),
    694                 active = fluid.children('.nav-tab-active'),
    695                 tabs = fluid.children('.nav-tab'),
    696                 tabsWidth = 0,
    697                 fixedRight, fixedLeft,
    698                 arrowLeft, arrowRight, resizeTimer, css = {},
    699                 marginFluid = api.isRTL ? 'margin-right' : 'margin-left',
    700                 marginFixed = api.isRTL ? 'margin-left' : 'margin-right',
    701                 msPerPx = 2;
    702 
    703             /**
    704              * Refreshes the menu tabs.
    705              * Will show and hide arrows where necessary.
    706              * Scrolls to the active tab by default.
    707              *
    708              * @param savePosition {boolean} Optional. Prevents scrolling so
    709              *        that the current position is maintained. Default false.
    710              **/
    711             api.refreshMenuTabs = function( savePosition ) {
    712                 var fixedWidth = fixed.width(),
    713                     margin = 0, css = {};
    714                 fixedLeft = fixed.offset().left;
    715                 fixedRight = fixedLeft + fixedWidth;
    716 
    717                 if( !savePosition )
    718                     active.makeTabVisible();
    719 
    720                 // Prevent space from building up next to the last tab if there's more to show
    721                 if( tabs.last().isTabVisible() ) {
    722                     margin = fixed.width() - tabsWidth;
    723                     margin = margin > 0 ? 0 : margin;
    724                     css[marginFluid] = margin + 'px';
    725                     fluid.animate( css, 100, "linear" );
    726                 }
    727 
    728                 // Show the arrows only when necessary
    729                 if( fixedWidth > tabsWidth )
    730                     arrowLeft.add( arrowRight ).hide();
    731                 else
    732                     arrowLeft.add( arrowRight ).show();
    733             }
    734 
    735             $.fn.extend({
    736                 makeTabVisible : function() {
    737                     var t = this.eq(0), left, right, css = {}, shift = 0;
    738 
    739                     if( ! t.length ) return this;
    740 
    741                     left = t.offset().left;
    742                     right = left + t.outerWidth();
    743 
    744                     if( right > fixedRight )
    745                         shift = fixedRight - right;
    746                     else if ( left < fixedLeft )
    747                         shift = fixedLeft - left;
    748 
    749                     if( ! shift ) return this;
    750 
    751                     css[marginFluid] = "+=" + api.negateIfRTL * shift + 'px';
    752                     fluid.animate( css, Math.abs( shift ) * msPerPx, "linear" );
    753                     return this;
    754                 },
    755                 isTabVisible : function() {
    756                     var t = this.eq(0),
    757                         left = t.offset().left,
    758                         right = left + t.outerWidth();
    759                     return ( right <= fixedRight && left >= fixedLeft ) ? true : false;
    760                 }
    761             });
    762 
    763             // Find the width of all tabs
    764             tabs.each(function(){
    765                 tabsWidth += $(this).outerWidth(true);
    766             });
    767 
    768             // Set up fixed margin for overflow, unset padding
    769             css['padding'] = 0;
    770             css[marginFixed] = (-1 * tabsWidth) + 'px';
    771             fluid.css( css );
    772 
    773             // Build tab navigation
    774             arrowLeft = $('<div class="nav-tabs-arrow nav-tabs-arrow-left"><a>&laquo;</a></div>');
    775             arrowRight = $('<div class="nav-tabs-arrow nav-tabs-arrow-right"><a>&raquo;</a></div>');
    776             // Attach to the document
    777             fixed.wrap('<div class="nav-tabs-nav"/>').parent().prepend( arrowLeft ).append( arrowRight );
    778 
    779             // Set the menu tabs
    780             api.refreshMenuTabs();
    781             // Make sure the tabs reset on resize
    782             $(window).resize(function() {
    783                 if( resizeTimer ) clearTimeout(resizeTimer);
    784                 resizeTimer = setTimeout( api.refreshMenuTabs, 200);
    785             });
    786 
    787             // Build arrow functions
    788             $.each([{
    789                     arrow : arrowLeft,
    790                     next : "next",
    791                     last : "first",
    792                     operator : "+="
    793                 },{
    794                     arrow : arrowRight,
    795                     next : "prev",
    796                     last : "last",
    797                     operator : "-="
    798                 }], function(){
    799                 var that = this;
    800                 this.arrow.mousedown(function(){
    801                     var marginFluidVal = Math.abs( parseInt( fluid.css(marginFluid) ) ),
    802                         shift = marginFluidVal,
    803                         css = {};
    804 
    805                     if( "-=" == that.operator )
    806                         shift = Math.abs( tabsWidth - fixed.width() ) - marginFluidVal;
    807 
    808                     if( ! shift ) return;
    809 
    810                     css[marginFluid] = that.operator + shift + 'px';
    811                     fluid.animate( css, shift * msPerPx, "linear" );
    812                 }).mouseup(function(){
    813                     var tab, next;
    814                     fluid.stop(true);
    815                     tab = tabs[that.last]();
    816                     while( (next = tab[that.next]()) && next.length && ! next.isTabVisible() ) {
    817                         tab = next;
    818                     }
    819                     tab.makeTabVisible();
    820                 });
    821865            });
    822866        },
     
    847891
    848892        eventOnClickCancelLink : function(clickedEl) {
    849             var settings = $(clickedEl).closest('.menu-item-settings');
    850             settings.setItemData( settings.data('menu-item-data') );
     893            var settings = $( clickedEl ).closest( '.menu-item-settings' ),
     894                thisMenuItem = $( clickedEl ).closest( '.menu-item' );
     895            thisMenuItem.removeClass('menu-item-edit-active').addClass('menu-item-edit-inactive');
     896            settings.setItemData( settings.data('menu-item-data') ).hide();
    851897            return false;
    852898        },
     
    945991                    var ins = $('#menu-instructions');
    946992                    el.remove();
    947                     children.shiftDepthClass(-1).updateParentMenuItemDBId();
    948                     if( ! ins.siblings().length )
    949                         ins.removeClass('menu-instructions-inactive');
     993                    children.shiftDepthClass( -1 ).updateParentMenuItemDBId();
     994                    if( 0 == $( '#menu-to-edit li' ).length ) {
     995                        $( '.drag-instructions' ).hide();
     996                        ins.removeClass( 'menu-instructions-inactive' );
     997                    }
    950998                });
    951999        },
  • trunk/wp-admin/nav-menus.php

    r23416 r23441  
    222222            $messages[] = '<div id="message" class="updated"><p>' . __('The menu item has been successfully deleted.') . '</p></div>';
    223223        break;
     224
    224225    case 'delete':
    225226        check_admin_referer( 'delete-nav_menu-' . $nav_menu_selected_id );
    226 
    227227        if ( is_nav_menu( $nav_menu_selected_id ) ) {
    228             $deleted_nav_menu = wp_get_nav_menu_object( $nav_menu_selected_id );
    229             $delete_nav_menu = wp_delete_nav_menu( $nav_menu_selected_id );
    230 
    231             if ( is_wp_error($delete_nav_menu) ) {
    232                 $messages[] = '<div id="message" class="error"><p>' . $delete_nav_menu->get_error_message() . '</p></div>';
    233             } else {
    234                 // Remove this menu from any locations.
    235                 $locations = get_theme_mod( 'nav_menu_locations' );
    236                 foreach ( (array) $locations as $location => $menu_id ) {
    237                     if ( $menu_id == $nav_menu_selected_id )
    238                         $locations[ $location ] = 0;
    239                 }
    240                 set_theme_mod( 'nav_menu_locations', $locations );
    241                 $messages[] = '<div id="message" class="updated"><p>' . __('The menu has been successfully deleted.') . '</p></div>';
    242                 // Select the next available menu
    243                 $nav_menu_selected_id = 0;
    244                 $_nav_menus = wp_get_nav_menus( array('orderby' => 'name') );
    245                 foreach( $_nav_menus as $index => $_nav_menu ) {
    246                     if ( strcmp( $_nav_menu->name, $deleted_nav_menu->name ) >= 0
    247                      || $index == count( $_nav_menus ) - 1 ) {
    248                         $nav_menu_selected_id = $_nav_menu->term_id;
    249                         break;
    250                     }
    251                 }
    252             }
    253             unset( $delete_nav_menu, $deleted_nav_menu, $_nav_menus );
     228            $deletion = _wp_delete_nav_menu( $nav_menu_selected_id );
    254229        } else {
    255230            // Reset the selected menu
     
    257232            unset( $_REQUEST['menu'] );
    258233        }
     234
     235        if ( ! isset( $deletion ) )
     236            break;
     237
     238        if ( is_wp_error( $deletion ) )
     239            $messages[] = '<div id="message" class="error"><p>' . $deletion->get_error_message() . '</p></div>';
     240        else
     241            $messages[] = '<div id="message" class="updated"><p>' . __( 'The menu has been successfully deleted.' ) . '</p></div>';
     242        break;
     243
     244    case 'delete_menus':
     245        check_admin_referer( 'nav_menus_bulk_actions' );
     246        foreach ( $_REQUEST['delete_menus'] as $menu_id_to_delete ) {
     247            if ( ! is_nav_menu( $menu_id_to_delete ) )
     248                continue;
     249
     250            $deletion = _wp_delete_nav_menu( $menu_id_to_delete );
     251            if ( is_wp_error( $deletion ) ) {
     252                $messages[] = '<div id="message" class="error"><p>' . $deletion->get_error_message() . '</p></div>';
     253                $deletion_error = true;
     254            }
     255        }
     256
     257        if ( empty( $deletion_error ) )
     258            $messages[] = '<div id="message" class="updated"><p>' . __( 'Selected menus have been successfully deleted.' ) . '</p></div>';
    259259        break;
    260260
     
    262262        check_admin_referer( 'update-nav_menu', 'update-nav-menu-nonce' );
    263263
    264         // Update menu theme locations
    265         if ( isset( $_POST['menu-locations'] ) )
    266             set_theme_mod( 'nav_menu_locations', array_map( 'absint', $_POST['menu-locations'] ) );
     264        // Get existing menu locations assignments
     265        $locations = get_registered_nav_menus();
     266        $menu_locations = get_nav_menu_locations();
     267
     268        // Remove menu locations that have been unchecked
     269        foreach ( $locations as $location => $description ) {
     270            if ( ( empty( $_POST['menu-locations'] ) || empty( $_POST['menu-locations'][ $location ] ) ) && isset( $menu_locations[ $location ] ) && $menu_locations[ $location ] == $nav_menu_selected_id )
     271                unset( $menu_locations[ $location ] );
     272        }
     273
     274        // Merge new and existing menu locations if any new ones are set
     275        if ( isset( $_POST['menu-locations'] ) ) {
     276            $new_menu_locations = array_map( 'absint', $_POST['menu-locations'] );
     277            $menu_locations = array_merge( $menu_locations, $new_menu_locations );
     278        }
     279
     280        // Set menu locations
     281        set_theme_mod( 'nav_menu_locations', $menu_locations );
    267282
    268283        // Add Menu
     
    279294                    $nav_menu_selected_id = $_nav_menu_selected_id;
    280295                    $nav_menu_selected_title = $_menu_object->name;
    281                     $messages[] = '<div id="message" class="updated"><p>' . sprintf( __('The <strong>%s</strong> menu has been successfully created.'), $nav_menu_selected_title ) . '</p></div>';
     296                    if ( isset( $_REQUEST['menu-item'] ) )
     297                        wp_save_nav_menu_items( $nav_menu_selected_id, absint( $_REQUEST['menu-item'] ) );
     298                    if ( isset( $_REQUEST['zero-menu-state'] ) ) {
     299                        // If there are menu items, add them
     300                        wp_nav_menu_update_menu_items( $nav_menu_selected_id, $nav_menu_selected_title );
     301                        // Auto-save nav_menu_locations
     302                        $locations = get_theme_mod( 'nav_menu_locations' );
     303                        foreach ( (array) $locations as $location => $menu_id ) {
     304                                $locations[ $location ] = $nav_menu_selected_id;
     305                                break; // There should only be 1
     306                        }
     307                        set_theme_mod( 'nav_menu_locations', $locations );
     308                    }
     309                    $messages[] = '<div id="message" class="updated"><p>' . sprintf( __( '<strong>%s</strong> has been created.' ), $nav_menu_selected_title ) . '</p></div>';
    282310                }
    283311            } else {
    284                 $messages[] = '<div id="message" class="error"><p>' . __('Please enter a valid menu name.') . '</p></div>';
     312                $messages[] = '<div id="message" class="error"><p>' . __( 'Please enter a valid menu name.' ) . '</p></div>';
    285313            }
    286314
    287         // update existing menu
     315        // Update existing menu
    288316        } else {
    289317
     
    292320            $menu_title = trim( esc_html( $_POST['menu-name'] ) );
    293321            if ( ! $menu_title ) {
    294                 $messages[] = '<div id="message" class="error"><p>' . __('Please enter a valid menu name.') . '</p></div>';
     322                $messages[] = '<div id="message" class="error"><p>' . __( 'Please enter a valid menu name.' ) . '</p></div>';
    295323                $menu_title = $_menu_object->name;
    296324            }
     
    308336
    309337            // Update menu items
    310 
    311338            if ( ! is_wp_error( $_menu_object ) ) {
    312                 $unsorted_menu_items = wp_get_nav_menu_items( $nav_menu_selected_id, array('orderby' => 'ID', 'output' => ARRAY_A, 'output_key' => 'ID', 'post_status' => 'draft,publish') );
    313                 $menu_items = array();
    314                 // Index menu items by db ID
    315                 foreach( $unsorted_menu_items as $_item )
    316                     $menu_items[$_item->db_id] = $_item;
    317 
    318                 $post_fields = array( 'menu-item-db-id', 'menu-item-object-id', 'menu-item-object', 'menu-item-parent-id', 'menu-item-position', 'menu-item-type', 'menu-item-title', 'menu-item-url', 'menu-item-description', 'menu-item-attr-title', 'menu-item-target', 'menu-item-classes', 'menu-item-xfn' );
    319                 wp_defer_term_counting(true);
    320                 // Loop through all the menu items' POST variables
    321                 if ( ! empty( $_POST['menu-item-db-id'] ) ) {
    322                     foreach( (array) $_POST['menu-item-db-id'] as $_key => $k ) {
    323 
    324                         // Menu item title can't be blank
    325                         if ( empty( $_POST['menu-item-title'][$_key] ) )
    326                             continue;
    327 
    328                         $args = array();
    329                         foreach ( $post_fields as $field )
    330                             $args[$field] = isset( $_POST[$field][$_key] ) ? $_POST[$field][$_key] : '';
    331 
    332                         $menu_item_db_id = wp_update_nav_menu_item( $nav_menu_selected_id, ( $_POST['menu-item-db-id'][$_key] != $_key ? 0 : $_key ), $args );
    333 
    334                         if ( is_wp_error( $menu_item_db_id ) )
    335                             $messages[] = '<div id="message" class="error"><p>' . $menu_item_db_id->get_error_message() . '</p></div>';
    336                         elseif ( isset( $menu_items[$menu_item_db_id] ) )
    337                             unset( $menu_items[$menu_item_db_id] );
    338                     }
    339                 }
    340 
    341                 // Remove menu items from the menu that weren't in $_POST
    342                 if ( ! empty( $menu_items ) ) {
    343                     foreach ( array_keys( $menu_items ) as $menu_item_id ) {
    344                         if ( is_nav_menu_item( $menu_item_id ) ) {
    345                             wp_delete_post( $menu_item_id );
    346                         }
    347                     }
    348                 }
    349 
    350                 // Store 'auto-add' pages.
    351                 $auto_add = ! empty( $_POST['auto-add-pages'] );
    352                 $nav_menu_option = (array) get_option( 'nav_menu_options' );
    353                 if ( ! isset( $nav_menu_option['auto_add'] ) )
    354                     $nav_menu_option['auto_add'] = array();
    355                 if ( $auto_add ) {
    356                     if ( ! in_array( $nav_menu_selected_id, $nav_menu_option['auto_add'] ) )
    357                         $nav_menu_option['auto_add'][] = $nav_menu_selected_id;
    358                 } else {
    359                     if ( false !== ( $key = array_search( $nav_menu_selected_id, $nav_menu_option['auto_add'] ) ) )
    360                         unset( $nav_menu_option['auto_add'][$key] );
    361                 }
    362                 // Remove nonexistent/deleted menus
    363                 $nav_menu_option['auto_add'] = array_intersect( $nav_menu_option['auto_add'], wp_get_nav_menus( array( 'fields' => 'ids' ) ) );
    364                 update_option( 'nav_menu_options', $nav_menu_option );
    365 
    366                 wp_defer_term_counting(false);
    367 
    368                 do_action( 'wp_update_nav_menu', $nav_menu_selected_id );
    369 
    370                 $messages[] = '<div id="message" class="updated"><p>' . sprintf( __('The <strong>%s</strong> menu has been updated.'), $nav_menu_selected_title ) . '</p></div>';
    371                 unset( $menu_items, $unsorted_menu_items );
     339                $messages = array_merge( $messages, wp_nav_menu_update_menu_items( $nav_menu_selected_id, $nav_menu_selected_title ) );
    372340            }
    373341        }
     
    377345// Get all nav menus
    378346$nav_menus = wp_get_nav_menus( array('orderby' => 'name') );
     347$menu_count = count( $nav_menus );
     348
     349// Are we on the add new screen?
     350$add_new_screen = ( isset( $_GET['menu'] ) && 0 == $_GET['menu'] ) ? true : false;
     351
     352// If we have one theme location, and zero menus, we take them right into editing their first menu
     353$page_count = wp_count_posts( 'page' );
     354$one_theme_location_no_menus = ( 1 == count( get_registered_nav_menus() ) && ! $add_new_screen && empty( $nav_menus ) && ! empty( $page_count->publish ) ) ? true : false;
     355
     356// Redirect to add screen if there are no menus and this users has either zero, or more than 1 theme locations
     357if ( 0 == $menu_count && ! $add_new_screen && ! $one_theme_location_no_menus )
     358    wp_redirect( admin_url( 'nav-menus.php?action=edit&menu=0' ) );
    379359
    380360// Get recently edited nav menu
    381 $recently_edited = (int) get_user_option( 'nav_menu_recently_edited' );
    382 
    383 // If there was no recently edited menu, and $nav_menu_selected_id is a nav menu, update recently edited menu.
    384 if ( !$recently_edited && is_nav_menu( $nav_menu_selected_id ) ) {
     361$recently_edited = absint( get_user_option( 'nav_menu_recently_edited' ) );
     362if ( empty( $recently_edited ) && is_nav_menu( $nav_menu_selected_id ) )
    385363    $recently_edited = $nav_menu_selected_id;
    386364
    387 // Else if $nav_menu_selected_id is not a menu and not requesting that we create a new menu, but $recently_edited is a menu, grab that one.
    388 } elseif ( 0 == $nav_menu_selected_id && ! isset( $_REQUEST['menu'] ) && is_nav_menu( $recently_edited ) ) {
     365// Use $recently_edited if none are selected
     366if ( empty( $nav_menu_selected_id ) && ! isset( $_GET['menu'] ) && is_nav_menu( $recently_edited ) )
    389367    $nav_menu_selected_id = $recently_edited;
    390368
    391 // Else try to grab the first menu from the menus list
    392 } elseif ( 0 == $nav_menu_selected_id && ! isset( $_REQUEST['menu'] ) && ! empty($nav_menus) ) {
     369// On deletion of menu, if another menu exists, show it
     370if ( ! $add_new_screen && 0 < $menu_count && isset( $_GET['action'] ) && 'delete' == $_GET['action'] )
    393371    $nav_menu_selected_id = $nav_menus[0]->term_id;
    394 }
     372
     373// Set $nav_menu_selected_id to 0 if no menus
     374if ( $one_theme_location_no_menus )
     375    $nav_menu_selected_id = 0;
    395376
    396377// Update the user's setting
     
    413394}
    414395
     396// Retrieve menu locations
     397if ( current_theme_supports( 'menus' ) ) {
     398    $locations = get_registered_nav_menus();
     399    $menu_locations = get_nav_menu_locations();
     400}
     401
    415402// Ensure the user will be able to scroll horizontally
    416403// by adding a class for the max menu depth.
     
    419406
    420407// Calling wp_get_nav_menu_to_edit generates $_wp_nav_menu_max_depth
    421 if ( is_nav_menu( $nav_menu_selected_id ) )
     408if ( is_nav_menu( $nav_menu_selected_id ) ) {
     409    $menu_items = wp_get_nav_menu_items( $nav_menu_selected_id, array( 'post_status' => 'any' ) );
    422410    $edit_markup = wp_get_nav_menu_to_edit( $nav_menu_selected_id );
     411}
    423412
    424413function wp_nav_menu_max_depth($classes) {
     
    461450<div class="wrap">
    462451    <?php screen_icon(); ?>
    463     <h2><?php esc_html_e('Menus'); ?></h2>
     452    <h2><?php _e( 'Menus' ); ?> <a href="<?php echo esc_url( add_query_arg( array( 'action' => 'edit', 'menu' => 0, ), admin_url( 'nav-menus.php' ) ) ); ?>" class="add-new-h2"><?php _e( 'Add New' ); ?></a></h2>
    464453    <?php
    465454    foreach( $messages as $message ) :
     
    467456    endforeach;
    468457    ?>
     458    <?php if ( 1 < $menu_count ) : ?>
     459    <form method="post" action="<?php echo admin_url( 'nav-menus.php' ); ?>">
     460        <input type="hidden" name="action" value="edit" />
     461        <div class="manage-menus">
     462            <label for="menu" class="selected-menu"><?php _e('Select menu to edit'); ?></label>
     463            <select name="menu" id="menu">
     464                <?php if ( $add_new_screen ) : ?>
     465                    <option value="0" selected="selected"><?php _e( '-- Select --' ); ?></option>
     466                <?php endif; ?>
     467                <?php foreach( (array) $nav_menus as $_nav_menu ) : ?>
     468                    <option value="<?php echo esc_attr( $_nav_menu->term_id ); ?>" <?php selected( $_nav_menu->term_id, $nav_menu_selected_id ); ?>>
     469                        <?php
     470                        echo esc_html( $_nav_menu->truncated_name ) ;
     471
     472                        if ( ! empty( $menu_locations ) && in_array( $_nav_menu->term_id, $menu_locations ) ) {
     473                            $locations_assigned_to_this_menu = array();
     474                            foreach ( array_keys( $menu_locations, $_nav_menu->term_id ) as $menu_location_key ) {
     475                                 $locations_assigned_to_this_menu[] = $locations[ $menu_location_key ];
     476                            }
     477                            $assigned_locations = array_slice( $locations_assigned_to_this_menu, 0, absint( apply_filters( 'wp_nav_locations_listed_per_menu', 3 ) ) );
     478
     479                            // Adds ellipses following the number of locations defined in $assigned_locations
     480                            printf( ' (%1$s%2$s)',
     481                                implode( ', ', $assigned_locations ),
     482                                count( $locations_assigned_to_this_menu ) > count( $assigned_locations ) ? ' &hellip;' : ''
     483                            );
     484                        }
     485                        ?>
     486                    </option>
     487                <?php endforeach; ?>
     488            </select>
     489            <span class="submit-btn"><input type="submit" class="button-secondary" value="<?php _e( 'Select' ); ?>"></span>
     490        </div>
     491    </form>
     492    <?php endif; ?>
    469493    <div id="nav-menus-frame">
    470     <div id="menu-settings-column" class="metabox-holder<?php if ( !$nav_menu_selected_id ) { echo ' metabox-holder-disabled'; } ?>">
     494    <div id="menu-settings-column" class="metabox-holder<?php if ( isset( $_GET['menu'] ) && '0' == $_GET['menu'] ) { echo ' metabox-holder-disabled'; } ?>">
     495
     496        <div class="clear"></div>
    471497
    472498        <form id="nav-menu-meta" action="<?php echo admin_url( 'nav-menus.php' ); ?>" class="nav-menu-meta" method="post" enctype="multipart/form-data">
     
    480506    <div id="menu-management-liquid">
    481507        <div id="menu-management">
    482             <div id="select-nav-menu-container" class="hide-if-js">
    483                 <form id="select-nav-menu" action="">
    484                     <strong><label for="select-nav-menu"><?php esc_html_e( 'Select Menu:' ); ?></label></strong>
    485                     <select class="select-nav-menu" name="menu">
    486                         <?php foreach( (array) $nav_menus as $_nav_menu ) : ?>
    487                             <option value="<?php echo esc_attr($_nav_menu->term_id) ?>" <?php selected($nav_menu_selected_id, $_nav_menu->term_id); ?>>
    488                                 <?php echo esc_html( $_nav_menu->truncated_name ); ?>
    489                             </option>
    490                         <?php endforeach; ?>
    491                         <option value="0"><?php esc_html_e('Add New Menu'); ?></option>
    492                     </select>
    493                     <input type="hidden" name="action" value="edit" />
    494                     <?php submit_button( __( 'Select' ), 'secondary', 'select_menu', false ); ?>
    495                 </form>
    496             </div>
    497             <div class="nav-tabs-wrapper">
    498             <div class="nav-tabs">
    499                 <?php
    500                 foreach( (array) $nav_menus as $_nav_menu ) :
    501                     if ( $nav_menu_selected_id == $_nav_menu->term_id ) : ?><span class="nav-tab nav-tab-active">
    502                             <?php echo esc_html( $_nav_menu->truncated_name ); ?>
    503                         </span><?php else : ?><a href="<?php
    504                             echo esc_url(add_query_arg(
    505                                 array(
    506                                     'action' => 'edit',
    507                                     'menu' => $_nav_menu->term_id,
    508                                 ),
    509                                 admin_url( 'nav-menus.php' )
    510                             ));
    511                         ?>" class="nav-tab hide-if-no-js">
    512                             <?php echo esc_html( $_nav_menu->truncated_name ); ?>
    513                         </a><?php endif;
    514                 endforeach;
    515                 if ( 0 == $nav_menu_selected_id ) : ?><span class="nav-tab menu-add-new nav-tab-active">
    516                     <?php printf( '<abbr title="%s">+</abbr>', esc_html__( 'Add menu' ) ); ?>
    517                 </span><?php else : ?><a href="<?php
    518                     echo esc_url(add_query_arg(
    519                         array(
    520                             'action' => 'edit',
    521                             'menu' => 0,
    522                         ),
    523                         admin_url( 'nav-menus.php' )
    524                     ));
    525                 ?>" class="nav-tab menu-add-new">
    526                     <?php printf( '<abbr title="%s">+</abbr>', esc_html__( 'Add menu' ) ); ?>
    527                 </a><?php endif; ?>
    528             </div>
    529             </div>
    530             <div class="menu-edit">
    531                 <form id="update-nav-menu" action="<?php echo admin_url( 'nav-menus.php' ); ?>" method="post" enctype="multipart/form-data">
     508            <form id="update-nav-menu" action="<?php echo esc_url( admin_url( 'nav-menus.php' ) ); ?>" method="post" enctype="multipart/form-data">
     509                <div class="menu-edit <?php if ( $add_new_screen ) echo 'blank-slate'; ?>">
     510                    <?php
     511                    wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
     512                    wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
     513                    wp_nonce_field( 'update-nav_menu', 'update-nav-menu-nonce' );
     514
     515                    if ( $one_theme_location_no_menus ) { ?>
     516                        <input type="hidden" name="zero-menu-state" value="true" />
     517                    <?php } ?>
     518                    <input type="hidden" name="action" value="update" />
     519                    <input type="hidden" name="menu" id="menu" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" />
    532520                    <div id="nav-menu-header">
    533                         <div id="submitpost" class="submitbox">
    534                             <div class="major-publishing-actions">
    535                                 <label class="menu-name-label howto open-label" for="menu-name">
    536                                     <span><?php _e('Menu Name'); ?></span>
    537                                     <input name="menu-name" id="menu-name" type="text" class="menu-name regular-text menu-item-textbox input-with-default-title" title="<?php esc_attr_e('Enter menu name here'); ?>" value="<?php echo esc_attr( $nav_menu_selected_title ); ?>" />
    538                                 </label>
    539                                 <?php if ( !empty( $nav_menu_selected_id ) ) :
    540                                     if ( ! isset( $auto_add ) ) {
    541                                         $auto_add = get_option( 'nav_menu_options' );
    542                                         if ( ! isset( $auto_add['auto_add'] ) )
    543                                             $auto_add = false;
    544                                         elseif ( false !== array_search( $nav_menu_selected_id, $auto_add['auto_add'] ) )
    545                                             $auto_add = true;
    546                                         else
    547                                             $auto_add = false;
    548                                     }
    549                                 ?>
    550                                 <div class="auto-add-pages">
    551                                     <label class="howto"><input type="checkbox"<?php checked( $auto_add ); ?> name="auto-add-pages" value="1" /> <?php printf( __('Automatically add new top-level pages' ), esc_url( admin_url( 'edit.php?post_type=page' ) ) ); ?></label>
    552                                 </div>
    553                                 <?php endif; ?>
    554                                 <br class="clear" />
    555                                 <div class="publishing-action">
    556                                     <?php submit_button( empty( $nav_menu_selected_id ) ? __( 'Create Menu' ) : __( 'Save Menu' ), 'button-primary menu-save', 'save_menu', false, array( 'id' => 'save_menu_header' ) ); ?>
    557                                 </div><!-- END .publishing-action -->
    558 
    559                                 <?php if ( ! empty( $nav_menu_selected_id ) ) : ?>
    560                                 <div class="delete-action">
    561                                     <a class="submitdelete deletion menu-delete" href="<?php echo esc_url( wp_nonce_url( admin_url('nav-menus.php?action=delete&amp;menu=' . $nav_menu_selected_id), 'delete-nav_menu-' . $nav_menu_selected_id ) ); ?>"><?php _e('Delete Menu'); ?></a>
    562                                 </div><!-- END .delete-action -->
    563                                 <?php endif; ?>
    564                             </div><!-- END .major-publishing-actions -->
    565                         </div><!-- END #submitpost .submitbox -->
    566                         <?php
    567                         wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
    568                         wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
    569                         wp_nonce_field( 'update-nav_menu', 'update-nav-menu-nonce' );
    570                         ?>
    571                         <input type="hidden" name="action" value="update" />
    572                         <input type="hidden" name="menu" id="menu" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" />
    573                     </div><!-- END #nav-menu-header -->
     521                        <div class="major-publishing-actions">
     522                            <label class="menu-name-label howto open-label" for="menu-name">
     523                                <span><?php _e( 'Menu Name' ); ?></span>
     524                                <input name="menu-name" id="menu-name" type="text" class="menu-name regular-text menu-item-textbox input-with-default-title" title="<?php esc_attr_e( 'Enter menu name here' ); ?>" value="<?php if ( $one_theme_location_no_menus ) _e( 'Menu 1' ); else echo esc_attr( $nav_menu_selected_title ); ?>" />
     525                            </label>
     526                            <div class="publishing-action">
     527                                <?php submit_button( empty( $nav_menu_selected_id ) ? __( 'Create Menu' ) : __( 'Save Menu' ), 'button-primary menu-save', 'save_menu', false, array( 'id' => 'save_menu_header' ) ); ?>
     528                            </div><!-- END .publishing-action -->
     529                        </div><!-- END .major-publishing-actions -->
     530                    </div><!-- END .nav-menu-header -->
    574531                    <div id="post-body">
    575532                        <div id="post-body-content">
     533                            <?php if ( ! $add_new_screen ) : ?>
     534                            <?php $starter_copy = ( $one_theme_location_no_menus ) ? __( 'Edit your default menu by adding or removing items. Drag each item into the order you prefer. Click Create Menu to save your changes.' ) : __( 'Drag each item into the order you prefer. Click an item to reveal additional configuration options.' ); ?>
     535                            <div class="drag-instructions post-body-plain" <?php if ( isset( $menu_items ) && 0 == count( $menu_items ) ) { ?>style="display: none;"<?php } ?>>
     536                                <p><?php echo $starter_copy; ?></p>
     537                            </div>
    576538                            <?php
    577                             if ( isset( $edit_markup ) ) {
    578                                 if ( ! is_wp_error( $edit_markup ) )
    579                                     echo $edit_markup;
    580                             } else if ( empty( $nav_menu_selected_id ) ) {
    581                                 echo '<div class="post-body-plain">';
    582                                 echo '<p>' . __('To create a custom menu, give it a name above and click Create Menu. Then choose items like pages, categories or custom links from the left column to add to this menu.') . '</p>';
    583                                 echo '<p>' . __('After you have added your items, drag and drop to put them in the order you want. You can also click each item to reveal additional configuration options.') . '</p>';
    584                                 echo '<p>' . __('When you have finished building your custom menu, make sure you click the Save Menu button.') . '</p>';
    585                                 echo '</div>';
    586                             }
     539                            if ( isset( $edit_markup ) && ! is_wp_error( $edit_markup ) ) {
     540                                echo $edit_markup;
     541                            } else {
    587542                            ?>
     543                            <ul class="menu" id="menu-to-edit"></ul>
     544                            <?php } ?>
     545                            <?php endif; ?>
     546                            <?php if ( $add_new_screen ) : ?>
     547                                <p class="post-body-plain"><?php _e( 'Give your menu a name above, then click Create Menu.' ); ?></p>
     548                            <?php endif; ?>
     549                            <div class="menu-settings" <?php if ( $one_theme_location_no_menus ) { ?>style="display: none;"<?php } ?>>
     550                                <?php
     551                                if ( ! isset( $auto_add ) ) {
     552                                    $auto_add = get_option( 'nav_menu_options' );
     553                                    if ( ! isset( $auto_add['auto_add'] ) )
     554                                        $auto_add = false;
     555                                    elseif ( false !== array_search( $nav_menu_selected_id, $auto_add['auto_add'] ) )
     556                                        $auto_add = true;
     557                                    else
     558                                        $auto_add = false;
     559                                } ?>
     560
     561                                <dl class="auto-add-pages">
     562                                    <dt class="howto"><?php _e( 'Auto add pages' ); ?></dt>
     563                                    <dd class="checkbox-input"><input type="checkbox"<?php checked( $auto_add ); ?> name="auto-add-pages" id="auto-add-pages" value="1" /> <label for="auto-add-pages"><?php printf( __('Automatically add new top-level pages to this menu' ), esc_url( admin_url( 'edit.php?post_type=page' ) ) ); ?></label></dd>
     564                                </dl>
     565
     566                                <?php if ( current_theme_supports( 'menus' ) ) : ?>
     567
     568                                    <dl class="menu-theme-locations">
     569                                        <dt class="howto"><?php _e( 'Theme locations' ); ?></dt>
     570                                        <?php foreach ( $locations as $location => $description ) : ?>
     571                                        <dd class="checkbox-input">
     572                                            <input type="checkbox"<?php checked( isset( $menu_locations[ $location ] ) && $menu_locations[ $location ] == $nav_menu_selected_id ); ?> name="menu-locations[<?php echo esc_attr( $location ); ?>]" id="locations-<?php echo esc_attr( $location ); ?>" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" /> <label for="locations-<?php echo esc_attr( $location ); ?>"><?php echo $description; ?></label>
     573                                            <?php if ( ! empty( $menu_locations[ $location ] ) && $menu_locations[ $location ] != $nav_menu_selected_id ) : ?>
     574                                            <span class="theme-location-set"> <?php printf( __( "(Currently set to: %s)" ), wp_get_nav_menu_object( $menu_locations[ $location ] )->name ); ?> </span>
     575                                            <?php endif; ?>
     576                                        </dd>
     577                                        <?php endforeach; ?>
     578                                    </dl>
     579
     580                                <?php endif; ?>
     581
     582                            </div>
    588583                        </div><!-- /#post-body-content -->
    589584                    </div><!-- /#post-body -->
    590585                    <div id="nav-menu-footer">
    591586                        <div class="major-publishing-actions">
    592                         <div class="publishing-action">
    593                             <?php
    594                             if ( ! empty( $nav_menu_selected_id ) )
    595                                 submit_button( __( 'Save Menu' ), 'button-primary menu-save', 'save_menu', false, array( 'id' => 'save_menu_footer' ) );
    596                             ?>
    597                         </div>
    598                         </div>
     587                            <?php if ( 0 != $menu_count && ! $add_new_screen ) : ?>
     588                            <span class="delete-action">
     589                                <a class="submitdelete deletion menu-delete" href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'action' => 'delete', 'menu' => $nav_menu_selected_id, admin_url() ) ), 'delete-nav_menu-' . $nav_menu_selected_id) ); ?>"><?php _e('Delete Menu'); ?></a>
     590                            </span><!-- END .delete-action -->
     591                            <?php endif; ?>
     592                            <div class="publishing-action">
     593                                <?php submit_button( empty( $nav_menu_selected_id ) ? __( 'Create Menu' ) : __( 'Save Menu' ), 'button-primary menu-save', 'save_menu', false, array( 'id' => 'save_menu_header' ) ); ?>
     594                            </div><!-- END .publishing-action -->
     595                        </div><!-- END .major-publishing-actions -->
    599596                    </div><!-- /#nav-menu-footer -->
    600                 </form><!-- /#update-nav-menu -->
    601             </div><!-- /.menu-edit -->
     597                </div><!-- /.menu-edit -->
     598            </form><!-- /#update-nav-menu -->
    602599        </div><!-- /#menu-management -->
    603600    </div><!-- /#menu-management-liquid -->
    604601    </div><!-- /#nav-menus-frame -->
    605602</div><!-- /.wrap-->
    606 
     603<script type="text/javascript">var oneThemeLocationNoMenus = <?php if ( $one_theme_location_no_menus ) echo 'true'; else echo 'false'; ?>;</script>
    607604<?php include( './admin-footer.php' ); ?>
Note: See TracChangeset for help on using the changeset viewer.