From 586ed69aa8f9df34076f4e3bb5e1ecf0cfc6581a Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Wed, 28 May 2014 06:38:34 -0400
Subject: [PATCH] Add method to make a treelist widget become a jQuery UI droppable with support for auto-scrolling and auto-expanding

---
 program/js/treelist.js |   43 +++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/program/js/treelist.js b/program/js/treelist.js
index 85d8aa9..90eeeea 100644
--- a/program/js/treelist.js
+++ b/program/js/treelist.js
@@ -64,6 +64,7 @@
     scroll_timer,
     searchfield,
     tree_state,
+    ui_droppable,
     list_id = (container.attr('id') || p.id_prefix || '0'),
     me = this;
 
@@ -79,6 +80,7 @@
   this.drag_start = drag_start;
   this.drag_end = drag_end;
   this.intersects = intersects;
+  this.droppable = droppable;
   this.update = update_node;
   this.insert = insert;
   this.remove = remove;
@@ -521,7 +523,8 @@
 
     var li = $('<li>')
       .attr('id', p.id_prefix + (p.id_encode ? p.id_encode(node.id) : node.id))
-      .addClass((node.classes || []).join(' '));
+      .addClass((node.classes || []).join(' '))
+      .data('id', node.id);
 
     if (replace)
       replace.replaceWith(li);
@@ -594,6 +597,7 @@
         selection = node.id;
       }
 
+      li.data('id', node.id);
       result.push(node);
       indexbyid[node.id] = node;
     })
@@ -802,7 +806,8 @@
     // no intersection with list bounding box
     if (mouse.x < box_coords.x1 || mouse.x >= box_coords.x2 || mouse.top < box_coords.y1 || mouse.top >= box_coords.y2) {
       // TODO: optimize performance for this operation
-      $('li.droptarget', container).removeClass('droptarget');
+      if (highlight)
+        $('li.droptarget', container).removeClass('droptarget');
       return result;
     }
 
@@ -823,6 +828,8 @@
             expand(autoexpand_item);
             drag_start();  // re-calculate item coords
             autoexpand_item = null;
+            if (ui_droppable)
+              $.ui.ddmanager.prepareOffsets($.ui.ddmanager.current, null);
           }, p.autoexpand);
         }
         else if (autoexpand_timer && autoexpand_item != id) {
@@ -851,6 +858,38 @@
 
     return result;
   }
+
+  /**
+   * Wrapper for jQuery.UI.droppable() activation on this widget
+   *
+   * @param object Options as passed to regular .droppable() function
+   */
+  function droppable(opts)
+  {
+    var my_opts = $.extend({ greedy: true, hoverClass: 'droptarget', addClasses:false }, opts);
+
+    my_opts.activate = function(e, ui) {
+      drag_start();
+      ui_droppable = ui;
+      if (opts.activate)
+        opts.activate(e, ui);
+    };
+
+    my_opts.deactivate = function(e, ui) {
+      drag_end();
+      ui_droppable = null;
+      if (opts.deactivate)
+        opts.deactivate(e, ui);
+    };
+
+    my_opts.over = function(e, ui) {
+      intersects(rcube_event.get_mouse_pos(e), false);
+      if (opts.over)
+        opts.over(e, ui);
+    };
+
+    $('li:not(.virtual)', container).droppable(my_opts);
+  }
 }
 
 // use event processing functions from Roundcube's rcube_event_engine

--
Gitblit v1.9.1