Changeset 1661

Show
Ignore:
Timestamp:
02/24/08 20:46:26 (3 months ago)
Author:
neuro
Message:

Adding js localization for dates with french translation.

Port by Eric Daspet

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/app/helpers/application_helper.rb

    r1653 r1661  
    4040 
    4141  def js_distance_of_time_in_words_to_now(date) 
    42     time = date.utc.strftime("%a, %d %b %Y %H:%M:%S GMT") 
    43     "<span class=\"typo_date\" title=\"#{time}\">#{time}</span>" 
     42    time = _(date.utc.strftime(_("%%a, %%d %%b %%Y %%H:%%M:%%S GMT", date.utc))) 
     43    timestamp = date.utc.to_i ; 
     44    "<span class=\"typo_date date gmttimestamp-#{timestamp}\" title=\"#{time}\" >#{time}</span>" 
    4445  end 
    4546 
     
    4950 
    5051  def date(date) 
    51     "<span class=\"typo_date\">#{date.utc.strftime("%d. %b")}</span>" 
     52    "<span class=\"typo_date\">" + date.utc.strftime(_("%%d. %%b", date.utc)) + "</span>" 
    5253  end 
    5354 
     
    197198  <link rel="alternate" type="application/atom+xml" title="Atom" href="#{ @auto_discovery_url_atom }" /> 
    198199  <link rel="alternate" type="application/rss+xml" title="RSS" href="#{ @auto_discovery_url_rss }" /> 
     200  #{ javascript_include_tag "lang/" + Localization.lang } 
    199201  #{ javascript_include_tag "cookies" } 
    200202  #{ javascript_include_tag "prototype" } 
  • trunk/lang/fr_FR.rb

    r1653 r1661  
    616616  l.store "comments", "commentaires" 
    617617  l.store "posted in", "publié dans" 
     618   
     619  # Dates  
     620  l.store "Mon", "Lun" 
     621  l.store "Tue", "Mar" 
     622  l.store "Wed", "Mer" 
     623  l.store "Thu", "Jeu"   
     624  l.store "Fri", "Ven"   
     625  l.store "Sat", "Sam"   
     626  l.store "Sun", "Dim" 
     627  l.store "Monday", "Lundi" 
     628  l.store "Tuesday", "Mardi" 
     629  l.store "Wednesday", "Mercredi" 
     630  l.store "Thursday", "Jeudi"   
     631  l.store "Friday", "Vendredi"   
     632  l.store "Saturday", "Samedi"   
     633  l.store "Sunday", "Dimanche" 
     634  l.store "Jan", "Jan"     
     635  l.store "Feb", "Fév" 
     636  l.store "Mar", "Mars" 
     637  l.store "Apr", "Avr" 
     638  l.store "May", "Mai" 
     639  l.store "Jun", "Juin" 
     640  l.store "Jul", "Juil" 
     641  l.store "Aug", "Août" 
     642  l.store "Sep", "Sept" 
     643  l.store "Oct", "Oct" 
     644  l.store "Nov", "Nov" 
     645  l.store "Dec", "Déc" 
     646  l.store "January", "Janvier"     
     647  l.store "February", "Février" 
     648  l.store "March", "Mars" 
     649  l.store "April", "Avril" 
     650  l.store "May", "Mai" 
     651  l.store "June", "Juin" 
     652  l.store "July", "Juillet" 
     653  l.store "August", "Août" 
     654  l.store "September", "September" 
     655  l.store "October", "Octorbre" 
     656  l.store "November", "Novembre" 
     657  l.store "December", "Décembre" 
     658  l.store "%%a, %%d %%b %%Y %%H:%%M:%%S GMT", Proc.new {|date| 
     659     sprintf( date.strftime("%%s %d %%s %Y %H:%M:%S GMT"), _(date.strftime("%a")), _(date.strftime("%b")).downcase ) 
     660  } 
     661  l.store "%%d. %%b", Proc.new {|date| 
     662     sprintf( date.strftime("%d. %%s"), _(date.strftime("%b")).downcase ) 
     663  } 
     664 
    618665end 
  • trunk/public/javascripts/prototype.js

    r1358 r1661  
    1 /*  Prototype JavaScript framework, version 1.5.0 
     1/*  Prototype JavaScript framework, version 1.6.0 
    22 *  (c) 2005-2007 Sam Stephenson 
    33 * 
    44 *  Prototype is freely distributable under the terms of an MIT-style license. 
    5  *  For details, see the Prototype web site: http://prototype.conio.net
     5 *  For details, see the Prototype web site: http://www.prototypejs.org
    66 * 
    7 /*--------------------------------------------------------------------------*/ 
     7 *--------------------------------------------------------------------------*/ 
    88 
    99var Prototype = { 
    10   Version: '1.5.0', 
     10  Version: '1.6.0', 
     11 
     12  Browser: { 
     13    IE:     !!(window.attachEvent && !window.opera), 
     14    Opera:  !!window.opera, 
     15    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, 
     16    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1, 
     17    MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/) 
     18  }, 
     19 
    1120  BrowserFeatures: { 
    12     XPath: !!document.evaluate 
    13   }, 
    14  
    15   ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)', 
    16   emptyFunction: function() {}, 
     21    XPath: !!document.evaluate, 
     22    ElementExtensions: !!window.HTMLElement, 
     23    SpecificElementExtensions: 
     24      document.createElement('div').__proto__ && 
     25      document.createElement('div').__proto__ !== 
     26        document.createElement('form').__proto__ 
     27  }, 
     28 
     29  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>', 
     30  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, 
     31 
     32  emptyFunction: function() { }, 
    1733  K: function(x) { return x } 
    18 
    19  
     34}; 
     35 
     36if (Prototype.Browser.MobileSafari) 
     37  Prototype.BrowserFeatures.SpecificElementExtensions = false; 
     38 
     39if (Prototype.Browser.WebKit) 
     40  Prototype.BrowserFeatures.XPath = false; 
     41 
     42/* Based on Alex Arnell's inheritance implementation. */ 
    2043var Class = { 
    2144  create: function() { 
    22     return function() { 
     45    var parent = null, properties = $A(arguments); 
     46    if (Object.isFunction(properties[0])) 
     47      parent = properties.shift(); 
     48 
     49    function klass() { 
    2350      this.initialize.apply(this, arguments); 
    2451    } 
    25   } 
    26 
    27  
    28 var Abstract = new Object(); 
     52 
     53    Object.extend(klass, Class.Methods); 
     54    klass.superclass = parent; 
     55    klass.subclasses = []; 
     56 
     57    if (parent) { 
     58      var subclass = function() { }; 
     59      subclass.prototype = parent.prototype; 
     60      klass.prototype = new subclass; 
     61      parent.subclasses.push(klass); 
     62    } 
     63 
     64    for (var i = 0; i < properties.length; i++) 
     65      klass.addMethods(properties[i]); 
     66 
     67    if (!klass.prototype.initialize) 
     68      klass.prototype.initialize = Prototype.emptyFunction; 
     69 
     70    klass.prototype.constructor = klass; 
     71 
     72    return klass; 
     73  } 
     74}; 
     75 
     76Class.Methods = { 
     77  addMethods: function(source) { 
     78    var ancestor   = this.superclass && this.superclass.prototype; 
     79    var properties = Object.keys(source); 
     80 
     81    if (!Object.keys({ toString: true }).length) 
     82      properties.push("toString", "valueOf"); 
     83 
     84    for (var i = 0, length = properties.length; i < length; i++) { 
     85      var property = properties[i], value = source[property]; 
     86      if (ancestor && Object.isFunction(value) && 
     87          value.argumentNames().first() == "$super") { 
     88        var method = value, value = Object.extend((function(m) { 
     89          return function() { return ancestor[m].apply(this, arguments) }; 
     90        })(property).wrap(method), { 
     91          valueOf:  function() { return method }, 
     92          toString: function() { return method.toString() } 
     93        }); 
     94      } 
     95      this.prototype[property] = value; 
     96    } 
     97 
     98    return this; 
     99  } 
     100}; 
     101 
     102var Abstract = { }; 
    29103 
    30104Object.extend = function(destination, source) { 
    31   for (var property in source) { 
     105  for (var property in source) 
    32106    destination[property] = source[property]; 
    33   } 
    34107  return destination; 
    35 } 
     108}; 
    36109 
    37110Object.extend(Object, { 
     
    47120  }, 
    48121 
     122  toJSON: function(object) { 
     123    var type = typeof object; 
     124    switch (type) { 
     125      case 'undefined': 
     126      case 'function': 
     127      case 'unknown': return; 
     128      case 'boolean': return object.toString(); 
     129    } 
     130 
     131    if (object === null) return 'null'; 
     132    if (object.toJSON) return object.toJSON(); 
     133    if (Object.isElement(object)) return; 
     134 
     135    var results = []; 
     136    for (var property in object) { 
     137      var value = Object.toJSON(object[property]); 
     138      if (value !== undefined) 
     139        results.push(property.toJSON() + ': ' + value); 
     140    } 
     141 
     142    return '{' + results.join(', ') + '}'; 
     143  }, 
     144 
     145  toQueryString: function(object) { 
     146    return $H(object).toQueryString(); 
     147  }, 
     148 
     149  toHTML: function(object) { 
     150    return object && object.toHTML ? object.toHTML() : String.interpret(object); 
     151  }, 
     152 
    49153  keys: function(object) { 
    50154    var keys = []; 
     
    62166 
    63167  clone: function(object) { 
    64     return Object.extend({}, object); 
     168    return Object.extend({ }, object); 
     169  }, 
     170 
     171  isElement: function(object) { 
     172    return object && object.nodeType == 1; 
     173  }, 
     174 
     175  isArray: function(object) { 
     176    return object && object.constructor === Array; 
     177  }, 
     178 
     179  isHash: function(object) { 
     180    return object instanceof Hash; 
     181  }, 
     182 
     183  isFunction: function(object) { 
     184    return typeof object == "function"; 
     185  }, 
     186 
     187  isString: function(object) { 
     188    return typeof object == "string"; 
     189  }, 
     190 
     191  isNumber: function(object) { 
     192    return typeof object == "number"; 
     193  }, 
     194 
     195  isUndefined: function(object) { 
     196    return typeof object == "undefined"; 
    65197  } 
    66198}); 
    67199 
    68 Function.prototype.bind = function() { 
    69   var __method = this, args = $A(arguments), object = args.shift(); 
    70   return function() { 
    71     return __method.apply(object, args.concat($A(arguments))); 
    72   } 
    73 
    74  
    75 Function.prototype.bindAsEventListener = function(object) { 
    76   var __method = this, args = $A(arguments), object = args.shift(); 
    77   return function(event) { 
    78     return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments))); 
    79   } 
    80 
    81  
    82 Object.extend(Number.prototype, { 
    83   toColorPart: function() { 
    84     var digits = this.toString(16); 
    85     if (this < 16) return '0' + digits; 
    86     return digits; 
    87   }, 
    88  
    89   succ: function() { 
    90     return this + 1; 
    91   }, 
    92  
    93   times: function(iterator) { 
    94     $R(0, this, true).each(iterator); 
    95     return this; 
     200Object.extend(Function.prototype, { 
     201  argumentNames: function() { 
     202    var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip"); 
     203    return names.length == 1 && !names[0] ? [] : names; 
     204  }, 
     205 
     206  bind: function() { 
     207    if (arguments.length < 2 && arguments[0] === undefined) return this; 
     208    var __method = this, args = $A(arguments), object = args.shift(); 
     209    return function() { 
     210      return __method.apply(object, args.concat($A(arguments))); 
     211    } 
     212  }, 
     213 
     214  bindAsEventListener: function() { 
     215    var __method = this, args = $A(arguments), object = args.shift(); 
     216    return function(event) { 
     217      return __method.apply(object, [event || window.event].concat(args)); 
     218    } 
     219  }, 
     220 
     221  curry: function() { 
     222    if (!arguments.length) return this; 
     223    var __method = this, args = $A(arguments); 
     224    return function() { 
     225      return __method.apply(this, args.concat($A(arguments))); 
     226    } 
     227  }, 
     228 
     229  delay: function() { 
     230    var __method = this, args = $A(arguments), timeout = args.shift() * 1000; 
     231    return window.setTimeout(function() { 
     232      return __method.apply(__method, args); 
     233    }, timeout); 
     234  }, 
     235 
     236  wrap: function(wrapper) { 
     237    var __method = this; 
     238    return function() { 
     239      return wrapper.apply(this, [__method.bind(this)].concat($A(arguments))); 
     240    } 
     241  }, 
     242 
     243  methodize: function() { 
     244    if (this._methodized) return this._methodized; 
     245    var __method = this; 
     246    return this._methodized = function() { 
     247      return __method.apply(null, [this].concat($A(arguments))); 
     248    }; 
    96249  } 
    97250}); 
     251 
     252Function.prototype.defer = Function.prototype.delay.curry(0.01); 
     253 
     254Date.prototype.toJSON = function() { 
     255  return '"' + this.getUTCFullYear() + '-' + 
     256    (this.getUTCMonth() + 1).toPaddedString(2) + '-' + 
     257    this.getUTCDate().toPaddedString(2) + 'T' + 
     258    this.getUTCHours().toPaddedString(2) + ':' + 
     259    this.getUTCMinutes().toPaddedString(2) + ':' + 
     260    this.getUTCSeconds().toPaddedString(2) + 'Z"'; 
     261}; 
    98262 
    99263var Try = { 
     
    106270        returnValue = lambda(); 
    107271        break; 
    108       } catch (e) {
     272      } catch (e) {
    109273    } 
    110274 
    111275    return returnValue; 
    112276  } 
    113 
     277}; 
     278 
     279RegExp.prototype.match = RegExp.prototype.test; 
     280 
     281RegExp.escape = function(str) { 
     282  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); 
     283}; 
    114284 
    115285/*--------------------------------------------------------------------------*/ 
    116286 
    117 var PeriodicalExecuter = Class.create(); 
    118 PeriodicalExecuter.prototype = { 
     287var PeriodicalExecuter = Class.create({ 
    119288  initialize: function(callback, frequency) { 
    120289    this.callback = callback; 
     
    129298  }, 
    130299 
     300  execute: function() { 
     301    this.callback(this); 
     302  }, 
     303 
    131304  stop: function() { 
    132305    if (!this.timer) return; 
     
    139312      try { 
    140313        this.currentlyExecuting = true; 
    141         this.callback(this); 
     314        this.execute(); 
    142315      } finally { 
    143316        this.currentlyExecuting = false; 
     
    145318    } 
    146319  } 
    147 
    148 String.interpret = function(value){ 
    149   return value == null ? '' : String(value); 
    150 
     320}); 
     321Object.extend(String, { 
     322  interpret: function(value) { 
     323    return value == null ? '' : String(value); 
     324  }, 
     325  specialChar: { 
     326    '\b': '\\b', 
     327    '\t': '\\t', 
     328    '\n': '\\n', 
     329    '\f': '\\f', 
     330    '\r': '\\r', 
     331    '\\': '\\\\' 
     332  } 
     333}); 
    151334 
    152335Object.extend(String.prototype, { 
     
    179362  scan: function(pattern, iterator) { 
    180363    this.gsub(pattern, iterator); 
    181     return this
     364    return String(this)
    182365  }, 
    183366 
     
    186369    truncation = truncation === undefined ? '...' : truncation; 
    187370    return this.length > length ? 
    188       this.slice(0, length - truncation.length) + truncation : this
     371      this.slice(0, length - truncation.length) + truncation : String(this)
    189372  }, 
    190373 
     
    214397 
    215398  escapeHTML: function() { 
    216     var div = document.createElement('div'); 
    217     var text = document.createTextNode(this); 
    218     div.appendChild(text); 
    219     return div.innerHTML; 
     399    var self = arguments.callee; 
     400    self.text.data = this; 
     401    return self.div.innerHTML; 
    220402  }, 
    221403 
    222404  unescapeHTML: function() { 
    223     var div = document.createElement('div'); 
     405    var div = new Element('div'); 
    224406    div.innerHTML = this.stripTags(); 
    225407    return div.childNodes[0] ? (div.childNodes.length > 1 ? 
    226       $A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) : 
     408      $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) : 
    227409      div.childNodes[0].nodeValue) : ''; 
    228410  }, 
     
    230412  toQueryParams: function(separator) { 
    231413    var match = this.strip().match(/([^?#]*)(#.*)?$/); 
    232     if (!match) return {}; 
    233  
    234     return match[1].split(separator || '&').inject({}, function(hash, pair) { 
     414    if (!match) return { }; 
     415 
     416    return match[1].split(separator || '&').inject({ }, function(hash, pair) { 
    235417      if ((pair = pair.split('='))[0]) { 
    236         var name = decodeURIComponent(pair[0]); 
    237         var value = pair[1] ? decodeURIComponent(pair[1]) : undefined
    238  
    239         if (hash[name] !== undefined) { 
    240           if (hash[name].constructor != Array) 
    241             hash[name] = [hash[name]]; 
    242           if (value) hash[name].push(value); 
     418        var key = decodeURIComponent(pair.shift()); 
     419        var value = pair.length > 1 ? pair.join('=') : pair[0]
     420        if (value != undefined) value = decodeURIComponent(value); 
     421 
     422        if (key in hash) { 
     423          if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; 
     424          hash[key].push(value); 
    243425        } 
    244         else hash[name] = value; 
     426        else hash[key] = value; 
    245427      } 
    246428      return hash; 
     
    257439  }, 
    258440 
     441  times: function(count) { 
     442    return count < 1 ? '' : new Array(count + 1).join(this); 
     443  }, 
     444 
    259445  camelize: function() { 
    260446    var parts = this.split('-'), len = parts.length; 
     
    271457  }, 
    272458 
    273   capitalize: function()
     459  capitalize: function()
    274460    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); 
    275461  }, 
     
    284470 
    285471  inspect: function(useDoubleQuotes) { 
    286     var escapedString = this.replace(/\\/g, '\\\\'); 
    287     if (useDoubleQuotes) 
    288       return '"' + escapedString.replace(/"/g, '\\"') + '"'; 
    289     else 
    290       return "'" + escapedString.replace(/'/g, '\\\'') + "'"; 
     472    var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) { 
     473      var character = String.specialChar[match[0]]; 
     474      return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16); 
     475    }); 
     476    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; 
     477    return "'" + escapedString.replace(/'/g, '\\\'') + "'"; 
     478  }, 
     479 
     480  toJSON: function() { 
     481    return this.inspect(true); 
     482  }, 
     483 
     484  unfilterJSON: function(filter) { 
     485    return this.sub(filter || Prototype.JSONFilter, '#{1}'); 
     486  }, 
     487 
     488  isJSON: function() { 
     489    var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''); 
     490    return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str); 
     491  }, 
     492 
     493  evalJSON: function(sanitize) { 
     494    var json = this.unfilterJSON(); 
     495    try { 
     496      if (!sanitize || json.isJSON()) return eval('(' + json + ')'); 
     497    } catch (e) { } 
     498    throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); 
     499  }, 
     500 
     501  include: function(pattern) { 
     502    return this.indexOf(pattern) > -1; 
     503  }, 
     504 
     505  startsWith: function(pattern) { 
     506    return this.indexOf(pattern) === 0; 
     507  }, 
     508 
     509  endsWith: function(pattern) { 
     510    var d = this.length - pattern.length; 
     511    return d >= 0 && this.lastIndexOf(pattern) === d; 
     512  }, 
     513 
     514  empty: function() { 
     515    return this == ''; 
     516  }, 
     517 
     518  blank: function() { 
     519    return /^\s*$/.test(this); 
     520  }, 
     521 
     522  interpolate: function(object, pattern) { 
     523    return new Template(this, pattern).evaluate(object); 
    291524  } 
    292525}); 
    293526 
     527if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, { 
     528  escapeHTML: function() { 
     529    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); 
     530  }, 
     531  unescapeHTML: function() { 
     532    return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>'); 
     533  } 
     534}); 
     535 
    294536String.prototype.gsub.prepareReplacement = function(replacement) { 
    295   if (typeof replacement == 'function') return replacement; 
     537  if (Object.isFunction(replacement)) return replacement; 
    296538  var template = new Template(replacement); 
    297539  return function(match) { return template.evaluate(match) }; 
    298 } 
     540}; 
    299541 
    300542String.prototype.parseQuery = String.prototype.toQueryParams; 
    301543 
    302 var Template = Class.create(); 
    303 Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; 
    304 Template.prototype = { 
     544Object.extend(String.prototype.escapeHTML, { 
     545  div:  document.createElement('div'), 
     546  text: document.createTextNode('') 
     547}); 
     548 
     549with (String.prototype.escapeHTML) div.appendChild(text); 
     550 
     551var Template = Class.create({ 
    305552  initialize: function(template, pattern) { 
    306553    this.template = template.toString(); 
    307     this.pattern = pattern || Template.Pattern; 
     554    this.pattern = pattern || Template.Pattern; 
    308555  }, 
    309556 
    310557  evaluate: function(object) { 
     558    if (Object.isFunction(object.toTemplateReplacements)) 
     559      object = object.toTemplateReplacements(); 
     560 
    311561    return this.template.gsub(this.pattern, function(match) { 
    312       var before = match[1]; 
     562      if (object == null) return ''; 
     563 
     564      var before = match[1] || ''; 
    313565      if (before == '\\') return match[2]; 
    314       return before + String.interpret(object[match[3]]); 
    315     }); 
    316   } 
    317 
    318  
    319 var $break    = new Object(); 
    320 var $continue = new Object(); 
     566 
     567      var ctx = object, expr = match[3]; 
     568      var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/, match = pattern.exec(expr); 
     569      if (match == null) return before; 
     570 
     571      while (match != null) { 
     572        var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1]; 
     573        ctx = ctx[comp]; 
     574        if (null == ctx || '' == match[3]) break; 
     575        expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); 
     576        match = pattern.exec(expr); 
     577      } 
     578 
     579      return before + String.interpret(ctx); 
     580    }.bind(this)); 
     581  } 
     582}); 
     583Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; 
     584 
     585var $break = { }; 
    321586 
    322587var Enumerable = { 
    323   each: function(iterator) { 
     588  each: function(iterator, context) { 
    324589    var index = 0; 
     590    iterator = iterator.bind(context); 
    325591    try { 
    326592      this._each(function(value) { 
    327         try { 
    328           iterator(value, index++); 
    329         } catch (e) { 
    330           if (e != $continue) throw e; 
    331         } 
     593        iterator(value, index++); 
    332594      }); 
    333595    } catch (e) { 
     
    337599  }, 
    338600 
    339   eachSlice: function(number, iterator) { 
     601  eachSlice: function(number, iterator, context) { 
     602    iterator = iterator ? iterator.bind(context) : Prototype.K; 
    340603    var index = -number, slices = [], array = this.toArray(); 
    341604    while ((index += number) < array.length) 
    342605      slices.push(array.slice(index, index+number)); 
    343     return slices.map(iterator); 
    344   }, 
    345  
    346   all: function(iterator) { 
     606    return slices.collect(iterator, context); 
     607  }, 
     608 
     609  all: function(iterator, context) { 
     610    iterator = iterator ? iterator.bind(context) : Prototype.K; 
    347611    var result = true; 
    348612    this.each(function(value, index) { 
    349       result = result && !!(iterator || Prototype.K)(value, index); 
     613      result = result && !!iterator(value, index); 
    350614      if (!result) throw $break; 
    351615    }); 
     
    353617  }, 
    354618 
    355   any: function(iterator) { 
     619  any: function(iterator, context) { 
     620    iterator = iterator ? iterator.bind(context) : Prototype.K; 
    356621    var result = false; 
    357622    this.each(function(value, index) { 
    358       if (result = !!(iterator || Prototype.K)(value, index)) 
     623      if (result = !!iterator(value, index)) 
    359624        throw $break; 
    360625    }); 
     
    362627  }, 
    363628 
    364   collect: function(iterator) { 
     629  collect: function(iterator, context) { 
     630    iterator = iterator ? iterator.bind(context) : Prototype.K; 
    365631    var results = []; 
    366632    this.each(function(value, index) { 
    367       results.push((iterator || Prototype.K)(value, index)); 
     633      results.push(iterator(value, index)); 
    368634    }); 
    369635    return results; 
    370636  }, 
    371637 
    372   detect: function(iterator) { 
     638  detect: function(iterator, context) { 
     639    iterator = iterator.bind(context); 
    373640    var result; 
    374641    this.each(function(value, index) { 
     
    381648  }, 
    382649 
    383   findAll: function(iterator) { 
     650  findAll: function(iterator, context) { 
     651    iterator = iterator.bind(context); 
    384652    var results = []; 
    385653    this.each(function(value, index) { 
     
    390658  }, 
    391659 
    392   grep: function(pattern, iterator) { 
     660  grep: function(filter, iterator, context) { 
     661    iterator = iterator ? iterator.bind(context) : Prototype.K; 
    393662    var results = []; 
     663 
     664    if (Object.isString(filter)) 
     665      filter = new RegExp(filter); 
     666 
    394667    this.each(function(value, index) { 
    395       var stringValue = value.toString(); 
    396       if (stringValue.match(pattern)) 
    397         results.push((iterator || Prototype.K)(value, index)); 
    398     }) 
     668      if (filter.match(value)) 
     669        results.push(iterator(value, index)); 
     670    }); 
    399671    return results; 
    400672  }, 
    401673 
    402674  include: function(object) { 
     675    if (Object.isFunction(this.indexOf)) 
     676      if (this.indexOf(object) != -1) return true; 
     677 
    403678    var found = false; 
    404679    this.each(function(value) { 
     
    419694  }, 
    420695 
    421   inject: function(memo, iterator) { 
     696  inject: function(memo, iterator, context) { 
     697    iterator = iterator.bind(context); 
    422698    this.each(function(value, index) { 
    423699      memo = iterator(memo, value, index); 
     
    433709  }, 
    434710 
    435   max: function(iterator) { 
     711  max: function(iterator, context) { 
     712    iterator = iterator ? iterator.bind(context) : Prototype.K; 
    436713    var result; 
    437714    this.each(function(value, index) { 
    438       value = (iterator || Prototype.K)(value, index); 
     715      value = iterator(value, index); 
    439716      if (result == undefined || value >= result) 
    440717        result = value; 
     
    443720  }, 
    444721 
    445   min: function(iterator) { 
     722  min: function(iterator, context) { 
     723    iterator = iterator ? iterator.bind(context) : Prototype.K; 
    446724    var result; 
    447725    this.each(function(value, index) { 
    448       value = (iterator || Prototype.K)(value, index); 
     726      value = iterator(value, index); 
    449727      if (result == undefined || value < result) 
    450728        result = value; 
     
    453731  }, 
    454732 
    455   partition: function(iterator) { 
     733  partition: function(iterator, context) { 
     734    iterator = iterator ? iterator.bind(context) : Prototype.K; 
    456735    var trues = [], falses = []; 
    457736    this.each(function(value, index) { 
    458       ((iterator || Prototype.K)(value, index) ? 
     737      (iterator(value, index) ? 
    459738        trues : falses).push(value); 
    460739    }); 
     
    464743  pluck: function(property) { 
    465744    var results = []; 
    466     this.each(function(value, index) { 
     745    this.each(function(value) { 
    467746      results.push(value[property]); 
    468747    }); 
     
    470749  }, 
    471750 
    472   reject: function(iterator) { 
     751  reject: function(iterator, context) { 
     752    iterator = iterator.bind(context); 
    473753    var results = []; 
    474754    this.each(function(value, index) { 
     
    479759  }, 
    480760 
    481   sortBy: function(iterator) { 
     761  sortBy: function(iterator, context) { 
     762    iterator = iterator.bind(context); 
    482763    return this.map(function(value, index) { 
    483764      return {value: value, criteria: iterator(value, index)}; 
     
    494775  zip: function() { 
    495776    var iterator = Prototype.K, args = $A(arguments); 
    496     if (typeof args.last() == 'function'
     777    if (Object.isFunction(args.last())
    497778      iterator = args.pop(); 
    498779 
     
    510791    return '#<Enumerable:' + this.toArray().inspect() + '>'; 
    511792  } 
    512 } 
     793}; 
    513794 
    514795Object.extend(Enumerable, { 
     
    516797  find:    Enumerable.detect, 
    517798  select:  Enumerable.findAll, 
     799  filter:  Enumerable.findAll, 
    518800  member:  Enumerable.include, 
    519   entries: Enumerable.toArray 
     801  entries: Enumerable.toArray, 
     802  every:   Enumerable.all, 
     803  some:    Enumerable.any 
    520804}); 
    521 var $A = Array.from = function(iterable) { 
     805function $A(iterable) { 
    522806  if (!iterable) return []; 
    523   if (iterable.toArray) { 
    524     return iterable.toArray(); 
    525   } else { 
    526     var results = []; 
    527     for (var i = 0, length = iterable.length; i < length; i++) 
    528       results.push(iterable[i]); 
     807  if (iterable.toArray) return iterable.toArray(); 
     808  var length = iterable.length, results = new Array(length); 
     809  while (length--) results[length] = iterable[length]; 
     810  return results; 
     811
     812 
     813if (Prototype.Browser.WebKit) { 
     814  function $A(iterable) { 
     815    if (!iterable) return []; 
     816    if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') && 
     817        iterable.toArray) return iterable.toArray(); 
     818    var length = iterable.length, results = new Array(length); 
     819    while (length--) results[length] = iterable[length]; 
    529820    return results; 
    530821  } 
    531822} 
    532823 
     824Array.from = $A; 
     825 
    533826Object.extend(Array.prototype, Enumerable); 
    534827 
    535 if (!Array.prototype._reverse) 
    536   Array.prototype._reverse = Array.prototype.reverse; 
     828if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse; 
    537829 
    538830Object.extend(Array.prototype, { 
     
    563855  flatten: function() { 
    564856    return this.inject([], function(array, value) { 
    565       return array.concat(value && value.constructor == Array
     857      return array.concat(Object.isArray(value)
    566858        value.flatten() : [value]); 
    567859    }); 
     
    575867  }, 
    576868 
    577   indexOf: function(object) { 
    578     for (var i = 0, length = this.length; i < length; i++) 
    579       if (this[i] == object) return i; 
    580     return -1; 
    581   }, 
    582  
    583869  reverse: function(inline) { 
    584870    return (inline !== false ? this : this.toArray())._reverse(); 
     
    589875  }, 
    590876 
    591   uniq: function() { 
    592     return this.inject([], function(array, value) { 
    593       return array.include(value) ? array : array.concat([value]); 
     877  uniq: function(sorted) { 
     878    return this.inject([], function(array, value, index) { 
     879      if (0 == index || (sorted ? array.last() != value : !array.include(value))) 
     880        array.push(value); 
     881      return array; 
     882    }); 
     883  }, 
     884 
     885  intersect: function(array) { 
     886    return this.uniq().findAll(function(item) { 
     887      return array.detect(function(value) { return item === value }); 
    594888    }); 
    595889  }, 
     
    605899  inspect: function() { 
    606900    return '[' + this.map(Object.inspect).join(', ') + ']'; 
     901  }, 
     902 
     903  toJSON: function() { 
     904    var results = []; 
     905    this.each(function(object) { 
     906      var value = Object.toJSON(object); 
     907      if (value !== undefined) results.push(value); 
     908    }); 
     909    return '[' + results.join(', ') + ']'; 
    607910  } 
    608911}); 
    609912 
     913// use native browser JS 1.6 implementation if available 
     914if (Object.isFunction(Array.prototype.forEach)) 
     915  Array.prototype._each = Array.prototype.forEach; 
     916 
     917if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) { 
     918  i || (i = 0); 
     919  var length = this.length; 
     920  if (i < 0) i = length + i; 
     921  for (; i < length; i++) 
     922    if (this[i] === item) return i; 
     923  return -1; 
     924}; 
     925 
     926if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) { 
     927  i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; 
     928  var n = this.slice(0, i).reverse().indexOf(item); 
     929  return (n < 0) ? n : i - n - 1; 
     930}; 
     931 
    610932Array.prototype.toArray = Array.prototype.clone; 
    611933 
    612 function $w(string){ 
     934function $w(string) { 
     935  if (!Object.isString(string)) return []; 
    613936  string = string.strip(); 
    614937  return string ? string.split(/\s+/) : []; 
    615938} 
    616939 
    617 if(window.opera){ 
    618   Array.prototype.concat = function()
     940if (Prototype.Browser.Opera){ 
     941  Array.prototype.concat = function()
    619942    var array = []; 
    620     for(var i = 0, length = this.length; i < length; i++) array.push(this[i]); 
    621     for(var i = 0, length = arguments.length; i < length; i++) { 
    622       if(arguments[i].constructor == Array) { 
    623         for(var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) 
     943    for (var i = 0, length = this.length; i < length; i++) array.push(this[i]); 
     944    for (var i = 0, length = arguments.length; i < length; i++) { 
     945      if (Object.isArray(arguments[i])) { 
     946        for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) 
    624947          array.push(arguments[i][j]); 
    625948      } else { 
     
    628951    } 
    629952    return array; 
    630   } 
     953  }; 
    631954} 
    632 var Hash = function(obj) { 
    633   Object.extend(this, obj || {}); 
    634 }; 
    635  
    636 Object.extend(Hash, { 
    637   toQueryString: function(obj) { 
    638     var parts = []; 
    639  
    640           this.prototype._each.call(obj, function(pair) { 
    641       if (!pair.key) return; 
    642  
    643       if (pair.value && pair.value.constructor == Array) { 
    644         var values = pair.value.compact(); 
    645         if (values.length < 2) pair.value = values.reduce(); 
    646         else { 
    647                 key = encodeURIComponent(pair.key); 
    648           values.each(function(value) { 
    649             value = value != undefined ? encodeURIComponent(value) : ''; 
    650             parts.push(key + '=' + encodeURIComponent(value)); 
    651           }); 
    652           return; 
    653         } 
    654       } 
    655       if (pair.value == undefined) pair[1] = ''; 
    656       parts.push(pair.map(encodeURIComponent).join('=')); 
    657           }); 
    658  
    659     return parts.join('&'); 
     955Object.extend(Number.prototype, { 
     956  toColorPart: function() { 
     957    return this.toPaddedString(2, 16); 
     958  }, 
     959 
     960  succ: function() { 
     961    return this + 1; 
     962  }, 
     963 
     964  times: function(iterator) { 
     965    $R(0, this, true).each(iterator); 
     966    return this; 
     967  }, 
     968 
     969  toPaddedString: function(length, radix) { 
     970    var string = this.toString(radix || 10); 
     971    return '0'.times(length - string.length) + string; 
     972  }, 
     973 
     974  toJSON: function() { 
     975    return isFinite(this) ? this.toString() : 'null'; 
    660976  } 
    661977}); 
    662978 
    663 Object.extend(Hash.prototype, Enumerable); 
    664 Object.extend(Hash.prototype, { 
    665   _each: function(iterator) { 
    666     for (var key in this) { 
    667       var value = this[key]; 
    668       if (value && value == Hash.prototype[key]) continue; 
    669  
    670       var pair = [key, value]; 
    671       pair.key = key; 
    672       pair.value = value; 
    673       iterator(pair); 
    674     } 
    675   }, 
    676  
    677   keys: function() { 
    678     return this.pluck('key'); 
    679   }, 
    680  
    681   values: function() { 
    682     return this.pluck('value'); 
    683   }, 
    684  
    685   merge: function(hash) { 
    686     return $H(hash).inject(this, function(mergedHash, pair) { 
    687       mergedHash[pair.key] = pair.value; 
    688       return mergedHash; 
    689     }); 
    690   }, 
    691  
    692   remove: function() { 
    693     var result; 
    694     for(var i = 0, length = arguments.length; i < length; i++) { 
    695       var value = this[arguments[i]]; 
    696       if (value !== undefined){ 
    697         if (result === undefined) result = value; 
    698         else { 
    699           if (result.constructor != Array) result = [result]; 
    700           result.push(value) 
    701         } 
    702       } 
    703       delete this[arguments[i]]; 
    704     } 
    705     return result; 
    706   }, 
    707  
    708   toQueryString: function() { 
    709     return Hash.toQueryString(this); 
    710   }, 
    711  
    712   inspect: function() { 
    713     return '#<Hash:{' + this.map(function(pair) { 
    714       return pair.map(Object.inspect).join(': '); 
    715     }).join(', ') + '}>'; 
    716   } 
     979$w('abs round ceil floor').each(function(method){ 
     980  Number.prototype[method] = Math[method].methodize(); 
    717981}); 
    718  
    719982function $H(object) { 
    720   if (object && object.constructor == Hash) return object; 
    721983  return new Hash(object); 
    722984}; 
    723 ObjectRange = Class.create(); 
    724 Object.extend(ObjectRange.prototype, Enumerable); 
    725 Object.extend(ObjectRange.prototype, { 
     985 
     986var Hash = Class.create(Enumerable, (function() { 
     987  if (function() { 
     988    var i = 0, Test = function(value) { this.key = value }; 
     989    Test.prototype.key = 'foo'; 
     990    for (var property in new Test('bar')) i++; 
     991    return i > 1; 
     992  }()) { 
     993    function each(iterator) { 
     994      var cache = []; 
     995      for (var key in this._object) { 
     996        var value = this._object[key]; 
     997        if (cache.include(key)) continue; 
     998        cache.push(key); 
     999        var pair = [key, value]; 
     1000        pair.key = key; 
     1001        pair.value = value; 
     1002        iterator(pair); 
     1003      } 
     1004    } 
     1005  } else { 
     1006    function each(iterator) { 
     1007      for (var key in this._object) { 
     1008        var value = this._object[key], pair = [key, value]; 
     1009        pair.key = key; 
     1010        pair.value = value; 
     1011        iterator(pair); 
     1012      } 
     1013    } 
     1014  } 
     1015 
     1016  function toQueryPair(key, value) { 
     1017    if (Object.isUndefined(value)) return key; 
     1018    return key + '=' + encodeURIComponent(String.interpret(value)); 
     1019  } 
     1020 
     1021  return { 
     1022    initialize: function(object) { 
     1023      this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); 
     1024    }, 
     1025 
     1026    _each: each, 
     1027 
     1028    set: function(key, value) { 
     1029      return this._object[key] = value; 
     1030    }, 
     1031 
     1032    get: function(key) { 
     1033