diff --git a/misc/tabledrag.js b/misc/tabledrag.js index fed674c..b1f7638 100644 --- a/misc/tabledrag.js +++ b/misc/tabledrag.js @@ -104,10 +104,16 @@ Drupal.tableDrag = function (table, tableSettings) { // manipulate form elements directly, rather than using drag-and-drop.. self.initColumns(); - // Add mouse bindings to the document. The self variable is passed along + // Add event bindings to the document. The self variable is passed along // as event handlers do not have direct access to the tableDrag object. - $(document).bind('mousemove', function (event) { return self.dragRow(event, self); }); - $(document).bind('mouseup', function (event) { return self.dropRow(event, self); }); + if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) { + $(document).bind('touchmove', function (event) { return self.dragRow(event.originalEvent.touches[0], self); }); + $(document).bind('touchend', function (event) { return self.dropRow(event.originalEvent.touches[0], self); }); + } + else { + $(document).bind('mousemove', function (event) { return self.dragRow(event, self); }); + $(document).bind('mouseup', function (event) { return self.dropRow(event, self); }); + } }; /** @@ -273,51 +279,19 @@ Drupal.tableDrag.prototype.makeDraggable = function (item) { self.dragObject == null ? $(this).removeClass('tabledrag-handle-hover') : null; }); - // Add the mousedown action for the handle. - handle.mousedown(function (event) { - // Create a new dragObject recording the event information. - self.dragObject = {}; - self.dragObject.initMouseOffset = self.getMouseOffset(item, event); - self.dragObject.initMouseCoords = self.mouseCoords(event); - if (self.indentEnabled) { - self.dragObject.indentMousePos = self.dragObject.initMouseCoords; - } - - // If there's a lingering row object from the keyboard, remove its focus. - if (self.rowObject) { - $('a.tabledrag-handle', self.rowObject.element).blur(); - } - - // Create a new rowObject for manipulation of this row. - self.rowObject = new self.row(item, 'mouse', self.indentEnabled, self.maxDepth, true); - - // Save the position of the table. - self.table.topY = $(self.table).offset().top; - self.table.bottomY = self.table.topY + self.table.offsetHeight; - - // Add classes to the handle and row. - $(this).addClass('tabledrag-handle-hover'); - $(item).addClass('drag'); - - // Set the document to use the move cursor during drag. - $('body').addClass('drag'); - if (self.oldRowElement) { - $(self.oldRowElement).removeClass('drag-previous'); - } - - // Hack for IE6 that flickers uncontrollably if select lists are moved. - if (navigator.userAgent.indexOf('MSIE 6.') != -1) { - $('select', this.table).css('display', 'none'); - } - - // Hack for Konqueror, prevent the blur handler from firing. - // Konqueror always gives links focus, even after returning false on mousedown. - self.safeBlur = false; - - // Call optional placeholder function. - self.onDrag(); - return false; - }); + if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) { + handle.bind('touchstart', function (event) { + event.preventDefault(); + event = event.originalEvent.touches[0]; + self.dragStart(event, self, item); + }); + } + else { + handle.mousedown(function (event) { + event.preventDefault(); + self.dragStart(event, self, item); + }); + } // Prevent the anchor tag from jumping us to the top of the page. handle.click(function () { @@ -460,7 +434,62 @@ Drupal.tableDrag.prototype.makeDraggable = function (item) { }; /** - * Mousemove event handler, bound to document. + * Pointer event initiator, creates drag object and information. + * + * @param jQuery.Event event + * The event object that triggered the drag. + * @param Drupal.tableDrag self + * The drag handle. + * @param DOM item + * The item that is being dragged. + */ +Drupal.tableDrag.prototype.dragStart = function (event, self, item) { + // Create a new dragObject recording the pointer information. + self.dragObject = {}; + self.dragObject.initMouseOffset = self.getMouseOffset(item, event); + self.dragObject.initMouseCoords = self.mouseCoords(event); + if (self.indentEnabled) { + self.dragObject.indentMousePos = self.dragObject.initMouseCoords; + } + + // If there's a lingering row object from the keyboard, remove its focus. + if (self.rowObject) { + $(self.rowObject.element).find('a.tabledrag-handle').blur(); + } + + // Create a new rowObject for manipulation of this row. + self.rowObject = new self.row(item, 'mouse', self.indentEnabled, self.maxDepth, true); + + // Save the position of the table. + self.table.topY = $(self.table).offset().top; + self.table.bottomY = self.table.topY + self.table.offsetHeight; + + // Add classes to the handle and row. + $(this).addClass('tabledrag-handle-hover'); + $(item).addClass('drag'); + + // Set the document to use the move cursor during drag. + $('body').addClass('drag'); + if (self.oldRowElement) { + $(self.oldRowElement).removeClass('drag-previous'); + } + + // Hack for IE6 that flickers uncontrollably if select lists are moved. + if (navigator.userAgent.indexOf('MSIE 6.') != -1) { + $('select', this.table).css('display', 'none'); + } + + // Hack for Konqueror, prevent the blur handler from firing. + // Konqueror always gives links focus, even after returning false on mousedown. + self.safeBlur = false; + + // Call optional placeholder function. + self.onDrag(); + return false; +} + +/** + * Mouse movement handler, bound to document. */ Drupal.tableDrag.prototype.dragRow = function (event, self) { if (self.dragObject) { @@ -499,12 +528,12 @@ Drupal.tableDrag.prototype.dragRow = function (event, self) { // Similar to row swapping, handle indentations. if (self.indentEnabled) { var xDiff = self.currentMouseCoords.x - self.dragObject.indentMousePos.x; - // Set the number of indentations the mouse has been moved left or right. + // Set the number of indentations the pointer has been moved left or right. var indentDiff = Math.round(xDiff / self.indentAmount * self.rtl); // 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. + // Update table and pointer indentations. self.dragObject.indentMousePos.x += self.indentAmount * indentChange * self.rtl; self.indentCount = Math.max(self.indentCount, self.rowObject.indents); } @@ -514,11 +543,10 @@ Drupal.tableDrag.prototype.dragRow = function (event, self) { }; /** - * Mouseup event handler, bound to document. - * Blur event handler, bound to drag handle for keyboard support. + * Pointerup behaviour. */ Drupal.tableDrag.prototype.dropRow = function (event, self) { - // Drop row functionality shared between mouseup and blur events. + // Drop row functionality. if (self.rowObject != null) { var droppedRow = self.rowObject.element; // The row is already in the right place so we just release it. @@ -556,7 +584,7 @@ Drupal.tableDrag.prototype.dropRow = function (event, self) { self.rowObject = null; } - // Functionality specific only to mouseup event. + // Functionality specific only to pointerup events. if (self.dragObject != null) { $('.tabledrag-handle', droppedRow).removeClass('tabledrag-handle-hover'); @@ -572,7 +600,7 @@ Drupal.tableDrag.prototype.dropRow = function (event, self) { }; /** - * Get the mouse coordinates from the event (allowing for browser differences). + * Get the coordinates from the event (allowing for browser differences). */ Drupal.tableDrag.prototype.mouseCoords = function (event) { if (event.pageX || event.pageY) { @@ -585,8 +613,8 @@ Drupal.tableDrag.prototype.mouseCoords = function (event) { }; /** - * Given a target element and a mouse event, get the mouse offset from that - * element. To do this we need the element's position and the mouse position. + * Given a target element and a pointer event, get the event offset from that + * element. To do this we need the element's position and the target position. */ Drupal.tableDrag.prototype.getMouseOffset = function (target, event) { var docPos = $(target).offset();