From: Jérémy Bobbio Date: Sat, 18 Jun 2011 15:02:44 +0000 (+0200) Subject: Imported Upstream version 0.2.1 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=1213c6e65f2bab1e140369839a9d0f6db28a9492;p=roundcube.git Imported Upstream version 0.2.1 --- diff --git a/.htaccess b/.htaccess index fcb8f6c..36d5748 100644 --- a/.htaccess +++ b/.htaccess @@ -23,11 +23,6 @@ php_value session.gc_probability 1 php_value mbstring.func_overload 0 - - Order allow,deny - Deny from all - - RewriteEngine On RewriteRule ^favicon.ico$ skins/default/images/favicon.ico diff --git a/CHANGELOG b/CHANGELOG index 6a2b489..78bf9d4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,204 +1,46 @@ CHANGELOG RoundCube Webmail ---------------------------- +=========================== -- Fix mark popup in IE 7 (#1485369) -- Fix line-break issue when copy & paste in Firefox (#1485425) -- Fix autocomplete "unknown server error" (#1485637) -- Fix STARTTLS before AUTH in SMTP connection (#1484883) -- Support multiple quota values in QUOTAROOT resonse (#1485626) -- Only abbreviate file name for IE < 7 browsers (#1485063) -- Performance: allow setting imap rootdir and delimiter before connect (#1485172) -- Fix sorting of folders with more than 2 levels (#1485569) -- Fix search results page jumps in LDAP addressbook (#1485253) -- Fix empty line before the signature in IE (#1485351) -- Fix horizontal scrollbar in preview pane on IE (#1484633) -- Add Robots meta tag in login page and installer (#1484846) -- Added 'show_images' option, removed 'addrbook_show_images' (#1485597) -- Option to check for new mails in all folders (#1484374) -- Don't set client busy when checking for new messages (#1485276) -- Allow UTF-8 folder names in config (#1485579) -- Add junk_mbox option configuration in installer (#1485579) -- Do serverside addressbook queries for autocompletion (#1485531) -- Allow setting attachment col position in 'list_cols' option -- Allow override 'list_cols' via skin (#1485577) -- Fix 'cache' table cleanup on session destroy (#1485516) -- Increase speed of session destroy and garbage clean up -- Fix session timeout when DB server got clock skew (#1485490) -- Fix handling of some malformed messages (#1484438) -- Speed up raw message body handling -- Better HTML entities conversion in html2text (#1485519) -- Fix big memory consumption and speed up searching on servers without SORT capability -- Fix setting locale to tr_TR, ku and az_AZ (#1485470) -- Use SORT for searching on servers with SORT capability -- Added message status filter -- Fix empty file sending (#1485389) -- Improved searching with many criterias (calling one SEARCH command) -- Fix HTML editor initialization on IE (#1485304) -- Add warning when switching editor mode from html to plain (#1485488) -- Make identities list scrollable (#1485538) -- Fix problem with numeric folder names (#1485527) -- Added BYE response simple support to prevent from endless loops in imap.inc (#1483956) -- Fix unread message unintentionally marked as read if read_when_deleted=true (#1485409) -- Remove port number from SERVER_NAME in smtp_helo_host (#1485518) -- Don't send disposition notification receipts for messages marked as 'read' (#1485523) -- Added 'keep_alive' and 'min_keep_alive' options (#1485360) -- Added option 'identities_level', removed 'multiple_identities' -- Allow deleting identities when multiple_identities=false (#1485435) -- Added option focus_on_new_message (#1485374) -- Fix html2text class autoloading on Windows (#1485505) -- Fix html signature formatting when identity save error occured (#1485426) -- Add feedback and set busy when moving folder (#1485497) -- Fix 'Empty' link visibility for some languages e.g. Slovak (#1485489) -- Fix messages count bar overlapping (#1485270) -- Fix adding signature in drafts compose mode (#1485484) -- Fix iil_C_Sort() to support very long and/or divided responses (#1485283) -- Fix matching case sensitivity when setting identity on reply (#1485480) -- Prefer default identity on reply -- Fix imap searching on ISMail server (#1485466) -- Add css class for flagged messages (#1485464) -- Write username instead of id in sendmail log (#1485477) -- Fix htmlspecialchars() use for PHP version < 5.2.3 (#1485475) -- Fix js keywords escaping in json_serialize() for IE/Opera (#1485472) -- Added bin/killcache.php script (#1485434) -- Add support for SJIS, GB2312, BIG5 in rc_detect_encoding() -- Fix vCard file encoding detection for non-UTF-8 strings (#1485410) -- Add 'skip_deleted' option in User Preferences (#1485445) -- Minimize "inline" javascript scripts use (#1485433) -- Fix css class setting for folders with names matching defined classes names (#1485355) -- Fix race conditions when changing mailbox -- Fix spellchecking when switching to html editor (#1485362) -- Fix compose window width/height (#1485396) -- Allow calling msgimport.sh/msgexport.sh from any directory (#1485431) -- Localized filesize units (#1485340) -- Better handling of "no identity" and "no email in identity" situations (#1485117) -- Added 'mime_param_folding' option with possibility to choose long/non-ascii attachment names encoding eg. to be readable in MS Outlook/OE (#1485320) -- Added "advanced options" feature in User Preferences -- Fix unread counter when displaying cached massage in preview panel (#1485290) -- Fix htmleditor spellchecking on MS Windows (#1485397) -- Fix problem with non-ascii attachment names in Mail_mime (#1485267, #1485096) -- Fix language autodetection (#1485401) -- Fix button label in folders management (#1485405) -- Fix collapsed folder not indicating unread msgs count of all subfolders (#1485403) -- Fix handling of apostrophes in filenames decoded according to rfc2231 - -RELEASE 0.2-BETA - -- Made config files location configurable (#1485215) -- Reduced memory footprint when forwarding attachments (#1485345) -- Allow and use spellcheck attribute for input/textarea fields (#1485060) -- Added icons for forwarded/forwarded+replied messages (#1485257) -- Added Reply-To to forwarded emails (#1485315) -- Display progress message for folders create/delete/rename (#1485357) -- Smart Tags and NOBR tag support in html messages (#1485363, #1485327) -- Redesign of the identities settings (#1484042) -- Add config option to disable creation/deletion of identities (#1484498) -- Added 'sendmail_delay' option to restrict messages sending interval (#1484491) -- Added vertical splitter for folders list resizing -- Added possibility to view all headers in message view -- Fixed splitter drag/resize on Opera (#1485170) -- Fixed quota img height/width setting from template (#1484857) -- Refactor drag & drop functionality. Don't rely on browser events anymore (#1484453) -- Insert "virtual" folders in subscription list (#1484779) -- Added link to open message in new window -- Enable export of address book contacts as vCard -- Add feature to import contacts from vcard files (#1326103) -- Respect Content-Location headers in multipart/related messages according to RFC2110 (#1484946) -- Allowed max. attachment size now indicated in compose screen (#1485030) -- Also capture backspace key in list mode (#1484566) -- Allow application/pgp parts to be displayed (#1484753) -- Correctly handle options in mailto-links (#1485228) -- Immediately save sort_col/sort_order in user prefs (#1485265) -- Truncate very long (above 50 characters) attachment filenames when displaying -- Allow to auto-detect client language if none set (#1484434) -- Auto-detect the client timezone (user configurable) -- Add RFC2231 header value continuations support for attachment filenames + hack for servers that not support that feature -- Fix Reply-To header displaying (#1485314) -- Mark form buttons that provide the most obvious operation (mainaction) -- Added option 'quota_zero_as_unlimited' (#1484604) -- Added PRE handling in html2text class (#1484740) -- Added folder hierarchy collapsing -- Added options to use syslog instead of log file (#1484850) -- Added Logging & Debugging section in Installer -- Fix In-Reply-To and References headers when composing saved draft message (#1485288) -- Fix html message charset conversion for charsets with underline (#1485287) -- Fix buttons status after contacts deletion (#1485233) -- Fix escaping of To: and From: fields when building message body for reply or forward in the HTML editor (#1484904) -- Use current mailbox name in template (#1485256) -- Better fix for skipping untagged responses (#1485261) -- Added pspell support patch by Kris Steinhoff (#1483960) -- Enable spellchecker for HTML editor (#1485114) -- Respect spellcheck_uri in tinyMCE spellchecker (#1484196) -- Case insensitive contacts searching using PostgreSQL (#1485259) -- Make default imap folders configurable for each user (#1485075) -- Save outgoing mail to selectable folder (#1324581) -- Fix hiding of mark menu when clicking th button again (#1484944) -- Use long date format in print mode (#1485191) -- Updated TinyMCE to version 3.1.0.1 -- Re-enable autocomplete attribute for login form (#1485211) -- Check PERMANENTFLAGS before saving $MDNSent flag (#1484963, #1485163) -- Added flag column on messages list (#1484623) -- Patched Mail/MimePart.php (http://pear.php.net/bugs/bug.php?id=14232) -- Allow trash/junk subfolders to be purged (#1485085) -- Store compose parameters in session and redirect to a unique URL -- Fixed CRAM-MD5 authentication (#1484819) -- Fixed forwarding messages with one HTML attachment (#1484442) -- Fixed encoding of message/rfc822 attachments and image/pjpeg handling (#1484914) -- Added option to select skin in user preferences -- Added option to configure displaying of attached images below the message body -- Added option to display images in messages from known senders (#1484601) -- User preferences grouped in more fieldsets -- Fix corrupted MIME headers of messages in Sent folder (#1485111) -- Fixed bug in MDB2 package: http://pear.php.net/bugs/bug.php?id=14124 -- Use keypress instead of keydown to select list's row (#1484816) -- Don't call expunge and don't remove message row after message move if flag_for_deletion is set to true (#1485002) - -RELEASE 0.2-ALPHA - -- Added option to disable autocompletion from selected LDAP address books (#1484922) -- TLS support in LDAP connections: 'use_tls' property (#1485104) -- Fixed removing messages from search set after deleting them (#1485106) -- imap.inc: Fixed iil_C_FetchStructureString() to handle many - literal strings in response (#1484969) -- Support for subfolders in default/protected folders (#1484665) -- Disallowed delimiter in folder name (#1484803) -- Support " and \ in folder names -- Escape \ in login (#1484614) -- Better HTML sanitization with the DOM-based washtml script (#1484701) -- Fixed sorting of folders with non-ascii characters -- Fixed Mysql DDL for default identities creation (#1485070) -- In Preferences added possibility to configure 'read_when_deleted', - 'mdn_requests', 'flag_for_deletion' options -- Made IMAP auth type configurable (#1483825) -- Fixed empty values with FROM_UNIXTIME() in rcube_mdb2 (#1485055) -- Fixed attachment list on IE 6/7 (#1484807) -- Fixed JavaScript in compose.html that shows cc/bcc fields if populated -- Make password input fields of type password in installer (#1484886) -- Don't attempt to delete cache entries if enable_caching is FALSE (#1485051) -- Optimized messages sorting on servers without sort capability (#1485049) -- Corrected message headers decoding when charset isn't specified and improved - support for native languages (#1485050, #1485048) -- Expanded LDAP configuration options to support LDAP server writes. -- Installer: encode special characters in DB username/password (#1485042) -- Fixed management of folders with national characters in names (#1485036, #1485001) -- Fixed identities saving when using MDB2 pgsql driver (#1485032) -- Fixed BCC header reset (#1484997) -- Improved messages list performance - patch from Justin Heesemann -- Append skin_path to images location only when it starts with '/' sign (#1484859) -- Fix IMAP response in message body when message has no body (#1484964) -- Fixed non-RFC dates formatting (#1484901) -- Fixed typo in set_charset() (#1484991) -- Decode entities when inserting HTML signature to plain text message (#1484990) -- HTML editing is now working with PHP5 updates and TinyMCE v3.0.6 -- Fixed signature loading on Windows (#1484545) -- Added language support to HTML editing (#1484862) -- Fixed remove signature when replying (#1333167) -- Fixed problem with line with a space at the end (#1484916) -- Fixed tag filtering (#1484391) -- Fixed tag filtering (#1484403) -- Added sections (fieldset+label) in Settings interface -- Mark as read in one action with message preview (#1484972) -- Deleted redundant quota reads (#1484972) -- Added options for empty trash and expunge inbox on logout (#1483863) -- Removed lines wrapping when displaying message -- Fixed month localization -- Changed codebase to PHP5 with autoloader +- Use US-ASCII as failover when Unicode searching fails (#1485762) +- Fix errors handling in IMAP command continuations (#1485762) +- Fix FETCH result parsing for servers returning flags at the end of result (#1485763) +- Fix datetime columns defaults in mysql's DDL (#1485641) +- Fix attaching more than nine inline images (#1485759) +- Support 'UNICODE-1-1-UTF-7' alias for UTF-7 encoding (#1485758) +- Fix mime-type detection using a hard-coded map (#1485311) +- Don't return empty string if charset conversion failed (#1485757) +- Disable concurrent autocomplete query results display (#1485743) +- Fix new lines stripped from message footer (#1485751) +- Fix IE problem with mouse click autocomplete (#1485739) +- Fix html body washing on reply/forward + fix attachments handling (#1485676) +- Fix multiple recipients input parsing (#1485733) +- Fix replying to message with html attachment (#1485676) +- Use default_charset for messages without specified charset (#1485661, #1484961) +- Support non-standard "GMT-XXXX" literal in date header (#1485729) +- Added TNEF support to decode MS Outlook attachments (winmail.dat) +- Fix "value continuation" MIME headers by adding required semicolon (#1485727) +- Fix pressing select all/unread multiple times (#1485723) +- Fix selecting all unread does not honor new messages (#1485724) +- Fix some base64 encoded attachments handling (#1485725) +- Support NGINX as IMAP backend: better BAD response handling (#1485720) +- Performance fix: don't fetch attachment parts headers twice to parse filename +- Fix checking for recent messages on various IMAP servers (#1485702) +- Performance fix: Don't fetch quota and recent messages in "message view" mode +- Fix displaying of alternative-inside-alternative messages (#1485713) +- Fix MDNSent flag checking, use arbitrary keywords (asterisk) flag (#1485706) +- Fix creation of folders with '&' sign in name +- Fix parsing of email addresses without angle brackets (#1485693) +- Save spellcheck corrections when switching from plain to html editor (and spellchecking is on) +- Fix large search results on server without SORT capability (#1485668) +- Get rid of preg_replace() with eval modifier and create_function usage (#1485686) +- Bring back and tags in HTML messages +- Fix XSS vulnerability through background attributes as reported by Julien Cayssol +- Fix problems with backslash as IMAP hierarchy delimiter (#1484467) +- Secure vcard export by getting rid of preg's 'e' modifier use (#1485689) +- Fix authentication when submitting form with existing session (#1485679) +- Allow absolute URLs to images in HTML messages/sigs (#1485666) +- Fix message body which contains both inline attachments and emotions +- Fix SQL query execution errors handling in rcube_mdb2 class (#1485509) +- Fix address names with '@' sign handling (#1485654) +- Improve messages display performance +- Fix messages searching with 'to:' modifier diff --git a/INSTALL b/INSTALL index 0cbc43b..fe71cdf 100644 --- a/INSTALL +++ b/INSTALL @@ -59,7 +59,7 @@ importing the table layout and granting the proper permissions to the roundcube user. Here is an example of that procedure: # mysql -> CREATE DATABASE roundcubemail; +> CREATE DATABASE roundcubemail /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; > GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost IDENTIFIED BY 'password'; > quit @@ -94,7 +94,7 @@ simple steps, which have to be done as the postgres system user (or which ever is the database superuser): $ createuser roundcube -$ createdb -O roundcube roundcubemail +$ createdb -O roundcube -E UNICODE roundcubemail $ psql roundcubemail roundcubemail =# ALTER USER roundcube WITH PASSWORD 'the_new_password'; diff --git a/SQL/mysql.initial.sql b/SQL/mysql.initial.sql index 5a1bfd1..9815282 100644 --- a/SQL/mysql.initial.sql +++ b/SQL/mysql.initial.sql @@ -10,8 +10,8 @@ CREATE TABLE `session` ( `sess_id` varchar(40) NOT NULL, - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `changed` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', + `changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', `ip` varchar(40) NOT NULL, `vars` text NOT NULL, PRIMARY KEY(`sess_id`), @@ -26,8 +26,8 @@ CREATE TABLE `users` ( `username` varchar(128) NOT NULL, `mail_host` varchar(128) NOT NULL, `alias` varchar(128) NOT NULL, - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `last_login` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', + `last_login` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', `language` varchar(5), `preferences` text, PRIMARY KEY(`user_id`), @@ -43,14 +43,14 @@ CREATE TABLE `messages` ( `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0', `del` tinyint(1) NOT NULL DEFAULT '0', `cache_key` varchar(128) /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */ NOT NULL, - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', `idx` int(11) UNSIGNED NOT NULL DEFAULT '0', `uid` int(11) UNSIGNED NOT NULL DEFAULT '0', `subject` varchar(255) NOT NULL, `from` varchar(255) NOT NULL, `to` varchar(255) NOT NULL, `cc` varchar(255) NOT NULL, - `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `date` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', `size` int(11) UNSIGNED NOT NULL DEFAULT '0', `headers` text NOT NULL, `structure` text, @@ -70,7 +70,7 @@ CREATE TABLE `messages` ( CREATE TABLE `cache` ( `cache_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, `cache_key` varchar(128) /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */ NOT NULL , - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', `data` longtext NOT NULL, `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0', PRIMARY KEY(`cache_id`), @@ -88,7 +88,7 @@ CREATE TABLE `cache` ( CREATE TABLE `contacts` ( `contact_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, - `changed` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', `del` tinyint(1) NOT NULL DEFAULT '0', `name` varchar(128) NOT NULL, `email` varchar(128) NOT NULL, diff --git a/UPGRADING b/UPGRADING index 54a4ca3..b2c1977 100644 --- a/UPGRADING +++ b/UPGRADING @@ -20,8 +20,9 @@ of RoundCube Webmail. in your local config/main.inc.php file. 3. Let the update script/installer check your configuration and update your config files as suggested by the updater. -4. Run all commands in ./SQL/[yourdbtype].update.sql that are superscribed - with the currently installed version number. +4. If suggested by the update script, run all commands in + ./SQL/[yourdbtype].update.sql that are superscribed with the + currently installed version number. 5. Make sure 'enable_installer' is set to false again. diff --git a/bin/html2text.php b/bin/html2text.php index b245b31..5b5c3c0 100644 --- a/bin/html2text.php +++ b/bin/html2text.php @@ -5,7 +5,7 @@ | bin/html2text.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -15,7 +15,7 @@ | Author: Thomas Bruederli | +-----------------------------------------------------------------------+ - $Id: html2text.php 2187 2008-12-24 14:19:27Z thomasb $ + $Id: html2text.php 2237 2009-01-17 01:55:39Z till $ */ diff --git a/bin/killcache.php b/bin/killcache.php index 8951eb4..cf2a648 100644 --- a/bin/killcache.php +++ b/bin/killcache.php @@ -5,7 +5,7 @@ | bin/killcache.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -15,39 +15,48 @@ | Author: Dennis P. Nikolaenko | +-----------------------------------------------------------------------+ - $Id: killcache.php 1955 2008-10-07 19:11:06Z alec $ + $Id: killcache.php 2238 2009-01-17 03:27:41Z till $ */ define('INSTALL_PATH', realpath(dirname(__FILE__).'/..') . '/'); -require INSTALL_PATH.'program/include/iniset.php'; +require INSTALL_PATH . 'program/include/iniset.php'; $config = new rcube_config(); // don't allow public access if not in devel_mode if (!$config->get('devel_mode') && $_SERVER['REMOTE_ADDR']) { - header("HTTP/1.0 401 Access denied"); - die("Access denied!"); + header("HTTP/1.0 401 Access denied"); + die("Access denied!"); } +$options = array( + 'use_transactions' => false, + 'log_line_break' => "\n", + 'idxname_format' => '%s', + 'debug' => false, + 'quote_identifier' => true, + 'force_defaults' => false, + 'portability' => true +); -$dbh =& MDB2::factory($config->get('db_dsnw'), $options); +$dbh = MDB2::factory($config->get('db_dsnw'), $options); if (PEAR::isError($dbh)) { - exit($mdb2->getMessage()); + exit($mdb2->getMessage()); } //TODO: transaction here (if supported by DB) would be a good thing $res =& $dbh->exec("DELETE FROM cache"); if (PEAR::isError($res)) { - $dbh->disconnect(); - exit($res->getMessage()); -}; + $dbh->disconnect(); + exit($res->getMessage()); +} $res =& $dbh->exec("DELETE FROM messages"); if (PEAR::isError($res)) { - $dbh->disconnect(); - exit($res->getMessage()); -}; + $dbh->disconnect(); + exit($res->getMessage()); +} echo "Cache cleared\n"; diff --git a/bin/modcss.php b/bin/modcss.php index b56accb..093add6 100644 --- a/bin/modcss.php +++ b/bin/modcss.php @@ -5,7 +5,7 @@ | bin/modcss.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2007-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2007-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -15,7 +15,7 @@ | Author: Thomas Bruederli | +-----------------------------------------------------------------------+ - $Id: modcss.php 2187 2008-12-24 14:19:27Z thomasb $ + $Id: modcss.php 2249 2009-01-22 11:23:00Z thomasb $ */ @@ -24,46 +24,64 @@ require INSTALL_PATH . 'program/include/iniset.php'; $RCMAIL = rcmail::get_instance(); -$source = ""; -if (!empty($RCMAIL->user->ID) && ($url = preg_replace('/[^a-z0-9.-_\?\$&=%]/i', '', $_GET['u']))) -{ - $a_uri = parse_url($url); - $port = $a_uri['port'] ? $a_uri['port'] : 80; - $host = $a_uri['host']; - $path = $a_uri['path'] . ($a_uri['query'] ? '?'.$a_uri['query'] : ''); +$source = ''; +$error = 'Requires a valid user session and source url'; +if (empty($RCMAIL->user->ID)) { + header('HTTP/1.1 403 Forbidden'); + echo $error; + exit; +} + +$url = preg_replace('/[^a-z0-9.-_\?\$&=%]/i', '', $_GET['u']); +if ($url === null) { + header('HTTP/1.1 403 Forbidden'); + echo $error; + exit; +} - if ($fp = fsockopen($host, $port, $errno, $errstr, 30)) - { - $out = "GET $path HTTP/1.0\r\n"; - $out .= "Host: $host\r\n"; - $out .= "Connection: Close\r\n\r\n"; - fwrite($fp, $out); +$a_uri = parse_url($url); +$port = $a_uri['port'] ? $a_uri['port'] : 80; +$host = $a_uri['host']; +$path = $a_uri['path'] . ($a_uri['query'] ? '?'.$a_uri['query'] : ''); - $header = true; - while (!feof($fp)) - { - $line = trim(fgets($fp, 4048)); - - if ($header && preg_match('/^HTTP\/1\..\s+(\d+)/', $line, $regs) && intval($regs[1]) != 200) - break; - else if (empty($line) && $header) - $header = false; - else if (!$header) - $source .= "$line\n"; - } - fclose($fp); - } +if (!($fp = fsockopen($host, $port, $errno, $errstr, 30))) { + header('HTTP/1.1 500 Internal Server Error'); + echo $error; + exit; } -if (!empty($source)) -{ - header("Content-Type: text/css"); - echo rcmail_mod_css_styles($source, preg_replace('/[^a-z0-9]/i', '', $_GET['c']), $url); +$out = "GET $path HTTP/1.0\r\n"; +$out .= "Host: $host\r\n"; +$out .= "Connection: Close\r\n\r\n"; +fwrite($fp, $out); + +$header = true; +while (!feof($fp)) { + $line = trim(fgets($fp, 4048)); + + if ($header + && preg_match('/^HTTP\/1\..\s+(\d+)/', $line, $regs) + && intval($regs[1]) != 200) { + break; + } else if (empty($line) && $header) { + $header = false; + } else if (!$header) { + $source .= "$line\n"; + } } -else { - header("HTTP/1.0 404 Not Found"); - echo "Requires a valid user session and source url"; +fclose($fp); + +if (!empty($source)) { + header('Content-Type: text/css'); + echo rcmail_mod_css_styles( + $source, + preg_replace('/[^a-z0-9]/i', '', $_GET['c']), + $url + ); + exit; } -?> +header('HTTP/1.0 404 Not Found'); +echo $error; +exit; diff --git a/bin/msgexport.sh b/bin/msgexport.sh index b15da1f..7dd56e9 100755 --- a/bin/msgexport.sh +++ b/bin/msgexport.sh @@ -1,5 +1,8 @@ -#!/usr/bin/php +#!/usr/bin/env php \ No newline at end of file +?> diff --git a/bin/msgimport.sh b/bin/msgimport.sh index fa5678c..a5161e0 100755 --- a/bin/msgimport.sh +++ b/bin/msgimport.sh @@ -1,5 +1,8 @@ -#!/usr/bin/php +#!/usr/bin/env php \ No newline at end of file +?> diff --git a/bin/quotaimg.php b/bin/quotaimg.php index 6e3d7de..ed6ce81 100644 --- a/bin/quotaimg.php +++ b/bin/quotaimg.php @@ -4,7 +4,7 @@ | bin/quotaimg.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -14,7 +14,7 @@ | Author: Brett Patterson | +-----------------------------------------------------------------------+ - $Id: quotaimg.php 2187 2008-12-24 14:19:27Z thomasb $ + $Id: quotaimg.php 2237 2009-01-17 01:55:39Z till $ */ diff --git a/bin/update.sh b/bin/update.sh index a9a917c..c93d92d 100755 --- a/bin/update.sh +++ b/bin/update.sh @@ -1,6 +1,8 @@ -#!/usr/bin/php +#!/usr/bin/env php \ No newline at end of file +?> diff --git a/config/db.inc.php.dist b/config/db.inc.php.dist index 255fb3e..4020b26 100644 --- a/config/db.inc.php.dist +++ b/config/db.inc.php.dist @@ -5,7 +5,7 @@ | Configuration file for database access | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | +-----------------------------------------------------------------------+ diff --git a/config/main.inc.php.dist b/config/main.inc.php.dist index f8d9b29..1870852 100644 --- a/config/main.inc.php.dist +++ b/config/main.inc.php.dist @@ -5,7 +5,7 @@ | Main configuration file | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | +-----------------------------------------------------------------------+ @@ -152,7 +152,7 @@ $rcmail_config['date_long'] = 'd.m.Y H:i'; $rcmail_config['date_today'] = 'H:i'; // add this user-agent to message headers when sending -$rcmail_config['useragent'] = 'RoundCube Webmail/0.2'; +$rcmail_config['useragent'] = 'RoundCube Webmail/0.2.1'; // use this name to compose page titles $rcmail_config['product_name'] = 'RoundCube Webmail'; @@ -248,43 +248,43 @@ $rcmail_config['ldap_public'] = array(); // o=root // ou=people // uid=user@domain -// mail=contact@contactdomain -// +// mail=contact@contactdomain +// // So the base_dn would be uid=%fu,ou=people,o=root // The bind_dn would be the same as based_dn or some super user login. -/** +/* * example config for Verisign directory * - * $rcmail_config['ldap_public']['Verisign'] = array( - * 'name' => 'Verisign.com', - * 'hosts' => array('directory.verisign.com'), - * 'port' => 389, - * 'use_tls' => false, - * 'user_specific' => false, // If true the base_dn, bind_dn and bind_pass default to the user's IMAP login. - * // %fu - The full username provided, assumes the username is an email - * // address, uses the username_domain value if not an email address. - * // %u - The username prior to the '@'. - * // %d - The domain name after the '@'. - * 'base_dn' => '', - * 'bind_dn' => '', - * 'bind_pass' => '', - * 'writable' => false, // Indicates if we can write to the LDAP directory or not. - * // If writable is true then these fields need to be populated: - * // LDAP_Object_Classes, required_fields, LDAP_rdn - * 'LDAP_Object_Classes' => array("top", "inetOrgPerson"), // To create a new contact these are the object classes to specify (or any other classes you wish to use). - * 'required_fields' => array("cn", "sn", "mail"), // The required fields needed to build a new contact as required by the object classes (can include additional fields not required by the object classes). - * 'LDAP_rdn' => 'mail', // The RDN field that is used for new entries, this field needs to be one of the search_fields, the base of base_dn is appended to the RDN to insert into the LDAP directory. - * 'ldap_version' => 3, // using LDAPv3 - * 'search_fields' => array('mail', 'cn'), // fields to search in - * 'name_field' => 'cn', // this field represents the contact's name - * 'email_field' => 'mail', // this field represents the contact's e-mail - * 'surname_field' => 'sn', // this field represents the contact's last name - * 'firstname_field' => 'gn', // this field represents the contact's first name - * 'sort' => 'cn', // The field to sort the listing by. - * 'scope' => 'sub', // search mode: sub|base|list - * 'filter' => '', // used for basic listing (if not empty) and will be &'d with search queries. example: status=act - * 'fuzzy_search' => true); // server allows wildcard search - */ +$rcmail_config['ldap_public']['Verisign'] = array( + 'name' => 'Verisign.com', + 'hosts' => array('directory.verisign.com'), + 'port' => 389, + 'use_tls' => false, + 'user_specific' => false, // If true the base_dn, bind_dn and bind_pass default to the user's IMAP login. + // %fu - The full username provided, assumes the username is an email + // address, uses the username_domain value if not an email address. + // %u - The username prior to the '@'. + // %d - The domain name after the '@'. + 'base_dn' => '', + 'bind_dn' => '', + 'bind_pass' => '', + 'writable' => false, // Indicates if we can write to the LDAP directory or not. + // If writable is true then these fields need to be populated: + // LDAP_Object_Classes, required_fields, LDAP_rdn + 'LDAP_Object_Classes' => array("top", "inetOrgPerson"), // To create a new contact these are the object classes to specify (or any other classes you wish to use). + 'required_fields' => array("cn", "sn", "mail"), // The required fields needed to build a new contact as required by the object classes (can include additional fields not required by the object classes). + 'LDAP_rdn' => 'mail', // The RDN field that is used for new entries, this field needs to be one of the search_fields, the base of base_dn is appended to the RDN to insert into the LDAP directory. + 'ldap_version' => 3, // using LDAPv3 + 'search_fields' => array('mail', 'cn'), // fields to search in + 'name_field' => 'cn', // this field represents the contact's name + 'email_field' => 'mail', // this field represents the contact's e-mail + 'surname_field' => 'sn', // this field represents the contact's last name + 'firstname_field' => 'gn', // this field represents the contact's first name + 'sort' => 'cn', // The field to sort the listing by. + 'scope' => 'sub', // search mode: sub|base|list + 'filter' => '', // used for basic listing (if not empty) and will be &'d with search queries. example: status=act + 'fuzzy_search' => true); // server allows wildcard search +*/ // An ordered array of the ids of the addressbooks that should be searched // when populating address autocomplete fields server-side. ex: array('sql','Verisign'); diff --git a/config/mimetypes.php b/config/mimetypes.php new file mode 100644 index 0000000..2e95a29 --- /dev/null +++ b/config/mimetypes.php @@ -0,0 +1,46 @@ + 'application/vnd.ms-excel', + 'xlm' => 'application/vnd.ms-excel', + 'xla' => 'application/vnd.ms-excel', + 'xlc' => 'application/vnd.ms-excel', + 'xlt' => 'application/vnd.ms-excel', + 'xlw' => 'application/vnd.ms-excel', + 'ppt' => 'application/vnd.ms-powerpoint', + 'pps' => 'application/vnd.ms-powerpoint', + 'pot' => 'application/vnd.ms-powerpoint', + 'doc' => 'application/msword', + 'dot' => 'application/msword', + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'otc' => 'application/vnd.oasis.opendocument.chart-template', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'otf' => 'application/vnd.oasis.opendocument.formula-template', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'otg' => 'application/vnd.oasis.opendocument.graphics-template', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'oti' => 'application/vnd.oasis.opendocument.image-template', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'otp' => 'application/vnd.oasis.opendocument.presentation-template', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'otm' => 'application/vnd.oasis.opendocument.text-master', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + 'oth' => 'application/vnd.oasis.opendocument.text-web', + 'docm' => 'application/vnd.ms-word.document.macroEnabled.12', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', + 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', + 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xps' => 'application/vnd.ms-xpsdocument', + 'rar' => 'application/x-rar-compressed', +); + +?> \ No newline at end of file diff --git a/index.php b/index.php index 5d19369..fa9ac50 100644 --- a/index.php +++ b/index.php @@ -2,9 +2,9 @@ /* +-------------------------------------------------------------------------+ | RoundCube Webmail IMAP Client | - | Version 0.2-stable | + | Version 0.2.1 | | | - | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland | | | | This program is free software; you can redistribute it and/or modify | | it under the terms of the GNU General Public License version 2 | @@ -23,7 +23,7 @@ | Author: Thomas Bruederli | +-------------------------------------------------------------------------+ - $Id: index.php 2201 2008-12-30 14:33:28Z thomasb $ + $Id: index.php 2348 2009-03-10 08:13:26Z thomasb $ */ @@ -72,6 +72,10 @@ if ($RCMAIL->action=='error' && !empty($_GET['_code'])) { // try to log in if ($RCMAIL->action=='login' && $RCMAIL->task=='mail') { + // purge the session in case of new login when a session already exists + $RCMAIL->kill_session(); + + // set IMAP host $host = $RCMAIL->autoselect_host(); // check if client supports cookies diff --git a/installer/index.php b/installer/index.php index f7a5cea..549b6f0 100644 --- a/installer/index.php +++ b/installer/index.php @@ -13,6 +13,7 @@ $include_path .= ini_get('include_path'); set_include_path($include_path); +require_once 'rcube_shared.inc'; require_once 'utils.php'; session_start(); @@ -105,7 +106,7 @@ if ($RCI->configured && empty($_REQUEST['_step'])) { step]) { include $include_steps[$RCI->step]; diff --git a/installer/rcube_install.php b/installer/rcube_install.php index 96134d2..b2b8257 100644 --- a/installer/rcube_install.php +++ b/installer/rcube_install.php @@ -5,7 +5,7 @@ | rcube_install.php | | | | This file is part of the RoundCube Webmail package | - | Copyright (C) 2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2008-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU Public License | +-----------------------------------------------------------------------+ diff --git a/program/include/html.php b/program/include/html.php index 032915f..01ad415 100644 --- a/program/include/html.php +++ b/program/include/html.php @@ -5,7 +5,7 @@ | program/include/html.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2005-2008, RoundCube Dev, - Switzerland | + | Copyright (C) 2005-2009, RoundCube Dev, - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | diff --git a/program/include/iniset.php b/program/include/iniset.php index 78eb270..7bcca4e 100755 --- a/program/include/iniset.php +++ b/program/include/iniset.php @@ -5,7 +5,7 @@ | program/include/iniset.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2008, RoundCube Dev, - Switzerland | + | Copyright (C) 2008-2009, RoundCube Dev, - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -22,7 +22,7 @@ // application constants -define('RCMAIL_VERSION', '0.2-stable'); +define('RCMAIL_VERSION', '0.2.1'); define('RCMAIL_CHARSET', 'UTF-8'); define('JS_OBJECT_NAME', 'rcmail'); @@ -50,11 +50,15 @@ if (set_include_path($include_path) === false) { die('Fatal error: ini_set/set_include_path does not work.'); } +ini_set('error_reporting', E_ALL&~E_NOTICE); +if (isset($_SERVER['HTTPS'])) { + ini_set('session.cookie_secure', ($_SERVER['HTTPS'] && ($_SERVER['HTTPS'] != 'off'))?1:0); +} else { + ini_set('session.cookie_secure', 0); +} ini_set('session.name', 'roundcube_sessid'); ini_set('session.use_cookies', 1); ini_set('session.only_use_cookies', 1); -ini_set('session.cookie_secure', ($_SERVER['HTTPS'] && ($_SERVER['HTTPS'] != 'off'))); -ini_set('error_reporting', E_ALL&~E_NOTICE); set_magic_quotes_runtime(0); // increase maximum execution time for php scripts @@ -72,6 +76,7 @@ if(extension_loaded('mbstring')) * Use PHP5 autoload for dynamic class loading * * @todo Make Zend, PEAR etc play with this + * @todo Make our classes conform to a more straight forward CS. */ function __autoload($classname) { @@ -90,7 +95,7 @@ function __autoload($classname) ), $classname ); - include_once $filename. '.php'; + include $filename. '.php'; } /** @@ -112,4 +117,3 @@ require_once 'include/rcube_shared.inc'; // set PEAR error handling (will also load the PEAR main class) PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'rcube_pear_error'); - diff --git a/program/include/main.inc b/program/include/main.inc index d308d93..c8bd137 100644 --- a/program/include/main.inc +++ b/program/include/main.inc @@ -5,7 +5,7 @@ | program/include/main.inc | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2005-2008, RoundCube Dev, - Switzerland | + | Copyright (C) 2005-2009, RoundCube Dev, - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -15,7 +15,7 @@ | Author: Thomas Bruederli | +-----------------------------------------------------------------------+ - $Id: main.inc 2187 2008-12-24 14:19:27Z thomasb $ + $Id: main.inc 2321 2009-03-01 08:14:14Z alec $ */ @@ -182,6 +182,12 @@ function rcube_charset_convert($str, $from, $to=NULL) $to = $to==NULL ? strtoupper(RCMAIL_CHARSET) : strtoupper($to); $error = false; $conv = null; + # RFC1642 + if ($from == 'UNICODE-1-1-UTF-7') + $from = 'UTF-7'; + if ($to == 'UNICODE-1-1-UTF-7') + $to = 'UTF-7'; + if ($from==$to || $str=='' || empty($from)) return $str; @@ -197,23 +203,19 @@ function rcube_charset_convert($str, $from, $to=NULL) ); // convert charset using iconv module - if (function_exists('iconv') && $from != 'UTF-7' && $to != 'UTF-7') - { + if (function_exists('iconv') && $from != 'UTF-7' && $to != 'UTF-7') { $aliases['GB2312'] = 'GB18030'; $_iconv = iconv(($aliases[$from] ? $aliases[$from] : $from), ($aliases[$to] ? $aliases[$to] : $to) . "//IGNORE", $str); - if ($_iconv !== false) - { + if ($_iconv !== false) { return $_iconv; - } } - + } if (is_null($mbstring_loaded)) $mbstring_loaded = extension_loaded('mbstring'); // convert charset using mbstring module - if ($mbstring_loaded) - { + if ($mbstring_loaded) { $aliases['UTF-7'] = 'UTF7-IMAP'; $aliases['WINDOWS-1257'] = 'ISO-8859-13'; @@ -226,45 +228,48 @@ function rcube_charset_convert($str, $from, $to=NULL) $mb_to = $aliases[$to] ? $aliases[$to] : $to; // return if encoding found, string matches encoding and convert succeeded - if (in_array($mb_from, $mbstring_list) && in_array($mb_to, $mbstring_list)) - if (mb_check_encoding($str, $mb_from)) - if ($out = mb_convert_encoding($str, $mb_to, $mb_from)) - return $out; + if (in_array($mb_from, $mbstring_list) && in_array($mb_to, $mbstring_list)) { + if (mb_check_encoding($str, $mb_from) && ($out = mb_convert_encoding($str, $mb_to, $mb_from))) + return $out; } - - + } + + # try to convert with custom classes if (class_exists('utf8')) $conv = new utf8(); // convert string to UTF-8 - if ($from == 'UTF-7') - $str = utf7_to_utf8($str); - else if (($from == 'ISO-8859-1') && function_exists('utf8_encode')) + if ($from == 'UTF-7') { + if ($_str = utf7_to_utf8($str)) + $str = $_str; + } + else if (($from == 'ISO-8859-1') && function_exists('utf8_encode')) { $str = utf8_encode($str); - else if ($from != 'UTF-8' && $conv) - { + } + else if ($from != 'UTF-8' && $conv) { $conv->loadCharset($from); $str = $conv->strToUtf8($str); - } - else if ($from != 'UTF-8') + } + else if ($from != 'UTF-8') {} $error = true; // encode string for output - if ($to == 'UTF-7') + if ($to == 'UTF-7') { return utf8_to_utf7($str); - else if ($to == 'ISO-8859-1' && function_exists('utf8_decode')) + } + else if ($to == 'ISO-8859-1' && function_exists('utf8_decode')) { return utf8_decode($str); - else if ($to != 'UTF-8' && $conv) - { + } + else if ($to != 'UTF-8' && $conv) { $conv->loadCharset($to); return $conv->utf8ToStr($str); - } - else if ($to != 'UTF-8') + } + else if ($to != 'UTF-8') { $error = true; - + } + // report error - if ($error && !$convert_warning) - { + if ($error && !$convert_warning){ raise_error(array( 'code' => 500, 'type' => 'php', @@ -273,7 +278,7 @@ function rcube_charset_convert($str, $from, $to=NULL) ), true, false); $convert_warning = true; - } + } // return UTF-8 string return $str; @@ -583,25 +588,24 @@ function rcmail_get_edit_field($col, $value, $attrib, $type='text') * @param string Container ID to use as prefix * @return string Modified CSS source */ -function rcmail_mod_css_styles($source, $container_id, $base_url = '') +function rcmail_mod_css_styles($source, $container_id) { - $a_css_values = array(); $last_pos = 0; + $replacements = new rcube_string_replacer; // ignore the whole block if evil styles are detected $stripped = preg_replace('/[^a-z\(:]/', '', rcmail_xss_entitiy_decode($source)); if (preg_match('/expression|behavior|url\(|import/', $stripped)) - return ''; + return '/* evil! */'; // cut out all contents between { and } while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos))) { - $key = sizeof($a_css_values); - $a_css_values[$key] = substr($source, $pos+1, $pos2-($pos+1)); - $source = substr($source, 0, $pos+1) . "<>" . substr($source, $pos2, strlen($source)-$pos2); + $key = $replacements->add(substr($source, $pos+1, $pos2-($pos+1))); + $source = substr($source, 0, $pos+1) . $replacements->get_replacement($key) . substr($source, $pos2, strlen($source)-$pos2); $last_pos = $pos+2; } - + // remove html comments and add #container to each tag selector. // also replace body definition because we also stripped off the tag $styles = preg_replace( @@ -617,17 +621,8 @@ function rcmail_mod_css_styles($source, $container_id, $base_url = '') ), $source); - // replace all @import statements to modify the imported CSS sources too - $styles = preg_replace_callback( - '/@import\s+(url\()?[\'"]?([^\)\'"]+)[\'"]?(\))?/im', - create_function('$matches', "return sprintf(\"@import url('./bin/modcss.php?u=%s&c=%s')\", urlencode(make_absolute_url(\$matches[2],'$base_url')), urlencode('$container_id'));"), - $styles); - // put block contents back in - $styles = preg_replace_callback( - '/<>/', - create_function('$matches', "\$values = ".var_export($a_css_values, true)."; return \$values[\$matches[1]];"), - $styles); + $styles = $replacements->resolve($styles); return $styles; } @@ -643,12 +638,23 @@ function rcmail_mod_css_styles($source, $container_id, $base_url = '') function rcmail_xss_entitiy_decode($content) { $out = html_entity_decode(html_entity_decode($content)); - $out = preg_replace_callback('/\\\([0-9a-f]{4})/i', create_function('$matches', 'return chr(hexdec($matches[1]));'), $out); + $out = preg_replace_callback('/\\\([0-9a-f]{4})/i', 'rcmail_xss_entitiy_decode_callback', $out); $out = preg_replace('#/\*.*\*/#Um', '', $out); return $out; } +/** + * preg_replace_callback callback for rcmail_xss_entitiy_decode_callback + * + * @param array matches result from preg_replace_callback + * @return string decoded entity + */ +function rcmail_xss_entitiy_decode_callback($matches) +{ + return chr(hexdec($matches[1])); +} + /** * Compose a valid attribute string for HTML tags * @@ -708,6 +714,8 @@ function format_date($date, $format=NULL) $ts = $date; else if (!empty($date)) { + // support non-standard "GMTXXXX" literal + $date = preg_replace('/GMT\s*([+-][0-9]+)/', '\\1', $date); // if date parsing fails, we have a date in non-rfc format. // remove token from the end and try again while ((($ts = @strtotime($date))===false) || ($ts < 0)) @@ -1205,4 +1213,25 @@ function rcube_html_editor($mode='') $OUTPUT->add_script('rcmail_editor_init("$__skin_path", "'.JQ($tinylang).'", '.intval($CONFIG['enable_spellcheck']).', "'.$mode.'");'); } + + +/** + * Helper class to turn relative urls into absolute ones + * using a predefined base + */ +class rcube_base_replacer +{ + private $base_url; + + public function __construct($base) + { + $this->base_url = $base; + } + + public function callback($matches) + { + return $matches[1] . '="' . make_absolute_url($matches[3], $this->base_url) . '"'; + } +} + ?> diff --git a/program/include/rcmail.php b/program/include/rcmail.php index fcd3950..f109c16 100644 --- a/program/include/rcmail.php +++ b/program/include/rcmail.php @@ -5,7 +5,7 @@ | program/include/rcmail.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2008-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -47,7 +47,7 @@ class rcmail /** * This implements the 'singleton' design pattern * - * @return object qvert The one and only instance + * @return object rcmail The one and only instance */ static function get_instance() { diff --git a/program/include/rcube_browser.php b/program/include/rcube_browser.php index 162844f..56e6d3c 100644 --- a/program/include/rcube_browser.php +++ b/program/include/rcube_browser.php @@ -5,7 +5,7 @@ | program/include/rcube_browser.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2007-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2007-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | diff --git a/program/include/rcube_config.php b/program/include/rcube_config.php index 7903407..7be2b0d 100644 --- a/program/include/rcube_config.php +++ b/program/include/rcube_config.php @@ -5,7 +5,7 @@ | program/include/rcube_config.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2008-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | diff --git a/program/include/rcube_contacts.php b/program/include/rcube_contacts.php index 7ef2af1..65d89ca 100644 --- a/program/include/rcube_contacts.php +++ b/program/include/rcube_contacts.php @@ -5,7 +5,7 @@ | program/include/rcube_contacts.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2006-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2006-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | diff --git a/program/include/rcube_html_page.php b/program/include/rcube_html_page.php index ab8eba5..78f6176 100644 --- a/program/include/rcube_html_page.php +++ b/program/include/rcube_html_page.php @@ -5,7 +5,7 @@ | program/include/rcube_html_page.php | | | | This file is part of the RoundCube PHP suite | - | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | CONTENTS: | diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index ab49dca..edbdb39 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -5,7 +5,7 @@ | program/include/rcube_imap.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -16,7 +16,7 @@ | Author: Thomas Bruederli | +-----------------------------------------------------------------------+ - $Id: rcube_imap.php 2189 2008-12-25 08:33:21Z alec $ + $Id: rcube_imap.php 2335 2009-03-06 20:58:32Z alec $ */ @@ -26,6 +26,7 @@ */ require_once('lib/imap.inc'); require_once('lib/mime.inc'); +require_once('lib/tnef_decoder.inc'); /** @@ -354,8 +355,9 @@ class rcube_imap */ function check_permflag($flag) { - $flagsmap = $GLOBALS['IMAP_FLAGS']; - return (($imap_flag = $flagsmap[strtoupper($flag)]) && in_array_nocase($imap_flag, $this->conn->permanentflags)); + $flag = strtoupper($flag); + $imap_flag = $GLOBALS['IMAP_FLAGS'][$flag]; + return (in_array_nocase($imap_flag, $this->conn->permanentflags)); } @@ -685,9 +687,9 @@ class rcube_imap $cnt = count($msgs); if ($cnt > 300 && $cnt > $this->page_size) { // experimantal value for best result // use memory less expensive (and quick) method for big result set - $a_index = $this->message_index($mailbox, $this->sort_field, $this->sort_order); + $a_index = $this->message_index('', $this->sort_field, $this->sort_order); // get messages uids for one page... - $msgs = array_slice(array_keys($a_index), $start_msg, min($cnt-$start_msg, $this->page_size)); + $msgs = array_slice($a_index, $start_msg, min($cnt-$start_msg, $this->page_size)); // ...and fetch headers $this->_fetch_headers($mailbox, join(',', $msgs), $a_msg_headers, NULL); @@ -953,11 +955,11 @@ class rcube_imap $results = $this->_search_index($mailbox, $str, $charset, $sort_field); - // try search with ISO charset (should be supported by server) + // try search with US-ASCII charset (should be supported by server) // only if UTF-8 search is not supported - if (empty($results) && !is_array($results) && !empty($charset) && $charset!='ISO-8859-1') + if (empty($results) && !is_array($results) && !empty($charset) && $charset!='US-ASCII') { - // convert strings to ISO-8859-1 + // convert strings to US_ASCII if(preg_match_all('/\{([0-9]+)\}\r\n/', $str, $matches, PREG_OFFSET_CAPTURE)) { $last = 0; $res = ''; @@ -965,7 +967,8 @@ class rcube_imap { $string_offset = $m[1] + strlen($m[0]) + 4; // {}\r\n $string = substr($str, $string_offset - 1, $m[0]); - $string = rcube_charset_convert($string, $charset, 'ISO-8859-1'); + $string = rcube_charset_convert($string, $charset, 'US-ASCII'); + if (!$string) continue; $res .= sprintf("%s{%d}\r\n%s", substr($str, $last, $m[1] - $last - 1), strlen($string), $string); $last = $m[0] + $string_offset - 1; } @@ -975,7 +978,7 @@ class rcube_imap else // strings for conversion not found $res = $str; - $results = $this->search($mbox_name, $res, 'ISO-8859-1', $sort_field); + $results = $this->search($mbox_name, $res, 'US-ASCII', $sort_field); } $this->set_search_set($str, $results, $charset, $sort_field); @@ -1047,9 +1050,10 @@ class rcube_imap * @param int Message ID * @param string Mailbox to read from * @param boolean True if $id is the message UID + * @param boolean True if we need also BODYSTRUCTURE in headers * @return object Message headers representation */ - function get_headers($id, $mbox_name=NULL, $is_uid=TRUE) + function get_headers($id, $mbox_name=NULL, $is_uid=TRUE, $bodystr=FALSE) { $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox; $uid = $is_uid ? $id : $this->_id2uid($id); @@ -1058,7 +1062,7 @@ class rcube_imap if ($uid && ($headers = &$this->get_cached_message($mailbox.'.msg', $uid))) return $headers; - $headers = iil_C_FetchHeader($this->conn, $mailbox, $id, $is_uid); + $headers = iil_C_FetchHeader($this->conn, $mailbox, $id, $is_uid, $bodystr); // write headers cache if ($headers) @@ -1078,9 +1082,10 @@ class rcube_imap * an object structure similar to the one generated by PEAR::Mail_mimeDecode * * @param int Message UID to fetch + * @param string Message BODYSTRUCTURE string (optional) * @return object rcube_message_part Message part tree or False on failure */ - function &get_structure($uid) + function &get_structure($uid, $structure_str='') { $cache_key = $this->mailbox.'.msg'; $headers = &$this->get_cached_message($cache_key, $uid, true); @@ -1095,7 +1100,8 @@ class rcube_imap return FALSE; } - $structure_str = iil_C_FetchStructureString($this->conn, $this->mailbox, $msg_id); + if (!$structure_str) + $structure_str = iil_C_FetchStructureString($this->conn, $this->mailbox, $msg_id); $structure = iml_GetRawStructureArray($structure_str); $struct = false; @@ -1130,7 +1136,7 @@ class rcube_imap * * @access private */ - function &_structure_part($part, $count=0, $parent='') + function &_structure_part($part, $count=0, $parent='', $raw_headers=null) { $struct = new rcube_message_part; $struct->mime_id = empty($parent) ? (string)$count : "$parent.$count"; @@ -1150,11 +1156,25 @@ class rcube_imap $struct->mimetype = 'multipart/'.$struct->ctype_secondary; + // build parts list for headers pre-fetching + for ($i=0, $count=0; $i 3) + // fetch message headers if message/rfc822 or named part (could contain Content-Location header) + if (strtolower($part[$i][0]) == 'message' || + (in_array('name', (array)$part[$i][2]) && (empty($part[$i][3]) || $part[$i][3]=='NIL'))) { + $part_headers[] = $struct->mime_id ? $struct->mime_id.'.'.$i+1 : $i+1; + } + + // pre-fetch headers of all parts (in one command for better performance) + if ($part_headers) + $part_headers = iil_C_FetchMIMEHeaders($this->conn, $this->mailbox, $this->_msg_id, $part_headers); + $struct->parts = array(); for ($i=0, $count=0; $i 3) - $struct->parts[] = $this->_structure_part($part[$i], ++$count, $struct->mime_id); - + $struct->parts[] = $this->_structure_part($part[$i], ++$count, $struct->mime_id, + $part_headers[$struct->mime_id ? $struck->mime_id.'.'.$i+1 : $i+1]); + return $struct; } @@ -1219,8 +1239,9 @@ class rcube_imap // fetch message headers if message/rfc822 or named part (could contain Content-Location header) if ($struct->ctype_primary == 'message' || ($struct->ctype_parameters['name'] && !$struct->content_id)) { - $part_headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, $struct->mime_id); - $struct->headers = $this->_parse_headers($part_headers) + $struct->headers; + if (empty($raw_headers)) + $raw_headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, $struct->mime_id); + $struct->headers = $this->_parse_headers($raw_headers) + $struct->headers; } if ($struct->ctype_primary=='message') { @@ -1229,7 +1250,7 @@ class rcube_imap } // normalize filename property - $this->_set_part_filename($struct); + $this->_set_part_filename($struct, $raw_headers); return $struct; } @@ -1240,8 +1261,9 @@ class rcube_imap * * @access private * @param object rcube_message_part Part object + * @param string Part's raw headers */ - function _set_part_filename(&$part) + function _set_part_filename(&$part, $headers=null) { if (!empty($part->d_parameters['filename'])) $filename_mime = $part->d_parameters['filename']; @@ -1259,10 +1281,9 @@ class rcube_imap } // some servers (eg. dovecot-1.x) have no support for parameter value continuations // we must fetch and parse headers "manually" - //TODO: fetching headers for a second time is not effecient, this code should be moved somewhere earlier --tensor if ($i<2) { - // TODO: fetch only Content-Type/Content-Disposition header - $headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, $part->mime_id); + if (!$headers) + $headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, $part->mime_id); $filename_mime = ''; $i = 0; while (preg_match('/filename\*'.$i.'\s*=\s*"*([^"\n;]+)[";]*/', $headers, $matches)) { @@ -1278,7 +1299,8 @@ class rcube_imap $i++; } if ($i<2) { - $headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, $part->mime_id); + if (!$headers) + $headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, $part->mime_id); $filename_encoded = ''; $i = 0; $matches = array(); while (preg_match('/filename\*'.$i.'\*\s*=\s*"*([^"\n;]+)[";]*/', $headers, $matches)) { @@ -1294,7 +1316,8 @@ class rcube_imap $i++; } if ($i<2) { - $headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, $part->mime_id); + if (!$headers) + $headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, $part->mime_id); $filename_mime = ''; $i = 0; $matches = array(); while (preg_match('/\s+name\*'.$i.'\s*=\s*"*([^"\n;]+)[";]*/', $headers, $matches)) { @@ -1310,7 +1333,8 @@ class rcube_imap $i++; } if ($i<2) { - $headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, $part->mime_id); + if (!$headers) + $headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, $part->mime_id); $filename_encoded = ''; $i = 0; $matches = array(); while (preg_match('/\s+name\*'.$i.'\*\s*=\s*"*([^"\n;]+)[";]*/', $headers, $matches)) { @@ -1550,7 +1574,6 @@ class rcube_imap */ function save_message($mbox_name, &$message) { - $mbox_name = stripslashes($mbox_name); $mailbox = $this->_mod_mailbox($mbox_name); // make sure mailbox exists @@ -1577,13 +1600,11 @@ class rcube_imap */ function move_message($uids, $to_mbox, $from_mbox='') { - $to_mbox_in = stripslashes($to_mbox); - $from_mbox = stripslashes($from_mbox); - $to_mbox = $this->_mod_mailbox($to_mbox_in); + $to_mbox = $this->_mod_mailbox($to_mbox); $from_mbox = $from_mbox ? $this->_mod_mailbox($from_mbox) : $this->mailbox; // make sure mailbox exists - if (!in_array($to_mbox, $this->_list_mailboxes())) + if ($to_mbox != 'INBOX' && !in_array($to_mbox, $this->_list_mailboxes())) { if (in_array($to_mbox_in, $this->default_folders)) $this->create_mailbox($to_mbox_in, TRUE); @@ -1654,7 +1675,6 @@ class rcube_imap */ function delete_message($uids, $mbox_name='') { - $mbox_name = stripslashes($mbox_name); $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox; // convert the list of uids to array @@ -1711,7 +1731,6 @@ class rcube_imap */ function clear_mailbox($mbox_name=NULL) { - $mbox_name = stripslashes($mbox_name); $mailbox = !empty($mbox_name) ? $this->_mod_mailbox($mbox_name) : $this->mailbox; $msg_count = $this->_messagecount($mailbox, 'ALL'); @@ -1744,7 +1763,6 @@ class rcube_imap */ function expunge($mbox_name='', $clear_cache=TRUE) { - $mbox_name = stripslashes($mbox_name); $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox; return $this->_expunge($mailbox, $clear_cache); } @@ -1863,9 +1881,6 @@ class rcube_imap { $result = FALSE; - // replace backslashes - $name = preg_replace('/[\\\]+/', '-', $name); - // reduce mailbox name to 100 chars $name = substr($name, 0, 100); @@ -1894,9 +1909,6 @@ class rcube_imap { $result = FALSE; - // replace backslashes - $name = preg_replace('/[\\\]+/', '-', $new_name); - // encode mailbox name and reduce it to 100 chars $name = substr($new_name, 0, 100); @@ -2341,7 +2353,7 @@ class rcube_imap { if (empty($key) || !is_object($headers) || empty($headers->uid)) return; - + // add to internal (fast) cache $this->cache['__single_msg'][$headers->uid] = $headers; $this->cache['__single_msg'][$headers->uid]->structure = $struct; @@ -2482,6 +2494,40 @@ class rcube_imap return $out; } + + + /** + * Decode a Microsoft Outlook TNEF part (winmail.dat) + * + * @param object rcube_message_part Message part to decode + * @param string UID of the message + * @return array List of rcube_message_parts extracted from windmail.dat + */ + function tnef_decode(&$part, $uid) + { + if (!isset($part->body)) + $part->body = $this->get_message_part($uid, $part->mime_id, $part); + + $pid = 0; + $tnef_parts = array(); + $tnef_arr = tnef_decode($part->body); + foreach ($tnef_arr as $winatt) { + $tpart = new rcube_message_part; + $tpart->filename = $winatt["name"]; + $tpart->encoding = 'stream'; + $tpart->ctype_primary = $winatt["type0"]; + $tpart->ctype_secondary = $winatt["type1"]; + $tpart->mimetype = strtolower($winatt["type0"] . "/" . $winatt["type1"]); + $tpart->mime_id = "winmail." . $part->mime_id . ".$pid"; + $tpart->size = $winatt["size"]; + $tpart->body = $winatt['stream']; + + $tnef_parts[] = $tpart; + $pid++; + } + + return $tnef_parts; + } /** @@ -2913,53 +2959,33 @@ class rcube_imap function _parse_address_list($str, $decode=true) { // remove any newlines and carriage returns before - $a = $this->_explode_quoted_string('[,;]', preg_replace( "/[\r\n]/", " ", $str)); + $a = rcube_explode_quoted_string('[,;]', preg_replace( "/[\r\n]/", " ", $str)); $result = array(); - + foreach ($a as $key => $val) { $val = preg_replace("/([\"\w])_explode_quoted_string(' ', $decode ? $this->decode_header($val) : $val); + $sub_a = rcube_explode_quoted_string(' ', $decode ? $this->decode_header($val) : $val); $result[$key]['name'] = ''; foreach ($sub_a as $k => $v) { - if (strpos($v, '@') > 0) - $result[$key]['address'] = str_replace('<', '', str_replace('>', '', $v)); + // use angle brackets in regexp to not handle names with @ sign + if (preg_match('/^<\S+@\S+>$/', $v)) + $result[$key]['address'] = trim($v, '<>'); else $result[$key]['name'] .= (empty($result[$key]['name'])?'':' ').str_replace("\"",'',stripslashes($v)); } if (empty($result[$key]['name'])) $result[$key]['name'] = $result[$key]['address']; + elseif (empty($result[$key]['address'])) + $result[$key]['address'] = $result[$key]['name']; } return $result; } - - /** - * @access private - */ - function _explode_quoted_string($delimiter, $string) - { - $result = array(); - $strlen = strlen($string); - for ($q=$p=$i=0; $i < $strlen; $i++) - { - if ($string{$i} == "\"" && $string{$i-1} != "\\") - $q = $q ? false : true; - else if (!$q && preg_match("/$delimiter/", $string{$i})) - { - $result[] = substr($string, $p, $i - $p); - $p = $i + 1; - } - } - - $result[] = substr($string, $p); - return $result; - } - } // end class rcube_imap diff --git a/program/include/rcube_json_output.php b/program/include/rcube_json_output.php index 00b7697..0bd3a2b 100644 --- a/program/include/rcube_json_output.php +++ b/program/include/rcube_json_output.php @@ -5,7 +5,7 @@ | program/include/rcube_json_output.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2008-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | diff --git a/program/include/rcube_ldap.php b/program/include/rcube_ldap.php index 7143aaf..f1bbab6 100644 --- a/program/include/rcube_ldap.php +++ b/program/include/rcube_ldap.php @@ -4,7 +4,7 @@ | program/include/rcube_ldap.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2006-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2006-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -14,7 +14,7 @@ | Author: Thomas Bruederli | +-----------------------------------------------------------------------+ - $Id: rcube_ldap.php 2157 2008-12-16 15:28:07Z thomasb $ + $Id: rcube_ldap.php 2237 2009-01-17 01:55:39Z till $ */ @@ -71,7 +71,7 @@ class rcube_ldap global $RCMAIL; if (!function_exists('ldap_connect')) - raise_error(array('type' => 'ldap', 'message' => "No ldap support in this installation of PHP"), true); + raise_error(array('code' => 100, 'type' => 'ldap', 'message' => "No ldap support in this installation of PHP"), true); if (is_resource($this->conn)) return true; @@ -122,7 +122,7 @@ class rcube_ldap $this->ready = $this->bind($this->prop['bind_dn'], $this->prop['bind_pass']); } else - raise_error(array('type' => 'ldap', 'message' => "Could not connect to any LDAP server, tried $host:{$this->prop[port]} last"), true); + raise_error(array('code' => 100, 'type' => 'ldap', 'message' => "Could not connect to any LDAP server, tried $host:{$this->prop[port]} last"), true); // See if the directory is writeable. if ($this->prop['writable']) { diff --git a/program/include/rcube_mail_mime.php b/program/include/rcube_mail_mime.php index c86be49..f59354f 100644 --- a/program/include/rcube_mail_mime.php +++ b/program/include/rcube_mail_mime.php @@ -5,7 +5,7 @@ | program/include/rcube_mail_mime.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2007-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2007-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -128,7 +128,7 @@ class rcube_mail_mime extends Mail_mime { // if header contains e-mail addresses if (preg_match('/\s<.+@[a-z0-9\-\.]+\.[a-z]+>/U', $hdr_value)) { - $chunks = $this->_explode_quoted_string(',', $hdr_value); + $chunks = rcube_explode_quoted_string(',', $hdr_value); } else { $chunks = array($hdr_value); @@ -187,24 +187,6 @@ class rcube_mail_mime extends Mail_mime } - function _explode_quoted_string($delimiter, $string) - { - $result = array(); - $strlen = strlen($string); - for ($q=$p=$i=0; $i < $strlen; $i++) { - if ($string{$i} == "\"" && $string{$i-1} != "\\") { - $q = $q ? false : true; - } - else if (!$q && $string{$i} == $delimiter) { - $result[] = substr($string, $p, $i - $p); - $p = $i + 1; - } - } - - $result[] = substr($string, $p); - return $result; - } - /** * Provides caching of body of constructed MIME Message to avoid * duplicate construction of message and damage of MIME headers diff --git a/program/include/rcube_mdb2.php b/program/include/rcube_mdb2.php index b8238a3..36b5cc7 100644 --- a/program/include/rcube_mdb2.php +++ b/program/include/rcube_mdb2.php @@ -5,7 +5,7 @@ | program/include/rcube_mdb2.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -16,7 +16,7 @@ | Author: Lukas Kahwe Smith | +-----------------------------------------------------------------------+ - $Id: rcube_mdb2.php 1978 2008-10-14 12:49:44Z thomasb $ + $Id: rcube_mdb2.php 2237 2009-01-17 01:55:39Z till $ */ @@ -288,17 +288,18 @@ class rcube_mdb2 /** - * Get number of affected rows fort he last query + * Get number of affected rows for the last query * + * @param number Optional query handle identifier * @return mixed Number of rows or FALSE on failure * @access public */ - function affected_rows($result = null) + function affected_rows($res_id = null) { if (!$this->db_handle) return FALSE; - return $this->_get_result($result); + return (int) $this->_get_result($res_id); } @@ -350,7 +351,7 @@ class rcube_mdb2 /** - * Get co values for a result row + * Get col values for a result row * * @param object Query result handle * @param number Fetch mode identifier @@ -359,12 +360,8 @@ class rcube_mdb2 */ function _fetch_row($result, $mode) { - if (PEAR::isError($result)) - { - raise_error(array('code' => 500, 'type' => 'db', 'line' => __LINE__, 'file' => __FILE__, - 'message' => $this->db_link->getMessage()), TRUE, FALSE); + if ($result === FALSE || PEAR::isError($result)) return FALSE; - } return $result->fetchRow($mode); } @@ -398,13 +395,13 @@ class rcube_mdb2 * @param string Value to quote * @return string Quoted string for use in query * @deprecated Replaced by rcube_MDB2::quote_identifier - * @see rcube_MDB2::quote_identifier + * @see rcube_mdb2::quote_identifier * @access public */ function quoteIdentifier($str) - { + { return $this->quote_identifier($str); - } + } /** @@ -529,7 +526,7 @@ class rcube_mdb2 * Adds a query result and returns a handle ID * * @param object Query handle - * @return mixed Handle ID or FALE on failure + * @return mixed Handle ID * @access private */ function _add_result($res) @@ -537,26 +534,27 @@ class rcube_mdb2 // sql error occured if (PEAR::isError($res)) { + $this->db_error = TRUE; + $this->db_error_msg = $res->getMessage(); raise_error(array('code' => 500, 'type' => 'db', 'line' => __LINE__, 'file' => __FILE__, - 'message' => $res->getMessage() . " Query: " . substr(preg_replace('/[\r\n]+\s*/', ' ', $res->userinfo), 0, 512)), TRUE, FALSE); - return FALSE; - } - else - { - $res_id = sizeof($this->a_query_results); - $this->a_query_results[$res_id] = $res; - $this->last_res_id = $res_id; - return $res_id; + 'message' => $res->getMessage() . " Query: " + . substr(preg_replace('/[\r\n]+\s*/', ' ', $res->userinfo), 0, 512)), + TRUE, FALSE); } + + $res_id = sizeof($this->a_query_results); + $this->last_res_id = $res_id; + $this->a_query_results[$res_id] = $res; + return $res_id; } /** * Resolves a given handle ID and returns the according query handle - * If no ID is specified, the last ressource handle will be returned + * If no ID is specified, the last resource handle will be returned * * @param number Handle ID - * @return mixed Ressource handle or FALE on failure + * @return mixed Resource handle or FALSE on failure * @access private */ function _get_result($res_id=NULL) @@ -564,10 +562,11 @@ class rcube_mdb2 if ($res_id==NULL) $res_id = $this->last_res_id; - if ($res_id && isset($this->a_query_results[$res_id])) - return $this->a_query_results[$res_id]; - else - return FALSE; + if (isset($this->a_query_results[$res_id])) + if (!PEAR::isError($this->a_query_results[$res_id])) + return $this->a_query_results[$res_id]; + + return FALSE; } diff --git a/program/include/rcube_message.php b/program/include/rcube_message.php index 6f4963b..ec3be4b 100644 --- a/program/include/rcube_message.php +++ b/program/include/rcube_message.php @@ -5,7 +5,7 @@ | program/include/rcube_message.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2008-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -65,19 +65,19 @@ class rcube_message $this->imap = $this->app->imap; $this->uid = $uid; - $this->headers = $this->imap->get_headers($uid); + $this->headers = $this->imap->get_headers($uid, NULL, true, true); + $this->subject = rcube_imap::decode_mime_string($this->headers->subject, $this->headers->charset); list(, $this->sender) = each($this->imap->decode_address_list($this->headers->from)); $this->set_safe((intval($_GET['_safe']) || $_SESSION['safe_messages'][$uid])); - $this->opt = array( 'safe' => $this->is_safe, 'prefer_html' => $this->app->config->get('prefer_html'), 'get_url' => rcmail_url('get', array('_mbox' => $this->imap->get_mailbox_name(), '_uid' => $uid)) ); - if ($this->structure = $this->imap->get_structure($uid)) { + if ($this->structure = $this->imap->get_structure($uid, $this->headers->body_structure)) { $this->get_mime_numbers($this->structure); $this->parse_structure($this->structure); } @@ -166,17 +166,13 @@ class rcube_message */ function first_html_part() { - $html_part = null; - // check all message parts foreach ($this->mime_parts as $mime_id => $part) { $mimetype = strtolower($part->ctype_primary . '/' . $part->ctype_secondary); if ($mimetype == 'text/html') { - $html_part = $this->imap->get_message_part($this->uid, $mime_id, $part); + return $this->imap->get_message_part($this->uid, $mime_id, $part); } } - - return $html_part; } @@ -266,7 +262,7 @@ class rcube_message $html_part = $p; else if ($sub_ctype_primary=='text' && $sub_ctype_secondary=='enriched') $enriched_part = $p; - else if ($sub_ctype_primary=='multipart' && ($sub_ctype_secondary=='related' || $sub_ctype_secondary=='mixed')) + else if ($sub_ctype_primary=='multipart' && in_array($sub_ctype_secondary, array('related', 'mixed', 'alternative'))) $related_part = $p; } @@ -366,6 +362,14 @@ class rcube_message // ignore "virtual" protocol parts else if ($primary_type == 'protocol') continue; + + // part is Microsoft outlook TNEF (winmail.dat) + else if ($primary_type == 'application' && $secondary_type == 'ms-tnef') { + foreach ((array)$this->imap->tnef_decode($mail_part, $structure->headers['uid']) as $tnef_part) { + $this->mime_parts[$tnef_part->mime_id] = $tnef_part; + $this->attachments[] = $tnef_part; + } + } // part is file/attachment else if ($mail_part->disposition == 'attachment' || $mail_part->disposition == 'inline' || @@ -381,10 +385,10 @@ class rcube_message if ($mail_part->headers['content-location']) $mail_part->content_location = $mail_part->headers['content-base'] . $mail_part->headers['content-location']; - if ($mail_part->content_id || $mail_part->content_location) { + if ($mail_part->content_id || $mail_part->content_location) { $this->inline_parts[] = $mail_part; } - } + } // is regular attachment else { if (!$mail_part->filename) diff --git a/program/include/rcube_result_set.php b/program/include/rcube_result_set.php index b3afe69..036ebc3 100644 --- a/program/include/rcube_result_set.php +++ b/program/include/rcube_result_set.php @@ -5,7 +5,7 @@ | program/include/rcube_result_set.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2006-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2006-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | diff --git a/program/include/rcube_shared.inc b/program/include/rcube_shared.inc index 345f75e..370b4bc 100644 --- a/program/include/rcube_shared.inc +++ b/program/include/rcube_shared.inc @@ -15,7 +15,7 @@ | Author: Thomas Bruederli | +-----------------------------------------------------------------------+ - $Id: rcube_shared.inc 2147 2008-12-11 17:29:50Z alec $ + $Id: rcube_shared.inc 2313 2009-02-27 10:18:18Z thomasb $ */ @@ -309,7 +309,7 @@ function make_absolute_url($path, $base_url) return $path; // cut base_url to the last directory - if (strpos($base_url, '/')>7) + if (strrpos($base_url, '/')>7) { $host_url = substr($base_url, 0, strpos($base_url, '/')); $base_url = substr($base_url, 0, strrpos($base_url, '/')); @@ -535,6 +535,7 @@ function get_offset_time($offset_str, $factor=1) * A method to guess the mime_type of an attachment. * * @param string $path Path to the file. + * @param string $name File name (with suffix) * @param string $failover Mime type supplied for failover. * * @return string @@ -542,25 +543,34 @@ function get_offset_time($offset_str, $factor=1) * @see http://de2.php.net/manual/en/ref.fileinfo.php * @see http://de2.php.net/mime_content_type */ -function rc_mime_content_type($path, $failover = 'application/octet-stream') +function rc_mime_content_type($path, $name, $failover = 'application/octet-stream') { $mime_type = null; $mime_magic = rcmail::get_instance()->config->get('mime_magic'); + $mime_ext = @include(RCMAIL_CONFIG_DIR . '/mimetypes.php'); + $suffix = $name ? substr($name, strrpos($name, '.')+1) : '*'; - if (!extension_loaded('fileinfo')) { - @dl('fileinfo.' . PHP_SHLIB_SUFFIX); + // use file name suffix with hard-coded mime-type map + if (is_array($mime_ext)) { + $mime_type = $mime_ext[$suffix]; } - - if (function_exists('finfo_open')) { - if ($finfo = finfo_open(FILEINFO_MIME, $mime_magic)) { - $mime_type = finfo_file($finfo, $path); - finfo_close($finfo); + // try fileinfo extension if available + if (!$mime_type) { + if (!extension_loaded('fileinfo')) { + @dl('fileinfo.' . PHP_SHLIB_SUFFIX); + } + if (function_exists('finfo_open')) { + if ($finfo = finfo_open(FILEINFO_MIME, $mime_magic)) { + $mime_type = finfo_file($finfo, $path); + finfo_close($finfo); + } } } + // try PHP's mime_content_type if (!$mime_type && function_exists('mime_content_type')) { $mime_type = mime_content_type($path); } - + // fall back to user-submitted string if (!$mime_type) { $mime_type = $failover; } @@ -599,4 +609,30 @@ function rc_detect_encoding($string, $failover='') return $result ? $result : $failover; } + +/** + * Explode quoted string + * + * @param string Delimiter expression string for preg_match() + * @param string Input string + */ +function rcube_explode_quoted_string($delimiter, $string) +{ + $result = array(); + $strlen = strlen($string); + + for ($q=$p=$i=0; $i < $strlen; $i++) { + if ($string[$i] == "\"" && $string[$i-1] != "\\") { + $q = $q ? false : true; + } + else if (!$q && preg_match("/$delimiter/", $string[$i])) { + $result[] = substr($string, $p, $i - $p); + $p = $i + 1; + } + } + + $result[] = substr($string, $p); + return $result; +} + ?> diff --git a/program/include/rcube_smtp.inc b/program/include/rcube_smtp.inc index 309d420..f4995d8 100644 --- a/program/include/rcube_smtp.inc +++ b/program/include/rcube_smtp.inc @@ -15,7 +15,7 @@ | Author: Thomas Bruederli | +-----------------------------------------------------------------------+ - $Id: rcube_smtp.inc 2155 2008-12-16 13:00:55Z alec $ + $Id: rcube_smtp.inc 2291 2009-02-13 10:44:49Z alec $ */ @@ -327,7 +327,7 @@ function smtp_parse_rfc822($recipients) $recipients = implode(', ', $recipients); $addresses = array(); - $recipients = smtp_explode_quoted_str(",", $recipients); + $recipients = rcube_explode_quoted_string(',', $recipients); reset($recipients); while (list($k, $recipient) = each($recipients)) @@ -346,24 +346,4 @@ function smtp_parse_rfc822($recipients) return $addresses; } - -/** - * @access private - */ -function smtp_explode_quoted_str($delimiter, $string) - { - $quotes=explode("\"", $string); - while ( list($key, $val) = each($quotes)) - if (($key % 2) == 1) - $quotes[$key] = str_replace($delimiter, "_!@!_", $quotes[$key]); - $string=implode("\"", $quotes); - - $result=explode($delimiter, $string); - while (list($key, $val) = each($result)) - $result[$key] = str_replace("_!@!_", $delimiter, $result[$key]); - - return $result; - } - - ?> diff --git a/program/include/rcube_string_replacer.php b/program/include/rcube_string_replacer.php new file mode 100644 index 0000000..fe082a5 --- /dev/null +++ b/program/include/rcube_string_replacer.php @@ -0,0 +1,116 @@ + | + +-----------------------------------------------------------------------+ + + $Id: $ + +*/ + + +/** + * Helper class for string replacements based on preg_replace_callback + * + * @package Core + */ +class rcube_string_replacer +{ + public static $pattern = '/##str_replacement\[([0-9]+)\]##/'; + + private $values = array(); + + + /** + * Add a string to the internal list + * + * @param string String value + * @return int Index of value for retrieval + */ + public function add($str) + { + $i = count($this->values); + $this->values[$i] = $str; + return $i; + } + + /** + * Build replacement string + */ + public function get_replacement($i) + { + return '##str_replacement['.$i.']##'; + } + + /** + * Callback function used to build HTML links around URL strings + * + * @param array Matches result from preg_replace_callback + * @return int Index of saved string value + */ + public function link_callback($matches) + { + $i = -1; + $scheme = strtolower($matches[1]); + + if ($scheme == 'http' || $scheme == 'https' || $scheme == 'ftp') { + $url = $matches[1] . '://' . $matches[2]; + $i = $this->add(html::a(array('href' => $url, 'target' => "_blank"), Q($url))); + } + else if ($matches[2] == 'www.') { + $url = $matches[2] . $matches[3]; + $i = $this->add($matches[1] . html::a(array('href' => 'http://' . $url, 'target' => "_blank"), Q($url))); + } + + return $i >= 0 ? $this->get_replacement($i) : ''; + } + + /** + * Callback function used to build mailto: links around e-mail strings + * + * @param array Matches result from preg_replace_callback + * @return int Index of saved string value + */ + public function mailto_callback($matches) + { + $i = $this->add(html::a(array( + 'href' => 'mailto:' . $matches[1], + 'onclick' => "return ".JS_OBJECT_NAME.".command('compose','".JQ($matches[1])."',this)", + ), + Q($matches[1]))); + + return $i >= 0 ? $this->get_replacement($i) : ''; + } + + /** + * Look up the index from the preg_replace matches array + * and return the substitution value. + * + * @param array Matches result from preg_replace_callback + * @return string Value at index $matches[1] + */ + public function replace_callback($matches) + { + return $this->values[$matches[1]]; + } + + /** + * Replace substituted strings with original values + */ + public function resolve($str) + { + return preg_replace_callback(self::$pattern, array($this, 'replace_callback'), $str); + } + +} \ No newline at end of file diff --git a/program/include/rcube_template.php b/program/include/rcube_template.php index 5e45fb6..1e732ca 100755 --- a/program/include/rcube_template.php +++ b/program/include/rcube_template.php @@ -5,7 +5,7 @@ | program/include/rcube_template.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2006-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2006-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | diff --git a/program/include/rcube_user.php b/program/include/rcube_user.php index 64d2c75..b8833b3 100644 --- a/program/include/rcube_user.php +++ b/program/include/rcube_user.php @@ -5,7 +5,7 @@ | program/include/rcube_user.inc | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | diff --git a/program/include/rcube_vcard.php b/program/include/rcube_vcard.php index 3179766..ce5087a 100644 --- a/program/include/rcube_vcard.php +++ b/program/include/rcube_vcard.php @@ -5,7 +5,7 @@ | program/include/rcube_vcard.php | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2008-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -226,10 +226,14 @@ class rcube_vcard return $vcard; } + private static function rfc2425_fold_callback($matches) + { + return ":\n ".rtrim(chunk_split($matches[1], 72, "\n ")); + } private static function rfc2425_fold($val) { - return preg_replace('/:([^\n]{72,})/e', '":\n ".rtrim(chunk_split("\\1", 72, "\n "))', $val) . "\n"; + return preg_replace_callback('/:([^\n]{72,})/', array('self', 'rfc2425_fold_callback'), $val) . "\n"; } diff --git a/program/include/session.inc b/program/include/session.inc index 9efded0..b1ff1d2 100644 --- a/program/include/session.inc +++ b/program/include/session.inc @@ -5,7 +5,7 @@ | program/include/session.inc | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland | + | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -15,7 +15,7 @@ | Author: Thomas Bruederli | +-----------------------------------------------------------------------+ - $Id: session.inc 2084 2008-11-23 13:24:49Z thomasb $ + $Id: session.inc 2237 2009-01-17 01:55:39Z till $ */ diff --git a/program/js/app.js b/program/js/app.js index b5e8a4f..e4f6a2a 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -1,3310 +1,4222 @@ +/* + +-----------------------------------------------------------------------+ + | RoundCube Webmail Client Script | + | | + | This file is part of the RoundCube Webmail client | + | Copyright (C) 2005-2009, RoundCube Dev, - Switzerland | + | Licensed under the GNU GPL | + | | + +-----------------------------------------------------------------------+ + | Authors: Thomas Bruederli | + | Charles McNulty | + +-----------------------------------------------------------------------+ + | Requires: common.js, list.js | + +-----------------------------------------------------------------------+ + + $Id: app.js 2318 2009-02-27 11:06:29Z thomasb $ +*/ + + var rcube_webmail_client; -function rcube_webmail(){ -this.env=new Object(); -this.labels=new Object(); -this.buttons=new Object(); -this.gui_objects=new Object(); -this.commands=new Object(); -this.onloads=new Array(); -rcube_webmail_client=this; -this.ref="rcube_webmail_client"; -var _1=this; -this.dblclick_time=500; -this.message_time=3000; -this.identifier_expr=new RegExp("[^0-9a-z-_]","gi"); -this.mimetypes=new Array("text/plain","text/html","text/xml","image/jpeg","image/gif","image/png","application/x-javascript","application/pdf","application/x-shockwave-flash"); -this.env.keep_alive=60; -this.env.request_timeout=180; -this.env.draft_autosave=0; -this.env.comm_path="./"; -this.env.bin_path="./bin/"; -this.env.blankpage="program/blank.gif"; -this.set_env=function(p,_3){ -if(p!=null&&typeof (p)=="object"&&!_3){ -for(var n in p){ -this.env[n]=p[n]; -} -}else{ -this.env[p]=_3; -} -}; -this.add_label=function(_5,_6){ -this.labels[_5]=_6; -}; -this.register_button=function(_7,id,_9,_a,_b,_c){ -if(!this.buttons[_7]){ -this.buttons[_7]=new Array(); -} -var _d={id:id,type:_9}; -if(_a){ -_d.act=_a; -} -if(_b){ -_d.sel=_b; -} -if(_c){ -_d.over=_c; -} -this.buttons[_7][this.buttons[_7].length]=_d; -}; -this.gui_object=function(_e,id){ -this.gui_objects[_e]=id; -}; -this.add_onload=function(f){ -this.onloads[this.onloads.length]=f; -}; -this.init=function(){ -var p=this; -this.task=this.env.task; -if(!bw.dom||!bw.xmlhttp_test()){ -this.goto_url("error","_code=0x199"); -return; -} -for(var n in this.gui_objects){ -this.gui_objects[n]=rcube_find_object(this.gui_objects[n]); -} -if(this.env.framed&&parent.rcmail&&parent.rcmail.set_busy){ -parent.rcmail.set_busy(false); -} -this.enable_command("logout","mail","addressbook","settings",true); -if(this.env.permaurl){ -this.enable_command("permaurl",true); -} -switch(this.task){ -case "mail": -if(this.gui_objects.messagelist){ -this.message_list=new rcube_list_widget(this.gui_objects.messagelist,{multiselect:true,draggable:true,keyboard:true,dblclick_time:this.dblclick_time}); -this.message_list.row_init=function(o){ -p.init_message_row(o); -}; -this.message_list.addEventListener("dblclick",function(o){ -p.msglist_dbl_click(o); -}); -this.message_list.addEventListener("keypress",function(o){ -p.msglist_keypress(o); -}); -this.message_list.addEventListener("select",function(o){ -p.msglist_select(o); -}); -this.message_list.addEventListener("dragstart",function(o){ -p.drag_start(o); -}); -this.message_list.addEventListener("dragmove",function(o,e){ -p.drag_move(e); -}); -this.message_list.addEventListener("dragend",function(o){ -p.drag_active=false; -}); -this.message_list.init(); -this.enable_command("toggle_status","toggle_flag",true); -if(this.gui_objects.mailcontframe){ -this.gui_objects.mailcontframe.onmousedown=function(e){ -return p.click_on_list(e); -}; -document.onmouseup=function(e){ -return p.doc_mouse_up(e); -}; -}else{ -this.message_list.focus(); -} -} -if(this.env.coltypes){ -this.set_message_coltypes(this.env.coltypes); -} -this.enable_command("list","checkmail","compose","add-contact","search","reset-search","collapse-folder",true); -if(this.env.search_text!=null&&document.getElementById("quicksearchbox")!=null){ -document.getElementById("quicksearchbox").value=this.env.search_text; -} -if(this.env.action=="show"||this.env.action=="preview"){ -this.enable_command("show","reply","reply-all","forward","moveto","delete","mark","viewsource","print","load-attachment","load-headers",true); -if(this.env.next_uid){ -this.enable_command("nextmessage",true); -this.enable_command("lastmessage",true); -} -if(this.env.prev_uid){ -this.enable_command("previousmessage",true); -this.enable_command("firstmessage",true); -} -} -if(this.env.trash_mailbox&&this.env.mailbox!=this.env.trash_mailbox){ -this.set_alttext("delete","movemessagetotrash"); -} -if(this.env.action=="preview"&&this.env.framed&&parent.rcmail){ -this.enable_command("compose","add-contact",false); -parent.rcmail.show_contentframe(true); -} -if((this.env.action=="show"||this.env.action=="preview")&&this.env.blockedobjects){ -if(this.gui_objects.remoteobjectsmsg){ -this.gui_objects.remoteobjectsmsg.style.display="block"; -} -this.enable_command("load-images","always-load",true); -} -if(this.env.action=="compose"){ -this.enable_command("add-attachment","send-attachment","remove-attachment","send",true); -if(this.env.spellcheck){ -this.env.spellcheck.spelling_state_observer=function(s){ -_1.set_spellcheck_state(s); -}; -this.set_spellcheck_state("ready"); -if(rcube_find_object("_is_html").value=="1"){ -this.display_spellcheck_controls(false); -} -} -if(this.env.drafts_mailbox){ -this.enable_command("savedraft",true); -} -document.onmouseup=function(e){ -return p.doc_mouse_up(e); -}; -} -if(this.env.messagecount){ -this.enable_command("select-all","select-none","expunge",true); -} -if(this.purge_mailbox_test()){ -this.enable_command("purge",true); -} -this.set_page_buttons(); -if(this.env.action=="compose"){ -this.init_messageform(); -} -if(this.env.action=="print"){ -window.print(); -} -if(this.gui_objects.mailboxlist){ -this.env.unread_counts={}; -this.gui_objects.folderlist=this.gui_objects.mailboxlist; -this.http_request("getunread",""); -} -if(this.env.mdn_request&&this.env.uid){ -var _1f="_uid="+this.env.uid+"&_mbox="+urlencode(this.env.mailbox); -if(confirm(this.get_label("mdnrequest"))){ -this.http_post("sendmdn",_1f); -}else{ -this.http_post("mark",_1f+"&_flag=mdnsent"); -} -} -break; -case "addressbook": -if(this.gui_objects.contactslist){ -this.contact_list=new rcube_list_widget(this.gui_objects.contactslist,{multiselect:true,draggable:true,keyboard:true}); -this.contact_list.addEventListener("keypress",function(o){ -p.contactlist_keypress(o); -}); -this.contact_list.addEventListener("select",function(o){ -p.contactlist_select(o); -}); -this.contact_list.addEventListener("dragstart",function(o){ -p.drag_start(o); -}); -this.contact_list.addEventListener("dragmove",function(o,e){ -p.drag_move(e); -}); -this.contact_list.addEventListener("dragend",function(o){ -p.drag_active=false; -}); -this.contact_list.init(); -if(this.env.cid){ -this.contact_list.highlight_row(this.env.cid); -} -if(this.gui_objects.contactslist.parentNode){ -this.gui_objects.contactslist.parentNode.onmousedown=function(e){ -return p.click_on_list(e); -}; -document.onmouseup=function(e){ -return p.doc_mouse_up(e); -}; -}else{ -this.contact_list.focus(); -} -} -this.set_page_buttons(); -if(this.env.address_sources&&this.env.address_sources[this.env.source]&&!this.env.address_sources[this.env.source].readonly){ -this.enable_command("add",true); -} -if(this.env.cid){ -this.enable_command("show","edit",true); -} -if((this.env.action=="add"||this.env.action=="edit")&&this.gui_objects.editform){ -this.enable_command("save",true); -}else{ -this.enable_command("search","reset-search","moveto","import",true); -} -if(this.contact_list&&this.contact_list.rowcount>0){ -this.enable_command("export",true); -} -this.enable_command("list",true); -break; -case "settings": -this.enable_command("preferences","identities","save","folders",true); -if(this.env.action=="identities"||this.env.action=="edit-identity"||this.env.action=="add-identity"){ -this.enable_command("add",this.env.identities_level<2); -this.enable_command("delete","edit",true); -} -if(this.env.action=="edit-identity"||this.env.action=="add-identity"){ -this.enable_command("save",true); -} -if(this.env.action=="folders"){ -this.enable_command("subscribe","unsubscribe","create-folder","rename-folder","delete-folder",true); -} -if(this.gui_objects.identitieslist){ -this.identity_list=new rcube_list_widget(this.gui_objects.identitieslist,{multiselect:false,draggable:false,keyboard:false}); -this.identity_list.addEventListener("select",function(o){ -p.identity_select(o); -}); -this.identity_list.init(); -this.identity_list.focus(); -if(this.env.iid){ -this.identity_list.highlight_row(this.env.iid); -} -} -if(this.gui_objects.subscriptionlist){ -this.init_subscription_list(); -} -break; -case "login": -var _29=rcube_find_object("rcmloginuser"); -var _2a=rcube_find_object("rcmloginpwd"); -var _2b=rcube_find_object("rcmlogintz"); -if(_29){ -_29.onkeyup=function(e){ -return rcmail.login_user_keyup(e); -}; -} -if(_29&&_29.value==""){ -_29.focus(); -}else{ -if(_2a){ -_2a.focus(); -} -} -if(_2b){ -_2b.value=new Date().getTimezoneOffset()/-60; -} -this.enable_command("login",true); -break; -default: -break; -} -this.enable_command("logout",true); -this.loaded=true; -if(this.pending_message){ -this.display_message(this.pending_message[0],this.pending_message[1]); -} -this.start_keepalive(); -for(var i=0;i=0){ -this.set_env("flagged_col",_32+1); -} -} -if(this.env.flagged_col&&(row.flagged_icon=row.obj.cells[this.env.flagged_col].childNodes[0])&&row.flagged_icon.nodeName=="IMG"){ -var p=this; -row.flagged_icon.id="flaggedicn_"+row.uid; -row.flagged_icon._row=row.obj; -row.flagged_icon.onmousedown=function(e){ -p.command("toggle_flag",this); -}; -} -}; -this.init_messageform=function(){ -if(!this.gui_objects.messageform){ -return false; -} -var _34=rcube_find_object("_from"); -var _35=rcube_find_object("_to"); -var _36=rcube_find_object("_cc"); -var _37=rcube_find_object("_bcc"); -var _38=rcube_find_object("_replyto"); -var _39=rcube_find_object("_subject"); -var _3a=rcube_find_object("_message"); -var _3b=rcube_find_object("_draft_saveid"); -if(_35){ -this.init_address_input_events(_35); -} -if(_36){ -this.init_address_input_events(_36); -} -if(_37){ -this.init_address_input_events(_37); -} -if(_34&&_34.type=="select-one"&&(!_3b||_3b.value=="")&&rcube_find_object("_is_html").value!="1"){ -this.change_identity(_34); -} -if(_35&&_35.value==""){ -_35.focus(); -}else{ -if(_39&&_39.value==""){ -_39.focus(); -}else{ -if(_3a){ -this.set_caret2start(_3a); -} -} -} -this.compose_field_hash(true); -this.auto_save_start(); -}; -this.init_address_input_events=function(obj){ -var _3d=function(e){ -return _1.ksearch_keypress(e,this); -}; -if(obj.addEventListener){ -obj.addEventListener(bw.safari?"keydown":"keypress",_3d,false); -}else{ -obj.onkeydown=_3d; -} -obj.setAttribute("autocomplete","off"); -}; -this.command=function(_3f,_40,obj){ -if(obj&&obj.blur){ -obj.blur(); -} -if(this.busy){ -return false; -} -if(!this.commands[_3f]){ -if(this.env.framed&&parent.rcmail&&parent.rcmail.command){ -parent.rcmail.command(_3f,_40); -} -return false; -} -if(this.task=="mail"&&this.env.action=="compose"&&(_3f=="list"||_3f=="mail"||_3f=="addressbook"||_3f=="settings")){ -if(this.cmp_hash!=this.compose_field_hash()&&!confirm(this.get_label("notsentwarning"))){ -return false; -} -} -switch(_3f){ -case "login": -if(this.gui_objects.loginform){ -this.gui_objects.loginform.submit(); -} -break; -case "logout": -this.goto_url("logout","",true); -break; -case "mail": -case "addressbook": -case "settings": -this.switch_task(_3f); -break; -case "permaurl": -if(obj&&obj.href&&obj.target){ -return true; -}else{ -if(this.env.permaurl){ -parent.location.href=this.env.permaurl; -} -} -break; -case "list": -if(this.task=="mail"){ -if(this.env.search_request<0||(_40!=""&&(this.env.search_request&&_40!=this.env.mailbox))){ -this.reset_qsearch(); -} -this.list_mailbox(_40); -if(this.env.trash_mailbox){ -this.set_alttext("delete",this.env.mailbox!=this.env.trash_mailbox?"movemessagetotrash":"deletemessage"); -} -}else{ -if(this.task=="addressbook"){ -if(this.env.search_request<0||(this.env.search_request&&_40!=this.env.source)){ -this.reset_qsearch(); -} -this.list_contacts(_40); -this.enable_command("add",(this.env.address_sources&&!this.env.address_sources[_40].readonly)); -} -} -break; -case "load-headers": -this.load_headers(obj); -break; -case "sort": -var _42=_40.split("_"); -var _43=_42[0]; -var _44=_42[1]?_42[1].toUpperCase():null; -var _45; -if(_44==null){ -if(this.env.sort_col==_43){ -_44=this.env.sort_order=="ASC"?"DESC":"ASC"; -}else{ -_44=this.env.sort_order; -} -} -if(this.env.sort_col==_43&&this.env.sort_order==_44){ -break; -} -if(_45=document.getElementById("rcm"+this.env.sort_col)){ -this.set_classname(_45,"sorted"+(this.env.sort_order.toUpperCase()),false); -} -if(_45=document.getElementById("rcm"+_43)){ -this.set_classname(_45,"sorted"+_44,true); -} -this.env.sort_col=_43; -this.env.sort_order=_44; -this.list_mailbox("","",_43+"_"+_44); -break; -case "nextpage": -this.list_page("next"); -break; -case "lastpage": -this.list_page("last"); -break; -case "previouspage": -this.list_page("prev"); -break; -case "firstpage": -this.list_page("first"); -break; -case "expunge": -if(this.env.messagecount){ -this.expunge_mailbox(this.env.mailbox); -} -break; -case "purge": -case "empty-mailbox": -if(this.env.messagecount){ -this.purge_mailbox(this.env.mailbox); -} -break; -case "show": -if(this.task=="mail"){ -var uid=this.get_single_uid(); -if(uid&&(!this.env.uid||uid!=this.env.uid)){ -if(this.env.mailbox==this.env.drafts_mailbox){ -this.goto_url("compose","_draft_uid="+uid+"&_mbox="+urlencode(this.env.mailbox),true); -}else{ -this.show_message(uid); -} -} -}else{ -if(this.task=="addressbook"){ -var cid=_40?_40:this.get_single_cid(); -if(cid&&!(this.env.action=="show"&&cid==this.env.cid)){ -this.load_contact(cid,"show"); -} -} -} -break; -case "add": -if(this.task=="addressbook"){ -this.load_contact(0,"add"); -}else{ -if(this.task=="settings"){ -this.identity_list.clear_selection(); -this.load_identity(0,"add-identity"); -} -} -break; -case "edit": -var cid; -if(this.task=="addressbook"&&(cid=this.get_single_cid())){ -this.load_contact(cid,"edit"); -}else{ -if(this.task=="settings"&&_40){ -this.load_identity(_40,"edit-identity"); -} -} -break; -case "save-identity": -case "save": -if(this.gui_objects.editform){ -var _48=rcube_find_object("_pagesize"); -var _49=rcube_find_object("_name"); -var _4a=rcube_find_object("_email"); -if(_48&&isNaN(parseInt(_48.value))){ -alert(this.get_label("nopagesizewarning")); -_48.focus(); -break; -}else{ -if(_49&&_49.value==""){ -alert(this.get_label("nonamewarning")); -_49.focus(); -break; -}else{ -if(_4a&&!rcube_check_email(_4a.value)){ -alert(this.get_label("noemailwarning")); -_4a.focus(); -break; -} -} -} -this.gui_objects.editform.submit(); -} -break; -case "delete": -if(this.task=="mail"){ -this.delete_messages(); -}else{ -if(this.task=="addressbook"){ -this.delete_contacts(); -}else{ -if(this.task=="settings"){ -this.delete_identity(); -} -} -} -break; -case "move": -case "moveto": -if(this.task=="mail"){ -this.move_messages(_40); -}else{ -if(this.task=="addressbook"&&this.drag_active){ -this.copy_contact(null,_40); -} -} -break; -case "mark": -if(_40){ -this.mark_message(_40); -} -break; -case "toggle_status": -if(_40&&!_40._row){ -break; -} -var uid; -var _4b="read"; -if(_40._row.uid){ -uid=_40._row.uid; -if(this.message_list.rows[uid].deleted){ -_4b="undelete"; -}else{ -if(!this.message_list.rows[uid].unread){ -_4b="unread"; -} -} -} -this.mark_message(_4b,uid); -break; -case "toggle_flag": -if(_40&&!_40._row){ -break; -} -var uid; -var _4b="flagged"; -if(_40._row.uid){ -uid=_40._row.uid; -if(this.message_list.rows[uid].flagged){ -_4b="unflagged"; -} -} -this.mark_message(_4b,uid); -break; -case "always-load": -if(this.env.uid&&this.env.sender){ -this.add_contact(urlencode(this.env.sender)); -window.setTimeout(function(){ -_1.command("load-images"); -},300); -break; -} -case "load-images": -if(this.env.uid){ -this.show_message(this.env.uid,true,this.env.action=="preview"); -} -break; -case "load-attachment": -var _4c="_mbox="+urlencode(this.env.mailbox)+"&_uid="+this.env.uid+"&_part="+_40.part; -if(this.env.uid&&_40.mimetype&&find_in_array(_40.mimetype,this.mimetypes)>=0){ -if(_40.mimetype=="text/html"){ -_4c+="&_safe=1"; -} -this.attachment_win=window.open(this.env.comm_path+"&_action=get&"+_4c+"&_frame=1","rcubemailattachment"); -if(this.attachment_win){ -window.setTimeout(function(){ -_1.attachment_win.focus(); -},10); -break; -} -} -this.goto_url("get",_4c+"&_download=1",false); -break; -case "select-all": -this.message_list.select_all(_40); -break; -case "select-none": -this.message_list.clear_selection(); -break; -case "nextmessage": -if(this.env.next_uid){ -this.show_message(this.env.next_uid,false,this.env.action=="preview"); -} -break; -case "lastmessage": -if(this.env.last_uid){ -this.show_message(this.env.last_uid); -} -break; -case "previousmessage": -if(this.env.prev_uid){ -this.show_message(this.env.prev_uid,false,this.env.action=="preview"); -} -break; -case "firstmessage": -if(this.env.first_uid){ -this.show_message(this.env.first_uid); -} -break; -case "checkmail": -this.check_for_recent(true); -break; -case "compose": -var url=this.env.comm_path+"&_action=compose"; -if(this.task=="mail"){ -url+="&_mbox="+urlencode(this.env.mailbox); -if(this.env.mailbox==this.env.drafts_mailbox){ -var uid; -if(uid=this.get_single_uid()){ -url+="&_draft_uid="+uid; -} -}else{ -if(_40){ -url+="&_to="+urlencode(_40); -} -} -}else{ -if(this.task=="addressbook"){ -if(_40&&_40.indexOf("@")>0){ -url=this.get_task_url("mail",url); -this.redirect(url+"&_to="+urlencode(_40)); -break; -} -var _4e=new Array(); -if(_40){ -_4e[_4e.length]=_40; -}else{ -if(this.contact_list){ -var _4f=this.contact_list.get_selection(); -for(var n=0;n<_4f.length;n++){ -_4e[_4e.length]=_4f[n]; -} -} -} -if(_4e.length){ -this.http_request("mailto","_cid="+urlencode(_4e.join(","))+"&_source="+urlencode(this.env.source),true); -} -break; -} -} -url=url.replace(/&_framed=1/,""); -this.redirect(url); -break; -case "spellcheck": -if(window.tinyMCE&&tinyMCE.get("compose-body")){ -tinyMCE.execCommand("mceSpellCheck",true); -}else{ -if(this.env.spellcheck&&this.env.spellcheck.spellCheck&&this.spellcheck_ready){ -this.env.spellcheck.spellCheck(this.env.spellcheck.check_link); -this.set_spellcheck_state("checking"); -} -} -break; -case "savedraft": -self.clearTimeout(this.save_timer); -if(!this.gui_objects.messageform){ -break; -} -if(!this.env.drafts_mailbox||this.cmp_hash==this.compose_field_hash()){ -break; -} -this.set_busy(true,"savingmessage"); -var _51=this.gui_objects.messageform; -_51.target="savetarget"; -_51._draft.value="1"; -_51.submit(); -break; -case "send": -if(!this.gui_objects.messageform){ -break; -} -if(!this.check_compose_input()){ -break; -} -self.clearTimeout(this.save_timer); -this.set_busy(true,"sendingmessage"); -var _51=this.gui_objects.messageform; -_51.target="savetarget"; -_51._draft.value=""; -_51.submit(); -clearTimeout(this.request_timer); -break; -case "add-attachment": -this.show_attachment_form(true); -case "send-attachment": -self.clearTimeout(this.save_timer); -this.upload_file(_40); -break; -case "remove-attachment": -this.remove_attachment(_40); -break; -case "reply-all": -case "reply": -var uid; -if(uid=this.get_single_uid()){ -this.goto_url("compose","_reply_uid="+uid+"&_mbox="+urlencode(this.env.mailbox)+(_3f=="reply-all"?"&_all=1":""),true); -} -break; -case "forward": -var uid; -if(uid=this.get_single_uid()){ -this.goto_url("compose","_forward_uid="+uid+"&_mbox="+urlencode(this.env.mailbox),true); -} -break; -case "print": -var uid; -if(uid=this.get_single_uid()){ -_1.printwin=window.open(this.env.comm_path+"&_action=print&_uid="+uid+"&_mbox="+urlencode(this.env.mailbox)+(this.env.safemode?"&_safe=1":"")); -if(this.printwin){ -window.setTimeout(function(){ -_1.printwin.focus(); -},20); -if(this.env.action!="show"){ -this.mark_message("read",uid); -} -} -} -break; -case "viewsource": -var uid; -if(uid=this.get_single_uid()){ -_1.sourcewin=window.open(this.env.comm_path+"&_action=viewsource&_uid="+this.env.uid+"&_mbox="+urlencode(this.env.mailbox)); -if(this.sourcewin){ -window.setTimeout(function(){ -_1.sourcewin.focus(); -},20); -} -} -break; -case "add-contact": -this.add_contact(_40); -break; -case "search": -if(!_40&&this.gui_objects.qsearchbox){ -_40=this.gui_objects.qsearchbox.value; -} -if(_40){ -this.qsearch(_40); -break; -} -case "reset-search": -var s=this.env.search_request; -this.reset_qsearch(); -if(s&&this.env.mailbox){ -this.list_mailbox(this.env.mailbox); -}else{ -if(s&&this.task=="addressbook"){ -this.list_contacts(this.env.source); -} -} -break; -case "import": -if(this.env.action=="import"&&this.gui_objects.importform){ -var _53=document.getElementById("rcmimportfile"); -if(_53&&!_53.value){ -alert(this.get_label("selectimportfile")); -break; -} -this.gui_objects.importform.submit(); -this.set_busy(true,"importwait"); -this.lock_form(this.gui_objects.importform,true); -}else{ -this.goto_url("import"); -} -break; -case "export": -if(this.contact_list.rowcount>0){ -var _54=(this.env.source?"_source="+urlencode(this.env.source)+"&":""); -if(this.env.search_request){ -_54+="_search="+this.env.search_request; -} -this.goto_url("export",_54); -} -break; -case "collapse-folder": -if(_40){ -this.collapse_folder(_40); -} -break; -case "preferences": -this.goto_url(""); -break; -case "identities": -this.goto_url("identities"); -break; -case "delete-identity": -this.delete_identity(); -case "folders": -this.goto_url("folders"); -break; -case "subscribe": -this.subscribe_folder(_40); -break; -case "unsubscribe": -this.unsubscribe_folder(_40); -break; -case "create-folder": -this.create_folder(_40); -break; -case "rename-folder": -this.rename_folder(_40); -break; -case "delete-folder": -this.delete_folder(_40); -break; -} -return obj?false:true; -}; -this.enable_command=function(){ -var _55=arguments; -if(!_55.length){ -return -1; -} -var _56; -var _57=_55[_55.length-1]; -for(var n=0;n<_55.length-1;n++){ -_56=_55[n]; -this.commands[_56]=_57; -this.set_button(_56,(_57?"act":"pas")); -} -return true; -}; -this.set_busy=function(a,_5a){ -if(a&&_5a){ -var msg=this.get_label(_5a); -if(msg==_5a){ -msg="Loading..."; -} -this.display_message(msg,"loading",true); -}else{ -if(!a){ -this.hide_message(); -} -} -this.busy=a; -if(this.gui_objects.editform){ -this.lock_form(this.gui_objects.editform,a); -} -if(this.request_timer){ -clearTimeout(this.request_timer); -} -if(a&&this.env.request_timeout){ -this.request_timer=window.setTimeout(function(){ -_1.request_timed_out(); -},this.env.request_timeout*1000); -} -}; -this.get_label=function(_5c){ -if(this.labels[_5c]){ -return this.labels[_5c]; -}else{ -return _5c; -} -}; -this.switch_task=function(_5d){ -if(this.task===_5d&&_5d!="mail"){ -return; -} -var url=this.get_task_url(_5d); -if(_5d=="mail"){ -url+="&_mbox=INBOX"; -} -this.redirect(url); -}; -this.get_task_url=function(_5f,url){ -if(!url){ -url=this.env.comm_path; -} -return url.replace(/_task=[a-z]+/,"_task="+_5f); -}; -this.request_timed_out=function(){ -this.set_busy(false); -this.display_message("Request timed out!","error"); -}; -this.doc_mouse_up=function(e){ -var _62,li; -if(this.message_list){ -this.message_list.blur(); -_62=this.env.mailboxes; -}else{ -if(this.contact_list){ -this.contact_list.blur(); -_62=this.env.address_sources; -}else{ -if(this.ksearch_value){ -this.ksearch_blur(); -} -} -} -if(this.drag_active&&_62&&this.env.last_folder_target){ -this.set_classname(this.get_folder_li(this.env.last_folder_target),"droptarget",false); -this.command("moveto",_62[this.env.last_folder_target].id); -this.env.last_folder_target=null; -} -}; -this.drag_start=function(_64){ -var _65=this.task=="mail"?this.env.mailboxes:this.env.address_sources; -this.drag_active=true; -if(this.preview_timer){ -clearTimeout(this.preview_timer); -} -if(this.gui_objects.folderlist&&_65){ -var li,pos,_64,_68; -_64=rcube_find_object(this.task=="mail"?"mailboxlist":"directorylist"); -pos=rcube_get_object_pos(_64); -this.env.folderlist_coords={x1:pos.x,y1:pos.y,x2:pos.x+_64.offsetWidth,y2:pos.y+_64.offsetHeight}; -this.env.folder_coords=new Array(); -for(var k in _65){ -if(li=this.get_folder_li(k)){ -pos=rcube_get_object_pos(li.firstChild); -if(_68=li.firstChild.offsetHeight){ -this.env.folder_coords[k]={x1:pos.x,y1:pos.y,x2:pos.x+li.firstChild.offsetWidth,y2:pos.y+_68}; -} -} -} -} -}; -this.drag_move=function(e){ -if(this.gui_objects.folderlist&&this.env.folder_coords){ -var li,pos,_6d; -_6d=rcube_event.get_mouse_pos(e); -pos=this.env.folderlist_coords; -if(_6d.x=pos.x2||_6d.y=pos.y2){ -if(this.env.last_folder_target){ -this.set_classname(this.get_folder_li(this.env.last_folder_target),"droptarget",false); -this.env.last_folder_target=null; -} -return; -} -for(var k in this.env.folder_coords){ -pos=this.env.folder_coords[k]; -if(this.check_droptarget(k)&&((_6d.x>=pos.x1)&&(_6d.x=pos.y1)&&(_6d.y0)&&li.nextSibling.getElementsByTagName("ul")[0].style&&(li.nextSibling.getElementsByTagName("ul")[0].style.display!="none")){ -li.nextSibling.getElementsByTagName("ul")[0].style.display="none"; -li.nextSibling.getElementsByTagName("ul")[0].style.display=""; -} -this.http_post("save-pref","_name=collapsed_folders&_value="+urlencode(this.env.collapsed_folders)); -this.set_unread_count_display(id,false); -} -}; -this.click_on_list=function(e){ -if(this.message_list){ -this.message_list.focus(); -}else{ -if(this.contact_list){ -this.contact_list.focus(); -} -} -var _74; -if(_74=this.get_folder_li()){ -this.set_classname(_74,"unfocused",true); -} -return rcube_event.get_button(e)==2?true:rcube_event.cancel(e); -}; -this.msglist_select=function(_75){ -if(this.preview_timer){ -clearTimeout(this.preview_timer); -} -var _76=_75.selection.length==1; -if(this.env.mailbox==this.env.drafts_mailbox){ -this.enable_command("reply","reply-all","forward",false); -this.enable_command("show",_76); -this.enable_command("delete","moveto","mark",(_75.selection.length>0?true:false)); -}else{ -this.enable_command("show","reply","reply-all","forward","print",_76); -this.enable_command("delete","moveto","mark",(_75.selection.length>0?true:false)); -} -if(_76&&this.env.contentframe&&!_75.multi_selecting){ -this.preview_timer=window.setTimeout(function(){ -_1.msglist_get_preview(); -},200); -}else{ -if(this.env.contentframe){ -this.show_contentframe(false); -} -} -}; -this.msglist_dbl_click=function(_77){ -if(this.preview_timer){ -clearTimeout(this.preview_timer); -} -var uid=_77.get_single_selection(); -if(uid&&this.env.mailbox==this.env.drafts_mailbox){ -this.goto_url("compose","_draft_uid="+uid+"&_mbox="+urlencode(this.env.mailbox),true); -}else{ -if(uid){ -this.show_message(uid,false,false); -} -} -}; -this.msglist_keypress=function(_79){ -if(_79.key_pressed==_79.ENTER_KEY){ -this.command("show"); -}else{ -if(_79.key_pressed==_79.DELETE_KEY){ -this.command("delete"); -}else{ -if(_79.key_pressed==_79.BACKSPACE_KEY){ -this.command("delete"); -}else{ -_79.shiftkey=false; -} -} -} -}; -this.msglist_get_preview=function(){ -var uid=this.get_single_uid(); -if(uid&&this.env.contentframe&&!this.drag_active){ -this.show_message(uid,false,true); -}else{ -if(this.env.contentframe){ -this.show_contentframe(false); -} -} -}; -this.check_droptarget=function(id){ -if(this.task=="mail"){ -return (this.env.mailboxes[id]&&this.env.mailboxes[id].id!=this.env.mailbox&&!this.env.mailboxes[id].virtual); -}else{ -if(this.task=="addressbook"){ -return (id!=this.env.source&&this.env.address_sources[id]&&!this.env.address_sources[id].readonly); -}else{ -if(this.task=="settings"){ -return (id!=this.env.folder); -} -} -} -}; -this.show_message=function(id,_7d,_7e){ -if(!id){ -return; -} -var _7f=""; -var _80=_7e?"preview":"show"; -var _81=window; -if(_7e&&this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){ -_81=window.frames[this.env.contentframe]; -_7f="&_framed=1"; -} -if(_7d){ -_7f="&_safe=1"; -} -if(this.env.search_request){ -_7f+="&_search="+this.env.search_request; -} -var url="&_action="+_80+"&_uid="+id+"&_mbox="+urlencode(this.env.mailbox)+_7f; -if(_80=="preview"&&String(_81.location.href).indexOf(url)>=0){ -this.show_contentframe(true); -}else{ -this.set_busy(true,"loading"); -_81.location.href=this.env.comm_path+url; -if(_80=="preview"&&this.message_list&&this.message_list.rows[id]&&this.message_list.rows[id].unread){ -this.set_message(id,"unread",false); -if(this.env.unread_counts[this.env.mailbox]){ -this.env.unread_counts[this.env.mailbox]-=1; -this.set_unread_count(this.env.mailbox,this.env.unread_counts[this.env.mailbox],this.env.mailbox=="INBOX"); -} -} -} -}; -this.show_contentframe=function(_83){ -var frm; -if(this.env.contentframe&&(frm=rcube_find_object(this.env.contentframe))){ -if(!_83&&window.frames[this.env.contentframe]){ -if(window.frames[this.env.contentframe].location.href.indexOf(this.env.blankpage)<0){ -window.frames[this.env.contentframe].location.href=this.env.blankpage; -} -}else{ -if(!bw.safari){ -frm.style.display=_83?"block":"none"; -} -} -} -if(!_83&&this.busy){ -this.set_busy(false); -} -}; -this.list_page=function(_85){ -if(_85=="next"){ -_85=this.env.current_page+1; -} -if(_85=="last"){ -_85=this.env.pagecount; -} -if(_85=="prev"&&this.env.current_page>1){ -_85=this.env.current_page-1; -} -if(_85=="first"&&this.env.current_page>1){ -_85=1; -} -if(_85>0&&_85<=this.env.pagecount){ -this.env.current_page=_85; -if(this.task=="mail"){ -this.list_mailbox(this.env.mailbox,_85); -}else{ -if(this.task=="addressbook"){ -this.list_contacts(this.env.source,_85); -} -} -} -}; -this.filter_mailbox=function(_86){ -var _87; -if(this.gui_objects.qsearchbox){ -_87=this.gui_objects.qsearchbox.value; -} -this.message_list.clear(); -this.env.current_page=1; -this.set_busy(true,"searching"); -this.http_request("search","_filter="+_86+(_87?"&_q="+urlencode(_87):"")+(this.env.mailbox?"&_mbox="+urlencode(this.env.mailbox):""),true); -}; -this.list_mailbox=function(_88,_89,_8a){ -this.last_selected=0; -var _8b=""; -var _8c=window; -if(!_88){ -_88=this.env.mailbox; -} -if(_8a){ -_8b+="&_sort="+_8a; -} -if(this.env.search_request){ -_8b+="&_search="+this.env.search_request; -} -if(!_89&&_88!=this.env.mailbox){ -_89=1; -this.env.current_page=_89; -if(this.message_list){ -this.message_list.clear_selection(); -} -this.show_contentframe(false); -} -if(_88!=this.env.mailbox||(_88==this.env.mailbox&&!_89&&!_8a)){ -_8b+="&_refresh=1"; -} -this.select_folder(_88,this.env.mailbox); -this.env.mailbox=_88; -if(this.gui_objects.messagelist){ -this.list_mailbox_remote(_88,_89,_8b); -return; -} -if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){ -_8c=window.frames[this.env.contentframe]; -_8b+="&_framed=1"; -} -if(_88){ -this.set_busy(true,"loading"); -_8c.location.href=this.env.comm_path+"&_mbox="+urlencode(_88)+(_89?"&_page="+_89:"")+_8b; -} -}; -this.list_mailbox_remote=function(_8d,_8e,_8f){ -this.message_list.clear(); -var url="_mbox="+urlencode(_8d)+(_8e?"&_page="+_8e:""); -this.set_busy(true,"loading"); -this.http_request("list",url+_8f,true); -}; -this.expunge_mailbox=function(_91){ -var _92=false; -var _93=""; -if(_91==this.env.mailbox){ -_92=true; -this.set_busy(true,"loading"); -_93="&_reload=1"; -} -var url="_mbox="+urlencode(_91); -this.http_post("expunge",url+_93,_92); -}; -this.purge_mailbox=function(_95){ -var _96=false; -var _97=""; -if(!confirm(this.get_label("purgefolderconfirm"))){ -return false; -} -if(_95==this.env.mailbox){ -_96=true; -this.set_busy(true,"loading"); -_97="&_reload=1"; -} -var url="_mbox="+urlencode(_95); -this.http_post("purge",url+_97,_96); -return true; -}; -this.purge_mailbox_test=function(){ -return (this.env.messagecount&&(this.env.mailbox==this.env.trash_mailbox||this.env.mailbox==this.env.junk_mailbox||this.env.mailbox.match("^"+RegExp.escape(this.env.trash_mailbox)+RegExp.escape(this.env.delimiter))||this.env.mailbox.match("^"+RegExp.escape(this.env.junk_mailbox)+RegExp.escape(this.env.delimiter)))); -}; -this.set_message_icon=function(uid){ -var _9a; -var _9b=this.message_list.rows; -if(!_9b[uid]){ -return false; -} -if(_9b[uid].deleted&&this.env.deletedicon){ -_9a=this.env.deletedicon; -}else{ -if(_9b[uid].replied&&this.env.repliedicon){ -if(_9b[uid].forwarded&&this.env.forwardedrepliedicon){ -_9a=this.env.forwardedrepliedicon; -}else{ -_9a=this.env.repliedicon; -} -}else{ -if(_9b[uid].forwarded&&this.env.forwardedicon){ -_9a=this.env.forwardedicon; -}else{ -if(_9b[uid].unread&&this.env.unreadicon){ -_9a=this.env.unreadicon; -}else{ -if(this.env.messageicon){ -_9a=this.env.messageicon; -} -} -} -} -} -if(_9a&&_9b[uid].icon){ -_9b[uid].icon.src=_9a; -} -_9a=""; -if(_9b[uid].flagged&&this.env.flaggedicon){ -_9a=this.env.flaggedicon; -}else{ -if(!_9b[uid].flagged&&this.env.unflaggedicon){ -_9a=this.env.unflaggedicon; -} -} -if(_9b[uid].flagged_icon&&_9a){ -_9b[uid].flagged_icon.src=_9a; -} -}; -this.set_message_status=function(uid,_9d,_9e){ -var _9f=this.message_list.rows; -if(!_9f[uid]){ -return false; -} -if(_9d=="unread"){ -_9f[uid].unread=_9e; -}else{ -if(_9d=="deleted"){ -_9f[uid].deleted=_9e; -}else{ -if(_9d=="replied"){ -_9f[uid].replied=_9e; -}else{ -if(_9d=="forwarded"){ -_9f[uid].forwarded=_9e; -}else{ -if(_9d=="flagged"){ -_9f[uid].flagged=_9e; -} -} -} -} -} -this.env.messages[uid]=_9f[uid]; -}; -this.set_message=function(uid,_a1,_a2){ -var _a3=this.message_list.rows; -if(!_a3[uid]){ -return false; -} -if(_a1){ -this.set_message_status(uid,_a1,_a2); -} -if(_a3[uid].unread&&_a3[uid].classname.indexOf("unread")<0){ -_a3[uid].classname+=" unread"; -this.set_classname(_a3[uid].obj,"unread",true); -}else{ -if(!_a3[uid].unread&&_a3[uid].classname.indexOf("unread")>=0){ -_a3[uid].classname=_a3[uid].classname.replace(/\s*unread/,""); -this.set_classname(_a3[uid].obj,"unread",false); -} -} -if(_a3[uid].deleted&&_a3[uid].classname.indexOf("deleted")<0){ -_a3[uid].classname+=" deleted"; -this.set_classname(_a3[uid].obj,"deleted",true); -}else{ -if(!_a3[uid].deleted&&_a3[uid].classname.indexOf("deleted")>=0){ -_a3[uid].classname=_a3[uid].classname.replace(/\s*deleted/,""); -this.set_classname(_a3[uid].obj,"deleted",false); -} -} -if(_a3[uid].flagged&&_a3[uid].classname.indexOf("flagged")<0){ -_a3[uid].classname+=" flagged"; -this.set_classname(_a3[uid].obj,"flagged",true); -}else{ -if(!_a3[uid].flagged&&_a3[uid].classname.indexOf("flagged")>=0){ -_a3[uid].classname=_a3[uid].classname.replace(/\s*flagged/,""); -this.set_classname(_a3[uid].obj,"flagged",false); -} -} -this.set_message_icon(uid); -}; -this.move_messages=function(_a4){ -if(!_a4||_a4==this.env.mailbox||(!this.env.uid&&(!this.message_list||!this.message_list.get_selection().length))){ -return; -} -var _a5=false; -var _a6="&_target_mbox="+urlencode(_a4)+"&_from="+(this.env.action?this.env.action:""); -if(this.env.action=="show"){ -_a5=true; -this.set_busy(true,"movingmessage"); -}else{ -if(!this.env.flag_for_deletion){ -this.show_contentframe(false); -} -} -this.enable_command("reply","reply-all","forward","delete","mark","print",false); -this._with_selected_messages("moveto",_a5,_a6,(this.env.flag_for_deletion?false:true)); -}; -this.delete_messages=function(){ -var _a7=this.message_list?this.message_list.get_selection():new Array(); -if(!this.env.uid&&!_a7.length){ -return; -} -if(this.env.trash_mailbox&&String(this.env.mailbox).toLowerCase()!=String(this.env.trash_mailbox).toLowerCase()){ -if(this.message_list&&this.message_list.shiftkey){ -if(confirm(this.get_label("deletemessagesconfirm"))){ -this.permanently_remove_messages(); -} -}else{ -this.move_messages(this.env.trash_mailbox); -} -}else{ -if(this.env.trash_mailbox&&String(this.env.mailbox).toLowerCase()==String(this.env.trash_mailbox).toLowerCase()){ -this.permanently_remove_messages(); -}else{ -if(!this.env.trash_mailbox&&this.env.flag_for_deletion){ -this.mark_message("delete"); -if(this.env.action=="show"){ -this.command("nextmessage","",this); -}else{ -if(_a7.length==1){ -this.message_list.select_next(); -} -} -}else{ -if(!this.env.trash_mailbox){ -this.permanently_remove_messages(); -} -} -} -} -}; -this.permanently_remove_messages=function(){ -if(!this.env.uid&&(!this.message_list||!this.message_list.get_selection().length)){ -return; -} -this.show_contentframe(false); -this._with_selected_messages("delete",false,"&_from="+(this.env.action?this.env.action:""),true); -}; -this._with_selected_messages=function(_a8,_a9,_aa,_ab){ -var _ac=new Array(); -if(this.env.uid){ -_ac[0]=this.env.uid; -}else{ -var _ad=this.message_list.get_selection(); -var _ae=this.message_list.rows; -var id; -for(var n=0;n<_ad.length;n++){ -id=_ad[n]; -_ac[_ac.length]=id; -if(_ab){ -this.message_list.remove_row(id,(n==_ad.length-1)); -}else{ -this.set_message_status(id,"deleted",true); -if(this.env.read_when_deleted){ -this.set_message_status(id,"unread",false); -} -this.set_message(id); -} -} -} -if(this.env.search_request){ -_aa+="&_search="+this.env.search_request; -} -this.http_post(_a8,"_uid="+_ac.join(",")+"&_mbox="+urlencode(this.env.mailbox)+_aa,_a9); -}; -this.mark_message=function(_b1,uid){ -var _b3=new Array(); -var _b4=new Array(); -var _b5=this.message_list?this.message_list.get_selection():new Array(); -if(uid){ -_b3[0]=uid; -}else{ -if(this.env.uid){ -_b3[0]=this.env.uid; -}else{ -if(this.message_list){ -for(var n=0;n<_b5.length;n++){ -_b3[_b3.length]=_b5[n]; -} -} -} -} -if(!this.message_list){ -_b4=_b3; -}else{ -for(var id,n=0;n<_b3.length;n++){ -id=_b3[n]; -if((_b1=="read"&&this.message_list.rows[id].unread)||(_b1=="unread"&&!this.message_list.rows[id].unread)||(_b1=="delete"&&!this.message_list.rows[id].deleted)||(_b1=="undelete"&&this.message_list.rows[id].deleted)||(_b1=="flagged"&&!this.message_list.rows[id].flagged)||(_b1=="unflagged"&&this.message_list.rows[id].flagged)){ -_b4[_b4.length]=id; -} -} -} -if(!_b4.length){ -return; -} -switch(_b1){ -case "read": -case "unread": -this.toggle_read_status(_b1,_b4); -break; -case "delete": -case "undelete": -this.toggle_delete_status(_b4); -break; -case "flagged": -case "unflagged": -this.toggle_flagged_status(_b1,_b3); -break; -} -}; -this.toggle_read_status=function(_b8,_b9){ -for(var i=0;i<_b9.length;i++){ -this.set_message(_b9[i],"unread",(_b8=="unread"?true:false)); -} -this.http_post("mark","_uid="+_b9.join(",")+"&_flag="+_b8); -}; -this.toggle_flagged_status=function(_bb,_bc){ -for(var i=0;i<_bc.length;i++){ -this.set_message(_bc[i],"flagged",(_bb=="flagged"?true:false)); -} -this.http_post("mark","_uid="+_bc.join(",")+"&_flag="+_bb); -}; -this.toggle_delete_status=function(_be){ -var _bf=this.message_list?this.message_list.rows:new Array(); -if(_be.length==1){ -if(!_bf.length||(_bf[_be[0]]&&!_bf[_be[0]].deleted)){ -this.flag_as_deleted(_be); -}else{ -this.flag_as_undeleted(_be); -} -return true; -} -var _c0=true; -for(var i=0;i<_be.length;i++){ -uid=_be[i]; -if(_bf[uid]){ -if(!_bf[uid].deleted){ -_c0=false; -break; -} -} -} -if(_c0){ -this.flag_as_undeleted(_be); -}else{ -this.flag_as_deleted(_be); -} -return true; -}; -this.flag_as_undeleted=function(_c2){ -for(var i=0;i<_c2.length;i++){ -this.set_message(_c2[i],"deleted",false); -} -this.http_post("mark","_uid="+_c2.join(",")+"&_flag=undelete"); -return true; -}; -this.flag_as_deleted=function(_c4){ -var _c5=""; -var _c6=new Array(); -var _c7=this.message_list?this.message_list.rows:new Array(); -for(var i=0;i<_c4.length;i++){ -uid=_c4[i]; -if(_c7[uid]){ -this.set_message(uid,"deleted",true); -if(_c7[uid].unread){ -_c6[_c6.length]=uid; -} -} -} -if(_c6.length){ -_c5="&_ruid="+_c6.join(","); -} -this.http_post("mark","_uid="+_c4.join(",")+"&_flag=delete"+_c5); -return true; -}; -this.flag_deleted_as_read=function(_c9){ -var _ca; -var _cb=this.message_list?this.message_list.rows:new Array(); -var str=String(_c9); -var _cd=new Array(); -_cd=str.split(","); -for(var uid,i=0;i<_cd.length;i++){ -uid=_cd[i]; -if(_cb[uid]){ -this.set_message(uid,"unread",false); -} -} -}; -this.login_user_keyup=function(e){ -var key=rcube_event.get_keycode(e); -var elm; -if((key==13)&&(elm=rcube_find_object("_pass"))){ -elm.focus(); -return false; -} -}; -this.check_compose_input=function(){ -var _d3=rcube_find_object("_to"); -var _d4=rcube_find_object("_cc"); -var _d5=rcube_find_object("_bcc"); -var _d6=rcube_find_object("_from"); -var _d7=rcube_find_object("_subject"); -var _d8=rcube_find_object("_message"); -if(_d6.type=="text"&&!rcube_check_email(_d6.value,true)){ -alert(this.get_label("nosenderwarning")); -_d6.focus(); -return false; -} -var _d9=_d3.value?_d3.value:(_d4.value?_d4.value:_d5.value); -if(!rcube_check_email(_d9.replace(/^\s+/,"").replace(/[\s,;]+$/,""),true)){ -alert(this.get_label("norecipientwarning")); -_d3.focus(); -return false; -} -if(_d7&&_d7.value==""){ -var _da=prompt(this.get_label("nosubjectwarning"),this.get_label("nosubject")); -if(!_da&&_da!==""){ -_d7.focus(); -return false; -}else{ -_d7.value=_da?_da:this.get_label("nosubject"); -} -} -if((!window.tinyMCE||!tinyMCE.get("compose-body"))&&_d8.value==""&&!confirm(this.get_label("nobodywarning"))){ -_d8.focus(); -return false; -}else{ -if(window.tinyMCE&&tinyMCE.get("compose-body")&&!tinyMCE.get("compose-body").getContent()&&!confirm(this.get_label("nobodywarning"))){ -tinyMCE.get("compose-body").focus(); -return false; -} -} -this.stop_spellchecking(); -return true; -}; -this.stop_spellchecking=function(){ -if(this.env.spellcheck&&!this.spellcheck_ready){ -exec_event(this.env.spellcheck.check_link,"click"); -this.set_spellcheck_state("ready"); -} -}; -this.display_spellcheck_controls=function(vis){ -if(this.env.spellcheck){ -if(!vis){ -this.stop_spellchecking(); -} -this.env.spellcheck.check_link.style.visibility=vis?"visible":"hidden"; -this.env.spellcheck.switch_lan_pic.style.visibility=vis?"visible":"hidden"; -} -}; -this.set_spellcheck_state=function(s){ -this.spellcheck_ready=(s=="check_spelling"||s=="ready"); -this.enable_command("spellcheck",this.spellcheck_ready); -}; -this.set_draft_id=function(id){ -var f; -if(f=rcube_find_object("_draft_saveid")){ -f.value=id; -} -}; -this.auto_save_start=function(){ -if(this.env.draft_autosave){ -this.save_timer=self.setTimeout(function(){ -_1.command("savedraft"); -},this.env.draft_autosave*1000); -} -this.busy=false; -}; -this.compose_field_hash=function(_df){ -var _e0=rcube_find_object("_to"); -var _e1=rcube_find_object("_cc"); -var _e2=rcube_find_object("_bcc"); -var _e3=rcube_find_object("_subject"); -var _e4,_e5; -var str=""; -if(_e0&&_e0.value){ -str+=_e0.value+":"; -} -if(_e1&&_e1.value){ -str+=_e1.value+":"; -} -if(_e2&&_e2.value){ -str+=_e2.value+":"; -} -if(_e3&&_e3.value){ -str+=_e3.value+":"; -} -if(_e4=tinyMCE.get("compose-body")){ -str+=_e4.getContent(); -}else{ -_e5=rcube_find_object("_message"); -str+=_e5.value; -} -if(_df){ -this.cmp_hash=str; -} -return str; -}; -this.change_identity=function(obj){ -if(!obj||!obj.options){ -return false; -} -var id=obj.options[obj.selectedIndex].value; -var _e9=rcube_find_object("_message"); -var _ea=_e9?_e9.value:""; -var _eb=(rcube_find_object("_is_html").value=="1"); -var sig,p; -if(!this.env.identity){ -this.env.identity=id; -} -if(!_eb){ -if(this.env.identity&&this.env.signatures&&this.env.signatures[this.env.identity]){ -if(this.env.signatures[this.env.identity]["is_html"]){ -sig=this.env.signatures[this.env.identity]["plain_text"]; -}else{ -sig=this.env.signatures[this.env.identity]["text"]; -} -if(sig.indexOf("-- ")!=0){ -sig="-- \n"+sig; -} -p=_ea.lastIndexOf(sig); -if(p>=0){ -_ea=_ea.substring(0,p-1)+_ea.substring(p+sig.length,_ea.length); -} -} -_ea=_ea.replace(/[\r\n]+$/,""); -if(this.env.signatures&&this.env.signatures[id]){ -sig=this.env.signatures[id]["text"]; -if(this.env.signatures[id]["is_html"]){ -sig=this.env.signatures[id]["plain_text"]; -} -if(sig.indexOf("-- ")!=0){ -sig="-- \n"+sig; -} -_ea+="\n\n"+sig; -} -}else{ -var _ee=tinyMCE.get("compose-body"); -if(this.env.signatures){ -var _ef=_ee.dom.get("_rc_sig"); -var _f0=""; -var _f1=true; -if(!_ef){ -if(bw.ie){ -_ee.getBody().appendChild(_ee.getDoc().createElement("br")); -} -_ef=_ee.getDoc().createElement("div"); -_ef.setAttribute("id","_rc_sig"); -_ee.getBody().appendChild(_ef); -} -if(this.env.signatures[id]){ -_f0=this.env.signatures[id]["text"]; -_f1=this.env.signatures[id]["is_html"]; -} -if(_f1){ -_ef.innerHTML=_f0; -}else{ -_ef.innerHTML="
"+_f0+"
"; -} -} -} -if(_e9){ -_e9.value=_ea; -} -this.env.identity=id; -return true; -}; -this.show_attachment_form=function(a){ -if(!this.gui_objects.uploadbox){ -return false; -} -var elm,_f4; -if(elm=this.gui_objects.uploadbox){ -if(a&&(_f4=this.gui_objects.attachmentlist)){ -var pos=rcube_get_object_pos(_f4); -var _f6=pos.x; -var top=pos.y+_f4.offsetHeight+10; -elm.style.top=top+"px"; -elm.style.left=_f6+"px"; -} -elm.style.visibility=a?"visible":"hidden"; -} -try{ -if(!a&&this.gui_objects.attachmentform!=this.gui_objects.messageform){ -this.gui_objects.attachmentform.reset(); -} -} -catch(e){ -} -return true; -}; -this.upload_file=function(_f8){ -if(!_f8){ -return false; -} -var _f9=false; -for(var n=0;n<_f8.elements.length;n++){ -if(_f8.elements[n].type=="file"&&_f8.elements[n].value){ -_f9=true; -break; -} -} -if(_f9){ -var ts=new Date().getTime(); -var _fc="rcmupload"+ts; -if(document.all){ -var _fd=""; -document.body.insertAdjacentHTML("BeforeEnd",_fd); -}else{ -var _fe=document.createElement("IFRAME"); -_fe.name=_fc; -_fe.style.border="none"; -_fe.style.width=0; -_fe.style.height=0; -_fe.style.visibility="hidden"; -document.body.appendChild(_fe); -} -_f8.target=_fc; -_f8.action=this.env.comm_path+"&_action=upload"; -_f8.setAttribute("enctype","multipart/form-data"); -_f8.submit(); -} -this.gui_objects.attachmentform=_f8; -return true; -}; -this.add2attachment_list=function(_ff,_100){ -if(!this.gui_objects.attachmentlist){ -return false; -} -var li=document.createElement("LI"); -li.id=_ff; -li.innerHTML=_100; -this.gui_objects.attachmentlist.appendChild(li); -return true; -}; -this.remove_from_attachment_list=function(name){ -if(!this.gui_objects.attachmentlist){ -return false; -} -var list=this.gui_objects.attachmentlist.getElementsByTagName("li"); -for(i=0;i/g,">").replace(/##([^%]+)%%/g,"$1"); -li.onmouseover=function(){ -_1.ksearch_select(this); -}; -li.onmouseup=function(){ -_1.ksearch_click(this); -}; -li._rcm_id=_122[i]; -ul.appendChild(li); -} -if(this.ksearch_selected!==null){ -p=find_in_array(this.ksearch_selected,_122); -if(p>=0&&ul.childNodes){ -ul.childNodes[p].setAttribute("id","rcmksearchSelected"); -this.set_classname(ul.childNodes[p],"selected",true); -}else{ -this.ksearch_selected=null; -} -} -if(this.ksearch_selected===null){ -ul.firstChild.setAttribute("id","rcmksearchSelected"); -this.set_classname(ul.firstChild,"selected",true); -this.ksearch_selected=_122[0]; -} -var pos=rcube_get_object_pos(this.ksearch_input); -this.ksearch_pane.move(pos.x,pos.y+this.ksearch_input.offsetHeight); -this.ksearch_pane.show(1); -}else{ -this.ksearch_hide(); -} -}; -this.ksearch_click=function(node){ -this.insert_recipient(node._rcm_id); -this.ksearch_hide(); -if(_1.ksearch_input){ -this.ksearch_input.focus(); -} -}; -this.ksearch_blur=function(){ -if(this.ksearch_timer){ -clearTimeout(this.ksearch_timer); -} -this.ksearch_value=""; -this.ksearch_input=null; -this.ksearch_hide(); -}; -this.ksearch_hide=function(){ -this.ksearch_selected=null; -if(this.ksearch_pane){ -this.ksearch_pane.show(0); -} -}; -this.contactlist_keypress=function(list){ -if(list.key_pressed==list.DELETE_KEY){ -this.command("delete"); -} -}; -this.contactlist_select=function(list){ -if(this.preview_timer){ -clearTimeout(this.preview_timer); -} -var id,_12c,_1=this; -if(id=list.get_single_selection()){ -this.preview_timer=window.setTimeout(function(){ -_1.load_contact(id,"show"); -},200); -}else{ -if(this.env.contentframe){ -this.show_contentframe(false); -} -} -this.enable_command("compose",list.selection.length>0); -this.enable_command("edit",(id&&this.env.address_sources&&!this.env.address_sources[this.env.source].readonly)?true:false); -this.enable_command("delete",list.selection.length&&this.env.address_sources&&!this.env.address_sources[this.env.source].readonly); -return false; -}; -this.list_contacts=function(src,page){ -var _12f=""; -var _130=window; -if(!src){ -src=this.env.source; -} -if(page&&this.current_page==page&&src==this.env.source){ -return false; -} -if(src!=this.env.source){ -page=1; -this.env.current_page=page; -this.reset_qsearch(); -} -this.select_folder(src,this.env.source); -this.env.source=src; -if(this.gui_objects.contactslist){ -this.list_contacts_remote(src,page); -return; -} -if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){ -_130=window.frames[this.env.contentframe]; -_12f="&_framed=1"; -} -if(this.env.search_request){ -_12f+="&_search="+this.env.search_request; -} -this.set_busy(true,"loading"); -_130.location.href=this.env.comm_path+(src?"&_source="+urlencode(src):"")+(page?"&_page="+page:"")+_12f; -}; -this.list_contacts_remote=function(src,page){ -this.contact_list.clear(true); -this.show_contentframe(false); -this.enable_command("delete","compose",false); -var url=(src?"_source="+urlencode(src):"")+(page?(src?"&":"")+"_page="+page:""); -this.env.source=src; -if(this.env.search_request){ -url+="&_search="+this.env.search_request; -} -this.set_busy(true,"loading"); -this.http_request("list",url,true); -}; -this.load_contact=function(cid,_135,_136){ -var _137=""; -var _138=window; -if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){ -_137="&_framed=1"; -_138=window.frames[this.env.contentframe]; -this.show_contentframe(true); -}else{ -if(_136){ -return false; -} -} -if(_135&&(cid||_135=="add")&&!this.drag_active){ -this.set_busy(true); -_138.location.href=this.env.comm_path+"&_action="+_135+"&_source="+urlencode(this.env.source)+"&_cid="+urlencode(cid)+_137; -} -return true; -}; -this.copy_contact=function(cid,to){ -if(!cid){ -cid=this.contact_list.get_selection().join(","); -} -if(to!=this.env.source&&cid&&this.env.address_sources[to]&&!this.env.address_sources[to].readonly){ -this.http_post("copy","_cid="+urlencode(cid)+"&_source="+urlencode(this.env.source)+"&_to="+urlencode(to)); -} -}; -this.delete_contacts=function(){ -var _13b=this.contact_list.get_selection(); -if(!(_13b.length||this.env.cid)||!confirm(this.get_label("deletecontactconfirm"))){ -return; -} -var _13c=new Array(); -var qs=""; -if(this.env.cid){ -_13c[_13c.length]=this.env.cid; -}else{ -var id; -for(var n=0;n<_13b.length;n++){ -id=_13b[n]; -_13c[_13c.length]=id; -this.contact_list.remove_row(id,(n==_13b.length-1)); -} -if(_13b.length==1){ -this.show_contentframe(false); -} -} -if(this.env.search_request){ -qs+="&_search="+this.env.search_request; -} -this.http_post("delete","_cid="+urlencode(_13c.join(","))+"&_source="+urlencode(this.env.source)+"&_from="+(this.env.action?this.env.action:"")+qs); -return true; -}; -this.update_contact_row=function(cid,_141){ -var row; -if(this.contact_list.rows[cid]&&(row=this.contact_list.rows[cid].obj)){ -for(var c=0;c<_141.length;c++){ -if(row.cells[c]){ -row.cells[c].innerHTML=_141[c]; -} -} -return true; -} -return false; -}; -this.init_subscription_list=function(){ -var p=this; -this.subscription_list=new rcube_list_widget(this.gui_objects.subscriptionlist,{multiselect:false,draggable:true,keyboard:false,toggleselect:true}); -this.subscription_list.addEventListener("select",function(o){ -p.subscription_select(o); -}); -this.subscription_list.addEventListener("dragstart",function(o){ -p.drag_active=true; -}); -this.subscription_list.addEventListener("dragend",function(o){ -p.subscription_move_folder(o); -}); -this.subscription_list.row_init=function(row){ -var _149=row.obj.getElementsByTagName("A"); -if(_149[0]){ -_149[0].onclick=function(){ -p.rename_folder(row.id); -return false; -}; -} -if(_149[1]){ -_149[1].onclick=function(){ -p.delete_folder(row.id); -return false; -}; -} -row.obj.onmouseover=function(){ -p.focus_subscription(row.id); -}; -row.obj.onmouseout=function(){ -p.unfocus_subscription(row.id); -}; -}; -this.subscription_list.init(); -}; -this.identity_select=function(list){ -var id; -if(id=list.get_single_selection()){ -this.load_identity(id,"edit-identity"); -} -}; -this.load_identity=function(id,_14d){ -if(_14d=="edit-identity"&&(!id||id==this.env.iid)){ -return false; -} -var _14e=""; -var _14f=window; -if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){ -_14e="&_framed=1"; -_14f=window.frames[this.env.contentframe]; -document.getElementById(this.env.contentframe).style.visibility="inherit"; -} -if(_14d&&(id||_14d=="add-identity")){ -this.set_busy(true); -_14f.location.href=this.env.comm_path+"&_action="+_14d+"&_iid="+id+_14e; -} -return true; -}; -this.delete_identity=function(id){ -var _151=this.identity_list.get_selection(); -if(!(_151.length||this.env.iid)){ -return; -} -if(!id){ -id=this.env.iid?this.env.iid:_151[0]; -} -this.goto_url("delete-identity","_iid="+id,true); -return true; -}; -this.focus_subscription=function(id){ -var row,_154; -var reg=RegExp("["+RegExp.escape(this.env.delimiter)+"]?[^"+RegExp.escape(this.env.delimiter)+"]+$"); -if(this.drag_active&&this.env.folder&&(row=document.getElementById(id))){ -if(this.env.subscriptionrows[id]&&(_154=this.env.subscriptionrows[id][0])){ -if(this.check_droptarget(_154)&&!this.env.subscriptionrows[this.get_folder_row_id(this.env.folder)][2]&&(_154!=this.env.folder.replace(reg,""))&&(!_154.match(new RegExp("^"+RegExp.escape(this.env.folder+this.env.delimiter))))){ -this.set_env("dstfolder",_154); -this.set_classname(row,"droptarget",true); -} -}else{ -if(this.env.folder.match(new RegExp(RegExp.escape(this.env.delimiter)))){ -this.set_env("dstfolder",this.env.delimiter); -this.set_classname(this.subscription_list.frame,"droptarget",true); -} -} -} -}; -this.unfocus_subscription=function(id){ -var row; -this.set_env("dstfolder",null); -if(this.env.subscriptionrows[id]&&(row=document.getElementById(id))){ -this.set_classname(row,"droptarget",false); -}else{ -this.set_classname(this.subscription_list.frame,"droptarget",false); -} -}; -this.subscription_select=function(list){ -var id,_15a; -if((id=list.get_single_selection())&&this.env.subscriptionrows["rcmrow"+id]&&(_15a=this.env.subscriptionrows["rcmrow"+id][0])){ -this.set_env("folder",_15a); -}else{ -this.set_env("folder",null); -} -if(this.gui_objects.createfolderhint){ -this.gui_objects.createfolderhint.innerHTML=this.env.folder?this.get_label("addsubfolderhint"):""; -} -}; -this.subscription_move_folder=function(list){ -var reg=RegExp("["+RegExp.escape(this.env.delimiter)+"]?[^"+RegExp.escape(this.env.delimiter)+"]+$"); -if(this.env.folder&&this.env.dstfolder&&(this.env.dstfolder!=this.env.folder)&&(this.env.dstfolder!=this.env.folder.replace(reg,""))){ -var reg=new RegExp("[^"+RegExp.escape(this.env.delimiter)+"]*["+RegExp.escape(this.env.delimiter)+"]","g"); -var _15d=this.env.folder.replace(reg,""); -var _15e=this.env.dstfolder==this.env.delimiter?_15d:this.env.dstfolder+this.env.delimiter+_15d; -this.set_busy(true,"foldermoving"); -this.http_post("rename-folder","_folder_oldname="+urlencode(this.env.folder)+"&_folder_newname="+urlencode(_15e),true); -} -this.drag_active=false; -this.unfocus_subscription(this.get_folder_row_id(this.env.dstfolder)); -}; -this.create_folder=function(name){ -if(this.edit_folder){ -this.reset_folder_rename(); -} -var form; -if((form=this.gui_objects.editform)&&form.elements["_folder_name"]){ -name=form.elements["_folder_name"].value; -if(name.indexOf(this.env.delimiter)>=0){ -alert(this.get_label("forbiddencharacter")+" ("+this.env.delimiter+")"); -return false; -} -if(this.env.folder&&name!=""){ -name=this.env.folder+this.env.delimiter+name; -} -this.set_busy(true,"foldercreating"); -this.http_post("create-folder","_name="+urlencode(name),true); -}else{ -if(form.elements["_folder_name"]){ -form.elements["_folder_name"].focus(); -} -} -}; -this.rename_folder=function(id){ -var temp,row,form; -if(temp=this.edit_folder){ -this.reset_folder_rename(); -if(temp==id){ -return; -} -} -if(id&&this.env.subscriptionrows[id]&&(row=document.getElementById(id))){ -var reg=new RegExp(".*["+RegExp.escape(this.env.delimiter)+"]"); -this.name_input=document.createElement("INPUT"); -this.name_input.value=this.env.subscriptionrows[id][0].replace(reg,""); -this.name_input.style.width="100%"; -reg=new RegExp("["+RegExp.escape(this.env.delimiter)+"]?[^"+RegExp.escape(this.env.delimiter)+"]+$"); -this.name_input.__parent=this.env.subscriptionrows[id][0].replace(reg,""); -this.name_input.onkeypress=function(e){ -rcmail.name_input_keypress(e); -}; -row.cells[0].replaceChild(this.name_input,row.cells[0].firstChild); -this.edit_folder=id; -this.name_input.select(); -if(form=this.gui_objects.editform){ -form.onsubmit=function(){ -return false; -}; -} -} -}; -this.reset_folder_rename=function(){ -var cell=this.name_input?this.name_input.parentNode:null; -if(cell&&this.edit_folder&&this.env.subscriptionrows[this.edit_folder]){ -cell.innerHTML=this.env.subscriptionrows[this.edit_folder][1]; -} -this.edit_folder=null; -}; -this.name_input_keypress=function(e){ -var key=rcube_event.get_keycode(e); -if(key==13){ -var _16a=this.name_input?this.name_input.value:null; -if(this.edit_folder&&_16a){ -if(_16a.indexOf(this.env.delimiter)>=0){ -alert(this.get_label("forbiddencharacter")+" ("+this.env.delimiter+")"); -return false; -} -if(this.name_input.__parent){ -_16a=this.name_input.__parent+this.env.delimiter+_16a; -} -this.set_busy(true,"folderrenaming"); -this.http_post("rename-folder","_folder_oldname="+urlencode(this.env.subscriptionrows[this.edit_folder][0])+"&_folder_newname="+urlencode(_16a),true); -} -}else{ -if(key==27){ -this.reset_folder_rename(); -} -} -}; -this.delete_folder=function(id){ -var _16c=this.env.subscriptionrows[id][0]; -if(this.edit_folder){ -this.reset_folder_rename(); -} -if(_16c&&confirm(this.get_label("deletefolderconfirm"))){ -this.set_busy(true,"folderdeleting"); -this.http_post("delete-folder","_mboxes="+urlencode(_16c),true); -this.set_env("folder",null); -if(this.gui_objects.createfolderhint){ -this.gui_objects.createfolderhint.innerHTML=""; -} -} -}; -this.add_folder_row=function(name,_16e,_16f,_170){ -if(!this.gui_objects.subscriptionlist){ -return false; -} -for(var _171 in this.env.subscriptionrows){ -if(this.env.subscriptionrows[_171]!=null&&!this.env.subscriptionrows[_171][2]){ -break; -} -} -var _172,form; -var _174=this.gui_objects.subscriptionlist.tBodies[0]; -var id="rcmrow"+(_174.childNodes.length+1); -var _176=this.subscription_list.get_single_selection(); -if(_16f&&_16f.id){ -id=_16f.id; -_171=_16f.id; -} -if(!id||!(_172=document.getElementById(_171))){ -this.goto_url("folders"); -}else{ -var row=this.clone_table_row(_172); -row.id=id; -if(_170&&(_170=this.get_folder_row_id(_170))){ -_174.insertBefore(row,document.getElementById(_170)); -}else{ -_174.appendChild(row); -} -if(_16f){ -_174.removeChild(_16f); -} -} -this.env.subscriptionrows[row.id]=[name,_16e,0]; -row.cells[0].innerHTML=_16e; -if(!_16f){ -row.cells[1].innerHTML="*"; -} -if(!_16f&&row.cells[2]&&row.cells[2].firstChild.tagName=="INPUT"){ -row.cells[2].firstChild.value=name; -row.cells[2].firstChild.checked=true; -} -if(!_16f&&(form=this.gui_objects.editform)){ -if(form.elements["_folder_oldname"]){ -form.elements["_folder_oldname"].options[form.elements["_folder_oldname"].options.length]=new Option(name,name); -} -if(form.elements["_folder_name"]){ -form.elements["_folder_name"].value=""; -} -} -this.init_subscription_list(); -if(_176&&document.getElementById("rcmrow"+_176)){ -this.subscription_list.select_row(_176); -} -if(document.getElementById(id).scrollIntoView){ -document.getElementById(id).scrollIntoView(); -} -}; -this.replace_folder_row=function(_178,_179,_17a,_17b){ -var id=this.get_folder_row_id(_178); -var row=document.getElementById(id); -this.add_folder_row(_179,_17a,row,_17b); -var form,elm; -if((form=this.gui_objects.editform)&&(elm=form.elements["_folder_oldname"])){ -for(var i=0;ithis.env.current_page)); -this.enable_command("lastpage",(this.env.pagecount>this.env.current_page)); -this.enable_command("previouspage",(this.env.current_page>1)); -this.enable_command("firstpage",(this.env.current_page>1)); -}; -this.set_button=function(_18f,_190){ -var _191=this.buttons[_18f]; -var _192,obj; -if(!_191||!_191.length){ -return false; -} -for(var n=0;n<_191.length;n++){ -_192=_191[n]; -obj=document.getElementById(_192.id); -if(obj&&_192.type=="image"&&!_192.status){ -_192.pas=obj._original_src?obj._original_src:obj.src; -if(obj.runtimeStyle&&obj.runtimeStyle.filter&&obj.runtimeStyle.filter.match(/src=['"]([^'"]+)['"]/)){ -_192.pas=RegExp.$1; -} -}else{ -if(obj&&!_192.status){ -_192.pas=String(obj.className); -} -} -if(obj&&_192.type=="image"&&_192[_190]){ -_192.status=_190; -obj.src=_192[_190]; -}else{ -if(obj&&typeof (_192[_190])!="undefined"){ -_192.status=_190; -obj.className=_192[_190]; -} -} -if(obj&&_192.type=="input"){ -_192.status=_190; -obj.disabled=!_190; -} -} -}; -this.set_alttext=function(_195,_196){ -if(!this.buttons[_195]||!this.buttons[_195].length){ -return; -} -var _197,obj,link; -for(var n=0;n"+cont+""; -} -var _1b6=this; -this.gui_objects.message.innerHTML=cont; -this.gui_objects.message.style.display="block"; -if(type!="loading"){ -this.gui_objects.message.onmousedown=function(){ -_1b6.hide_message(); -return true; -}; -} -if(!hold){ -this.message_timer=window.setTimeout(function(){ -_1.hide_message(); -},this.message_time); -} -}; -this.hide_message=function(){ -if(this.gui_objects.message){ -this.gui_objects.message.style.display="none"; -this.gui_objects.message.onmousedown=null; -} -}; -this.select_folder=function(name,old){ -if(this.gui_objects.folderlist){ -var _1b9,_1ba; -if((_1b9=this.get_folder_li(old))){ -this.set_classname(_1b9,"selected",false); -this.set_classname(_1b9,"unfocused",false); -} -if((_1ba=this.get_folder_li(name))){ -this.set_classname(_1ba,"unfocused",false); -this.set_classname(_1ba,"selected",true); -} -} -}; -this.get_folder_li=function(name){ -if(this.gui_objects.folderlist){ -name=String(name).replace(this.identifier_expr,""); -return document.getElementById("rcmli"+name); -} -return null; -}; -this.set_message_coltypes=function(_1bc){ -this.coltypes=_1bc; -var cell,col; -var _1bf=this.gui_objects.messagelist?this.gui_objects.messagelist.tHead:null; -for(var n=0;_1bf&&n":""; -row.appendChild(col); -for(var n=0;n"; -}else{ -if(!_1c3.flagged&&this.env.unflaggedicon){ -col.innerHTML="\"\""; -} -} -}else{ -if(c=="attachment"){ -col.innerHTML=_1c4&&this.env.attachmenticon?"\"\"":" "; -}else{ -col.innerHTML=cols[c]; -} -} -row.appendChild(col); -} -this.message_list.insert_row(row,_1c5); -if(_1c5&&this.env.pagesize&&this.message_list.rowcount>this.env.pagesize){ -var uid=this.message_list.get_last_row(); -this.message_list.remove_row(uid); -this.message_list.clear_selection(uid); -} -}; -this.set_rowcount=function(text){ -if(this.gui_objects.countdisplay){ -this.gui_objects.countdisplay.innerHTML=text; -} -this.set_page_buttons(); -}; -this.set_mailboxname=function(_1cf){ -if(this.gui_objects.mailboxname&&_1cf){ -this.gui_objects.mailboxname.innerHTML=_1cf; -} -}; -this.set_quota=function(_1d0){ -if(this.gui_objects.quotadisplay&&_1d0){ -this.gui_objects.quotadisplay.innerHTML=_1d0; -} -}; -this.set_unread_count=function(mbox,_1d2,_1d3){ -if(!this.gui_objects.mailboxlist){ -return false; -} -this.env.unread_counts[mbox]=_1d2; -this.set_unread_count_display(mbox,_1d3); -}; -this.set_unread_count_display=function(mbox,_1d5){ -var reg,_1d7,item,_1d9,_1da,div; -if(item=this.get_folder_li(mbox)){ -_1d9=this.env.unread_counts[mbox]?this.env.unread_counts[mbox]:0; -_1d7=item.getElementsByTagName("a")[0]; -reg=/\s+\([0-9]+\)$/i; -_1da=0; -if((div=item.getElementsByTagName("div")[0])&&div.className.match(/collapsed/)){ -for(var k in this.env.unread_counts){ -if(k.indexOf(mbox+this.env.delimiter)==0){ -_1da+=this.env.unread_counts[k]; -} -} -} -if(_1d9&&_1d7.innerHTML.match(reg)){ -_1d7.innerHTML=_1d7.innerHTML.replace(reg," ("+_1d9+")"); -}else{ -if(_1d9){ -_1d7.innerHTML+=" ("+_1d9+")"; -}else{ -_1d7.innerHTML=_1d7.innerHTML.replace(reg,""); -} -} -reg=new RegExp(RegExp.escape(this.env.delimiter)+"[^"+RegExp.escape(this.env.delimiter)+"]+$"); -if(mbox.match(reg)){ -this.set_unread_count_display(mbox.replace(reg,""),false); -} -this.set_classname(item,"unread",(_1d9+_1da)>0?true:false); -} -reg=/^\([0-9]+\)\s+/i; -if(_1d5&&document.title){ -var _1dd=String(document.title); -var _1de=""; -if(_1d9&&_1dd.match(reg)){ -_1de=_1dd.replace(reg,"("+_1d9+") "); -}else{ -if(_1d9){ -_1de="("+_1d9+") "+_1dd; -}else{ -_1de=_1dd.replace(reg,""); -} -} -this.set_pagetitle(_1de); -} -}; -this.new_message_focus=function(){ -if(this.env.framed&&window.parent){ -window.parent.focus(); -}else{ -window.focus(); -} -}; -this.add_contact_row=function(cid,cols,_1e1){ -if(!this.gui_objects.contactslist||!this.gui_objects.contactslist.tBodies[0]){ -return false; -} -var _1e2=this.gui_objects.contactslist.tBodies[0]; -var _1e3=_1e2.rows.length; -var even=_1e3%2; -var row=document.createElement("TR"); -row.id="rcmrow"+cid; -row.className="contact "+(even?"even":"odd"); -if(this.contact_list.in_selection(cid)){ -row.className+=" selected"; -} -for(var c in cols){ -col=document.createElement("TD"); -col.className=String(c).toLowerCase(); -col.innerHTML=cols[c]; -row.appendChild(col); -} -this.contact_list.insert_row(row); -this.enable_command("export",(this.contact_list.rowcount>0)); -}; -this.toggle_prefer_html=function(_1e7){ -var _1e8; -if(_1e8=document.getElementById("rcmfd_addrbook_show_images")){ -_1e8.disabled=!_1e7.checked; -} -}; -this.set_headers=function(_1e9){ -if(this.gui_objects.all_headers_row&&this.gui_objects.all_headers_box&&_1e9){ -var box=this.gui_objects.all_headers_box; -box.innerHTML=_1e9; -box.style.display="block"; -if(this.env.framed&&parent.rcmail){ -parent.rcmail.set_busy(false); -}else{ -this.set_busy(false); -} -} -}; -this.load_headers=function(elem){ -if(!this.gui_objects.all_headers_row||!this.gui_objects.all_headers_box||!this.env.uid){ -return; -} -this.set_classname(elem,"show-headers",false); -this.set_classname(elem,"hide-headers",true); -this.gui_objects.all_headers_row.style.display=bw.ie?"block":"table-row"; -elem.onclick=function(){ -rcmail.hide_headers(elem); -}; -if(!this.gui_objects.all_headers_box.innerHTML){ -this.display_message(this.get_label("loading"),"loading",true); -this.http_post("headers","_uid="+this.env.uid); -} -}; -this.hide_headers=function(elem){ -if(!this.gui_objects.all_headers_row||!this.gui_objects.all_headers_box){ -return; -} -this.set_classname(elem,"hide-headers",false); -this.set_classname(elem,"show-headers",true); -this.gui_objects.all_headers_row.style.display="none"; -elem.onclick=function(){ -rcmail.load_headers(elem); -}; -}; -this.html2plain=function(_1ed,id){ -var _1ef=new rcube_http_request(); -var url=this.env.bin_path+"html2text.php"; -var _1f1=this; -this.set_busy(true,"converting"); -_1ef.onerror=function(o){ -_1f1.http_error(o); -}; -_1ef.oncomplete=function(o){ -_1f1.set_text_value(o,id); -}; -_1ef.POST(url,_1ed,"application/octet-stream"); -}; -this.set_text_value=function(_1f4,id){ -this.set_busy(false); -document.getElementById(id).value=_1f4.get_text(); -}; -this.redirect=function(url,lock){ -if(lock||lock===null){ -this.set_busy(true); -} -if(this.env.framed&&window.parent){ -parent.location.href=url; -}else{ -location.href=url; -} -}; -this.goto_url=function(_1f8,_1f9,lock){ -var _1fb=_1f9?"&"+_1f9:""; -this.redirect(this.env.comm_path+"&_action="+_1f8+_1fb,lock); -}; -this.http_sockets=new Array(); -this.get_request_obj=function(){ -for(var n=0;n0)); -} -case "moveto": -if(this.env.action=="show"){ -this.command("list"); -}else{ -if(this.message_list){ -this.message_list.init(); -} -} -break; -case "purge": -case "expunge": -if(!this.env.messagecount&&this.task=="mail"){ -if(this.env.contentframe){ -this.show_contentframe(false); -} -this.enable_command("show","reply","reply-all","forward","moveto","delete","mark","viewsource","print","load-attachment","purge","expunge","select-all","select-none","sort",false); -} -break; -case "check-recent": -case "getunread": -case "list": -if(this.task=="mail"){ -if(this.message_list&&_20c.__action=="list"){ -this.msglist_select(this.message_list); -} -this.enable_command("show","expunge","select-all","select-none","sort",(this.env.messagecount>0)); -this.enable_command("purge",this.purge_mailbox_test()); -}else{ -if(this.task=="addressbook"){ -this.enable_command("export",(this.contact_list&&this.contact_list.rowcount>0)); -} -} -break; -} -_20c.reset(); -}; -this.http_error=function(_210){ -if(_210.__lock){ -this.set_busy(false); -} -_210.reset(); -_210.__lock=false; -this.display_message("Unknown Server Error!","error"); -}; -this.send_keep_alive=function(){ -var d=new Date(); -this.http_request("keep-alive","_t="+d.getTime()); -}; -this.check_for_recent=function(_212){ -if(this.busy){ -return; -} -if(_212){ -this.set_busy(true,"checkingmail"); -} -this.http_request("check-recent",(this.env.search_request?"_search="+this.env.search_request+"&":"")+"_t="+(new Date().getTime()),true); -}; -this.get_single_uid=function(){ -return this.env.uid?this.env.uid:(this.message_list?this.message_list.get_single_selection():null); -}; -this.get_single_cid=function(){ -return this.env.cid?this.env.cid:(this.contact_list?this.contact_list.get_single_selection():null); -}; -this.get_caret_pos=function(obj){ -if(typeof (obj.selectionEnd)!="undefined"){ -return obj.selectionEnd; -}else{ -if(document.selection&&document.selection.createRange){ -var _214=document.selection.createRange(); -if(_214.parentElement()!=obj){ -return 0; -} -var gm=_214.duplicate(); -if(obj.tagName=="TEXTAREA"){ -gm.moveToElementText(obj); -}else{ -gm.expand("textedit"); -} -gm.setEndPoint("EndToStart",_214); -var p=gm.text.length; -return p<=obj.value.length?p:-1; -}else{ -return obj.value.length; -} -} -}; -this.set_caret2start=function(obj){ -if(obj.createTextRange){ -var _218=obj.createTextRange(); -_218.collapse(true); -_218.select(); -}else{ -if(obj.setSelectionRange){ -obj.setSelectionRange(0,0); -} -} -obj.focus(); -}; -this.lock_form=function(form,lock){ -if(!form||!form.elements){ -return; -} -var type; -for(var n=0;n 0) + this.enable_command('export', true); + + this.enable_command('list', true); + break; + + + case 'settings': + this.enable_command('preferences', 'identities', 'save', 'folders', true); + + if (this.env.action=='identities' || this.env.action=='edit-identity' || this.env.action=='add-identity') { + this.enable_command('add', this.env.identities_level < 2); + this.enable_command('delete', 'edit', true); + } + + if (this.env.action=='edit-identity' || this.env.action=='add-identity') + this.enable_command('save', true); + + if (this.env.action=='folders') + this.enable_command('subscribe', 'unsubscribe', 'create-folder', 'rename-folder', 'delete-folder', true); + + if (this.gui_objects.identitieslist) + { + this.identity_list = new rcube_list_widget(this.gui_objects.identitieslist, {multiselect:false, draggable:false, keyboard:false}); + this.identity_list.addEventListener('select', function(o){ p.identity_select(o); }); + this.identity_list.init(); + this.identity_list.focus(); + + if (this.env.iid) + this.identity_list.highlight_row(this.env.iid); + } + + if (this.gui_objects.subscriptionlist) + this.init_subscription_list(); + + break; + + case 'login': + var input_user = rcube_find_object('rcmloginuser'); + var input_pass = rcube_find_object('rcmloginpwd'); + var input_tz = rcube_find_object('rcmlogintz'); + + if (input_user) + input_user.onkeyup = function(e){ return rcmail.login_user_keyup(e); }; + if (input_user && input_user.value=='') + input_user.focus(); + else if (input_pass) + input_pass.focus(); + + // detect client timezone + if (input_tz) + input_tz.value = new Date().getTimezoneOffset() / -60; + + this.enable_command('login', true); + break; + + default: + break; + } + + // enable basic commands + this.enable_command('logout', true); + + // flag object as complete + this.loaded = true; + + // show message + if (this.pending_message) + this.display_message(this.pending_message[0], this.pending_message[1]); + + // start keep-alive interval + this.start_keepalive(); + + // execute all foreign onload scripts + for (var i=0; i= 0) + this.set_env('flagged_col', found+1); + } + + // set eventhandler to flag icon, if icon found + if (this.env.flagged_col && (row.flagged_icon = row.obj.cells[this.env.flagged_col].childNodes[0]) + && row.flagged_icon.nodeName=='IMG') + { + var p = this; + row.flagged_icon.id = 'flaggedicn_'+row.uid; + row.flagged_icon._row = row.obj; + row.flagged_icon.onmousedown = function(e) { p.command('toggle_flag', this); }; + } + }; + + // init message compose form: set focus and eventhandlers + this.init_messageform = function() + { + if (!this.gui_objects.messageform) + return false; + + //this.messageform = this.gui_objects.messageform; + var input_from = rcube_find_object('_from'); + var input_to = rcube_find_object('_to'); + var input_cc = rcube_find_object('_cc'); + var input_bcc = rcube_find_object('_bcc'); + var input_replyto = rcube_find_object('_replyto'); + var input_subject = rcube_find_object('_subject'); + var input_message = rcube_find_object('_message'); + var draftid = rcube_find_object('_draft_saveid'); + + // init live search events + if (input_to) + this.init_address_input_events(input_to); + if (input_cc) + this.init_address_input_events(input_cc); + if (input_bcc) + this.init_address_input_events(input_bcc); + + // add signature according to selected identity + if (input_from && input_from.type=='select-one' && (!draftid || draftid.value=='') + // if we have HTML editor, signature is added in callback + && rcube_find_object('_is_html').value != '1') + { + this.change_identity(input_from); + } + + if (input_to && input_to.value=='') + input_to.focus(); + else if (input_subject && input_subject.value=='') + input_subject.focus(); + else if (input_message) + this.set_caret2start(input_message); + + // get summary of all field values + this.compose_field_hash(true); + + // start the auto-save timer + this.auto_save_start(); + }; + + this.init_address_input_events = function(obj) + { + var handler = function(e){ return ref.ksearch_keypress(e,this); }; + + if (obj.addEventListener) + obj.addEventListener(bw.safari ? 'keydown' : 'keypress', handler, false); + else + obj.onkeydown = handler; + + obj.setAttribute('autocomplete', 'off'); + }; + + + /*********************************************************/ + /********* client command interface *********/ + /*********************************************************/ + + // execute a specific command on the web client + this.command = function(command, props, obj) + { + if (obj && obj.blur) + obj.blur(); + + if (this.busy) + return false; + + // command not supported or allowed + if (!this.commands[command]) + { + // pass command to parent window + if (this.env.framed && parent.rcmail && parent.rcmail.command) + parent.rcmail.command(command, props); + + return false; + } + + // check input before leaving compose step + if (this.task=='mail' && this.env.action=='compose' && (command=='list' || command=='mail' || command=='addressbook' || command=='settings')) + { + if (this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning'))) + return false; + } + + // process command + switch (command) + { + case 'login': + if (this.gui_objects.loginform) + this.gui_objects.loginform.submit(); + break; + + case 'logout': + this.goto_url('logout', '', true); + break; + + // commands to switch task + case 'mail': + case 'addressbook': + case 'settings': + this.switch_task(command); + break; + + case 'permaurl': + if (obj && obj.href && obj.target) + return true; + else if (this.env.permaurl) + parent.location.href = this.env.permaurl; + break; + + // misc list commands + case 'list': + if (this.task=='mail') + { + if (this.env.search_request<0 || (props != '' && (this.env.search_request && props != this.env.mailbox))) + this.reset_qsearch(); + + this.list_mailbox(props); + + if (this.env.trash_mailbox) + this.set_alttext('delete', this.env.mailbox != this.env.trash_mailbox ? 'movemessagetotrash' : 'deletemessage'); + } + else if (this.task=='addressbook') + { + if (this.env.search_request<0 || (this.env.search_request && props != this.env.source)) + this.reset_qsearch(); + + this.list_contacts(props); + this.enable_command('add', (this.env.address_sources && !this.env.address_sources[props].readonly)); + } + break; + + + case 'load-headers': + this.load_headers(obj); + break; + + + case 'sort': + // get the type of sorting + var a_sort = props.split('_'); + var sort_col = a_sort[0]; + var sort_order = a_sort[1] ? a_sort[1].toUpperCase() : null; + var header; + + // no sort order specified: toggle + if (sort_order==null) + { + if (this.env.sort_col==sort_col) + sort_order = this.env.sort_order=='ASC' ? 'DESC' : 'ASC'; + else + sort_order = this.env.sort_order; + } + + if (this.env.sort_col==sort_col && this.env.sort_order==sort_order) + break; + + // set table header class + if (header = document.getElementById('rcm'+this.env.sort_col)) + this.set_classname(header, 'sorted'+(this.env.sort_order.toUpperCase()), false); + if (header = document.getElementById('rcm'+sort_col)) + this.set_classname(header, 'sorted'+sort_order, true); + + // save new sort properties + this.env.sort_col = sort_col; + this.env.sort_order = sort_order; + + // reload message list + this.list_mailbox('', '', sort_col+'_'+sort_order); + break; + + case 'nextpage': + this.list_page('next'); + break; + + case 'lastpage': + this.list_page('last'); + break; + + case 'previouspage': + this.list_page('prev'); + break; + + case 'firstpage': + this.list_page('first'); + break; + + case 'expunge': + if (this.env.messagecount) + this.expunge_mailbox(this.env.mailbox); + break; + + case 'purge': + case 'empty-mailbox': + if (this.env.messagecount) + this.purge_mailbox(this.env.mailbox); + break; + + + // common commands used in multiple tasks + case 'show': + if (this.task=='mail') + { + var uid = this.get_single_uid(); + if (uid && (!this.env.uid || uid != this.env.uid)) + { + if (this.env.mailbox == this.env.drafts_mailbox) + this.goto_url('compose', '_draft_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true); + else + this.show_message(uid); + } + } + else if (this.task=='addressbook') + { + var cid = props ? props : this.get_single_cid(); + if (cid && !(this.env.action=='show' && cid==this.env.cid)) + this.load_contact(cid, 'show'); + } + break; + + case 'add': + if (this.task=='addressbook') + this.load_contact(0, 'add'); + else if (this.task=='settings') + { + this.identity_list.clear_selection(); + this.load_identity(0, 'add-identity'); + } + break; + + case 'edit': + var cid; + if (this.task=='addressbook' && (cid = this.get_single_cid())) + this.load_contact(cid, 'edit'); + else if (this.task=='settings' && props) + this.load_identity(props, 'edit-identity'); + break; + + case 'save-identity': + case 'save': + if (this.gui_objects.editform) + { + var input_pagesize = rcube_find_object('_pagesize'); + var input_name = rcube_find_object('_name'); + var input_email = rcube_find_object('_email'); + + // user prefs + if (input_pagesize && isNaN(parseInt(input_pagesize.value))) + { + alert(this.get_label('nopagesizewarning')); + input_pagesize.focus(); + break; + } + // contacts/identities + else + { + if (input_name && input_name.value == '') + { + alert(this.get_label('nonamewarning')); + input_name.focus(); + break; + } + else if (input_email && !rcube_check_email(input_email.value)) + { + alert(this.get_label('noemailwarning')); + input_email.focus(); + break; + } + } + + this.gui_objects.editform.submit(); + } + break; + + case 'delete': + // mail task + if (this.task=='mail') + this.delete_messages(); + // addressbook task + else if (this.task=='addressbook') + this.delete_contacts(); + // user settings task + else if (this.task=='settings') + this.delete_identity(); + break; + + + // mail task commands + case 'move': + case 'moveto': + if (this.task == 'mail') + this.move_messages(props); + else if (this.task == 'addressbook' && this.drag_active) + this.copy_contact(null, props); + break; + + case 'mark': + if (props) + this.mark_message(props); + break; + + case 'toggle_status': + if (props && !props._row) + break; + + var uid; + var flag = 'read'; + + if (props._row.uid) + { + uid = props._row.uid; + + // toggle read/unread + if (this.message_list.rows[uid].deleted) { + flag = 'undelete'; + } else if (!this.message_list.rows[uid].unread) + flag = 'unread'; + } + + this.mark_message(flag, uid); + break; + + case 'toggle_flag': + if (props && !props._row) + break; + + var uid; + var flag = 'flagged'; + + if (props._row.uid) + { + uid = props._row.uid; + // toggle flagged/unflagged + if (this.message_list.rows[uid].flagged) + flag = 'unflagged'; + } + this.mark_message(flag, uid); + break; + + case 'always-load': + if (this.env.uid && this.env.sender) { + this.add_contact(urlencode(this.env.sender)); + window.setTimeout(function(){ ref.command('load-images'); }, 300); + break; + } + + case 'load-images': + if (this.env.uid) + this.show_message(this.env.uid, true, this.env.action=='preview'); + break; + + case 'load-attachment': + var qstring = '_mbox='+urlencode(this.env.mailbox)+'&_uid='+this.env.uid+'&_part='+props.part; + + // open attachment in frame if it's of a supported mimetype + if (this.env.uid && props.mimetype && find_in_array(props.mimetype, this.mimetypes)>=0) + { + if (props.mimetype == 'text/html') + qstring += '&_safe=1'; + this.attachment_win = window.open(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1', 'rcubemailattachment'); + if (this.attachment_win) + { + window.setTimeout(function(){ ref.attachment_win.focus(); }, 10); + break; + } + } + + this.goto_url('get', qstring+'&_download=1', false); + break; + + case 'select-all': + this.message_list.select_all(props); + break; + + case 'select-none': + this.message_list.clear_selection(); + break; + + case 'nextmessage': + if (this.env.next_uid) + this.show_message(this.env.next_uid, false, this.env.action=='preview'); + break; + + case 'lastmessage': + if (this.env.last_uid) + this.show_message(this.env.last_uid); + break; + + case 'previousmessage': + if (this.env.prev_uid) + this.show_message(this.env.prev_uid, false, this.env.action=='preview'); + break; + + case 'firstmessage': + if (this.env.first_uid) + this.show_message(this.env.first_uid); + break; + + case 'checkmail': + this.check_for_recent(true); + break; + + case 'compose': + var url = this.env.comm_path+'&_action=compose'; + + if (this.task=='mail') + { + url += '&_mbox='+urlencode(this.env.mailbox); + + if (this.env.mailbox==this.env.drafts_mailbox) + { + var uid; + if (uid = this.get_single_uid()) + url += '&_draft_uid='+uid; + } + else if (props) + url += '&_to='+urlencode(props); + } + // modify url if we're in addressbook + else if (this.task=='addressbook') + { + // switch to mail compose step directly + if (props && props.indexOf('@') > 0) + { + url = this.get_task_url('mail', url); + this.redirect(url + '&_to='+urlencode(props)); + break; + } + + // use contact_id passed as command parameter + var a_cids = new Array(); + if (props) + a_cids[a_cids.length] = props; + // get selected contacts + else if (this.contact_list) + { + var selection = this.contact_list.get_selection(); + for (var n=0; n 0) { + var add_url = (this.env.source ? '_source='+urlencode(this.env.source)+'&' : ''); + if (this.env.search_request) + add_url += '_search='+this.env.search_request; + + this.goto_url('export', add_url); + } + break; + + // collapse/expand folder + case 'collapse-folder': + if (props) + this.collapse_folder(props); + break; + + // user settings commands + case 'preferences': + this.goto_url(''); + break; + + case 'identities': + this.goto_url('identities'); + break; + + case 'delete-identity': + this.delete_identity(); + + case 'folders': + this.goto_url('folders'); + break; + + case 'subscribe': + this.subscribe_folder(props); + break; + + case 'unsubscribe': + this.unsubscribe_folder(props); + break; + + case 'create-folder': + this.create_folder(props); + break; + + case 'rename-folder': + this.rename_folder(props); + break; + + case 'delete-folder': + this.delete_folder(props); + break; + + } + + return obj ? false : true; + }; + + // set command enabled or disabled + this.enable_command = function() + { + var args = arguments; + if(!args.length) return -1; + + var command; + var enable = args[args.length-1]; + + for(var n=0; n= pos.x2 + || mouse.y < pos.y1 || mouse.y >= pos.y2) + { + if (this.env.last_folder_target) { + this.set_classname(this.get_folder_li(this.env.last_folder_target), 'droptarget', false); + this.env.last_folder_target = null; + } + return; + } + + // over the folders + for (var k in this.env.folder_coords) + { + pos = this.env.folder_coords[k]; + if (this.check_droptarget(k) && ((mouse.x >= pos.x1) && (mouse.x < pos.x2) + && (mouse.y >= pos.y1) && (mouse.y < pos.y2))) + { + this.set_classname(this.get_folder_li(k), 'droptarget', true); + this.env.last_folder_target = k; + } + else + this.set_classname(this.get_folder_li(k), 'droptarget', false); + } + } + }; + + this.collapse_folder = function(id) + { + var div; + if ((li = this.get_folder_li(id)) && + (div = li.getElementsByTagName("div")[0]) && + (div.className.match(/collapsed/) || div.className.match(/expanded/))) + { + var ul = li.getElementsByTagName("ul")[0]; + if (div.className.match(/collapsed/)) + { + ul.style.display = ''; + this.set_classname(div, 'collapsed', false); + this.set_classname(div, 'expanded', true); + var reg = new RegExp('&'+urlencode(id)+'&'); + this.set_env('collapsed_folders', this.env.collapsed_folders.replace(reg, '')); + } + else + { + ul.style.display = 'none'; + this.set_classname(div, 'expanded', false); + this.set_classname(div, 'collapsed', true); + this.set_env('collapsed_folders', this.env.collapsed_folders+'&'+urlencode(id)+'&'); + + // select parent folder if one of its childs is currently selected + if (this.env.mailbox.indexOf(id + this.env.delimiter) == 0) + this.command('list', id); + } + + // Work around a bug in IE6 and IE7, see #1485309 + if ((bw.ie6 || bw.ie7) && + li.nextSibling && + (li.nextSibling.getElementsByTagName("ul").length>0) && + li.nextSibling.getElementsByTagName("ul")[0].style && + (li.nextSibling.getElementsByTagName("ul")[0].style.display!='none')) + { + li.nextSibling.getElementsByTagName("ul")[0].style.display = 'none'; + li.nextSibling.getElementsByTagName("ul")[0].style.display = ''; + } + + this.http_post('save-pref', '_name=collapsed_folders&_value='+urlencode(this.env.collapsed_folders)); + this.set_unread_count_display(id, false); + } + } + + this.click_on_list = function(e) + { + if (this.message_list) + this.message_list.focus(); + else if (this.contact_list) + this.contact_list.focus(); + + var mbox_li; + if (mbox_li = this.get_folder_li()) + this.set_classname(mbox_li, 'unfocused', true); + + return rcube_event.get_button(e) == 2 ? true : rcube_event.cancel(e); + }; + + this.msglist_select = function(list) + { + if (this.preview_timer) + clearTimeout(this.preview_timer); + + var selected = list.selection.length==1; + + // Hide certain command buttons when Drafts folder is selected + if (this.env.mailbox == this.env.drafts_mailbox) + { + this.enable_command('reply', 'reply-all', 'forward', false); + this.enable_command('show', 'print', selected); + this.enable_command('delete', 'moveto', 'mark', (list.selection.length > 0 ? true : false)); + } + else + { + this.enable_command('show', 'reply', 'reply-all', 'forward', 'print', selected); + this.enable_command('delete', 'moveto', 'mark', (list.selection.length > 0 ? true : false)); + } + + // start timer for message preview (wait for double click) + if (selected && this.env.contentframe && !list.multi_selecting) + this.preview_timer = window.setTimeout(function(){ ref.msglist_get_preview(); }, 200); + else if (this.env.contentframe) + this.show_contentframe(false); + }; + + this.msglist_dbl_click = function(list) + { + if (this.preview_timer) + clearTimeout(this.preview_timer); + + var uid = list.get_single_selection(); + if (uid && this.env.mailbox == this.env.drafts_mailbox) + this.goto_url('compose', '_draft_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true); + else if (uid) + this.show_message(uid, false, false); + }; + + this.msglist_keypress = function(list) + { + if (list.key_pressed == list.ENTER_KEY) + this.command('show'); + else if (list.key_pressed == list.DELETE_KEY) + this.command('delete'); + else if (list.key_pressed == list.BACKSPACE_KEY) + this.command('delete'); + else + list.shiftkey = false; + }; + + this.msglist_get_preview = function() + { + var uid = this.get_single_uid(); + if (uid && this.env.contentframe && !this.drag_active) + this.show_message(uid, false, true); + else if (this.env.contentframe) + this.show_contentframe(false); + }; + + this.check_droptarget = function(id) + { + if (this.task == 'mail') + return (this.env.mailboxes[id] && this.env.mailboxes[id].id != this.env.mailbox && !this.env.mailboxes[id].virtual); + else if (this.task == 'addressbook') + return (id != this.env.source && this.env.address_sources[id] && !this.env.address_sources[id].readonly); + else if (this.task == 'settings') + return (id != this.env.folder); + }; + + + /*********************************************************/ + /********* (message) list functionality *********/ + /*********************************************************/ + + // when user doble-clicks on a row + this.show_message = function(id, safe, preview) + { + if (!id) return; + + var add_url = ''; + var action = preview ? 'preview': 'show'; + var target = window; + + if (preview && this.env.contentframe && window.frames && window.frames[this.env.contentframe]) + { + target = window.frames[this.env.contentframe]; + add_url = '&_framed=1'; + } + + if (safe) + add_url = '&_safe=1'; + + // also send search request to get the right messages + if (this.env.search_request) + add_url += '&_search='+this.env.search_request; + var url = '&_action='+action+'&_uid='+id+'&_mbox='+urlencode(this.env.mailbox)+add_url; + if (action == 'preview' && String(target.location.href).indexOf(url) >= 0) + this.show_contentframe(true); + else + { + this.set_busy(true, 'loading'); + target.location.href = this.env.comm_path+url; + // mark as read and change mbox unread counter + if (action == 'preview' && this.message_list && this.message_list.rows[id] && this.message_list.rows[id].unread) + { + this.set_message(id, 'unread', false); + if (this.env.unread_counts[this.env.mailbox]) + { + this.env.unread_counts[this.env.mailbox] -= 1; + this.set_unread_count(this.env.mailbox, this.env.unread_counts[this.env.mailbox], this.env.mailbox == 'INBOX'); + } + } + } + }; + + this.show_contentframe = function(show) + { + var frm; + if (this.env.contentframe && (frm = rcube_find_object(this.env.contentframe))) + { + if (!show && window.frames[this.env.contentframe]) + { + if (window.frames[this.env.contentframe].location.href.indexOf(this.env.blankpage)<0) + window.frames[this.env.contentframe].location.href = this.env.blankpage; + } + else if (!bw.safari) + frm.style.display = show ? 'block' : 'none'; + } + + if (!show && this.busy) + this.set_busy(false); + }; + + // list a specific page + this.list_page = function(page) + { + if (page=='next') + page = this.env.current_page+1; + if (page=='last') + page = this.env.pagecount; + if (page=='prev' && this.env.current_page>1) + page = this.env.current_page-1; + if (page=='first' && this.env.current_page>1) + page = 1; + + if (page > 0 && page <= this.env.pagecount) + { + this.env.current_page = page; + + if (this.task=='mail') + this.list_mailbox(this.env.mailbox, page); + else if (this.task=='addressbook') + this.list_contacts(this.env.source, page); + } + }; + + // list messages of a specific mailbox using filter + this.filter_mailbox = function(filter) + { + var search; + if (this.gui_objects.qsearchbox) + search = this.gui_objects.qsearchbox.value; + + this.message_list.clear(); + + // reset vars + this.env.current_page = 1; + this.set_busy(true, 'searching'); + this.http_request('search', '_filter='+filter + + (search ? '&_q='+urlencode(search) : '') + + (this.env.mailbox ? '&_mbox='+urlencode(this.env.mailbox) : ''), true); + } + + + // list messages of a specific mailbox + this.list_mailbox = function(mbox, page, sort) + { + this.last_selected = 0; + var add_url = ''; + var target = window; + + if (!mbox) + mbox = this.env.mailbox; + + // add sort to url if set + if (sort) + add_url += '&_sort=' + sort; + + // also send search request to get the right messages + if (this.env.search_request) + add_url += '&_search='+this.env.search_request; + + // set page=1 if changeing to another mailbox + if (!page && mbox != this.env.mailbox) + { + page = 1; + this.env.current_page = page; + if (this.message_list) + this.message_list.clear_selection(); + this.show_contentframe(false); + } + + if (mbox != this.env.mailbox || (mbox == this.env.mailbox && !page && !sort)) + add_url += '&_refresh=1'; + + this.select_folder(mbox, this.env.mailbox); + this.env.mailbox = mbox; + + // load message list remotely + if (this.gui_objects.messagelist) + { + this.list_mailbox_remote(mbox, page, add_url); + return; + } + + if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) + { + target = window.frames[this.env.contentframe]; + add_url += '&_framed=1'; + } + + // load message list to target frame/window + if (mbox) + { + this.set_busy(true, 'loading'); + target.location.href = this.env.comm_path+'&_mbox='+urlencode(mbox)+(page ? '&_page='+page : '')+add_url; + } + }; + + // send remote request to load message list + this.list_mailbox_remote = function(mbox, page, add_url) + { + // clear message list first + this.message_list.clear(); + + // send request to server + var url = '_mbox='+urlencode(mbox)+(page ? '&_page='+page : ''); + this.set_busy(true, 'loading'); + this.http_request('list', url+add_url, true); + }; + + this.expunge_mailbox = function(mbox) + { + var lock = false; + var add_url = ''; + + // lock interface if it's the active mailbox + if (mbox == this.env.mailbox) + { + lock = true; + this.set_busy(true, 'loading'); + add_url = '&_reload=1'; + } + + // send request to server + var url = '_mbox='+urlencode(mbox); + this.http_post('expunge', url+add_url, lock); + }; + + this.purge_mailbox = function(mbox) + { + var lock = false; + var add_url = ''; + + if (!confirm(this.get_label('purgefolderconfirm'))) + return false; + + // lock interface if it's the active mailbox + if (mbox == this.env.mailbox) + { + lock = true; + this.set_busy(true, 'loading'); + add_url = '&_reload=1'; + } + + // send request to server + var url = '_mbox='+urlencode(mbox); + this.http_post('purge', url+add_url, lock); + return true; + }; + + // test if purge command is allowed + this.purge_mailbox_test = function() + { + return (this.env.messagecount && (this.env.mailbox == this.env.trash_mailbox || this.env.mailbox == this.env.junk_mailbox + || this.env.mailbox.match('^' + RegExp.escape(this.env.trash_mailbox) + RegExp.escape(this.env.delimiter)) + || this.env.mailbox.match('^' + RegExp.escape(this.env.junk_mailbox) + RegExp.escape(this.env.delimiter)))); + }; + + // set message icon + this.set_message_icon = function(uid) + { + var icn_src; + var rows = this.message_list.rows; + + if (!rows[uid]) + return false; + + if (rows[uid].deleted && this.env.deletedicon) + icn_src = this.env.deletedicon; + else if (rows[uid].replied && this.env.repliedicon) + { + if (rows[uid].forwarded && this.env.forwardedrepliedicon) + icn_src = this.env.forwardedrepliedicon; + else + icn_src = this.env.repliedicon; + } + else if (rows[uid].forwarded && this.env.forwardedicon) + icn_src = this.env.forwardedicon; + else if (rows[uid].unread && this.env.unreadicon) + icn_src = this.env.unreadicon; + else if (this.env.messageicon) + icn_src = this.env.messageicon; + + if (icn_src && rows[uid].icon) + rows[uid].icon.src = icn_src; + + icn_src = ''; + + if (rows[uid].flagged && this.env.flaggedicon) + icn_src = this.env.flaggedicon; + else if (!rows[uid].flagged && this.env.unflaggedicon) + icn_src = this.env.unflaggedicon; + + if (rows[uid].flagged_icon && icn_src) + rows[uid].flagged_icon.src = icn_src; + } + + // set message status + this.set_message_status = function(uid, flag, status) + { + var rows = this.message_list.rows; + + if (!rows[uid]) return false; + + if (flag == 'unread') + rows[uid].unread = status; + else if(flag == 'deleted') + rows[uid].deleted = status; + else if (flag == 'replied') + rows[uid].replied = status; + else if (flag == 'forwarded') + rows[uid].forwarded = status; + else if (flag == 'flagged') + rows[uid].flagged = status; + + this.env.messages[uid] = rows[uid]; + } + + // set message row status, class and icon + this.set_message = function(uid, flag, status) + { + var rows = this.message_list.rows; + + if (!rows[uid]) return false; + + if (flag) + this.set_message_status(uid, flag, status); + + if (rows[uid].unread && rows[uid].classname.indexOf('unread')<0) + { + rows[uid].classname += ' unread'; + this.set_classname(rows[uid].obj, 'unread', true); + } + else if (!rows[uid].unread && rows[uid].classname.indexOf('unread')>=0) + { + rows[uid].classname = rows[uid].classname.replace(/\s*unread/, ''); + this.set_classname(rows[uid].obj, 'unread', false); + } + + if (rows[uid].deleted && rows[uid].classname.indexOf('deleted')<0) + { + rows[uid].classname += ' deleted'; + this.set_classname(rows[uid].obj, 'deleted', true); + } + else if (!rows[uid].deleted && rows[uid].classname.indexOf('deleted')>=0) + { + rows[uid].classname = rows[uid].classname.replace(/\s*deleted/, ''); + this.set_classname(rows[uid].obj, 'deleted', false); + } + + if (rows[uid].flagged && rows[uid].classname.indexOf('flagged')<0) + { + rows[uid].classname += ' flagged'; + this.set_classname(rows[uid].obj, 'flagged', true); + } + else if (!rows[uid].flagged && rows[uid].classname.indexOf('flagged')>=0) + { + rows[uid].classname = rows[uid].classname.replace(/\s*flagged/, ''); + this.set_classname(rows[uid].obj, 'flagged', false); + } + + this.set_message_icon(uid); + } + + // move selected messages to the specified mailbox + this.move_messages = function(mbox) + { + // exit if current or no mailbox specified or if selection is empty + if (!mbox || mbox == this.env.mailbox || (!this.env.uid && (!this.message_list || !this.message_list.get_selection().length))) + return; + + var lock = false; + var add_url = '&_target_mbox='+urlencode(mbox)+'&_from='+(this.env.action ? this.env.action : ''); + + // show wait message + if (this.env.action=='show') + { + lock = true; + this.set_busy(true, 'movingmessage'); + } + else if (!this.env.flag_for_deletion) + this.show_contentframe(false); + + // Hide message command buttons until a message is selected + this.enable_command('reply', 'reply-all', 'forward', 'delete', 'mark', 'print', false); + + this._with_selected_messages('moveto', lock, add_url, (this.env.flag_for_deletion ? false : true)); + }; + + // delete selected messages from the current mailbox + this.delete_messages = function() + { + var selection = this.message_list ? this.message_list.get_selection() : new Array(); + + // exit if no mailbox specified or if selection is empty + if (!this.env.uid && !selection.length) + return; + + // if there is a trash mailbox defined and we're not currently in it: + if (this.env.trash_mailbox && String(this.env.mailbox).toLowerCase() != String(this.env.trash_mailbox).toLowerCase()) + { + // if shift was pressed delete it immediately + if (this.message_list && this.message_list.shiftkey) + { + if (confirm(this.get_label('deletemessagesconfirm'))) + this.permanently_remove_messages(); + } + else + this.move_messages(this.env.trash_mailbox); + } + // if there is a trash mailbox defined but we *are* in it: + else if (this.env.trash_mailbox && String(this.env.mailbox).toLowerCase() == String(this.env.trash_mailbox).toLowerCase()) + this.permanently_remove_messages(); + // if there isn't a defined trash mailbox and the config is set to flag for deletion + else if (!this.env.trash_mailbox && this.env.flag_for_deletion) + { + this.mark_message('delete'); + if(this.env.action=="show") + this.command('nextmessage','',this); + else if (selection.length == 1) + this.message_list.select_next(); + } + // if there isn't a defined trash mailbox and the config is set NOT to flag for deletion + else if (!this.env.trash_mailbox) + this.permanently_remove_messages(); + }; + + // delete the selected messages permanently + this.permanently_remove_messages = function() + { + // exit if no mailbox specified or if selection is empty + if (!this.env.uid && (!this.message_list || !this.message_list.get_selection().length)) + return; + + this.show_contentframe(false); + this._with_selected_messages('delete', false, '&_from='+(this.env.action ? this.env.action : ''), true); + }; + + // Send a specifc request with UIDs of all selected messages + // @private + this._with_selected_messages = function(action, lock, add_url, remove) + { + var a_uids = new Array(); + + if (this.env.uid) + a_uids[0] = this.env.uid; + else + { + var selection = this.message_list.get_selection(); + var rows = this.message_list.rows; + var id; + for (var n=0; n=0) + message = message.substring(0, p-1) + message.substring(p+sig.length, message.length); + } + + message = message.replace(/[\r\n]+$/, ''); + + // add the new signature string + if (this.env.signatures && this.env.signatures[id]) + { + sig = this.env.signatures[id]['text']; + if (this.env.signatures[id]['is_html']) + { + sig = this.env.signatures[id]['plain_text']; + } + if (sig.indexOf('-- ')!=0) + sig = '-- \n'+sig; + message += '\n\n'+sig; + } + } + else + { + var editor = tinyMCE.get('compose-body'); + + if (this.env.signatures) + { + // Append the signature as a div within the body + var sigElem = editor.dom.get('_rc_sig'); + var newsig = ''; + var htmlsig = true; + + if (!sigElem) + { + // add empty line before signature on IE + if (bw.ie) + editor.getBody().appendChild(editor.getDoc().createElement('br')); + + sigElem = editor.getDoc().createElement('div'); + sigElem.setAttribute('id', '_rc_sig'); + editor.getBody().appendChild(sigElem); + } + + if (this.env.signatures[id]) + { + newsig = this.env.signatures[id]['text']; + htmlsig = this.env.signatures[id]['is_html']; + } + + if (htmlsig) + sigElem.innerHTML = newsig; + else + sigElem.innerHTML = '
' + newsig + '
'; + } + } + + if (input_message) + input_message.value = message; + + this.env.identity = id; + return true; + }; + + this.show_attachment_form = function(a) + { + if (!this.gui_objects.uploadbox) + return false; + + var elm, list; + if (elm = this.gui_objects.uploadbox) + { + if (a && (list = this.gui_objects.attachmentlist)) + { + var pos = rcube_get_object_pos(list); + var left = pos.x; + var top = pos.y + list.offsetHeight + 10; + + elm.style.top = top+'px'; + elm.style.left = left+'px'; + } + + elm.style.visibility = a ? 'visible' : 'hidden'; + } + + // clear upload form + try { + if (!a && this.gui_objects.attachmentform != this.gui_objects.messageform) + this.gui_objects.attachmentform.reset(); + } + catch(e){} // ignore errors + + return true; + }; + + // upload attachment file + this.upload_file = function(form) + { + if (!form) + return false; + + // get file input fields + var send = false; + for (var n=0; n