WordPress.org

Make WordPress Core

Ticket #12713: new-menu-wireframe.2.diff

File new-menu-wireframe.2.diff, 156.5 KB (added by filosofo, 8 years ago)
  • wp-includes/nav-menu-template.php

     
    88 */
    99
    1010/**
     11 * Create HTML list of nav menu items.
     12 *
     13 * @package WordPress
     14 * @since 3.0.0
     15 * @uses Walker
     16 */
     17class Walker_Nav_Menu extends Walker {
     18        /**
     19         * @see Walker::$tree_type
     20         * @since 3.0.0
     21         * @var string
     22         */
     23        var $tree_type = array( 'post_type', 'taxonomy', 'custom' );
     24
     25        /**
     26         * @see Walker::$db_fields
     27         * @since 3.0.0
     28         * @todo Decouple this.
     29         * @var array
     30         */
     31        var $db_fields = array( 'parent' => 'post_parent', 'id' => 'object_id' );
     32
     33        /**
     34         * @see Walker::start_lvl()
     35         * @since 3.0.0
     36         *
     37         * @param string $output Passed by reference. Used to append additional content.
     38         * @param int $depth Depth of page. Used for padding.
     39         */
     40        function start_lvl(&$output, $depth) {
     41                $indent = str_repeat("\t", $depth);
     42                $output .= "\n$indent<ul class=\"sub-menu\">\n";
     43        }
     44
     45        /**
     46         * @see Walker::end_lvl()
     47         * @since 3.0.0
     48         *
     49         * @param string $output Passed by reference. Used to append additional content.
     50         * @param int $depth Depth of page. Used for padding.
     51         */
     52        function end_lvl(&$output, $depth) {
     53                $indent = str_repeat("\t", $depth);
     54                $output .= "$indent</ul>\n";
     55        }
     56
     57        /**
     58         * @see Walker::start_el()
     59         * @since 3.0.0
     60         *
     61         * @param string $output Passed by reference. Used to append additional content.
     62         * @param object $item Menu item data object.
     63         * @param int $depth Depth of menu item. Used for padding.
     64         * @param int $current_page Menu item ID.
     65         * @param object $args
     66         */
     67        function start_el(&$output, $item, $depth, $args) {
     68                global $wp_query;
     69                $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
     70
     71                $classes = $value = '';
     72
     73                $classes = array( 'menu-item', 'menu-item-type-'. $item->type, $item->classes );
     74
     75                if ( 'custom' != $item->object )
     76                        $classes[] = 'menu-item-object-'. $item->object;
     77
     78                if ( $item->object_id == $wp_query->get_queried_object_id() )
     79                        $classes[] = 'current-menu-item';
     80
     81                // @todo add classes for parent/child relationships
     82
     83                $classes = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
     84                $classes = ' class="' . esc_attr( $classes ) . '"';
     85
     86                $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $classes .'>';
     87               
     88                $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
     89                $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
     90                $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
     91                $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';
     92
     93                $item_output = $args->before;
     94                $item_output .= '<a'. $attributes .'>';
     95                $item_output .= $args->link_before . apply_filters( 'the_title', $item->title ) . $args->link_after;
     96                $item_output .= '</a>';
     97                $item_output .= $args->after;
     98       
     99                $output .= apply_filters( 'wp_get_nav_menu_item', $item_output, $args );
     100        }
     101
     102        /**
     103         * @see Walker::end_el()
     104         * @since 3.0.0
     105         *
     106         * @param string $output Passed by reference. Used to append additional content.
     107         * @param object $item Page data object. Not used.
     108         * @param int $depth Depth of page. Not Used.
     109         */
     110        function end_el(&$output, $item, $depth) {
     111                $output .= "</li>\n";
     112        }
     113}
     114
     115/**
     116 * Create HTML list of nav menu input items.
     117 *
     118 * @package WordPress
     119 * @since 3.0.0
     120 * @uses Walker_Nav_Menu
     121 */
     122class Walker_Nav_Menu_Checklist extends Walker_Nav_Menu  {
     123
     124        /**
     125         * @see Walker::start_el()
     126         * @since 3.0.0
     127         *
     128         * @param string $output Passed by reference. Used to append additional content.
     129         * @param object $item Menu item data object.
     130         * @param int $depth Depth of menu item. Used for padding.
     131         * @param int $current_page Menu item ID.
     132         * @param object $args
     133         */
     134        function start_el(&$output, $item, $depth, $args) {
     135                static $_placeholder;
     136                $_placeholder = 0 > $_placeholder ? $_placeholder - 1 : -1;
     137                $possible_object_id = isset( $item->post_type ) && 'nav_menu_item' == $item->post_type ? $item->object_id : $_placeholder;
     138                $possible_db_id = ( ! empty( $item->ID ) ) && ( 0 < $possible_object_id ) ? (int) $item->ID : 0;
     139
     140                $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
     141
     142                $output .= $indent . '<li>';
     143                $output .= '<label class="menu-item-title">';
     144                $output .= '<input type="checkbox" name="menu-item[' . $possible_object_id . '][menu-item-object-id]" value="'. esc_attr( $item->object_id ) .'" />';
     145                $output .= $item->title .'</label>';
     146
     147                // Menu item hidden fields
     148                $output .= '<input type="hidden" class="menu-item-db-id" name="menu-item[' . $possible_object_id . '][menu-item-db-id]" value="' . $possible_db_id . '" />';
     149                $output .= '<input type="hidden" class="menu-item-object" name="menu-item[' . $possible_object_id . '][menu-item-object]" value="'. esc_attr( $item->object ) .'" />';
     150                $output .= '<input type="hidden" class="menu-item-parent-id" name="menu-item[' . $possible_object_id . '][menu-item-parent-id]" value="'. esc_attr( $item->post_parent ) .'" />';
     151                $output .= '<input type="hidden" class="menu-item-type" name="menu-item[' . $possible_object_id . '][menu-item-type]" value="'. esc_attr( $item->type ) .'" />';
     152                $output .= '<input type="hidden" class="menu-item-append" name="menu-item[' . $possible_object_id . '][menu-item-append]" value="'. esc_attr( $item->append ) .'" />';
     153                $output .= '<input type="hidden" class="menu-item-title" name="menu-item[' . $possible_object_id . '][menu-item-title]" value="'. esc_attr( $item->title ) .'" />';
     154                $output .= '<input type="hidden" class="menu-item-url" name="menu-item[' . $possible_object_id . '][menu-item-url]" value="'. esc_attr( $item->url ) .'" />';
     155                $output .= '<input type="hidden" class="menu-item-append" name="menu-item[' . $possible_object_id . '][menu-item-append]" value="'. esc_attr( $item->append ) .'" />';
     156                $output .= '<input type="hidden" class="menu-item-target" name="menu-item[' . $possible_object_id . '][menu-item-target]" value="'. esc_attr( $item->target ) .'" />';
     157                $output .= '<input type="hidden" class="menu-item-attr_title" name="menu-item[' . $possible_object_id . '][menu-item-attr_title]" value="'. esc_attr( $item->attr_title ) .'" />';
     158                $output .= '<input type="hidden" class="menu-item-description" name="menu-item[' . $possible_object_id . '][menu-item-description]" value="'. esc_attr( $item->description ) .'" />';
     159                $output .= '<input type="hidden" class="menu-item-classes" name="menu-item[' . $possible_object_id . '][menu-item-classes]" value="'. esc_attr( $item->classes ) .'" />';
     160                $output .= '<input type="hidden" class="menu-item-xfn" name="menu-item[' . $possible_object_id . '][menu-item-xfn]" value="'. esc_attr( $item->xfn ) .'" />';
     161        }
     162}
     163
     164/**
    11165 * Displays a navigation menu.
    12166 *
    13167 * Optional $args contents:
     
    17171 * menu_class - CSS class to use for the div container of the menu list. Defaults to 'menu'.
    18172 * format - Whether to format the ul. Defaults to 'div'.
    19173 * fallback_cb - If the menu doesn't exists, a callback function will fire. Defaults to 'wp_page_menu'.
    20  * container - Type of container tag. Avalible options div, p, or nav. Defaults to 'div'.
    21  * container_class - Chooses a class for the container.
    22  * container_id - Chooses an id for the container.
    23174 * before - Text before the link text.
    24175 * after - Text after the link text.
    25176 * link_before - Text before the link.
     
    33184 * @param array $args Arguments
    34185 */
    35186function wp_nav_menu( $args = array() ) {
    36         $defaults = array( 'menu' => '', 'container' => 'div', 'container_class' => '', 'container_id' => '', 'menu_class' => 'menu', 'echo' => true,
     187        $defaults = array( 'menu' => '', 'container' => 'div', 'container_class' => '', 'menu_class' => 'menu', 'echo' => true,
    37188        'fallback_cb' => 'wp_page_menu', 'before' => '', 'after' => '', 'link_before' => '', 'link_after' => '',
    38189        'depth' => 0, 'walker' => '', 'context' => 'frontend' );
    39190
     
    46197
    47198        // If we couldn't find a menu based off the name, id or slug,
    48199        // get the first menu that has items.
    49         if ( !$menu ) {
     200        if ( ! $menu ) {
    50201                $menus = wp_get_nav_menus();
    51202                foreach ( $menus as $menu_maybe ) {
    52203                        if ( wp_get_nav_menu_items($menu_maybe->term_id) ) {
     
    56207                }
    57208        }
    58209       
    59         // If the menu exists, get it's items.
    60         if ( $menu && !is_wp_error($menu) )
    61                 $menu_items = wp_get_nav_menu_items( $menu->term_id, $args->context );
     210        // If the menu exists, get its items.
     211        if ( $menu && ! is_wp_error($menu) )
     212                $menu_items = wp_get_nav_menu_items( $menu->term_id );
    62213
    63214        // If no menu was found or if the menu has no items, call the fallback_cb
    64215        if ( !$menu || is_wp_error($menu) || ( isset($menu_items) && empty($menu_items) ) ) {
     
    73224
    74225        if ( in_array( $args->container, $container_allowedtags ) ) {
    75226                $class = $args->container_class ? ' class="' . esc_attr($args->container_class) . '"' : ' class="menu-'. $menu->slug .'-container"';
    76                 $container_id = $args->container_id ? ' id="' . esc_attr($args->container_id) . '"' : '' ;
    77                 $nav_menu .= '<'. $args->container . $class . $container_id .'>';
     227                $nav_menu .= '<'. $args->container . $class .'>';
    78228        }
    79229
    80230        // Set up the $menu_item variables
     231        $sorted_menu_items = array();
    81232        foreach ( (array) $menu_items as $key => $menu_item )
    82                 $menu_items[$menu_item->menu_order] = wp_setup_nav_menu_item( $menu_item, 'frontend' );
     233                $sorted_menu_items[$menu_item->menu_order] = wp_setup_nav_menu_item( $menu_item );
    83234
    84         $items .= walk_nav_menu_tree( $menu_items, $args->depth, $args );
     235        $items .= walk_nav_menu_tree( $sorted_menu_items, $args->depth, $args );
    85236
    86237        // Attributes   
    87238        $attributes  = ' id="menu-' . $menu->slug . '"';
     
    112263}
    113264
    114265/**
    115  * Returns the menu item formatted based on it's context.
     266 * Retrieve the HTML list content for nav menu items.
    116267 *
    117  * @since 3.0.0
    118  *
    119  * @param string $menu_item The menu item to format.
    120  * @param string $context The context to which the menu item will be formatted to.
    121  * @param string $args Optional. Args used for the 'template' context.
    122  * @return string $output The menu formatted menu item.
     268 * @uses Walker_Nav_Menu to create HTML list content.
     269 * @since 2.1.0
     270 * @see Walker::walk() for parameters and return description.
    123271 */
    124 function wp_get_nav_menu_item( $menu_item, $context = 'frontend', $args = array() ) {
    125         $output = '';
    126         switch ( $context ) {
    127                 case 'frontend':
    128                         $attributes  = ! empty( $menu_item->attr_title ) ? ' title="'  . esc_attr( $menu_item->attr_title ) .'"' : '';
    129                         $attributes .= ! empty( $menu_item->target )     ? ' target="' . esc_attr( $menu_item->target     ) .'"' : '';
    130                         $attributes .= ! empty( $menu_item->xfn )        ? ' rel="'    . esc_attr( $menu_item->xfn        ) .'"' : '';
    131                         $attributes .= ! empty( $menu_item->url )        ? ' href="'   . esc_attr( $menu_item->url        ) .'"' : '';
     272function walk_nav_menu_tree( $items, $depth, $r ) {
     273        $walker = ( empty($r->walker) ) ? new Walker_Nav_Menu : $r->walker;
     274        $args = array( $items, $depth, $r );
    132275
    133                         $output .= $args->before;
    134                         $output .= '<a'. $attributes .'>';
    135                         $output .= $args->link_before . apply_filters( 'the_title', $menu_item->title ) . $args->link_after;
    136                         $output .= '</a>';
    137                         $output .= $args->after;
     276        return call_user_func_array( array(&$walker, 'walk'), $args );
     277}
    138278
    139                         break;
    140 
    141                 case 'backend':
    142                         $output .= '<dl><dt>';
    143                         $output .= '<span class="item-title">'. esc_html( $menu_item->title ) .'</span>';
    144                         $output .= '<span class="item-controls">';
    145                         $output .= '<span class="item-type">'. esc_html( $menu_item->append ) .'</span>';
    146 
    147                         // Actions
    148                         $output .= '<a class="item-edit thickbox" id="edit-'. esc_attr( $menu_item->ID ) .'" value="'. esc_attr( $menu_item->ID ) .'" title="'. __('Edit Menu Item') .'" href="#TB_inline?height=540&width=300&inlineId=menu-item-settings">'. __('Edit') .'</a> | ';
    149                         $output .= '<a class="item-delete" id="delete-'. esc_attr( $menu_item->ID ) .'" value="'. esc_attr( $menu_item->ID ) .'">'. __('Delete') .'</a>';
    150 
    151                         $output .= '</span></dt></dl>';
    152 
    153                         // Menu Item Settings
    154                         $output .= '<input type="hidden" name="menu-item-db-id[]" value="'. esc_attr( $menu_item->ID ) .'" />';
    155                         $output .= '<input type="hidden" name="menu-item-object-id[]" value="'. esc_attr( $menu_item->object_id ) .'" />';
    156                         $output .= '<input type="hidden" name="menu-item-object[]" value="'. esc_attr( $menu_item->object ) .'" />';
    157                         $output .= '<input type="hidden" name="menu-item-parent-id[]" value="'. esc_attr( $menu_item->post_parent ) .'" />';
    158                         $output .= '<input type="hidden" name="menu-item-position[]" value="'. esc_attr( $menu_item->menu_order ) .'" />';
    159                         $output .= '<input type="hidden" name="menu-item-type[]" value="'. esc_attr( $menu_item->type ) .'" />';
    160                         $output .= '<input type="hidden" name="menu-item-title[]" value="'. esc_attr( $menu_item->title ) .'" />';
    161                         $output .= '<input type="hidden" name="menu-item-url[]" value="'. esc_attr( $menu_item->url ) .'" />';
    162                         $output .= '<input type="hidden" name="menu-item-description[]" value="'. esc_attr( $menu_item->description ) .'" />';
    163                         $output .= '<input type="hidden" name="menu-item-classes[]" value="'. esc_attr( $menu_item->classes ) .'" />';
    164                         $output .= '<input type="hidden" name="menu-item-xfn[]" value="'. esc_attr( $menu_item->xfn ) .'" />';
    165                         $output .= '<input type="hidden" name="menu-item-attr-title[]" value="'.esc_attr( $menu_item->post_excerpt )  .'" />';
    166                         $output .= '<input type="hidden" name="menu-item-target[]" value="'. esc_attr( $menu_item->target ) .'" />';
    167                         break;
    168 
    169                 case 'custom':
    170                 case 'taxonomy':
    171                 case 'post_type':
    172                         $output .= '<label class="menu-item-title"><input type="checkbox" id="'. esc_attr( 'menu-item-' . $menu_item->object_id ) .'" value="'. esc_attr( $menu_item->url ) .'" />'. $menu_item->title .'</label>';
    173 
    174                         // Menu item hidden fields
    175                         $output .= '<input type="hidden" class="menu-item-db-id" value="0" />';
    176                         $output .= '<input type="hidden" class="menu-item-object-id" value="'. esc_attr( $menu_item->object_id ) .'" />';
    177                         $output .= '<input type="hidden" class="menu-item-object" value="'. esc_attr( $menu_item->object ) .'" />';
    178                         $output .= '<input type="hidden" class="menu-item-parent-id" value="'. esc_attr( $menu_item->post_parent ) .'" />';
    179                         $output .= '<input type="hidden" class="menu-item-type" value="'. esc_attr( $menu_item->type ) .'" />';
    180                         $output .= '<input type="hidden" class="menu-item-append" value="'. esc_attr( $menu_item->append ) .'" />';
    181                         $output .= '<input type="hidden" class="menu-item-title" value="'. esc_attr( $menu_item->title ) .'" />';
    182                         $output .= '<input type="hidden" class="menu-item-url" value="'. esc_attr( $menu_item->url ) .'" />';
    183                         $output .= '<input type="hidden" class="menu-item-append" value="'. esc_attr( $menu_item->append ) .'" />';
    184                         $output .= '<input type="hidden" class="menu-item-target" value="'. esc_attr( $menu_item->target ) .'" />';
    185                         $output .= '<input type="hidden" class="menu-item-attr_title" value="'. esc_attr( $menu_item->attr_title ) .'" />';
    186                         $output .= '<input type="hidden" class="menu-item-description" value="'. esc_attr( $menu_item->description ) .'" />';
    187                         $output .= '<input type="hidden" class="menu-item-classes" value="'. esc_attr( $menu_item->classes ) .'" />';
    188                         $output .= '<input type="hidden" class="menu-item-xfn" value="'. esc_attr( $menu_item->xfn ) .'" />';
    189                         break;
    190         }
    191 
    192         return apply_filters( 'wp_get_nav_menu_item', $output, $context, $args );
    193 }
    194 ?>
    195  No newline at end of file
     279?>
  • wp-includes/post.php

     
    21902190        $data = stripslashes_deep( $data );
    21912191        $where = array( 'ID' => $post_ID );
    21922192
    2193         if ($update) {
     2193        if ( $update ) {
    21942194                do_action( 'pre_post_update', $post_ID );
    21952195                if ( false === $wpdb->update( $wpdb->posts, $data, $where ) ) {
    21962196                        if ( $wp_error )
     
    22652265
    22662266        wp_transition_post_status($data['post_status'], $previous_status, $post);
    22672267
    2268         if ( $update)
     2268        if ( $update )
    22692269                do_action('edit_post', $post_ID, $post);
    22702270
    22712271        do_action('save_post', $post_ID, $post);
  • wp-includes/classes.php

     
    11241124}
    11251125
    11261126/**
    1127  * Create HTML list of nav menu items.
    1128  *
    1129  * @package WordPress
    1130  * @since 3.0.0
    1131  * @uses Walker
    1132  */
    1133 class Walker_Nav_Menu extends Walker {
    1134         /**
    1135          * @see Walker::$tree_type
    1136          * @since 3.0.0
    1137          * @var string
    1138          */
    1139         var $tree_type = array( 'post_type', 'taxonomy', 'custom' );
    1140 
    1141         /**
    1142          * @see Walker::$db_fields
    1143          * @since 3.0.0
    1144          * @todo Decouple this.
    1145          * @var array
    1146          */
    1147         var $db_fields = array( 'parent' => 'post_parent', 'id' => 'object_id' );
    1148 
    1149         /**
    1150          * @see Walker::start_lvl()
    1151          * @since 3.0.0
    1152          *
    1153          * @param string $output Passed by reference. Used to append additional content.
    1154          * @param int $depth Depth of page. Used for padding.
    1155          */
    1156         function start_lvl(&$output, $depth) {
    1157                 $indent = str_repeat("\t", $depth);
    1158                 $output .= "\n$indent<ul class=\"sub-menu\">\n";
    1159         }
    1160 
    1161         /**
    1162          * @see Walker::end_lvl()
    1163          * @since 3.0.0
    1164          *
    1165          * @param string $output Passed by reference. Used to append additional content.
    1166          * @param int $depth Depth of page. Used for padding.
    1167          */
    1168         function end_lvl(&$output, $depth) {
    1169                 $indent = str_repeat("\t", $depth);
    1170                 $output .= "$indent</ul>\n";
    1171         }
    1172 
    1173         /**
    1174          * @see Walker::start_el()
    1175          * @since 3.0.0
    1176          *
    1177          * @param string $output Passed by reference. Used to append additional content.
    1178          * @param object $item Menu item data object.
    1179          * @param int $depth Depth of menu item. Used for padding.
    1180          * @param int $current_page Menu item ID.
    1181          * @param object $args
    1182          */
    1183         function start_el(&$output, $item, $depth, $args) {
    1184                 $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
    1185 
    1186                 $classes = $value = '';
    1187                 if ( 'frontend' == $args->context ) {
    1188                         global $wp_query;
    1189 
    1190                         $classes = array( 'menu-item', 'menu-item-type-'. $item->type, $item->classes );
    1191 
    1192                         if ( 'custom' != $item->object )
    1193                                 $classes[] = 'menu-item-object-'. $item->object;
    1194 
    1195                         if ( $item->object_id == $wp_query->get_queried_object_id() )
    1196                                 $classes[] = 'current-menu-item';
    1197 
    1198                         // @todo add classes for parent/child relationships
    1199 
    1200                         $classes = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
    1201                         $classes = ' class="' . esc_attr( $classes ) . '"';
    1202                 } else {
    1203                         $value = ' value="' . $item->ID . '"';
    1204                 }
    1205 
    1206                 $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $classes .'>' . wp_get_nav_menu_item( $item, $args->context, $args );
    1207         }
    1208 
    1209         /**
    1210          * @see Walker::end_el()
    1211          * @since 3.0.0
    1212          *
    1213          * @param string $output Passed by reference. Used to append additional content.
    1214          * @param object $item Page data object. Not used.
    1215          * @param int $depth Depth of page. Not Used.
    1216          */
    1217         function end_el(&$output, $item, $depth) {
    1218                 $output .= "</li>\n";
    1219         }
    1220 }
    1221 
    1222 /**
    12231127 * Create HTML list of pages.
    12241128 *
    12251129 * @package WordPress
  • wp-includes/script-loader.php

     
    393393                ) );
    394394
    395395                // Custom Navigation
    396                 $scripts->add( 'nav-menu', "/wp-admin/js/nav-menu$suffix.js", false, '20100403' );
     396                $scripts->add( 'nav-menu', "/wp-admin/js/nav-menu$suffix.js", false, '20100426' );
    397397                $scripts->localize( 'nav-menu', 'navMenuL10n', array(
    398398                        'custom' => _x('Custom', 'menu nav item type'),
    399399                        'thickbox' => _x('Edit Menu Item', 'Thickbox Title'),
    400400                        'edit' => _x('Edit', 'menu item edit text'),
    401                         'warnDelete' => __( "You are about to permanently delete this menu. \n 'Cancel' to stop, 'OK' to delete." ),
     401                        'warnDeleteMenu' => __( "You are about to permanently delete this menu. \n 'Cancel' to stop, 'OK' to delete." ),
     402                        'warnDeleteMenuItem' => __( "You are about to permanently delete this menu item. \n 'Cancel' to stop, 'OK' to delete." ),
    402403                ) );
    403404
    404405                $scripts->add( 'custom-background', "/wp-admin/js/custom-background$suffix.js", array('farbtastic'), '20100321' );
     
    472473        $styles->add( 'farbtastic', '/wp-admin/css/farbtastic.css', array(), '1.2' );
    473474        $styles->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.css', array(), '0.9.8' );
    474475        $styles->add( 'imgareaselect', '/wp-includes/js/imgareaselect/imgareaselect.css', array(), '0.9.1' );
    475         $styles->add( 'nav-menu', "/wp-admin/css/nav-menu$suffix.css", array(), '20100322' );
     476        $styles->add( 'nav-menu', "/wp-admin/css/nav-menu$suffix.css", array(), '20100426' );
    476477
    477478        foreach ( $rtl_styles as $rtl_style ) {
    478479                $styles->add_data( $rtl_style, 'rtl', true );
  • wp-includes/nav-menu.php

     
    1616 * @return mixed $menu|false Or WP_Error
    1717 */
    1818function wp_get_nav_menu_object( $menu ) {
    19         return is_nav_menu( $menu );
     19        if ( ! $menu )
     20                return false;
     21
     22        $menu_obj = get_term( $menu, 'nav_menu' );
     23
     24        if ( ! $menu_obj )
     25                $menu_obj = get_term_by( 'slug', $menu, 'nav_menu' );
     26
     27        if ( ! $menu_obj )
     28                $menu_obj = get_term_by( 'name', $menu, 'nav_menu' );
     29
     30        if ( ! $menu_obj ) {
     31                $menu_obj = false;
     32        }
     33
     34        return $menu_obj;
    2035}
    2136
    2237/**
     
    2742 * @since 3.0.0
    2843 *
    2944 * @param int|string $menu The menu to check
    30  * @return mixed Menu Object, if it exists. Else, false or WP_Error
     45 * @return bool Whether the menu exists.
    3146 */
    3247function is_nav_menu( $menu ) {
    33         if ( !$menu )
     48        if ( ! $menu )
    3449                return false;
     50       
     51        $menu_obj = wp_get_nav_menu_object( $menu );
    3552
    36         $menu_obj = get_term( $menu, 'nav_menu' );
    37 
    38         if ( !$menu_obj )
    39                 $menu_obj = get_term_by( 'slug', $menu, 'nav_menu' );
    40 
    41         if ( !$menu_obj )
    42                 $menu_obj = get_term_by( 'name', $menu, 'nav_menu' );
    43 
    44         if ( !$menu_obj ) {
    45                 $menu_obj = false;
    46         }
    47 
    48         return $menu_obj;
     53        if ( $menu_obj && ! is_wp_error( $menu_obj ) && ! empty( $menu_obj->term_id ) )
     54                return true;
     55       
     56        return false;
    4957}
    5058
    5159/**
     
    96104 */
    97105function wp_delete_nav_menu( $menu ) {
    98106        $menu = wp_get_nav_menu_object( $menu );
    99         if ( !$menu  )
     107        if ( ! $menu  )
    100108                return false;
    101109
    102110        $menu_objects = get_objects_in_term( $menu->term_id, 'nav_menu' );
     
    117125}
    118126
    119127/**
     128 * Save the properties of a menu or create a new menu with those properties.
     129 *
     130 * @since 3.0.0
     131 *
     132 * @param int $menu_id The ID of the menu
     133 * @param array $menu_data The array of menu data.
     134 * @return int The menu's ID.
     135 */
     136function wp_update_nav_menu_object( $menu_id = 0, $menu_data = array() ) {
     137        $menu_id = (int) $menu_id;
     138
     139        $_menu = wp_get_nav_menu_object( $menu_id );
     140
     141        // menu doesn't already exist
     142        if ( ! $_menu || is_wp_error( $_menu ) ) {
     143                $_menu = wp_create_nav_menu( $menu_data['menu-name'] );
     144        }
     145
     146        if ( $_menu && isset( $_menu->term_id ) && ! is_wp_error( $_menu ) ) {
     147                $args = array(
     148                        'description' => ( isset( $menu_data['description'] ) ? $menu_data['description'] : '' ),
     149                        'name' => ( isset( $menu_data['menu-name'] ) ? $menu_data['menu-name'] : '' ),
     150                        'parent' => ( isset( $menu_data['parent'] ) ? (int) $menu_data['parent'] : 0 ),
     151                        'slug' => null,
     152                );
     153       
     154                $menu_id = (int) $_menu->term_id;
     155
     156                $update_response = wp_update_term( $menu_id, 'nav_menu', $args );
     157
     158                if ( ! is_wp_error( $update_response ) ) {
     159                        return $menu_id;
     160                }
     161        } else {
     162                return 0;
     163        }
     164}
     165
     166/**
     167 * Save the properties of a menu item or create a new one.
     168 *
     169 * @since 3.0.0
     170 *
     171 * @param int $menu_id The ID of the menu. Required.
     172 * @param int $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
     173 * @param array $menu_item_data The menu item's data.
     174 * @return int The menu item's database ID or WP_Error object on failure.
     175 */
     176function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array() ) {
     177
     178        $menu_id = (int) $menu_id;
     179        $menu_item_db_id = (int) $menu_item_db_id;
     180
     181        $menu = wp_get_nav_menu_object( $menu_id );
     182
     183        if ( ! $menu || is_wp_error( $menu ) ) {
     184                return $menu;
     185        }
     186
     187        $menu_items = (array) wp_get_nav_menu_items( $menu_id );
     188
     189        $count = count( $menu_items );
     190
     191        $defaults = array(
     192                'menu-item-db-id' => $menu_item_db_id,
     193                'menu-item-object-id' => 0,
     194                'menu-item-object' => '',
     195                'menu-item-parent-id' => 0,
     196                'menu-item-position' => 0,
     197                'menu-item-type' => 'custom',
     198                'menu-item-append' => 'custom',
     199                'menu-item-title' => '',
     200                'menu-item-url' => '',
     201                'menu-item-description' => '',
     202                'menu-item-attr-title' => '',
     203                'menu-item-target' => '',
     204                'menu-item-classes' => '',
     205                'menu-item-xfn' => '',
     206        );
     207
     208        $args = wp_parse_args( $menu_item_data, $defaults );
     209
     210        if ( 0 == (int) $args['menu-item-position'] ) {
     211                $last_item = array_pop( $menu_items );
     212                if ( $last_item && isset( $last_item->ID ) ) {
     213                        $last_data = get_post( $last_item->ID );
     214                        if ( ! is_wp_error( $last_data ) && isset( $last_data->menu_order ) ) {
     215                                $args['menu-item-position'] = 1 + (int) $last_data->menu_order;
     216                        }
     217
     218                } else {
     219                        $args['menu-item-position'] = $count;
     220                }
     221        }
     222       
     223        // Populate the menu item object
     224        $post = array(
     225                'menu_order' => $args['menu-item-position'],
     226                'ping_status' => 0,
     227                'post_content' => $args['menu-item-description'],
     228                'post_excerpt' => $args['menu-item-attr-title'],
     229                'post_parent' => $args['menu-item-parent-id'],
     230                'post_status' => 'publish',
     231                'post_title' => $args['menu-item-title'],
     232                'post_type' => 'nav_menu_item',
     233                'tax_input' => array( 'nav_menu' => $menu->name ),
     234        );
     235
     236        // New menu item
     237        if ( 0 == $menu_item_db_id ) {
     238                $menu_item_db_id = wp_insert_post( $post );
     239
     240        // Update existing menu item
     241        } else {
     242                $post['ID'] = $menu_item_db_id;
     243                wp_update_post( $post );
     244        }
     245
     246        if ( 'custom' == $args['menu-item-type'] ) {
     247                $args['menu-item-object-id'] = $menu_item_db_id;
     248                $args['menu-item-object'] = 'custom';
     249        }
     250
     251        if ( $menu_item_db_id && ! is_wp_error( $menu_item_db_id ) ) {
     252
     253                $menu_item_db_id = (int) $menu_item_db_id;
     254
     255                update_post_meta( $menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']) );
     256                update_post_meta( $menu_item_db_id, '_menu_item_object_id', (int) $args['menu-item-object-id'] );
     257                update_post_meta( $menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']) );
     258                update_post_meta( $menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']) );
     259                // @todo handle sanitizing multiple classes separated by whitespace.
     260                update_post_meta( $menu_item_db_id, '_menu_item_classes', sanitize_html_class($args['menu-item-classes']) );
     261                update_post_meta( $menu_item_db_id, '_menu_item_xfn', sanitize_html_class($args['menu-item-xfn']) );
     262
     263                // @todo: only save custom link urls.
     264                update_post_meta( $menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']) );
     265
     266                do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args );
     267        }
     268
     269        return $menu_item_db_id;
     270}
     271
     272/**
    120273 * Returns all navigation menu objects.
    121274 *
    122275 * @since 3.0.0
     
    127280        return get_terms( 'nav_menu', array( 'hide_empty' => false, 'orderby' => 'id' ) );
    128281}
    129282
     283
    130284/**
     285 * Sort menu items by the desired key.
     286 *
     287 * @since 3.0.0
     288 * @access private
     289 *
     290 * @param object $a The first object to compare
     291 * @param object $b The second object to compare
     292 * @return int -1, 0, or 1 if $a is considered to be respectively less than, equal to, or greater than $b.
     293 */
     294function _sort_nav_menu_items($a, $b) {
     295        global $_menu_item_sort_prop;
     296
     297        if ( empty( $_menu_item_sort_prop ) ) {
     298                return 0;
     299        }
     300
     301        if ( isset( $a->$_menu_item_sort_prop ) && isset( $b->$_menu_item_sort_prop ) ) {
     302                $_a = (int) $a->$_menu_item_sort_prop;
     303                $_b = (int) $b->$_menu_item_sort_prop;
     304
     305                if ( $a->$_menu_item_sort_prop == $b->$_menu_item_sort_prop ) {
     306                        return 0;       
     307                } elseif (
     308                        ( $_a == $a->$_menu_item_sort_prop ) &&
     309                        ( $_b == $b->$_menu_item_sort_prop )
     310                ) {
     311                        return $_a < $_b ? -1 : 1;
     312                } else {
     313                        return strcmp( $a->$_menu_item_sort_prop, $b->$_menu_item_sort_prop );
     314                }
     315        } else {
     316                return 0;
     317        }
     318}
     319
     320/**
    131321 * Returns all menu items of a navigation menu.
    132322 *
    133323 * @since 3.0.0
     
    139329function wp_get_nav_menu_items( $menu, $args = array() ) {
    140330        $menu = wp_get_nav_menu_object( $menu );
    141331
    142         if ( !$menu )
     332        if ( ! $menu )
    143333                return false;
    144 
     334       
    145335        $items = get_objects_in_term( $menu->term_id, 'nav_menu' );
    146336
    147337        if ( ! empty( $items ) ) {
    148                 $defaults = array( 'orderby' => 'menu_order', 'post_type' => 'nav_menu_item', 'post_status' => 'publish', 'output' => ARRAY_A, 'output_key' => 'menu_order' );
     338                $defaults = array( 'order' => 'ASC', 'orderby' => 'menu_order', 'post_type' => 'nav_menu_item', 'post_status' => 'publish', 'output' => ARRAY_A, 'output_key' => 'menu_order' );
    149339                $args = wp_parse_args( $args, $defaults );
    150340                if ( count( $items ) > 1 )
    151341                        $args['include'] = implode( ',', $items );
     
    155345                $items = get_posts( $args );
    156346
    157347                if ( ARRAY_A == $args['output'] ) {
    158                         $output = array();
    159                         foreach ( $items as $item ) {
    160                                 $output[$item->$args['output_key']] = $item;
     348                        $GLOBALS['_menu_item_sort_prop'] = $args['output_key'];
     349                        usort($items, '_sort_nav_menu_items');
     350                        $i = 1;
     351                        foreach( $items as $k => $item ) {
     352                                $items[$k]->$args['output_key'] = $i++;
    161353                        }
    162                         unset( $items );
    163                         ksort( $output );
    164                         return $output;
    165354                }
    166355        }
    167356        return $items;
    168357}
    169358
    170359/**
    171  * Retrieve the HTML list content for nav menu items.
     360 * Decorates a menu item object with the shared navigation menu item properties.
    172361 *
    173  * @uses Walker_Nav_Menu to create HTML list content.
    174  * @since 2.1.0
    175  * @see Walker::walk() for parameters and return description.
    176  */
    177 function walk_nav_menu_tree( $items, $depth, $r ) {
    178         $walker = ( empty($r->walker) ) ? new Walker_Nav_Menu : $r->walker;
    179         $args = array( $items, $depth, $r );
    180 
    181         return call_user_func_array( array(&$walker, 'walk'), $args );
    182 }
    183 
    184 /**
    185  * Adds all the navigation menu properties to the menu item.
     362 * Properties:
     363 * - db_id:             The DB ID of the this item as a nav_menu_item object, if it exists (0 if it doesn't exist).
     364 * - object_id:         The DB ID of the original object this menu item represents, e.g. ID for posts and term_id for categories.
     365 * - type:              The family of objects originally represented, such as "post_type" or "taxonomy."
     366 * - object:            The type of object originally represented, such as "category," "post", or "attachment."
     367 * - append:            The singular label used to describe this type of menu item.
     368 * - parent:            The DB ID of the original object's parent object, if any (0 otherwise).
     369 * - url:               The URL to which this menu item points.
     370 * - title:             The title of this menu item.
     371 * - target:            The target attribute of the link element for this menu item.
     372 * - attr_title:        The title attribute of the link element for this menu item.     
     373 * - classes:           The class attribute value for the link element of this menu item.
     374 * - xfn:               The XFN relationship expressed in the link of this menu item.
     375 * - description:       The description of this menu item.
    186376 *
    187377 * @since 3.0.0
    188378 *
    189  * @param string $menu_item The menu item to modify
    190  * @param string $menu_item_type The menu item type (frontend, custom, post_type, taxonomy).
    191  * @param string $menu_item_object Optional. The menu item object type (post type or taxonomy).
    192  * @return object $menu_item The modified menu item.
     379 * @param object $menu_item The menu item to modify.
     380 * @return object $menu_item The menu item with standard menu item properties.
    193381 */
    194 function wp_setup_nav_menu_item( $menu_item, $menu_item_type = null, $menu_item_object = '' ) {
    195         switch ( $menu_item_type ) {
    196                 case 'frontend':
     382function wp_setup_nav_menu_item( $menu_item ) {
     383        if ( isset( $menu_item->post_type ) ) {
     384                if ( 'nav_menu_item' == $menu_item->post_type ) {
    197385                        $menu_item->db_id = (int) $menu_item->ID;
    198386                        $menu_item->object_id = get_post_meta( $menu_item->ID, '_menu_item_object_id', true );
    199387                        $menu_item->object = get_post_meta( $menu_item->ID, '_menu_item_object', true );
    200388                        $menu_item->type = get_post_meta( $menu_item->ID, '_menu_item_type', true );
    201 
     389                       
    202390                        if ( 'post_type' == $menu_item->type ) {
    203391                                $object = get_post_type_object( $menu_item->object );
    204392                                $menu_item->append = $object->singular_label;
     
    213401                                $menu_item->append = __('Custom');
    214402                                $menu_item->url = get_post_meta( $menu_item->ID, '_menu_item_url', true );
    215403                        }
    216 
     404                       
    217405                        $menu_item->title = $menu_item->post_title;
    218406                        $menu_item->target = get_post_meta( $menu_item->ID, '_menu_item_target', true );
    219407
     
    222410
    223411                        $menu_item->classes = get_post_meta( $menu_item->ID, '_menu_item_classes', true );
    224412                        $menu_item->xfn = get_post_meta( $menu_item->ID, '_menu_item_xfn', true );
    225                         break;
    226                
    227                 case 'custom':
     413                } else {
    228414                        $menu_item->db_id = 0;
    229415                        $menu_item->object_id = (int) $menu_item->ID;
    230                         $menu_item->object = 'custom';
    231                         $menu_item->type = 'custom';
    232                         $menu_item->append = __('custom');
     416                        $menu_item->type = 'post_type';
    233417
    234                         $menu_item->attr_title = strip_tags( $menu_item->post_excerpt );
    235                         $menu_item->description = strip_tags( $menu_item->post_content );
    236 
    237                         $menu_item->title = $menu_item->post_title;
    238                         $menu_item->url = get_post_meta( $menu_item->ID, '_menu_item_url', true );
    239                         $menu_item->target = get_post_meta( $menu_item->ID, '_menu_item_target', true );
    240                         $menu_item->classes = get_post_meta( $menu_item->ID, '_menu_item_target', true );
    241                         $menu_item->xfn = get_post_meta( $menu_item->ID, '_menu_item_xfn', true );
    242                         break;
    243 
    244                 case 'post_type':
    245                         $menu_item->db_id = 0;
    246                         $menu_item->object_id = (int) $menu_item->ID;
    247                         $menu_item->type = $menu_item_type;
    248 
    249                         $object = get_post_type_object( $menu_item_object );
     418                        $object = get_post_type_object( $menu_item->post_type );
    250419                        $menu_item->object = $object->name;
    251420                        $menu_item->append = strtolower( $object->singular_label );
    252421
     
    254423                        $menu_item->url = get_permalink( $menu_item->ID );
    255424                        $menu_item->target = '';
    256425
    257                         $menu_item->attr_title = '';
     426                        $menu_item->attr_title = strip_tags( $menu_item->post_excerpt );
    258427                        $menu_item->description = strip_tags( $menu_item->post_content );
    259428                        $menu_item->classes = '';
    260429                        $menu_item->xfn = '';
    261                         break;
     430                }
     431        } elseif ( isset( $menu_item->taxonomy ) ) {
     432                $menu_item->ID = $menu_item->term_id;
     433                $menu_item->db_id = 0;
     434                $menu_item->object_id = (int) $menu_item->term_id;
     435                $menu_item->post_parent = (int) $menu_item->parent;
     436                $menu_item->type = 'taxonomy';
    262437
    263                 case 'taxonomy':
    264                         $menu_item->ID = $menu_item->term_id;
    265                         $menu_item->db_id = 0;
    266                         $menu_item->object_id = (int) $menu_item->term_id;
    267                         $menu_item->post_parent = (int) $menu_item->parent;
    268                         $menu_item->type = $menu_item_type;
     438                $object = get_taxonomy( $menu_item->taxonomy );
     439                $menu_item->object = $object->name;
     440                $menu_item->append = strtolower( $object->singular_label );
    269441
    270                         $object = get_taxonomy( $menu_item_object );
    271                         $menu_item->object = $object->name;
    272                         $menu_item->append = strtolower( $object->singular_label );
     442                $menu_item->title = $menu_item->name;
     443                $menu_item->url = get_term_link( $menu_item, $menu_item->taxonomy );
     444                $menu_item->target = '';
     445                $menu_item->attr_title = '';
     446                $menu_item->description = strip_tags( get_term_field( 'description', $menu_item->term_id, $menu_item->taxonomy ) );
     447                $menu_item->classes = '';
     448                $menu_item->xfn = '';
    273449
    274                         $menu_item->title = $menu_item->name;
    275                         $menu_item->url = get_term_link( $menu_item, $menu_item_object );
    276                         $menu_item->target = '';
    277                         $menu_item->attr_title = '';
    278                         $menu_item->description = '';
    279                         $menu_item->classes = '';
    280                         $menu_item->xfn = '';
    281                         break;
    282450        }
    283        
    284         return apply_filters( 'wp_setup_nav_menu_item', $menu_item, $menu_item_type, $menu_item_object );
     451
     452        return apply_filters( 'wp_setup_nav_menu_item', $menu_item );
    285453}
    286 ?>
    287  No newline at end of file
     454?>
  • wp-admin/admin-ajax.php

     
    126126        check_ajax_referer( "image_editor-$post_id" );
    127127
    128128        include_once( ABSPATH . 'wp-admin/includes/image-edit.php' );
    129         if ( !stream_preview_image($post_id) )
     129        if ( ! stream_preview_image($post_id) )
    130130                die('-1');
    131131
    132132        die();
    133133        break;
     134case 'menu-quick-search':
     135        if ( ! current_user_can( 'switch_themes' ) )
     136                die('-1');
     137       
     138        require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
     139
     140        _wp_ajax_menu_quick_search( $_REQUEST );
     141
     142        exit;
     143        break;
    134144case 'oembed-cache' :
    135145        $return = ( $wp_embed->cache_oembed( $_GET['post'] ) ) ? '1' : '0';
    136146        die( $return );
     
    386396        else
    387397                die('0');
    388398        break;
     399case 'delete-menu-item' :
     400        $menu_item_id = (int) $_POST['menu-item'];
     401        check_admin_referer( 'delete-menu_item_' . $menu_item_id );
     402        if ( ! current_user_can( 'switch_themes' ) )
     403                die('-1');
     404
     405        if ( 'nav_menu_item' == get_post_type( $menu_item_id ) && wp_delete_post( $menu_item_id, true ) )
     406                die('1');
     407        else
     408                die('0');
     409        break;
    389410case 'delete-meta' :
    390411        check_ajax_referer( "delete-meta_$id" );
    391412        if ( !$meta = get_post_meta_by_id( $id ) )
     
    795816
    796817        $x->send();
    797818        break;
     819case 'add-menu-item' :
     820        if ( ! current_user_can( 'switch_themes' ) )
     821                die('-1');
     822
     823        check_admin_referer( 'add-menu_item', 'menu-settings-column-nonce' );
     824
     825        require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
     826
     827        $menu_id = (int) $_POST['menu'];
     828        if ( isset( $_POST['menu-item'] ) ) {
     829                $item_ids = wp_save_nav_menu_item( $menu_id, $_POST['menu-item'] );
     830        } else {
     831                $item_ids = array();
     832        }
     833       
     834        foreach ( (array) $item_ids as $menu_item_id ) {
     835                $menu_obj = get_post( $menu_item_id );
     836                if ( ! empty( $menu_obj->ID ) ) {
     837                        $menu_items[] = wp_setup_nav_menu_item( $menu_obj );
     838                }
     839        }
     840
     841        if ( ! empty( $menu_items ) ) {
     842                $args = array(
     843                        'after' => '',
     844                        'before' => '',
     845                        'context' => 'backend',
     846                        'link_after' => '',
     847                        'link_before' => '',
     848                        'walker' => new Walker_Nav_Menu_Edit,
     849                );
     850                echo walk_nav_menu_tree( $menu_items, 0, (object) $args );
     851        }
     852        break;
    798853case 'add-meta' :
    799854        check_ajax_referer( 'add-meta' );
    800855        $c = 0;
     
    10331088
    10341089        die('1');
    10351090        break;
     1091case 'menu-quick-search':
     1092        if ( ! current_user_can( 'switch_themes' ) )
     1093                die('-1');
     1094       
     1095        require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
     1096
     1097        _wp_ajax_menu_quick_search( $_REQUEST );
     1098
     1099        exit;
     1100        break;
    10361101case 'meta-box-order':
    10371102        check_ajax_referer( 'meta-box-order' );
    10381103        $order = isset( $_POST['order'] ) ? (array) $_POST['order'] : false;
  • wp-admin/includes/nav-menu.php

     
    11<?php
     2
    23/**
     4 * Create HTML list of nav menu input items.
     5 *
     6 * @package WordPress
     7 * @since 3.0.0
     8 * @uses Walker_Nav_Menu
     9 */
     10class Walker_Nav_Menu_Edit extends Walker_Nav_Menu  {
     11
     12        /**
     13         * @see Walker::start_el()
     14         * @since 3.0.0
     15         *
     16         * @param string $output Passed by reference. Used to append additional content.
     17         * @param object $item Menu item data object.
     18         * @param int $depth Depth of menu item. Used for padding.
     19         * @param int $current_page Menu item ID.
     20         * @param object $args
     21         */
     22        function start_el(&$output, $item, $depth, $args) {
     23                $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
     24
     25                ob_start();
     26                $item_id = esc_attr( $item->ID );
     27                $removed_args = array(
     28                        'action',
     29                        'customlink-tab',
     30                        'edit-menu-item',
     31                        'menu-item',
     32                        'page-tab',
     33                        '_wpnonce',
     34                );
     35                ?>
     36                <li id="menu-item-<?php echo $item_id; ?>">
     37                        <dl>
     38                                <dt>
     39                                        <span class="item-title"><?php echo esc_html( $item->title ); ?></span>
     40                                        <span class="item-controls">
     41                                                <span class="item-type"><?php echo esc_html( $item->append ); ?></span>
     42                                                <span class="item-order">
     43                                                        <a href="<?php
     44                                                                echo wp_nonce_url(
     45                                                                        add_query_arg(
     46                                                                                array(
     47                                                                                        'action' => 'move-up-menu-item',
     48                                                                                        'menu-item' => $item_id,
     49                                                                                ),
     50                                                                                remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
     51                                                                        ),
     52                                                                        'move-item'
     53                                                                );
     54                                                        ?>" class="item-move-up"><abbr title="<?php esc_attr_e('Move up'); ?>">&#8593;</abbr></a>
     55                                                        |
     56                                                        <a href="<?php
     57                                                                echo wp_nonce_url(
     58                                                                        add_query_arg(
     59                                                                                array(
     60                                                                                        'action' => 'move-down-menu-item',
     61                                                                                        'menu-item' => $item_id,
     62                                                                                ),
     63                                                                                remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
     64                                                                        ),
     65                                                                        'move-item'
     66                                                                );
     67                                                        ?>" class="item-move-down"><abbr title="<?php esc_attr_e('Move down'); ?>">&#8595;</abbr></a>
     68                                                        |
     69                                                </span>
     70                                                <a class="item-edit" id="edit-<?php echo $item_id; ?>" title="<?php _e('Edit Menu Item'); ?>" href="<?php
     71                                                        echo add_query_arg('edit-menu-item', $item_id, remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) ) );
     72                                                ?>#menu-item-settings-<?php echo $item_id; ?>"><?php _e('Edit'); ?></a> |
     73                                                <a class="item-delete submitdelete deletion" id="delete-<?php echo $item_id; ?>" href="<?php
     74                                                echo wp_nonce_url(
     75                                                        add_query_arg(
     76                                                                array(
     77                                                                        'action' => 'delete-menu-item',
     78                                                                        'menu-item' => $item_id,
     79                                                                ),
     80                                                                remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
     81                                                        ),
     82                                                        'delete-menu_item_' . $item_id
     83                                                ); ?>"><?php _e('Delete'); ?></a>
     84                                        </span>
     85                                </dt>
     86                        </dl>
     87
     88                        <div class="menu-item-settings <?php
     89                                if ( isset($_GET['edit-menu-item']) && $item_id == $_GET['edit-menu-item'] ) :
     90                                        echo ' menu-item-edit-active';
     91                                else :
     92                                        echo ' menu-item-edit-inactive';
     93                                endif;
     94                        ?>" id="menu-item-settings-<?php echo $item_id; ?>">
     95                                <p class="description">
     96                                        <label for="edit-menu-item-title-<?php echo $item_id; ?>">
     97                                                <?php _e( 'Menu Title' ); ?><br />
     98                                                <input type="text" id="edit-menu-item-title-<?php echo $item_id; ?>" class="widefat edit-menu-item-title" name="menu-item-title[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->title ); ?>" />
     99                                        </label>
     100                                </p>
     101                                <p class="description">
     102                                        <label for="edit-menu-item-url-<?php echo $item_id; ?>">
     103                                                <?php _e( 'URL' ); ?><br />
     104                                                <input type="text" id="edit-menu-item-url-<?php echo $item_id; ?>" class="widefat code edit-menu-item-url" name="menu-item-url[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->url ); ?>" />
     105                                        </label>
     106                                </p>
     107                                <p class="description">
     108                                        <label for="edit-menu-item-attr-title-<?php echo $item_id; ?>">
     109                                                <?php _e( 'Title Attribute' ); ?><br />
     110                                                <input type="text" id="edit-menu-item-attr-title-<?php echo $item_id; ?>" class="widefat edit-menu-item-attr-title" name="menu-item-attr-title[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->post_excerpt ); ?>" />
     111                                        </label>
     112                                </p>
     113                                <p class="description">
     114                                        <label for="edit-menu-item-target-<?php echo $item_id; ?>">
     115                                                <?php _e( 'Link Target' ); ?><br />
     116                                                <select id="edit-menu-item-target-<?php echo $item_id; ?>" class="widefat edit-menu-item-target" name="menu-item-target[<?php echo $item_id; ?>]">
     117                                                        <option value="" <?php selected( $item->target, ''); ?>><?php _e('Same window or tab'); ?></option>
     118                                                        <option value="_blank" <?php selected( $item->target, '_blank'); ?>><?php _e('New window or tab'); ?></option>
     119                                                </select>
     120                                        </label>
     121                                </p>
     122                                <p class="description">
     123                                        <label for="edit-menu-item-classes-<?php echo $item_id; ?>">
     124                                                <?php _e( 'CSS Classes (optional)' ); ?><br />
     125                                                <input type="text" id="edit-menu-item-classes-<?php echo $item_id; ?>" class="widefat code edit-menu-item-classes" name="menu-item-classes[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->classes ); ?>" />
     126                                        </label>
     127                                </p>
     128                                <p class="description">
     129                                        <label for="edit-menu-item-xfn-<?php echo $item_id; ?>">
     130                                                <?php _e( 'Link Relationship (XFN) (optional)' ); ?><br />
     131                                                <input type="text" id="edit-menu-item-xfn-<?php echo $item_id; ?>" class="widefat code edit-menu-item-xfn" name="menu-item-xfn[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->xfn ); ?>" />
     132                                        </label>
     133                                </p>
     134                                <p class="description">
     135                                        <label for="edit-menu-item-description-<?php echo $item_id; ?>">
     136                                                <?php _e( 'Description (optional)' ); ?><br />
     137                                                <textarea id="edit-menu-item-description-<?php echo $item_id; ?>" class="widefat edit-menu-item-description" rows="3" name="menu-item-description[<?php echo $item_id; ?>]"><?php echo esc_html( $item->description ); ?></textarea>
     138                                                <span class="description"><?php _e('The description will be displayed in the menu if the current theme supports it.'); ?></span>
     139                                        </label>
     140                                </p>
     141                               
     142                                <input type="hidden" name="menu-item-append[<?php echo $item_id; ?>]" value="<?php echo $item->append; ?>" />
     143                                <input type="hidden" name="menu-item-db-id[<?php echo $item_id; ?>]" value="<?php echo $item_id; ?>" />
     144                                <input type="hidden" name="menu-item-object-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->object_id ); ?>" />
     145                                <input type="hidden" name="menu-item-object[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->object ); ?>" />
     146                                <input type="hidden" name="menu-item-parent-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->post_parent ); ?>" />
     147                                <input type="hidden" class="menu-item-position" name="menu-item-position[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->menu_order ); ?>" />
     148                                <input type="hidden" name="menu-item-type[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->type ); ?>" />
     149                        </div><!-- .menu-item-settings-->
     150                <?php
     151                $output .= ob_get_clean();
     152        }
     153}
     154
     155/**
     156 * Prints the appropriate response to a menu quick search.
     157 *
     158 * @since 3.0.0
     159 *
     160 * @param array $request The unsanitized request values.
     161 */
     162function _wp_ajax_menu_quick_search( $request = array() ) {
     163        $args = array();
     164        $type = isset( $request['type'] ) ? $request['type'] : '';
     165        $object_type = isset( $request['object_type'] ) ? $request['object_type'] : '';
     166        $query = isset( $request['q'] ) ? $request['q'] : '';
     167        $response_format = isset( $request['response-format'] ) && in_array( $request['response-format'], array( 'json', 'markup' ) ) ? $request['response-format'] : 'json';
     168
     169        if ( 'markup' == $response_format ) {
     170                $args['walker'] = new Walker_Nav_Menu_Checklist;
     171        }
     172
     173        if ( 'get-post-item' == $type ) {
     174                if ( get_post_type_object( $object_type ) ) {
     175                        if ( isset( $request['ID'] ) ) {
     176                                $object_id = (int) $request['ID'];
     177                                if ( 'markup' == $response_format ) {
     178                                        echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( get_post( $object_id ) ) ), 0, (object) $args );
     179                                } elseif ( 'json' == $response_format ) {
     180                                        $post_obj = get_post( $object_id );
     181                                        echo json_encode(
     182                                                array(
     183                                                        'ID' => $object_id,
     184                                                        'post_title' => get_the_title( $object_id ),
     185                                                        'post_type' => get_post_type( $object_id ),
     186                                                )
     187                                        );
     188                                        echo "\n";
     189                                }
     190                        }
     191                } elseif ( is_taxonomy( $object_type ) ) {
     192                        if ( isset( $request['ID'] ) ) {
     193                                $object_id = (int) $request['ID'];
     194                                if ( 'markup' == $response_format ) {
     195                                        echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( get_term( $object_id, $object_type ) ) ), 0, (object) $args );
     196                                } elseif ( 'json' == $response_format ) {
     197                                        $post_obj = get_term( $object_id, $object_type );
     198                                        echo json_encode(
     199                                                array(
     200                                                        'ID' => $object_id,
     201                                                        'post_title' => $post_obj->name,
     202                                                        'post_type' => $object_type,
     203                                                )
     204                                        );
     205                                        echo "\n";
     206                                }
     207                        }
     208
     209                }
     210
     211
     212        } elseif ( preg_match('/quick-search-(posttype|taxonomy)-([a-zA-Z_-]*\b)/', $type, $matches) ) {
     213                if ( 'posttype' == $matches[1] && get_post_type_object( $matches[2] ) ) {
     214                        query_posts(array(
     215                                'posts_per_page' => 10,
     216                                'post_type' => $matches[2],
     217                                's' => $query,
     218                        ));
     219                        while ( have_posts() ) {
     220                                the_post();
     221                                if ( 'markup' == $response_format ) {
     222                                        echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( get_post( get_the_ID() ) ) ), 0, (object) $args );
     223                                } elseif ( 'json' == $response_format ) {
     224                                        echo json_encode(
     225                                                array(
     226                                                        'ID' => get_the_ID(),
     227                                                        'post_title' => get_the_title(),
     228                                                        'post_type' => get_post_type(),
     229                                                )
     230                                        );
     231                                        echo "\n";
     232                                }
     233                        }
     234                } elseif ( 'taxonomy' == $matches[1] ) {
     235                        $terms = get_terms( $matches[2], array(
     236                                'name__like' => $query,
     237                                'number' => 10,
     238                        ));
     239                        foreach( (array) $terms as $term ) {
     240                                if ( 'markup' == $response_format ) {
     241                                        echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( $term ) ), 0, (object) $args );
     242                                } elseif ( 'json' == $response_format ) {
     243                                        echo json_encode(
     244                                                array(
     245                                                        'ID' => $term->term_id,
     246                                                        'post_title' => $term->name,
     247                                                        'post_type' => $matches[2],
     248                                                )
     249                                        );
     250                                        echo "\n";
     251                                }
     252                        }
     253                }
     254        }
     255}
     256
     257/**
    3258 * Register nav menu metaboxes
    4259 *
    5260 * @since 3.0.0
    6261 **/
    7 function wp_nav_menu_metaboxes_setup() {
    8         add_meta_box( 'add-custom-links', __('Add Custom Links'), 'wp_nav_menu_item_link_metabox', 'nav-menus', 'side', 'default' );
    9         wp_nav_menu_post_type_metaboxes();
    10         wp_nav_menu_taxonomy_metaboxes();
     262function wp_nav_menu_meta_boxes_setup() {
     263        add_meta_box( 'add-custom-links', __('Add Custom Links'), 'wp_nav_menu_item_link_meta_box', 'nav-menus', 'side', 'default' );
     264        wp_nav_menu_post_type_meta_boxes();
     265        wp_nav_menu_taxonomy_meta_boxes();
    11266}
    12267
    13268/**
     
    18273function wp_initial_nav_menu_meta_boxes() {
    19274        global $wp_meta_boxes;
    20275
    21         if ( !get_user_option( 'metaboxhidden_nav-menus' ) && is_array($wp_meta_boxes) ) {
     276        if ( !get_user_option( 'meta-box-hidden_nav-menus' ) && is_array($wp_meta_boxes) ) {
    22277
    23278                $initial_meta_boxes = array( 'manage-menu', 'create-menu', 'add-custom-links', 'add-page', 'add-category' );
    24279                $hidden_meta_boxes = array();
     
    35290                        }
    36291                }
    37292                $user = wp_get_current_user();
    38                 update_user_meta( $user->ID, 'metaboxhidden_nav-menus', $hidden_meta_boxes );
     293                update_user_meta( $user->ID, 'meta-box-hidden_nav-menus', $hidden_meta_boxes );
    39294
    40295                // returns all the hidden metaboxes to the js function: wpNavMenu.initial_meta_boxes()
    41296                return join( ',', $hidden_meta_boxes );
     
    47302 *
    48303 * @since 3.0.0
    49304 */
    50 function wp_nav_menu_post_type_metaboxes() {
     305function wp_nav_menu_post_type_meta_boxes() {
    51306        $post_types = get_post_types( array( 'public' => true ), 'object' );
    52307
    53308        if ( !$post_types )
     
    55310
    56311        foreach ( $post_types as $post_type ) {
    57312                $id = $post_type->name;
    58                 add_meta_box( "add-{$id}", sprintf( __('Add %s'), $post_type->label ), 'wp_nav_menu_item_post_type_metabox', 'nav-menus', 'side', 'default', $post_type );
     313                add_meta_box( "add-{$id}", sprintf( __('Add %s'), $post_type->label ), 'wp_nav_menu_item_post_type_meta_box', 'nav-menus', 'side', 'default', $post_type );
    59314        }
    60315}
    61316
     
    64319 *
    65320 * @since 3.0.0
    66321 */
    67 function wp_nav_menu_taxonomy_metaboxes() {
     322function wp_nav_menu_taxonomy_meta_boxes() {
    68323        $taxonomies = get_taxonomies( array( 'show_ui' => true ), 'object' );
    69324
    70325        if ( !$taxonomies )
     
    72327
    73328        foreach ( $taxonomies as $tax ) {
    74329                $id = $tax->name;
    75                 add_meta_box( "add-{$id}", sprintf( __('Add %s'), $tax->label ), 'wp_nav_menu_item_taxonomy_metabox', 'nav-menus', 'side', 'default', $tax );
     330                add_meta_box( "add-{$id}", sprintf( __('Add %s'), $tax->label ), 'wp_nav_menu_item_taxonomy_meta_box', 'nav-menus', 'side', 'default', $tax );
    76331        }
    77332}
    78333
    79334/**
    80  * Displays a metabox for managing the active menu being edited.
     335 * Displays a metabox for the custom links menu item.
    81336 *
    82337 * @since 3.0.0
    83338 */
    84 function wp_nav_menu_manage_menu_metabox( $object, $menu ) { ?>
    85         <div id="submitpost" class="submitbox">
    86                 <div id="minor-publishing">
    87                         <div class="misc-pub-section misc-pub-section-last">
    88                                 <label class="howto" for="menu-name">
    89                                         <span><?php _e('Name'); ?></span>
    90                                         <input id="menu-name" name="menu-name" type="text" class="regular-text menu-item-textbox" value="<?php echo esc_attr( $menu['args'][1] ); ?>" />
    91                                         <br class="clear" />
    92                                 </label>
    93                         </div><!--END .misc-pub-section misc-pub-section-last-->
    94                         <br class="clear" />
    95                 </div><!--END #misc-publishing-actions-->
    96                 <div id="major-publishing-actions">
    97                         <div id="delete-action">
    98                                 <a class="submitdelete deletion" href="<?php echo wp_nonce_url( admin_url('nav-menus.php?action=delete&amp;menu=' . $menu['args'][0]), 'delete-nav_menu-' . $menu['args'][0] ); ?>"><?php _e('Delete Menu'); ?></a>
    99                         </div><!--END #delete-action-->
     339function wp_nav_menu_item_link_meta_box() {
     340        static $_placeholder;
     341        $_placeholder = 0 > $_placeholder ? $_placeholder - 1 : -1;
    100342
    101                         <div id="publishing-action">
    102                                 <input class="button-primary" name="save_menu" type="submit" value="<?php esc_attr_e('Save Menu'); ?>" />
    103                         </div><!--END #publishing-action-->
    104                         <br class="clear" />
    105                 </div><!--END #major-publishing-actions-->
    106         </div><!--END #submitpost .submitbox-->
    107         <?php
    108 }
    109 
    110 /**
    111  * Displays a metabox for creating a new menu.
    112  *
    113  * @since 3.0.0
    114  */
    115 function wp_nav_menu_create_metabox() { ?>
    116         <p>
    117                 <input type="text" name="create-menu-name" id="create-menu-name" class="regular-text" value="<?php esc_attr_e( 'Menu name' ); ?>"  />
    118                 <input type="submit" name="create-menu-button" id="create-menu-button" class="button" value="<?php esc_attr_e('Create Menu'); ?>" />
    119         </p>
    120         <?php
    121 }
    122 
    123 /**
    124  * Displays a metabox for the custom links menu item.
    125  *
    126  * @since 3.0.0
    127  */
    128 function wp_nav_menu_item_link_metabox() {
    129343        // @note: hacky query, see #12660
    130344        $args = array( 'post_type' => 'nav_menu_item', 'post_status' => 'any', 'meta_key' => '_menu_item_type', 'numberposts' => -1, 'orderby' => 'title', );
    131345
    132346        // @todo transient caching of these results with proper invalidation on updating links
    133347        $links = get_posts( $args );
     348
     349        $current_tab = 'create';
     350        if ( isset( $_REQUEST['customlink-tab'] ) && in_array( $_REQUEST['customlink-tab'], array('create', 'all') ) ) {
     351                $current_tab = $_REQUEST['customlink-tab'];
     352        }
     353
     354        $removed_args = array(
     355                'action',
     356                'customlink-tab',
     357                'edit-menu-item',
     358                'menu-item',
     359                'page-tab',
     360                '_wpnonce',
     361        );
     362
    134363        ?>
    135         <p id="menu-item-url-wrap">
    136                 <label class="howto" for="menu-item-url">
    137                         <span><?php _e('URL'); ?></span>
    138                         <input id="custom-menu-item-url" name="custom-menu-item-url" type="text" class="code menu-item-textbox" value="http://" />
    139                 </label>
    140         </p>
    141         <p id="menu-item-name-wrap">
    142                 <label class="howto" for="custom-menu-item-name">
    143                         <span><?php _e('Text'); ?></span>
    144                         <input id="custom-menu-item-name" name="custom-menu-item-name" type="text" class="regular-text menu-item-textbox" value="<?php echo esc_attr( __('Menu Item') ); ?>" />
    145                 </label>
    146         </p>
     364        <div class="customlinkdiv">
     365                <ul id="customlink-tabs" class="customlink-tabs add-menu-item-tabs">
     366                        <li <?php echo ( 'create' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="menu-tab-link" href="<?php echo add_query_arg('customlink-tab', 'create', remove_query_arg($removed_args)); ?>#tabs-panel-create-custom"><?php _e('Create New'); ?></a></li>
     367                        <li <?php echo ( 'all' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="menu-tab-link" href="<?php echo add_query_arg('customlink-tab', 'all', remove_query_arg($removed_args)); ?>#tabs-panel-all-custom"><?php _e('View All'); ?></a></li>
     368                </ul>
    147369
    148         <p class="button-controls">
    149                 <span class="lists-controls">
    150                         <a class="show-all"><?php _e('View All'); ?></a>
    151                         <a class="hide-all"><?php _e('Hide All'); ?></a>
    152                 </span>
     370                <div class="tabs-panel <?php
     371                        echo ( 'create' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' );
     372                ?>" id="tabs-panel-create-custom">
     373                        <input type="hidden" value="custom" name="menu-item[<?php echo $_placeholder; ?>][menu-item-type]" />
     374                        <p id="menu-item-url-wrap">
     375                                <label class="howto" for="custom-menu-item-url">
     376                                        <span><?php _e('URL'); ?></span>
     377                                        <input id="custom-menu-item-url" name="menu-item[<?php echo $_placeholder; ?>][menu-item-url]" type="text" class="code menu-item-textbox" value="http://" />
     378                                </label>
     379                        </p>
    153380
    154                 <span class="add-to-menu">
    155                         <a class="button"><?php _e('Add to Menu'); ?></a>
    156                 </span>
    157         </p>
    158         <div id="available-links" class="list-wrap">
    159                 <div class="list-container">
    160                         <ul class="list">
    161                                 <?php echo wp_nav_menu_get_items( $links, 'custom', 'custom' ); ?>
     381                        <p id="menu-item-name-wrap">
     382                                <label class="howto" for="custom-menu-item-name">
     383                                        <span><?php _e('Text'); ?></span>
     384                                        <input id="custom-menu-item-name" name="menu-item[<?php echo $_placeholder; ?>][menu-item-title]" type="text" class="regular-text menu-item-textbox" value="<?php echo esc_attr( __('Menu Item') ); ?>" />
     385                                </label>
     386                        </p>
     387                </div><!-- /.tabs-panel -->
     388
     389                <div class="tabs-panel <?php
     390                        echo ( 'all' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' );
     391                ?>" id="tabs-panel-all-custom">
     392                        <ul id="customlinkchecklist" class="list:customlink customlinkchecklist form-no-clear">
     393                                <?php
     394                                $args['walker'] = new Walker_Nav_Menu_Checklist;
     395                                echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $links), 0, (object) $args );
     396                                ?>
    162397                        </ul>
    163                 </div><!-- /.list-container-->
    164         </div><!-- /#available-links-->
    165         <div class="clear"></div>
     398                </div><!-- /.tabs-panel -->
     399
     400                <p class="button-controls">
     401                        <span class="add-to-menu">
     402                                <input type="submit" class="button-secondary" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-custom-menu-item" />
     403                        </span>
     404                </p>
     405
     406                <div class="clear"></div>
     407        </div><!-- /.customlinkdiv -->
    166408        <?php
    167409}
    168410
     
    174416 * @param string $object Not used.
    175417 * @param string $post_type The post type object.
    176418 */
    177 function wp_nav_menu_item_post_type_metabox( $object, $post_type ) {
    178         $args = array( 'post_type' => $post_type['args']->name, 'numberposts' => -1, 'orderby' => 'title', );
     419function wp_nav_menu_item_post_type_meta_box( $object, $post_type ) {
     420        $post_type_name = $post_type['args']->name;
    179421
     422        // paginate browsing for large numbers of post objects
     423        $per_page = 50;
     424        $pagenum = isset( $_REQUEST[$post_type_name . '-tab'] ) && isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 1;
     425        $offset = 0 < $pagenum ? $per_page * ( $pagenum - 1 ) : 0;
     426
     427        $args = array(
     428                'offset' => $offset,
     429                'order' => 'ASC',
     430                'orderby' => 'title',
     431                'posts_per_page' => $per_page,
     432                'post_type' => $post_type_name,
     433                'suppress_filters' => true,
     434        );
     435
    180436        // @todo transient caching of these results with proper invalidation on updating of a post of this type
    181         $posts = get_posts( $args );
     437        $get_posts = new WP_Query;
     438        $posts = $get_posts->query( $args );
    182439
     440        $post_type_object = get_post_type_object($post_type_name);
     441
     442        $num_pages = $get_posts->max_num_pages;
     443
     444        $count_posts = (int) @count( $posts );
     445
     446        if ( isset( $get_posts->found_posts ) && ( $get_posts->found_posts > $count_posts ) ) {
     447                // somewhat like display_page_row(), let's make sure ancestors show up on paged display
     448                $parent_ids = array();
     449                $child_ids = array();
     450                foreach( (array) $posts as $post ) {
     451                        $parent_ids[] = (int) $post->post_parent;
     452                        $child_ids[] = (int) $post->ID;
     453                }
     454                $parent_ids = array_unique($parent_ids);
     455                $child_ids = array_unique($child_ids);
     456               
     457                $missing_parents = array();
     458                do {
     459                        foreach( (array) $missing_parents as $missing_parent_id ) {
     460                                $missing_parent = get_post($missing_parent_id);
     461                                $posts[] = $missing_parent;
     462                                $child_ids[] = $missing_parent_id;
     463                                $parent_ids[] = $missing_parent->post_parent;
     464                        }
     465                       
     466                        $missing_parents = array_filter( array_diff( array_unique( $parent_ids ), array_unique( $child_ids ) ) );
     467
     468                } while( 0 < count( $missing_parents ) );
     469               
     470        }
     471
     472        $page_links = paginate_links( array(
     473                'base' => add_query_arg(
     474                        array(
     475                                $post_type_name . '-tab' => 'all',
     476                                'paged' => '%#%',
     477                        )
     478                ),
     479                'format' => '',
     480                'prev_text' => __('&laquo;'),
     481                'next_text' => __('&raquo;'),
     482                'total' => $num_pages,
     483                'current' => $pagenum
     484        ));
     485       
    183486        if ( !$posts )
    184487                $error = '<li id="error">'. sprintf( __( 'No %s exists' ), $post_type['args']->label ) .'</li>';
    185488
    186         $pt_names = '';
    187         if ( is_array($posts) ) {
    188                 foreach ( $posts as $post ) {
    189                         if ( $post->post_title ) {
    190                                 $pt_names .= htmlentities( $post->post_title ) .'|';
    191                         }
    192                 }
     489        $current_tab = 'search';
     490        if ( isset( $_REQUEST[$post_type_name . '-tab'] ) && in_array( $_REQUEST[$post_type_name . '-tab'], array('all', 'search') ) ) {
     491                $current_tab = $_REQUEST[$post_type_name . '-tab'];
    193492        }
    194493
    195         $id = $post_type['args']->name;
     494        if ( ! empty( $_REQUEST['quick-search-posttype-' . $post_type_name] ) ) {
     495                $current_tab = 'search';
     496        }
     497
     498        $removed_args = array(
     499                'action',
     500                'customlink-tab',
     501                'edit-menu-item',
     502                'menu-item',
     503                'page-tab',
     504                '_wpnonce',
     505        );
     506
    196507        ?>
    197         <p class="quick-search-wrap">
    198                 <input type="text" class="quick-search regular-text" value="" />
    199                 <a class="quick-search-submit button-secondary"><?php _e('Search'); ?></a>
    200         </p>
     508        <div id="posttype-<?php echo $post_type_name; ?>" class="posttypediv">
     509                <ul id="posttype-<?php echo $post_type_name; ?>-tabs" class="posttype-tabs add-menu-item-tabs">
     510                        <li <?php echo ( 'search' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="menu-tab-link" href="<?php echo add_query_arg($post_type_name . '-tab', 'search', remove_query_arg($removed_args)); ?>#tabs-panel-posttype-<?php echo $post_type_name; ?>-search"><?php _e('Search'); ?></a></li>
     511                        <li <?php echo ( 'all' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="menu-tab-link" href="<?php echo add_query_arg($post_type_name . '-tab', 'all', remove_query_arg($removed_args)); ?>#<?php echo $post_type_name; ?>-all"><?php _e('View All'); ?></a></li>
     512                </ul>
    201513
    202         <p class="button-controls">
    203                 <span class="lists-controls">
    204                         <a class="show-all"><?php _e('View All'); ?></a>
    205                         <a class="hide-all"><?php _e('Hide All'); ?></a>
    206                 </span>
     514                <div class="tabs-panel <?php
     515                        echo ( 'search' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' );
     516                ?>" id="tabs-panel-posttype-<?php echo $post_type_name; ?>-search">
     517                        <?php
     518                        if ( isset( $_REQUEST['quick-search-posttype-' . $post_type_name] ) ) {
     519                                $searched = esc_attr( $_REQUEST['quick-search-posttype-' . $post_type_name] );
     520                                $search_results = get_posts( array( 's' => $searched, 'post_type' => $post_type_name, 'fields' => 'all', 'order' => 'DESC', ) );
     521                        } else {
     522                                $searched = '';
     523                                $search_results = array();
     524                        }
     525                        ?>
     526                        <p class="quick-search-wrap">
     527                                <input type="text" class="quick-search regular-text" value="<?php echo $searched; ?>" name="quick-search-posttype-<?php echo $post_type_name; ?>" />
     528                                <input type="submit" class="quick-search-submit button-secondary" value="<?php esc_attr_e('Search'); ?>" />
     529                        </p>
    207530
    208                 <span class="add-to-menu">
    209                         <a class="button"><?php _e('Add to Menu'); ?></a>
    210                 </span>
    211         </p>
     531                        <ul id="<?php echo $post_type_name; ?>-search-checklist" class="list:<?php echo $post_type_name?> categorychecklist form-no-clear">
     532                        <?php if ( ! empty( $search_results ) && ! is_wp_error( $search_results ) ) : ?>
     533                                <?php
     534                                $args['walker'] = new Walker_Nav_Menu_Checklist;
     535                                echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $search_results), 0, (object) $args );
     536                                ?>
     537                        <?php endif; ?>
     538                        </ul>
     539                </div><!-- /.tabs-panel -->
    212540
    213         <div id="existing-<?php echo esc_attr( $id ); ?>" class="list-wrap">
    214                 <div class="list-container">
    215                         <ul class="list">
    216                                 <?php echo isset( $error ) ? $error : wp_nav_menu_get_items( $posts, 'post_type', $id ); ?>
     541
     542                <div id="<?php echo $post_type_name; ?>-all" class="tabs-panel <?php
     543                        echo ( 'all' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' );
     544                ?>">
     545                        <div class="add-menu-item-pagelinks">
     546                                <?php echo $page_links; ?>
     547                        </div>
     548                        <ul id="<?php echo $post_type_name; ?>checklist" class="list:<?php echo $post_type_name?> categorychecklist form-no-clear">
     549                                <?php
     550                                $args['walker'] = new Walker_Nav_Menu_Checklist;
     551                                $checkbox_items = walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $posts), 0, (object) $args );
     552
     553                                if ( 'all' == $current_tab && ! empty( $_REQUEST['selectall'] ) ) {
     554                                        $checkbox_items = preg_replace('/(type=(.)checkbox(\2))/', '$1 checked=$2checked$2', $checkbox_items);
     555                                       
     556                                }
     557                                echo $checkbox_items;
     558                                ?>
    217559                        </ul>
    218                 </div><!-- /.list-container-->
    219         </div><!-- /#existing-categories-->
    220         <input type="hidden" class="autocomplete" name="autocomplete-<?php echo esc_attr( $id ); ?>-names" value="<?php echo esc_js( $pt_names ); ?>" />
    221         <br class="clear" />
    222         <script type="text/javascript" charset="utf-8">
    223                 // <![CDATA[
    224                 jQuery(document).ready(function(){
    225                         wpNavMenu.autocomplete('<?php echo esc_attr($id); ?>');
    226                 });
    227                 // ]]>
    228         </script>
     560                        <div class="add-menu-item-pagelinks">
     561                                <?php echo $page_links; ?>
     562                        </div>
     563                </div><!-- /.tabs-panel -->
     564
     565
     566                <p class="button-controls">
     567                        <span class="lists-controls">
     568                                <a href="<?php
     569                                        echo add_query_arg(
     570                                                array(
     571                                                        $post_type_name . '-tab' => 'all',
     572                                                        'selectall' => 1,
     573                                                ),
     574                                                remove_query_arg($removed_args)
     575                                        );
     576                                ?>#posttype-<?php echo $post_type_name; ?>" class="select-all"><?php _e('Select All'); ?></a>
     577                        </span>
     578
     579                        <span class="add-to-menu">
     580                                <input type="submit" class="button-secondary" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-post-type-menu-item" />
     581                        </span>
     582                </p>
     583
     584                <br class="clear" />
     585        </div><!-- /.posttypediv -->
    229586        <?php
    230587}
    231588
     
    237594 * @param string $object Not used.
    238595 * @param string $taxonomy The taxonomy object.
    239596 */
    240 function wp_nav_menu_item_taxonomy_metabox( $object, $taxonomy ) {
     597function wp_nav_menu_item_taxonomy_meta_box( $object, $taxonomy ) {
     598        $taxonomy_name = $taxonomy['args']->name;
     599        // paginate browsing for large numbers of objects
     600        $per_page = 50;
     601        $pagenum = isset( $_REQUEST[$taxonomy_name . '-tab'] ) && isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 1;
     602        $offset = 0 < $pagenum ? $per_page * ( $pagenum - 1 ) : 0;
     603       
    241604        $args = array(
    242                 'child_of' => 0, 'orderby' => 'name', 'order' => 'ASC',
    243                 'hide_empty' => false, 'include_last_update_time' => false, 'hierarchical' => 1, 'exclude' => '',
    244                 'include' => '', 'number' => '', 'pad_counts' => false
     605                'child_of' => 0,
     606                'exclude' => '',
     607                'hide_empty' => false,
     608                'hierarchical' => 1,
     609                'include' => '',
     610                'include_last_update_time' => false,
     611                'number' => $per_page,
     612                'offset' => $offset,
     613                'order' => 'ASC',
     614                'orderby' => 'name',
     615                'pad_counts' => false,
    245616        );
    246617
     618        $num_pages = ceil( wp_count_terms($taxonomy_name) / $per_page );
     619
     620        $page_links = paginate_links( array(
     621                'base' => add_query_arg(
     622                        array(
     623                                $taxonomy_name . '-tab' => 'all',
     624                                'paged' => '%#%',
     625                        )
     626                ),
     627                'format' => '',
     628                'prev_text' => __('&laquo;'),
     629                'next_text' => __('&raquo;'),
     630                'total' => $num_pages,
     631                'current' => $pagenum
     632        ));
     633       
     634        $walker = new Walker_Nav_Menu_Checklist;
    247635        // @todo transient caching of these results with proper invalidation on updating of a tax of this type
    248         $terms = get_terms( $taxonomy['args']->name, $args );
     636        $terms = get_terms( $taxonomy_name, $args );
    249637
    250         if ( !$terms || is_wp_error($terms) )
     638        if ( ! $terms || is_wp_error($terms) )
    251639                $error = '<li id="error">'. sprintf( __( 'No %s exists' ), $taxonomy['args']->label ) .'</li>';
    252640
    253         $term_names = '';
    254         if ( is_array($terms) ) {
    255                 foreach ( $terms as $term ) {
    256                         if ( $term->name ) {
    257                                 $term_names .= htmlentities( $term->name ) .'|';
    258                         }
    259                 }
     641        $current_tab = 'most-used';
     642        if ( isset( $_REQUEST[$taxonomy_name . '-tab'] ) && in_array( $_REQUEST[$taxonomy_name . '-tab'], array('all', 'most-used', 'search') ) ) {
     643                $current_tab = $_REQUEST[$taxonomy_name . '-tab'];
    260644        }
    261645
    262         $id = $taxonomy['args']->name;
     646        if ( ! empty( $_REQUEST['quick-search-taxonomy-' . $taxonomy_name] ) ) {
     647                $current_tab = 'search';
     648        }
     649
     650        $removed_args = array(
     651                'action',
     652                'customlink-tab',
     653                'edit-menu-item',
     654                'menu-item',
     655                'page-tab',
     656                '_wpnonce',
     657        );
     658
    263659        ?>
    264         <p class="quick-search-wrap">
    265                 <input type="text" class="quick-search regular-text" value="" />
    266                 <a class="quick-search-submit button-secondary"><?php _e('Search'); ?></a>
    267         </p>
     660        <div id="taxonomy-<?php echo $taxonomy_name; ?>" class="taxonomydiv">
     661                <ul id="taxonomy-<?php echo $taxonomy_name; ?>-tabs" class="taxonomy-tabs add-menu-item-tabs">
     662                        <li <?php echo ( 'most-used' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="menu-tab-link" href="<?php echo add_query_arg($taxonomy_name . '-tab', 'most-used', remove_query_arg($removed_args)); ?>#tabs-panel-<?php echo $taxonomy_name; ?>-pop"><?php _e('Most Used'); ?></a></li>
     663                        <li <?php echo ( 'search' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="menu-tab-link" href="<?php echo add_query_arg($taxonomy_name . '-tab', 'search', remove_query_arg($removed_args)); ?>#tabs-panel-search-taxonomy-<?php echo $taxonomy_name; ?>"><?php _e('Search'); ?></a></li>
     664                        <li <?php echo ( 'all' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="menu-tab-link" href="<?php echo add_query_arg($taxonomy_name . '-tab', 'all', remove_query_arg($removed_args)); ?>#tabs-panel-<?php echo $taxonomy_name; ?>-all"><?php _e('View All'); ?></a></li>
     665                </ul>
    268666
    269         <p class="button-controls">
    270                 <span class="lists-controls">
    271                         <a class="show-all"><?php _e('View All'); ?></a>
    272                         <a class="hide-all"><?php _e('Hide All'); ?></a>
    273                 </span>
     667                <div id="tabs-panel-<?php echo $taxonomy_name; ?>-pop" class="tabs-panel <?php
     668                        echo ( 'most-used' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' );
     669                ?>">
     670                        <ul id="<?php echo $taxonomy_name; ?>checklist-pop" class="categorychecklist form-no-clear" >
     671                                <?php
     672                                $popular_terms = get_terms( $taxonomy_name, array( 'orderby' => 'count', 'order' => 'DESC', 'number' => 10, 'hierarchical' => false ) );
     673                                $args['walker'] = $walker;
     674                                echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $popular_terms), 0, (object) $args );
     675                                ?>
     676                                <?php
     677                                ?>
     678                        </ul>
     679                </div><!-- /.tabs-panel -->
    274680
    275                 <span class="add-to-menu">
    276                         <a class="button"><?php _e('Add to Menu'); ?></a>
    277                 </span>
    278         </p>
     681                <div class="tabs-panel <?php
     682                        echo ( 'search' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' );
     683                ?>" id="tabs-panel-search-taxonomy-<?php echo $taxonomy_name; ?>">
     684                        <?php
     685                        if ( isset( $_REQUEST['quick-search-taxonomy-' . $taxonomy_name] ) ) {
     686                                $searched = esc_attr( $_REQUEST['quick-search-taxonomy-' . $taxonomy_name] );
     687                                $search_results = get_terms( $taxonomy_name, array( 'name__like' => $searched, 'fields' => 'all', 'orderby' => 'count', 'order' => 'DESC', 'hierarchical' => false ) );
     688                        } else {
     689                                $searched = '';
     690                                $search_results = array();
     691                        }
     692                        ?>
     693                        <p class="quick-search-wrap">
     694                                <input type="text" class="quick-search regular-text" value="<?php echo $searched; ?>" name="quick-search-taxonomy-<?php echo $taxonomy_name; ?>" />
     695                                <input type="submit" class="quick-search-submit button-secondary" value="<?php esc_attr_e('Search'); ?>" />
     696                        </p>
     697               
     698                        <ul id="<?php echo $taxonomy_name; ?>-search-checklist" class="list:<?php echo $taxonomy_name?> categorychecklist form-no-clear">
     699                        <?php if ( ! empty( $search_results ) && ! is_wp_error( $search_results ) ) : ?>
     700                                <?php
     701                                $args['walker'] = $walker;
     702                                echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $search_results), 0, (object) $args );
     703                                ?>
     704                        <?php endif; ?>
     705                        </ul>
     706                </div><!-- /.tabs-panel -->
    279707
    280         <div id="existing-<?php echo esc_attr( $id ); ?>" class="list-wrap">
    281                 <div class="list-container">
    282                         <ul class="list">
    283                                 <?php echo isset( $error ) ? $error : wp_nav_menu_get_items( $terms, 'taxonomy', $id ); ?>
     708                <div id="tabs-panel-<?php echo $taxonomy_name; ?>-all" class="tabs-panel <?php
     709                        echo ( 'all' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' );
     710                ?>">
     711                        <div class="add-menu-item-pagelinks">
     712                                <?php echo $page_links; ?>
     713                        </div>
     714                        <ul id="<?php echo $taxonomy_name; ?>checklist" class="list:<?php echo $taxonomy_name?> categorychecklist form-no-clear">
     715                                <?php
     716                                $args['walker'] = $walker;
     717                                echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $terms), 0, (object) $args );
     718                                ?>
    284719                        </ul>
    285                 </div><!-- /.list-container-->
    286         </div><!-- /#existing-categories-->
    287         <input type="hidden" class="autocomplete" name="autocomplete-<?php echo esc_attr($id); ?>-names" value="<?php echo esc_js( $term_names ); ?>" />
    288         <br class="clear" />
    289         <script type="text/javascript" charset="utf-8">
    290                 // <![CDATA[
    291                 jQuery(document).ready(function(){
    292                         wpNavMenu.autocomplete('<?php echo esc_attr($id); ?>');
    293                 });
    294                 // ]]>
    295         </script>
     720                        <div class="add-menu-item-pagelinks">
     721                                <?php echo $page_links; ?>
     722                        </div>
     723                </div><!-- /.tabs-panel -->
     724
     725                <p class="button-controls">
     726                        <span class="lists-controls">
     727                                <a href="<?php
     728                                        echo add_query_arg(
     729                                                array(
     730                                                        $taxonomy_name . '-tab' => 'all',
     731                                                        'selectall' => 1,
     732                                                ),
     733                                                remove_query_arg($removed_args)
     734                                        );
     735                                ?>#taxonomy-<?php echo $taxonomy_name; ?>" class="select-all"><?php _e('Select All'); ?></a>
     736                        </span>
     737
     738                        <span class="add-to-menu">
     739                                <input type="submit" class="button-secondary" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-taxonomy-menu-item" />
     740                        </span>
     741                </p>
     742
     743                <br class="clear" />
     744        </div><!-- /.taxonomydiv -->
    296745        <?php
    297746}
    298747
    299748/**
    300  * Abstract function for returning all menu items of a menu item type.
     749 * Save posted nav menu item data.
    301750 *
    302751 * @since 3.0.0
    303752 *
    304  * @param string $menu_items Array of objects containing all menu items to be displayed.
    305  * @param string $object_type Menu item type.
    306  * @param string $object Optional. Menu item type name.
    307  * @param string $context Optional. The context for how the menu items should be formatted.
    308  * @return string $ouput Menu items.
     753 * @param int $menu_id The menu ID for which to save this item.
     754 * @param array $menu_data The unsanitized posted menu item data.
     755 * @return array The database IDs of the items saved.
    309756 */
    310 function wp_nav_menu_get_items( $menu_items, $object_type, $object = null, $context = 'frontend' ) {
    311         if ( !$menu_items )
    312                 return __( 'Not Found' );
     757function wp_save_nav_menu_item( $menu_id = 0, $menu_data = array() ) {
     758        $menu_id = (int) $menu_id;
     759        $items_saved = array();
    313760
    314         $output = '';
    315         $i = 1;
    316         foreach ( $menu_items as $menu_item ) {
    317                 // convert the 'parent' taxonomy property to 'post_parent'
    318                 // so we don't have to duplicate this entire function.
    319                 if ( !isset($menu_item->post_parent) )
    320                         $menu_item->post_parent = $menu_item->parent;
     761        if ( is_nav_menu( $menu_id ) ) {
    321762
    322                 // Get all attachements and links
    323                 if ( in_array($object, array( 'attachment', 'custom' )) )
    324                         $menu_item->post_parent = 0;
     763                // Loop through all the menu items' POST values
     764                foreach( (array) $menu_data as $_possible_db_id => $_item_object_data ) {
     765                        if (
     766                                empty( $_item_object_data['menu-item-object-id'] ) && // checkbox is not checked
     767                                (
     768                                        ! isset( $_item_object_data['menu-item-type'] ) || // and item type either isn't set
     769                                        in_array( $_item_object_data['menu-item-url'], array( 'http://', '' ) ) || // or URL is the default
     770                                        'custom' != $_item_object_data['menu-item-type'] ||  // or it's not a custom menu item 
     771                                        ! empty( $_item_object_data['menu-item-db-id'] ) // or it *is* a custom menu item that already exists
     772                                )
     773                        ) {
     774                                continue; // then this potential menu item is not getting added to this menu
     775                        }
    325776
    326                 if ( 0 == $menu_item->post_parent ) {
    327                         // Set up the menu item
    328                         $menu_item = wp_setup_nav_menu_item( $menu_item, $object_type, $object );
     777                        // if this possible menu item doesn't actually have a menu database ID yet
     778                        if (
     779                                empty( $_item_object_data['menu-item-db-id'] ) ||
     780                                ( 0 > $_possible_db_id ) ||
     781                                $_possible_db_id != $_item_object_data['menu-item-db-id']
     782                        ) {
     783                                $_actual_db_id = 0;
     784                        } else {
     785                                $_actual_db_id = (int) $_item_object_data['menu-item-db-id'];
     786                        }
     787                       
     788                        $args = array(
     789                                'menu-item-db-id' => ( isset( $_item_object_data['menu-item-db-id'] ) ? $_item_object_data['menu-item-db-id'] : '' ),
     790                                'menu-item-object-id' => ( isset( $_item_object_data['menu-item-object-id'] ) ? $_item_object_data['menu-item-object-id'] : '' ),
     791                                'menu-item-object' => ( isset( $_item_object_data['menu-item-object'] ) ? $_item_object_data['menu-item-object'] : '' ),
     792                                'menu-item-parent-id' => ( isset( $_item_object_data['menu-item-parent-id'] ) ? $_item_object_data['menu-item-parent-id'] : '' ),
     793                                'menu-item-position' => ( isset( $_item_object_data['menu-item-position'] ) ? $_item_object_data['menu-item-position'] : '' ),
     794                                'menu-item-type' => ( isset( $_item_object_data['menu-item-type'] ) ? $_item_object_data['menu-item-type'] : '' ),
     795                                'menu-item-append' => ( isset( $_item_object_data['menu-item-append'] ) ? $_item_object_data['menu-item-append'] : '' ),
     796                                'menu-item-title' => ( isset( $_item_object_data['menu-item-title'] ) ? $_item_object_data['menu-item-title'] : '' ),
     797                                'menu-item-url' => ( isset( $_item_object_data['menu-item-url'] ) ? $_item_object_data['menu-item-url'] : '' ),
     798                                'menu-item-description' => ( isset( $_item_object_data['menu-item-description'] ) ? $_item_object_data['menu-item-description'] : '' ),
     799                                'menu-item-attr-title' => ( isset( $_item_object_data['menu-item-attr-title'] ) ? $_item_object_data['menu-item-attr-title'] : '' ),
     800                                'menu-item-target' => ( isset( $_item_object_data['menu-item-target'] ) ? $_item_object_data['menu-item-target'] : '' ),
     801                                'menu-item-classes' => ( isset( $_item_object_data['menu-item-classes'] ) ? $_item_object_data['menu-item-classes'] : '' ),
     802                                'menu-item-xfn' => ( isset( $_item_object_data['menu-item-xfn'] ) ? $_item_object_data['menu-item-xfn'] : '' ),
     803                        );
    329804
    330                         // No blank titles
    331                         if ( empty($menu_item->title) )
    332                                 continue;
     805                        $items_saved[] = wp_update_nav_menu_item( $menu_id, $_actual_db_id, $args );
    333806
    334                         $attributes = ( 'backend' == $context ) ? ' id="menu-item-'. $i .'" value="'. $i .'"' : '';
    335 
    336                         $output .= '<li'. $attributes .'>';
    337                         $output .= wp_get_nav_menu_item( $menu_item, $object_type, $object );
    338                         $output .= wp_get_nav_menu_sub_items( $menu_item->ID, $object_type, $object, $context );
    339                         $output .= '</li>';
    340 
    341                         ++$i;
    342807                }
    343808        }
    344 
    345         return $output;
     809        return $items_saved;
    346810}
    347811
    348812/**
    349  * Recursive function to retrieve sub menu items.
     813 * Returns the menu item formatted to edit.
    350814 *
    351815 * @since 3.0.0
    352816 *
    353  * @param string $childof The Parent ID.
    354  * @param string $object_type The object type.
    355  * @param string $object The object name.
    356  * @return string $output sub menu items.
     817 * @param string $menu_item_id The ID of the menu item to format.
     818 * @return string|WP_Error $output The menu formatted to edit or error object on failure.
    357819 */
    358 function wp_get_nav_menu_sub_items( $childof, $object_type, $object = null, $context = 'frontend' ) {
    359         $args = array( 'child_of' => $childof, 'parent' => $childof, 'hide_empty' => false, );
     820function wp_get_nav_menu_to_edit( $menu_item_id = 0 ) {
     821        static $_placeholder;
     822       
     823        $menu = wp_get_nav_menu_object( $menu_item_id );
     824       
     825        // If the menu exists, get its items.
     826        if ( is_nav_menu( $menu ) ) {
     827                $menu_items = wp_get_nav_menu_items( $menu->term_id );
    360828
    361         switch ( $object_type ) {
    362                 case 'post_type':
    363                         $hierarchical_post_types = get_post_types( array( 'hierarchical' => true ) );
    364                         if ( in_array( $object, $hierarchical_post_types ) ) {
    365                                 $args['post_type'] = $object;
    366                                 $sub_menu_items = get_pages( $args );
    367                         } else {
    368                                 $sub_menu_items = array();
    369                         }
    370                         break;
     829                $walker = new Walker_Nav_Menu_Edit;
    371830
    372                 case 'taxonomy':
    373                         if ( is_taxonomy_hierarchical( $object ) ) {
    374                                 $sub_menu_items = get_terms( $object, $args );
    375                         } else {
    376                                 $sub_menu_items = array();
    377                         }
    378                         break;
    379 
    380                 default:
    381                         $sub_menu_items = array();
    382                         break;
     831                return walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $menu_items), 0, (object) array('walker' => $walker ) );
     832        } elseif ( is_wp_error( $menu ) ) {
     833                return $menu;   
    383834        }
    384835
    385         $output = '';
    386         $i = 1;
    387         if ( !empty($sub_menu_items) && !is_wp_error($sub_menu_items) ) {
    388                 $output .= '<ul class="sub-menu menu-item-type-'. $object_type .'">';
    389                 foreach ( $sub_menu_items as $menu_item ) {
    390                         // Set up the menu item
    391                         $menu_item = wp_setup_nav_menu_item( $menu_item, $object_type, $object );
    392                         $attributes = ( 'backend' == $context ) ? ' id="menu-item-'. $i .'" value="'. $i .'"' : '';
    393836
    394                         $output .= '<li'. $attributes .'>';
    395                         $output .= wp_get_nav_menu_item( $menu_item, $object_type, $object );
    396                         $output .= wp_get_nav_menu_sub_items( $menu_item->ID, $object_type, $object );
    397                         $output .= '</li>';
     837}
    398838
    399                         ++$i;
    400                 }
    401                 $output .= '</ul>';
    402         }
    403         return $output;
    404 }
    405 ?>
    406  No newline at end of file
     839?>
  • wp-admin/js/nav-menu.dev.js

     
    88 * @subpackage Administration
    99 */
    1010
    11 var wpNavMenu;
     11var WPNavMenuHandler = function () {
     12        var $ = jQuery,
     13        activeHovering = false,
     14        currentDropzone = null,
     15       
     16        customLinkNameInput,
     17        customLinkURLInput,
     18        customLinkNameDefault,
     19        customLinkURLDefault,
    1220
    13 (function($) {
     21        autoCompleteData = {},
     22
     23        formatAutocompleteResponse = function( resultRow, pos, total, queryTerm ) {
     24                if ( resultRow && resultRow[0] ) {
     25                        var data = $.parseJSON(resultRow[0]);
     26                        if ( data.post_title ) {
     27                                if ( data.ID && data.post_type )
     28                                        autoCompleteData[data.post_title] = {ID: data.ID, object_type: data.post_type};
     29                                return data.post_title;
     30                        }
     31                }
     32        },
     33
     34        formatAutocompleteResult = function( resultRow, pos, total, queryTerm ) {
     35                if ( resultRow && resultRow[0] ) {
     36                        var data = $.parseJSON(resultRow[0]);
     37                        if ( data.post_title )
     38                                return data.post_title;
     39                }
     40        },
    1441       
    15         wpNavMenu = {
     42        getListDataFromID = function(menuItemID, parentEl) {
     43                if ( ! menuItemID )
     44                        return false;
     45                parentEl = parentEl || document;
     46                var fields = [
     47                        'menu-item-db-id',
     48                        'menu-item-object-id',
     49                        'menu-item-object',
     50                        'menu-item-parent-id',
     51                        'menu-item-position',
     52                        'menu-item-type',
     53                        'menu-item-append',
     54                        'menu-item-title',
     55                        'menu-item-url',
     56                        'menu-item-description',
     57                        'menu-item-attr-title',
     58                        'menu-item-target',
     59                        'menu-item-classes',
     60                        'menu-item-xfn'
     61                ],
     62                itemData = {},
     63                inputs = parentEl.getElementsByTagName('input'),
     64                i = inputs.length,
     65                j,
     66                menuID = document.getElementById('nav-menu-meta-object-id').value;
     67
     68                while ( i-- ) {
     69                        j = fields.length;
     70                        while ( j-- ) {
     71                                if (
     72                                        inputs[i] &&
     73                                        inputs[i].name &&
     74                                        'menu-item[' + menuItemID + '][' + fields[j] + ']' == inputs[i].name
     75                                ) {
     76                                        itemData[fields[j]] = inputs[i].value;
     77                                }
     78                        }
     79                }
     80
     81                return itemData;
     82        },
     83
     84        getParentMenuItemDBId = function() {
     85                var allInputs = this.getElementsByTagName('input'),
     86                i = allInputs.length,
     87                j,
     88                parentEl,
     89                parentInputs;
     90
     91                while( i-- ) {
     92                        if ( -1 != allInputs[i].name.indexOf('menu-item-parent-id[' + parseInt(this.id.replace('menu-item-', ''), 10) + ']') ) {
     93                                /*  This LI element is not in a submenu */
     94                                if ( ! this.parentNode.className || -1 == this.parentNode.className.indexOf('sub-menu') ) {
     95                                        allInputs[i].value = 0;
     96
     97                                /* This LI is in a submenu, so need to get the parent's object ID (which is different from the parent's DB ID, the ID in its attributes) */
     98                                } else if ( 'LI' == this.parentNode.parentNode.nodeName && -1 != this.parentNode.parentNode.id.indexOf('menu-item-') )  {
     99                                         parentEl = this.parentNode.parentNode;
     100                                         parentInputs = parentEl.getElementsByTagName('input');
     101                                         j = parentInputs.length;
     102                                         while ( j-- ) {
     103                                                if ( parentInputs[j].name && -1 != parentInputs[j].name.indexOf('menu-item-object-id[' + parseInt(parentEl.id.replace('menu-item-', ''), 10) + ']') ) {
     104                                                        allInputs[i].value = parseInt(parentInputs[j].value, 10);
     105                                                        break;
     106                                                }
     107                                         }
     108                                }
     109                                break;
     110                        }
     111                }
     112        },
     113
     114        makeDroppable = function(el) {
     115                var that = this;
     116
     117                $(el).droppable({
     118                        accept: '.menu li',
     119                        tolerance: 'pointer',
     120                        drop: function(e, ui) {
     121                                that.eventOnDrop(ui.draggable[0], this, ui, e);
     122                        },
     123
     124                        over: function(e,ui) {
     125                                that.eventOnDragOver(ui.draggable[0], this, ui, e);
     126                        },
     127
     128                        out: function(e, ui) {
     129                                that.eventOnDragOut(ui.draggable[0], this, ui, e);
     130                        }
     131                });
     132        },
     133
     134        menuList,
     135
     136        setupListItemsDragAndDrop = function(list) {
     137                if ( ! list )
     138                        return;
     139
     140                var menuListItems = list.getElementsByTagName('li'),
     141                i = menuListItems.length;
    16142               
     143                while ( i-- )
     144                        this.setupListItemDragAndDrop(menuListItems[i]);
     145        };
     146
     147        return {
     148               
    17149                // Functions that run on init.
    18150                init : function() {
     151                        menuList = document.getElementById('menu-to-edit');
    19152                       
    20                         wpNavMenu.initial_meta_boxes();
     153                        this.attachMenuEditListeners();
     154
     155                        this.attachMenuMetaListeners(document.getElementById('nav-menu-meta'));
    21156                       
    22                         wpNavMenu.drag_and_drop();
     157                        this.attachTabsPanelListeners();
    23158                       
    24                         // Delete AYS
    25                         $('#update-nav-menu .deletion').click(function(){
    26                                 if ( confirm( navMenuL10n.warnDelete ) ) {
    27                                         return true;
    28                                 } else {
    29                                         return false;
    30                                 };
    31                         });
     159                        // init drag and drop
     160                        setupListItemsDragAndDrop.call(this, menuList);
    32161
    33                         // Handle Save Button Clicks
    34                         $('#update-nav-menu').submit(function(){
    35                                 wpNavMenu.update_post_data();
    36                         });
    37 
    38                         // Handle some return keypresses
    39                         $('#create-menu-name').keypress(function(e){
    40                                 if ( 13 == e.keyCode ) {
    41                                         $('#create-menu-button').click();
    42                                         return false;
     162                        postboxes.add_postbox_toggles('nav-menus');
     163                },
     164               
     165                attachMenuEditListeners : function() {
     166                        var that = this;
     167                        $('#update-nav-menu').bind('click', function(e) {
     168                                if ( e.target && e.target.className ) {
     169                                        if ( -1 != e.target.className.indexOf('item-edit') ) {
     170                                                return that.eventOnClickEditLink(e.target);
     171                                        } else if ( -1 != e.target.className.indexOf('menu-delete') ) {
     172                                                return that.eventOnClickMenuDelete(e.target);
     173                                        } else if ( -1 != e.target.className.indexOf('item-delete') ) {
     174                                                return that.eventOnClickMenuItemDelete(e.target);
     175                                        }
    43176                                }
    44177                        });
     178                },
    45179
    46                         $('#custom-menu-item-url, #custom-menu-item-name').keypress(function(e){
    47                                 if ( 13 == e.keyCode ) {
    48                                         $('#add-custom-links a.button').click();
    49                                         return false;
    50                                 }
    51                         }).focus(function(){
    52                                 if ( $(this).val() == $(this).attr('defaultValue') && $(this).attr('id') != 'custom-menu-item-url' ) {
    53                                         $(this).val('');
    54                                 }
    55                         }).blur(function(){
    56                                 if ( $(this).val() == '' ) {
    57                                         $(this).val($(this).attr('defaultValue'));
    58                                 }
    59                         });
     180                attachMenuMetaListeners : function(formEL) {
     181                        if ( ! formEL )
     182                                return;
    60183
    61                         $('#create-menu-name').focus(function(){
    62                                 if ( $(this).val() == $(this).attr('defaultValue') ) {
    63                                         $(this).val('');
    64                                 }
    65                         }).blur(function(){
    66                                 if ( $(this).val() == '' ) {
    67                                         $(this).val($(this).attr('defaultValue'));
    68                                 }
    69                         });
     184                        var that = this;
    70185
    71                         // close postboxes that should be closed
    72                         $('.if-js-closed').removeClass('if-js-closed').addClass('closed');
     186                        // set default value for custom link name
     187                        customLinkNameInput = document.getElementById('custom-menu-item-name');
     188                        customLinkURLInput = document.getElementById('custom-menu-item-url');
    73189
    74                         // postboxes setup
    75                         postboxes.add_postbox_toggles('nav-menus');
     190                        if ( customLinkNameInput ) {
     191                                customLinkNameDefault = 'undefined' != typeof customLinkNameInput.defaultValue ? customLinkNameInput.defaultValue : customLinkNameInput.getAttribute('value');
     192                                customLinkURLDefault = 'undefined' != typeof customLinkURLInput.defaultValue ? customLinkURLInput.defaultValue : customLinkURLInput.getAttribute('value');
     193                                $(customLinkNameInput).bind('focus', function(e) {
     194                                        this.value = customLinkNameDefault == this.value ? '' : this.value;
     195                                });
     196                               
     197                                $(customLinkNameInput).bind('blur', function(e) {
     198                                        this.value = '' == this.value ? customLinkNameDefault : this.value;
     199                                });
     200                        }
    76201
    77                         // Clear the quick search textbox
    78                         $('.quick-search').click(function(){
    79                                 $(this).attr( 'value', '' );
     202                        // auto-suggest for the quick-search boxes
     203                        $('input.quick-search').each(function(i, el) {
     204                                that.setupQuickSearchEventListeners(el);
    80205                        });
    81 
    82                         // Quick Search submit
    83                         $('.quick-search-submit').click(function(){
    84                                 $(this).siblings('.quick-search').search();
     206                       
     207                        $(formEL).bind('submit', function(e) {
     208                                return that.eventSubmitMetaForm.call(that, this, e);
    85209                        });
     210                },
    86211
    87                         // Edit menu item
    88                         $('#menu-container .item-edit').click(function(){
    89                                 wpNavMenu.edit_menu_item( $(this).attr('value') );
    90                         });
     212                attachTabsPanelListeners : function() {
     213                        $('#menu-settings-column').bind('click', function(e) {
     214                                if ( e.target && e.target.className && -1 != e.target.className.indexOf('menu-tab-link') ) {
     215                                        var i = e.target.parentNode,
     216                                        activePanel,
     217                                        panelIdMatch = /#(.*)$/.exec(e.target.href),
     218                                        tabPanels;
     219                                        while ( ! i.className || -1 == i.className.indexOf('inside') ) {
     220                                                i = i.parentNode;
     221                                        }
     222                                        $('.tabs-panel', i).each(function() {
     223                                                if ( this.className )
     224                                                        this.className = this.className.replace('tabs-panel-active', 'tabs-panel-inactive');
     225                                        });
    91226
    92                         // Delete menu item
    93                         $('#menu-container .item-delete').click(function(){
    94                                 wpNavMenu.remove_menu_item( $(this).attr('value') );
    95                         });
     227                                        $('.tabs', i).each(function() {
     228                                                this.className = this.className.replace('tabs', '');
     229                                        });
    96230
    97                         // Update menu item settings (thickbox)
    98                         $('#update-menu-item').click(function(){
    99                                 wpNavMenu.update_menu_item();
    100                                 tb_remove();
    101                         });
     231                                        e.target.parentNode.className += ' tabs';
    102232
    103                         // Close thickbox
    104                         $('#cancel-save').click(function(){
    105                                 tb_remove();
     233                                        if ( panelIdMatch && panelIdMatch[1] ) {
     234                                                activePanel = document.getElementById(panelIdMatch[1]);
     235                                                if ( activePanel ) {
     236                                                        activePanel.className = activePanel.className.replace('tabs-panel-inactive', 'tabs-panel-active');
     237                                                }
     238                                        }
     239                                       
     240                                        return false;
     241                                } else if ( e.target && e.target.className && -1 != e.target.className.indexOf('select-all') ) {
     242                                        var selectAreaMatch = /#(.*)$/.exec(e.target.href);
     243                                        if ( selectAreaMatch && selectAreaMatch[1] ) {
     244                                                $('#' + selectAreaMatch[1] + ' .tabs-panel-active input[type=checkbox]').attr('checked', 'checked');
     245                                                return false;
     246                                        }
     247                                }
    106248                        });
     249                },
    107250
    108                         // Show All Button
    109                         $('.show-all').click(function(e){
    110                                 $(e.currentTarget).parent().parent().siblings('.list-wrap').css( 'display', 'block' );
    111                                 $(e.currentTarget).parent().parent().siblings('.list-wrap').find('li').css( 'display', 'block' );
    112                                 $(e.currentTarget).hide();
    113                                 $(e.currentTarget).siblings('.hide-all').show();
    114                         });
     251                setupListItemDragAndDrop : function(el) {
     252                        var defLists = el.getElementsByTagName('dl'),
     253                        dropZone = this.makeListItemDropzone(el),
     254                        i = defLists.length;
    115255
    116                         // Hide All Button
    117                         $('.hide-all').click(function(e){
    118                                 $(e.currentTarget).parent().parent().siblings('.list-wrap').css( 'display', 'none' );
    119                                 $(e.currentTarget).parent().parent().siblings('.list-wrap').find('li').css( 'display', 'none' );
    120                                 $(e.currentTarget).hide();
    121                                 $(e.currentTarget).siblings('.show-all').show();
    122                         });
     256                        makeDroppable.call(this, dropZone);
     257                        this.makeListItemDraggable(el);
    123258
    124                         // Add menu items into the menu
    125                         $('.add-to-menu').click(function(e){
    126                                 wpNavMenu.add_checked_items_to_menu(e.currentTarget);
    127                         });
     259                        while( i-- ) {
     260                                makeDroppable.call(this, defLists[i]);
     261                        }
     262                },
    128263
    129                         // Create a new link then add it to the menu
    130                         $('#add-custom-links .add-to-menu a').click(function(e){
    131                                 // Add link to menu
    132                                 if ( $('#custom-menu-item-url').val() == $('#custom-menu-item-url').attr('defaultValue') )
    133                                         return; // Do not allow "http://" submissions to go through
    134 
    135                                 wpNavMenu.add_custom_link( $('#custom-menu-item-name').val(), $('#custom-menu-item-url').val() );
    136                                
    137                                 // Reset the fields back to their defaults
    138                                 $('#custom-menu-item-name').val($('#custom-menu-item-name').attr('defaultValue'));
    139                                 $('#custom-menu-item-url' ).val($('#custom-menu-item-url' ).attr('defaultValue')).focus();
     264                /**
     265                 * Set up quick-search input fields' events.
     266                 *
     267                 * @param object el The input element.
     268                 */
     269                setupQuickSearchEventListeners : function(el) {
     270                        var that = this;
     271                        $(el).autocomplete( ajaxurl + '?action=menu-quick-search&type=' + el.name,
     272                                {
     273                                        delay: 500,
     274                                        formatItem: formatAutocompleteResponse,
     275                                        formatResult: formatAutocompleteResult,
     276                                        minchars: 2,
     277                                        multiple: false
     278                                }
     279                        ).bind('blur', function(e) {
     280                                var changedData = autoCompleteData[this.value],
     281                                inputEl = this;
     282                                if ( changedData ) {
     283                                        $.post(
     284                                                ajaxurl + '?action=menu-quick-search&type=get-post-item&response-format=markup',
     285                                                changedData,
     286                                                function(r) {
     287                                                        that.processQuickSearchQueryResponse.call(that, r, changedData);
     288                                                        autoCompleteData[inputEl.value] = false;
     289                                                }
     290                                        );
     291                                }
    140292                        });
    141293                },
     294
     295                eventOnClickEditLink : function(clickedEl) {
     296                        var activeEdit,
     297                        matchedSection = /#(.*)$/.exec(clickedEl.href);
     298                        if ( matchedSection && matchedSection[1] ) {
     299                                activeEdit = document.getElementById(matchedSection[1]);
     300                                if ( activeEdit ) {
     301                                        if ( -1 != activeEdit.className.indexOf('menu-item-edit-inactive') ) {
     302                                                activeEdit.className = activeEdit.className.replace('menu-item-edit-inactive', 'menu-item-edit-active');
     303                                        } else {
     304                                                activeEdit.className = activeEdit.className.replace('menu-item-edit-active', 'menu-item-edit-inactive');
     305                                        }
     306                                        return false;
     307                                }
     308                        }
     309                },
    142310               
    143                 add_custom_link : function( link_name, link_url ) {
    144                         var params = {
    145                                 action: 'save-custom-link',
    146                                 link_name: link_name,
    147                                 link_url: link_url
     311                eventOnClickMenuDelete : function(clickedEl) {
     312                        // Delete warning AYS
     313                        if ( confirm( navMenuL10n.warnDeleteMenu ) ) {
     314                                return true;
     315                        } else {
     316                                return false;
    148317                        }
    149                        
    150                         $.post( ajaxurl, params, function(link_id) {
    151                                 if ( '-1' == link_id )
    152                                         return;
     318                },
    153319
    154                                 wpNavMenu.add_to_menu( link_id, link_id, 'custom', 'custom', navMenuL10n.custom, 0, link_name, link_url, '', '', '', '', '' );
    155                         }, 'json');
     320                eventOnClickMenuItemDelete : function(clickedEl) {
     321                        var itemID,
     322                        matchedSection,
     323                        that = this;
     324
     325                        // Delete warning AYS
     326                        if ( confirm( navMenuL10n.warnDeleteMenuItem ) ) {
     327                                matchedSection = /_wpnonce=([a-zA-Z0-9]*)$/.exec(clickedEl.href);
     328                                if ( matchedSection && matchedSection[1] ) {
     329                                        itemID = parseInt(clickedEl.id.replace('delete-', ''), 10);     
     330                                        $.post(
     331                                                ajaxurl,
     332                                                {
     333                                                        action:'delete-menu-item',
     334                                                        'menu-item':itemID,
     335                                                        '_wpnonce':matchedSection[1]
     336                                                },
     337                                                function (resp) {
     338                                                        if ( '1' == resp )
     339                                                                that.removeMenuItem(document.getElementById('menu-item-' + itemID));
     340                                                }
     341                                        );
     342                                        return false;   
     343                                }
     344                                return true;
     345                        } else {
     346                                return false;
     347                        }
    156348                },
    157                
     349
    158350                /**
    159                  * In combination with the php function wp_initial_nav_menu_meta_boxes(),
    160                  * this function limits the metaboxes for first time users to just links, pages and cats.
     351                 * Callback for the drag over action when dragging a list item.
     352                 *
     353                 * @param object draggedEl The DOM element being dragged
     354                 * @param object dropEl The DOM element on top of which we're dropping.
    161355                 */
    162                 initial_meta_boxes : function() {
    163                         var hidden = $('#hidden-metaboxes').val().split( ',' );
     356                eventOnDragOver : function(draggedEl, dropEl) {
     357                        activeHovering = true;
     358                        currentDropzone = dropEl;
     359                        dropEl.className += ' sortable-placeholder';
     360                },
    164361
    165                         if ( '' != hidden ) {
    166                                 for ( var i = 0; i < hidden.length; i++ ) {
    167                                         $( '#' + hidden[i] ).attr( 'style', 'display: none;' );
    168                                         $( '#' + hidden[i] + '-hide' ).attr( 'checked', false );
    169                                 };
    170                         };
     362                /**
     363                 * Callback for the drag out action when dragging a list item.
     364                 *
     365                 * @param object draggedEl The DOM element being dragged
     366                 * @param object dropEl The DOM element on top of which we're dropping.
     367                 */
     368                eventOnDragOut : function(draggedEl, dropEl) {
     369                        activeHovering = false;
     370
     371                        /* delay the disappearance of the droppable area so it doesn't flicker in and out */
     372                        (function(that) {
     373                                setTimeout(function() {
     374                                        if ( that != currentDropzone || ( ! activeHovering && that.className && -1 != that.className.indexOf('sortable-placeholder') ) ) {
     375                                                that.className = that.className.replace(/sortable-placeholder/g, '');
     376                                        }
     377                                }, 500);
     378                        })(dropEl);
    171379                },
    172                
    173                 // Makes the menu items drag and droppable.
    174                 drag_and_drop : function() {
    175                         // Make sure all li's have dropzones
    176                         $('.menu li').each(function(){
    177                                 if ( !$(this).children('.dropzone').attr('class') ) {
    178                                         $(this).prepend('<div class="dropzone"></div>');
    179                                 };
    180                         });
    181380
    182                         // make menu item draggable
    183                         $('.menu li').draggable({
    184                                 handle: ' > dl',
    185                                 opacity: .8,
    186                                 addClasses: false,
    187                                 helper: 'clone',
    188                                 zIndex: 100
    189                         });
     381                /**
     382                 * Callback for the drop action when dragging and dropping a list item.
     383                 *
     384                 * @param object draggedEl The DOM element being dragged (and now dropped)
     385                 * @param object dropEl The DOM element on top of which we're dropping.
     386                 */
     387                eventOnDrop : function(draggedEl, dropEl) {
     388                        var dropIntoSublist = !! ( -1 == dropEl.className.indexOf('dropzone') ),
     389                        subLists = dropEl.parentNode.getElementsByTagName('ul'),
     390                        hasSublist = false,
     391                        i = subLists.length,
     392                        subList;
    190393
    191                         // make menu item droppable
    192                         $('.menu li dl, .menu li .dropzone').droppable({
    193                                 accept: '.menu li',
    194                                 tolerance: 'pointer',
    195                                 drop: function(e, ui) {
    196                                         var li = $(this).parent();
    197                                         var child = !$(this).hasClass('dropzone');
     394                        activeHovering = false;
     395                       
     396                        dropEl.className = dropEl.className.replace(/sortable-placeholder/g, '');
    198397
    199                                         var parent_id = li.children('input[name=menu-item-object-id[]]').val();
    200                                         var child_id = ui.draggable.children('input[name=menu-item-object-id[]]').val();
    201  
    202                                         // An item cannot be a child of itself. Use a custom link for the effect.
    203                                         if ( parent_id == child_id ) {
    204                                                 ui.draggable.find('dt').animate( { backgroundColor: '#FF3333' }, { duration: 'normal', complete: function() { $(this).css( 'backgroundColor', '' ) } } );
    205                                                 $(this).parent().find('dt').removeAttr('style');
    206                                                 return;
    207                                         };
    208  
    209                                         // Append UL to first child
    210                                         if ( child && li.children('ul').length == 0 ) {
    211                                                 li.append( '<ul class="sub-menu" />' );
     398                        if ( dropIntoSublist ) {
     399                                while ( i-- ) {
     400                                        if ( subLists[i] && 1 != subLists[i].className.indexOf('sub-menu') ) {
     401                                                hasSublist = true;
     402                                                subList = subLists[i];
    212403                                        }
    213                                         // Make it draggable
    214                                         if ( child ) {
    215                                                 li.children('ul').append( ui.draggable );
    216                                         } else {
    217                                                 li.before( ui.draggable );
    218                                         }
     404                                }
    219405
    220                                         li.find('dl,.dropzone').css({ backgroundColor: '', borderColor: '' });
     406                                if ( ! hasSublist ) {
     407                                        subList = document.createElement('ul');
     408                                        subList.className = 'sub-menu';
     409                                        dropEl.parentNode.appendChild(subList);
     410                                }
    221411
    222                                         var draggablevalue = ui.draggable.attr('value');
    223                                         var droppablevalue = li.attr('value');
     412                                subList.appendChild(draggedEl);
     413                        } else {
     414                                dropEl.parentNode.parentNode.insertBefore(draggedEl, dropEl.parentNode);
     415                        }
    224416
    225                                         li.find('#menu-' + draggablevalue).find('#parent' + draggablevalue).val(droppablevalue);
    226                                         $(this).parent().find('dt').removeAttr('style');
    227                                         $(this).parent().find('div:first').removeAttr('style');
     417                        this.recalculateSortOrder(menuList);
    228418
    229                                 },
    230                                 over: function(e) {
    231                                 // Add child
    232                                         if ( $(this).attr('class') == 'dropzone ui-droppable' ) {
    233                                         $(this).parent().find('div:first').css({ background: '#f5f5f5', border: '1px dashed #bbb', margin: '10px 0px', height: '40px' });
    234                                 }
    235                                         // Add above
    236                                 else if ( $(this).attr('class') == 'ui-droppable' ) {
    237                                                 $(this).parent().find('dt:first').css('background', '#d8d8d8');
    238                                 } else {
    239                                                 // Do nothing
    240                                 }
    241                         },
    242                             out: function() {
    243                                 $(this).parent().find('dt').removeAttr('style');
    244                                 $(this).parent().find('div:first').removeAttr('style');
    245                                 $(this).filter('.dropzone').css({ borderColor: '' });
    246                         }
    247                         });
     419                        getParentMenuItemDBId.call(draggedEl);
    248420                },
    249        
    250                 // Prepares menu items for POST.
    251                 update_post_data : function() {
    252                         var i = 0; // counter
    253421
    254                         $('.menu li').each(function(){
    255                                 i = i + 1; // the menu order for each item
     422                /**
     423                 * Callback for the meta form submit action listener.
     424                 *
     425                 * @param object thisForm The submitted form.
     426                 * @param object e The event object.
     427                 */
     428                eventSubmitMetaForm : function(thisForm, e) {
     429                        var inputs = thisForm.getElementsByTagName('input'),
     430                        i = inputs.length,
     431                        j,
     432                        listItemData,
     433                        listItemDBID,
     434                        listItemDBIDMatch,
     435                        params = {},
     436                        processMethod = function(){},
     437                        re = new RegExp('menu-item\\[(\[^\\]\]*)');
    256438
    257                                 var j = $(this).attr('value'); // reference to the current menu item (e.g. li#menu-item + j)
     439                        thisForm.className = thisForm.className + ' processing',
     440                        that = this;
    258441
    259                                 // Grab the menu item id
    260                                 var id = $(this).children('input[name=menu-item-db-id[]]').val();
     442                        params['action'] = '';
    261443
    262                                 // Update the li value to equal the menu order
    263                                 $(this).attr('value', i);
     444                        while ( i-- ) {
     445                                if (    // we're submitting a checked item
     446                                        inputs[i].name &&
     447                                        -1 != inputs[i].name.indexOf('menu-item-object-id') &&
     448                                        inputs[i].checked ||
     449                                        ( // or we're dealing with a custom link
     450                                                'undefined' != typeof inputs[i].id &&
     451                                                'custom-menu-item-url' == inputs[i].id &&
     452                                                '' != inputs[i].value &&
     453                                                'http://' != inputs[i].value
     454                                        )
     455                                ) {
     456                                        params['action'] = 'add-menu-item';
     457                                        processMethod = that.processAddMenuItemResponse;
    264458
    265                                 // Update the position
    266                                 $(this).children('input[name=menu-item-position[]]').attr( 'value', i );
     459                                        listItemDBIDMatch = re.exec(inputs[i].name);
     460                                        listItemDBID = 'undefined' == typeof listItemDBIDMatch[1] ? 0 : parseInt(listItemDBIDMatch[1], 10);
     461                                        listItemData = getListDataFromID(listItemDBID);
     462                                       
     463                                        for ( j in listItemData ) {
     464                                                params['menu-item[' + listItemDBID + '][' + j + ']'] = listItemData[j];
     465                                        }
    267466
    268                                 // Update the parent id
    269                                 var pid = $(this).parent('.sub-menu').siblings('input[name=menu-item-object-id[]]').val();
    270                                
    271                                 if ( undefined == pid ) {
    272                                         pid = 0;
    273                                 };
     467                                        inputs[i].checked = false;
    274468
    275                                 $(this).children('input[name=menu-item-parent-id[]]').attr( 'value', pid );
     469                                // we're submitting a search term
     470                                } else if (
     471                                        '' == params['action'] && // give precedence to adding items
     472                                        '' != inputs[i].value &&
     473                                        inputs[i].className &&
     474                                        -1 != inputs[i].className.search(/quick-search\b[^-]/)
     475                                ) {
     476                                        params['action'] = 'menu-quick-search';
     477                                        params['q'] = inputs[i].value;
     478                                        params['response-format'] = 'markup';
     479                                        params['type'] = inputs[i].name;
     480                                        processMethod = that.processQuickSearchQueryResponse;
     481                                }
     482                        }
     483                        params['menu'] = thisForm.elements['menu'].value;
     484                        params['menu-settings-column-nonce'] = thisForm.elements['menu-settings-column-nonce'].value;
    276485
    277                                 // Update the menu item count
    278                                 $('#li-count').attr( 'value', i );
     486                        $.post( ajaxurl, params, function(menuMarkup) {
     487                                processMethod.call(that, menuMarkup, params);   
     488                                thisForm.className = thisForm.className.replace(/processing/g, '');
    279489                        });
     490
     491                        return false;
    280492                },
    281                
    282                 /**
    283                  * Enables autocomplete for nav menu types.
    284                  *
    285                  * @param int id - the id of the menu item type.
    286                  */
    287                 autocomplete : function( id ) {
    288                         $('#add-'+ id +' .quick-search').autocomplete( $( '#add-'+ id +' .autocomplete' ).val().split('|') );
    289493
    290                         $('#add-'+ id +' .quick-search').result(function( event, data, formatted ) {
    291                                 $('#add-'+ id +' .list-wrap').css( 'display', 'block' );
    292                                 $("#add-"+ id +" .list-wrap li:contains('" + data + "')").css( 'display', 'block' );
    293                                 $('#add-'+ id +' .show-all').hide();
    294                                 $('#add-'+ id +' .hide-all').show();
     494                makeListItemDraggable : function(el) {
     495                        // make menu item draggable
     496                        $(el).draggable({
     497                                handle: ' > dl',
     498                                opacity: .8,
     499                                addClasses: false,
     500                                helper: 'clone',
     501                                zIndex: 100
    295502                        });
    296503                },
    297                
     504
    298505                /**
    299                  * Populate the thickbox window with the selected menu items
    300                  *
    301                  * @param int id - the id of the menu item to edit.
     506                 * Add the child element that acts as the dropzone for drag-n-drop.
     507                 *
     508                 * @param object el The parent object to which we'll prepend the dropzone.
     509                 * @return object The dropzone DOM element.
    302510                 */
    303                 edit_menu_item : function( id ) {
    304                         var item_type = $('#menu-item-' + id).children('input[name=menu-item-type[]]').val();
    305                         var item_title = $('#menu-item-' + id).children('input[name=menu-item-title[]]').val();
    306                         var item_link = $('#menu-item-' + id).children('input[name=menu-item-url[]]').val();
    307                         var item_attr_title = $('#menu-item-' + id).children('input[name=menu-item-attr-title[]]').val();
    308                         var item_target = $('#menu-item-' + id).children('input[name=menu-item-target[]]').val();
    309                         var item_description = $('#menu-item-' + id).children('input[name=menu-item-description[]]').val();
    310                         var item_classes = $('#menu-item-' + id).children('input[name=menu-item-classes[]]').val();
    311                         var item_xfn = $('#menu-item-' + id).children('input[name=menu-item-xfn[]]').val();
     511                makeListItemDropzone : function(el) {
     512                        if ( ! el )
     513                                return false;
     514                        var divs = el.getElementsByTagName('div'),
     515                        i = divs.length,
     516                        dropZone = document.createElement('div');
    312517
    313                         // Only allow custom links to be editable.
    314                         if ( 'custom' != item_type )
    315                                 $( '#edit-menu-item-url' ).attr('disabled', 'disabled' );
     518                        while( i-- ) {
     519                                if ( divs[i].className && -1 != divs[i].className.indexOf('dropzone') && ( el == divs[i].parentNode ) )
     520                                        return divs[i];
     521                        }
    316522
    317                         // Populate the fields for thickbox
    318                         $( '#edit-menu-item-id' ).val(id);
    319                         $( '#edit-menu-item-title' ).val(item_title);
    320                         $( '#edit-menu-item-url' ).val(item_link);
    321                         $( '#edit-menu-item-attr-title' ).val(item_attr_title);
    322                         $( '#edit-menu-item-target' ).val(item_target);
    323                         $( "#edit-menu-item-target option[value='" + item_target  + "']" ).attr('selected', 'selected');
    324                         $( '#edit-menu-item-description' ).val(item_description);
    325                         $( '#edit-menu-item-classes' ).val(item_classes);
    326                         $( '#edit-menu-item-xfn' ).val(item_xfn);
     523                        dropZone.className = 'dropzone';
     524                        el.insertBefore(dropZone, el.firstChild);
     525                        return dropZone;
     526                },
    327527
    328                         // @todo: focus on #edit-menu-item-title
    329                 },
    330                
    331528                /**
    332                  * Update the values for the menu item being editing
     529                 * Process the add menu item request response into menu list item.
     530                 *
     531                 * @param string menuMarkup The text server response of menu item markup.
     532                 * @param object req The request arguments.
    333533                 */
    334                 update_menu_item : function() {
    335                         var id = $('#edit-menu-item-id').val();
    336                         var item_title = $('#edit-menu-item-title').val();
    337                         var item_link = $('#edit-menu-item-url').val();
    338                         var item_attr_title = $('#edit-menu-item-attr-title').val();
    339                         var item_target = $('#edit-menu-item-target').val();
    340                         var item_description = $('#edit-menu-item-description').val();
    341                         var item_classes = $('#edit-menu-item-classes').val();
    342                         var item_xfn = $('#edit-menu-item-xfn').val();
     534                processAddMenuItemResponse : function( menuMarkup, req ) {
     535                        if ( ! req )
     536                                req = {};
     537                        var dropZone,
     538                        i,
     539                        listElements,
     540                        wrap = document.createElement('ul');
    343541
    344                         // update menu item settings
    345                         $('.menu #menu-item-' + id).find('span.item-title:first').html(item_title);
     542                        wrap.innerHTML = menuMarkup;
     543                        listElements = wrap.getElementsByTagName('li');
     544                        i = listElements.length;
     545                        while ( i-- ) {
     546                                this.setupListItemDragAndDrop(listElements[i]);
     547                                menuList.appendChild(listElements[i]);
     548                        }
    346549
    347                         $('#menu-item-' + id).children('input[name=menu-item-title[]]').val(item_title);
    348                         $('#menu-item-' + id).children('input[name=menu-item-url[]]').val(item_link);
    349                         $('#menu-item-' + id).children('input[name=menu-item-attr-title[]]').val(item_attr_title);
    350                         $('#menu-item-' + id).children('input[name=menu-item-target[]]').val(item_target);
    351                         $('#menu-item-' + id).children('input[name=menu-item-description[]]').val(item_description);
    352                         $('#menu-item-' + id).children('input[name=menu-item-classes[]]').val(item_classes);
    353                         $('#menu-item-' + id).children('input[name=menu-item-xfn[]]').val(item_xfn);
     550                        /* set custom link form back to defaults */
     551                        if ( customLinkNameInput && customLinkURLInput ) {
     552                                customLinkNameInput.value = customLinkNameDefault;
     553                                customLinkURLInput.value = customLinkURLDefault;
     554                        }
     555                },
    354556
    355                         $('.menu #menu-item-' + id + ' dt:first').animate( { backgroundColor: '#FFFF33' }, { duration: 'normal', complete: function() { $(this).css( 'backgroundColor', '' ); }});
    356                 },
    357                
    358557                /**
    359                  * Removes a menu item from current menu
    360                  *
    361                  * @param int id - the id of the menu item to remove.
     558                 * Process the quick search response into a search result
     559                 *
     560                 * @param string resp The server response to the query.
     561                 * @param object req The request arguments.
    362562                 */
    363                 remove_menu_item : function( id ) {
    364                         var todelete = $('#menu-item-' + id);
     563                processQuickSearchQueryResponse : function(resp, req) {
     564                        if ( ! req )
     565                                req = {};
     566                        var wrap = document.createElement('ul'),
     567                        form = document.getElementById('nav-menu-meta'),
     568                        i,
     569                        items,
     570                        matched,
     571                        newID,
     572                        pattern = new RegExp('menu-item\\[(\[^\\]\]*)'),
     573                        resultList;
    365574
    366                         if ( todelete ) {
    367                                 // Give some feedback to the user
    368                                 $( todelete ).find('dt').each(function(){
    369                                         $(this).animate( { backgroundColor: '#FF3333' }, { duration: 'normal', complete: function() { $(this).parent().parent().remove() } } );
    370                                 });
     575                        // make a unique DB ID number
     576                        matched = pattern.exec(resp);
     577                        if ( matched && matched[1] ) {
     578                                newID = matched[1];
     579                                while( form.elements['menu-item[' + newID + '][menu-item-type]'] ) {
     580                                        newID--;
     581                                }
     582
     583                                if ( newID != matched[1] ) {
     584                                        resp = resp.replace(new RegExp('menu-item\\[' + matched[1] + '\\]', 'g'), 'menu-item[' + newID + ']');
     585                                }
    371586                        }
    372                 },
    373                
    374                 /**
    375                  * Adds the item to the menu
    376                  *
    377                  * @param string item_db_id - The menu item's db id.
    378                  * @param string item_object_id - The menu item's object id.
    379                  * @param string item_object - The menu item's object name.
    380                  * @param string item_type - The menu item's object type.
    381                  * @param string item_append - The menu item's nice name.
    382                  * @param string item_parent_id - The menu item's parent id.
    383                  * @param string item_title - The menu item title.
    384                  * @param string item_url - The menu item url
    385                  * @param string item_description - The menu item description.
    386                  * @param string item_attr_title - The title attribute.
    387                  * @param string item_target - The target attribute.
    388                  * @param string item_classes - Optional. Additional CSS classes for the menu item
    389                  * @param string item_xfn - Optional. The rel attribute.
    390                  */
    391                 add_to_menu : function( item_db_id, item_object_id, item_object, item_type, item_append, item_parent_id, item_title, item_url, item_description, item_attr_title, item_target, item_classes, item_xfn ) {
    392                         var randomnumber = $('.menu li').length + 1;
    393                         var hidden = wpNavMenu.get_hidden_inputs( randomnumber, item_db_id, item_object_id, item_object, item_type, item_parent_id, item_title, item_url, item_description, item_attr_title, item_target, item_classes, item_xfn );
     587
     588                        wrap.innerHTML = resp;
    394589                       
    395                         // Adds the item to the menu
    396                         $('.menu').append('<li id="menu-item-' + randomnumber + '" value="' + randomnumber + '"><div class="dropzone ui-droppable"></div><dl class="ui-droppable"><dt><span class="item-title">' + item_title + '</span><span class="item-controls"><span class="item-type">' + item_append + '</span><a class="item-edit thickbox" id="edit' + randomnumber + '" value="' + randomnumber +'" onclick="wpNavMenu.edit_menu_item('+ randomnumber +');" title="' + navMenuL10n.thickbox + '" href="#TB_inline?height=540&width=300&inlineId=menu-item-settings">' + navMenuL10n.edit + '</a> | <a class="item-delete" id="delete' + randomnumber + '" value="' + randomnumber +'" onclick="wpNavMenu.remove_menu_item('+ randomnumber +');">Delete</a></span></dt></dl>' + hidden + '</li>');
     590                        items = wrap.getElementsByTagName('li');
    397591
    398                         // Give some feedback to the user
    399                         $( '.menu #menu-item-' + randomnumber + ' dt:first' ).animate( { backgroundColor: '#FFFF33' }, { duration: 'normal', complete: function() { $(this).css( 'backgroundColor', '' ); }});
     592                        if ( items[0] && req.object_type ) {
     593                                resultList = document.getElementById(req.object_type + '-search-checklist');
     594                                if ( resultList ) {
     595                                        resultList.appendChild(items[0]);
     596                                }
     597                        } else if ( req.type ) {
     598                                matched = /quick-search-posttype-([a-zA-Z_-]*)/.exec(req.type);
     599                                if ( matched && matched[1] ) {
     600                                        resultList = document.getElementById(matched[1] + '-search-checklist');
     601                                        if ( resultList ) {
     602                                                i = items.length;
     603                                                while( i-- ) {
     604                                                        resultList.appendChild(items[i]);
     605                                                }
     606                                        }
     607                                }
     608                        }
     609                },
    400610
    401                         // Enable drag-n-drop
    402                         wpNavMenu.drag_and_drop();
     611                recalculateSortOrder : function(parentEl) {
     612                        var allInputs = parentEl.getElementsByTagName('input'),
     613                        i,
     614                        j = 0;
    403615
    404                         // Reload thickbox
    405                         tb_init('a.thickbox, area.thickbox, input.thickbox');
     616                        for( i = 0; i < allInputs.length; i++ ) {
     617                                if ( allInputs[i].name && -1 != allInputs[i].name.indexOf('menu-item-position') ) {
     618                                        allInputs[i].value = ++j;
     619                                }
     620                        }
    406621                },
    407                
    408                 /**
    409                  * Grabs items from the queue and adds them to the menu.
    410                  *
    411                  * @param string button - a reference to the button that was clicked
    412                  */
    413                 add_checked_items_to_menu : function( button ) {
    414                         // Grab checked items
    415                         var items = $(button).parent().siblings('.list-wrap').find(':checked');
    416622
    417                         // If nothing was checked, cancel
    418                         if ( 0 == items.length )
     623                removeMenuItem : function(el) {
     624                        if ( ! el )
    419625                                return false;
    420626
    421                         // Loop through each item, grab it's hidden data and add it to the menu.
    422                         $(items).each(function(){
    423                                 var item_type = $(this).parent().siblings('.menu-item-type').val();
     627                        var subMenus = el.getElementsByTagName('ul'),
     628                        subs,
     629                        i;
    424630
    425                                 if ( 'custom' == item_type ) {
    426                                         var item_attr_title = $(this).parent().siblings('.menu-item-attr-title').val();
    427                                         var item_target = $(this).parent().siblings('.menu-item-target').val();
    428                                         var item_classes = $(this).parent().siblings('.menu-item-classes').val();
    429                                         var item_xfn = $(this).parent().siblings('.menu-item-xfn').val();
    430                                 } else {
    431                                         var item_attr_title = '';
    432                                         var item_target = '';
    433                                         var item_classes = '';
    434                                         var item_xfn = '';
    435                                 };
     631                        if ( subMenus[0] ) {
     632                                subs = subMenus[0].getElementsByTagName('li');
     633                                for ( i = 0; i < subs.length; i++ ) {
     634                                        if ( subs[i].id && -1 != subs[i].id.indexOf('menu-item-') && subs[i].parentNode == subMenus[0] ) {
     635                                                el.parentNode.insertBefore(subs[i], el);
     636                                        }
     637                                }
     638                        }
    436639
    437                                 var item_db_id = $(this).parent().siblings('.menu-item-db-id').val();
    438                                 var item_object_id = $(this).parent().siblings('.menu-item-object-id').val();
    439                                 var item_object = $(this).parent().siblings('.menu-item-object').val();
    440                                 var item_append = $(this).parent().siblings('.menu-item-append').val();
    441                                 var item_parent_id = $(this).parent().siblings('.menu-item-parent-id').val();
    442                                 var item_title = $(this).parent().siblings('.menu-item-title').val();
    443                                 var item_url = $(this).parent().siblings('.menu-item-url').val();
    444                                 var item_description = $(this).parent().siblings('.menu-item-description').val();
    445 
    446                                 if ( undefined == item_description ) {
    447                                         item_description = '';
    448                                 };
    449 
    450                                 if ( undefined == item_attr_title ) {
    451                                         item_attr_title = '';
    452                                 };
    453 
    454                                 // Add the menu item to the menu
    455                                 wpNavMenu.add_to_menu( item_db_id, item_object_id, item_object, item_type, item_append, item_parent_id, item_title, item_url, item_description, item_attr_title, item_target, item_classes, item_xfn );
    456 
    457                                 // uncheck the menu item in the list
    458                                 $(this).attr( 'checked', false );
     640                        el.className += ' deleting';
     641                        $(el).fadeOut( 350 , function() {
     642                                this.parentNode.removeChild(this);     
    459643                        });
    460                 },
    461                
    462                 /**
    463                  * Returns all the nessecary hidden inputs for each menu item.
    464                  *
    465                  * @param string item_db_id - The menu item's db id.
    466                  * @param string item_object_id - The menu item's object id.
    467                  * @param string item_object - The menu item's object name.
    468                  * @param string item_type - The menu item's object type.
    469                  * @param string item_append - The menu item's nice name.
    470                  * @param string item_parent_id - The menu item's parent id.
    471                  * @param string item_title - The menu item title.
    472                  * @param string item_url - The menu item url
    473                  * @param string item_description - The menu item description.
    474                  * @param string item_attr_title - The title attribute.
    475                  * @param string item_target - The target attribute.
    476                  * @param string item_classes - Optional. Additional CSS classes for the menu item
    477                  * @param string item_xfn - Optional. The rel attribute.
    478                  */
    479                 get_hidden_inputs : function( randomnumber, item_db_id, item_object_id, item_object, item_type, item_parent_id, item_title, item_url, item_description, item_attr_title, item_target, item_classes, item_xfn ) {
    480                         var hidden = '';
     644                       
     645                        this.recalculateSortOrder(menuList);
     646                }
     647        }
     648}
    481649
    482                         hidden += '<input type="hidden" name="menu-item-db-id[]" value="' + item_db_id + '" />';
    483                         hidden += '<input type="hidden" name="menu-item-object-id[]" value="' + item_object_id + '" />';
    484                         hidden += '<input type="hidden" name="menu-item-object[]" value="' + item_object + '" />';
    485                         hidden += '<input type="hidden" name="menu-item-type[]" value="' + item_type + '" />';
    486                         hidden += '<input type="hidden" name="menu-item-parent-id[]" value="' + item_parent_id + '" />';
    487                         hidden += '<input type="hidden" name="menu-item-position[]" value="' + randomnumber + '" />';
    488                         hidden += '<input type="hidden" name="menu-item-title[]" value="' + item_title + '" />';
    489                         hidden += '<input type="hidden" name="menu-item-attr-title[]" value="' + item_attr_title + '" />';
    490                         hidden += '<input type="hidden" name="menu-item-url[]" value="' + item_url + '" />';
    491                         hidden += '<input type="hidden" name="menu-item-target[]" value="' + item_target + '" />';
    492                         hidden += '<input type="hidden" name="menu-item-description[]" value="' + item_description + '" />';
    493                         hidden += '<input type="hidden" name="menu-item-classes[]" value="' + item_classes + '" />';
    494                         hidden += '<input type="hidden" name="menu-item-xfn[]" value="' + item_xfn + '" />';
     650var wpNavMenu = new WPNavMenuHandler();
    495651
    496                         return hidden;
    497                 }
    498         }
    499        
    500         $(document).ready(function($){ wpNavMenu.init(); });
    501 })(jQuery);
    502  No newline at end of file
     652jQuery(function() {
     653        wpNavMenu.init();
     654});
  • wp-admin/nav-menus.php

     
    1010 */
    1111
    1212/** Load WordPress Administration Bootstrap */
    13 require_once( './admin.php' );
     13require_once( 'admin.php' );
    1414
    1515// Load all the nav menu interface functions
    1616require_once( ABSPATH . 'wp-admin/includes/nav-menu.php' );
     
    3737wp_enqueue_script( 'wp-lists' );
    3838wp_enqueue_script( 'postbox' );
    3939
    40 // Thickbox
    41 add_thickbox();
    42 
    4340// Container for any messages displayed to the user
    4441$messages_div = '';
    4542
     
    5350$action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : 'edit';
    5451
    5552switch ( $action ) {
     53        case 'add-menu-item':
     54                if ( current_user_can( 'switch_themes' ) ) {
     55                        check_admin_referer( 'add-menu_item', 'menu-settings-column-nonce' );
     56                        if ( isset( $_REQUEST['menu-item'] ) ) {
     57                                wp_save_nav_menu_item( $nav_menu_selected_id, $_REQUEST['menu-item'] );
     58                        }
     59                }
     60                break;
     61        case 'move-down-menu-item' :
     62                // moving down a menu item is the same as moving up the next in order
     63                check_admin_referer( 'move-menu_item' );
     64                $menu_item_id = (int) $_REQUEST['menu-item'];
     65                $next_item_id = 0;
     66                if ( 'nav_menu_item' == get_post_type( $menu_item_id ) ) {
     67                        $menus = isset( $_REQUEST['menu'] ) ? array( (int) $_REQUEST['menu'] ) : wp_get_object_terms( $menu_item_id, 'nav_menu', array( 'fields' => 'ids' ) );
     68                        if ( ! is_wp_error( $menus ) ) {
     69                                foreach( (array) $menus as $menu_id ) {
     70                                        $move_down_ordered_menu_items = (array) wp_get_nav_menu_items( $menu_id );
     71                                        while ( $next = array_shift( $move_down_ordered_menu_items ) ) {
     72                                                if ( isset( $next->ID ) && $next->ID == $menu_item_id ) {
     73                                                        break;
     74                                                }
     75                                        }
     76
     77                                        if ( $following = array_shift( $move_down_ordered_menu_items ) ) {
     78                                                $next_item_id = (int) $following->ID;
     79                                        }
     80                                }
     81                        }
     82                }
     83                // fall through to next case
     84        case 'move-up-menu-item' :
     85                check_admin_referer( 'move-menu_item' );
     86                $menu_item_id = empty( $next_item_id ) ? (int) $_REQUEST['menu-item'] : $next_item_id;
     87                if ( 'nav_menu_item' == get_post_type( $menu_item_id ) ) {
     88                        $menus = isset( $_REQUEST['menu'] ) ? array( (int) $_REQUEST['menu'] ) : wp_get_object_terms( $menu_item_id, 'nav_menu', array( 'fields' => 'ids' ) );
     89                        if ( ! is_wp_error( $menus ) ) {
     90                                foreach( (array) $menus as $menu_id ) {
     91                                        $ordered_menu_items = wp_get_nav_menu_items( $menu_id );
     92                                        $menu_item_data = get_post( $menu_item_id , ARRAY_A );
     93
     94                                        // setup the data we need in one pass through the array of menu items
     95                                        $dbids_to_orders = array();
     96                                        $orders_to_dbids = array();
     97                                        $objectids_to_dbids = array();
     98                                        $dbids_to_objectids = array();
     99                                        foreach( (array) $ordered_menu_items as $ordered_menu_item_object ) {
     100                                                if ( isset( $ordered_menu_item_object->ID ) ) {
     101                                                        if ( isset( $ordered_menu_item_object->menu_order ) ) {
     102                                                                $dbids_to_orders[$ordered_menu_item_object->ID] = $ordered_menu_item_object->menu_order;
     103                                                                $orders_to_dbids[$ordered_menu_item_object->menu_order] = $ordered_menu_item_object->ID;
     104                                                        }
     105
     106                                                        $possible_object_id = (int) get_post_meta( $ordered_menu_item_object->ID, '_menu_item_object_id', true );
     107                                                        if ( ! empty( $possible_object_id ) ) {
     108                                                                $dbids_to_objectids[$ordered_menu_item_object->ID] = $possible_object_id;
     109                                                                $objectids_to_dbids[$possible_object_id] = $ordered_menu_item_object->ID;
     110                                                        }
     111                                                }
     112                                        }
     113
     114
     115                                        // if this menu item is not first
     116                                        if ( ! empty( $dbids_to_orders[$menu_item_id] ) && ! empty( $orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1] ) ) {
     117                                               
     118                                                // if this menu item is a child of the previous
     119                                                if (
     120                                                        ! empty( $menu_item_data['post_parent'] ) &&
     121                                                        isset( $objectids_to_dbids[$menu_item_data['post_parent']] ) &&
     122                                                        isset( $orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1] ) &&
     123                                                        ( $objectids_to_dbids[$menu_item_data['post_parent']] == $orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1] )
     124                                                ) {
     125
     126                                                        $parent_db_id = $objectids_to_dbids[$menu_item_data['post_parent']];
     127                                                        $parent_data = get_post( $parent_db_id, ARRAY_A );
     128
     129                                                        if ( ! is_wp_error( $parent_data ) ) {
     130                                                               
     131                                                                // if there is something before the parent, make menu item a child of the parent's parent
     132                                                                if ( ! empty( $dbids_to_orders[$parent_db_id] ) && ! empty( $orders_to_dbids[$dbids_to_orders[$parent_db_id] - 1] ) ) {
     133                                                                        $menu_item_data['post_parent'] = $parent_data['post_parent'];
     134
     135                                                                // else there isn't something before the parent
     136                                                                } else {
     137                                                                        $menu_item_data['post_parent'] = 0;
     138                                                                }
     139                                                               
     140                                                                // set former parent's [menu_order] to that of menu-item's
     141                                                                $parent_data['menu_order'] = $parent_data['menu_order'] + 1;
     142
     143                                                                // set menu-item's [menu_order] to that of former parent
     144                                                                $menu_item_data['menu_order'] = $menu_item_data['menu_order'] - 1;
     145                                                               
     146                                                                // save changes
     147                                                                wp_update_post($menu_item_data);
     148                                                                wp_update_post($parent_data);
     149                                                        }
     150
     151                                                // else this menu item is not a child of the previous
     152                                                } elseif ( isset($dbids_to_objectids[$orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1]] ) ) {
     153                                                        // just make it a child of the previous; keep the order
     154                                                        $menu_item_data['post_parent'] = (int) $dbids_to_objectids[$orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1]];
     155                                                        wp_update_post($menu_item_data);
     156                                                }
     157                                        }
     158                                }
     159                        }
     160                }
     161                break;
     162
     163        case 'delete-menu-item':
     164                $menu_item_id = (int) $_REQUEST['menu-item'];
     165
     166                check_admin_referer( 'delete-menu_item_' . $menu_item_id );
     167
     168
     169                if ( 'nav_menu_item' == get_post_type( $menu_item_id ) ) {
     170                        if ( wp_delete_post( $menu_item_id, true ) ) {
     171                               
     172                                $messages_div = '<div id="message" class="updated"><p>' . __('The menu item has been successfully deleted.') . '</p></div>';
     173                        }
     174                }
     175                break;
    56176        case 'delete':
    57177                check_admin_referer( 'delete-nav_menu-' . $nav_menu_selected_id );
    58178
    59                 if ( is_nav_menu($nav_menu_selected_id) ) {
     179                if ( is_nav_menu( $nav_menu_selected_id ) ) {
    60180                        $delete_nav_menu = wp_delete_nav_menu( $nav_menu_selected_id );
    61181
    62182                        if ( is_wp_error($delete_nav_menu) ) {
     
    70190                break;
    71191
    72192        case 'update':
    73                 check_admin_referer( 'update-nav_menu' );
     193                check_admin_referer( 'update-nav_menu', 'update-nav-menu-nonce' );
    74194
    75195                // Add Menu
    76                 if ( isset($_POST['create-menu-button']) ) {
     196                if ( 0 == $nav_menu_selected_id ) {
    77197                        if ( current_theme_supports('nav-menus') || current_theme_supports('widgets') ) {
    78                                 $add_nav_menu = esc_html( $_POST['create-menu-name'] );
     198                                $new_menu_title = esc_html( $_POST['menu-name'] );
    79199
    80                                 if ( $add_nav_menu ) {
    81                                         $add_nav_menu = wp_create_nav_menu( $add_nav_menu );
     200                                if ( $new_menu_title ) {
     201                                        $_nav_menu_selected_id = wp_update_nav_menu_object( 0, array('menu-name' => $new_menu_title) );
    82202
    83                                         if ( is_wp_error( $add_nav_menu ) ) {
    84                                                 $messages_div = '<div id="message" class="error"><p>' . $add_nav_menu->get_error_message() . '</p></div>';
     203                                        if ( is_wp_error( $_nav_menu_selected_id ) ) {
     204                                                $messages_div = '<div id="message" class="error"><p>' . $_nav_menu_selected_id->get_error_message() . '</p></div>';
    85205                                        } else {
    86                                                 $nav_menu_selected_id = $add_nav_menu->term_id;
    87                                                 $nav_menu_selected_title = $add_nav_menu->name;
    88                                                 $messages_div = '<div id="message" class="updated"><p>' . sprintf( __('The <strong>%s</strong> menu has been successfully created.'), $add_nav_menu->name ) . '</p></div>';
     206                                                $_menu_object = wp_get_nav_menu_object( $_nav_menu_selected_id );
     207                                                $nav_menu_selected_id = $_nav_menu_selected_id;
     208                                                $nav_menu_selected_title = $_menu_object->name;
     209                                                $messages_div = '<div id="message" class="updated"><p>' . sprintf( __('The <strong>%s</strong> menu has been successfully created.'), $nav_menu_selected_title ) . '</p></div>';
    89210                                        }
    90211                                } else {
    91212                                        $messages_div = '<div id="message" class="error"><p>' . __('Please enter a valid menu name.') . '</p></div>';
    92213                                }
    93                                 unset( $add_nav_menu );
    94214                        }
     215
     216                // update existing menu
    95217                } else {
    96218
    97                         // @todo wrap this into wp_update_nav_menu_object();
    98                         if ( isset($_POST['menu-name']) ) {
    99                                 $old_nav_menu = get_term( $nav_menu_selected_id, 'nav_menu', ARRAY_A );
    100                                 $args = array( 'name' => $_POST['menu-name'], 'slug' => null, 'description' => $old_nav_menu['description'], 'parent' => $old_nav_menu['parent'], );
    101                                 $new_nav_menu = wp_update_term( $nav_menu_selected_id, 'nav_menu', $args );
     219                        $_menu_object = wp_get_nav_menu_object( $nav_menu_selected_id );
     220
     221                        if ( ! is_wp_error( $_menu_object ) ) {
     222                                wp_update_nav_menu_object( $nav_menu_selected_id, array( 'menu-name' => $_POST['menu-name'] ) );
     223                                $nav_menu_selected_title = $_menu_object->name;
    102224                        }
    103225
    104226                        // Update menu items
    105227
    106                         // @todo: wrap update logic into wp_update_nav_menu();
    107                         $update_count = isset( $_POST['li-count'] ) ? (int) $_POST['li-count'] : 0;
    108                         $update_nav_menu = is_nav_menu( $nav_menu_selected_id );
    109 
    110                         if ( !is_wp_error($update_nav_menu) ) {
     228                        if ( ! is_wp_error( $_menu_object ) ) {
    111229                                $menu_items = wp_get_nav_menu_items( $nav_menu_selected_id, array('orderby' => 'ID', 'output' => ARRAY_A, 'output_key' => 'ID') );
    112230
    113                                 // Loop through all POST variables
    114                                 for ( $k = 0; $k < $update_count; $k++ ) {
     231                                // Loop through all the menu items' POST variables
     232                                foreach( (array) $_POST['menu-item-db-id'] as $_key => $k ) {
    115233
    116234                                        // Menu item title can't be blank
    117                                         if ( '' == $_POST['menu-item-title'][$k] )
     235                                        if ( '' == $_POST['menu-item-title'][$_key] )
    118236                                                continue;
    119 
    120                                         $menu_item_db_id       = isset( $_POST['menu-item-db-id'][$k] )       ? $_POST['menu-item-db-id'][$k]       : 0;
    121                                         $menu_item_object_id   = isset( $_POST['menu-item-object-id'][$k] )   ? $_POST['menu-item-object-id'][$k]   : 0;
    122                                         $menu_item_object      = isset( $_POST['menu-item-object'][$k] )      ? $_POST['menu-item-object'][$k]      : '';
    123                                         $menu_item_parent_id   = isset( $_POST['menu-item-parent-id'][$k] )   ? $_POST['menu-item-parent-id'][$k]   : 0;
    124                                         $menu_item_position    = isset( $_POST['menu-item-position'][$k] )    ? $_POST['menu-item-position'][$k]    : 0;
    125                                         $menu_item_type        = isset( $_POST['menu-item-type'][$k] )        ? $_POST['menu-item-type'][$k]        : 'custom';
    126                                         $menu_item_append      = isset( $_POST['menu-item-append'][$k] )      ? $_POST['menu-item-append'][$k]      : 'custom';
    127                                         $menu_item_title       = isset( $_POST['menu-item-title'][$k] )       ? $_POST['menu-item-title'][$k]       : '';
    128                                         $menu_item_url         = isset( $_POST['menu-item-url'][$k] )         ? $_POST['menu-item-url'][$k]         : '';
    129                                         $menu_item_description = isset( $_POST['menu-item-description'][$k] ) ? $_POST['menu-item-description'][$k] : '';
    130                                         $menu_item_attr_title  = isset( $_POST['menu-item-attr-title'][$k] )  ? $_POST['menu-item-attr-title'][$k]  : '';
    131                                         $menu_item_target      = isset( $_POST['menu-item-target'][$k] )      ? $_POST['menu-item-target'][$k]      : '';
    132                                         $menu_item_classes     = isset( $_POST['menu-item-classes'][$k] )     ? $_POST['menu-item-classes'][$k]     : '';
    133                                         $menu_item_xfn         = isset( $_POST['menu-item-xfn'][$k] )         ? $_POST['menu-item-xfn'][$k]         : '';
    134 
    135                                         // Populate the menu item object
    136                                         $post = array(
    137                                                 'post_status' => 'publish', 'post_type' => 'nav_menu_item', 'ping_status' => 0,
    138                                                 'post_author' => $user_ID, 'tax_input' => array( 'nav_menu' => $update_nav_menu->name ),
    139                                                 'post_title' => $menu_item_title, 'post_excerpt' => $menu_item_attr_title,
    140                                                 'post_parent' => $menu_item_parent_id, 'menu_order' => $menu_item_position,
    141                                                 'post_content' => $menu_item_description,
     237       
     238                                        $args = array(
     239                                                'menu-item-db-id' => $_POST['menu-item-db-id'][$_key],
     240                                                'menu-item-object-id' => $_POST['menu-item-object-id'][$_key],
     241                                                'menu-item-object' => $_POST['menu-item-object'][$_key],
     242                                                'menu-item-parent-id' => $_POST['menu-item-parent-id'][$_key],
     243                                                'menu-item-position' => $_POST['menu-item-position'][$_key],
     244                                                'menu-item-type' => $_POST['menu-item-type'][$_key],
     245                                                'menu-item-append' => $_POST['menu-item-append'][$_key],
     246                                                'menu-item-title' => $_POST['menu-item-title'][$_key],
     247                                                'menu-item-url' => $_POST['menu-item-url'][$_key],
     248                                                'menu-item-description' => $_POST['menu-item-description'][$_key],
     249                                                'menu-item-attr-title' => $_POST['menu-item-attr-title'][$_key],
     250                                                'menu-item-target' => $_POST['menu-item-target'][$_key],
     251                                                'menu-item-classes' => $_POST['menu-item-classes'][$_key],
     252                                                'menu-item-xfn' => $_POST['menu-item-xfn'][$_key],
    142253                                        );
    143254
    144                                         // New menu item
    145                                         if ( $menu_item_db_id == 0 ) {
    146                                                 $menu_item_db_id = wp_insert_post( $post );
     255                                        $menu_item_db_id = wp_update_nav_menu_item( $nav_menu_selected_id, ( $_POST['menu-item-db-id'][$_key] != $_key ? 0 : $_key ), $args );
    147256
    148                                         // Update existing menu item
    149                                         } elseif ( isset($menu_items[$menu_item_db_id]) || ( 'custom' == $menu_item_type && 0 != $menu_item_db_id ) ) {
    150                                                 $post['ID'] = $menu_item_db_id;
    151                                                 wp_update_post( $post );
     257                                        if ( ! is_wp_error( $menu_item_db_id ) && isset( $menu_items[$menu_item_db_id] ) ) {
    152258                                                unset( $menu_items[$menu_item_db_id] );
    153259                                        }
    154 
    155                                         update_post_meta( $menu_item_db_id, '_menu_item_type', sanitize_key($menu_item_type) );
    156                                         update_post_meta( $menu_item_db_id, '_menu_item_object_id', (int) $menu_item_object_id );
    157                                         update_post_meta( $menu_item_db_id, '_menu_item_object', sanitize_key($menu_item_object) );
    158                                         update_post_meta( $menu_item_db_id, '_menu_item_target', sanitize_key($menu_item_target) );
    159                                         // @todo handle sanitizing multiple classes separated by whitespace.
    160                                         update_post_meta( $menu_item_db_id, '_menu_item_classes', sanitize_html_class($menu_item_classes) );
    161                                         update_post_meta( $menu_item_db_id, '_menu_item_xfn', sanitize_html_class($menu_item_xfn) );
    162 
    163                                         // @todo: only save custom link urls.
    164                                         update_post_meta( $menu_item_db_id, '_menu_item_url', esc_url_raw($menu_item_url) );
    165260                                }
    166261
    167262                                // Remove menu items from the menu that weren't in $_POST
     
    173268
    174269                                do_action( 'wp_update_nav_menu', $nav_menu_selected_id );
    175270
    176                                 $messages_div = '<div id="message" class="updated"><p>' . sprintf( __('The <strong>%s</strong> menu has been updated.'), $update_nav_menu->name ) . '</p></div>';
    177                                 unset( $update_nav_menu, $update_count, $menu_items );
     271                                $messages_div = '<div id="message" class="updated"><p>' . sprintf( __('The <strong>%s</strong> menu has been updated.'), $nav_menu_selected_title ) . '</p></div>';
     272                                unset( $menu_items );
    178273                        }
    179274                }
    180275                break;
     
    184279$nav_menus = wp_get_nav_menus();
    185280
    186281// Get recently edited nav menu
    187 $recently_edited = get_user_option( 'nav_menu_recently_edited' );
     282$recently_edited = (int) get_user_option( 'nav_menu_recently_edited' );
    188283
    189284// If there was no recently edited menu, and $nav_menu_selected_id is a nav menu, update recently edited menu.
    190 if ( !$recently_edited && is_nav_menu($nav_menu_selected_id) ) {
     285if ( !$recently_edited && is_nav_menu( $nav_menu_selected_id ) ) {
    191286        $recently_edited = $nav_menu_selected_id;
    192287
    193 // Else if $nav_menu_selected_id is not a menu, but $recently_edited is, grab that one.
    194 } elseif ( 0 == $nav_menu_selected_id && is_nav_menu($recently_edited) ) {
     288// 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.
     289} elseif ( 0 == $nav_menu_selected_id && ! isset( $_REQUEST['menu'] ) && is_nav_menu( $recently_edited ) ) {
    195290        $nav_menu_selected_id = $recently_edited;
    196291
    197292// Else try to grab the first menu from the menus list
    198 } elseif ( 0 == $nav_menu_selected_id && ! empty($nav_menus) ) {
     293} elseif ( 0 == $nav_menu_selected_id && ! isset( $_REQUEST['menu'] ) && ! empty($nav_menus) ) {
    199294        $nav_menu_selected_id = $nav_menus[0]->term_id;
    200295}
    201296
    202297// Update the user's setting
    203 if ( $nav_menu_selected_id != $recently_edited && is_nav_menu($nav_menu_selected_id) )
     298if ( $nav_menu_selected_id != $recently_edited && is_nav_menu( $nav_menu_selected_id ) )
    204299        update_user_meta( $current_user->ID, 'nav_menu_recently_edited', $nav_menu_selected_id );
    205300
    206 // If there's a menu, get it's name.
    207 if ( !$nav_menu_selected_title && $nav_menu_selected_title = is_nav_menu( $nav_menu_selected_id ) ) {
    208         $nav_menu_selected_title = $nav_menu_selected_title->name;
     301// If there's a menu, get its name.
     302if ( ! $nav_menu_selected_title && is_nav_menu( $nav_menu_selected_id ) ) {
     303        $_menu_object = wp_get_nav_menu_object( $nav_menu_selected_id );
     304        $nav_menu_selected_title = ! is_wp_error( $_menu_object ) ? $_menu_object->name : '';
    209305}
    210306
    211 // Create Menu Metabox
    212 add_meta_box( 'create-menu', __('Create Menu'), 'wp_nav_menu_create_metabox', 'nav-menus', 'side', 'core' );
    213 
    214 // The user has no menus.
    215 if ( !is_nav_menu( $nav_menu_selected_id ) ) {
    216         $messages_div = '<div id="message" class="updated"><p>' . __('You do not have any menus. Create a new menu.') . '</p></div>';
    217 
    218307// The theme supports menus
    219 } elseif ( current_theme_supports('nav-menus') ) {
     308if ( current_theme_supports('nav-menus') ) {
    220309        // Register nav menu metaboxes
    221         add_meta_box( 'manage-menu', __( 'Menu Settings' ), 'wp_nav_menu_manage_menu_metabox', 'nav-menus', 'side', 'high', array( $nav_menu_selected_id, $nav_menu_selected_title ) );
    222         wp_nav_menu_metaboxes_setup();
     310        wp_nav_menu_meta_boxes_setup();
    223311
    224312// The theme does not support menus but supports widgets
    225313} elseif ( current_theme_supports('widgets') ) {
    226314        // Register nav menu metaboxes
    227         add_meta_box( 'manage-menu', __( 'Menu Settings' ), 'wp_nav_menu_manage_menu_metabox', 'nav-menus', 'side', 'high', array( $nav_menu_selected_id, $nav_menu_selected_title ) );
    228         wp_nav_menu_metaboxes_setup();
     315        wp_nav_menu_meta_boxes_setup();
    229316        $messages_div = '<div id="message" class="error"><p>' . __('The current theme does not natively support menus, but you can use the &#8220;Navigation Menu&#8221; widget to add any menus you create here to the theme&#8217;s sidebar.') . '</p></div>';
    230317
    231318// The theme supports neither menus nor widgets.
     
    235322}
    236323
    237324// Get the admin header
    238 require_once( './admin-header.php' );
     325require_once( 'admin-header.php' );
    239326?>
    240 <div class="wrap">
     327<div class="wrap nav-edit-wrap">
    241328        <?php screen_icon(); ?>
    242329        <h2><?php esc_html_e('Menus'); ?></h2>
    243         <?php /* OMGWTFBBQ */ ?><div class="error"><p><strong><?php _e('Beta Testers:') ?></strong> <?php _e('This feature is still under construction. You can try it out, but expect it to change in layout and functionality in the second beta release.'); ?></p></div>
    244330        <?php echo $messages_div; ?>
    245         <div class="hide-if-js error"><p><?php _e('You do not have JavaScript enabled in your browser. Please enable it to access the Menus functionality.'); ?></p></div>
     331       
     332        <?php if ( current_theme_supports('nav-menus') || current_theme_supports('widgets') ) : ?>
     333        <div id="menu-settings-column" class="metabox-holder">
    246334
    247         <?php if ( !empty($nav_menus) && count($nav_menus) > 1 && ( current_theme_supports('nav-menus') || current_theme_supports('widgets') ) ) : ?>
    248         <ul class="subsubsub">
    249                 <?php
    250                         foreach ( $nav_menus as $_nav_menu ) {
    251                                 $sep = end( $nav_menus ) == $_nav_menu ? '' : ' | ';
     335                <form id="nav-menu-meta" action="<?php echo admin_url( 'nav-menus.php' ); ?>" class="nav-menu-meta" method="post" enctype="multipart/form-data">
     336                        <input type="hidden" name="menu" id="nav-menu-meta-object-id" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" />
     337                        <input type="hidden" name="action" value="add-menu-item" />
     338                        <?php wp_nonce_field( 'add-menu_item', 'menu-settings-column-nonce' ); ?>
     339                        <?php do_meta_boxes( 'nav-menus', 'side', null ); ?>
     340                </form>
    252341
    253                                 if ( $nav_menu_selected_id == $_nav_menu->term_id )
    254                                         echo '<li><a href="'. admin_url( 'nav-menus.php?action=edit&amp;menu=' . esc_attr($_nav_menu->term_id) ) .'" class="current">'. esc_html( $_nav_menu->name ) .'</a>'. $sep .'</li>';
    255                                 else
    256                                         echo '<li><a href="'. admin_url( 'nav-menus.php?action=edit&amp;menu=' . esc_attr($_nav_menu->term_id) ) .'">'. esc_html( $_nav_menu->name ) .'</a>'. $sep .'</li>';
    257                         }
    258                 ?>
    259         </ul>
    260         <?php endif; ?>
     342        </div><!-- /#menu-settings-column -->
     343       
     344        <div id="menu-management" class="">
     345                <h2>
     346                        <?php
     347                        foreach( (array) $nav_menus as $_nav_menu ) :
     348                               
     349                                ?>
     350                                <a href="<?php
     351                                        echo add_query_arg(
     352                                                array(
     353                                                        'action' => 'edit',
     354                                                        'menu' => $_nav_menu->term_id,
     355                                                ),
     356                                                admin_url( 'nav-menus.php' )
     357                                        );
     358                                ?>" class="menu-tabs<?php
     359                                        if ( $nav_menu_selected_id != $_nav_menu->term_id )
     360                                                echo ' menu-tab-inactive';
     361                                ?>"><?php echo esc_html( $_nav_menu->name ); ?></a>
    261362
    262         <div id="menu-management" class="metabox-holder has-right-sidebar">
    263                 <form id="update-nav-menu" action="<?php echo admin_url( 'nav-menus.php' ); ?>" method="post" enctype="multipart/form-data">
    264                         <?php wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?>
    265                         <?php wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); ?>
    266                         <?php wp_nonce_field( 'update-nav_menu' ); ?>
    267                         <input type="hidden" name="action" value="update" />
    268                         <input type="hidden" name="li-count" id="li-count" value="-1" />
    269                         <input type="hidden" name="menu" id="menu" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" />
    270                         <input type="hidden" id="hidden-metaboxes" value="<?php echo wp_initial_nav_menu_meta_boxes(); ?>" />
    271                         <div id="post-body">
    272                                 <div id="post-body-content">
    273                                         <?php if ( is_nav_menu($nav_menu_selected_id) && ( current_theme_supports('nav-menus') || current_theme_supports('widgets') ) ) : ?>
    274                                                 <div id="menu-container" class="postbox">
    275                                                         <h3 class="hndle"><?php echo esc_html( $nav_menu_selected_title ); ?></h3>
    276                                                         <div class="inside">
    277                                                                 <?php wp_nav_menu( array( 'menu' => $nav_menu_selected_id, 'context' => 'backend' ) ); ?>
    278                                                         </div><!-- /.inside -->
    279                                                 <!-- /#nav-menu-canvas .postbox-->
    280                                                 </div>
    281                                         <?php endif; ?>
    282                                 </div><!-- /#post-body-content-->
    283                         </div><!--- /#post-body -->
    284                         <div id="menu-settings-column" class="inner-sidebar">
     363                                <?php
     364                        endforeach;
     365                        ?>
     366                        <a href="<?php
     367                                echo add_query_arg(
     368                                        array(
     369                                                'action' => 'edit',
     370                                                'menu' => 0,
     371                                        ),
     372                                        admin_url( 'nav-menus.php' )
     373                                );
     374                        ?>" class="menu-tabs menu-add-new<?php
     375                                if ( 0 != $nav_menu_selected_id )
     376                                        echo ' menu-tab-inactive';
     377                        ?>"><?php printf( '<abbr title="%s">+</abbr>', esc_html__( 'Add menu' ) ); ?></a>
     378                </h2>
     379                <div class="menu-edit">
     380                        <form id="update-nav-menu" action="<?php echo admin_url( 'nav-menus.php' ); ?>" method="post" enctype="multipart/form-data">
     381                                <div id="submitpost" class="submitbox">
     382                                        <div id="minor-publishing">
     383                                                <div class="misc-pub-section misc-pub-section-last">
     384                                                        <label class="howto" for="menu-name">
     385                                                                <span><?php _e('Name'); ?></span>
     386                                                                <input id="menu-name" name="menu-name" type="text" class="regular-text menu-item-textbox" value="<?php echo esc_attr( $nav_menu_selected_title  ); ?>" />
     387                                                                <br class="clear" />
     388                                                        </label>
     389                                                </div><!--END .misc-pub-section misc-pub-section-last-->
     390                                                <br class="clear" />
     391                                        </div><!--END #misc-publishing-actions-->
     392                                        <div id="major-publishing-actions">
    285393
    286                                 <?php do_meta_boxes( 'nav-menus', 'side', null ); ?>
     394                                                <?php if ( ! empty( $nav_menu_selected_id ) ) : ?>
     395                                                <div id="delete-action">
     396                                                        <a class="submitdelete deletion menu-delete" href="<?php echo 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>
     397                                                </div><!--END #delete-action-->
     398                                                <?php endif; ?>
    287399
    288                         </div><!-- /#menu-settings-column -->
    289                 </form><!--/#update-nav-menu-->
    290                 <br class="clear" />
    291         </div><!-- /.metabox-holder has-right-sidebar-->
     400                                                <div id="publishing-action">
     401                                                        <input class="button-primary" name="save_menu" type="submit" value="<?php esc_attr_e('Save Menu'); ?>" />
     402                                                </div><!--END #publishing-action-->
     403                                                <br class="clear" />
     404                                        </div><!--END #major-publishing-actions-->
     405                                </div><!--END #submitpost .submitbox-->
     406                                <?php wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?>
     407                                <?php wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); ?>
     408                                <?php wp_nonce_field( 'update-nav_menu', 'update-nav-menu-nonce' ); ?>
     409                                <input type="hidden" name="action" value="update" />
     410                                <input type="hidden" name="menu" id="menu" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" />
     411                                <input type="hidden" id="hidden-metaboxes" value="<?php echo wp_initial_nav_menu_meta_boxes(); ?>" />
     412                                <div id="post-body">
     413                                        <div id="post-body-content">
     414                                                <?php if ( is_nav_menu( $nav_menu_selected_id ) && ( current_theme_supports('nav-menus') || current_theme_supports('widgets') ) ) : ?>
     415                                                        <ul class="menu" id="menu-to-edit">
     416                                                        <?php
     417                                                        $edit_markup = wp_get_nav_menu_to_edit( $nav_menu_selected_id  );
     418                                                        if ( ! is_wp_error( $edit_markup ) ) {
     419                                                                echo $edit_markup;
     420                                                        }
     421                                                        ?>
     422                                                        </ul>
     423                                                <?php endif; ?>
     424                                                <br class="clear" />
     425                                        </div><!-- /#post-body-content-->
     426                                </div><!--- /#post-body -->
     427                        </form><!--/#update-nav-menu-->
     428                </div><!-- /.menu-edit -->
     429        </div><!-- /#menu-management -->
     430        <?php endif; // if menus supported in current theme ?>
    292431</div><!-- /.wrap-->
    293432
    294 <div id="menu-item-settings">
    295         <p class="description">
    296                 <label for="edit-menu-item-title">
    297                         <?php _e( 'Menu Title' ); ?><br />
    298                         <input type="text" id="edit-menu-item-title" class="widefat" name="edit-menu-item-title" value="" tabindex="1" />
    299                 </label>
    300         </p>
    301         <p class="description">
    302                 <label for="edit-menu-item-url">
    303                         <?php _e( 'URL' ); ?><br />
    304                         <input type="text" id="edit-menu-item-url" class="widefat code" name="edit-menu-item-url" value="" tabindex="2" />
    305                 </label>
    306         </p>
    307         <p class="description">
    308                 <label for="edit-menu-item-attr-title">
    309                         <?php _e( 'Title Attribute' ); ?><br />
    310                         <input type="text" id="edit-menu-item-attr-title" class="widefat" name="edit-menu-item-attr-title" value="" tabindex="3" />
    311                 </label>
    312         </p>
    313         <p class="description">
    314                 <label for="edit-menu-item-target">
    315                         <?php _e( 'Link Target' ); ?><br />
    316                         <select id="edit-menu-item-target" class="widefat" name="edit-menu-item-target" tabindex="4">
    317                                 <option value=""><?php _e('Same window or tab'); ?></option>
    318                                 <option value="_blank"><?php _e('New window or tab'); ?></option>
    319                         </select>
    320                 </label>
    321         </p>
    322         <p class="description">
    323                 <label for="edit-menu-item-classes">
    324                         <?php _e( 'CSS Classes (optional)' ); ?><br />
    325                         <input type="text" id="edit-menu-item-classes" class="widefat code" name="edit-menu-item-classes" value="" tabindex="5" />
    326                 </label>
    327         </p>
    328         <p class="description">
    329                 <label for="edit-menu-item-xfn">
    330                         <?php _e( 'Link Relationship (XFN) (optional)' ); ?><br />
    331                         <input type="text" id="edit-menu-item-xfn" class="widefat code" name="edit-menu-item-xfn" value="" tabindex="6" />
    332                 </label>
    333         </p>
    334         <p class="description">
    335                 <label for="edit-menu-item-description">
    336                         <?php _e( 'Description (optional)' ); ?><br />
    337                         <textarea id="edit-menu-item-description" class="widefat" rows="3" name="edit-menu-item-description" tabindex="7" /></textarea>
    338                         <span class="description"><?php _e('The description will be displayed in the menu if the current theme supports it.'); ?></span>
    339                 </label>
    340         </p>
    341         <p>
    342                 <a id="update-menu-item" class="save button-primary" tabindex="8"><?php _e('Save Changes'); ?></a>
    343                 <a id="cancel-save" class="submitdelete deletion" tabindex="9"><?php _e('Cancel'); ?></a>
    344         </p>
    345         <input type="hidden" id="edit-menu-item-id" name="edit-item-id" value="" />
    346 </div><!-- /#menu-item-settings-->
    347433
    348 <?php include( './admin-footer.php' ); ?>
    349  No newline at end of file
     434<?php include( 'admin-footer.php' ); ?>
  • wp-admin/css/wp-admin-rtl.dev.css

     
    298298        margin-left: 0;
    299299        margin-right: 120px;
    300300}
    301 #post-body ul.category-tabs li.tabs {
     301#post-body ul.category-tabs li.tabs,
     302#post-body ul.add-menu-item-tabs li.tabs {
    302303        -moz-border-radius: 0 3px 3px 0;
    303304        -webkit-border-top-left-radius: 0;
    304305        -webkit-border-top-right-radius: 3px;
     
    309310        border-bottom-left-radius: 0;
    310311        border-bottom-right-radius: 3px;
    311312}
    312 #post-body ul.category-tabs {
     313#post-body ul.category-tabs,
     314#post-body ul.add-menu-item-tabs {
    313315        float: right;
    314316        text-align: left;
    315317        margin: 0 0 0 -120px;
    316318}
    317319#post-body .categorydiv div.tabs-panel,
     320#post-body .taxonomy div.tabs-panel,
    318321#post-body #linkcategorydiv div.tabs-panel {
    319322        margin: 0 120px 0 5px;
    320323}
    321324/* 1800 - 2000
    322325=================================== */
    323 #side-sortables .category-tabs li {
     326#side-sortables .category-tabs li,
     327#side-sortables .add-menu-item-tabs li {
    324328        padding-left: 8px;
    325329}
    326330.categorydiv ul.categorychecklist ul,
     331.taxonomydiv ul.categorychecklist ul,
    327332#linkcategorydiv ul.categorychecklist ul {
    328333        margin-left: 0;
    329334        margin-right: 18px;
  • wp-admin/css/colors-classic.dev.css

     
    110110}
    111111
    112112div.tabs-panel,
    113 ul.category-tabs li.tabs {
     113ul.category-tabs li.tabs,
     114ul.add-menu-item-tabs li.tabs {
    114115        border-color: #dfdfdf;
    115116}
    116117
    117 ul.category-tabs li.tabs {
     118ul.category-tabs li.tabs,
     119ul.add-menu-item-tabs li.tabs {
    118120        background-color: #f1f1f1;
    119121}
    120122
     
    380382        border-color: #dfdfdf;
    381383}
    382384
    383 #side-sortables .category-tabs .tabs a {
     385#side-sortables .category-tabs .tabs a,
     386#side-sortables .add-menu-item-tabs .tabs a {
    384387        color: #333;
    385388}
    386389
     
    14671470        background-color: #f5f5f5;
    14681471}
    14691472
    1470 #post-body ul.category-tabs li.tabs a {
     1473#post-body ul.category-tabs li.tabs a,
     1474#post-body ul.add-menu-item-tabs li.tabs a {
    14711475        color: #333;
    14721476}
    14731477
  • wp-admin/css/colors-fresh.dev.css

     
    110110}
    111111
    112112div.tabs-panel,
    113 ul.category-tabs li.tabs {
     113ul.category-tabs li.tabs,
     114ul.add-menu-item-tabs li.tabs {
    114115        border-color: #dfdfdf;
    115116}
    116117
    117 ul.category-tabs li.tabs {
     118ul.category-tabs li.tabs,
     119ul.add-menu-item-tabs li.tabs {
    118120        background-color: #f1f1f1;
    119121}
    120122
     
    379381        border-color: #dfdfdf;
    380382}
    381383
    382 #side-sortables .category-tabs .tabs a {
     384#side-sortables .category-tabs .tabs a,
     385#side-sortables .add-menu-item-tabs .tabs a {
    383386        color: #333;
    384387}
    385388
     
    490493}
    491494
    492495/* Because we don't want visited on these links */
     496body.press-this .tabs a,
    493497body.press-this .tabs a:hover {
     498        background-color: #fff;
    494499        border-color: #c6d9e9;
    495500        border-bottom-color: #fff;
    496501        color: #d54e21;
     
    14601465        background-color: #f5f5f5;
    14611466}
    14621467
    1463 #post-body ul.category-tabs li.tabs a {
     1468#post-body ul.category-tabs li.tabs a,
     1469#post-body ul.add-menu-item-tabs li.tabs a {
    14641470        color: #333;
    14651471}
    14661472
  • wp-admin/css/wp-admin.dev.css

     
    19591959        width: auto;
    19601960}
    19611961
    1962 #post-body ul.category-tabs {
     1962#post-body ul.category-tabs,
     1963#post-body ul.add-menu-item-tabs {
    19631964        float: left;
    19641965        width: 120px;
    19651966        text-align: right;
     
    19681969        padding: 0;
    19691970}
    19701971
    1971 #post-body ul.category-tabs li {
     1972#post-body ul.category-tabs li,
     1973#post-body ul.add-menu-item-tabs li {
    19721974        padding: 8px;
    19731975}
    19741976
    1975 #post-body ul.category-tabs li.tabs {
     1977#post-body ul.category-tabs li.tabs,
     1978#post-body ul.add-menu-item-tabs li.tabs {
    19761979        -moz-border-radius: 3px 0 0 3px;
    19771980        -webkit-border-top-left-radius: 3px;
    19781981        -webkit-border-bottom-left-radius: 3px;
     
    19821985        border-bottom-left-radius: 3px;
    19831986}
    19841987
    1985 #post-body ul.category-tabs li.tabs a {
     1988#post-body ul.category-tabs li.tabs a,
     1989#post-body ul.add-menu-item-tabs li.tabs a {
    19861990        font-weight: bold;
    19871991        text-decoration: none;
    19881992}
    19891993
    19901994.categorydiv div.tabs-panel,
     1995.customlinkdiv div.tabs-panel,
     1996.posttypediv div.tabs-panel,
     1997.taxonomydiv div.tabs-panel,
    19911998#linkcategorydiv div.tabs-panel {
    19921999        height: 200px;
    19932000        overflow: auto;
     
    19962003        border-width: 1px;
    19972004}
    19982005
     2006div.tabs-panel-active {
     2007        display:block; 
     2008}
     2009
     2010div.tabs-panel-inactive {
     2011        display:none;   
     2012}
     2013
    19992014#post-body .categorydiv div.tabs-panel,
     2015.taxonomy div.tabs-panel,
    20002016#post-body #linkcategorydiv div.tabs-panel {
    20012017        margin: 0 5px 0 125px;
    20022018}
    20032019
    2004 #side-sortables .category-tabs li {
     2020#side-sortables .category-tabs li,
     2021#side-sortables .add-menu-item-tabs li {
    20052022        display: inline;
    20062023        padding-right: 8px;
    20072024}
    20082025
    2009 #side-sortables .category-tabs a {
     2026#side-sortables .category-tabs a,
     2027#side-sortables .add-menu-item-tabs a {
    20102028        text-decoration: none;
    20112029}
    20122030
    2013 #side-sortables .category-tabs {
     2031#side-sortables .category-tabs,
     2032#side-sortables .add-menu-item-tabs {
    20142033        margin-bottom: 3px;
    20152034}
    20162035
    20172036.categorydiv ul,
     2037.customlinkdiv ul,
     2038.posttypediv ul,
     2039.taxonomydiv ul,
    20182040#linkcategorydiv ul {
    20192041        list-style: none;
    20202042        padding: 0;
     
    20252047#front-static-pages ul,
    20262048.inline-editor ul.cat-checklist ul,
    20272049.categorydiv ul.categorychecklist ul,
     2050.customlinkdiv ul.categorychecklist ul,
     2051.posttypediv ul.categorychecklist ul,
     2052.taxonomydiv ul.categorychecklist ul,
    20282053#linkcategorydiv ul.categorychecklist ul {
    20292054        margin-left: 18px;
    20302055}
     
    20402065        margin-bottom: 0px;
    20412066}
    20422067
    2043 .categorydiv .tabs-panel {
     2068.categorydiv .tabs-panel,
     2069.customlinkdiv .tabs-panel,
     2070.posttypediv .tabs-panel,
     2071.taxonomydiv .tabs-panel {
    20442072        border-width: 3px;
    20452073        border-style: solid;
    20462074}
    20472075
    2048 ul.category-tabs {
     2076ul.category-tabs,
     2077ul.add-menu-item-tabs {
    20492078        margin-top: 12px;
    20502079}
    20512080
    2052 ul.category-tabs li.tabs {
     2081ul.category-tabs li.tabs,
     2082ul.add-menu-item-tabs li.tabs {
    20532083        border-style: solid solid none;
    20542084        border-width: 1px 1px 0;
    20552085}
    20562086
    2057 #post-body .category-tabs li.tabs {
     2087#post-body .category-tabs li.tabs,
     2088#post-body .add-menu-item-tabs li.tabs {
    20582089        border-style: solid none solid solid;
    20592090        border-width: 1px 0 1px 1px;
    20602091        margin-right: -1px;
    20612092}
    20622093
    2063 ul.category-tabs li {
     2094ul.category-tabs li,
     2095ul.add-menu-item-tabs li {
    20642096        padding: 5px 8px;
    20652097        -moz-border-radius: 3px 3px 0 0;
    20662098        -webkit-border-top-left-radius: 3px;
     
    37053737        border-width: 1px 1px 0;
    37063738        background-color: #fafafa;
    37073739        color: #c1c1c1;
    3708 }
    3709  No newline at end of file
     3740}
  • wp-admin/css/nav-menu.dev.css

     
    88 * @subpackage Administration
    99 */
    1010
     11.nav-edit-wrap {
     12        clear:both;
     13}
     14
     15#menu-settings-column {
     16        display:block;
     17        float:left;
     18        width:281px;
     19}
     20
     21#menu-settings-column .inside {
     22        padding:0 10px;
     23}
     24
    1125/* Menu Container */
    12 #menu-management { clear: both; }
     26#menu-management {
     27        float:left;
     28        margin-left:15px;
     29}
     30        #menu-management .menu-edit {
     31                background-color:#fff;
     32                border-color: #dfdfdf;
     33                border-width: 1px;
     34                border-style: solid;
     35                margin-bottom: 20px;
     36                padding:0 10px 10px;
     37                -moz-border-radius-bottomleft: 6px;
     38                -webkit-border-bottom-left-radius: 6px;
     39                -khtml-border-bottom-left-radius: 6px;
     40                border-bottom-left-radius: 6px;
     41                -moz-border-radius-bottomright: 6px;
     42                -webkit-border-bottom-right-radius: 6px;
     43                -khtml-border-bottom-right-radius: 6px;
     44                border-bottom-right-radius: 6px;
     45                -moz-border-radius-topright: 6px;
     46                -webkit-border-top-right-radius: 6px;
     47                -khtml-border-top-right-radius: 6px;
     48                border-top-right-radius: 6px;
     49        }
     50
     51        #menu-management .menu-add-new abbr {
     52                font-weight:bold;
     53        }
     54
     55        #menu-management .menu-tabs {
     56                background-color:#fff;
     57                border-color:#dfdfdf;
     58                border-bottom-color:#fff;
     59        }
     60       
     61        #menu-management .menu-tab-inactive {
     62                background-color:#fafafa;
     63                border-bottom-color:#fafafa;
     64        }
     65
    1366#menu-management .inside { padding: 0 10px; }
    1467
    1568/* Button Primary Actions */
     
    2174
    2275/* Button Secondary Actions */
    2376.list-controls { float: left; }
    24 .add-to-menu { float: right; }
     77.add-to-menu {
     78        float: right;
     79}
     80
     81form.processing .add-to-menu {
     82        background: url("../images/wpspin_light.gif") no-repeat top center;
     83        display:block;
     84        height:20px;
     85        overflow:hidden;
     86        text-align:left;
     87        text-indent:-999em;
     88        width:20px;
     89}
     90
    2591.button-controls { margin: 10px 0; }
    2692.show-all, .hide-all { cursor: pointer; }
    2793.hide-all { display: none; }
     
    61127/* Nav Menu */
    62128#menu-container .inside { padding-bottom: 10px; }
    63129
     130.menu {
     131        padding-top:1em;
     132}
     133
    64134.menu ul { width: 100%; }
    65 .menu li { margin: 0; }
    66 .menu li dl dt { -webkit-border-radius: 6px; border-radius: 6px; -moz-border-radius: 6px; border: 1px solid #E6E6E6; position: relative; padding-left: 10px; background-color: #f1f1f1; height: 35px; line-height: 35px; }
    67 .menu li dl dt:hover { cursor: move; }
     135.menu ul.sub-menu {
     136}
     137.menu li {
     138        margin: 0;
     139}
     140.menu li dl {
     141        clear:both;
     142        line-height:1.5em;
     143        position:relative;
     144}
     145.menu li dl dt {
     146        -webkit-border-radius: 6px;
     147        border-radius: 6px;
     148        -moz-border-radius: 6px;
     149        border: 1px solid #E6E6E6;
     150        clear:both;
     151        cursor: move;
     152        position: relative;
     153        padding-left: 10px;
     154        background-color: #f1f1f1;
     155        height: 35px;
     156        line-height: 35px;
     157}
     158.menu li dl dt:hover {
     159}
     160.menu li.deleting dl dt {
     161        background-color:#faa;
     162}
    68163
    69 .menu li .item-title { }
     164.menu li .item-title {
     165        display:block;
     166        height:1em;
     167        margin-right:18em;
     168}
     169
     170.menu li div.sortable-placeholder {
     171        background: #f5f5f5;
     172        border: 1px dashed #bbb;
     173        margin: 10px 0px;
     174        padding-top:40px;
     175}
     176
     177.menu li dl.sortable-placeholder {
     178        background: #f5f5f5;
     179        padding-bottom:40px;
     180}
     181
    70182.menu li ul li { margin-left: 20px; opacity: .7; }
    71183.menu li ul li ul li { opacity: .9; }
    72184.menu li ul li ul li ul li { opacity: .9; }
     
    81193.item-controls { font-size: 11px; position: absolute; right: 15px; top: -1px; }
    82194.item-controls a { text-decoration: none; }
    83195.item-controls a:hover { cursor: pointer; }
     196.item-controls .item-order a {
     197        font-weight:bold;
     198}
     199
     200body.js .item-order {
     201        display:none;
     202}
     203
    84204.item-controls .menu-item-delete:hover { color: #ff0000; }
    85205
    86 /* Thickbox */
    87 #menu-item-settings { display: none; }
     206/* Menu editing */
     207.menu-item-edit-active {
     208        display:block;
     209}
     210
     211.menu-item-edit-inactive {
     212        display:none;
     213}
     214
     215.add-menu-item-pagelinks {
     216        margin:.5em auto;
     217        text-align:center;
     218}
     219
    88220#cancel-save { cursor: pointer; }
    89221#cancel-save:hover { color: #fff !important; }
    90222#update-menu-item { color: #fff !important; }
     
    94226
    95227/* Clearfix */
    96228.button-controls:after, #menu-item-url-wrap:after, #menu-item-name-wrap:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
    97 .button-controls, #menu-item-url-wrap, #menu-item-name-wrap { display: block; }
    98  No newline at end of file
     229.button-controls, #menu-item-url-wrap, #menu-item-name-wrap { display: block; }