From: Michael M Slusarz Date: Fri, 16 Jan 2009 07:46:43 +0000 (-0700) Subject: Begin reworking Event handling model. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=be4fc0073a45403d212e6ccd8873371811771e75;p=horde.git Begin reworking Event handling model. Instead of attaching event handlers to every DOM element, set a single event handler on the document and sniff the Event object to determine what DOM element it hit. This is not fully complete yet, and there still are some issues (i.e dealing with context menu actions). --- diff --git a/imp/js/src/DimpBase.js b/imp/js/src/DimpBase.js index a877d077c..eff17afbb 100644 --- a/imp/js/src/DimpBase.js +++ b/imp/js/src/DimpBase.js @@ -9,9 +9,9 @@ var DimpBase = { // Vars used and defaulting to null/false: - // filter_on, filtertoggle, fl_visible, folder, folderswitch, fspecial, - // isvisible, message_list_template, offset, pollPE, pp, searchobserve, - // uid, viewport + // cfolderaction, filter_on, filtertoggle, fl_visible, folder, + // folderswitch, fspecial, isvisible, message_list_template, offset, + // pollPE, pp, searchobserve, uid, viewport bcache: $H(), cacheids: {}, lastrow: -1, @@ -520,7 +520,6 @@ var DimpBase = { }.bind(this), onFirstContent: function() { this.clearPreviewPane(); - $('msgList').observe('dblclick', this._handleMsgListDblclick.bindAsEventListener(this)); }.bind(this), onClearRows: function(r) { r.each(function(row) { @@ -574,7 +573,6 @@ var DimpBase = { // Set up viewport filter events. this.viewport.addFilter('ListMessages', this._addSearchfilterParams.bind(this)); - mf.observe('keyup', this._searchfilterOnKeyup.bind(this)); mf.observe('focus', this._searchfilterOnFocus.bind(this)); mf.observe('blur', this._searchfilterOnBlur.bind(this)); mf.addClassName('msgFilterDefault'); @@ -686,7 +684,6 @@ var DimpBase = { } row = this.viewport.createSelection('domid', elt.id).get('dataob').first(); row.draft ? DimpCore.compose('resume', { folder: row.view, uid: row.imapuid }) : this.msgWindow(row); - e.stop(); }, _handleMsgListCheckbox: function(e) @@ -1115,27 +1112,9 @@ var DimpBase = { }); } $('dimpmain_portal').update(r.response.portal); - - /* Link portal block headers to the application. */ - $('dimpmain_portal').select('h1.header a').each(this.bcache.get('portalClkLink') || this.bcache.set('portalClkLink', function(d) { - d.observe('click', function(e, d) { - this.go('app:' + d.readAttribute('app')); - e.stop(); - }.bindAsEventListener(this, d)); - }.bind(this))); }, /* Search filter functions. */ - _searchfilterOnKeyup: function() - { - if (this.searchobserve) { - clearTimeout(this.searchobserve); - } - if (this.filter_on) { - this.searchobserve = (this.bcache.get('searchfilterR') || this.bcache.set('searchfilterR', this.searchfilterRun.bind(this))).delay(0.5); - } - }, - searchfilterRun: function() { if (!this.viewport.isFiltering()) { @@ -1292,33 +1271,42 @@ var DimpBase = { /* Keydown event handler */ _keydownHandler: function(e) { - // Only catch keyboard shortcuts in message list view. Disable - // catching when the RedBox overlay is visible. - if (!$('dimpmain_folder').visible() || - RedBox.overlayVisible()) { - return; - } - - var co, ps, r, row, rowoff, - kc = e.keyCode || e.charCode, - sel = this.viewport.getSelected(); + var co, form, ps, r, row, rowoff, sel, + kc = e.keyCode || e.charCode; // Form catching - normally we will ignore, but certain cases we want // to catch. - if (e.findElement('FORM')) { + form = e.findElement('FORM'); + if (form) { switch (kc) { case Event.KEY_ESC: + // Catch escapes in search box if (e.element().readAttribute('id') == 'msgList_filter') { e.element().blur(); this.searchfilterClear(false); e.stop(); } break; + + case Event.KEY_RETURN: + // Catch returns in RedBox + if (form.readAttribute('id') == 'RB_folder') { + this.cfolderaction(); + e.stop(); + } + break; } return; } + // Only catch keyboard shortcuts in message list view. + if (!$('dimpmain_folder').visible()) { + return; + } + + sel = this.viewport.getSelected(); + switch (kc) { case Event.KEY_DELETE: case Event.KEY_BACKSPACE: @@ -1398,6 +1386,287 @@ var DimpBase = { } }, + _keyupHandler: function(e) + { + if (e.element().readAttribute('id') == 'msgList_filter') { + if (this.searchobserve) { + clearTimeout(this.searchobserve); + } + if (this.filter_on) { + this.searchobserve = (this.bcache.get('searchfilterR') || this.bcache.set('searchfilterR', this.searchfilterRun.bind(this))).delay(0.5); + } + } + }, + + _clickHandler: function(e, dblclick) + { + if (e.isRightClick()) { + return; + } + + var elt = e.element(), f, id, mbox, tmp; + + while (Object.isElement(elt)) { + id = elt.readAttribute('id'); + + switch (id) { + case 'msgList': + if (dblclick) { + this._handleMsgListDblclick(e); + e.stop(); + return; + } + break; + + case 'RB_Folder_ok': + this.cfolderaction(); + e.stop(); + return; + + case 'RB_Folder_cancel': + this._closeRedBox(); + e.stop(); + return; + + case 'normalfolders': + case 'specialfolders': + this._handleFolderMouseEvent(e, 'click'); + break; + + case 'hometab': + case 'logolink': + this.go('portal'); + e.stop(); + return; + + case 'button_compose': + case 'composelink': + DimpCore.compose('new'); + e.stop(); + return; + + case 'checkmaillink': + this.pollFolders(); + e.stop(); + return; + + case 'fetchmaillink': + IMPDialog.display({ dialog_load: DIMP.conf.URI_IMP + '/FetchmailDialog' }); + e.stop(); + return; + + case 'appportal': + case 'appoptions': + this.go(id.substring(3)); + e.stop(); + return; + + case 'applogout': + elt.down('A').update('[' + DIMP.text.onlogout + ']'); + DimpCore.logout(); + e.stop(); + return; + + case 'newfolder': + this.createBaseFolder(); + e.stop(); + return; + + case 'button_forward': + case 'button_reply': + this.composeMailbox(id == 'button_reply' ? 'reply' : DIMP.conf.forward_default); + break; + + case 'button_deleted': + case 'button_ham': + case 'button_spam': + this.flag(id.substring(7)); + e.stop(); + return; + + case 'button_other': + DimpCore.DMenu.trigger(e.findElement('A').next(), true); + e.stop(); + return; + + case 'sf_all': + case 'sf_current': + this.updateSearchfilter(id.substring(3), 'folder'); + e.stop(); + return; + + case 'sf_msgall': + case 'sf_from': + case 'sf_to': + case 'sf_subject': + this.updateSearchfilter(id.substring(3), 'msg'); + e.stop(); + return; + + case 'msglistHeader': + this.sort(e); + e.stop(); + return; + + case 'ctx_folder_create': + this.createSubFolder(DimpCore.DMenu.element()); + break; + + case 'ctx_folder_rename': + this.renameFolder(DimpCore.DMenu.element()); + break; + + case 'ctx_folder_empty': + mbox = DimpCore.DMenu.element().readAttribute('mbox'); + DimpCore.DMenu.close(true); + if (window.confirm(DIMP.text.empty_folder)) { + DimpCore.doAction('EmptyFolder', { view: mbox }, null, this._emptyFolderCallback.bind(this)); + } + break; + + case 'ctx_folder_delete': + mbox = DimpCore.DMenu.element().readAttribute('mbox'); + DimpCore.DMenu.close(true); + if (window.confirm(DIMP.text.delete_folder)) { + DimpCore.doAction('DeleteFolder', { view: mbox }, null, this.bcache.get('folderC') || this.bcache.set('folderC', this._folderCallback.bind(this))); + } + break; + + case 'ctx_folder_seen': + case 'ctx_folder_unseen': + this.flag(id == 'ctx_folder_seen' ? 'allSeen' : 'allUnseen', null, DimpCore.DMenu.element().readAttribute('mbox')); + break; + + case 'ctx_folder_poll': + case 'ctx_folder_nopoll': + this.modifyPollFolder(DimpCore.DMenu.element().readAttribute('mbox'), id == 'ctx_folder_poll'); + break; + + case 'ctx_container_create': + this.createSubFolder(DimpCore.DMenu.element()); + break; + + case 'ctx_container_rename': + this.renameFolder(DimpCore.DMenu.element()); + break; + + case 'ctx_message_reply': + case 'ctx_message_reply_all': + case 'ctx_message_reply_list': + case 'ctx_message_forward_all': + case 'ctx_message_forward_body': + case 'ctx_message_forward_attachments': + this.composeMailbox(id.substring(12)); + break; + + case 'ctx_message_seen': + case 'ctx_message_unseen': + case 'ctx_message_flagged': + case 'ctx_message_clear': + case 'ctx_message_spam': + case 'ctx_message_ham': + case 'ctx_message_blacklist': + case 'ctx_message_whitelist': + case 'ctx_message_deleted': + case 'ctx_message_undeleted': + this.flag(id.substring(12)); + break; + + case 'ctx_draft_resume': + this.composeMailbox('resume'); + e.stop(); + return; + + case 'ctx_draft_flagged': + case 'ctx_draft_clear': + case 'ctx_draft_deleted': + case 'ctx_draft_undeleted': + this.flag(id.substring(10)); + break; + + case 'ctx_reply_reply': + case 'ctx_reply_reply_all': + case 'ctx_reply_reply_list': + this.composeMailbox(id.substring(10)); + break; + + case 'ctx_forward_forward_all': + case 'ctx_forward_forward_body': + case 'ctx_forward_forward_attachments': + this.composeMailbox(id.substring(12)); + break; + + case 'previewtoggle': + this.togglePreviewPane(); + break; + + case 'oa_seen': + case 'oa_unseen': + case 'oa_flagged': + case 'oa_clear': + case 'oa_blacklist': + case 'oa_whitelist': + case 'oa_undeleted': + this.flag(id.substring(3)); + break; + + case 'oa_selectall': + this.selectAll(); + break; + + case 'oa_purge_deleted': + this.purgeDeleted(); + break; + + case 'th_expand': + case 'th_collapse': + this._toggleHeaders(id, true); + break; + + case 'msg_newwin': + case 'msg_newwin_options': + this.msgWindow(this.viewport.getViewportSelection().search({ imapuid: { equal: [ DIMP.conf.msg_index ] } , view: { equal: [ DIMP.conf.msg_folder ] } }).get('dataob').first()); + e.stop(); + return; + + case 'qclose': + this.searchfilterClear(false); + e.stop(); + return; + + case 'applicationfolders': + tmp = e.element(); + if (!tmp.hasClassName('custom')) { + tmp.up('LI.custom'); + } + if (tmp) { + this.go('app:' + tmp.down('A').readAttribute('id').substring(3)); + e.stop(); + return; + } + break; + + case 'tabbar': + if (e.element().hasClassName('applicationtab')) { + this.go('app:' + e.element().readAttribute('id').substring(6)); + e.stop(); + return; + } + break; + + case 'dimpmain_portal': + if (e.element().match('H1.header a')) { + this.go('app:' + e.element().readAttribute('app')); + e.stop(); + return; + } + break; + } + + elt = elt.up(); + } + }, + /* Handle rename folder actions. */ renameFolder: function(folder) { @@ -1428,14 +1697,16 @@ var DimpBase = { _createFolderForm: function(action, text) { var n = new Element('FORM', { action: '#', id: 'RB_folder' }).insert( - new Element('P').insert(text) - ).insert( - new Element('INPUT', { type: 'text', size: 15 }) - ).insert( - new Element('INPUT', { type: 'button', className: 'button', value: DIMP.text.ok }).observe('click', action) - ).insert( - new Element('INPUT', { type: 'button', className: 'button', value: DIMP.text.cancel }).observe('click', this.bcache.get('closeRB') || this.bcache.set('closeRB', this._closeRedBox.bind(this))) - ).observe('keydown', function(e) { if ((e.keyCode || e.charCode) == Event.KEY_RETURN) { e.stop(); action(e); } }); + new Element('P').insert(text) + ).insert( + new Element('INPUT', { type: 'text', size: 15 }) + ).insert( + new Element('INPUT', { type: 'button', id: 'RB_Folder_ok', className: 'button', value: DIMP.text.ok }) + ).insert( + new Element('INPUT', { type: 'button', id: 'RB_Folder_cancel', className: 'button', value: DIMP.text.cancel }) + ); + + this.cfolderaction = action; RedBox.overlay = true; RedBox.onDisplay = Form.focusFirstElement.curry(n); @@ -1445,9 +1716,8 @@ var DimpBase = { _closeRedBox: function() { - var c = RedBox.getWindowContents(); - DimpCore.addGC([ c, c.descendants() ].flatten()); RedBox.close(); + this.cfolderaction = null; }, _folderAction: function(folder, e, mode) @@ -1568,7 +1838,6 @@ var DimpBase = { nf = $('normalfolders'), nfheight = nf.getStyle('max-height'); - elts.invoke('observe', 'click', this._handleFolderMouseEvent.bindAsEventListener(this, 'click')); elts.invoke('observe', 'mouseover', this._handleFolderMouseEvent.bindAsEventListener(this, 'over')); if (DIMP.conf.is_ie6) { elts.invoke('observe', 'mouseout', this._handleFolderMouseEvent.bindAsEventListener(this, 'out')); @@ -1985,10 +2254,6 @@ var DimpBase = { /* Onload function. */ _onLoad: function() { - var tmp, - C = DimpCore.clickObserveHandler, - dmenu = DimpCore.DMenu; - if (Horde.dhtmlHistory.initialize()) { Horde.dhtmlHistory.addListener(this.go.bind(this)); } @@ -2011,133 +2276,17 @@ var DimpBase = { /* Add popdown menus. */ DimpCore.addPopdown('button_reply', 'reply'); - dmenu.disable('button_reply_img', true, true); + DimpCore.DMenu.disable('button_reply_img', true, true); DimpCore.addPopdown('button_forward', 'forward'); - dmenu.disable('button_forward_img', true, true); + DimpCore.DMenu.disable('button_forward_img', true, true); DimpCore.addPopdown('button_other', 'otheractions'); - /* Set up click event observers for elements on main page. */ - tmp = $('logo'); - if (tmp.visible()) { - C({ d: tmp.down('a'), f: this.go.bind(this, 'portal') }); - } - - C({ d: $('composelink'), f: DimpCore.compose.bind(DimpCore, 'new') }); - C({ d: $('checkmaillink'), f: this.pollFolders.bind(this) }); - - tmp = $('fetchmaillink'); - if (tmp) { - C({ d: tmp, f: IMPDialog.display.bind(IMPDialog, { dialog_load: DIMP.conf.URI_IMP + '/FetchmailDialog' }) }); - } - - [ 'portal', 'options' ].each(function(a) { - var d = $('app' + a); - if (d) { - C({ d: d, f: this.go.bind(this, a) }); - } - }, this); - tmp = $('applogout'); - if (tmp) { - C({ d: tmp, f: function() { $('applogout').down('A').update('[' + DIMP.text.onlogout + ']'); DimpCore.logout(); } }); - } - - tmp = $('applicationfolders'); - if (tmp) { - tmp.select('li.custom a').each(function(s) { - C({ d: s, f: this.go.bind(this, 'app:' + s.readAttribute('app')) }); - }, this); - } - - C({ d: $('newfolder'), f: this.createBaseFolder.bind(this) }); new Drop('dropbase', this._folderDropConfig); - tmp = $('hometab'); - if (tmp) { - C({ d: tmp, f: this.go.bind(this, 'portal') }); - } - $('tabbar').select('a.applicationtab').each(function(a) { - C({ d: a, f: this.go.bind(this, 'app:' + a.readAttribute('app')) }); - }, this); - C({ d: $('button_reply'), f: this.composeMailbox.bind(this, 'reply'), ns: true }); - C({ d: $('button_forward'), f: this.composeMailbox.bind(this, DIMP.conf.forward_default), ns: true }); - [ 'spam', 'ham', 'deleted' ].each(function(a) { - var d = $('button_' + a); - if (d) { - C({ d: d, f: this.flag.bind(this, a) }); - } - }, this); - C({ d: $('button_compose').down('A'), f: DimpCore.compose.bind(DimpCore, 'new') }); - C({ d: $('button_other'), f: function(e) { dmenu.trigger(e.findElement('A').next(), true); }, p: true }); - C({ d: $('qoptions').down('.qclose a'), f: this.searchfilterClear.bind(this, false) }); - [ 'all', 'current' ].each(function(a) { - var d = $('sf_' + a); - if (d) { - C({ d: d, f: this.updateSearchfilter.bind(this, a, 'folder') }); - } - }, this); - [ 'msgall', 'from', 'to', 'subject' ].each(function(a) { - C({ d: $('sf_' + a), f: this.updateSearchfilter.bind(this, a, 'msg') }); - }, this); - C({ d: $('msglistHeader'), f: this.sort.bind(this), p: true }); - C({ d: $('ctx_folder_create'), f: function() { this.createSubFolder(dmenu.element()); }.bind(this), ns: true }); - C({ d: $('ctx_folder_rename'), f: function() { this.renameFolder(dmenu.element()); }.bind(this), ns: true }); - C({ d: $('ctx_folder_empty'), f: function() { var mbox = dmenu.element().readAttribute('mbox'); dmenu.close(true); if (window.confirm(DIMP.text.empty_folder)) { DimpCore.doAction('EmptyFolder', { view: mbox }, null, this._emptyFolderCallback.bind(this)); } }.bind(this), ns: true }); - C({ d: $('ctx_folder_delete'), f: function() { var mbox = dmenu.element().readAttribute('mbox'); dmenu.close(true); if (window.confirm(DIMP.text.delete_folder)) { DimpCore.doAction('DeleteFolder', { view: mbox }, null, this.bcache.get('folderC') || this.bcache.set('folderC', this._folderCallback.bind(this))); } }.bind(this), ns: true }); - [ 'ctx_folder_seen', 'ctx_folder_unseen' ].each(function(a) { - C({ d: $(a), f: function(type) { this.flag(type, null, dmenu.element().readAttribute('mbox')); }.bind(this, a == 'ctx_folder_seen' ? 'allSeen' : 'allUnseen'), ns: true }); - }, this); - [ 'ctx_folder_poll', 'ctx_folder_nopoll' ].each(function(a) { - C({ d: $(a), f: function(modify) { this.modifyPollFolder(dmenu.element().readAttribute('mbox'), modify); }.bind(this, a == 'ctx_folder_poll'), ns: true }); - }, this); - C({ d: $('ctx_container_create'), f: function() { this.createSubFolder(dmenu.element()); }.bind(this), ns: true }); - C({ d: $('ctx_container_rename'), f: function() { this.renameFolder(dmenu.element()); }.bind(this), ns: true }); - [ 'reply', 'reply_all', 'reply_list', 'forward_all', 'forward_body', 'forward_attachments' ].each(function(a) { - C({ d: $('ctx_message_' + a), f: this.composeMailbox.bind(this, a), ns: true }); - }, this); - [ 'seen', 'unseen', 'flagged', 'clear', 'spam', 'ham', 'blacklist', 'whitelist', 'deleted', 'undeleted' ].each(function(a) { - var d = $('ctx_message_' + a); - if (d) { - C({ d: d, f: this.flag.bind(this, a), ns: true }); - } - }, this); - C({ d: $('ctx_draft_resume'), f: this.composeMailbox.bind(this, 'resume') }); - [ 'flagged', 'clear', 'deleted', 'undeleted' ].each(function(a) { - var d = $('ctx_draft_' + a); - if (d) { - C({ d: d, f: this.flag.bind(this, a), ns: true }); - } - }, this); - [ 'reply', 'reply_all', 'reply_list' ].each(function(a) { - C({ d: $('ctx_reply_' + a), f: this.composeMailbox.bind(this, a), ns: true }); - }, this); - [ 'forward_all', 'forward_body', 'forward_attachments' ].each(function(a) { - C({ d: $('ctx_forward_' + a), f: this.composeMailbox.bind(this, a), ns: true }); - }, this); - C({ d: $('previewtoggle'), f: this.togglePreviewPane.bind(this), ns: true }); - [ 'seen', 'unseen', 'flagged', 'clear', 'blacklist', 'whitelist', 'undeleted' ].each(function(a) { - var d = $('oa_' + a); - if (d) { - C({ d: d, f: this.flag.bind(this, a), ns: true }); - } - }, this); - C({ d: $('oa_selectall'), f: this.selectAll.bind(this), ns: true }); - tmp = $('oa_purge_deleted'); - if (tmp) { - C({ d: tmp, f: this.purgeDeleted.bind(this), ns: true }); - } - - $('th_expand', 'th_collapse').each(function(a) { - C({ d: a, f: this._toggleHeaders.bind(this, a, true), ns: true }); - }.bind(this)); if (DIMP.conf.toggle_pref) { this._toggleHeaders($('th_expand')); } - $('msg_newwin', 'msg_newwin_options').compact().each(function(a) { - C({ d: a, f: function() { this.msgWindow(this.viewport.getViewportSelection().search({ imapuid: { equal: [ DIMP.conf.msg_index ] } , view: { equal: [ DIMP.conf.msg_folder ] } }).get('dataob').first()); }.bind(this) }); - }, this); - - DimpCore.messageOnLoad(); this._resizeIE6(); }, @@ -2260,7 +2409,12 @@ document.observe('dom:loaded', function() { DimpBase.setPollFolders(); /* Bind key shortcuts. */ - document.observe('keydown', DimpBase._keydownHandler.bind(DimpBase)); + document.observe('keydown', DimpBase._keydownHandler.bindAsEventListener(DimpBase)); + document.observe('keyup', DimpBase._keyupHandler.bindAsEventListener(DimpBase)); + + /* Bind mouse clicks. */ + document.observe('click', DimpBase._clickHandler.bindAsEventListener(DimpBase)); + document.observe('dblclick', DimpBase._clickHandler.bindAsEventListener(DimpBase, true)); /* Resize elements on window size change. */ Event.observe(window, 'resize', DimpBase._onResize.bind(DimpBase)); diff --git a/imp/js/src/DimpCore.js b/imp/js/src/DimpCore.js index 61f4a4247..60ec52be8 100644 --- a/imp/js/src/DimpCore.js +++ b/imp/js/src/DimpCore.js @@ -138,7 +138,7 @@ DimpCore = { } uids = tmp; } - params.set('uid', DimpCore.toRangeString(uids)); + params.set('uid', this.toRangeString(uids)); } if (DIMP.conf.SESSION_ID) { params.update(DIMP.conf.SESSION_ID.toQueryParams()); @@ -451,53 +451,12 @@ DimpCore = { [ id.select('.address'), id.select('.largeaddrtoggle') ].flatten().compact().each(this.removeMouseEvents.bind(this)); }, - /* Add event observers to message output. Adds observers used in both - * the base page and the popup message window. */ - messageOnLoad: function() - { - var C = this.clickObserveHandler, tmp; - - if ($('partlist')) { - C({ d: $('partlist_col').up(), f: function() { $('partlist', 'partlist_col', 'partlist_exp').invoke('toggle'); } }); - } - if (tmp = $('msg_print')) { - C({ d: tmp, f: function() { window.print(); } }); - } - if (tmp = $('msg_view_source')) { - C({ d: tmp, f: function() { view(DimpCore.addURLParam(DIMP.conf.URI_VIEW, { index: DIMP.conf.msg_index, mailbox: DIMP.conf.msg_folder, actionID: 'view_source', id: 0 }, true), DIMP.conf.msg_index + '|' + DIMP.conf.msg_folder) } }); - } - C({ d: $('ctx_contacts_new'), f: function() { this.compose('new', { to: this.DMenu.element().readAttribute('address') }); }.bind(this), ns: true }); - C({ d: $('ctx_contacts_add'), f: function() { this.doAction('AddContact', { name: this.DMenu.element().readAttribute('personal'), email: this.DMenu.element().readAttribute('email') }, null, true); }.bind(this), ns: true }); - if ($('alertslog')) { - C({ d: $('alertsloglink'), f: this.toggleAlertsLog.bind(this) }); - } - }, - /* Utility functions. */ addGC: function(elt) { this.remove_gc = this.remove_gc.concat(elt); }, - // o: (object) Contains the following items: - // 'd' - (required) The DOM element - // 'f' - (required) The function to bind to the click event - // 'ns' - (optional) If set, don't stop the event's propogation - // 'p' - (optional) If set, passes in the event object to the called - // function - clickObserveHandler: function(o) - { - return o.d.observe('click', DimpCore._clickFunc.curry(o)); - }, - - _clickFunc: function(o, e) - { - o.p ? o.f(e) : o.f(); - if (!o.ns) { - e.stop(); - } - }, - addURLParam: function(url, params) { var q = url.indexOf('?'); @@ -522,6 +481,56 @@ DimpCore = { } else { DimpBase.loadPreview(null, params); } + }, + + /* Mouse click handler. */ + _clickHandler: function(e) + { + if (e.isRightClick()) { + return; + } + + var elt = e.element(), id, tmp; + + while (Object.isElement(elt)) { + id = elt.readAttribute('id'); + + switch (id) { + case 'partlist_toggle': + tmp = $('partlist'); + $('partlist_col', 'partlist_exp').invoke('toggle'); + if (tmp.visible()) { + Effect.BlindUp(tmp, { duration: 0.2 }); + } else { + Effect.BlindDown(tmp, { duration: 0.2 }); + } + e.stop(); + return; + + case 'msg_print': + window.print(); + e.stop(); + return; + + case 'msg_view_source': + this.popupWindow(this.addURLParam(DIMP.conf.URI_VIEW, { index: DIMP.conf.msg_index, mailbox: DIMP.conf.msg_folder, actionID: 'view_source', id: 0 }, true), DIMP.conf.msg_index + '|' + DIMP.conf.msg_folder); + break; + + case 'ctx_contacts_new': + this.compose('new', { to: this.DMenu.element().readAttribute('address') }); + break; + + case 'ctx_contacts_add': + this.doAction('AddContact', { name: this.DMenu.element().readAttribute('personal'), email: this.DMenu.element().readAttribute('email') }, null, true); + break; + + case 'alertsloglink': + this.toggleAlertsLog(); + break; + } + + elt = elt.up(); + } } }; @@ -561,6 +570,9 @@ document.observe('dom:loaded', function() { } } }, 10); + + /* Add click handler. */ + document.observe('click', DimpCore._clickHandler.bindAsEventListener(DimpCore)); }); Event.observe(window, 'load', function() { @@ -634,12 +646,3 @@ Object.extend(String.prototype, { }); } }); - -/** Functions overriding IMP/prototypejs JS functions. **/ - -/* We need to replace the IMP javascript for this function with code that - * calls the correct DIMP functions. */ -function popup_imp(url, w, h, args) -{ - DimpCore.compose('new', args.toQueryParams().toObject()); -} diff --git a/imp/js/src/compose-dimp.js b/imp/js/src/compose-dimp.js index 8961cc967..9b643dcbe 100644 --- a/imp/js/src/compose-dimp.js +++ b/imp/js/src/compose-dimp.js @@ -495,14 +495,10 @@ var DimpCompose = { { var span = new Element('SPAN').insert(name), div = new Element('DIV').insert(span).insert(' [' + type + '] (' + size + ' KB) '), - input = new Element('INPUT', { type: 'button', atc_id: atc_num, value: DIMP.text_compose.remove }), - C = DimpCore.clickObserveHandler; + input = new Element('INPUT', { type: 'button', atc_id: atc_num, value: DIMP.text_compose.remove }); div.insert(input); $('attach_list').insert(div); - C({ d: input, f: this.removeAttach.bind(this, [ input.up() ]) }); - if (type != 'application/octet-stream') { - C({ d: span.addClassName('attachName'), f: function() { view(DimpCore.addURLParam(DIMP.conf.URI_VIEW, { composeCache: $F('composeCache'), actionID: 'compose_attach_preview', id: atc_num }), $F('composeCache') + '|' + atc_num) } }); - } + this.resizeMsgArea(); }, @@ -629,6 +625,57 @@ var DimpCompose = { openAddressbook: function() { window.open(DIMP.conf_compose.abook_url, 'contacts', 'toolbar=no,location=no,status=no,scrollbars=yes,resizable=yes,width=550,height=300,left=100,top=100'); + }, + + /* Click observe handler. */ + + _clickHandler: function(e) + { + if (e.isRightClick()) { + return; + } + + var elt = e.element(), id, tmp; + + while (Object.isElement(elt)) { + id = elt.readAttribute('id'); + + switch (id) { + case 'togglebcc': + case 'togglecc': + this.toggleCC(id.substring(6)); + this.resizeMsgArea(); + break; + + case 'compose_close': + this.confirmCancel(); + break; + + case 'draft_button': + case 'send_button': + this.uniqueSubmit(id == 'send_button' ? 'send_message' : 'save_draft'); + break; + + case 'htmlcheckbox': + this.toggleHtmlCheckbox(); + break; + } + + /* + if (DIMP.conf_compose.abook_url) { + $('sendto', 'sendcc', 'sendbcc').each(function(a) { + C({ d: a.down('TD.label SPAN').addClassName('composeAddrbook'), f: DC.openAddressbook.bind(DC) }); + }); + } + + C({ d: input, f: this.removeAttach.bind(this, [ input.up() ]) }); + if (type != 'application/octet-stream') { + C({ d: span.addClassName('attachName'), f: function() { view(DimpCore.addURLParam(DIMP.conf.URI_VIEW, { composeCache: $F('composeCache'), actionID: 'compose_attach_preview', id: atc_num }), $F('composeCache') + '|' + atc_num) } }); + } + */ + + elt = elt.up(); + } } }, @@ -676,8 +723,7 @@ ResizeTextArea = Class.create({ document.observe('dom:loaded', function() { var tmp, DC = DimpCompose, - boundResize = DC.resizeMsgArea.bind(DC), - C = DimpCore.clickObserveHandler; + boundResize = DC.resizeMsgArea.bind(DC); DC.resizeMsgArea(); DC.initializeSpellChecker(); @@ -695,24 +741,8 @@ document.observe('dom:loaded', function() { $('submit_frame').writeAttribute({ position: 'absolute', width: '1px', height: '1px' }).setStyle({ left: '-999px' }).show(); } - /* Attach click handlers. */ - if (tmp = $('compose_close')) { - C({ d: tmp, f: DC.confirmCancel.bind(DC) }); - } - C({ d: $('send_button'), f: DC.uniqueSubmit.bind(DC, 'send_message') }); - C({ d: $('draft_button'), f: DC.uniqueSubmit.bind(DC, 'save_draft') }); - [ 'cc', 'bcc' ].each(function(a) { - C({ d: $('toggle' + a), f: DC.toggleCC.bind(DC, a) }); - }); - if (tmp = $('htmlcheckbox')) { - C({ d: tmp, f: DC.toggleHtmlCheckbox.bind(DC), ns: true }); - } - - if (DIMP.conf_compose.abook_url) { - $('sendto', 'sendcc', 'sendbcc').each(function(a) { - C({ d: a.down('TD.label SPAN').addClassName('composeAddrbook'), f: DC.openAddressbook.bind(DC) }); - }); - } + /* Mouse click handler. */ + document.observe('click', DC._clickHandler.bindAsEventListener(DC)); /* Only allow submit through send button. */ $('compose').observe('submit', Event.stop); @@ -720,9 +750,5 @@ document.observe('dom:loaded', function() { /* Attach other handlers. */ $('identity').observe('change', DC.change_identity.bind(DC)); - // Various events that may cause the textarea to grow larger than the - // window size. - $('togglecc').observe('click', boundResize); - $('togglebcc').observe('click', boundResize); Event.observe(window, 'resize', boundResize); }); diff --git a/imp/js/src/fullmessage-dimp.js b/imp/js/src/fullmessage-dimp.js index 9442a8b15..058ea73b0 100644 --- a/imp/js/src/fullmessage-dimp.js +++ b/imp/js/src/fullmessage-dimp.js @@ -64,13 +64,62 @@ var DimpFullmessage = { if (r.imp_compose) { $('composeCache').setValue(r.imp_compose); } + }, + + /* Mouse click handler. */ + _clickHandler: function(e) + { + if (e.isRightClick()) { + return; + } + + var elt = e.element(), id; + + while (Object.isElement(elt)) { + id = elt.readAttribute('id'); + + switch (id) { + case 'windowclose': + window.close(); + e.stop(); + exit; + + case 'forward_link': + case 'reply_link': + this.quickreply(id == 'reply_link' ? 'reply' : DIMP.conf.forward_default); + e.stop(); + exit; + + case 'button_deleted': + case 'button_ham': + case 'button_spam': + DIMP.baseWindow.DimpBase.flag(id.substring(7), DIMP.conf.msg_index, DIMP.conf.msg_folder); + window.close(); + e.stop(); + exit; + + case 'ctx_replypopdown_reply': + case 'ctx_replypopdown_reply_all': + case 'ctx_replypopdown_reply_list': + this.quickreply(id.substring(17)); + break; + + case 'ctx_fwdpopdown_forward_all': + case 'ctx_fwdpopdown_forward_body': + case 'ctx_fwdpopdown_forward_attachments': + this.quickreply(id.substring(15)); + break; + } + + // C({ d: $('qreply').select('div.headercloseimg img').first(), f: DimpCompose.confirmCancel.bind(DimpCompose) }); + elt = elt.up(); + } } }; document.observe('dom:loaded', function() { window.focus(); - DimpCore.messageOnLoad(); DimpCore.addPopdown('reply_link', 'replypopdown'); DimpCore.addPopdown('forward_link', 'fwdpopdown'); @@ -83,24 +132,5 @@ document.observe('dom:loaded', function() { }); /* Set up click handlers. */ - var C = DimpCore.clickObserveHandler; - C({ d: $('windowclose'), f: function() { window.close(); } }); - C({ d: $('reply_link'), f: DimpFullmessage.quickreply.bind(DimpFullmessage, 'reply') }); - C({ d: $('forward_link'), f: DimpFullmessage.quickreply.bind(DimpFullmessage, DIMP.conf.forward_default) }); - [ 'spam', 'ham', 'deleted' ].each(function(a) { - var d = $('button_' + a); - if (d) { - C({ d: d, f: function(a) { DIMP.baseWindow.DimpBase.flag(a, DIMP.conf.msg_index, DIMP.conf.msg_folder); window.close(); }.curry(a) }); - } - }); - C({ d: $('qreply').select('div.headercloseimg img').first(), f: DimpCompose.confirmCancel.bind(DimpCompose) }); - [ 'reply', 'reply_all', 'reply_list' ].each(function(a) { - var d = $('ctx_replypopdown_' + a); - if (d) { - C({ d: d, f: DimpFullmessage.quickreply.bind(DimpFullmessage, a), ns: true }); - } - }); - [ 'forward_all', 'forward_body', 'forward_attachments' ].each(function(a) { - C({ d: $('ctx_fwdpopdown_' + a), f: DimpFullmessage.quickreply.bind(DimpFullmessage, a), ns: true }); - }); + document.observe('click', DimpFullmessage.clickHandler.bindAsEventListener(DimpFullmessage)); }); diff --git a/imp/templates/chunks/message.php b/imp/templates/chunks/message.php index d1940dde1..f1607a5a5 100644 --- a/imp/templates/chunks/message.php +++ b/imp/templates/chunks/message.php @@ -69,7 +69,7 @@ function _createDAfmsg($text, $image, $id, $class = '', $show_text = true) - + diff --git a/imp/templates/index/index.inc b/imp/templates/index/index.inc index 8aacf92fc..f532b5f38 100644 --- a/imp/templates/index/index.inc +++ b/imp/templates/index/index.inc @@ -58,7 +58,7 @@ function _simpleButton($id, $text, $image, $imagedir = null)
- +
    @@ -91,7 +91,7 @@ function _simpleButton($id, $text, $image, $imagedir = null)
  • <?php echo $val['name'] ?> - +
@@ -143,7 +143,7 @@ function _simpleButton($id, $text, $image, $imagedir = null) > - <?php echo $val['name'] ?> + <?php echo $val['name'] ?> $menu_item): if ($menu_item == 'separator') continue; ?> @@ -209,7 +209,7 @@ function _simpleButton($id, $text, $image, $imagedir = null)
- x + x @@ -316,7 +316,7 @@ function _simpleButton($id, $text, $image, $imagedir = null) - +
diff --git a/imp/themes/screen-dimp.css b/imp/themes/screen-dimp.css index 89f00fe8d..6a2a20e60 100644 --- a/imp/themes/screen-dimp.css +++ b/imp/themes/screen-dimp.css @@ -725,8 +725,8 @@ div.dimpActionsCompose { padding: 4px; } .mimeStatusMessage { - background: #ffc; - border: 1px #fffba4 solid; + margin-bottom: 4px; + margin-top: 2px; } .mimePartInfo { background: #efefef; @@ -1074,7 +1074,7 @@ a.address:hover img { -webkit-border-radius: 5px; padding: 1px 4px; } -#qoptions .qclose a, #qoptions .qclose a:visited { +#qclose a, #qclose a:visited { float: right; margin-top: -2px; width: 10px; @@ -1092,7 +1092,7 @@ a.address:hover img { padding: 0px 2px 2px 4px; text-decoration: none; } -#qoptions .qclose a:hover { +#qclose a:hover { background: #fff; } #qoptions .qlabel {