Changeset 77449d0 in github


Ignore:
Timestamp:
Nov 28, 2011 4:03:27 AM (18 months ago)
Author:
alecpl <alec@…>
Branches:
release-0.7
Children:
230ccba
Parents:
2a3e0276
Message:
  • Applied fixes from trunk up to r5498
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • CHANGELOG

    r3ad2b1b r77449d0  
    22=========================== 
    33 
     4- Use strpos() instead of strstr() when possible (#1488211) 
     5- Fix handling HTML entities when converting HTML to text (#1488212) 
     6- Fix fit_string_to_size() renders browser and ui unresponsive (#1488207) 
     7- Fix handling of invalid characters in request (#1488124) 
     8- Fix merging some configuration options in update.sh script (#1485864) 
     9- Fix so TEXT key will remove all HEADER keys in IMAP SEARCH (#1488208) 
     10- Fix handling contact photo url with https:// prefix (#1488202) 
    411- Fix possible infinite redirect on attachment preview (#1488199) 
    512- Improved clickjacking protection for browsers which don't support X-Frame-Options headers 
  • config/main.inc.php.dist

    r3fec695 r77449d0  
    654654$rcmail_config['timezone'] = 'auto'; 
    655655 
    656 // is daylight saving On? 
    657 $rcmail_config['dst_active'] = (bool)date('I'); 
     656// is daylight saving On? Default: (bool)date('I'); 
     657$rcmail_config['dst_active'] = null; 
    658658 
    659659// prefer displaying HTML messages 
  • installer/rcube_install.php

    r4348692 r77449d0  
    143143    foreach ($this->config as $prop => $default) { 
    144144 
    145       $value = (isset($_POST["_$prop"]) || $this->bool_config_props[$prop]) ? $_POST["_$prop"] : $default; 
     145      $is_default = !isset($_POST["_$prop"]); 
     146      $value      = !$is_default || $this->bool_config_props[$prop] ? $_POST["_$prop"] : $default; 
    146147 
    147148      // convert some form data 
    148       if ($prop == 'debug_level') { 
    149         $val = 0; 
    150         if (is_array($value)) 
     149      if ($prop == 'debug_level' && !$is_default) { 
     150        if (is_array($value)) { 
     151          $val = 0; 
    151152          foreach ($value as $dbgval) 
    152153            $val += intval($dbgval); 
    153         $value = $val; 
     154          $value = $val; 
     155        } 
    154156      } 
    155157      else if ($which == 'db' && $prop == 'db_dsnw' && !empty($_POST['_dbtype'])) { 
    156158        if ($_POST['_dbtype'] == 'sqlite') 
    157159          $value = sprintf('%s://%s?mode=0646', $_POST['_dbtype'], $_POST['_dbname']{0} == '/' ? '/' . $_POST['_dbname'] : $_POST['_dbname']); 
    158         else 
     160        else if ($_POST['_dbtype']) 
    159161          $value = sprintf('%s://%s:%s@%s/%s', $_POST['_dbtype'],  
    160162            rawurlencode($_POST['_dbuser']), rawurlencode($_POST['_dbpass']), $_POST['_dbhost'], $_POST['_dbname']); 
     
    178180      } 
    179181      else if ($prop == 'default_imap_folders') { 
    180             $value = Array(); 
     182            $value = array(); 
    181183            foreach ($this->config['default_imap_folders'] as $_folder) { 
    182               switch($_folder) { 
     184              switch ($_folder) { 
    183185              case 'Drafts': $_folder = $this->config['drafts_mbox']; break; 
    184186              case 'Sent':   $_folder = $this->config['sent_mbox']; break; 
     
    207209      $out = preg_replace( 
    208210        '/(\$rcmail_config\[\''.preg_quote($prop).'\'\])\s+=\s+(.+);/Uie', 
    209         "'\\1 = ' . rcube_install::_dump_var(\$value) . ';'", 
     211        "'\\1 = ' . rcube_install::_dump_var(\$value, \$prop) . ';'", 
    210212        $out); 
    211213    } 
     
    300302    $this->config = array(); 
    301303    $this->load_defaults(); 
    302      
     304 
    303305    foreach ($this->replaced_config as $prop => $replacement) { 
    304306      if (isset($current[$prop])) { 
     
    329331    if ($current['keep_alive'] && $current['session_lifetime'] < $current['keep_alive']) 
    330332      $current['session_lifetime'] = max(10, ceil($current['keep_alive'] / 60) * 2); 
    331      
     333 
    332334    $this->config  = array_merge($this->config, $current); 
    333      
     335 
    334336    foreach ((array)$current['ldap_public'] as $key => $values) { 
    335337      $this->config['ldap_public'][$key] = $current['ldap_public'][$key]; 
     
    615617   
    616618   
    617   static function _dump_var($var) { 
     619  static function _dump_var($var, $name=null) { 
     620    // special values 
     621    switch ($name) { 
     622    case 'syslog_facility': 
     623      $list = array(32 => 'LOG_AUTH', 80 => 'LOG_AUTHPRIV', 72 => ' LOG_CRON', 
     624                    24 => 'LOG_DAEMON', 0 => 'LOG_KERN', 128 => 'LOG_LOCAL0', 
     625                    136 => 'LOG_LOCAL1', 144 => 'LOG_LOCAL2', 152 => 'LOG_LOCAL3', 
     626                    160 => 'LOG_LOCAL4', 168 => 'LOG_LOCAL5', 176 => 'LOG_LOCAL6', 
     627                    184 => 'LOG_LOCAL7', 48 => 'LOG_LPR', 16 => 'LOG_MAIL', 
     628                    56 => 'LOG_NEWS', 40 => 'LOG_SYSLOG', 8 => 'LOG_USER', 64 => 'LOG_UUCP'); 
     629      if ($val = $list[$var]) 
     630        return $val; 
     631      break; 
     632    } 
     633 
     634 
    618635    if (is_array($var)) { 
    619636      if (empty($var)) { 
  • program/include/main.inc

    r3ad2b1b r77449d0  
    641641{ 
    642642  $value = NULL; 
    643    
    644   if ($source==RCUBE_INPUT_GET && isset($_GET[$fname])) 
    645     $value = $_GET[$fname]; 
    646   else if ($source==RCUBE_INPUT_POST && isset($_POST[$fname])) 
    647     $value = $_POST[$fname]; 
    648   else if ($source==RCUBE_INPUT_GPC) 
    649     { 
     643 
     644  if ($source == RCUBE_INPUT_GET) { 
     645    if (isset($_GET[$fname])) 
     646      $value = $_GET[$fname]; 
     647  } 
     648  else if ($source == RCUBE_INPUT_POST) { 
     649    if (isset($_POST[$fname])) 
     650      $value = $_POST[$fname]; 
     651  } 
     652  else if ($source == RCUBE_INPUT_GPC) { 
    650653    if (isset($_POST[$fname])) 
    651654      $value = $_POST[$fname]; 
     
    654657    else if (isset($_COOKIE[$fname])) 
    655658      $value = $_COOKIE[$fname]; 
    656     } 
     659  } 
    657660 
    658661  return parse_input_value($value, $allow_html, $charset); 
     
    662665 * Parse/validate input value. See get_input_value() 
    663666 * Performs stripslashes() and charset conversion if necessary 
    664  *  
     667 * 
    665668 * @param  string   Input value 
    666669 * @param  boolean  Allow HTML tags in field value 
     
    688691    $value = stripslashes($value); 
    689692 
    690   // remove HTML tags if not allowed     
     693  // remove HTML tags if not allowed 
    691694  if (!$allow_html) 
    692695    $value = strip_tags($value); 
    693    
     696 
     697  $output_charset = is_object($OUTPUT) ? $OUTPUT->get_charset() : null; 
     698 
     699  // remove invalid characters (#1488124) 
     700  if ($output_charset == 'UTF-8') 
     701    $value = rc_utf8_clean($value); 
     702 
    694703  // convert to internal charset 
    695   if (is_object($OUTPUT) && $charset) 
    696     return rcube_charset_convert($value, $OUTPUT->get_charset(), $charset); 
    697   else 
    698     return $value; 
     704  if ($charset && $output_charset) 
     705    $value = rcube_charset_convert($value, $output_charset, $charset); 
     706 
     707  return $value; 
    699708} 
    700709 
     
    712721  foreach ($src as $key => $value) { 
    713722    $fname = $key[0] == '_' ? substr($key, 1) : $key; 
    714     if ($ignore && !preg_match("/($ignore)/", $fname)) 
     723    if ($ignore && !preg_match('/^(' . $ignore . ')$/', $fname)) 
    715724      $out[$fname] = get_input_value($key, $mode); 
    716725  } 
    717    
     726 
    718727  return $out; 
    719728} 
  • program/include/rcube_browser.php

    rdcf8112 r77449d0  
    3434 
    3535        $this->ver = 0; 
    36         $this->win = strstr($HTTP_USER_AGENT, 'win'); 
    37         $this->mac = strstr($HTTP_USER_AGENT, 'mac'); 
    38         $this->linux = strstr($HTTP_USER_AGENT, 'linux'); 
    39         $this->unix  = strstr($HTTP_USER_AGENT, 'unix'); 
     36        $this->win = strpos($HTTP_USER_AGENT, 'win') != false; 
     37        $this->mac = strpos($HTTP_USER_AGENT, 'mac') != false; 
     38        $this->linux = strpos($HTTP_USER_AGENT, 'linux') != false; 
     39        $this->unix  = strpos($HTTP_USER_AGENT, 'unix') != false; 
    4040 
    41         $this->opera = strstr($HTTP_USER_AGENT, 'opera'); 
    42         $this->ns4 = strstr($HTTP_USER_AGENT, 'mozilla/4') && !stristr($HTTP_USER_AGENT, 'msie'); 
    43         $this->ns  = ($this->ns4 || strstr($HTTP_USER_AGENT, 'netscape')); 
    44         $this->ie  = !$this->opera && stristr($HTTP_USER_AGENT, 'compatible; msie'); 
    45         $this->mz  = !$this->ie && strstr($HTTP_USER_AGENT, 'mozilla/5'); 
    46         $this->chrome = strstr($HTTP_USER_AGENT, 'chrome'); 
    47         $this->khtml = strstr($HTTP_USER_AGENT, 'khtml'); 
    48         $this->safari = !$this->chrome && ($this->khtml || strstr($HTTP_USER_AGENT, 'safari')); 
     41        $this->opera = strpos($HTTP_USER_AGENT, 'opera') !== false; 
     42        $this->ns4 = strpos($HTTP_USER_AGENT, 'mozilla/4') !== false && strpos($HTTP_USER_AGENT, 'msie') === false; 
     43        $this->ns  = ($this->ns4 || strpos($HTTP_USER_AGENT, 'netscape') !== false); 
     44        $this->ie  = !$this->opera && strpos($HTTP_USER_AGENT, 'compatible; msie') !== false; 
     45        $this->mz  = !$this->ie && strpos($HTTP_USER_AGENT, 'mozilla/5') !== false; 
     46        $this->chrome = strpos($HTTP_USER_AGENT, 'chrome') !== false; 
     47        $this->khtml = strpos($HTTP_USER_AGENT, 'khtml') !== false; 
     48        $this->safari = !$this->chrome && ($this->khtml || strpos($HTTP_USER_AGENT, 'safari') !== false); 
    4949 
    5050        if ($this->ns || $this->chrome) { 
  • program/include/rcube_config.php

    rf4f4354f r77449d0  
    9191        // enable display_errors in 'show' level, but not for ajax requests 
    9292        ini_set('display_errors', intval(empty($_REQUEST['_remote']) && ($this->prop['debug_level'] & 4))); 
    93          
     93 
    9494        // set timezone auto settings values 
    9595        if ($this->prop['timezone'] == 'auto') { 
    9696          $this->prop['dst_active'] = intval(date('I')); 
    97           $this->prop['_timezone_value']   = date('Z') / 3600 - $this->prop['dst_active']; 
     97          $this->prop['_timezone_value'] = date('Z') / 3600 - $this->prop['dst_active']; 
     98        } 
     99        else if ($this->prop['dst_active'] === null) { 
     100          $this->prop['dst_active'] = intval(date('I')); 
    98101        } 
    99102 
  • program/include/rcube_smtp.php

    rfb40f37 r77449d0  
    382382 
    383383        // Reject envelope From: addresses with spaces. 
    384         if (strstr($from, ' ')) 
     384        if (strpos($from, ' ') !== false) 
    385385          return false; 
    386386 
  • program/js/app.js

    r3ad2b1b r77449d0  
    57445744  }; 
    57455745 
    5746   this.plain2html = function(plainText, id) 
     5746  this.plain2html = function(plain, id) 
    57475747  { 
    57485748    var lock = this.set_busy(true, 'converting'); 
    5749     $('#'+id).val(plainText ? '<pre>'+plainText+'</pre>' : ''); 
     5749 
     5750    plain = plain.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); 
     5751    $('#'+id).val(plain ? '<pre>'+plain+'</pre>' : ''); 
     5752 
    57505753    this.set_busy(false, null, lock); 
    57515754  }; 
  • program/lib/html2text.php

    r4d7fbd5 r77449d0  
    146146        "/\r/",                                  // Non-legal carriage return 
    147147        "/[\n\t]+/",                             // Newlines and tabs 
    148         '/[ ]{2,}/',                             // Runs of spaces, pre-handling 
    149148        '/<script[^>]*>.*?<\/script>/i',         // <script>s -- which strip_tags supposedly has problems with 
    150149        '/<style[^>]*>.*?<\/style>/i',           // <style>s -- which strip_tags supposedly has problems with 
     
    162161        '/(<tr[^>]*>|<\/tr>)/i',                 // <tr> and </tr> 
    163162        '/<td[^>]*>(.*?)<\/td>/i',               // <td> and </td> 
     163    ); 
     164 
     165    /** 
     166     *  List of pattern replacements corresponding to patterns searched. 
     167     * 
     168     *  @var array $replace 
     169     *  @access public 
     170     *  @see $search 
     171     */ 
     172    var $replace = array( 
     173        '',                                     // Non-legal carriage return 
     174        ' ',                                    // Newlines and tabs 
     175        '',                                     // <script>s -- which strip_tags supposedly has problems with 
     176        '',                                     // <style>s -- which strip_tags supposedly has problems with 
     177        "\n\n",                                 // <P> 
     178        "\n",                                   // <br> 
     179        '_\\1_',                                // <i> 
     180        '_\\1_',                                // <em> 
     181        "\n\n",                                 // <ul> and </ul> 
     182        "\n\n",                                 // <ol> and </ol> 
     183        "\t* \\1\n",                            // <li> and </li> 
     184        "\n\t* ",                               // <li> 
     185        "\n-------------------------\n",        // <hr> 
     186        "<div>\n",                              // <div> 
     187        "\n\n",                                 // <table> and </table> 
     188        "\n",                                   // <tr> and </tr> 
     189        "\t\t\\1\n",                            // <td> and </td> 
     190    ); 
     191 
     192    /** 
     193     *  List of preg* regular expression patterns to search for, 
     194     *  used in conjunction with $ent_replace. 
     195     * 
     196     *  @var array $ent_search 
     197     *  @access public 
     198     *  @see $ent_replace 
     199     */ 
     200    var $ent_search = array( 
    164201        '/&(nbsp|#160);/i',                      // Non-breaking space 
    165202        '/&(quot|rdquo|ldquo|#8220|#8221|#147|#148);/i', 
     
    177214        '/&(euro|#8364);/i',                     // Euro sign 
    178215        '/&(amp|#38);/i',                        // Ampersand: see _converter() 
    179         '/[ ]{2,}/'                              // Runs of spaces, post-handling 
     216        '/[ ]{2,}/',                             // Runs of spaces, post-handling 
    180217    ); 
    181218 
     
    183220     *  List of pattern replacements corresponding to patterns searched. 
    184221     * 
    185      *  @var array $replace 
    186      *  @access public 
    187      *  @see $search 
    188      */ 
    189     var $replace = array( 
    190         '',                                     // Non-legal carriage return 
    191         ' ',                                    // Newlines and tabs 
    192         ' ',                                    // Runs of spaces, pre-handling 
    193         '',                                     // <script>s -- which strip_tags supposedly has problems with 
    194         '',                                     // <style>s -- which strip_tags supposedly has problems with 
    195         "\n\n",                                 // <P> 
    196         "\n",                                   // <br> 
    197         '_\\1_',                                // <i> 
    198         '_\\1_',                                // <em> 
    199         "\n\n",                                 // <ul> and </ul> 
    200         "\n\n",                                 // <ol> and </ol> 
    201         "\t* \\1\n",                            // <li> and </li> 
    202         "\n\t* ",                               // <li> 
    203         "\n-------------------------\n",        // <hr> 
    204         "<div>\n",                              // <div> 
    205         "\n\n",                                 // <table> and </table> 
    206         "\n",                                   // <tr> and </tr> 
    207         "\t\t\\1\n",                            // <td> and </td> 
     222     *  @var array $ent_replace 
     223     *  @access public 
     224     *  @see $ent_search 
     225     */ 
     226    var $ent_replace = array( 
    208227        ' ',                                    // Non-breaking space 
    209228        '"',                                    // Double quotes 
     
    220239        'EUR',                                  // Euro sign. € ? 
    221240        '|+|amp|+|',                            // Ampersand: see _converter() 
    222         ' '                                     // Runs of spaces, post-handling 
     241        ' ',                                    // Runs of spaces, post-handling 
    223242    ); 
    224243 
     
    304323     */ 
    305324    var $_link_list = ''; 
    306      
     325 
    307326    /** 
    308327     *  Number of valid links detected in the text, used for plain text 
     
    315334    var $_link_count = 0; 
    316335 
    317     /**  
    318      * Boolean flag, true if a table of link URLs should be listed after the text.  
    319      *   
    320      * @var boolean $_do_links  
    321      * @access private  
    322      * @see html2text()  
     336    /** 
     337     * Boolean flag, true if a table of link URLs should be listed after the text. 
     338     * 
     339     * @var boolean $_do_links 
     340     * @access private 
     341     * @see html2text() 
    323342     */ 
    324343    var $_do_links = true; 
    325   
     344 
    326345    /** 
    327346     *  Constructor. 
     
    493512        $this->_convert_pre($text); 
    494513 
    495         // Run our defined search-and-replace 
     514        // Run our defined tags search-and-replace 
    496515        $text = preg_replace($this->search, $this->replace, $text); 
     516 
     517        // Run our defined tags search-and-replace with callback 
     518        $text = preg_replace_callback($this->callback_search, array('html2text', '_preg_callback'), $text); 
     519 
     520        // Strip any other HTML tags 
     521        $text = strip_tags($text, $this->allowed_tags); 
     522 
     523        // Run our defined entities/characters search-and-replace 
     524        $text = preg_replace($this->ent_search, $this->ent_replace, $text); 
    497525 
    498526        // Replace known html entities 
    499527        $text = html_entity_decode($text, ENT_COMPAT, 'UTF-8'); 
    500  
    501         // Run our defined search-and-replace with callback 
    502         $text = preg_replace_callback($this->callback_search, array('html2text', '_preg_callback'), $text); 
    503528 
    504529        // Remove unknown/unhandled entities (this cannot be done in search-and-replace block) 
     
    509534        $text = str_replace('|+|amp|+|', '&', $text); 
    510535 
    511         // Strip any other HTML tags 
    512         $text = strip_tags($text, $this->allowed_tags); 
    513  
    514536        // Bring down number of empty lines to 2 max 
    515537        $text = preg_replace("/\n\s+\n/", "\n\n", $text); 
     
    517539 
    518540        // remove leading empty lines (can be produced by eg. P tag on the beginning) 
    519         $text = preg_replace('/^\n+/', '', $text); 
     541        $text = ltrim($text, "\n"); 
    520542 
    521543        // Wrap the text to a readable format 
     
    545567                return $display; 
    546568 
    547             if ( substr($link, 0, 7) == 'http://' || substr($link, 0, 8) == 'https://' || 
    548             substr($link, 0, 7) == 'mailto:' 
    549         ) { 
     569            if ( preg_match('!^(https?://|mailto:)!', $link) ) { 
    550570            $this->_link_count++; 
    551571            $this->_link_list .= '[' . $this->_link_count . "] $link\n"; 
  • program/steps/addressbook/func.inc

    r51f7a5b r77449d0  
    706706    unset($attrib['placeholder']); 
    707707 
    708     if (strpos($record['photo'], 'http:') === 0) 
     708    if (preg_match('!^https?://!i', $record['photo'])) 
    709709        $photo_img = $record['photo']; 
    710710    else if ($record['photo']) 
  • program/steps/mail/search.inc

    rb1f0846 r77449d0  
    3232$filter  = get_input_value('_filter', RCUBE_INPUT_GET); 
    3333$headers = get_input_value('_headers', RCUBE_INPUT_GET); 
     34$subject = array(); 
    3435 
    3536$search_request = md5($mbox.$filter.$str); 
     
    7172  $subject['text'] = "TEXT"; 
    7273} 
    73 else if(trim($str)) 
     74else if (strlen(trim($str))) 
    7475{ 
    7576  if ($headers) { 
    76     foreach(explode(',', $headers) as $header) 
    77       switch ($header) { 
    78         case 'text': $subject['text'] = 'TEXT'; break; 
    79         default:     $subject[$header] = 'HEADER '.strtoupper($header); 
     77    foreach (explode(',', $headers) as $header) { 
     78      if ($header == 'text') { 
     79        // #1488208: get rid of other headers when searching by "TEXT" 
     80        $subject = array('text' => 'TEXT'); 
     81        break; 
    8082      } 
     83      else { 
     84        $subject[$header] = 'HEADER '.strtoupper($header); 
     85      } 
     86    } 
    8187 
    8288    // save search modifiers for the current folder to user prefs 
     
    9096} 
    9197 
    92 $search = $srch ? trim($srch) : trim($str); 
     98$search = isset($srch) ? trim($srch) : trim($str); 
    9399 
    94 if ($subject) { 
     100if (!empty($subject)) { 
    95101  $search_str .= str_repeat(' OR', count($subject)-1); 
    96102  foreach ($subject as $sub) 
  • skins/default/functions.js

    r4b09fb6 r77449d0  
    193193  if (show && ref) { 
    194194    var pos = $(ref).offset(); 
    195     obj.css({ left:pos.left, top:(pos.top + ref.offsetHeight + 2)}) 
    196         .find(':checked').prop('checked', false); 
     195    obj.css({left:pos.left, top:(pos.top + ref.offsetHeight + 2)}); 
    197196 
    198197    if (rcmail.env.search_mods) { 
    199       var n, mbox = rcmail.env.mailbox, mods = rcmail.env.search_mods; 
    200  
    201       if (rcmail.env.task != 'addressbook') { 
     198      var n, all, 
     199        list = $('input:checkbox[name="s_mods[]"]', obj), 
     200        mbox = rcmail.env.mailbox, 
     201        mods = rcmail.env.search_mods; 
     202 
     203      if (rcmail.env.task == 'mail') { 
    202204        mods = mods[mbox] ? mods[mbox] : mods['*']; 
    203  
     205        all = 'text'; 
     206      } 
     207      else { 
     208        all = '*'; 
     209      } 
     210 
     211      if (mods[all]) 
     212        list.map(function() { 
     213          this.checked = true; 
     214          this.disabled = this.value != all; 
     215        }); 
     216      else { 
     217        list.prop('disabled', false).prop('checked', false); 
    204218        for (n in mods) 
    205219          $('#s_mod_' + n).prop('checked', true); 
    206220      } 
    207       else { 
    208         if (mods['*']) 
    209           $('input:checkbox[name="s_mods[]"]').map(function() { 
    210             this.checked = true; 
    211             this.disabled = this.value != '*'; 
    212           }); 
    213         else { 
    214           for (n in mods) 
    215             $('#s_mod_' + n).prop('checked', true); 
    216         } 
    217       } 
    218221    } 
    219222  } 
     
    223226set_searchmod: function(elem) 
    224227{ 
    225   var task = rcmail.env.task, 
     228  var all, m, task = rcmail.env.task, 
    226229    mods = rcmail.env.search_mods, 
    227230    mbox = rcmail.env.mailbox; 
     
    233236    if (!mods[mbox]) 
    234237      mods[mbox] = rcube_clone_object(mods['*']); 
    235     if (!elem.checked) 
    236       delete(mods[mbox][elem.value]); 
    237     else 
    238       mods[mbox][elem.value] = 1; 
     238    m = mods[mbox]; 
     239    all = 'text'; 
    239240  } 
    240241  else { //addressbook 
    241     if (!elem.checked) 
    242       delete(mods[elem.value]); 
    243     else 
    244       mods[elem.value] = 1; 
    245  
    246     // mark all fields 
    247     if (elem.value == '*') { 
    248       $('input:checkbox[name="s_mods[]"]').map(function() { 
    249         if (this == elem) 
    250           return; 
    251  
    252         if (elem.checked) { 
    253           mods[this.value] = 1; 
    254           this.checked = true; 
    255           this.disabled = true; 
    256         } 
    257         else { 
    258           this.disabled = false; 
    259         } 
    260       }); 
    261     } 
    262   } 
    263  
    264   rcmail.env.search_mods = mods; 
     242    m = mods; 
     243    all = '*'; 
     244  } 
     245 
     246  if (!elem.checked) 
     247    delete(m[elem.value]); 
     248  else 
     249    m[elem.value] = 1; 
     250 
     251  // mark all fields 
     252  if (elem.value != all) 
     253    return; 
     254 
     255  $('input:checkbox[name="s_mods[]"]').map(function() { 
     256    if (this == elem) 
     257      return; 
     258 
     259    this.checked = true; 
     260    if (elem.checked) { 
     261      this.disabled = true; 
     262      delete m[this.value]; 
     263    } 
     264    else { 
     265      this.disabled = false; 
     266      m[this.value] = 1; 
     267    } 
     268  }); 
    265269}, 
    266270 
     
    567571      rcmail.addEventListener('responseaftercheck-recent', rcube_render_mailboxlist); 
    568572      rcmail.addEventListener('aftercollapse-folder', rcube_render_mailboxlist); 
    569       rcube_render_mailboxlist(); 
    570573    } 
    571574 
     
    589592function rcube_render_mailboxlist() 
    590593{ 
    591   if (bw.ie6)  // doesn't work well on IE6 
     594  var list = $('#mailboxlist > li a, #mailboxlist ul:visible > li a'); 
     595 
     596  // it's too slow with really big number of folders, especially on IE 
     597  if (list.length > 500 * (bw.ie ? 0.2 : 1)) 
    592598    return; 
    593599 
    594   $('#mailboxlist > li a, #mailboxlist ul:visible > li a').each(function(){ 
    595     var elem = $(this); 
    596     var text = elem.data('text'); 
     600  list.each(function(){ 
     601    var elem = $(this), 
     602      text = elem.data('text'); 
     603 
    597604    if (!text) { 
    598605      text = elem.text().replace(/\s+\(.+$/, ''); 
     
    612619function fit_string_to_size(str, elem, len) 
    613620{ 
    614     var result = str; 
    615     var ellip = '...'; 
    616     var span = $('<b>').css({ visibility:'hidden', padding:'0px' }).appendTo(elem).get(0); 
    617  
    618     // on first run, check if string fits into the length already. 
    619     span.innerHTML = result; 
    620     if (span.offsetWidth > len) { 
    621         var cut = Math.max(1, Math.floor(str.length * ((span.offsetWidth - len) / span.offsetWidth) / 2)), 
    622           mid = Math.floor(str.length / 2); 
    623         var offLeft = mid, offRight = mid; 
    624         while (true) { 
    625             offLeft = mid - cut; 
    626             offRight = mid + cut; 
    627             span.innerHTML = str.substring(0,offLeft) + ellip + str.substring(offRight); 
    628  
    629             // break loop if string fits size 
    630             if (span.offsetWidth <= len || offLeft < 3) 
    631               break; 
    632  
    633             cut++; 
    634         } 
    635  
    636         // build resulting string 
    637         result = str.substring(0,offLeft) + ellip + str.substring(offRight); 
    638     } 
    639      
    640     span.parentNode.removeChild(span); 
    641     return result; 
     621  var w, span, result = str, ellip = '...'; 
     622 
     623  if (!rcmail.env.tmp_span) { 
     624    // it should be appended to elem to use the same css style 
     625    // but for performance reasons we'll append it to body (once) 
     626    span = $('<b>').css({visibility: 'hidden', padding: '0px'}) 
     627      .appendTo($('body', document)).get(0); 
     628    rcmail.env.tmp_span = span; 
     629  } 
     630  else { 
     631    span = rcmail.env.tmp_span; 
     632  } 
     633  span.innerHTML = result; 
     634 
     635  // on first run, check if string fits into the length already. 
     636  w = span.offsetWidth; 
     637  if (w > len) { 
     638    var cut = Math.max(1, Math.floor(str.length * ((w - len) / w) / 2)), 
     639      mid = Math.floor(str.length / 2), 
     640      offLeft = mid, 
     641      offRight = mid; 
     642 
     643    while (true) { 
     644      offLeft = mid - cut; 
     645      offRight = mid + cut; 
     646      span.innerHTML = str.substring(0,offLeft) + ellip + str.substring(offRight); 
     647 
     648      // break loop if string fits size 
     649      if (offLeft < 3 || span.offsetWidth) 
     650        break; 
     651 
     652      cut++; 
     653    } 
     654 
     655    // build resulting string 
     656    result = str.substring(0,offLeft) + ellip + str.substring(offRight); 
     657  } 
     658 
     659  return result; 
    642660} 
    643661 
  • tests/mailfunc.php

    r3ad2b1b r77449d0  
    107107    $washed = rcmail_print_body($part); 
    108108 
    109     $this->assertPattern('/<p>ÑÐşÐŒÐ²ÐŞÐ»<\/p>/', $washed, "Remove non-unicode characters from HTML message body"); 
     109    $this->assertPattern('/<p>сОЌвПл<\/p>/', $washed, "Remove non-unicode characters from HTML message body"); 
    110110  } 
    111111 
Note: See TracChangeset for help on using the changeset viewer.