root
2012-05-08 269b1433db56f58d9e8a1d38c0580fd483021871
skins/default/functions.js
@@ -8,12 +8,24 @@
function rcube_init_settings_tabs()
{
  var tab = '#settingstabdefault';
  if (window.rcmail && rcmail.env.action)
    tab = '#settingstab' + (rcmail.env.action=='preferences' ? 'default' : (rcmail.env.action.indexOf('identity')>0 ? 'identities' : rcmail.env.action.replace(/\./g, '')));
  var el, cl, container = $('#tabsbar'),
    last_tab = $('span:last', container),
    tab = '#settingstabdefault',
    action = window.rcmail && rcmail.env.action ? rcmail.env.action : null;
  // move About tab to the end
  if (last_tab && last_tab.attr('id') != 'settingstababout' && (el = $('#settingstababout'))) {
    cl = el.clone(true);
    el.remove();
    last_tab.after(cl);
  }
  // get selected tab
  if (action)
    tab = '#settingstab' + (action == 'preferences' ? 'default' : (action.indexOf('identity')>0 ? 'identities' : action.replace(/\./g, '')));
  $(tab).addClass('tablink-selected');
  $(tab + '> a').removeAttr('onclick').click(function() { return false; });
  $('a', tab).removeAttr('onclick').click(function() { return false; });
}
function rcube_show_advanced(visible)
@@ -82,14 +94,15 @@
  this.popups = {
    markmenu:       {id:'markmessagemenu'},
    replyallmenu:   {id:'replyallmenu'},
    forwardmenu:    {id:'forwardmenu'},
    forwardmenu:    {id:'forwardmenu', editable:1},
    searchmenu:     {id:'searchmenu', editable:1},
    messagemenu:    {id:'messagemenu'},
    listmenu:       {id:'listmenu', editable:1},
    dragmessagemenu:{id:'dragmessagemenu', sticky:1},
    groupmenu:      {id:'groupoptionsmenu', above:1},
    mailboxmenu:    {id:'mailboxoptionsmenu', above:1},
    composemenu:    {id:'composeoptionsmenu', editable:1},
    composemenu:    {id:'composeoptionsmenu', editable:1, overlap:1},
    spellmenu:      {id:'spellmenu'},
    // toggle: #1486823, #1486930
    uploadmenu:     {id:'attachment-form', editable:1, above:1, toggle:!bw.ie&&!bw.linux },
    uploadform:     {id:'upload-form', editable:1, toggle:!bw.ie&&!bw.linux }
@@ -108,8 +121,13 @@
rcube_mail_ui.prototype = {
show_popup: function(popup, show)
show_popup: function(popup, show, config)
{
  var obj;
  // auto-register menu object
  if (!this.popups[popup] && (obj = $('#'+popup)) && obj.length)
    this.popups[popup] = $.extend(config, {id: popup, obj: obj});
  if (typeof this[popup] == 'function')
    return this[popup](show);
  else
@@ -141,11 +159,23 @@
  }
  obj[show?'show':'hide']();
  if (bw.ie6 && this.popups[popup].overlap) {
    $('select').css('visibility', show?'hidden':'inherit');
    $('select', obj).css('visibility', 'inherit');
  }
},
dragmessagemenu: function(show)
{
  this.popups.dragmessagemenu.obj[show?'show':'hide']();
},
forwardmenu: function(show)
{
  $("input[name='forwardtype'][value="+(rcmail.env.forward_attachment ? 1 : 0)+"]", this.popups.forwardmenu.obj)
    .prop('checked', true);
  this.show_popupmenu('forwardmenu', show);
},
uploadmenu: function(show)
@@ -175,13 +205,32 @@
  if (show && ref) {
    var pos = $(ref).offset();
    obj.css({ left:pos.left, top:(pos.top + ref.offsetHeight + 2)})
        .find(':checked').prop('checked', false);
    obj.css({left:pos.left, top:(pos.top + ref.offsetHeight + 2)});
    if (rcmail.env.search_mods) {
      var search_mods = rcmail.env.search_mods[rcmail.env.mailbox] ? rcmail.env.search_mods[rcmail.env.mailbox] : rcmail.env.search_mods['*'];
      for (var n in search_mods)
        $('#s_mod_' + n).prop('checked', true);
      var n, all,
        list = $('input:checkbox[name="s_mods[]"]', obj),
        mbox = rcmail.env.mailbox,
        mods = rcmail.env.search_mods;
      if (rcmail.env.task == 'mail') {
        mods = mods[mbox] ? mods[mbox] : mods['*'];
        all = 'text';
      }
      else {
        all = '*';
      }
      if (mods[all])
        list.map(function() {
          this.checked = true;
          this.disabled = this.value != all;
        });
      else {
        list.prop('disabled', false).prop('checked', false);
        for (n in mods)
          $('#s_mod_' + n).prop('checked', true);
      }
    }
  }
  obj[show?'show':'hide']();
@@ -189,16 +238,47 @@
set_searchmod: function(elem)
{
  if (!rcmail.env.search_mods)
    rcmail.env.search_mods = {};
  var all, m, task = rcmail.env.task,
    mods = rcmail.env.search_mods,
    mbox = rcmail.env.mailbox;
  if (!rcmail.env.search_mods[rcmail.env.mailbox])
    rcmail.env.search_mods[rcmail.env.mailbox] = rcube_clone_object(rcmail.env.search_mods['*']);
  if (!mods)
    mods = {};
  if (task == 'mail') {
    if (!mods[mbox])
      mods[mbox] = rcube_clone_object(mods['*']);
    m = mods[mbox];
    all = 'text';
  }
  else { //addressbook
    m = mods;
    all = '*';
  }
  if (!elem.checked)
    delete(rcmail.env.search_mods[rcmail.env.mailbox][elem.value]);
    delete(m[elem.value]);
  else
    rcmail.env.search_mods[rcmail.env.mailbox][elem.value] = elem.value;
    m[elem.value] = 1;
  // mark all fields
  if (elem.value != all)
    return;
  $('input:checkbox[name="s_mods[]"]').map(function() {
    if (this == elem)
      return;
    this.checked = true;
    if (elem.checked) {
      this.disabled = true;
      delete m[this.value];
    }
    else {
      this.disabled = false;
      m[this.value] = 1;
    }
  });
},
listmenu: function(show)
@@ -272,6 +352,43 @@
  rcmail.set_list_options(cols, sort, ord, thread == 'thread' ? 1 : 0);
},
spellmenu: function(show)
{
  var link, li,
    lang = rcmail.spellcheck_lang(),
    menu = this.popups.spellmenu.obj,
    ul = $('ul', menu);
  if (!ul.length) {
    ul = $('<ul>');
    for (i in rcmail.env.spell_langs) {
      li = $('<li>');
      link = $('<a href="#">').text(rcmail.env.spell_langs[i])
        .addClass('active').data('lang', i)
        .click(function() {
          rcmail.spellcheck_lang_set($(this).data('lang'));
        });
      link.appendTo(li);
      li.appendTo(ul);
    }
    ul.appendTo(menu);
  }
  // select current language
  $('li', ul).each(function() {
    var el = $('a', this);
    if (el.data('lang') == lang)
      el.addClass('selected');
    else if (el.hasClass('selected'))
      el.removeClass('selected');
  });
  this.show_popupmenu('spellmenu', show);
},
body_mouseup: function(evt, p)
{
  var i, target = rcube_event.get_target(evt);
@@ -282,7 +399,7 @@
      && (!this.popups[i].editable || !this.target_overlaps(target, this.popups[i].id))
      && (!this.popups[i].sticky || !rcube_mouse_is_over(evt, rcube_find_object(this.popups[i].id)))
    ) {
      window.setTimeout('$("#'+this.popups[i].id+'").hide()', 50);
      window.setTimeout('rcmail_ui.show_popup("'+i+'",false);', 50);
    }
  }
},
@@ -347,7 +464,8 @@
    rcmail.env.contentframe = null;
    rcmail.show_contentframe(false);
  }
  rcmail.http_post('save-pref', '_name=preview_pane&_value='+(elem.checked?1:0));
  rcmail.command('save-pref', {name: 'preview_pane', value: (elem.checked?1:0)});
},
/* Message composing */
@@ -390,15 +508,10 @@
  w -= 8;  // 2 x 3px padding + 2 x 1px border
  h -= 4;
  $('#compose-body_tbl').width((w+6)+'px').height('');
  $('#compose-body_ifr').width((w+6)+'px').height((h-54)+'px');
  $('#compose-body').width(w+'px').height(h+'px');
  if (window.tinyMCE && tinyMCE.get('compose-body')) {
    $('#compose-body_tbl').width((w+6)+'px').height('');
    $('#compose-body_ifr').width((w+6)+'px').height((h-54)+'px');
  }
  else {
    $('#googie_edit_layer').height(h+'px');
  }
  $('#googie_edit_layer').height(h+'px');
},
resize_compose_body_ev: function()
@@ -478,6 +591,198 @@
};
/**
 * Scroller
 */
function rcmail_scroller(list, top, bottom)
{
  var ref = this;
  this.list = $(list);
  this.top = $(top);
  this.bottom = $(bottom);
  this.step_size = 6;
  this.step_time = 20;
  this.delay = 500;
  this.top
    .mouseenter(function() { ref.ts = window.setTimeout(function() { ref.scroll('down'); }, ref.delay); })
    .mouseout(function() { if (ref.ts) window.clearTimeout(ref.ts); });
  this.bottom
    .mouseenter(function() { ref.ts = window.setTimeout(function() { ref.scroll('up'); }, ref.delay); })
    .mouseout(function() { if (ref.ts) window.clearTimeout(ref.ts); });
  this.scroll = function(dir)
  {
    var ref = this, size = this.step_size;
    if (!rcmail.drag_active)
      return;
    if (dir == 'down')
      size *= -1;
    this.list.get(0).scrollTop += size;
    this.ts = window.setTimeout(function() { ref.scroll(dir); }, this.step_time);
  };
};
// Events handling in iframes (eg. preview pane)
function iframe_events()
{
  // this==iframe
  var doc = this.contentDocument ? this.contentDocument : this.contentWindow ? this.contentWindow.document : null;
  rcube_event.add_listener({ element: doc, object:rcmail_ui, method:'body_mouseup', event:'mouseup' });
};
// Abbreviate mailbox names to fit width of the container
function rcube_render_mailboxlist()
{
  var list = $('#mailboxlist > li a, #mailboxlist ul:visible > li a');
  // it's too slow with really big number of folders, especially on IE
  if (list.length > 500 * (bw.ie ? 0.2 : 1))
    return;
  list.each(function(){
    var elem = $(this),
      text = elem.data('text');
    if (!text) {
      text = elem.text().replace(/\s+\(.+$/, '');
      elem.data('text', text);
    }
    if (text.length < 6)
      return;
    var abbrev = fit_string_to_size(text, elem, elem.width() - elem.children('span.unreadcount').width());
    if (abbrev != text)
      elem.attr('title', text);
    elem.contents().filter(function(){ return (this.nodeType == 3); }).get(0).data = abbrev;
  });
};
// inspired by https://gist.github.com/24261/7fdb113f1e26111bd78c0c6fe515f6c0bf418af5
function fit_string_to_size(str, elem, len)
{
  var w, span, result = str, ellip = '...';
  if (!rcmail.env.tmp_span) {
    // it should be appended to elem to use the same css style
    // but for performance reasons we'll append it to body (once)
    span = $('<b>').css({visibility: 'hidden', padding: '0px'})
      .appendTo($('body', document)).get(0);
    rcmail.env.tmp_span = span;
  }
  else {
    span = rcmail.env.tmp_span;
  }
  span.innerHTML = result;
  // on first run, check if string fits into the length already.
  w = span.offsetWidth;
  if (w > len) {
    var cut = Math.max(1, Math.floor(str.length * ((w - len) / w) / 2)),
      mid = Math.floor(str.length / 2),
      offLeft = mid,
      offRight = mid;
    while (true) {
      offLeft = mid - cut;
      offRight = mid + cut;
      span.innerHTML = str.substring(0,offLeft) + ellip + str.substring(offRight);
      // break loop if string fits size
      if (offLeft < 3 || span.offsetWidth)
        break;
      cut++;
    }
    // build resulting string
    result = str.substring(0,offLeft) + ellip + str.substring(offRight);
  }
  return result;
};
function update_quota(data)
{
  percent_indicator(rcmail.gui_objects.quotadisplay, data);
};
// percent (quota) indicator
function percent_indicator(obj, data)
{
  if (!data || !obj)
    return false;
  var limit_high = 80,
    limit_mid  = 55,
    width = data.width ? data.width : rcmail.env.indicator_width ? rcmail.env.indicator_width : 100,
    height = data.height ? data.height : rcmail.env.indicator_height ? rcmail.env.indicator_height : 14,
    quota = data.percent ? Math.abs(parseInt(data.percent)) : 0,
    quota_width = parseInt(quota / 100 * width),
    pos = $(obj).position();
  // workarounds for Opera and Webkit bugs
  pos.top = Math.max(0, pos.top);
  pos.left = Math.max(0, pos.left);
  rcmail.env.indicator_width = width;
  rcmail.env.indicator_height = height;
  // overlimit
  if (quota_width > width) {
    quota_width = width;
    quota = 100;
  }
  if (data.title)
    data.title = rcmail.get_label('quota') + ': ' +  data.title;
  // main div
  var main = $('<div>');
  main.css({position: 'absolute', top: pos.top, left: pos.left,
      width: width + 'px', height: height + 'px', zIndex: 100, lineHeight: height + 'px'})
    .attr('title', data.title).addClass('quota_text').html(quota + '%');
  // used bar
  var bar1 = $('<div>');
  bar1.css({position: 'absolute', top: pos.top + 1, left: pos.left + 1,
      width: quota_width + 'px', height: height + 'px', zIndex: 99});
  // background
  var bar2 = $('<div>');
  bar2.css({position: 'absolute', top: pos.top + 1, left: pos.left + 1,
      width: width + 'px', height: height + 'px', zIndex: 98})
   .addClass('quota_bg');
  if (quota >= limit_high) {
    main.addClass(' quota_text_high');
    bar1.addClass('quota_high');
  }
  else if(quota >= limit_mid) {
    main.addClass(' quota_text_mid');
    bar1.addClass('quota_mid');
  }
  else {
    main.addClass(' quota_text_low');
    bar1.addClass('quota_low');
  }
  // replace quota image
  $(obj).html('').append(bar1).append(bar2).append(main);
  // update #quotaimg title
  $('#quotaimg').attr('title', data.title);
};
// Optional parameters used by TinyMCE
var rcmail_editor_settings = {
  skin : "default", // "default", "o2k7"
  skin_variant : "" // "", "silver", "black"
};
var rcmail_ui;
@@ -486,6 +791,10 @@
  rcmail_ui = new rcube_mail_ui();
  rcube_event.add_listener({ object:rcmail_ui, method:'body_mouseup', event:'mouseup' });
  rcube_event.add_listener({ object:rcmail_ui, method:'body_keydown', event:'keydown' });
  if (rcmail.env.quota_content)
    update_quota(rcmail.env.quota_content);
  rcmail.addEventListener('setquota', update_quota);
  $('iframe').load(iframe_events)
    .contents().mouseup(function(e){rcmail_ui.body_mouseup(e)});
@@ -502,7 +811,8 @@
      rcmail.addEventListener('responseaftergetunread', rcube_render_mailboxlist);
      rcmail.addEventListener('responseaftercheck-recent', rcube_render_mailboxlist);
      rcmail.addEventListener('aftercollapse-folder', rcube_render_mailboxlist);
      rcube_render_mailboxlist();
      new rcmail_scroller('#mailboxlist-content', '#mailboxlist-title', '#mailboxlist-footer');
    }
    if (rcmail.env.action == 'compose')
@@ -510,75 +820,12 @@
  }
  else if (rcmail.env.task == 'addressbook') {
    rcmail.addEventListener('afterupload-photo', function(){ rcmail_ui.show_popup('uploadform', false); });
    if (rcmail.gui_objects.folderlist)
      new rcmail_scroller('#directorylist-content', '#directorylist-title', '#directorylist-footer');
  }
  else if (rcmail.env.task == 'settings') {
    if (rcmail.gui_objects.subscriptionlist)
      new rcmail_scroller('#folderlist-content', '#folderlist-title', '#folderlist-footer');
  }
}
// Events handling in iframes (eg. preview pane)
function iframe_events()
{
  // this==iframe
  var doc = this.contentDocument ? this.contentDocument : this.contentWindow ? this.contentWindow.document : null;
  rcube_event.add_listener({ element: doc, object:rcmail_ui, method:'body_mouseup', event:'mouseup' });
}
// Abbreviate mailbox names to fit width of the container
function rcube_render_mailboxlist()
{
  if (bw.ie6)  // doesn't work well on IE6
    return;
  $('#mailboxlist > li a, #mailboxlist ul:visible > li a').each(function(){
    var elem = $(this);
    var text = elem.data('text');
    if (!text) {
      text = elem.text().replace(/\s+\(.+$/, '');
      elem.data('text', text);
    }
    if (text.length < 6)
      return;
    var abbrev = fit_string_to_size(text, elem, elem.width() - elem.children('span.unreadcount').width());
    if (abbrev != text)
      elem.attr('title', text);
    elem.contents().filter(function(){ return (this.nodeType == 3); }).get(0).data = abbrev;
  });
}
// inspired by https://gist.github.com/24261/7fdb113f1e26111bd78c0c6fe515f6c0bf418af5
function fit_string_to_size(str, elem, len)
{
    var result = str;
    var ellip = '...';
    var span = $('<b>').css({ visibility:'hidden', padding:'0px' }).appendTo(elem).get(0);
    // on first run, check if string fits into the length already.
    span.innerHTML = result;
    if (span.offsetWidth > len) {
        var cut = Math.max(1, Math.floor(str.length * ((span.offsetWidth - len) / span.offsetWidth) / 2)),
          mid = Math.floor(str.length / 2);
        var offLeft = mid, offRight = mid;
        while (true) {
            offLeft = mid - cut;
            offRight = mid + cut;
            span.innerHTML = str.substring(0,offLeft) + ellip + str.substring(offRight);
            // break loop if string fits size
            if (span.offsetWidth <= len || offLeft < 3)
              break;
            cut++;
        }
        // build resulting string
        result = str.substring(0,offLeft) + ellip + str.substring(offRight);
    }
    span.parentNode.removeChild(span);
    return result;
}
// Optional parameters used by TinyMCE
var rcmail_editor_settings = {
  skin : "default", // "default", "o2k7"
  skin_variant : "" // "", "silver", "black"
};