From a039c626eef6ad0e6c915d1618fbd0e6e40f57a2 Mon Sep 17 00:00:00 2001 From: alecpl <alec@alec.pl> Date: Thu, 04 Mar 2010 09:39:47 -0500 Subject: [PATCH] - Fix deleting all messages from last list page (#1486293) --- program/js/app.js | 909 ++++++++++++++++++++++++++++++++++++++------------------ 1 files changed, 616 insertions(+), 293 deletions(-) diff --git a/program/js/app.js b/program/js/app.js index 4f12e80..f6cf04b 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -22,6 +22,7 @@ this.env = new Object(); this.labels = new Object(); this.buttons = new Object(); + this.buttons_sel = new Object(); this.gui_objects = new Object(); this.gui_containers = new Object(); this.commands = new Object(); @@ -55,7 +56,7 @@ // set jQuery ajax options jQuery.ajaxSetup({ cache:false, error:function(request, status, err){ ref.http_error(request, status, err); }, - beforeSend:function(xmlhttp){ xmlhttp.setRequestHeader('X-RoundCube-Referer', bw.get_cookie('roundcube_sessid')); } + beforeSend:function(xmlhttp){ xmlhttp.setRequestHeader('X-RoundCube-Request', ref.env.request_token); } }); // set environment variable(s) @@ -134,7 +135,7 @@ this.goto_url('error', '_code=0x199'); return; } - + // find all registered gui containers for (var n in this.gui_containers) this.gui_containers[n] = $('#'+this.gui_containers[n]); @@ -142,6 +143,9 @@ // find all registered gui objects for (var n in this.gui_objects) this.gui_objects[n] = rcube_find_object(this.gui_objects[n]); + + // init registered buttons + this.init_buttons(); // tell parent window that this frame is loaded if (this.env.framed && parent.rcmail && parent.rcmail.set_busy) @@ -152,7 +156,7 @@ if (this.env.permaurl) this.enable_command('permaurl', true); - + switch (this.task) { case 'mail': @@ -164,8 +168,8 @@ this.message_list.addEventListener('keypress', function(o){ p.msglist_keypress(o); }); this.message_list.addEventListener('select', function(o){ p.msglist_select(o); }); this.message_list.addEventListener('dragstart', function(o){ p.drag_start(o); }); - this.message_list.addEventListener('dragmove', function(o, e){ p.drag_move(e); }); - this.message_list.addEventListener('dragend', function(o, e){ p.drag_end(e); }); + this.message_list.addEventListener('dragmove', function(e){ p.drag_move(e); }); + this.message_list.addEventListener('dragend', function(e){ p.drag_end(e); }); document.onmouseup = function(e){ return p.doc_mouse_up(e); }; this.message_list.init(); @@ -189,7 +193,7 @@ if (this.env.action=='show' || this.env.action=='preview') { this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete', - 'open', 'mark', 'viewsource', 'download', 'print', 'load-attachment', 'load-headers', true); + 'open', 'mark', 'edit', 'viewsource', 'download', 'print', 'load-attachment', 'load-headers', true); if (this.env.next_uid) { @@ -202,7 +206,7 @@ this.enable_command('firstmessage', true); } - if (this.env.blockedobjects) + if (this.env.blockedobjects) { if (this.gui_objects.remoteobjectsmsg) this.gui_objects.remoteobjectsmsg.style.display = 'block'; @@ -234,6 +238,9 @@ this.enable_command('savedraft', true); document.onmouseup = function(e){ return p.doc_mouse_up(e); }; + + // init message compose form + this.init_messageform(); } if (this.env.messagecount) @@ -243,10 +250,6 @@ this.enable_command('purge', true); this.set_page_buttons(); - - // init message compose form - if (this.env.action=='compose') - this.init_messageform(); // show printing dialog if (this.env.action=='print') @@ -277,11 +280,12 @@ if (this.gui_objects.contactslist) { this.contact_list = new rcube_list_widget(this.gui_objects.contactslist, {multiselect:true, draggable:true, keyboard:true}); + this.contact_list.row_init = function(row){ p.triggerEvent('insertrow', { cid:row.uid, row:row }); }; this.contact_list.addEventListener('keypress', function(o){ p.contactlist_keypress(o); }); this.contact_list.addEventListener('select', function(o){ p.contactlist_select(o); }); this.contact_list.addEventListener('dragstart', function(o){ p.drag_start(o); }); - this.contact_list.addEventListener('dragmove', function(o, e){ p.drag_move(e); }); - this.contact_list.addEventListener('dragend', function(o, e){ p.drag_end(e); }); + this.contact_list.addEventListener('dragmove', function(e){ p.drag_move(e); }); + this.contact_list.addEventListener('dragend', function(e){ p.drag_end(e); }); this.contact_list.init(); if (this.env.cid) @@ -301,7 +305,7 @@ this.set_page_buttons(); if (this.env.address_sources && this.env.address_sources[this.env.source] && !this.env.address_sources[this.env.source].readonly) - this.enable_command('add', true); + this.enable_command('add', 'import', true); if (this.env.cid) this.enable_command('show', 'edit', true); @@ -309,7 +313,7 @@ if ((this.env.action=='add' || this.env.action=='edit') && this.gui_objects.editform) this.enable_command('save', true); else - this.enable_command('search', 'reset-search', 'moveto', 'import', true); + this.enable_command('search', 'reset-search', 'moveto', true); if (this.contact_list && this.contact_list.rowcount > 0) this.enable_command('export', true); @@ -321,15 +325,14 @@ case 'settings': this.enable_command('preferences', 'identities', 'save', 'folders', true); - if (this.env.action=='identities' || this.env.action=='edit-identity' || this.env.action=='add-identity') { + if (this.env.action=='identities') { this.enable_command('add', this.env.identities_level < 2); - this.enable_command('delete', 'edit', true); } - - if (this.env.action=='edit-identity' || this.env.action=='add-identity') - this.enable_command('save', true); - - if (this.env.action=='folders') + else if (this.env.action=='edit-identity' || this.env.action=='add-identity') { + this.enable_command('add', this.env.identities_level < 2); + this.enable_command('save', 'delete', 'edit', true); + } + else if (this.env.action=='folders') this.enable_command('subscribe', 'unsubscribe', 'create-folder', 'rename-folder', 'delete-folder', true); if (this.gui_objects.identitieslist) @@ -342,8 +345,15 @@ if (this.env.iid) this.identity_list.highlight_row(this.env.iid); } - - if (this.gui_objects.subscriptionlist) + else if (this.gui_objects.sectionslist) + { + this.sections_list = new rcube_list_widget(this.gui_objects.sectionslist, {multiselect:false, draggable:false, keyboard:false}); + this.sections_list.addEventListener('select', function(o){ p.section_select(o); }); + this.sections_list.init(); + this.sections_list.focus(); + this.sections_list.select_first(); // open first section by default + } + else if (this.gui_objects.subscriptionlist) this.init_subscription_list(); break; @@ -366,9 +376,6 @@ default: break; } - - // enable basic commands - this.enable_command('logout', true); // flag object as complete this.loaded = true; @@ -420,7 +427,7 @@ } // set eventhandler to message icon - if (row.icon = row.obj.getElementsByTagName('TD')[0].getElementsByTagName('IMG')[0]) + if (row.icon = row.obj.getElementsByTagName('td')[0].getElementsByTagName('img')[0]) { var p = this; row.icon.id = 'msgicn_'+row.uid; @@ -437,13 +444,15 @@ } // set eventhandler to flag icon, if icon found - if (this.env.flagged_col && (row.flagged_icon = row.obj.getElementsByTagName('TD')[this.env.flagged_col].getElementsByTagName('IMG')[0])) + if (this.env.flagged_col && (row.flagged_icon = row.obj.getElementsByTagName('td')[this.env.flagged_col].getElementsByTagName('img')[0])) { var p = this; row.flagged_icon.id = 'flaggedicn_'+row.uid; row.flagged_icon._row = row.obj; row.flagged_icon.onmousedown = function(e) { p.command('toggle_flag', this); }; } + + this.triggerEvent('insertrow', { uid:uid, row:row }); }; // init message compose form: set focus and eventhandlers @@ -457,23 +466,29 @@ var input_to = $("[name='_to']"); var input_subject = $("input[name='_subject']"); var input_message = $("[name='_message']").get(0); + var html_mode = $("input[name='_is_html']").val() == '1'; // init live search events this.init_address_input_events(input_to); this.init_address_input_events($("[name='_cc']")); this.init_address_input_events($("[name='_bcc']")); + + if (!html_mode) + this.set_caret_pos(input_message, this.env.top_posting ? 0 : $(input_message).val().length); // add signature according to selected identity if (input_from.attr('type') == 'select-one' && $("input[name='_draft_saveid']").val() == '' - && $("input[name='_is_html']").val() != '1') { // if we have HTML editor, signature is added in callback + && !html_mode) { // if we have HTML editor, signature is added in callback this.change_identity(input_from[0]); } + else if (!html_mode) + this.set_caret_pos(input_message, this.env.top_posting ? 0 : $(input_message).val().length); if (input_to.val() == '') input_to.focus(); else if (input_subject.val() == '') input_subject.focus(); - else if (input_message) + else if (input_message && !html_mode) input_message.focus(); // get summary of all field values @@ -551,14 +566,11 @@ this.gui_objects.loginform.submit(); break; - case 'logout': - this.goto_url('logout', '', true); - break; - // commands to switch task case 'mail': case 'addressbook': case 'settings': + case 'logout': this.switch_task(command); break; @@ -596,7 +608,7 @@ this.reset_qsearch(); this.list_contacts(props); - this.enable_command('add', (this.env.address_sources && !this.env.address_sources[props].readonly)); + this.enable_command('add', 'import', (this.env.address_sources && !this.env.address_sources[props].readonly)); } break; @@ -612,8 +624,8 @@ if (this.env.sort_col==sort_col) sort_order = this.env.sort_order=='ASC' ? 'DESC' : 'ASC'; else - sort_order = 'ASC'; - + sort_order = 'ASC'; + // set table header class $('#rcm'+this.env.sort_col).removeClass('sorted'+(this.env.sort_order.toUpperCase())); $('#rcm'+sort_col).addClass('sorted'+sort_order); @@ -691,6 +703,10 @@ this.load_contact(cid, 'edit'); else if (this.task=='settings' && props) this.load_identity(props, 'edit-identity'); + else if (this.task=='mail' && (cid = this.get_single_uid())) { + var url = (this.env.mailbox == this.env.drafts_mailbox) ? '_draft_uid=' : '_uid='; + this.goto_url('compose', url+cid+'&_mbox='+urlencode(this.env.mailbox), true); + } break; case 'save-identity': @@ -828,7 +844,7 @@ case 'select-all': if (props == 'invert') this.message_list.invert_selection(); - else + else this.message_list.select_all(props); break; @@ -912,7 +928,7 @@ break; case 'spellcheck': - if (window.tinyMCE && tinyMCE.get('compose-body')) { + if (window.tinyMCE && tinyMCE.get(this.env.composebody)) { tinyMCE.execCommand('mceSpellCheck', true); } else if (this.env.spellcheck && this.env.spellcheck.spellCheck && this.spellcheck_ready) { @@ -973,6 +989,10 @@ case 'remove-attachment': this.remove_attachment(props); + break; + + case 'insert-sig': + this.change_identity($("[name='_from']")[0], true); break; case 'reply-all': @@ -1055,7 +1075,7 @@ this.lock_form(this.gui_objects.importform, true); } else - this.goto_url('import'); + this.goto_url('import', (this.env.source ? '_target='+urlencode(this.env.source)+'&' : '')); break; case 'export': @@ -1205,6 +1225,16 @@ this.set_busy(false); this.display_message('Request timed out!', 'error'); }; + + this.reload = function(delay) + { + if (this.env.framed && parent.rcmail) + parent.rcmail.reload(delay); + else if (delay) + window.setTimeout(function(){ rcmail.reload(); }, delay); + else if (window.location) + location.href = this.env.comm_path; + }; /*********************************************************/ @@ -1238,6 +1268,14 @@ this.env.last_folder_target = null; list.draglayer.hide(); } + + // reset 'pressed' buttons + if (this.buttons_sel) { + for (var id in this.buttons_sel) + if (typeof id != 'function') + this.button_out(this.buttons_sel[id], id); + this.buttons_sel = {}; + } }; this.drag_start = function(list) @@ -1262,10 +1300,12 @@ this.env.folder_coords = new Array(); for (var k in model) { if (li = this.get_folder_li(k)) { - pos = $(li.firstChild).offset(); // only visible folders - if (height = li.firstChild.offsetHeight) - this.env.folder_coords[k] = { x1:pos.left, y1:pos.top, x2:pos.left + li.firstChild.offsetWidth, y2:pos.top + height }; + if (height = li.firstChild.offsetHeight) { + pos = $(li.firstChild).offset(); + this.env.folder_coords[k] = { x1:pos.left, y1:pos.top, + x2:pos.left + li.firstChild.offsetWidth, y2:pos.top + height, on:0 }; + } } } } @@ -1274,14 +1314,19 @@ this.drag_end = function(e) { this.drag_active = false; + this.env.last_folder_target = null; + + if (this.folder_auto_timer) { + window.clearTimeout(this.folder_auto_timer); + this.folder_auto_timer = null; + this.folder_auto_expand = null; + } // over the folders if (this.gui_objects.folderlist && this.env.folder_coords) { for (var k in this.env.folder_coords) { - if (k == this.env.last_folder_target) { + if (this.env.folder_coords[k].on) $(this.get_folder_li(k)).removeClass('droptarget'); - this.env.last_folder_target = null; - } } } }; @@ -1294,38 +1339,58 @@ var moffset = this.initialListScrollTop-this.gui_objects.folderlist.parentNode.scrollTop; var toffset = -moffset-boffset; - var li, pos, mouse; + var li, div, pos, mouse; mouse = rcube_event.get_mouse_pos(e); pos = this.env.folderlist_coords; - mouse.y += toffset; // if mouse pointer is outside of folderlist if (mouse.x < pos.x1 || mouse.x >= pos.x2 || mouse.y < pos.y1 || mouse.y >= pos.y2) { if (this.env.last_folder_target) { $(this.get_folder_li(this.env.last_folder_target)).removeClass('droptarget'); + this.env.folder_coords[this.env.last_folder_target].on = 0; this.env.last_folder_target = null; } return; } - + // over the folders for (var k in this.env.folder_coords) { pos = this.env.folder_coords[k]; - if (this.check_droptarget(k) && ((mouse.x >= pos.x1) && (mouse.x < pos.x2) - && (mouse.y >= pos.y1) && (mouse.y < pos.y2))) { - $(this.get_folder_li(k)).addClass('droptarget'); + if (mouse.x >= pos.x1 && mouse.x < pos.x2 && mouse.y >= pos.y1 && mouse.y < pos.y2 + && this.check_droptarget(k)) { + + li = this.get_folder_li(k); + div = $(li.getElementsByTagName("div")[0]); + + // 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); + + this.folder_auto_expand = k; + this.folder_auto_timer = window.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); + this.folder_auto_timer = null; + this.folder_auto_expand = null; + } + + $(li).addClass('droptarget'); this.env.last_folder_target = k; + this.env.folder_coords[k].on = 1; } - else { + else if (pos.on) { $(this.get_folder_li(k)).removeClass('droptarget'); - if (k == this.env.last_folder_target) - this.env.last_folder_target = null; + this.env.folder_coords[k].on = 0; } } } }; - + this.collapse_folder = function(id) { var div; @@ -1392,12 +1457,12 @@ if (this.env.mailbox == this.env.drafts_mailbox) { this.enable_command('reply', 'reply-all', 'forward', false); - this.enable_command('show', 'print', 'open', 'download', 'viewsource', selected); + this.enable_command('show', 'print', 'open', 'edit', 'download', 'viewsource', selected); this.enable_command('delete', 'moveto', 'mark', (list.selection.length > 0 ? true : false)); } else { - this.enable_command('show', 'reply', 'reply-all', 'forward', 'print', 'open', 'download', 'viewsource', selected); + this.enable_command('show', 'reply', 'reply-all', 'forward', 'print', 'edit', 'open', 'download', 'viewsource', selected); this.enable_command('delete', 'moveto', 'mark', (list.selection.length > 0 ? true : false)); } @@ -1553,15 +1618,14 @@ this.env.current_page = 1; this.set_busy(true, 'searching'); this.http_request('search', '_filter='+filter - + (search ? '&_q='+urlencode(search) : '') - + (this.env.mailbox ? '&_mbox='+urlencode(this.env.mailbox) : ''), true); + + (search ? '&_q='+urlencode(search) : '') + + (this.env.mailbox ? '&_mbox='+urlencode(this.env.mailbox) : ''), true); } // list messages of a specific mailbox this.list_mailbox = function(mbox, page, sort) { - this.last_selected = 0; var add_url = ''; var target = window; @@ -1575,19 +1639,22 @@ // also send search request to get the right messages if (this.env.search_request) add_url += '&_search='+this.env.search_request; - + // set page=1 if changeing to another mailbox - if (!page && mbox != this.env.mailbox) + if (!page && this.env.mailbox != mbox) { page = 1; this.env.current_page = page; - if (this.message_list) - this.message_list.clear_selection(); this.show_contentframe(false); } - + if (mbox != this.env.mailbox || (mbox == this.env.mailbox && !page && !sort)) add_url += '&_refresh=1'; + + // unselect selected messages + this.last_selected = 0; + if (this.message_list) + this.message_list.clear_selection(); this.select_folder(mbox, this.env.mailbox); this.env.mailbox = mbox; @@ -1796,13 +1863,13 @@ lock = true; this.set_busy(true, 'movingmessage'); } - else if (!this.env.flag_for_deletion) + else this.show_contentframe(false); // Hide message command buttons until a message is selected - this.enable_command('reply', 'reply-all', 'forward', 'delete', 'mark', 'print', 'open', 'viewsource', 'download', false); + this.enable_command('reply', 'reply-all', 'forward', 'delete', 'mark', 'print', 'open', 'edit', 'viewsource', 'download', false); - this._with_selected_messages('moveto', lock, add_url, (this.env.flag_for_deletion ? false : true)); + this._with_selected_messages('moveto', lock, add_url); }; // delete selected messages from the current mailbox @@ -1814,9 +1881,14 @@ if (!this.env.uid && !selection.length) return; - // if there is a trash mailbox defined and we're not currently in it: - if (this.env.trash_mailbox && String(this.env.mailbox).toLowerCase() != String(this.env.trash_mailbox).toLowerCase()) - { + // if config is set to flag for deletion + if (this.env.flag_for_deletion) + this.mark_message('delete'); + // if there isn't a defined trash mailbox or we are in it + else if (!this.env.trash_mailbox || this.env.mailbox == this.env.trash_mailbox) + this.permanently_remove_messages(); + // if there is a trash mailbox defined and we're not currently in it + else { // if shift was pressed delete it immediately if (this.message_list && this.message_list.shiftkey) { @@ -1826,21 +1898,6 @@ else this.move_messages(this.env.trash_mailbox); } - // if there is a trash mailbox defined but we *are* in it: - else if (this.env.trash_mailbox && String(this.env.mailbox).toLowerCase() == String(this.env.trash_mailbox).toLowerCase()) - this.permanently_remove_messages(); - // if there isn't a defined trash mailbox and the config is set to flag for deletion - else if (!this.env.trash_mailbox && this.env.flag_for_deletion) - { - this.mark_message('delete'); - if (this.env.action == 'show') - this.command('nextmessage', '', this); - else if (selection.length == 1) - this.message_list.select_next(); - } - // if there isn't a defined trash mailbox and the config is set NOT to flag for deletion - else if (!this.env.trash_mailbox) - this.permanently_remove_messages(); }; // delete the selected messages permanently @@ -1851,7 +1908,7 @@ return; this.show_contentframe(false); - this._with_selected_messages('delete', false, '&_from='+(this.env.action ? this.env.action : ''), true); + this._with_selected_messages('delete', false, '&_from='+(this.env.action ? this.env.action : '')); }; // Send a specifc request with UIDs of all selected messages @@ -1867,28 +1924,21 @@ var selection = this.message_list.get_selection(); var rows = this.message_list.rows; var id; - for (var n=0; n<selection.length; n++) - { + for (var n=0; n<selection.length; n++) { id = selection[n]; a_uids[a_uids.length] = id; - - if (remove) - this.message_list.remove_row(id, (n == selection.length-1)); - else - { - this.set_message_status(id, 'deleted', true); - if (this.env.read_when_deleted) - this.set_message_status(id, 'unread', false); - this.set_message(id); - } + this.message_list.remove_row(id, (this.env.display_next && n == selection.length-1)); } + // make sure there are no selected rows + if (!this.env.display_next) + this.message_list.clear_selection(); } // also send search request to get the right messages if (this.env.search_request) add_url += '&_search='+this.env.search_request; - if (this.env.next_uid) + if (this.env.display_next && this.env.next_uid) add_url += '&_next_uid='+this.env.next_uid; // send request to server @@ -2028,15 +2078,33 @@ uid = a_uids[i]; if (rows[uid]) { - this.set_message(uid, 'deleted', true); if (rows[uid].unread) r_uids[r_uids.length] = uid; + + if (this.env.skip_deleted) + this.message_list.remove_row(uid, (this.env.display_next && i == this.message_list.selection.length-1)); + else + this.set_message(uid, 'deleted', true); } } - if (r_uids.length) - add_url = '&_ruid='+r_uids.join(','); + // make sure there are no selected rows + if (this.env.skip_deleted && !this.env.display_next && this.message_list) + this.message_list.clear_selection(); + add_url = '&_from='+(this.env.action ? this.env.action : ''); + + if (r_uids.length) + add_url += '&_ruid='+r_uids.join(','); + + if (this.env.skip_deleted) { + // also send search request to get the right messages + if (this.env.search_request) + add_url += '&_search='+this.env.search_request; + if (this.env.display_next && this.env.next_uid) + add_url += '&_next_uid='+this.env.next_uid; + } + this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag=delete'+add_url); return true; }; @@ -2113,6 +2181,14 @@ return false; } + // check if all files has been uploaded + for (var key in this.env.attachments) { + if (typeof this.env.attachments[key] == 'object' && !this.env.attachments[key].complete) { + alert(this.get_label('notuploadedwarning')); + return false; + } + } + // display localized warning for missing subject if (input_subject.val() == '') { @@ -2131,19 +2207,26 @@ } // check for empty body - if ((!window.tinyMCE || !tinyMCE.get('compose-body')) && input_message.val() == '' && !confirm(this.get_label('nobodywarning'))) + if ((!window.tinyMCE || !tinyMCE.get(this.env.composebody)) + && input_message.val() == '' && !confirm(this.get_label('nobodywarning'))) { input_message.focus(); return false; } - else if (window.tinyMCE && tinyMCE.get('compose-body') && !tinyMCE.get('compose-body').getContent() && !confirm(this.get_label('nobodywarning'))) + else if (window.tinyMCE && tinyMCE.get(this.env.composebody) + && !tinyMCE.get(this.env.composebody).getContent() + && !confirm(this.get_label('nobodywarning'))) { - tinyMCE.get('compose-body').focus(); + tinyMCE.get(this.env.composebody).focus(); return false; } // Apply spellcheck changes if spell checker is active this.stop_spellchecking(); + + // move body from html editor to textarea (just to be sure, #1485860) + if (window.tinyMCE && tinyMCE.get(this.env.composebody)) + tinyMCE.triggerSave(); return true; }; @@ -2205,118 +2288,148 @@ if (value_subject) str += value_subject+':'; - var editor = tinyMCE.get('compose-body'); + var editor = tinyMCE.get(this.env.composebody); if (editor) str += editor.getContent(); else str += $("[name='_message']").val(); - + + if (this.env.attachments) + for (var upload_id in this.env.attachments) + str += upload_id; + if (save) this.cmp_hash = str; - + return str; }; - this.change_identity = function(obj) - { + this.change_identity = function(obj, show_sig) + { if (!obj || !obj.options) return false; + + if (!show_sig) + show_sig = this.env.show_sig; var id = obj.options[obj.selectedIndex].value; var input_message = $("[name='_message']"); var message = input_message.val(); var is_html = ($("input[name='_is_html']").val() == '1'); - var sig, p, len; + var sig_separator = this.env.sig_above && (this.env.compose_mode == 'reply' || this.env.compose_mode == 'forward') ? '---' : '-- '; + var sig, cursor_pos, p = -1; if (!this.env.identity) this.env.identity = id - if (!is_html) - { + // enable manual signature insert + if (this.env.signatures && this.env.signatures[id]) + this.enable_command('insert-sig', true); + else + this.enable_command('insert-sig', false); + + if (!is_html) { // remove the 'old' signature - if (this.env.identity && this.env.signatures && this.env.signatures[this.env.identity]) - { - if (this.env.signatures[this.env.identity]['is_html']) - sig = this.env.signatures[this.env.identity]['plain_text']; - else - sig = this.env.signatures[this.env.identity]['text']; + if (show_sig && this.env.identity && this.env.signatures && this.env.signatures[this.env.identity]) { + sig = this.env.signatures[this.env.identity].is_html ? this.env.signatures[this.env.identity].plain_text : this.env.signatures[this.env.identity].text; - if (sig.indexOf('-- ')!=0) - sig = '-- \n'+sig; + if (sig.indexOf('-- ') != 0) + sig = sig_separator + '\n' + sig; - p = message.lastIndexOf(sig); - if (p>=0) - message = message.substring(0, p-1) + message.substring(p+sig.length, message.length); - } - - message = message.replace(/[\r\n]+$/, ''); - len = message.length; + p = this.env.sig_above ? message.indexOf(sig) : message.lastIndexOf(sig); + if (p >= 0) + message = message.substring(0, p) + message.substring(p+sig.length, message.length); + } // add the new signature string - if (this.env.signatures && this.env.signatures[id]) - { - sig = this.env.signatures[id]['text']; - if (this.env.signatures[id]['is_html']) - { - sig = this.env.signatures[id]['plain_text']; + 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']; + if (sig.indexOf('-- ') != 0) + 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 (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); + cursor_pos = pos; } - if (sig.indexOf('-- ')!=0) - sig = '-- \n'+sig; - message += '\n\n'+sig; - if (len) len += 1; + else { // on top + cursor_pos = 0; + message = '\n\n' + sig + '\n\n' + message.replace(/^[\r\n]+/, ''); + } + } + else { + message = message.replace(/[\r\n]+$/, ''); + cursor_pos = !this.env.top_posting && message.length ? message.length+1 : 0; + message += '\n\n' + sig; } } - else - { - var editor = tinyMCE.get('compose-body'); + else + cursor_pos = this.env.top_posting ? 0 : message.length; - if (this.env.signatures) - { - // Append the signature as a div within the body - var sigElem = editor.dom.get('_rc_sig'); - var newsig = ''; - var htmlsig = true; + input_message.val(message); + + // move cursor before the signature + this.set_caret_pos(input_message.get(0), cursor_pos); + } + else if (is_html && show_sig && this.env.signatures) { // html + var editor = tinyMCE.get(this.env.composebody); + var sigElem = editor.dom.get('_rc_sig'); - if (!sigElem) - { - // add empty line before signature on IE - if (bw.ie) - editor.getBody().appendChild(editor.getDoc().createElement('br')); - - sigElem = editor.getDoc().createElement('div'); - sigElem.setAttribute('id', '_rc_sig'); - editor.getBody().appendChild(sigElem); + // Append the signature as a div within the body + if (!sigElem) { + var body = editor.getBody(); + var doc = editor.getDoc(); + + sigElem = doc.createElement('div'); + sigElem.setAttribute('id', '_rc_sig'); + + if (this.env.sig_above) { + // if no existing sig and top posting then insert at caret pos + editor.getWin().focus(); // correct focus in IE + + var node = editor.selection.getNode(); + if (node.nodeName == 'BODY') { + // no real focus, insert at start + body.insertBefore(sigElem, body.firstChild); + body.insertBefore(doc.createElement('br'), body.firstChild); } - - if (this.env.signatures[id]) - { - newsig = this.env.signatures[id]['text']; - htmlsig = this.env.signatures[id]['is_html']; - - if (newsig) { - if (htmlsig && this.env.signatures[id]['plain_text'].indexOf('-- ')!=0) - newsig = '<p>-- </p>' + newsig; - else if (!htmlsig && newsig.indexOf('-- ')!=0) - newsig = '-- \n' + newsig; + else { + body.insertBefore(sigElem, node.nextSibling); + body.insertBefore(doc.createElement('br'), node.nextSibling); } } + else { + if (bw.ie) // add empty line before signature on IE + body.appendChild(doc.createElement('br')); - if (htmlsig) - sigElem.innerHTML = newsig; - else - sigElem.innerHTML = '<pre>' + newsig + '</pre>'; + body.appendChild(sigElem); } } - input_message.val(message); + 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.indexOf('-- ') != 0) + sig = sig_separator + '<br />' + sig; + } + else { + sig = this.env.signatures[id].text; + if (sig.indexOf('-- ') != 0) + sig = sig_separator + '\n' + sig; + sig = '<pre>' + sig + '</pre>'; + } - // move cursor before the signature - if (!is_html) - this.set_caret_pos(input_message.get(0), len); + sigElem.innerHTML = sig; + } + } this.env.identity = id; return true; - }; + }; this.show_attachment_form = function(a) { @@ -2376,7 +2489,7 @@ } else // for standards-compilant browsers { - var frame = document.createElement('IFRAME'); + var frame = document.createElement('iframe'); frame.name = frame_name; frame.style.border = 'none'; frame.style.width = 0; @@ -2385,10 +2498,42 @@ document.body.appendChild(frame); } + // handle upload errors, parsing iframe content in onload + var fr = document.getElementsByName(frame_name)[0]; + $(fr).bind('load', {ts:ts}, function(e) { + var content = ''; + try { + if (this.contentDocument) { + var d = this.contentDocument; + } else if (this.contentWindow) { + var d = this.contentWindow.document; + } + content = d.childNodes[0].innerHTML; + } catch (e) {} + + if (!String(content).match(/add2attachment/) && (!bw.opera || (rcmail.env.uploadframe && rcmail.env.uploadframe == e.data.ts))) { + rcmail.display_message(rcmail.get_label('fileuploaderror'), 'error'); + rcmail.remove_from_attachment_list(e.data.ts); + } + // Opera hack: handle double onload + if (bw.opera) + rcmail.env.uploadframe = e.data.ts; + }); + form.target = frame_name; - form.action = this.env.comm_path+'&_action=upload'; + form.action = this.env.comm_path+'&_action=upload&_uploadid='+ts; form.setAttribute('enctype', 'multipart/form-data'); form.submit(); + + // hide upload form + this.show_attachment_form(false); + // display upload indicator and cancel button + var content = this.get_label('uploading'); + if (this.env.loadingicon) + content = '<img src="'+this.env.loadingicon+'" alt="" />'+content; + if (this.env.cancelicon) + content = '<a title="'+this.get_label('cancel')+'" onclick="return rcmail.cancel_attachment_upload(\''+ts+'\', \''+frame_name+'\');" href="#cancelupload"><img src="'+this.env.cancelicon+'" alt="" /></a>'+content; + this.add2attachment_list(ts, { name:'', html:content, complete:false }); } // set reference to the form object @@ -2398,17 +2543,35 @@ // add file name to attachment list // called from upload page - this.add2attachment_list = function(name, content) - { + this.add2attachment_list = function(name, att, upload_id) + { if (!this.gui_objects.attachmentlist) return false; - - $('<li>').attr('id', name).html(content).appendTo(this.gui_objects.attachmentlist); + + var li = $('<li>').attr('id', name).html(att.html); + var indicator; + + // replace indicator's li + if (upload_id && (indicator = document.getElementById(upload_id))) { + li.replaceAll(indicator); + } + else { // add new li + li.appendTo(this.gui_objects.attachmentlist); + } + + if (upload_id && this.env.attachments[upload_id]) + delete this.env.attachments[upload_id]; + + this.env.attachments[name] = att; + return true; - }; + }; this.remove_from_attachment_list = function(name) - { + { + if (this.env.attachments[name]) + delete this.env.attachments[name]; + if (!this.gui_objects.attachmentlist) return false; @@ -2416,14 +2579,24 @@ for (i=0;i<list.length;i++) if (list[i].id == name) this.gui_objects.attachmentlist.removeChild(list[i]); - }; + }; this.remove_attachment = function(name) { - if (name) + if (name && this.env.attachments[name]) this.http_post('remove-attachment', '_file='+urlencode(name)); return true; + }; + + this.cancel_attachment_upload = function(name, frame_name) + { + if (!name || !frame_name) + return false; + + this.remove_from_attachment_list(name); + $("iframe[name='"+frame_name+"']").remove(); + return false; }; // send remote request to add a new contact @@ -2443,11 +2616,14 @@ var addurl = ''; if (this.message_list) { this.message_list.clear(); - if (this.env.search_mods) { - var head_arr = new Array(); - for (var n in this.env.search_mods) - head_arr.push(n); - addurl += '&_headers='+head_arr.join(','); + if (this.env.search_mods) { + var mods = this.env.search_mods[this.env.mailbox] ? this.env.search_mods[this.env.mailbox] : this.env.search_mods['*']; + if (mods) { + var head_arr = new Array(); + for (var n in mods) + head_arr.push(n); + addurl += '&_headers='+head_arr.join(','); + } } } else if (this.contact_list) { this.contact_list.clear(true); @@ -2567,7 +2743,7 @@ return; // get cursor pos - var inp_value = this.ksearch_input.value.toLowerCase(); + var inp_value = this.ksearch_input.value; var cpos = this.get_caret_pos(this.ksearch_input); var p = inp_value.lastIndexOf(this.ksearch_value, cpos); @@ -2599,15 +2775,21 @@ var q = inp_value.substring(p+1, cpos); // trim query string - q = q.replace(/(^\s+|\s+$)/g, '').toLowerCase(); + q = q.replace(/(^\s+|\s+$)/g, ''); - // Don't (re-)search if string is empty or if the last results are still active + // Don't (re-)search if the last results are still active if (q == this.ksearch_value) return; + var old_value = this.ksearch_value; this.ksearch_value = q; + // ...string is empty if (!q.length) + return; + + // ...new search value contains old one and previous search result was empty + if (old_value && old_value.length && this.env.contacts && !this.env.contacts.length && q.indexOf(old_value) == 0) return; this.display_message(this.get_label('searching'), 'loading', true); @@ -2628,8 +2810,8 @@ this.ksearch_display_results = function (a_results) { // display search results - if (a_results.length && this.ksearch_input) { - var p, ul, li; + if (a_results.length && this.ksearch_input && this.ksearch_value) { + var p, ul, li, s_val = this.ksearch_value; // create results pane if not present if (!this.ksearch_pane) { @@ -2641,11 +2823,11 @@ // remove all search results ul = this.ksearch_pane.__ul; ul.innerHTML = ''; - + // add each result line to list for (i=0; i<a_results.length; i++) { li = document.createElement('LI'); - li.innerHTML = a_results[i].replace(new RegExp('('+this.ksearch_value+')', 'ig'), '##$1%%').replace(/</g, '<').replace(/>/g, '>').replace(/##([^%]+)%%/g, '<b>$1</b>'); + li.innerHTML = a_results[i].replace(new RegExp('('+s_val+')', 'ig'), '##$1%%').replace(/</g, '<').replace(/>/g, '>').replace(/##([^%]+)%%/g, '<b>$1</b>'); li.onmouseover = function(){ ref.ksearch_select(this); }; li.onmouseup = function(){ ref.ksearch_click(this) }; li._rcm_id = i; @@ -2855,7 +3037,7 @@ }; // update a contact record in the list - this.update_contact_row = function(cid, cols_arr) + this.update_contact_row = function(cid, cols_arr, newcid) { var row; if (this.contact_list.rows[cid] && (row = this.contact_list.rows[cid].obj)) { @@ -2863,11 +3045,50 @@ if (row.cells[c]) $(row.cells[c]).html(cols_arr[c]); + // cid change + if (newcid) { + row.id = 'rcmrow' + newcid; + this.contact_list.remove_row(cid); + this.contact_list.init_row(row); + this.contact_list.selection[0] = newcid; + row.style.display = ''; + } + return true; } return false; }; + + // add row to contacts list + this.add_contact_row = function(cid, cols, select) + { + if (!this.gui_objects.contactslist || !this.gui_objects.contactslist.tBodies[0]) + return false; + + var tbody = this.gui_objects.contactslist.tBodies[0]; + var rowcount = tbody.rows.length; + var even = rowcount%2; + + var row = document.createElement('tr'); + row.id = 'rcmrow'+cid; + row.className = 'contact '+(even ? 'even' : 'odd'); + + if (this.contact_list.in_selection(cid)) + row.className += ' selected'; + + // add each submitted col + for (var c in cols) { + col = document.createElement('td'); + col.className = String(c).toLowerCase(); + col.innerHTML = cols[c]; + row.appendChild(col); + } + + this.contact_list.insert_row(row); + + this.enable_command('export', (this.contact_list.rowcount > 0)); + }; /*********************************************************/ @@ -2883,7 +3104,7 @@ this.subscription_list.addEventListener('dragend', function(o){ p.subscription_move_folder(o); }); this.subscription_list.row_init = function (row) { - var anchors = row.obj.getElementsByTagName('A'); + var anchors = row.obj.getElementsByTagName('a'); if (anchors[0]) anchors[0].onclick = function() { p.rename_folder(row.id); return false; }; if (anchors[1]) @@ -2894,6 +3115,26 @@ this.subscription_list.init(); } + // preferences section select and load options frame + this.section_select = function(list) + { + var id = list.get_single_selection(); + + if (id) { + var add_url = ''; + var target = window; + this.set_busy(true); + + if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) { + add_url = '&_framed=1'; + target = window.frames[this.env.contentframe]; + } + target.location.href = this.env.comm_path+'&_action=edit-prefs&_section='+id+add_url; + } + + return true; + }; + this.identity_select = function(list) { var id; @@ -2901,7 +3142,7 @@ this.load_identity(id, 'edit-identity'); }; - // load contact record + // load identity record this.load_identity = function(id, action) { if (action=='edit-identity' && (!id || id==this.env.iid)) @@ -2934,8 +3175,9 @@ if (!id) id = this.env.iid ? this.env.iid : selection[0]; - // if (this.env.framed && id) - this.goto_url('delete-identity', '_iid='+id, true); + // append token to request + this.goto_url('delete-identity', '_iid='+id+'&_token='+this.env.request_token, true); + return true; }; @@ -3049,7 +3291,8 @@ if (id && this.env.subscriptionrows[id] && (row = document.getElementById(id))) { var reg = new RegExp('.*['+RegExp.escape(this.env.delimiter)+']'); - this.name_input = document.createElement('INPUT'); + this.name_input = document.createElement('input'); + this.name_input.type = 'text'; this.name_input.value = this.env.subscriptionrows[id][0].replace(reg, ''); reg = new RegExp('['+RegExp.escape(this.env.delimiter)+']?[^'+RegExp.escape(this.env.delimiter)+']+$'); @@ -3129,10 +3372,13 @@ if (!this.gui_objects.subscriptionlist) return false; - // find not protected folder - for (var refid in this.env.subscriptionrows) - if (this.env.subscriptionrows[refid]!=null && !this.env.subscriptionrows[refid][2]) + // find not protected folder + var refid; + for (var rid in this.env.subscriptionrows) + if (this.env.subscriptionrows[rid]!=null && !this.env.subscriptionrows[rid][2]) { + refid = rid; break; + } var refrow, form; var tbody = this.gui_objects.subscriptionlist.tBodies[0]; @@ -3145,10 +3391,11 @@ refid = replace.id; } - if (!id || !(refrow = document.getElementById(refid))) + if (!id || !refid || !(refrow = document.getElementById(refid))) { // Refresh page if we don't have a table row to clone this.goto_url('folders'); + return false; } else { @@ -3174,8 +3421,8 @@ // set messages count to zero if (!replace) row.cells[1].innerHTML = '*'; - - if (!replace && row.cells[2] && row.cells[2].firstChild.tagName=='INPUT') + + if (!replace && row.cells[2] && row.cells[2].firstChild.tagName.toLowerCase()=='input') { row.cells[2].firstChild.value = name; row.cells[2].firstChild.checked = true; @@ -3278,11 +3525,11 @@ this.clone_table_row = function(row) { var cell, td; - var new_row = document.createElement('TR'); + var new_row = document.createElement('tr'); for(var n=0; n<row.cells.length; n++) { cell = row.cells[n]; - td = document.createElement('TD'); + td = document.createElement('td'); if (cell.className) td.className = cell.className; @@ -3303,12 +3550,49 @@ // eable/disable buttons for page shifting this.set_page_buttons = function() - { + { this.enable_command('nextpage', (this.env.pagecount > this.env.current_page)); this.enable_command('lastpage', (this.env.pagecount > this.env.current_page)); this.enable_command('previouspage', (this.env.current_page > 1)); this.enable_command('firstpage', (this.env.current_page > 1)); + }; + + // set event handlers on registered buttons + this.init_buttons = function() + { + for (var cmd in this.buttons) { + if (typeof cmd != 'string') + continue; + + for (var i=0; i< this.buttons[cmd].length; i++) { + var prop = this.buttons[cmd][i]; + var elm = document.getElementById(prop.id); + if (!elm) + continue; + + var preload = false; + if (prop.type == 'image') { + elm = elm.parentNode; + preload = true; + } + + elm._command = cmd; + elm._id = prop.id; + if (prop.sel) { + elm.onmousedown = function(e){ return rcmail.button_sel(this._command, this._id); }; + elm.onmouseup = function(e){ return rcmail.button_out(this._command, this._id); }; + if (preload) + new Image().src = prop.sel; + } + if (prop.over) { + elm.onmouseover = function(e){ return rcmail.button_over(this._command, this._id); }; + elm.onmouseout = function(e){ return rcmail.button_out(this._command, this._id); }; + if (preload) + new Image().src = prop.over; + } + } } + }; // set button to a specific state this.set_button = function(command, state) @@ -3370,7 +3654,7 @@ if (button.type=='image' && obj) { obj.setAttribute('alt', this.get_label(label)); - if ((link = obj.parentNode) && link.tagName == 'A') + if ((link = obj.parentNode) && link.tagName.toLowerCase() == 'a') link.setAttribute('title', this.get_label(label)); } else if (obj) @@ -3380,67 +3664,79 @@ // mouse over button this.button_over = function(command, id) - { + { var a_buttons = this.buttons[command]; - var button, img; + var button, elm; if(!a_buttons || !a_buttons.length) return false; for(var n=0; n<a_buttons.length; n++) - { + { button = a_buttons[n]; if(button.id==id && button.status=='act') - { - img = document.getElementById(button.id); - if (img && button.over) - img.src = button.over; + { + elm = document.getElementById(button.id); + if (elm && button.over) { + if (button.type == 'image') + elm.src = button.over; + else + elm.className = button.over; } } - - }; + } + }; // mouse down on button this.button_sel = function(command, id) - { + { var a_buttons = this.buttons[command]; - var button, img; + var button, elm; if(!a_buttons || !a_buttons.length) return; for(var n=0; n<a_buttons.length; n++) - { + { button = a_buttons[n]; if(button.id==id && button.status=='act') - { - img = document.getElementById(button.id); - if (img && button.sel) - img.src = button.sel; + { + elm = document.getElementById(button.id); + if (elm && button.sel) { + if (button.type == 'image') + elm.src = button.sel; + else + elm.className = button.sel; } + this.buttons_sel[id] = command; } - }; + } + }; // mouse out of button this.button_out = function(command, id) - { + { var a_buttons = this.buttons[command]; - var button, img; + var button, elm; if(!a_buttons || !a_buttons.length) return; for(var n=0; n<a_buttons.length; n++) - { + { button = a_buttons[n]; if(button.id==id && button.status=='act') - { - img = document.getElementById(button.id); - if (img && button.act) - img.src = button.act; + { + elm = document.getElementById(button.id); + if (elm && button.act) { + if (button.type == 'image') + elm.src = button.act; + else + elm.className = button.act; } } - }; + } + }; // write to the document/window title this.set_pagetitle = function(title) @@ -3498,7 +3794,6 @@ if ((current_li = this.get_folder_li(old))) { $(current_li).removeClass('selected').removeClass('unfocused'); } - if ((target_li = this.get_folder_li(name))) { $(target_li).removeClass('unfocused').addClass('selected'); } @@ -3513,7 +3808,7 @@ { if (this.gui_objects.folderlist) { - name = String(name).replace(this.identifier_expr, ''); + name = String(name).replace(this.identifier_expr, '_'); return document.getElementById('rcmli'+name); } @@ -3534,7 +3829,7 @@ if ((cell = thead.rows[0].cells[n+1]) && (col=='from' || col=='to')) { // if we have links for sorting, it's a bit more complicated... - if (cell.firstChild && cell.firstChild.tagName=='A') + if (cell.firstChild && cell.firstChild.tagName.toLowerCase()=='a') { cell.firstChild.innerHTML = this.get_label(this.coltypes[n]); cell.firstChild.onclick = function(){ return rcmail.command('sort', this.__col, this); }; @@ -3580,7 +3875,7 @@ + (this.message_list.in_selection(uid) ? ' selected' : ''); // for performance use DOM instead of jQuery here - var row = document.createElement('TR'); + var row = document.createElement('tr'); row.id = 'rcmrow'+uid; row.className = css_class; @@ -3600,7 +3895,7 @@ icon = this.env.unreadicon; // add icon col - var col = document.createElement('TD'); + var col = document.createElement('td'); col.className = 'icon'; col.innerHTML = icon ? '<img src="'+icon+'" alt="" />' : ''; row.appendChild(col); @@ -3608,7 +3903,7 @@ // add each submitted col for (var n = 0; n < this.coltypes.length; n++) { var c = this.coltypes[n]; - col = document.createElement('TD'); + col = document.createElement('td'); col.className = String(c).toLowerCase(); if (c=='flag') { @@ -3626,7 +3921,6 @@ } this.message_list.insert_row(row, attop); - this.triggerEvent('insertrow', { uid:uid, row:row }); // remove 'old' row if (attop && this.env.pagesize && this.message_list.rowcount > this.env.pagesize) { @@ -3662,8 +3956,12 @@ // replace content of quota display this.set_quota = function(content) { - if (content && this.gui_objects.quotadisplay) - $(this.gui_objects.quotadisplay).html(content); + if (content && this.gui_objects.quotadisplay) { + if (typeof(content) == 'object') + this.percent_indicator(this.gui_objects.quotadisplay, content); + else + $(this.gui_objects.quotadisplay).html(content); + } }; // update the mailboxlist @@ -3743,37 +4041,6 @@ window.focus(); } - // add row to contacts list - this.add_contact_row = function(cid, cols, select) - { - if (!this.gui_objects.contactslist || !this.gui_objects.contactslist.tBodies[0]) - return false; - - var tbody = this.gui_objects.contactslist.tBodies[0]; - var rowcount = tbody.rows.length; - var even = rowcount%2; - - var row = document.createElement('TR'); - row.id = 'rcmrow'+cid; - row.className = 'contact '+(even ? 'even' : 'odd'); - - if (this.contact_list.in_selection(cid)) - row.className += ' selected'; - - // add each submitted col - for (var c in cols) { - col = document.createElement('TD'); - col.className = String(c).toLowerCase(); - col.innerHTML = cols[c]; - row.appendChild(col); - } - - this.contact_list.insert_row(row); - this.triggerEvent('insertrow', { cid:cid, row:row }); - - this.enable_command('export', (this.contact_list.rowcount > 0)); - }; - this.toggle_prefer_html = function(checkbox) { var addrbook_show_images; @@ -3823,6 +4090,61 @@ elem.onclick = function() { rcmail.load_headers(elem); } } + // percent (quota) indicator + this.percent_indicator = function(obj, data) + { + if (!data || !obj) + return false; + + var limit_high = 80; + var limit_mid = 55; + var width = data.width ? data.width : this.env.indicator_width ? this.env.indicator_width : 100; + var height = data.height ? data.height : this.env.indicator_height ? this.env.indicator_height : 14; + var quota = data.percent ? Math.abs(parseInt(data.percent)) : 0; + var quota_width = parseInt(quota / 100 * width); + var pos = $(obj).position(); + + this.env.indicator_width = width; + this.env.indicator_height = height; + + // overlimit + if (quota_width > width) { + quota_width = width; + quota = 100; + } + + // main div + var main = $('<div>'); + main.css({position: 'absolute', top: pos.top, left: pos.left, + width: width + 'px', height: height + 'px', zIndex: 100, lineHeight: height + 'px'}) + .attr('title', data.title).addClass('quota_text').html(quota + '%'); + // used bar + var bar1 = $('<div>'); + bar1.css({position: 'absolute', top: pos.top + 1, left: pos.left + 1, + width: quota_width + 'px', height: height + 'px', zIndex: 99}); + // background + var bar2 = $('<div>'); + bar2.css({position: 'absolute', top: pos.top + 1, left: pos.left + 1, + width: width + 'px', height: height + 'px', zIndex: 98}) + .addClass('quota_bg'); + + if (quota >= limit_high) { + main.addClass(' quota_text_high'); + bar1.addClass('quota_high'); + } + else if(quota >= limit_mid) { + main.addClass(' quota_text_mid'); + bar1.addClass('quota_mid'); + } + else { + main.addClass(' quota_text_normal'); + bar1.addClass('quota_low'); + } + + // replace quota image + obj.innerHTML = ''; + $(obj).append(bar1).append(bar2).append(main); + } /********************************************************/ /********* html to text conversion functions *********/ @@ -3861,7 +4183,7 @@ if (this.env.framed && window.parent) parent.location.href = url; - else + else location.href = url; }; @@ -3878,7 +4200,7 @@ var url = this.env.comm_path + '&_action=' + action + '&' + querystring // send request - console.log('HTTP POST: ' + url); + console.log('HTTP GET: ' + url); jQuery.get(url, { _unlock:(lock?1:0) }, function(data){ ref.http_response(data); }, 'json'); }; @@ -3942,8 +4264,8 @@ case 'moveto': if (this.env.action == 'show') { - // re-enable commands on move/delete error - this.enable_command('reply', 'reply-all', 'forward', 'delete', 'mark', 'print', 'open', 'viewsource', 'download', true); + // re-enable commands on move/delete error + this.enable_command('reply', 'reply-all', 'forward', 'delete', 'mark', 'print', 'open', 'edit', 'viewsource', 'download', true); } else if (this.message_list) this.message_list.init(); break; @@ -3956,8 +4278,8 @@ this.show_contentframe(false); // disable commands useless when mailbox is empty this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete', - 'mark', 'viewsource', 'open', 'download', 'print', 'load-attachment', - 'purge', 'expunge', 'select-all', 'select-none', 'sort', false); + 'mark', 'viewsource', 'open', 'edit', 'download', 'print', 'load-attachment', + 'purge', 'expunge', 'select-all', 'select-none', 'sort', false); } break; @@ -4003,15 +4325,17 @@ }; // send periodic request to check for recent messages - this.check_for_recent = function(setbusy) + this.check_for_recent = function(refresh) { if (this.busy) return; - if (setbusy) - this.set_busy(true, 'checkingmail'); - var addurl = '_t=' + (new Date().getTime()); + + if (refresh) { + this.set_busy(true, 'checkingmail'); + addurl += '&_refresh=1'; + } if (this.gui_objects.messagelist) addurl += '&_list=1'; @@ -4105,4 +4429,3 @@ rcube_webmail.prototype.addEventListener = rcube_event_engine.prototype.addEventListener; rcube_webmail.prototype.removeEventListener = rcube_event_engine.prototype.removeEventListener; rcube_webmail.prototype.triggerEvent = rcube_event_engine.prototype.triggerEvent; - -- Gitblit v1.9.1