Changeset 1661
- Timestamp:
- 02/24/08 20:46:26 (3 months ago)
- Files:
-
- trunk/app/helpers/application_helper.rb (modified) (3 diffs)
- trunk/lang/fr_FR.rb (modified) (1 diff)
- trunk/public/javascripts/lang (added)
- trunk/public/javascripts/lang/fr_FR.js (added)
- trunk/public/javascripts/prototype.js (modified) (83 diffs)
- trunk/public/javascripts/typo.js (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/app/helpers/application_helper.rb
r1653 r1661 40 40 41 41 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>" 44 45 end 45 46 … … 49 50 50 51 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>" 52 53 end 53 54 … … 197 198 <link rel="alternate" type="application/atom+xml" title="Atom" href="#{ @auto_discovery_url_atom }" /> 198 199 <link rel="alternate" type="application/rss+xml" title="RSS" href="#{ @auto_discovery_url_rss }" /> 200 #{ javascript_include_tag "lang/" + Localization.lang } 199 201 #{ javascript_include_tag "cookies" } 200 202 #{ javascript_include_tag "prototype" } trunk/lang/fr_FR.rb
r1653 r1661 616 616 l.store "comments", "commentaires" 617 617 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 618 665 end trunk/public/javascripts/prototype.js
r1358 r1661 1 /* Prototype JavaScript framework, version 1. 5.01 /* Prototype JavaScript framework, version 1.6.0 2 2 * (c) 2005-2007 Sam Stephenson 3 3 * 4 4 * 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/ 6 6 * 7 /*--------------------------------------------------------------------------*/7 *--------------------------------------------------------------------------*/ 8 8 9 9 var 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 11 20 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() { }, 17 33 K: function(x) { return x } 18 } 19 34 }; 35 36 if (Prototype.Browser.MobileSafari) 37 Prototype.BrowserFeatures.SpecificElementExtensions = false; 38 39 if (Prototype.Browser.WebKit) 40 Prototype.BrowserFeatures.XPath = false; 41 42 /* Based on Alex Arnell's inheritance implementation. */ 20 43 var Class = { 21 44 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() { 23 50 this.initialize.apply(this, arguments); 24 51 } 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 76 Class.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 102 var Abstract = { }; 29 103 30 104 Object.extend = function(destination, source) { 31 for (var property in source) {105 for (var property in source) 32 106 destination[property] = source[property]; 33 }34 107 return destination; 35 } 108 }; 36 109 37 110 Object.extend(Object, { … … 47 120 }, 48 121 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 49 153 keys: function(object) { 50 154 var keys = []; … … 62 166 63 167 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"; 65 197 } 66 198 }); 67 199 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; 200 Object.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 }; 96 249 } 97 250 }); 251 252 Function.prototype.defer = Function.prototype.delay.curry(0.01); 253 254 Date.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 }; 98 262 99 263 var Try = { … … 106 270 returnValue = lambda(); 107 271 break; 108 } catch (e) { }272 } catch (e) { } 109 273 } 110 274 111 275 return returnValue; 112 276 } 113 } 277 }; 278 279 RegExp.prototype.match = RegExp.prototype.test; 280 281 RegExp.escape = function(str) { 282 return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); 283 }; 114 284 115 285 /*--------------------------------------------------------------------------*/ 116 286 117 var PeriodicalExecuter = Class.create(); 118 PeriodicalExecuter.prototype = { 287 var PeriodicalExecuter = Class.create({ 119 288 initialize: function(callback, frequency) { 120 289 this.callback = callback; … … 129 298 }, 130 299 300 execute: function() { 301 this.callback(this); 302 }, 303 131 304 stop: function() { 132 305 if (!this.timer) return; … … 139 312 try { 140 313 this.currentlyExecuting = true; 141 this. callback(this);314 this.execute(); 142 315 } finally { 143 316 this.currentlyExecuting = false; … … 145 318 } 146 319 } 147 } 148 String.interpret = function(value){ 149 return value == null ? '' : String(value); 150 } 320 }); 321 Object.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 }); 151 334 152 335 Object.extend(String.prototype, { … … 179 362 scan: function(pattern, iterator) { 180 363 this.gsub(pattern, iterator); 181 return this;364 return String(this); 182 365 }, 183 366 … … 186 369 truncation = truncation === undefined ? '...' : truncation; 187 370 return this.length > length ? 188 this.slice(0, length - truncation.length) + truncation : this;371 this.slice(0, length - truncation.length) + truncation : String(this); 189 372 }, 190 373 … … 214 397 215 398 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; 220 402 }, 221 403 222 404 unescapeHTML: function() { 223 var div = document.createElement('div');405 var div = new Element('div'); 224 406 div.innerHTML = this.stripTags(); 225 407 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 }) : 227 409 div.childNodes[0].nodeValue) : ''; 228 410 }, … … 230 412 toQueryParams: function(separator) { 231 413 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) { 235 417 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); 243 425 } 244 else hash[ name] = value;426 else hash[key] = value; 245 427 } 246 428 return hash; … … 257 439 }, 258 440 441 times: function(count) { 442 return count < 1 ? '' : new Array(count + 1).join(this); 443 }, 444 259 445 camelize: function() { 260 446 var parts = this.split('-'), len = parts.length; … … 271 457 }, 272 458 273 capitalize: function() {459 capitalize: function() { 274 460 return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); 275 461 }, … … 284 470 285 471 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); 291 524 } 292 525 }); 293 526 527 if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, { 528 escapeHTML: function() { 529 return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); 530 }, 531 unescapeHTML: function() { 532 return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); 533 } 534 }); 535 294 536 String.prototype.gsub.prepareReplacement = function(replacement) { 295 if ( typeof replacement == 'function') return replacement;537 if (Object.isFunction(replacement)) return replacement; 296 538 var template = new Template(replacement); 297 539 return function(match) { return template.evaluate(match) }; 298 } 540 }; 299 541 300 542 String.prototype.parseQuery = String.prototype.toQueryParams; 301 543 302 var Template = Class.create(); 303 Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; 304 Template.prototype = { 544 Object.extend(String.prototype.escapeHTML, { 545 div: document.createElement('div'), 546 text: document.createTextNode('') 547 }); 548 549 with (String.prototype.escapeHTML) div.appendChild(text); 550 551 var Template = Class.create({ 305 552 initialize: function(template, pattern) { 306 553 this.template = template.toString(); 307 this.pattern = pattern || Template.Pattern;554 this.pattern = pattern || Template.Pattern; 308 555 }, 309 556 310 557 evaluate: function(object) { 558 if (Object.isFunction(object.toTemplateReplacements)) 559 object = object.toTemplateReplacements(); 560 311 561 return this.template.gsub(this.pattern, function(match) { 312 var before = match[1]; 562 if (object == null) return ''; 563 564 var before = match[1] || ''; 313 565 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 }); 583 Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; 584 585 var $break = { }; 321 586 322 587 var Enumerable = { 323 each: function(iterator ) {588 each: function(iterator, context) { 324 589 var index = 0; 590 iterator = iterator.bind(context); 325 591 try { 326 592 this._each(function(value) { 327 try { 328 iterator(value, index++); 329 } catch (e) { 330 if (e != $continue) throw e; 331 } 593 iterator(value, index++); 332 594 }); 333 595 } catch (e) { … … 337 599 }, 338 600 339 eachSlice: function(number, iterator) { 601 eachSlice: function(number, iterator, context) { 602 iterator = iterator ? iterator.bind(context) : Prototype.K; 340 603 var index = -number, slices = [], array = this.toArray(); 341 604 while ((index += number) < array.length) 342 605 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; 347 611 var result = true; 348 612 this.each(function(value, index) { 349 result = result && !! (iterator || Prototype.K)(value, index);613 result = result && !!iterator(value, index); 350 614 if (!result) throw $break; 351 615 }); … … 353 617 }, 354 618 355 any: function(iterator) { 619 any: function(iterator, context) { 620 iterator = iterator ? iterator.bind(context) : Prototype.K; 356 621 var result = false; 357 622 this.each(function(value, index) { 358 if (result = !! (iterator || Prototype.K)(value, index))623 if (result = !!iterator(value, index)) 359 624 throw $break; 360 625 }); … … 362 627 }, 363 628 364 collect: function(iterator) { 629 collect: function(iterator, context) { 630 iterator = iterator ? iterator.bind(context) : Prototype.K; 365 631 var results = []; 366 632 this.each(function(value, index) { 367 results.push( (iterator || Prototype.K)(value, index));633 results.push(iterator(value, index)); 368 634 }); 369 635 return results; 370 636 }, 371 637 372 detect: function(iterator) { 638 detect: function(iterator, context) { 639 iterator = iterator.bind(context); 373 640 var result; 374 641 this.each(function(value, index) { … … 381 648 }, 382 649 383 findAll: function(iterator) { 650 findAll: function(iterator, context) { 651 iterator = iterator.bind(context); 384 652 var results = []; 385 653 this.each(function(value, index) { … … 390 658 }, 391 659 392 grep: function(pattern, iterator) { 660 grep: function(filter, iterator, context) { 661 iterator = iterator ? iterator.bind(context) : Prototype.K; 393 662 var results = []; 663 664 if (Object.isString(filter)) 665 filter = new RegExp(filter); 666 394 667 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 }); 399 671 return results; 400 672 }, 401 673 402 674 include: function(object) { 675 if (Object.isFunction(this.indexOf)) 676 if (this.indexOf(object) != -1) return true; 677 403 678 var found = false; 404 679 this.each(function(value) { … … 419 694 }, 420 695 421 inject: function(memo, iterator) { 696 inject: function(memo, iterator, context) { 697 iterator = iterator.bind(context); 422 698 this.each(function(value, index) { 423 699 memo = iterator(memo, value, index); … … 433 709 }, 434 710 435 max: function(iterator) { 711 max: function(iterator, context) { 712 iterator = iterator ? iterator.bind(context) : Prototype.K; 436 713 var result; 437 714 this.each(function(value, index) { 438 value = (iterator || Prototype.K)(value, index);715 value = iterator(value, index); 439 716 if (result == undefined || value >= result) 440 717 result = value; … … 443 720 }, 444 721 445 min: function(iterator) { 722 min: function(iterator, context) { 723 iterator = iterator ? iterator.bind(context) : Prototype.K; 446 724 var result; 447 725 this.each(function(value, index) { 448 value = (iterator || Prototype.K)(value, index);726 value = iterator(value, index); 449 727 if (result == undefined || value < result) 450 728 result = value; … … 453 731 }, 454 732 455 partition: function(iterator) { 733 partition: function(iterator, context) { 734 iterator = iterator ? iterator.bind(context) : Prototype.K; 456 735 var trues = [], falses = []; 457 736 this.each(function(value, index) { 458 ( (iterator || Prototype.K)(value, index) ?737 (iterator(value, index) ? 459 738 trues : falses).push(value); 460 739 }); … … 464 743 pluck: function(property) { 465 744 var results = []; 466 this.each(function(value , index) {745 this.each(function(value) { 467 746 results.push(value[property]); 468 747 }); … … 470 749 }, 471 750 472 reject: function(iterator) { 751 reject: function(iterator, context) { 752 iterator = iterator.bind(context); 473 753 var results = []; 474 754 this.each(function(value, index) { … … 479 759 }, 480 760 481 sortBy: function(iterator) { 761 sortBy: function(iterator, context) { 762 iterator = iterator.bind(context); 482 763 return this.map(function(value, index) { 483 764 return {value: value, criteria: iterator(value, index)}; … … 494 775 zip: function() { 495 776 var iterator = Prototype.K, args = $A(arguments); 496 if ( typeof args.last() == 'function')777 if (Object.isFunction(args.last())) 497 778 iterator = args.pop(); 498 779 … … 510 791 return '#<Enumerable:' + this.toArray().inspect() + '>'; 511 792 } 512 } 793 }; 513 794 514 795 Object.extend(Enumerable, { … … 516 797 find: Enumerable.detect, 517 798 select: Enumerable.findAll, 799 filter: Enumerable.findAll, 518 800 member: Enumerable.include, 519 entries: Enumerable.toArray 801 entries: Enumerable.toArray, 802 every: Enumerable.all, 803 some: Enumerable.any 520 804 }); 521 var $A = Array.from = function(iterable) {805 function $A(iterable) { 522 806 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 813 if (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]; 529 820 return results; 530 821 } 531 822 } 532 823 824 Array.from = $A; 825 533 826 Object.extend(Array.prototype, Enumerable); 534 827 535 if (!Array.prototype._reverse) 536 Array.prototype._reverse = Array.prototype.reverse; 828 if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse; 537 829 538 830 Object.extend(Array.prototype, { … … 563 855 flatten: function() { 564 856 return this.inject([], function(array, value) { 565 return array.concat( value && value.constructor == Array?857 return array.concat(Object.isArray(value) ? 566 858 value.flatten() : [value]); 567 859 }); … … 575 867 }, 576 868 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 583 869 reverse: function(inline) { 584 870 return (inline !== false ? this : this.toArray())._reverse(); … … 589 875 }, 590 876 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 }); 594 888 }); 595 889 }, … … 605 899 inspect: function() { 606 900 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(', ') + ']'; 607 910 } 608 911 }); 609 912 913 // use native browser JS 1.6 implementation if available 914 if (Object.isFunction(Array.prototype.forEach)) 915 Array.prototype._each = Array.prototype.forEach; 916 917 if (!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 926 if (!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 610 932 Array.prototype.toArray = Array.prototype.clone; 611 933 612 function $w(string){ 934 function $w(string) { 935 if (!Object.isString(string)) return []; 613 936 string = string.strip(); 614 937 return string ? string.split(/\s+/) : []; 615 938 } 616 939 617 if (window.opera){618 Array.prototype.concat = function() {940 if (Prototype.Browser.Opera){ 941 Array.prototype.concat = function() { 619 942 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++) 624 947 array.push(arguments[i][j]); 625 948 } else { … … 628 951 } 629 952 return array; 630 } 953 }; 631 954 } 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('&'); 955 Object.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'; 660 976 } 661 977 }); 662 978 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(); 717 981 }); 718 719 982 function $H(object) { 720 if (object && object.constructor == Hash) return object;721 983 return new Hash(object); 722 984 }; 723 ObjectRange = Class.create(); 724 Object.extend(ObjectRange.prototype, Enumerable); 725 Object.extend(ObjectRange.prototype, { 985 986 var 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
