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/list.js | 84 ++++++++++++++++++++++++++---------------- 1 files changed, 52 insertions(+), 32 deletions(-) diff --git a/program/js/list.js b/program/js/list.js index 7e84ef2..99fd48f 100644 --- a/program/js/list.js +++ b/program/js/list.js @@ -114,7 +114,8 @@ 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; + if (rows[r].nodeType == 1) + this.rowcount += this.init_row(rows[r]) ? 1 : 0; } this.init_header(); @@ -131,7 +132,7 @@ } if (this.parent_focus) { - this.list.parentNode.onclick = function(e) { me.focus(e); }; + this.list.parentNode.onclick = function(e) { me.focus(); }; } return this; @@ -150,11 +151,17 @@ var self = this, uid = row.uid; this.rows[uid] = {uid:uid, id:row.id, obj:row}; - // set eventhandlers to table row - row.onmousedown = function(e){ return self.drag_row(e, this.uid); }; - row.onmouseup = function(e){ return self.click_row(e, this.uid); }; + $(row).data('uid', uid) + // set eventhandlers to table row (only left-button-clicks in mouseup) + .mousedown(function(e) { return self.drag_row(e, this.uid); }) + .mouseup(function(e) { + if (e.which == 1 && !self.drag_active) + return self.click_row(e, this.uid); + else + return true; + }); - if (bw.touch) { + if (bw.touch && row.addEventListener) { row.addEventListener('touchstart', function(e) { if (e.touches.length == 1) { self.touchmoved = false; @@ -219,7 +226,7 @@ if (this.column_fixed == r) continue; col = this.thead.rows[0].cells[r]; - col.onmousedown = function(e){ return p.drag_column(e, this); }; + col.onmousedown = function(e) { return p.drag_column(e, this); }; this.colcount++; } } @@ -240,12 +247,13 @@ $(this.list).before(this.fixed_header); var me = this; - $(window).resize(function(){ me.resize() }); - $(window).scroll(function(){ + $(window).resize(function() { me.resize(); }); + $(window).scroll(function() { var w = $(window); - me.fixed_header.css('marginLeft', (-w.scrollLeft()) + 'px'); - if (!bw.webkit) - me.fixed_header.css('marginTop', (-w.scrollTop()) + 'px'); + me.fixed_header.css({ + marginLeft: -w.scrollLeft() + 'px', + marginTop: -w.scrollTop() + 'px' + }); }); } else { @@ -270,14 +278,14 @@ var column_widths = []; // get column widths from original thead - $(this.tbody).parent().find('thead tr td').each(function(index) { + $(this.tbody).parent().find('thead th,thead td').each(function(index) { column_widths[index] = $(this).width(); }); // apply fixed widths to fixed table header $(this.thead).parent().width($(this.tbody).parent().width()); - $(this.thead).find('tr td').each(function(index) { - $(this).css('width', column_widths[index]); + $(this.thead).find('th,td').each(function(index) { + $(this).width(column_widths[index]); }); $(window).scroll(); @@ -349,10 +357,11 @@ if (row.nodeName === undefined) { // for performance reasons use DOM instead of jQuery here var domrow = document.createElement(this.row_tagname()); + if (row.id) domrow.id = row.id; + if (row.uid) domrow.uid = row.uid; if (row.className) domrow.className = row.className; if (row.style) $.extend(domrow.style, row.style); - 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]; @@ -388,18 +397,22 @@ var row = this.rows[id]; if (!row) return false; - var domrow = row.obj; - for (var domcell, col, i=0; cols && i < cols.length; i++) { + var i, domrow = row.obj; + for (i = 0; cols && i < cols.length; i++) { this.get_cell(domrow, i).html(cols[i]); } if (newid) { delete this.rows[id]; + domrow.uid = newid; domrow.id = 'rcmrow' + newid; this.init_row(domrow); if (select) this.selection[0] = newid; + + if (this.last_selected == id) + this.last_selected = newid; } }, @@ -559,6 +572,10 @@ */ click_row: function(e, id) { + // sanity check + if (!id || !this.rows[id]) + return false; + // don't do anything (another action processed before) if (!this.is_event_target(e)) return true; @@ -816,14 +833,16 @@ get_row_uid: function(row) { - if (row && row.uid) - return row.uid; + if (!row) + return; - var uid; - if (row && (uid = $(row).data('uid'))) - row.uid = uid; - else if (row && String(row.id).match(this.id_regexp)) - row.uid = RegExp.$1; + if (!row.uid) { + var uid = $(row).data('uid'); + if (uid) + row.uid = uid; + else if (String(row.id).match(this.id_regexp)) + row.uid = RegExp.$1; + } return row.uid; }, @@ -1085,11 +1104,11 @@ /** * Check if given id is part of the current selection */ -in_selection: function(id) +in_selection: function(id, index) { for (var n in this.selection) if (this.selection[n] == id) - return true; + return index ? parseInt(n) : true; return false; }, @@ -1237,18 +1256,19 @@ } } else { - if (!this.in_selection(id)) { // select row + var pre, post, p = this.in_selection(id, true); + + if (p === false) { // select row this.selection.push(id); $(this.rows[id].obj).addClass('selected').attr('aria-selected', 'true'); if (!norecur && !this.rows[id].expanded) this.highlight_children(id, true); } else { // unselect row - var p = $.inArray(id, this.selection), - a_pre = this.selection.slice(0, p), - a_post = this.selection.slice(p+1, this.selection.length); + pre = this.selection.slice(0, p); + post = this.selection.slice(p+1, this.selection.length); - this.selection = a_pre.concat(a_post); + this.selection = pre.concat(post); $(this.rows[id].obj).removeClass('selected').removeAttr('aria-selected'); if (!norecur && !this.rows[id].expanded) this.highlight_children(id, false); -- Gitblit v1.9.1