| | |
| | | +-----------------------------------------------------------------------+ |
| | | | Requires: jquery.js, common.js, list.js | |
| | | +-----------------------------------------------------------------------+ |
| | | |
| | | $Id$ |
| | | */ |
| | | |
| | | function rcube_webmail() |
| | |
| | | |
| | | // set jQuery ajax options |
| | | $.ajaxSetup({ |
| | | cache:false, |
| | | error:function(request, status, err){ ref.http_error(request, status, err); }, |
| | | beforeSend:function(xmlhttp){ xmlhttp.setRequestHeader('X-Roundcube-Request', ref.env.request_token); } |
| | | cache: false, |
| | | timeout: this.env.request_timeout * 1000, |
| | | error: function(request, status, err){ ref.http_error(request, status, err); }, |
| | | beforeSend: function(xmlhttp){ xmlhttp.setRequestHeader('X-Roundcube-Request', ref.env.request_token); } |
| | | }); |
| | | |
| | | // set environment variable(s) |
| | |
| | | |
| | | this.env.message_commands = ['show', 'reply', 'reply-all', 'reply-list', 'forward', |
| | | 'moveto', 'copy', 'delete', 'open', 'mark', 'edit', 'viewsource', 'download', |
| | | 'print', 'load-attachment', 'load-headers', 'forward-attachment']; |
| | | 'print', 'load-attachment', 'show-headers', 'hide-headers', 'forward-attachment']; |
| | | |
| | | if (this.env.action == 'show' || this.env.action == 'preview') { |
| | | this.enable_command(this.env.message_commands, this.env.uid); |
| | |
| | | // show printing dialog |
| | | else if (this.env.action == 'print' && this.env.uid) |
| | | if (bw.safari) |
| | | window.setTimeout('window.print()', 10); |
| | | setTimeout('window.print()', 10); |
| | | else |
| | | window.print(); |
| | | |
| | |
| | | } |
| | | this.http_post(postact, postdata); |
| | | } |
| | | |
| | | // detect browser capabilities |
| | | if (!this.is_framed()) |
| | | this.browser_capabilities_check(); |
| | | |
| | | break; |
| | | |
| | |
| | | if (this.gui_objects.folderlist) |
| | | 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)) { |
| | | $(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'); }) |
| | | .get(0).addEventListener('drop', function(e){ return ref.file_dropped(e); }, false); |
| | | } |
| | | |
| | | // trigger init event hook |
| | | this.triggerEvent('init', { task:this.task, action:this.env.action }); |
| | | |
| | |
| | | this.list_contacts(props); |
| | | break; |
| | | |
| | | case 'load-headers': |
| | | this.load_headers(obj); |
| | | break; |
| | | |
| | | case 'sort': |
| | | var sort_order, sort_col = props; |
| | | |
| | |
| | | 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='+urlencode(this.env.mailbox), true); |
| | | this.goto_url('compose', { _draft_uid: uid, _mbox: this.env.mailbox }, true); |
| | | else |
| | | this.show_message(uid); |
| | | } |
| | |
| | | break; |
| | | |
| | | case 'edit': |
| | | if (this.task=='addressbook' && (cid = this.get_single_cid())) |
| | | if (this.task == 'addressbook' && (cid = this.get_single_cid())) |
| | | this.load_contact(cid, 'edit'); |
| | | else if (this.task=='settings' && props) |
| | | else if (this.task == 'settings' && props) |
| | | this.load_identity(props, 'edit-identity'); |
| | | else if (this.task=='mail' && (cid = this.get_single_uid())) { |
| | | url = (this.env.mailbox == this.env.drafts_mailbox) ? '_draft_uid=' : '_uid='; |
| | | this.goto_url('compose', url+cid+'&_mbox='+urlencode(this.env.mailbox), true); |
| | | 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); |
| | | } |
| | | break; |
| | | |
| | |
| | | |
| | | case 'always-load': |
| | | if (this.env.uid && this.env.sender) { |
| | | this.add_contact(urlencode(this.env.sender)); |
| | | window.setTimeout(function(){ ref.command('load-images'); }, 300); |
| | | this.add_contact(this.env.sender); |
| | | setTimeout(function(){ ref.command('load-images'); }, 300); |
| | | break; |
| | | } |
| | | |
| | |
| | | qstring += '&_safe=1'; |
| | | this.attachment_win = window.open(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1', 'rcubemailattachment'); |
| | | if (this.attachment_win) { |
| | | window.setTimeout(function(){ ref.attachment_win.focus(); }, 10); |
| | | setTimeout(function(){ ref.attachment_win.focus(); }, 10); |
| | | break; |
| | | } |
| | | } |
| | |
| | | break; |
| | | |
| | | case 'savedraft': |
| | | var form = this.gui_objects.messageform, msgid; |
| | | |
| | | // Reset the auto-save timer |
| | | self.clearTimeout(this.save_timer); |
| | | clearTimeout(this.save_timer); |
| | | |
| | | if (!this.gui_objects.messageform) |
| | | // saving Drafts is disabled |
| | | if (!form) |
| | | break; |
| | | |
| | | // if saving Drafts is disabled in main.inc.php |
| | | // or if compose form did not change |
| | | if (!this.env.drafts_mailbox || this.cmp_hash == this.compose_field_hash()) |
| | | // compose form did not change |
| | | if (this.cmp_hash == this.compose_field_hash()) { |
| | | this.auto_save_start(); |
| | | break; |
| | | } |
| | | |
| | | var form = this.gui_objects.messageform, |
| | | msgid = this.set_busy(true, 'savingmessage'); |
| | | // re-set keep-alive timeout |
| | | this.start_keepalive(); |
| | | |
| | | msgid = this.set_busy(true, 'savingmessage'); |
| | | |
| | | form.target = "savetarget"; |
| | | form._draft.value = '1'; |
| | |
| | | break; |
| | | |
| | | // Reset the auto-save timer |
| | | self.clearTimeout(this.save_timer); |
| | | clearTimeout(this.save_timer); |
| | | |
| | | // all checks passed, send message |
| | | var lang = this.spellcheck_lang(), |
| | |
| | | form.action = this.add_url(form.action, '_lang', lang); |
| | | form.submit(); |
| | | |
| | | // clear timeout (sending could take longer) |
| | | clearTimeout(this.request_timer); |
| | | break; |
| | | |
| | | case 'send-attachment': |
| | | // Reset the auto-save timer |
| | | self.clearTimeout(this.save_timer); |
| | | clearTimeout(this.save_timer); |
| | | |
| | | this.upload_file(props || this.gui_objects.uploadform); |
| | | break; |
| | |
| | | case 'reply-list': |
| | | case 'reply': |
| | | if (uid = this.get_single_uid()) { |
| | | url = '_reply_uid='+uid+'&_mbox='+urlencode(this.env.mailbox); |
| | | url = {_reply_uid: uid, _mbox: this.env.mailbox}; |
| | | if (command == 'reply-all') |
| | | // do reply-list, when list is detected and popup menu wasn't used |
| | | url += '&_all=' + (!props && this.commands['reply-list'] ? 'list' : 'all'); |
| | | 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); |
| | | } |
| | |
| | | case 'forward-attachment': |
| | | case 'forward': |
| | | if (uid = this.get_single_uid()) { |
| | | url = '_forward_uid='+uid+'&_mbox='+urlencode(this.env.mailbox); |
| | | url = { _forward_uid: uid, _mbox: this.env.mailbox }; |
| | | if (command == 'forward-attachment' || (!props && this.env.forward_attachment)) |
| | | url += '&_attachment=1'; |
| | | url._attachment = 1; |
| | | this.goto_url('compose', url, true); |
| | | } |
| | | break; |
| | |
| | | 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.printwin) { |
| | | window.setTimeout(function(){ ref.printwin.focus(); }, 20); |
| | | setTimeout(function(){ ref.printwin.focus(); }, 20); |
| | | if (this.env.action != 'show') |
| | | this.mark_message('read', uid); |
| | | } |
| | |
| | | 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) |
| | | window.setTimeout(function(){ ref.sourcewin.focus(); }, 20); |
| | | setTimeout(function(){ ref.sourcewin.focus(); }, 20); |
| | | } |
| | | break; |
| | | |
| | | case 'download': |
| | | if (uid = this.get_single_uid()) |
| | | this.goto_url('viewsource', '&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+'&_save=1'); |
| | | this.goto_url('viewsource', { _uid: uid, _mbox: this.env.mailbox, _save: 1 }); |
| | | break; |
| | | |
| | | // quicksearch |
| | |
| | | |
| | | case 'export': |
| | | if (this.contact_list.rowcount > 0) { |
| | | this.goto_url('export', { _source:this.env.source, _gid:this.env.group, _search:this.env.search_request }); |
| | | this.goto_url('export', { _source: this.env.source, _gid: this.env.group, _search: this.env.search_request }); |
| | | } |
| | | break; |
| | | |
| | |
| | | default: |
| | | var func = command.replace(/-/g, '_'); |
| | | if (this[func] && typeof this[func] === 'function') { |
| | | ret = this[func](props); |
| | | ret = this[func](props, obj); |
| | | } |
| | | break; |
| | | } |
| | |
| | | if (this.gui_objects.editform) |
| | | this.lock_form(this.gui_objects.editform, a); |
| | | |
| | | // clear pending timer |
| | | if (this.request_timer) |
| | | clearTimeout(this.request_timer); |
| | | |
| | | // set timer for requests |
| | | if (a && this.env.request_timeout) |
| | | this.request_timer = window.setTimeout(function(){ ref.request_timed_out(); }, this.env.request_timeout * 1000); |
| | | |
| | | return id; |
| | | }; |
| | | |
| | |
| | | return url.replace(/_task=[a-z]+/, '_task='+task); |
| | | }; |
| | | |
| | | // called when a request timed out |
| | | this.request_timed_out = function() |
| | | { |
| | | this.set_busy(false); |
| | | this.display_message('Request timed out!', 'error'); |
| | | }; |
| | | |
| | | this.reload = function(delay) |
| | | { |
| | | if (this.is_framed()) |
| | | parent.rcmail.reload(delay); |
| | | else if (delay) |
| | | window.setTimeout(function(){ rcmail.reload(); }, delay); |
| | | setTimeout(function(){ rcmail.reload(); }, delay); |
| | | else if (window.location) |
| | | location.href = this.env.comm_path + (this.env.action ? '&_action='+this.env.action : ''); |
| | | }; |
| | |
| | | this.env.last_folder_target = null; |
| | | |
| | | if (this.folder_auto_timer) { |
| | | window.clearTimeout(this.folder_auto_timer); |
| | | clearTimeout(this.folder_auto_timer); |
| | | this.folder_auto_timer = null; |
| | | this.folder_auto_expand = null; |
| | | } |
| | |
| | | // if the folder is collapsed, expand it after 1sec and restart the drag & drop process. |
| | | if (div.hasClass('collapsed')) { |
| | | if (this.folder_auto_timer) |
| | | window.clearTimeout(this.folder_auto_timer); |
| | | clearTimeout(this.folder_auto_timer); |
| | | |
| | | this.folder_auto_expand = this.env.mailboxes[k].id; |
| | | this.folder_auto_timer = window.setTimeout(function() { |
| | | this.folder_auto_timer = setTimeout(function() { |
| | | rcmail.command('collapse-folder', rcmail.folder_auto_expand); |
| | | rcmail.drag_start(null); |
| | | }, 1000); |
| | | } else if (this.folder_auto_timer) { |
| | | window.clearTimeout(this.folder_auto_timer); |
| | | clearTimeout(this.folder_auto_timer); |
| | | this.folder_auto_timer = null; |
| | | this.folder_auto_expand = null; |
| | | } |
| | |
| | | |
| | | // start timer for message preview (wait for double click) |
| | | if (selected && this.env.contentframe && !list.multi_selecting && !this.dummy_select) |
| | | this.preview_timer = window.setTimeout(function(){ ref.msglist_get_preview(); }, 200); |
| | | this.preview_timer = setTimeout(function(){ ref.msglist_get_preview(); }, 200); |
| | | else if (this.env.contentframe) |
| | | this.show_contentframe(false); |
| | | }; |
| | |
| | | clearTimeout(this.preview_timer); |
| | | if (this.preview_read_timer) |
| | | clearTimeout(this.preview_read_timer); |
| | | this.preview_timer = window.setTimeout(function(){ ref.msglist_get_preview(); }, 200); |
| | | 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='+urlencode(this.env.mailbox), true); |
| | | this.goto_url('compose', { _draft_uid: uid, _mbox: this.env.mailbox }, true); |
| | | else if (uid) |
| | | this.show_message(uid, false, false); |
| | | }; |
| | |
| | | else if (c == 'threads') |
| | | html = expando; |
| | | else if (c == 'subject') { |
| | | if (bw.ie) |
| | | if (bw.ie) { |
| | | col.onmouseover = function() { rcube_webmail.long_subject_title_ie(this, message.depth+1); }; |
| | | if (bw.ie8) |
| | | tree = '<span></span>' + tree; // #1487821 |
| | | } |
| | | html = tree + cols[c]; |
| | | } |
| | | else if (c == 'priority') { |
| | |
| | | if (this.env.search_request) |
| | | url += '&_search='+this.env.search_request; |
| | | |
| | | if (action == 'preview' && String(target.location.href).indexOf(url) >= 0) |
| | | // add browser capabilities, so we can properly handle attachments |
| | | url += '&_caps='+urlencode(this.browser_capabilities()); |
| | | |
| | | if (preview && String(target.location.href).indexOf(url) >= 0) |
| | | this.show_contentframe(true); |
| | | else { |
| | | this.location_href(this.env.comm_path+url, target, true); |
| | | |
| | | // mark as read and change mbox unread counter |
| | | if (action == 'preview' && this.message_list && this.message_list.rows[id] && this.message_list.rows[id].unread && this.env.preview_pane_mark_read >= 0) { |
| | | this.preview_read_timer = window.setTimeout(function() { |
| | | if (preview && this.message_list && this.message_list.rows[id] && this.message_list.rows[id].unread && this.env.preview_pane_mark_read >= 0) { |
| | | this.preview_read_timer = setTimeout(function() { |
| | | ref.set_message(id, 'unread', false); |
| | | ref.update_thread_root(id, 'read'); |
| | | if (ref.env.unread_counts[ref.env.mailbox]) { |
| | |
| | | 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' && $("input[name='_draft_saveid']").val() == '') { |
| | | if (input_from.prop('type') == 'select-one') { |
| | | this.change_identity(input_from[0]); |
| | | } |
| | | } |
| | |
| | | tinyMCE.execCommand('mceAddControl', false, props.id); |
| | | |
| | | if (this.env.default_font) |
| | | window.setTimeout(function() { |
| | | setTimeout(function() { |
| | | $(tinyMCE.get(props.id).getBody()).css('font-family', rcmail.env.default_font); |
| | | }, 500); |
| | | } |
| | |
| | | this.auto_save_start = function() |
| | | { |
| | | if (this.env.draft_autosave) |
| | | this.save_timer = self.setTimeout(function(){ ref.command("savedraft"); }, this.env.draft_autosave * 1000); |
| | | this.save_timer = setTimeout(function(){ ref.command("savedraft"); }, this.env.draft_autosave * 1000); |
| | | |
| | | // Unlock interface now that saving is complete |
| | | this.busy = false; |
| | |
| | | this.compose_field_hash = function(save) |
| | | { |
| | | // check input fields |
| | | var ed, str = '', |
| | | value_to = $("[name='_to']").val(), |
| | | value_cc = $("[name='_cc']").val(), |
| | | value_bcc = $("[name='_bcc']").val(), |
| | | value_subject = $("[name='_subject']").val(); |
| | | var ed, i, val, str = '', hash_fields = ['to', 'cc', 'bcc', 'subject']; |
| | | |
| | | if (value_to) |
| | | str += value_to+':'; |
| | | if (value_cc) |
| | | str += value_cc+':'; |
| | | if (value_bcc) |
| | | str += value_bcc+':'; |
| | | if (value_subject) |
| | | str += value_subject+':'; |
| | | for (i=0; i<hash_fields.length; i++) |
| | | if (val = $('[name="_' + hash_fields[i] + '"]').val()) |
| | | str += val + ':'; |
| | | |
| | | if (window.tinyMCE && (ed = tinyMCE.get(this.env.composebody))) |
| | | str += ed.getContent(); |
| | |
| | | var content = '<span>' + this.get_label('uploading' + (files > 1 ? 'many' : '')) + '</span>', |
| | | ts = frame_name.replace(/^rcmupload/, ''); |
| | | |
| | | if (this.env.loadingicon) |
| | | content = '<img src="'+this.env.loadingicon+'" alt="" class="uploading" />'+content; |
| | | content = '<a title="'+this.get_label('cancel')+'" onclick="return rcmail.cancel_attachment_upload(\''+ts+'\', \''+frame_name+'\');" href="#cancelupload" class="cancelupload">' |
| | | + (this.env.cancelicon ? '<img src="'+this.env.cancelicon+'" alt="" />' : this.get_label('cancel')) + '</a>' + content; |
| | | |
| | | this.add2attachment_list(ts, { name:'', html:content, classname:'uploading', complete:false }); |
| | | this.add2attachment_list(ts, { name:'', html:content, classname:'uploading', frame:frame_name, complete:false }); |
| | | |
| | | // upload progress support |
| | | if (this.env.upload_progress_time) { |
| | |
| | | { |
| | | if (!this.gui_objects.attachmentlist) |
| | | return false; |
| | | |
| | | if (!att.complete && ref.env.loadingicon) |
| | | att.html = '<img src="'+ref.env.loadingicon+'" alt="" class="uploading" />' + att.html; |
| | | |
| | | if (!att.complete && att.frame) |
| | | 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); |
| | | |
| | |
| | | |
| | | this.upload_progress_start = function(action, name) |
| | | { |
| | | window.setTimeout(function() { rcmail.http_request(action, {_progress: name}); }, |
| | | setTimeout(function() { rcmail.http_request(action, {_progress: name}); }, |
| | | this.env.upload_progress_time * 1000); |
| | | }; |
| | | |
| | |
| | | { |
| | | this.display_message(msg, type); |
| | | // before redirect we need to wait some time for Chrome (#1486177) |
| | | window.setTimeout(function(){ ref.list_mailbox(); }, 500); |
| | | setTimeout(function(){ ref.list_mailbox(); }, 500); |
| | | }; |
| | | |
| | | |
| | |
| | | case 37: // left |
| | | case 39: // right |
| | | if (mod != SHIFT_KEY) |
| | | return; |
| | | return; |
| | | } |
| | | |
| | | // start timer |
| | | this.ksearch_timer = window.setTimeout(function(){ ref.ksearch_get_results(props); }, 200); |
| | | this.ksearch_timer = setTimeout(function(){ ref.ksearch_get_results(props); }, 200); |
| | | this.ksearch_input = obj; |
| | | |
| | | return true; |
| | |
| | | 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) && this.env.contacts && !this.env.contacts.length) |
| | | if (old_value && old_value.length && q.indexOf(old_value) == 0 && (!ac || ac.num <= 0) && this.env.contacts && !this.env.contacts.length) |
| | | return; |
| | | |
| | | var i, lock, source, xhr, reqid = new Date().getTime(), |
| | |
| | | |
| | | for (i=0; i<threads; i++) { |
| | | source = this.ksearch_data.sources.shift(); |
| | | if (threads > 1 && source === null) |
| | | if (threads > 1 && source === undefined) |
| | | break; |
| | | |
| | | post_data._source = source ? source : ''; |
| | |
| | | source = this.env.source ? this.env.address_sources[this.env.source] : null; |
| | | |
| | | if (id = list.get_single_selection()) |
| | | this.preview_timer = window.setTimeout(function(){ ref.load_contact(id, 'show'); }, 200); |
| | | this.preview_timer = setTimeout(function(){ ref.load_contact(id, 'show'); }, 200); |
| | | else if (this.env.contentframe) |
| | | this.show_contentframe(false); |
| | | |
| | |
| | | if (colprop.type == 'date' && $.datepicker) |
| | | input.datepicker(); |
| | | } |
| | | else if (colprop.type == 'textarea') { |
| | | input = $('<textarea>') |
| | | .addClass('ff_'+col) |
| | | .attr({ name: '_'+col+name_suffix, cols:colprop.size, rows:colprop.rows }) |
| | | .appendTo(cell); |
| | | |
| | | this.init_edit_field(col, input); |
| | | } |
| | | else if (colprop.type == 'composite') { |
| | | var childcol, cp, first, templ, cols = [], suffices = []; |
| | | // read template for composite field order |
| | |
| | | |
| | | // submit request with appended token |
| | | if (confirm(this.get_label('deleteidentityconfirm'))) |
| | | this.goto_url('delete-identity', '_iid='+id+'&_token='+this.env.request_token, true); |
| | | this.goto_url('delete-identity', { _iid: id, _token: this.env.request_token }, true); |
| | | |
| | | return true; |
| | | }; |
| | |
| | | } |
| | | // add element and set timeout |
| | | this.messages[key].elements.push(id); |
| | | window.setTimeout(function() { ref.hide_message(id, type == 'loading'); }, timeout); |
| | | setTimeout(function() { ref.hide_message(id, type == 'loading'); }, timeout); |
| | | return id; |
| | | } |
| | | |
| | |
| | | this.triggerEvent('message', { message:msg, type:type, timeout:timeout, object:obj }); |
| | | |
| | | if (timeout > 0) |
| | | window.setTimeout(function() { ref.hide_message(id, type == 'loading'); }, timeout); |
| | | setTimeout(function() { ref.hide_message(id, type == 'loading'); }, timeout); |
| | | return id; |
| | | }; |
| | | |
| | |
| | | }; |
| | | |
| | | // display all-headers row and fetch raw message headers |
| | | this.load_headers = function(elem) |
| | | this.show_headers = function(props, elem) |
| | | { |
| | | if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box || !this.env.uid) |
| | | return; |
| | | |
| | | $(elem).removeClass('show-headers').addClass('hide-headers'); |
| | | $(this.gui_objects.all_headers_row).show(); |
| | | elem.onclick = function() { rcmail.hide_headers(elem); }; |
| | | elem.onclick = function() { rcmail.command('hide-headers', '', elem); }; |
| | | |
| | | // fetch headers only once |
| | | if (!this.gui_objects.all_headers_box.innerHTML) { |
| | |
| | | }; |
| | | |
| | | // hide all-headers row |
| | | this.hide_headers = function(elem) |
| | | this.hide_headers = function(props, elem) |
| | | { |
| | | if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box) |
| | | return; |
| | | |
| | | $(elem).removeClass('hide-headers').addClass('show-headers'); |
| | | $(this.gui_objects.all_headers_row).hide(); |
| | | elem.onclick = function() { rcmail.load_headers(elem); }; |
| | | elem.onclick = function() { rcmail.command('show-headers', '', elem); }; |
| | | }; |
| | | |
| | | |
| | |
| | | return $.ajax({ |
| | | type: 'GET', url: url, data: { _unlock:(lock?lock:0) }, dataType: 'json', |
| | | success: function(data){ ref.http_response(data); }, |
| | | error: function(o, status, err) { rcmail.http_error(o, status, err, lock); } |
| | | error: function(o, status, err) { ref.http_error(o, status, err, lock, action); } |
| | | }); |
| | | }; |
| | | |
| | |
| | | return $.ajax({ |
| | | type: 'POST', url: url, data: postdata, dataType: 'json', |
| | | success: function(data){ ref.http_response(data); }, |
| | | error: function(o, status, err) { rcmail.http_error(o, status, err, lock); } |
| | | error: function(o, status, err) { ref.http_error(o, status, err, lock, action); } |
| | | }); |
| | | }; |
| | | |
| | |
| | | }; |
| | | |
| | | // handle HTTP request errors |
| | | this.http_error = function(request, status, err, lock) |
| | | this.http_error = function(request, status, err, lock, action) |
| | | { |
| | | var errmsg = request.statusText; |
| | | |
| | |
| | | |
| | | if (request.status && errmsg) |
| | | this.display_message(this.get_label('servererror') + ' (' + errmsg + ')', 'error'); |
| | | else if (status == 'timeout') |
| | | this.display_message(this.get_label('requesttimedout'), 'error'); |
| | | else if (request.status == 0 && status != 'abort') |
| | | this.display_message(this.get_label('servererror') + ' (No connection)', 'error'); |
| | | |
| | | // 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); |
| | | }; |
| | | |
| | | // post the given form to a hidden iframe |
| | |
| | | return frame_name; |
| | | }; |
| | | |
| | | // html5 file-drop API |
| | | this.document_drag_hover = function(e, over) |
| | | { |
| | | e.preventDefault(); |
| | | $(ref.gui_objects.filedrop)[(over?'addClass':'removeClass')]('active'); |
| | | }; |
| | | |
| | | this.file_drag_hover = function(e, over) |
| | | { |
| | | e.preventDefault(); |
| | | e.stopPropagation(); |
| | | $(ref.gui_objects.filedrop)[(over?'addClass':'removeClass')]('hover'); |
| | | }; |
| | | |
| | | // handler when files are dropped to a designated area. |
| | | // compose a multipart form data and submit it to the server |
| | | this.file_dropped = function(e) |
| | | { |
| | | // abort event and reset UI |
| | | this.file_drag_hover(e, false); |
| | | |
| | | // 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', |
| | | boundary = '------multipartformboundary' + (new Date).getTime(), |
| | | dashdash = '--', crlf = '\r\n', |
| | | multipart = dashdash + boundary + crlf; |
| | | |
| | | if (!files || !files.length) |
| | | return; |
| | | |
| | | // inline function to submit the files to the server |
| | | var submit_data = function() { |
| | | var multiple = files.length > 1, |
| | | ts = new Date().getTime(), |
| | | 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 }); |
| | | |
| | | // 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 }), |
| | | contentType: formdata ? false : 'multipart/form-data; boundary=' + boundary, |
| | | processData: false, |
| | | data: formdata || multipart, |
| | | 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++) { |
| | | if (!f.name) f.name = f.fileName; |
| | | if (!f.size) f.size = f.fileSize; |
| | | if (!f.type) f.type = 'application/octet-stream'; |
| | | |
| | | // binary encode file name |
| | | if (!formdata && /[^\x20-\x7E]/.test(f.name)) |
| | | f.name_bin = unescape(encodeURIComponent(f.name)); |
| | | |
| | | if (this.env.filedrop.filter && !f.type.match(new RegExp(this.env.filedrop.filter))) { |
| | | // TODO: show message to user |
| | | continue; |
| | | } |
| | | |
| | | // the easy way with FormData (FF4+, Chrome, Safari) |
| | | if (formdata) { |
| | | formdata.append(fieldname + '[]', f); |
| | | if (i == last) |
| | | return submit_data(); |
| | | } |
| | | // use FileReader supporetd by Firefox 3.6 |
| | | else if (window.FileReader) { |
| | | var reader = new FileReader(); |
| | | |
| | | // closure to pass file properties to async callback function |
| | | reader.onload = (function(file, i) { |
| | | return function(e) { |
| | | 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 |
| | | return submit_data(); |
| | | } |
| | | })(f,i); |
| | | reader.readAsBinaryString(f); |
| | | } |
| | | // Firefox 3 |
| | | else if (f.getAsBinary) { |
| | | 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) |
| | | return submit_data(); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | |
| | | // starts interval for keep-alive/check-recent signal |
| | | this.start_keepalive = function() |
| | | { |
| | | if (!this.env.keep_alive || this.env.framed) |
| | | return; |
| | | |
| | | if (this._int) |
| | | clearInterval(this._int); |
| | | |
| | | if (this.env.keep_alive && !this.env.framed && this.task == 'mail' && this.gui_objects.mailboxlist) |
| | | 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.env.keep_alive && !this.env.framed && this.task != 'login' && this.env.action != 'print') |
| | | else if (this.task != 'login' && this.env.action != 'print') |
| | | this._int = setInterval(function(){ ref.keep_alive(); }, this.env.keep_alive * 1000); |
| | | }; |
| | | |
| | |
| | | return obj.selectionEnd; |
| | | else if (document.selection && document.selection.createRange) { |
| | | var range = document.selection.createRange(); |
| | | if (range.parentElement()!=obj) |
| | | if (range.parentElement() != obj) |
| | | return 0; |
| | | |
| | | var gm = range.duplicate(); |
| | |
| | | $(elem).click(function() { rcmail.register_protocol_handler(name); return false; }); |
| | | }; |
| | | |
| | | // Checks browser capabilities eg. PDF support, TIF support |
| | | this.browser_capabilities_check = function() |
| | | { |
| | | if (!this.env.browser_capabilities) |
| | | this.env.browser_capabilities = {}; |
| | | |
| | | if (this.env.browser_capabilities.pdf === undefined) |
| | | this.env.browser_capabilities.pdf = this.pdf_support_check(); |
| | | |
| | | if (this.env.browser_capabilities.flash === undefined) |
| | | this.env.browser_capabilities.flash = this.flash_support_check(); |
| | | |
| | | if (this.env.browser_capabilities.tif === undefined) |
| | | this.tif_support_check(); |
| | | }; |
| | | |
| | | // Returns browser capabilities string |
| | | this.browser_capabilities = function() |
| | | { |
| | | if (!this.env.browser_capabilities) |
| | | return ''; |
| | | |
| | | var n, ret = []; |
| | | |
| | | for (n in this.env.browser_capabilities) |
| | | ret.push(n + '=' + this.env.browser_capabilities[n]); |
| | | |
| | | return ret.join(); |
| | | }; |
| | | |
| | | this.tif_support_check = function() |
| | | { |
| | | var img = new Image(); |
| | | |
| | | img.onload = function() { rcmail.env.browser_capabilities.tif = 1; }; |
| | | img.onerror = function() { rcmail.env.browser_capabilities.tif = 0; }; |
| | | img.src = 'program/blank.tif'; |
| | | }; |
| | | |
| | | this.pdf_support_check = function() |
| | | { |
| | | var plugin = navigator.mimeTypes ? navigator.mimeTypes["application/pdf"] : {}, |
| | | plugins = navigator.plugins, |
| | | len = plugins.length, |
| | | regex = /Adobe Reader|PDF|Acrobat/i; |
| | | |
| | | if (plugin && plugin.enabledPlugin) |
| | | return 1; |
| | | |
| | | if (window.ActiveXObject) { |
| | | try { |
| | | if (axObj = new ActiveXObject("AcroPDF.PDF")) |
| | | return 1; |
| | | } |
| | | catch (e) {} |
| | | try { |
| | | if (axObj = new ActiveXObject("PDF.PdfCtrl")) |
| | | return 1; |
| | | } |
| | | catch (e) {} |
| | | } |
| | | |
| | | for (i=0; i<len; i++) { |
| | | plugin = plugins[i]; |
| | | if (typeof plugin === 'String') { |
| | | if (regex.test(plugin)) |
| | | return 1; |
| | | } |
| | | else if (plugin.name && regex.test(plugin.name)) |
| | | return 1; |
| | | } |
| | | |
| | | return 0; |
| | | }; |
| | | |
| | | this.flash_support_check = function() |
| | | { |
| | | var plugin = navigator.mimeTypes ? navigator.mimeTypes["application/x-shockwave-flash"] : {}; |
| | | |
| | | if (plugin && plugin.enabledPlugin) |
| | | return 1; |
| | | |
| | | if (window.ActiveXObject) { |
| | | try { |
| | | if (axObj = new ActiveXObject("ShockwaveFlash.ShockwaveFlash")) |
| | | return 1; |
| | | } |
| | | catch (e) {} |
| | | } |
| | | |
| | | return 0; |
| | | }; |
| | | |
| | | } // end object rcube_webmail |
| | | |
| | | |