From 7abfe41ab792e93b94e186f9ece4a5fd3b58a3e4 Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Sun, 24 Apr 2016 05:12:38 -0400
Subject: [PATCH] Fix bug where getting HTML editor content could steal focus from other form controls (#5223)

---
 program/js/treelist.js |   80 +++++++++++++++++++---------------------
 1 files changed, 38 insertions(+), 42 deletions(-)

diff --git a/program/js/treelist.js b/program/js/treelist.js
index 2927d02..bcbfeeb 100644
--- a/program/js/treelist.js
+++ b/program/js/treelist.js
@@ -110,37 +110,43 @@
   else
     update_data();
 
-  // register click handlers on list
-  container.on('click', 'div.treetoggle', function(e){
-    toggle(dom2id($(this).parent()));
-    e.stopPropagation();
-  });
-
-  container.on('click', 'li', function(e) {
-    // do not select record on checkbox/input click
-    if ($(e.target).is('input'))
-      return true;
-
-    var node = p.selectable ? indexbyid[dom2id($(this))] : null;
-    if (node && !node.virtual) {
-      select(node.id);
+  container.attr('role', 'tree')
+    .on('focusin', function(e) {
+      // TODO: only accept focus on virtual nodes from keyboard events
+      has_focus = true;
+    })
+    .on('focusout', function(e) {
+      has_focus = false;
+    })
+    // register click handlers on list
+    .on('click', 'div.treetoggle', function(e) {
+      toggle(dom2id($(this).parent()));
       e.stopPropagation();
-    }
-  });
+    })
+    .on('click', 'li', function(e) {
+      // do not select record on checkbox/input click
+      if ($(e.target).is('input'))
+        return true;
 
-  // mute clicks on virtual folder links (they need tabindex="0" in order to be selectable by keyboard)
-  container.on('mousedown', 'a', function(e) {
-    var link = $(e.target), node = indexbyid[dom2id(link.closest('li'))];
-    if (node && node.virtual && !link.attr('href')) {
-      e.preventDefault();
-      e.stopPropagation();
-      return false;
-    }
-  });
+      var node = p.selectable ? indexbyid[dom2id($(this))] : null;
+      if (node && !node.virtual) {
+        select(node.id);
+        e.stopPropagation();
+      }
+    })
+    // mute clicks on virtual folder links (they need tabindex="0" in order to be selectable by keyboard)
+    .on('mousedown', 'a', function(e) {
+      var link = $(e.target), node = indexbyid[dom2id(link.closest('li'))];
+      if (node && node.virtual && !link.attr('href')) {
+        e.preventDefault();
+        e.stopPropagation();
+        return false;
+      }
+    });
 
   // activate search function
   if (p.searchbox) {
-    searchfield = $(p.searchbox).on('keyup', function(e) {
+    searchfield = $(p.searchbox).off('keyup.treelist').on('keyup.treelist', function(e) {
       var key = rcube_event.get_keycode(e),
         mod = rcube_event.get_modifier(e);
 
@@ -169,24 +175,13 @@
     }).attr('autocomplete', 'off');
 
     // find the reset button for this search field
-    searchfield.parent().find('a.reset').click(function(e) {
+    searchfield.parent().find('a.reset').off('click.treelist').on('click.treelist', function(e) {
       reset_search();
       return false;
     })
   }
 
-  container.on('focusin', function(e){
-      // TODO: only accept focus on virtual nodes from keyboard events
-      has_focus = true;
-    })
-    .on('focusout', function(e){
-      has_focus = false;
-    });
-
-  container.attr('role', 'tree');
-
-  $(document.body)
-    .bind('keydown', keypress);
+  $(document.body).on('keydown', keypress);
 
   // catch focus when clicking the list container area
   if (p.parent_focus) {
@@ -334,7 +329,7 @@
 
       // re-render the entire subtree
       if (parent_node.children.length == 1) {
-        render_node(parent_node, parent_li.parent(), parent_li);
+        render_node(parent_node, null, parent_li);
         li = id2dom(node.id);
       }
       else {
@@ -583,9 +578,10 @@
     // search recursively in tree (to keep sorting order)
     search_tree(data);
     search_active = true;
-    last_search = q;
 
     me.triggerEvent('search', { query: q, last: last_search, count: hits.length, ids: hits, execute: enter||false });
+
+    last_search = q;
 
     return hits.count;
   }
@@ -947,7 +943,7 @@
     for (var id in indexbyid) {
       li = id2dom(id);
       item = li.children().first().get(0);
-      if (height = item.offsetHeight) {
+      if (item && (height = item.offsetHeight)) {
         pos = $(item).offset();
         pos.top += list_scroll_top;
         item_coords[id] = {

--
Gitblit v1.9.1