Mercurial > hg > rc1
view plugins/contextmenu/contextmenu.js @ 0:1e000243b222
vanilla 1.3.3 distro, I hope
author | Charlie Root |
---|---|
date | Thu, 04 Jan 2018 15:50:29 -0500 |
parents | |
children |
line wrap: on
line source
/** * ContextMenu plugin script * * @licstart The following is the entire license notice for the * JavaScript code in this file. * * Copyright (C) 2009-2014 Philip Weir * * The JavaScript code in this page is free software: you can redistribute it * and/or modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * @licend The above is the entire license notice * for the JavaScript code in this file. */ rcube_webmail.prototype.context_menu_skip_commands = new Array('mail-checkmail', 'mail-compose', 'addressbook-add', 'addressbook-import', 'addressbook-advanced-search', 'addressbook-search-create'); rcube_webmail.prototype.context_menu_overload_commands = new Array('move', 'copy'); rcube_webmail.prototype.context_menu_commands = new Array(); rcube_webmail.prototype.context_menu_popup_menus = new Array(); rcube_webmail.prototype.context_menu_popup_commands = {}; rcube_webmail.prototype.context_menu_command_pattern = /rcmail\.command\(\'([^\']+)\',\s?\'((?:\\\'|[^\'])*)\'/; function rcm_listmenu_init(row, props, events) { if (!events) events = {}; var menu = rcm_callbackmenu_init(props, $.extend({ 'beforeactivate': function(p) { rcmail.env.contextmenu_selection = p.ref.list_selection(true); }, 'afteractivate': function(p) { p.ref.menu_selection = p.ref.list_object.get_selection(); p.ref.list_selection(false, rcmail.env.contextmenu_selection); } }, events)); var list_object = props.list_object ? props.list_object : rcmail.message_list; $("#" + row).on("contextmenu", function(e) { if (uid = list_object.get_row_uid(this)) { rcm_show_menu(e, this, uid, menu); } }); } function rcm_foldermenu_init(el, props, events) { if (!events) events = {}; var menu = rcm_callbackmenu_init($.extend({'menu_name': 'folderlist', 'list_object': null}, props), $.extend({ 'beforeactivate': function(p) { if (rcmail.env.contextmenu_messagecount_request) { rcmail.env.contextmenu_messagecount_request.abort(); } rcmail.env.contextmenu_messagecount_request = null; }, 'activate': function(p) { if ($.inArray(p.command, Array('expunge', 'purge', 'mark-all-read')) >= 0) { // disable the commands by default $(p.el).addClass('disabled').removeClass('active'); // if menu is opened on current folder (or special mark-all-read command) then enable the commands same as in UI if ((rcmail.env.context_menu_source_id == rcmail.env.mailbox || p.command == 'mark-all-read') && rcm_check_button_state(p.btn, true)) { $(p.el).addClass('active').removeClass('disabled'); } // if menu is opened on difference folder then get message count for the folder else if (rcmail.env.context_menu_source_id != rcmail.env.mailbox && !rcmail.env.contextmenu_messagecount_request) { // folder check called async to prevent slowdown on menu load rcmail.env.contextmenu_messagecount_request = $.ajax({ type: 'POST', url: rcmail.url('plugin.contextmenu.messagecount'), data: {'_mbox': rcmail.env.context_menu_source_id}, dataType: 'json', async: true, success: function(data) { if (data.messagecount > 0 && $('#rcm_folderlist').is(':visible')) { // override the environment to check if commands should be abled var temp_exists = rcmail.env.exists; var temp_mailbox = rcmail.env.mailbox; rcmail.env.exists = data.messagecount; rcmail.env.mailbox = rcmail.env.context_menu_source_id; $('#rcm_folderlist').find('a.cmd_expunge').addClass('active').removeClass('disabled'); if (rcmail.purge_mailbox_test()) { $('#rcm_folderlist').find('a.cmd_purge').addClass('active').removeClass('disabled'); } rcmail.env.exists = temp_exists; rcmail.env.mailbox = temp_mailbox; } } }); } } }, 'beforecommand': function(p) { if (rcmail.env.context_menu_source_id != rcmail.env.mailbox && $.inArray(p.command, Array('expunge', 'purge')) >= 0) { var result = rcmail[p.command + '_mailbox'](rcmail.env.context_menu_source_id); // update the unread count and trash icon if (p.command == 'purge' && result !== false) { rcmail.set_unread_count(rcmail.env.context_menu_source_id, 0, false); if (rcmail.env.context_menu_source_id == rcmail.env.trash_mailbox) rcmail.set_trash_count(0); } return {'abort': true, 'result': true}; } else if (rcmail.env.context_menu_source_id != rcmail.env.mailbox && p.command == 'mark-all-read') { rcmail.mark_all_read(rcmail.env.context_menu_source_id); return {'abort': true, 'result': true}; } } }, events)); $(el).click(function(e) { // hide menu when changing folder menu.hide(e); }) .on("contextmenu", function(e) { var source = $(this).children('a'); // remove focus (and keyboard nav highlighting) from A source.blur(); if (source.attr('rel') && source.attr('onclick') && source.attr('onclick').match(rcmail.context_menu_command_pattern)) { rcm_show_menu(e, this, source.attr('rel'), menu); } }); } function rcm_abookmenu_init(el, props, events) { if (!events) events = {}; var menu = rcm_callbackmenu_init($.extend({'menu_name': 'abooklist'}, props), $.extend({ 'beforeactivate': function(p) { p.ref.container.find('li.submenu').remove(); }, 'activate': function(p) { var ids = rcmail.env.context_menu_source_id.split(':', 2); cur_source = ids[0]; if (p.command == 'group-create') { // addressbook if ($(p.source).hasClass('addressbook') && rcmail.env.address_sources[cur_source].groups && !rcmail.env.address_sources[cur_source].readonly) { $(p.el).addClass('active').removeClass('disabled'); } else { $(p.el).addClass('disabled').removeClass('active'); } } else if (p.command == 'group-rename' || p.command == 'group-delete') { // group if ($(p.source).hasClass('contactgroup') && !rcmail.env.address_sources[cur_source].readonly) { $(p.el).addClass('active').removeClass('disabled'); } else { $(p.el).addClass('disabled').removeClass('active'); } } else if (p.command == 'search-delete') { // saved search if ($(p.source).hasClass('contactsearch')) { $(p.el).addClass('active').removeClass('disabled'); } else { $(p.el).addClass('disabled').removeClass('active'); } } }, 'command': function(p) { if (!$(p.el).hasClass('active')) return; var prev_source = rcmail.env.source; var prev_group = rcmail.env.group; var result = false; var ids = rcmail.env.context_menu_source_id.split(':', 2); cur_source = ids[0]; cur_id = ids[1]; rcmail.env.source = cur_source; rcmail.env.group = cur_id; // enable the required command var prev_command = rcmail.commands[p.command]; rcmail.enable_command(p.command, true); switch (p.command) { case 'search-delete': var result = false; if ($(p.ref.selected_object).children('a').attr('rel')) { var prev_search_id = rcmail.env.search_id; var prev_search_request = rcmail.env.search_request; rcmail.env.search_request = true; rcmail.env.search_id = $(p.ref.selected_object).children('a').attr('rel').replace('S', ''); result = rcmail.command(p.command, p.args, p.el, p.evt); rcmail.env.search_request = prev_search_request; rcmail.env.search_id = prev_search_id; } break; default: result = rcmail.command(p.command, p.args, p.el, p.evt); break; } rcmail.enable_command(p.command, prev_command); rcmail.env.source = prev_source; rcmail.env.group = prev_group; return result; } }, events)); $(el).click(function(e) { // hide menu when changing address book menu.hide(e); }) .on("contextmenu",function(e) { var source = $(this).children('a'); // remove focus (and keyboard nav highlighting) from A source.blur(); if (source.attr('rel') && source.attr('rel').match(/([A-Z0-9\-_]+(:[A-Z0-9\-_]+)?)/i)) { rcm_show_menu(e, this, RegExp.$1, menu); } }); } function rcm_callbackmenu_init(props, events) { var std_events = { 'command': function(p) { if (!$(p.el).hasClass('active')) return; if (p.ref.list_object) { var prev_display_next = rcmail.env.display_next; if (!(p.ref.list_object.selection.length == 1 && p.ref.list_object.in_selection(rcmail.env.context_menu_source_id))) rcmail.env.display_next = false; var prev_sel = p.ref.list_selection(true); } // enable the required command var prev_command = rcmail.commands[p.command]; rcmail.enable_command(p.command, true); var result = rcmail.command(p.command, p.args, p.el, p.evt); rcmail.enable_command(p.command, prev_command); if (p.ref.list_object) { p.ref.list_selection(false, prev_sel); rcmail.env.display_next = prev_display_next; } if ($.inArray(p.command, rcmail.context_menu_overload_commands) >= 0) { rcmail.context_menu_commands[p.command] = rcmail.commands[p.command]; rcmail.enable_command(p.command, true); } return result; }, 'activate': function(p) { $(p.el).addClass(p.enabled ? 'active' : 'disabled'); } } if (events) $.extend(std_events, events); if (!rcmail.env.contextmenus[props.menu_name]) { var menu = new rcube_context_menu(props); $.each(std_events, function(trigger, func) { menu.addEventListener(trigger, function(p) { return func(p); }); }); menu.init(); rcmail.env.contextmenus[props.menu_name] = menu; } else { var menu = rcmail.env.contextmenus[props.menu_name]; } return menu; } function rcm_show_menu(e, obj, id, menu) { // if contextmenus have been disabled then show browser context menu as normal if (!rcmail.env.contextmenu) return true; e.preventDefault(); e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); // hide any other open menus for (var i = 0; i < rcmail.menu_stack.length; i++) { rcmail.hide_menu(rcmail.menu_stack[i], e); } rcmail.env.context_menu_source_id = id; menu.show(obj, e); } function rcm_hide_menu(e, sub_only) { $.each($(sub_only ? '.rcmsubmenu' : 'div.contextmenu'), function() { if ($(this).is(':visible')) { $(this).hide(); rcmail.triggerEvent('menu-close', { name: $(this).attr('id'), props:{ menu: $(this).attr('id') }, originalEvent: e }); } }); // close popup menus opened by the contextmenu for (var i = rcmail.context_menu_popup_menus.length - 1; i >= 0; i--) { rcmail.hide_menu(rcmail.context_menu_popup_menus[i], e); rcmail.context_menu_popup_menus.pop(); } } function rcube_context_menu(p) { this.menu_name = null; this.menu_source = null; this.list_object = rcmail.message_list; this.source_class = 'contextRow'; this.mouseover_timeout = 400; this.is_submenu = false; this.parent_menu = this; this.parent_object = null; this.selected_object = null this.container = null; this.original_selection = new Array(); this.menu_selection = new Array(); this.submenus = new Array(); this.timers = new Array(); // overwrite default parameters if (p && typeof p === 'object') for (var n in p) this[n] = p[n]; var ref = this; this.init = function() { if (!this.container) { rcmail.triggerEvent('contextmenu_init', this); this.container = $('<div id="rcm_'+ this.menu_name +'" style="display: none;"></div>'); this.container.addClass('contextmenu popupmenu'); this.container.addClass(this.is_submenu ? 'rcmsubmenu' : 'rcmmainmenu'); var rows = [], ul = $('<ul role="menu">'), li = $('<li>'), link = $('<a>'), span = $('<span>'); ul.addClass('toolbarmenu iconized'); li.attr('role', 'menuitem'); link.attr('href', '#'); link.addClass('icon active'); link.attr('role', 'button'); link.attr('tabindex', '-1'); link.attr('aria-disabled', 'true'); span.addClass('icon'); // loop over possible menu elements and build settings object sources = typeof this.menu_source == 'string' ? [this.menu_source] : this.menu_source; this.menu_source = {} $.each(sources, function(i) { var source_elements; if (typeof sources[i] == 'string') { ref.menu_source[sources[i]] = { 'toggle': !$(sources[i]).is(':visible') }; source_elements = $(sources[i]).children(); } else { ref.menu_source[i] = { 'toggle': false }; source_elements = $(sources[i]); } ul.attr('aria-labelledby', $(sources[i]).attr('aria-labelledby')); $.each(source_elements, function() { var elem, command, args; if ($(this).is('a')) { elem = $(this).clone(); } else if ($(this).is('span') && $(this).children().length == 2) { elem = $(this).children(':first').clone(); if ($(this).children(':last').attr('onclick').match(rcmail.context_menu_popup_pattern)) { $(elem).attr('onclick', $(this).children(':last').attr('onclick')); } } else if ($(this).is('li') && $(this).children('a').length == 1) { elem = $(this).children('a').clone(); if (!elem.attr('onclick') || !elem.attr('onclick').match(rcmail.context_menu_command_pattern)) return; } else if ($(this).parent().is('a')) { elem = $(this).parent().clone(); } else if (this.command && this.label) { elem = $('<a>').attr('href', '#') .attr('id', 'rcmjs') .attr('onclick', "return rcmail.command('"+ this.command +"','"+ this.props +"',this,event)") .addClass(this.classes) .html(this.label); } else { return; } // skip any element that does not look like a Roundcube button if (!elem.attr('onclick')) { return; } if (elem.attr('onclick').match(rcmail.context_menu_command_pattern)) { command = RegExp.$1; args = RegExp.$2; } // skip elements we don't need if ($.inArray(rcmail.env.task + '-' + command, rcmail.context_menu_skip_commands) > -1 || elem.hasClass('rcm_ignore')) { return; } var a = link.clone(), row = li.clone(); // add command name element tmp = span.clone(); tmp.text($.trim(elem.text()).length > 0 ? $.trim(elem.text()) : elem.attr('title')); tmp.addClass(elem.children('span').attr('class')); a.append(tmp); a.addClass(elem.attr('class')); a.removeClass('button').removeClass('disabled'); a.addClass('rcm_elem_' + elem.attr('id')); if (elem.attr('onclick').match(rcmail.context_menu_popup_pattern)) { a.data('command', RegExp.$1); a.append($('<span>').addClass('right-arrow')); row.addClass('submenu'); a.click(function(e) { if (!$(this).hasClass('active')) return; ref.submenu(a, e); return false; }); if (ref.mouseover_timeout > -1) { a.mouseover(function(e) { if (!$(this).hasClass('active')) return; ref.timers['submenu_show'] = window.setTimeout(function(a, e) { ref.submenu(a, e); }, ref.mouseover_timeout, a, e); }); a.mouseout(function(e) { if (!$(this).hasClass('active')) return; $(this).blur(); clearTimeout(ref.timers['submenu_show']); }); } } else { a.addClass('cmd_' + command); a.data('command', command); if (elem.attr('target')) a.attr('target', elem.attr('target')); a.click(function(e) { if ($(this).parents('.rcmsubmenu').length == 0) { rcm_hide_menu(e, true); clearTimeout(ref.timers['submenu_hide']); } var cur_popups = rcmail.menu_stack.length; var result; var callback = ref.parent_menu.triggerEvent('beforecommand', {ref: ref, el: this, command: command, args: args}); if (!callback || !callback.abort) { result = ref.parent_menu.triggerEvent('command', {ref: ref, el: this, command: command, args: args, evt: e}); } else { result = callback.result; } if (!callback || !callback.skipaftercommand) ref.parent_menu.triggerEvent('aftercommand', {ref: ref, el: this, command: command, args: args}); if (rcmail.menu_stack.length > cur_popups) { var popup_name = rcmail.menu_stack[rcmail.menu_stack.length - 1]; rcmail.context_menu_popup_menus.push(popup_name); // make sure enabled commands match context menu message selection $.each(rcmail.context_menu_popup_commands[popup_name], function(cmd, state) { rcmail.enable_command(cmd, state); }); } // ensure menu is always hidden after action (for Safari) ref.hide(e); return result; }); if (ref.mouseover_timeout > -1 && !ref.is_submenu) { a.mouseover(function(e) { ref.timers['submenu_hide'] = window.setTimeout(function(e) { rcm_hide_menu(e, true); }, ref.mouseover_timeout, e); }); a.mouseout(function(e) { clearTimeout(ref.timers['submenu_hide']); }); } } row.append(a); ref.parent_menu.triggerEvent('insertitem', {item: row}); rows.push(row); }); }); ul.append(rows).appendTo(this.container); this.parent_menu.triggerEvent('init', {ref: this}); this.container.appendTo($('body')); } }; this.show = function(obj, e) { if (obj) { this.hide(e); } var callback = this.parent_menu.triggerEvent('beforeactivate', {ref: this, source: obj}); if (!callback || !callback.abort) { if (obj) { $(obj).addClass(this.source_class); } $.each(ref.menu_source, function(id, props) { if (props.toggle) { $(id).parent().show(); } }); $.each(this.container.find('a'), function() { if ($(this).hasClass('rcm_active')) { $(this).addClass('active'); } else if (btn = $(this).attr('class').match(/rcm_elem_([a-z0-9]+)/)) { $(this).parent('li')[(btn[1] == 'rcmjs' || $('#' + btn[1]).is(':visible')) ? 'show' : 'hide'](); $(this).removeClass('active').removeClass('disabled'); var enabled = false; if (!rcm_check_button_state(btn[1], false) && (!ref.is_submenu || rcm_check_button_state(btn[1], true))) { enabled = true; } var ret = ref.parent_menu.triggerEvent('activate', {el: this, btn: btn[1], source: obj, command: $(this).data('command'), enabled: enabled}); if (ret === true) { $(this).addClass('active').removeClass('disabled'); } else if (ret === false) { $(this).addClass('disabled').removeClass('active'); } } }); $.each(ref.menu_source, function(id, props) { if (props.toggle) { $(id).parent().hide(); } }); this.parent_menu.triggerEvent('afteractivate', {ref: this, source: obj}); } // position menu on the screen if (this.is_submenu) { rcmail.element_position(this.container, this.parent_object); } else { this.position(e, this.container); } if (!callback || callback.show !== false) { this.selected_object = obj; this.container.show(); rcmail.triggerEvent('menu-open', { name: this.container.attr('id'), props:{ menu: this.container.attr('id') }, originalEvent: e }); } }; this.hide = function(e) { // use window.event when e is not defined (legacy support for IE8) var target = e ? e.target : window.event.srcElement; if ($('div.contextmenu').is(':visible') && (rcmail.context_menu_popup_menus.length == 0 || $(target).parents('div.contextmenu').length == 0)) { this.selected_object = null; $('.' + this.source_class).removeClass(this.source_class); rcm_hide_menu(e); for (var i in rcmail.context_menu_commands) { if (!rcmail.context_menu_commands[i]) { rcmail.enable_command(i, false); } } rcmail.context_menu_commands = new Array(); } }; this.submenu = function(link, e) { // use window.event when e is not defined (legacy support for IE8) if (!e) e = window.event; if (e) { e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); } rcm_hide_menu(e, true); var id = rcmail.gui_containers[$(link).data('command')] ? rcmail.gui_containers[$(link).data('command')].attr('id') : $(link).data('command'); if (!this.submenus[id]) { var elem = !$('#' + id).is('ul') ? '#' + id + ' ul' : '#' + id; // check if the container returned is a ul else there should be one directly beneath it this.submenus[id] = new rcube_context_menu({'menu_name': id, 'menu_source': elem, 'parent_menu': this, 'parent_object': link, 'is_submenu': true, 'list_object': this.list_object}); this.submenus[id].init(); } this.submenus[id].show(null, e); }; this.position = function(e, menu) { // temporarily show element to calculate its size menu.css({left: '-1000px', top: '-1000px'}).show(); var win = $(window), win_height = win.height(), elem_height = $(menu).height(), elem_width = $(menu).width(), top = e.pageY, left = e.pageX; if (top + elem_height > win_height) { top -= elem_height; if (top < 0) top = Math.max(0, (win_height - elem_height) / 2); } if (left + elem_width > win.width()) left -= elem_width; menu.hide(); menu.css({left: left + 'px', top: top + 'px'}); }; this.list_selection = function(show, prev_sel) { // make the system think no preview pane exists while we do some fake message selects // to enable/disable relevent commands for current selection var prev_contentframe = rcmail.env.contentframe; rcmail.env.contentframe = null; if (show) { if (this.list_object.selection.length == 0 || !this.list_object.in_selection(rcmail.env.context_menu_source_id)) { prev_sel = this.list_object.get_selection(); this.list_object.highlight_row(rcmail.env.context_menu_source_id, true); for (var i in prev_sel) this.list_object.highlight_row(prev_sel[i], true); this.list_object.triggerEvent('select'); } else { // trigger a select event to update active commands // use case: select multiple message, open contextmenu; open contextmenu on a message not in selection; open contextmenu on selection this.list_object.triggerEvent('select'); } } else if (prev_sel) { for (var i in prev_sel) this.list_object.highlight_row(prev_sel[i], true); this.list_object.highlight_row(rcmail.env.context_menu_source_id, true); this.list_object.triggerEvent('select'); } rcmail.env.contentframe = prev_contentframe; return prev_sel; }; this.addEventListener = rcube_event_engine.prototype.addEventListener; this.removeEventListener = rcube_event_engine.prototype.removeEventListener; this.triggerEvent = rcube_event_engine.prototype.triggerEvent; }; function rcm_override_mailbox_command(menu, props, before) { if ($('div.contextmenu').is(':visible') && $.inArray(props.action, rcmail.context_menu_overload_commands) >= 0) { if (before) { rcmail.env.context_menu_prev_display_next = rcmail.env.display_next; if (!(menu.list_object.selection.length == 1 && menu.list_object.in_selection(rcmail.env.context_menu_source_id))) rcmail.env.display_next = false; rcmail.env.context_menu_prev_sel = menu.list_selection(true); } else if (rcmail.env.context_menu_prev_sel) { menu.list_selection(false, rcmail.env.context_menu_prev_sel); rcmail.env.display_next = rcmail.env.context_menu_prev_display_next; } } } function rcm_check_button_state(btn, active) { var classes = active ? rcmail.context_menu_button_active_class : rcmail.context_menu_button_disabled_class; var found = false; $.each(classes, function(i) { if ($('#' + btn).hasClass(classes[i])) { found = true; // stop processing return false; } }); return found; } function rcm_addressbook_selector(event, command, callback) { var container = rcmail.rcm_addressbook_selector_element; if (!container) { var rows = [], ul = $('<ul class="toolbarmenu">'); container = $('<div id="addressbook-selector" class="popupmenu"></div>'); // loop over address books $.each(rcmail.env.address_sources, function() { if (!this.readonly) { rows.push(rcm_addressbook_selector_item(this)); if (this.groups) { var ref = this; $.each(rcmail.env.contactgroups, function() { rows.push(rcm_addressbook_selector_item(this, ref.id)); }); } } }); ul.append(rows).appendTo(container); // temporarily show element to calculate its size container.css({left: '-1000px', top: '-1000px'}) .appendTo($('body')).show(); // set max-height if the list is long if (rows.length > 10) container.css('max-height', $('li', container)[0].offsetHeight * 10 + 9); // register delegate event handler for folder item clicks container.on('click', 'a.active', function(e) { container.data('callback')(this, container.data('command'), e); return false; }); rcmail.rcm_addressbook_selector_element = container; } container.data('command', command); container.data('callback', callback); // customize menu for move or copy container.find('li').show(); // search result may contain contacts from many sources, but if there is only one... var source = rcmail.env.source; if (source == '' && rcmail.env.selection_sources.length == 1) source = rcmail.env.selection_sources[0]; // hide currently open address book from menu if (source) { $.each(container.find('a'), function() { if (($(this).data('source') && $(this).data('source') == source) || $(this).data('id') == source) $(this).parent('li').hide(); }); } // position menu on the screen rcmail.show_menu('addressbook-selector', true, event); } function rcm_group_selector(event, command, callback) { var container = rcmail.rcm_addressgroup_selector_element; if (!container) { var rows = [], ul = $('<ul class="toolbarmenu">'); container = $('<div id="addressgroup-selector" class="popupmenu"></div>'); // loop over address books $.each(rcmail.env.address_sources, function() { if (this.id === rcmail.env.source) { var ref = this; $.each(rcmail.env.contactgroups, function() { rows.push(rcm_addressbook_selector_item(this, ref.id)); }); } }); ul.append(rows).appendTo(container); // remove indent added by rcm_addressbook_selector_item() $(ul).find('a').removeAttr('style'); // temporarily show element to calculate its size container.css({left: '-1000px', top: '-1000px'}) .appendTo($('body')).show(); // set max-height if the list is long if (rows.length > 10) container.css('max-height', $('li', container)[0].offsetHeight * 10 + 9); // register delegate event handler for folder item clicks container.on('click', 'a.active', {cmd: command}, function(e) { container.data('callback')(this, e); return false; }); rcmail.rcm_addressgroup_selector_element = container; } container.data('callback', callback); // customize menu for move or copy container.find('li').show(); // hide currently open group from menu if (rcmail.env.group) { $.each(container.find('a'), function() { if ($(this).data('id') == rcmail.env.group) $(this).parent('li').hide(); }); } // position menu on the screen rcmail.show_menu('addressgroup-selector', true, event); } function rcm_addressbook_selector_item(obj, abook_id) { if (abook_id && abook_id === obj.source || !abook_id) { var a = $('<a>').attr('href', '#').addClass('icon'), row = $('<li>'); if (obj.type == 'group') { a.addClass('active contactgroup') a.data('source', obj.source); a.data('id', obj.id); a.css('padding-left', '16px'); } else { a.addClass('addressbook active').data('id', obj.id); } // add address book name element a.append($('<span>').text(obj.name)); return row.append(a); } } $(document).ready(function() { if (window.rcmail) { rcmail.env.contextmenus = {}; rcmail.addEventListener('init', function() { // no need to reattach events inside iframe if (rcmail.is_framed()) return; var body_mouseup = function(e) { $.each(rcmail.env.contextmenus, function() { this.hide(e); }); }; $(document.body).on('click contextmenu', body_mouseup); // Hide menu after clicks in iframes (eg. preview pane) $('iframe').on('load', function(e) { try { $(this.contentDocument || this.contentWindow).on('mouseup', body_mouseup) } catch (e) { /* catch possible "Permission denied" error in IE */ } }) .contents().on('mouseup', body_mouseup); }); if ((rcmail.env.task == 'mail' || rcmail.env.task == 'addressbook') && rcmail.env.action == '') { // special handeling for move/copy functions (folder/address book selector) rcmail.addEventListener('actionbefore', function(props) { var menu = rcmail.env.task == 'addressbook' ? rcmail.env.contextmenus['contactlist'] : rcmail.env.contextmenus['messagelist']; rcm_override_mailbox_command(menu, props, true); }); rcmail.addEventListener('actionafter', function(props) { var menu = rcmail.env.task == 'addressbook' ? rcmail.env.contextmenus['contactlist'] : rcmail.env.contextmenus['messagelist']; rcm_override_mailbox_command(menu, props, false); }); } if (rcmail.env.task == 'mail' && rcmail.env.action == '') { rcmail.register_command('plugin.contextmenu.collapseall', function(props, obj) { $("#mailboxlist div.expanded").each(function() { $(this).click(); }); }, false); rcmail.register_command('plugin.contextmenu.expandall', function(props, obj) { $("#mailboxlist div.collapsed").each(function() { $(this).click(); }); }, false); rcmail.register_command('plugin.contextmenu.openfolder', function(props, obj) { var button_id = rcmail.buttons['plugin.contextmenu.openfolder'][0].id; rcube_find_object(button_id).href = '?_task=mail&_mbox='+urlencode(rcmail.env.context_menu_source_id); rcmail.sourcewin = window.open(rcube_find_object(button_id).href); if (rcmail.sourcewin) window.setTimeout(function() { rcmail.sourcewin.focus(); }, 20); rcube_find_object(button_id).href = '#'; }, false); } if (rcmail.env.task == 'addressbook' && rcmail.env.action == '') { // address book selector rcmail.addEventListener('actionbefore', function(props) { if ((props.action == 'move' || props.action == 'copy') && props.props == '') { rcm_addressbook_selector(props.originalEvent, props.action, function(obj, cmd, evt) { // search result may contain contacts from many sources, but if there is only one... var source = rcmail.env.source; if (source == '' && rcmail.env.selection_sources.length == 1) source = rcmail.env.selection_sources[0]; if ($(obj).data('source')) { rcmail.command(cmd, rcmail.env.contactgroups['G' + $(obj).data('source') + $(obj).data('id')], evt); } else { rcmail.command(cmd, rcmail.env.address_sources[$(obj).data('id')], evt); } }); return false; } }); // address book group selector rcmail.register_command('plugin.contextmenu.assigngroup', function(props, obj, event) { rcm_group_selector(event, props, function(obj, evt) { // search result may contain contacts from many sources, but if there is only one... rcm_override_mailbox_command(rcmail.env.contextmenus['contactlist'], { action: 'copy' } , true); rcmail.group_member_change('add', rcmail.contact_list.get_selection().join(','), rcmail.env.source, $(obj).data('id')); rcm_override_mailbox_command(rcmail.env.contextmenus['contactlist'], { action: 'copy' } , false); }); }, false); // reset address book selector when groups change rcmail.addEventListener('group_insert', function() { $("#addressbook-selector").remove(); $("#addressgroup-selector").remove(); rcmail.rcm_addressbook_selector_element = undefined; rcmail.rcm_addressgroup_selector_element = undefined; } ); rcmail.addEventListener('group_update', function() { $("#addressbook-selector").remove(); $("#addressgroup-selector").remove(); rcmail.rcm_addressbook_selector_element = undefined; rcmail.rcm_addressgroup_selector_element = undefined; } ); rcmail.addEventListener('group_delete', function() { $("#addressbook-selector").remove(); $("#addressgroup-selector").remove(); rcmail.rcm_addressbook_selector_element = undefined; rcmail.rcm_addressgroup_selector_element = undefined; } ); } // special event listeners for intreacting with plugins which open popup menus (eg: zipdownload) rcmail.addEventListener('menu-open', function(p) { // check for popupmenus that arent part of contextmenu if ($('div.contextmenu').is(':visible') && p.name.indexOf('rcm_') != 0) { rcmail.context_menu_popup_commands[p.name] = {}; $('#' + p.name).find('a').each(function() { if ($(this).attr('onclick') && $(this).attr('onclick').match(rcmail.context_menu_command_pattern)) { var cmd = RegExp.$1; rcmail.context_menu_popup_commands[p.name][cmd] = rcmail.commands[cmd]; } }); } }); rcmail.addEventListener('menu-close', function(p) { // check required args are present, other plugins trigger this event too if (!p.originalEvent) { return; } // check for popupmenus that arent part of contextmenu var e = p.originalEvent.currentTarget ? p.originalEvent.currentTarget : p.originalEvent.srcElement; if ($('div.contextmenu').is(':visible') && p.name.indexOf('rcm_') != 0 && $(e).attr('class').indexOf('rcm_elem_') == -1) { rcm_hide_menu(p.originalEvent); } }); rcmail.addEventListener('get_single_uid', function() { if ($('#rcm_messagelist').is(':visible') && rcmail.env.contextmenus['messagelist'].menu_selection.length == 1) { return rcmail.env.contextmenus['messagelist'].menu_selection[0]; } }); rcmail.addEventListener('get_single_cid', function() { if ($('#rcm_contactlist').is(':visible') && rcmail.env.contextmenus['contactlist'].menu_selection.length == 1) { return rcmail.env.contextmenus['contactlist'].menu_selection[0]; } else if ($('#rcm_composeto').is(':visible') && rcmail.env.contextmenus['composeto'].menu_selection.length == 1) { return rcmail.env.contextmenus['composeto'].menu_selection[0]; } }); } });