| | |
| | | |
| | | function rcube_webmail() |
| | | { |
| | | this.env = { recipients_separator:',', recipients_delimiter:', ' }; |
| | | this.labels = {}; |
| | | this.buttons = {}; |
| | | this.buttons_sel = {}; |
| | |
| | | this.messages = {}; |
| | | this.group2expand = {}; |
| | | |
| | | // create protected reference to myself |
| | | this.ref = 'rcmail'; |
| | | var ref = this; |
| | | |
| | | // webmail client settings |
| | | this.dblclick_time = 500; |
| | | this.message_time = 4000; |
| | | |
| | | this.identifier_expr = new RegExp('[^0-9a-z\-_]', 'gi'); |
| | | |
| | | // default environment vars |
| | | this.env.keep_alive = 60; // seconds |
| | | this.env.request_timeout = 180; // seconds |
| | | this.env.draft_autosave = 0; // seconds |
| | | this.env.comm_path = './'; |
| | | this.env.blankpage = 'program/blank.gif'; |
| | | // environment defaults |
| | | this.env = { |
| | | request_timeout: 180, // seconds |
| | | draft_autosave: 0, // seconds |
| | | comm_path: './', |
| | | blankpage: 'program/resources/blank.gif', |
| | | recipients_separator: ',', |
| | | recipients_delimiter: ', ' |
| | | }; |
| | | |
| | | // create protected reference to myself |
| | | this.ref = 'rcmail'; |
| | | var ref = this; |
| | | |
| | | // set jQuery ajax options |
| | | $.ajaxSetup({ |
| | |
| | | error: function(request, status, err){ ref.http_error(request, status, err); }, |
| | | beforeSend: function(xmlhttp){ xmlhttp.setRequestHeader('X-Roundcube-Request', ref.env.request_token); } |
| | | }); |
| | | |
| | | // unload fix |
| | | $(window).bind('beforeunload', function() { rcmail.unload = true; }); |
| | | |
| | | // set environment variable(s) |
| | | this.set_env = function(p, value) |
| | |
| | | // add a button to the button list |
| | | this.register_button = function(command, id, type, act, sel, over) |
| | | { |
| | | if (!this.buttons[command]) |
| | | this.buttons[command] = []; |
| | | |
| | | var button_prop = {id:id, type:type}; |
| | | |
| | | if (act) button_prop.act = act; |
| | | if (sel) button_prop.sel = sel; |
| | | if (over) button_prop.over = over; |
| | | |
| | | if (!this.buttons[command]) |
| | | this.buttons[command] = []; |
| | | |
| | | this.buttons[command].push(button_prop); |
| | | |
| | |
| | | } |
| | | |
| | | // enable general commands |
| | | this.enable_command('logout', 'mail', 'addressbook', 'settings', 'save-pref', 'compose', 'undo', 'about', 'switch-task', true); |
| | | this.enable_command('close', 'logout', 'mail', 'addressbook', 'settings', 'save-pref', 'compose', 'undo', 'about', 'switch-task', true); |
| | | |
| | | if (this.env.permaurl) |
| | | this.enable_command('permaurl', true); |
| | | this.enable_command('permaurl', 'extwin', true); |
| | | |
| | | switch (this.task) { |
| | | |
| | |
| | | this.enable_command('list', 'checkmail', 'add-contact', 'search', 'reset-search', 'collapse-folder', true); |
| | | |
| | | if (this.gui_objects.messagelist) { |
| | | |
| | | this.message_list = new rcube_list_widget(this.gui_objects.messagelist, { |
| | | multiselect:true, multiexpand:true, draggable:true, keyboard:true, |
| | | column_movable:this.env.col_movable, dblclick_time:this.dblclick_time |
| | |
| | | this.gui_objects.messagelist.parentNode.onmousedown = function(e){ return p.click_on_list(e); }; |
| | | |
| | | this.message_list.init(); |
| | | this.enable_command('toggle_status', 'toggle_flag', 'menu-open', 'menu-save', true); |
| | | this.enable_command('toggle_status', 'toggle_flag', 'menu-open', 'menu-save', 'sort', true); |
| | | |
| | | // load messages |
| | | this.command('list'); |
| | | } |
| | | |
| | | if (this.gui_objects.qsearchbox) { |
| | | if (this.env.search_text != null) { |
| | | if (this.env.search_text != null) |
| | | this.gui_objects.qsearchbox.value = this.env.search_text; |
| | | } |
| | | $(this.gui_objects.qsearchbox).focusin(function() { rcmail.message_list.blur(); }); |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | else if (this.env.action == 'compose') { |
| | | this.env.compose_commands = ['send-attachment', 'remove-attachment', 'send', 'cancel', 'toggle-editor', 'list-adresses']; |
| | | this.env.compose_commands = ['send-attachment', 'remove-attachment', 'send', 'cancel', 'toggle-editor', 'list-adresses', 'extwin']; |
| | | |
| | | if (this.env.drafts_mailbox) |
| | | this.env.compose_commands.push('savedraft') |
| | |
| | | this.enable_command('list', 'listgroup', 'listsearch', 'advanced-search', true); |
| | | |
| | | if (this.gui_objects.contactslist) { |
| | | |
| | | this.contact_list = new rcube_list_widget(this.gui_objects.contactslist, |
| | | {multiselect:true, draggable:this.gui_objects.folderlist?true:false, keyboard:true}); |
| | | this.contact_list.row_init = function(row){ p.triggerEvent('insertrow', { cid:row.uid, row:row }); }; |
| | |
| | | |
| | | this.gui_objects.contactslist.parentNode.onmousedown = function(e){ return p.click_on_list(e); }; |
| | | document.onmouseup = function(e){ return p.doc_mouse_up(e); }; |
| | | if (this.gui_objects.qsearchbox) { |
| | | if (this.gui_objects.qsearchbox) |
| | | $(this.gui_objects.qsearchbox).focusin(function() { rcmail.contact_list.blur(); }); |
| | | } |
| | | |
| | | this.update_group_commands(); |
| | | this.command('list'); |
| | |
| | | this.init_contact_form(); |
| | | } |
| | | |
| | | if (this.gui_objects.qsearchbox) { |
| | | if (this.gui_objects.qsearchbox) |
| | | this.enable_command('search', 'reset-search', 'moveto', true); |
| | | } |
| | | |
| | | break; |
| | | |
| | |
| | | $('#rcmloginpwd').focus(); |
| | | |
| | | // detect client timezone |
| | | var dt = new Date(), |
| | | tz = dt.getTimezoneOffset() / -60, |
| | | stdtz = dt.getStdTimezoneOffset() / -60; |
| | | |
| | | $('#rcmlogintz').val(stdtz); |
| | | $('#rcmlogindst').val(tz > stdtz ? 1 : 0); |
| | | if (window.jstz && !bw.ie6) { |
| | | var timezone = jstz.determine(); |
| | | if (timezone.name()) |
| | | $('#rcmlogintz').val(timezone.name()); |
| | | } |
| | | else { |
| | | $('#rcmlogintz').val(new Date().getStdTimezoneOffset() / -60); |
| | | } |
| | | |
| | | // display 'loading' message on form submit, lock submit button |
| | | $('form').submit(function () { |
| | |
| | | this.gui_containers.foldertray = $(this.gui_objects.folderlist); |
| | | |
| | | // activate html5 file drop feature (if browser supports it and if configured) |
| | | if (this.gui_objects.filedrop && this.env.filedrop && ((XMLHttpRequest && XMLHttpRequest.prototype.sendAsBinary) || window.FormData)) { |
| | | if (this.gui_objects.filedrop && this.env.filedrop && ((window.XMLHttpRequest && XMLHttpRequest.prototype && XMLHttpRequest.prototype.sendAsBinary) || window.FormData)) { |
| | | $(document.body).bind('dragover dragleave drop', function(e){ return ref.document_drag_hover(e, e.type == 'dragover'); }); |
| | | $(this.gui_objects.filedrop).addClass('droptarget') |
| | | .bind('dragover dragleave', function(e){ return ref.file_drag_hover(e, e.type == 'dragover'); }) |
| | |
| | | this.onloads[i](); |
| | | } |
| | | |
| | | // start keep-alive interval |
| | | // start keep-alive and refresh intervals |
| | | this.start_refresh(); |
| | | this.start_keepalive(); |
| | | }; |
| | | |
| | |
| | | /*********************************************************/ |
| | | |
| | | // execute a specific command on the web client |
| | | this.command = function(command, props, obj) |
| | | this.command = function(command, props, obj, event) |
| | | { |
| | | var ret, uid, cid, url, flag; |
| | | |
| | |
| | | |
| | | if (this.busy) |
| | | return false; |
| | | |
| | | // let the browser handle this click (shift/ctrl usually opens the link in a new window/tab) |
| | | if ((obj && obj.href && String(obj.href).indexOf(location.href) < 0) && rcube_event.get_modifier(event)) { |
| | | return true; |
| | | } |
| | | |
| | | // command not supported or allowed |
| | | if (!this.commands[command]) { |
| | |
| | | break; |
| | | |
| | | case 'about': |
| | | location.href = '?_task=settings&_action=about'; |
| | | this.redirect('?_task=settings&_action=about', false); |
| | | break; |
| | | |
| | | case 'permaurl': |
| | |
| | | parent.location.href = this.env.permaurl; |
| | | break; |
| | | |
| | | case 'extwin': |
| | | if (this.env.action == 'compose') { |
| | | var prevstate = this.env.compose_extwin; |
| | | $("input[name='_action']", this.gui_objects.messageform).val('compose'); |
| | | this.gui_objects.messageform.action = this.url('mail/compose', { _id: this.env.compose_id, _extwin: 1 }); |
| | | this.gui_objects.messageform.target = this.open_window('', 1150, 900); |
| | | this.gui_objects.messageform.submit(); |
| | | } |
| | | else { |
| | | this.open_window(this.env.permaurl, 1000, 1200); |
| | | } |
| | | break; |
| | | |
| | | case 'menu-open': |
| | | case 'menu-save': |
| | | this.triggerEvent(command, {props:props}); |
| | |
| | | |
| | | case 'open': |
| | | if (uid = this.get_single_uid()) { |
| | | obj.href = '?_task='+this.env.task+'&_action=show&_mbox='+urlencode(this.env.mailbox)+'&_uid='+uid; |
| | | obj.href = this.url('show', {_mbox: this.env.mailbox, _uid: uid}); |
| | | return true; |
| | | } |
| | | break; |
| | | |
| | | case 'close': |
| | | if (this.env.extwin) |
| | | window.close(); |
| | | break; |
| | | |
| | | case 'list': |
| | | if (props && props != '') |
| | | this.reset_qsearch(); |
| | | if (this.task == 'mail') { |
| | | if (this.env.action == 'compose' && this.env.extwin) |
| | | window.close(); |
| | | else if (this.task == 'mail') { |
| | | this.list_mailbox(props); |
| | | this.set_button_titles(); |
| | | } |
| | |
| | | break; |
| | | |
| | | case 'sort': |
| | | var sort_order, sort_col = props; |
| | | var sort_order = this.env.sort_order, |
| | | sort_col = !this.env.disabled_sort_col ? props : this.env.sort_col; |
| | | |
| | | if (this.env.sort_col==sort_col) |
| | | sort_order = this.env.sort_order=='ASC' ? 'DESC' : 'ASC'; |
| | | else |
| | | sort_order = 'ASC'; |
| | | if (!this.env.disabled_sort_order) |
| | | sort_order = this.env.sort_col == sort_col && sort_order == 'ASC' ? 'DESC' : 'ASC'; |
| | | |
| | | // set table header and update env |
| | | this.set_list_sorting(sort_col, sort_order); |
| | |
| | | uid = this.get_single_uid(); |
| | | if (uid && (!this.env.uid || uid != this.env.uid)) { |
| | | if (this.env.mailbox == this.env.drafts_mailbox) |
| | | this.goto_url('compose', { _draft_uid: uid, _mbox: this.env.mailbox }, true); |
| | | this.open_compose_step({ _draft_uid: uid, _mbox: this.env.mailbox }); |
| | | else |
| | | this.show_message(uid); |
| | | } |
| | |
| | | this.load_identity(props, 'edit-identity'); |
| | | else if (this.task == 'mail' && (cid = this.get_single_uid())) { |
| | | url = { _mbox: this.env.mailbox }; |
| | | url[this.env.mailbox == this.env.drafts_mailbox ? '_draft_uid' : '_uid'] = cid; |
| | | this.goto_url('compose', url, true); |
| | | url[this.env.mailbox == this.env.drafts_mailbox && props != 'new' ? '_draft_uid' : '_uid'] = cid; |
| | | this.open_compose_step(url); |
| | | } |
| | | break; |
| | | |
| | |
| | | case 'delete': |
| | | // mail task |
| | | if (this.task == 'mail') |
| | | this.delete_messages(); |
| | | this.delete_messages(event); |
| | | // addressbook task |
| | | else if (this.task == 'addressbook') |
| | | this.delete_contacts(); |
| | |
| | | uid = props._row.uid; |
| | | |
| | | // toggle read/unread |
| | | if (this.message_list.rows[uid].deleted) { |
| | | if (this.message_list.rows[uid].deleted) |
| | | flag = 'undelete'; |
| | | } |
| | | else if (!this.message_list.rows[uid].unread) |
| | | flag = 'unread'; |
| | | } |
| | |
| | | // toggle flagged/unflagged |
| | | if (this.message_list.rows[uid].flagged) |
| | | flag = 'unflagged'; |
| | | } |
| | | } |
| | | this.mark_message(flag, uid); |
| | | break; |
| | | |
| | |
| | | |
| | | case 'previousmessage': |
| | | if (this.env.prev_uid) |
| | | this.show_message(this.env.prev_uid, false, this.env.action=='preview'); |
| | | this.show_message(this.env.prev_uid, false, this.env.action == 'preview'); |
| | | break; |
| | | |
| | | case 'firstmessage': |
| | |
| | | this.show_message(this.env.first_uid); |
| | | break; |
| | | |
| | | case 'checkmail': |
| | | this.check_for_recent(true); |
| | | break; |
| | | |
| | | case 'compose': |
| | | url = this.url('mail/compose'); |
| | | url = {}; |
| | | |
| | | if (this.task == 'mail') { |
| | | url += '&_mbox='+urlencode(this.env.mailbox); |
| | | url._mbox = this.env.mailbox; |
| | | if (props) |
| | | url += '&_to='+urlencode(props); |
| | | url._to = props; |
| | | // also send search request so we can go back to search result after message is sent |
| | | if (this.env.search_request) |
| | | url += '&_search='+this.env.search_request; |
| | | url._search = this.env.search_request; |
| | | } |
| | | // modify url if we're in addressbook |
| | | else if (this.task == 'addressbook') { |
| | | // switch to mail compose step directly |
| | | if (props && props.indexOf('@') > 0) { |
| | | url = this.get_task_url('mail', url); |
| | | this.redirect(url + '&_to='+urlencode(props)); |
| | | url._to = props; |
| | | } |
| | | else { |
| | | // use contact_id passed as command parameter |
| | | var n, len, a_cids = []; |
| | | if (props) |
| | | a_cids.push(props); |
| | | // get selected contacts |
| | | else if (this.contact_list) { |
| | | var selection = this.contact_list.get_selection(); |
| | | for (n=0, len=selection.length; n<len; n++) |
| | | a_cids.push(selection[n]); |
| | | } |
| | | |
| | | if (a_cids.length) |
| | | this.http_post('mailto', { _cid: a_cids.join(','), _source: this.env.source }, true); |
| | | else if (this.env.group) |
| | | this.http_post('mailto', { _gid: this.env.group, _source: this.env.source }, true); |
| | | |
| | | break; |
| | | } |
| | | |
| | | // use contact_id passed as command parameter |
| | | var n, len, a_cids = []; |
| | | if (props) |
| | | a_cids.push(props); |
| | | // get selected contacts |
| | | else if (this.contact_list) { |
| | | var selection = this.contact_list.get_selection(); |
| | | for (n=0, len=selection.length; n<len; n++) |
| | | a_cids.push(selection[n]); |
| | | } |
| | | |
| | | if (a_cids.length) |
| | | this.http_post('mailto', { _cid: a_cids.join(','), _source: this.env.source}, true); |
| | | else if (this.env.group) |
| | | this.http_post('mailto', { _gid: this.env.group, _source: this.env.source}, true); |
| | | |
| | | break; |
| | | } |
| | | else if (props) |
| | | url += '&_to='+urlencode(props); |
| | | url._to = props; |
| | | |
| | | this.redirect(url); |
| | | this.open_compose_step(url); |
| | | break; |
| | | |
| | | case 'spellcheck': |
| | |
| | | break; |
| | | |
| | | case 'savedraft': |
| | | var form = this.gui_objects.messageform, msgid; |
| | | |
| | | // Reset the auto-save timer |
| | | clearTimeout(this.save_timer); |
| | | |
| | | // saving Drafts is disabled |
| | | if (!form) |
| | | break; |
| | | |
| | | // compose form did not change |
| | | if (this.cmp_hash == this.compose_field_hash()) { |
| | |
| | | break; |
| | | } |
| | | |
| | | // re-set keep-alive timeout |
| | | this.start_keepalive(); |
| | | |
| | | msgid = this.set_busy(true, 'savingmessage'); |
| | | |
| | | form.target = "savetarget"; |
| | | form._draft.value = '1'; |
| | | form.action = this.add_url(form.action, '_unlock', msgid); |
| | | form.submit(); |
| | | this.submit_messageform(true); |
| | | break; |
| | | |
| | | case 'send': |
| | | if (!this.gui_objects.messageform) |
| | | break; |
| | | |
| | | if (!props.nocheck && !this.check_compose_input(command)) |
| | | break; |
| | | |
| | | // Reset the auto-save timer |
| | | clearTimeout(this.save_timer); |
| | | |
| | | // all checks passed, send message |
| | | var lang = this.spellcheck_lang(), |
| | | form = this.gui_objects.messageform, |
| | | msgid = this.set_busy(true, 'sendingmessage'); |
| | | |
| | | form.target = 'savetarget'; |
| | | form._draft.value = ''; |
| | | form.action = this.add_url(form.action, '_unlock', msgid); |
| | | form.action = this.add_url(form.action, '_lang', lang); |
| | | form.submit(); |
| | | |
| | | this.submit_messageform(); |
| | | break; |
| | | |
| | | case 'send-attachment': |
| | |
| | | // do reply-list, when list is detected and popup menu wasn't used |
| | | url._all = (!props && this.commands['reply-list'] ? 'list' : 'all'); |
| | | else if (command == 'reply-list') |
| | | url._all = list; |
| | | url._all = 'list'; |
| | | |
| | | this.goto_url('compose', url, true); |
| | | this.open_compose_step(url); |
| | | } |
| | | break; |
| | | |
| | |
| | | url = { _forward_uid: uid, _mbox: this.env.mailbox }; |
| | | if (command == 'forward-attachment' || (!props && this.env.forward_attachment)) |
| | | url._attachment = 1; |
| | | this.goto_url('compose', url, true); |
| | | this.open_compose_step(url); |
| | | } |
| | | break; |
| | | |
| | |
| | | |
| | | this.doc_mouse_up = function(e) |
| | | { |
| | | var model, list, li, id; |
| | | var model, list, id; |
| | | |
| | | // ignore event if jquery UI dialog is open |
| | | if ($(rcube_event.get_target(e)).closest('.ui-dialog, .ui-widget-overlay').length) |
| | | return; |
| | | |
| | | if (list = this.message_list) { |
| | | if (!rcube_mouse_is_over(e, list.list.parentNode)) |
| | | list.blur(); |
| | | else |
| | | list.focus(); |
| | | if (list = this.message_list) |
| | | model = this.env.mailboxes; |
| | | } |
| | | else if (list = this.contact_list) { |
| | | if (!rcube_mouse_is_over(e, list.list.parentNode)) |
| | | list.blur(); |
| | | else |
| | | list.focus(); |
| | | else if (list = this.contact_list) |
| | | model = this.env.contactfolders; |
| | | } |
| | | else if (this.ksearch_value) { |
| | | else if (this.ksearch_value) |
| | | this.ksearch_blur(); |
| | | } |
| | | |
| | | if (list && !rcube_mouse_is_over(e, list.list.parentNode)) |
| | | list.blur(); |
| | | |
| | | // handle mouse release when dragging |
| | | if (this.drag_active && model && this.env.last_folder_target) { |
| | |
| | | if (list.multi_selecting || !this.env.contentframe) |
| | | return; |
| | | |
| | | if (list.get_single_selection() && window.frames && window.frames[this.env.contentframe]) { |
| | | if (window.frames[this.env.contentframe].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); |
| | | } |
| | | if (list.get_single_selection()) |
| | | return; |
| | | |
| | | var win = this.get_frame_window(this.env.contentframe); |
| | | |
| | | 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); |
| | | } |
| | | }; |
| | | |
| | |
| | | |
| | | var uid = list.get_single_selection(); |
| | | if (uid && this.env.mailbox == this.env.drafts_mailbox) |
| | | this.goto_url('compose', { _draft_uid: uid, _mbox: this.env.mailbox }, true); |
| | | this.open_compose_step({ _draft_uid: uid, _mbox: this.env.mailbox }); |
| | | else if (uid) |
| | | this.show_message(uid, false, false); |
| | | }; |
| | |
| | | for (i=0; i<cols.length; i++) |
| | | if (cols[i].id && cols[i].id.match(/^rcm/)) { |
| | | name = cols[i].id.replace(/^rcm/, ''); |
| | | this.env.coltypes.push(name == 'to' ? 'from' : name); |
| | | this.env.coltypes.push(name); |
| | | } |
| | | |
| | | if ((found = $.inArray('flag', this.env.coltypes)) >= 0) |
| | |
| | | } |
| | | |
| | | return allow ? (copy ? 2 : 1) : 0; |
| | | }; |
| | | |
| | | this.open_window = function(url, width, height) |
| | | { |
| | | var w = Math.min(width, screen.width - 10), |
| | | h = Math.min(height, screen.height - 100), |
| | | l = (screen.width - w) / 2 + (screen.left || 0), |
| | | t = Math.max(0, (screen.height - h) / 2 + (screen.top || 0) - 20); |
| | | |
| | | var wname = 'rcmextwin' + new Date().getTime(), |
| | | extwin = window.open(url + '&_extwin=1', wname, 'width='+w+',height='+h+',top='+t+',left='+l+',resizable=yes,toolbar=no,status=no'); |
| | | extwin.moveTo(l,t); |
| | | |
| | | // write loading... message to empty windows |
| | | if (!url && extwin.document) { |
| | | extwin.document.write('<html><body>' + this.get_label('loading') + '</body></html>'); |
| | | } |
| | | |
| | | // focus window, delayed to bring to front |
| | | window.setTimeout(function(){ extwin.focus(); }, 10); |
| | | |
| | | return wname; |
| | | }; |
| | | |
| | | |
| | |
| | | html = '<span id="flagicn'+uid+'" class="'+css_class+'"> </span>'; |
| | | } |
| | | else if (c == 'attachment') { |
| | | if (/application\/|multipart\/m/.test(flags.ctype)) |
| | | if (/application\/|multipart\/(m|signed)/.test(flags.ctype)) |
| | | html = '<span class="attachment"> </span>'; |
| | | else if (/multipart\/report/.test(flags.ctype)) |
| | | html = '<span class="report"> </span>'; |
| | |
| | | // make sure new columns are added at the end of the list |
| | | var i, idx, name, newcols = [], oldcols = this.env.coltypes; |
| | | for (i=0; i<oldcols.length; i++) { |
| | | name = oldcols[i] == 'to' ? 'from' : oldcols[i]; |
| | | name = oldcols[i]; |
| | | idx = $.inArray(name, cols); |
| | | if (idx != -1) { |
| | | newcols.push(name); |
| | |
| | | this.list_mailbox('', '', sort_col+'_'+sort_order, post_data); |
| | | }; |
| | | |
| | | // when user doble-clicks on a row |
| | | // when user double-clicks on a row |
| | | this.show_message = function(id, safe, preview) |
| | | { |
| | | if (!id) |
| | | return; |
| | | |
| | | var target = window, |
| | | var win, target = window, |
| | | action = preview ? 'preview': 'show', |
| | | url = '&_action='+action+'&_uid='+id+'&_mbox='+urlencode(this.env.mailbox); |
| | | |
| | | if (preview && this.env.contentframe && window.frames && window.frames[this.env.contentframe]) { |
| | | target = window.frames[this.env.contentframe]; |
| | | if (preview && (win = this.get_frame_window(this.env.contentframe))) { |
| | | target = win; |
| | | url += '&_framed=1'; |
| | | } |
| | | |
| | |
| | | // add browser capabilities, so we can properly handle attachments |
| | | url += '&_caps='+urlencode(this.browser_capabilities()); |
| | | |
| | | if (preview && String(target.location.href).indexOf(url) >= 0) |
| | | if (this.env.extwin) |
| | | url += '&_extwin=1'; |
| | | |
| | | if (preview && String(target.location.href).indexOf(url) >= 0) { |
| | | this.show_contentframe(true); |
| | | } |
| | | else { |
| | | this.location_href(this.env.comm_path+url, target, true); |
| | | if (!preview && this.env.message_extwin && !this.env.extwin) |
| | | this.open_window(this.env.comm_path+url, 1000, 1200); |
| | | else |
| | | this.location_href(this.env.comm_path+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) { |
| | |
| | | |
| | | this.show_contentframe = function(show) |
| | | { |
| | | var frm, win; |
| | | if (this.env.contentframe && (frm = $('#'+this.env.contentframe)) && frm.length) { |
| | | if (!show && (win = window.frames[this.env.contentframe])) { |
| | | var frame, win, name = this.env.contentframe; |
| | | |
| | | 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; |
| | | } |
| | | else if (!bw.safari && !bw.konq) |
| | | frm[show ? 'show' : 'hide'](); |
| | | } |
| | | $(frame)[show ? 'show' : 'hide'](); |
| | | } |
| | | |
| | | if (!show && this.busy) |
| | | this.set_busy(false, null, this.env.frame_lock); |
| | | }; |
| | | |
| | | this.get_frame_element = function(id) |
| | | { |
| | | var frame; |
| | | |
| | | if (id && (frame = document.getElementById(id))) |
| | | return frame; |
| | | }; |
| | | |
| | | this.get_frame_window = function(id) |
| | | { |
| | | var frame = this.get_frame_element(id); |
| | | |
| | | if (frame && frame.name && window.frames) |
| | | return window.frames[frame.name]; |
| | | }; |
| | | |
| | | this.lock_frame = function() |
| | |
| | | } |
| | | }; |
| | | |
| | | // sends request to check for recent messages |
| | | this.checkmail = function() |
| | | { |
| | | var lock = this.set_busy(true, 'checkingmail'), |
| | | params = this.check_recent_params(); |
| | | |
| | | this.http_request('check-recent', params, lock); |
| | | }; |
| | | |
| | | // list messages of a specific mailbox using filter |
| | | this.filter_mailbox = function(filter) |
| | | { |
| | |
| | | // list messages of a specific mailbox |
| | | this.list_mailbox = function(mbox, page, sort, url) |
| | | { |
| | | var target = window; |
| | | var win, target = window; |
| | | |
| | | if (typeof url != 'object') |
| | | url = {}; |
| | |
| | | return; |
| | | } |
| | | |
| | | if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) { |
| | | target = window.frames[this.env.contentframe]; |
| | | if (win = this.get_frame_window(this.env.contentframe)) { |
| | | target = win; |
| | | url._framed = 1; |
| | | } |
| | | |
| | |
| | | // set message row status, class and icon |
| | | this.set_message = function(uid, flag, status) |
| | | { |
| | | var row = this.message_list.rows[uid]; |
| | | var row = this.message_list && this.message_list.rows[uid]; |
| | | |
| | | if (!row) |
| | | return false; |
| | |
| | | }; |
| | | |
| | | // delete selected messages from the current mailbox |
| | | this.delete_messages = function() |
| | | this.delete_messages = function(event) |
| | | { |
| | | var uid, i, len, trash = this.env.trash_mailbox, |
| | | list = this.message_list, |
| | |
| | | // if there is a trash mailbox defined and we're not currently in it |
| | | else { |
| | | // if shift was pressed delete it immediately |
| | | if (list && list.modkey == SHIFT_KEY) { |
| | | if ((list && list.modkey == SHIFT_KEY) || (event && rcube_event.get_modifier(event) == SHIFT_KEY)) { |
| | | if (confirm(this.get_label('deletemessagesconfirm'))) |
| | | this.permanently_remove_messages(); |
| | | } |
| | |
| | | // set a specific flag to one or more messages |
| | | this.mark_message = function(flag, uid) |
| | | { |
| | | var a_uids = [], r_uids = [], len, n, id, |
| | | selection = this.message_list ? this.message_list.get_selection() : []; |
| | | var a_uids = [], r_uids = [], len, n, id, selection, |
| | | list = this.message_list; |
| | | |
| | | if (uid) |
| | | a_uids[0] = uid; |
| | | else if (this.env.uid) |
| | | a_uids[0] = this.env.uid; |
| | | else if (this.message_list) { |
| | | else if (list) { |
| | | selection = list.get_selection(); |
| | | for (n=0, len=selection.length; n<len; n++) { |
| | | a_uids.push(selection[n]); |
| | | } |
| | | } |
| | | |
| | | if (!this.message_list) |
| | | if (!list) |
| | | r_uids = a_uids; |
| | | else |
| | | else { |
| | | list.focus(); |
| | | for (n=0, len=a_uids.length; n<len; n++) { |
| | | id = a_uids[n]; |
| | | if ((flag=='read' && this.message_list.rows[id].unread) |
| | | || (flag=='unread' && !this.message_list.rows[id].unread) |
| | | || (flag=='delete' && !this.message_list.rows[id].deleted) |
| | | || (flag=='undelete' && this.message_list.rows[id].deleted) |
| | | || (flag=='flagged' && !this.message_list.rows[id].flagged) |
| | | || (flag=='unflagged' && this.message_list.rows[id].flagged)) |
| | | if ((flag=='read' && list.rows[id].unread) |
| | | || (flag=='unread' && !list.rows[id].unread) |
| | | || (flag=='delete' && !list.rows[id].deleted) |
| | | || (flag=='undelete' && list.rows[id].deleted) |
| | | || (flag=='flagged' && !list.rows[id].flagged) |
| | | || (flag=='unflagged' && list.rows[id].flagged)) |
| | | { |
| | | r_uids.push(id); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // nothing to do |
| | | if (!r_uids.length && !this.select_all_mode) |
| | |
| | | /********* message compose methods *********/ |
| | | /*********************************************************/ |
| | | |
| | | this.open_compose_step = function(p) |
| | | { |
| | | var url = this.url('mail/compose', p); |
| | | |
| | | // open new compose window |
| | | if (this.env.compose_extwin && !this.env.extwin) { |
| | | this.open_window(url, 1150, 900); |
| | | } |
| | | else { |
| | | this.redirect(url); |
| | | window.resizeTo(Math.max(1150, $(window).width()), Math.max(900, $(window).height())); |
| | | } |
| | | }; |
| | | |
| | | // init message compose form: set focus and eventhandlers |
| | | this.init_messageform = function() |
| | | { |
| | |
| | | html_mode = $("input[name='_is_html']").val() == '1', |
| | | ac_fields = ['cc', 'bcc', 'replyto', 'followupto'], |
| | | ac_props; |
| | | |
| | | // close compose step in opener |
| | | if (window.opener && opener.rcmail && opener.rcmail.env.action == 'compose') { |
| | | setTimeout(function(){ opener.history.back(); }, 100); |
| | | this.env.opened_extwin = true; |
| | | } |
| | | |
| | | // configure parallel autocompletion |
| | | if (this.env.autocomplete_threads > 0) { |
| | |
| | | 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') { |
| | | if (input_from.prop('type') == 'select-one' && !this.env.opened_extwin) { |
| | | this.change_identity(input_from[0]); |
| | | } |
| | | } |
| | |
| | | |
| | | obj[bw.ie || bw.safari || bw.chrome ? 'keydown' : 'keypress'](function(e) { return ref.ksearch_keydown(e, this, props); }) |
| | | .attr('autocomplete', 'off'); |
| | | }; |
| | | |
| | | this.submit_messageform = function(draft) |
| | | { |
| | | var form = this.gui_objects.messageform; |
| | | |
| | | if (!form) |
| | | return; |
| | | |
| | | // all checks passed, send message |
| | | var msgid = this.set_busy(true, draft ? 'savingmessage' : 'sendingmessage'), |
| | | lang = this.spellcheck_lang(), |
| | | files = []; |
| | | |
| | | // send files list |
| | | $('li', this.gui_objects.attachmentlist).each(function() { files.push(this.id.replace(/^rcmfile/, '')); }); |
| | | $('input[name="_attachments"]', form).val(files.join()); |
| | | |
| | | form.target = 'savetarget'; |
| | | form._draft.value = draft ? '1' : ''; |
| | | form.action = this.add_url(form.action, '_unlock', msgid); |
| | | form.action = this.add_url(form.action, '_lang', lang); |
| | | form.submit(); |
| | | }; |
| | | |
| | | this.compose_recipient_select = function(list) |
| | |
| | | input_message = $("[name='_message']"), |
| | | message = input_message.val(), |
| | | is_html = ($("input[name='_is_html']").val() == '1'), |
| | | sig = this.env.identity, |
| | | sig_separator = this.env.sig_above && (this.env.compose_mode == 'reply' || this.env.compose_mode == 'forward') ? '---' : '-- '; |
| | | sig = this.env.identity; |
| | | |
| | | // enable manual signature insert |
| | | if (this.env.signatures && this.env.signatures[id]) { |
| | |
| | | if (!is_html) { |
| | | // remove the 'old' signature |
| | | if (show_sig && sig && this.env.signatures && this.env.signatures[sig]) { |
| | | |
| | | sig = this.env.signatures[sig].is_html ? this.env.signatures[sig].plain_text : this.env.signatures[sig].text; |
| | | sig = this.env.signatures[sig].text; |
| | | sig = sig.replace(/\r\n/g, '\n'); |
| | | |
| | | if (!sig.match(/^--[ -]\n/m)) |
| | | sig = sig_separator + '\n' + sig; |
| | | |
| | | p = this.env.sig_above ? message.indexOf(sig) : message.lastIndexOf(sig); |
| | | if (p >= 0) |
| | |
| | | } |
| | | // add the new signature string |
| | | if (show_sig && this.env.signatures && this.env.signatures[id]) { |
| | | sig = this.env.signatures[id]['is_html'] ? this.env.signatures[id]['plain_text'] : this.env.signatures[id]['text']; |
| | | sig = this.env.signatures[id].text; |
| | | sig = sig.replace(/\r\n/g, '\n'); |
| | | |
| | | if (!sig.match(/^--[ -]\n/m)) |
| | | sig = sig_separator + '\n' + sig; |
| | | |
| | | if (this.env.sig_above) { |
| | | if (p >= 0) { // in place of removed signature |
| | | message = message.substring(0, p) + sig + message.substring(p, message.length); |
| | | cursor_pos = p - 1; |
| | | } |
| | | else if (!message) { // empty message |
| | | cursor_pos = 0; |
| | | message = '\n\n' + sig; |
| | | } |
| | | else if (pos = this.get_caret_pos(input_message.get(0))) { // at cursor position |
| | | message = message.substring(0, pos) + '\n' + sig + '\n\n' + message.substring(pos, message.length); |
| | |
| | | } |
| | | } |
| | | |
| | | if (this.env.signatures[id]) { |
| | | if (this.env.signatures[id].is_html) { |
| | | sig = this.env.signatures[id].text; |
| | | if (!this.env.signatures[id].plain_text.match(/^--[ -]\r?\n/m)) |
| | | sig = sig_separator + '<br />' + sig; |
| | | } |
| | | else { |
| | | sig = this.env.signatures[id].text; |
| | | if (!sig.match(/^--[ -]\r?\n/m)) |
| | | sig = sig_separator + '\n' + sig; |
| | | sig = '<pre>' + sig + '</pre>'; |
| | | } |
| | | |
| | | sigElem.innerHTML = sig; |
| | | } |
| | | if (this.env.signatures[id]) |
| | | sigElem.innerHTML = this.env.signatures[id].html; |
| | | } |
| | | |
| | | this.env.identity = id; |
| | |
| | | this.sent_successfully = function(type, msg) |
| | | { |
| | | this.display_message(msg, type); |
| | | // before redirect we need to wait some time for Chrome (#1486177) |
| | | setTimeout(function(){ ref.list_mailbox(); }, 500); |
| | | |
| | | if (this.env.extwin && window.opener && opener.rcmail) { |
| | | this.lock_form(this.gui_objects.messageform); |
| | | opener.rcmail.display_message(msg, type); |
| | | setTimeout(function(){ window.close() }, 1000); |
| | | } |
| | | else { |
| | | // before redirect we need to wait some time for Chrome (#1486177) |
| | | setTimeout(function(){ ref.list_mailbox(); }, 500); |
| | | } |
| | | }; |
| | | |
| | | |
| | |
| | | |
| | | // 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', typeof this.env.group != 'undefined' && list.selection.length > 0); |
| | | |
| | | this.enable_command('group-remove-selected', this.env.group && list.selection.length > 0); |
| | | this.enable_command('compose', this.env.group || list.selection.length > 0); |
| | | this.enable_command('edit', id && writable); |
| | | this.enable_command('delete', list.selection.length && writable); |
| | |
| | | |
| | | this.list_contacts = function(src, group, page) |
| | | { |
| | | var folder, url = {}, |
| | | var win, folder, url = {}, |
| | | target = window; |
| | | |
| | | if (!src) |
| | |
| | | return; |
| | | } |
| | | |
| | | if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) { |
| | | target = window.frames[this.env.contentframe]; |
| | | if (win = this.get_frame_window(this.env.contentframe)) { |
| | | target = win; |
| | | url._framed = 1; |
| | | } |
| | | |
| | |
| | | // load contact record |
| | | this.load_contact = function(cid, action, framed) |
| | | { |
| | | var url = {}, target = window; |
| | | var win, url = {}, target = window; |
| | | |
| | | if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) { |
| | | if (win = this.get_frame_window(this.env.contentframe)) { |
| | | url._framed = 1; |
| | | target = window.frames[this.env.contentframe]; |
| | | target = win; |
| | | this.show_contentframe(true); |
| | | |
| | | // load dummy content |
| | |
| | | if (!this.gui_objects.contactslist) |
| | | return false; |
| | | |
| | | var c, list = this.contact_list, |
| | | var c, col, list = this.contact_list, |
| | | row = document.createElement('tr'); |
| | | |
| | | row.id = 'rcmrow'+this.html_identifier(cid); |
| | |
| | | { |
| | | if (form && form.elements._photo.value) { |
| | | this.async_upload_form(form, 'upload-photo', function(e) { |
| | | rcmail.set_busy(false, null, rcmail.photo_upload_id); |
| | | rcmail.set_busy(false, null, rcmail.file_upload_id); |
| | | }); |
| | | |
| | | // display upload indicator |
| | | this.photo_upload_id = this.set_busy(true, 'uploading'); |
| | | this.file_upload_id = this.set_busy(true, 'uploading'); |
| | | } |
| | | }; |
| | | |
| | |
| | | |
| | | this.photo_upload_end = function() |
| | | { |
| | | this.set_busy(false, null, this.photo_upload_id); |
| | | delete this.photo_upload_id; |
| | | this.set_busy(false, null, this.file_upload_id); |
| | | delete this.file_upload_id; |
| | | }; |
| | | |
| | | this.set_photo_actions = function(id) |
| | |
| | | // load advanced search page |
| | | this.advanced_search = function() |
| | | { |
| | | var url = {_form: 1, _action: 'search'}, target = window; |
| | | var win, url = {_form: 1, _action: 'search'}, target = window; |
| | | |
| | | if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) { |
| | | if (win = this.get_frame_window(this.env.contentframe)) { |
| | | url._framed = 1; |
| | | target = window.frames[this.env.contentframe]; |
| | | target = win; |
| | | this.contact_list.clear_selection(); |
| | | } |
| | | |
| | |
| | | // preferences section select and load options frame |
| | | this.section_select = function(list) |
| | | { |
| | | var id = list.get_single_selection(), target = window, |
| | | var win, id = list.get_single_selection(), target = window, |
| | | url = {_action: 'edit-prefs', _section: id}; |
| | | |
| | | if (id) { |
| | | if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) { |
| | | if (win = this.get_frame_window(this.env.contentframe)) { |
| | | url._framed = 1; |
| | | target = window.frames[this.env.contentframe]; |
| | | target = win; |
| | | } |
| | | this.location_href(url, target, true); |
| | | } |
| | |
| | | if (action == 'edit-identity' && (!id || id == this.env.iid)) |
| | | return false; |
| | | |
| | | var target = window, |
| | | var win, target = window, |
| | | url = {_action: action, _iid: id}; |
| | | |
| | | if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) { |
| | | if (win = this.get_frame_window(this.env.contentframe)) { |
| | | url._framed = 1; |
| | | target = window.frames[this.env.contentframe]; |
| | | document.getElementById(this.env.contentframe).style.visibility = 'inherit'; |
| | | target = win; |
| | | } |
| | | |
| | | if (action && (id || action == 'add-identity')) { |
| | |
| | | // when user select a folder in manager |
| | | this.show_folder = function(folder, path, force) |
| | | { |
| | | var target = window, |
| | | var win, target = window, |
| | | url = '&_action=edit-folder&_mbox='+urlencode(folder); |
| | | |
| | | if (path) |
| | | url += '&_path='+urlencode(path); |
| | | |
| | | if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) { |
| | | target = window.frames[this.env.contentframe]; |
| | | if (win = this.get_frame_window(this.env.contentframe)) { |
| | | target = win; |
| | | url += '&_framed=1'; |
| | | } |
| | | |
| | |
| | | } |
| | | }; |
| | | |
| | | // enable/disable buttons for page shifting |
| | | this.set_page_buttons = function() |
| | | { |
| | | this.enable_command('nextpage', 'lastpage', (this.env.pagecount > this.env.current_page)); |
| | | this.enable_command('previouspage', 'firstpage', (this.env.current_page > 1)); |
| | | }; |
| | | |
| | | // set event handlers on registered buttons |
| | | this.init_buttons = function() |
| | | { |
| | |
| | | if (typeof cmd !== 'string') |
| | | continue; |
| | | |
| | | for (var i=0; i< this.buttons[cmd].length; i++) { |
| | | for (var i=0; i<this.buttons[cmd].length; i++) { |
| | | init_button(cmd, this.buttons[cmd][i]); |
| | | } |
| | | } |
| | |
| | | button = a_buttons[n]; |
| | | obj = document.getElementById(button.id); |
| | | |
| | | if (!obj) |
| | | continue; |
| | | |
| | | // get default/passive setting of the button |
| | | if (obj && button.type == 'image' && !button.status) { |
| | | if (button.type == 'image' && !button.status) { |
| | | button.pas = obj._original_src ? obj._original_src : obj.src; |
| | | // respect PNG fix on IE browsers |
| | | if (obj.runtimeStyle && obj.runtimeStyle.filter && obj.runtimeStyle.filter.match(/src=['"]([^'"]+)['"]/)) |
| | | button.pas = RegExp.$1; |
| | | } |
| | | else if (obj && !button.status) |
| | | else if (!button.status) |
| | | button.pas = String(obj.className); |
| | | |
| | | // set image according to button state |
| | | if (obj && button.type == 'image' && button[state]) { |
| | | if (button.type == 'image' && button[state]) { |
| | | button.status = state; |
| | | obj.src = button[state]; |
| | | } |
| | | // set class name according to button state |
| | | else if (obj && button[state] !== undefined) { |
| | | else if (button[state] !== undefined) { |
| | | button.status = state; |
| | | obj.className = button[state]; |
| | | } |
| | | // disable/enable input buttons |
| | | if (obj && button.type=='input') { |
| | | if (button.type == 'input') { |
| | | button.status = state; |
| | | obj.disabled = !state; |
| | | } |
| | |
| | | this.messages = {}; |
| | | }; |
| | | |
| | | // open a jquery UI dialog with the given content |
| | | this.show_popup_dialog = function(html, title) |
| | | { |
| | | // forward call to parent window |
| | | if (this.is_framed()) { |
| | | parent.rcmail.show_popup_dialog(html, title); |
| | | return; |
| | | } |
| | | |
| | | var popup = $('<div class="popup">') |
| | | .html(html) |
| | | .dialog({ |
| | | title: title, |
| | | modal: true, |
| | | resizable: true, |
| | | width: 580, |
| | | close: function(event, ui) { $(this).remove() } |
| | | }); |
| | | |
| | | // resize and center popup |
| | | var win = $(window), w = win.width(), h = win.height(), |
| | | width = popup.width(), height = popup.height(); |
| | | popup.dialog('option', { height: Math.min(h-40, height+50), width: Math.min(w-20, width+50) }) |
| | | .dialog('option', 'position', ['center', 'center']); // only works in a separate call (!?) |
| | | }; |
| | | |
| | | // enable/disable buttons for page shifting |
| | | this.set_page_buttons = function() |
| | | { |
| | | this.enable_command('nextpage', 'lastpage', (this.env.pagecount > this.env.current_page)); |
| | | this.enable_command('previouspage', 'firstpage', (this.env.current_page > 1)); |
| | | }; |
| | | |
| | | // mark a mailbox as selected and set environment variable |
| | | this.select_folder = function(name, prefix, encode) |
| | | { |
| | |
| | | |
| | | // for reordering column array (Konqueror workaround) |
| | | // and for setting some message list global variables |
| | | this.set_message_coltypes = function(coltypes, repl) |
| | | this.set_message_coltypes = function(coltypes, repl, smart_col) |
| | | { |
| | | var list = this.message_list, |
| | | thead = list ? list.list.tHead : null, |
| | |
| | | |
| | | for (n=0, len=this.env.coltypes.length; n<len; n++) { |
| | | col = this.env.coltypes[n]; |
| | | if ((cell = thead.rows[0].cells[n]) && (col=='from' || col=='to')) { |
| | | if ((cell = thead.rows[0].cells[n]) && (col == 'from' || col == 'to' || col == 'fromto')) { |
| | | cell.id = 'rcm'+col; |
| | | $('span,a', cell).text(this.get_label(col == 'fromto' ? smart_col : col)); |
| | | // if we have links for sorting, it's a bit more complicated... |
| | | if (cell.firstChild && cell.firstChild.tagName.toLowerCase()=='a') { |
| | | cell = cell.firstChild; |
| | | cell.onclick = function(){ return rcmail.command('sort', this.__col, this); }; |
| | | cell.__col = col; |
| | | } |
| | | cell.innerHTML = this.get_label(col); |
| | | $('a', cell).click(function(){ |
| | | return rcmail.command('sort', this.id.replace(/^rcm/, ''), this); |
| | | }); |
| | | } |
| | | } |
| | | } |
| | |
| | | if (lock || lock === null) |
| | | this.set_busy(true); |
| | | |
| | | if (this.is_framed()) |
| | | if (this.is_framed()) { |
| | | parent.rcmail.redirect(url, lock); |
| | | else |
| | | } |
| | | else { |
| | | if (this.env.extwin) { |
| | | if (typeof url == 'string') |
| | | url += (url.indexOf('?') < 0 ? '?' : '&') + '_extwin=1'; |
| | | else |
| | | url._extwin = 1; |
| | | } |
| | | this.location_href(url, window); |
| | | } |
| | | }; |
| | | |
| | | this.goto_url = function(action, query, lock) |
| | |
| | | $('<a>').attr('href', url).appendTo(document.body).get(0).click(); |
| | | else |
| | | target.location.href = url; |
| | | |
| | | // reset keep-alive interval |
| | | this.start_keepalive(); |
| | | }; |
| | | |
| | | // send a http request to the server |
| | |
| | | success: function(data){ ref.http_response(data); }, |
| | | error: function(o, status, err) { ref.http_error(o, status, err, lock, action); } |
| | | }); |
| | | |
| | | // reset keep-alive interval |
| | | this.start_keepalive(); |
| | | }; |
| | | |
| | | // send a http POST request to the server |
| | |
| | | // trigger plugin hook |
| | | var result = this.triggerEvent('request'+action, postdata); |
| | | if (result !== undefined) { |
| | | // abort if one the handlers returned false |
| | | // abort if one of the handlers returned false |
| | | if (result === false) |
| | | return false; |
| | | else |
| | |
| | | success: function(data){ ref.http_response(data); }, |
| | | error: function(o, status, err) { ref.http_error(o, status, err, lock, action); } |
| | | }); |
| | | |
| | | // reset keep-alive interval |
| | | this.start_keepalive(); |
| | | }; |
| | | |
| | | // aborts ajax request |
| | |
| | | this.show_contentframe(false); |
| | | // disable commands useless when mailbox is empty |
| | | this.enable_command(this.env.message_commands, 'purge', 'expunge', |
| | | 'select-all', 'select-none', 'sort', 'expand-all', 'expand-unread', 'collapse-all', false); |
| | | 'select-all', 'select-none', 'expand-all', 'expand-unread', 'collapse-all', false); |
| | | } |
| | | if (this.message_list) |
| | | this.triggerEvent('listupdate', { folder:this.env.mailbox, rowcount:this.message_list.rowcount }); |
| | | } |
| | | break; |
| | | |
| | | case 'refresh': |
| | | case 'check-recent': |
| | | case 'getunread': |
| | | case 'search': |
| | | this.env.qsearch = null; |
| | | case 'list': |
| | | if (this.task == 'mail') { |
| | | this.enable_command('show', 'expunge', 'select-all', 'select-none', 'sort', (this.env.messagecount > 0)); |
| | | this.enable_command('show', 'expunge', 'select-all', 'select-none', (this.env.messagecount > 0)); |
| | | this.enable_command('purge', this.purge_mailbox_test()); |
| | | this.enable_command('expand-all', 'expand-unread', 'collapse-all', this.env.threading && this.env.messagecount); |
| | | |
| | |
| | | |
| | | this.triggerEvent('responseafter', {response: response}); |
| | | this.triggerEvent('responseafter'+response.action, {response: response}); |
| | | |
| | | // reset keep-alive interval |
| | | this.start_keepalive(); |
| | | }; |
| | | |
| | | // handle HTTP request errors |
| | |
| | | this.set_busy(false, null, lock); |
| | | request.abort(); |
| | | |
| | | // don't display error message on page unload (#1488547) |
| | | if (this.unload) |
| | | return; |
| | | |
| | | if (request.status && errmsg) |
| | | this.display_message(this.get_label('servererror') + ' (' + errmsg + ')', 'error'); |
| | | else if (status == 'timeout') |
| | |
| | | else if (request.status == 0 && status != 'abort') |
| | | this.display_message(this.get_label('servererror') + ' (No connection)', 'error'); |
| | | |
| | | // redirect to url specified in location header if not empty |
| | | var location_url = request.getResponseHeader("Location"); |
| | | if (location_url) |
| | | this.redirect(location_url); |
| | | |
| | | // re-send keep-alive requests after 30 seconds |
| | | if (action == 'keep-alive') |
| | | setTimeout(function(){ ref.keep_alive(); }, 30000); |
| | | else if (action == 'check-recent') |
| | | setTimeout(function(){ ref.check_for_recent(false); }, 30000); |
| | | setTimeout(function(){ ref.keep_alive(); ref.start_keepalive(); }, 30000); |
| | | }; |
| | | |
| | | // post the given form to a hidden iframe |
| | |
| | | // have to do it this way for IE |
| | | // otherwise the form will be posted to a new window |
| | | if (document.all) { |
| | | var html = '<iframe name="'+frame_name+'" src="program/blank.gif" style="width:0;height:0;visibility:hidden;"></iframe>'; |
| | | var html = '<iframe name="'+frame_name+'" src="program/resources/blank.gif" style="width:0;height:0;visibility:hidden;"></iframe>'; |
| | | document.body.insertAdjacentHTML('BeforeEnd', html); |
| | | } |
| | | else { // for standards-compilant browsers |
| | |
| | | // prepare multipart form data composition |
| | | var files = e.target.files || e.dataTransfer.files, |
| | | formdata = window.FormData ? new FormData() : null, |
| | | fieldname = this.env.filedrop.fieldname || '_file', |
| | | fieldname = (this.env.filedrop.fieldname || '_file') + (this.env.filedrop.single ? '' : '[]'), |
| | | boundary = '------multipartformboundary' + (new Date).getTime(), |
| | | dashdash = '--', crlf = '\r\n', |
| | | multipart = dashdash + boundary + crlf; |
| | |
| | | content = '<span>' + (multiple ? ref.get_label('uploadingmany') : files[0].name) + '</span>'; |
| | | |
| | | // add to attachments list |
| | | ref.add2attachment_list(ts, { name:'', html:content, classname:'uploading', complete:false }); |
| | | if (!ref.add2attachment_list(ts, { name:'', html:content, classname:'uploading', complete:false })) |
| | | ref.file_upload_id = ref.set_busy(true, 'uploading'); |
| | | |
| | | // complete multipart content and post request |
| | | multipart += dashdash + boundary + dashdash + crlf; |
| | |
| | | $.ajax({ |
| | | type: 'POST', |
| | | dataType: 'json', |
| | | url: ref.url(ref.env.filedrop.action||'upload', { _id:ref.env.compose_id||'', _uploadid:ts, _remote:1 }), |
| | | 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, |
| | | data: formdata || multipart, |
| | | headers: {'X-Roundcube-Request': ref.env.request_token}, |
| | | beforeSend: function(xhr, s) { if (!formdata && xhr.sendAsBinary) xhr.send = xhr.sendAsBinary; }, |
| | | success: function(data){ ref.http_response(data); }, |
| | | error: function(o, status, err) { ref.http_error(o, status, err, null, 'attachment'); } |
| | |
| | | |
| | | // get contents of all dropped files |
| | | var last = this.env.filedrop.single ? 0 : files.length - 1; |
| | | for (var i=0, f; i <= last && (f = files[i]); i++) { |
| | | for (var j=0, i=0, f; j <= last && (f = files[i]); i++) { |
| | | if (!f.name) f.name = f.fileName; |
| | | if (!f.size) f.size = f.fileSize; |
| | | if (!f.type) f.type = 'application/octet-stream'; |
| | |
| | | |
| | | // do it the easy way with FormData (FF 4+, Chrome 5+, Safari 5+) |
| | | if (formdata) { |
| | | formdata.append(fieldname + '[]', f); |
| | | if (i == last) |
| | | formdata.append(fieldname, f); |
| | | if (j == last) |
| | | return submit_data(); |
| | | } |
| | | // use FileReader supporetd by Firefox 3.6 |
| | |
| | | var reader = new FileReader(); |
| | | |
| | | // closure to pass file properties to async callback function |
| | | reader.onload = (function(file, i) { |
| | | reader.onload = (function(file, j) { |
| | | return function(e) { |
| | | multipart += 'Content-Disposition: form-data; name="' + fieldname + '[]"'; |
| | | multipart += 'Content-Disposition: form-data; name="' + fieldname + '"'; |
| | | 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 += dashdash + boundary + crlf; |
| | | |
| | | if (i == last) // we're done, submit the data |
| | | if (j == last) // we're done, submit the data |
| | | return submit_data(); |
| | | } |
| | | })(f,i); |
| | | })(f,j); |
| | | reader.readAsBinaryString(f); |
| | | } |
| | | // Firefox 3 |
| | | else if (f.getAsBinary) { |
| | | multipart += 'Content-Disposition: form-data; name="' + fieldname + '[]"'; |
| | | multipart += 'Content-Disposition: form-data; name="' + fieldname + '"'; |
| | | multipart += '; filename="' + (f.name_bin || f.name) + '"' + crlf; |
| | | multipart += 'Content-Length: ' + f.size + crlf; |
| | | multipart += 'Content-Type: ' + f.type + crlf + crlf; |
| | | multipart += f.getAsBinary() + crlf; |
| | | multipart += dashdash + boundary +crlf; |
| | | |
| | | if (i == last) |
| | | if (j == last) |
| | | return submit_data(); |
| | | } |
| | | |
| | | j++; |
| | | } |
| | | }; |
| | | |
| | | |
| | | // starts interval for keep-alive/check-recent signal |
| | | // starts interval for keep-alive signal |
| | | this.start_keepalive = function() |
| | | { |
| | | if (!this.env.keep_alive || this.env.framed) |
| | | if (!this.env.session_lifetime || this.env.framed || this.env.extwin || this.task == 'login' || this.env.action == 'print') |
| | | return; |
| | | |
| | | if (this._int) |
| | | clearInterval(this._int); |
| | | if (this._keepalive) |
| | | clearInterval(this._keepalive); |
| | | |
| | | if (this.task == 'mail' && this.gui_objects.mailboxlist) |
| | | this._int = setInterval(function(){ ref.check_for_recent(false); }, this.env.keep_alive * 1000); |
| | | else if (this.task != 'login' && this.env.action != 'print') |
| | | this._int = setInterval(function(){ ref.keep_alive(); }, this.env.keep_alive * 1000); |
| | | this._keepalive = setInterval(function(){ ref.keep_alive(); }, this.env.session_lifetime * 0.5 * 1000); |
| | | }; |
| | | |
| | | // starts interval for refresh signal |
| | | this.start_refresh = function() |
| | | { |
| | | if (!this.env.refresh_interval || this.env.framed || this.env.extwin || this.task == 'login' || this.env.action == 'print') |
| | | return; |
| | | |
| | | if (this._refresh) |
| | | clearInterval(this._refresh); |
| | | |
| | | this._refresh = setInterval(function(){ ref.refresh(); }, this.env.refresh_interval * 1000); |
| | | }; |
| | | |
| | | // sends keep-alive signal |
| | |
| | | this.http_request('keep-alive'); |
| | | }; |
| | | |
| | | // sends request to check for recent messages |
| | | this.check_for_recent = function(refresh) |
| | | // sends refresh signal |
| | | this.refresh = function() |
| | | { |
| | | if (this.busy) |
| | | if (this.busy) { |
| | | // try again after 10 seconds |
| | | setTimeout(function(){ ref.refresh(); ref.start_refresh(); }, 10000); |
| | | return; |
| | | |
| | | var lock, url = {_mbox: this.env.mailbox}; |
| | | |
| | | if (refresh) { |
| | | lock = this.set_busy(true, 'checkingmail'); |
| | | url._refresh = 1; |
| | | // reset check-recent interval |
| | | this.start_keepalive(); |
| | | } |
| | | |
| | | if (this.gui_objects.messagelist) |
| | | url._list = 1; |
| | | if (this.gui_objects.quotadisplay) |
| | | url._quota = 1; |
| | | if (this.env.search_request) |
| | | url._search = this.env.search_request; |
| | | var params = {}, lock = this.set_busy(true, 'refreshing'); |
| | | |
| | | this.http_request('check-recent', url, lock); |
| | | if (this.task == 'mail' && this.gui_objects.mailboxlist) |
| | | params = this.check_recent_params(); |
| | | |
| | | // plugins should bind to 'requestrefresh' event to add own params |
| | | this.http_request('refresh', params, lock); |
| | | }; |
| | | |
| | | // returns check-recent request parameters |
| | | this.check_recent_params = function() |
| | | { |
| | | var params = {_mbox: this.env.mailbox}; |
| | | |
| | | if (this.gui_objects.mailboxlist) |
| | | params._folderlist = 1; |
| | | if (this.gui_objects.messagelist) |
| | | params._list = 1; |
| | | if (this.gui_objects.quotadisplay) |
| | | params._quota = 1; |
| | | if (this.env.search_request) |
| | | params._search = this.env.search_request; |
| | | |
| | | return params; |
| | | }; |
| | | |
| | | |
| | |
| | | { |
| | | if (obj.selectionEnd !== undefined) |
| | | return obj.selectionEnd; |
| | | else if (document.selection && document.selection.createRange) { |
| | | |
| | | if (document.selection && document.selection.createRange) { |
| | | var range = document.selection.createRange(); |
| | | if (range.parentElement() != obj) |
| | | return 0; |
| | |
| | | gm.setEndPoint('EndToStart', range); |
| | | var p = gm.text.length; |
| | | |
| | | return p<=obj.value.length ? p : -1; |
| | | return p <= obj.value.length ? p : -1; |
| | | } |
| | | else |
| | | return obj.value.length; |
| | | |
| | | return obj.value.length; |
| | | }; |
| | | |
| | | // moves cursor to specified position |
| | |
| | | |
| | | img.onload = function() { rcmail.env.browser_capabilities.tif = 1; }; |
| | | img.onerror = function() { rcmail.env.browser_capabilities.tif = 0; }; |
| | | img.src = 'program/blank.tif'; |
| | | img.src = 'program/resources/blank.tif'; |
| | | }; |
| | | |
| | | this.pdf_support_check = function() |
| | |
| | | return 0; |
| | | }; |
| | | |
| | | // Cookie setter |
| | | this.set_cookie = function(name, value, expires) |
| | | { |
| | | setCookie(name, value, expires, this.env.cookie_path, this.env.cookie_domain, this.env.cookie_secure); |
| | | } |
| | | |
| | | } // end object rcube_webmail |
| | | |
| | | |
| | |
| | | } |
| | | }; |
| | | |
| | | rcube_webmail.prototype.get_cookie = getCookie; |
| | | |
| | | // copy event engine prototype |
| | | rcube_webmail.prototype.addEventListener = rcube_event_engine.prototype.addEventListener; |
| | | rcube_webmail.prototype.removeEventListener = rcube_event_engine.prototype.removeEventListener; |