From 0b36d151572e050b51d82e7429fee847ebb33e22 Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Thu, 20 Nov 2014 06:03:22 -0500
Subject: [PATCH] Add method to display operation (uploading) progress in UI message

---
 program/js/list.js |   81 +++++++++++++++++++++++++++++-----------
 1 files changed, 58 insertions(+), 23 deletions(-)

diff --git a/program/js/list.js b/program/js/list.js
index 65d4a92..dbc14d6 100644
--- a/program/js/list.js
+++ b/program/js/list.js
@@ -60,12 +60,14 @@
   this.column_movable = false;
   this.keyboard = false;
   this.toggleselect = false;
+  this.aria_listbox = false;
+  this.parent_focus = true;
 
   this.drag_active = false;
   this.col_drag_active = false;
   this.column_fixed = null;
-  this.last_selected = 0;
-  this.shift_start = 0;
+  this.last_selected = null;
+  this.shift_start = null;
   this.focused = false;
   this.drag_mouse_start = null;
   this.dblclick_time = 500; // default value on MS Windows is 500
@@ -75,6 +77,9 @@
   if (p && typeof p === 'object')
     for (var n in p)
       this[n] = p[n];
+
+  // register this instance
+  rcube_list_widget._instances.push(this);
 };
 
 
@@ -94,11 +99,19 @@
     this.tbody = this.list;
   }
 
+  if ($(this.list).attr('role') == 'listbox') {
+    this.aria_listbox = true;
+    if (this.multiselect)
+      $(this.list).attr('aria-multiselectable', 'true');
+  }
+
+  var me = this;
+
   if (this.tbody) {
     this.rows = {};
     this.rowcount = 0;
 
-    var r, len, rows = this.tbody.childNodes, me = this;
+    var r, len, rows = this.tbody.childNodes;
 
     for (r=0, len=rows.length; r<len; r++) {
       this.rowcount += this.init_row(rows[r]) ? 1 : 0;
@@ -117,6 +130,10 @@
     }
   }
 
+  if (this.parent_focus) {
+    this.list.parentNode.onclick = function(e) { me.focus(); };
+  }
+
   return this;
 },
 
@@ -133,9 +150,9 @@
     var self = this, uid = row.uid;
     this.rows[uid] = {uid:uid, id:row.id, obj:row};
 
-    // set eventhandlers to table row
+    // set eventhandlers to table row (only left-button-clicks in mouseup)
     row.onmousedown = function(e){ return self.drag_row(e, this.uid); };
-    row.onmouseup = function(e){ return self.click_row(e, this.uid); };
+    row.onmouseup = function(e){ if (e.which == 1) return self.click_row(e, this.uid); };
 
     if (bw.touch) {
       row.addEventListener('touchstart', function(e) {
@@ -159,6 +176,15 @@
       }, false);
     }
 
+    // label the list row with the subject col as descriptive label
+    if (this.aria_listbox) {
+      var lbl_id = 'l:' + row.id;
+      $(row)
+        .attr('role', 'option')
+        .attr('aria-labelledby', lbl_id)
+        .find(this.col_tagname()).eq(this.subject_col).attr('id', lbl_id);
+    }
+
     if (document.all)
       row.onselectstart = function() { return false; };
 
@@ -180,7 +206,7 @@
 
     if (this.fixed_header) {  // copy (modified) fixed header back to the actual table
       $(this.list.tHead).replaceWith($(this.fixed_header).find('thead').clone());
-      $(this.list.tHead).find('tr td').attr('style', '').find('a').attr('tabindex', '-1');  // remove fixed widths
+      $(this.list.tHead).find('th,td').attr('style', '').find('a').attr('tabindex', '-1');  // remove fixed widths
     }
     else if (!bw.touch && this.list.className.indexOf('fixedheader') >= 0) {
       this.init_fixed_header();
@@ -274,7 +300,7 @@
 
   this.rows = {};
   this.rowcount = 0;
-  this.last_selected = 0;
+  this.last_selected = null;
 
   if (sel)
     this.clear_selection();
@@ -326,7 +352,7 @@
     if (row.id) domrow.id = row.id;
     if (row.className) domrow.className = row.className;
     if (row.style) $.extend(domrow.style, row.style);
-    if (row.uid) $(domrow).data('uid', row.uid);
+    if (row.uid) $(domrow).data('uid', String(row.uid)); // #1489906
 
     for (var e, domcell, col, i=0; row.cols && i < row.cols.length; i++) {
       col = row.cols[i];
@@ -836,9 +862,9 @@
 get_first_row: function()
 {
   if (this.rowcount) {
-    var i, len, uid, rows = this.tbody.childNodes;
+    var i, uid, rows = this.tbody.childNodes;
 
-    for (i=0, len=rows.length-1; i<len; i++)
+    for (i=0; i<rows.length; i++)
       if (rows[i].id && (uid = this.get_row_uid(rows[i])))
         return uid;
   }
@@ -881,9 +907,10 @@
  */
 select_row: function(id, mod_key, with_mouse)
 {
-  var select_before = this.selection.join(',');
+  var select_before = this.selection.join(','),
+    in_selection_before = this.in_selection(id);
 
-  if (!this.multiselect)
+  if (!this.multiselect && with_mouse)
     mod_key = 0;
 
   if (!this.shift_start)
@@ -919,21 +946,21 @@
     this.multi_selecting = true;
   }
 
-  // trigger event if selection changed
-  if (this.selection.join(',') != select_before)
-    this.triggerEvent('select');
-
-  if (this.last_selected != 0 && this.rows[this.last_selected]) {
+  if (this.last_selected && this.rows[this.last_selected]) {
     $(this.rows[this.last_selected].obj).removeClass('focused')
       .find(this.col_tagname()).eq(this.subject_col).removeAttr('tabindex');
   }
 
   // unselect if toggleselect is active and the same row was clicked again
-  if (this.toggleselect && this.last_selected == id) {
+  if (this.toggleselect && in_selection_before && !mod_key) {
     this.clear_selection();
-    id = null;
   }
-  else {
+  // trigger event if selection changed
+  else if (this.selection.join(',') != select_before) {
+    this.triggerEvent('select');
+  }
+
+  if (this.rows[id]) {
     $(this.rows[id].obj).addClass('focused');
     // set cursor focus to link inside selected row
     if (this.focused)
@@ -1151,7 +1178,7 @@
 
   if (num_select && !this.selection.length && !no_event) {
     this.triggerEvent('select');
-    this.last_selected = 0;
+    this.last_selected = null;
   }
 },
 
@@ -1390,7 +1417,8 @@
  */
 scrollto: function(id)
 {
-  var row = this.rows[id].obj;
+  var row = this.rows[id] ? this.rows[id].obj : null;
+
   if (row && this.frame) {
     var scroll_to = Number(row.offsetTop),
       head_offset = 0;
@@ -1479,7 +1507,11 @@
 
       $('> ' + self.col_tagname(), self.rows[uid].obj).each(function(n, cell) {
         if (self.subject_col < 0 || (self.subject_col >= 0 && self.subject_col == n)) {
-          var subject = $(cell).text();
+          // remove elements marked with "skip-on-drag" class
+          cell = $(cell).clone();
+          $(cell).find('.skip-on-drag').remove();
+
+          var subject = cell.text();
 
           if (subject) {
             // remove leading spaces
@@ -1774,3 +1806,6 @@
 rcube_list_widget.prototype.addEventListener = rcube_event_engine.prototype.addEventListener;
 rcube_list_widget.prototype.removeEventListener = rcube_event_engine.prototype.removeEventListener;
 rcube_list_widget.prototype.triggerEvent = rcube_event_engine.prototype.triggerEvent;
+
+// static
+rcube_list_widget._instances = [];

--
Gitblit v1.9.1