Thomas Bruederli
2014-05-27 d0d7f43ef53d71322a8793ec10f7179f30615127
program/js/app.js
@@ -3381,7 +3381,9 @@
    this.env.recipients_delimiter = this.env.recipients_separator + ' ';
    obj.keydown(function(e) { return ref.ksearch_keydown(e, this, props); })
      .attr('autocomplete', 'off');
      .attr('autocomplete', 'off')
      .attr('aria-autocomplete', 'list')
      .attr('aria-expanded', 'false');
  };
  this.submit_messageform = function(draft)
@@ -4471,7 +4473,7 @@
        var dir = key==38 ? 1 : 0;
        highlight = document.getElementById('rcmksearchSelected');
        highlight = document.getElementById('rcmkSearchItem' + this.ksearch_selected);
        if (!highlight)
          highlight = this.ksearch_pane.__ul.firstChild;
@@ -4519,14 +4521,14 @@
  this.ksearch_select = function(node)
  {
    var current = $('#rcmksearchSelected');
    if (current[0] && node) {
      current.removeAttr('id').removeClass('selected');
    if (this.ksearch_pane && node) {
      this.ksearch_pane.find('li.selected').removeClass('selected').removeAttr('aria-selected');
    }
    if (node) {
      $(node).attr('id', 'rcmksearchSelected').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);
    }
  };
@@ -4657,16 +4659,20 @@
      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;
    // create results pane if not present
    if (!this.ksearch_pane) {
      ul = $('<ul>');
      this.ksearch_pane = $('<div>').attr('id', 'rcmKSearchpane')
      this.ksearch_pane = $('<div>').attr('id', 'rcmKSearchpane').attr('role', 'listbox')
        .css({ position:'absolute', 'z-index':30000 }).append(ul).appendTo(document.body);
      this.ksearch_pane.__ul = ul[0];
      // register (delegate) event handlers
      ul.on('mouseover', 'li', function(e){ ref.ksearch_select(e.target); })
        .on('onmouseup', 'li', function(e){ ref.ksearch_click(e.target); })
    }
    ul = this.ksearch_pane.__ul;
@@ -4691,13 +4697,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.innerHTML = text.replace(new RegExp('('+RegExp.escape(value)+')', 'ig'), '##$1%%').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/##([^%]+)%%/g, '<b>$1</b>');
        li.onmouseover = function(){ ref.ksearch_select(this); };
        li.onmouseup = function(){ ref.ksearch_click(this) };
        li._rcm_id = this.env.contacts.length + i;
        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;
      }
    }
@@ -4706,9 +4712,14 @@
      this.ksearch_pane.show();
      // select the first
      if (!this.env.contacts.length) {
        $('li:first', ul).attr('id', 'rcmksearchSelected').addClass('selected');
        this.ksearch_selected = 0;
        this.ksearch_select($('li:first', ul).get(0));
      }
      // set the right aria-* attributes to the input field
      $(this.ksearch_input)
        .attr('aria-haspopup', 'true')
        .attr('aria-expanded', 'true')
        .attr('aria-owns', 'rcmKSearchpane')
    }
    if (len)
@@ -4743,6 +4754,12 @@
    if (this.ksearch_pane)
      this.ksearch_pane.hide();
    $(this.ksearch_input)
      .attr('aria-haspopup', 'false')
      .attr('aria-expanded', 'false')
      .removeAttr('aria-activedecendant')
      .removeAttr('aria-owns');
    this.ksearch_destroy();
  };
@@ -6581,10 +6598,8 @@
      this.treelist.select(name);
    }
    else if (this.gui_objects.folderlist) {
      $('li.selected', this.gui_objects.folderlist)
        .removeClass('selected').addClass('unfocused');
      $(this.get_folder_li(name, prefix, encode))
        .removeClass('unfocused').addClass('selected');
      $('li.selected', this.gui_objects.folderlist).removeClass('selected');
      $(this.get_folder_li(name, prefix, encode)).addClass('selected');
      // trigger event hook
      this.triggerEvent('selectfolder', { folder:name, prefix:prefix });
@@ -6960,14 +6975,14 @@
          this.hide_menu(this.menu_stack[i]);
      }
      if (stack && this.menu_stack.length) {
        obj.data('parent', this.menu_stack.last());
        obj.css('z-index', ($('#'+this.menu_stack.last()).css('z-index') || 0) + 1);
        obj.data('parent', $.last(this.menu_stack));
        obj.css('z-index', ($('#'+$.last(this.menu_stack)).css('z-index') || 0) + 1);
      }
      else if (!stack && this.menu_stack.length) {
        this.hide_menu(this.menu_stack[0], event);
      }
      obj.show().attr('aria-hidden', 'false').data('opener', ref.get(0));
      obj.show().attr('aria-hidden', 'false').data('opener', ref.attr('aria-expanded', 'true').get(0));
      this.triggerEvent('menu-open', { name:name, obj:obj, props:prop, originalEvent:event });
      this.menu_stack.push(name);
@@ -6999,8 +7014,10 @@
      this.triggerEvent('menu-close', { name:this.menu_stack[j], obj:obj, props:{ menu:this.menu_stack[j] }, originalEvent:event });
      if (this.menu_stack[j] == name) {
        j = -1;  // stop loop
        if (keyboard && obj.data('opener')) {
          obj.data('opener').focus();
        if (obj.data('opener')) {
          $(obj.data('opener')).attr('aria-expanded', 'false');
          if (keyboard)
            obj.data('opener').focus();
        }
      }
      this.menu_stack.pop();
@@ -7009,7 +7026,7 @@
    // focus previous menu in stack
    if (this.menu_stack.length && keyboard) {
      this.menu_keyboard_active = true;
      this.focused_menu = this.menu_stack.last();
      this.focused_menu = $.last(this.menu_stack);
      if (!obj || !obj.data('opener'))
        $('#'+this.focused_menu).find('a,input:not(:disabled)').not('[aria-disabled=true]').first().focus();
    }