alecpl
2011-05-13 bff88dcb94a95d53ac37d8ac3c2b86f512b5869a
- Apply fixes from trunk (up to r4756)


12 files modified
214 ■■■■ changed files
CHANGELOG 3 ●●●●● patch | view | raw | blame | history
plugins/new_user_dialog/new_user_dialog.php 4 ●●●● patch | view | raw | blame | history
plugins/new_user_dialog/package.xml 26 ●●●● patch | view | raw | blame | history
program/include/main.inc 52 ●●●● patch | view | raw | blame | history
program/include/rcube_imap.php 12 ●●●● patch | view | raw | blame | history
program/include/rcube_template.php 40 ●●●●● patch | view | raw | blame | history
program/js/app.js 47 ●●●● patch | view | raw | blame | history
program/js/list.js 8 ●●●●● patch | view | raw | blame | history
program/localization/pl_PL/labels.inc 2 ●●● patch | view | raw | blame | history
skins/default/ie6hacks.css 9 ●●●●● patch | view | raw | blame | history
skins/default/iehacks.css 9 ●●●●● patch | view | raw | blame | history
skins/default/mail.css 2 ●●● patch | view | raw | blame | history
CHANGELOG
@@ -1,6 +1,9 @@
CHANGELOG Roundcube Webmail
===========================
- Fix some CSS issues in Settings for Internet Explorer
- Fixed handling of folder with name "0" in folder selector
- Fix bug where messages were deleted instead moved to trash folder after Shift key was used (#1487902)
- Fix relative URLs handling according to a <base> in HTML (#1487889)
- Fix handling of top-level domains with more than 5 chars or unicode chars (#1487883)
- Fix usage of non-standard HTTP error codes (#1487797)
plugins/new_user_dialog/new_user_dialog.php
@@ -62,7 +62,7 @@
      $table->add(null, html::tag('input', array(
        'type' => 'text',
        'name' => '_email',
        'value' => idn_to_utf8($identity['email']),
        'value' => rcube_idn_to_utf8($identity['email']),
        'disabled' => ($identities_level == 1 || $identities_level == 3)
      )));
@@ -113,7 +113,7 @@
    if ($identities_level == 1 || $identities_level == 3)
      $save_data['email'] = $identity['email'];
    else
      $save_data['email'] = idn_to_ascii($save_data['email']);
      $save_data['email'] = rcube_idn_to_ascii($save_data['email']);
    // save data if not empty
    if (!empty($save_data['name']) && !empty($save_data['email'])) {
plugins/new_user_dialog/package.xml
@@ -13,10 +13,10 @@
        <email>roundcube@gmail.com</email>
        <active>yes</active>
    </lead>
    <date>2010-12-02</date>
    <time>12:00:00</time>
    <date>2011-05-12</date>
    <time>10:00</time>
    <version>
        <release>1.3</release>
        <release>1.4</release>
        <api>1.0</api>
    </version>
    <stability>
@@ -25,8 +25,7 @@
    </stability>
    <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
    <notes>
- Added setting of focus on name input
- Added gl_ES translation
- Fixed IDNA encoding/decoding of e-mail addresses (#1487909)
    </notes>
    <contents>
        <dir baseinstalldir="/" name="/">
@@ -119,5 +118,22 @@
- Fix possible error on form submission (#1486103)
            </notes>
        </release>
        <release>
            <date>2010-12-02</date>
            <time>12:00:00</time>
            <version>
                <release>1.3</release>
                <api>1.0</api>
            </version>
            <stability>
                <release>stable</release>
                <api>stable</api>
            </stability>
            <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
            <notes>
- Added setting of focus on name input
- Added gl_ES translation
            </notes>
        </release>
    </changelog>
</package>
program/include/main.inc
@@ -1289,12 +1289,12 @@
{
  global $RCMAIL;
  static $a_mailboxes;
  $attrib += array('maxlength' => 100, 'realnames' => false);
  // add some labels to client
  $RCMAIL->output->add_label('purgefolderconfirm', 'deletemessagesconfirm');
  $type = $attrib['type'] ? $attrib['type'] : 'ul';
  unset($attrib['type']);
@@ -1303,7 +1303,7 @@
  // get mailbox list
  $mbox_name = $RCMAIL->imap->get_mailbox_name();
  // build the folders tree
  if (empty($a_mailboxes)) {
    // get mailbox list
@@ -1318,20 +1318,20 @@
  // allow plugins to alter the folder tree or to localize folder names
  $hook = $RCMAIL->plugins->exec_hook('render_mailboxlist', array('list' => $a_mailboxes, 'delimiter' => $delimiter));
  if ($type=='select') {
  if ($type == 'select') {
    $select = new html_select($attrib);
    // add no-selection option
    if ($attrib['noselection'])
      $select->add(rcube_label($attrib['noselection']), '0');
      $select->add(rcube_label($attrib['noselection']), '');
    rcmail_render_folder_tree_select($hook['list'], $mbox_name, $attrib['maxlength'], $select, $attrib['realnames']);
    $out = $select->show();
  }
  else {
    $js_mailboxlist = array();
    $out = html::tag('ul', $attrib, rcmail_render_folder_tree_html($hook['list'], $mbox_name, $js_mailboxlist, $attrib), html::$common_attrib);
    $RCMAIL->output->add_gui_object('mailboxlist', $attrib['id']);
    $RCMAIL->output->set_env('mailboxes', $js_mailboxlist);
    $RCMAIL->output->set_env('collapsed_folders', $RCMAIL->config->get('collapsed_folders'));
@@ -1350,7 +1350,7 @@
function rcmail_mailbox_select($p = array())
{
  global $RCMAIL;
  $p += array('maxlength' => 100, 'realnames' => false);
  $a_mailboxes = array();
@@ -1423,7 +1423,7 @@
  if (strlen($subFolders))
    rcmail_build_folder_tree($arrFolders[$currentFolder]['folders'], $subFolders, $delm, $path.$delm);
}
/**
 * Return html for a structured list &lt;ul&gt; for the mailbox tree
@@ -1433,7 +1433,7 @@
function rcmail_render_folder_tree_html(&$arrFolders, &$mbox_name, &$jslist, $attrib, $nestLevel=0)
{
  global $RCMAIL, $CONFIG;
  $maxlength = intval($attrib['maxlength']);
  $realnames = (bool)$attrib['realnames'];
  $msgcounts = $RCMAIL->imap->get_cache('messagecount');
@@ -1476,15 +1476,15 @@
      $classes[] = 'inbox';
    else
      $classes[] = '_'.asciiwords($folder_class ? $folder_class : strtolower($folder['id']), true);
    $classes[] = $zebra_class;
    if ($folder['id'] == $mbox_name)
      $classes[] = 'selected';
    $collapsed = preg_match('/&'.rawurlencode($folder['id']).'&/', $RCMAIL->config->get('collapsed_folders'));
    $unread = $msgcounts ? intval($msgcounts[$folder['id']]['UNSEEN']) : 0;
    if ($folder['virtual'])
      $classes[] = 'virtual';
    else if ($unread)
@@ -1508,9 +1508,9 @@
        'style' => "position:absolute",
        'onclick' => sprintf("%s.command('collapse-folder', '%s')", JS_OBJECT_NAME, $js_name)
      ), '&nbsp;') : ''));
    $jslist[$folder_id] = array('id' => $folder['id'], 'name' => $foldername, 'virtual' => $folder['virtual']);
    if (!empty($folder['folders'])) {
      $out .= html::tag('ul', array('style' => ($collapsed ? "display:none;" : null)),
        rcmail_render_folder_tree_html($folder['folders'], $mbox_name, $jslist, $attrib, $nestLevel+1));
@@ -1530,32 +1530,28 @@
 * @return string
 */
function rcmail_render_folder_tree_select(&$arrFolders, &$mbox_name, $maxlength, &$select, $realnames=false, $nestLevel=0)
  {
  $idx = 0;
{
  $out = '';
  foreach ($arrFolders as $key=>$folder)
    {
  foreach ($arrFolders as $key=>$folder) {
    if (!$realnames && ($folder_class = rcmail_folder_classname($folder['id'])))
      $foldername = rcube_label($folder_class);
    else
      {
    else {
      $foldername = $folder['name'];
      // shorten the folder name to a given length
      if ($maxlength && $maxlength>1)
        $foldername = abbreviate_string($foldername, $maxlength);
      }
    }
    $select->add(str_repeat('&nbsp;', $nestLevel*4) . $foldername, $folder['id']);
    if (!empty($folder['folders']))
      $out .= rcmail_render_folder_tree_select($folder['folders'], $mbox_name, $maxlength, $select, $realnames, $nestLevel+1);
    $idx++;
    }
  }
  return $out;
  }
}
/**
program/include/rcube_imap.php
@@ -3564,7 +3564,7 @@
            return $this->conn->setMetadata($mailbox, $entries);
        }
        else if ($this->get_capability('ANNOTATEMORE') || $this->get_capability('ANNOTATEMORE2')) {
            foreach ($entries as $entry => $value) {
            foreach ((array)$entries as $entry => $value) {
                list($ent, $attr) = $this->md2annotate($entry);
                $entries[$entry] = array($ent, $attr, $value);
            }
@@ -3597,7 +3597,7 @@
            return $this->conn->deleteMetadata($mailbox, $entries);
        }
        else if ($this->get_capability('ANNOTATEMORE') || $this->get_capability('ANNOTATEMORE2')) {
            foreach ($entries as $idx => $entry) {
            foreach ((array)$entries as $idx => $entry) {
                list($ent, $attr) = $this->md2annotate($entry);
                $entries[$idx] = array($ent, $attr, NULL);
            }
@@ -3626,7 +3626,7 @@
            $mailbox = $this->mod_mailbox($mailbox);
        if ($this->get_capability('METADATA') || 
            !strlen(($mailbox) && $this->get_capability('METADATA-SERVER'))
            (!strlen($mailbox) && $this->get_capability('METADATA-SERVER'))
        ) {
            return $this->conn->getMetadata($mailbox, $entries, $options);
        }
@@ -3635,7 +3635,7 @@
            $res     = array();
            // Convert entry names
            foreach ($entries as $entry) {
            foreach ((array)$entries as $entry) {
                list($ent, $attr) = $this->md2annotate($entry);
                $queries[$attr][] = $ent;
            }
@@ -3656,11 +3656,11 @@
     * Converts the METADATA extension entry name into the correct
     * entry-attrib names for older ANNOTATEMORE version.
     *
     * @param string Entry name
     * @param string $entry Entry name
     *
     * @return array Entry-attribute list, NULL if not supported (?)
     */
    private function md2annotate($name)
    private function md2annotate($entry)
    {
        if (substr($entry, 0, 7) == '/shared') {
            return array(substr($entry, 7), 'value.shared');
program/include/rcube_template.php
@@ -113,7 +113,6 @@
        }
    }
    /**
     * Set page title variable
     */
@@ -121,7 +120,6 @@
    {
        $this->pagetitle = $title;
    }
    /**
     * Getter for the current page title
@@ -142,7 +140,6 @@
        return $title;
    }
    /**
     * Set skin
@@ -226,7 +223,6 @@
          $this->js_commands[] = $cmd;
    }
    /**
     * Add a localized label to the client environment
     */
@@ -240,7 +236,6 @@
            $this->command('add_label', $name, rcube_label($name));
        }
    }
    /**
     * Invoke display_message command
@@ -262,7 +257,6 @@
        }
    }
    /**
     * Delete all stored env variables and commands
     *
@@ -282,7 +276,6 @@
        parent::reset();
    }
    /**
     * Redirect to a certain url
     *
@@ -295,7 +288,6 @@
        header('Location: ' . $location);
        exit;
    }
    /**
     * Send the request output to the client.
@@ -361,16 +353,15 @@
    }
    /**
     * Parse a specific skin template and deliver to stdout
     *
     * Either returns nothing, or exists hard (exit();)
     * Parse a specific skin template and deliver to stdout (or return)
     *
     * @param  string  Template name
     * @param  boolean Exit script
     * @return void
     * @param  boolean Don't write to stdout, return parsed content instead
     *
     * @link   http://php.net/manual/en/function.exit.php
     */
    private function parse($name = 'main', $exit = true)
    function parse($name = 'main', $exit = true, $write = true)
    {
        $skin_path = $this->config['skin_path'];
        $plugin    = false;
@@ -428,21 +419,26 @@
        // trigger generic hook where plugins can put additional content to the page
        $hook = $this->app->plugins->exec_hook("render_page", array('template' => $realname, 'content' => $output));
        // add debug console
        if ($this->config['debug_level'] & 8) {
            $this->add_footer('<div id="console" style="position:absolute;top:5px;left:5px;width:405px;padding:2px;background:white;z-index:9000;">
                <a href="#toggle" onclick="con=$(\'#dbgconsole\');con[con.is(\':visible\')?\'hide\':\'show\']();return false">console</a>
                <textarea name="console" id="dbgconsole" rows="20" cols="40" wrap="off" style="display:none;width:400px;border:none;font-size:10px" spellcheck="false"></textarea></div>'
            );
        $output = $this->parse_with_globals($hook['content']);
        if ($write) {
            // add debug console
            if ($this->config['debug_level'] & 8) {
                $this->add_footer('<div id="console" style="position:absolute;top:5px;left:5px;width:405px;padding:2px;background:white;z-index:9000;">
                    <a href="#toggle" onclick="con=$(\'#dbgconsole\');con[con.is(\':visible\')?\'hide\':\'show\']();return false">console</a>
                    <textarea name="console" id="dbgconsole" rows="20" cols="40" wrap="off" style="display:none;width:400px;border:none;font-size:10px" spellcheck="false"></textarea></div>'
                );
            }
            $this->write(trim($output));
        }
        else {
            return $output;
        }
        $output = $this->parse_with_globals($hook['content']);
        $this->write(trim($output));
        if ($exit) {
            exit;
        }
    }
    /**
     * Return executable javascript code for all registered commands
program/js/app.js
@@ -647,13 +647,13 @@
      case 'delete':
        // mail task
        if (this.task=='mail')
        if (this.task == 'mail')
          this.delete_messages();
        // addressbook task
        else if (this.task=='addressbook')
        else if (this.task == 'addressbook')
          this.delete_contacts();
        // user settings task
        else if (this.task=='settings')
        else if (this.task == 'settings')
          this.delete_identity();
        break;
@@ -1353,22 +1353,20 @@
  this.doc_mouse_up = function(e)
  {
    var model, list, li;
    var model, list, li, id;
    if (this.message_list) {
      if (!rcube_mouse_is_over(e, this.message_list.list.parentNode))
        this.message_list.blur();
    if (list = this.message_list) {
      if (!rcube_mouse_is_over(e, list.list.parentNode))
        list.blur();
      else
        this.message_list.focus();
      list = this.message_list;
        list.focus();
      model = this.env.mailboxes;
    }
    else if (this.contact_list) {
      if (!rcube_mouse_is_over(e, this.contact_list.list.parentNode))
        this.contact_list.blur();
    else if (list = this.contact_list) {
      if (!rcube_mouse_is_over(e, list.list.parentNode))
        list.blur();
      else
        this.contact_list.focus();
      list = this.contact_list;
        list.focus();
      model = this.env.contactfolders;
    }
    else if (this.ksearch_value) {
@@ -1389,7 +1387,7 @@
    // reset 'pressed' buttons
    if (this.buttons_sel) {
      for (var id in this.buttons_sel)
      for (id in this.buttons_sel)
        if (typeof id != 'function')
          this.button_out(this.buttons_sel[id], id);
      this.buttons_sel = {};
@@ -1488,8 +1486,6 @@
      this.command('previouspage');
    else if (list.key_pressed == 34)
      this.command('nextpage');
    else
      list.shiftkey = false;
  };
  this.msglist_get_preview = function()
@@ -2415,17 +2411,19 @@
  // delete selected messages from the current mailbox
  this.delete_messages = function()
  {
    var selection = this.message_list ? $.merge([], this.message_list.get_selection()) : [];
    var uid, i, len, trash = this.env.trash_mailbox,
      list = this.message_list,
      selection = list ? $.merge([], list.get_selection()) : [];
    // exit if no mailbox specified or if selection is empty
    if (!this.env.uid && !selection.length)
      return;
    // also select childs of collapsed rows
    for (var uid, i=0, len=selection.length; i<len; i++) {
    for (i=0, len=selection.length; i<len; i++) {
      uid = selection[i];
      if (this.message_list.rows[uid].has_children && !this.message_list.rows[uid].expanded)
        this.message_list.select_childs(uid);
      if (list.rows[uid].has_children && !list.rows[uid].expanded)
        list.select_childs(uid);
    }
    // if config is set to flag for deletion
@@ -2434,17 +2432,18 @@
      return false;
    }
    // if there isn't a defined trash mailbox or we are in it
    else if (!this.env.trash_mailbox || this.env.mailbox == this.env.trash_mailbox)
    // @TODO: we should check if defined trash mailbox exists
    else if (!trash || this.env.mailbox == trash)
      this.permanently_remove_messages();
    // if there is a trash mailbox defined and we're not currently in it
    else {
      // if shift was pressed delete it immediately
      if (this.message_list && this.message_list.shiftkey) {
      if (list && list.shiftkey) {
        if (confirm(this.get_label('deletemessagesconfirm')))
          this.permanently_remove_messages();
      }
      else
        this.move_messages(this.env.trash_mailbox);
        this.move_messages(trash);
    }
    return true;
program/js/list.js
@@ -101,7 +101,7 @@
init_row: function(row)
{
  // make references in internal array and set event handlers
  if (row && String(row.id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)) {
  if (row && String(row.id).match(/^rcmrow([a-z0-9\-_=\+\/]+)/i)) {
    var self = this,
      uid = RegExp.$1;
    row.uid = uid;
@@ -601,7 +601,7 @@
    var i, len, rows = this.list.tBodies[0].rows;
    for (i=0, len=rows.length-1; i<len; i++)
      if (rows[i].id && String(rows[i].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i) && this.rows[RegExp.$1] != null)
      if (rows[i].id && String(rows[i].id).match(/^rcmrow([a-z0-9\-_=\+\/]+)/i) && this.rows[RegExp.$1] != null)
        return RegExp.$1;
  }
@@ -614,7 +614,7 @@
    var i, rows = this.list.tBodies[0].rows;
    for (i=rows.length-1; i>=0; i--)
      if (rows[i].id && String(rows[i].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i) && this.rows[RegExp.$1] != null)
      if (rows[i].id && String(rows[i].id).match(/^rcmrow([a-z0-9\-_=\+\/]+)/i) && this.rows[RegExp.$1] != null)
        return RegExp.$1;
  }
@@ -988,6 +988,8 @@
      this.shiftkey = e.shiftKey;
      this.key_pressed = keyCode;
      this.triggerEvent('keypress');
      // reset shiftkey flag, we need it only for registered events
      this.shiftkey = false;
      if (this.key_pressed == this.BACKSPACE_KEY)
        return rcube_event.cancel(e);
program/localization/pl_PL/labels.inc
@@ -357,7 +357,7 @@
$labels['replysamefolder'] = 'Umieszczaj odpowiedzi w folderze wiadomości, na którą odpowiadam';
$labels['contactproperties'] = 'Właściwości';
$labels['properties'] = 'Właściwości';
$labels['folderproperties'] = 'Włąściwości folderu';
$labels['folderproperties'] = 'Właściwości folderu';
$labels['parentfolder'] = 'Folder nadrzędny';
$labels['location'] = 'Położenie';
$labels['info'] = 'Informacje';
skins/default/ie6hacks.css
@@ -143,3 +143,12 @@
  background-image: url(images/messageicons.gif);
}
body.iframe .boxtitle
{
  position: absolute;
}
#subscription-table
{
  width: auto;
}
skins/default/iehacks.css
@@ -117,11 +117,6 @@
  width: expression((parseInt(document.documentElement.clientWidth)-240)+'px');
}
#subscription-table
{
  width: auto;
}
#messagelist
{
  width: inherit;
@@ -181,9 +176,11 @@
}
#contacts-box,
#prefs-box
#prefs-box,
#folder-box
{
  width: expression((parseInt(this.parentNode.offsetWidth)-555)+'px');
  overflow: hidden;
}
#rcmdraglayer
skins/default/mail.css
@@ -149,7 +149,7 @@
  padding-left: 15px;
}
#messagetoolbar select.mboxlist option[value="0"]
#messagetoolbar select.mboxlist option[value=""]
{
  padding-left: 2px;
}