X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=program%2Fjs%2Fapp.js;h=c871cc66356370d9bb6541afcc1e6d2ede3dae96;hb=76507f7c63a660742e76889ad6e3919f3dde3bb0;hp=e4f6a2a1b5eb4efe73bb22f8deb98cf89b24529d;hpb=1213c6e65f2bab1e140369839a9d0f6db28a9492;p=roundcube.git diff --git a/program/js/app.js b/program/js/app.js index e4f6a2a..c871cc6 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -1,4222 +1,213 @@ -/* - +-----------------------------------------------------------------------+ - | RoundCube Webmail Client Script | - | | - | This file is part of the RoundCube Webmail client | - | Copyright (C) 2005-2009, RoundCube Dev, - Switzerland | - | Licensed under the GNU GPL | - | | - +-----------------------------------------------------------------------+ - | Authors: Thomas Bruederli | - | Charles McNulty | - +-----------------------------------------------------------------------+ - | Requires: common.js, list.js | - +-----------------------------------------------------------------------+ - - $Id: app.js 2318 2009-02-27 11:06:29Z thomasb $ -*/ - - -var rcube_webmail_client; - -function rcube_webmail() - { - this.env = new Object(); - this.labels = new Object(); - this.buttons = new Object(); - this.gui_objects = new Object(); - this.commands = new Object(); - this.onloads = new Array(); - - // create protected reference to myself - rcube_webmail_client = this; - this.ref = 'rcube_webmail_client'; - var ref = this; - - // webmail client settings - this.dblclick_time = 500; - this.message_time = 3000; - - this.identifier_expr = new RegExp('[^0-9a-z\-_]', 'gi'); - - // mimetypes supported by the browser (default settings) - this.mimetypes = new Array('text/plain', 'text/html', 'text/xml', - 'image/jpeg', 'image/gif', 'image/png', - 'application/x-javascript', 'application/pdf', - 'application/x-shockwave-flash'); - - // default environment vars - this.env.keep_alive = 60; // seconds - this.env.request_timeout = 180; // seconds - this.env.draft_autosave = 0; // seconds - this.env.comm_path = './'; - this.env.bin_path = './bin/'; - this.env.blankpage = 'program/blank.gif'; - - - // set environment variable(s) - this.set_env = function(p, value) - { - if (p != null && typeof(p) == 'object' && !value) - for (var n in p) - this.env[n] = p[n]; - else - this.env[p] = value; - }; - - // add a localized label to the client environment - this.add_label = function(key, value) - { - this.labels[key] = value; - }; - - // add a button to the button list - this.register_button = function(command, id, type, act, sel, over) - { - if (!this.buttons[command]) - this.buttons[command] = new Array(); - - var button_prop = {id:id, type:type}; - if (act) button_prop.act = act; - if (sel) button_prop.sel = sel; - if (over) button_prop.over = over; - - this.buttons[command][this.buttons[command].length] = button_prop; - }; - - // register a specific gui object - this.gui_object = function(name, id) - { - this.gui_objects[name] = id; - }; - - // execute the given script on load - this.add_onload = function(f) - { - this.onloads[this.onloads.length] = f; - }; - - // initialize webmail client - this.init = function() - { - var p = this; - this.task = this.env.task; - - // check browser - if (!bw.dom || !bw.xmlhttp_test()) - { - this.goto_url('error', '_code=0x199'); - return; - } - - // find all registered gui objects - for (var n in this.gui_objects) - this.gui_objects[n] = rcube_find_object(this.gui_objects[n]); - - // tell parent window that this frame is loaded - if (this.env.framed && parent.rcmail && parent.rcmail.set_busy) - parent.rcmail.set_busy(false); - - // 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': - if (this.gui_objects.messagelist) - { - this.message_list = new rcube_list_widget(this.gui_objects.messagelist, {multiselect:true, draggable:true, keyboard:true, dblclick_time:this.dblclick_time}); - this.message_list.row_init = function(o){ p.init_message_row(o); }; - this.message_list.addEventListener('dblclick', function(o){ p.msglist_dbl_click(o); }); - 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){ p.drag_active = false; }); - - this.message_list.init(); - this.enable_command('toggle_status', 'toggle_flag', true); - - if (this.gui_objects.mailcontframe) - { - this.gui_objects.mailcontframe.onmousedown = function(e){ return p.click_on_list(e); }; - document.onmouseup = function(e){ return p.doc_mouse_up(e); }; - } - else - this.message_list.focus(); - } - - if (this.env.coltypes) - this.set_message_coltypes(this.env.coltypes); - - // enable mail commands - 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', 'load-headers', true); - if (this.env.next_uid) - { - this.enable_command('nextmessage', true); - this.enable_command('lastmessage', true); - } - if (this.env.prev_uid) - { - this.enable_command('previousmessage', true); - this.enable_command('firstmessage', true); - } - } - - if (this.env.trash_mailbox && this.env.mailbox != this.env.trash_mailbox) - this.set_alttext('delete', 'movemessagetotrash'); - - // make preview/message frame visible - if (this.env.action == 'preview' && this.env.framed && parent.rcmail) - { - this.enable_command('compose', 'add-contact', false); - parent.rcmail.show_contentframe(true); - } - - if ((this.env.action=='show' || this.env.action=='preview') && this.env.blockedobjects) - { - if (this.gui_objects.remoteobjectsmsg) - this.gui_objects.remoteobjectsmsg.style.display = 'block'; - this.enable_command('load-images', 'always-load', true); - } - - if (this.env.action=='compose') - { - this.enable_command('add-attachment', 'send-attachment', 'remove-attachment', 'send', true); - if (this.env.spellcheck) - { - 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); - - document.onmouseup = function(e){ return p.doc_mouse_up(e); }; - } - - if (this.env.messagecount) - this.enable_command('select-all', 'select-none', 'expunge', true); - - if (this.purge_mailbox_test()) - 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') - window.print(); - - // 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', ''); - } - - // ask user to send MDN - if (this.env.mdn_request && this.env.uid) - { - var mdnurl = '_uid='+this.env.uid+'&_mbox='+urlencode(this.env.mailbox); - if (confirm(this.get_label('mdnrequest'))) - this.http_post('sendmdn', mdnurl); - else - this.http_post('mark', mdnurl+'&_flag=mdnsent'); - } - - break; - - - case 'addressbook': - 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.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){ p.drag_active = false; }); - this.contact_list.init(); - - if (this.env.cid) - this.contact_list.highlight_row(this.env.cid); - - if (this.gui_objects.contactslist.parentNode) - { - this.gui_objects.contactslist.parentNode.onmousedown = function(e){ return p.click_on_list(e); }; - document.onmouseup = function(e){ return p.doc_mouse_up(e); }; - } - else - this.contact_list.focus(); - } - - 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); - - if (this.env.cid) - this.enable_command('show', 'edit', true); - - 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); - - if (this.contact_list && this.contact_list.rowcount > 0) - this.enable_command('export', true); - - this.enable_command('list', true); - break; - - - 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('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') - this.enable_command('subscribe', 'unsubscribe', 'create-folder', 'rename-folder', 'delete-folder', true); - - if (this.gui_objects.identitieslist) - { - this.identity_list = new rcube_list_widget(this.gui_objects.identitieslist, {multiselect:false, draggable:false, keyboard:false}); - this.identity_list.addEventListener('select', function(o){ p.identity_select(o); }); - this.identity_list.init(); - this.identity_list.focus(); - - if (this.env.iid) - this.identity_list.highlight_row(this.env.iid); - } - - if (this.gui_objects.subscriptionlist) - this.init_subscription_list(); - - break; - - 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; - - default: - break; - } - - // enable basic commands - this.enable_command('logout', true); - - // flag object as complete - this.loaded = true; - - // show message - if (this.pending_message) - this.display_message(this.pending_message[0], this.pending_message[1]); - - // start keep-alive interval - this.start_keepalive(); - - // execute all foreign onload scripts - for (var i=0; i= 0) - this.set_env('flagged_col', found+1); - } - - // set eventhandler to flag icon, if icon found - if (this.env.flagged_col && (row.flagged_icon = row.obj.cells[this.env.flagged_col].childNodes[0]) - && row.flagged_icon.nodeName=='IMG') - { - 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); }; - } - }; - - // init message compose form: set focus and eventhandlers - this.init_messageform = function() - { - if (!this.gui_objects.messageform) - return false; - - //this.messageform = this.gui_objects.messageform; - var input_from = rcube_find_object('_from'); - var input_to = rcube_find_object('_to'); - var input_cc = rcube_find_object('_cc'); - var input_bcc = rcube_find_object('_bcc'); - var input_replyto = rcube_find_object('_replyto'); - var input_subject = rcube_find_object('_subject'); - var input_message = rcube_find_object('_message'); - var draftid = rcube_find_object('_draft_saveid'); - - // init live search events - if (input_to) - this.init_address_input_events(input_to); - if (input_cc) - this.init_address_input_events(input_cc); - if (input_bcc) - this.init_address_input_events(input_bcc); - - // add signature according to selected identity - if (input_from && input_from.type=='select-one' && (!draftid || draftid.value=='') - // if we have HTML editor, signature is added in callback - && rcube_find_object('_is_html').value != '1') - { - this.change_identity(input_from); - } - - if (input_to && input_to.value=='') - input_to.focus(); - else if (input_subject && input_subject.value=='') - input_subject.focus(); - else if (input_message) - this.set_caret2start(input_message); - - // get summary of all field values - this.compose_field_hash(true); - - // start the auto-save timer - this.auto_save_start(); - }; - - this.init_address_input_events = function(obj) - { - var handler = function(e){ return ref.ksearch_keypress(e,this); }; - - if (obj.addEventListener) - obj.addEventListener(bw.safari ? 'keydown' : 'keypress', handler, false); - else - obj.onkeydown = handler; - - obj.setAttribute('autocomplete', 'off'); - }; - - - /*********************************************************/ - /********* client command interface *********/ - /*********************************************************/ - - // execute a specific command on the web client - this.command = function(command, props, obj) - { - if (obj && obj.blur) - obj.blur(); - - if (this.busy) - return false; - - // command not supported or allowed - if (!this.commands[command]) - { - // pass command to parent window - if (this.env.framed && parent.rcmail && parent.rcmail.command) - parent.rcmail.command(command, props); - - return false; - } - - // check input before leaving compose step - if (this.task=='mail' && this.env.action=='compose' && (command=='list' || command=='mail' || command=='addressbook' || command=='settings')) - { - if (this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning'))) - return false; - } - - // process command - switch (command) - { - case 'login': - if (this.gui_objects.loginform) - this.gui_objects.loginform.submit(); - break; - - case 'logout': - this.goto_url('logout', '', true); - break; - - // commands to switch task - case 'mail': - case 'addressbook': - case 'settings': - 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': - if (this.task=='mail') - { - if (this.env.search_request<0 || (props != '' && (this.env.search_request && props != this.env.mailbox))) - this.reset_qsearch(); - - this.list_mailbox(props); - - if (this.env.trash_mailbox) - this.set_alttext('delete', this.env.mailbox != this.env.trash_mailbox ? 'movemessagetotrash' : 'deletemessage'); - } - else if (this.task=='addressbook') - { - if (this.env.search_request<0 || (this.env.search_request && props != this.env.source)) - this.reset_qsearch(); - - 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; - - - case 'sort': - // get the type of sorting - var a_sort = props.split('_'); - var sort_col = a_sort[0]; - var sort_order = a_sort[1] ? a_sort[1].toUpperCase() : null; - var header; - - // no sort order specified: toggle - if (sort_order==null) - { - if (this.env.sort_col==sort_col) - sort_order = this.env.sort_order=='ASC' ? 'DESC' : 'ASC'; - else - sort_order = this.env.sort_order; - } - - if (this.env.sort_col==sort_col && this.env.sort_order==sort_order) - break; - - // set table header class - if (header = document.getElementById('rcm'+this.env.sort_col)) - this.set_classname(header, 'sorted'+(this.env.sort_order.toUpperCase()), false); - if (header = document.getElementById('rcm'+sort_col)) - this.set_classname(header, 'sorted'+sort_order, true); - - // save new sort properties - this.env.sort_col = sort_col; - this.env.sort_order = sort_order; - - // reload message list - this.list_mailbox('', '', sort_col+'_'+sort_order); - break; - - case 'nextpage': - this.list_page('next'); - break; - - case 'lastpage': - this.list_page('last'); - break; - - case 'previouspage': - this.list_page('prev'); - break; - - case 'firstpage': - this.list_page('first'); - break; - - case 'expunge': - if (this.env.messagecount) - this.expunge_mailbox(this.env.mailbox); - break; - - case 'purge': - case 'empty-mailbox': - if (this.env.messagecount) - this.purge_mailbox(this.env.mailbox); - break; - - - // common commands used in multiple tasks - case 'show': - if (this.task=='mail') - { - var 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); - else - this.show_message(uid); - } - } - else if (this.task=='addressbook') - { - var cid = props ? props : this.get_single_cid(); - if (cid && !(this.env.action=='show' && cid==this.env.cid)) - this.load_contact(cid, 'show'); - } - break; - - case 'add': - if (this.task=='addressbook') - this.load_contact(0, 'add'); - else if (this.task=='settings') - { - this.identity_list.clear_selection(); - this.load_identity(0, 'add-identity'); - } - break; - - case 'edit': - var cid; - if (this.task=='addressbook' && (cid = this.get_single_cid())) - this.load_contact(cid, 'edit'); - else if (this.task=='settings' && props) - this.load_identity(props, 'edit-identity'); - break; - - case 'save-identity': - case 'save': - if (this.gui_objects.editform) - { - var input_pagesize = rcube_find_object('_pagesize'); - var input_name = rcube_find_object('_name'); - var input_email = rcube_find_object('_email'); - - // user prefs - if (input_pagesize && isNaN(parseInt(input_pagesize.value))) - { - alert(this.get_label('nopagesizewarning')); - input_pagesize.focus(); - break; - } - // contacts/identities - else - { - if (input_name && input_name.value == '') - { - alert(this.get_label('nonamewarning')); - input_name.focus(); - break; - } - else if (input_email && !rcube_check_email(input_email.value)) - { - alert(this.get_label('noemailwarning')); - input_email.focus(); - break; - } - } - - this.gui_objects.editform.submit(); - } - break; - - case 'delete': - // mail task - if (this.task=='mail') - this.delete_messages(); - // addressbook task - else if (this.task=='addressbook') - this.delete_contacts(); - // user settings task - else if (this.task=='settings') - this.delete_identity(); - break; - - - // mail task commands - case 'move': - case 'moveto': - if (this.task == 'mail') - this.move_messages(props); - else if (this.task == 'addressbook' && this.drag_active) - this.copy_contact(null, props); - break; - - case 'mark': - if (props) - this.mark_message(props); - break; - - case 'toggle_status': - if (props && !props._row) - break; - - var uid; - var flag = 'read'; - - if (props._row.uid) - { - uid = props._row.uid; - - // toggle read/unread - if (this.message_list.rows[uid].deleted) { - flag = 'undelete'; - } else if (!this.message_list.rows[uid].unread) - flag = 'unread'; - } - - this.mark_message(flag, uid); - break; - - case 'toggle_flag': - if (props && !props._row) - break; - - var uid; - var flag = 'flagged'; - - if (props._row.uid) - { - uid = props._row.uid; - // toggle flagged/unflagged - if (this.message_list.rows[uid].flagged) - flag = 'unflagged'; - } - this.mark_message(flag, uid); - 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); - break; - } - - case 'load-images': - if (this.env.uid) - this.show_message(this.env.uid, true, this.env.action=='preview'); - break; - - case 'load-attachment': - var qstring = '_mbox='+urlencode(this.env.mailbox)+'&_uid='+this.env.uid+'&_part='+props.part; - - // open attachment in frame if it's of a supported mimetype - if (this.env.uid && props.mimetype && find_in_array(props.mimetype, this.mimetypes)>=0) - { - if (props.mimetype == 'text/html') - 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); - break; - } - } - - this.goto_url('get', qstring+'&_download=1', false); - break; - - case 'select-all': - this.message_list.select_all(props); - break; - - case 'select-none': - this.message_list.clear_selection(); - break; - - case 'nextmessage': - if (this.env.next_uid) - this.show_message(this.env.next_uid, false, this.env.action=='preview'); - break; - - case 'lastmessage': - if (this.env.last_uid) - this.show_message(this.env.last_uid); - break; - - case 'previousmessage': - if (this.env.prev_uid) - this.show_message(this.env.prev_uid, false, this.env.action=='preview'); - break; - - case 'firstmessage': - if (this.env.first_uid) - this.show_message(this.env.first_uid); - break; - - case 'checkmail': - this.check_for_recent(true); - break; - - case 'compose': - var url = this.env.comm_path+'&_action=compose'; - - if (this.task=='mail') - { - url += '&_mbox='+urlencode(this.env.mailbox); - - if (this.env.mailbox==this.env.drafts_mailbox) - { - var uid; - if (uid = this.get_single_uid()) - url += '&_draft_uid='+uid; - } - else if (props) - url += '&_to='+urlencode(props); - } - // modify url if we're in addressbook - else if (this.task=='addressbook') - { - // switch to mail compose step directly - if (props && props.indexOf('@') > 0) - { - url = this.get_task_url('mail', url); - this.redirect(url + '&_to='+urlencode(props)); - break; - } - - // use contact_id passed as command parameter - var a_cids = new Array(); - if (props) - a_cids[a_cids.length] = props; - // get selected contacts - else if (this.contact_list) - { - var selection = this.contact_list.get_selection(); - for (var n=0; n 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': - this.goto_url(''); - break; - - case 'identities': - this.goto_url('identities'); - break; - - case 'delete-identity': - this.delete_identity(); - - case 'folders': - this.goto_url('folders'); - break; - - case 'subscribe': - this.subscribe_folder(props); - break; - - case 'unsubscribe': - this.unsubscribe_folder(props); - break; - - case 'create-folder': - this.create_folder(props); - break; - - case 'rename-folder': - this.rename_folder(props); - break; - - case 'delete-folder': - this.delete_folder(props); - break; - - } - - return obj ? false : true; - }; - - // set command enabled or disabled - this.enable_command = function() - { - var args = arguments; - if(!args.length) return -1; - - var command; - var enable = args[args.length-1]; - - for(var n=0; n= pos.x2 - || mouse.y < pos.y1 || mouse.y >= pos.y2) - { - if (this.env.last_folder_target) { - this.set_classname(this.get_folder_li(this.env.last_folder_target), 'droptarget', false); - 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.set_classname(this.get_folder_li(k), 'droptarget', true); - this.env.last_folder_target = k; - } - else - this.set_classname(this.get_folder_li(k), 'droptarget', false); - } - } - }; - - 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('&'+urlencode(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+'&'+urlencode(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='+urlencode(this.env.collapsed_folders)); - this.set_unread_count_display(id, false); - } - } - - this.click_on_list = function(e) - { - if (this.message_list) - this.message_list.focus(); - else if (this.contact_list) - this.contact_list.focus(); - - var mbox_li; - if (mbox_li = this.get_folder_li()) - this.set_classname(mbox_li, 'unfocused', true); - - return rcube_event.get_button(e) == 2 ? true : rcube_event.cancel(e); - }; - - this.msglist_select = function(list) - { - if (this.preview_timer) - clearTimeout(this.preview_timer); - - var selected = list.selection.length==1; - - // Hide certain command buttons when Drafts folder is selected - if (this.env.mailbox == this.env.drafts_mailbox) - { - this.enable_command('reply', 'reply-all', 'forward', false); - this.enable_command('show', 'print', selected); - this.enable_command('delete', 'moveto', 'mark', (list.selection.length > 0 ? true : false)); - } - else - { - this.enable_command('show', 'reply', 'reply-all', 'forward', 'print', selected); - this.enable_command('delete', 'moveto', 'mark', (list.selection.length > 0 ? true : false)); - } - - // 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(); }, 200); - else if (this.env.contentframe) - this.show_contentframe(false); - }; - - this.msglist_dbl_click = function(list) - { - if (this.preview_timer) - clearTimeout(this.preview_timer); - - 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); - else if (uid) - this.show_message(uid, false, false); - }; - - this.msglist_keypress = function(list) - { - if (list.key_pressed == list.ENTER_KEY) - 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; - }; - - this.msglist_get_preview = function() - { - var uid = this.get_single_uid(); - if (uid && this.env.contentframe && !this.drag_active) - this.show_message(uid, false, true); - else if (this.env.contentframe) - this.show_contentframe(false); - }; - - this.check_droptarget = function(id) - { - if (this.task == 'mail') - return (this.env.mailboxes[id] && this.env.mailboxes[id].id != this.env.mailbox && !this.env.mailboxes[id].virtual); - 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') - return (id != this.env.folder); - }; - - - /*********************************************************/ - /********* (message) list functionality *********/ - /*********************************************************/ - - // when user doble-clicks on a row - this.show_message = function(id, safe, preview) - { - if (!id) return; - - var add_url = ''; - var action = preview ? 'preview': 'show'; - var target = window; - - if (preview && this.env.contentframe && window.frames && window.frames[this.env.contentframe]) - { - target = window.frames[this.env.contentframe]; - add_url = '&_framed=1'; - } - - if (safe) - add_url = '&_safe=1'; - - // also send search request to get the right messages - if (this.env.search_request) - add_url += '&_search='+this.env.search_request; - var url = '&_action='+action+'&_uid='+id+'&_mbox='+urlencode(this.env.mailbox)+add_url; - if (action == 'preview' && String(target.location.href).indexOf(url) >= 0) - this.show_contentframe(true); - else - { - this.set_busy(true, 'loading'); - target.location.href = this.env.comm_path+url; - // 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.set_message(id, 'unread', false); - if (this.env.unread_counts[this.env.mailbox]) - { - this.env.unread_counts[this.env.mailbox] -= 1; - this.set_unread_count(this.env.mailbox, this.env.unread_counts[this.env.mailbox], this.env.mailbox == 'INBOX'); - } - } - } - }; - - this.show_contentframe = function(show) - { - var frm; - if (this.env.contentframe && (frm = rcube_find_object(this.env.contentframe))) - { - 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; - } - else if (!bw.safari) - frm.style.display = show ? 'block' : 'none'; - } - - if (!show && this.busy) - this.set_busy(false); - }; - - // list a specific page - this.list_page = function(page) - { - if (page=='next') - page = this.env.current_page+1; - if (page=='last') - page = this.env.pagecount; - if (page=='prev' && this.env.current_page>1) - page = this.env.current_page-1; - if (page=='first' && this.env.current_page>1) - page = 1; - - if (page > 0 && page <= this.env.pagecount) - { - this.env.current_page = page; - - if (this.task=='mail') - this.list_mailbox(this.env.mailbox, page); - else if (this.task=='addressbook') - this.list_contacts(this.env.source, page); - } - }; - - // list messages of a specific mailbox using filter - this.filter_mailbox = function(filter) - { - var search; - if (this.gui_objects.qsearchbox) - search = this.gui_objects.qsearchbox.value; - - this.message_list.clear(); - - // reset vars - 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); - } - - - // list messages of a specific mailbox - this.list_mailbox = function(mbox, page, sort) - { - this.last_selected = 0; - var add_url = ''; - var target = window; - - if (!mbox) - mbox = this.env.mailbox; - - // add sort to url if set - if (sort) - add_url += '&_sort=' + sort; - - // 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) - { - 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'; - - this.select_folder(mbox, this.env.mailbox); - this.env.mailbox = mbox; - - // load message list remotely - if (this.gui_objects.messagelist) - { - this.list_mailbox_remote(mbox, page, add_url); - return; - } - - if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) - { - target = window.frames[this.env.contentframe]; - add_url += '&_framed=1'; - } - - // load message list to target frame/window - if (mbox) - { - this.set_busy(true, 'loading'); - target.location.href = this.env.comm_path+'&_mbox='+urlencode(mbox)+(page ? '&_page='+page : '')+add_url; - } - }; - - // send remote request to load message list - this.list_mailbox_remote = function(mbox, page, add_url) - { - // clear message list first - this.message_list.clear(); - - // send request to server - var url = '_mbox='+urlencode(mbox)+(page ? '&_page='+page : ''); - this.set_busy(true, 'loading'); - this.http_request('list', url+add_url, true); - }; - - this.expunge_mailbox = function(mbox) - { - var lock = false; - var add_url = ''; - - // lock interface if it's the active mailbox - if (mbox == this.env.mailbox) - { - lock = true; - this.set_busy(true, 'loading'); - add_url = '&_reload=1'; - } - - // send request to server - var url = '_mbox='+urlencode(mbox); - this.http_post('expunge', url+add_url, lock); - }; - - this.purge_mailbox = function(mbox) - { - var lock = false; - var add_url = ''; - - if (!confirm(this.get_label('purgefolderconfirm'))) - return false; - - // lock interface if it's the active mailbox - if (mbox == this.env.mailbox) - { - lock = true; - this.set_busy(true, 'loading'); - add_url = '&_reload=1'; - } - - // send request to server - var url = '_mbox='+urlencode(mbox); - this.http_post('purge', url+add_url, lock); - 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 (!rows[uid].flagged && 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; - - this.env.messages[uid] = rows[uid]; - } - - // 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); - } - - if (rows[uid].flagged && rows[uid].classname.indexOf('flagged')<0) - { - rows[uid].classname += ' flagged'; - this.set_classname(rows[uid].obj, 'flagged', true); - } - else if (!rows[uid].flagged && rows[uid].classname.indexOf('flagged')>=0) - { - rows[uid].classname = rows[uid].classname.replace(/\s*flagged/, ''); - this.set_classname(rows[uid].obj, 'flagged', false); - } - - this.set_message_icon(uid); - } - - // move selected messages to the specified mailbox - this.move_messages = function(mbox) - { - // exit if current or no mailbox specified or if selection is empty - if (!mbox || mbox == this.env.mailbox || (!this.env.uid && (!this.message_list || !this.message_list.get_selection().length))) - return; - - var lock = false; - var add_url = '&_target_mbox='+urlencode(mbox)+'&_from='+(this.env.action ? this.env.action : ''); - - // show wait message - if (this.env.action=='show') - { - lock = true; - this.set_busy(true, 'movingmessage'); - } - else if (!this.env.flag_for_deletion) - this.show_contentframe(false); - - // Hide message command buttons until a message is selected - this.enable_command('reply', 'reply-all', 'forward', 'delete', 'mark', 'print', false); - - this._with_selected_messages('moveto', lock, add_url, (this.env.flag_for_deletion ? false : true)); - }; - - // delete selected messages from the current mailbox - this.delete_messages = function() - { - var selection = this.message_list ? this.message_list.get_selection() : new Array(); - - // exit if no mailbox specified or if selection is empty - 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 shift was pressed delete it immediately - if (this.message_list && this.message_list.shiftkey) - { - if (confirm(this.get_label('deletemessagesconfirm'))) - this.permanently_remove_messages(); - } - 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 - this.permanently_remove_messages = function() - { - // exit if no mailbox specified or if selection is empty - if (!this.env.uid && (!this.message_list || !this.message_list.get_selection().length)) - return; - - this.show_contentframe(false); - this._with_selected_messages('delete', false, '&_from='+(this.env.action ? this.env.action : ''), true); - }; - - // 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; - for (var n=0; n=0) - message = message.substring(0, p-1) + message.substring(p+sig.length, message.length); - } - - message = message.replace(/[\r\n]+$/, ''); - - // 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 (sig.indexOf('-- ')!=0) - sig = '-- \n'+sig; - message += '\n\n'+sig; - } - } - else - { - var editor = tinyMCE.get('compose-body'); - - 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; - - 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); - } - - 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 = '
' + newsig + '
'; - } - } - - if (input_message) - input_message.value = message; - - this.env.identity = id; - return true; - }; - - this.show_attachment_form = function(a) - { - if (!this.gui_objects.uploadbox) - return false; - - var elm, list; - if (elm = this.gui_objects.uploadbox) - { - if (a && (list = this.gui_objects.attachmentlist)) - { - var pos = rcube_get_object_pos(list); - var left = pos.x; - var top = pos.y + list.offsetHeight + 10; - - elm.style.top = top+'px'; - elm.style.left = left+'px'; - } - - elm.style.visibility = a ? 'visible' : 'hidden'; - } - - // clear upload form - try { - if (!a && this.gui_objects.attachmentform != this.gui_objects.messageform) - this.gui_objects.attachmentform.reset(); - } - catch(e){} // ignore errors - - return true; - }; - - // upload attachment file - this.upload_file = function(form) - { - if (!form) - return false; - - // get file input fields - var send = false; - for (var n=0; n