Thomas Bruederli
2014-06-03 458af8d30a1bca153f770358b8f914554b0da6c3
program/js/app.js
@@ -342,7 +342,16 @@
            .addEventListener('initrow', function(o) { ref.triggerEvent('insertrow', { cid:o.uid, row:o }); })
            .addEventListener('select', function(o) { ref.compose_recipient_select(o); })
            .addEventListener('dblclick', function(o) { ref.compose_add_recipient('to'); })
            .addEventListener('keypress', function(o) { if (o.key_pressed == o.ENTER_KEY) ref.compose_add_recipient('to'); })
            .addEventListener('keypress', function(o) {
              if (o.key_pressed == o.ENTER_KEY) {
                if (!ref.compose_add_recipient('to')) {
                  // execute link action on <enter> if not a recipient entry
                  if (o.last_selected && String(o.last_selected).charAt(0) == 'G') {
                    $(o.rows[o.last_selected].obj).find('a').first().click();
                  }
                }
              }
            })
            .init();
        }
@@ -602,7 +611,7 @@
  {
    var ret, uid, cid, url, flag, aborted = false;
    if (obj && obj.blur)
    if (obj && obj.blur && !(event || rcube_event.is_keyboard(event)))
      obj.blur();
    // do nothing if interface is locked by other command (with exception for searching reset)
@@ -1647,9 +1656,12 @@
  {
    // Helper method to move focus to the next/prev active menu item
    var focus_menu_item = function(dir) {
      var obj, mod = dir < 0 ? 'prevAll' : 'nextAll', limit = dir < 0 ? 'last' : 'first';
      var obj, item, mod = dir < 0 ? 'prevAll' : 'nextAll', limit = dir < 0 ? 'last' : 'first';
      if (ref.focused_menu && (obj = $('#'+ref.focused_menu))) {
        return obj.find(':focus').closest('li')[mod](':has(:not([aria-disabled=true]))').find('a,input')[limit]().focus().length;
        item = obj.find(':focus').closest('li')[mod](':has(:not([aria-disabled=true]))').find('a,input')[limit]();
        if (!item.length)
          item = obj.find(':focus').closest('ul')[mod](':has(:not([aria-disabled=true]))').find('a,input')[limit]();
        return item.focus().length;
      }
      return 0;
@@ -1974,7 +1986,7 @@
      flags: flags.extra_flags
    });
    var c, n, col, html, css_class,
    var c, n, col, html, css_class, label, status_class = '', status_label = '',
      tree = '', expando = '',
      list = this.message_list,
      rows = list.rows,
@@ -1990,17 +2002,26 @@
    css_class = 'msgicon';
    if (this.env.status_col === null) {
      css_class += ' status';
      if (flags.deleted)
        css_class += ' deleted';
      else if (!flags.seen)
        css_class += ' unread';
      else if (flags.unread_children > 0)
        css_class += ' unreadchildren';
      if (flags.deleted) {
        status_class += ' deleted';
        status_label += this.get_label('deleted') + ' ';
      }
      else if (!flags.seen) {
        status_class += ' unread';
        status_label += this.get_label('unread') + ' ';
      }
      else if (flags.unread_children > 0) {
        status_class += ' unreadchildren';
      }
    }
    if (flags.answered)
      css_class += ' replied';
    if (flags.forwarded)
      css_class += ' forwarded';
    if (flags.answered) {
      status_class += ' replied';
      status_label += this.get_label('replied') + ' ';
    }
    if (flags.forwarded) {
      status_class += ' forwarded';
      status_label += this.get_label('replied') + ' ';
    }
    // update selection
    if (message.selected && !list.in_selection(uid))
@@ -2037,7 +2058,7 @@
        row_class += ' unroot';
    }
    tree += '<span id="msgicn'+row.id+'" class="'+css_class+'">&nbsp;</span>';
    tree += '<span id="msgicn'+row.id+'" class="'+css_class+status_class+'" title="'+status_label+'"></span>';
    row.className = row_class;
    // build subject link
@@ -2061,28 +2082,36 @@
      if (c == 'flag') {
        css_class = (flags.flagged ? 'flagged' : 'unflagged');
        html = '<span id="flagicn'+row.id+'" class="'+css_class+'">&nbsp;</span>';
        label = this.get_label(css_class);
        html = '<span id="flagicn'+row.id+'" class="'+css_class+'" title="'+label+'"></span>';
      }
      else if (c == 'attachment') {
        label = this.get_label('withattachment');
        if (flags.attachmentClass)
          html = '<span class="'+flags.attachmentClass+'">&nbsp;</span>';
          html = '<span class="'+flags.attachmentClass+'" title="'+label+'"></span>';
        else if (/application\/|multipart\/(m|signed)/.test(flags.ctype))
          html = '<span class="attachment">&nbsp;</span>';
          html = '<span class="attachment" title="'+label+'"></span>';
        else if (/multipart\/report/.test(flags.ctype))
          html = '<span class="report">&nbsp;</span>';
        else
          html = '<span class="report"></span>';
          else
          html = '&nbsp;';
      }
      else if (c == 'status') {
        if (flags.deleted)
        label = '';
        if (flags.deleted) {
          css_class = 'deleted';
        else if (!flags.seen)
          label = this.get_label('deleted');
        }
        else if (!flags.seen) {
          css_class = 'unread';
        else if (flags.unread_children > 0)
          label = this.get_label('unread');
        }
        else if (flags.unread_children > 0) {
          css_class = 'unreadchildren';
        }
        else
          css_class = 'msgicon';
        html = '<span id="statusicn'+row.id+'" class="'+css_class+'">&nbsp;</span>';
        html = '<span id="statusicn'+row.id+'" class="'+css_class+status_class+'" title="'+label+'"></span>';
      }
      else if (c == 'threads')
        html = expando;
@@ -2092,8 +2121,10 @@
        html = tree + cols[c];
      }
      else if (c == 'priority') {
        if (flags.prio > 0 && flags.prio < 6)
          html = '<span class="prio'+flags.prio+'">&nbsp;</span>';
        if (flags.prio > 0 && flags.prio < 6) {
          label = this.get_label('priority') + ' ' + flags.prio;
          html = '<span class="prio'+flags.prio+'" title="'+label+'"></span>';
        }
        else
          html = '&nbsp;';
      }
@@ -2383,7 +2414,6 @@
  this.clear_message_list = function()
  {
    this.env.messages = {};
    this.last_selected = 0;
    this.show_contentframe(false);
    if (this.message_list)
@@ -2676,7 +2706,7 @@
  // set message icon
  this.set_message_icon = function(uid)
  {
    var css_class,
    var css_class, label = '',
      row = this.message_list.rows[uid];
    if (!row)
@@ -2684,38 +2714,55 @@
    if (row.icon) {
      css_class = 'msgicon';
      if (row.deleted)
      if (row.deleted) {
        css_class += ' deleted';
      else if (row.unread)
        label += this.get_label('deleted') + ' ';
      }
      else if (row.unread) {
        css_class += ' unread';
        label += this.get_label('unread') + ' ';
      }
      else if (row.unread_children)
        css_class += ' unreadchildren';
      if (row.msgicon == row.icon) {
        if (row.replied)
        if (row.replied) {
          css_class += ' replied';
        if (row.forwarded)
          label += this.get_label('replied') + ' ';
        }
        if (row.forwarded) {
          css_class += ' forwarded';
          label += this.get_label('forwarded') + ' ';
        }
        css_class += ' status';
      }
      row.icon.className = css_class;
      $(row.icon).attr('class', css_class).attr('title', label);
    }
    if (row.msgicon && row.msgicon != row.icon) {
      label = '';
      css_class = 'msgicon';
      if (!row.unread && row.unread_children)
      if (!row.unread && row.unread_children) {
        css_class += ' unreadchildren';
      if (row.replied)
      }
      if (row.replied) {
        css_class += ' replied';
      if (row.forwarded)
        label += this.get_label('replied') + ' ';
      }
      if (row.forwarded) {
        css_class += ' forwarded';
        label += this.get_label('forwarded') + ' ';
      }
      row.msgicon.className = css_class;
      $(row.msgicon).attr('class', css_class).attr('title', label);
    }
    if (row.flagicon) {
      css_class = (row.flagged ? 'flagged' : 'unflagged');
      row.flagicon.className = css_class;
      label = this.get_label(css_class);
      $(row.flagicon).attr('class', css_class)
        .attr('aria-label', label)
        .attr('title', label);
    }
  };
@@ -3454,6 +3501,8 @@
      input.val(oldval + recipients.join(delim + ' ') + delim + ' ');
      this.triggerEvent('add-recipient', { field:field, recipients:recipients });
    }
    return recipients.length;
  };
  // checks the input fields before sending a message
@@ -4522,11 +4571,11 @@
  this.ksearch_select = function(node)
  {
    if (this.ksearch_pane && node) {
      this.ksearch_pane.find('li.selected').removeClass('selected');
      this.ksearch_pane.find('li.selected').removeClass('selected').removeAttr('aria-selected');
    }
    if (node) {
      $(node).addClass('selected');
      $(node).addClass('selected').removeAttr('aria-selected', 'true');
      this.ksearch_selected = node._rcm_id;
      $(this.ksearch_input).attr('aria-activedecendant', 'rcmkSearchItem' + this.ksearch_selected);
    }
@@ -4659,7 +4708,7 @@
      return;
    // display search results
    var i, len, ul, li, text, type, init,
    var i, id, len, ul, text, type, init,
      value = this.ksearch_value,
      maxlen = this.env.autocomplete_max ? this.env.autocomplete_max : 15;
@@ -4697,12 +4746,13 @@
      for (i=0; i < len && maxlen > 0; i++) {
        text = typeof results[i] === 'object' ? results[i].name : results[i];
        type = typeof results[i] === 'object' ? results[i].type : '';
        li = document.createElement('LI');
        li._rcm_id = i + this.env.contacts.length;
        li.id = 'rcmkSearchItem' + li._rcm_id;
        li.innerHTML = this.quote_html(text.replace(new RegExp('('+RegExp.escape(value)+')', 'ig'), '##$1%%')).replace(/##([^%]+)%%/g, '<b>$1</b>');
        if (type) li.className = type;
        ul.appendChild(li);
        id = i + this.env.contacts.length;
        $('<li>').attr('id', 'rcmkSearchItem' + id)
          .attr('role', 'option')
          .html(this.quote_html(text.replace(new RegExp('('+RegExp.escape(value)+')', 'ig'), '##$1%%')).replace(/##([^%]+)%%/g, '<b>$1</b>'))
          .addClass(type || '')
          .appendTo(ul)
          .get(0)._rcm_id = id;
        maxlen -= 1;
      }
    }
@@ -4964,6 +5014,7 @@
      // add link to pop back to parent group
      if (this.env.address_group_stack.length > 1) {
        $('<a href="#list">...</a>')
          .attr('title', this.gettext('uponelevel'))
          .addClass('poplink')
          .appendTo(boxtitle)
          .click(function(e){ return ref.command('popgroup','',this); });
@@ -7368,7 +7419,8 @@
          this.enable_command('set-listmode', this.env.threads && !is_multifolder);
          if ((response.action == 'list' || response.action == 'search') && this.message_list) {
            this.message_list.focus();
            if (this.message_list.rowcount > 0)
              this.message_list.focus();
            this.msglist_select(this.message_list);
            this.triggerEvent('listupdate', { folder:this.env.mailbox, rowcount:this.message_list.rowcount });
          }
@@ -7380,11 +7432,18 @@
            this.enable_command('search-create', this.env.source == '');
            this.enable_command('search-delete', this.env.search_id);
            this.update_group_commands();
            this.contact_list.focus();
            if (this.contact_list.rowcount > 0)
              this.contact_list.focus();
            this.triggerEvent('listupdate', { folder:this.env.source, rowcount:this.contact_list.rowcount });
          }
        }
        break;
      case 'list-contacts':
      case 'search-contacts':
        if (this.contact_list && this.contact_list.rowcount > 0)
          this.contact_list.focus();
        break;
    }
    if (response.unlock)