Mercurial > hg > rc1
diff plugins/advanced_search/advanced_search.js @ 34:50ac5484d514
one fix to distro
author | Charlie Root |
---|---|
date | Sun, 27 May 2018 16:53:56 -0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/advanced_search/advanced_search.js Sun May 27 16:53:56 2018 -0400 @@ -0,0 +1,726 @@ +(function($) { + /** + * The fontend scripts for an advanced search. + * + * @version 2.1.6 + * @licence GNU GPLv3+ + * @author Wilwert Claude + * @author Ludovicy Steve + * @author Chris Moules + * @website http://www.gms.lu + */ + + $.stack = { + /** + * This object is used to buffer all the server side information which doesn't change. So the script + * doesn't have to send an ajax-request for every new added row. + * + * @name stack + * @namespace + */ + date_criteria: {}, + flag_criteria: {}, + email_criteria: {}, + row: null, + messages: null + }; + + var search_loading = ''; + + $(document).on("change", "#button_display_option", function(e) { + var img = $('img', $(this).closest('p')); + var src = img.attr('src'); + if(this.value == 'messagemenu') { + src = src.replace('menu_location_b.jpg', 'menu_location_a.jpg'); + } else { + src = src.replace('menu_location_a.jpg', 'menu_location_b.jpg'); + } + img.attr('src', src); + }); + + $(document).on("change", "#_show_message_mbox_info, #_show_message_label_header", function(e) { + var img = $('img', $(this).closest('p')); + if($(this).is(':checked')) { + img.removeClass('disabled'); + } else { + img.addClass('disabled'); + } + }); + + /** + * The callback function of the initial dialog call. It creates the dialog and buffers the serverside + * informations into an object. + * + * @param {object} r The serverside informations + */ + rcmail.addEventListener('plugin.show', function(r) { + $.stack.date_criteria = r.date_criteria; + $.stack.flag_criteria = r.flag_criteria; + $.stack.email_criteria = r.email_criteria; + $.stack.row = r.row; + $.stack.html = r.html; + + var $html = $(r.html); + var saved_searches_label = rcmail.gettext('saved_searches', 'advanced_search'); + var saved_searches = '<span class="saved_searches"> <label for="select_saved_search">' + saved_searches_label + ': <select name="select_saved_search" id="select_saved_search"><option value=""></option></select></label></span>'; + title = $('<div>' + r.title + saved_searches + '<div>'); + var saved_searches_select = $('[name=select_saved_search]', title); + if (r.saved_searches.length) { + var i; + for (i in r.saved_searches) { + saved_searches_select.append('<option value="' + r.saved_searches[i] + '">' + r.saved_searches[i] + '</option>'); + } + } + $html.dialog({ + width: 640, + height: 300, + resizable: true, + draggable: true, + title: title, + dialogClass: "advanced_search_dialog", + close: function() { + $('body').css('overflow', 'auto'); + }, + create: function() { + $('body').css('overflow', 'hidden'); + } + }); + + saved_searches_select.bind("blur click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select", function(e) { + e.stopPropagation(); + }); + + saved_searches_select.bind("mouseenter", function(e) { + saved_searches_select.focus(); + }); + + saved_searches_select.bind('change', function(e) { + var search_name = $(this).val(); + if (search_name == "") { + $('#adsearch-popup').html($.stack.html); + } else { + rcmail.http_request('plugin.get_saved_search', { search_name : search_name }); + $('[name=delete]', '#adsearch-popup').show(); + } + }); + + }); + + rcmail.addEventListener('plugin.load_saved_search', function(search) { + var $form = $("#adsearch-popup form"), + $tr = $('tr', $('tbody', $form)).not(':first').not(':last'), + $last = $('tr:last', $('tbody', $form)); + saved_search = search.search, + data = []; + $tr.remove(); + $("[name=folder]", $form).val(search.folder); + $("[name=subfolder]", $form).prop('checked', search.sub_folders == "true"); + $('span.sub-folders', $form).css('display', search.folder == 'all' ? 'none' : 'inline'); + + var i = 0; + for (i; i < saved_search.length; i++) { + var row; + if (i == 0) { + row = $('<tr>' + $("tr:eq(1)", $.stack.html).html() + '</tr>'); + } else { + row = $($.stack.row); + } + $("[name=method]", row).val(saved_search[i].method); + $("[name=filter]", row).val(saved_search[i].filter); + $("[name=not]", row).prop('checked', saved_search[i]['not'] == "true"); + $("[name=filter-exclude]", row).prop('checked', saved_search[i]['excluded'] == "true"); + $last.before(row); + $("[name=filter]", row).trigger("change"); + $("[name=filter-val]", row).val(saved_search[i]['filter-val']); + } + }); +//messagelistcontainer table thead + rcmail.addEventListener('plugin.advanced_search_add_header', function(evt) { + if($("#messagelistcontainer #rcavbox1").length == 0) { + var Mbox = rcmail.gettext('mbox', 'advanced_search'); + $("#messagelistcontainer table.fixedcopy thead tr:first").append('<td class="mbox" id="rcavbox1"><span class="mbox">' + Mbox + '</span></td>'); + $("#messagelistcontainer table#messagelist thead tr:first").append('<td class="mbox" id="rcavbox2"><span class="mbox">' + Mbox + '</span></td>'); + } + }); + + rcmail.addEventListener('plugin.advanced_search_del_header', function(evt) { + $("#messagelistcontainer #rcavbox1").remove(); + $("#messagelistcontainer #rcavbox2").remove(); + }); + + rcube_webmail.prototype.advanced_search_add_mbox = function (mbox, count, showMbox) { + if (!this.gui_objects.messagelist || !this.message_list) { + return false; + } + + var colspan = showMbox == true ? 9 : 8; + $(rcmail.message_list.list).append('<tr class="aslabel_mbox"><td><span class="aslabel_found">' + count + '</span></td><td colspan="' + colspan + '">' + mbox + '</td></tr>'); + } + + rcube_webmail.prototype.advanced_search_active = function(param) { + var page = param.replace('_page=', ''); + rcmail.http_request('plugin.trigger_search_pagination', { _page : page }); + } + + /** + * Builds the search to send to the server + */ + var get_search_data = function() + { + var $form = $("#adsearch-popup form"), + $tr = $('tr', $('tbody', $form)).not(':first').not(':last'), + data = []; + + if ($tr.length) { + $tr.each(function() { + var item = {not: $('input[name=not]', $(this)).prop('checked'), + excluded: $('input[name=filter-exclude]', $(this)).prop('checked'), + filter: $('option:selected', $('select[name=filter]', $(this))).val(), + 'filter-val': $('input[name=filter-val]', $(this)).val()}; + + if ($('select[name=method]', $(this)).length) { + item.method = $('option:selected', $('select[name=method]', $(this))).val(); + } + + data.push(item); + }); + } + + return data; + } + + /** + * The onclick event handler for the search button. This generates the search query and sends them + * to the server. It also stores the wrapped set of the old rows into an object for later cleanup. + * + * @param {object} e The event element + */ + $(document).on("click", 'input[name=search]', function(e) { + e.preventDefault(); + + rcmail.clear_message_list(); + + $.stack.messages = $('tr', $('tbody', '#messagelist')); + + var $form = $("#adsearch-popup form"); + search_loading = rcmail.set_busy(true, 'loading'); + rcmail.http_request('plugin.trigger_search', + {search: get_search_data(), + current_folder: rcmail.env.mailbox, + folder: $('select[name=folder]', $form).val(), + sub_folders: $('input[name=subfolder]', $form).prop('checked')}); + + $("#adsearch-popup").closest('div.ui-dialog-content').dialog('close'); + }); + + /** + * The onclick event handler of the "reset search" button, which resets the advanced search + * back to its initial state. + * + * @param {object} e The event element + */ + $(document).on("click", 'input[name=reset]', function(e) { + e.preventDefault(); + $('#adsearch-popup').html($.stack.html); + $('[name=select_saved_search]').val(""); + }); + + /** + * The onclick event handler for the "add" button. This adds one new row to the query dialog + * + * @param {object} e The event element + */ + $(document).on("click", 'button[name=add]', function(e) { + e.preventDefault(); + + $(this).closest('tr').after($.stack.row); + }); + + /** + * The onclick event handler for the "delete" button. This removes the containing row from + * the query dialog + * + * @param {object} e The event element + */ + $(document).on("click", 'button[name=delete]', function(e) { + e.preventDefault(); + + $(this).closest('tr').remove(); + }); + + /** + * The change event handler for the filter selector. + * Make the input field context relevent. + * + * @param {object} e The event element + */ + $(document).on("click", 'select[name=filter]', function(e) { + var $row_input = $(this).nextUntil('tr', 'input[name=filter-val]'), + old_avs_type = $row_input.data("avs_type"); + + if ($.inArray($(this).val(), $.stack.date_criteria) >= 0) { + if(old_avs_type !== "date") { + $row_input.val(''); + $row_input.datepicker({dateFormat: rcmail.env.date_format}); + } + + $row_input.data("avs_type", "date"); + } else if ($.inArray($(this).val(), $.stack.email_criteria) >= 0) { + if(old_avs_type !== "email") { + rcmail.init_address_input_events($row_input, ""); + rcmail.addEventListener('autocomplete_insert', function(e){ + e.field.value = e.insert.replace(/.*<(\S*?@\S*?)>.*/, "$1"); + }); + } + + $row_input.data("avs_type", "email"); + } else if ($.inArray($(this).val(), $.stack.flag_criteria) >= 0) { + if (old_avs_type !== "flag_criteria") { + $row_input.val(''); + $row_input.hide(); + } + + $row_input.data("avs_type", "flag_criteria"); + } else { + $row_input.data("avs_type", "none"); + } + + switch (old_avs_type) { + case "date": + if (($row_input.data("avs_type") !== "date") && $row_input.hasClass("hasDatepicker")) { + $row_input.datepicker("destroy"); + } + break; + case "email": + if (($row_input.data("avs_type") !== "email")) { + $row_input.removeAttr("autocomplete"); + $row_input.unbind('keydown'); + $row_input.unbind('keypress'); + } + break; + case "flag_criteria": + if (($row_input.data("avs_type") !== "flag_criteria") && !$row_input.is(":visible")) { + $row_input.show(); + } + break; + } + }); + + /** + * The change event handler for the folder select box. It makes the subfolder checkbox invisible + * when selecting the "all folders" option + * + * @param {object} e The event element + */ + $(document).on("click", 'select[name=folder]', function(e) { + $('span.sub-folders', $(this).closest('form')).css('display', $(this).val() == 'all' ? 'none' : 'inline'); + }); + + /** + * The onclick event handler for the menu entry of the advanced search. This makes the initial call + * of the advanced search and fires a query to the server to get every important information. + * + * @param {object} e The event element + */ + $(document).on("click", 'a.icon.advanced-search, a.button.advanced-search', function(e) { + e.preventDefault(); + + if (!$('#adsearch-popup').length) { + rcmail.http_request('plugin.display_advanced_search'); + } else { + $("#adsearch-popup").closest('div.ui-dialog-content').dialog('open'); + } + }); + + /** + * Stop propagation of keydown and keypress events. + * This should stop these events being processed by other listeners in the mailbox. + * + * @param {object} e The event element + */ + $(document).on("keydown keypress", "#adsearch-popup", function(e) { + e.stopPropagation(); + }); + + $(document).on("click", "#adsearch-popup input.delete_search", function(e) { + e.stopPropagation(); + e.preventDefault(); + var search_name = $("[name=select_saved_search]").val(); + var txt = {}; + txt['cancel'] = rcmail.get_label('advanced_search.cancel'); + txt['delete'] = rcmail.get_label('advanced_search.delete'); + $( "<p><strong>" + search_name + "</strong></p>" ).dialog({ + resizable: true, + height:180, + modal: true, + title: rcmail.gettext('advanced_search.deletesearch'), + buttons: [ + { + text: txt['delete'], + click: function() { + rcmail.http_request('plugin.delete_search', {search_name: search_name}); + $("[value=" + search_name + "]", "[name=select_saved_search]").remove(); + $("[name=select_saved_search]").val("").trigger("change"); + $( this ).dialog( "close" ); + }, + }, + { + text: txt['cancel'], + click: function() { + $( this ).dialog( "close" ); + } + }] + + }); + }); + + $(document).on("click", "#save_the_search", function(e) { + e.stopPropagation(); + e.preventDefault(); + var labelName = rcmail.gettext('name', 'advanced_search'); + var labelSave = rcmail.gettext('save', 'advanced_search'); + var labelCancel = rcmail.gettext('cancel', 'advanced_search'); + var save_search = '<table>' + + ' <tr><td>' + labelName + ' </td><td><input type="text" name="search_name" /></td></tr>' + + ' <tr><td></td><td><input type="submit" class="button mainaction" value="' + labelSave + '" /> <input type="reset" class="button reset" value="' + labelCancel + '" /></td></tr>' + + '</table>'; + save_search = $(save_search); + $("[name=search_name]", save_search).val($("[name=select_saved_search]").val()); + + save_search.dialog({ + title: rcmail.gettext('advanced_search.save_the_search'), + dialogClass: 'saveTheSearch', + close: function() { + $(this).remove(); + }, + width: $("#adsearch-popup").width(), + height: $("#adsearch-popup").height(), + modal: true + }); + $(".mainaction", save_search).bind('click', function(e) { + e.preventDefault(); + e.stopPropagation(); + var search_name = $("[name=search_name]", save_search).val(); + var $form = $("#adsearch-popup form"); + rcmail.http_request('plugin.save_search', + {search: get_search_data(), + search_name: search_name, + folder: $('select[name=folder]', $form).val(), + sub_folders: $('input[name=subfolder]', $form).prop('checked')}); + var isNewSearch = true; + $("[name=select_saved_search] option").each(function(e) { + if ($(this).attr("value") == search_name) { + isNewSearch = false; + } + }); + if (isNewSearch) { + $("[name=select_saved_search]").append('<option value="' + search_name + '">' + search_name + '</option>'); + $("[name=select_saved_search]").val(search_name); + } + save_search.dialog('close'); + }); + + $(".reset", save_search).bind('click', function(e) { + e.preventDefault(); + e.stopPropagation(); + save_search.dialog('close'); + }); + + }); + + var advanced_search_redirect_draft_messages = function(check) { + if (rcmail.env.search_request == "advanced_search_active") { + if (rcmail.task == 'mail') { + uid = rcmail.get_single_uid(); + if (uid && (!rcmail.env.uid || uid != rcmail.env.uid || check)) { + if ((rcmail.env.mailbox == rcmail.env.drafts_mailbox) || check) { + url = { + _mbox: this.env.mailbox, + _search: 'advanced_search_active' + }; + url[this.env.mailbox == this.env.drafts_mailbox ? '_draft_uid' : '_uid'] = uid; + this.goto_url('compose', url, true); + } + } + } + return true; + } + return false; + } + + var advanced_search_perform_action = function(props, action) { + + var raw_selection = rcmail.message_list.get_selection(); + var md5_folders = rcmail.env.as_md5_folders; + var i; + var selections = {}; + for (i in raw_selection) { + raw_selection[i]; + var parts = raw_selection[i].split('__MB__'); + var mid = parts[0]; + var md5Mbox = parts[1]; + var mbox = md5_folders[md5Mbox]; + if (!selections[mbox]) { + selections[mbox] = []; + } + selections[mbox].push(mid); + } + + if (i != undefined) { + // show wait message + if (rcmail.env.action == 'show') { + lock = rcmail.set_busy(true, 'movingmessage'); + } else { + rcmail.show_contentframe(false); + } + // Hide message command buttons until a message is selected + rcmail.enable_command(rcmail.env.message_commands, false); + var j; + for (j in selections) { + rcmail.select_folder(j, '', true); + rcmail.env.mailbox = j; + var uids = selections[j].join(','); + var lock = false, + post_data = rcmail.selection_post_data({ + _target_mbox: props.id, + _uid: uids + }); + rcmail._with_selected_messages(action, post_data, lock); + } + // Make sure we have no selection + rcmail.env.uid = undefined; + rcmail.message_list.selection = []; + } + + } + + var advanced_search_check_multi_mbox = function () { + var raw_selection = rcmail.message_list.get_selection(); + var md5_folders = rcmail.env.as_md5_folders; + var i; + var mcount = 0; + var selections = {}; + for (i in raw_selection) { + raw_selection[i]; + var parts = raw_selection[i].split('__MB__'); + var mid = parts[0]; + var md5Mbox = parts[1]; + var mbox = md5_folders[md5Mbox]; + if (!selections[mbox]) { + selections[mbox] = []; + mcount++; + } + selections[mbox].push(mid); + } + + return { + isMulti: mcount > 1, + selections: selections + }; + } + + /** + * The roundcube init funtion, which registers and enables the advanced search command. + */ + rcmail.addEventListener('init', function() { + rcmail.register_command('plugin.advanced_search', true, true); + rcmail.enable_command('plugin.advanced_search', true); + + rcmail.addEventListener('plugin.search_complete', function(r) { + rcmail.set_busy(false, 'loading', search_loading); + /* Start registering event listeners for handling drag/drop, marking, flagging etc... */ + rcmail.addEventListener('beforeedit', function (command) { + rcmail.env.framed = true; + if (advanced_search_redirect_draft_messages(true)) { + return false; + } + }); + + rcmail.message_list.addEventListener('dblclick', function (o) { + advanced_search_redirect_draft_messages(); + }); + + rcmail.message_list.addEventListener('select', function (list) { + if (rcmail.env.search_request == "advanced_search_active") { + if (list.selection.length == 1) { + var parts = list.selection[0].split('__MB__'); + var mid = parts[0]; + var md5Mbox = parts[1]; + var mbox = rcmail.env.as_md5_folders[md5Mbox]; + rcmail.env.uid = mid; + if (rcmail.env.mailbox != mbox) { + var ex = []; + li = rcmail.get_folder_li(mbox, '', true); + parent = $(li).parents(".mailbox"); + parent.each(function () { + div = $(this.getElementsByTagName('div')[0]); + a = $(this.getElementsByTagName('a')[0]); + if (div.hasClass('collapsed')) { + ex.push($(a).attr("rel")); + } + }); + for (var i = ex.length - 1; i >= 0; i--) { + rcmail.command('collapse-folder', ex[i]); + } + rcmail.select_folder(mbox, '', true); + rcmail.env.mailbox = mbox; + } + return false; + } + } + }); + + rcmail.addEventListener('beforemoveto', function (props) { + if (rcmail.env.search_request == 'advanced_search_active') { + advanced_search_perform_action(props, 'moveto'); + + return false; + } + }); + + rcmail.addEventListener('beforedelete', function (props) { + if (rcmail.env.search_request == 'advanced_search_active') { + advanced_search_perform_action(props, 'delete'); + + return false; + } + }); + + rcmail.addEventListener('beforemark', function (flag) { + if (rcmail.env.search_request == 'advanced_search_active') { + var res = advanced_search_check_multi_mbox(); + //Update on server + var i; + var sel = res.selections; + for (i in sel) { + var uids = sel[i].join(','); + var lock = false; + var post_data = { + _uid: uids, + _flag: flag, + _mbox: i, + _remote: 1 + }; + rcmail.http_post('mark', post_data, lock); + } + var raw_selection = rcmail.message_list.get_selection(); + for(i in raw_selection) { + var key = raw_selection[i]; + switch (flag) { + case 'read': + rcmail.message_list.rows[key].unread = 0; + break; + case 'unread': + rcmail.message_list.rows[key].unread = 1; + break; + case 'flagged': + rcmail.message_list.rows[key].flagged = 1; + break; + case 'unflagged': + rcmail.message_list.rows[key].flagged = 0; + break; + } + } + //Refresh ui + var messages = []; + var selections = rcmail.message_list.get_selection(); + var j; + for (j in selections) { + messages.push('#rcmrow' + selections[j]); + } + var selector = messages.join(', '); + var selection = $(selector); + switch (flag) { + case 'read': + selection.removeClass('unread'); + break; + case 'unread': + selection.addClass('unread'); + break; + case 'flagged': + selection.addClass('flagged'); + $("td.flag span", selection).removeClass('unflagged').addClass('flagged'); + break; + case 'unflagged': + selection.removeClass('flagged'); + $("td.flag span", selection).removeClass('flagged').addClass('unflagged'); + break; + default: + break; + } + return false; + } + }); + + rcmail.addEventListener('beforeforward', function (props) { + if (rcmail.env.search_request == 'advanced_search_active' && rcmail.message_list.selection.length > 1) { + var res = advanced_search_check_multi_mbox(); + if (res.isMulti == true) { + //Selections from more then one folder + return false; + } else { + //Only one folder, redirecting + var i, url, sel = res.selections; + for (i in sel) { + url = '&_forward_uid=' + sel[i].join(',') + '&_mbox=' + i; + } + url += '&_attachment=1&_action=compose'; + window.location = location.pathname + rcmail.env.comm_path + url; + + return false; + } + } + }); + + rcmail.addEventListener('beforeforward-attachment', function (props) { + if (rcmail.env.search_request == 'advanced_search_active' && rcmail.message_list.selection.length > 1) { + var res = advanced_search_check_multi_mbox(); + if (res.isMulti == true) { + //Selections from more then one folder + return false; + } else { + //Only one folder, redirecting + var i, url, sel = res.selections; + for (i in sel) { + url = '&_forward_uid=' + sel[i].join(',') + '&_mbox=' + i; + } + url += '&_attachment=1&_action=compose'; + window.location = location.pathname + rcmail.env.comm_path + url; + + return false; + } + } + }); + + rcmail.addEventListener('beforetoggle_flag', function (props) { + if (rcmail.env.search_request == 'advanced_search_active') { + var flag = $(props).hasClass('unflagged') ? 'flagged' : 'unflagged'; + var tr = $(props).closest('tr'); + var id = tr.attr('id').replace('rcmrow', ''); + var parts = id.split('__MB__'); + var lock = false; + var mbox = rcmail.env.as_md5_folders[parts[1]]; + var post_data = { + _uid: parts[0], + _flag: flag, + _mbox: mbox, + _remote: 1 + }; + rcmail.http_post('mark', post_data, lock); + if (flag == 'flagged') { + tr.addClass('flagged'); + $("td.flag span", tr).removeClass('unflagged').addClass('flagged'); + rcmail.message_list.rows[id].flagged = 1; + } else { + tr.removeClass('flagged'); + $("td.flag span", tr).removeClass('flagged').addClass('unflagged'); + rcmail.message_list.rows[id].flagged = 0; + } + return false; + } + }); + /* End registering event listeners */ + }); + + }); +})(jQuery);