thomascube
2007-08-10 31d9efd97d9da09605d4329457ee218cba48f82f
program/js/app.js
@@ -3,7 +3,7 @@
 | RoundCube Webmail Client Script                                       |
 |                                                                       |
 | This file is part of the RoundCube Webmail client                     |
 | Copyright (C) 2005-2006, RoundCube Dev, - Switzerland                 |
 | Copyright (C) 2005-2007, RoundCube Dev, - Switzerland                 |
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
@@ -35,9 +35,9 @@
 
  // webmail client settings
  this.dblclick_time = 500;
  this.message_time = 5000;
  this.message_time = 3000;
  
  this.mbox_expression = new RegExp('[^0-9a-z\-_]', 'gi');
  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',
@@ -49,12 +49,19 @@
  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
  this.set_env = function(name, value)
  // set environment variable(s)
  this.set_env = function(p, value)
    {
    this.env[name] = value;
    if (p != null && typeof(p) == 'object' && !value)
      for (var n in p)
        this.env[n] = p[n];
    else
      this.env[p] = value;
    };
@@ -162,8 +169,8 @@
        if (this.env.action == 'preview' && this.env.framed && parent.rcmail)
          {
          this.enable_command('compose', 'add-contact', false);
          parent.rcmail.show_messageframe(true);
          parent.rcmail.mark_message('read', this.uid);
          parent.rcmail.show_contentframe(true);
          parent.rcmail.mark_message('read', this.env.uid);
          }
        if ((this.env.action=='show' || this.env.action=='preview') && this.env.blockedobjects)
@@ -178,7 +185,7 @@
          this.enable_command('add-attachment', 'send-attachment', 'remove-attachment', 'send', true);
          if (this.env.spellcheck)
            {
            this.env.spellcheck.spelling_state_observer = function(s){ rcube_webmail_client.set_spellcheck_state(s); };
            this.env.spellcheck.spelling_state_observer = function(s){ ref.set_spellcheck_state(s); };
            this.set_spellcheck_state('ready');
            }
          if (this.env.drafts_mailbox)
@@ -206,7 +213,10 @@
        // get unread count for each mailbox
        if (this.gui_objects.mailboxlist)
        {
          this.gui_objects.folderlist = this.gui_objects.mailboxlist;
          this.http_request('getunread', '');
        }
        break;
@@ -214,9 +224,11 @@
      case 'addressbook':
        if (this.gui_objects.contactslist)
          {
          this.contact_list = new rcube_list_widget(this.gui_objects.contactslist, {multiselect:true, draggable:false, keyboard:true});
          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_active = true; });
          this.contact_list.addEventListener('dragend', function(o){ p.drag_active = false; });
          this.contact_list.init();
          if (this.env.cid)
@@ -232,17 +244,19 @@
          }
        this.set_page_buttons();
        if (this.env.address_sources && !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', true);
        this.enable_command('list', 'add', true);
        // this.enable_command('ldappublicsearch', this.env.ldappublicsearch);
        this.enable_command('list', true);
        break;
@@ -274,6 +288,8 @@
      case 'login':
        var input_user = rcube_find_object('_user');
        var input_pass = rcube_find_object('_pass');
        if (input_user)
          input_user.onkeypress = function(e){ return rcmail.login_user_keypress(e); };
        if (input_user && input_user.value=='')
          input_user.focus();
        else if (input_pass)
@@ -327,9 +343,9 @@
    var uid = row.uid;
    if (uid && this.env.messages[uid])
      {
      row.deleted = this.env.messages[uid].deleted;
      row.unread = this.env.messages[uid].unread;
      row.replied = this.env.messages[uid].replied;
      row.deleted = this.env.messages[uid].deleted ? true : false;
      row.unread = this.env.messages[uid].unread ? true : false;
      row.replied = this.env.messages[uid].replied ? true : false;
      }
    // set eventhandler to message icon
@@ -378,7 +394,7 @@
      this.set_caret2start(input_message);
    // get summary of all field values
    this.cmp_hash = this.compose_field_hash();
    this.compose_field_hash(true);
 
    // start the auto-save timer
    this.auto_save_start();
@@ -386,18 +402,19 @@
  this.init_address_input_events = function(obj)
    {
    var handler = function(e){ return rcube_webmail_client.ksearch_keypress(e,this); };
    var handler2 = function(e){ return rcube_webmail_client.ksearch_blur(e,this); };
    if (bw.safari)
      obj.addEventListener('keydown', handler, false);
    else if (bw.mz)
      {
      obj.addEventListener('keypress', handler, false);
    var handler = function(e){ return ref.ksearch_keypress(e,this); };
    var handler2 = function(e){ return ref.ksearch_blur(e,this); };
    if (obj.addEventListener)
    {
      obj.addEventListener(bw.safari ? 'keydown' : 'keypress', handler, false);
      obj.addEventListener('blur', handler2, false);
      }
    else if (bw.ie)
    }
    else
    {
      obj.onkeydown = handler;
      obj.onblur = handler2;
    }
    obj.setAttribute('autocomplete', 'off');       
    };
@@ -446,7 +463,7 @@
        break;
      case 'logout':
        this.goto_url('logout');
        this.goto_url('logout', true);
        break;      
      // commands to switch task
@@ -467,7 +484,13 @@
          this.list_mailbox(props);
          }
        else if (this.task=='addressbook')
          this.list_contacts();
          {
          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;
@@ -556,18 +579,6 @@
      case 'add':
        if (this.task=='addressbook')
          this.load_contact(0, 'add');
        /* LDAP stuff, has to be re-written with new address book
          if (!window.frames[this.env.contentframe].rcmail)
            this.load_contact(0, 'add');
          else
            {
            if (window.frames[this.env.contentframe].rcmail.selection.length)
              this.add_ldap_contacts();
            else
              this.load_contact(0, 'add');
            }
        */
        else if (this.task=='settings')
          {
          this.identity_list.clear_selection();
@@ -635,7 +646,10 @@
      // mail task commands
      case 'move':
      case 'moveto':
        this.move_messages(props);
        if (this.task == 'mail')
          this.move_messages(props);
        else if (this.task == 'addressbook' && this.drag_active)
          this.copy_contact(null, props);
        break;
        
      case 'toggle_status':
@@ -680,7 +694,7 @@
            }
          }
        this.goto_url('get', qstring+'&_download=1');
        this.goto_url('get', qstring+'&_download=1', false);
        break;
        
      case 'select-all':
@@ -723,55 +737,42 @@
          var uid;
          if (uid = this.get_single_uid())
            url += '&_draft_uid='+uid+'&_mbox='+urlencode(this.env.mailbox);
          }
          }
        // modify url if we're in addressbook
        else if (this.task=='addressbook')
          {
          url = this.get_task_url('mail', url);
          var a_cids = new Array();
          // 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
          else if (this.contact_list)
            {
            var selection = this.contact_list.get_selection();
            for (var n=0; n<selection.length; n++)
              a_cids[a_cids.length] = selection[n];
            /* LDAP stuff, has to be re-written with new address book
            if (!window.frames[this.env.contentframe].rcmail.selection.length)
              {
              for (var n=0; n<selection.length; n++)
                a_cids[a_cids.length] = selection[n];
              }
            else
              {
              var frameRcmail = window.frames[this.env.contentframe].rcmail;
              // get the email address(es)
              for (var n=0; n<frameRcmail.selection.length; n++)
                a_cids[a_cids.length] = frameRcmail.ldap_contact_rows[frameRcmail.selection[n]].obj.cells[1].innerHTML;
              }
            */
            }
          if (a_cids.length)
            url += '&_to='+a_cids.join(',');
          else
            break;
            this.http_request('mailto', '_cid='+urlencode(a_cids.join(','))+'&_source='+urlencode(this.env.source), true);
          break;
          }
        else if (props)
           url += '&_to='+urlencode(props);
        // don't know if this is necessary...
        url = url.replace(/&_framed=1/, "");
        this.set_busy(true);
        // need parent in case we are coming from the contact frame
        if (this.env.framed)
          parent.location.href = url;
        else
          location.href = url;
        this.redirect(url);
        break;
        
      case 'spellcheck':
@@ -872,30 +873,26 @@
        this.add_contact(props);
        break;
      
      // mail quicksearch
      // quicksearch
      case 'search':
        if (!props && this.gui_objects.qsearchbox)
          props = this.gui_objects.qsearchbox.value;
        if (props)
          this.qsearch(urlencode(props), this.env.mailbox);
        break;
        {
          this.qsearch(props);
          break;
        }
      // reset quicksearch        
      case 'reset-search':
        var s = this.env.search_request;
        this.reset_qsearch();
        
        if (s)
        if (s && this.env.mailbox)
          this.list_mailbox(this.env.mailbox);
        else if (s && this.task == 'addressbook')
          this.list_contacts(this.env.source);
        break;
      // ldap search
      case 'ldappublicsearch':
        if (this.gui_objects.ldappublicsearchform)
          this.gui_objects.ldappublicsearchform.submit();
        else
          this.ldappublicsearch(command);
        break;
      // user settings commands
@@ -971,7 +968,7 @@
      this.display_message(msg, 'loading', true);
      }
    else if (!a && this.busy)
    else if (!a)
      this.hide_message();
    this.busy = a;
@@ -1010,8 +1007,7 @@
    if (task=='mail')
      url += '&_mbox=INBOX';
    this.set_busy(true);
    location.href = url;
    this.redirect(url);
    };
@@ -1045,21 +1041,33 @@
      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);
    }
  // onmouseup handler for mailboxlist item
  this.mbox_mouse_up = function(mbox)
  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_mailbox(mbox);
      this.command('moveto', mbox);
      this.unfocus_folder(id);
      this.command('moveto', id);
      }
    else
      this.command('list', mbox);
    // Hide message command buttons until a message is selected
    this.enable_command('reply', 'reply-all', 'forward', 'delete', 'print', false);
    return false;
    };
  this.click_on_list = function(e)
    {
@@ -1069,7 +1077,7 @@
        this.contact_list.focus();
    var mbox_li;
    if (mbox_li = this.get_mailbox_li())
    if (mbox_li = this.get_folder_li())
      this.set_classname(mbox_li, 'unfocused', true);
    rcube_event.cancel(e);
@@ -1082,22 +1090,23 @@
      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('show', selected);
      this.enable_command('delete', 'moveto', list.selection.length>0 ? true : false);
      this.enable_command('reply', 'reply-all', 'forward', false);
      this.enable_command('show', 'delete', 'moveto', selected);
      }
    else
      {
      this.enable_command('show', 'reply', 'reply-all', 'forward', 'print', selected);
      this.enable_command('delete', 'moveto', list.selection.length>0 ? true : false);
      this.enable_command('show', 'reply', 'reply-all', 'forward', 'print', 'delete', 'moveto', selected);
      }
    // start timer for message preview (wait for double click)
    if (selected && this.env.contentframe)
      this.preview_timer = setTimeout(function(){ ref.msglist_get_preview(); }, this.dblclick_time + 10);
    else if (this.env.contentframe)
      this.show_messageframe(false);
      this.show_contentframe(false);
    };
@@ -1126,10 +1135,19 @@
  this.msglist_get_preview = function()
  {
    var uid = this.get_single_uid();
    if (uid && this.env.contentframe)
    if (uid && this.env.contentframe && !this.drag_active)
      this.show_message(uid, false, true);
    else if (this.env.contentframe)
      this.show_messageframe(false);
      this.show_contentframe(false);
  };
  this.check_droptarget = function(id)
  {
    if (this.task == 'mail')
      return (id != this.env.mailbox);
    else if (this.task == 'addressbook')
      return (id != this.env.source && this.env.address_sources[id] && !this.env.address_sources[id].readonly);
  };
@@ -1157,7 +1175,7 @@
      {
      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_messageframe(true);
        this.show_contentframe(true);
      else
        {
        this.set_busy(true, 'loading');
@@ -1167,14 +1185,15 @@
    };
  this.show_messageframe = function(show)
  this.show_contentframe = function(show)
    {
    var frm;
    if (this.env.contentframe && (frm = rcube_find_object(this.env.contentframe)))
      {
      if (window.frames[this.env.contentframe] && !show)
        window.frames[this.env.contentframe].location.href = 'program/blank.gif';
      frm.style.display = show ? 'block' : 'none';
      if (!show && window.frames[this.env.contentframe] && frames[this.env.contentframe].location.href.indexOf(this.env.blankpage)<0)
        frames[this.env.contentframe].location.href = this.env.blankpage;
      if (!bw.safari)
        frm.style.display = show ? 'block' : 'none';
      }
      
    if (!show && this.busy)
@@ -1201,7 +1220,7 @@
      if (this.task=='mail')
        this.list_mailbox(this.env.mailbox, page);
      else if (this.task=='addressbook')
        this.list_contacts(page);
        this.list_contacts(this.env.source, page);
      }
    };
@@ -1219,23 +1238,26 @@
    // 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;
      add_url += '&_refresh=1';
      this.env.current_page = page;
      if (this.message_list)
        this.message_list.clear_selection();
      this.show_messageframe(false);
      this.show_contentframe(false);
      }
    
    // also send search request to get the right messages
    if (this.env.search_request)
      add_url += '&_search='+this.env.search_request;
    this.select_mailbox(mbox);
    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)
@@ -1287,7 +1309,7 @@
    // send request to server
    var url = '_mbox='+urlencode(mbox);
    this.http_request('expunge', url+add_url, lock);
    this.http_post('expunge', url+add_url, lock);
    };
@@ -1309,23 +1331,10 @@
    // send request to server
    var url = '_mbox='+urlencode(mbox);
    this.http_request('purge', url+add_url, lock);
    this.http_post('purge', url+add_url, lock);
    return true;
    };
  this.focus_mailbox = function(mbox)
    {
    var mbox_li;
    if (this.drag_active && mbox != this.env.mailbox && (mbox_li = this.get_mailbox_li(mbox)))
      this.set_classname(mbox_li, 'droptarget', true);
    }
  this.unfocus_mailbox = function(mbox)
    {
    var mbox_li;
    if (this.drag_active && (mbox_li = this.get_mailbox_li(mbox)))
      this.set_classname(mbox_li, 'droptarget', false);
    }
  
  // move selected messages to the specified mailbox
  this.move_messages = function(mbox)
@@ -1347,7 +1356,7 @@
      this.set_busy(true, 'movingmessage');
      }
    else
      this.show_messageframe(false);
      this.show_contentframe(false);
    this._with_selected_messages('moveto', lock, add_url);
    };
@@ -1355,15 +1364,14 @@
  // 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)
      {
      if (!this.message_list || !this.message_list.get_selection().length)
    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 (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)
@@ -1380,8 +1388,7 @@
    // 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)
      {
      flag = 'delete';
      this.mark_message(flag);
      this.mark_message('delete');
      if(this.env.action=="show")
        this.command('nextmessage','',this);
      else if (selection.length == 1)
@@ -1399,8 +1406,8 @@
    // 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_messageframe(false);
    this.show_contentframe(false);
    this._with_selected_messages('delete', false, '&_from='+(this.env.action ? this.env.action : ''));
    };
@@ -1424,13 +1431,13 @@
      this.message_list.select_next();
      }
    // also send search request to get the right messages
    if (this.env.search_request)
    // also send search request to get the right messages
    if (this.env.search_request)
      add_url += '&_search='+this.env.search_request;
    // send request to server
    this.http_request(action, '_uid='+a_uids.join(',')+'&_mbox='+urlencode(this.env.mailbox)+add_url, lock);
    this.http_post(action, '_uid='+a_uids.join(',')+'&_mbox='+urlencode(this.env.mailbox)+add_url, lock);
    };
@@ -1444,13 +1451,13 @@
      a_uids[0] = uid;
    else if (this.env.uid)
      a_uids[0] = this.env.uid;
    else
    else if (this.message_list)
      {
      var id;
      for (var n=0; n<selection.length; n++)
      for (var id, n=0; n<selection.length; n++)
        {
        id = selection[n];
        if ((flag=='read' && this.message_list.rows[id].unread) || (flag=='unread' && !this.message_list.rows[id].unread))
        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))
          a_uids[a_uids.length] = id;
        }
      }
@@ -1509,7 +1516,7 @@
        }
      }
      
    this.http_request('mark', '_uid='+a_uids.join(',')+'&_flag='+flag);
    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag='+flag);
  };
  
  // mark all message rows as deleted/undeleted
@@ -1523,7 +1530,8 @@
      return false;
    var rows = this.message_list.rows;
    if (a_uids.length==1) {
    if (a_uids.length==1)
    {
      if (rows[a_uids[0]] && rows[a_uids[0]].classname.indexOf('deleted') < 0)
        this.flag_as_deleted(a_uids);
      else
@@ -1533,10 +1541,12 @@
    }
    
    var all_deleted = true;
    for (var i=0; i<a_uids.length; i++) {
    for (var i=0; i<a_uids.length; i++)
    {
      uid = a_uids[i];
      if (rows[uid]) {
        if (rows[uid].classname.indexOf('deleted')<0) {
        if (rows[uid].classname.indexOf('deleted')<0)
        {
          all_deleted = false;
          break;
        }
@@ -1561,12 +1571,14 @@
    var icn_src;
    var rows = this.message_list.rows;
      
    for (var i=0; i<a_uids.length; i++) {
    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) {
        if (rows[uid].classname.indexOf('deleted') > 0)
        {
          rows[uid].classname = rows[uid].classname.replace(/\s*deleted/, '');
          this.set_classname(rows[uid].obj, 'deleted', false);
        }
@@ -1581,7 +1593,7 @@
      }
    }
    this.http_request('mark', '_uid='+a_uids.join(',')+'&_flag=undelete');
    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag=undelete');
    return true;
  };
@@ -1593,7 +1605,8 @@
      return false;
    var rows = this.message_list.rows;
    for (var i=0; i<a_uids.length; i++) {
    for (var i=0; i<a_uids.length; i++)
    {
      uid = a_uids[i];
      if (rows[uid]) {
        rows[uid].deleted = true;
@@ -1607,22 +1620,29 @@
      }
    }
    this.http_request('mark', '_uid='+a_uids.join(',')+'&_flag=delete');
    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag=delete');
    return true;  
  };
  this.get_mailbox_li = function(mbox)
  /*********************************************************/
  /*********           login form methods          *********/
  /*********************************************************/
  // handler for keyboard events on the _user field
  this.login_user_keypress = function(e)
  {
    var key = rcube_event.get_keycode(e);
    var elm;
    // enter
    if ((key==13) && (elm = rcube_find_object('_pass')))
    {
    if (this.gui_objects.mailboxlist)
      {
      mbox = String((mbox ? mbox : this.env.mailbox)).toLowerCase().replace(this.mbox_expression, '');
      return document.getElementById('rcmbx'+mbox);
      }
    return null;
    };
      elm.focus();
      return false;
    }
  };
  /*********************************************************/
  /*********        message compose methods        *********/
@@ -1663,13 +1683,10 @@
      }
    // check for empty body
    if ((input_message.value=='')&&(tinyMCE.getContent()==''))
    if ((input_message.value == '' || (window.tinyMCE && tinyMCE.getContent() == '')) && !confirm(this.get_label('nobodywarning')))
      {
      if (!confirm(this.get_label('nobodywarning')))
        {
        input_message.focus();
        return false;
        }
      input_message.focus();
      return false;
      }
    return true;
@@ -1678,19 +1695,29 @@
  this.set_spellcheck_state = function(s)
    {
  this.spellcheck_ready = (s=='check_spelling' || s=='ready');
    this.spellcheck_ready = (s=='check_spelling' || s=='ready');
    this.enable_command('spellcheck', this.spellcheck_ready);
  };
    };
  this.set_draft_id = function(id)
    {
    var f;
    if (f = rcube_find_object('_draft_saveid'))
      f.value = id;
    };
  this.auto_save_start = function()
    {
    if (this.env.draft_autosave)
      this.save_timer = self.setTimeout(function(){ ref.command("savedraft"); }, this.env.draft_autosave * 1000);
    // Unlock interface now that saving is complete
    this.busy = false;
    };
  this.compose_field_hash = function()
  this.compose_field_hash = function(save)
    {
    // check input fields
    var input_to = rcube_find_object('_to');
@@ -1710,7 +1737,10 @@
      str += input_subject.value+':';
    if (input_message && input_message.value)
      str += input_message.value;
    if (save)
      this.cmp_hash = str;
    return str;
    };
    
@@ -1901,7 +1931,7 @@
  this.remove_attachment = function(name)
    {
    if (name)
      this.http_request('remove-attachment', '_file='+urlencode(name));
      this.http_post('remove-attachment', '_file='+urlencode(name));
    return true;
    };
@@ -1910,19 +1940,27 @@
  this.add_contact = function(value)
    {
    if (value)
      this.http_request('addcontact', '_address='+value);
      this.http_post('addcontact', '_address='+value);
    
    return true;
    };
  // send remote request to search mail
  this.qsearch = function(value, mbox)
  // send remote request to search mail or contacts
  this.qsearch = function(value)
    {
    if (value && mbox)
    if (value != '')
      {
      this.message_list.clear();
      if (this.message_list)
        this.message_list.clear();
      else if (this.contact_list) {
        this.contact_list.clear(true);
        this.show_contentframe(false);
      }
      // reset vars
      this.env.current_page = 1;
      this.set_busy(true, 'searching');
      this.http_request('search', '_search='+value+'&_mbox='+mbox, true);
      this.http_request('search', '_q='+urlencode(value)+(this.env.mailbox ? '&_mbox='+this.env.mailbox : '')+(this.env.source ? '&_source='+urlencode(this.env.source) : ''), true);
      }
    return true;
    };
@@ -1959,11 +1997,9 @@
    if (this.ksearch_timer)
      clearTimeout(this.ksearch_timer);
    if (!e)
      e = window.event;
    var highlight;
    var key = e.keyCode ? e.keyCode : e.which;
    var key = rcube_event.get_keycode(e);
    var mod = rcube_event.get_modifier(e);
    switch (key)
      {
@@ -1982,7 +2018,6 @@
        if (highlight && (next = dir ? highlight.previousSibling : highlight.nextSibling))
          {
          highlight.removeAttribute('id');
          //highlight.removeAttribute('class');
          this.set_classname(highlight, 'selected', false);
          }
@@ -1993,42 +2028,21 @@
          this.ksearch_selected = next._rcm_id;
          }
        if (e.preventDefault)
          e.preventDefault();
        return false;
        return rcube_event.cancel(e);
      case 9:  // tab
        if(e.shiftKey)
        if(mod == SHIFT_KEY)
          break;
      case 13:  // enter     
        if (this.ksearch_selected===null || !this.ksearch_input || !this.ksearch_value)
          break;
        // get cursor pos
        var inp_value = this.ksearch_input.value.toLowerCase();
        var cpos = this.get_caret_pos(this.ksearch_input);
        var p = inp_value.lastIndexOf(this.ksearch_value, cpos);
        // replace search string with full address
        var pre = this.ksearch_input.value.substring(0, p);
        var end = this.ksearch_input.value.substring(p+this.ksearch_value.length, this.ksearch_input.value.length);
        var insert = this.env.contacts[this.ksearch_selected]+', ';
        this.ksearch_input.value = pre + insert + end;
        //this.ksearch_input.value = this.ksearch_input.value.substring(0, p)+insert;
        // set caret to insert pos
        cpos = p+insert.length;
        if (this.ksearch_input.setSelectionRange)
          this.ksearch_input.setSelectionRange(cpos, cpos);
        // hide ksearch pane
        // insert selected address and hide ksearch pane
        this.insert_recipient(this.ksearch_selected);
        this.ksearch_hide();
        if (e.preventDefault)
          e.preventDefault();
        return false;
        return rcube_event.cancel(e);
      case 27:  // escape
        this.ksearch_hide();
@@ -2042,6 +2056,30 @@
    
    return true;
    };
  this.insert_recipient = function(id)
  {
    if (!this.env.contacts[id] || !this.ksearch_input)
      return;
    // get cursor pos
    var inp_value = this.ksearch_input.value.toLowerCase();
    var cpos = this.get_caret_pos(this.ksearch_input);
    var p = inp_value.lastIndexOf(this.ksearch_value, cpos);
    // replace search string with full address
    var pre = this.ksearch_input.value.substring(0, p);
    var end = this.ksearch_input.value.substring(p+this.ksearch_value.length, this.ksearch_input.value.length);
    var insert  = this.env.contacts[id]+', ';
    this.ksearch_input.value = pre + insert + end;
    // set caret to insert pos
    cpos = p+insert.length;
    if (this.ksearch_input.setSelectionRange)
      this.ksearch_input.setSelectionRange(cpos, cpos);
  };
  // address search processor
@@ -2109,6 +2147,8 @@
        {
        li = document.createElement('LI');
        li.innerHTML = a_results[i].replace(/</, '&lt;').replace(/>/, '&gt;');
        li.onmousedown = function(e){ ref.insert_recipient(this._rcm_id); ref.ksearch_pane.show(0); return rcube_event.cancel(e); };
        li.style.cursor = 'pointer';
        li._rcm_id = a_result_ids[i];
        ul.appendChild(li);
        }
@@ -2134,9 +2174,6 @@
        this.ksearch_selected = a_result_ids[0];
        }
      // resize the containing layer to fit the list
      //this.ksearch_pane.resize(ul.offsetWidth, ul.offsetHeight);
      // move the results pane right under the input box and make it visible
      var pos = rcube_get_object_pos(this.ksearch_input);
      this.ksearch_pane.move(pos.x, pos.y+this.ksearch_input.offsetHeight);
@@ -2184,33 +2221,47 @@
  this.contactlist_select = function(list)
    {
      var id, frame;
      if (this.preview_timer)
        clearTimeout(this.preview_timer);
      var id, frame, ref = this;
      if (id = list.get_single_selection())
        this.load_contact(id, 'show');
      else if (frame = document.getElementById(this.env.contentframe))
        frame.style.visibility = 'hidden';
        this.preview_timer = setTimeout(function(){ ref.load_contact(id, 'show'); }, this.dblclick_time + 10);
      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('delete', list.selection.length && this.env.address_sources && !this.env.address_sources[this.env.source].readonly);
      if (list.selection.length)
        this.enable_command('delete', 'compose', true);
      return false;
      return false;
    };
  this.list_contacts = function(page)
  this.list_contacts = function(src, page)
    {
    var add_url = '';
    var target = window;
    
    if (page && this.current_page==page)
    if (!src)
      src = this.env.source;
    if (page && this.current_page==page && src == this.env.source)
      return false;
    if (src != this.env.source)
      {
      page = 1;
      this.env.current_page = page;
      }
    this.select_folder(src, this.env.source);
    this.env.source = src;
    // load contacts remotely
    if (this.gui_objects.contactslist)
      {
      this.list_contacts_remote(page);
      this.list_contacts_remote(src, page);
      return;
      }
@@ -2220,19 +2271,31 @@
      add_url = '&_framed=1';
      }
    // also send search request to get the correct listing
    if (this.env.search_request)
      add_url += '&_search='+this.env.search_request;
    this.set_busy(true, 'loading');
    target.location.href = this.env.comm_path+(page ? '&_page='+page : '')+add_url;
    target.location.href = this.env.comm_path+(src ? '&_source='+urlencode(src) : '')+(page ? '&_page='+page : '')+add_url;
    };
  // send remote request to load contacts list
  this.list_contacts_remote = function(page)
  this.list_contacts_remote = function(src, page)
    {
    // clear message list first
    this.contact_list.clear();
    this.contact_list.clear(true);
    this.show_contentframe(false);
    this.enable_command('delete', 'compose', false);
    // send request to server
    var url = page ? '&_page='+page : '';
    var url = (src ? '&_source='+urlencode(src) : '') + (page ? '&_page='+page : '');
    this.env.source = src;
    // also send search request to get the right messages
    if (this.env.search_request)
      url += '&_search='+this.env.search_request;
    this.set_busy(true, 'loading');
    this.http_request('list', url, true);
    };
@@ -2247,18 +2310,28 @@
      {
      add_url = '&_framed=1';
      target = window.frames[this.env.contentframe];
      document.getElementById(this.env.contentframe).style.visibility = 'inherit';
      this.show_contentframe(true);
      }
    else if (framed)
      return false;
    if (action && (cid || action=='add'))
    if (action && (cid || action=='add') && !this.drag_active)
      {
      this.set_busy(true);
      target.location.href = this.env.comm_path+'&_action='+action+'&_cid='+cid+add_url;
      target.location.href = this.env.comm_path+'&_action='+action+'&_source='+urlencode(this.env.source)+'&_cid='+urlencode(cid) + add_url;
      }
    return true;
    };
  // copy a contact to the specified target (group or directory)
  this.copy_contact = function(cid, to)
  {
    if (!cid)
      cid = this.contact_list.get_selection().join(',');
    if (to != this.env.source && cid && this.env.address_sources[to] && !this.env.address_sources[to].readonly)
      this.http_post('copy', '_cid='+urlencode(cid)+'&_source='+urlencode(this.env.source)+'&_to='+urlencode(to));
  };
  this.delete_contacts = function()
@@ -2283,15 +2356,12 @@
        }
      // hide content frame if we delete the currently displayed contact
      if (selection.length==1 && this.env.contentframe)
        {
        var elm = document.getElementById(this.env.contentframe);
        elm.style.visibility = 'hidden';
        }
      if (selection.length == 1)
        this.show_contentframe(false);
      }
    // send request to server
    this.http_request('delete', '_cid='+a_cids.join(',')+'&_from='+(this.env.action ? this.env.action : ''));
    this.http_post('delete', '_cid='+urlencode(a_cids.join(','))+'&_from='+(this.env.action ? this.env.action : ''));
    return true;
    };
@@ -2311,51 +2381,6 @@
    return false;
    };
  // load ldap search form
  // deprecated
  this.ldappublicsearch = function(action)
    {
    var add_url = '';
    var target = window;
    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
      {
      add_url = '&_framed=1';
      target = window.frames[this.env.contentframe];
      document.getElementById(this.env.contentframe).style.visibility = 'inherit';
      }
    else
      return false;
    if (action == 'ldappublicsearch')
      target.location.href = this.env.comm_path+'&_action='+action+add_url;
    return true;
    };
  // add ldap contacts to address book
  this.add_ldap_contacts = function()
    {
    if (window.frames[this.env.contentframe].rcmail)
      {
      var frame = window.frames[this.env.contentframe];
      // build the url
      var url    = '&_framed=1';
      var emails = '&_emails=';
      var names  = '&_names=';
      var end    = '';
      for (var n=0; n<frame.rcmail.selection.length; n++)
        {
        end = n < frame.rcmail.selection.length - 1 ? ',' : '';
        emails += frame.rcmail.ldap_contact_rows[frame.rcmail.selection[n]].obj.cells[1].innerHTML + end;
        names  += frame.rcmail.ldap_contact_rows[frame.rcmail.selection[n]].obj.cells[0].innerHTML + end;
        }
      frame.location.href = this.env.comm_path + '&_action=save&_framed=1' + emails + names;
      }
    return false;
    }
  /*********************************************************/
@@ -2393,7 +2418,6 @@
    };
  this.delete_identity = function(id)
    {
    // exit if no mailbox specified or if selection is empty
@@ -2403,15 +2427,6 @@
    
    if (!id)
      id = this.env.iid ? this.env.iid : selection[0];
/*
    // 'remove' row from list (just hide it)
    if (this.identity_rows && this.identity_rows[id].obj)
      {
      this.clear_selection();
      this.identity_rows[id].obj.style.display = 'none';
      }
*/
    // if (this.env.framed && id)
    this.goto_url('delete-identity', '_iid='+id, true);
@@ -2430,7 +2445,7 @@
      name = form.elements['_folder_name'].value;
    if (name)
      this.http_request('create-folder', '_name='+urlencode(name), true);
      this.http_post('create-folder', '_name='+urlencode(name), true);
    else if (form.elements['_folder_name'])
      form.elements['_folder_name'].focus();
    };
@@ -2453,7 +2468,7 @@
      }
    if (oldname && newname)
      this.http_request('rename-folder', '_folder_oldname='+urlencode(oldname)+'&_folder_newname='+urlencode(newname));
      this.http_post('rename-folder', '_folder_oldname='+urlencode(oldname)+'&_folder_newname='+urlencode(newname));
    };
@@ -2503,14 +2518,14 @@
  // handler for keyboard events on the input field
  this.name_input_keypress = function(e)
    {
    var key = document.all ? event.keyCode : document.getElementById ? e.keyCode : 0;
    var key = rcube_event.get_keycode(e);
    // enter
    if (key==13)
      {
      var newname = this.name_input ? this.name_input.value : null;
      if (this.edit_folder && newname)
        this.http_request('rename-folder', '_folder_oldname='+urlencode(this.env.subscriptionrows[this.edit_folder][0])+'&_folder_newname='+urlencode(newname));
        this.http_post('rename-folder', '_folder_oldname='+urlencode(this.env.subscriptionrows[this.edit_folder][0])+'&_folder_newname='+urlencode(newname));
      }
    // escape
    else if (key==27)
@@ -2525,7 +2540,7 @@
    this.reset_folder_rename();
    
    if (folder)
      this.http_request('delete-folder', '_mboxes='+urlencode(folder));
      this.http_post('delete-folder', '_mboxes='+urlencode(folder));
    };
@@ -2652,7 +2667,7 @@
    if ((form = this.gui_objects.editform) && form.elements['_unsubscribed'])
      this.change_subscription('_unsubscribed', '_subscribed', 'subscribe');
    else if (folder)
      this.http_request('subscribe', '_mboxes='+urlencode(folder));
      this.http_post('subscribe', '_mboxes='+urlencode(folder));
    };
@@ -2662,7 +2677,7 @@
    if ((form = this.gui_objects.editform) && form.elements['_subscribed'])
      this.change_subscription('_subscribed', '_unsubscribed', 'unsubscribe');
    else if (folder)
      this.http_request('unsubscribe', '_mboxes='+urlencode(folder));
      this.http_post('unsubscribe', '_mboxes='+urlencode(folder));
    };
    
@@ -2696,7 +2711,7 @@
          list_to[index] = new Option(a_folders[n]);
          }
          
        this.http_request(action, '_mboxes='+urlencode(a_folders.join(',')));
        this.http_post(action, '_mboxes='+urlencode(a_folders.join(',')));
        }
      }
      
@@ -2737,28 +2752,27 @@
  // sort subscription folder list
  this.sort_subscription_list = function()
    {
    var index = new Array();
    var tbody = this.gui_objects.subscriptionlist.tBodies[0];
    var swapped = false;
    for (var i = 0; i<(tbody.childNodes.length-1); i++)
      {
      if (this.env.subscriptionrows[tbody.childNodes[i].id]!=null)
        index.push(i);
    for (i = 0; i<(index.length-1); i++)
      {
      if (this.env.subscriptionrows[tbody.childNodes[index[i]].id][0]>
          this.env.subscriptionrows[tbody.childNodes[index[i+1]].id][0])
        {
        var swapped = false;
        for (var j = i+1; j<(tbody.childNodes.length); j++)
          {
          if ((this.env.subscriptionrows[tbody.childNodes[j].id]!=null) &&
              (this.env.subscriptionrows[tbody.childNodes[i].id][0]>
               this.env.subscriptionrows[tbody.childNodes[j].id][0]))
            {
            var swap = tbody.replaceChild(tbody.childNodes[i], tbody.childNodes[j]);
            if (typeof(tbody.childNodes[i]) != 'undefined')
              tbody.insertBefore(swap, tbody.childNodes[i])
            else
              tbody.appendChild(swap);
            swapped = true;
            }
          }
        var swap = tbody.replaceChild(tbody.childNodes[index[i]], tbody.childNodes[index[i+1]]);
        if (typeof(tbody.childNodes[index[i]]) != 'undefined')
          tbody.insertBefore(swap, tbody.childNodes[index[i]])
        else
          tbody.appendChild(swap);
        swapped = true;
        }
      }
    if (swapped)
      this.sort_subscription_list();
    };
@@ -2904,13 +2918,16 @@
  // display a system message
  this.display_message = function(msg, type, hold)
    {
    this.set_busy(false);
    if (!this.loaded)  // save message in order to display after page loaded
      {
      this.pending_message = new Array(msg, type);
      return true;
      }
    // pass command to parent window
    if (this.env.framed && parent.rcmail)
      return parent.rcmail.display_message(msg, type, hold);
    if (!this.gui_objects.message)
      return false;
@@ -2921,12 +2938,12 @@
    if (type)
      cont = '<div class="'+type+'">'+cont+'</div>';
    this.gui_objects.message._rcube = this;
    var _rcube = this;
    this.gui_objects.message.innerHTML = cont;
    this.gui_objects.message.style.display = 'block';
    if (type!='loading')
      this.gui_objects.message.onmousedown = function(){ this._rcube.hide_message(); return true; };
      this.gui_objects.message.onmousedown = function(){ _rcube.hide_message(); return true; };
    
    if (!hold)
      this.message_timer = setTimeout(function(){ ref.hide_message(); }, this.message_time);
@@ -2945,38 +2962,37 @@
  // mark a mailbox as selected and set environment variable
  this.select_mailbox = function(mbox)
  this.select_folder = function(name, old)
  {
    if (this.gui_objects.folderlist)
    {
    if (this.gui_objects.mailboxlist )
      {
      var item, reg, text_obj;
      var current_li = this.get_mailbox_li();
      var mbox_li = this.get_mailbox_li(mbox);
      var current_li, target_li;
      
      if (current_li)
        {
      if ((current_li = this.get_folder_li(old)))
      {
        this.set_classname(current_li, 'selected', false);
        this.set_classname(current_li, 'unfocused', false);
        }
      if (mbox_li || this.env.mailbox == mbox)
        {
        this.set_classname(mbox_li, 'unfocused', false);
        this.set_classname(mbox_li, 'selected', true);
        }
      }
    // also update mailbox name in window title
    if (document.title)
      if ((target_li = this.get_folder_li(name)))
      {
      var doc_title = String(document.title);
      var reg = new RegExp(this.env.mailbox.toLowerCase(), 'i');
      if (this.env.mailbox && doc_title.match(reg))
        document.title = doc_title.replace(reg, mbox).replace(/^\([0-9]+\)\s+/i, '');
        this.set_classname(target_li, 'unfocused', false);
        this.set_classname(target_li, 'selected', true);
      }
    this.env.mailbox = mbox;
    };
    }
  };
  // helper method to find a folder list item
  this.get_folder_li = function(name)
  {
    if (this.gui_objects.folderlist)
    {
      name = String(name).replace(this.identifier_expr, '');
      return document.getElementById('rcmli'+name);
    }
    return null;
  };
  // for reordering column array, Konqueror workaround
@@ -3068,14 +3084,14 @@
    };
  // replace content of quota display
   this.set_quota = function()
     {
     if (this.gui_objects.quotadisplay &&
         this.gui_objects.quotadisplay.attributes.getNamedItem('display') &&
         this.gui_objects.quotadisplay.attributes.getNamedItem('id'))
       this.http_request('quotadisplay', '_display='+
         this.gui_objects.quotadisplay.attributes.getNamedItem('display').nodeValue+
         '&_id='+this.gui_objects.quotadisplay.attributes.getNamedItem('id').nodeValue, false);
  this.set_quota = function()
    {
    if (this.gui_objects.quotadisplay &&
        this.gui_objects.quotadisplay.attributes.getNamedItem('display') &&
        this.gui_objects.quotadisplay.attributes.getNamedItem('id'))
      this.http_request('quotadisplay', '_display='+
      this.gui_objects.quotadisplay.attributes.getNamedItem('display').nodeValue+
      '&_id='+this.gui_objects.quotadisplay.attributes.getNamedItem('id').nodeValue, false);
     };
@@ -3089,8 +3105,8 @@
      set_title = true;
    var reg, text_obj;
    var item = this.get_mailbox_li(mbox);
    mbox = String(mbox).toLowerCase().replace(this.mbox_expression, '');
    var item = this.get_folder_li(mbox);
    mbox = String(mbox).toLowerCase().replace(this.identifier_expr, '');
    if (item && item.className && item.className.indexOf('mailbox '+mbox)>=0)
      {
@@ -3174,14 +3190,21 @@
  /*********        remote request methods        *********/
  /********************************************************/
  this.redirect = function(url, lock)
    {
    if (lock || lock === null)
      this.set_busy(true);
    if (this.env.framed && window.parent)
      parent.location.href = url;
    else
      location.href = url;
    };
  this.goto_url = function(action, query, lock)
    {
    if (lock)
    this.set_busy(true);
    var querystring = query ? '&'+query : '';
    location.href = this.env.comm_path+'&_action='+action+querystring;
    this.redirect(this.env.comm_path+'&_action='+action+querystring, lock);
    };
@@ -3217,20 +3240,45 @@
    // send request
    if (request_obj)
      {
      // prompt('request', this.env.comm_path+'&_action='+urlencode(action)+'&'+querystring);
      console('HTTP request: '+this.env.comm_path+'&_action='+action+'&'+querystring);
      console.log('HTTP request: '+this.env.comm_path+'&_action='+action+'&'+querystring);
      if (lock)
        this.set_busy(true);
      var rcm = this;
      request_obj.__lock = lock ? true : false;
      request_obj.__action = action;
      request_obj.onerror = function(o){ rcube_webmail_client.http_error(o); };
      request_obj.oncomplete = function(o){ rcube_webmail_client.http_response(o); };
      request_obj.onerror = function(o){ ref.http_error(o); };
      request_obj.oncomplete = function(o){ ref.http_response(o); };
      request_obj.GET(this.env.comm_path+'&_action='+action+'&'+querystring);
      }
    };
    // send a http POST request to the server
    this.http_post = function(action, postdata, lock)
      {
      var request_obj;
      if (postdata && typeof(postdata) == 'object')
        postdata._remote = 1;
      else
        postdata += (postdata ? '&' : '') + '_remote=1';
      // send request
      if (request_obj = this.get_request_obj())
        {
        console.log('HTTP POST: '+this.env.comm_path+'&_action='+action);
        if (lock)
          this.set_busy(true);
        var rcm = this;
        request_obj.__lock = lock ? true : false;
        request_obj.__action = action;
        request_obj.onerror = function(o){ rcm.http_error(o); };
        request_obj.oncomplete = function(o){ rcm.http_response(o); };
        request_obj.POST(this.env.comm_path+'&_action='+action, postdata);
        }
      };
  // handle HTTP response
  this.http_response = function(request_obj)
@@ -3244,7 +3292,7 @@
    this.set_busy(false);
  console(request_obj.get_text());
    console.log(request_obj.get_text());
    // if we get javascript code from server -> execute it
    if (request_obj.get_text() && (ctype=='text/javascript' || ctype=='application/x-javascript'))
@@ -3426,7 +3474,10 @@
    if (window.XMLHttpRequest)
      this.xmlhttp = new XMLHttpRequest();
    else if (window.ActiveXObject)
      this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
      {
      try { this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
      catch(e) { this.xmlhttp = null; }
      }
    else
      {
      
@@ -3444,12 +3495,13 @@
      return false;
      }
    var ref = this;
    var _ref = this;
    this.url = url;
    this.busy = true;
    this.xmlhttp.onreadystatechange = function(){ ref.xmlhttp_onreadystatechange(); };
    this.xmlhttp.onreadystatechange = function(){ _ref.xmlhttp_onreadystatechange(); };
    this.xmlhttp.open('GET', url);
    this.xmlhttp.setRequestHeader('X-RoundCube-Referer', bw.get_cookie('sessid'));
    this.xmlhttp.send(null);
    };
@@ -3457,8 +3509,8 @@
  this.POST = function(url, body, contentType)
    {
    // default value for contentType if not provided
    contentType = typeof(contentType) != 'undefined' ?
      contentType : 'application/x-www-form-urlencoded';
    if (typeof(contentType) == 'undefined')
      contentType = 'application/x-www-form-urlencoded';
    this.build();
    
@@ -3467,15 +3519,24 @@
       this.onerror(this);
       return false;
    }
    var req_body = body;
    if (typeof(body) == 'object')
    {
      req_body = '';
      for (var p in body)
        req_body += (req_body ? '&' : '') + p+'='+urlencode(body[p]);
    }
    var ref=this;
    var ref = this;
    this.url = url;
    this.busy = true;
    
    this.xmlhttp.onreadystatechange = function() { ref.xmlhttp_onreadystatechange(); };
    this.xmlhttp.open('POST', url, true);
    this.xmlhttp.setRequestHeader('Content-Type', contentType);
    this.xmlhttp.send(body);
    this.xmlhttp.setRequestHeader('X-RoundCube-Referer', bw.get_cookie('sessid'));
    this.xmlhttp.send(req_body);
    };
@@ -3537,11 +3598,5 @@
  {
  if (window[o] && window[o].init)
    setTimeout(o+'.init()', 200);
  }
function console(str)
  {
  if (document.debugform && document.debugform.console)
    document.debugform.console.value += str+'\n--------------------------------------\n';
  }