- Applied fixes from trunk up to r5498
| | |
| | | CHANGELOG Roundcube Webmail |
| | | =========================== |
| | | |
| | | - Use strpos() instead of strstr() when possible (#1488211) |
| | | - Fix handling HTML entities when converting HTML to text (#1488212) |
| | | - Fix fit_string_to_size() renders browser and ui unresponsive (#1488207) |
| | | - Fix handling of invalid characters in request (#1488124) |
| | | - Fix merging some configuration options in update.sh script (#1485864) |
| | | - Fix so TEXT key will remove all HEADER keys in IMAP SEARCH (#1488208) |
| | | - Fix handling contact photo url with https:// prefix (#1488202) |
| | | - Fix possible infinite redirect on attachment preview (#1488199) |
| | | - Improved clickjacking protection for browsers which don't support X-Frame-Options headers |
| | | - Fixed bug where similiar folder names were highlighted wrong (#1487860) |
| | |
| | | // use this timezone to display date/time |
| | | $rcmail_config['timezone'] = 'auto'; |
| | | |
| | | // is daylight saving On? |
| | | $rcmail_config['dst_active'] = (bool)date('I'); |
| | | // is daylight saving On? Default: (bool)date('I'); |
| | | $rcmail_config['dst_active'] = null; |
| | | |
| | | // prefer displaying HTML messages |
| | | $rcmail_config['prefer_html'] = true; |
| | |
| | | |
| | | foreach ($this->config as $prop => $default) { |
| | | |
| | | $value = (isset($_POST["_$prop"]) || $this->bool_config_props[$prop]) ? $_POST["_$prop"] : $default; |
| | | $is_default = !isset($_POST["_$prop"]); |
| | | $value = !$is_default || $this->bool_config_props[$prop] ? $_POST["_$prop"] : $default; |
| | | |
| | | // convert some form data |
| | | if ($prop == 'debug_level') { |
| | | $val = 0; |
| | | if (is_array($value)) |
| | | if ($prop == 'debug_level' && !$is_default) { |
| | | if (is_array($value)) { |
| | | $val = 0; |
| | | foreach ($value as $dbgval) |
| | | $val += intval($dbgval); |
| | | $value = $val; |
| | | $value = $val; |
| | | } |
| | | } |
| | | else if ($which == 'db' && $prop == 'db_dsnw' && !empty($_POST['_dbtype'])) { |
| | | if ($_POST['_dbtype'] == 'sqlite') |
| | | $value = sprintf('%s://%s?mode=0646', $_POST['_dbtype'], $_POST['_dbname']{0} == '/' ? '/' . $_POST['_dbname'] : $_POST['_dbname']); |
| | | else |
| | | else if ($_POST['_dbtype']) |
| | | $value = sprintf('%s://%s:%s@%s/%s', $_POST['_dbtype'], |
| | | rawurlencode($_POST['_dbuser']), rawurlencode($_POST['_dbpass']), $_POST['_dbhost'], $_POST['_dbname']); |
| | | } |
| | |
| | | $value = '%p'; |
| | | } |
| | | else if ($prop == 'default_imap_folders') { |
| | | $value = Array(); |
| | | $value = array(); |
| | | foreach ($this->config['default_imap_folders'] as $_folder) { |
| | | switch($_folder) { |
| | | switch ($_folder) { |
| | | case 'Drafts': $_folder = $this->config['drafts_mbox']; break; |
| | | case 'Sent': $_folder = $this->config['sent_mbox']; break; |
| | | case 'Junk': $_folder = $this->config['junk_mbox']; break; |
| | |
| | | // replace the matching line in config file |
| | | $out = preg_replace( |
| | | '/(\$rcmail_config\[\''.preg_quote($prop).'\'\])\s+=\s+(.+);/Uie', |
| | | "'\\1 = ' . rcube_install::_dump_var(\$value) . ';'", |
| | | "'\\1 = ' . rcube_install::_dump_var(\$value, \$prop) . ';'", |
| | | $out); |
| | | } |
| | | |
| | |
| | | $current = $this->config; |
| | | $this->config = array(); |
| | | $this->load_defaults(); |
| | | |
| | | |
| | | foreach ($this->replaced_config as $prop => $replacement) { |
| | | if (isset($current[$prop])) { |
| | | if ($prop == 'skin_path') |
| | |
| | | |
| | | if ($current['keep_alive'] && $current['session_lifetime'] < $current['keep_alive']) |
| | | $current['session_lifetime'] = max(10, ceil($current['keep_alive'] / 60) * 2); |
| | | |
| | | |
| | | $this->config = array_merge($this->config, $current); |
| | | |
| | | |
| | | foreach ((array)$current['ldap_public'] as $key => $values) { |
| | | $this->config['ldap_public'][$key] = $current['ldap_public'][$key]; |
| | | } |
| | |
| | | } |
| | | |
| | | |
| | | static function _dump_var($var) { |
| | | static function _dump_var($var, $name=null) { |
| | | // special values |
| | | switch ($name) { |
| | | case 'syslog_facility': |
| | | $list = array(32 => 'LOG_AUTH', 80 => 'LOG_AUTHPRIV', 72 => ' LOG_CRON', |
| | | 24 => 'LOG_DAEMON', 0 => 'LOG_KERN', 128 => 'LOG_LOCAL0', |
| | | 136 => 'LOG_LOCAL1', 144 => 'LOG_LOCAL2', 152 => 'LOG_LOCAL3', |
| | | 160 => 'LOG_LOCAL4', 168 => 'LOG_LOCAL5', 176 => 'LOG_LOCAL6', |
| | | 184 => 'LOG_LOCAL7', 48 => 'LOG_LPR', 16 => 'LOG_MAIL', |
| | | 56 => 'LOG_NEWS', 40 => 'LOG_SYSLOG', 8 => 'LOG_USER', 64 => 'LOG_UUCP'); |
| | | if ($val = $list[$var]) |
| | | return $val; |
| | | break; |
| | | } |
| | | |
| | | |
| | | if (is_array($var)) { |
| | | if (empty($var)) { |
| | | return 'array()'; |
| | |
| | | function get_input_value($fname, $source, $allow_html=FALSE, $charset=NULL) |
| | | { |
| | | $value = NULL; |
| | | |
| | | if ($source==RCUBE_INPUT_GET && isset($_GET[$fname])) |
| | | $value = $_GET[$fname]; |
| | | else if ($source==RCUBE_INPUT_POST && isset($_POST[$fname])) |
| | | $value = $_POST[$fname]; |
| | | else if ($source==RCUBE_INPUT_GPC) |
| | | { |
| | | |
| | | if ($source == RCUBE_INPUT_GET) { |
| | | if (isset($_GET[$fname])) |
| | | $value = $_GET[$fname]; |
| | | } |
| | | else if ($source == RCUBE_INPUT_POST) { |
| | | if (isset($_POST[$fname])) |
| | | $value = $_POST[$fname]; |
| | | } |
| | | else if ($source == RCUBE_INPUT_GPC) { |
| | | if (isset($_POST[$fname])) |
| | | $value = $_POST[$fname]; |
| | | else if (isset($_GET[$fname])) |
| | | $value = $_GET[$fname]; |
| | | else if (isset($_COOKIE[$fname])) |
| | | $value = $_COOKIE[$fname]; |
| | | } |
| | | } |
| | | |
| | | return parse_input_value($value, $allow_html, $charset); |
| | | } |
| | |
| | | /** |
| | | * Parse/validate input value. See get_input_value() |
| | | * Performs stripslashes() and charset conversion if necessary |
| | | * |
| | | * |
| | | * @param string Input value |
| | | * @param boolean Allow HTML tags in field value |
| | | * @param string Charset to convert into |
| | |
| | | else if (get_magic_quotes_gpc() || get_magic_quotes_runtime()) |
| | | $value = stripslashes($value); |
| | | |
| | | // remove HTML tags if not allowed |
| | | // remove HTML tags if not allowed |
| | | if (!$allow_html) |
| | | $value = strip_tags($value); |
| | | |
| | | |
| | | $output_charset = is_object($OUTPUT) ? $OUTPUT->get_charset() : null; |
| | | |
| | | // remove invalid characters (#1488124) |
| | | if ($output_charset == 'UTF-8') |
| | | $value = rc_utf8_clean($value); |
| | | |
| | | // convert to internal charset |
| | | if (is_object($OUTPUT) && $charset) |
| | | return rcube_charset_convert($value, $OUTPUT->get_charset(), $charset); |
| | | else |
| | | return $value; |
| | | if ($charset && $output_charset) |
| | | $value = rcube_charset_convert($value, $output_charset, $charset); |
| | | |
| | | return $value; |
| | | } |
| | | |
| | | /** |
| | |
| | | $src = $mode == RCUBE_INPUT_GET ? $_GET : ($mode == RCUBE_INPUT_POST ? $_POST : $_REQUEST); |
| | | foreach ($src as $key => $value) { |
| | | $fname = $key[0] == '_' ? substr($key, 1) : $key; |
| | | if ($ignore && !preg_match("/($ignore)/", $fname)) |
| | | if ($ignore && !preg_match('/^(' . $ignore . ')$/', $fname)) |
| | | $out[$fname] = get_input_value($key, $mode); |
| | | } |
| | | |
| | | |
| | | return $out; |
| | | } |
| | | |
| | |
| | | $HTTP_USER_AGENT = strtolower($_SERVER['HTTP_USER_AGENT']); |
| | | |
| | | $this->ver = 0; |
| | | $this->win = strstr($HTTP_USER_AGENT, 'win'); |
| | | $this->mac = strstr($HTTP_USER_AGENT, 'mac'); |
| | | $this->linux = strstr($HTTP_USER_AGENT, 'linux'); |
| | | $this->unix = strstr($HTTP_USER_AGENT, 'unix'); |
| | | $this->win = strpos($HTTP_USER_AGENT, 'win') != false; |
| | | $this->mac = strpos($HTTP_USER_AGENT, 'mac') != false; |
| | | $this->linux = strpos($HTTP_USER_AGENT, 'linux') != false; |
| | | $this->unix = strpos($HTTP_USER_AGENT, 'unix') != false; |
| | | |
| | | $this->opera = strstr($HTTP_USER_AGENT, 'opera'); |
| | | $this->ns4 = strstr($HTTP_USER_AGENT, 'mozilla/4') && !stristr($HTTP_USER_AGENT, 'msie'); |
| | | $this->ns = ($this->ns4 || strstr($HTTP_USER_AGENT, 'netscape')); |
| | | $this->ie = !$this->opera && stristr($HTTP_USER_AGENT, 'compatible; msie'); |
| | | $this->mz = !$this->ie && strstr($HTTP_USER_AGENT, 'mozilla/5'); |
| | | $this->chrome = strstr($HTTP_USER_AGENT, 'chrome'); |
| | | $this->khtml = strstr($HTTP_USER_AGENT, 'khtml'); |
| | | $this->safari = !$this->chrome && ($this->khtml || strstr($HTTP_USER_AGENT, 'safari')); |
| | | $this->opera = strpos($HTTP_USER_AGENT, 'opera') !== false; |
| | | $this->ns4 = strpos($HTTP_USER_AGENT, 'mozilla/4') !== false && strpos($HTTP_USER_AGENT, 'msie') === false; |
| | | $this->ns = ($this->ns4 || strpos($HTTP_USER_AGENT, 'netscape') !== false); |
| | | $this->ie = !$this->opera && strpos($HTTP_USER_AGENT, 'compatible; msie') !== false; |
| | | $this->mz = !$this->ie && strpos($HTTP_USER_AGENT, 'mozilla/5') !== false; |
| | | $this->chrome = strpos($HTTP_USER_AGENT, 'chrome') !== false; |
| | | $this->khtml = strpos($HTTP_USER_AGENT, 'khtml') !== false; |
| | | $this->safari = !$this->chrome && ($this->khtml || strpos($HTTP_USER_AGENT, 'safari') !== false); |
| | | |
| | | if ($this->ns || $this->chrome) { |
| | | $test = preg_match('/(mozilla|chrome)\/([0-9.]+)/', $HTTP_USER_AGENT, $regs); |
| | |
| | | |
| | | // enable display_errors in 'show' level, but not for ajax requests |
| | | ini_set('display_errors', intval(empty($_REQUEST['_remote']) && ($this->prop['debug_level'] & 4))); |
| | | |
| | | |
| | | // set timezone auto settings values |
| | | if ($this->prop['timezone'] == 'auto') { |
| | | $this->prop['dst_active'] = intval(date('I')); |
| | | $this->prop['_timezone_value'] = date('Z') / 3600 - $this->prop['dst_active']; |
| | | $this->prop['_timezone_value'] = date('Z') / 3600 - $this->prop['dst_active']; |
| | | } |
| | | else if ($this->prop['dst_active'] === null) { |
| | | $this->prop['dst_active'] = intval(date('I')); |
| | | } |
| | | |
| | | // export config data |
| | |
| | | $from = $addresses[0]; |
| | | |
| | | // Reject envelope From: addresses with spaces. |
| | | if (strstr($from, ' ')) |
| | | if (strpos($from, ' ') !== false) |
| | | return false; |
| | | |
| | | $lines[] = $key . ': ' . $value; |
| | |
| | | }); |
| | | }; |
| | | |
| | | this.plain2html = function(plainText, id) |
| | | this.plain2html = function(plain, id) |
| | | { |
| | | var lock = this.set_busy(true, 'converting'); |
| | | $('#'+id).val(plainText ? '<pre>'+plainText+'</pre>' : ''); |
| | | |
| | | plain = plain.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); |
| | | $('#'+id).val(plain ? '<pre>'+plain+'</pre>' : ''); |
| | | |
| | | this.set_busy(false, null, lock); |
| | | }; |
| | | |
| | |
| | | var $search = array( |
| | | "/\r/", // Non-legal carriage return |
| | | "/[\n\t]+/", // Newlines and tabs |
| | | '/[ ]{2,}/', // Runs of spaces, pre-handling |
| | | '/<script[^>]*>.*?<\/script>/i', // <script>s -- which strip_tags supposedly has problems with |
| | | '/<style[^>]*>.*?<\/style>/i', // <style>s -- which strip_tags supposedly has problems with |
| | | '/<p[^>]*>/i', // <P> |
| | |
| | | '/(<table[^>]*>|<\/table>)/i', // <table> and </table> |
| | | '/(<tr[^>]*>|<\/tr>)/i', // <tr> and </tr> |
| | | '/<td[^>]*>(.*?)<\/td>/i', // <td> and </td> |
| | | '/&(nbsp|#160);/i', // Non-breaking space |
| | | '/&(quot|rdquo|ldquo|#8220|#8221|#147|#148);/i', |
| | | // Double quotes |
| | | '/&(apos|rsquo|lsquo|#8216|#8217);/i', // Single quotes |
| | | '/>/i', // Greater-than |
| | | '/</i', // Less-than |
| | | '/&(copy|#169);/i', // Copyright |
| | | '/&(trade|#8482|#153);/i', // Trademark |
| | | '/&(reg|#174);/i', // Registered |
| | | '/&(mdash|#151|#8212);/i', // mdash |
| | | '/&(ndash|minus|#8211|#8722);/i', // ndash |
| | | '/&(bull|#149|#8226);/i', // Bullet |
| | | '/&(pound|#163);/i', // Pound sign |
| | | '/&(euro|#8364);/i', // Euro sign |
| | | '/&(amp|#38);/i', // Ampersand: see _converter() |
| | | '/[ ]{2,}/' // Runs of spaces, post-handling |
| | | ); |
| | | |
| | | /** |
| | |
| | | var $replace = array( |
| | | '', // Non-legal carriage return |
| | | ' ', // Newlines and tabs |
| | | ' ', // Runs of spaces, pre-handling |
| | | '', // <script>s -- which strip_tags supposedly has problems with |
| | | '', // <style>s -- which strip_tags supposedly has problems with |
| | | "\n\n", // <P> |
| | |
| | | "\n\n", // <table> and </table> |
| | | "\n", // <tr> and </tr> |
| | | "\t\t\\1\n", // <td> and </td> |
| | | ); |
| | | |
| | | /** |
| | | * List of preg* regular expression patterns to search for, |
| | | * used in conjunction with $ent_replace. |
| | | * |
| | | * @var array $ent_search |
| | | * @access public |
| | | * @see $ent_replace |
| | | */ |
| | | var $ent_search = array( |
| | | '/&(nbsp|#160);/i', // Non-breaking space |
| | | '/&(quot|rdquo|ldquo|#8220|#8221|#147|#148);/i', |
| | | // Double quotes |
| | | '/&(apos|rsquo|lsquo|#8216|#8217);/i', // Single quotes |
| | | '/>/i', // Greater-than |
| | | '/</i', // Less-than |
| | | '/&(copy|#169);/i', // Copyright |
| | | '/&(trade|#8482|#153);/i', // Trademark |
| | | '/&(reg|#174);/i', // Registered |
| | | '/&(mdash|#151|#8212);/i', // mdash |
| | | '/&(ndash|minus|#8211|#8722);/i', // ndash |
| | | '/&(bull|#149|#8226);/i', // Bullet |
| | | '/&(pound|#163);/i', // Pound sign |
| | | '/&(euro|#8364);/i', // Euro sign |
| | | '/&(amp|#38);/i', // Ampersand: see _converter() |
| | | '/[ ]{2,}/', // Runs of spaces, post-handling |
| | | ); |
| | | |
| | | /** |
| | | * List of pattern replacements corresponding to patterns searched. |
| | | * |
| | | * @var array $ent_replace |
| | | * @access public |
| | | * @see $ent_search |
| | | */ |
| | | var $ent_replace = array( |
| | | ' ', // Non-breaking space |
| | | '"', // Double quotes |
| | | "'", // Single quotes |
| | |
| | | '£', |
| | | 'EUR', // Euro sign. ? |
| | | '|+|amp|+|', // Ampersand: see _converter() |
| | | ' ' // Runs of spaces, post-handling |
| | | ' ', // Runs of spaces, post-handling |
| | | ); |
| | | |
| | | /** |
| | |
| | | * @see _build_link_list() |
| | | */ |
| | | var $_link_list = ''; |
| | | |
| | | |
| | | /** |
| | | * Number of valid links detected in the text, used for plain text |
| | | * display (rendered similar to footnotes). |
| | |
| | | */ |
| | | var $_link_count = 0; |
| | | |
| | | /** |
| | | * Boolean flag, true if a table of link URLs should be listed after the text. |
| | | * |
| | | * @var boolean $_do_links |
| | | * @access private |
| | | * @see html2text() |
| | | /** |
| | | * Boolean flag, true if a table of link URLs should be listed after the text. |
| | | * |
| | | * @var boolean $_do_links |
| | | * @access private |
| | | * @see html2text() |
| | | */ |
| | | var $_do_links = true; |
| | | |
| | | |
| | | /** |
| | | * Constructor. |
| | | * |
| | |
| | | // Convert <PRE> |
| | | $this->_convert_pre($text); |
| | | |
| | | // Run our defined search-and-replace |
| | | // Run our defined tags search-and-replace |
| | | $text = preg_replace($this->search, $this->replace, $text); |
| | | |
| | | // Run our defined tags search-and-replace with callback |
| | | $text = preg_replace_callback($this->callback_search, array('html2text', '_preg_callback'), $text); |
| | | |
| | | // Strip any other HTML tags |
| | | $text = strip_tags($text, $this->allowed_tags); |
| | | |
| | | // Run our defined entities/characters search-and-replace |
| | | $text = preg_replace($this->ent_search, $this->ent_replace, $text); |
| | | |
| | | // Replace known html entities |
| | | $text = html_entity_decode($text, ENT_COMPAT, 'UTF-8'); |
| | | |
| | | // Run our defined search-and-replace with callback |
| | | $text = preg_replace_callback($this->callback_search, array('html2text', '_preg_callback'), $text); |
| | | |
| | | // Remove unknown/unhandled entities (this cannot be done in search-and-replace block) |
| | | $text = preg_replace('/&([a-zA-Z0-9]{2,6}|#[0-9]{2,4});/', '', $text); |
| | |
| | | // This properly handles situation of "&quot;" in input string |
| | | $text = str_replace('|+|amp|+|', '&', $text); |
| | | |
| | | // Strip any other HTML tags |
| | | $text = strip_tags($text, $this->allowed_tags); |
| | | |
| | | // Bring down number of empty lines to 2 max |
| | | $text = preg_replace("/\n\s+\n/", "\n\n", $text); |
| | | $text = preg_replace("/[\n]{3,}/", "\n\n", $text); |
| | | |
| | | // remove leading empty lines (can be produced by eg. P tag on the beginning) |
| | | $text = preg_replace('/^\n+/', '', $text); |
| | | $text = ltrim($text, "\n"); |
| | | |
| | | // Wrap the text to a readable format |
| | | // for PHP versions >= 4.0.2. Default width is 75 |
| | |
| | | if ( !$this->_do_links ) |
| | | return $display; |
| | | |
| | | if ( substr($link, 0, 7) == 'http://' || substr($link, 0, 8) == 'https://' || |
| | | substr($link, 0, 7) == 'mailto:' |
| | | ) { |
| | | if ( preg_match('!^(https?://|mailto:)!', $link) ) { |
| | | $this->_link_count++; |
| | | $this->_link_list .= '[' . $this->_link_count . "] $link\n"; |
| | | $additional = ' [' . $this->_link_count . ']'; |
| | |
| | | $RCMAIL->output->set_env('photo_placeholder', $photo_img); |
| | | unset($attrib['placeholder']); |
| | | |
| | | if (strpos($record['photo'], 'http:') === 0) |
| | | if (preg_match('!^https?://!i', $record['photo'])) |
| | | $photo_img = $record['photo']; |
| | | else if ($record['photo']) |
| | | $photo_img = $RCMAIL->url(array('_action' => 'photo', '_cid' => $record['ID'], '_source' => $SOURCE_ID)); |
| | |
| | | $mbox = get_input_value('_mbox', RCUBE_INPUT_GET, true); |
| | | $filter = get_input_value('_filter', RCUBE_INPUT_GET); |
| | | $headers = get_input_value('_headers', RCUBE_INPUT_GET); |
| | | $subject = array(); |
| | | |
| | | $search_request = md5($mbox.$filter.$str); |
| | | |
| | |
| | | list(,$srch) = explode(":", $str); |
| | | $subject['text'] = "TEXT"; |
| | | } |
| | | else if(trim($str)) |
| | | else if (strlen(trim($str))) |
| | | { |
| | | if ($headers) { |
| | | foreach(explode(',', $headers) as $header) |
| | | switch ($header) { |
| | | case 'text': $subject['text'] = 'TEXT'; break; |
| | | default: $subject[$header] = 'HEADER '.strtoupper($header); |
| | | foreach (explode(',', $headers) as $header) { |
| | | if ($header == 'text') { |
| | | // #1488208: get rid of other headers when searching by "TEXT" |
| | | $subject = array('text' => 'TEXT'); |
| | | break; |
| | | } |
| | | else { |
| | | $subject[$header] = 'HEADER '.strtoupper($header); |
| | | } |
| | | } |
| | | |
| | | // save search modifiers for the current folder to user prefs |
| | | $search_mods = $RCMAIL->config->get('search_mods', $SEARCH_MODS_DEFAULT); |
| | |
| | | } |
| | | } |
| | | |
| | | $search = $srch ? trim($srch) : trim($str); |
| | | $search = isset($srch) ? trim($srch) : trim($str); |
| | | |
| | | if ($subject) { |
| | | if (!empty($subject)) { |
| | | $search_str .= str_repeat(' OR', count($subject)-1); |
| | | foreach ($subject as $sub) |
| | | $search_str .= sprintf(" %s {%d}\r\n%s", $sub, strlen($search), $search); |
| | |
| | | |
| | | if (show && ref) { |
| | | var pos = $(ref).offset(); |
| | | obj.css({ left:pos.left, top:(pos.top + ref.offsetHeight + 2)}) |
| | | .find(':checked').prop('checked', false); |
| | | obj.css({left:pos.left, top:(pos.top + ref.offsetHeight + 2)}); |
| | | |
| | | if (rcmail.env.search_mods) { |
| | | var n, mbox = rcmail.env.mailbox, mods = rcmail.env.search_mods; |
| | | var n, all, |
| | | list = $('input:checkbox[name="s_mods[]"]', obj), |
| | | mbox = rcmail.env.mailbox, |
| | | mods = rcmail.env.search_mods; |
| | | |
| | | if (rcmail.env.task != 'addressbook') { |
| | | if (rcmail.env.task == 'mail') { |
| | | mods = mods[mbox] ? mods[mbox] : mods['*']; |
| | | |
| | | for (n in mods) |
| | | $('#s_mod_' + n).prop('checked', true); |
| | | all = 'text'; |
| | | } |
| | | else { |
| | | if (mods['*']) |
| | | $('input:checkbox[name="s_mods[]"]').map(function() { |
| | | this.checked = true; |
| | | this.disabled = this.value != '*'; |
| | | }); |
| | | else { |
| | | for (n in mods) |
| | | $('#s_mod_' + n).prop('checked', true); |
| | | } |
| | | all = '*'; |
| | | } |
| | | |
| | | if (mods[all]) |
| | | list.map(function() { |
| | | this.checked = true; |
| | | this.disabled = this.value != all; |
| | | }); |
| | | else { |
| | | list.prop('disabled', false).prop('checked', false); |
| | | for (n in mods) |
| | | $('#s_mod_' + n).prop('checked', true); |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | set_searchmod: function(elem) |
| | | { |
| | | var task = rcmail.env.task, |
| | | var all, m, task = rcmail.env.task, |
| | | mods = rcmail.env.search_mods, |
| | | mbox = rcmail.env.mailbox; |
| | | |
| | |
| | | if (task == 'mail') { |
| | | if (!mods[mbox]) |
| | | mods[mbox] = rcube_clone_object(mods['*']); |
| | | if (!elem.checked) |
| | | delete(mods[mbox][elem.value]); |
| | | else |
| | | mods[mbox][elem.value] = 1; |
| | | m = mods[mbox]; |
| | | all = 'text'; |
| | | } |
| | | else { //addressbook |
| | | if (!elem.checked) |
| | | delete(mods[elem.value]); |
| | | else |
| | | mods[elem.value] = 1; |
| | | |
| | | // mark all fields |
| | | if (elem.value == '*') { |
| | | $('input:checkbox[name="s_mods[]"]').map(function() { |
| | | if (this == elem) |
| | | return; |
| | | |
| | | if (elem.checked) { |
| | | mods[this.value] = 1; |
| | | this.checked = true; |
| | | this.disabled = true; |
| | | } |
| | | else { |
| | | this.disabled = false; |
| | | } |
| | | }); |
| | | } |
| | | m = mods; |
| | | all = '*'; |
| | | } |
| | | |
| | | rcmail.env.search_mods = mods; |
| | | if (!elem.checked) |
| | | delete(m[elem.value]); |
| | | else |
| | | m[elem.value] = 1; |
| | | |
| | | // mark all fields |
| | | if (elem.value != all) |
| | | return; |
| | | |
| | | $('input:checkbox[name="s_mods[]"]').map(function() { |
| | | if (this == elem) |
| | | return; |
| | | |
| | | this.checked = true; |
| | | if (elem.checked) { |
| | | this.disabled = true; |
| | | delete m[this.value]; |
| | | } |
| | | else { |
| | | this.disabled = false; |
| | | m[this.value] = 1; |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | listmenu: function(show) |
| | |
| | | rcmail.addEventListener('responseaftergetunread', rcube_render_mailboxlist); |
| | | rcmail.addEventListener('responseaftercheck-recent', rcube_render_mailboxlist); |
| | | rcmail.addEventListener('aftercollapse-folder', rcube_render_mailboxlist); |
| | | rcube_render_mailboxlist(); |
| | | } |
| | | |
| | | if (rcmail.env.action == 'compose') |
| | |
| | | // Abbreviate mailbox names to fit width of the container |
| | | function rcube_render_mailboxlist() |
| | | { |
| | | if (bw.ie6) // doesn't work well on IE6 |
| | | var list = $('#mailboxlist > li a, #mailboxlist ul:visible > li a'); |
| | | |
| | | // it's too slow with really big number of folders, especially on IE |
| | | if (list.length > 500 * (bw.ie ? 0.2 : 1)) |
| | | return; |
| | | |
| | | $('#mailboxlist > li a, #mailboxlist ul:visible > li a').each(function(){ |
| | | var elem = $(this); |
| | | var text = elem.data('text'); |
| | | list.each(function(){ |
| | | var elem = $(this), |
| | | text = elem.data('text'); |
| | | |
| | | if (!text) { |
| | | text = elem.text().replace(/\s+\(.+$/, ''); |
| | | elem.data('text', text); |
| | |
| | | // inspired by https://gist.github.com/24261/7fdb113f1e26111bd78c0c6fe515f6c0bf418af5 |
| | | function fit_string_to_size(str, elem, len) |
| | | { |
| | | var result = str; |
| | | var ellip = '...'; |
| | | var span = $('<b>').css({ visibility:'hidden', padding:'0px' }).appendTo(elem).get(0); |
| | | var w, span, result = str, ellip = '...'; |
| | | |
| | | // on first run, check if string fits into the length already. |
| | | span.innerHTML = result; |
| | | if (span.offsetWidth > len) { |
| | | var cut = Math.max(1, Math.floor(str.length * ((span.offsetWidth - len) / span.offsetWidth) / 2)), |
| | | mid = Math.floor(str.length / 2); |
| | | var offLeft = mid, offRight = mid; |
| | | while (true) { |
| | | offLeft = mid - cut; |
| | | offRight = mid + cut; |
| | | span.innerHTML = str.substring(0,offLeft) + ellip + str.substring(offRight); |
| | | if (!rcmail.env.tmp_span) { |
| | | // it should be appended to elem to use the same css style |
| | | // but for performance reasons we'll append it to body (once) |
| | | span = $('<b>').css({visibility: 'hidden', padding: '0px'}) |
| | | .appendTo($('body', document)).get(0); |
| | | rcmail.env.tmp_span = span; |
| | | } |
| | | else { |
| | | span = rcmail.env.tmp_span; |
| | | } |
| | | span.innerHTML = result; |
| | | |
| | | // break loop if string fits size |
| | | if (span.offsetWidth <= len || offLeft < 3) |
| | | break; |
| | | // on first run, check if string fits into the length already. |
| | | w = span.offsetWidth; |
| | | if (w > len) { |
| | | var cut = Math.max(1, Math.floor(str.length * ((w - len) / w) / 2)), |
| | | mid = Math.floor(str.length / 2), |
| | | offLeft = mid, |
| | | offRight = mid; |
| | | |
| | | cut++; |
| | | } |
| | | while (true) { |
| | | offLeft = mid - cut; |
| | | offRight = mid + cut; |
| | | span.innerHTML = str.substring(0,offLeft) + ellip + str.substring(offRight); |
| | | |
| | | // build resulting string |
| | | result = str.substring(0,offLeft) + ellip + str.substring(offRight); |
| | | // break loop if string fits size |
| | | if (offLeft < 3 || span.offsetWidth) |
| | | break; |
| | | |
| | | cut++; |
| | | } |
| | | |
| | | span.parentNode.removeChild(span); |
| | | return result; |
| | | |
| | | // build resulting string |
| | | result = str.substring(0,offLeft) + ellip + str.substring(offRight); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | // Optional parameters used by TinyMCE |
| | |
| | | $part = $this->get_html_part('src/invalidchars.html'); |
| | | $washed = rcmail_print_body($part); |
| | | |
| | | $this->assertPattern('/<p>ÑОЌвПл<\/p>/', $washed, "Remove non-unicode characters from HTML message body"); |
| | | $this->assertPattern('/<p>символ<\/p>/', $washed, "Remove non-unicode characters from HTML message body"); |
| | | } |
| | | |
| | | /** |