thomascube
2008-09-15 f645ce169e11339d45cbc0b5b4cf6154346fd4c7
program/js/app.js
@@ -122,6 +122,9 @@
    // enable general commands
    this.enable_command('logout', 'mail', 'addressbook', 'settings', true);
    
    if (this.env.permaurl)
      this.enable_command('permaurl', true);
    switch (this.task)
      {
      case 'mail':
@@ -133,6 +136,7 @@
          this.message_list.addEventListener('keypress', function(o){ p.msglist_keypress(o); });
          this.message_list.addEventListener('select', function(o){ p.msglist_select(o); });
          this.message_list.addEventListener('dragstart', function(o){ p.drag_active = true; if (p.preview_timer) clearTimeout(p.preview_timer); });
          this.message_list.addEventListener('dragmove', function(o, e){ p.drag_move(e); });
          this.message_list.addEventListener('dragend', function(o){ p.drag_active = false; });
          this.message_list.init();
@@ -158,7 +162,7 @@
        
        if (this.env.action=='show' || this.env.action=='preview')
          {
          this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete', 'mark', 'viewsource', 'print', 'load-attachment', true);
          this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete', 'mark', 'viewsource', 'print', 'load-attachment', 'load-headers', true);
          if (this.env.next_uid)
            {
            this.enable_command('nextmessage', true);
@@ -205,10 +209,7 @@
        if (this.env.messagecount)
          this.enable_command('select-all', 'select-none', 'expunge', true);
        if (this.env.messagecount
            && (this.env.mailbox == this.env.trash_mailbox || this.env.mailbox == this.env.junk_mailbox
              || this.env.mailbox.match('^' + RegExp.escape(this.env.trash_mailbox) + RegExp.escape(this.env.delimiter))
              || this.env.mailbox.match('^' + RegExp.escape(this.env.junk_mailbox) + RegExp.escape(this.env.delimiter))))
        if (this.purge_mailbox_test())
          this.enable_command('purge', true);
        this.set_page_buttons();
@@ -230,6 +231,7 @@
        // get unread count for each mailbox
        if (this.gui_objects.mailboxlist)
        {
          this.env.unread_counts = {};
          this.gui_objects.folderlist = this.gui_objects.mailboxlist;
          this.http_request('getunread', '');
        }
@@ -254,6 +256,7 @@
          this.contact_list.addEventListener('keypress', function(o){ p.contactlist_keypress(o); });
          this.contact_list.addEventListener('select', function(o){ p.contactlist_select(o); });
          this.contact_list.addEventListener('dragstart', function(o){ p.drag_active = true; });
          this.contact_list.addEventListener('dragmove', function(o, e){ p.drag_move(e); });
          this.contact_list.addEventListener('dragend', function(o){ p.drag_active = false; });
          this.contact_list.init();
@@ -280,7 +283,10 @@
        if ((this.env.action=='add' || this.env.action=='edit') && this.gui_objects.editform)
          this.enable_command('save', true);
        else
          this.enable_command('search', 'reset-search', 'moveto', true);
          this.enable_command('search', 'reset-search', 'moveto', 'import', true);
        if (this.contact_list && this.contact_list.rowcount > 0)
          this.enable_command('export', true);
        this.enable_command('list', true);
        break;
@@ -289,8 +295,10 @@
      case 'settings':
        this.enable_command('preferences', 'identities', 'save', 'folders', true);
        
        if (this.env.action=='identities' || this.env.action=='edit-identity' || this.env.action=='add-identity')
          this.enable_command('edit', 'add', 'delete', true);
        if (this.env.action=='identities' || this.env.action=='edit-identity' || this.env.action=='add-identity') {
          this.enable_command('add', 'delete', this.env.multiple_identities);
          this.enable_command('edit', true);
        }
        if (this.env.action=='edit-identity' || this.env.action=='add-identity')
          this.enable_command('save', true);
@@ -317,13 +325,19 @@
      case 'login':
        var input_user = rcube_find_object('rcmloginuser');
        var input_pass = rcube_find_object('rcmloginpwd');
        var input_tz = rcube_find_object('rcmlogintz');
        if (input_user)
          input_user.onkeyup = function(e){ return rcmail.login_user_keyup(e); };
        if (input_user && input_user.value=='')
          input_user.focus();
        else if (input_pass)
          input_pass.focus();
        // detect client timezone
        if (input_tz)
          input_tz.value = new Date().getTimezoneOffset() / -60;
        this.enable_command('login', true);
        break;
      
@@ -501,7 +515,6 @@
        return false;
     }
    // process command
    switch (command)
      {
@@ -521,6 +534,12 @@
        this.switch_task(command);
        break;
      case 'permaurl':
        if (obj && obj.href && obj.target)
          return true;
        else if (this.env.permaurl)
          parent.location.href = this.env.permaurl;
          break;
      // misc list commands
      case 'list':
@@ -542,6 +561,11 @@
          this.list_contacts(props);
          this.enable_command('add', (this.env.address_sources && !this.env.address_sources[props].readonly));
          }
        break;
      case 'load-headers':
        this.load_headers(obj);
        break;
@@ -971,7 +995,7 @@
          break;
        }
      // reset quicksearch
      // reset quicksearch
      case 'reset-search':
        var s = this.env.search_request;
        this.reset_qsearch();
@@ -980,6 +1004,31 @@
          this.list_mailbox(this.env.mailbox);
        else if (s && this.task == 'addressbook')
          this.list_contacts(this.env.source);
        break;
      case 'import':
        if (this.env.action == 'import' && this.gui_objects.importform) {
          var file = document.getElementById('rcmimportfile');
          if (file && !file.value) {
            alert(this.get_label('selectimportfile'));
            break;
          }
          this.gui_objects.importform.submit();
          this.set_busy(true, 'importwait');
          this.lock_form(this.gui_objects.importform, true);
        }
        else
          this.goto_url('import');
        break;
      case 'export':
        if (this.contact_list.rowcount > 0) {
          var add_url = (this.env.source ? '_source='+urlencode(this.env.source)+'&' : '');
          if (this.env.search_request)
            add_url += '_search='+this.env.search_request;
          this.goto_url('export', add_url);
        }
        break;
      // collapse/expand folder
@@ -1126,27 +1175,43 @@
  this.doc_mouse_up = function(e)
    {
    if (this.message_list)
  {
    var model, li;
    if (this.message_list) {
      this.message_list.blur();
    else if (this.contact_list)
      model = this.env.mailboxes;
    }
    else if (this.contact_list) {
      this.contact_list.blur();
    };
  this.focus_folder = function(id)
    {
    var li;
    if (this.drag_active && this.check_droptarget(id) && (li = this.get_folder_li(id)))
      this.set_classname(li, 'droptarget', true);
      model = this.env.address_sources;
    }
  this.unfocus_folder = function(id)
    {
    var li;
    if (this.drag_active && (li = this.get_folder_li(id)))
      this.set_classname(li, 'droptarget', false);
    // handle mouse release when dragging
    if (this.drag_active && model) {
      for (var k in model) {
        if ((li = this.get_folder_li(k)) && rcube_mouse_is_over(e, li.firstChild) && this.check_droptarget(k)) {
          this.set_classname(li, 'droptarget', false);
          this.command('moveto', model[k].id);
          break;
        }
      }
    }
  };
  this.drag_move = function(e)
  {
    var li;
    var model = this.task == 'mail' ? this.env.mailboxes : this.env.address_sources;
    if (this.gui_objects.folderlist && model) {
      for (var k in model) {
        if (li = this.get_folder_li(k))
          this.set_classname(li, 'droptarget', (rcube_mouse_is_over(e, li.firstChild) && this.check_droptarget(k)));
      }
    }
  };
  this.collapse_folder = function(id)
    {
    var div;
@@ -1169,20 +1234,15 @@
        this.set_classname(div, 'expanded', false);
        this.set_classname(div, 'collapsed', true);
        this.set_env('collapsed_folders', this.env.collapsed_folders+'&'+escape(id)+'&');
        // select parent folder if one of its childs is currently selected
        if (this.env.mailbox.indexOf(id + this.env.delimiter) == 0)
          this.command('list', id);
        }
      this.http_post('save-pref', '_name=collapsed_folders&_value='+escape(this.env.collapsed_folders));
      this.set_unread_count_display(id, false);
      }
    }
  // onmouseup handler for folder list item
  this.folder_mouse_up = function(id)
    {
    if (this.drag_active)
      {
      this.unfocus_folder(id);
      this.command('moveto', id);
      }
    };
  this.click_on_list = function(e)
    {
@@ -1195,7 +1255,7 @@
    if (mbox_li = this.get_folder_li())
      this.set_classname(mbox_li, 'unfocused', true);
    rcube_event.cancel(e);
    return rcube_event.get_button(e) == 2 ? true : rcube_event.cancel(e);
    };
@@ -1246,6 +1306,8 @@
      this.command('show');
    else if (list.key_pressed == list.DELETE_KEY)
      this.command('delete');
    else if (list.key_pressed == list.BACKSPACE_KEY)
      this.command('delete');
    else
      list.shiftkey = false;
    };
@@ -1264,7 +1326,7 @@
  this.check_droptarget = function(id)
  {
    if (this.task == 'mail')
      return (id != this.env.mailbox);
      return (this.env.mailboxes[id] && this.env.mailboxes[id].id != this.env.mailbox && !this.env.mailboxes[id].virtual);
    else if (this.task == 'addressbook')
      return (id != this.env.source && this.env.address_sources[id] && !this.env.address_sources[id].readonly);
    else if (this.task == 'settings')
@@ -1463,7 +1525,15 @@
    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))));
  };
  // move selected messages to the specified mailbox
  this.move_messages = function(mbox)
    {
@@ -1873,7 +1943,8 @@
        }
      }
  };
  /*********************************************************/
  /*********           login form methods          *********/
  /*********************************************************/
@@ -2034,8 +2105,12 @@
      // remove the 'old' signature
      if (this.env.identity && this.env.signatures && this.env.signatures[this.env.identity])
        {
        sig = this.env.signatures[this.env.identity]['text'];
        if (sig.indexOf('-- ')!=0)
        if (this.env.signatures[this.env.identity]['is_html'])
          sig = this.env.signatures[this.env.identity]['plain_text'];
        else
     sig = this.env.signatures[this.env.identity]['text'];
   if (sig.indexOf('-- ')!=0)
          sig = '-- \n'+sig;
        p = message.lastIndexOf(sig);
@@ -2060,24 +2135,30 @@
      {
      var editor = tinyMCE.get('compose-body');
      if (this.env.signatures && this.env.signatures[id])
      if (this.env.signatures)
        {
        // Append the signature as a span within the body
        // Append the signature as a div within the body
        var sigElem = editor.dom.get("_rc_sig");
   var newsig = '';
   var htmlsig = true;
        if (!sigElem)
          {
          sigElem = editor.getDoc().createElement("span");
          sigElem = editor.getDoc().createElement("div");
          sigElem.setAttribute("id", "_rc_sig");
          editor.getBody().appendChild(sigElem);
          }
        if (this.env.signatures[id]['is_html'])
          {
          sigElem.innerHTML = this.env.signatures[id]['text'];
          }
   if (this.env.signatures[id])
     {
     newsig = this.env.signatures[id]['text'];
     htmlsig = this.env.signatures[id]['is_html'];
     }
        if (htmlsig)
          sigElem.innerHTML = newsig;
        else
          {
          sigElem.innerHTML = '<pre>' + this.env.signatures[id]['text'] + '</pre>';
          }
          sigElem.innerHTML = '<pre>' + newsig + '</pre>';
        }
      }
@@ -2951,12 +3032,12 @@
      row.id = id;
      if (before && (before = this.get_folder_row_id(before)))
   tbody.insertBefore(row, document.getElementById(before));
        tbody.insertBefore(row, document.getElementById(before));
      else
        tbody.appendChild(row);
        tbody.appendChild(row);
      
      if (replace)
   tbody.removeChild(replace);
        tbody.removeChild(replace);
      }
    // add to folder/row-ID map
@@ -3078,9 +3159,9 @@
    {
    var cell, td;
    var new_row = document.createElement('TR');
    for(var n=0; n<row.childNodes.length; n++)
    for(var n=0; n<row.cells.length; n++)
      {
      cell = row.childNodes[n];
      cell = row.cells[n];
      td = document.createElement('TD');
      if (cell.className)
@@ -3469,22 +3550,46 @@
    if (!this.gui_objects.mailboxlist)
      return false;
    var reg, text_obj, item;
    this.env.unread_counts[mbox] = count;
    this.set_unread_count_display(mbox, set_title);
    }
  // update the mailbox count display
  this.set_unread_count_display = function(mbox, set_title)
    {
    var reg, text_obj, item, mycount, childcount, div;
    if (item = this.get_folder_li(mbox))
      {
      // set new text
      text_obj = item.firstChild.nextSibling;
      mycount = this.env.unread_counts[mbox];
      text_obj = item.getElementsByTagName('a')[0];
      reg = /\s+\([0-9]+\)$/i;
      if (count && text_obj.innerHTML.match(reg))
        text_obj.innerHTML = text_obj.innerHTML.replace(reg, ' ('+count+')');
      else if (count)
        text_obj.innerHTML += ' ('+count+')';
      childcount = 0;
      if ((div = item.getElementsByTagName('div')[0]) &&
          div.className.match(/collapsed/))
        {
        // add children's counters
        for (var k in this.env.unread_counts)
          if (k.indexOf(mbox + this.env.delimiter) == 0) {
            childcount += this.env.unread_counts[k];
          }
        }
      if (mycount && text_obj.innerHTML.match(reg))
        text_obj.innerHTML = text_obj.innerHTML.replace(reg, ' ('+mycount+')');
      else if (mycount)
        text_obj.innerHTML += ' ('+mycount+')';
      else
        text_obj.innerHTML = text_obj.innerHTML.replace(reg, '');
      // set parent's display
      reg = new RegExp(RegExp.escape(this.env.delimiter) + '[^' + RegExp.escape(this.env.delimiter) + ']+');
      if (mbox.match(reg))
        this.set_unread_count_display(mbox.replace(reg, ''), false);
      // set the right classes
      this.set_classname(item, 'unread', count>0 ? true : false);
      this.set_classname(item, 'unread', (mycount+childcount)>0 ? true : false);
      }
    // set unread count to window title
@@ -3494,10 +3599,10 @@
      var doc_title = String(document.title);
      var new_title = "";
      if (count && doc_title.match(reg))
        new_title = doc_title.replace(reg, '('+count+') ');
      else if (count)
        new_title = '('+count+') '+doc_title;
      if (mycount && doc_title.match(reg))
        new_title = doc_title.replace(reg, '('+mycount+') ');
      else if (mycount)
        new_title = '('+mycount+') '+doc_title;
      else
        new_title = doc_title.replace(reg, '');
        
@@ -3538,19 +3643,28 @@
      }
    
    this.contact_list.insert_row(row);
    this.enable_command('export', (this.contact_list.rowcount > 0));
    };
  this.toggle_editor = function(checkbox, textAreaId)
    {
    var ischecked = checkbox.checked;
    var composeElement = document.getElementById(textAreaId);
    if (ischecked)
      {
        tinyMCE.execCommand('mceAddControl', true, textAreaId);
      var existingPlainText = composeElement.value;
      var htmlText = "<pre>" + existingPlainText + "</pre>";
      composeElement.value = htmlText;
      tinyMCE.execCommand('mceAddControl', true, textAreaId);
      }
    else
      {
        tinyMCE.execCommand('mceRemoveControl', true, textAreaId);
      var thisMCE = tinyMCE.get(textAreaId);
      var existingHtml = thisMCE.getContent();
      this.html2plain(existingHtml, textAreaId);
      tinyMCE.execCommand('mceRemoveControl', true, textAreaId);
      }
    };
@@ -3562,6 +3676,81 @@
      addrbook_show_images.disabled = !checkbox.checked;
    }
  // display fetched raw headers
  this.set_headers = function(content)
    {
    if (this.gui_objects.all_headers_row && this.gui_objects.all_headers_box && content)
      {
      var box = this.gui_objects.all_headers_box;
      box.innerHTML = content;
      box.style.display = 'block';
      if (this.env.framed && parent.rcmail)
   parent.rcmail.set_busy(false);
      else
        this.set_busy(false);
      }
    };
  // display all-headers row and fetch raw message headers
  this.load_headers = function(elem)
    {
    if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box || !this.env.uid)
      return;
    this.set_classname(elem, 'show-headers', false);
    this.set_classname(elem, 'hide-headers', true);
    this.gui_objects.all_headers_row.style.display = bw.ie ? 'block' : 'table-row';
    elem.onclick = function() { rcmail.hide_headers(elem); }
    // fetch headers only once
    if (!this.gui_objects.all_headers_box.innerHTML)
      {
      this.display_message(this.get_label('loading'), 'loading', true);
      this.http_post('headers', '_uid='+this.env.uid);
      }
    }
  // hide all-headers row
  this.hide_headers = function(elem)
    {
    if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box)
      return;
    this.set_classname(elem, 'hide-headers', false);
    this.set_classname(elem, 'show-headers', true);
    this.gui_objects.all_headers_row.style.display = 'none';
    elem.onclick = function() { rcmail.load_headers(elem); }
    }
  /********************************************************/
  /*********  html to text conversion functions   *********/
  /********************************************************/
  this.html2plain = function(htmlText, id)
    {
    var http_request = new rcube_http_request();
    var url = this.env.bin_path+'html2text.php';
    var rcmail = this;
    this.set_busy(true, 'converting');
    console.log('HTTP POST: '+url);
    http_request.onerror = function(o) { rcmail.http_error(o); };
    http_request.oncomplete = function(o) { rcmail.set_text_value(o, id); };
    http_request.POST(url, htmlText, 'application/octet-stream');
    }
  this.set_text_value = function(httpRequest, id)
    {
    this.set_busy(false);
    document.getElementById(id).value = httpRequest.get_text();
    console.log(httpRequest.get_text());
    }
  /********************************************************/
@@ -3669,7 +3858,7 @@
    }
    if (request_obj.__lock)
        this.set_busy(false);
      this.set_busy(false);
    console.log(request_obj.get_text());
@@ -3678,53 +3867,47 @@
      eval(request_obj.get_text());
    // process the response data according to the sent action
    switch (request_obj.__action)
      {
    switch (request_obj.__action) {
      case 'delete':
   if (this.task == 'addressbook')
     {
       var uid = this.contact_list.get_selection();
       this.enable_command('compose', (uid && this.contact_list.rows[uid]));
       this.enable_command('delete', 'edit', (uid && this.contact_list.rows[uid] && this.env.address_sources && !this.env.address_sources[this.env.source].readonly));
       break;
     }
        if (this.task == 'addressbook') {
          var uid = this.contact_list.get_selection();
          this.enable_command('compose', (uid && this.contact_list.rows[uid]));
          this.enable_command('delete', 'edit', (uid && this.contact_list.rows[uid] && this.env.address_sources && !this.env.address_sources[this.env.source].readonly));
          this.enable_command('export', (this.contact_list && this.contact_list.rowcount > 0));
        }
      case 'moveto':
        if (this.env.action=='show')
        if (this.env.action == 'show')
          this.command('list');
        else if (this.message_list)
          this.message_list.init();
        break;
      case 'purge':
      case 'expunge':      
   if (!this.env.messagecount && this.task == 'mail')
         {
       // clear preview pane content
       if (this.env.contentframe)
         this.show_contentframe(false);
       // disable commands useless when mailbox is empty
       this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete', 'mark', 'viewsource',
         'print', 'load-attachment', 'purge', 'expunge', 'select-all', 'select-none', 'sort', false);
     }
   break;
      case 'list':
   this.msglist_select(this.message_list);
        if (!this.env.messagecount && this.task == 'mail') {
          // clear preview pane content
          if (this.env.contentframe)
            this.show_contentframe(false);
          // disable commands useless when mailbox is empty
          this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete', 'mark', 'viewsource',
            'print', 'load-attachment', 'purge', 'expunge', 'select-all', 'select-none', 'sort', false);
        }
        break;
      case 'check-recent':
      case 'getunread':
   if (this.task == 'mail')
   {
     this.enable_command('show', 'expunge', 'select-all', 'select-none', 'sort', (this.env.messagecount > 0));
     var mailboxtest = (this.env.mailbox == this.env.trash_mailbox || this.env.mailbox == this.env.junk_mailbox
       || this.env.mailbox.match('^' + RegExp.escape(this.env.trash_mailbox) + RegExp.escape(this.env.delimiter))
       || this.env.mailbox.match('^' + RegExp.escape(this.env.junk_mailbox) + RegExp.escape(this.env.delimiter))) ? true : false;
     this.enable_command('purge', (this.env.messagecount && mailboxtest));
   }
   break;
      }
      case 'list':
        if (this.task == 'mail') {
          if (this.message_list)
            this.msglist_select(this.message_list);
          this.enable_command('show', 'expunge', 'select-all', 'select-none', 'sort', (this.env.messagecount > 0));
          this.enable_command('purge', this.purge_mailbox_test());
        }
        else if (this.task == 'addressbook')
          this.enable_command('export', (this.contact_list && this.contact_list.rowcount > 0));
        break;
    }
    request_obj.reset();
    };
@@ -3733,13 +3916,14 @@
  // handle HTTP request errors
  this.http_error = function(request_obj)
    {
    //alert('Error sending request: '+request_obj.url);
    //alert('Error sending request: '+request_obj.url+' => HTTP '+request_obj.xmlhttp.status);
    if (request_obj.__lock)
      this.set_busy(false);
    request_obj.reset();
    request_obj.__lock = false;
    this.display_message('Unknown Server Error!', 'error');
    };
@@ -3904,7 +4088,7 @@
    this.busy = true;
    this.xmlhttp.onreadystatechange = function(){ _ref.xmlhttp_onreadystatechange(); };
    this.xmlhttp.open('GET', url);
    this.xmlhttp.open('GET', url, true);
    this.xmlhttp.setRequestHeader('X-RoundCube-Referer', bw.get_cookie('roundcube_sessid'));
    this.xmlhttp.send(null);
    };