Rework contextmenu click event firing.
authorMichael M Slusarz <slusarz@curecanti.org>
Fri, 13 Feb 2009 09:08:08 +0000 (02:08 -0700)
committerMichael M Slusarz <slusarz@curecanti.org>
Wed, 18 Feb 2009 06:40:14 +0000 (23:40 -0700)
Update contextmenus in full message view to match style used on base
page.
Load contacts contextmenu images from CSS.

imp/js/src/ContextSensitive.js
imp/js/src/DimpBase.js
imp/js/src/DimpCore.js
imp/js/src/fullmessage-dimp.js
imp/templates/chunks/message.php
imp/templates/index/index-dimp.inc
imp/themes/screen-dimp.css
imp/themes/silver/screen-dimp.css

index b50498a..3b5d0b9 100644 (file)
@@ -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' }) });
         }
     },
index 4b7a64f..665d56a 100644 (file)
@@ -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));
index bd6fe5d..1ccee0e 100644 (file)
@@ -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
index b8b45c4..42fa7a8 100644 (file)
@@ -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));
index 2aa7d15..52fc6aa 100644 (file)
@@ -105,22 +105,22 @@ function _createDAfmsg($text, $image, $id, $class = '', $show_text = true)
 </div>
 
 <div class="context" id="ctx_replypopdown" style="display:none">
- <div><?php _createDAfmsg(_("To Sender"), 'reply.png', 'ctx_replypopdown_reply') ?></div>
- <div><?php _createDAfmsg(_("To All"), 'replyall.png', 'ctx_replypopdown_reply_all') ?></div>
+ <a id="ctx_reply_reply"><span class="contextImg"></span><?php echo _("To Sender") ?></a>
+ <a id="ctx_reply_reply_all"><span class="contextImg"></span><?php echo _("To All") ?></a>
 <?php if ($show_msg_result['list_info']['exists']): ?>
- <div><?php _createDAfmsg(_("To List"), 'replyall.png', 'ctx_replypopdown_reply_list') ?></div>
+ <a id="ctx_reply_reply_list"><span class="contextImg"></span><?php echo _("To List") ?></a>
 <?php endif; ?>
 </div>
 
 <div class="context" id="ctx_fwdpopdown" style="display:none">
- <div><?php _createDAfmsg(_("Entire Message"), 'forward.png', 'ctx_fwdpopdown_forward_all') ?></div>
- <div><?php _createDAfmsg(_("Body Text Only"), 'forward.png', 'ctx_fwdpopdown_forward_body') ?></div>
- <div><?php _createDAfmsg(_("Attachments Only"), 'forward.png', 'ctx_fwdpopdown_forward_attachments') ?></div>
+ <a id="ctx_forward_forward_all"><span class="contextImg"></span><?php echo _("Entire Message") ?></a>
+ <a id="ctx_forward_forward_body"><span class="contextImg"></span><?php echo _("Body Text Only") ?></a>
+ <a id="ctx_forward_forward_attachments"><span class="contextImg"></span><?php echo _("Attachments Only") ?></a>
 </div>
 
 <div class="context" id="ctx_contacts" style="display:none">
- <div><?php _createDAfmsg(_("New Message"), 'compose.png', 'ctx_contacts_new') ?></div>
- <div><?php _createDAfmsg(_("Add to Address Book"), 'add_contact.png', 'ctx_contacts_add') ?></div>
+ <a id="ctx_contacts_new"><span class="contextImg"></span><?php echo _("New Message") ?></a>
+ <a id="ctx_contacts_add"><span class="contextImg"></span><?php echo _("Add to Address Book") ?></a>
 </div>
 
 <span id="popdown_img" class="iconImg popdownImg popdown" style="display:none"></span>
index 7c46ae7..c0ec2b8 100644 (file)
@@ -431,8 +431,8 @@ function _simpleButton($id, $text, $image, $imagedir = null)
 </div>
 
 <div class="context" id="ctx_contacts" style="display:none">
- <div><?php _createDA(_("New Message"), 'compose.png', 'ctx_contacts_new') ?></div>
- <div><?php _createDA(_("Add to Address Book"), 'add_contact.png', 'ctx_contacts_add') ?></div>
+ <a id="ctx_contacts_new"><span class="contextImg"></span><?php echo _("New Message") ?></a>
+ <a id="ctx_contacts_add"><span class="contextImg"></span><?php echo _("Add to Address Book") ?></a>
 </div>
 
 <div style="display:none">
index b4e4300..642e59b 100644 (file)
@@ -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 {
index bea60c0..98b67bf 100644 (file)
 #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 {