From bff88dcb94a95d53ac37d8ac3c2b86f512b5869a Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Fri, 13 May 2011 13:31:09 -0400
Subject: [PATCH] - Apply fixes from trunk (up to r4756)

---
 program/js/list.js                          |    8 +
 CHANGELOG                                   |    3 
 skins/default/ie6hacks.css                  |    9 ++
 program/include/main.inc                    |   52 ++++++-------
 program/include/rcube_imap.php              |   12 +-
 skins/default/mail.css                      |    2 
 plugins/new_user_dialog/package.xml         |   26 +++++-
 program/localization/pl_PL/labels.inc       |    2 
 program/include/rcube_template.php          |   40 ++++-----
 plugins/new_user_dialog/new_user_dialog.php |    4 
 skins/default/iehacks.css                   |    9 -
 program/js/app.js                           |   47 +++++------
 12 files changed, 116 insertions(+), 98 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 94b58f5..d31404b 100644
--- a/CHANGELOG
+++ b/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)
diff --git a/plugins/new_user_dialog/new_user_dialog.php b/plugins/new_user_dialog/new_user_dialog.php
index 96cd0da..c537b9b 100644
--- a/plugins/new_user_dialog/new_user_dialog.php
+++ b/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'])) {
diff --git a/plugins/new_user_dialog/package.xml b/plugins/new_user_dialog/package.xml
index 198a9fa..5287470 100644
--- a/plugins/new_user_dialog/package.xml
+++ b/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>
diff --git a/program/include/main.inc b/program/include/main.inc
index 3ac26dc..72a1905 100644
--- a/program/include/main.inc
+++ b/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;
-  }
+}
 
 
 /**
diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index e2ab550..32e7871 100644
--- a/program/include/rcube_imap.php
+++ b/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');
diff --git a/program/include/rcube_template.php b/program/include/rcube_template.php
index 5c69290..5e0f4c1 100755
--- a/program/include/rcube_template.php
+++ b/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
diff --git a/program/js/app.js b/program/js/app.js
index 07947db..dcfed47 100644
--- a/program/js/app.js
+++ b/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;
diff --git a/program/js/list.js b/program/js/list.js
index 8da3181..788b7a5 100644
--- a/program/js/list.js
+++ b/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);
diff --git a/program/localization/pl_PL/labels.inc b/program/localization/pl_PL/labels.inc
index e2b9fac..ce21b24 100644
--- a/program/localization/pl_PL/labels.inc
+++ b/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';
diff --git a/skins/default/ie6hacks.css b/skins/default/ie6hacks.css
index aef4f17..c23f77e 100644
--- a/skins/default/ie6hacks.css
+++ b/skins/default/ie6hacks.css
@@ -143,3 +143,12 @@
   background-image: url(images/messageicons.gif);
 }
 
+body.iframe .boxtitle
+{
+  position: absolute;
+}
+
+#subscription-table
+{
+  width: auto;
+}
diff --git a/skins/default/iehacks.css b/skins/default/iehacks.css
index a5c6546..87dbc93 100644
--- a/skins/default/iehacks.css
+++ b/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
diff --git a/skins/default/mail.css b/skins/default/mail.css
index b5630e3..605bcb2 100644
--- a/skins/default/mail.css
+++ b/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;
 }

--
Gitblit v1.9.1