From c17dc6aa31aaa6e7f61bd25993be55354e428996 Mon Sep 17 00:00:00 2001 From: alecpl <alec@alec.pl> Date: Sat, 20 Sep 2008 13:21:15 -0400 Subject: [PATCH] #1485385: fix missing close form tag --- program/js/app.js | 806 +++++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 524 insertions(+), 282 deletions(-) diff --git a/program/js/app.js b/program/js/app.js index 9682ada..d1341c7 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -122,6 +122,9 @@ // enable general commands this.enable_command('logout', 'mail', 'addressbook', 'settings', true); + if (this.env.permaurl) + this.enable_command('permaurl', true); + switch (this.task) { case 'mail': @@ -133,6 +136,7 @@ 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_active = true; if (p.preview_timer) clearTimeout(p.preview_timer); }); + this.message_list.addEventListener('dragmove', function(o, e){ p.drag_move(e); }); this.message_list.addEventListener('dragend', function(o){ p.drag_active = false; }); this.message_list.init(); @@ -151,14 +155,14 @@ this.set_message_coltypes(this.env.coltypes); // enable mail commands - this.enable_command('list', 'checkmail', 'compose', 'add-contact', 'search', 'reset-search', true); + this.enable_command('list', 'checkmail', 'compose', 'add-contact', 'search', 'reset-search', 'collapse-folder', true); if (this.env.search_text != null && document.getElementById('quicksearchbox') != null) document.getElementById('quicksearchbox').value = this.env.search_text; if (this.env.action=='show' || this.env.action=='preview') { - this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete', 'mark', 'viewsource', 'print', 'load-attachment', true); + this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete', 'mark', 'viewsource', 'print', 'load-attachment', 'load-headers', true); if (this.env.next_uid) { this.enable_command('nextmessage', true); @@ -195,6 +199,8 @@ { this.env.spellcheck.spelling_state_observer = function(s){ ref.set_spellcheck_state(s); }; this.set_spellcheck_state('ready'); + if (rcube_find_object('_is_html').value == '1') + this.display_spellcheck_controls(false); } if (this.env.drafts_mailbox) this.enable_command('savedraft', true); @@ -203,19 +209,10 @@ if (this.env.messagecount) this.enable_command('select-all', 'select-none', 'expunge', true); - if (this.env.messagecount - && (this.env.mailbox == this.env.trash_mailbox || this.env.mailbox == this.env.junk_mailbox - || this.env.mailbox.match('^' + RegExp.escape(this.env.trash_mailbox) + RegExp.escape(this.env.delimiter)) - || this.env.mailbox.match('^' + RegExp.escape(this.env.junk_mailbox) + RegExp.escape(this.env.delimiter)))) + if (this.purge_mailbox_test()) this.enable_command('purge', true); this.set_page_buttons(); - - // focus main window - if (this.env.framed && window.parent) - window.parent.focus(); - else - window.focus(); // init message compose form if (this.env.action=='compose') @@ -228,6 +225,7 @@ // get unread count for each mailbox if (this.gui_objects.mailboxlist) { + this.env.unread_counts = {}; this.gui_objects.folderlist = this.gui_objects.mailboxlist; this.http_request('getunread', ''); } @@ -252,6 +250,7 @@ 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_active = true; }); + this.contact_list.addEventListener('dragmove', function(o, e){ p.drag_move(e); }); this.contact_list.addEventListener('dragend', function(o){ p.drag_active = false; }); this.contact_list.init(); @@ -278,7 +277,10 @@ 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', true); + this.enable_command('search', 'reset-search', 'moveto', 'import', true); + + if (this.contact_list && this.contact_list.rowcount > 0) + this.enable_command('export', true); this.enable_command('list', true); break; @@ -287,8 +289,10 @@ 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') - this.enable_command('edit', 'add', 'delete', true); + if (this.env.action=='identities' || this.env.action=='edit-identity' || this.env.action=='add-identity') { + this.enable_command('add', 'delete', this.env.multiple_identities); + this.enable_command('edit', true); + } if (this.env.action=='edit-identity' || this.env.action=='add-identity') this.enable_command('save', true); @@ -315,13 +319,19 @@ case 'login': var input_user = rcube_find_object('rcmloginuser'); var input_pass = rcube_find_object('rcmloginpwd'); + var input_tz = rcube_find_object('rcmlogintz'); + if (input_user) input_user.onkeyup = function(e){ return rcmail.login_user_keyup(e); }; if (input_user && input_user.value=='') input_user.focus(); else if (input_pass) input_pass.focus(); - + + // detect client timezone + if (input_tz) + input_tz.value = new Date().getTimezoneOffset() / -60; + this.enable_command('login', true); break; @@ -374,6 +384,7 @@ row.unread = this.env.messages[uid].unread ? true : false; row.replied = this.env.messages[uid].replied ? true : false; row.flagged = this.env.messages[uid].flagged ? true : false; + row.forwarded = this.env.messages[uid].forwarded ? true : false; } // set eventhandler to message icon @@ -499,7 +510,6 @@ return false; } - // process command switch (command) { @@ -519,6 +529,12 @@ this.switch_task(command); break; + case 'permaurl': + if (obj && obj.href && obj.target) + return true; + else if (this.env.permaurl) + parent.location.href = this.env.permaurl; + break; // misc list commands case 'list': @@ -540,6 +556,11 @@ this.list_contacts(props); this.enable_command('add', (this.env.address_sources && !this.env.address_sources[props].readonly)); } + break; + + + case 'load-headers': + this.load_headers(obj); break; @@ -737,7 +758,6 @@ if (props._row.uid) { uid = props._row.uid; - this.message_list.dont_select = true; // toggle flagged/unflagged if (this.message_list.rows[uid].flagged) flag = 'unflagged'; @@ -855,11 +875,13 @@ break; case 'spellcheck': - if (this.env.spellcheck && this.env.spellcheck.spellCheck && this.spellcheck_ready) - { + if (window.tinyMCE && tinyMCE.get('compose-body')) { + tinyMCE.execCommand('mceSpellCheck', true); + } + else if (this.env.spellcheck && this.env.spellcheck.spellCheck && this.spellcheck_ready) { this.env.spellcheck.spellCheck(this.env.spellcheck.check_link); this.set_spellcheck_state('checking'); - } + } break; case 'savedraft': @@ -967,7 +989,7 @@ break; } - // reset quicksearch + // reset quicksearch case 'reset-search': var s = this.env.search_request; this.reset_qsearch(); @@ -978,6 +1000,36 @@ this.list_contacts(this.env.source); break; + case 'import': + if (this.env.action == 'import' && this.gui_objects.importform) { + var file = document.getElementById('rcmimportfile'); + if (file && !file.value) { + alert(this.get_label('selectimportfile')); + break; + } + this.gui_objects.importform.submit(); + this.set_busy(true, 'importwait'); + this.lock_form(this.gui_objects.importform, true); + } + else + this.goto_url('import'); + break; + + case 'export': + if (this.contact_list.rowcount > 0) { + var add_url = (this.env.source ? '_source='+urlencode(this.env.source)+'&' : ''); + if (this.env.search_request) + add_url += '_search='+this.env.search_request; + + this.goto_url('export', add_url); + } + break; + + // collapse/expand folder + case 'collapse-folder': + if (props) + this.collapse_folder(props); + break; // user settings commands case 'preferences': @@ -1117,36 +1169,86 @@ this.doc_mouse_up = function(e) - { - if (this.message_list) + { + var model, li; + + if (this.message_list) { this.message_list.blur(); - else if (this.contact_list) + model = this.env.mailboxes; + } + else if (this.contact_list) { this.contact_list.blur(); - }; - - this.focus_folder = function(id) - { - var li; - if (this.drag_active && this.check_droptarget(id) && (li = this.get_folder_li(id))) - this.set_classname(li, 'droptarget', true); + model = this.env.address_sources; } - - this.unfocus_folder = function(id) - { - var li; - if (this.drag_active && (li = this.get_folder_li(id))) - this.set_classname(li, 'droptarget', false); - } - - // onmouseup handler for folder list item - this.folder_mouse_up = function(id) - { - if (this.drag_active) - { - this.unfocus_folder(id); - this.command('moveto', id); + + // handle mouse release when dragging + if (this.drag_active && model) { + for (var k in model) { + if ((li = this.get_folder_li(k)) && rcube_mouse_is_over(e, li.firstChild) && this.check_droptarget(k)) { + this.set_classname(li, 'droptarget', false); + this.command('moveto', model[k].id); + break; + } } - }; + } + }; + + this.drag_move = function(e) + { + var li; + var model = this.task == 'mail' ? this.env.mailboxes : this.env.address_sources; + + if (this.gui_objects.folderlist && model) { + for (var k in model) { + if (li = this.get_folder_li(k)) + this.set_classname(li, 'droptarget', (rcube_mouse_is_over(e, li.firstChild) && this.check_droptarget(k))); + } + } + }; + + this.collapse_folder = function(id) + { + var div; + if ((li = this.get_folder_li(id)) && + (div = li.getElementsByTagName("div")[0]) && + (div.className.match(/collapsed/) || div.className.match(/expanded/))) + { + var ul = li.getElementsByTagName("ul")[0]; + if (div.className.match(/collapsed/)) + { + ul.style.display = ''; + this.set_classname(div, 'collapsed', false); + this.set_classname(div, 'expanded', true); + var reg = new RegExp('&'+escape(id)+'&'); + this.set_env('collapsed_folders', this.env.collapsed_folders.replace(reg, '')); + } + else + { + ul.style.display = 'none'; + this.set_classname(div, 'expanded', false); + this.set_classname(div, 'collapsed', true); + this.set_env('collapsed_folders', this.env.collapsed_folders+'&'+escape(id)+'&'); + + // select parent folder if one of its childs is currently selected + if (this.env.mailbox.indexOf(id + this.env.delimiter) == 0) + this.command('list', id); + } + + // Work around a bug in IE6 and IE7, see #1485309 + if ((bw.ie6 || bw.ie7) && + li.nextSibling && + (li.nextSibling.getElementsByTagName("ul").length>0) && + li.nextSibling.getElementsByTagName("ul")[0].style && + (li.nextSibling.getElementsByTagName("ul")[0].style.display!='none')) + { + li.nextSibling.getElementsByTagName("ul")[0].style.display = 'none'; + li.nextSibling.getElementsByTagName("ul")[0].style.display = ''; + } + + this.http_post('save-pref', '_name=collapsed_folders&_value='+escape(this.env.collapsed_folders)); + this.set_unread_count_display(id, false); + } + } this.click_on_list = function(e) { @@ -1159,7 +1261,7 @@ if (mbox_li = this.get_folder_li()) this.set_classname(mbox_li, 'unfocused', true); - rcube_event.cancel(e); + return rcube_event.get_button(e) == 2 ? true : rcube_event.cancel(e); }; @@ -1185,7 +1287,7 @@ // start timer for message preview (wait for double click) if (selected && this.env.contentframe && !list.multi_selecting) - this.preview_timer = window.setTimeout(function(){ ref.msglist_get_preview(); }, this.dblclick_time + 10); + this.preview_timer = window.setTimeout(function(){ ref.msglist_get_preview(); }, 200); else if (this.env.contentframe) this.show_contentframe(false); }; @@ -1210,6 +1312,8 @@ this.command('show'); else if (list.key_pressed == list.DELETE_KEY) this.command('delete'); + else if (list.key_pressed == list.BACKSPACE_KEY) + this.command('delete'); else list.shiftkey = false; }; @@ -1228,7 +1332,7 @@ this.check_droptarget = function(id) { if (this.task == 'mail') - return (id != this.env.mailbox); + return (this.env.mailboxes[id] && this.env.mailboxes[id].id != this.env.mailbox && !this.env.mailboxes[id].virtual); else if (this.task == 'addressbook') return (id != this.env.source && this.env.address_sources[id] && !this.env.address_sources[id].readonly); else if (this.task == 'settings') @@ -1239,7 +1343,6 @@ /*********************************************************/ /********* (message) list functionality *********/ /*********************************************************/ - // when user doble-clicks on a row this.show_message = function(id, safe, preview) @@ -1282,8 +1385,8 @@ if (!show && window.frames[this.env.contentframe]) { if (window.frames[this.env.contentframe].location.href.indexOf(this.env.blankpage)<0) - window.frames[this.env.contentframe].location.href = this.env.blankpage; - } + window.frames[this.env.contentframe].location.href = this.env.blankpage; + } else if (!bw.safari) frm.style.display = show ? 'block' : 'none'; } @@ -1427,7 +1530,107 @@ return true; }; - + // test if purge command is allowed + this.purge_mailbox_test = function() + { + return (this.env.messagecount && (this.env.mailbox == this.env.trash_mailbox || this.env.mailbox == this.env.junk_mailbox + || this.env.mailbox.match('^' + RegExp.escape(this.env.trash_mailbox) + RegExp.escape(this.env.delimiter)) + || this.env.mailbox.match('^' + RegExp.escape(this.env.junk_mailbox) + RegExp.escape(this.env.delimiter)))); + }; + + // set message icon + this.set_message_icon = function(uid) + { + var icn_src; + var rows = this.message_list.rows; + + if (!rows[uid]) + return false; + + if (rows[uid].deleted && this.env.deletedicon) + icn_src = this.env.deletedicon; + else if (rows[uid].replied && this.env.repliedicon) + { + if (rows[uid].forwarded && this.env.forwardedrepliedicon) + icn_src = this.env.forwardedrepliedicon; + else + icn_src = this.env.repliedicon; + } + else if (rows[uid].forwarded && this.env.forwardedicon) + icn_src = this.env.forwardedicon; + else if (rows[uid].unread && this.env.unreadicon) + icn_src = this.env.unreadicon; + else if (this.env.messageicon) + icn_src = this.env.messageicon; + + if (icn_src && rows[uid].icon) + rows[uid].icon.src = icn_src; + + icn_src = ''; + + if (rows[uid].flagged && this.env.flaggedicon) + icn_src = this.env.flaggedicon; + else if (this.env.unflaggedicon) + icn_src = this.env.unflaggedicon; + + if (rows[uid].flagged_icon && icn_src) + rows[uid].flagged_icon.src = icn_src; + } + + // set message status + this.set_message_status = function(uid, flag, status) + { + var rows = this.message_list.rows; + + if (!rows[uid]) return false; + + if (flag == 'unread') + rows[uid].unread = status; + else if(flag == 'deleted') + rows[uid].deleted = status; + else if (flag == 'replied') + rows[uid].replied = status; + else if (flag == 'forwarded') + rows[uid].forwarded = status; + else if (flag == 'flagged') + rows[uid].flagged = status; + } + + // set message row status, class and icon + this.set_message = function(uid, flag, status) + { + var rows = this.message_list.rows; + + if (!rows[uid]) return false; + + if (flag) + this.set_message_status(uid, flag, status); + + if (rows[uid].unread && rows[uid].classname.indexOf('unread')<0) + { + rows[uid].classname += ' unread'; + this.set_classname(rows[uid].obj, 'unread', true); + } + else if (!rows[uid].unread && rows[uid].classname.indexOf('unread')>=0) + { + rows[uid].classname = rows[uid].classname.replace(/\s*unread/, ''); + this.set_classname(rows[uid].obj, 'unread', false); + } + + if (rows[uid].deleted && rows[uid].classname.indexOf('deleted')<0) + { + rows[uid].classname += ' deleted'; + this.set_classname(rows[uid].obj, 'deleted', true); + } + else if (!rows[uid].deleted && rows[uid].classname.indexOf('deleted')>=0) + { + rows[uid].classname = rows[uid].classname.replace(/\s*deleted/, ''); + this.set_classname(rows[uid].obj, 'deleted', false); + } + + this.set_message_icon(uid); + } + // move selected messages to the specified mailbox this.move_messages = function(mbox) { @@ -1506,13 +1709,13 @@ // Send a specifc request with UIDs of all selected messages // @private this._with_selected_messages = function(action, lock, add_url, remove) - { + { var a_uids = new Array(); if (this.env.uid) a_uids[0] = this.env.uid; else - { + { var selection = this.message_list.get_selection(); var rows = this.message_list.rows; var id; @@ -1521,23 +1724,17 @@ id = selection[n]; a_uids[a_uids.length] = id; - if (remove) + if (remove) this.message_list.remove_row(id, (n == selection.length-1)); else - { - rows[id].deleted = true; - - if (rows[id].classname.indexOf('deleted')<0) - { - rows[id].classname += ' deleted'; - this.set_classname(rows[id].obj, 'deleted', true); - } - - if (rows[id].icon && this.env.deletedicon) - rows[id].icon.src = this.env.deletedicon; - } + { + rows[id].deleted = true; + if (this.env.read_when_deleted) + rows[id].unread = false; + this.set_message(id); } } + } // also send search request to get the right messages if (this.env.search_request) @@ -1545,7 +1742,7 @@ // send request to server this.http_post(action, '_uid='+a_uids.join(',')+'&_mbox='+urlencode(this.env.mailbox)+add_url, lock); - }; + }; // set a specific flag to one or more messages @@ -1574,14 +1771,14 @@ { 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)) - { - r_uids[r_uids.length] = id; - } + || (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)) + { + r_uids[r_uids.length] = id; + } } // nothing to do @@ -1609,88 +1806,18 @@ this.toggle_read_status = function(flag, a_uids) { // mark all message rows as read/unread - var icn_src; - var rows = this.message_list.rows; for (var i=0; i<a_uids.length; i++) - { - uid = a_uids[i]; - if (rows[uid]) - { - rows[uid].unread = (flag=='unread' ? true : false); - - if (rows[uid].classname.indexOf('unread')<0 && rows[uid].unread) - { - rows[uid].classname += ' unread'; - this.set_classname(rows[uid].obj, 'unread', true); - - if (this.env.unreadicon) - icn_src = this.env.unreadicon; - } - else if (!rows[uid].unread) - { - rows[uid].classname = rows[uid].classname.replace(/\s*unread/, ''); - this.set_classname(rows[uid].obj, 'unread', false); - - if (this.env.messageicon) - icn_src = this.env.messageicon; - } - - if (rows[uid].icon && icn_src - && !(rows[uid].replied && this.env.repliedicon) - && !(rows[uid].deleted && this.env.deletedicon)) - rows[uid].icon.src = icn_src; - } - } + this.set_message(a_uids[i], 'unread', (flag=='unread' ? true : false)); this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag='+flag); }; - // set class to read/unread - this.mark_as_read_from_preview = function(uid) - { - var icn_src; - var rows = parent.rcmail.message_list.rows; - if(rows[uid].unread) - { - rows[uid].unread = false; - rows[uid].classname = rows[uid].classname.replace(/\s*unread/, ''); - parent.rcmail.set_classname(rows[uid].obj, 'unread', false); - - if (rows[uid].replied && parent.rcmail.env.repliedicon) - icn_src = parent.rcmail.env.repliedicon; - else if (rows[uid].deleted && parent.rcmail.env.deletedicon) - icn_src = parent.rcmail.env.deletedicon; - else if (parent.rcmail.env.messageicon) - icn_src = parent.rcmail.env.messageicon; - - if (rows[uid].icon && icn_src) - rows[uid].icon.src = icn_src; - } - } - - // set image to flagged or unflagged this.toggle_flagged_status = function(flag, a_uids) { // mark all message rows as flagged/unflagged - var icn_src; - var rows = this.message_list.rows; for (var i=0; i<a_uids.length; i++) - { - uid = a_uids[i]; - if (rows[uid]) - { - rows[uid].flagged = (flag=='flagged' ? true : false); - - if (rows[uid].flagged && this.env.flaggedicon) - icn_src = this.env.flaggedicon; - else if (this.env.unflaggedicon) - icn_src = this.env.unflaggedicon; - - if (rows[uid].flagged_icon && icn_src) - rows[uid].flagged_icon.src = icn_src; - } - } + this.set_message(a_uids[i], 'flagged', (flag=='flagged' ? true : false)); this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag='+flag); }; @@ -1702,7 +1829,7 @@ if (a_uids.length==1) { - if (!rows.length || (rows[a_uids[0]] && rows[a_uids[0]].classname.indexOf('deleted') < 0)) + if (!rows.length || (rows[a_uids[0]] && !rows[a_uids[0]].deleted)) this.flag_as_deleted(a_uids); else this.flag_as_undeleted(a_uids); @@ -1715,7 +1842,7 @@ { uid = a_uids[i]; if (rows[uid]) { - if (rows[uid].classname.indexOf('deleted')<0) + if (!rows[uid].deleted) { all_deleted = false; break; @@ -1734,31 +1861,8 @@ this.flag_as_undeleted = function(a_uids) { - var icn_src; - var rows = this.message_list ? this.message_list.rows : new Array(); - for (var i=0; i<a_uids.length; i++) - { - uid = a_uids[i]; - if (rows[uid]) { - rows[uid].deleted = false; - - if (rows[uid].classname.indexOf('deleted') > 0) - { - rows[uid].classname = rows[uid].classname.replace(/\s*deleted/, ''); - this.set_classname(rows[uid].obj, 'deleted', false); - } - if (rows[uid].unread && this.env.unreadicon) - icn_src = this.env.unreadicon; - else if (rows[uid].replied && this.env.repliedicon) - icn_src = this.env.repliedicon; - else if (this.env.messageicon) - icn_src = this.env.messageicon; - - if (rows[uid].icon && icn_src) - rows[uid].icon.src = icn_src; - } - } + this.set_message(a_uids[i], 'deleted', false); this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag=undelete'); return true; @@ -1776,19 +1880,9 @@ uid = a_uids[i]; if (rows[uid]) { - rows[uid].deleted = true; - - if (rows[uid].classname.indexOf('deleted')<0) - { - rows[uid].classname += ' deleted'; - this.set_classname(rows[uid].obj, 'deleted', true); - } - - if (rows[uid].icon && this.env.deletedicon) - rows[uid].icon.src = this.env.deletedicon; - - if (rows[uid].unread) - r_uids[r_uids.length] = uid; + this.set_message(uid, 'deleted', true); + if (rows[uid].unread) + r_uids[r_uids.length] = uid; } } @@ -1817,17 +1911,13 @@ if (rows[uid]) { rows[uid].unread = false; - rows[uid].read = true; - - rows[uid].classname = rows[uid].classname.replace(/\s*unread/, ''); - this.set_classname(rows[uid].obj, 'unread', false); - - if (rows[uid].icon) - rows[uid].icon.src = this.env.deletedicon; + rows[uid].read = true; + this.set_message(uid); } } }; - + + /*********************************************************/ /********* login form methods *********/ /*********************************************************/ @@ -1889,17 +1979,27 @@ } // check for empty body - if ((((!window.tinyMCE || !tinyMCE.get('compose-body')) && input_message.value == '') - || (window.tinyMCE && tinyMCE.get('compose-body') && tinyMCE.get('compose-body').getContent() == '')) - && !confirm(this.get_label('nobodywarning'))) + if ((!window.tinyMCE || !tinyMCE.get('compose-body')) && input_message.value == '' && !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'))) + { + tinyMCE.get('compose-body').focus(); return false; } return true; }; + this.display_spellcheck_controls = function(vis) + { + if (this.env.spellcheck) { + this.env.spellcheck.check_link.style.visibility = vis ? 'visible' : 'hidden'; + this.env.spellcheck.switch_lan_pic.style.visibility = vis ? 'visible' : 'hidden'; + } + }; this.set_spellcheck_state = function(s) { @@ -1978,8 +2078,12 @@ // remove the 'old' signature if (this.env.identity && this.env.signatures && this.env.signatures[this.env.identity]) { - sig = this.env.signatures[this.env.identity]['text']; - if (sig.indexOf('-- ')!=0) + 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 (sig.indexOf('-- ')!=0) sig = '-- \n'+sig; p = message.lastIndexOf(sig); @@ -2004,24 +2108,30 @@ { var editor = tinyMCE.get('compose-body'); - if (this.env.signatures && this.env.signatures[id]) + if (this.env.signatures) { - // Append the signature as a span within the body + // Append the signature as a div within the body var sigElem = editor.dom.get("_rc_sig"); + var newsig = ''; + var htmlsig = true; + if (!sigElem) { - sigElem = editor.getDoc().createElement("span"); + sigElem = editor.getDoc().createElement("div"); sigElem.setAttribute("id", "_rc_sig"); editor.getBody().appendChild(sigElem); } - if (this.env.signatures[id]['is_html']) - { - sigElem.innerHTML = this.env.signatures[id]['text']; - } + + if (this.env.signatures[id]) + { + newsig = this.env.signatures[id]['text']; + htmlsig = this.env.signatures[id]['is_html']; + } + + if (htmlsig) + sigElem.innerHTML = newsig; else - { - sigElem.innerHTML = '<pre>' + this.env.signatures[id]['text'] + '</pre>'; - } + sigElem.innerHTML = '<pre>' + newsig + '</pre>'; } } @@ -2189,17 +2299,16 @@ }; - this.sent_successfully = function(msg) + this.sent_successfully = function(type, msg) { this.list_mailbox(); - this.display_message(msg, 'confirmation', true); + this.display_message(msg, type, true); } /*********************************************************/ /********* keyboard live-search methods *********/ /*********************************************************/ - // handler for keyboard events on address-fields this.ksearch_keypress = function(e, obj) @@ -2421,7 +2530,6 @@ /********* address book methods *********/ /*********************************************************/ - this.contactlist_keypress = function(list) { if (list.key_pressed == list.DELETE_KEY) @@ -2436,12 +2544,12 @@ var id, frame, ref = this; if (id = list.get_single_selection()) - this.preview_timer = window.setTimeout(function(){ ref.load_contact(id, 'show'); }, this.dblclick_time + 10); + this.preview_timer = window.setTimeout(function(){ ref.load_contact(id, 'show'); }, 200); else if (this.env.contentframe) this.show_contentframe(false); - this.enable_command('edit', id?true:false); this.enable_command('compose', list.selection.length > 0); + this.enable_command('edit', (id && this.env.address_sources && !this.env.address_sources[this.env.source].readonly) ? true : false); this.enable_command('delete', list.selection.length && this.env.address_sources && !this.env.address_sources[this.env.source].readonly); return false; @@ -2759,6 +2867,7 @@ if (this.env.folder && name != '') name = this.env.folder+this.env.delimiter+name; + this.set_busy(true, 'foldercreating'); this.http_post('create-folder', '_name='+urlencode(name), true); } else if (form.elements['_folder_name']) @@ -2833,6 +2942,7 @@ if (this.name_input.__parent) newname = this.name_input.__parent + this.env.delimiter + newname; + this.set_busy(true, 'folderrenaming'); this.http_post('rename-folder', '_folder_oldname='+urlencode(this.env.subscriptionrows[this.edit_folder][0])+'&_folder_newname='+urlencode(newname), true); } } @@ -2852,7 +2962,8 @@ if (folder && confirm(this.get_label('deletefolderconfirm'))) { - this.http_post('delete-folder', '_mboxes='+urlencode(folder)); + this.set_busy(true, 'folderdeleting'); + this.http_post('delete-folder', '_mboxes='+urlencode(folder), true); this.set_env('folder', null); if (this.gui_objects.createfolderhint) @@ -2895,12 +3006,12 @@ row.id = id; if (before && (before = this.get_folder_row_id(before))) - tbody.insertBefore(row, document.getElementById(before)); + tbody.insertBefore(row, document.getElementById(before)); else - tbody.appendChild(row); + tbody.appendChild(row); if (replace) - tbody.removeChild(replace); + tbody.removeChild(replace); } // add to folder/row-ID map @@ -3022,9 +3133,9 @@ { var cell, td; var new_row = document.createElement('TR'); - for(var n=0; n<row.childNodes.length; n++) + for(var n=0; n<row.cells.length; n++) { - cell = row.childNodes[n]; + cell = row.cells[n]; td = document.createElement('TD'); if (cell.className) @@ -3334,6 +3445,7 @@ this.env.messages[uid] = {deleted:flags.deleted?1:0, replied:flags.replied?1:0, unread:flags.unread?1:0, + forwarded:flags.forwarded?1:0, flagged:flags.flagged?1:0}; var row = document.createElement('TR'); @@ -3343,10 +3455,21 @@ if (this.message_list.in_selection(uid)) row.className += ' selected'; - var icon = flags.deleted && this.env.deletedicon ? this.env.deletedicon: - (flags.unread && this.env.unreadicon ? this.env.unreadicon : - (flags.replied && this.env.repliedicon ? this.env.repliedicon : this.env.messageicon)); - + var icon = this.env.messageicon; + if (flags.deleted && this.env.deletedicon) + icon = this.env.deletedicon; + else if (flags.replied && this.env.repliedicon) + { + if (flags.forwarded && this.env.forwardedrepliedicon) + icon = this.env.forwardedrepliedicon; + else + icon = this.env.repliedicon; + } + else if (flags.forwarded && this.env.forwardedicon) + icon = this.env.forwardedicon; + else if(flags.unread && this.env.unreadicon) + icon = this.env.unreadicon; + var col = document.createElement('TD'); col.className = 'icon'; col.innerHTML = icon ? '<img src="'+icon+'" alt="" />' : ''; @@ -3378,6 +3501,14 @@ row.appendChild(col); this.message_list.insert_row(row, attop); + + // remove 'old' row + if (attop && this.env.pagesize && this.message_list.rowcount > this.env.pagesize) + { + var uid = this.message_list.get_last_row(); + this.message_list.remove_row(uid); + this.message_list.clear_selection(uid); + } }; @@ -3391,6 +3522,13 @@ this.set_page_buttons(); }; + + // replace content of mailboxname display + this.set_mailboxname = function(content) + { + if (this.gui_objects.mailboxname && content) + this.gui_objects.mailboxname.innerHTML = content; + }; // replace content of quota display this.set_quota = function(content) @@ -3406,22 +3544,46 @@ if (!this.gui_objects.mailboxlist) return false; - var reg, text_obj, item; + this.env.unread_counts[mbox] = count; + this.set_unread_count_display(mbox, set_title); + } + + + // update the mailbox count display + this.set_unread_count_display = function(mbox, set_title) + { + var reg, text_obj, item, mycount, childcount, div; if (item = this.get_folder_li(mbox)) { - // set new text - text_obj = item.firstChild; + mycount = this.env.unread_counts[mbox]; + text_obj = item.getElementsByTagName('a')[0]; reg = /\s+\([0-9]+\)$/i; - if (count && text_obj.innerHTML.match(reg)) - text_obj.innerHTML = text_obj.innerHTML.replace(reg, ' ('+count+')'); - else if (count) - text_obj.innerHTML += ' ('+count+')'; + childcount = 0; + if ((div = item.getElementsByTagName('div')[0]) && + div.className.match(/collapsed/)) + { + // add children's counters + for (var k in this.env.unread_counts) + if (k.indexOf(mbox + this.env.delimiter) == 0) { + childcount += this.env.unread_counts[k]; + } + } + + if (mycount && text_obj.innerHTML.match(reg)) + text_obj.innerHTML = text_obj.innerHTML.replace(reg, ' ('+mycount+')'); + else if (mycount) + text_obj.innerHTML += ' ('+mycount+')'; else text_obj.innerHTML = text_obj.innerHTML.replace(reg, ''); + // set parent's display + reg = new RegExp(RegExp.escape(this.env.delimiter) + '[^' + RegExp.escape(this.env.delimiter) + ']+'); + if (mbox.match(reg)) + this.set_unread_count_display(mbox.replace(reg, ''), false); + // set the right classes - this.set_classname(item, 'unread', count>0 ? true : false); + this.set_classname(item, 'unread', (mycount+childcount)>0 ? true : false); } // set unread count to window title @@ -3431,10 +3593,10 @@ var doc_title = String(document.title); var new_title = ""; - if (count && doc_title.match(reg)) - new_title = doc_title.replace(reg, '('+count+') '); - else if (count) - new_title = '('+count+') '+doc_title; + if (mycount && doc_title.match(reg)) + new_title = doc_title.replace(reg, '('+mycount+') '); + else if (mycount) + new_title = '('+mycount+') '+doc_title; else new_title = doc_title.replace(reg, ''); @@ -3442,12 +3604,6 @@ } }; - // update parent's mailboxlist (from preview) - this.set_unread_count_from_preview = function(mbox, count, set_title) - { - parent.rcmail.set_unread_count(mbox, count, set_title); - } - // add row to contacts list this.add_contact_row = function(cid, cols, select) { @@ -3475,19 +3631,28 @@ } this.contact_list.insert_row(row); + this.enable_command('export', (this.contact_list.rowcount > 0)); }; this.toggle_editor = function(checkbox, textAreaId) { var ischecked = checkbox.checked; + var composeElement = document.getElementById(textAreaId); + if (ischecked) { - tinyMCE.execCommand('mceAddControl', true, textAreaId); + var existingPlainText = composeElement.value; + var htmlText = "<pre>" + existingPlainText + "</pre>"; + composeElement.value = htmlText; + tinyMCE.execCommand('mceAddControl', true, textAreaId); } else { - tinyMCE.execCommand('mceRemoveControl', true, textAreaId); + var thisMCE = tinyMCE.get(textAreaId); + var existingHtml = thisMCE.getContent(); + this.html2plain(existingHtml, textAreaId); + tinyMCE.execCommand('mceRemoveControl', true, textAreaId); } }; @@ -3499,6 +3664,81 @@ addrbook_show_images.disabled = !checkbox.checked; } + + // display fetched raw headers + this.set_headers = function(content) + { + if (this.gui_objects.all_headers_row && this.gui_objects.all_headers_box && content) + { + var box = this.gui_objects.all_headers_box; + box.innerHTML = content; + box.style.display = 'block'; + + if (this.env.framed && parent.rcmail) + parent.rcmail.set_busy(false); + else + this.set_busy(false); + } + }; + + + // display all-headers row and fetch raw message headers + this.load_headers = function(elem) + { + if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box || !this.env.uid) + return; + + this.set_classname(elem, 'show-headers', false); + this.set_classname(elem, 'hide-headers', true); + this.gui_objects.all_headers_row.style.display = bw.ie ? 'block' : 'table-row'; + elem.onclick = function() { rcmail.hide_headers(elem); } + + // fetch headers only once + if (!this.gui_objects.all_headers_box.innerHTML) + { + this.display_message(this.get_label('loading'), 'loading', true); + this.http_post('headers', '_uid='+this.env.uid); + } + } + + + // hide all-headers row + this.hide_headers = function(elem) + { + if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box) + return; + + this.set_classname(elem, 'hide-headers', false); + this.set_classname(elem, 'show-headers', true); + this.gui_objects.all_headers_row.style.display = 'none'; + elem.onclick = function() { rcmail.load_headers(elem); } + } + + + /********************************************************/ + /********* html to text conversion functions *********/ + /********************************************************/ + + this.html2plain = function(htmlText, id) + { + var http_request = new rcube_http_request(); + var url = this.env.bin_path+'html2text.php'; + var rcmail = this; + + this.set_busy(true, 'converting'); + console.log('HTTP POST: '+url); + + http_request.onerror = function(o) { rcmail.http_error(o); }; + http_request.oncomplete = function(o) { rcmail.set_text_value(o, id); }; + http_request.POST(url, htmlText, 'application/octet-stream'); + } + + this.set_text_value = function(httpRequest, id) + { + this.set_busy(false); + document.getElementById(id).value = httpRequest.get_text(); + console.log(httpRequest.get_text()); + } /********************************************************/ @@ -3606,7 +3846,7 @@ } if (request_obj.__lock) - this.set_busy(false); + this.set_busy(false); console.log(request_obj.get_text()); @@ -3615,45 +3855,47 @@ eval(request_obj.get_text()); // process the response data according to the sent action - switch (request_obj.__action) - { - + switch (request_obj.__action) { case 'delete': + if (this.task == 'addressbook') { + var uid = this.contact_list.get_selection(); + this.enable_command('compose', (uid && this.contact_list.rows[uid])); + this.enable_command('delete', 'edit', (uid && this.contact_list.rows[uid] && this.env.address_sources && !this.env.address_sources[this.env.source].readonly)); + this.enable_command('export', (this.contact_list && this.contact_list.rowcount > 0)); + } + case 'moveto': - if (this.env.action=='show') + if (this.env.action == 'show') this.command('list'); else if (this.message_list) this.message_list.init(); - + break; + case 'purge': case 'expunge': - if (!this.env.messagecount) - { - // clear preview pane content - if (this.env.contentframe) - this.show_contentframe(false); - // disable commands useless when mailbox is empty - this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete', 'mark', 'viewsource', - 'print', 'load-attachment', 'purge', 'expunge', 'select-all', 'select-none', 'sort', false); - } - - break; - - case 'list': - this.msglist_select(this.message_list); + if (!this.env.messagecount && this.task == 'mail') { + // clear preview pane content + if (this.env.contentframe) + this.show_contentframe(false); + // disable commands useless when mailbox is empty + this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete', 'mark', 'viewsource', + 'print', 'load-attachment', 'purge', 'expunge', 'select-all', 'select-none', 'sort', false); + } + break; case 'check-recent': case 'getunread': - this.enable_command('show', 'expunge', 'select-all', 'select-none', 'sort', (this.env.messagecount > 0)); - var mailboxtest = (this.env.mailbox == this.env.trash_mailbox || this.env.mailbox == this.env.junk_mailbox - || this.env.mailbox.match('^' + RegExp.escape(this.env.trash_mailbox) + RegExp.escape(this.env.delimiter)) - || this.env.mailbox.match('^' + RegExp.escape(this.env.junk_mailbox) + RegExp.escape(this.env.delimiter))) ? true : false; - - this.enable_command('purge', (this.env.messagecount && mailboxtest)); - - break; - - } + case 'list': + if (this.task == 'mail') { + if (this.message_list) + this.msglist_select(this.message_list); + this.enable_command('show', 'expunge', 'select-all', 'select-none', 'sort', (this.env.messagecount > 0)); + this.enable_command('purge', this.purge_mailbox_test()); + } + else if (this.task == 'addressbook') + this.enable_command('export', (this.contact_list && this.contact_list.rowcount > 0)); + break; + } request_obj.reset(); }; @@ -3662,13 +3904,14 @@ // handle HTTP request errors this.http_error = function(request_obj) { - //alert('Error sending request: '+request_obj.url); + //alert('Error sending request: '+request_obj.url+' => HTTP '+request_obj.xmlhttp.status); if (request_obj.__lock) this.set_busy(false); request_obj.reset(); request_obj.__lock = false; + this.display_message('Unknown Server Error!', 'error'); }; @@ -3833,7 +4076,7 @@ this.busy = true; this.xmlhttp.onreadystatechange = function(){ _ref.xmlhttp_onreadystatechange(); }; - this.xmlhttp.open('GET', url); + this.xmlhttp.open('GET', url, true); this.xmlhttp.setRequestHeader('X-RoundCube-Referer', bw.get_cookie('roundcube_sessid')); this.xmlhttp.send(null); }; @@ -3932,4 +4175,3 @@ window.setTimeout('if (window[\''+o+'\'] && window[\''+o+'\'].init) { '+o+'.init(); }', bw.win ? 500 : 200); } - -- Gitblit v1.9.1