From fe79b1bcf828b6b9f947c4b32d5e7bf297438be4 Mon Sep 17 00:00:00 2001
From: thomascube <thomas@roundcube.net>
Date: Sun, 30 Jul 2006 06:14:19 -0400
Subject: [PATCH] Alter links in HTML messages; highlight droptargets

---
 CHANGELOG                   |    7 ++
 program/include/main.inc    |   42 ++++++++-----
 skins/default/mail.css      |    4 +
 program/steps/mail/func.inc |   27 ++++++++
 program/js/app.js           |   76 ++++++++++++++++++-------
 5 files changed, 116 insertions(+), 40 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 4d3bfa5..df15463 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,13 @@
 CHANGELOG RoundCube Webmail
 ---------------------------
 
+2006/07/30 (thomasb)
+----------
+- Alter links in HTML messages (Bug #1326402)
+- Added fallback if host not found in 'mail_domain' array
+- Applied patch of Charles to highlight droptargets (Ticket #1473034)
+
+
 2006/07/25 (thomasb)
 ----------
 - Made folder renaming a bit more ajax-style
diff --git a/program/include/main.inc b/program/include/main.inc
index e77df19..bbfba07 100644
--- a/program/include/main.inc
+++ b/program/include/main.inc
@@ -541,12 +541,14 @@
 
   if ($user_id = $DB->insert_id(get_sequence_name('users')))
     {
-    if (is_array($CONFIG['mail_domain']) && isset($CONFIG['mail_domain'][$host]))
-      $mail_domain = $CONFIG['mail_domain'][$host];
+    $mail_domain = $host;
+    if (is_array($CONFIG['mail_domain']))
+      {
+      if (isset($CONFIG['mail_domain'][$host]))
+        $mail_domain = $CONFIG['mail_domain'][$host];
+      }
     else if (!empty($CONFIG['mail_domain']))
       $mail_domain = $CONFIG['mail_domain'];
-    else
-      $mail_domain = $host;
    
     if ($user_email=='')
       $user_email = strstr($user, '@') ? $user : sprintf('%s@%s', $user, $mail_domain);
@@ -1125,21 +1127,12 @@
   }
 
 
-function rcube_xml_command($command, $str_attrib, $a_attrib=NULL)
+function rcube_xml_command($command, $str_attrib, $add_attrib=array())
   {
   global $IMAP, $CONFIG, $OUTPUT;
   
-  $attrib = array();
   $command = strtolower($command);
-
-  preg_match_all('/\s*([-_a-z]+)=["]([^"]+)["]?/i', stripslashes($str_attrib), $regs, PREG_SET_ORDER);
-
-  // convert attributes to an associative array (name => value)
-  if ($regs)
-    foreach ($regs as $attr)
-      $attrib[strtolower($attr[1])] = $attr[2];
-  else if ($a_attrib)
-    $attrib = $a_attrib;
+  $attrib = parse_attrib_string($str_attrib) + $add_attrib;
 
   // execute command
   switch ($command)
@@ -1223,7 +1216,7 @@
         'identityform' => 'rcube_identity_form',
         'foldersubscription' => 'rcube_subscription_form',
         'createfolder' => 'rcube_create_folder_form',
-	'renamefolder' => 'rcube_rename_folder_form',
+        'renamefolder' => 'rcube_rename_folder_form',
         'composebody' => 'rcmail_compose_body'
       );
 
@@ -1523,18 +1516,33 @@
   }
 
 
+// compose a valid attribute string for HTML tags
 function create_attrib_string($attrib, $allowed_attribs=array('id', 'class', 'style'))
   {
   // allow the following attributes to be added to the <iframe> tag
   $attrib_str = '';
   foreach ($allowed_attribs as $a)
     if (isset($attrib[$a]))
-      $attrib_str .= sprintf(' %s="%s"', $a, $attrib[$a]);
+      $attrib_str .= sprintf(' %s="%s"', $a, str_replace('"', '&quot;', $attrib[$a]));
 
   return $attrib_str;
   }
 
 
+// convert a HTML attribute string attributes to an associative array (name => value)
+function parse_attrib_string($str)
+  {
+  $attrib = array();
+  preg_match_all('/\s*([-_a-z]+)=["]([^"]+)["]?/i', stripslashes($str), $regs, PREG_SET_ORDER);
+
+  // convert attributes to an associative array (name => value)
+  if ($regs)
+    foreach ($regs as $attr)
+      $attrib[strtolower($attr[1])] = $attr[2];
+
+  return $attrib;
+  }
+
 
 function format_date($date, $format=NULL)
   {
diff --git a/program/js/app.js b/program/js/app.js
index 47545e2..84e9e45 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -287,14 +287,20 @@
     if (!e)
       e = window.event;
 
-    for (var n=0; n<this.selection.length; n++) {
+    for (var n=0; n<this.selection.length; n++)
+      {
       id = this.selection[n];
-      if (this.list_rows[id].obj) {
+      if (this.list_rows[id].obj)
+        {
         this.set_classname(this.list_rows[id].obj, 'selected', true);
 		this.set_classname(this.list_rows[id].obj, 'unfocused', false);
-	  }
-    }
+        }
+      }
 
+    var mbox_li;
+    if (mbox_li = this.get_mailbox_li()) 
+      this.set_classname(mbox_li, 'unfocused', true);
+    
     this.in_message_list = true;
     e.cancelBubble = true;
     };
@@ -1183,10 +1189,13 @@
   this.mbox_mouse_up = function(mbox)
     {
     if (this.drag_active)
+      {
+      this.unfocus_mailbox(mbox);
       this.command('moveto', mbox);
+      }
     else
       this.command('list', mbox);
-      
+  
     return false;
     };
 
@@ -1556,8 +1565,7 @@
     if (this.env.search_request)
       add_url += '&_search='+this.env.search_request;
       
-    if (this.env.mailbox!=mbox)
-      this.select_mailbox(mbox);
+    this.select_mailbox(mbox);
 
     // load message list remotely
     if (this.gui_objects.messagelist)
@@ -1667,7 +1675,20 @@
     return true;
     };
     
-
+  this.focus_mailbox = function(mbox)
+    {
+    var mbox_li;
+  	if (this.drag_active && mbox != this.env.mailbox && (mbox_li = this.get_mailbox_li(mbox)))
+      this.set_classname(mbox_li, 'droptarget', true);
+    }
+    
+  this.unfocus_mailbox = function(mbox)
+    {
+    var mbox_li;
+  	if (this.drag_active && (mbox_li = this.get_mailbox_li(mbox)))
+      this.set_classname(mbox_li, 'droptarget', false);
+    }
+  
   // move selected messages to the specified mailbox
   this.move_messages = function(mbox)
     {
@@ -1929,6 +1950,19 @@
     this.http_request('mark', '_uid='+a_uids.join(',')+'&_flag=delete');
     return true;  
   }
+
+
+  this.get_mailbox_li = function(mbox)
+    {
+    if (this.gui_objects.mailboxlist)
+      {
+      mbox = String((mbox ? mbox : this.env.mailbox)).toLowerCase().replace(this.mbox_expression, '');
+      return document.getElementById('rcmbx'+mbox);
+      }
+    
+    return null;
+    };
+    
 
   /*********************************************************/
   /*********        message compose methods        *********/
@@ -2237,7 +2271,6 @@
           highlight.removeAttribute('id');
           //highlight.removeAttribute('class');
           this.set_classname(highlight, 'selected', false);
-          this.set_classname(highlight, 'unfocused', false);
           }
 
         if (next)
@@ -3152,22 +3185,23 @@
   // mark a mailbox as selected and set environment variable
   this.select_mailbox = function(mbox)
     {
-    if (this.gui_objects.mailboxlist)
+    if (this.gui_objects.mailboxlist )
       {
-      var item, reg, text_obj;
-      var s_current = this.env.mailbox.toLowerCase().replace(this.mbox_expression, '');
-      var s_mbox = String(mbox).toLowerCase().replace(this.mbox_expression, '');
-      var s_current = this.env.mailbox.toLowerCase().replace(this.mbox_expression, '');
+      var item, reg, text_obj;      
+      var current_li = this.get_mailbox_li();
+      var mbox_li = this.get_mailbox_li(mbox);
       
-      var current_li = document.getElementById('rcmbx'+s_current);
-      var mbox_li = document.getElementById('rcmbx'+s_mbox);
-      
-      if (current_li) {
+      if (current_li)
+        {
         this.set_classname(current_li, 'selected', false);
         this.set_classname(current_li, 'unfocused', false);
         }
-      if (mbox_li)
+
+      if (mbox_li || this.env.mailbox == mbox)
+        {
+        this.set_classname(mbox_li, 'unfocused', false);
         this.set_classname(mbox_li, 'selected', true);
+        }
       }
     
     this.env.mailbox = mbox;
@@ -3284,9 +3318,9 @@
     if (mbox==this.env.mailbox)
       set_title = true;
 
-    var item, reg, text_obj;
+    var reg, text_obj;
+    var item = this.get_mailbox_li(mbox);
     mbox = String(mbox).toLowerCase().replace(this.mbox_expression, '');
-    item = document.getElementById('rcmbx'+mbox);
 
     if (item && item.className && item.className.indexOf('mailbox '+mbox)>=0)
       {
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index b1d3d8b..fd0d2c2 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -216,6 +216,8 @@
 
     $out .= sprintf('<li id="rcmbx%s" class="mailbox %s %s%s%s"><a href="%s&amp;_mbox=%s"'.
                     ' onclick="return %s.command(\'list\',\'%s\')"'.
+                    ' onmouseover="return %s.focus_mailbox(\'%s\')"' .            
+                    ' onmouseout="return %s.unfocus_mailbox(\'%s\')"' .
                     ' onmouseup="return %s.mbox_mouse_up(\'%s\')"%s>%s</a>',
                     $folder_css,
                     $class_name,
@@ -224,6 +226,10 @@
                     addslashes($folder['id'])==addslashes($mbox_name) ? ' selected' : '',
                     $COMM_PATH,
                     urlencode($folder['id']),
+                    $JS_OBJECT_NAME,
+                    addslashes($folder['id']),
+                    $JS_OBJECT_NAME,
+                    addslashes($folder['id']),
                     $JS_OBJECT_NAME,
                     addslashes($folder['id']),
                     $JS_OBJECT_NAME,
@@ -1170,11 +1176,14 @@
     $body = preg_replace('/(url\s*\()(["\']?)([\.\/]+[^"\'\)\s]+)(\2)\)/Uie', "'\\1\''.make_absolute_url('\\3', '$base_url').'\')'", $body);
     $body = preg_replace($base_reg, '', $body);
     }
+    
+  // modify HTML links to open a new window if clicked
+  $body = preg_replace('/<a\s+([^>]+)>/Uie', "rcmail_alter_html_link('\\1');", $body);
 
   // add comments arround html and other tags
   $out = preg_replace(array('/(<\/?html[^>]*>)/i',
                             '/(<\/?head[^>]*>)/i',
-                            '/(<title[^>]*>.+<\/title>)/ui',
+                            '/(<title[^>]*>.*<\/title>)/Ui',
                             '/(<\/?meta[^>]*>)/i'),
                       '<!--\\1-->',
                       $body);
@@ -1184,12 +1193,26 @@
                       array('<div class="rcmBody">',
                             '</div>'),
                       $out);
-
   
   return $out;
   }
 
 
+// parse link attributes and set correct target
+function rcmail_alter_html_link($in)
+  {
+  $attrib = parse_attrib_string($in);
+
+  if (stristr((string)$attrib['href'], 'mailto:'))
+    $attrib['onclick'] = sprintf("return %s.command('compose','%s',this)",
+                                 $GLOBALS['JS_OBJECT_NAME'],
+                                 substr($attrib['href'], 7));
+  else if (!empty($attrib['href']) && $attrib['href']{0}!='#')
+    $attrib['target'] = '_blank';
+  
+  return '<a' . create_attrib_string($attrib, array('href', 'name', 'target', 'onclick', 'id', 'class', 'style', 'title')) . '>';
+  }
+
 
 // replace all css definitions with #container [def]
 function rcmail_mod_css_styles($source, $container_id)
diff --git a/skins/default/mail.css b/skins/default/mail.css
index 86d6e1e..72a782b 100644
--- a/skins/default/mail.css
+++ b/skins/default/mail.css
@@ -276,6 +276,10 @@
   font-weight: bold;
 }
 
+#mailboxlist li.droptarget
+{
+  background-color: #FFFFA6;
+}
 
 /* styles for nested folders */
 #mailboxlist ul {

--
Gitblit v1.9.1