| | |
| | | var n; |
| | | this.task = this.env.task; |
| | | |
| | | // check browser |
| | | if (this.env.server_error != 409 && (!bw.dom || !bw.xmlhttp_test() || (bw.mz && bw.vendver < 1.9) || (bw.ie && bw.vendver < 7))) { |
| | | // check browser capabilities (never use version checks here) |
| | | if (this.env.server_error != 409 && (!bw.dom || !bw.xmlhttp_test())) { |
| | | this.goto_url('error', '_code=0x199'); |
| | | return; |
| | | } |
| | |
| | | else if (this.env.action == 'get') |
| | | this.enable_command('download', 'print', true); |
| | | // show printing dialog |
| | | else if (this.env.action == 'print' && this.env.uid) { |
| | | else if (this.env.action == 'print' && this.env.uid |
| | | && !this.env.is_pgp_content && !this.env.pgp_mime_part |
| | | ) { |
| | | this.print_dialog(); |
| | | } |
| | | |
| | |
| | | } |
| | | this.http_post(postact, postdata); |
| | | } |
| | | |
| | | this.check_mailvelope(this.env.action); |
| | | |
| | | // detect browser capabilities |
| | | if (!this.is_framed() && !this.env.extwin) |
| | |
| | | break; |
| | | |
| | | case 'login': |
| | | var input_user = $('#rcmloginuser'); |
| | | input_user.bind('keyup', function(e){ return ref.login_user_keyup(e); }); |
| | | var tz, tz_name, jstz = window.jstz, |
| | | input_user = $('#rcmloginuser'), |
| | | input_tz = $('#rcmlogintz'); |
| | | |
| | | input_user.bind('keyup', function(e) { return ref.login_user_keyup(e); }); |
| | | |
| | | if (input_user.val() == '') |
| | | input_user.focus(); |
| | |
| | | $('#rcmloginpwd').focus(); |
| | | |
| | | // detect client timezone |
| | | if (window.jstz) { |
| | | var timezone = jstz.determine(); |
| | | if (timezone.name()) |
| | | $('#rcmlogintz').val(timezone.name()); |
| | | } |
| | | else { |
| | | $('#rcmlogintz').val(new Date().getStdTimezoneOffset() / -60); |
| | | } |
| | | if (jstz && (tz = jstz.determine())) |
| | | tz_name = tz.name(); |
| | | |
| | | input_tz.val(tz_name ? tz_name : (new Date().getStdTimezoneOffset() / -60)); |
| | | |
| | | // display 'loading' message on form submit, lock submit button |
| | | $('form').submit(function () { |
| | |
| | | .bind('mouseup', body_mouseup) |
| | | .bind('keydown', function(e){ return ref.doc_keypress(e); }); |
| | | |
| | | $('iframe').load(function(e) { |
| | | $('iframe').on('load', function(e) { |
| | | try { $(this.contentDocument || this.contentWindow).on('mouseup', body_mouseup); } |
| | | catch (e) {/* catch possible "Permission denied" error in IE */ } |
| | | }) |
| | |
| | | } |
| | | |
| | | // check input before leaving compose step |
| | | if (this.task == 'mail' && this.env.action == 'compose' && $.inArray(command, this.env.compose_commands) < 0 && !this.env.server_error) { |
| | | if (this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning'))) |
| | | if (this.task == 'mail' && this.env.action == 'compose' && !this.env.server_error && command != 'save-pref' |
| | | && $.inArray(command, this.env.compose_commands) < 0 |
| | | ) { |
| | | if (!this.env.is_sent && this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning'))) |
| | | return false; |
| | | |
| | | // remove copy from local storage if compose screen is left intentionally |
| | |
| | | |
| | | case 'open': |
| | | if (uid = this.get_single_uid()) { |
| | | obj.href = this.url('show', {_mbox: this.get_message_mailbox(uid), _uid: uid}); |
| | | obj.href = this.url('show', this.params_from_uid(uid)); |
| | | return true; |
| | | } |
| | | break; |
| | |
| | | |
| | | case 'list': |
| | | if (props && props != '') { |
| | | this.reset_qsearch(); |
| | | this.reset_qsearch(true); |
| | | } |
| | | if (this.env.action == 'compose' && this.env.extwin) { |
| | | window.close(); |
| | |
| | | else { |
| | | // reload form |
| | | if (props == 'reload') { |
| | | form.action += '?_reload=1'; |
| | | form.action += '&_reload=1'; |
| | | } |
| | | else if (this.task == 'settings' && (this.env.identities_level % 2) == 0 && |
| | | (input = $("input[name='_email']", form)) && input.length && !rcube_check_email(input.val()) |
| | |
| | | break; |
| | | |
| | | case 'send': |
| | | if (!props.nocheck && !this.check_compose_input(command)) |
| | | if (!props.nocheck && !this.env.is_sent && !this.check_compose_input(command)) |
| | | break; |
| | | |
| | | // Reset the auto-save timer |
| | |
| | | this.gui_objects.messagepartframe.contentWindow.print(); |
| | | } |
| | | else if (uid = this.get_single_uid()) { |
| | | url = '&_action=print&_uid='+uid+'&_mbox='+urlencode(this.get_message_mailbox(uid))+(this.env.safemode ? '&_safe=1' : ''); |
| | | if (this.open_window(this.env.comm_path + url, true, true)) { |
| | | url = this.url('print', this.params_from_uid(uid, {_safe: this.env.safemode ? 1 : 0})); |
| | | if (this.open_window(url, true, true)) { |
| | | if (this.env.action != 'show') |
| | | this.mark_message('read', uid); |
| | | } |
| | |
| | | |
| | | case 'viewsource': |
| | | if (uid = this.get_single_uid()) |
| | | this.open_window(this.env.comm_path+'&_action=viewsource&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true, true); |
| | | this.open_window(this.url('viewsource', this.params_from_uid(uid)), true, true); |
| | | break; |
| | | |
| | | case 'download': |
| | |
| | | location.href = location.href.replace(/_frame=/, '_download='); |
| | | } |
| | | else if (uid = this.get_single_uid()) { |
| | | this.goto_url('viewsource', { _uid: uid, _mbox: this.get_message_mailbox(uid), _save: 1 }); |
| | | this.goto_url('viewsource', this.params_from_uid(uid, {_save: 1})); |
| | | } |
| | | break; |
| | | |
| | |
| | | |
| | | // reset quicksearch |
| | | case 'reset-search': |
| | | var n, s = this.env.search_request || this.env.qsearch, |
| | | ss = this.gui_objects.qsearchbox && this.gui_objects.qsearchbox.value != ''; |
| | | var n, s = this.env.search_request || this.env.qsearch; |
| | | |
| | | this.reset_qsearch(); |
| | | this.reset_qsearch(true); |
| | | this.select_all_mode = false; |
| | | |
| | | if (s && this.env.action == 'compose') { |
| | | if (this.contact_list) |
| | | this.list_contacts_clear(); |
| | | } |
| | | else if (s && ss && this.env.mailbox) { |
| | | else if (s && this.env.mailbox) { |
| | | this.list_mailbox(this.env.mailbox, 1); |
| | | } |
| | | else if (s && this.task == 'addressbook') { |
| | |
| | | |
| | | $('input[name="_unlock"]', form).val(importlock); |
| | | |
| | | if (!(flag = this.upload_file(form, 'import'))) { |
| | | if (!(flag = this.upload_file(form, 'import', importlock))) { |
| | | this.set_busy(false, null, importlock); |
| | | if (flag !== false) |
| | | alert(this.get_label('selectimportfile')); |
| | |
| | | else if (delay) |
| | | setTimeout(function() { ref.reload(); }, delay); |
| | | else if (window.location) |
| | | location.href = this.env.comm_path + (this.env.action ? '&_action='+this.env.action : ''); |
| | | location.href = this.url('', {_extwin: this.env.extwin}); |
| | | }; |
| | | |
| | | // Add variable to GET string, replace old value if exists |
| | |
| | | |
| | | this.folder_collapsed = function(node) |
| | | { |
| | | var prefname = this.env.task == 'addressbook' ? 'collapsed_abooks' : 'collapsed_folders'; |
| | | var prefname = this.env.task == 'addressbook' ? 'collapsed_abooks' : 'collapsed_folders', |
| | | old = this.env[prefname]; |
| | | |
| | | if (node.collapsed) { |
| | | this.env[prefname] = this.env[prefname] + '&'+urlencode(node.id)+'&'; |
| | | |
| | | // select the folder if one of its childs is currently selected |
| | | // don't select if it's virtual (#1488346) |
| | | if (!node.virtual && this.env.mailbox && this.env.mailbox.startsWith(name + this.env.delimiter)) |
| | | this.command('list', name); |
| | | if (!node.virtual && this.env.mailbox && this.env.mailbox.startsWith(node.id + this.env.delimiter)) |
| | | this.command('list', node.id); |
| | | } |
| | | else { |
| | | var reg = new RegExp('&'+urlencode(node.id)+'&'); |
| | |
| | | } |
| | | |
| | | if (!this.drag_active) { |
| | | this.command('save-pref', { name: prefname, value: this.env[prefname] }); |
| | | if (old !== this.env[prefname]) |
| | | this.command('save-pref', { name: prefname, value: this.env[prefname] }); |
| | | |
| | | if (this.env.unread_counts) |
| | | this.set_unread_count_display(node.id, false); |
| | |
| | | |
| | | this.set_list_sorting = function(sort_col, sort_order) |
| | | { |
| | | var sort_old = this.env.sort_col == 'arrival' ? 'date' : this.env.sort_col, |
| | | sort_new = sort_col == 'arrival' ? 'date' : sort_col; |
| | | |
| | | // set table header class |
| | | $('#rcm'+this.env.sort_col).removeClass('sorted'+(this.env.sort_order.toUpperCase())); |
| | | if (sort_col) |
| | | $('#rcm'+sort_col).addClass('sorted'+sort_order); |
| | | $('#rcm' + sort_old).removeClass('sorted' + this.env.sort_order.toUpperCase()); |
| | | if (sort_new) |
| | | $('#rcm' + sort_new).addClass('sorted' + sort_order); |
| | | |
| | | // if sorting by 'arrival' is selected, click on date column should not switch to 'date' |
| | | $('#rcmdate > a').prop('rel', sort_col == 'arrival' ? 'arrival' : 'date'); |
| | | |
| | | this.env.sort_col = sort_col; |
| | | this.env.sort_order = sort_order; |
| | |
| | | return; |
| | | |
| | | var win, target = window, |
| | | action = preview ? 'preview': 'show', |
| | | url = '&_action='+action+'&_uid='+id+'&_mbox='+urlencode(this.get_message_mailbox(id)); |
| | | url = this.params_from_uid(id, {_caps: this.browser_capabilities()}); |
| | | |
| | | if (preview && (win = this.get_frame_window(this.env.contentframe))) { |
| | | target = win; |
| | | url += '&_framed=1'; |
| | | url._framed = 1; |
| | | } |
| | | |
| | | if (safe) |
| | | url += '&_safe=1'; |
| | | url._safe = 1; |
| | | |
| | | // also send search request to get the right messages |
| | | if (this.env.search_request) |
| | | url += '&_search='+this.env.search_request; |
| | | |
| | | // add browser capabilities, so we can properly handle attachments |
| | | url += '&_caps='+urlencode(this.browser_capabilities()); |
| | | url._search = this.env.search_request; |
| | | |
| | | if (this.env.extwin) |
| | | url += '&_extwin=1'; |
| | | url._extwin = 1; |
| | | |
| | | url = this.url(preview ? 'preview': 'show', url); |
| | | |
| | | if (preview && String(target.location.href).indexOf(url) >= 0) { |
| | | this.show_contentframe(true); |
| | | } |
| | | else { |
| | | if (!preview && this.env.message_extwin && !this.env.extwin) |
| | | this.open_window(this.env.comm_path+url, true); |
| | | this.open_window(url, true); |
| | | else |
| | | this.location_href(this.env.comm_path+url, target, true); |
| | | this.location_href(url, target, true); |
| | | |
| | | // mark as read and change mbox unread counter |
| | | if (preview && this.message_list && this.message_list.rows[id] && this.message_list.rows[id].unread && this.env.preview_pane_mark_read > 0) { |
| | |
| | | // list messages of a specific mailbox using filter |
| | | this.filter_mailbox = function(filter) |
| | | { |
| | | if (this.filter_disabled) |
| | | return; |
| | | |
| | | var lock = this.set_busy(true, 'searching'); |
| | | |
| | | this.clear_message_list(); |
| | |
| | | if (sort) |
| | | url._sort = sort; |
| | | |
| | | // also send search request to get the right messages |
| | | if (this.env.search_request) |
| | | url._search = this.env.search_request; |
| | | |
| | | // set page=1 if changeing to another mailbox |
| | | // folder change, reset page, search scope, etc. |
| | | if (this.env.mailbox != mbox) { |
| | | page = 1; |
| | | this.env.current_page = page; |
| | | this.env.search_scope = 'base'; |
| | | this.select_all_mode = false; |
| | | this.reset_search_filter(); |
| | | } |
| | | // also send search request to get the right messages |
| | | else if (this.env.search_request) |
| | | url._search = this.env.search_request; |
| | | |
| | | if (!update_only) { |
| | | // unselect selected messages and clear the list and message data |
| | |
| | | this.set_alttext('delete', label); |
| | | }; |
| | | |
| | | // Initialize input element for list page jump |
| | | this.init_pagejumper = function(element) |
| | | { |
| | | $(element).addClass('rcpagejumper') |
| | | .on('focus', function(e) { |
| | | // create and display popup with page selection |
| | | var i, html = ''; |
| | | |
| | | for (i = 1; i <= ref.env.pagecount; i++) |
| | | html += '<li>' + i + '</li>'; |
| | | |
| | | html = '<ul class="toolbarmenu">' + html + '</ul>'; |
| | | |
| | | if (!ref.pagejump) { |
| | | ref.pagejump = $('<div id="pagejump-selector" class="popupmenu"></div>') |
| | | .appendTo(document.body) |
| | | .on('click', 'li', function() { |
| | | if (!ref.busy) |
| | | $(element).val($(this).text()).change(); |
| | | }); |
| | | } |
| | | |
| | | if (ref.pagejump.data('count') != i) |
| | | ref.pagejump.html(html); |
| | | |
| | | ref.pagejump.attr('rel', '#' + this.id).data('count', i); |
| | | |
| | | // display page selector |
| | | ref.show_menu('pagejump-selector', true, e); |
| | | $(this).keydown(); |
| | | }) |
| | | // keyboard navigation |
| | | .on('keydown keyup click', function(e) { |
| | | var current, selector = $('#pagejump-selector'), |
| | | ul = $('ul', selector), |
| | | list = $('li', ul), |
| | | height = ul.height(), |
| | | p = parseInt(this.value); |
| | | |
| | | if (e.which != 27 && e.which != 9 && e.which != 13 && !selector.is(':visible')) |
| | | return ref.show_menu('pagejump-selector', true, e); |
| | | |
| | | if (e.type == 'keydown') { |
| | | // arrow-down |
| | | if (e.which == 40) { |
| | | if (list.length > p) |
| | | this.value = (p += 1); |
| | | } |
| | | // arrow-up |
| | | else if (e.which == 38) { |
| | | if (p > 1 && list.length > p - 1) |
| | | this.value = (p -= 1); |
| | | } |
| | | // enter |
| | | else if (e.which == 13) { |
| | | return $(this).change(); |
| | | } |
| | | // esc, tab |
| | | else if (e.which == 27 || e.which == 9) { |
| | | return $(element).val(ref.env.current_page); |
| | | } |
| | | } |
| | | |
| | | $('li.selected', ul).removeClass('selected'); |
| | | |
| | | if ((current = $(list[p - 1])).length) { |
| | | current.addClass('selected'); |
| | | $('#pagejump-selector').scrollTop(((ul.height() / list.length) * (p - 1)) - selector.height() / 2); |
| | | } |
| | | }) |
| | | .on('change', function(e) { |
| | | // go to specified page |
| | | var p = parseInt(this.value); |
| | | if (p && p != ref.env.current_page && !ref.busy) { |
| | | ref.hide_menu('pagejump-selector'); |
| | | ref.list_page(p); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // Update page-jumper state on list updates |
| | | this.update_pagejumper = function() |
| | | { |
| | | $('input.rcpagejumper').val(this.env.current_page).prop('disabled', this.env.pagecount < 2); |
| | | }; |
| | | |
| | | // check for mailvelope API |
| | | this.check_mailvelope = function(action) |
| | | { |
| | | if (typeof window.mailvelope !== 'undefined') { |
| | | this.mailvelope_load(action); |
| | | } |
| | | else { |
| | | $(window).on('mailvelope', function() { |
| | | ref.mailvelope_load(action); |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | // Load Mailvelope functionality (and initialize keyring if needed) |
| | | this.mailvelope_load = function(action) |
| | | { |
| | | if (this.env.browser_capabilities) |
| | | this.env.browser_capabilities['pgpmime'] = 1; |
| | | |
| | | var keyring = this.env.user_id; |
| | | |
| | | mailvelope.getKeyring(keyring).then(function(kr) { |
| | | ref.mailvelope_keyring = kr; |
| | | ref.mailvelope_init(action, kr); |
| | | }).catch(function(err) { |
| | | // attempt to create a new keyring for this app/user |
| | | mailvelope.createKeyring(keyring).then(function(kr) { |
| | | ref.mailvelope_keyring = kr; |
| | | ref.mailvelope_init(action, kr); |
| | | }).catch(function(err) { |
| | | console.error(err); |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | // Initializes Mailvelope editor or display container |
| | | this.mailvelope_init = function(action, keyring) |
| | | { |
| | | if (!window.mailvelope) |
| | | return; |
| | | |
| | | if (action == 'show' || action == 'preview' || action == 'print') { |
| | | // decrypt text body |
| | | if (this.env.is_pgp_content) { |
| | | var data = $(this.env.is_pgp_content).text(); |
| | | ref.mailvelope_display_container(this.env.is_pgp_content, data, keyring); |
| | | } |
| | | // load pgp/mime message and pass it to the mailvelope display container |
| | | else if (this.env.pgp_mime_part) { |
| | | var msgid = this.display_message(this.get_label('loadingdata'), 'loading'), |
| | | selector = this.env.pgp_mime_container; |
| | | |
| | | $.ajax({ |
| | | type: 'GET', |
| | | url: this.url('get', { '_mbox': this.env.mailbox, '_uid': this.env.uid, '_part': this.env.pgp_mime_part }), |
| | | error: function(o, status, err) { |
| | | ref.http_error(o, status, err, msgid); |
| | | }, |
| | | success: function(data) { |
| | | ref.mailvelope_display_container(selector, data, keyring, msgid); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | else if (action == 'compose') { |
| | | this.env.compose_commands.push('compose-encrypted'); |
| | | // display the toolbar button |
| | | $('#' + this.buttons['compose-encrypted'][0].id).show(); |
| | | |
| | | var is_html = $('input[name="_is_html"]').val() > 0; |
| | | |
| | | if (this.env.pgp_mime_message) { |
| | | // fetch PGP/Mime part and open load into Mailvelope editor |
| | | var lock = this.set_busy(true, this.get_label('loadingdata')); |
| | | |
| | | $.ajax({ |
| | | type: 'GET', |
| | | url: this.url('get', this.env.pgp_mime_message), |
| | | error: function(o, status, err) { |
| | | ref.http_error(o, status, err, lock); |
| | | ref.enable_command('compose-encrypted', !is_html); |
| | | }, |
| | | success: function(data) { |
| | | ref.set_busy(false, null, lock); |
| | | |
| | | if (is_html) { |
| | | ref.command('toggle-editor', {html: false, noconvert: true}); |
| | | $('#' + ref.env.composebody).val(''); |
| | | } |
| | | |
| | | ref.compose_encrypted({ quotedMail: data }); |
| | | ref.enable_command('compose-encrypted', true); |
| | | } |
| | | }); |
| | | } |
| | | else { |
| | | // enable encrypted compose toggle |
| | | this.enable_command('compose-encrypted', !is_html); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | // handler for the 'compose-encrypted' command |
| | | this.compose_encrypted = function(props) |
| | | { |
| | | var options, container = $('#' + this.env.composebody).parent(); |
| | | |
| | | // remove Mailvelope editor if active |
| | | if (ref.mailvelope_editor) { |
| | | ref.mailvelope_editor = null; |
| | | ref.compose_skip_unsavedcheck = false; |
| | | ref.set_button('compose-encrypted', 'act'); |
| | | |
| | | container.removeClass('mailvelope') |
| | | .find('iframe:not([aria-hidden=true])').remove(); |
| | | $('#' + ref.env.composebody).show(); |
| | | $("[name='_pgpmime']").remove(); |
| | | |
| | | // disable commands that operate on the compose body |
| | | ref.enable_command('spellcheck', 'insert-sig', 'toggle-editor', 'insert-response', 'save-response', true); |
| | | ref.triggerEvent('compose-encrypted', { active:false }); |
| | | } |
| | | // embed Mailvelope editor container |
| | | else { |
| | | if (this.spellcheck_state()) |
| | | this.editor.spellcheck_stop(); |
| | | |
| | | if (props.quotedMail) { |
| | | options = { quotedMail: props.quotedMail, quotedMailIndent: false }; |
| | | } |
| | | else { |
| | | options = { predefinedText: $('#' + this.env.composebody).val() }; |
| | | } |
| | | |
| | | if (this.env.compose_mode == 'reply') { |
| | | options.quotedMailIndent = true; |
| | | options.quotedMailHeader = this.env.compose_reply_header; |
| | | } |
| | | |
| | | mailvelope.createEditorContainer('#' + container.attr('id'), ref.mailvelope_keyring, options).then(function(editor) { |
| | | ref.mailvelope_editor = editor; |
| | | ref.compose_skip_unsavedcheck = true; |
| | | ref.set_button('compose-encrypted', 'sel'); |
| | | |
| | | container.addClass('mailvelope'); |
| | | $('#' + ref.env.composebody).hide(); |
| | | |
| | | // disable commands that operate on the compose body |
| | | ref.enable_command('spellcheck', 'insert-sig', 'toggle-editor', 'insert-response', 'save-response', false); |
| | | ref.triggerEvent('compose-encrypted', { active:true }); |
| | | |
| | | // notify user about loosing attachments |
| | | if (ref.env.attachments && !$.isEmptyObject(ref.env.attachments)) { |
| | | alert(ref.get_label('encryptnoattachments')); |
| | | |
| | | $.each(ref.env.attachments, function(name, attach) { |
| | | ref.remove_from_attachment_list(name); |
| | | }); |
| | | } |
| | | }).catch(function(err) { |
| | | console.error(err); |
| | | console.log(options); |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | // callback to replace the message body with the full armored |
| | | this.mailvelope_submit_messageform = function(draft, saveonly) |
| | | { |
| | | // get recipients |
| | | var recipients = []; |
| | | $.each(['to', 'cc', 'bcc'], function(i,field) { |
| | | var pos, rcpt, val = $.trim($('[name="_' + field + '"]').val()); |
| | | while (val.length && rcube_check_email(val, true)) { |
| | | rcpt = RegExp.$2; |
| | | recipients.push(rcpt); |
| | | val = val.substr(val.indexOf(rcpt) + rcpt.length + 1).replace(/^\s*,\s*/, ''); |
| | | } |
| | | }); |
| | | |
| | | // check if we have keys for all recipients |
| | | var isvalid = recipients.length > 0; |
| | | ref.mailvelope_keyring.validKeyForAddress(recipients).then(function(status) { |
| | | var missing_keys = []; |
| | | $.each(status, function(k,v) { |
| | | if (v === false) { |
| | | isvalid = false; |
| | | missing_keys.push(k); |
| | | } |
| | | }); |
| | | |
| | | // list recipients with missing keys |
| | | if (!isvalid && missing_keys.length) { |
| | | // load publickey.js |
| | | if (!$('script#publickeyjs').length) { |
| | | $('<script>') |
| | | .attr('id', 'publickeyjs') |
| | | .attr('src', ref.assets_path('program/js/publickey.js')) |
| | | .appendTo(document.body); |
| | | } |
| | | |
| | | // display dialog with missing keys |
| | | ref.show_popup_dialog( |
| | | ref.get_label('nopubkeyfor').replace('$email', missing_keys.join(', ')) + |
| | | '<p>' + ref.get_label('searchpubkeyservers') + '</p>', |
| | | ref.get_label('encryptedsendialog'), |
| | | [{ |
| | | text: ref.get_label('search'), |
| | | 'class': 'mainaction', |
| | | click: function() { |
| | | var $dialog = $(this); |
| | | ref.mailvelope_search_pubkeys(missing_keys, function() { |
| | | $dialog.dialog('close') |
| | | }); |
| | | } |
| | | }, |
| | | { |
| | | text: ref.get_label('cancel'), |
| | | click: function(){ |
| | | $(this).dialog('close'); |
| | | } |
| | | }] |
| | | ); |
| | | return false; |
| | | } |
| | | |
| | | if (!isvalid) { |
| | | if (!recipients.length) { |
| | | alert(ref.get_label('norecipientwarning')); |
| | | $("[name='_to']").focus(); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | // add sender identity to recipients to be able to decrypt our very own message |
| | | var senders = [], selected_sender = ref.env.identities[$("[name='_from'] option:selected").val()]; |
| | | $.each(ref.env.identities, function(k, sender) { |
| | | senders.push(sender.email); |
| | | }); |
| | | |
| | | ref.mailvelope_keyring.validKeyForAddress(senders).then(function(status) { |
| | | valid_sender = null; |
| | | $.each(status, function(k,v) { |
| | | if (v !== false) { |
| | | valid_sender = k; |
| | | if (valid_sender == selected_sender) { |
| | | return false; // break |
| | | } |
| | | } |
| | | }); |
| | | |
| | | if (!valid_sender) { |
| | | if (!confirm(ref.get_label('nopubkeyforsender'))) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | recipients.push(valid_sender); |
| | | |
| | | ref.mailvelope_editor.encrypt(recipients).then(function(armored) { |
| | | // all checks passed, send message |
| | | var form = ref.gui_objects.messageform, |
| | | hidden = $("[name='_pgpmime']", form), |
| | | msgid = ref.set_busy(true, draft || saveonly ? 'savingmessage' : 'sendingmessage') |
| | | |
| | | form.target = 'savetarget'; |
| | | form._draft.value = draft ? '1' : ''; |
| | | form.action = ref.add_url(form.action, '_unlock', msgid); |
| | | form.action = ref.add_url(form.action, '_framed', 1); |
| | | |
| | | if (saveonly) { |
| | | form.action = ref.add_url(form.action, '_saveonly', 1); |
| | | } |
| | | |
| | | // send pgp conent via hidden field |
| | | if (!hidden.length) { |
| | | hidden = $('<input type="hidden" name="_pgpmime">').appendTo(form); |
| | | } |
| | | hidden.val(armored); |
| | | |
| | | form.submit(); |
| | | |
| | | }).catch(function(err) { |
| | | console.log(err); |
| | | }); // mailvelope_editor.encrypt() |
| | | |
| | | }).catch(function(err) { |
| | | console.error(err); |
| | | }); // mailvelope_keyring.validKeyForAddress(senders) |
| | | |
| | | }).catch(function(err) { |
| | | console.error(err); |
| | | }); // mailvelope_keyring.validKeyForAddress(recipients) |
| | | |
| | | return false; |
| | | }; |
| | | |
| | | // wrapper for the mailvelope.createDisplayContainer API call |
| | | this.mailvelope_display_container = function(selector, data, keyring, msgid) |
| | | { |
| | | mailvelope.createDisplayContainer(selector, data, keyring, { showExternalContent: this.env.safemode }).then(function() { |
| | | $(selector).addClass('mailvelope').children().not('iframe').hide(); |
| | | ref.hide_message(msgid); |
| | | setTimeout(function() { $(window).resize(); }, 10); |
| | | }).catch(function(err) { |
| | | console.error(err); |
| | | ref.hide_message(msgid); |
| | | ref.display_message('Message decryption failed: ' + err.message, 'error') |
| | | }); |
| | | }; |
| | | |
| | | // subroutine to query keyservers for public keys |
| | | this.mailvelope_search_pubkeys = function(emails, resolve) |
| | | { |
| | | // query with publickey.js |
| | | var deferreds = [], |
| | | pk = new PublicKey(), |
| | | lock = ref.display_message(ref.get_label('loading'), 'loading'); |
| | | |
| | | $.each(emails, function(i, email) { |
| | | var d = $.Deferred(); |
| | | pk.search(email, function(results, errorCode) { |
| | | if (errorCode !== null) { |
| | | // rejecting would make all fail |
| | | // d.reject(email); |
| | | d.resolve([email]); |
| | | } |
| | | else { |
| | | d.resolve([email].concat(results)); |
| | | } |
| | | }); |
| | | deferreds.push(d); |
| | | }); |
| | | |
| | | $.when.apply($, deferreds).then(function() { |
| | | var missing_keys = [], |
| | | key_selection = []; |
| | | |
| | | // alanyze results of all queries |
| | | $.each(arguments, function(i, result) { |
| | | var email = result.shift(); |
| | | if (!result.length) { |
| | | missing_keys.push(email); |
| | | } |
| | | else { |
| | | key_selection = key_selection.concat(result); |
| | | } |
| | | }); |
| | | |
| | | ref.hide_message(lock); |
| | | resolve(true); |
| | | |
| | | // show key import dialog |
| | | if (key_selection.length) { |
| | | ref.mailvelope_key_import_dialog(key_selection); |
| | | } |
| | | // some keys could not be found |
| | | if (missing_keys.length) { |
| | | ref.display_message(ref.get_label('nopubkeyfor').replace('$email', missing_keys.join(', ')), 'warning'); |
| | | } |
| | | }, function() { |
| | | console.error('Pubkey lookup failed with', arguments); |
| | | ref.hide_message(lock); |
| | | ref.display_message('pubkeysearcherror', 'error'); |
| | | resolve(false); |
| | | }); |
| | | }; |
| | | |
| | | // list the given public keys in a dialog with options to import |
| | | // them into the local Maivelope keyring |
| | | this.mailvelope_key_import_dialog = function(candidates) |
| | | { |
| | | var ul = $('<div>').addClass('listing mailvelopekeyimport'); |
| | | $.each(candidates, function(i, keyrec) { |
| | | var li = $('<div>').addClass('key'); |
| | | if (keyrec.revoked) li.addClass('revoked'); |
| | | if (keyrec.disabled) li.addClass('disabled'); |
| | | if (keyrec.expired) li.addClass('expired'); |
| | | |
| | | li.append($('<label>').addClass('keyid').text(ref.get_label('keyid'))); |
| | | li.append($('<a>').text(keyrec.keyid.substr(-8).toUpperCase()) |
| | | .attr('href', keyrec.info) |
| | | .attr('target', '_blank') |
| | | .attr('tabindex', '-1')); |
| | | |
| | | li.append($('<label>').addClass('keylen').text(ref.get_label('keylength'))); |
| | | li.append($('<span>').text(keyrec.keylen)); |
| | | |
| | | if (keyrec.expirationdate) { |
| | | li.append($('<label>').addClass('keyexpired').text(ref.get_label('keyexpired'))); |
| | | li.append($('<span>').text(new Date(keyrec.expirationdate * 1000).toDateString())); |
| | | } |
| | | |
| | | if (keyrec.revoked) { |
| | | li.append($('<span>').addClass('keyrevoked').text(ref.get_label('keyrevoked'))); |
| | | } |
| | | |
| | | var ul_ = $('<ul>').addClass('uids'); |
| | | $.each(keyrec.uids, function(j, uid) { |
| | | var li_ = $('<li>').addClass('uid'); |
| | | if (uid.revoked) li_.addClass('revoked'); |
| | | if (uid.disabled) li_.addClass('disabled'); |
| | | if (uid.expired) li_.addClass('expired'); |
| | | |
| | | ul_.append(li_.text(uid.uid)); |
| | | }); |
| | | |
| | | li.append(ul_); |
| | | li.append($('<input>') |
| | | .attr('type', 'button') |
| | | .attr('rel', keyrec.keyid) |
| | | .attr('value', ref.get_label('import')) |
| | | .addClass('button importkey') |
| | | .prop('disabled', keyrec.revoked || keyrec.disabled || keyrec.expired)); |
| | | |
| | | ul.append(li); |
| | | }); |
| | | |
| | | // display dialog with missing keys |
| | | ref.show_popup_dialog( |
| | | $('<div>') |
| | | .append($('<p>').html(ref.get_label('encryptpubkeysfound'))) |
| | | .append(ul), |
| | | ref.get_label('importpubkeys'), |
| | | [{ |
| | | text: ref.get_label('close'), |
| | | click: function(){ |
| | | $(this).dialog('close'); |
| | | } |
| | | }] |
| | | ); |
| | | |
| | | // delegate handler for import button clicks |
| | | ul.on('click', 'input.button.importkey', function() { |
| | | var btn = $(this), |
| | | keyid = btn.attr('rel'), |
| | | pk = new PublicKey(), |
| | | lock = ref.display_message(ref.get_label('loading'), 'loading'); |
| | | |
| | | // fetch from keyserver and import to Mailvelope keyring |
| | | pk.get(keyid, function(armored, errorCode) { |
| | | ref.hide_message(lock); |
| | | |
| | | if (errorCode) { |
| | | ref.display_message(ref.get_label('keyservererror'), 'error'); |
| | | return; |
| | | } |
| | | |
| | | // import to keyring |
| | | ref.mailvelope_keyring.importPublicKey(armored).then(function(status) { |
| | | if (status === 'REJECTED') { |
| | | // alert(ref.get_label('Key import was rejected')); |
| | | } |
| | | else { |
| | | var $key = keyid.substr(-8).toUpperCase(); |
| | | btn.closest('.key').fadeOut(); |
| | | ref.display_message(ref.get_label('keyimportsuccess').replace('$key', $key), 'confirmation'); |
| | | } |
| | | }).catch(function(err) { |
| | | console.log(err); |
| | | }); |
| | | }); |
| | | }); |
| | | |
| | | }; |
| | | |
| | | |
| | | /*********************************************************/ |
| | | /********* mailbox folders methods *********/ |
| | | /*********************************************************/ |
| | |
| | | if (!this.gui_objects.messageform) |
| | | return false; |
| | | |
| | | var i, pos, input_from = $("[name='_from']"), |
| | | var i, elem, pos, input_from = $("[name='_from']"), |
| | | input_to = $("[name='_to']"), |
| | | input_subject = $("input[name='_subject']"), |
| | | input_message = $("[name='_message']").get(0), |
| | |
| | | |
| | | if (!html_mode) { |
| | | pos = this.env.top_posting ? 0 : input_message.value.length; |
| | | this.set_caret_pos(input_message, pos); |
| | | |
| | | // add signature according to selected identity |
| | | // if we have HTML editor, signature is added in callback |
| | | // if we have HTML editor, signature is added in a callback |
| | | if (input_from.prop('type') == 'select-one') { |
| | | this.change_identity(input_from[0]); |
| | | } |
| | | |
| | | // set initial cursor position |
| | | this.set_caret_pos(input_message, pos); |
| | | |
| | | // scroll to the bottom of the textarea (#1490114) |
| | | if (pos) { |
| | |
| | | this.compose_restore_dialog(0, html_mode) |
| | | |
| | | if (input_to.val() == '') |
| | | input_to.focus(); |
| | | elem = input_to; |
| | | else if (input_subject.val() == '') |
| | | input_subject.focus(); |
| | | elem = input_subject; |
| | | else if (input_message) |
| | | input_message.focus(); |
| | | elem = input_message; |
| | | |
| | | // focus first empty element (need to be visible on IE8) |
| | | $(elem).filter(':visible').focus(); |
| | | |
| | | this.env.compose_focus_elem = document.activeElement; |
| | | |
| | |
| | | .attr({ 'autocomplete': 'off', 'aria-autocomplete': 'list', 'aria-expanded': 'false', 'role': 'combobox' }); |
| | | }; |
| | | |
| | | this.submit_messageform = function(draft) |
| | | this.submit_messageform = function(draft, saveonly) |
| | | { |
| | | var form = this.gui_objects.messageform; |
| | | |
| | | if (!form) |
| | | return; |
| | | |
| | | // the message has been sent but not saved, ask the user what to do |
| | | if (!saveonly && this.env.is_sent) { |
| | | return this.show_popup_dialog(this.get_label('messageissent'), '', |
| | | [{ |
| | | text: this.get_label('save'), |
| | | 'class': 'mainaction', |
| | | click: function() { |
| | | ref.submit_messageform(false, true); |
| | | $(this).dialog('close'); |
| | | } |
| | | }, |
| | | { |
| | | text: this.get_label('cancel'), |
| | | click: function() { |
| | | $(this).dialog('close'); |
| | | } |
| | | }] |
| | | ); |
| | | } |
| | | |
| | | // delegate sending to Mailvelope routine |
| | | if (this.mailvelope_editor) { |
| | | return this.mailvelope_submit_messageform(draft, saveonly); |
| | | } |
| | | |
| | | // all checks passed, send message |
| | | var msgid = this.set_busy(true, draft ? 'savingmessage' : 'sendingmessage'), |
| | | var msgid = this.set_busy(true, draft || saveonly ? 'savingmessage' : 'sendingmessage'), |
| | | lang = this.spellcheck_lang(), |
| | | files = []; |
| | | |
| | |
| | | form.action = this.add_url(form.action, '_unlock', msgid); |
| | | form.action = this.add_url(form.action, '_lang', lang); |
| | | form.action = this.add_url(form.action, '_framed', 1); |
| | | |
| | | if (saveonly) { |
| | | form.action = this.add_url(form.action, '_saveonly', 1); |
| | | } |
| | | |
| | | // register timer to notify about connection timeout |
| | | this.submit_timer = setTimeout(function(){ |
| | |
| | | var oldval = input.val(), rx = new RegExp(RegExp.escape(delim) + '\\s*$'); |
| | | if (oldval && !rx.test(oldval)) |
| | | oldval += delim + ' '; |
| | | input.val(oldval + recipients.join(delim + ' ') + delim + ' '); |
| | | input.val(oldval + recipients.join(delim + ' ') + delim + ' ').change(); |
| | | this.triggerEvent('add-recipient', { field:field, recipients:recipients }); |
| | | } |
| | | |
| | |
| | | if (result) { |
| | | // update internal format flag |
| | | $("input[name='_is_html']").val(props.html ? 1 : 0); |
| | | // enable encrypted compose toggle |
| | | this.enable_command('compose-encrypted', !props.html); |
| | | } |
| | | |
| | | return result; |
| | |
| | | |
| | | // reset history of hidden iframe used for saving draft (#1489643) |
| | | // but don't do this on timer-triggered draft-autosaving (#1489789) |
| | | if (window.frames['savetarget'] && window.frames['savetarget'].history && !this.draft_autosave_submit) { |
| | | if (window.frames['savetarget'] && window.frames['savetarget'].history && !this.draft_autosave_submit && !this.mailvelope_editor) { |
| | | window.frames['savetarget'].history.back(); |
| | | } |
| | | |
| | |
| | | } |
| | | }, 5000); |
| | | |
| | | $(window).unload(function() { |
| | | $(window).on('unload', function() { |
| | | // remove copy from local storage if compose screen is left after warning |
| | | if (!ref.env.server_error) |
| | | ref.remove_compose_data(ref.env.compose_id); |
| | |
| | | if (this.env.attachments) |
| | | for (id in this.env.attachments) |
| | | str += id; |
| | | |
| | | // we can't detect changes in the Mailvelope editor so assume it changed |
| | | if (this.mailvelope_editor) { |
| | | str += ';' + new Date().getTime(); |
| | | } |
| | | |
| | | if (save) |
| | | this.cmp_hash = str; |
| | |
| | | }; |
| | | |
| | | // upload (attachment) file |
| | | this.upload_file = function(form, action) |
| | | this.upload_file = function(form, action, lock) |
| | | { |
| | | if (!form) |
| | | return; |
| | |
| | | if (!content.match(/display_message/)) |
| | | ref.display_message(ref.get_label('fileuploaderror'), 'error'); |
| | | ref.remove_from_attachment_list(e.data.ts); |
| | | |
| | | if (lock) |
| | | ref.set_busy(false, null, lock); |
| | | } |
| | | // Opera hack: handle double onload |
| | | if (bw.opera) |
| | |
| | | return url; |
| | | }; |
| | | |
| | | // reset search filter |
| | | this.reset_search_filter = function() |
| | | { |
| | | this.filter_disabled = true; |
| | | if (this.gui_objects.search_filter) |
| | | $(this.gui_objects.search_filter).val('ALL').change(); |
| | | this.filter_disabled = false; |
| | | }; |
| | | |
| | | // reset quick-search form |
| | | this.reset_qsearch = function() |
| | | this.reset_qsearch = function(all) |
| | | { |
| | | if (this.gui_objects.qsearchbox) |
| | | this.gui_objects.qsearchbox.value = ''; |
| | | |
| | | if (this.env.qsearch) |
| | | this.abort_request(this.env.qsearch); |
| | | |
| | | if (all) { |
| | | this.env.search_scope = 'base'; |
| | | this.reset_search_filter(); |
| | | } |
| | | |
| | | this.env.qsearch = null; |
| | | this.env.search_request = null; |
| | |
| | | }; |
| | | |
| | | // action executed after mail is sent |
| | | this.sent_successfully = function(type, msg, folders) |
| | | this.sent_successfully = function(type, msg, folders, save_error) |
| | | { |
| | | this.display_message(msg, type); |
| | | this.compose_skip_unsavedcheck = true; |
| | | |
| | | if (this.env.extwin) { |
| | | this.lock_form(this.gui_objects.messageform); |
| | | if (!save_error) |
| | | this.lock_form(this.gui_objects.messageform); |
| | | |
| | | var filter = {task: 'mail', action: ''}, |
| | | rc = this.opener(false, filter) || this.opener(true, filter); |
| | |
| | | } |
| | | } |
| | | |
| | | setTimeout(function() { window.close(); }, 1000); |
| | | if (!save_error) |
| | | setTimeout(function() { window.close(); }, 1000); |
| | | } |
| | | else { |
| | | else if (!save_error) { |
| | | // before redirect we need to wait some time for Chrome (#1486177) |
| | | setTimeout(function() { ref.list_mailbox(); }, 500); |
| | | } |
| | | |
| | | if (save_error) |
| | | this.env.is_sent = true; |
| | | }; |
| | | |
| | | |
| | |
| | | { |
| | | this.enable_command('nextpage', 'lastpage', this.env.pagecount > this.env.current_page); |
| | | this.enable_command('previouspage', 'firstpage', this.env.current_page > 1); |
| | | |
| | | this.update_pagejumper(); |
| | | }; |
| | | |
| | | // mark a mailbox as selected and set environment variable |
| | |
| | | repl, cell, col, n, len, tr; |
| | | |
| | | this.env.listcols = listcols; |
| | | |
| | | if (!this.env.coltypes) |
| | | this.env.coltypes = {}; |
| | | |
| | | // replace old column headers |
| | | if (thead) { |
| | |
| | | if (show) { |
| | | // truncate stack down to the one containing the ref link |
| | | for (var i = this.menu_stack.length - 1; stack && i >= 0; i--) { |
| | | if (!$(ref).parents('#'+this.menu_stack[i]).length) |
| | | if (!$(ref).parents('#'+this.menu_stack[i]).length && $(event.target).parent().attr('role') != 'menuitem') |
| | | this.hide_menu(this.menu_stack[i], event); |
| | | } |
| | | if (stack && this.menu_stack.length) { |
| | |
| | | // compose a valid url with the given parameters |
| | | this.url = function(action, query) |
| | | { |
| | | var querystring = typeof query === 'string' ? '&' + query : ''; |
| | | var querystring = typeof query === 'string' ? query : ''; |
| | | |
| | | if (typeof action !== 'string') |
| | | query = action; |
| | |
| | | else if (this.env.action) |
| | | query._action = this.env.action; |
| | | |
| | | var base = this.env.comm_path, k, param = {}; |
| | | var url = this.env.comm_path, k, param = {}; |
| | | |
| | | // overwrite task name |
| | | if (action && action.match(/([a-z0-9_-]+)\/([a-z0-9-_.]+)/)) { |
| | | query._action = RegExp.$2; |
| | | base = base.replace(/\_task=[a-z0-9_-]+/, '_task='+RegExp.$1); |
| | | url = url.replace(/\_task=[a-z0-9_-]+/, '_task=' + RegExp.$1); |
| | | } |
| | | |
| | | // remove undefined values |
| | |
| | | param[k] = query[k]; |
| | | } |
| | | |
| | | return base + (base.indexOf('?') > -1 ? '&' : '?') + $.param(param) + querystring; |
| | | if (param = $.param(param)) |
| | | url += (url.indexOf('?') > -1 ? '&' : '?') + param; |
| | | |
| | | if (querystring) |
| | | url += (url.indexOf('?') > -1 ? '&' : '?') + querystring; |
| | | |
| | | return url; |
| | | }; |
| | | |
| | | this.redirect = function(url, lock) |
| | |
| | | }; |
| | | |
| | | // send a http request to the server |
| | | this.http_request = function(action, query, lock) |
| | | this.http_request = function(action, data, lock) |
| | | { |
| | | var url = this.url(action, query); |
| | | if (typeof data !== 'object') |
| | | data = rcube_parse_query(data); |
| | | |
| | | data._remote = 1; |
| | | data._unlock = lock ? lock : 0; |
| | | |
| | | // trigger plugin hook |
| | | var result = this.triggerEvent('request'+action, query); |
| | | var result = this.triggerEvent('request' + action, data); |
| | | |
| | | if (result !== undefined) { |
| | | // abort if one the handlers returned false |
| | | if (result === false) |
| | | return false; |
| | | else |
| | | url = this.url(action, result); |
| | | // abort if one of the handlers returned false |
| | | if (result === false) { |
| | | if (data._unlock) |
| | | this.set_busy(false, null, data._unlock); |
| | | return false; |
| | | } |
| | | else if (result !== undefined) { |
| | | data = result; |
| | | if (data._action) { |
| | | action = data._action; |
| | | delete data._action; |
| | | } |
| | | } |
| | | |
| | | url += '&_remote=1'; |
| | | var url = this.url(action, data); |
| | | |
| | | // send request |
| | | this.log('HTTP GET: ' + url); |
| | |
| | | this.start_keepalive(); |
| | | |
| | | return $.ajax({ |
| | | type: 'GET', url: url, data: { _unlock:(lock?lock:0) }, dataType: 'json', |
| | | success: function(data){ ref.http_response(data); }, |
| | | type: 'GET', url: url, dataType: 'json', |
| | | success: function(data) { ref.http_response(data); }, |
| | | error: function(o, status, err) { ref.http_error(o, status, err, lock, action); } |
| | | }); |
| | | }; |
| | | |
| | | // send a http POST request to the server |
| | | this.http_post = function(action, postdata, lock) |
| | | this.http_post = function(action, data, lock) |
| | | { |
| | | var url = this.url(action); |
| | | if (typeof data !== 'object') |
| | | data = rcube_parse_query(data); |
| | | |
| | | if (postdata && typeof postdata === 'object') { |
| | | postdata._remote = 1; |
| | | postdata._unlock = (lock ? lock : 0); |
| | | } |
| | | else |
| | | postdata += (postdata ? '&' : '') + '_remote=1' + (lock ? '&_unlock='+lock : ''); |
| | | data._remote = 1; |
| | | data._unlock = lock ? lock : 0; |
| | | |
| | | // trigger plugin hook |
| | | var result = this.triggerEvent('request'+action, postdata); |
| | | if (result !== undefined) { |
| | | // abort if one of the handlers returned false |
| | | if (result === false) |
| | | return false; |
| | | else |
| | | postdata = result; |
| | | var result = this.triggerEvent('request'+action, data); |
| | | |
| | | // abort if one of the handlers returned false |
| | | if (result === false) { |
| | | if (data._unlock) |
| | | this.set_busy(false, null, data._unlock); |
| | | return false; |
| | | } |
| | | else if (result !== undefined) { |
| | | data = result; |
| | | if (data._action) { |
| | | action = data._action; |
| | | delete data._action; |
| | | } |
| | | } |
| | | |
| | | var url = this.url(action); |
| | | |
| | | // send request |
| | | this.log('HTTP POST: ' + url); |
| | |
| | | this.start_keepalive(); |
| | | |
| | | return $.ajax({ |
| | | type: 'POST', url: url, data: postdata, dataType: 'json', |
| | | type: 'POST', url: url, data: data, dataType: 'json', |
| | | success: function(data){ ref.http_response(data); }, |
| | | error: function(o, status, err) { ref.http_error(o, status, err, lock, action); } |
| | | }); |
| | |
| | | this.env.qsearch = null; |
| | | case 'list': |
| | | if (this.task == 'mail') { |
| | | var is_multifolder = this.is_multifolder_listing(); |
| | | var is_multifolder = this.is_multifolder_listing(), |
| | | list = this.message_list, |
| | | uid = this.env.list_uid; |
| | | |
| | | this.enable_command('show', 'select-all', 'select-none', this.env.messagecount > 0); |
| | | this.enable_command('expunge', this.env.exists && !is_multifolder); |
| | | this.enable_command('purge', this.purge_mailbox_test() && !is_multifolder); |
| | | this.enable_command('import-messages', !is_multifolder); |
| | | this.enable_command('expand-all', 'expand-unread', 'collapse-all', this.env.threading && this.env.messagecount && !is_multifolder); |
| | | |
| | | if ((response.action == 'list' || response.action == 'search') && this.message_list) { |
| | | var list = this.message_list, uid = this.env.list_uid; |
| | | |
| | | // highlight message row when we're back from message page |
| | | if (uid) { |
| | | if (!list.rows[uid]) |
| | | uid += '-' + this.env.mailbox; |
| | | if (list.rows[uid]) { |
| | | list.select(uid); |
| | | if (list) { |
| | | if (response.action == 'list' || response.action == 'search') { |
| | | // highlight message row when we're back from message page |
| | | if (uid) { |
| | | if (!list.rows[uid]) |
| | | uid += '-' + this.env.mailbox; |
| | | if (list.rows[uid]) { |
| | | list.select(uid); |
| | | } |
| | | delete this.env.list_uid; |
| | | } |
| | | delete this.env.list_uid; |
| | | |
| | | this.enable_command('set-listmode', this.env.threads && !is_multifolder); |
| | | if (list.rowcount > 0 && !$(document.activeElement).is('input,textarea')) |
| | | list.focus(); |
| | | this.msglist_select(list); |
| | | } |
| | | |
| | | this.enable_command('set-listmode', this.env.threads && !is_multifolder); |
| | | if (list.rowcount > 0) |
| | | list.focus(); |
| | | this.msglist_select(list); |
| | | this.triggerEvent('listupdate', { folder:this.env.mailbox, rowcount:list.rowcount }); |
| | | |
| | | if (response.action != 'getunread') |
| | | this.triggerEvent('listupdate', { folder:this.env.mailbox, rowcount:list.rowcount }); |
| | | } |
| | | } |
| | | else if (this.task == 'addressbook') { |
| | |
| | | this.enable_command('search-create', this.env.source == ''); |
| | | this.enable_command('search-delete', this.env.search_id); |
| | | this.update_group_commands(); |
| | | if (this.contact_list.rowcount > 0) |
| | | if (this.contact_list.rowcount > 0 && !$(document.activeElement).is('input,textarea')) |
| | | this.contact_list.focus(); |
| | | this.triggerEvent('listupdate', { folder:this.env.source, rowcount:this.contact_list.rowcount }); |
| | | } |
| | |
| | | var submit_data = function() { |
| | | var multiple = files.length > 1, |
| | | ts = new Date().getTime(), |
| | | content = '<span>' + (multiple ? ref.get_label('uploadingmany') : files[0].name) + '</span>'; |
| | | // jQuery way to escape filename (#1490530) |
| | | content = $('<span>').text(multiple ? ref.get_label('uploadingmany') : files[0].name).html(); |
| | | |
| | | // add to attachments list |
| | | if (!ref.add2attachment_list(ts, { name:'', html:content, classname:'uploading', complete:false })) |
| | |
| | | // get the IMP mailbox of the message with the given UID |
| | | this.get_message_mailbox = function(uid) |
| | | { |
| | | var msg = this.env.messages ? this.env.messages[uid] : {}; |
| | | var msg = (this.env.messages && uid ? this.env.messages[uid] : null) || {}; |
| | | return msg.mbox || this.env.mailbox; |
| | | }; |
| | | |
| | | // build request parameters from single message id (maybe with mailbox name) |
| | | this.params_from_uid = function(uid, params) |
| | | { |
| | | if (!params) |
| | | params = {}; |
| | | |
| | | params._uid = String(uid).split('-')[0]; |
| | | params._mbox = this.get_message_mailbox(uid); |
| | | |
| | | return params; |
| | | }; |
| | | |
| | | // gets cursor position |
| | | this.get_caret_pos = function(obj) |
| | | { |