thomascube
2006-03-20 8c2e58b42e89ca0216307553a906c2ca776c44f8
Minor improvements and bugfixes (see changelog)


8 files modified
151 ■■■■■ changed files
CHANGELOG 12 ●●●●● patch | view | raw | blame | history
UPGRADING 10 ●●●●● patch | view | raw | blame | history
index.php 15 ●●●● patch | view | raw | blame | history
program/include/main.inc 17 ●●●● patch | view | raw | blame | history
program/js/app.js 42 ●●●●● patch | view | raw | blame | history
program/lib/imap.inc 25 ●●●● patch | view | raw | blame | history
program/steps/mail/func.inc 19 ●●●●● patch | view | raw | blame | history
program/steps/mail/show.inc 11 ●●●● patch | view | raw | blame | history
CHANGELOG
@@ -1,6 +1,18 @@
CHANGELOG RoundCube Webmail
---------------------------
2006/03/20
----------
- Fixed hard-coded cols selection for sent folder (Bug #1354586)
- Enable some HTML links for use with "open in new window" or "save target"
- Check meta-key instead of ctrl on Macs
- Ignore double clicks when holding down a modifier key
- Fixed reloading of the login page
- Fixed typo in compose template (Bug #1446852)
- Added compose button to message read step (Request #1433288)
- New config parameter for persistent database connections (Bug #1431817)
2006/03/14
----------
- Don't remove internal HTML tags in plaintext messages
UPGRADING
@@ -101,3 +101,13 @@
  $rcmail_config['db_sequence_cache_ids'] = 'cache_ids';
  $rcmail_config['db_sequence_message_ids'] = 'message_ids';
  
form version 0.1-beta
----------------------------------------
- replace index.php
- replace all files in folder /program/
- replace all files in folder /skins/default/
- add these lines to /config/db.inc.php
  $rcmail_config['db_persistent'] = TRUE;
index.php
@@ -2,7 +2,7 @@
/*
 +-----------------------------------------------------------------------+
 | RoundCube Webmail IMAP Client                                         |
 | Version 0.1-20060314                                                  |
 | Version 0.1-20060320                                                  |
 |                                                                       |
 | Copyright (C) 2005, RoundCube Dev. - Switzerland                      |
 | Licensed under the GNU GPL                                            |
@@ -40,14 +40,15 @@
*/
define('RCMAIL_VERSION', '0.1-20060220');
define('RCMAIL_VERSION', '0.1-20060320');
// define global vars
$INSTALL_PATH = dirname($_SERVER['SCRIPT_FILENAME']);
$CHARSET = 'UTF-8';
$OUTPUT_TYPE = 'html';
$JS_OBJECT_NAME = 'rcmail';
$CHARSET = 'UTF-8';
$INSTALL_PATH = dirname($_SERVER['SCRIPT_FILENAME']);
$MAIN_TASKS = array('mail','settings','addressbook','logout');
if (empty($INSTALL_PATH))
  $INSTALL_PATH = './';
@@ -331,11 +332,9 @@
  }
// only allow these templates to be included
$valid_tasks = array('mail','settings','addressbook');
// parse main template
if (in_array($_task, $valid_tasks))
// only allow these templates to be included
if (in_array($_task, $MAIN_TASKS))
  parse_template($_task);
program/include/main.inc
@@ -72,7 +72,7 @@
  // prepare DB connection
  require_once('include/rcube_'.(empty($CONFIG['db_backend']) ? 'db' : $CONFIG['db_backend']).'.inc');
  
  $DB = new rcube_db($CONFIG['db_dsnw'], $CONFIG['db_dsnr']);
  $DB = new rcube_db($CONFIG['db_dsnw'], $CONFIG['db_dsnr'], $CONFIG['db_persistent']);
  $DB->sqlite_initials = $INSTALL_PATH.'SQL/sqlite.initial.sql';
  $DB->db_connect('w');
    
@@ -1123,7 +1123,12 @@
      // execute object handler function
      if ($object_handlers[$object] && function_exists($object_handlers[$object]))
        return call_user_func($object_handlers[$object], $attrib);
      else if ($object=='productname')
        {
        $name = !empty($CONFIG['product_name']) ? $CONFIG['product_name'] : 'RoundCube Webmail';
        return rep_specialchars_output($name, 'html', 'all');
        }
      else if ($object=='pagetitle')
        {
        $task = $GLOBALS['_task'];
@@ -1151,7 +1156,7 @@
// create and register a button
function rcube_button($attrib)
  {
  global $CONFIG, $OUTPUT, $JS_OBJECT_NAME, $BROWSER;
  global $CONFIG, $OUTPUT, $JS_OBJECT_NAME, $BROWSER, $COMM_PATH, $MAIN_TASKS;
  static $sa_buttons = array();
  static $s_button_count = 100;
  
@@ -1223,6 +1228,7 @@
  // register button in the system
  if ($attrib['command'])
    {
    $OUTPUT->add_script(sprintf("%s.register_button('%s', '%s', '%s', '%s', '%s', '%s');",
                                $JS_OBJECT_NAME,
                                $command,
@@ -1232,6 +1238,11 @@
                                $attirb['imagesel'] ? $skin_path.$attirb['imagesel'] : $attrib['classsel'],
                                $attrib['imageover'] ? $skin_path.$attrib['imageover'] : ''));
    // make valid href to task buttons
    if (in_array($attrib['command'], $MAIN_TASKS))
      $attrib['href'] = ereg_replace('_task=[a-z]+', '_task='.$attrib['command'], $COMM_PATH);
    }
  // overwrite attributes
  if (!$attrib['href'])
    $attrib['href'] = '#';
program/js/app.js
@@ -7,7 +7,8 @@
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
 | Author: Thomas Bruederli <roundcube@gmail.com>                        |
 | Authors: Thomas Bruederli <roundcube@gmail.com>                       |
 |          Charles McNulty <charles@charlesmcnulty.com>                 |
 +-----------------------------------------------------------------------+
 
  $Id$
@@ -231,7 +232,7 @@
    this.enable_command('logout', true);
    // disable browser's contextmenus
    document.oncontextmenu = function(){ return false; }
    // document.oncontextmenu = function(){ return false; }
    // load body click event
    document.onmousedown = function(){ return rcube_webmail_client.reset_click(); };
@@ -248,7 +249,7 @@
    // start interval for keep-alive/recent_check signal
    if (this.kepp_alive_interval && this.task=='mail' && this.gui_objects.messagelist)
      this.kepp_alive_int = setInterval(this.ref+'.check_for_recent()', this.kepp_alive_interval);
    else
    else if (this.task!='login')
      this.kepp_alive_int = setInterval(this.ref+'.send_keep_alive()', this.kepp_alive_interval);
    };
@@ -275,7 +276,7 @@
    var keyCode = document.layers ? e.which : document.all ? event.keyCode : document.getElementById ? e.keyCode : 0;
    var mod_key = this.get_modifier(e);
    var scroll_to = 0;
    var last_selected_row = this.list_rows[this.last_selected];
    if (keyCode == 40) { // down arrow key pressed
@@ -1089,6 +1090,7 @@
  // onmouseup-handler of message list row
  this.click_row = function(e, id)
    {
    var mod_key = this.get_modifier(e);
    // don't do anything (another action processed before)
    if (this.dont_select)
@@ -1098,15 +1100,14 @@
      }
    
    // unselects currently selected row    
    if (!this.drag_active && this.in_selection_before==id) {
      var mod_key = this.get_modifier(e);
    if (!this.drag_active && this.in_selection_before==id)
      this.select_row(id,mod_key);
    }
    this.drag_start = false;
    this.in_selection_before = false;
        
    // row was double clicked
    if (this.task=='mail' && this.list_rows && this.list_rows[id].clicked)
    if (this.task=='mail' && this.list_rows && this.list_rows[id].clicked && !mod_key)
      {
      this.show_message(id);
      return false;
@@ -2934,6 +2935,8 @@
    };
/* deprecated methods
  // check if Shift-key is pressed on event
  this.check_shiftkey = function(e)
    {
@@ -2963,22 +2966,29 @@
    else
      return false;
    }
*/
// returns modifier key (constants defined at top of file)
  // returns modifier key (constants defined at top of file)
  this.get_modifier = function(e)
    {
    var opcode = 0;
    if (e = e || window.event)
    {
    e = e || window.event;
    if (bw.mac && e)
      {
      opcode += (e.metaKey && CONTROL_KEY) + (e.shiftKey && SHIFT_KEY);
      return opcode;
      }
    if (e)
      {
      opcode += (e.ctrlKey && CONTROL_KEY) + (e.shiftKey && SHIFT_KEY);
      return opcode;
    }
      return opcode;
      }
    if (e.cancelBubble)
    {
      {
      e.cancelBubble = true;
      e.returnValue = false;
    }
      }
    else if (e.preventDefault)
      e.preventDefault();
  }
program/lib/imap.inc
@@ -39,6 +39,7 @@
        - Added BCC and REFERENCE to the list of headers to fetch in iil_C_FetchHeaders()
        - Leave messageID unchanged in iil_C_FetchHeaders()
        - Avoid stripslahes in iil_Connect()
        - Removed <br> from error messages (better for logging)
        - Removed some debuggers (echo ...)
********************************************************/
@@ -209,7 +210,7 @@
        $conn->errorNum = 0;
        return $conn->fp;
    }else{
        $conn->error .= 'Authentication failed (AUTH): <br>"'.htmlspecialchars($line)."\"";
        $conn->error .= 'Authentication for '.$user.' failed (AUTH): "'.htmlspecialchars($line)."\"";
        $conn->errorNum = -2;
        return false;
    }
@@ -230,7 +231,7 @@
    }else{
        $result=false;
        fclose($conn->fp);
        $conn->error .= 'Authentication failed (LOGIN):<br>"'.htmlspecialchars($line)."\"";
        $conn->error .= 'Authentication for '.$user.' failed (LOGIN): "'.htmlspecialchars($line)."\"";
        $conn->errorNum = -2;
    }
    return $result;
@@ -335,9 +336,9 @@
    //echo '<!-- conn sort_field: '.$my_prefs['sort_field'].' //-->';
    
    //check input
    if (empty($host)) $iil_error .= "Invalid host<br>\n";
    if (empty($user)) $iil_error .= "Invalid user<br>\n";
    if (empty($password)) $iil_error .= "Invalid password<br>\n";
    if (empty($host)) $iil_error .= "Invalid host\n";
    if (empty($user)) $iil_error .= "Invalid user\n";
    if (empty($password)) $iil_error .= "Invalid password\n";
    if (!empty($iil_error)) return false;
    if (!$ICL_PORT) $ICL_PORT = 143;
    
@@ -1576,12 +1577,12 @@
        $result_code=iil_ParseResult($line);
        if ($result_code==0) return $messages;
        else{
            $conn->error = "iil_C_Search: ".$line."<br>\n";
            $conn->error = "iil_C_Search: ".$line."\n";
            return false;
        }
        
    }else{
        $conn->error = "iil_C_Search: Couldn't select \"$folder\" <br>\n";
        $conn->error = "iil_C_Search: Couldn't select \"$folder\"\n";
        return false;
    }
}
@@ -1929,11 +1930,11 @@
        }while($line[0]!="A");
    
        $result = (iil_ParseResult($line)==0);
        if (!$result) $conn->error .= $line."<br>\n";
        if (!$result) $conn->error .= $line."\n";
        return $result;
    
    }else{
        $conn->error .= "Couldn't send command \"$request\"<br>\n";
        $conn->error .= "Couldn't send command \"$request\"\n";
        return false;
    }
}
@@ -1946,7 +1947,7 @@
    $in_fp = false;                
    if (file_exists(realpath($path))) $in_fp = fopen($path, "r");
    if (!$in_fp){ 
        $conn->error .= "Couldn't open $path for reading<br>\n";
        $conn->error .= "Couldn't open $path for reading\n";
        return false;
    }
    
@@ -1976,11 +1977,11 @@
        }while($line[0]!="A");
            
        $result = (iil_ParseResult($line)==0);
        if (!$result) $conn->error .= $line."<br>\n";
        if (!$result) $conn->error .= $line."\n";
        return $result;
    
    }else{
        $conn->error .= "Couldn't send command \"$request\"<br>\n";
        $conn->error .= "Couldn't send command \"$request\"\n";
        return false;
    }
}
program/steps/mail/func.inc
@@ -161,7 +161,7 @@
// return html for a structured list <ul> for the mailbox tree
function rcmail_render_folder_tree_html(&$arrFolders, &$special, &$mbox, $maxlength, $nestLevel=0)
  {
  global $JS_OBJECT_NAME, $IMAP, $CONFIG, $OUTPUT;
  global $JS_OBJECT_NAME, $COMM_PATH, $IMAP, $CONFIG, $OUTPUT;
  $idx = 0;
  $out = '';
@@ -190,7 +190,7 @@
    // add unread message count display
    if ($unread_count = $IMAP->messagecount($folder['id'], 'RECENT', ($folder['id']==$mbox)))
      $foldername .= sprintf(' (%d)', $unread_count);
    // make folder name safe for ids and class names
    $folder_css = $class_name = preg_replace('/[^a-z0-9\-_]/', '', $folder_lc);
@@ -204,13 +204,16 @@
    else if ($folder['id']==$CONFIG['junk_mbox'])
      $class_name = 'junk';
    $out .= sprintf('<li id="rcmbx%s" class="mailbox %s %s%s%s"><a href="./#%s" onclick="return %s.command(\'list\',\'%s\')" onmouseup="return %s.mbox_mouse_up(\'%s\')"%s>%s</a>',
    $out .= sprintf('<li id="rcmbx%s" class="mailbox %s %s%s%s"><a href="%s&_mbox=%s"'.
                    ' onclick="return %s.command(\'list\',\'%s\')"'.
                    ' onmouseup="return %s.mbox_mouse_up(\'%s\')"%s>%s</a>',
                    $folder_css,
                    $class_name,
                    $zebra_class,
                    $unread_count ? ' unread' : '',
                    $folder['id']==$mbox ? ' selected' : '',
                    $folder['id'],
                    $COMM_PATH,
                    urlencode($folder['id']),
                    $JS_OBJECT_NAME,
                    $folder['id'],
                    $JS_OBJECT_NAME,
@@ -295,9 +298,10 @@
  $a_sort_cols = array('subject', 'date', 'from', 'to');
  
  // show 'to' instead of from in sent messages
  if (strtolower($IMAP->get_mailbox_name())=='sent' && ($f = array_search('from', $a_show_cols)))
  if (strtolower($IMAP->get_mailbox_name())=='sent' && ($f = array_search('from', $a_show_cols))
      && !array_search('to', $a_show_cols))
    $a_show_cols[$f] = 'to';
  // add col definition
  $out .= '<colgroup>';
  $out .= '<col class="icon" />';
@@ -478,7 +482,8 @@
  $a_show_cols = is_array($CONFIG['list_cols']) ? $CONFIG['list_cols'] : array('subject');
  // show 'to' instead of from in sent messages
  if (strtolower($IMAP->get_mailbox_name())=='sent' && ($f = array_search('from', $a_show_cols)))
  if (strtolower($IMAP->get_mailbox_name())=='sent' && ($f = array_search('from', $a_show_cols))
      && !array_search('to', $a_show_cols))
    $a_show_cols[$f] = 'to';
  // loop through message headers
program/steps/mail/show.inc
@@ -95,18 +95,13 @@
                        $attach_prop['filename'],
                        show_bytes($attach_prop['size']));
      else
        $out .= sprintf('<li><a href="#attachment" onclick="return %s.command(\'load-attachment\',{part:\'%s\', mimetype:\'%s\'},this)">%s</a></li>'."\n",
        $out .= sprintf('<li><a href="%s&_part=%s" onclick="return %s.command(\'load-attachment\',{part:\'%s\', mimetype:\'%s\'},this)">%s</a></li>'."\n",
                        $GET_URL,
                        $attach_prop['part_id'],
                        $JS_OBJECT_NAME,
                        $attach_prop['part_id'],
                        $attach_prop['mimetype'],
                        $attach_prop['filename']);
    /* direct link
      else
        $out .= sprintf('<li><a href="%s&_part=%s&_frame=1" target="rcubemailattachment">%s</a></li>'."\n",
                        $GET_URL,
                        $attach_prop['part_id'],
                        $attach_prop['filename']);
    */
      }
    $out .= "</ul>";