From 663689d8acaaa2b3ecab6425a25f9e5444969900 Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Fri, 3 Apr 2009 14:04:01 -0600 Subject: [PATCH] Improve row rendering. Instead of inserting a row into the DOM, and then altering the row via DOM manipulation/javascript, do all necessary data processing before the row is inserted into the DOM. --- imp/js/src/DimpBase.js | 148 ++++++++++++------------------- imp/js/src/ViewPort.js | 59 ++++++++---- imp/templates/javascript/mailbox-dimp.js | 8 +- 3 files changed, 106 insertions(+), 109 deletions(-) diff --git a/imp/js/src/DimpBase.js b/imp/js/src/DimpBase.js index e8f8bc770..076a13d49 100644 --- a/imp/js/src/DimpBase.js +++ b/imp/js/src/DimpBase.js @@ -401,46 +401,70 @@ var DimpBase = { page_size: DIMP.conf.splitbar_pos, onScrollIdle: settitle, onSlide: settitle, - onContent: function(rows) { - var mf, search, + onContent: function(row) { + var bg, search, thread = ((this.viewport.getMetaData('sortby') == DIMP.conf.sortthread) && this.viewport.getMetaData('thread')); + if (this.viewport.isFiltering()) { - search = this.sfilters.get(this._getSearchfilterField()).capitalize(); - mf = new RegExp("(" + $F('msgList_filter') + ")", "i"); + search = this.sfilters.get(this._getSearchfilterField()); } - rows.get('dataob').each(function(row) { - var elt, tmp, u, - r = $(row.domid); - - this.updateStatusFlags(row); - - // Add thread graphics - if (thread && thread.get(row.imapuid)) { - elt = r.down('.msgSubject'); - tmp = document.createDocumentFragment(); - u = thread.get(row.imapuid); - $R(0, u.length, true).each(function(i) { - var c = u.charAt(i); - if (!this.tcache[c]) { - this.tcache[c] = new Element('SPAN', { className: 'threadImg threadImg' + c }); - } - tmp.appendChild(this.tcache[c].cloneNode(false)); - }, this); - elt.select('SPAN.threadImg').invoke('remove'); - elt.insertBefore(tmp, elt.firstChild); + row.subjectdata = row.status = ''; + + // Add thread graphics + if (thread && thread.get(row.imapuid)) { + u = thread.get(row.imapuid); + $R(0, u.length, true).each(function(i) { + var c = u.charAt(i); + if (!this.tcache[c]) { + this.tcache[c] = ''; + } + row.subjectdata += this.tcache[c]; + }, this); + } + + /* Generate the status flags. */ + row.flag.each(function(a) { + var ptr = DIMP.conf.flags[a]; + if (ptr.p) { + if (!ptr.elt) { + /* Until text-overflow is supported on all + * browsers, need to truncate label text + * ourselves. */ + ptr.elt = '' + ptr.l.truncate(10) + ''; + } + row.subjectdata += ptr.elt; + } else { + if (!ptr.elt) { + ptr.elt = '
'; + } + row.status += ptr.elt; + + row.bg_string += ' ' + ptr.c; + + if (ptr.b) { + bg = ptr.b; + } } + }); + + // Set bg + if (bg) { + row.style = 'background:' + bg; + } + // Highlight search terms + if (search == 'from' || search == 'subject') { + row[search] = row[search].gsub(new RegExp("(" + $F('msgList_filter') + ")", "i"), '#{1}'); + } + }.bind(this), + onContentComplete: function(rows) { + rows.each(function(row) { // Add context menu this._addMouseEvents({ id: row.domid, type: row.menutype }); - new Drag(r, this._msgDragConfig); - - // Highlight search terms - if (search == 'From' || search == 'Subject') { - elt = r.down('.msg' + search); - elt.update(elt.getText().escapeHTML().gsub(mf, '#{1}')); - } + new Drag(row.domid, this._msgDragConfig); }, this); + this.setMessageListTitle(); }.bind(this), onComplete: function() { @@ -2193,68 +2217,10 @@ var DimpBase = { ob.flag = ob.flag.without(flag); if (add) { ob.flag.push(flag); - } else { - var r = $(ob.domid); - if (r) { - r.removeClassName(DIMP.conf.flags[flag].c); - } } - this.updateStatusFlags(ob); - }, this); - }, - - updateStatusFlags: function(row) - { - var bg = null, - pf = document.createDocumentFragment(), - r = $(row.domid), - sf = document.createDocumentFragment(), - stat, sub; - if (!r) { - return; - } - - stat = r.down('.msgStatus'); - sub = r.down('.msgSubject'); - - /* Clear existing user flags. */ - sub.select('.flagUser').invoke('remove'); - - row.flag.each(function(a) { - var ptr = DIMP.conf.flags[a]; - if (ptr.p) { - if (!ptr.elt) { - // Until text-overflow is supported on all browsers, - // need to truncate label text ourselves. - ptr.elt = new Element('SPAN', { className: ptr.c, title: ptr.l }).setStyle({ background: ptr.b }).update(ptr.l.truncate(10)); - } - pf.appendChild(ptr.elt.cloneNode(true)); - } else { - if (!ptr.elt) { - ptr.elt = new Element('DIV', { className: 'msgflags ' + ptr.c, title: ptr.l }); - } - r.addClassName(ptr.c); - sf.appendChild(ptr.elt.cloneNode(false)); - if (ptr.b) { - bg = ptr.b; - } - } - }); - - /* Clear existing flags. */ - stat.down().nextSiblings().invoke('remove'); - - /* Add flag graphics. */ - if (sf.firstChild) { - stat.appendChild(sf); - } - if (pf.firstChild) { - sub.insertBefore(pf, sub.lastChild); - } - - /* Set (or reset) the background row color. */ - r.setStyle({ background: bg }); + this.viewport.updateRow(ob); + }, this); }, /* Miscellaneous folder actions. */ diff --git a/imp/js/src/ViewPort.js b/imp/js/src/ViewPort.js index e955c7893..661018694 100644 --- a/imp/js/src/ViewPort.js +++ b/imp/js/src/ViewPort.js @@ -678,8 +678,7 @@ var ViewPort = Class.create({ var c = this.opts.content, c_nodes = [], page_size = this.getPageSize(), - rows, - sel = this.getSelected(); + rows; if (this.opts.onClearRows) { this.opts.onClearRows(c.childElements()); @@ -692,31 +691,59 @@ var ViewPort = Class.create({ rows = this.createSelection('rownum', $A($R(offset + 1, offset + page_size))); if (rows.size()) { - rows.get('dataob').each(function(row) { - var r = Object.clone(row); - if (r.bg) { - r.bg = row.bg.clone(); - if (sel.contains('uid', r.vp_id)) { - r.bg.push(this.opts.selected_class); - } - r.bg_string = r.bg.join(' '); - } - c_nodes.push(this.template.evaluate(r)); - }, this); - c.update(c_nodes.join('')); + c_nodes = rows.get('dataob'); + c.update(c_nodes.collect(this.prepareRow.bind(this)).join('')); } else { // If loading a viewport for the first time, show a blank // viewport rather than the empty viewport status message. c.update((this.opts.empty && this.viewport_init != 1) ? this.opts.empty.innerHTML : ''); } - if (this.opts.onContent) { - this.opts.onContent(rows); + if (this.opts.onContentComplete) { + this.opts.onContentComplete(c_nodes); } return true; }, + prepareRow: function(row) + { + var r = Object.clone(row); + + if (r.bg) { + r.bg = row.bg.clone(); + if (this.getSelected().contains('uid', r.vp_id)) { + r.bg.push(this.opts.selected_class); + } + r.bg_string = r.bg.join(' '); + } else { + r.bg_string = ''; + } + + if (this.opts.onContent) { + this.opts.onContent(r); + } + + return this.template.evaluate(r); + }, + + updateRow: function(row) + { + var d = $(row.domid); + if (d) { + if (this.opts.onClearRows) { + this.opts.onClearRows([ d ]); + } + + d.replace(this.prepareRow(row)); + + if (this.opts.onContentComplete) { + this.opts.onContentComplete([ row ]); + } + } + + }, + _displayFetchError: function() { if (this.opts.onFail) { diff --git a/imp/templates/javascript/mailbox-dimp.js b/imp/templates/javascript/mailbox-dimp.js index 8cb3b894e..615bdc8b6 100644 --- a/imp/templates/javascript/mailbox-dimp.js +++ b/imp/templates/javascript/mailbox-dimp.js @@ -2,6 +2,9 @@ * mailbox-dimp.js - Template used to format the rows in the message list * display. * + * 'status', 'style', and 'subjectdata' are entries that are internally + * created by DimpBase.js. + * * See the documentation of prototypejs - Template for the template format: * http://www.prototypejs.org/api/template * @@ -12,12 +15,13 @@ */ DimpBase.message_list_template = -'
' + +'
' + '
' + '
' + + '#{status}' + '
' + '
#{from}
' + - '
#{subject}
' + + '
#{subjectdata}#{subject}
' + '
#{date}
' + '
#{size}
' + '
'; -- 2.11.0