From: Michael M Slusarz Date: Fri, 13 Feb 2009 09:08:08 +0000 (-0700) Subject: Rework contextmenu click event firing. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=864f4454f2ad3a2dd2c963b92def28a84a8a2de6;p=horde.git Rework contextmenu click event firing. Update contextmenus in full message view to match style used on base page. Load contacts contextmenu images from CSS. --- diff --git a/imp/js/src/ContextSensitive.js b/imp/js/src/ContextSensitive.js index b50498af3..3b5d0b9e6 100644 --- a/imp/js/src/ContextSensitive.js +++ b/imp/js/src/ContextSensitive.js @@ -32,7 +32,7 @@ var ContextSensitive = Class.create({ initialize: function(opts) { - this.basectx = this.lasttarget = this.target = null; + this.basectx = this.target = null; this.elements = $H(); this.submenus = $H(); this.current = []; @@ -76,23 +76,17 @@ var ContextSensitive = Class.create({ */ _closeSubmenu: function(idx, immediate) { - this.current.splice(idx, this.current.size() - idx).each(function(s) { - if (immediate) { - $(s).hide(); - } else { - Effect.Fade(s, { duration: 0.2, queue: { position: 'end', scope: 'cm_' + s, limit: 2 } }); - } - }); - this.target = this.current[idx]; - this.basectx = null; - }, - - /** - * Get the element that triggered the current context menu (if any). - */ - element: function(current) - { - return current ? this.target : this.lasttarget; + if (this.current.size()) { + this.current.splice(idx, this.current.size() - idx).each(function(s) { + if (immediate) { + $(s).hide(); + } else { + Effect.Fade(s, { duration: 0.2, queue: { position: 'end', scope: 'cm_' + s, limit: 2 } }); + } + }); + this.target = this.current[idx]; + this.basectx = null; + } }, /** @@ -130,12 +124,36 @@ var ContextSensitive = Class.create({ */ _leftClickHandler: function(e) { + var curr, elt, elt_up; + // Check for a right click. FF on Linux triggers an onclick event even // w/a right click, so disregard. if (e.isRightClick()) { return; } + // Check for click in open contextmenu. + if (this.current.size()) { + elt = e.element(); + elt_up = elt.up(); + + if (elt_up.hasClassName('contextMenu')) { + e.stop(); + + if (elt.hasClassName('contextSubmenu') && + elt_up.readAttribute('id') != this.currentmenu()) { + this._closeSubmenu(this.current.indexOf(elt.readAttribute('id'))); + } else { + curr = $(this.target); + this.close(true); + if (this.opts.onClick) { + this.opts.onClick(elt.readAttribute('id'), curr); + } + } + return; + } + } + // Check if the mouseclick is registered to an element now. this._rightClickHandler(e, true); }, @@ -164,10 +182,7 @@ var ContextSensitive = Class.create({ // Return if event not found or event is disabled. if (!ctx || ctx.disable) { - // Return if this is a click on a submenu item. - if (!ctx || !ctx.hasClassName('contextSubmenu')) { - this.close(); - } + this.close(); return false; } @@ -187,7 +202,7 @@ var ContextSensitive = Class.create({ // Register the current element that will be shown and the element // that was clicked on. this.close(); - this.lasttarget = this.target = $(ctx.id); + this.target = ctx.id; offset = ctx.opts.offset; if (!offset && (Object.isUndefined(x) || Object.isUndefined(y))) { @@ -245,6 +260,7 @@ var ContextSensitive = Class.create({ document.observe('mouseover', this._mouseoverHandler.bindAsEventListener(this)); } this.submenus.set(id, submenu); + $(submenu).addClassName('contextMenu'); $(id).addClassName('contextSubmenu').insert({ top: new Element('SPAN', { className: 'contextExpand' }) }); } }, diff --git a/imp/js/src/DimpBase.js b/imp/js/src/DimpBase.js index 4b7a64f44..665d56ac2 100644 --- a/imp/js/src/DimpBase.js +++ b/imp/js/src/DimpBase.js @@ -600,7 +600,114 @@ var DimpBase = { DimpCore.DMenu.removeElement($(elt).identify()); }, - _onMenuShow: function(ctx_id, ctx) + contextOnClick: function(parentfunc, id, elt) + { + switch (id) { + case 'ctx_folder_create': + this.createSubFolder(elt); + break; + + case 'ctx_container_rename': + case 'ctx_folder_rename': + this.renameFolder(elt); + break; + + case 'ctx_folder_empty': + mbox = elt.readAttribute('mbox'); + if (window.confirm(DIMP.text.empty_folder)) { + DimpCore.doAction('EmptyFolder', { view: mbox }, null, this._emptyFolderCallback.bind(this)); + } + break; + + case 'ctx_folder_delete': + mbox = elt.readAttribute('mbox'); + 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', { mailbox: elt.readAttribute('mbox') }); + break; + + case 'ctx_folder_poll': + case 'ctx_folder_nopoll': + this.modifyPollFolder(elt.readAttribute('mbox'), id == 'ctx_folder_poll'); + break; + + case 'ctx_container_create': + this.createSubFolder(elt); + break; + + 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'); + break; + + 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 'flag_seen': + case 'flag_unseen': + case 'flag_flagged': + case 'flag_clear': + case 'flag_answered': + case 'flag_unanswered': + case 'flag_draft': + case 'flag_notdraft': + this.flag(id.substring(5)); + break; + + 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; + + default: + parentfunc(id, elt); + break; + } + }, + + contextOnShow: function(parentfunc, ctx_id, ctx) { var elts, folder, ob, sel, tmp; @@ -633,6 +740,10 @@ var DimpBase = { case 'ctx_otheractions': $('oa_setflag', 'oa_sep1', 'oa_blacklist', 'oa_whitelist', 'oa_sep2', 'oa_undeleted').compact().invoke(this.viewport.getSelected().size() ? 'show' : 'hide'); break; + + default: + parentfunc(ctx_id, ctx); + break; } }, @@ -1458,110 +1569,6 @@ var DimpBase = { 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', { mailbox: 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_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 'flag_seen': - case 'flag_unseen': - case 'flag_flagged': - case 'flag_clear': - case 'flag_answered': - case 'flag_unanswered': - case 'flag_draft': - case 'flag_notdraft': - this.flag(id.substring(5)); - break; - - 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(elt, true); @@ -2250,16 +2257,16 @@ var DimpBase = { /* Onload function. */ onDomLoad: function() { - var DC = DimpCore, DM = DimpCore.DMenu; + DimpCore.init(); - DC.init({ DMenu_onShow: this._onMenuShow.bind(this) }); + var DM = DimpCore.DMenu; $('dimpLoading').hide(); $('dimpPage').show(); /* Create the folder list. Any pending notifications will be caught * via the return from this call. */ - DC.doAction('ListFolders', {}, null, this._folderLoadCallback.bind(this)); + DimpCore.doAction('ListFolders', {}, null, this._folderLoadCallback.bind(this)); /* Start message list loading as soon as possible. */ if (Horde.dhtmlHistory.initialize()) { @@ -2431,6 +2438,10 @@ DimpCore.onDoActionComplete = function(r) { } }; +/* ContextSensitive functions. */ +DimpCore.contextOnClick = DimpCore.contextOnClick.wrap(DimpBase.contextOnClick.bind(DimpBase)); +DimpCore.contextOnShow = DimpCore.contextOnShow.wrap(DimpBase.contextOnShow.bind(DimpBase)); + /* Initialize global event handlers. */ document.observe('dom:loaded', DimpBase.onDomLoad.bind(DimpBase)); document.observe('keydown', DimpBase.keydownHandler.bindAsEventListener(DimpBase)); diff --git a/imp/js/src/DimpCore.js b/imp/js/src/DimpCore.js index bd6fe5da6..1ccee0ec3 100644 --- a/imp/js/src/DimpCore.js +++ b/imp/js/src/DimpCore.js @@ -474,14 +474,6 @@ DimpCore = { 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; @@ -500,13 +492,27 @@ DimpCore = { } }, - /* Dimp initialization function. */ - init: function(opts) + // By default, no context onShow action + contextOnShow: Prototype.emptyFunction, + + contextOnClick: function(id, elt) { - opts = opts || {}; + switch (id) { + case 'ctx_contacts_new': + this.compose('new', { to: elt.readAttribute('address') }); + break; + + case 'ctx_contacts_add': + this.doAction('AddContact', { name: elt.readAttribute('personal'), email: elt.readAttribute('email') }, null, true); + break; + } + }, + /* DIMP initialization function. */ + init: function() + { if (typeof ContextSensitive != 'undefined') { - this.DMenu = new ContextSensitive({ onShow: opts.DMenu_onShow }); + this.DMenu = new ContextSensitive({ onClick: this.contextOnClick, onShow: this.contextOnShow }); } /* Don't do additional onload stuff if we are in a popup. We need a diff --git a/imp/js/src/fullmessage-dimp.js b/imp/js/src/fullmessage-dimp.js index b8b45c477..42fa7a88f 100644 --- a/imp/js/src/fullmessage-dimp.js +++ b/imp/js/src/fullmessage-dimp.js @@ -66,7 +66,7 @@ var DimpFullmessage = { } }, - /* Mouse click handler. */ + /* Click handlers. */ clickHandler: function(e) { if (e.isRightClick()) { @@ -98,18 +98,6 @@ var DimpFullmessage = { e.stop(); return; - 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; - case 'qreply': if (orig.match('DIV.headercloseimg IMG')) { DimpCompose.confirmCancel(); @@ -121,6 +109,27 @@ var DimpFullmessage = { } }, + contextOnClick: function(parentfunc, id, elt) + { + switch (id) { + case 'ctx_reply_reply': + case 'ctx_reply_reply_all': + case 'ctx_reply_reply_list': + this.quickreply(id.substring(10)); + break; + + case 'ctx_forward_forward_all': + case 'ctx_forward_forward_body': + case 'ctx_forward_forward_attachments': + this.quickreply(id.substring(12)); + break; + + default: + parentfunc(id, elt); + break; + } + }, + /* Add a popdown menu to a dimpactions button. */ _addPopdown: function(bid, ctx) { @@ -133,8 +142,8 @@ var DimpFullmessage = { { DimpCore.init(); - this.addPopdown('reply_link', 'replypopdown'); - this.addPopdown('forward_link', 'fwdpopdown'); + this._addPopdown('reply_link', 'replypopdown'); + this._addPopdown('forward_link', 'fwdpopdown'); /* Set up address linking. */ [ 'from', 'to', 'cc', 'bcc', 'replyTo' ].each(function(a) { @@ -147,5 +156,9 @@ var DimpFullmessage = { }; +/* ContextSensitive functions. */ +DimpCore.contextOnClick = DimpCore.contextOnClick.wrap(DimpFullmessage.contextOnClick.bind(DimpFullmessage)); + +/* Attach event handlers. */ document.observe('dom:loaded', DimpFullmessage.onDomLoad.bind(DimpFullmessage)); document.observe('click', DimpFullmessage.clickHandler.bindAsEventListener(DimpFullmessage)); diff --git a/imp/templates/chunks/message.php b/imp/templates/chunks/message.php index 2aa7d154d..52fc6aad4 100644 --- a/imp/templates/chunks/message.php +++ b/imp/templates/chunks/message.php @@ -105,22 +105,22 @@ function _createDAfmsg($text, $image, $id, $class = '', $show_text = true) diff --git a/imp/templates/index/index-dimp.inc b/imp/templates/index/index-dimp.inc index 7c46ae74d..c0ec2b820 100644 --- a/imp/templates/index/index-dimp.inc +++ b/imp/templates/index/index-dimp.inc @@ -431,8 +431,8 @@ function _simpleButton($id, $text, $image, $imagedir = null)
diff --git a/imp/themes/screen-dimp.css b/imp/themes/screen-dimp.css index b4e430055..642e59b98 100644 --- a/imp/themes/screen-dimp.css +++ b/imp/themes/screen-dimp.css @@ -1044,6 +1044,12 @@ span.iconImg, span.contextImg, span.spellcheckPopdownImg { #ctx_message_whitelist span.contextImg, #oa_whitelist span.contextImg { background-image: url("graphics/whitelist.png"); } +#ctx_contacts_new span.contextImg { + background-image: url("graphics/compose.png"); +} +#ctx_contacts_add span.contextImg { + background-image: url("graphics/add_contact.png"); +} /* Other images */ #msg_newwin span.iconImg, #msg_newwin_options span.iconImg { diff --git a/imp/themes/silver/screen-dimp.css b/imp/themes/silver/screen-dimp.css index bea60c0e6..98b67bf25 100644 --- a/imp/themes/silver/screen-dimp.css +++ b/imp/themes/silver/screen-dimp.css @@ -140,6 +140,12 @@ #ctx_message_whitelist span.contextImg, #oa_whitelist span.contextImg { background-image: url("graphics/whitelist.png"); } +#ctx_contacts_new span.contextImg { + background-image: url("graphics/compose.png"); +} +#ctx_contacts_add span.contextImg { + background-image: url("graphics/add_contact.png"); +} /* Other images */ #msg_newwin span.iconImg, #msg_newwin_options span.iconImg {