| | |
| | | this.onloads = []; |
| | | this.messages = {}; |
| | | this.group2expand = {}; |
| | | this.http_request_jobs = {}; |
| | | |
| | | // webmail client settings |
| | | this.dblclick_time = 500; |
| | |
| | | comm_path: './', |
| | | blankpage: 'program/resources/blank.gif', |
| | | recipients_separator: ',', |
| | | recipients_delimiter: ', ' |
| | | recipients_delimiter: ', ', |
| | | popup_width: 1150, |
| | | popup_width_small: 900 |
| | | }; |
| | | |
| | | // create protected reference to myself |
| | |
| | | |
| | | case 'mail': |
| | | // enable mail commands |
| | | this.enable_command('list', 'checkmail', 'add-contact', 'search', 'reset-search', 'collapse-folder', true); |
| | | this.enable_command('list', 'checkmail', 'add-contact', 'search', 'reset-search', 'collapse-folder', 'import-messages', true); |
| | | |
| | | if (this.gui_objects.messagelist) { |
| | | this.message_list = new rcube_list_widget(this.gui_objects.messagelist, { |
| | |
| | | this.set_button_titles(); |
| | | |
| | | this.env.message_commands = ['show', 'reply', 'reply-all', 'reply-list', |
| | | 'moveto', 'copy', 'delete', 'open', 'mark', 'edit', 'viewsource', |
| | | 'move', 'copy', 'delete', 'open', 'mark', 'edit', 'viewsource', |
| | | 'print', 'load-attachment', 'download-attachment', 'show-headers', 'hide-headers', 'download', |
| | | 'forward', 'forward-inline', 'forward-attachment', 'change-format']; |
| | | |
| | |
| | | } |
| | | } |
| | | else if (this.env.action == 'compose') { |
| | | this.env.compose_commands = ['send-attachment', 'remove-attachment', 'send', 'cancel', 'toggle-editor', 'list-adresses', 'search', 'reset-search', 'extwin']; |
| | | this.env.address_group_stack = []; |
| | | this.env.compose_commands = ['send-attachment', 'remove-attachment', 'send', 'cancel', 'toggle-editor', 'list-adresses', 'pushgroup', 'search', 'reset-search', 'extwin']; |
| | | |
| | | if (this.env.drafts_mailbox) |
| | | this.env.compose_commands.push('savedraft') |
| | |
| | | // init message compose form |
| | | this.init_messageform(); |
| | | } |
| | | 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) { |
| | | if (bw.safari) |
| | | setTimeout('window.print()', 10); |
| | | else |
| | | window.print(); |
| | | } |
| | | |
| | | // get unread count for each mailbox |
| | | if (this.gui_objects.mailboxlist) { |
| | |
| | | break; |
| | | |
| | | case 'addressbook': |
| | | this.env.address_group_stack = []; |
| | | |
| | | if (this.gui_objects.folderlist) |
| | | this.env.contactfolders = $.extend($.extend({}, this.env.address_sources), this.env.contactgroups); |
| | | |
| | | this.enable_command('add', 'import', this.env.writable_source); |
| | | this.enable_command('list', 'listgroup', 'listsearch', 'advanced-search', true); |
| | | this.enable_command('list', 'listgroup', 'pushgroup', 'popgroup', 'listsearch', 'advanced-search', true); |
| | | |
| | | if (this.gui_objects.contactslist) { |
| | | this.contact_list = new rcube_list_widget(this.gui_objects.contactslist, |
| | |
| | | } |
| | | |
| | | if (this.gui_objects.qsearchbox) |
| | | this.enable_command('search', 'reset-search', 'moveto', true); |
| | | this.enable_command('search', 'reset-search', true); |
| | | |
| | | break; |
| | | |
| | |
| | | } |
| | | else if (this.env.action == 'edit-folder' && this.gui_objects.editform) { |
| | | this.enable_command('save', 'folder-size', true); |
| | | parent.rcmail.env.messagecount = this.env.messagecount; |
| | | parent.rcmail.env.exists = this.env.messagecount; |
| | | parent.rcmail.enable_command('purge', this.env.messagecount); |
| | | $("input[type='text']").first().select(); |
| | | } |
| | |
| | | |
| | | case 'extwin': |
| | | if (this.env.action == 'compose') { |
| | | var form = this.gui_objects.messageform; |
| | | var form = this.gui_objects.messageform, |
| | | win = this.open_window(''); |
| | | |
| | | $("input[name='_action']", form).val('compose'); |
| | | form.action = this.url('mail/compose', { _id: this.env.compose_id, _extwin: 1 }); |
| | | form.target = this.open_window('', 1100, 900); |
| | | form.target = win.name; |
| | | form.submit(); |
| | | } |
| | | else { |
| | | this.open_window(this.env.permaurl, 900, 900); |
| | | this.open_window(this.env.permaurl, true); |
| | | } |
| | | break; |
| | | |
| | |
| | | |
| | | // mail task commands |
| | | case 'move': |
| | | case 'moveto': |
| | | case 'moveto': // deprecated |
| | | if (this.task == 'mail') |
| | | this.move_messages(props); |
| | | else if (this.task == 'addressbook') |
| | | this.copy_contact(null, props); |
| | | this.move_contacts(props); |
| | | break; |
| | | |
| | | case 'copy': |
| | | if (this.task == 'mail') |
| | | this.copy_messages(props); |
| | | else if (this.task == 'addressbook') |
| | | this.copy_contacts(props); |
| | | break; |
| | | |
| | | case 'mark': |
| | |
| | | |
| | | // open attachment in frame if it's of a supported mimetype |
| | | if (command != 'download-attachment' && mimetype && this.env.mimetypes && $.inArray(mimetype, this.env.mimetypes) >= 0) { |
| | | var attachment_win = window.open(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1', this.html_identifier('rcubemailattachment'+this.env.uid+props)); |
| | | if (attachment_win) { |
| | | setTimeout(function(){ attachment_win.focus(); }, 10); |
| | | if (this.open_window(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1')) |
| | | break; |
| | | } |
| | | } |
| | | |
| | | this.goto_url('get', qstring+'&_download=1', false); |
| | |
| | | // Reset the auto-save timer |
| | | clearTimeout(this.save_timer); |
| | | |
| | | this.upload_file(props || this.gui_objects.uploadform); |
| | | this.upload_file(props || this.gui_objects.uploadform, 'upload'); |
| | | break; |
| | | |
| | | case 'insert-sig': |
| | |
| | | break; |
| | | |
| | | case 'print': |
| | | if (uid = this.get_single_uid()) { |
| | | ref.printwin = window.open(this.env.comm_path+'&_action=print&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(this.env.safemode ? '&_safe=1' : '')); |
| | | if (this.env.action == 'get') { |
| | | this.gui_objects.messagepartframe.contentWindow.print(); |
| | | } |
| | | else if (uid = this.get_single_uid()) { |
| | | ref.printwin = this.open_window(this.env.comm_path+'&_action=print&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(this.env.safemode ? '&_safe=1' : ''), true, true); |
| | | if (this.printwin) { |
| | | setTimeout(function(){ ref.printwin.focus(); }, 20); |
| | | if (this.env.action != 'show') |
| | | this.mark_message('read', uid); |
| | | } |
| | |
| | | break; |
| | | |
| | | case 'viewsource': |
| | | if (uid = this.get_single_uid()) { |
| | | ref.sourcewin = window.open(this.env.comm_path+'&_action=viewsource&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)); |
| | | if (this.sourcewin) |
| | | setTimeout(function(){ ref.sourcewin.focus(); }, 20); |
| | | } |
| | | if (uid = this.get_single_uid()) |
| | | this.open_window(this.env.comm_path+'&_action=viewsource&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true, true); |
| | | break; |
| | | |
| | | case 'download': |
| | | if (uid = this.get_single_uid()) |
| | | if (this.env.action == 'get') { |
| | | location.href = location.href.replace(/_frame=/, '_download='); |
| | | } |
| | | else if (uid = this.get_single_uid()) |
| | | this.goto_url('viewsource', { _uid: uid, _mbox: this.env.mailbox, _save: 1 }); |
| | | break; |
| | | |
| | |
| | | } |
| | | break; |
| | | |
| | | case 'pushgroup': |
| | | // add group ID to stack |
| | | this.env.address_group_stack.push(props.id); |
| | | if (obj && event) |
| | | rcube_event.cancel(event); |
| | | |
| | | case 'listgroup': |
| | | this.reset_qsearch(); |
| | | this.list_contacts(props.source, props.id); |
| | | break; |
| | | |
| | | case 'popgroup': |
| | | if (this.env.address_group_stack.length > 1) { |
| | | this.env.address_group_stack.pop(); |
| | | this.reset_qsearch(); |
| | | this.list_contacts(props.source, this.env.address_group_stack[this.env.address_group_stack.length-1]); |
| | | } |
| | | break; |
| | | |
| | | case 'import-messages': |
| | | var form = props || this.gui_objects.importform; |
| | | $('input[name="_unlock"]', form).val(this.set_busy(true, 'importwait')); |
| | | this.upload_file(form, 'import'); |
| | | break; |
| | | |
| | | case 'import': |
| | |
| | | if (typeof cmd === 'string') { |
| | | this.commands[cmd] = enable; |
| | | this.set_button(cmd, (enable ? 'act' : 'pas')); |
| | | this.triggerEvent('enable-command', {command: cmd, status: enable}); |
| | | } |
| | | // push array elements into commands array |
| | | else { |
| | |
| | | this.drag_menu = function(e, target) |
| | | { |
| | | var modkey = rcube_event.get_modifier(e), |
| | | menu = this.gui_objects.message_dragmenu; |
| | | menu = this.gui_objects.dragmenu; |
| | | |
| | | if (menu && modkey == SHIFT_KEY && this.commands['copy']) { |
| | | var pos = rcube_event.get_mouse_pos(e); |
| | |
| | | |
| | | this.drag_menu_action = function(action) |
| | | { |
| | | var menu = this.gui_objects.message_dragmenu; |
| | | var menu = this.gui_objects.dragmenu; |
| | | if (menu) { |
| | | $(menu).hide(); |
| | | } |
| | |
| | | list.draglayer.hide(); |
| | | this.drag_end(e); |
| | | |
| | | if (!this.drag_menu(e, target)) |
| | | this.command('moveto', target); |
| | | if (this.contact_list) { |
| | | if (!this.contacts_drag_menu(e, target)) |
| | | this.command('move', target); |
| | | } |
| | | else if (!this.drag_menu(e, target)) |
| | | this.command('move', target); |
| | | } |
| | | |
| | | // reset 'pressed' buttons |
| | |
| | | } |
| | | } |
| | | // Multi-message commands |
| | | this.enable_command('delete', 'moveto', 'copy', 'mark', 'forward', 'forward-attachment', list.selection.length > 0); |
| | | this.enable_command('delete', 'move', 'copy', 'mark', 'forward', 'forward-attachment', list.selection.length > 0); |
| | | |
| | | // reset all-pages-selection |
| | | if (selected || (list.selection.length && list.selection.length != list.rowcount)) |
| | |
| | | |
| | | // start timer for message preview (wait for double click) |
| | | if (selected && this.env.contentframe && !list.multi_selecting && !this.dummy_select) |
| | | this.preview_timer = setTimeout(function(){ ref.msglist_get_preview(); }, 200); |
| | | this.preview_timer = setTimeout(function() { ref.msglist_get_preview(); }, this.dblclick_time); |
| | | else if (this.env.contentframe) |
| | | this.show_contentframe(false); |
| | | }; |
| | |
| | | |
| | | var win = this.get_frame_window(this.env.contentframe); |
| | | |
| | | if (win && win.location.href.indexOf(this.env.blankpage)>=0) { |
| | | if (win && win.location.href.indexOf(this.env.blankpage) >= 0) { |
| | | if (this.preview_timer) |
| | | clearTimeout(this.preview_timer); |
| | | if (this.preview_read_timer) |
| | | clearTimeout(this.preview_read_timer); |
| | | this.preview_timer = setTimeout(function(){ ref.msglist_get_preview(); }, 200); |
| | | |
| | | this.preview_timer = setTimeout(function() { ref.msglist_get_preview(); }, this.dblclick_time); |
| | | } |
| | | }; |
| | | |
| | |
| | | { |
| | | if (this.preview_timer) |
| | | clearTimeout(this.preview_timer); |
| | | |
| | | if (this.preview_read_timer) |
| | | clearTimeout(this.preview_read_timer); |
| | | |
| | | var uid = list.get_single_selection(); |
| | | |
| | | if (uid && this.env.mailbox == this.env.drafts_mailbox) |
| | | this.open_compose_step({ _draft_uid: uid, _mbox: this.env.mailbox }); |
| | | else if (uid) |
| | |
| | | |
| | | this.check_droptarget = function(id) |
| | | { |
| | | if (this.task == 'mail') |
| | | return (this.env.mailboxes[id] && this.env.mailboxes[id].id != this.env.mailbox && !this.env.mailboxes[id].virtual) ? 1 : 0; |
| | | switch (this.task) { |
| | | case 'mail': |
| | | return (this.env.mailboxes[id] && this.env.mailboxes[id].id != this.env.mailbox && !this.env.mailboxes[id].virtual) ? 1 : 0; |
| | | |
| | | if (this.task == 'settings') |
| | | return id != this.env.mailbox ? 1 : 0; |
| | | case 'settings': |
| | | return id != this.env.mailbox ? 1 : 0; |
| | | |
| | | if (this.task == 'addressbook') { |
| | | if (id != this.env.source && this.env.contactfolders[id]) { |
| | | // droptarget is a group - contact add to group action |
| | | if (this.env.contactfolders[id].type == 'group') { |
| | | var target_abook = this.env.contactfolders[id].source; |
| | | if (this.env.contactfolders[id].id != this.env.group && !this.env.contactfolders[target_abook].readonly) { |
| | | // search result may contain contacts from many sources |
| | | return (this.env.selection_sources.length > 1 || $.inArray(target_abook, this.env.selection_sources) == -1) ? 2 : 1; |
| | | case 'addressbook': |
| | | var target; |
| | | if (id != this.env.source && (target = this.env.contactfolders[id])) { |
| | | // droptarget is a group |
| | | if (target.type == 'group') { |
| | | if (target.id != this.env.group && !this.env.contactfolders[target.source].readonly) { |
| | | var is_other = this.env.selection_sources.length > 1 || $.inArray(target.source, this.env.selection_sources) == -1; |
| | | return !is_other || this.commands.move ? 1 : 2; |
| | | } |
| | | } |
| | | // droptarget is a (writable) addressbook and it's not the source |
| | | else if (!target.readonly && (this.env.selection_sources.length > 1 || $.inArray(id, this.env.selection_sources) == -1)) { |
| | | return this.commands.move ? 1 : 2; |
| | | } |
| | | } |
| | | // droptarget is a (writable) addressbook - contact copy action |
| | | else if (!this.env.contactfolders[id].readonly) { |
| | | // search result may contain contacts from many sources |
| | | return (this.env.selection_sources.length > 1 || $.inArray(id, this.env.selection_sources) == -1) ? 2 : 0; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return 0; |
| | | }; |
| | | |
| | | this.open_window = function(url, width, height) |
| | | // open popup window |
| | | this.open_window = function(url, small, toolbar) |
| | | { |
| | | var dh = (window.outerHeight || 0) - (window.innerHeight || 0), |
| | | dw = (window.outerWidth || 0) - (window.innerWidth || 0), |
| | | sh = screen.availHeight || screen.height, |
| | | sw = screen.availWidth || screen.width, |
| | | w = Math.min(width, sw), |
| | | h = Math.min(height, sh), |
| | | l = Math.max(0, (sw - w) / 2 + (screen.left || 0)), |
| | | t = Math.max(0, (sh - h) / 2 + (screen.top || 0)), |
| | | wname = 'rcmextwin' + new Date().getTime(), |
| | | extwin = window.open(url + (url.match(/\?/) ? '&' : '?') + '_extwin=1', wname, |
| | | 'width='+(w-dw)+',height='+(h-dh)+',top='+t+',left='+l+',resizable=yes,toolbar=no,status=no,location=no'); |
| | | var wname = 'rcmextwin' + new Date().getTime(); |
| | | |
| | | url += (url.match(/\?/) ? '&' : '?') + '_extwin=1'; |
| | | |
| | | if (this.env.standard_windows) |
| | | extwin = window.open(url, wname); |
| | | else { |
| | | var win = this.is_framed() ? parent.window : window, |
| | | page = $(win), |
| | | page_width = page.width(), |
| | | page_height = bw.mz ? $('body', win).height() : page.height(), |
| | | w = Math.min(small ? this.env.popup_width_small : this.env.popup_width, page_width), |
| | | h = page_height, // always use same height |
| | | l = (win.screenLeft || win.screenX) + 20, |
| | | t = (win.screenTop || win.screenY) + 20, |
| | | extwin = window.open(url, wname, |
| | | 'width='+w+',height='+h+',top='+t+',left='+l+',resizable=yes,location=no,scrollbars=yes' |
| | | +(toolbar ? ',toolbar=yes,menubar=yes,status=yes' : ',toolbar=no,menubar=no,status=no')); |
| | | } |
| | | |
| | | // write loading... message to empty windows |
| | | if (!url && extwin.document) { |
| | |
| | | // focus window, delayed to bring to front |
| | | window.setTimeout(function() { extwin.focus(); }, 10); |
| | | |
| | | return wname; |
| | | return extwin; |
| | | }; |
| | | |
| | | |
| | |
| | | if (!row.depth && row.has_children && (expando = document.getElementById('rcmexpando'+row.uid))) { |
| | | row.expando = expando; |
| | | expando.onmousedown = function(e) { return self.expand_message_row(e, uid); }; |
| | | if (bw.touch) { |
| | | expando.addEventListener('touchend', function(e) { |
| | | if (e.changedTouches.length == 1) { |
| | | self.expand_message_row(e, uid); |
| | | return rcube_event.cancel(e); |
| | | } |
| | | }, false); |
| | | } |
| | | } |
| | | |
| | | this.triggerEvent('insertrow', { uid:uid, row:row }); |
| | |
| | | + (!flags.seen ? ' unread' : '') |
| | | + (flags.deleted ? ' deleted' : '') |
| | | + (flags.flagged ? ' flagged' : '') |
| | | + (flags.unread_children && flags.seen && !this.env.autoexpand_threads ? ' unroot' : '') |
| | | + (message.selected ? ' selected' : ''), |
| | | row = { cols:[], style:{}, id:'rcmrow'+uid }; |
| | | |
| | |
| | | expando = '<div id="rcmexpando' + uid + '" class="' + (message.expanded ? 'expanded' : 'collapsed') + '"> </div>'; |
| | | row_class += ' thread' + (message.expanded? ' expanded' : ''); |
| | | } |
| | | |
| | | if (flags.unread_children && flags.seen && !message.expanded) |
| | | row_class += ' unroot'; |
| | | } |
| | | |
| | | tree += '<span id="msgicn'+uid+'" class="'+css_class+'"> </span>'; |
| | |
| | | html = expando; |
| | | else if (c == 'subject') { |
| | | if (bw.ie) { |
| | | col.onmouseover = function() { rcube_webmail.long_subject_title_ie(this, message.depth+1); }; |
| | | col.onmouseover = function() { rcube_webmail.long_subject_title_ex(this, message.depth+1); }; |
| | | if (bw.ie8) |
| | | tree = '<span></span>' + tree; // #1487821 |
| | | } |
| | |
| | | } |
| | | else { |
| | | if (!preview && this.env.message_extwin && !this.env.extwin) |
| | | this.open_window(this.env.comm_path+url, 1000, 1200); |
| | | this.open_window(this.env.comm_path+url, true); |
| | | else |
| | | this.location_href(this.env.comm_path+url, target, true); |
| | | |
| | |
| | | |
| | | if (name && (frame = this.get_frame_element(name))) { |
| | | if (!show && (win = this.get_frame_window(name))) { |
| | | if (win.location && win.location.href.indexOf(this.env.blankpage)<0) |
| | | win.location.href = this.env.blankpage; |
| | | if (win.stop) |
| | | win.stop(); |
| | | else // IE |
| | | win.document.execCommand('Stop'); |
| | | |
| | | win.location.href = this.env.blankpage; |
| | | } |
| | | else if (!bw.safari && !bw.konq) |
| | | $(frame)[show ? 'show' : 'hide'](); |
| | | } |
| | | |
| | | if (!show && this.busy) |
| | | if (!show && this.env.frame_lock) |
| | | this.set_busy(false, null, this.env.frame_lock); |
| | | }; |
| | | |
| | |
| | | |
| | | this.clear_message_list = function() |
| | | { |
| | | this.env.messages = {}; |
| | | this.last_selected = 0; |
| | | this.env.messages = {}; |
| | | this.last_selected = 0; |
| | | |
| | | this.show_contentframe(false); |
| | | if (this.message_list) |
| | | this.message_list.clear(true); |
| | | this.show_contentframe(false); |
| | | if (this.message_list) |
| | | this.message_list.clear(true); |
| | | }; |
| | | |
| | | // send remote request to load message list |
| | |
| | | // Hide message command buttons until a message is selected |
| | | this.enable_command(this.env.message_commands, false); |
| | | |
| | | this._with_selected_messages('moveto', post_data, lock); |
| | | this._with_selected_messages('move', post_data, lock); |
| | | }; |
| | | |
| | | // delete selected messages from the current mailbox |
| | |
| | | this._with_selected_messages('delete', post_data); |
| | | }; |
| | | |
| | | // Send a specifc moveto/delete request with UIDs of all selected messages |
| | | // Send a specifc move/delete request with UIDs of all selected messages |
| | | // @private |
| | | this._with_selected_messages = function(action, post_data, lock) |
| | | { |
| | |
| | | this.delete_excessive_thread_rows(); |
| | | |
| | | if (!lock) { |
| | | msg = action == 'moveto' ? 'movingmessage' : 'deletingmessage'; |
| | | msg = action == 'move' ? 'movingmessage' : 'deletingmessage'; |
| | | lock = this.display_message(this.get_label(msg), 'loading'); |
| | | } |
| | | |
| | |
| | | { |
| | | var len = a_uids.length, |
| | | i, uid, all_deleted = true, |
| | | rows = this.message_list ? this.message_list.rows : []; |
| | | rows = this.message_list ? this.message_list.rows : {}; |
| | | |
| | | if (len == 1) { |
| | | if (!rows.length || (rows[a_uids[0]] && !rows[a_uids[0]].deleted)) |
| | | if (!this.message_list || (rows[a_uids[0]] && !rows[a_uids[0]].deleted)) |
| | | this.flag_as_deleted(a_uids); |
| | | else |
| | | this.flag_as_undeleted(a_uids); |
| | |
| | | var r_uids = [], |
| | | post_data = this.selection_post_data({_uid: this.uids_to_list(a_uids), _flag: 'delete'}), |
| | | lock = this.display_message(this.get_label('markingmessage'), 'loading'), |
| | | rows = this.message_list ? this.message_list.rows : [], |
| | | rows = this.message_list ? this.message_list.rows : {}, |
| | | count = 0; |
| | | |
| | | for (var i=0, len=a_uids.length; i<len; i++) { |
| | |
| | | |
| | | // make sure there are no selected rows |
| | | if (this.env.skip_deleted && this.message_list) { |
| | | if(!this.env.display_next) |
| | | if (!this.env.display_next) |
| | | this.message_list.clear_selection(); |
| | | if (count < 0) |
| | | post_data._count = (count*-1); |
| | |
| | | this.flag_deleted_as_read = function(uids) |
| | | { |
| | | var icn_src, uid, i, len, |
| | | rows = this.message_list ? this.message_list.rows : []; |
| | | rows = this.message_list ? this.message_list.rows : {}; |
| | | |
| | | uids = String(uids).split(','); |
| | | |
| | |
| | | |
| | | // open new compose window |
| | | if (this.env.compose_extwin && !this.env.extwin) { |
| | | this.open_window(url, 1150, 900); |
| | | this.open_window(url); |
| | | } |
| | | else { |
| | | this.redirect(url); |
| | | window.resizeTo(Math.max(1150, $(window).width()), Math.max(900, $(window).height())); |
| | | if (this.env.extwin) |
| | | window.resizeTo(Math.max(this.env.popup_width, $(window).width()), $(window).height() + 24); |
| | | } |
| | | }; |
| | | |
| | |
| | | this.set_caret_pos(input_message, this.env.top_posting ? 0 : $(input_message).val().length); |
| | | // add signature according to selected identity |
| | | // if we have HTML editor, signature is added in callback |
| | | if (input_from.prop('type') == 'select-one' && !this.env.opened_extwin) { |
| | | if (input_from.prop('type') == 'select-one') { |
| | | this.change_identity(input_from[0]); |
| | | } |
| | | } |
| | |
| | | |
| | | this.compose_recipient_select = function(list) |
| | | { |
| | | this.enable_command('add-recipient', list.selection.length > 0); |
| | | var id, n, recipients = 0; |
| | | for (n=0; n < list.selection.length; n++) { |
| | | id = list.selection[n]; |
| | | if (this.env.contactdata[id]) |
| | | recipients++; |
| | | } |
| | | this.enable_command('add-recipient', recipients); |
| | | }; |
| | | |
| | | this.compose_add_recipient = function(field) |
| | | { |
| | | var recipients = [], input = $('#_'+field); |
| | | var recipients = [], input = $('#_'+field), delim = this.env.recipients_delimiter; |
| | | |
| | | if (this.contact_list && this.contact_list.selection.length) { |
| | | for (var id, n=0; n < this.contact_list.selection.length; n++) { |
| | |
| | | } |
| | | |
| | | if (recipients.length && input.length) { |
| | | var oldval = input.val(); |
| | | input.val((oldval ? oldval + this.env.recipients_delimiter : '') + recipients.join(this.env.recipients_delimiter)); |
| | | 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 + ' '); |
| | | this.triggerEvent('add-recipient', { field:field, recipients:recipients }); |
| | | } |
| | | }; |
| | |
| | | if (!show_sig) |
| | | show_sig = this.env.show_sig; |
| | | |
| | | var cursor_pos, p = -1, |
| | | // first function execution |
| | | if (!this.env.identities_initialized) { |
| | | this.env.identities_initialized = true; |
| | | if (this.env.show_sig_later) |
| | | this.env.show_sig = true; |
| | | if (this.env.opened_extwin) |
| | | return; |
| | | } |
| | | |
| | | var i, rx, cursor_pos, p = -1, |
| | | id = obj.options[obj.selectedIndex].value, |
| | | input_message = $("[name='_message']"), |
| | | message = input_message.val(), |
| | | is_html = ($("input[name='_is_html']").val() == '1'), |
| | | sig = this.env.identity; |
| | | sig = this.env.identity, |
| | | delim = this.env.recipients_separator, |
| | | rx_delim = RegExp.escape(delim), |
| | | headers = ['replyto', 'bcc']; |
| | | |
| | | // update reply-to/bcc fields with addresses defined in identities |
| | | for (i in headers) { |
| | | var key = headers[i], |
| | | old_val = sig && this.env.identities[sig] ? this.env.identities[sig][key] : '', |
| | | new_val = id && this.env.identities[id] ? this.env.identities[id][key] : '', |
| | | input = $('[name="_'+key+'"]'), input_val = input.val(); |
| | | |
| | | // remove old address(es) |
| | | if (old_val && input_val) { |
| | | rx = new RegExp('\\s*' + RegExp.escape(old_val) + '\\s*'); |
| | | input_val = input_val.replace(rx, ''); |
| | | } |
| | | |
| | | // cleanup |
| | | rx = new RegExp(rx_delim + '\\s*' + rx_delim, 'g'); |
| | | input_val = input_val.replace(rx, delim); |
| | | rx = new RegExp('^[\\s' + rx_delim + ']+'); |
| | | input_val = input_val.replace(rx, ''); |
| | | |
| | | // add new address(es) |
| | | if (new_val && input_val.indexOf(new_val) == -1 && input_val.indexOf(new_val.replace(/"/g, '')) == -1) { |
| | | if (input_val) { |
| | | rx = new RegExp('[' + rx_delim + '\\s]+$') |
| | | input_val = input_val.replace(rx, '') + delim + ' '; |
| | | } |
| | | |
| | | input_val += new_val + delim + ' '; |
| | | } |
| | | |
| | | if (old_val || new_val) |
| | | input.val(input_val).change(); |
| | | } |
| | | |
| | | // enable manual signature insert |
| | | if (this.env.signatures && this.env.signatures[id]) { |
| | |
| | | return true; |
| | | }; |
| | | |
| | | // upload attachment file |
| | | this.upload_file = function(form) |
| | | // upload (attachment) file |
| | | this.upload_file = function(form, action) |
| | | { |
| | | if (!form) |
| | | return false; |
| | |
| | | return; |
| | | } |
| | | |
| | | var frame_name = this.async_upload_form(form, 'upload', function(e) { |
| | | var frame_name = this.async_upload_form(form, action || 'upload', function(e) { |
| | | var d, content = ''; |
| | | try { |
| | | if (this.contentDocument) { |
| | |
| | | att.html = '<a title="'+this.get_label('cancel')+'" onclick="return rcmail.cancel_attachment_upload(\''+name+'\', \''+att.frame+'\');" href="#cancelupload" class="cancelupload">' |
| | | + (this.env.cancelicon ? '<img src="'+this.env.cancelicon+'" alt="" />' : this.get_label('cancel')) + '</a>' + att.html; |
| | | |
| | | var indicator, li = $('<li>').attr('id', name).addClass(att.classname).html(att.html); |
| | | var indicator, li = $('<li>'); |
| | | |
| | | li.attr('id', name) |
| | | .addClass(att.classname) |
| | | .html(att.html) |
| | | .on('mouseover', function() { rcube_webmail.long_subject_title_ex(this, 0); }); |
| | | |
| | | // replace indicator's li |
| | | if (upload_id && (indicator = document.getElementById(upload_id))) { |
| | |
| | | this.env.search_id = null; |
| | | }; |
| | | |
| | | this.sent_successfully = function(type, msg, target) |
| | | this.sent_successfully = function(type, msg, folders) |
| | | { |
| | | this.display_message(msg, type); |
| | | |
| | |
| | | this.lock_form(this.gui_objects.messageform); |
| | | if (rc) { |
| | | rc.display_message(msg, type); |
| | | // refresh the folder where sent message was saved |
| | | if (target && rc.env.task == 'mail' && rc.env.action == '' && rc.env.mailbox == target) |
| | | rc.command('checkmail'); |
| | | // refresh the folder where sent message was saved or replied message comes from |
| | | if (folders && rc.env.task == 'mail' && rc.env.action == '' && $.inArray(rc.env.mailbox, folders) >= 0) { |
| | | // @TODO: try with 'checkmail' here when #1485186 is fixed. See also #1489249. |
| | | rc.command('list'); |
| | | } |
| | | } |
| | | setTimeout(function(){ window.close() }, 1000); |
| | | } |
| | |
| | | p = inp_value.lastIndexOf(this.env.recipients_separator, cpos-1), |
| | | q = inp_value.substring(p+1, cpos), |
| | | min = this.env.autocomplete_min_length, |
| | | ac = this.ksearch_data; |
| | | data = this.ksearch_data; |
| | | |
| | | // trim query string |
| | | q = $.trim(q); |
| | |
| | | return; |
| | | |
| | | // ...new search value contains old one and previous search was not finished or its result was empty |
| | | if (old_value && old_value.length && q.indexOf(old_value) == 0 && (!ac || ac.num <= 0) && this.env.contacts && !this.env.contacts.length) |
| | | if (old_value && old_value.length && q.indexOf(old_value) == 0 && (!data || data.num <= 0) && this.env.contacts && !this.env.contacts.length) |
| | | return; |
| | | |
| | | var i, lock, source, xhr, reqid = new Date().getTime(), |
| | | post_data = {_search: q, _id: reqid}, |
| | | threads = props && props.threads ? props.threads : 1, |
| | | sources = props && props.sources ? props.sources : [], |
| | | action = props && props.action ? props.action : 'mail/autocomplete'; |
| | | var sources = props && props.sources ? props.sources : ['']; |
| | | var reqid = this.multi_thread_http_request({ |
| | | items: sources, |
| | | threads: props && props.threads ? props.threads : 1, |
| | | action: props && props.action ? props.action : 'mail/autocomplete', |
| | | postdata: { _search:q, _source:'%s' }, |
| | | lock: this.display_message(this.get_label('searching'), 'loading') |
| | | }); |
| | | |
| | | this.ksearch_data = {id: reqid, sources: sources.slice(), action: action, |
| | | locks: [], requests: [], num: sources.length}; |
| | | |
| | | for (i=0; i<threads; i++) { |
| | | source = this.ksearch_data.sources.shift(); |
| | | if (threads > 1 && source === undefined) |
| | | break; |
| | | |
| | | post_data._source = source ? source : ''; |
| | | lock = this.display_message(this.get_label('searching'), 'loading'); |
| | | xhr = this.http_post(action, post_data, lock); |
| | | |
| | | this.ksearch_data.locks.push(lock); |
| | | this.ksearch_data.requests.push(xhr); |
| | | } |
| | | this.ksearch_data = { id:reqid, sources:sources.slice(), num:sources.length }; |
| | | }; |
| | | |
| | | this.ksearch_query_results = function(results, search, reqid) |
| | | { |
| | | // trigger multi-thread http response callback |
| | | this.multi_thread_http_response(results, reqid); |
| | | |
| | | // search stopped in meantime? |
| | | if (!this.ksearch_value) |
| | | return; |
| | |
| | | // display search results |
| | | var i, len, ul, li, text, init, |
| | | value = this.ksearch_value, |
| | | data = this.ksearch_data, |
| | | maxlen = this.env.autocomplete_max ? this.env.autocomplete_max : 15; |
| | | |
| | | // create results pane if not present |
| | |
| | | if (len) |
| | | this.env.contacts = this.env.contacts.concat(results); |
| | | |
| | | // run next parallel search |
| | | if (data.id == reqid) { |
| | | data.num--; |
| | | if (maxlen > 0 && data.sources.length) { |
| | | var lock, xhr, source = data.sources.shift(), post_data; |
| | | if (source) { |
| | | post_data = {_search: value, _id: reqid, _source: source}; |
| | | lock = this.display_message(this.get_label('searching'), 'loading'); |
| | | xhr = this.http_post(data.action, post_data, lock); |
| | | |
| | | this.ksearch_data.locks.push(lock); |
| | | this.ksearch_data.requests.push(xhr); |
| | | } |
| | | } |
| | | else if (!maxlen) { |
| | | if (!this.ksearch_msg) |
| | | this.ksearch_msg = this.display_message(this.get_label('autocompletemore')); |
| | | // abort pending searches |
| | | this.ksearch_abort(); |
| | | } |
| | | } |
| | | if (this.ksearch_data.id == reqid) |
| | | this.ksearch_data.num--; |
| | | }; |
| | | |
| | | this.ksearch_click = function(node) |
| | |
| | | // Clears autocomplete data/requests |
| | | this.ksearch_destroy = function() |
| | | { |
| | | this.ksearch_abort(); |
| | | if (this.ksearch_data) |
| | | this.multi_thread_request_abort(this.ksearch_data.id); |
| | | |
| | | if (this.ksearch_info) |
| | | this.hide_message(this.ksearch_info); |
| | |
| | | this.ksearch_data = null; |
| | | this.ksearch_info = null; |
| | | this.ksearch_msg = null; |
| | | } |
| | | |
| | | // Aborts pending autocomplete requests |
| | | this.ksearch_abort = function() |
| | | { |
| | | var i, len, ac = this.ksearch_data; |
| | | |
| | | if (!ac) |
| | | return; |
| | | |
| | | for (i=0, len=ac.locks.length; i<len; i++) |
| | | this.abort_request({request: ac.requests[i], lock: ac.locks[i]}); |
| | | }; |
| | | |
| | | |
| | |
| | | if (this.preview_timer) |
| | | clearTimeout(this.preview_timer); |
| | | |
| | | var n, id, sid, ref = this, writable = false, |
| | | var n, id, sid, contact, ref = this, writable = false, |
| | | source = this.env.source ? this.env.address_sources[this.env.source] : null; |
| | | |
| | | // we don't have dblclick handler here, so use 200 instead of this.dblclick_time |
| | | if (id = list.get_single_selection()) |
| | | this.preview_timer = setTimeout(function(){ ref.load_contact(id, 'show'); }, 200); |
| | | else if (this.env.contentframe) |
| | | this.show_contentframe(false); |
| | | |
| | | if (list.selection.length) { |
| | | list.draggable = false; |
| | | |
| | | // no source = search result, we'll need to detect if any of |
| | | // selected contacts are in writable addressbook to enable edit/delete |
| | | // we'll also need to know sources used in selection for copy |
| | | // and group-addmember operations (drag&drop) |
| | | this.env.selection_sources = []; |
| | | if (!source) { |
| | | for (n in list.selection) { |
| | | |
| | | if (source) { |
| | | this.env.selection_sources.push(this.env.source); |
| | | } |
| | | |
| | | for (n in list.selection) { |
| | | contact = list.data[list.selection[n]]; |
| | | if (!source) { |
| | | sid = String(list.selection[n]).replace(/^[^-]+-/, ''); |
| | | if (sid && this.env.address_sources[sid]) { |
| | | writable = writable || !this.env.address_sources[sid].readonly; |
| | | writable = writable || (!this.env.address_sources[sid].readonly && !contact.readonly); |
| | | this.env.selection_sources.push(sid); |
| | | } |
| | | } |
| | | this.env.selection_sources = $.unique(this.env.selection_sources); |
| | | else { |
| | | writable = writable || (!source.readonly && !contact.readonly); |
| | | } |
| | | |
| | | if (contact._type != 'group') |
| | | list.draggable = true; |
| | | } |
| | | else { |
| | | this.env.selection_sources.push(this.env.source); |
| | | writable = !source.readonly; |
| | | } |
| | | |
| | | this.env.selection_sources = $.unique(this.env.selection_sources); |
| | | } |
| | | |
| | | // if a group is currently selected, and there is at least one contact selected |
| | | // thend we can enable the group-remove-selected command |
| | | this.enable_command('group-remove-selected', this.env.group && list.selection.length > 0); |
| | | this.enable_command('group-remove-selected', this.env.group && list.selection.length > 0 && writable); |
| | | this.enable_command('compose', this.env.group || list.selection.length > 0); |
| | | this.enable_command('export-selected', list.selection.length > 0); |
| | | this.enable_command('export-selected', 'copy', list.selection.length > 0); |
| | | this.enable_command('edit', id && writable); |
| | | this.enable_command('delete', list.selection.length && writable); |
| | | this.enable_command('delete', 'move', list.selection.length > 0 && writable); |
| | | |
| | | return false; |
| | | }; |
| | |
| | | else if (!this.env.search_request) |
| | | folder = group ? 'G'+src+group : src; |
| | | |
| | | this.select_folder(folder, '', true); |
| | | |
| | | this.env.source = src; |
| | | this.env.group = group; |
| | | |
| | | // truncate groups listing stack |
| | | var index = $.inArray(this.env.group, this.env.address_group_stack); |
| | | if (index < 0) |
| | | this.env.address_group_stack = []; |
| | | else |
| | | this.env.address_group_stack = this.env.address_group_stack.slice(0,index); |
| | | |
| | | // make sure the current group is on top of the stack |
| | | if (this.env.group) { |
| | | this.env.address_group_stack.push(this.env.group); |
| | | |
| | | // mark the first group on the stack as selected in the directory list |
| | | folder = 'G'+src+this.env.address_group_stack[0]; |
| | | } |
| | | else if (this.gui_objects.addresslist_title) { |
| | | $(this.gui_objects.addresslist_title).html(this.get_label('contacts')); |
| | | } |
| | | |
| | | this.select_folder(folder, '', true); |
| | | |
| | | // load contacts remotely |
| | | if (this.gui_objects.contactslist) { |
| | |
| | | |
| | | this.list_contacts_clear = function() |
| | | { |
| | | this.contact_list.data = {}; |
| | | this.contact_list.clear(true); |
| | | this.show_contentframe(false); |
| | | this.enable_command('delete', false); |
| | | this.enable_command('delete', 'move', 'copy', false); |
| | | this.enable_command('compose', this.env.group ? true : false); |
| | | }; |
| | | |
| | | this.set_group_prop = function(prop) |
| | | { |
| | | if (this.gui_objects.addresslist_title) { |
| | | var boxtitle = $(this.gui_objects.addresslist_title).html(''); // clear contents |
| | | |
| | | // add link to pop back to parent group |
| | | if (this.env.address_group_stack.length > 1) { |
| | | $('<a href="#list">...</a>') |
| | | .addClass('poplink') |
| | | .appendTo(boxtitle) |
| | | .click(function(e){ return ref.command('popgroup','',this); }); |
| | | boxtitle.append(' » '); |
| | | } |
| | | |
| | | boxtitle.append($('<span>').text(prop.name)); |
| | | } |
| | | |
| | | this.triggerEvent('groupupdate', prop); |
| | | }; |
| | | |
| | | // load contact record |
| | | this.load_contact = function(cid, action, framed) |
| | | { |
| | | var win, url = {}, target = window; |
| | | var win, url = {}, target = window, |
| | | rec = this.contact_list ? this.contact_list.data[cid] : null; |
| | | |
| | | if (win = this.get_frame_window(this.env.contentframe)) { |
| | | url._framed = 1; |
| | |
| | | // load dummy content, unselect selected row(s) |
| | | if (!cid) |
| | | this.contact_list.clear_selection(); |
| | | this.enable_command('delete', 'compose', 'export-selected', cid); |
| | | |
| | | this.enable_command('compose', rec && rec.email); |
| | | this.enable_command('export-selected', rec && rec._type != 'group'); |
| | | } |
| | | else if (framed) |
| | | return false; |
| | |
| | | this.http_post('group-'+what+'members', post_data, lock); |
| | | }; |
| | | |
| | | // copy a contact to the specified target (group or directory) |
| | | this.copy_contact = function(cid, to) |
| | | this.contacts_drag_menu = function(e, to) |
| | | { |
| | | var dest = to.type == 'group' ? to.source : to.id, |
| | | source = this.env.source; |
| | | |
| | | if (!this.env.address_sources[dest] || this.env.address_sources[dest].readonly) |
| | | return true; |
| | | |
| | | // search result may contain contacts from many sources, but if there is only one... |
| | | if (source == '' && this.env.selection_sources.length == 1) |
| | | source = this.env.selection_sources[0]; |
| | | |
| | | if (to.type == 'group' && dest == source) { |
| | | var cid = this.contact_list.get_selection().join(','); |
| | | this.group_member_change('add', cid, dest, to.id); |
| | | return true; |
| | | } |
| | | // move action is not possible, "redirect" to copy if menu wasn't requested |
| | | else if (!this.commands.move && rcube_event.get_modifier(e) != SHIFT_KEY) { |
| | | this.copy_contacts(to); |
| | | return true; |
| | | } |
| | | |
| | | return this.drag_menu(e, to); |
| | | }; |
| | | |
| | | // copy contact(s) to the specified target (group or directory) |
| | | this.copy_contacts = function(to) |
| | | { |
| | | var n, dest = to.type == 'group' ? to.source : to.id, |
| | | source = this.env.source, |
| | | group = this.env.group ? this.env.group : ''; |
| | | |
| | | if (!cid) |
| | | group = this.env.group ? this.env.group : '', |
| | | cid = this.contact_list.get_selection().join(','); |
| | | |
| | | if (!cid || !this.env.address_sources[dest] || this.env.address_sources[dest].readonly) |
| | |
| | | // tagret is a group |
| | | if (to.type == 'group') { |
| | | if (dest == source) |
| | | this.group_member_change('add', cid, dest, to.id); |
| | | else { |
| | | var lock = this.display_message(this.get_label('copyingcontact'), 'loading'), |
| | | post_data = {_cid: cid, _source: this.env.source, _to: dest, _togid: to.id, _gid: group}; |
| | | return; |
| | | |
| | | this.http_post('copy', post_data, lock); |
| | | } |
| | | var lock = this.display_message(this.get_label('copyingcontact'), 'loading'), |
| | | post_data = {_cid: cid, _source: this.env.source, _to: dest, _togid: to.id, _gid: group}; |
| | | |
| | | this.http_post('copy', post_data, lock); |
| | | } |
| | | // target is an addressbook |
| | | else if (to.id != source) { |
| | |
| | | } |
| | | }; |
| | | |
| | | this.delete_contacts = function() |
| | | // move contact(s) to the specified target (group or directory) |
| | | this.move_contacts = function(to) |
| | | { |
| | | var selection = this.contact_list.get_selection(), |
| | | undelete = this.env.source && this.env.address_sources[this.env.source].undelete; |
| | | var dest = to.type == 'group' ? to.source : to.id, |
| | | source = this.env.source, |
| | | group = this.env.group ? this.env.group : ''; |
| | | |
| | | // exit if no mailbox specified or if selection is empty |
| | | if (!(selection.length || this.env.cid) || (!undelete && !confirm(this.get_label('deletecontactconfirm')))) |
| | | if (!this.env.address_sources[dest] || this.env.address_sources[dest].readonly) |
| | | return; |
| | | |
| | | var id, n, a_cids = [], |
| | | post_data = {_source: this.env.source, _from: (this.env.action ? this.env.action : '')}, |
| | | lock = this.display_message(this.get_label('contactdeleting'), 'loading'); |
| | | // search result may contain contacts from many sources, but if there is only one... |
| | | if (source == '' && this.env.selection_sources.length == 1) |
| | | source = this.env.selection_sources[0]; |
| | | |
| | | if (to.type == 'group') { |
| | | if (dest == source) |
| | | return; |
| | | |
| | | this._with_selected_contacts('move', {_to: dest, _togid: to.id}); |
| | | } |
| | | // target is an addressbook |
| | | else if (to.id != source) |
| | | this._with_selected_contacts('move', {_to: to.id}); |
| | | }; |
| | | |
| | | // delete contact(s) |
| | | this.delete_contacts = function() |
| | | { |
| | | var undelete = this.env.source && this.env.address_sources[this.env.source].undelete; |
| | | |
| | | if (!undelete && !confirm(this.get_label('deletecontactconfirm'))) |
| | | return; |
| | | |
| | | return this._with_selected_contacts('delete'); |
| | | }; |
| | | |
| | | this._with_selected_contacts = function(action, post_data) |
| | | { |
| | | var selection = this.contact_list ? this.contact_list.get_selection() : []; |
| | | |
| | | // exit if no mailbox specified or if selection is empty |
| | | if (!selection.length && !this.env.cid) |
| | | return; |
| | | |
| | | var n, a_cids = [], |
| | | label = action == 'delete' ? 'contactdeleting' : 'movingcontact', |
| | | lock = this.display_message(this.get_label(label), 'loading'); |
| | | if (this.env.cid) |
| | | a_cids.push(this.env.cid); |
| | | else { |
| | |
| | | this.show_contentframe(false); |
| | | } |
| | | |
| | | if (!post_data) |
| | | post_data = {}; |
| | | |
| | | post_data._source = this.env.source; |
| | | post_data._from = this.env.action; |
| | | post_data._cid = a_cids.join(','); |
| | | |
| | | if (this.env.group) |
| | |
| | | post_data._search = this.env.search_request; |
| | | |
| | | // send request to server |
| | | this.http_post('delete', post_data, lock) |
| | | this.http_post(action, post_data, lock) |
| | | |
| | | return true; |
| | | }; |
| | | |
| | | // update a contact record in the list |
| | | this.update_contact_row = function(cid, cols_arr, newcid, source) |
| | | this.update_contact_row = function(cid, cols_arr, newcid, source, data) |
| | | { |
| | | var c, row, list = this.contact_list; |
| | | |
| | |
| | | } |
| | | |
| | | list.update_row(cid, cols_arr, newcid, true); |
| | | list.data[cid] = data; |
| | | }; |
| | | |
| | | // add row to contacts list |
| | | this.add_contact_row = function(cid, cols, classes) |
| | | this.add_contact_row = function(cid, cols, classes, data) |
| | | { |
| | | if (!this.gui_objects.contactslist) |
| | | return false; |
| | |
| | | row.cols.push(col); |
| | | } |
| | | |
| | | // store data in list member |
| | | list.data[cid] = data; |
| | | list.insert_row(row); |
| | | |
| | | this.enable_command('export', list.rowcount > 0); |
| | |
| | | this.replace_contact_photo = function(id) |
| | | { |
| | | var img_src = id == '-del-' ? this.env.photo_placeholder : |
| | | this.env.comm_path + '&_action=photo&_source=' + this.env.source + '&_cid=' + this.env.cid + '&_photo=' + id; |
| | | this.env.comm_path + '&_action=photo&_source=' + this.env.source + '&_cid=' + (this.env.cid || 0) + '&_photo=' + id; |
| | | |
| | | this.set_photo_actions(id); |
| | | $(this.gui_objects.contactphoto).children('img').attr('src', img_src); |
| | |
| | | |
| | | for (c=0, len=repl.length; c < len; c++) { |
| | | cell = document.createElement('td'); |
| | | cell.innerHTML = repl[c].html; |
| | | cell.innerHTML = repl[c].html || ''; |
| | | if (repl[c].id) cell.id = repl[c].id; |
| | | if (repl[c].className) cell.className = repl[c].className; |
| | | tr.appendChild(cell); |
| | | } |
| | | th.appendChild(tr); |
| | | thead.parentNode.replaceChild(th, thead); |
| | | thead = th; |
| | | list.thead = thead = th; |
| | | } |
| | | |
| | | for (n=0, len=this.env.coltypes.length; n<len; n++) { |
| | |
| | | this.enable_command('export-selected', false); |
| | | } |
| | | |
| | | case 'moveto': |
| | | case 'move': |
| | | if (this.env.action == 'show') { |
| | | // re-enable commands on move/delete error |
| | | this.enable_command(this.env.message_commands, true); |
| | |
| | | |
| | | if ((response.action == 'list' || response.action == 'search') && this.message_list) { |
| | | this.msglist_select(this.message_list); |
| | | this.message_list.resize(); |
| | | this.triggerEvent('listupdate', { folder:this.env.mailbox, rowcount:this.message_list.rowcount }); |
| | | } |
| | | } |
| | |
| | | this.enable_command('search-create', this.env.source == ''); |
| | | this.enable_command('search-delete', this.env.search_id); |
| | | this.update_group_commands(); |
| | | this.contact_list.resize(); |
| | | this.triggerEvent('listupdate', { folder:this.env.source, rowcount:this.contact_list.rowcount }); |
| | | } |
| | | } |
| | |
| | | |
| | | if (this.submit_timer) |
| | | clearTimeout(this.submit_timer); |
| | | }; |
| | | |
| | | /** |
| | | Send multi-threaded parallel HTTP requests to the server for a list if items. |
| | | The string '%' in either a GET query or POST parameters will be replaced with the respective item value. |
| | | This is the argument object expected: { |
| | | items: ['foo','bar','gna'], // list of items to send requests for |
| | | action: 'task/some-action', // Roudncube action to call |
| | | query: { q:'%s' }, // GET query parameters |
| | | postdata: { source:'%s' }, // POST data (sends a POST request if present) |
| | | threads: 3, // max. number of concurrent requests |
| | | onresponse: function(data){ }, // Callback function called for every response received from server |
| | | whendone: function(alldata){ } // Callback function called when all requests have been sent |
| | | } |
| | | */ |
| | | this.multi_thread_http_request = function(prop) |
| | | { |
| | | var reqid = new Date().getTime(); |
| | | |
| | | prop.reqid = reqid; |
| | | prop.running = 0; |
| | | prop.requests = []; |
| | | prop.result = []; |
| | | prop._items = $.extend([], prop.items); // copy items |
| | | |
| | | if (!prop.lock) |
| | | prop.lock = this.display_message(this.get_label('loading'), 'loading'); |
| | | |
| | | // add the request arguments to the jobs pool |
| | | this.http_request_jobs[reqid] = prop; |
| | | |
| | | // start n threads |
| | | var item, threads = prop.threads || 1; |
| | | for (var i=0; i < threads; i++) { |
| | | item = prop._items.shift(); |
| | | if (item === undefined) |
| | | break; |
| | | |
| | | prop.running++; |
| | | prop.requests.push(this.multi_thread_send_request(prop, item)); |
| | | } |
| | | |
| | | return reqid; |
| | | }; |
| | | |
| | | // helper method to send an HTTP request with the given iterator value |
| | | this.multi_thread_send_request = function(prop, item) |
| | | { |
| | | var postdata, query; |
| | | |
| | | // replace %s in post data |
| | | if (prop.postdata) { |
| | | postdata = {}; |
| | | for (var k in prop.postdata) { |
| | | postdata[k] = String(prop.postdata[k]).replace('%s', item); |
| | | } |
| | | postdata._reqid = prop.reqid; |
| | | } |
| | | // replace %s in query |
| | | else if (typeof prop.query == 'string') { |
| | | query = prop.query.replace('%s', item); |
| | | query += '&_reqid=' + prop.reqid; |
| | | } |
| | | else if (typeof prop.query == 'object' && prop.query) { |
| | | query = {}; |
| | | for (var k in prop.query) { |
| | | query[k] = String(prop.query[k]).replace('%s', item); |
| | | } |
| | | query._reqid = prop.reqid; |
| | | } |
| | | |
| | | // send HTTP GET or POST request |
| | | return postdata ? this.http_post(prop.action, postdata) : this.http_request(prop.action, query); |
| | | }; |
| | | |
| | | // callback function for multi-threaded http responses |
| | | this.multi_thread_http_response = function(data, reqid) |
| | | { |
| | | var prop = this.http_request_jobs[reqid]; |
| | | if (!prop || prop.running <= 0 || prop.cancelled) |
| | | return; |
| | | |
| | | prop.running--; |
| | | |
| | | // trigger response callback |
| | | if (prop.onresponse && typeof prop.onresponse == 'function') { |
| | | prop.onresponse(data); |
| | | } |
| | | |
| | | prop.result = $.extend(prop.result, data); |
| | | |
| | | // send next request if prop.items is not yet empty |
| | | var item = prop._items.shift(); |
| | | if (item !== undefined) { |
| | | prop.running++; |
| | | prop.requests.push(this.multi_thread_send_request(prop, item)); |
| | | } |
| | | // trigger whendone callback and mark this request as done |
| | | else if (prop.running == 0) { |
| | | if (prop.whendone && typeof prop.whendone == 'function') { |
| | | prop.whendone(prop.result); |
| | | } |
| | | |
| | | this.set_busy(false, '', prop.lock); |
| | | |
| | | // remove from this.http_request_jobs pool |
| | | delete this.http_request_jobs[reqid]; |
| | | } |
| | | }; |
| | | |
| | | // abort a running multi-thread request with the given identifier |
| | | this.multi_thread_request_abort = function(reqid) |
| | | { |
| | | var prop = this.http_request_jobs[reqid]; |
| | | if (prop) { |
| | | for (var i=0; prop.running > 0 && i < prop.requests.length; i++) { |
| | | if (prop.requests[i].abort) |
| | | prop.requests[i].abort(); |
| | | } |
| | | |
| | | prop.running = 0; |
| | | prop.cancelled = true; |
| | | this.set_busy(false, '', prop.lock); |
| | | } |
| | | }; |
| | | |
| | | // post the given form to a hidden iframe |
| | |
| | | url: ref.url(ref.env.filedrop.action||'upload', { _id:ref.env.compose_id||ref.env.cid||'', _uploadid:ts, _remote:1 }), |
| | | contentType: formdata ? false : 'multipart/form-data; boundary=' + boundary, |
| | | processData: false, |
| | | timeout: 0, // disable default timeout set in ajaxSetup() |
| | | data: formdata || multipart, |
| | | headers: {'X-Roundcube-Request': ref.env.request_token}, |
| | | beforeSend: function(xhr, s) { if (!formdata && xhr.sendAsBinary) xhr.send = xhr.sendAsBinary; }, |
| | | xhr: function() { var xhr = jQuery.ajaxSettings.xhr(); if (!formdata && xhr.sendAsBinary) xhr.send = xhr.sendAsBinary; return xhr; }, |
| | | success: function(data){ ref.http_response(data); }, |
| | | error: function(o, status, err) { ref.http_error(o, status, err, null, 'attachment'); } |
| | | }); |
| | |
| | | multipart += '; filename="' + (f.name_bin || file.name) + '"' + crlf; |
| | | multipart += 'Content-Length: ' + file.size + crlf; |
| | | multipart += 'Content-Type: ' + file.type + crlf + crlf; |
| | | multipart += e.target.result + crlf; |
| | | multipart += reader.result + crlf; |
| | | multipart += dashdash + boundary + crlf; |
| | | |
| | | if (j == last) // we're done, submit the data |
| | |
| | | return 1; |
| | | } |
| | | |
| | | // this will detect any pdf plugin including PDF.js in Firefox |
| | | var obj = document.createElement('OBJECT'); |
| | | obj.onload = function() { rcmail.env.browser_capabilities.pdf = 1; }; |
| | | obj.onerror = function() { rcmail.env.browser_capabilities.pdf = 0; }; |
| | | obj.style.display = 'none'; |
| | | obj.type = 'application/pdf'; |
| | | obj.data = 'program/resources/blank.pdf'; |
| | | document.body.appendChild(obj); |
| | | |
| | | return 0; |
| | | }; |
| | | |
| | |
| | | if (!elem.title) { |
| | | var $elem = $(elem); |
| | | if ($elem.width() + indent * 15 > $elem.parent().width()) |
| | | elem.title = $elem.html(); |
| | | elem.title = $elem.text(); |
| | | } |
| | | }; |
| | | |
| | | rcube_webmail.long_subject_title_ie = function(elem, indent) |
| | | rcube_webmail.long_subject_title_ex = function(elem, indent) |
| | | { |
| | | if (!elem.title) { |
| | | var $elem = $(elem), |