thomascube
2012-01-02 7c2a9310c4104f51fcf56379dcc3511fa5bfae2d
program/js/app.js
@@ -145,6 +145,22 @@
    for (n in this.gui_objects)
      this.gui_objects[n] = rcube_find_object(this.gui_objects[n]);
    // clickjacking protection
    if (this.env.x_frame_options) {
      try {
        // bust frame if not allowed
        if (this.env.x_frame_options == 'deny' && top.location.href != self.location.href)
          top.location.href = self.location.href;
        else if (top.location.hostname != self.location.hostname)
          throw 1;
      } catch (e) {
        // possible clickjacking attack: disable all form elements
        $('form').each(function(){ ref.lock_form(this, true); });
        this.display_message("Blocked: possible clickjacking attack!", 'error');
        return;
      }
    }
    // init registered buttons
    this.init_buttons();
@@ -212,7 +228,8 @@
          this.enable_command('reply-list', this.env.list_post);
          if (this.env.action == 'show') {
            this.http_request('pagenav', '_uid='+this.env.uid+'&_mbox='+urlencode(this.env.mailbox),
            this.http_request('pagenav', '_uid='+this.env.uid+'&_mbox='+urlencode(this.env.mailbox)
              + (this.env.search_request ? '&_search='+this.env.search_request : ''),
              this.display_message('', 'loading'));
          }
@@ -334,11 +351,18 @@
        this.enable_command('preferences', 'identities', 'save', 'folders', true);
        if (this.env.action == 'identities') {
          this.enable_command('add', this.env.identities_level < 2);
          this.enable_command('add', 'delete', this.env.identities_level < 2);
        }
        else if (this.env.action == 'edit-identity' || this.env.action == 'add-identity') {
          this.enable_command('add', this.env.identities_level < 2);
          this.enable_command('save', 'delete', 'edit', 'toggle-editor', true);
          this.enable_command('save', 'edit', 'toggle-editor', true);
          if (this.is_framed() && this.env.identities_level < 2)
            this.set_button('delete', 'act');  // activate button but delegate command to parent
          else
            this.enable_command('delete', this.env.identities_level < 2);
          if (this.env.action == 'add-identity')
            $("input[type='text']").first().select();
        }
        else if (this.env.action == 'folders') {
          this.enable_command('subscribe', 'unsubscribe', 'create-folder', 'rename-folder', true);
@@ -890,7 +914,7 @@
        if (!this.gui_objects.messageform)
          break;
        if (!this.check_compose_input())
        if (!props.nocheck && !this.check_compose_input(command))
          break;
        // Reset the auto-save timer
@@ -914,8 +938,8 @@
      case 'send-attachment':
        // Reset the auto-save timer
        self.clearTimeout(this.save_timer);
        this.upload_file(props)
        this.upload_file(props || this.gui_objects.uploadform);
        break;
      case 'insert-sig':
@@ -1026,7 +1050,7 @@
        break;
      case 'upload-photo':
        this.upload_contact_photo(props);
        this.upload_contact_photo(props || this.gui_objects.uploadform);
        break;
      case 'delete-photo':
@@ -1347,7 +1371,7 @@
              if (this.folder_auto_timer)
                window.clearTimeout(this.folder_auto_timer);
              this.folder_auto_expand = k;
              this.folder_auto_expand = this.env.mailboxes[k].id;
              this.folder_auto_timer = window.setTimeout(function() {
                rcmail.command('collapse-folder', rcmail.folder_auto_expand);
                rcmail.drag_start(null);
@@ -1380,12 +1404,8 @@
  this.collapse_folder = function(name)
  {
    var li = this.get_folder_li(name, '', true),
      div = $(li.getElementsByTagName('div')[0]);
    if (!div || (!div.hasClass('collapsed') && !div.hasClass('expanded')))
      return;
    var ul = $(li.getElementsByTagName('ul')[0]);
      div = $('div:first', li),
      ul = $('ul:first', li);
    if (div.hasClass('collapsed')) {
      ul.show();
@@ -1393,7 +1413,7 @@
      var reg = new RegExp('&'+urlencode(name)+'&');
      this.env.collapsed_folders = this.env.collapsed_folders.replace(reg, '');
    }
    else {
    else if (div.hasClass('expanded')) {
      ul.hide();
      div.removeClass('expanded').addClass('collapsed');
      this.env.collapsed_folders = this.env.collapsed_folders+'&'+urlencode(name)+'&';
@@ -1402,6 +1422,8 @@
      if (this.env.mailbox.indexOf(name + this.env.delimiter) == 0)
        this.command('list', name);
    }
    else
      return;
    // Work around a bug in IE6 and IE7, see #1485309
    if (bw.ie6 || bw.ie7) {
@@ -2007,6 +2029,7 @@
      url += '&_refresh=1';
    this.select_folder(mbox, '', true);
    this.unmark_folder(mbox, 'recent', '', true);
    this.env.mailbox = mbox;
    // load message list remotely
@@ -2944,7 +2967,7 @@
  };
  // checks the input fields before sending a message
  this.check_compose_input = function()
  this.check_compose_input = function(cmd)
  {
    // check input fields
    var ed, input_to = $("[name='_to']"),
@@ -2979,15 +3002,28 @@
    // display localized warning for missing subject
    if (input_subject.val() == '') {
      var subject = prompt(this.get_label('nosubjectwarning'), this.get_label('nosubject'));
      var myprompt = $('<div class="prompt">').html('<div class="message">' + this.get_label('nosubjectwarning') + '</div>').appendTo(document.body);
      var prompt_value = $('<input>').attr('type', 'text').attr('size', 30).appendTo(myprompt).val(this.get_label('nosubject'));
      // user hit cancel, so don't send
      if (!subject && subject !== '') {
      var buttons = {};
      buttons[this.get_label('cancel')] = function(){
        input_subject.focus();
        return false;
      }
      else
        input_subject.val((subject ? subject : this.get_label('nosubject')));
        $(this).dialog('close');
      };
      buttons[this.get_label('sendmessage')] = function(){
        input_subject.val(prompt_value.val());
        $(this).dialog('close');
        ref.command(cmd, { nocheck:true });  // repeat command which triggered this
      };
      myprompt.dialog({
        modal: true,
        resizable: false,
        buttons: buttons,
        close: function(event, ui) { $(this).remove() }
      });
      prompt_value.select();
      return false;
    }
    // Apply spellcheck changes if spell checker is active
@@ -3019,6 +3055,11 @@
      this.display_spellcheck_controls(false);
      this.plain2html($('#'+props.id).val(), props.id);
      tinyMCE.execCommand('mceAddControl', false, props.id);
      if (this.env.default_font)
        window.setTimeout(function() {
          $(tinyMCE.get(props.id).getBody()).css('font-family', rcmail.env.default_font);
        }, 500);
    }
    else {
      var thisMCE = tinyMCE.get(props.id), existingHtml;
@@ -3058,7 +3099,7 @@
      if (!vis)
        this.stop_spellchecking();
      $(this.env.spellcheck.spell_container).css('visibility', vis ? 'visible' : 'hidden');
      $(this.env.spellcheck.spell_container)[vis ? 'show' : 'hide']();
    }
  };
@@ -3323,10 +3364,10 @@
        ts = frame_name.replace(/^rcmupload/, '');
      if (this.env.loadingicon)
        content = '<img src="'+this.env.loadingicon+'" alt="" />'+content;
        content = '<img src="'+this.env.loadingicon+'" alt="" class="uploading" />'+content;
      if (this.env.cancelicon)
        content = '<a title="'+this.get_label('cancel')+'" onclick="return rcmail.cancel_attachment_upload(\''+ts+'\', \''+frame_name+'\');" href="#cancelupload"><img src="'+this.env.cancelicon+'" alt="" /></a>'+content;
      this.add2attachment_list(ts, { name:'', html:content, complete:false });
        content = '<a title="'+this.get_label('cancel')+'" onclick="return rcmail.cancel_attachment_upload(\''+ts+'\', \''+frame_name+'\');" href="#cancelupload" class="cancelupload"><img src="'+this.env.cancelicon+'" alt="" /></a>'+content;
      this.add2attachment_list(ts, { name:'', html:content, classname:'uploading', complete:false });
      // upload progress support
      if (this.env.upload_progress_time) {
@@ -3346,7 +3387,7 @@
    if (!this.gui_objects.attachmentlist)
      return false;
    var indicator, li = $('<li>').attr('id', name).html(att.html);
    var indicator, li = $('<li>').attr('id', name).addClass(att.classname).html(att.html);
    // replace indicator's li
    if (upload_id && (indicator = document.getElementById(upload_id))) {
@@ -4041,7 +4082,7 @@
  this.delete_contacts = function()
  {
    var selection = this.contact_list.get_selection(),
      undelete = this.env.address_sources[this.env.source].undelete;
      undelete = this.env.source && this.env.address_sources[this.env.source].undelete;
    // exit if no mailbox specified or if selection is empty
    if (!(selection.length || this.env.cid) || (!undelete && !confirm(this.get_label('deletecontactconfirm'))))
@@ -4166,7 +4207,6 @@
        yearRange: '-100:+10',
        showOtherMonths: true,
        selectOtherMonths: true,
        monthNamesShort: this.env.month_names,
        onSelect: function(dateText) { $(this).focus().val(dateText) }
      });
      $('input.datepicker').datepicker();
@@ -4737,10 +4777,27 @@
    if (!id)
      id = this.env.iid ? this.env.iid : selection[0];
    // append token to request
    this.goto_url('delete-identity', '_iid='+id+'&_token='+this.env.request_token, true);
    // submit request with appended token
    if (confirm(this.get_label('deleteidentityconfirm')))
      this.goto_url('delete-identity', '_iid='+id+'&_token='+this.env.request_token, true);
    return true;
  };
  this.update_identity_row = function(id, name, add)
  {
    var row, col, list = this.identity_list,
      rid = this.html_identifier(id);
    if (list.rows[rid] && (row = list.rows[rid].obj)) {
      $(row.cells[0]).html(name);
    }
    else if (add) {
      row = $('<tr>').attr('id', 'rcmrow'+rid).get(0);
      col = $('<td>').addClass('mail').html(name).appendTo(row);
      list.insert_row(row);
      list.select(rid);
    }
  };
@@ -5434,6 +5491,18 @@
    }
  };
  // adds a class to selected folder
  this.mark_folder = function(name, class_name, prefix, encode)
  {
    $(this.get_folder_li(name, prefix, encode)).addClass(class_name);
  };
  // adds a class to selected folder
  this.unmark_folder = function(name, class_name, prefix, encode)
  {
    $(this.get_folder_li(name, prefix, encode)).removeClass(class_name);
  };
  // helper method to find a folder list item
  this.get_folder_li = function(name, prefix, encode)
  {
@@ -5536,18 +5605,24 @@
      if (typeof content === 'object' && content.type == 'image')
        this.percent_indicator(this.gui_objects.quotadisplay, content);
      else
        $(this.gui_objects.quotadisplay).html(content);
        $(this.gui_objects.quotadisplay).html(content.percent+'%').attr('title', content.title);
    }
    this.triggerEvent('setquota', content);
  };
  // update the mailboxlist
  this.set_unread_count = function(mbox, count, set_title)
  this.set_unread_count = function(mbox, count, set_title, mark)
  {
    if (!this.gui_objects.mailboxlist)
      return false;
    this.env.unread_counts[mbox] = count;
    this.set_unread_count_display(mbox, set_title);
    if (mark)
      this.mark_folder(mbox, mark, '', true);
    else if (!count)
      this.unmark_folder(mbox, 'recent', '', true);
  };
  // update the mailbox count display
@@ -5573,7 +5648,7 @@
      }
      if (mycount && text_obj.length)
        text_obj.html(' ('+mycount+')');
        text_obj.html(this.env.unreadwrap.replace(/%[sd]/, mycount));
      else if (text_obj.length)
        text_obj.remove();
@@ -5604,16 +5679,6 @@
      this.set_pagetitle(new_title);
    }
  };
  this.toggle_prefer_html = function(checkbox)
  {
    $('#rcmfd_show_images').prop('disabled', !checkbox.checked).val(0);
  };
  this.toggle_preview_pane = function(checkbox)
  {
    $('#rcmfd_preview_pane_mark_read').prop('disabled', !checkbox.checked);
  };
  // display fetched raw headers
@@ -5733,10 +5798,13 @@
    });
  };
  this.plain2html = function(plainText, id)
  this.plain2html = function(plain, id)
  {
    var lock = this.set_busy(true, 'converting');
    $('#'+id).val(plainText ? '<pre>'+plainText+'</pre>' : '');
    plain = plain.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
    $('#'+id).val(plain ? '<pre>'+plain+'</pre>' : '');
    this.set_busy(false, null, lock);
  };