Aleksander Machniak
2014-07-30 31b02362653e6399ef63a2342dc0e777c173c33b
program/js/app.js
@@ -236,8 +236,6 @@
            return ref.command('sort', $(this).attr('rel'), this);
          });
          this.gui_objects.messagelist.parentNode.onclick = function(e){ return ref.click_on_list(e || window.event); };
          this.enable_command('toggle_status', 'toggle_flag', 'sort', true);
          this.enable_command('set-listmode', this.env.threads && !this.is_multifolder_listing());
@@ -405,8 +403,6 @@
            .addEventListener('dragmove', function(e) { ref.drag_move(e); })
            .addEventListener('dragend', function(e) { ref.drag_end(e); })
            .init();
          this.gui_objects.contactslist.parentNode.onmousedown = function(e){ return ref.click_on_list(e); };
          $(this.gui_objects.qsearchbox).focusin(function() { ref.contact_list.blur(); });
@@ -1056,7 +1052,7 @@
        if (this.task == 'mail') {
          url._mbox = this.env.mailbox;
          if (props)
             url._to = props;
            url._to = props;
          // also send search request so we can go back to search result after message is sent
          if (this.env.search_request)
            url._search = this.env.search_request;
@@ -1084,8 +1080,12 @@
            break;
          }
        }
        else if (props)
        else if (props && typeof props == 'string') {
          url._to = props;
        }
        else if (props && typeof props == 'object') {
          $.extend(url, props);
        }
        this.open_compose_step(url);
        break;
@@ -1713,19 +1713,6 @@
    return true;
  }
  this.click_on_list = function(e)
  {
    if (this.gui_objects.qsearchbox)
      this.gui_objects.qsearchbox.blur();
    if (this.message_list)
      this.message_list.focus(e);
    else if (this.contact_list)
      this.contact_list.focus(e);
    return true;
  };
  this.msglist_select = function(list)
  {
@@ -3374,9 +3361,7 @@
    }
    // check for locally stored compose data
    if (window.localStorage) {
      this.compose_restore_dialog(0, html_mode)
    }
    this.compose_restore_dialog(0, html_mode)
    if (input_to.val() == '')
      input_to.focus();
@@ -3900,15 +3885,16 @@
      }
    });
    if (window.localStorage && !empty) {
    if (!empty) {
      var index = this.local_storage_get_item('compose.index', []),
        key = this.env.compose_id;
        if ($.inArray(key, index) < 0) {
          index.push(key);
        }
        this.local_storage_set_item('compose.' + key, formdata, true);
        this.local_storage_set_item('compose.index', index);
      if ($.inArray(key, index) < 0) {
        index.push(key);
      }
      this.local_storage_set_item('compose.' + key, formdata, true);
      this.local_storage_set_item('compose.index', index);
    }
  };
@@ -3940,27 +3926,24 @@
  // remove stored compose data from localStorage
  this.remove_compose_data = function(key)
  {
    if (window.localStorage) {
      var index = this.local_storage_get_item('compose.index', []);
    var index = this.local_storage_get_item('compose.index', []);
      if ($.inArray(key, index) >= 0) {
        this.local_storage_remove_item('compose.' + key);
        this.local_storage_set_item('compose.index', $.grep(index, function(val,i) { return val != key; }));
      }
    if ($.inArray(key, index) >= 0) {
      this.local_storage_remove_item('compose.' + key);
      this.local_storage_set_item('compose.index', $.grep(index, function(val,i) { return val != key; }));
    }
  };
  // clear all stored compose data of this user
  this.clear_compose_data = function()
  {
    if (window.localStorage) {
      var i, index = this.local_storage_get_item('compose.index', []);
    var i, index = this.local_storage_get_item('compose.index', []);
      for (i=0; i < index.length; i++) {
        this.local_storage_remove_item('compose.' + index[i]);
      }
      this.local_storage_remove_item('compose.index');
    for (i=0; i < index.length; i++) {
      this.local_storage_remove_item('compose.' + index[i]);
    }
    this.local_storage_remove_item('compose.index');
  };
@@ -3981,18 +3964,16 @@
        return;
    }
    var i, rx,
      id = obj.options[obj.selectedIndex].value,
    var id = obj.options[obj.selectedIndex].value,
      sig = this.env.identity,
      delim = this.env.recipients_separator,
      rx_delim = RegExp.escape(delim),
      headers = ['replyto', 'bcc'];
      rx_delim = RegExp.escape(delim);
    // update reply-to/bcc fields with addresses defined in identities
    for (i in headers) {
      var key = headers[i],
        old_val = sig && this.env.identities[sig] ? this.env.identities[sig][key] : '',
        new_val = id && this.env.identities[id] ? this.env.identities[id][key] : '',
    $.each(['replyto', 'bcc'], function() {
      var rx, key = this,
        old_val = sig && ref.env.identities[sig] ? ref.env.identities[sig][key] : '',
        new_val = id && ref.env.identities[id] ? ref.env.identities[id][key] : '',
        input = $('[name="_'+key+'"]'), input_val = input.val();
      // remove old address(es)
@@ -4019,7 +4000,7 @@
      if (old_val || new_val)
        input.val(input_val).change();
    }
    });
    // enable manual signature insert
    if (this.env.signatures && this.env.signatures[id]) {
@@ -5162,29 +5143,55 @@
        .submit(function() { $('input.mainaction').click(); return false; });
  };
  // group creation dialog
  this.group_create = function()
  {
    this.add_input_row('contactgroup');
    var input = $('<input>').attr('type', 'text'),
      content = $('<label>').text(this.get_label('namex')).append(input);
    this.show_popup_dialog(content, this.get_label('newgroup'),
      [{
        text: this.get_label('save'),
        click: function() {
          var name;
          if (name = input.val()) {
            ref.http_post('group-create', {_source: ref.env.source, _name: name},
              ref.set_busy(true, 'loading'));
          }
          $(this).dialog('close');
        }
      }]
    );
  };
  // group rename dialog
  this.group_rename = function()
  {
    if (!this.env.group || !this.gui_objects.folderlist)
    if (!this.env.group)
      return;
    if (!this.name_input) {
      this.enable_command('list', 'listgroup', false);
      this.name_input = $('<input>').attr('type', 'text').val(this.env.contactgroups['G'+this.env.source+this.env.group].name);
      this.name_input.bind('keydown', function(e) { return ref.add_input_keydown(e); });
      this.env.group_renaming = true;
    var group_name = this.env.contactgroups['G' + this.env.source + this.env.group].name,
      input = $('<input>').attr('type', 'text').val(group_name),
      content = $('<label>').text(this.get_label('namex')).append(input);
      var link, li = this.get_folder_li('G'+this.env.source+this.env.group,'',true);
      if (li && (link = li.firstChild)) {
        $(link).hide().before(this.name_input);
      }
    }
    this.show_popup_dialog(content, this.get_label('grouprename'),
      [{
        text: this.get_label('save'),
        click: function() {
          var name;
    this.name_input.select().focus();
          if ((name = input.val()) && name != group_name) {
            ref.http_post('group-rename', {_source: ref.env.source, _gid: ref.env.group, _name: name},
              ref.set_busy(true, 'loading'));
          }
          $(this).dialog('close');
        }
      }],
      {open: function() { input.select(); }}
    );
  };
  this.group_delete = function()
@@ -5209,38 +5216,6 @@
    this.list_contacts(prop.source, 0);
  };
  // @TODO: maybe it would be better to use popup instead of inserting input to the list?
  this.add_input_row = function(type)
  {
    if (!this.gui_objects.folderlist)
      return;
    if (!this.name_input) {
      this.name_input = $('<input>').attr('type', 'text').data('tt', type);
      this.name_input.bind('keydown', function(e) { return ref.add_input_keydown(e); });
      this.name_input_li = $('<li>').addClass(type).append(this.name_input);
      var ul, li;
      // find list (UL) element
      if (type == 'contactsearch')
        ul = this.gui_objects.savedsearchlist;
      else
        ul = $('ul.groups', this.get_folder_li(this.env.source,'',true));
      // append to the list
      li = $('li:last', ul);
      if (li.length)
        this.name_input_li.insertAfter(li);
      else {
        this.name_input_li.appendTo(ul);
        ul.show(); // make sure the list is visible
      }
    }
    this.name_input.select().focus();
  };
  //remove selected contacts from current active group
  this.group_remove_selected = function()
  {
@@ -5260,62 +5235,9 @@
    }
  };
  // handler for keyboard events on the input field
  this.add_input_keydown = function(e)
  {
    var key = rcube_event.get_keycode(e),
      input = $(e.target), itype = input.data('tt');
    // enter
    if (key == 13) {
      var newname = input.val();
      if (newname) {
        var lock = this.set_busy(true, 'loading');
        if (itype == 'contactsearch')
          this.http_post('search-create', {_search: this.env.search_request, _name: newname}, lock);
        else if (this.env.group_renaming)
          this.http_post('group-rename', {_source: this.env.source, _gid: this.env.group, _name: newname}, lock);
        else
          this.http_post('group-create', {_source: this.env.source, _name: newname}, lock);
      }
      return false;
    }
    // escape
    else if (key == 27)
      this.reset_add_input();
    return true;
  };
  this.reset_add_input = function()
  {
    if (this.name_input) {
      var li = this.name_input.parent();
      if (this.env.group_renaming) {
        li.children().last().show();
        this.env.group_renaming = false;
      }
      else if ($('li', li.parent()).length == 1)
        li.parent().hide();
      this.name_input.remove();
      if (this.name_input_li)
        this.name_input_li.remove();
      this.name_input = this.name_input_li = null;
    }
    this.enable_command('list', 'listgroup', true);
  };
  // callback for creating a new contact group
  this.insert_contact_group = function(prop)
  {
    this.reset_add_input();
    prop.type = 'group';
    var key = 'G'+prop.source+prop.id,
@@ -5333,8 +5255,6 @@
  // callback for renaming a contact group
  this.update_contact_group = function(prop)
  {
    this.reset_add_input();
    var key = 'G'+prop.source+prop.id,
      newnode = {};
@@ -5598,8 +5518,6 @@
  // callback for creating a new saved search record
  this.insert_saved_search = function(name, id)
  {
    this.reset_add_input();
    var key = 'S'+id,
      link = $('<a>').attr('href', '#')
        .attr('rel', id)
@@ -5615,10 +5533,27 @@
    this.triggerEvent('abook_search_insert', prop);
  };
  // creates an input for saved search name
  // creates a dialog for saved search
  this.search_create = function()
  {
    this.add_input_row('contactsearch');
    var input = $('<input>').attr('type', 'text'),
      content = $('<label>').text(this.get_label('namex')).append(input);
    this.show_popup_dialog(content, this.get_label('searchsave'),
      [{
        text: this.get_label('save'),
        click: function() {
          var name;
          if (name = input.val()) {
            ref.http_post('search-create', {_search: ref.env.search_request, _name: name},
              ref.set_busy(true, 'loading'));
          }
          $(this).dialog('close');
        }
      }]
    );
  };
  this.search_delete = function()
@@ -5896,6 +5831,9 @@
  {
    if (!this.gui_objects.subscriptionlist)
      return false;
    // disable drag-n-drop temporarily
    this.subscription_list.draggable('destroy').droppable('destroy');
    var row, n, tmp, tmp_name, rowid, collator, pos, p, parent = '',
      folders = [], list = [], slist = [],
@@ -6473,22 +6411,27 @@
  };
  // open a jquery UI dialog with the given content
  this.show_popup_dialog = function(html, title, buttons, options)
  this.show_popup_dialog = function(content, title, buttons, options)
  {
    // forward call to parent window
    if (this.is_framed()) {
      return parent.rcmail.show_popup_dialog(html, title, buttons, options);
      return parent.rcmail.show_popup_dialog(content, title, buttons, options);
    }
    var popup = $('<div class="popup">')
      .html(html)
      .dialog($.extend({
    var popup = $('<div class="popup">');
    if (typeof content == 'object')
      popup.append(content);
    else
      popup.html(content);
    popup.dialog($.extend({
        title: title,
        buttons: buttons,
        modal: true,
        resizable: true,
        width: 500,
        close: function(event, ui) { $(this).remove() }
        close: function(event, ui) { $(this).remove(); }
      }, options || {}));
    // resize and center popup
@@ -8032,22 +7975,43 @@
  // wrapper for localStorage.getItem(key)
  this.local_storage_get_item = function(key, deflt, encrypted)
  {
    var item;
    // TODO: add encryption
    var item = localStorage.getItem(this.get_local_storage_prefix() + key);
    try {
      item = localStorage.getItem(this.get_local_storage_prefix() + key);
    }
    catch (e) { }
    return item !== null ? JSON.parse(item) : (deflt || null);
  };
  // wrapper for localStorage.setItem(key, data)
  this.local_storage_set_item = function(key, data, encrypted)
  {
    // TODO: add encryption
    return localStorage.setItem(this.get_local_storage_prefix() + key, JSON.stringify(data));
    // try/catch to handle no localStorage support, but also error
    // in Safari-in-private-browsing-mode where localStorage exists
    // but can't be used (#1489996)
    try {
      // TODO: add encryption
      localStorage.setItem(this.get_local_storage_prefix() + key, JSON.stringify(data));
      return true;
    }
    catch (e) {
      return false;
    }
  };
  // wrapper for localStorage.removeItem(key)
  this.local_storage_remove_item = function(key)
  {
    return localStorage.removeItem(this.get_local_storage_prefix() + key);
    try {
      localStorage.removeItem(this.get_local_storage_prefix() + key);
      return true;
    }
    catch (e) {
      return false;
    }
  };
}  // end object rcube_webmail