Index: misc/tabledrag.js =================================================================== RCS file: /cvs/drupal/drupal/misc/tabledrag.js,v retrieving revision 1.9 diff -u -r1.9 tabledrag.js --- misc/tabledrag.js 6 Dec 2007 09:53:53 -0000 1.9 +++ misc/tabledrag.js 12 Dec 2007 22:31:02 -0000 @@ -269,6 +269,7 @@ keyChange = true; if (self.rowObject.isValidSwap(previousRow, 0)) { self.rowObject.swap('before', previousRow); + self.rowObject.indent(0); window.scrollBy(0, -parseInt(item.offsetHeight)); } else if (self.table.tBodies[0].rows[0] != previousRow || $(previousRow).is('.draggable')) { @@ -294,15 +295,18 @@ self.safeBlur = false; // Do not allow the onBlur cleanup. self.rowObject.direction = 'down'; keyChange = true; + if (self.rowObject.isValidSwap(nextRow, 0)) { self.rowObject.swap('after', nextRow); + self.rowObject.indent(0); + window.scrollBy(0, parseInt(item.offsetHeight)); } else { self.rowObject.swap('after', nextRow); self.rowObject.indent(-1); + window.scrollBy(0, parseInt(item.offsetHeight)); } handle.get(0).focus(); // Regain focus after the DOM manipulation. - window.scrollBy(0, parseInt(item.offsetHeight)); } break; } @@ -375,7 +379,7 @@ } // Similar to row swapping, handle indentations. - if (self.indentEnabled && x != self.oldX) { + if (self.indentEnabled) { self.oldX = x; var xDiff = self.currentMouseCoords.x - self.dragObject.indentMousePos.x; // Set the number of indentations the mouse has been moved left or right. @@ -383,17 +387,14 @@ // Limit the indentation to no less than the left edge of the table and no // more than the total amount of indentation in the table. indentDiff = indentDiff > 0 ? Math.min(indentDiff, self.indentCount - self.rowObject.indents + 1) : Math.max(indentDiff, -self.rowObject.indents); - if (indentDiff != 0) { - // Indent the row with our estimated diff, which may be further - // restricted according to the rows around this row. - var indentChange = self.rowObject.indent(indentDiff); - - // Update table and mouse indentations. - self.dragObject.indentMousePos.x += self.indentAmount * indentChange; - self.indentCount = Math.max(self.indentCount, self.rowObject.indents); - } + // Indent the row with our estimated diff, which may be further + // restricted according to the rows around this row. + var indentChange = self.rowObject.indent(indentDiff); + + // Update table and mouse indentations. + self.dragObject.indentMousePos.x += self.indentAmount * indentChange; + self.indentCount = Math.max(self.indentCount, self.rowObject.indents); } - return false; } }; @@ -547,7 +548,7 @@ return null; } - // We've may have found the row the mouse just passed over, but it doesn't + // We may have found the row the mouse just passed over, but it doesn't // take into account hidden rows. Skip backwards until we find a draggable // row. while ($(row).is(':hidden') && $(row).prev('tr').is(':hidden')) { @@ -861,13 +862,17 @@ var rowIndents = $('.indentation', row).size(); var prevIndents = $('.indentation', $(row).prev('tr')).size(); var nextIndents = $('.indentation', $(row).next('tr')).size(); + var indentAllowed = !$(this.element).is('.no-parent'); if ( (this.direction == 'down') && ( // Prevent being able to drag a row downward with 2 indentations from a parent. this.indents > rowIndents + 1 || // Prevent orphaning children when dragging into a parent. - this.indents < nextIndents - indentDiff + this.indents < nextIndents - indentDiff || + // Prevent orphaning children when dragging into a parent if the + // current row can't be nested. + (!indentAllowed && indentDiff && nextIndents) ) || (this.direction == 'up') && ( // Prevent being able to drag a row upward with 2 indentations from a parent. @@ -914,24 +919,34 @@ * positive. */ Drupal.tableDrag.prototype.row.prototype.indent = function(indentDiff) { - if (indentDiff > 0) { - var prevRow = $(this.group).filter(':first').prev('tr').get(0); - if (prevRow) { - var prevIndent = $('.indentation', $(this.group).filter(':first').prev('tr')).size(); - indentDiff = Math.min(prevIndent - this.indents + 1, indentDiff); + if ($(this.element).is('.no-parent')) { + indentDiff = -this.indents; + } + else { + // Find the deepest suitable parent. + var parentRow = $(this.element).prev('tr').get(0); + while (parentRow && $(parentRow).is('.no-child') && $('.indentation', parentRow).size()) { + parentRow = $(parentRow).prev('tr').get(0); + } + if (parentRow && !$(parentRow).is('.no-child')) { + // Set as a child of the parent we found. + var parentIndent = $('.indentation', parentRow).size(); + indentDiff = Math.min(parentIndent - this.indents + 1, indentDiff); } else { - indentDiff = 0; // First row may not contain indents. + // No suitable parent was found : no indentation. + indentDiff = -this.indents; + } + + if (indentDiff < 0) { + var nextIndent = $('.indentation', $(this.group).filter(':last').next('tr')).size(); + indentDiff = Math.max(nextIndent - this.indents, indentDiff); } - } - else { - var nextIndent = $('.indentation', $(this.group).filter(':last').next('tr')).size(); - indentDiff = Math.max(nextIndent - this.indents, indentDiff); - } - // Never allow indentation greater the set limit. - if (this.maxDepth && indentDiff + this.groupDepth > this.maxDepth) { - indentDiff = 0; + // Never allow indentation greater than the set limit. + if (this.maxDepth && indentDiff + this.groupDepth > this.maxDepth) { + indentDiff = 0; + } } for (var n = 1; n <= Math.abs(indentDiff); n++) {