| ... | ...@@ -1,42 +1,113 @@ |
| 1 | | /* Prototype JavaScript framework, version 1.5.0 |
| 1 | /* Prototype JavaScript framework, version 1.6.0.1 |
| 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.1', |
| 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 |
| 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__ |
| 13 | 27 | }, |
| 14 | 28 | |
| 15 | | ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)', |
| 16 | | emptyFunction: function() {}, |
| 29 | ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>', |
| 30 | JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, |
| 31 | |
| 32 | emptyFunction: function() { }, |
| 17 | 33 | K: function(x) { return x } |
| 18 | | } |
| 34 | }; |
| 35 | |
| 36 | if (Prototype.Browser.MobileSafari) |
| 37 | Prototype.BrowserFeatures.SpecificElementExtensions = false; |
| 19 | 38 | |
| 39 | |
| 40 | /* Based on Alex Arnell's inheritance implementation. */ |
| 20 | 41 | var Class = { |
| 21 | 42 | create: function() { |
| 22 | | return function() { |
| 43 | var parent = null, properties = $A(arguments); |
| 44 | if (Object.isFunction(properties[0])) |
| 45 | parent = properties.shift(); |
| 46 | |
| 47 | function klass() { |
| 23 | 48 | this.initialize.apply(this, arguments); |
| 24 | 49 | } |
| 50 | |
| 51 | Object.extend(klass, Class.Methods); |
| 52 | klass.superclass = parent; |
| 53 | klass.subclasses = []; |
| 54 | |
| 55 | if (parent) { |
| 56 | var subclass = function() { }; |
| 57 | subclass.prototype = parent.prototype; |
| 58 | klass.prototype = new subclass; |
| 59 | parent.subclasses.push(klass); |
| 60 | } |
| 61 | |
| 62 | for (var i = 0; i < properties.length; i++) |
| 63 | klass.addMethods(properties[i]); |
| 64 | |
| 65 | if (!klass.prototype.initialize) |
| 66 | klass.prototype.initialize = Prototype.emptyFunction; |
| 67 | |
| 68 | klass.prototype.constructor = klass; |
| 69 | |
| 70 | return klass; |
| 71 | } |
| 72 | }; |
| 73 | |
| 74 | Class.Methods = { |
| 75 | addMethods: function(source) { |
| 76 | var ancestor = this.superclass && this.superclass.prototype; |
| 77 | var properties = Object.keys(source); |
| 78 | |
| 79 | if (!Object.keys({ toString: true }).length) |
| 80 | properties.push("toString", "valueOf"); |
| 81 | |
| 82 | for (var i = 0, length = properties.length; i < length; i++) { |
| 83 | var property = properties[i], value = source[property]; |
| 84 | if (ancestor && Object.isFunction(value) && |
| 85 | value.argumentNames().first() == "$super") { |
| 86 | var method = value, value = Object.extend((function(m) { |
| 87 | return function() { return ancestor[m].apply(this, arguments) }; |
| 88 | })(property).wrap(method), { |
| 89 | valueOf: function() { return method }, |
| 90 | toString: function() { return method.toString() } |
| 91 | }); |
| 92 | } |
| 93 | this.prototype[property] = value; |
| 94 | } |
| 95 | |
| 96 | return this; |
| 25 | 97 | } |
| 26 | | } |
| 98 | }; |
| 27 | 99 | |
| 28 | | var Abstract = new Object(); |
| 100 | var Abstract = { }; |
| 29 | 101 | |
| 30 | 102 | Object.extend = function(destination, source) { |
| 31 | | for (var property in source) { |
| 103 | for (var property in source) |
| 32 | 104 | destination[property] = source[property]; |
| 33 | | } |
| 34 | 105 | return destination; |
| 35 | | } |
| 106 | }; |
| 36 | 107 | |
| 37 | 108 | Object.extend(Object, { |
| 38 | 109 | inspect: function(object) { |
| 39 | 110 | try { |
| 40 | | if (object === undefined) return 'undefined'; |
| 111 | if (Object.isUndefined(object)) return 'undefined'; |
| 41 | 112 | if (object === null) return 'null'; |
| 42 | 113 | return object.inspect ? object.inspect() : object.toString(); |
| ... | ...@@ -47,4 +118,35 @@ |
| 47 | 118 | }, |
| 48 | 119 | |
| 120 | toJSON: function(object) { |
| 121 | var type = typeof object; |
| 122 | switch (type) { |
| 123 | case 'undefined': |
| 124 | case 'function': |
| 125 | case 'unknown': return; |
| 126 | case 'boolean': return object.toString(); |
| 127 | } |
| 128 | |
| 129 | if (object === null) return 'null'; |
| 130 | if (object.toJSON) return object.toJSON(); |
| 131 | if (Object.isElement(object)) return; |
| 132 | |
| 133 | var results = []; |
| 134 | for (var property in object) { |
| 135 | var value = Object.toJSON(object[property]); |
| 136 | if (!Object.isUndefined(value)) |
| 137 | results.push(property.toJSON() + ': ' + value); |
| 138 | } |
| 139 | |
| 140 | return '{' + results.join(', ') + '}'; |
| 141 | }, |
| 142 | |
| 143 | toQueryString: function(object) { |
| 144 | return $H(object).toQueryString(); |
| 145 | }, |
| 146 | |
| 147 | toHTML: function(object) { |
| 148 | return object && object.toHTML ? object.toHTML() : String.interpret(object); |
| 149 | }, |
| 150 | |
| 49 | 151 | keys: function(object) { |
| 50 | 152 | var keys = []; |
| ... | ...@@ -62,39 +164,99 @@ |
| 62 | 164 | |
| 63 | 165 | clone: function(object) { |
| 64 | | return Object.extend({}, object); |
| 166 | return Object.extend({ }, object); |
| 167 | }, |
| 168 | |
| 169 | isElement: function(object) { |
| 170 | return object && object.nodeType == 1; |
| 171 | }, |
| 172 | |
| 173 | isArray: function(object) { |
| 174 | return object && object.constructor === Array; |
| 175 | }, |
| 176 | |
| 177 | isHash: function(object) { |
| 178 | return object instanceof Hash; |
| 179 | }, |
| 180 | |
| 181 | isFunction: function(object) { |
| 182 | return typeof object == "function"; |
| 183 | }, |
| 184 | |
| 185 | isString: function(object) { |
| 186 | return typeof object == "string"; |
| 187 | }, |
| 188 | |
| 189 | isNumber: function(object) { |
| 190 | return typeof object == "number"; |
| 191 | }, |
| 192 | |
| 193 | isUndefined: function(object) { |
| 194 | return typeof object == "undefined"; |
| 65 | 195 | } |
| 66 | 196 | }); |
| 67 | 197 | |
| 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 | | } |
| 198 | Object.extend(Function.prototype, { |
| 199 | argumentNames: function() { |
| 200 | var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip"); |
| 201 | return names.length == 1 && !names[0] ? [] : names; |
| 202 | }, |
| 74 | 203 | |
| 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 | | } |
| 204 | bind: function() { |
| 205 | if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this; |
| 206 | var __method = this, args = $A(arguments), object = args.shift(); |
| 207 | return function() { |
| 208 | return __method.apply(object, args.concat($A(arguments))); |
| 209 | } |
| 210 | }, |
| 81 | 211 | |
| 82 | | Object.extend(Number.prototype, { |
| 83 | | toColorPart: function() { |
| 84 | | var digits = this.toString(16); |
| 85 | | if (this < 16) return '0' + digits; |
| 86 | | return digits; |
| 212 | bindAsEventListener: function() { |
| 213 | var __method = this, args = $A(arguments), object = args.shift(); |
| 214 | return function(event) { |
| 215 | return __method.apply(object, [event || window.event].concat(args)); |
| 216 | } |
| 87 | 217 | }, |
| 88 | 218 | |
| 89 | | succ: function() { |
| 90 | | return this + 1; |
| 219 | curry: function() { |
| 220 | if (!arguments.length) return this; |
| 221 | var __method = this, args = $A(arguments); |
| 222 | return function() { |
| 223 | return __method.apply(this, args.concat($A(arguments))); |
| 224 | } |
| 91 | 225 | }, |
| 92 | 226 | |
| 93 | | times: function(iterator) { |
| 94 | | $R(0, this, true).each(iterator); |
| 95 | | return this; |
| 227 | delay: function() { |
| 228 | var __method = this, args = $A(arguments), timeout = args.shift() * 1000; |
| 229 | return window.setTimeout(function() { |
| 230 | return __method.apply(__method, args); |
| 231 | }, timeout); |
| 232 | }, |
| 233 | |
| 234 | wrap: function(wrapper) { |
| 235 | var __method = this; |
| 236 | return function() { |
| 237 | return wrapper.apply(this, [__method.bind(this)].concat($A(arguments))); |
| 238 | } |
| 239 | }, |
| 240 | |
| 241 | methodize: function() { |
| 242 | if (this._methodized) return this._methodized; |
| 243 | var __method = this; |
| 244 | return this._methodized = function() { |
| 245 | return __method.apply(null, [this].concat($A(arguments))); |
| 246 | }; |
| 96 | 247 | } |
| 97 | 248 | }); |
| 98 | 249 | |
| 250 | Function.prototype.defer = Function.prototype.delay.curry(0.01); |
| 251 | |
| 252 | Date.prototype.toJSON = function() { |
| 253 | return '"' + this.getUTCFullYear() + '-' + |
| 254 | (this.getUTCMonth() + 1).toPaddedString(2) + '-' + |
| 255 | this.getUTCDate().toPaddedString(2) + 'T' + |
| 256 | this.getUTCHours().toPaddedString(2) + ':' + |
| 257 | this.getUTCMinutes().toPaddedString(2) + ':' + |
| 258 | this.getUTCSeconds().toPaddedString(2) + 'Z"'; |
| 259 | }; |
| 260 | |
| 99 | 261 | var Try = { |
| 100 | 262 | these: function() { |
| ... | ...@@ -106,15 +268,20 @@ |
| 106 | 268 | returnValue = lambda(); |
| 107 | 269 | break; |
| 108 | | } catch (e) {} |
| 270 | } catch (e) { } |
| 109 | 271 | } |
| 110 | 272 | |
| 111 | 273 | return returnValue; |
| 112 | 274 | } |
| 113 | | } |
| 275 | }; |
| 276 | |
| 277 | RegExp.prototype.match = RegExp.prototype.test; |
| 278 | |
| 279 | RegExp.escape = function(str) { |
| 280 | return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); |
| 281 | }; |
| 114 | 282 | |
| 115 | 283 | /*--------------------------------------------------------------------------*/ |
| 116 | 284 | |
| 117 | | var PeriodicalExecuter = Class.create(); |
| 118 | | PeriodicalExecuter.prototype = { |
| 285 | var PeriodicalExecuter = Class.create({ |
| 119 | 286 | initialize: function(callback, frequency) { |
| 120 | 287 | this.callback = callback; |
| ... | ...@@ -129,4 +296,8 @@ |
| 129 | 296 | }, |
| 130 | 297 | |
| 298 | execute: function() { |
| 299 | this.callback(this); |
| 300 | }, |
| 301 | |
| 131 | 302 | stop: function() { |
| 132 | 303 | if (!this.timer) return; |
| ... | ...@@ -139,5 +310,5 @@ |
| 139 | 310 | try { |
| 140 | 311 | this.currentlyExecuting = true; |
| 141 | | this.callback(this); |
| 312 | this.execute(); |
| 142 | 313 | } finally { |
| 143 | 314 | this.currentlyExecuting = false; |
| ... | ...@@ -145,8 +316,18 @@ |
| 145 | 316 | } |
| 146 | 317 | } |
| 147 | | } |
| 148 | | String.interpret = function(value){ |
| 149 | | return value == null ? '' : String(value); |
| 150 | | } |
| 318 | }); |
| 319 | Object.extend(String, { |
| 320 | interpret: function(value) { |
| 321 | return value == null ? '' : String(value); |
| 322 | }, |
| 323 | specialChar: { |
| 324 | '\b': '\\b', |
| 325 | '\t': '\\t', |
| 326 | '\n': '\\n', |
| 327 | '\f': '\\f', |
| 328 | '\r': '\\r', |
| 329 | '\\': '\\\\' |
| 330 | } |
| 331 | }); |
| 151 | 332 | |
| 152 | 333 | Object.extend(String.prototype, { |
| ... | ...@@ -169,5 +350,5 @@ |
| 169 | 350 | sub: function(pattern, replacement, count) { |
| 170 | 351 | replacement = this.gsub.prepareReplacement(replacement); |
| 171 | | count = count === undefined ? 1 : count; |
| 352 | count = Object.isUndefined(count) ? 1 : count; |
| 172 | 353 | |
| 173 | 354 | return this.gsub(pattern, function(match) { |
| ... | ...@@ -179,12 +360,12 @@ |
| 179 | 360 | scan: function(pattern, iterator) { |
| 180 | 361 | this.gsub(pattern, iterator); |
| 181 | | return this; |
| 362 | return String(this); |
| 182 | 363 | }, |
| 183 | 364 | |
| 184 | 365 | truncate: function(length, truncation) { |
| 185 | 366 | length = length || 30; |
| 186 | | truncation = truncation === undefined ? '...' : truncation; |
| 367 | truncation = Object.isUndefined(truncation) ? '...' : truncation; |
| 187 | 368 | return this.length > length ? |
| 188 | | this.slice(0, length - truncation.length) + truncation : this; |
| 369 | this.slice(0, length - truncation.length) + truncation : String(this); |
| 189 | 370 | }, |
| 190 | 371 | |
| ... | ...@@ -214,15 +395,14 @@ |
| 214 | 395 | |
| 215 | 396 | escapeHTML: function() { |
| 216 | | var div = document.createElement('div'); |
| 217 | | var text = document.createTextNode(this); |
| 218 | | div.appendChild(text); |
| 219 | | return div.innerHTML; |
| 397 | var self = arguments.callee; |
| 398 | self.text.data = this; |
| 399 | return self.div.innerHTML; |
| 220 | 400 | }, |
| 221 | 401 | |
| 222 | 402 | unescapeHTML: function() { |
| 223 | | var div = document.createElement('div'); |
| 403 | var div = new Element('div'); |
| 224 | 404 | div.innerHTML = this.stripTags(); |
| 225 | 405 | return div.childNodes[0] ? (div.childNodes.length > 1 ? |
| 226 | | $A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) : |
| 406 | $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) : |
| 227 | 407 | div.childNodes[0].nodeValue) : ''; |
| 228 | 408 | }, |
| ... | ...@@ -230,17 +410,17 @@ |
| 230 | 410 | toQueryParams: function(separator) { |
| 231 | 411 | var match = this.strip().match(/([^?#]*)(#.*)?$/); |
| 232 | | if (!match) return {}; |
| 412 | if (!match) return { }; |
| 233 | 413 | |
| 234 | | return match[1].split(separator || '&').inject({}, function(hash, pair) { |
| 414 | return match[1].split(separator || '&').inject({ }, function(hash, pair) { |
| 235 | 415 | 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); |
| 416 | var key = decodeURIComponent(pair.shift()); |
| 417 | var value = pair.length > 1 ? pair.join('=') : pair[0]; |
| 418 | if (value != undefined) value = decodeURIComponent(value); |
| 419 | |
| 420 | if (key in hash) { |
| 421 | if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; |
| 422 | hash[key].push(value); |
| 243 | 423 | } |
| 244 | | else hash[name] = value; |
| 424 | else hash[key] = value; |
| 245 | 425 | } |
| 246 | 426 | return hash; |
| ... | ...@@ -257,4 +437,8 @@ |
| 257 | 437 | }, |
| 258 | 438 | |
| 439 | times: function(count) { |
| 440 | return count < 1 ? '' : new Array(count + 1).join(this); |
| 441 | }, |
| 442 | |
| 259 | 443 | camelize: function() { |
| 260 | 444 | var parts = this.split('-'), len = parts.length; |
| ... | ...@@ -271,5 +455,5 @@ |
| 271 | 455 | }, |
| 272 | 456 | |
| 273 | | capitalize: function(){ |
| 457 | capitalize: function() { |
| 274 | 458 | return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); |
| 275 | 459 | }, |
| ... | ...@@ -284,50 +468,129 @@ |
| 284 | 468 | |
| 285 | 469 | inspect: function(useDoubleQuotes) { |
| 286 | | var escapedString = this.replace(/\\/g, '\\\\'); |
| 287 | | if (useDoubleQuotes) |
| 288 | | return '"' + escapedString.replace(/"/g, '\\"') + '"'; |
| 289 | | else |
| 290 | | return "'" + escapedString.replace(/'/g, '\\\'') + "'"; |
| 470 | var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) { |
| 471 | var character = String.specialChar[match[0]]; |
| 472 | return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16); |
| 473 | }); |
| 474 | if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; |
| 475 | return "'" + escapedString.replace(/'/g, '\\\'') + "'"; |
| 476 | }, |
| 477 | |
| 478 | toJSON: function() { |
| 479 | return this.inspect(true); |
| 480 | }, |
| 481 | |
| 482 | unfilterJSON: function(filter) { |
| 483 | return this.sub(filter || Prototype.JSONFilter, '#{1}'); |
| 484 | }, |
| 485 | |
| 486 | isJSON: function() { |
| 487 | var str = this; |
| 488 | if (str.blank()) return false; |
| 489 | 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); |
| 524 | } |
| 525 | }); |
| 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,'>'); |
| 291 | 533 | } |
| 292 | 534 | }); |
| 293 | 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 | | }); |
| 566 | |
| 567 | var ctx = object, expr = match[3]; |
| 568 | var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; |
| 569 | match = pattern.exec(expr); |
| 570 | if (match == null) return before; |
| 571 | |
| 572 | while (match != null) { |
| 573 | var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1]; |
| 574 | ctx = ctx[comp]; |
| 575 | if (null == ctx || '' == match[3]) break; |
| 576 | expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); |
| 577 | match = pattern.exec(expr); |
| 578 | } |
| 579 | |
| 580 | return before + String.interpret(ctx); |
| 581 | }.bind(this)); |
| 316 | 582 | } |
| 317 | | } |
| 583 | }); |
| 584 | Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; |
| 318 | 585 | |
| 319 | | var $break = new Object(); |
| 320 | | var $continue = new Object(); |
| 586 | var $break = { }; |
| 321 | 587 | |
| 322 | 588 | var Enumerable = { |
| 323 | | each: function(iterator) { |
| 589 | each: function(iterator, context) { |
| 324 | 590 | var index = 0; |
| 591 | iterator = iterator.bind(context); |
| 325 | 592 | try { |
| 326 | 593 | this._each(function(value) { |
| 327 | | try { |
| 328 | | iterator(value, index++); |
| 329 | | } catch (e) { |
| 330 | | if (e != $continue) throw e; |
| 331 | | } |
| 594 | iterator(value, index++); |
| 332 | 595 | }); |
| 333 | 596 | } catch (e) { |
| ... | ...@@ -337,15 +600,17 @@ |
| 337 | 600 | }, |
| 338 | 601 | |
| 339 | | eachSlice: function(number, iterator) { |
| 602 | eachSlice: function(number, iterator, context) { |
| 603 | iterator = iterator ? iterator.bind(context) : Prototype.K; |
| 340 | 604 | var index = -number, slices = [], array = this.toArray(); |
| 341 | 605 | while ((index += number) < array.length) |
| 342 | 606 | slices.push(array.slice(index, index+number)); |
| 343 | | return slices.map(iterator); |
| 607 | return slices.collect(iterator, context); |
| 344 | 608 | }, |
| 345 | 609 | |
| 346 | | all: function(iterator) { |
| 610 | all: function(iterator, context) { |
| 611 | iterator = iterator ? iterator.bind(context) : Prototype.K; |
| 347 | 612 | var result = true; |
| 348 | 613 | this.each(function(value, index) { |
| 349 | | result = result && !!(iterator || Prototype.K)(value, index); |
| 614 | result = result && !!iterator(value, index); |
| 350 | 615 | if (!result) throw $break; |
| 351 | 616 | }); |
| ... | ...@@ -353,8 +618,9 @@ |
| 353 | 618 | }, |
| 354 | 619 | |
| 355 | | any: function(iterator) { |
| 620 | any: function(iterator, context) { |
| 621 | iterator = iterator ? iterator.bind(context) : Prototype.K; |
| 356 | 622 | var result = false; |
| 357 | 623 | this.each(function(value, index) { |
| 358 | | if (result = !!(iterator || Prototype.K)(value, index)) |
| 624 | if (result = !!iterator(value, index)) |
| 359 | 625 | throw $break; |
| 360 | 626 | }); |
| ... | ...@@ -362,13 +628,15 @@ |
| 362 | 628 | }, |
| 363 | 629 | |
| 364 | | collect: function(iterator) { |
| 630 | collect: function(iterator, context) { |
| 631 | iterator = iterator ? iterator.bind(context) : Prototype.K; |
| 365 | 632 | var results = []; |
| 366 | 633 | this.each(function(value, index) { |
| 367 | | results.push((iterator || Prototype.K)(value, index)); |
| 634 | results.push(iterator(value, index)); |
| 368 | 635 | }); |
| 369 | 636 | return results; |
| 370 | 637 | }, |
| 371 | 638 | |
| 372 | | detect: function(iterator) { |
| 639 | detect: function(iterator, context) { |
| 640 | iterator = iterator.bind(context); |
| 373 | 641 | var result; |
| 374 | 642 | this.each(function(value, index) { |
| ... | ...@@ -381,5 +649,6 @@ |
| 381 | 649 | }, |
| 382 | 650 | |
| 383 | | findAll: function(iterator) { |
| 651 | findAll: function(iterator, context) { |
| 652 | iterator = iterator.bind(context); |
| 384 | 653 | var results = []; |
| 385 | 654 | this.each(function(value, index) { |
| ... | ...@@ -390,15 +659,22 @@ |
| 390 | 659 | }, |
| 391 | 660 | |
| 392 | | grep: function(pattern, iterator) { |
| 661 | grep: function(filter, iterator, context) { |
| 662 | iterator = iterator ? iterator.bind(context) : Prototype.K; |
| 393 | 663 | var results = []; |
| 664 | |
| 665 | if (Object.isString(filter)) |
| 666 | filter = new RegExp(filter); |
| 667 | |
| 394 | 668 | this.each(function(value, index) { |
| 395 | | var stringValue = value.toString(); |
| 396 | | if (stringValue.match(pattern)) |
| 397 | | results.push((iterator || Prototype.K)(value, index)); |
| 398 | | }) |
| 669 | if (filter.match(value)) |
| 670 | results.push(iterator(value, index)); |
| 671 | }); |
| 399 | 672 | return results; |
| 400 | 673 | }, |
| 401 | 674 | |
| 402 | 675 | include: function(object) { |
| 676 | if (Object.isFunction(this.indexOf)) |
| 677 | if (this.indexOf(object) != -1) return true; |
| 678 | |
| 403 | 679 | var found = false; |
| 404 | 680 | this.each(function(value) { |
| ... | ...@@ -412,5 +688,5 @@ |
| 412 | 688 | |
| 413 | 689 | inGroupsOf: function(number, fillWith) { |
| 414 | | fillWith = fillWith === undefined ? null : fillWith; |
| 690 | fillWith = Object.isUndefined(fillWith) ? null : fillWith; |
| 415 | 691 | return this.eachSlice(number, function(slice) { |
| 416 | 692 | while(slice.length < number) slice.push(fillWith); |
| ... | ...@@ -419,5 +695,6 @@ |
| 419 | 695 | }, |
| 420 | 696 | |
| 421 | | inject: function(memo, iterator) { |
| 697 | inject: function(memo, iterator, context) { |
| 698 | iterator = iterator.bind(context); |
| 422 | 699 | this.each(function(value, index) { |
| 423 | 700 | memo = iterator(memo, value, index); |
| ... | ...@@ -433,9 +710,10 @@ |
| 433 | 710 | }, |
| 434 | 711 | |
| 435 | | max: function(iterator) { |
| 712 | max: function(iterator, context) { |
| 713 | iterator = iterator ? iterator.bind(context) : Prototype.K; |
| 436 | 714 | var result; |
| 437 | 715 | this.each(function(value, index) { |
| 438 | | value = (iterator || Prototype.K)(value, index); |
| 439 | | if (result == undefined || value >= result) |
| 716 | value = iterator(value, index); |
| 717 | if (result == null || value >= result) |
| 440 | 718 | result = value; |
| 441 | 719 | }); |
| ... | ...@@ -443,9 +721,10 @@ |
| 443 | 721 | }, |
| 444 | 722 | |
| 445 | | min: function(iterator) { |
| 723 | min: function(iterator, context) { |
| 724 | iterator = iterator ? iterator.bind(context) : Prototype.K; |
| 446 | 725 | var result; |
| 447 | 726 | this.each(function(value, index) { |
| 448 | | value = (iterator || Prototype.K)(value, index); |
| 449 | | if (result == undefined || value < result) |
| 727 | value = iterator(value, index); |
| 728 | if (result == null || value < result) |
| 450 | 729 | result = value; |
| 451 | 730 | }); |
| ... | ...@@ -453,8 +732,9 @@ |
| 453 | 732 | }, |
| 454 | 733 | |
| 455 | | partition: function(iterator) { |
| 734 | partition: function(iterator, context) { |
| 735 | iterator = iterator ? iterator.bind(context) : Prototype.K; |
| 456 | 736 | var trues = [], falses = []; |
| 457 | 737 | this.each(function(value, index) { |
| 458 | | ((iterator || Prototype.K)(value, index) ? |
| 738 | (iterator(value, index) ? |
| 459 | 739 | trues : falses).push(value); |
| 460 | 740 | }); |
| ... | ...@@ -464,5 +744,5 @@ |
| 464 | 744 | pluck: function(property) { |
| 465 | 745 | var results = []; |
| 466 | | this.each(function(value, index) { |
| 746 | this.each(function(value) { |
| 467 | 747 | results.push(value[property]); |
| 468 | 748 | }); |
| ... | ...@@ -470,5 +750,6 @@ |
| 470 | 750 | }, |
| 471 | 751 | |
| 472 | | reject: function(iterator) { |
| 752 | reject: function(iterator, context) { |
| 753 | iterator = iterator.bind(context); |
| 473 | 754 | var results = []; |
| 474 | 755 | this.each(function(value, index) { |
| ... | ...@@ -479,5 +760,6 @@ |
| 479 | 760 | }, |
| 480 | 761 | |
| 481 | | sortBy: function(iterator) { |
| 762 | sortBy: function(iterator, context) { |
| 763 | iterator = iterator.bind(context); |
| 482 | 764 | return this.map(function(value, index) { |
| 483 | 765 | return {value: value, criteria: iterator(value, index)}; |
| ... | ...@@ -494,5 +776,5 @@ |
| 494 | 776 | zip: function() { |
| 495 | 777 | var iterator = Prototype.K, args = $A(arguments); |
| 496 | | if (typeof args.last() == 'function') |
| 778 |