Alot of drag/drop/sortable improvements to nav menu admin UI. props koopersmith, fixes #12675.

git-svn-id: https://develop.svn.wordpress.org/trunk@14337 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Andrew Nacin 2010-05-02 19:09:10 +00:00
parent b459f516b9
commit 103e30ed7e
7 changed files with 295 additions and 322 deletions

File diff suppressed because one or more lines are too long

View File

@ -79,6 +79,10 @@
border-bottom-right-radius: 6px; border-bottom-right-radius: 6px;
} }
#post-body-content {
position: relative;
}
.post-body-plain { .post-body-plain {
padding: 10px 10px 0 0; padding: 10px 10px 0 0;
} }
@ -119,7 +123,7 @@
padding-right: 10px; padding-right: 10px;
} }
.js .label-with-default-title { .js .input-with-default-title {
color: #aaa; color: #aaa;
font-style: italic; font-style: italic;
} }
@ -203,12 +207,13 @@ form.processing .postbox img.waiting {
.menu ul.sub-menu { .menu ul.sub-menu {
} }
.menu li { .menu li {
margin: 0; margin-bottom: 0;
} }
.menu li dl { .menu li dl {
clear:both; clear:both;
line-height:1.5em; line-height:1.5em;
position:relative; position:relative;
margin-top: 13px;
} }
.menu li dl dt { .menu li dl dt {
background: url("../images/gray-grad.png") repeat-x scroll left top #DFDFDF; background: url("../images/gray-grad.png") repeat-x scroll left top #DFDFDF;
@ -223,12 +228,6 @@ form.processing .postbox img.waiting {
font-weight:bold; font-weight:bold;
overflow: hidden; overflow: hidden;
} }
.menu li.deleting dl dt {
background-color:#f66;
background-image: none;
text-shadow: 0 0 0 #ccc;
}
.menu li dl.menu-item-edit-inactive dt { .menu li dl.menu-item-edit-inactive dt {
border-radius: 6px; border-radius: 6px;
-webkit-border-radius: 6px; -webkit-border-radius: 6px;
@ -247,8 +246,10 @@ form.processing .postbox img.waiting {
.js .menu li dl dt { .js .menu li dl dt {
cursor: move; cursor: move;
} }
.no-js .menu li dl { .menu li dl dt:hover {
margin-top: 13px; }
.menu li.deleting dl dt {
background-color:#faa;
} }
.menu li .item-title { .menu li .item-title {
@ -258,25 +259,45 @@ form.processing .postbox img.waiting {
margin-right:13em; margin-right:13em;
} }
.menu li .sortable-placeholder { /* Sortables */
width: 430px; li.menu-item.ui-sortable-helper dl {
margin-top: 0;
} }
.menu li div.sortable-placeholder { li.menu-item.ui-sortable-helper .menu-item-transport dl {
background: #f5f5f5; margin-top: 13px;
border: 1px dashed #bbb; }
margin: 10px 0; .menu .sortable-placeholder {
padding-top:40px; height: 35px;
width: 410px;
margin-top: 13px;
} }
.menu li dl.sortable-placeholder { /* WARNING: The factor of 30px is hardcoded into the nav-menus javascript. */
background: #f5f5f5; .menu-item-depth-0 { margin-left: 0px; }
padding-bottom:40px; .menu-item-depth-1 { margin-left: 30px; }
} .menu-item-depth-2 { margin-left: 60px; }
.menu-item-depth-3 { margin-left: 90px; }
.menu-item-depth-4 { margin-left: 120px; }
.menu-item-depth-5 { margin-left: 150px; }
.menu-item-depth-6 { margin-left: 180px; }
.menu-item-depth-7 { margin-left: 210px; }
.menu-item-depth-8 { margin-left: 240px; }
.menu-item-depth-9 { margin-left: 270px; }
.menu-item-depth-10 { margin-left: 300px; }
.menu-item-depth-11 { margin-left: 330px; }
.menu li li { margin-left: 20px; } .menu-item-depth-0 .menu-item-transport { margin-left: 0px; }
.menu-item-depth-1 .menu-item-transport { margin-left: -30px; }
/* Drag and Drop */ .menu-item-depth-2 .menu-item-transport { margin-left: -60px; }
.dropzone { height: 7px; margin: 3px 0 3px 0; } .menu-item-depth-3 .menu-item-transport { margin-left: -90px; }
.menu-item-depth-4 .menu-item-transport { margin-left: -120px; }
.menu-item-depth-5 .menu-item-transport { margin-left: -150px; }
.menu-item-depth-6 .menu-item-transport { margin-left: -180px; }
.menu-item-depth-7 .menu-item-transport { margin-left: -210px; }
.menu-item-depth-8 .menu-item-transport { margin-left: -240px; }
.menu-item-depth-9 .menu-item-transport { margin-left: -270px; }
.menu-item-depth-10 .menu-item-transport { margin-left: -300px; }
.menu-item-depth-11 .menu-item-transport { margin-left: -330px; }
/* Menu item controls */ /* Menu item controls */
.item-type { text-transform: uppercase; font-size: 11px; color: #999999; padding-right: 10px; } .item-type { text-transform: uppercase; font-size: 11px; color: #999999; padding-right: 10px; }

View File

@ -8,6 +8,23 @@
* @uses Walker_Nav_Menu * @uses Walker_Nav_Menu
*/ */
class Walker_Nav_Menu_Edit extends Walker_Nav_Menu { class Walker_Nav_Menu_Edit extends Walker_Nav_Menu {
/**
* @see Walker_Nav_Menu::start_lvl()
* @since 3.0.0
*
* @param string $output Passed by reference.
* @param int $depth Depth of page.
*/
function start_lvl(&$output, $depth) {}
/**
* @see Walker_Nav_Menu::end_lvl()
* @since 3.0.0
*
* @param string $output Passed by reference.
* @param int $depth Depth of page.
*/
function end_lvl(&$output, $depth) {}
/** /**
* @see Walker::start_el() * @see Walker::start_el()
@ -41,7 +58,7 @@ class Walker_Nav_Menu_Edit extends Walker_Nav_Menu {
$original_title = $original_object->post_title; $original_title = $original_object->post_title;
} }
?> ?>
<li id="menu-item-<?php echo $item_id; ?>" class="menu-item-<?php echo strtolower(esc_attr( $item->append )); ?>"> <li id="menu-item-<?php echo $item_id; ?>" class="menu-item menu-item-depth-<?php echo $depth; ?> menu-item-<?php echo strtolower(esc_attr( $item->append )); ?>">
<dl class="<?php <dl class="<?php
if ( isset($_GET['edit-menu-item']) && $item_id == $_GET['edit-menu-item'] ) if ( isset($_GET['edit-menu-item']) && $item_id == $_GET['edit-menu-item'] )
echo 'menu-item-edit-active'; echo 'menu-item-edit-active';
@ -166,14 +183,15 @@ class Walker_Nav_Menu_Edit extends Walker_Nav_Menu {
<input class="button-primary save-menu-item" name="save_menu_item" type="submit" value="<?php esc_attr_e('Save Menu Item'); ?>" /> <input class="button-primary save-menu-item" name="save_menu_item" type="submit" value="<?php esc_attr_e('Save Menu Item'); ?>" />
</span> </span>
<input type="hidden" name="menu-item-append[<?php echo $item_id; ?>]" value="<?php echo $item->append; ?>" /> <input class="menu-item-data-append" type="hidden" name="menu-item-append[<?php echo $item_id; ?>]" value="<?php echo $item->append; ?>" />
<input type="hidden" name="menu-item-db-id[<?php echo $item_id; ?>]" value="<?php echo $item_id; ?>" /> <input class="menu-item-data-db-id" type="hidden" name="menu-item-db-id[<?php echo $item_id; ?>]" value="<?php echo $item_id; ?>" />
<input type="hidden" name="menu-item-object-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->object_id ); ?>" /> <input class="menu-item-data-object-id" type="hidden" name="menu-item-object-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->object_id ); ?>" />
<input type="hidden" name="menu-item-object[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->object ); ?>" /> <input class="menu-item-data-object" type="hidden" name="menu-item-object[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->object ); ?>" />
<input type="hidden" name="menu-item-parent-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->post_parent ); ?>" /> <input class="menu-item-data-parent-id" type="hidden" name="menu-item-parent-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->post_parent ); ?>" />
<input type="hidden" class="menu-item-position" name="menu-item-position[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->menu_order ); ?>" /> <input class="menu-item-data-position" type="hidden" class="menu-item-position" name="menu-item-position[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->menu_order ); ?>" />
<input type="hidden" name="menu-item-type[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->type ); ?>" /> <input class="menu-item-data-type" type="hidden" name="menu-item-type[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->type ); ?>" />
</div><!-- .menu-item-settings--> </div><!-- .menu-item-settings-->
<ul class="menu-item-transport"></ul>
<?php <?php
$output .= ob_get_clean(); $output .= ob_get_clean();
} }
@ -426,7 +444,7 @@ function wp_nav_menu_item_link_meta_box() {
<p id="menu-item-name-wrap"> <p id="menu-item-name-wrap">
<label class="howto" for="custom-menu-item-name"> <label class="howto" for="custom-menu-item-name">
<span><?php _e('Text'); ?></span> <span><?php _e('Text'); ?></span>
<input id="custom-menu-item-name" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-title]" type="text" class="regular-text menu-item-textbox label-with-default-title" title="<?php esc_attr_e('Menu Item'); ?>" /> <input id="custom-menu-item-name" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-title]" type="text" class="regular-text menu-item-textbox input-with-default-title" title="<?php esc_attr_e('Menu Item'); ?>" />
</label> </label>
</p> </p>

View File

@ -8,17 +8,11 @@
* @subpackage Administration * @subpackage Administration
*/ */
var WPNavMenuHandler = function () { var WPNavMenuHandler = function ($) {
var $ = jQuery, var autoCompleteData = {},
activeHovering = false,
currentDropzone = null,
customLinkNameInput, menuItemDepthPerLevel = 30, // Do not use directly. Use depthToPx and pxToDepth instead.
customLinkURLInput, globalMaxDepth = 11,
customLinkNameDefault,
customLinkURLDefault,
autoCompleteData = {},
formatAutocompleteResponse = function( resultRow, pos, total, queryTerm ) { formatAutocompleteResponse = function( resultRow, pos, total, queryTerm ) {
if ( resultRow && resultRow[0] ) { if ( resultRow && resultRow[0] ) {
@ -81,82 +75,84 @@ var WPNavMenuHandler = function () {
return itemData; return itemData;
}, },
getParentMenuItemDBId = function() { recalculateMenuItemPositions = function() {
var allInputs = this.getElementsByTagName('input'), menuList.find('.menu-item-data-position').val( function(index) { return index + 1; } );
i = allInputs.length, },
j,
parentEl,
parentInputs;
while( i-- ) { depthToPx = function(depth) {
if ( -1 != allInputs[i].name.indexOf('menu-item-parent-id[' + parseInt(this.id.replace('menu-item-', ''), 10) + ']') ) { return depth * menuItemDepthPerLevel;
/* This LI element is not in a submenu */ },
if ( ! this.parentNode.className || -1 == this.parentNode.className.indexOf('sub-menu') ) {
allInputs[i].value = 0;
/* 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) */ pxToDepth = function(px) {
} else if ( 'LI' == this.parentNode.parentNode.nodeName && -1 != this.parentNode.parentNode.id.indexOf('menu-item-') ) { return Math.floor(px / menuItemDepthPerLevel);
parentEl = this.parentNode.parentNode; },
parentInputs = parentEl.getElementsByTagName('input');
j = parentInputs.length; menuList;
while ( j-- ) {
if ( parentInputs[j].name && -1 != parentInputs[j].name.indexOf('menu-item-object-id[' + parseInt(parentEl.id.replace('menu-item-', ''), 10) + ']') ) { // jQuery extensions
allInputs[i].value = parseInt(parentInputs[j].value, 10); $.fn.extend({
break; menuItemDepth : function() {
} return pxToDepth( this.eq(0).css('margin-left').slice(0, -2) );
} },
updateDepthClass : function(current, prev) {
return this.each(function(){
var t = $(this);
prev = prev || t.menuItemDepth();
$(this).removeClass('menu-item-depth-'+ prev )
.addClass('menu-item-depth-'+ current );
});
},
shiftDepthClass : function(change) {
return this.each(function(){
var t = $(this),
depth = t.menuItemDepth();
$(this).removeClass('menu-item-depth-'+ depth )
.addClass('menu-item-depth-'+ (depth + change) );
});
},
childMenuItems : function() {
var result = $();
this.each(function(){
var t = $(this), depth = t.menuItemDepth(), next = t.next();
while( next.length && next.menuItemDepth() > depth ) {
result = result.add( next );
next = next.next();
} }
break; });
} return result;
} },
}, updateParentMenuItemDBId : function() {
return this.each(function(){
var item = $(this),
input = item.find('.menu-item-data-parent-id'),
depth = item.menuItemDepth(),
parent = item.prev();
makeDroppable = function(el) { if( depth == 0 ) { // Item is on the top level, has no parent
var that = this; input.val(0);
} else { // Find the parent item, and retrieve its object id.
$(el).droppable({ while( parent.menuItemDepth() != depth - 1 ) {
accept: '.menu li', parent = parent.prev();
tolerance: 'pointer', }
drop: function(e, ui) { input.val( parent.find('.menu-item-data-object-id').val() );
that.eventOnDrop(ui.draggable[0], this, ui, e); }
}, });
},
over: function(e,ui) { hideAdvancedMenuItemFields : function() {
that.eventOnDragOver(ui.draggable[0], this, ui, e); return this.each(function(){
}, var that = $(this);
$('.hide-column-tog').not(':checked').each(function(){
out: function(e, ui) { that.find('.field-' + $(this).val() ).addClass('hidden-field');
that.eventOnDragOut(ui.draggable[0], this, ui, e); });
} });
}); },
}, });
menuList,
setupListItemsDragAndDrop = function(list) {
if ( ! list )
return;
var dummyListItem = document.getElementById(list.id + '-dummy-list-item'),
menuListItems = list.getElementsByTagName('li'),
i = menuListItems.length;
if ( ! dummyListItem ) {
dummyListItem = document.createElement('li');
dummyListItem.id = list.id + '-dummy-list-item';
list.appendChild(dummyListItem);
this.setupListItemDragAndDrop(dummyListItem);
}
while ( i-- )
this.setupListItemDragAndDrop(menuListItems[i]);
};
return { return {
// Functions that run on init. // Functions that run on init.
init : function() { init : function() {
menuList = document.getElementById('menu-to-edit'); menuList = $('#menu-to-edit');
this.attachMenuEditListeners(); this.attachMenuEditListeners();
@ -164,8 +160,8 @@ var WPNavMenuHandler = function () {
this.attachTabsPanelListeners(); this.attachTabsPanelListeners();
// init drag and drop if( menuList.length ) // If no menu, we're in the + tab.
setupListItemsDragAndDrop.call(this, menuList); this.initSortables();
this.initToggles(); this.initToggles();
}, },
@ -183,14 +179,106 @@ var WPNavMenuHandler = function () {
$('.field-' + field).addClass('hidden-field'); $('.field-' + field).addClass('hidden-field');
} }
// hide fields // hide fields
this.hideAdvancedMenuItemFields(); menuList.hideAdvancedMenuItemFields();
}, },
hideAdvancedMenuItemFields : function(container) { initSortables : function() {
container = container || '.menu'; var currentDepth = 0, originalDepth, minDepth, maxDepth,
$('.hide-column-tog').not(':checked').each(function(){ menuLeft = menuList.offset().left;
$(container).find('.field-' + $(this).val() ).addClass('hidden-field');
menuList.sortable({
handle: ' > dl',
placeholder: 'sortable-placeholder',
start: function(e, ui) {
var next, height, width, parent, children, maxChildDepth,
transport = ui.item.children('.menu-item-transport');
// Set depths
originalDepth = ui.item.menuItemDepth();
updateCurrentDepth(ui, originalDepth);
// Attach child elements to parent
// Skip the placeholder
parent = ( ui.item.next()[0] == ui.placeholder[0] ) ? ui.item.next() : ui.item;
children = parent.childMenuItems();
transport.append( children );
// Now that the element is complete, we can update...
updateDepthRange(ui);
// Update the height of the placeholder to match the moving item.
height = transport.outerHeight();
// If there are children, account for distance between top of children and parent
height += ( height > 0 ) ? (ui.placeholder.css('margin-top').slice(0, -2) * 1) : 0;
height += ui.item.outerHeight();
height -= 2; // Subtract 2 for borders
ui.placeholder.height(height);
// Update the width of the placeholder to match the moving item.
maxChildDepth = originalDepth;
children.each(function(){
var depth = $(this).menuItemDepth();
maxChildDepth = (depth > maxChildDepth) ? depth : maxChildDepth;
});
width = ui.item.find('dl dt').outerWidth(); // Get original width
width += depthToPx(maxChildDepth - originalDepth); // Account for children
width -= 2; // Subtract 2 for borders
ui.placeholder.width(width);
},
stop: function(e, ui) {
var children, depthChange = currentDepth - originalDepth;
// Return child elements to the list
children = ui.item.children('.menu-item-transport').children().insertAfter(ui.item);
// Update depth classes
if( depthChange != 0 ) {
ui.item.updateDepthClass( currentDepth );
children.shiftDepthClass( depthChange );
}
// Finally, update the item/menu data.
ui.item.updateParentMenuItemDBId();
recalculateMenuItemPositions();
},
change: function(e, ui) {
// Make sure the placeholder is inside the menu.
// Otherwise fix it, or we're in trouble.
if( ! ui.placeholder.parent().hasClass('menu') )
ui.placeholder.appendTo(menuList);
updateDepthRange(ui);
},
sort: function(e, ui) {
var depth = pxToDepth(ui.item.offset().left - menuLeft);
// Check and correct if depth is not within range.
if ( depth < minDepth ) depth = minDepth;
else if ( depth > maxDepth ) depth = maxDepth;
if( depth != currentDepth )
updateCurrentDepth(ui, depth);
}
}); });
function updateDepthRange(ui) {
var prev = ui.placeholder.prev(),
next = ui.placeholder.next(), depth;
// Make sure we don't select the moving item.
if( prev[0] == ui.item[0] ) prev = prev.prev();
if( next[0] == ui.item[0] ) next = next.next();
minDepth = (next.length) ? next.menuItemDepth() : 0;
if( prev.length )
maxDepth = ( (depth = prev.menuItemDepth() + 1) > globalMaxDepth ) ? globalMaxDepth : depth;
else
maxDepth = 0;
}
function updateCurrentDepth(ui, depth) {
ui.placeholder.updateDepthClass( depth, currentDepth );
currentDepth = depth;
}
}, },
attachMenuEditListeners : function() { attachMenuEditListeners : function() {
@ -210,27 +298,40 @@ var WPNavMenuHandler = function () {
}); });
}, },
/**
* An interface for managing default values for input elements
* that is both JS and accessibility-friendly.
*
* Input elements that add the class 'input-with-default-title'
* will have their values set to the provided HTML title when empty.
*/
setupInputWithDefaultTitle : function() {
var name = 'input-with-default-title';
$('.' + name).each( function(){
var $t = $(this), title = $t.attr('title'), val = $t.val();
$t.data( name, title );
if( '' == val ) $t.val( title );
else if ( title == val ) return;
else $t.removeClass( name );
}).focus( function(){
var $t = $(this);
if( $t.val() == $t.data(name) )
$t.val('').removeClass( name );
}).blur( function(){
var $t = $(this);
if( '' == $t.val() )
$t.val( $t.data(name) ).addClass( name );
});
},
attachMenuMetaListeners : function(formEL) { attachMenuMetaListeners : function(formEL) {
if ( ! formEL ) if ( ! formEL )
return; return;
var that = this, lwd = 'label-with-default-title'; var that = this;
this.setupInputWithDefaultTitle();
$('.'+lwd).each(function(){
var $t = $(this), title = $t.attr('title'), val = $t.val();
$t.data(lwd, title);
if( '' == val ) $t.val(title);
else if ( title == val ) return;
else $t.removeClass(lwd);
}).focus(function(){
var $t = $(this);
if( $t.val() == $t.data(lwd) )
$t.val('').removeClass(lwd);
}).blur(function(){
var $t = $(this);
if( '' == $t.val() )
$t.val( $t.data(lwd) ).addClass(lwd);
});
// auto-suggest for the quick-search boxes // auto-suggest for the quick-search boxes
$('input.quick-search').each(function(i, el) { $('input.quick-search').each(function(i, el) {
@ -240,9 +341,6 @@ var WPNavMenuHandler = function () {
$(formEL).bind('submit', function(e) { $(formEL).bind('submit', function(e) {
return that.eventSubmitMetaForm.call(that, this, e); return that.eventSubmitMetaForm.call(that, this, e);
}); });
$(formEL).find('input:submit').click(function() {
$(this).siblings('img.waiting').show();
});
}, },
attachTabsPanelListeners : function() { attachTabsPanelListeners : function() {
@ -288,19 +386,6 @@ var WPNavMenuHandler = function () {
}); });
}, },
setupListItemDragAndDrop : function(el) {
var defLists = el.getElementsByTagName('dl'),
dropZone = this.makeListItemDropzone(el),
i = defLists.length;
makeDroppable.call(this, dropZone);
this.makeListItemDraggable(el);
while( i-- ) {
makeDroppable.call(this, defLists[i]);
}
},
/** /**
* Set up quick-search input fields' events. * Set up quick-search input fields' events.
* *
@ -398,78 +483,6 @@ var WPNavMenuHandler = function () {
} }
}, },
/**
* Callback for the drag over action when dragging a list item.
*
* @param object draggedEl The DOM element being dragged
* @param object dropEl The DOM element on top of which we're dropping.
*/
eventOnDragOver : function(draggedEl, dropEl) {
activeHovering = true;
currentDropzone = dropEl;
dropEl.className += ' sortable-placeholder';
},
/**
* Callback for the drag out action when dragging a list item.
*
* @param object draggedEl The DOM element being dragged
* @param object dropEl The DOM element on top of which we're dropping.
*/
eventOnDragOut : function(draggedEl, dropEl) {
activeHovering = false;
/* delay the disappearance of the droppable area so it doesn't flicker in and out */
(function(that) {
setTimeout(function() {
if ( that != currentDropzone || ( ! activeHovering && that.className && -1 != that.className.indexOf('sortable-placeholder') ) ) {
that.className = that.className.replace(/sortable-placeholder/g, '');
}
}, 800);
})(dropEl);
},
/**
* Callback for the drop action when dragging and dropping a list item.
*
* @param object draggedEl The DOM element being dragged (and now dropped)
* @param object dropEl The DOM element on top of which we're dropping.
*/
eventOnDrop : function(draggedEl, dropEl) {
var dropIntoSublist = !! ( -1 == dropEl.className.indexOf('dropzone') ),
subLists = dropEl.parentNode.getElementsByTagName('ul'),
hasSublist = false,
i = subLists.length,
subList;
activeHovering = false;
dropEl.className = dropEl.className.replace(/sortable-placeholder/g, '');
if ( dropIntoSublist ) {
while ( i-- ) {
if ( subLists[i] && 1 != subLists[i].className.indexOf('sub-menu') ) {
hasSublist = true;
subList = subLists[i];
}
}
if ( ! hasSublist ) {
subList = document.createElement('ul');
subList.className = 'sub-menu';
dropEl.parentNode.appendChild(subList);
}
subList.appendChild(draggedEl);
} else {
dropEl.parentNode.parentNode.insertBefore(draggedEl, dropEl.parentNode);
}
this.recalculateSortOrder(menuList);
getParentMenuItemDBId.call(draggedEl);
},
/** /**
* Callback for the meta form submit action listener. * Callback for the meta form submit action listener.
* *
@ -487,6 +500,7 @@ var WPNavMenuHandler = function () {
processMethod = function(){}, processMethod = function(){},
re = new RegExp('menu-item\\[(\[^\\]\]*)'); re = new RegExp('menu-item\\[(\[^\\]\]*)');
thisForm.className = thisForm.className + ' processing',
that = this; that = this;
params['action'] = ''; params['action'] = '';
@ -534,46 +548,12 @@ var WPNavMenuHandler = function () {
$.post( ajaxurl, params, function(menuMarkup) { $.post( ajaxurl, params, function(menuMarkup) {
processMethod.call(that, menuMarkup, params); processMethod.call(that, menuMarkup, params);
$(thisForm).find('img.waiting').hide(); thisForm.className = thisForm.className.replace(/processing/g, '');
}); });
return false; return false;
}, },
makeListItemDraggable : function(el) {
// make menu item draggable
$(el).draggable({
handle: ' > dl',
opacity: .8,
addClasses: false,
helper: 'clone',
zIndex: 100
});
},
/**
* Add the child element that acts as the dropzone for drag-n-drop.
*
* @param object el The parent object to which we'll prepend the dropzone.
* @return object The dropzone DOM element.
*/
makeListItemDropzone : function(el) {
if ( ! el )
return false;
var divs = el.getElementsByTagName('div'),
i = divs.length,
dropZone = document.createElement('div');
while( i-- ) {
if ( divs[i].className && -1 != divs[i].className.indexOf('dropzone') && ( el == divs[i].parentNode ) )
return divs[i];
}
dropZone.className = 'dropzone';
el.insertBefore(dropZone, el.firstChild);
return dropZone;
},
/** /**
* Process the add menu item request response into menu list item. * Process the add menu item request response into menu list item.
* *
@ -581,27 +561,7 @@ var WPNavMenuHandler = function () {
* @param object req The request arguments. * @param object req The request arguments.
*/ */
processAddMenuItemResponse : function( menuMarkup, req ) { processAddMenuItemResponse : function( menuMarkup, req ) {
if ( ! req ) $(menuMarkup).hideAdvancedMenuItemFields().appendTo( menuList );
req = {};
var dropZone,
dummyListItem = document.getElementById(menuList.id + '-dummy-list-item'),
i,
listElements,
wrap = document.createElement('ul');
wrap.innerHTML = menuMarkup;
listElements = wrap.getElementsByTagName('li');
i = listElements.length;
while ( i-- ) {
this.setupListItemDragAndDrop(listElements[i]);
if ( dummyListItem )
menuList.insertBefore(listElements[i], dummyListItem);
else
menuList.appendChild(listElements[i]);
}
this.recalculateSortOrder(menuList);
this.hideAdvancedMenuItemFields(menuList);
/* set custom link form back to defaults */ /* set custom link form back to defaults */
$('#custom-menu-item-name').val('').blur(); $('#custom-menu-item-name').val('').blur();
@ -668,46 +628,20 @@ var WPNavMenuHandler = function () {
} }
}, },
recalculateSortOrder : function(parentEl) {
var allInputs = parentEl.getElementsByTagName('input'),
i,
j = 0;
for( i = 0; i < allInputs.length; i++ ) {
if ( allInputs[i].name && -1 != allInputs[i].name.indexOf('menu-item-position') ) {
allInputs[i].value = ++j;
}
}
},
removeMenuItem : function(el) { removeMenuItem : function(el) {
if ( ! el ) el = $(el)
return false; var children = el.childMenuItems();
var subMenus = el.getElementsByTagName('ul'), el.addClass('deleting').fadeOut( 350 , function() {
subs, el.remove();
i; children.shiftDepthClass(-1).updateParentMenuItemDBId();
recalculateMenuItemPositions();
if ( subMenus[0] ) {
subs = subMenus[0].getElementsByTagName('li');
for ( i = 0; i < subs.length; i++ ) {
if ( subs[i].id && -1 != subs[i].id.indexOf('menu-item-') && subs[i].parentNode == subMenus[0] ) {
el.parentNode.insertBefore(subs[i], el);
}
}
}
el.className += ' deleting';
$(el).fadeOut( 350 , function() {
this.parentNode.removeChild(this);
}); });
this.recalculateSortOrder(menuList);
} }
} }
} }
var wpNavMenu = new WPNavMenuHandler(); var wpNavMenu = new WPNavMenuHandler(jQuery);
jQuery(function() { jQuery(function() {
wpNavMenu.init(); wpNavMenu.init();

File diff suppressed because one or more lines are too long

View File

@ -384,7 +384,7 @@ require_once( 'admin-header.php' );
<div class="major-publishing-actions"> <div class="major-publishing-actions">
<label class="menu-name-label howto open-label" for="menu-name"> <label class="menu-name-label howto open-label" for="menu-name">
<span><?php _e('Menu Name'); ?></span> <span><?php _e('Menu Name'); ?></span>
<input name="menu-name" type="text" class="menu-name regular-text menu-item-textbox label-with-default-title" title="Enter menu name here." value="<?php echo esc_attr( $nav_menu_selected_title ); ?>" /> <input name="menu-name" type="text" class="menu-name regular-text menu-item-textbox input-with-default-title" title="Enter menu name here." value="<?php echo esc_attr( $nav_menu_selected_title ); ?>" />
<br class="clear" /> <br class="clear" />
</label> </label>

View File

@ -393,7 +393,7 @@ function wp_default_scripts( &$scripts ) {
) ); ) );
// Custom Navigation // Custom Navigation
$scripts->add( 'nav-menu', "/wp-admin/js/nav-menu$suffix.js", false, '20100502' ); $scripts->add( 'nav-menu', "/wp-admin/js/nav-menu$suffix.js", false, '20100502a' );
$scripts->localize( 'nav-menu', 'navMenuL10n', array( $scripts->localize( 'nav-menu', 'navMenuL10n', array(
'custom' => _x('Custom', 'menu nav item type'), 'custom' => _x('Custom', 'menu nav item type'),
'thickbox' => _x('Edit Menu Item', 'Thickbox Title'), 'thickbox' => _x('Edit Menu Item', 'Thickbox Title'),
@ -474,7 +474,7 @@ function wp_default_styles( &$styles ) {
$styles->add( 'farbtastic', '/wp-admin/css/farbtastic.css', array(), '1.2' ); $styles->add( 'farbtastic', '/wp-admin/css/farbtastic.css', array(), '1.2' );
$styles->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.css', array(), '0.9.8' ); $styles->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.css', array(), '0.9.8' );
$styles->add( 'imgareaselect', '/wp-includes/js/imgareaselect/imgareaselect.css', array(), '0.9.1' ); $styles->add( 'imgareaselect', '/wp-includes/js/imgareaselect/imgareaselect.css', array(), '0.9.1' );
$styles->add( 'nav-menu', "/wp-admin/css/nav-menu$suffix.css", array(), '20100429a' ); $styles->add( 'nav-menu', "/wp-admin/css/nav-menu$suffix.css", array(), '20100501a' );
foreach ( $rtl_styles as $rtl_style ) { foreach ( $rtl_styles as $rtl_style ) {
$styles->add_data( $rtl_style, 'rtl', true ); $styles->add_data( $rtl_style, 'rtl', true );