Sie sind auf Seite 1von 91

prototype.

js
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:

Tue Jan 04 14:26:58 2011

/* Prototype JavaScript framework, version 1.7


* (c) 2005-2010 Sam Stephenson
*
* Prototype is freely distributable under the terms of an MIT-style license.
* For details, see the Prototype web site: http://www.prototypejs.org/
*
*--------------------------------------------------------------------------*/
var Prototype = {
Version: 1.7,
Browser: (function(){
var ua = navigator.userAgent;
var isOpera = Object.prototype.toString.call(window.opera) == [object Opera];
return {
IE:
!!window.attachEvent && !isOpera,
Opera:
isOpera,
WebKit:
ua.indexOf(AppleWebKit/) > -1,
Gecko:
ua.indexOf(Gecko) > -1 && ua.indexOf(KHTML) === -1,
MobileSafari:
/Apple.*Mobile/.test(ua)
}
})(),
BrowserFeatures: {
XPath: !!document.evaluate,
SelectorsAPI: !!document.querySelector,
ElementExtensions: (function() {
var constructor = window.Element || window.HTMLElement;
return !!(constructor && constructor.prototype);
})(),
SpecificElementExtensions: (function() {
if (typeof window.HTMLDivElement !== undefined)
return true;
var div = document.createElement(div),
form = document.createElement(form),
isSupported = false;
if (div[__proto__] && (div[__proto__] !== form[__proto__])) {
isSupported = true;
}
div = form = null;
return isSupported;
})()
},
ScriptFragment: <script[^>]*>([\\S\\s]*?)<\/script>,
JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
emptyFunction: function() { },
K: function(x) { return x }
};
if (Prototype.Browser.MobileSafari)
Prototype.BrowserFeatures.SpecificElementExtensions = false;

var Abstract = { };

var Try = {
these: function() {

prototype.js

Tue Jan 04 14:26:58 2011

var returnValue;
69:
70:
71:
for (var i = 0, length = arguments.length; i < length; i++) {
72:
var lambda = arguments[i];
73:
try {
74:
returnValue = lambda();
75:
break;
76:
} catch (e) { }
77:
}
78:
79:
return returnValue;
80:
}
81: };
82:
83: /* Based on Alex Arnells inheritance implementation. */
84:
85: var Class = (function() {
86:
87:
var IS_DONTENUM_BUGGY = (function(){
88:
for (var p in { toString: 1 }) {
89:
if (p === toString) return false;
90:
}
91:
return true;
92:
})();
93:
94:
function subclass() {};
95:
function create() {
96:
var parent = null, properties = $A(arguments);
97:
if (Object.isFunction(properties[0]))
98:
parent = properties.shift();
99:
100:
function klass() {
101:
this.initialize.apply(this, arguments);
102:
}
103:
104:
Object.extend(klass, Class.Methods);
105:
klass.superclass = parent;
106:
klass.subclasses = [];
107:
108:
if (parent) {
109:
subclass.prototype = parent.prototype;
110:
klass.prototype = new subclass;
111:
parent.subclasses.push(klass);
112:
}
113:
114:
for (var i = 0, length = properties.length; i < length; i++)
115:
klass.addMethods(properties[i]);
116:
117:
if (!klass.prototype.initialize)
118:
klass.prototype.initialize = Prototype.emptyFunction;
119:
120:
klass.prototype.constructor = klass;
121:
return klass;
122:
}
123:
124:
function addMethods(source) {
125:
var ancestor
= this.superclass && this.superclass.prototype,
126:
properties = Object.keys(source);
127:
128:
if (IS_DONTENUM_BUGGY) {
129:
if (source.toString != Object.prototype.toString)
130:
properties.push("toString");
131:
if (source.valueOf != Object.prototype.valueOf)
132:
properties.push("valueOf");
133:
}
134:
135:
for (var i = 0, length = properties.length; i < length; i++) {
136:
var property = properties[i], value = source[property];

prototype.js

Tue Jan 04 14:26:58 2011

if (ancestor && Object.isFunction(value) &&


137:
138:
value.argumentNames()[0] == "$super") {
139:
var method = value;
140:
value = (function(m) {
141:
return function() { return ancestor[m].apply(this, arguments); };
142:
})(property).wrap(method);
143:
144:
value.valueOf = method.valueOf.bind(method);
145:
value.toString = method.toString.bind(method);
146:
}
147:
this.prototype[property] = value;
148:
}
149:
150:
return this;
151:
}
152:
153:
return {
154:
create: create,
155:
Methods: {
156:
addMethods: addMethods
157:
}
158:
};
159: })();
160: (function() {
161:
162:
var _toString = Object.prototype.toString,
163:
NULL_TYPE = Null,
164:
UNDEFINED_TYPE = Undefined,
165:
BOOLEAN_TYPE = Boolean,
166:
NUMBER_TYPE = Number,
167:
STRING_TYPE = String,
168:
OBJECT_TYPE = Object,
169:
FUNCTION_CLASS = [object Function],
170:
BOOLEAN_CLASS = [object Boolean],
171:
NUMBER_CLASS = [object Number],
172:
STRING_CLASS = [object String],
173:
ARRAY_CLASS = [object Array],
174:
DATE_CLASS = [object Date],
175:
NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
176:
typeof JSON.stringify === function &&
177:
JSON.stringify(0) === 0 &&
178:
typeof JSON.stringify(Prototype.K) === undefined;
179:
180:
function Type(o) {
181:
switch(o) {
182:
case null: return NULL_TYPE;
183:
case (void 0): return UNDEFINED_TYPE;
184:
}
185:
var type = typeof o;
186:
switch(type) {
187:
case boolean: return BOOLEAN_TYPE;
188:
case number: return NUMBER_TYPE;
189:
case string: return STRING_TYPE;
190:
}
191:
return OBJECT_TYPE;
192:
}
193:
194:
function extend(destination, source) {
195:
for (var property in source)
196:
destination[property] = source[property];
197:
return destination;
198:
}
199:
200:
function inspect(object) {
201:
try {
202:
if (isUndefined(object)) return undefined;
203:
if (object === null) return null;
204:
return object.inspect ? object.inspect() : String(object);

prototype.js
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:

Tue Jan 04 14:26:58 2011

} catch (e) {
if (e instanceof RangeError) return ...;
throw e;
}
}
function toJSON(value) {
return Str(, { : value }, []);
}
function Str(key, holder, stack) {
var value = holder[key],
type = typeof value;
if (Type(value) === OBJECT_TYPE && typeof value.toJSON === function) {
value = value.toJSON(key);
}
var _class = _toString.call(value);
switch (_class) {
case NUMBER_CLASS:
case BOOLEAN_CLASS:
case STRING_CLASS:
value = value.valueOf();
}
switch
case
case
case
}

(value) {
null: return null;
true: return true;
false: return false;

type = typeof value;


switch (type) {
case string:
return value.inspect(true);
case number:
return isFinite(value) ? String(value) : null;
case object:
for (var i = 0, length = stack.length; i < length; i++) {
if (stack[i] === value) { throw new TypeError(); }
}
stack.push(value);
var partial = [];
if (_class === ARRAY_CLASS) {
for (var i = 0, length = value.length; i < length; i++) {
var str = Str(i, value, stack);
partial.push(typeof str === undefined ? null : str);
}
partial = [ + partial.join(,) + ];
} else {
var keys = Object.keys(value);
for (var i = 0, length = keys.length; i < length; i++) {
var key = keys[i], str = Str(key, value, stack);
if (typeof str !== "undefined") {
partial.push(key.inspect(true)+ : + str);
}
}
partial = { + partial.join(,) + };
}
stack.pop();
return partial;
}
}

prototype.js
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:

Tue Jan 04 14:26:58 2011

function stringify(object) {
return JSON.stringify(object);
}
function toQueryString(object) {
return $H(object).toQueryString();
}
function toHTML(object) {
return object && object.toHTML ? object.toHTML() : String.interpret(object);
}
function keys(object) {
if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
var results = [];
for (var property in object) {
if (object.hasOwnProperty(property)) {
results.push(property);
}
}
return results;
}
function values(object) {
var results = [];
for (var property in object)
results.push(object[property]);
return results;
}
function clone(object) {
return extend({ }, object);
}
function isElement(object) {
return !!(object && object.nodeType == 1);
}
function isArray(object) {
return _toString.call(object) === ARRAY_CLASS;
}
var hasNativeIsArray = (typeof Array.isArray == function)
&& Array.isArray([]) && !Array.isArray({});
if (hasNativeIsArray) {
isArray = Array.isArray;
}
function isHash(object) {
return object instanceof Hash;
}
function isFunction(object) {
return _toString.call(object) === FUNCTION_CLASS;
}
function isString(object) {
return _toString.call(object) === STRING_CLASS;
}
function isNumber(object) {
return _toString.call(object) === NUMBER_CLASS;
}
function isDate(object) {
return _toString.call(object) === DATE_CLASS;
}

prototype.js

Tue Jan 04 14:26:58 2011

341:
function isUndefined(object) {
342:
343:
return typeof object === "undefined";
344:
}
345:
346:
extend(Object, {
347:
extend:
extend,
348:
inspect:
inspect,
349:
toJSON:
NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
350:
toQueryString: toQueryString,
351:
toHTML:
toHTML,
352:
keys:
Object.keys || keys,
353:
values:
values,
354:
clone:
clone,
355:
isElement:
isElement,
356:
isArray:
isArray,
357:
isHash:
isHash,
358:
isFunction:
isFunction,
359:
isString:
isString,
360:
isNumber:
isNumber,
361:
isDate:
isDate,
362:
isUndefined:
isUndefined
363:
});
364: })();
365: Object.extend(Function.prototype, (function() {
366:
var slice = Array.prototype.slice;
367:
368:
function update(array, args) {
369:
var arrayLength = array.length, length = args.length;
370:
while (length--) array[arrayLength + length] = args[length];
371:
return array;
372:
}
373:
374:
function merge(array, args) {
375:
array = slice.call(array, 0);
376:
return update(array, args);
377:
}
378:
379:
function argumentNames() {
380:
var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
381:
.replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, )
382:
.replace(/\s+/g, ).split(,);
383:
return names.length == 1 && !names[0] ? [] : names;
384:
}
385:
386:
function bind(context) {
387:
if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
388:
var __method = this, args = slice.call(arguments, 1);
389:
return function() {
390:
var a = merge(args, arguments);
391:
return __method.apply(context, a);
392:
}
393:
}
394:
395:
function bindAsEventListener(context) {
396:
var __method = this, args = slice.call(arguments, 1);
397:
return function(event) {
398:
var a = update([event || window.event], args);
399:
return __method.apply(context, a);
400:
}
401:
}
402:
403:
function curry() {
404:
if (!arguments.length) return this;
405:
var __method = this, args = slice.call(arguments, 0);
406:
return function() {
407:
var a = merge(args, arguments);
408:
return __method.apply(this, a);

prototype.js

Tue Jan 04 14:26:58 2011

409:
}
410:
}
411:
function delay(timeout) {
412:
413:
var __method = this, args = slice.call(arguments, 1);
414:
timeout = timeout * 1000;
415:
return window.setTimeout(function() {
416:
return __method.apply(__method, args);
417:
}, timeout);
418:
}
419:
420:
function defer() {
421:
var args = update([0.01], arguments);
422:
return this.delay.apply(this, args);
423:
}
424:
425:
function wrap(wrapper) {
426:
var __method = this;
427:
return function() {
428:
var a = update([__method.bind(this)], arguments);
429:
return wrapper.apply(this, a);
430:
}
431:
}
432:
433:
function methodize() {
434:
if (this._methodized) return this._methodized;
435:
var __method = this;
436:
return this._methodized = function() {
437:
var a = update([this], arguments);
438:
return __method.apply(null, a);
439:
};
440:
}
441:
442:
return {
443:
argumentNames:
argumentNames,
444:
bind:
bind,
445:
bindAsEventListener: bindAsEventListener,
446:
curry:
curry,
447:
delay:
delay,
448:
defer:
defer,
449:
wrap:
wrap,
450:
methodize:
methodize
451:
}
452: })());
453:
454:
455:
456: (function(proto) {
457:
458:
459:
function toISOString() {
460:
return this.getUTCFullYear() + - +
461:
(this.getUTCMonth() + 1).toPaddedString(2) + - +
462:
this.getUTCDate().toPaddedString(2) + T +
463:
this.getUTCHours().toPaddedString(2) + : +
464:
this.getUTCMinutes().toPaddedString(2) + : +
465:
this.getUTCSeconds().toPaddedString(2) + Z;
466:
}
467:
468:
469:
function toJSON() {
470:
return this.toISOString();
471:
}
472:
473:
if (!proto.toISOString) proto.toISOString = toISOString;
474:
if (!proto.toJSON) proto.toJSON = toJSON;
475:
476: })(Date.prototype);

prototype.js
477:
478:
479:
480:
481:
482:
483:
484:
485:
486:
487:
488:
489:
490:
491:
492:
493:
494:
495:
496:
497:
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508:
509:
510:
511:
512:
513:
514:
515:
516:
517:
518:
519:
520:
521:
522:
523:
524:
525:
526:
527:
528:
529:
530:
531:
532:
533:
534:
535:
536:
537:
538:
539:
540:
541:
542:
543:
544:

Tue Jan 04 14:26:58 2011

RegExp.prototype.match = RegExp.prototype.test;
RegExp.escape = function(str) {
return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, \\$1);
};
var PeriodicalExecuter = Class.create({
initialize: function(callback, frequency) {
this.callback = callback;
this.frequency = frequency;
this.currentlyExecuting = false;
this.registerCallback();
},
registerCallback: function() {
this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
},
execute: function() {
this.callback(this);
},
stop: function() {
if (!this.timer) return;
clearInterval(this.timer);
this.timer = null;
},
onTimerEvent: function() {
if (!this.currentlyExecuting) {
try {
this.currentlyExecuting = true;
this.execute();
this.currentlyExecuting = false;
} catch(e) {
this.currentlyExecuting = false;
throw e;
}
}
}
});
Object.extend(String, {
interpret: function(value) {
return value == null ? : String(value);
},
specialChar: {
\b: \\b,
\t: \\t,
\n: \\n,
\f: \\f,
\r: \\r,
\\: \\\\
}
});
Object.extend(String.prototype, (function() {
var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
typeof JSON.parse === function &&
JSON.parse({"test": true}).test;
function prepareReplacement(replacement) {
if (Object.isFunction(replacement)) return replacement;
var template = new Template(replacement);
return function(match) { return template.evaluate(match) };
}

prototype.js
545:
546:
547:
548:
549:
550:
551:
552:
553:
554:
555:
556:
557:
558:
559:
560:
561:
562:
563:
564:
565:
566:
567:
568:
569:
570:
571:
572:
573:
574:
575:
576:
577:
578:
579:
580:
581:
582:
583:
584:
585:
586:
587:
588:
589:
590:
591:
592:
593:
594:
595:
596:
597:
598:
599:
600:
601:
602:
603:
604:
605:
606:
607:
608:
609:
610:
611:
612:

Tue Jan 04 14:26:58 2011

function gsub(pattern, replacement) {


var result = , source = this, match;
replacement = prepareReplacement(replacement);
if (Object.isString(pattern))
pattern = RegExp.escape(pattern);
if (!(pattern.length || pattern.source)) {
replacement = replacement();
return replacement + source.split().join(replacement) + replacement;
}
while (source.length > 0) {
if (match = source.match(pattern)) {
result += source.slice(0, match.index);
result += String.interpret(replacement(match));
source = source.slice(match.index + match[0].length);
} else {
result += source, source = ;
}
}
return result;
}
function sub(pattern, replacement, count) {
replacement = prepareReplacement(replacement);
count = Object.isUndefined(count) ? 1 : count;
return this.gsub(pattern, function(match) {
if (--count < 0) return match[0];
return replacement(match);
});
}
function scan(pattern, iterator) {
this.gsub(pattern, iterator);
return String(this);
}
function truncate(length, truncation) {
length = length || 30;
truncation = Object.isUndefined(truncation) ? ... : truncation;
return this.length > length ?
this.slice(0, length - truncation.length) + truncation : String(this);
}
function strip() {
return this.replace(/^\s+/, ).replace(/\s+$/, );
}
function stripTags() {
return this.replace(/<\w+(\s+("[^"]*"|[^]*|[^>])+)?>|<\/\w+>/gi, );
}
function stripScripts() {
return this.replace(new RegExp(Prototype.ScriptFragment, img), );
}
function extractScripts() {
var matchAll = new RegExp(Prototype.ScriptFragment, img),
matchOne = new RegExp(Prototype.ScriptFragment, im);
return (this.match(matchAll) || []).map(function(scriptTag) {
return (scriptTag.match(matchOne) || [, ])[1];
});
}
function evalScripts() {
return this.extractScripts().map(function(script) { return eval(script) });

prototype.js
613:
614:
615:
616:
617:
618:
619:
620:
/g,&);
621:
622:
623:
624:
625:
626:
627:
628:
629:
630:
631:
632:
633:
634:
635:
636:
637:
638:
639:
640:
641:
642:
643:
644:
645:
646:
647:
648:
649:
650:
651:
652:
653:
654:
655:
656:
657:
658:
659:
660:
661:
662:
663:
664:
665:
666:
667:
668:
669:
670:
671:
672:
673:
674:
675:
676:
677:
678:
679:

Tue Jan 04 14:26:58 2011

10

}
function escapeHTML() {
return this.replace(/&/g,&amp;).replace(/</g,&lt;).replace(/>/g,&gt;);
}
function unescapeHTML() {
return this.stripTags().replace(/&lt;/g,<).replace(/&gt;/g,>).replace(/&amp;
}

function toQueryParams(separator) {
var match = this.strip().match(/([^?#]*)(#.*)?$/);
if (!match) return { };
return match[1].split(separator || &).inject({ }, function(hash, pair) {
if ((pair = pair.split(=))[0]) {
var key = decodeURIComponent(pair.shift()),
value = pair.length > 1 ? pair.join(=) : pair[0];
if (value != undefined) value = decodeURIComponent(value);
if (key in hash) {
if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
hash[key].push(value);
}
else hash[key] = value;
}
return hash;
});
}
function toArray() {
return this.split();
}
function succ() {
return this.slice(0, this.length - 1) +
String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
}
function times(count) {
return count < 1 ? : new Array(count + 1).join(this);
}
function camelize() {
return this.replace(/-+(.)?/g, function(match, chr) {
return chr ? chr.toUpperCase() : ;
});
}
function capitalize() {
return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
}
function underscore() {
return this.replace(/::/g, /)
.replace(/([A-Z]+)([A-Z][a-z])/g, $1_$2)
.replace(/([a-z\d])([A-Z])/g, $1_$2)
.replace(/-/g, _)
.toLowerCase();
}
function dasherize() {
return this.replace(/_/g, -);
}

prototype.js

Tue Jan 04 14:26:58 2011

11

function inspect(useDoubleQuotes) {
680:
681:
var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
682:
if (character in String.specialChar) {
683:
return String.specialChar[character];
684:
}
685:
return \\u00 + character.charCodeAt().toPaddedString(2, 16);
686:
});
687:
if (useDoubleQuotes) return " + escapedString.replace(/"/g, \\") + ";
688:
return "" + escapedString.replace(//g, \\\) + "";
689:
}
690:
691:
function unfilterJSON(filter) {
692:
return this.replace(filter || Prototype.JSONFilter, $1);
693:
}
694:
695:
function isJSON() {
696:
var str = this;
697:
if (str.blank()) return false;
698:
str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, @);
699:
str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+
)?/g, ]);
700:
str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, );
701:
return (/^[\],:{}\s]*$/).test(str);
702:
}
703:
704:
function evalJSON(sanitize) {
705:
var json = this.unfilterJSON(),
706:
cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f
\u2060-\u206f\ufeff\ufff0-\uffff]/g;
707:
if (cx.test(json)) {
708:
json = json.replace(cx, function (a) {
709:
return \\u + (0000 + a.charCodeAt(0).toString(16)).slice(-4);
710:
});
711:
}
712:
try {
713:
if (!sanitize || json.isJSON()) return eval(( + json + ));
714:
} catch (e) { }
715:
throw new SyntaxError(Badly formed JSON string: + this.inspect());
716:
}
717:
718:
function parseJSON() {
719:
var json = this.unfilterJSON();
720:
return JSON.parse(json);
721:
}
722:
723:
function include(pattern) {
724:
return this.indexOf(pattern) > -1;
725:
}
726:
727:
function startsWith(pattern) {
728:
return this.lastIndexOf(pattern, 0) === 0;
729:
}
730:
731:
function endsWith(pattern) {
732:
var d = this.length - pattern.length;
733:
return d >= 0 && this.indexOf(pattern, d) === d;
734:
}
735:
736:
function empty() {
737:
return this == ;
738:
}
739:
740:
function blank() {
741:
return /^\s*$/.test(this);
742:
}
743:
744:
function interpolate(object, pattern) {
745:
return new Template(this, pattern).evaluate(object);

prototype.js

Tue Jan 04 14:26:58 2011

12

746:
}
747:
return {
748:
749:
gsub:
gsub,
750:
sub:
sub,
751:
scan:
scan,
752:
truncate:
truncate,
753:
strip:
String.prototype.trim || strip,
754:
stripTags:
stripTags,
755:
stripScripts:
stripScripts,
756:
extractScripts: extractScripts,
757:
evalScripts:
evalScripts,
758:
escapeHTML:
escapeHTML,
759:
unescapeHTML:
unescapeHTML,
760:
toQueryParams: toQueryParams,
761:
parseQuery:
toQueryParams,
762:
toArray:
toArray,
763:
succ:
succ,
764:
times:
times,
765:
camelize:
camelize,
766:
capitalize:
capitalize,
767:
underscore:
underscore,
768:
dasherize:
dasherize,
769:
inspect:
inspect,
770:
unfilterJSON:
unfilterJSON,
771:
isJSON:
isJSON,
772:
evalJSON:
NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
773:
include:
include,
774:
startsWith:
startsWith,
775:
endsWith:
endsWith,
776:
empty:
empty,
777:
blank:
blank,
778:
interpolate:
interpolate
779:
};
780: })());
781:
782: var Template = Class.create({
783:
initialize: function(template, pattern) {
784:
this.template = template.toString();
785:
this.pattern = pattern || Template.Pattern;
786:
},
787:
788:
evaluate: function(object) {
789:
if (object && Object.isFunction(object.toTemplateReplacements))
790:
object = object.toTemplateReplacements();
791:
792:
return this.template.gsub(this.pattern, function(match) {
793:
if (object == null) return (match[1] + );
794:
795:
var before = match[1] || ;
796:
if (before == \\) return match[2];
797:
798:
var ctx = object, expr = match[3],
799:
pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
800:
801:
match = pattern.exec(expr);
802:
if (match == null) return before;
803:
804:
while (match != null) {
805:
var comp = match[1].startsWith([) ? match[2].replace(/\\\\]/g, ]) : matc
h[1];
806:
ctx = ctx[comp];
807:
if (null == ctx || == match[3]) break;
808:
expr = expr.substring([ == match[3] ? match[1].length : match[0].length);
809:
match = pattern.exec(expr);
810:
}
811:
812:
return before + String.interpret(ctx);

prototype.js
813:
814:
815:
816:
817:
818:
819:
820:
821:
822:
823:
824:
825:
826:
827:
828:
829:
830:
831:
832:
833:
834:
835:
836:
837:
838:
839:
840:
841:
842:
843:
844:
845:
846:
847:
848:
849:
850:
851:
852:
853:
854:
855:
856:
857:
858:
859:
860:
861:
862:
863:
864:
865:
866:
867:
868:
869:
870:
871:
872:
873:
874:
875:
876:
877:
878:
879:
880:

Tue Jan 04 14:26:58 2011

13

});
}
});
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
var $break = { };
var Enumerable = (function() {
function each(iterator, context) {
var index = 0;
try {
this._each(function(value) {
iterator.call(context, value, index++);
});
} catch (e) {
if (e != $break) throw e;
}
return this;
}
function eachSlice(number, iterator, context) {
var index = -number, slices = [], array = this.toArray();
if (number < 1) return array;
while ((index += number) < array.length)
slices.push(array.slice(index, index+number));
return slices.collect(iterator, context);
}
function all(iterator, context) {
iterator = iterator || Prototype.K;
var result = true;
this.each(function(value, index) {
result = result && !!iterator.call(context, value, index);
if (!result) throw $break;
});
return result;
}
function any(iterator, context) {
iterator = iterator || Prototype.K;
var result = false;
this.each(function(value, index) {
if (result = !!iterator.call(context, value, index))
throw $break;
});
return result;
}
function collect(iterator, context) {
iterator = iterator || Prototype.K;
var results = [];
this.each(function(value, index) {
results.push(iterator.call(context, value, index));
});
return results;
}
function detect(iterator, context) {
var result;
this.each(function(value, index) {
if (iterator.call(context, value, index)) {
result = value;
throw $break;
}
});
return result;
}

prototype.js
881:
882:
883:
884:
885:
886:
887:
888:
889:
890:
891:
892:
893:
894:
895:
896:
897:
898:
899:
900:
901:
902:
903:
904:
905:
906:
907:
908:
909:
910:
911:
912:
913:
914:
915:
916:
917:
918:
919:
920:
921:
922:
923:
924:
925:
926:
927:
928:
929:
930:
931:
932:
933:
934:
935:
936:
937:
938:
939:
940:
941:
942:
943:
944:
945:
946:
947:
948:

Tue Jan 04 14:26:58 2011

14

function findAll(iterator, context) {


var results = [];
this.each(function(value, index) {
if (iterator.call(context, value, index))
results.push(value);
});
return results;
}
function grep(filter, iterator, context) {
iterator = iterator || Prototype.K;
var results = [];
if (Object.isString(filter))
filter = new RegExp(RegExp.escape(filter));
this.each(function(value, index) {
if (filter.match(value))
results.push(iterator.call(context, value, index));
});
return results;
}
function include(object) {
if (Object.isFunction(this.indexOf))
if (this.indexOf(object) != -1) return true;
var found = false;
this.each(function(value) {
if (value == object) {
found = true;
throw $break;
}
});
return found;
}
function inGroupsOf(number, fillWith) {
fillWith = Object.isUndefined(fillWith) ? null : fillWith;
return this.eachSlice(number, function(slice) {
while(slice.length < number) slice.push(fillWith);
return slice;
});
}
function inject(memo, iterator, context) {
this.each(function(value, index) {
memo = iterator.call(context, memo, value, index);
});
return memo;
}
function invoke(method) {
var args = $A(arguments).slice(1);
return this.map(function(value) {
return value[method].apply(value, args);
});
}
function max(iterator, context) {
iterator = iterator || Prototype.K;
var result;
this.each(function(value, index) {
value = iterator.call(context, value, index);
if (result == null || value >= result)
result = value;
});
return result;

prototype.js
949:
950:
951:
952:
953:
954:
955:
956:
957:
958:
959:
960:
961:
962:
963:
964:
965:
966:
967:
968:
969:
970:
971:
972:
973:
974:
975:
976:
977:
978:
979:
980:
981:
982:
983:
984:
985:
986:
987:
988:
989:
990:
991:
992:
993:
994:
995:
996:
997:
998:
999:
1000:
1001:
1002:
1003:
1004:
1005:
1006:
1007:
1008:
1009:
1010:
1011:
1012:
1013:
1014:
1015:
1016:

Tue Jan 04 14:26:58 2011

15

}
function min(iterator, context) {
iterator = iterator || Prototype.K;
var result;
this.each(function(value, index) {
value = iterator.call(context, value, index);
if (result == null || value < result)
result = value;
});
return result;
}
function partition(iterator, context) {
iterator = iterator || Prototype.K;
var trues = [], falses = [];
this.each(function(value, index) {
(iterator.call(context, value, index) ?
trues : falses).push(value);
});
return [trues, falses];
}
function pluck(property) {
var results = [];
this.each(function(value) {
results.push(value[property]);
});
return results;
}
function reject(iterator, context) {
var results = [];
this.each(function(value, index) {
if (!iterator.call(context, value, index))
results.push(value);
});
return results;
}
function sortBy(iterator, context) {
return this.map(function(value, index) {
return {
value: value,
criteria: iterator.call(context, value, index)
};
}).sort(function(left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
}).pluck(value);
}
function toArray() {
return this.map();
}
function zip() {
var iterator = Prototype.K, args = $A(arguments);
if (Object.isFunction(args.last()))
iterator = args.pop();
var collections = [this].concat(args).map($A);
return this.map(function(value, index) {
return iterator(collections.pluck(index));
});
}
function size() {

prototype.js
1017:
1018:
1019:
1020:
1021:
1022:
1023:
1024:
1025:
1026:
1027:
1028:
1029:
1030:
1031:
1032:
1033:
1034:
1035:
1036:
1037:
1038:
1039:
1040:
1041:
1042:
1043:
1044:
1045:
1046:
1047:
1048:
1049:
1050:
1051:
1052:
1053:
1054:
1055:
1056:
1057:
1058:
1059:
1060:
1061:
1062:
1063:
1064:
1065:
1066:
1067:
1068:
1069:
1070:
1071:
1072:
1073:
1074:
1075:
1076:
1077:
1078:
1079:
1080:
1081:
1082:
1083:
1084:

Tue Jan 04 14:26:58 2011

16

return this.toArray().length;
}
function inspect() {
return #<Enumerable: + this.toArray().inspect() + >;
}

return {
each:
eachSlice:
all:
every:
any:
some:
collect:
map:
detect:
findAll:
select:
filter:
grep:
include:
member:
inGroupsOf:
inject:
invoke:
max:
min:
partition:
pluck:
reject:
sortBy:
toArray:
entries:
zip:
size:
inspect:
find:
};
})();

each,
eachSlice,
all,
all,
any,
any,
collect,
collect,
detect,
findAll,
findAll,
findAll,
grep,
include,
include,
inGroupsOf,
inject,
invoke,
max,
min,
partition,
pluck,
reject,
sortBy,
toArray,
toArray,
zip,
size,
inspect,
detect

function $A(iterable) {
if (!iterable) return [];
if (toArray in Object(iterable)) return iterable.toArray();
var length = iterable.length || 0, results = new Array(length);
while (length--) results[length] = iterable[length];
return results;
}

function $w(string) {
if (!Object.isString(string)) return [];
string = string.strip();
return string ? string.split(/\s+/) : [];
}
Array.from = $A;

(function() {

prototype.js
1085:
1086:
1087:
ilable
1088:
1089:
1090:
1091:
1092:
1093:
1094:
1095:
1096:
1097:
1098:
1099:
1100:
1101:
1102:
1103:
1104:
1105:
1106:
1107:
1108:
1109:
1110:
1111:
1112:
1113:
1114:
1115:
1116:
1117:
1118:
1119:
1120:
1121:
1122:
1123:
1124:
1125:
1126:
1127:
1128:
1129:
1130:
1131:
1132:
1133:
1134:
1135:
1136:
1137:
1138:
1139:
1140:
1141:
1142:
1143:
1144:
1145:
1146:
1147:
1148:
1149:
1150:
1151:

Tue Jan 04 14:26:58 2011

17

var arrayProto = Array.prototype,


slice = arrayProto.slice,
_each = arrayProto.forEach; // use native browser JS 1.6 implementation if ava

function each(iterator, context) {


for (var i = 0, length = this.length >>> 0; i < length; i++) {
if (i in this) iterator.call(context, this[i], i, this);
}
}
if (!_each) _each = each;
function clear() {
this.length = 0;
return this;
}
function first() {
return this[0];
}
function last() {
return this[this.length - 1];
}
function compact() {
return this.select(function(value) {
return value != null;
});
}
function flatten() {
return this.inject([], function(array, value) {
if (Object.isArray(value))
return array.concat(value.flatten());
array.push(value);
return array;
});
}
function without() {
var values = slice.call(arguments, 0);
return this.select(function(value) {
return !values.include(value);
});
}
function reverse(inline) {
return (inline === false ? this.toArray() : this)._reverse();
}
function uniq(sorted) {
return this.inject([], function(array, value, index) {
if (0 == index || (sorted ? array.last() != value : !array.include(value)))
array.push(value);
return array;
});
}
function intersect(array) {
return this.uniq().findAll(function(item) {
return array.detect(function(value) { return item === value });
});
}

function clone() {
return slice.call(this, 0);

prototype.js
1152:
1153:
1154:
1155:
1156:
1157:
1158:
1159:
1160:
1161:
1162:
1163:
1164:
1165:
1166:
1167:
1168:
1169:
1170:
1171:
1172:
1173:
1174:
1175:
1176:
1177:
1178:
1179:
1180:
1181:
1182:
1183:
1184:
1185:
1186:
1187:
1188:
1189:
1190:
1191:
1192:
1193:
1194:
1195:
1196:
1197:
1198:
1199:
1200:
1201:
1202:
1203:
1204:
1205:
1206:
1207:
1208:
1209:
1210:
1211:
1212:
1213:
1214:
1215:
1216:
1217:
1218:
1219:

Tue Jan 04 14:26:58 2011

18

}
function size() {
return this.length;
}
function inspect() {
return [ + this.map(Object.inspect).join(, ) + ];
}
function indexOf(item, i) {
i || (i = 0);
var length = this.length;
if (i < 0) i = length + i;
for (; i < length; i++)
if (this[i] === item) return i;
return -1;
}
function lastIndexOf(item, i) {
i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
var n = this.slice(0, i).reverse().indexOf(item);
return (n < 0) ? n : i - n - 1;
}
function concat() {
var array = slice.call(this, 0), item;
for (var i = 0, length = arguments.length; i < length; i++) {
item = arguments[i];
if (Object.isArray(item) && !(callee in item)) {
for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
array.push(item[j]);
} else {
array.push(item);
}
}
return array;
}
Object.extend(arrayProto, Enumerable);
if (!arrayProto._reverse)
arrayProto._reverse = arrayProto.reverse;
Object.extend(arrayProto, {
_each:
_each,
clear:
clear,
first:
first,
last:
last,
compact:
compact,
flatten:
flatten,
without:
without,
reverse:
reverse,
uniq:
uniq,
intersect: intersect,
clone:
clone,
toArray:
clone,
size:
size,
inspect:
inspect
});
var CONCAT_ARGUMENTS_BUGGY = (function() {
return [].concat(arguments)[0][0] !== 1;
})(1,2)
if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;

prototype.js
1220:
1221:
1222:
1223:
1224:
1225:
1226:
1227:
1228:
1229:
1230:
1231:
1232:
1233:
1234:
1235:
1236:
1237:
1238:
1239:
1240:
1241:
1242:
1243:
1244:
1245:
1246:
1247:
1248:
1249:
1250:
1251:
1252:
1253:
1254:
1255:
1256:
1257:
1258:
1259:
1260:
1261:
1262:
1263:
1264:
1265:
1266:
1267:
1268:
1269:
1270:
1271:
1272:
1273:
1274:
1275:
1276:
1277:
1278:
1279:
1280:
1281:
1282:
1283:
1284:
1285:
1286:
1287:

Tue Jan 04 14:26:58 2011

19

if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;


})();
function $H(object) {
return new Hash(object);
};
var Hash = Class.create(Enumerable, (function() {
function initialize(object) {
this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
}

function _each(iterator) {
for (var key in this._object) {
var value = this._object[key], pair = [key, value];
pair.key = key;
pair.value = value;
iterator(pair);
}
}
function set(key, value) {
return this._object[key] = value;
}
function get(key) {
if (this._object[key] !== Object.prototype[key])
return this._object[key];
}
function unset(key) {
var value = this._object[key];
delete this._object[key];
return value;
}
function toObject() {
return Object.clone(this._object);
}

function keys() {
return this.pluck(key);
}
function values() {
return this.pluck(value);
}
function index(value) {
var match = this.detect(function(pair) {
return pair.value === value;
});
return match && match.key;
}
function merge(object) {
return this.clone().update(object);
}
function update(object) {
return new Hash(object).inject(this, function(result, pair) {
result.set(pair.key, pair.value);
return result;
});
}

prototype.js

Tue Jan 04 14:26:58 2011

20

function toQueryPair(key, value) {


1288:
1289:
if (Object.isUndefined(value)) return key;
1290:
return key + = + encodeURIComponent(String.interpret(value));
1291:
}
1292:
1293:
function toQueryString() {
1294:
return this.inject([], function(results, pair) {
1295:
var key = encodeURIComponent(pair.key), values = pair.value;
1296:
1297:
if (values && typeof values == object) {
1298:
if (Object.isArray(values)) {
1299:
var queryValues = [];
1300:
for (var i = 0, len = values.length, value; i < len; i++) {
1301:
value = values[i];
1302:
queryValues.push(toQueryPair(key, value));
1303:
}
1304:
return results.concat(queryValues);
1305:
}
1306:
} else results.push(toQueryPair(key, values));
1307:
return results;
1308:
}).join(&);
1309:
}
1310:
1311:
function inspect() {
1312:
return #<Hash:{ + this.map(function(pair) {
1313:
return pair.map(Object.inspect).join(: );
1314:
}).join(, ) + }>;
1315:
}
1316:
1317:
function clone() {
1318:
return new Hash(this);
1319:
}
1320:
1321:
return {
1322:
initialize:
initialize,
1323:
_each:
_each,
1324:
set:
set,
1325:
get:
get,
1326:
unset:
unset,
1327:
toObject:
toObject,
1328:
toTemplateReplacements: toObject,
1329:
keys:
keys,
1330:
values:
values,
1331:
index:
index,
1332:
merge:
merge,
1333:
update:
update,
1334:
toQueryString:
toQueryString,
1335:
inspect:
inspect,
1336:
toJSON:
toObject,
1337:
clone:
clone
1338:
};
1339: })());
1340:
1341: Hash.from = $H;
1342: Object.extend(Number.prototype, (function() {
1343:
function toColorPart() {
1344:
return this.toPaddedString(2, 16);
1345:
}
1346:
1347:
function succ() {
1348:
return this + 1;
1349:
}
1350:
1351:
function times(iterator, context) {
1352:
$R(0, this, true).each(iterator, context);
1353:
return this;
1354:
}
1355:

prototype.js
1356:
1357:
1358:
1359:
1360:
1361:
1362:
1363:
1364:
1365:
1366:
1367:
1368:
1369:
1370:
1371:
1372:
1373:
1374:
1375:
1376:
1377:
1378:
1379:
1380:
1381:
1382:
1383:
1384:
1385:
1386:
1387:
1388:
1389:
1390:
1391:
1392:
1393:
1394:
1395:
1396:
1397:
1398:
1399:
1400:
1401:
1402:
1403:
1404:
1405:
1406:
1407:
1408:
1409:
1410:
1411:
1412:
1413:
1414:
1415:
1416:
1417:
1418:
1419:
1420:
1421:
1422:
1423:

Tue Jan 04 14:26:58 2011

21

function toPaddedString(length, radix) {


var string = this.toString(radix || 10);
return 0.times(length - string.length) + string;
}
function abs() {
return Math.abs(this);
}
function round() {
return Math.round(this);
}
function ceil() {
return Math.ceil(this);
}
function floor() {
return Math.floor(this);
}
return {
toColorPart:
succ:
times:
toPaddedString:
abs:
round:
ceil:
floor:
};
})());

toColorPart,
succ,
times,
toPaddedString,
abs,
round,
ceil,
floor

function $R(start, end, exclusive) {


return new ObjectRange(start, end, exclusive);
}
var ObjectRange = Class.create(Enumerable, (function() {
function initialize(start, end, exclusive) {
this.start = start;
this.end = end;
this.exclusive = exclusive;
}
function _each(iterator) {
var value = this.start;
while (this.include(value)) {
iterator(value);
value = value.succ();
}
}
function include(value) {
if (value < this.start)
return false;
if (this.exclusive)
return value < this.end;
return value <= this.end;
}
return {
initialize: initialize,
_each:
_each,
include:
include
};
})());

prototype.js
1424:
1425:
1426:
1427:
1428:
1429:
1430:
1431:
1432:
1433:
1434:
1435:
1436:
1437:
1438:
1439:
1440:
1441:
1442:
1443:
1444:
1445:
1446:
1447:
1448:
1449:
1450:
1451:
1452:
1453:
1454:
1455:
1456:
1457:
1458:
1459:
1460:
1461:
1462:
1463:
1464:
1465:
1466:
1467:
1468:
1469:
1470:
1471:
1472:
1473:
1474:
1475:
1476:
1477:
1478:
1479:
1480:
1481:
1482:
1483:
1484:
1485:
1486:
1487:
1488:
1489:
1490:
1491:

Tue Jan 04 14:26:58 2011

22

var Ajax = {
getTransport: function() {
return Try.these(
function() {return new XMLHttpRequest()},
function() {return new ActiveXObject(Msxml2.XMLHTTP)},
function() {return new ActiveXObject(Microsoft.XMLHTTP)}
) || false;
},
activeRequestCount: 0
};
Ajax.Responders = {
responders: [],
_each: function(iterator) {
this.responders._each(iterator);
},
register: function(responder) {
if (!this.include(responder))
this.responders.push(responder);
},
unregister: function(responder) {
this.responders = this.responders.without(responder);
},
dispatch: function(callback, request, transport, json) {
this.each(function(responder) {
if (Object.isFunction(responder[callback])) {
try {
responder[callback].apply(responder, [request, transport, json]);
} catch (e) { }
}
});
}
};
Object.extend(Ajax.Responders, Enumerable);
Ajax.Responders.register({
onCreate:
function() { Ajax.activeRequestCount++ },
onComplete: function() { Ajax.activeRequestCount-- }
});
Ajax.Base = Class.create({
initialize: function(options) {
this.options = {
method:
post,
asynchronous: true,
contentType: application/x-www-form-urlencoded,
encoding:
UTF-8,
parameters:
,
evalJSON:
true,
evalJS:
true
};
Object.extend(this.options, options || { });
this.options.method = this.options.method.toLowerCase();
if (Object.isHash(this.options.parameters))
this.options.parameters = this.options.parameters.toObject();
}
});
Ajax.Request = Class.create(Ajax.Base, {
_complete: false,

prototype.js
1492:
1493:
1494:
1495:
1496:
1497:
1498:
1499:
1500:
1501:
1502:
1503:
1504:
1505:
1506:
1507:
1508:
1509:
1510:
1511:
1512:
1513:
1514:
1515:
1516:
1517:
1518:
1519:
1520:
1521:
1522:
1523:
1524:
1525:
1526:
1527:
1528:
1529:
1530:
1531:
1532:
1533:
1534:
1535:
1536:
1537:
1538:
1539:
1540:
1541:
1542:
1543:
1544:
1545:
1546:
1547:
1548:
1549:
1550:
1551:
1552:
1553:
1554:
1555:
1556:
1557:
1558:
1559:

Tue Jan 04 14:26:58 2011

23

initialize: function($super, url, options) {


$super(options);
this.transport = Ajax.getTransport();
this.request(url);
},
request: function(url) {
this.url = url;
this.method = this.options.method;
var params = Object.isString(this.options.parameters) ?
this.options.parameters :
Object.toQueryString(this.options.parameters);
if (![get, post].include(this.method)) {
params += (params ? & : ) + "_method=" + this.method;
this.method = post;
}
if (params && this.method === get) {
this.url += (this.url.include(?) ? & : ?) + params;
}
this.parameters = params.toQueryParams();
try {
var response = new Ajax.Response(this);
if (this.options.onCreate) this.options.onCreate(response);
Ajax.Responders.dispatch(onCreate, this, response);
this.transport.open(this.method.toUpperCase(), this.url,
this.options.asynchronous);
if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
this.transport.onreadystatechange = this.onStateChange.bind(this);
this.setRequestHeaders();
this.body = this.method == post ? (this.options.postBody || params) : null;
this.transport.send(this.body);
/* Force Firefox to handle ready state 4 for synchronous requests */
if (!this.options.asynchronous && this.transport.overrideMimeType)
this.onStateChange();
}
catch (e) {
this.dispatchException(e);
}
},
onStateChange: function() {
var readyState = this.transport.readyState;
if (readyState > 1 && !((readyState == 4) && this._complete))
this.respondToReadyState(this.transport.readyState);
},
setRequestHeaders: function() {
var headers = {
X-Requested-With: XMLHttpRequest,
X-Prototype-Version: Prototype.Version,
Accept: text/javascript, text/html, application/xml, text/xml, */*
};
if (this.method == post) {
headers[Content-type] = this.options.contentType +
(this.options.encoding ? ; charset= + this.options.encoding : );
/* Force "Connection: close" for older Mozilla browsers to work

prototype.js

Tue Jan 04 14:26:58 2011

24

1560:
* around a bug where XMLHttpRequest sends an incorrect
1561:
* Content-length header. See Mozilla Bugzilla #246651.
1562:
*/
1563:
if (this.transport.overrideMimeType &&
1564:
(navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
1565:
headers[Connection] = close;
1566:
}
1567:
1568:
if (typeof this.options.requestHeaders == object) {
1569:
var extras = this.options.requestHeaders;
1570:
1571:
if (Object.isFunction(extras.push))
1572:
for (var i = 0, length = extras.length; i < length; i += 2)
1573:
headers[extras[i]] = extras[i+1];
1574:
else
1575:
$H(extras).each(function(pair) { headers[pair.key] = pair.value });
1576:
}
1577:
1578:
for (var name in headers)
1579:
this.transport.setRequestHeader(name, headers[name]);
1580:
},
1581:
1582:
success: function() {
1583:
var status = this.getStatus();
1584:
return !status || (status >= 200 && status < 300) || status == 304;
1585:
},
1586:
1587:
getStatus: function() {
1588:
try {
1589:
if (this.transport.status === 1223) return 204;
1590:
return this.transport.status || 0;
1591:
} catch (e) { return 0 }
1592:
},
1593:
1594:
respondToReadyState: function(readyState) {
1595:
var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
1596:
1597:
if (state == Complete) {
1598:
try {
1599:
this._complete = true;
1600:
(this.options[on + response.status]
1601:
|| this.options[on + (this.success() ? Success : Failure)]
1602:
|| Prototype.emptyFunction)(response, response.headerJSON);
1603:
} catch (e) {
1604:
this.dispatchException(e);
1605:
}
1606:
1607:
var contentType = response.getHeader(Content-type);
1608:
if (this.options.evalJS == force
1609:
|| (this.options.evalJS && this.isSameOrigin() && contentType
1610:
&& contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?
\s*$/i)))
1611:
this.evalResponse();
1612:
}
1613:
1614:
try {
1615:
(this.options[on + state] || Prototype.emptyFunction)(response, response.hea
derJSON);
1616:
Ajax.Responders.dispatch(on + state, this, response, response.headerJSON);
1617:
} catch (e) {
1618:
this.dispatchException(e);
1619:
}
1620:
1621:
if (state == Complete) {
1622:
this.transport.onreadystatechange = Prototype.emptyFunction;
1623:
}
1624:
},
1625:

prototype.js

Tue Jan 04 14:26:58 2011

25

1626:
isSameOrigin: function() {
1627:
var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
1628:
return !m || (m[0] == #{protocol}//#{domain}#{port}.interpolate({
1629:
protocol: location.protocol,
1630:
domain: document.domain,
1631:
port: location.port ? : + location.port :
1632:
}));
1633:
},
1634:
1635:
getHeader: function(name) {
1636:
try {
1637:
return this.transport.getResponseHeader(name) || null;
1638:
} catch (e) { return null; }
1639:
},
1640:
1641:
evalResponse: function() {
1642:
try {
1643:
return eval((this.transport.responseText || ).unfilterJSON());
1644:
} catch (e) {
1645:
this.dispatchException(e);
1646:
}
1647:
},
1648:
1649:
dispatchException: function(exception) {
1650:
(this.options.onException || Prototype.emptyFunction)(this, exception);
1651:
Ajax.Responders.dispatch(onException, this, exception);
1652:
}
1653: });
1654:
1655: Ajax.Request.Events =
1656:
[Uninitialized, Loading, Loaded, Interactive, Complete];
1657:
1658:
1659:
1660:
1661:
1662:
1663:
1664:
1665: Ajax.Response = Class.create({
1666:
initialize: function(request){
1667:
this.request = request;
1668:
var transport = this.transport = request.transport,
1669:
readyState = this.readyState = transport.readyState;
1670:
1671:
if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
1672:
this.status
= this.getStatus();
1673:
this.statusText
= this.getStatusText();
1674:
this.responseText = String.interpret(transport.responseText);
1675:
this.headerJSON
= this._getHeaderJSON();
1676:
}
1677:
1678:
if (readyState == 4) {
1679:
var xml = transport.responseXML;
1680:
this.responseXML = Object.isUndefined(xml) ? null : xml;
1681:
this.responseJSON = this._getResponseJSON();
1682:
}
1683:
},
1684:
1685:
status:
0,
1686:
1687:
statusText: ,
1688:
1689:
getStatus: Ajax.Request.prototype.getStatus,
1690:
1691:
getStatusText: function() {
1692:
try {
1693:
return this.transport.statusText || ;

prototype.js

Tue Jan 04 14:26:58 2011

26

1694:
} catch (e) { return }
1695:
},
1696:
1697:
getHeader: Ajax.Request.prototype.getHeader,
1698:
1699:
getAllHeaders: function() {
1700:
try {
1701:
return this.getAllResponseHeaders();
1702:
} catch (e) { return null }
1703:
},
1704:
1705:
getResponseHeader: function(name) {
1706:
return this.transport.getResponseHeader(name);
1707:
},
1708:
1709:
getAllResponseHeaders: function() {
1710:
return this.transport.getAllResponseHeaders();
1711:
},
1712:
1713:
_getHeaderJSON: function() {
1714:
var json = this.getHeader(X-JSON);
1715:
if (!json) return null;
1716:
json = decodeURIComponent(escape(json));
1717:
try {
1718:
return json.evalJSON(this.request.options.sanitizeJSON ||
1719:
!this.request.isSameOrigin());
1720:
} catch (e) {
1721:
this.request.dispatchException(e);
1722:
}
1723:
},
1724:
1725:
_getResponseJSON: function() {
1726:
var options = this.request.options;
1727:
if (!options.evalJSON || (options.evalJSON != force &&
1728:
!(this.getHeader(Content-type) || ).include(application/json)) ||
1729:
this.responseText.blank())
1730:
return null;
1731:
try {
1732:
return this.responseText.evalJSON(options.sanitizeJSON ||
1733:
!this.request.isSameOrigin());
1734:
} catch (e) {
1735:
this.request.dispatchException(e);
1736:
}
1737:
}
1738: });
1739:
1740: Ajax.Updater = Class.create(Ajax.Request, {
1741:
initialize: function($super, container, url, options) {
1742:
this.container = {
1743:
success: (container.success || container),
1744:
failure: (container.failure || (container.success ? null : container))
1745:
};
1746:
1747:
options = Object.clone(options);
1748:
var onComplete = options.onComplete;
1749:
options.onComplete = (function(response, json) {
1750:
this.updateContent(response.responseText);
1751:
if (Object.isFunction(onComplete)) onComplete(response, json);
1752:
}).bind(this);
1753:
1754:
$super(url, options);
1755:
},
1756:
1757:
updateContent: function(responseText) {
1758:
var receiver = this.container[this.success() ? success : failure],
1759:
options = this.options;
1760:
1761:
if (!options.evalScripts) responseText = responseText.stripScripts();

prototype.js
1762:
1763:
1764:
1765:
1766:
1767:
1768:
1769:
1770:
1771:
1772:
1773:
1774:
1775:
1776:
1777:
1778:
1779:
1780:
1781:
1782:
1783:
1784:
1785:
1786:
1787:
1788:
1789:
1790:
1791:
1792:
1793:
1794:
1795:
1796:
1797:
1798:
1799:
1800:
1801:
1802:
1803:
1804:
1805:
1806:
1807:
1808:
1809:
1810:
1811:
1812:
1813:
1814:
1815:
1816:
1817:
1818:
1819:
1820:
1821:
1822:
1823:
1824:
1825:
1826:
1827:
1828:
1829:

Tue Jan 04 14:26:58 2011

27

if (receiver = $(receiver)) {
if (options.insertion) {
if (Object.isString(options.insertion)) {
var insertion = { }; insertion[options.insertion] = responseText;
receiver.insert(insertion);
}
else options.insertion(receiver, responseText);
}
else receiver.update(responseText);
}
}
});
Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
initialize: function($super, container, url, options) {
$super(options);
this.onComplete = this.options.onComplete;
this.frequency = (this.options.frequency || 2);
this.decay = (this.options.decay || 1);
this.updater = { };
this.container = container;
this.url = url;
this.start();
},
start: function() {
this.options.onComplete = this.updateComplete.bind(this);
this.onTimerEvent();
},
stop: function() {
this.updater.options.onComplete = undefined;
clearTimeout(this.timer);
(this.onComplete || Prototype.emptyFunction).apply(this, arguments);
},
updateComplete: function(response) {
if (this.options.decay) {
this.decay = (response.responseText == this.lastText ?
this.decay * this.options.decay : 1);
this.lastText = response.responseText;
}
this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
},
onTimerEvent: function() {
this.updater = new Ajax.Updater(this.container, this.url, this.options);
}
});

function $(element) {
if (arguments.length > 1) {
for (var i = 0, elements = [], length = arguments.length; i < length; i++)
elements.push($(arguments[i]));
return elements;
}
if (Object.isString(element))
element = document.getElementById(element);
return Element.extend(element);
}
if (Prototype.BrowserFeatures.XPath) {

prototype.js
1830:
1831:
1832:
1833:
1834:
1835:
1836:
1837:
1838:
1839:
1840:
1841:
1842:
1843:
1844:
1845:
1846:
1847:
1848:
1849:
1850:
1851:
1852:
1853:
1854:
1855:
1856:
1857:
1858:
1859:
1860:
1861:
1862:
1863:
1864:
1865:
1866:
1867:
1868:
1869:
1870:
1871:
1872:
1873:
1874:
1875:
1876:
1877:
1878:
1879:
1880:
1881:
1882:
1883:
1884:
1885:
1886:
1887:
1888:
1889:
1890:
1891:
1892:
1893:
ame));
1894:
1895:
1896:

Tue Jan 04 14:26:58 2011

28

document._getElementsByXPath = function(expression, parentElement) {


var results = [];
var query = document.evaluate(expression, $(parentElement) || document,
null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0, length = query.snapshotLength; i < length; i++)
results.push(Element.extend(query.snapshotItem(i)));
return results;
};
}
/*--------------------------------------------------------------------------*/
if (!Node) var Node = { };
if (!Node.ELEMENT_NODE) {
Object.extend(Node, {
ELEMENT_NODE: 1,
ATTRIBUTE_NODE: 2,
TEXT_NODE: 3,
CDATA_SECTION_NODE: 4,
ENTITY_REFERENCE_NODE: 5,
ENTITY_NODE: 6,
PROCESSING_INSTRUCTION_NODE: 7,
COMMENT_NODE: 8,
DOCUMENT_NODE: 9,
DOCUMENT_TYPE_NODE: 10,
DOCUMENT_FRAGMENT_NODE: 11,
NOTATION_NODE: 12
});
}

(function(global) {
function shouldUseCache(tagName, attributes) {
if (tagName === select) return false;
if (type in attributes) return false;
return true;
}
var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
try {
var el = document.createElement(<input name="x">);
return el.tagName.toLowerCase() === input && el.name === x;
}
catch(err) {
return false;
}
})();
var element = global.Element;
global.Element = function(tagName, attributes) {
attributes = attributes || { };
tagName = tagName.toLowerCase();
var cache = Element.cache;
if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) {
tagName = < + tagName + name=" + attributes.name + ">;
delete attributes.name;
return Element.writeAttribute(document.createElement(tagName), attributes);
}
if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagN

var node = shouldUseCache(tagName, attributes) ?


cache[tagName].cloneNode(false) : document.createElement(tagName);

prototype.js
1897:
1898:
1899:
1900:
1901:
1902:
1903:
1904:
1905:
1906:
1907:
1908:
1909:
1910:
1911:
1912:
1913:
1914:
1915:
1916:
1917:
1918:
1919:
1920:
1921:
1922:
1923:
1924:
1925:
1926:
1927:
1928:
1929:
1930:
1931:
1932:
1933:
1934:
1935:
1936:
1937:
1938:
1939:
1940:
1941:
1942:
1943:
1944:
1945:
1946:
1947:
1948:
1949:
1950:
1951:
1952:
1953:
1954:
1955:
1956:
1957:
1958:
1959:
1960:
1961:
1962:
1963:
1964:

Tue Jan 04 14:26:58 2011

29

return Element.writeAttribute(node, attributes);


};
Object.extend(global.Element, element || { });
if (element) global.Element.prototype = element.prototype;
})(this);
Element.idCounter = 1;
Element.cache = { };
Element._purgeElement = function(element) {
var uid = element._prototypeUID;
if (uid) {
Element.stopObserving(element);
element._prototypeUID = void 0;
delete Element.Storage[uid];
}
}
Element.Methods = {
visible: function(element) {
return $(element).style.display != none;
},
toggle: function(element) {
element = $(element);
Element[Element.visible(element) ? hide : show](element);
return element;
},
hide: function(element) {
element = $(element);
element.style.display = none;
return element;
},
show: function(element) {
element = $(element);
element.style.display = ;
return element;
},
remove: function(element) {
element = $(element);
element.parentNode.removeChild(element);
return element;
},
update: (function(){
var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
var el = document.createElement("select"),
isBuggy = true;
el.innerHTML = "<option value=\"test\">test</option>";
if (el.options && el.options[0]) {
isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
}
el = null;
return isBuggy;
})();
var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
try {
var el = document.createElement("table");
if (el && el.tBodies) {
el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";

prototype.js
1965:
1966:
1967:
1968:
1969:
1970:
1971:
1972:
1973:
1974:
1975:
1976:
1977:
1978:
1979:
1980:
1981:
1982:
1983:
1984:
1985:
1986:
1987:
1988:
1989:
1990:
1991:
1992:
1993:
1994:
1995:
1996:
1997:
1998:
1999:
2000:
2001:
2002:
2003:
2004:
2005:
2006:
2007:
2008:
2009:
2010:
2011:
2012:
2013:
2014:
2015:
2016:
2017:
2018:
2019:
2020:
2021:
2022:
2023:
2024:
2025:
2026:
2027:
2028:
2029:
2030:
2031:
2032:

Tue Jan 04 14:26:58 2011

30

var isBuggy = typeof el.tBodies[0] == "undefined";


el = null;
return isBuggy;
}
} catch (e) {
return true;
}
})();
var LINK_ELEMENT_INNERHTML_BUGGY = (function() {
try {
var el = document.createElement(div);
el.innerHTML = "<link>";
var isBuggy = (el.childNodes.length === 0);
el = null;
return isBuggy;
} catch(e) {
return true;
}
})();
var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY ||
TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY;
var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
var s = document.createElement("script"),
isBuggy = false;
try {
s.appendChild(document.createTextNode(""));
isBuggy = !s.firstChild ||
s.firstChild && s.firstChild.nodeType !== 3;
} catch (e) {
isBuggy = true;
}
s = null;
return isBuggy;
})();

function update(element, content) {


element = $(element);
var purgeElement = Element._purgeElement;
var descendants = element.getElementsByTagName(*),
i = descendants.length;
while (i--) purgeElement(descendants[i]);
if (content && content.toElement)
content = content.toElement();
if (Object.isElement(content))
return element.update().insert(content);
content = Object.toHTML(content);
var tagName = element.tagName.toUpperCase();
if (tagName === SCRIPT && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
element.text = content;
return element;
}
if (ANY_INNERHTML_BUGGY) {
if (tagName in Element._insertionTranslations.tags) {
while (element.firstChild) {
element.removeChild(element.firstChild);
}
Element._getContentFromAnonymousElement(tagName, content.stripScripts())

prototype.js

Tue Jan 04 14:26:58 2011

31

2033:
.each(function(node) {
2034:
element.appendChild(node)
2035:
});
2036:
} else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && conte
nt.indexOf(<link) > -1) {
2037:
while (element.firstChild) {
2038:
element.removeChild(element.firstChild);
2039:
}
2040:
var nodes = Element._getContentFromAnonymousElement(tagName, content.strip
Scripts(), true);
2041:
nodes.each(function(node) { element.appendChild(node) });
2042:
}
2043:
else {
2044:
element.innerHTML = content.stripScripts();
2045:
}
2046:
}
2047:
else {
2048:
element.innerHTML = content.stripScripts();
2049:
}
2050:
2051:
content.evalScripts.bind(content).defer();
2052:
return element;
2053:
}
2054:
2055:
return update;
2056:
})(),
2057:
2058:
replace: function(element, content) {
2059:
element = $(element);
2060:
if (content && content.toElement) content = content.toElement();
2061:
else if (!Object.isElement(content)) {
2062:
content = Object.toHTML(content);
2063:
var range = element.ownerDocument.createRange();
2064:
range.selectNode(element);
2065:
content.evalScripts.bind(content).defer();
2066:
content = range.createContextualFragment(content.stripScripts());
2067:
}
2068:
element.parentNode.replaceChild(content, element);
2069:
return element;
2070:
},
2071:
2072:
insert: function(element, insertions) {
2073:
element = $(element);
2074:
2075:
if (Object.isString(insertions) || Object.isNumber(insertions) ||
2076:
Object.isElement(insertions) || (insertions && (insertions.toElement || inse
rtions.toHTML)))
2077:
insertions = {bottom:insertions};
2078:
2079:
var content, insert, tagName, childNodes;
2080:
2081:
for (var position in insertions) {
2082:
content = insertions[position];
2083:
position = position.toLowerCase();
2084:
insert = Element._insertionTranslations[position];
2085:
2086:
if (content && content.toElement) content = content.toElement();
2087:
if (Object.isElement(content)) {
2088:
insert(element, content);
2089:
continue;
2090:
}
2091:
2092:
content = Object.toHTML(content);
2093:
2094:
tagName = ((position == before || position == after)
2095:
? element.parentNode : element).tagName.toUpperCase();
2096:
2097:
childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScr

prototype.js
ipts());
2098:
2099:
2100:
2101:
2102:
2103:
2104:
2105:
2106:
2107:
2108:
2109:
2110:
2111:
2112:
2113:
2114:
2115:
2116:
2117:
2118:
2119:
2120:
2121:
2122:
2123:
2124:
2125:
2126:
2127:
2128:
2129:
2130:
2131:
2132:
2133:
2134:
2135:
2136:
2137:
2138:
2139:
2140:
2141:
2142:
2143:
2144:
2145:
2146:
2147:
2148:
2149:
2150:
2151:
2152:
2153:
2154:
2155:
2156:
2157:
2158:
2159:
2160:
2161:
2162:
2163:
2164:

Tue Jan 04 14:26:58 2011

32

if (position == top || position == after) childNodes.reverse();


childNodes.each(insert.curry(element));
content.evalScripts.bind(content).defer();
}
return element;
},
wrap: function(element, wrapper, attributes) {
element = $(element);
if (Object.isElement(wrapper))
$(wrapper).writeAttribute(attributes || { });
else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
else wrapper = new Element(div, wrapper);
if (element.parentNode)
element.parentNode.replaceChild(wrapper, element);
wrapper.appendChild(element);
return wrapper;
},
inspect: function(element) {
element = $(element);
var result = < + element.tagName.toLowerCase();
$H({id: id, className: class}).each(function(pair) {
var property = pair.first(),
attribute = pair.last(),
value = (element[property] || ).toString();
if (value) result += + attribute + = + value.inspect(true);
});
return result + >;
},
recursivelyCollect: function(element, property, maximumLength) {
element = $(element);
maximumLength = maximumLength || -1;
var elements = [];
while (element = element[property]) {
if (element.nodeType == 1)
elements.push(Element.extend(element));
if (elements.length == maximumLength)
break;
}
return elements;
},
ancestors: function(element) {
return Element.recursivelyCollect(element, parentNode);
},
descendants: function(element) {
return Element.select(element, "*");
},
firstDescendant: function(element) {
element = $(element).firstChild;
while (element && element.nodeType != 1) element = element.nextSibling;
return $(element);
},
immediateDescendants: function(element) {
var results = [], child = $(element).firstChild;
while (child) {
if (child.nodeType === 1) {

prototype.js
2165:
2166:
2167:
2168:
2169:
2170:
2171:
2172:
2173:
2174:
2175:
2176:
2177:
2178:
2179:
2180:
2181:
2182:
2183:
2184:
2185:
2186:
2187:
2188:
2189:
2190:
2191:
2192:
2193:
2194:
2195:
2196:
2197:
2198:
2199:
2200:
2201:
2202:
2203:
2204:
2205:
2206:
2207:
2208:
2209:
2210:
2211:
2212:
2213:
2214:
2215:
2216:
2217:
2218:
2219:
2220:
2221:
2222:
2223:
2224:
2225:
2226:
2227:
2228:
2229:
2230:
2231:
2232:

Tue Jan 04 14:26:58 2011

33

results.push(Element.extend(child));
}
child = child.nextSibling;
}
return results;
},
previousSiblings: function(element, maximumLength) {
return Element.recursivelyCollect(element, previousSibling);
},
nextSiblings: function(element) {
return Element.recursivelyCollect(element, nextSibling);
},
siblings: function(element) {
element = $(element);
return Element.previousSiblings(element).reverse()
.concat(Element.nextSiblings(element));
},
match: function(element, selector) {
element = $(element);
if (Object.isString(selector))
return Prototype.Selector.match(element, selector);
return selector.match(element);
},
up: function(element, expression, index) {
element = $(element);
if (arguments.length == 1) return $(element.parentNode);
var ancestors = Element.ancestors(element);
return Object.isNumber(expression) ? ancestors[expression] :
Prototype.Selector.find(ancestors, expression, index);
},
down: function(element, expression, index) {
element = $(element);
if (arguments.length == 1) return Element.firstDescendant(element);
return Object.isNumber(expression) ? Element.descendants(element)[expression] :
Element.select(element, expression)[index || 0];
},
previous: function(element, expression, index) {
element = $(element);
if (Object.isNumber(expression)) index = expression, expression = false;
if (!Object.isNumber(index)) index = 0;
if (expression) {
return Prototype.Selector.find(element.previousSiblings(), expression, index);
} else {
return element.recursivelyCollect("previousSibling", index + 1)[index];
}
},
next: function(element, expression, index) {
element = $(element);
if (Object.isNumber(expression)) index = expression, expression = false;
if (!Object.isNumber(index)) index = 0;
if (expression) {
return Prototype.Selector.find(element.nextSiblings(), expression, index);
} else {
var maximumLength = Object.isNumber(index) ? index + 1 : 1;
return element.recursivelyCollect("nextSibling", index + 1)[index];
}
},

prototype.js
2233:
2234:
2235:
2236:
2237:
2238:
2239:
2240:
2241:
2242:
2243:
t);
2244:
2245:
2246:
2247:
2248:
2249:
2250:
2251:
2252:
2253:
2254:
2255:
2256:
2257:
2258:
2259:
2260:
2261:
2262:
2263:
2264:
2265:
2266:
2267:
2268:
2269:
2270:
2271:
2272:
2273:
2274:
2275:
2276:
2277:
2278:
2279:
2280:
2281:
2282:
2283:
2284:
2285:
2286:
2287:
2288:
2289:
2290:
2291:
2292:
2293:
2294:
2295:
2296:
2297:
2298:
2299:

Tue Jan 04 14:26:58 2011

34

select: function(element) {
element = $(element);
var expressions = Array.prototype.slice.call(arguments, 1).join(, );
return Prototype.Selector.select(expressions, element);
},
adjacent: function(element) {
element = $(element);
var expressions = Array.prototype.slice.call(arguments, 1).join(, );
return Prototype.Selector.select(expressions, element.parentNode).without(elemen
},
identify: function(element) {
element = $(element);
var id = Element.readAttribute(element, id);
if (id) return id;
do { id = anonymous_element_ + Element.idCounter++ } while ($(id));
Element.writeAttribute(element, id, id);
return id;
},
readAttribute: function(element, name) {
element = $(element);
if (Prototype.Browser.IE) {
var t = Element._attributeTranslations.read;
if (t.values[name]) return t.values[name](element, name);
if (t.names[name]) name = t.names[name];
if (name.include(:)) {
return (!element.attributes || !element.attributes[name]) ? null :
element.attributes[name].value;
}
}
return element.getAttribute(name);
},
writeAttribute: function(element, name, value) {
element = $(element);
var attributes = { }, t = Element._attributeTranslations.write;
if (typeof name == object) attributes = name;
else attributes[name] = Object.isUndefined(value) ? true : value;
for (var attr in attributes) {
name = t.names[attr] || attr;
value = attributes[attr];
if (t.values[attr]) name = t.values[attr](element, value);
if (value === false || value === null)
element.removeAttribute(name);
else if (value === true)
element.setAttribute(name, name);
else element.setAttribute(name, value);
}
return element;
},
getHeight: function(element) {
return Element.getDimensions(element).height;
},
getWidth: function(element) {
return Element.getDimensions(element).width;
},
classNames: function(element) {
return new Element.ClassNames(element);
},

prototype.js
2300:
2301:
2302:
2303:
2304:
2305:
2306:
2307:
2308:
2309:
2310:
2311:
2312:
2313:
2314:
2315:
2316:
2317:
2318:
2319:
2320:
2321:
2322:
2323:
2324:
2325:
2326:
2327:
2328:
2329:
2330:
2331:
2332:
2333:
2334:
2335:
2336:
2337:
2338:
2339:
2340:
2341:
2342:
2343:
2344:
2345:
2346:
2347:
2348:
2349:
2350:
2351:
2352:
2353:
2354:
2355:
2356:
2357:
2358:
2359:
2360:
2361:
2362:
2363:
2364:
2365:
2366:
2367:

Tue Jan 04 14:26:58 2011

35

hasClassName: function(element, className) {


if (!(element = $(element))) return;
var elementClassName = element.className;
return (elementClassName.length > 0 && (elementClassName == className ||
new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
},
addClassName: function(element, className) {
if (!(element = $(element))) return;
if (!Element.hasClassName(element, className))
element.className += (element.className ? : ) + className;
return element;
},
removeClassName: function(element, className) {
if (!(element = $(element))) return;
element.className = element.className.replace(
new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ).strip();
return element;
},
toggleClassName: function(element, className) {
if (!(element = $(element))) return;
return Element[Element.hasClassName(element, className) ?
removeClassName : addClassName](element, className);
},
cleanWhitespace: function(element) {
element = $(element);
var node = element.firstChild;
while (node) {
var nextNode = node.nextSibling;
if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
element.removeChild(node);
node = nextNode;
}
return element;
},
empty: function(element) {
return $(element).innerHTML.blank();
},
descendantOf: function(element, ancestor) {
element = $(element), ancestor = $(ancestor);
if (element.compareDocumentPosition)
return (element.compareDocumentPosition(ancestor) & 8) === 8;
if (ancestor.contains)
return ancestor.contains(element) && ancestor !== element;
while (element = element.parentNode)
if (element == ancestor) return true;
return false;
},
scrollTo: function(element) {
element = $(element);
var pos = Element.cumulativeOffset(element);
window.scrollTo(pos[0], pos[1]);
return element;
},
getStyle: function(element, style) {
element = $(element);

prototype.js
2368:
2369:
2370:
2371:
2372:
2373:
2374:
2375:
2376:
2377:
2378:
2379:
2380:
2381:
2382:
2383:
2384:
2385:
2386:
2387:
2388:
2389:
2390:
2391:
2392:
2393:
2394:

Tue Jan 04 14:26:58 2011

36

style = style == float ? cssFloat : style.camelize();


var value = element.style[style];
if (!value || value == auto) {
var css = document.defaultView.getComputedStyle(element, null);
value = css ? css[style] : null;
}
if (style == opacity) return value ? parseFloat(value) : 1.0;
return value == auto ? null : value;
},
getOpacity: function(element) {
return $(element).getStyle(opacity);
},
setStyle: function(element, styles) {
element = $(element);
var elementStyle = element.style, match;
if (Object.isString(styles)) {
element.style.cssText += ; + styles;
return styles.include(opacity) ?
element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
}
for (var property in styles)
if (property == opacity) element.setOpacity(styles[property]);
else
elementStyle[(property == float || property == cssFloat) ?
(Object.isUndefined(elementStyle.styleFloat) ? cssFloat : styleFloat)

:
2395:
2396:
2397:
2398:
2399:
2400:
2401:
2402:
2403:
2404:
2405:
2406:
2407:
2408:
2409:
2410:
2411:
2412:
2413:
2414:
2415:
2416:
2417:
2418:
2419:
2420:
2421:
2422:
2423:
2424:
2425:
2426:
2427:
2428:
2429:
2430:
2431:
2432:
2433:
2434:

property] = styles[property];
return element;
},
setOpacity: function(element, value) {
element = $(element);
element.style.opacity = (value == 1 || value === ) ? :
(value < 0.00001) ? 0 : value;
return element;
},
makePositioned: function(element) {
element = $(element);
var pos = Element.getStyle(element, position);
if (pos == static || !pos) {
element._madePositioned = true;
element.style.position = relative;
if (Prototype.Browser.Opera) {
element.style.top = 0;
element.style.left = 0;
}
}
return element;
},
undoPositioned: function(element) {
element = $(element);
if (element._madePositioned) {
element._madePositioned = undefined;
element.style.position =
element.style.top =
element.style.left =
element.style.bottom =
element.style.right = ;
}
return element;
},
makeClipping: function(element) {

prototype.js

Tue Jan 04 14:26:58 2011

37

2435:
element = $(element);
if (element._overflow) return element;
2436:
2437:
element._overflow = Element.getStyle(element, overflow) || auto;
2438:
if (element._overflow !== hidden)
2439:
element.style.overflow = hidden;
2440:
return element;
2441:
},
2442:
2443:
undoClipping: function(element) {
2444:
element = $(element);
2445:
if (!element._overflow) return element;
2446:
element.style.overflow = element._overflow == auto ? : element._overflow;
2447:
element._overflow = null;
2448:
return element;
2449:
},
2450:
2451:
clonePosition: function(element, source) {
2452:
var options = Object.extend({
2453:
setLeft:
true,
2454:
setTop:
true,
2455:
setWidth:
true,
2456:
setHeight: true,
2457:
offsetTop: 0,
2458:
offsetLeft: 0
2459:
}, arguments[2] || { });
2460:
2461:
source = $(source);
2462:
var p = Element.viewportOffset(source), delta = [0, 0], parent = null;
2463:
2464:
element = $(element);
2465:
2466:
if (Element.getStyle(element, position) == absolute) {
2467:
parent = Element.getOffsetParent(element);
2468:
delta = Element.viewportOffset(parent);
2469:
}
2470:
2471:
if (parent == document.body) {
2472:
delta[0] -= document.body.offsetLeft;
2473:
delta[1] -= document.body.offsetTop;
2474:
}
2475:
2476:
if (options.setLeft)
element.style.left = (p[0] - delta[0] + options.offsetLe
ft) + px;
2477:
if (options.setTop)
element.style.top
= (p[1] - delta[1] + options.offsetTo
p) + px;
2478:
if (options.setWidth) element.style.width = source.offsetWidth + px;
2479:
if (options.setHeight) element.style.height = source.offsetHeight + px;
2480:
return element;
2481:
}
2482: };
2483:
2484: Object.extend(Element.Methods, {
2485:
getElementsBySelector: Element.Methods.select,
2486:
2487:
childElements: Element.Methods.immediateDescendants
2488: });
2489:
2490: Element._attributeTranslations = {
2491:
write: {
2492:
names: {
2493:
className: class,
2494:
htmlFor:
for
2495:
},
2496:
values: { }
2497:
}
2498: };
2499:
2500: if (Prototype.Browser.Opera) {

prototype.js

Tue Jan 04 14:26:58 2011

38

2501:
Element.Methods.getStyle = Element.Methods.getStyle.wrap(
function(proceed, element, style) {
2502:
2503:
switch (style) {
2504:
case height: case width:
2505:
if (!Element.visible(element)) return null;
2506:
2507:
var dim = parseInt(proceed(element, style), 10);
2508:
2509:
if (dim !== element[offset + style.capitalize()])
2510:
return dim + px;
2511:
2512:
var properties;
2513:
if (style === height) {
2514:
properties = [border-top-width, padding-top,
2515:
padding-bottom, border-bottom-width];
2516:
}
2517:
else {
2518:
properties = [border-left-width, padding-left,
2519:
padding-right, border-right-width];
2520:
}
2521:
return properties.inject(dim, function(memo, property) {
2522:
var val = proceed(element, property);
2523:
return val === null ? memo : memo - parseInt(val, 10);
2524:
}) + px;
2525:
default: return proceed(element, style);
2526:
}
2527:
}
2528:
);
2529:
2530:
Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
2531:
function(proceed, element, attribute) {
2532:
if (attribute === title) return element.title;
2533:
return proceed(element, attribute);
2534:
}
2535:
);
2536: }
2537:
2538: else if (Prototype.Browser.IE) {
2539:
Element.Methods.getStyle = function(element, style) {
2540:
element = $(element);
2541:
style = (style == float || style == cssFloat) ? styleFloat : style.cameliz
e();
2542:
var value = element.style[style];
2543:
if (!value && element.currentStyle) value = element.currentStyle[style];
2544:
2545:
if (style == opacity) {
2546:
if (value = (element.getStyle(filter) || ).match(/alpha\(opacity=(.*)\)/))
2547:
if (value[1]) return parseFloat(value[1]) / 100; //
2548:
return 1.0;
2549:
}
2550:
2551:
if (value == auto) {
2552:
if ((style == width || style == height) && (element.getStyle(display) !=
none))
2553:
return element[offset + style.capitalize()] + px;
2554:
return null;
2555:
}
2556:
return value;
2557:
};
2558:
2559:
Element.Methods.setOpacity = function(element, value) {
2560:
function stripAlpha(filter){
2561:
return filter.replace(/alpha\([^\)]*\)/gi,);
2562:
}
2563:
element = $(element);
2564:
var currentStyle = element.currentStyle;
2565:
if ((currentStyle && !currentStyle.hasLayout) ||
2566:
(!currentStyle && element.style.zoom == normal))

prototype.js
2567:
2568:
2569:
2570:
2571:
2572:
2573:
2574:
2575:
2576:
2577:
2578:
2579:
2580:
2581:
2582:
2583:
2584:
2585:
2586:
2587:
2588:
2589:
2590:
2591:
2592:
2593:
2594:
2595:
2596:
2597:
2598:
2599:
2600:
2601:
2602:
2603:
2604:
2605:
2606:
2607:
2608:
2609:
2610:
2611:
2612:
2613:
2614:
2615:
2616:
2617:
2618:
2619:
2620:
2621:
2622:
2623:
2624:
2625:
2626:
2627:
2628:
2629:
2630:
2631:
2632:
2633:
2634:

Tue Jan 04 14:26:58 2011

39

element.style.zoom = 1;
var filter = element.getStyle(filter), style = element.style;
if (value == 1 || value === ) {
(filter = stripAlpha(filter)) ?
style.filter = filter : style.removeAttribute(filter);
return element;
} else if (value < 0.00001) value = 0;
style.filter = stripAlpha(filter) +
alpha(opacity= + (value * 100) + );
return element;
};
Element._attributeTranslations = (function(){
var classProp = className,
forProp = for,
el = document.createElement(div);
el.setAttribute(classProp, x);
if (el.className !== x) {
el.setAttribute(class, x);
if (el.className === x) {
classProp = class;
}
}
el = null;
el = document.createElement(label);
el.setAttribute(forProp, x);
if (el.htmlFor !== x) {
el.setAttribute(htmlFor, x);
if (el.htmlFor === x) {
forProp = htmlFor;
}
}
el = null;
return {
read: {
names: {
class:
classProp,
className: classProp,
for:
forProp,
htmlFor:
forProp
},
values: {
_getAttr: function(element, attribute) {
return element.getAttribute(attribute);
},
_getAttr2: function(element, attribute) {
return element.getAttribute(attribute, 2);
},
_getAttrNode: function(element, attribute) {
var node = element.getAttributeNode(attribute);
return node ? node.value : "";
},
_getEv: (function(){
var el = document.createElement(div), f;
el.onclick = Prototype.emptyFunction;
var value = el.getAttribute(onclick);
if (String(value).indexOf({) > -1) {
f = function(element, attribute) {
attribute = element.getAttribute(attribute);
if (!attribute) return null;

prototype.js
2635:
2636:
2637:
2638:
2639:
2640:
2641:
2642:
2643:
2644:
2645:
2646:
2647:
2648:
2649:
2650:
2651:
2652:
2653:
2654:
2655:
2656:
2657:
2658:
2659:
2660:
2661:
2662:
2663:
2664:
2665:
2666:
2667:
2668:
2669:
2670:
2671:
2672:
2673:
2674:
2675:
2676:
2677:
2678:
2679:
2680:
2681:
2682:
2683:
2684:
2685:
2686:
2687:
2688:
2689:
2690:
2691:
2692:
2693:
2694:
2695:
2696:
2697:
2698:
2699:
2700:
2701:
2702:

Tue Jan 04 14:26:58 2011

40

attribute = attribute.toString();
attribute = attribute.split({)[1];
attribute = attribute.split(})[0];
return attribute.strip();
};
}
else if (value === ) {
f = function(element, attribute) {
attribute = element.getAttribute(attribute);
if (!attribute) return null;
return attribute.strip();
};
}
el = null;
return f;
})(),
_flag: function(element, attribute) {
return $(element).hasAttribute(attribute) ? attribute : null;
},
style: function(element) {
return element.style.cssText.toLowerCase();
},
title: function(element) {
return element.title;
}
}
}
}
})();
Element._attributeTranslations.write = {
names: Object.extend({
cellpadding: cellPadding,
cellspacing: cellSpacing
}, Element._attributeTranslations.read.names),
values: {
checked: function(element, value) {
element.checked = !!value;
},
style: function(element, value) {
element.style.cssText = value ? value : ;
}
}
};
Element._attributeTranslations.has = {};
$w(colSpan rowSpan vAlign dateTime accessKey tabIndex +
encType maxLength readOnly longDesc frameBorder).each(function(attr) {
Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
Element._attributeTranslations.has[attr.toLowerCase()] = attr;
});
(function(v) {
Object.extend(v, {
href:
v._getAttr2,
src:
v._getAttr2,
type:
v._getAttr,
action:
v._getAttrNode,
disabled:
v._flag,
checked:
v._flag,
readonly:
v._flag,
multiple:
v._flag,
onload:
v._getEv,
onunload:
v._getEv,
onclick:
v._getEv,
ondblclick: v._getEv,

prototype.js
2703:
2704:
2705:
2706:
2707:
2708:
2709:
2710:
2711:
2712:
2713:
2714:
2715:
2716:
2717:
2718:
2719:
2720:
2721:
2722:
2723:
2724:
2725:
2726:
2727:
2728:
2729:
2730:
2731:
2732:
2733:
2734:
2735:
2736:
2737:
2738:
2739:
2740:
2741:
2742:
2743:
2744:
2745:
2746:
2747:
2748:
2749:
2750:
2751:
2752:
2753:
2754:
2755:
2756:
2757:
2758:
2759:
2760:
2761:
2762:
2763:
2764:
2765:
2766:
2767:
2768:
2769:
2770:

Tue Jan 04 14:26:58 2011

41

onmousedown: v._getEv,
onmouseup:
v._getEv,
onmouseover: v._getEv,
onmousemove: v._getEv,
onmouseout: v._getEv,
onfocus:
v._getEv,
onblur:
v._getEv,
onkeypress: v._getEv,
onkeydown:
v._getEv,
onkeyup:
v._getEv,
onsubmit:
v._getEv,
onreset:
v._getEv,
onselect:
v._getEv,
onchange:
v._getEv
});
})(Element._attributeTranslations.read.values);
if (Prototype.BrowserFeatures.ElementExtensions) {
(function() {
function _descendants(element) {
var nodes = element.getElementsByTagName(*), results = [];
for (var i = 0, node; node = nodes[i]; i++)
if (node.tagName !== "!") // Filter out comment nodes.
results.push(node);
return results;
}
Element.Methods.down = function(element, expression, index) {
element = $(element);
if (arguments.length == 1) return element.firstDescendant();
return Object.isNumber(expression) ? _descendants(element)[expression] :
Element.select(element, expression)[index || 0];
}
})();
}
}
else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
Element.Methods.setOpacity = function(element, value) {
element = $(element);
element.style.opacity = (value == 1) ? 0.999999 :
(value === ) ? : (value < 0.00001) ? 0 : value;
return element;
};
}
else if (Prototype.Browser.WebKit) {
Element.Methods.setOpacity = function(element, value) {
element = $(element);
element.style.opacity = (value == 1 || value === ) ? :
(value < 0.00001) ? 0 : value;
if (value == 1)
if (element.tagName.toUpperCase() == IMG && element.width) {
element.width++; element.width--;
} else try {
var n = document.createTextNode( );
element.appendChild(n);
element.removeChild(n);
} catch (e) { }
return element;
};
}
if (outerHTML in document.documentElement) {
Element.Methods.replace = function(element, content) {

prototype.js

Tue Jan 04 14:26:58 2011

42

2771:
element = $(element);
2772:
2773:
if (content && content.toElement) content = content.toElement();
2774:
if (Object.isElement(content)) {
2775:
element.parentNode.replaceChild(content, element);
2776:
return element;
2777:
}
2778:
2779:
content = Object.toHTML(content);
2780:
var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
2781:
2782:
if (Element._insertionTranslations.tags[tagName]) {
2783:
var nextSibling = element.next(),
2784:
fragments = Element._getContentFromAnonymousElement(tagName, content.strip
Scripts());
2785:
parent.removeChild(element);
2786:
if (nextSibling)
2787:
fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
2788:
else
2789:
fragments.each(function(node) { parent.appendChild(node) });
2790:
}
2791:
else element.outerHTML = content.stripScripts();
2792:
2793:
content.evalScripts.bind(content).defer();
2794:
return element;
2795:
};
2796: }
2797:
2798: Element._returnOffset = function(l, t) {
2799:
var result = [l, t];
2800:
result.left = l;
2801:
result.top = t;
2802:
return result;
2803: };
2804:
2805: Element._getContentFromAnonymousElement = function(tagName, html, force) {
2806:
var div = new Element(div),
2807:
t = Element._insertionTranslations.tags[tagName];
2808:
2809:
var workaround = false;
2810:
if (t) workaround = true;
2811:
else if (force) {
2812:
workaround = true;
2813:
t = [, , 0];
2814:
}
2815:
2816:
if (workaround) {
2817:
div.innerHTML = &nbsp; + t[0] + html + t[1];
2818:
div.removeChild(div.firstChild);
2819:
for (var i = t[2]; i--; ) {
2820:
div = div.firstChild;
2821:
}
2822:
}
2823:
else {
2824:
div.innerHTML = html;
2825:
}
2826:
return $A(div.childNodes);
2827: };
2828:
2829: Element._insertionTranslations = {
2830:
before: function(element, node) {
2831:
element.parentNode.insertBefore(node, element);
2832:
},
2833:
top: function(element, node) {
2834:
element.insertBefore(node, element.firstChild);
2835:
},
2836:
bottom: function(element, node) {
2837:
element.appendChild(node);

prototype.js
2838:
2839:
2840:
2841:
2842:
2843:
2844:
2845:
2846:
2847:
2848:
2849:
2850:
2851:
2852:
2853:
2854:
2855:
2856:
2857:
2858:
2859:
2860:
2861:
2862:
2863:
2864:
2865:
2866:
2867:
2868:
2869:
2870:
2871:
2872:
2873:
2874:
2875:
2876:
2877:
2878:
2879:
2880:
2881:
2882:
2883:
2884:
2885:
2886:
2887:
2888:
2889:
2890:
2891:
2892:
2893:
2894:
2895:
2896:
2897:
2898:
2899:
2900:
2901:
2902:
2903:
2904:
2905:

Tue Jan 04 14:26:58 2011

43

},
after: function(element, node) {
element.parentNode.insertBefore(node, element.nextSibling);
},
tags: {
TABLE: [<table>,
</table>,
TBODY: [<table><tbody>,
</tbody></table>,
TR:
[<table><tbody><tr>,
</tr></tbody></table>,
TD:
[<table><tbody><tr><td>, </td></tr></tbody></table>,
SELECT: [<select>,
</select>,
}

1],
2],
3],
4],
1]

};
(function() {
var tags = Element._insertionTranslations.tags;
Object.extend(tags, {
THEAD: tags.TBODY,
TFOOT: tags.TBODY,
TH:
tags.TD
});
})();
Element.Methods.Simulated = {
hasAttribute: function(element, attribute) {
attribute = Element._attributeTranslations.has[attribute] || attribute;
var node = $(element).getAttributeNode(attribute);
return !!(node && node.specified);
}
};
Element.Methods.ByTag = { };
Object.extend(Element, Element.Methods);
(function(div) {
if (!Prototype.BrowserFeatures.ElementExtensions && div[__proto__]) {
window.HTMLElement = { };
window.HTMLElement.prototype = div[__proto__];
Prototype.BrowserFeatures.ElementExtensions = true;
}
div = null;
})(document.createElement(div));
Element.extend = (function() {
function checkDeficiency(tagName) {
if (typeof window.Element != undefined) {
var proto = window.Element.prototype;
if (proto) {
var id = _ + (Math.random()+).slice(2),
el = document.createElement(tagName);
proto[id] = x;
var isBuggy = (el[id] !== x);
delete proto[id];
el = null;
return isBuggy;
}
}
return false;
}
function extendElementWith(element, methods) {
for (var property in methods) {
var value = methods[property];
if (Object.isFunction(value) && !(property in element))

prototype.js
2906:
2907:
2908:
2909:
2910:
2911:
2912:
2913:
2914:
2915:
2916:
2917:
2918:
2919:
2920:
2921:
2922:
2923:
2924:
2925:
2926:
2927:
2928:
2929:
2930:
2931:
2932:
2933:
2934:
2935:
2936:
2937:
2938:
2939:
2940:
2941:
2942:
2943:
2944:
2945:
2946:
2947:
2948:
2949:
2950:
2951:
2952:
2953:
2954:
2955:
2956:
2957:
2958:
2959:
2960:
2961:
2962:
2963:
2964:
2965:
2966:
2967:
2968:
2969:
2970:
2971:
2972:
2973:

Tue Jan 04 14:26:58 2011

44

element[property] = value.methodize();
}
}
var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency(object);
if (Prototype.BrowserFeatures.SpecificElementExtensions) {
if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) {
return function(element) {
if (element && typeof element._extendedByPrototype == undefined) {
var t = element.tagName;
if (t && (/^(?:object|applet|embed)$/i.test(t))) {
extendElementWith(element, Element.Methods);
extendElementWith(element, Element.Methods.Simulated);
extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
}
}
return element;
}
}
return Prototype.K;
}
var Methods = { }, ByTag = Element.Methods.ByTag;
var extend = Object.extend(function(element) {
if (!element || typeof element._extendedByPrototype != undefined ||
element.nodeType != 1 || element == window) return element;
var methods = Object.clone(Methods),
tagName = element.tagName.toUpperCase();
if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
extendElementWith(element, methods);
element._extendedByPrototype = Prototype.emptyFunction;
return element;
}, {
refresh: function() {
if (!Prototype.BrowserFeatures.ElementExtensions) {
Object.extend(Methods, Element.Methods);
Object.extend(Methods, Element.Methods.Simulated);
}
}
});
extend.refresh();
return extend;
})();
if (document.documentElement.hasAttribute) {
Element.hasAttribute = function(element, attribute) {
return element.hasAttribute(attribute);
};
}
else {
Element.hasAttribute = Element.Methods.Simulated.hasAttribute;
}
Element.addMethods = function(methods) {
var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
if (!methods) {
Object.extend(Form, Form.Methods);
Object.extend(Form.Element, Form.Element.Methods);
Object.extend(Element.Methods.ByTag, {

prototype.js
2974:
2975:
2976:
2977:
2978:
2979:
2980:
2981:
2982:
2983:
2984:
2985:
2986:
2987:
2988:
2989:
2990:
2991:
2992:
2993:
2994:
2995:
2996:
2997:
2998:
2999:
3000:
3001:
3002:
3003:
3004:
3005:
3006:
3007:
3008:
3009:
3010:
3011:
3012:
3013:
3014:
3015:
3016:
3017:
3018:
3019:
3020:
3021:
3022:
3023:
3024:
3025:
3026:
3027:
3028:
3029:
3030:
3031:
3032:
3033:
3034:
3035:
3036:
3037:
3038:
3039:
3040:
3041:

Tue Jan 04 14:26:58 2011

"FORM":
"INPUT":
"SELECT":
"TEXTAREA":
"BUTTON":
});

45

Object.clone(Form.Methods),
Object.clone(Form.Element.Methods),
Object.clone(Form.Element.Methods),
Object.clone(Form.Element.Methods),
Object.clone(Form.Element.Methods)

}
if (arguments.length == 2) {
var tagName = methods;
methods = arguments[1];
}
if (!tagName) Object.extend(Element.Methods, methods || { });
else {
if (Object.isArray(tagName)) tagName.each(extend);
else extend(tagName);
}
function extend(tagName) {
tagName = tagName.toUpperCase();
if (!Element.Methods.ByTag[tagName])
Element.Methods.ByTag[tagName] = { };
Object.extend(Element.Methods.ByTag[tagName], methods);
}
function copy(methods, destination, onlyIfAbsent) {
onlyIfAbsent = onlyIfAbsent || false;
for (var property in methods) {
var value = methods[property];
if (!Object.isFunction(value)) continue;
if (!onlyIfAbsent || !(property in destination))
destination[property] = value.methodize();
}
}
function findDOMClass(tagName) {
var klass;
var trans = {
"OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
"FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
"DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
"H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
"INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
"TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
"TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
"TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
"FrameSet", "IFRAME": "IFrame"
};
if (trans[tagName]) klass = HTML + trans[tagName] + Element;
if (window[klass]) return window[klass];
klass = HTML + tagName + Element;
if (window[klass]) return window[klass];
klass = HTML + tagName.capitalize() + Element;
if (window[klass]) return window[klass];
var element = document.createElement(tagName),
proto = element[__proto__] || element.constructor.prototype;
element = null;
return proto;
}
var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
Element.prototype;
if (F.ElementExtensions) {
copy(Element.Methods, elementPrototype);

prototype.js

Tue Jan 04 14:26:58 2011

46

3042:
copy(Element.Methods.Simulated, elementPrototype, true);
3043:
}
3044:
3045:
if (F.SpecificElementExtensions) {
3046:
for (var tag in Element.Methods.ByTag) {
3047:
var klass = findDOMClass(tag);
3048:
if (Object.isUndefined(klass)) continue;
3049:
copy(T[tag], klass.prototype);
3050:
}
3051:
}
3052:
3053:
Object.extend(Element, Element.Methods);
3054:
delete Element.ByTag;
3055:
3056:
if (Element.extend.refresh) Element.extend.refresh();
3057:
Element.cache = { };
3058: };
3059:
3060:
3061: document.viewport = {
3062:
3063:
getDimensions: function() {
3064:
return { width: this.getWidth(), height: this.getHeight() };
3065:
},
3066:
3067:
getScrollOffsets: function() {
3068:
return Element._returnOffset(
3069:
window.pageXOffset || document.documentElement.scrollLeft || document.body.scr
ollLeft,
3070:
window.pageYOffset || document.documentElement.scrollTop || document.body.scr
ollTop);
3071:
}
3072: };
3073:
3074: (function(viewport) {
3075:
var B = Prototype.Browser, doc = document, element, property = {};
3076:
3077:
function getRootElement() {
3078:
if (B.WebKit && !doc.evaluate)
3079:
return document;
3080:
3081:
if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
3082:
return document.body;
3083:
3084:
return document.documentElement;
3085:
}
3086:
3087:
function define(D) {
3088:
if (!element) element = getRootElement();
3089:
3090:
property[D] = client + D;
3091:
3092:
viewport[get + D] = function() { return element[property[D]] };
3093:
return viewport[get + D]();
3094:
}
3095:
3096:
viewport.getWidth = define.curry(Width);
3097:
3098:
viewport.getHeight = define.curry(Height);
3099: })(document.viewport);
3100:
3101:
3102: Element.Storage = {
3103:
UID: 1
3104: };
3105:
3106: Element.addMethods({
3107:
getStorage: function(element) {

prototype.js
3108:
3109:
3110:
3111:
3112:
3113:
3114:
3115:
3116:
3117:
3118:
3119:
3120:
3121:
3122:
3123:
3124:
3125:
3126:
3127:
3128:
3129:
3130:
3131:
3132:
3133:
3134:
3135:
3136:
3137:
3138:
3139:
3140:
3141:
3142:
3143:
3144:
3145:
3146:
3147:
3148:
3149:
3150:
3151:
3152:
3153:
3154:
3155:
3156:
3157:
3158:
3159:
3160:
3161:
3162:
3163:
3164:
3165:
3166:
3167:
3168:
3169:
3170:
3171:
3172:
3173:
3174:
3175:

Tue Jan 04 14:26:58 2011

47

if (!(element = $(element))) return;


var uid;
if (element === window) {
uid = 0;
} else {
if (typeof element._prototypeUID === "undefined")
element._prototypeUID = Element.Storage.UID++;
uid = element._prototypeUID;
}
if (!Element.Storage[uid])
Element.Storage[uid] = $H();
return Element.Storage[uid];
},
store: function(element, key, value) {
if (!(element = $(element))) return;
if (arguments.length === 2) {
Element.getStorage(element).update(key);
} else {
Element.getStorage(element).set(key, value);
}
return element;
},
retrieve: function(element, key, defaultValue) {
if (!(element = $(element))) return;
var hash = Element.getStorage(element), value = hash.get(key);
if (Object.isUndefined(value)) {
hash.set(key, defaultValue);
value = defaultValue;
}
return value;
},
clone: function(element, deep) {
if (!(element = $(element))) return;
var clone = element.cloneNode(deep);
clone._prototypeUID = void 0;
if (deep) {
var descendants = Element.select(clone, *),
i = descendants.length;
while (i--) {
descendants[i]._prototypeUID = void 0;
}
}
return Element.extend(clone);
},
purge: function(element) {
if (!(element = $(element))) return;
var purgeElement = Element._purgeElement;
purgeElement(element);
var descendants = element.getElementsByTagName(*),
i = descendants.length;
while (i--) purgeElement(descendants[i]);
return null;
}

prototype.js

Tue Jan 04 14:26:58 2011

48

3176: });
3177:
3178: (function() {
3179:
3180:
function toDecimal(pctString) {
3181:
var match = pctString.match(/^(\d+)%?$/i);
3182:
if (!match) return null;
3183:
return (Number(match[1]) / 100);
3184:
}
3185:
3186:
function getPixelValue(value, property, context) {
3187:
var element = null;
3188:
if (Object.isElement(value)) {
3189:
element = value;
3190:
value = element.getStyle(property);
3191:
}
3192:
3193:
if (value === null) {
3194:
return null;
3195:
}
3196:
3197:
if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) {
3198:
return window.parseFloat(value);
3199:
}
3200:
3201:
var isPercentage = value.include(%), isViewport = (context === document.viewpo
rt);
3202:
3203:
if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isV
iewport)) {
3204:
var style = element.style.left, rStyle = element.runtimeStyle.left;
3205:
element.runtimeStyle.left = element.currentStyle.left;
3206:
element.style.left = value || 0;
3207:
value = element.style.pixelLeft;
3208:
element.style.left = style;
3209:
element.runtimeStyle.left = rStyle;
3210:
3211:
return value;
3212:
}
3213:
3214:
if (element && isPercentage) {
3215:
context = context || element.parentNode;
3216:
var decimal = toDecimal(value);
3217:
var whole = null;
3218:
var position = element.getStyle(position);
3219:
3220:
var isHorizontal = property.include(left) || property.include(right) ||
3221:
property.include(width);
3222:
3223:
var isVertical = property.include(top) || property.include(bottom) ||
3224:
property.include(height);
3225:
3226:
if (context === document.viewport) {
3227:
if (isHorizontal) {
3228:
whole = document.viewport.getWidth();
3229:
} else if (isVertical) {
3230:
whole = document.viewport.getHeight();
3231:
}
3232:
} else {
3233:
if (isHorizontal) {
3234:
whole = $(context).measure(width);
3235:
} else if (isVertical) {
3236:
whole = $(context).measure(height);
3237:
}
3238:
}
3239:
3240:
return (whole === null) ? 0 : whole * decimal;
3241:
}

prototype.js
3242:
3243:
3244:
3245:
3246:
3247:
3248:
3249:
3250:
3251:
3252:
3253:
3254:
3255:
3256:
3257:
3258:
3259:
3260:
3261:
3262:
3263:
3264:
3265:
3266:
3267:
3268:
3269:
3270:
3271:
3272:
3273:
3274:
3275:
3276:
3277:
3278:
3279:
3280:
3281:
3282:
3283:
3284:
3285:
3286:
3287:
3288:
3289:
3290:
3291:
3292:
3293:
3294:
3295:
3296:
3297:
3298:
3299:
3300:
3301:
3302:
3303:
3304:
3305:
3306:
3307:
3308:
3309:

Tue Jan 04 14:26:58 2011

49

return 0;
}
function toCSSPixels(number) {
if (Object.isString(number) && number.endsWith(px)) {
return number;
}
return number + px;
}
function isDisplayed(element) {
var originalElement = element;
while (element && element.parentNode) {
var display = element.getStyle(display);
if (display === none) {
return false;
}
element = $(element.parentNode);
}
return true;
}
var hasLayout = Prototype.K;
if (currentStyle in document.documentElement) {
hasLayout = function(element) {
if (!element.currentStyle.hasLayout) {
element.style.zoom = 1;
}
return element;
};
}
function cssNameFor(key) {
if (key.include(border)) key = key + -width;
return key.camelize();
}
Element.Layout = Class.create(Hash, {
initialize: function($super, element, preCompute) {
$super();
this.element = $(element);
Element.Layout.PROPERTIES.each( function(property) {
this._set(property, null);
}, this);
if (preCompute) {
this._preComputing = true;
this._begin();
Element.Layout.PROPERTIES.each( this._compute, this );
this._end();
this._preComputing = false;
}
},
_set: function(property, value) {
return Hash.prototype.set.call(this, property, value);
},
set: function(property, value) {
throw "Properties of Element.Layout are read-only.";
},
get: function($super, property) {
var value = $super(property);
return value === null ? this._compute(property) : value;
},

prototype.js
3310:
3311:
3312:
3313:
3314:
3315:
3316:
3317:
3318:
3319:
3320:
3321:
3322:
3323:
3324:
3325:
3326:
3327:
3328:
3329:
3330:
3331:
3332:
3333:
3334:
3335:
3336:
3337:
3338:
3339:
3340:
3341:
3342:
3343:
3344:
3345:
3346:
3347:
3348:
3349:
3350:
3351:
3352:
3353:
3354:
3355:
3356:
3357:
3358:
3359:
3360:
3361:
3362:
3363:
3364:
3365:
3366:
3367:
3368:
3369:
3370:
3371:
3372:
3373:
3374:
3375:
3376:
3377:

Tue Jan 04 14:26:58 2011

50

_begin: function() {
if (this._prepared) return;
var element = this.element;
if (isDisplayed(element)) {
this._prepared = true;
return;
}
var originalStyles = {
position:
element.style.position
width:
element.style.width
visibility: element.style.visibility
display:
element.style.display
};

||
||
||
||

,
,
,

element.store(prototype_original_styles, originalStyles);
var position = element.getStyle(position),
width = element.getStyle(width);
if (width === "0px" || width === null) {
element.style.display = block;
width = element.getStyle(width);
}
var context = (position === fixed) ? document.viewport :
element.parentNode;
element.setStyle({
position:
absolute,
visibility: hidden,
display:
block
});
var positionedWidth = element.getStyle(width);
var newWidth;
if (width && (positionedWidth === width)) {
newWidth = getPixelValue(element, width, context);
} else if (position === absolute || position === fixed) {
newWidth = getPixelValue(element, width, context);
} else {
var parent = element.parentNode, pLayout = $(parent).getLayout();
newWidth = pLayout.get(width) this.get(margin-left) this.get(border-left) this.get(padding-left) this.get(padding-right) this.get(border-right) this.get(margin-right);
}
element.setStyle({ width: newWidth + px });
this._prepared = true;
},
_end: function() {
var element = this.element;
var originalStyles = element.retrieve(prototype_original_styles);
element.store(prototype_original_styles, null);
element.setStyle(originalStyles);
this._prepared = false;
},

prototype.js

Tue Jan 04 14:26:58 2011

51

3378:
_compute: function(property) {
3379:
var COMPUTATIONS = Element.Layout.COMPUTATIONS;
3380:
if (!(property in COMPUTATIONS)) {
3381:
throw "Property not found.";
3382:
}
3383:
3384:
return this._set(property, COMPUTATIONS[property].call(this, this.element));
3385:
},
3386:
3387:
toObject: function() {
3388:
var args = $A(arguments);
3389:
var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3390:
args.join( ).split( );
3391:
var obj = {};
3392:
keys.each( function(key) {
3393:
if (!Element.Layout.PROPERTIES.include(key)) return;
3394:
var value = this.get(key);
3395:
if (value != null) obj[key] = value;
3396:
}, this);
3397:
return obj;
3398:
},
3399:
3400:
toHash: function() {
3401:
var obj = this.toObject.apply(this, arguments);
3402:
return new Hash(obj);
3403:
},
3404:
3405:
toCSS: function() {
3406:
var args = $A(arguments);
3407:
var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3408:
args.join( ).split( );
3409:
var css = {};
3410:
3411:
keys.each( function(key) {
3412:
if (!Element.Layout.PROPERTIES.include(key)) return;
3413:
if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return;
3414:
3415:
var value = this.get(key);
3416:
if (value != null) css[cssNameFor(key)] = value + px;
3417:
}, this);
3418:
return css;
3419:
},
3420:
3421:
inspect: function() {
3422:
return "#<Element.Layout>";
3423:
}
3424:
});
3425:
3426:
Object.extend(Element.Layout, {
3427:
PROPERTIES: $w(height width top left right bottom border-left border-right bord
er-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margi
n-bottom margin-left margin-right padding-box-width padding-box-height border-box-width bor
der-box-height margin-box-width margin-box-height),
3428:
3429:
COMPOSITE_PROPERTIES: $w(padding-box-width padding-box-height margin-box-width
margin-box-height border-box-width border-box-height),
3430:
3431:
COMPUTATIONS: {
3432:
height: function(element) {
3433:
if (!this._preComputing) this._begin();
3434:
3435:
var bHeight = this.get(border-box-height);
3436:
if (bHeight <= 0) {
3437:
if (!this._preComputing) this._end();
3438:
return 0;
3439:
}
3440:
3441:
var bTop = this.get(border-top),

prototype.js
3442:
3443:
3444:
3445:
3446:
3447:
3448:
3449:
3450:
3451:
3452:
3453:
3454:
3455:
3456:
3457:
3458:
3459:
3460:
3461:
3462:
3463:
3464:
3465:
3466:
3467:
3468:
3469:
3470:
3471:
3472:
3473:
3474:
3475:
3476:
3477:
3478:
3479:
3480:
3481:
3482:
3483:
3484:
3485:
3486:
3487:
3488:
3489:
3490:
3491:
3492:
3493:
3494:
3495:
3496:
3497:
3498:
3499:
3500:
3501:
3502:
3503:
3504:
3505:
3506:
3507:
3508:
3509:

Tue Jan 04 14:26:58 2011

52

bBottom = this.get(border-bottom);
var pTop = this.get(padding-top),
pBottom = this.get(padding-bottom);
if (!this._preComputing) this._end();
return bHeight - bTop - bBottom - pTop - pBottom;
},
width: function(element) {
if (!this._preComputing) this._begin();
var bWidth = this.get(border-box-width);
if (bWidth <= 0) {
if (!this._preComputing) this._end();
return 0;
}
var bLeft = this.get(border-left),
bRight = this.get(border-right);
var pLeft = this.get(padding-left),
pRight = this.get(padding-right);
if (!this._preComputing) this._end();
return bWidth - bLeft - bRight - pLeft - pRight;
},
padding-box-height: function(element) {
var height = this.get(height),
pTop = this.get(padding-top),
pBottom = this.get(padding-bottom);
return height + pTop + pBottom;
},
padding-box-width: function(element) {
var width = this.get(width),
pLeft = this.get(padding-left),
pRight = this.get(padding-right);
return width + pLeft + pRight;
},
border-box-height: function(element) {
if (!this._preComputing) this._begin();
var height = element.offsetHeight;
if (!this._preComputing) this._end();
return height;
},
border-box-width: function(element) {
if (!this._preComputing) this._begin();
var width = element.offsetWidth;
if (!this._preComputing) this._end();
return width;
},
margin-box-height: function(element) {
var bHeight = this.get(border-box-height),
mTop = this.get(margin-top),
mBottom = this.get(margin-bottom);
if (bHeight <= 0) return 0;
return bHeight + mTop + mBottom;

prototype.js
3510:
3511:
3512:
3513:
3514:
3515:
3516:
3517:
3518:
3519:
3520:
3521:
3522:
3523:
3524:
3525:
3526:
3527:
3528:
3529:
3530:
3531:
3532:
3533:
3534:
3535:
3536:
3537:
3538:
3539:
3540:
3541:
3542:
3543:
3544:
3545:
3546:
3547:
3548:
3549:
3550:
3551:
3552:
3553:
3554:
3555:
3556:
3557:
3558:
3559:
3560:
3561:
3562:
3563:
3564:
3565:
3566:
3567:
3568:
3569:
3570:
3571:
3572:
3573:
3574:
3575:
3576:
3577:

Tue Jan 04 14:26:58 2011

53

},
margin-box-width: function(element) {
var bWidth = this.get(border-box-width),
mLeft = this.get(margin-left),
mRight = this.get(margin-right);
if (bWidth <= 0) return 0;
return bWidth + mLeft + mRight;
},
top: function(element) {
var offset = element.positionedOffset();
return offset.top;
},
bottom: function(element) {
var offset = element.positionedOffset(),
parent = element.getOffsetParent(),
pHeight = parent.measure(height);
var mHeight = this.get(border-box-height);
return pHeight - mHeight - offset.top;
},
left: function(element) {
var offset = element.positionedOffset();
return offset.left;
},
right: function(element) {
var offset = element.positionedOffset(),
parent = element.getOffsetParent(),
pWidth = parent.measure(width);
var mWidth = this.get(border-box-width);
return pWidth - mWidth - offset.left;
},
padding-top: function(element) {
return getPixelValue(element, paddingTop);
},
padding-bottom: function(element) {
return getPixelValue(element, paddingBottom);
},
padding-left: function(element) {
return getPixelValue(element, paddingLeft);
},
padding-right: function(element) {
return getPixelValue(element, paddingRight);
},
border-top: function(element) {
return getPixelValue(element, borderTopWidth);
},
border-bottom: function(element) {
return getPixelValue(element, borderBottomWidth);
},
border-left: function(element) {
return getPixelValue(element, borderLeftWidth);

prototype.js
3578:
3579:
3580:
3581:
3582:
3583:
3584:
3585:
3586:
3587:
3588:
3589:
3590:
3591:
3592:
3593:
3594:
3595:
3596:
3597:
3598:
3599:
3600:
3601:
3602:
3603:
3604:
3605:
3606:
3607:
3608:
3609:
3610:
3611:
3612:
3613:
3614:
3615:
3616:
3617:
3618:
3619:
3620:
3621:
3622:
3623:
3624:
3625:
3626:
3627:
3628:
3629:
3630:
3631:
3632:
3633:
3634:
3635:
3636:
3637:
3638:
3639:
3640:
3641:
3642:
3643:
3644:
3645:

Tue Jan 04 14:26:58 2011

54

},
border-right: function(element) {
return getPixelValue(element, borderRightWidth);
},
margin-top: function(element) {
return getPixelValue(element, marginTop);
},
margin-bottom: function(element) {
return getPixelValue(element, marginBottom);
},
margin-left: function(element) {
return getPixelValue(element, marginLeft);
},
margin-right: function(element) {
return getPixelValue(element, marginRight);
}
}
});
if (getBoundingClientRect in document.documentElement) {
Object.extend(Element.Layout.COMPUTATIONS, {
right: function(element) {
var parent = hasLayout(element.getOffsetParent());
var rect = element.getBoundingClientRect(),
pRect = parent.getBoundingClientRect();
return (pRect.right - rect.right).round();
},
bottom: function(element) {
var parent = hasLayout(element.getOffsetParent());
var rect = element.getBoundingClientRect(),
pRect = parent.getBoundingClientRect();
return (pRect.bottom - rect.bottom).round();
}
});
}
Element.Offset = Class.create({
initialize: function(left, top) {
this.left = left.round();
this.top = top.round();
this[0] = this.left;
this[1] = this.top;
},
relativeTo: function(offset) {
return new Element.Offset(
this.left - offset.left,
this.top - offset.top
);
},
inspect: function() {
return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this);
},
toString: function() {
return "[#{left}, #{top}]".interpolate(this);
},

prototype.js
3646:
3647:
3648:
3649:
3650:
3651:
3652:
3653:
3654:
3655:
3656:
3657:
3658:
3659:
3660:
3661:
3662:
3663:
3664:
3665:
3666:
3667:
3668:
3669:
3670:
3671:
3672:
3673:
3674:
3675:
3676:
3677:
3678:
3679:
3680:
3681:
3682:
3683:
3684:
3685:
3686:
3687:
3688:
3689:
3690:
3691:
3692:
3693:
3694:
3695:
3696:
3697:
ent))
3698:
3699:
3700:
3701:
3702:
3703:
3704:
3705:
3706:
3707:
3708:
3709:
3710:
3711:
3712:

Tue Jan 04 14:26:58 2011

55

toArray: function() {
return [this.left, this.top];
}
});
function getLayout(element, preCompute) {
return new Element.Layout(element, preCompute);
}
function measure(element, property) {
return $(element).getLayout().get(property);
}
function getDimensions(element) {
element = $(element);
var display = Element.getStyle(element, display);
if (display && display !== none) {
return { width: element.offsetWidth, height: element.offsetHeight };
}
var style = element.style;
var originalStyles = {
visibility: style.visibility,
position:
style.position,
display:
style.display
};
var newStyles = {
visibility: hidden,
display:
block
};
if (originalStyles.position !== fixed)
newStyles.position = absolute;
Element.setStyle(element, newStyles);
var dimensions = {
width: element.offsetWidth,
height: element.offsetHeight
};
Element.setStyle(element, originalStyles);
return dimensions;
}
function getOffsetParent(element) {
element = $(element);
if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(elem
return $(document.body);
var isInline = (Element.getStyle(element, display) === inline);
if (!isInline && element.offsetParent) return $(element.offsetParent);
while ((element = element.parentNode) && element !== document.body) {
if (Element.getStyle(element, position) !== static) {
return isHtml(element) ? $(document.body) : $(element);
}
}
return $(document.body);
}

prototype.js
3713:
3714:
3715:
3716:
3717:
3718:
3719:
3720:
3721:
3722:
3723:
3724:
3725:
3726:
3727:
3728:
3729:
3730:
3731:
3732:
3733:
3734:
3735:
3736:
3737:
3738:
3739:
3740:
3741:
3742:
3743:
3744:
3745:
3746:
3747:
3748:
3749:
3750:
3751:
3752:
3753:
3754:
3755:
3756:
3757:
3758:
3759:
3760:
3761:
3762:
3763:
3764:
3765:
3766:
3767:
3768:
3769:
3770:
3771:
3772:
3773:
3774:
3775:
3776:
3777:
3778:
3779:
3780:

Tue Jan 04 14:26:58 2011

56

function cumulativeOffset(element) {
element = $(element);
var valueT = 0, valueL = 0;
if (element.parentNode) {
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
element = element.offsetParent;
} while (element);
}
return new Element.Offset(valueL, valueT);
}
function positionedOffset(element) {
element = $(element);
var layout = element.getLayout();
var valueT = 0, valueL = 0;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
element = element.offsetParent;
if (element) {
if (isBody(element)) break;
var p = Element.getStyle(element, position);
if (p !== static) break;
}
} while (element);
valueL -= layout.get(margin-top);
valueT -= layout.get(margin-left);
return new Element.Offset(valueL, valueT);
}
function cumulativeScrollOffset(element) {
var valueT = 0, valueL = 0;
do {
valueT += element.scrollTop || 0;
valueL += element.scrollLeft || 0;
element = element.parentNode;
} while (element);
return new Element.Offset(valueL, valueT);
}
function viewportOffset(forElement) {
element = $(element);
var valueT = 0, valueL = 0, docBody = document.body;
var element = forElement;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
if (element.offsetParent == docBody &&
Element.getStyle(element, position) == absolute) break;
} while (element = element.offsetParent);
element = forElement;
do {
if (element != docBody) {
valueT -= element.scrollTop || 0;
valueL -= element.scrollLeft || 0;
}
} while (element = element.parentNode);
return new Element.Offset(valueL, valueT);
}

prototype.js

Tue Jan 04 14:26:58 2011

57

3781:
function absolutize(element) {
3782:
element = $(element);
3783:
3784:
if (Element.getStyle(element, position) === absolute) {
3785:
return element;
3786:
}
3787:
3788:
var offsetParent = getOffsetParent(element);
3789:
var eOffset = element.viewportOffset(),
3790:
pOffset = offsetParent.viewportOffset();
3791:
3792:
var offset = eOffset.relativeTo(pOffset);
3793:
var layout = element.getLayout();
3794:
3795:
element.store(prototype_absolutize_original_styles, {
3796:
left:
element.getStyle(left),
3797:
top:
element.getStyle(top),
3798:
width: element.getStyle(width),
3799:
height: element.getStyle(height)
3800:
});
3801:
3802:
element.setStyle({
3803:
position: absolute,
3804:
top:
offset.top + px,
3805:
left:
offset.left + px,
3806:
width: layout.get(width) + px,
3807:
height: layout.get(height) + px
3808:
});
3809:
3810:
return element;
3811:
}
3812:
3813:
function relativize(element) {
3814:
element = $(element);
3815:
if (Element.getStyle(element, position) === relative) {
3816:
return element;
3817:
}
3818:
3819:
var originalStyles =
3820:
element.retrieve(prototype_absolutize_original_styles);
3821:
3822:
if (originalStyles) element.setStyle(originalStyles);
3823:
return element;
3824:
}
3825:
3826:
if (Prototype.Browser.IE) {
3827:
getOffsetParent = getOffsetParent.wrap(
3828:
function(proceed, element) {
3829:
element = $(element);
3830:
3831:
if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(
element))
3832:
return $(document.body);
3833:
3834:
var position = element.getStyle(position);
3835:
if (position !== static) return proceed(element);
3836:
3837:
element.setStyle({ position: relative });
3838:
var value = proceed(element);
3839:
element.setStyle({ position: position });
3840:
return value;
3841:
}
3842:
);
3843:
3844:
positionedOffset = positionedOffset.wrap(function(proceed, element) {
3845:
element = $(element);
3846:
if (!element.parentNode) return new Element.Offset(0, 0);
3847:
var position = element.getStyle(position);

prototype.js
3848:
3849:
3850:
3851:
3852:
3853:
3854:
3855:
3856:
3857:
3858:
3859:
3860:
3861:
3862:
3863:
3864:
3865:
3866:
3867:
3868:
3869:
3870:
3871:
3872:
3873:
3874:
3875:
3876:
3877:
3878:
3879:
3880:
3881:
3882:
3883:
3884:
3885:
3886:
3887:
3888:
3889:
3890:
3891:
3892:
3893:
3894:
3895:
3896:
3897:
3898:
3899:
3900:
3901:
3902:
3903:
3904:
3905:
3906:
3907:
3908:
3909:
3910:
3911:
3912:
3913:
3914:
3915:

Tue Jan 04 14:26:58 2011

58

if (position !== static) return proceed(element);


var offsetParent = element.getOffsetParent();
if (offsetParent && offsetParent.getStyle(position) === fixed)
hasLayout(offsetParent);
element.setStyle({ position: relative });
var value = proceed(element);
element.setStyle({ position: position });
return value;
});
} else if (Prototype.Browser.Webkit) {
cumulativeOffset = function(element) {
element = $(element);
var valueT = 0, valueL = 0;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
if (element.offsetParent == document.body)
if (Element.getStyle(element, position) == absolute) break;
element = element.offsetParent;
} while (element);
return new Element.Offset(valueL, valueT);
};
}

Element.addMethods({
getLayout:
measure:
getDimensions:
getOffsetParent:
cumulativeOffset:
positionedOffset:
cumulativeScrollOffset:
viewportOffset:
absolutize:
relativize:
});

getLayout,
measure,
getDimensions,
getOffsetParent,
cumulativeOffset,
positionedOffset,
cumulativeScrollOffset,
viewportOffset,
absolutize,
relativize

function isBody(element) {
return element.nodeName.toUpperCase() === BODY;
}
function isHtml(element) {
return element.nodeName.toUpperCase() === HTML;
}
function isDocument(element) {
return element.nodeType === Node.DOCUMENT_NODE;
}
function isDetached(element) {
return element !== document.body &&
!Element.descendantOf(element, document.body);
}
if (getBoundingClientRect in document.documentElement) {
Element.addMethods({
viewportOffset: function(element) {
element = $(element);
if (isDetached(element)) return new Element.Offset(0, 0);
var rect = element.getBoundingClientRect(),
docEl = document.documentElement;
return new Element.Offset(rect.left - docEl.clientLeft,

prototype.js

Tue Jan 04 14:26:58 2011

59

3916:
rect.top - docEl.clientTop);
3917:
}
3918:
});
3919:
}
3920: })();
3921: window.$$ = function() {
3922:
var expression = $A(arguments).join(, );
3923:
return Prototype.Selector.select(expression, document);
3924: };
3925:
3926: Prototype.Selector = (function() {
3927:
3928:
function select() {
3929:
throw new Error(Method "Prototype.Selector.select" must be defined.);
3930:
}
3931:
3932:
function match() {
3933:
throw new Error(Method "Prototype.Selector.match" must be defined.);
3934:
}
3935:
3936:
function find(elements, expression, index) {
3937:
index = index || 0;
3938:
var match = Prototype.Selector.match, length = elements.length, matchIndex = 0,
i;
3939:
3940:
for (i = 0; i < length; i++) {
3941:
if (match(elements[i], expression) && index == matchIndex++) {
3942:
return Element.extend(elements[i]);
3943:
}
3944:
}
3945:
}
3946:
3947:
function extendElements(elements) {
3948:
for (var i = 0, length = elements.length; i < length; i++) {
3949:
Element.extend(elements[i]);
3950:
}
3951:
return elements;
3952:
}
3953:
3954:
3955:
var K = Prototype.K;
3956:
3957:
return {
3958:
select: select,
3959:
match: match,
3960:
find: find,
3961:
extendElements: (Element.extend === K) ? K : extendElements,
3962:
extendElement: Element.extend
3963:
};
3964: })();
3965: Prototype._original_property = window.Sizzle;
3966: /*!
3967: * Sizzle CSS Selector Engine - v1.0
3968: * Copyright 2009, The Dojo Foundation
3969: * Released under the MIT, BSD, and GPL Licenses.
3970: * More information: http://sizzlejs.com/
3971: */
3972: (function(){
3973:
3974: var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|["][^"]*["]|[^[\]
"]+)+\]|\\.|[^ >+,(\[\\]+)+|[>+])(\s*,\s*)?((?:.|\r|\n)*)/g,
3975:
done = 0,
3976:
toString = Object.prototype.toString,
3977:
hasDuplicate = false,
3978:
baseHasDuplicate = true;
3979:
3980: [0, 0].sort(function(){
3981:
baseHasDuplicate = false;

prototype.js

Tue Jan 04 14:26:58 2011

60

3982:
return 0;
3983: });
3984:
3985: var Sizzle = function(selector, context, results, seed) {
3986:
results = results || [];
3987:
var origContext = context = context || document;
3988:
3989:
if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3990:
return [];
3991:
}
3992:
3993:
if ( !selector || typeof selector !== "string" ) {
3994:
return results;
3995:
}
3996:
3997:
var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextX
ML = isXML(context),
3998:
soFar = selector;
3999:
4000:
while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
4001:
soFar = m[3];
4002:
4003:
parts.push( m[1] );
4004:
4005:
if ( m[2] ) {
4006:
extra = m[3];
4007:
break;
4008:
}
4009:
}
4010:
4011:
if ( parts.length > 1 && origPOS.exec( selector ) ) {
4012:
if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
4013:
set = posProcess( parts[0] + parts[1], context );
4014:
} else {
4015:
set = Expr.relative[ parts[0] ] ?
4016:
[ context ] :
4017:
Sizzle( parts.shift(), context );
4018:
4019:
while ( parts.length ) {
4020:
selector = parts.shift();
4021:
4022:
if ( Expr.relative[ selector ] )
4023:
selector += parts.shift();
4024:
4025:
set = posProcess( selector, set );
4026:
}
4027:
}
4028:
} else {
4029:
if ( !seed && parts.length > 1 && context.nodeType === 9 && !context
XML &&
4030:
Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(
parts[parts.length - 1]) ) {
4031:
var ret = Sizzle.find( parts.shift(), context, contextXML );
4032:
context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] :
ret.set[0];
4033:
}
4034:
4035:
if ( context ) {
4036:
var ret = seed ?
4037:
{ expr: parts.pop(), set: makeArray(seed) } :
4038:
Sizzle.find( parts.pop(), parts.length === 1 && (par
ts[0] === "" || parts[0] === "+") && context.parentNode ? context.parentNode : context, co
ntextXML );
4039:
set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.se
t;
4040:
4041:
if ( parts.length > 0 ) {
4042:
checkSet = makeArray(set);

prototype.js

Tue Jan 04 14:26:58 2011

61

4043:
} else {
4044:
prune = false;
4045:
}
4046:
4047:
while ( parts.length ) {
4048:
var cur = parts.pop(), pop = cur;
4049:
4050:
if ( !Expr.relative[ cur ] ) {
4051:
cur = "";
4052:
} else {
4053:
pop = parts.pop();
4054:
}
4055:
4056:
if ( pop == null ) {
4057:
pop = context;
4058:
}
4059:
4060:
Expr.relative[ cur ]( checkSet, pop, contextXML );
4061:
}
4062:
} else {
4063:
checkSet = parts = [];
4064:
}
4065:
}
4066:
4067:
if ( !checkSet ) {
4068:
checkSet = set;
4069:
}
4070:
4071:
if ( !checkSet ) {
4072:
throw "Syntax error, unrecognized expression: " + (cur || selector);
4073:
}
4074:
4075:
if ( toString.call(checkSet) === "[object Array]" ) {
4076:
if ( !prune ) {
4077:
results.push.apply( results, checkSet );
4078:
} else if ( context && context.nodeType === 1 ) {
4079:
for ( var i = 0; checkSet[i] != null; i++ ) {
4080:
if ( checkSet[i] && (checkSet[i] === true || checkSe
t[i].nodeType === 1 && contains(context, checkSet[i])) ) {
4081:
results.push( set[i] );
4082:
}
4083:
}
4084:
} else {
4085:
for ( var i = 0; checkSet[i] != null; i++ ) {
4086:
if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
4087:
results.push( set[i] );
4088:
}
4089:
}
4090:
}
4091:
} else {
4092:
makeArray( checkSet, results );
4093:
}
4094:
4095:
if ( extra ) {
4096:
Sizzle( extra, origContext, results, seed );
4097:
Sizzle.uniqueSort( results );
4098:
}
4099:
4100:
return results;
4101: };
4102:
4103: Sizzle.uniqueSort = function(results){
4104:
if ( sortOrder ) {
4105:
hasDuplicate = baseHasDuplicate;
4106:
results.sort(sortOrder);
4107:
4108:
if ( hasDuplicate ) {
4109:
for ( var i = 1; i < results.length; i++ ) {

prototype.js

Tue Jan 04 14:26:58 2011

62

4110:
if ( results[i] === results[i-1] ) {
4111:
results.splice(i--, 1);
4112:
}
4113:
}
4114:
}
4115:
}
4116:
4117:
return results;
4118: };
4119:
4120: Sizzle.matches = function(expr, set){
4121:
return Sizzle(expr, null, null, set);
4122: };
4123:
4124: Sizzle.find = function(expr, context, isXML){
4125:
var set, match;
4126:
4127:
if ( !expr ) {
4128:
return [];
4129:
}
4130:
4131:
for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
4132:
var type = Expr.order[i], match;
4133:
4134:
if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
4135:
var left = match[1];
4136:
match.splice(1,1);
4137:
4138:
if ( left.substr( left.length - 1 ) !== "\\" ) {
4139:
match[1] = (match[1] || "").replace(/\\/g, "");
4140:
set = Expr.find[ type ]( match, context, isXML );
4141:
if ( set != null ) {
4142:
expr = expr.replace( Expr.match[ type ], ""
);
4143:
break;
4144:
}
4145:
}
4146:
}
4147:
}
4148:
4149:
if ( !set ) {
4150:
set = context.getElementsByTagName("*");
4151:
}
4152:
4153:
return {set: set, expr: expr};
4154: };
4155:
4156: Sizzle.filter = function(expr, set, inplace, not){
4157:
var old = expr, result = [], curLoop = set, match, anyFound,
4158:
isXMLFilter = set && set[0] && isXML(set[0]);
4159:
4160:
while ( expr && set.length ) {
4161:
for ( var type in Expr.filter ) {
4162:
if ( (match = Expr.match[ type ].exec( expr )) != null ) {
4163:
var filter = Expr.filter[ type ], found, item;
4164:
anyFound = false;
4165:
4166:
if ( curLoop == result ) {
4167:
result = [];
4168:
}
4169:
4170:
if ( Expr.preFilter[ type ] ) {
4171:
match = Expr.preFilter[ type ]( match, curLo
op, inplace, result, not, isXMLFilter );
4172:
4173:
if ( !match ) {
4174:
anyFound = found = true;
4175:
} else if ( match === true ) {

prototype.js

Tue Jan 04 14:26:58 2011

63

4176:
continue;
4177:
}
4178:
}
4179:
4180:
if ( match ) {
4181:
for ( var i = 0; (item = curLoop[i]) != null
; i++ ) {
4182:
if ( item ) {
4183:
found = filter( item, match,
i, curLoop );
4184:
var pass = not ^ !!found;
4185:
4186:
if ( inplace && found != nul
l ) {
4187:
if ( pass ) {
4188:
anyFound = t
rue;
4189:
} else {
4190:
curLoop[i] =
false;
4191:
}
4192:
} else if ( pass ) {
4193:
result.push( item );
4194:
anyFound = true;
4195:
}
4196:
}
4197:
}
4198:
}
4199:
4200:
if ( found !== undefined ) {
4201:
if ( !inplace ) {
4202:
curLoop = result;
4203:
}
4204:
4205:
expr = expr.replace( Expr.match[ type ], ""
);
4206:
4207:
if ( !anyFound ) {
4208:
return [];
4209:
}
4210:
4211:
break;
4212:
}
4213:
}
4214:
}
4215:
4216:
if ( expr == old ) {
4217:
if ( anyFound == null ) {
4218:
throw "Syntax error, unrecognized expression: " + ex
pr;
4219:
} else {
4220:
break;
4221:
}
4222:
}
4223:
4224:
old = expr;
4225:
}
4226:
4227:
return curLoop;
4228: };
4229:
4230: var Expr = Sizzle.selectors = {
4231:
order: [ "ID", "NAME", "TAG" ],
4232:
match: {
4233:
ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
4234:
CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
4235:
NAME: /\[name=["]*((?:[\w\u00c0-\uFFFF-]|\\.)+)["]*\]/,
4236:
ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(["]*)(.*?)

prototype.js

Tue Jan 04 14:26:58 2011

64

\3|)\s*\]/,
4237:
TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
4238:
CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
4239:
POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
4240:
PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((["]*)((?:\([^\)]+\)|[^
\2\(\)]*)+)\2\))?/
4241:
},
4242:
leftMatch: {},
4243:
attrMap: {
4244:
"class": "className",
4245:
"for": "htmlFor"
4246:
},
4247:
attrHandle: {
4248:
href: function(elem){
4249:
return elem.getAttribute("href");
4250:
}
4251:
},
4252:
relative: {
4253:
"+": function(checkSet, part, isXML){
4254:
var isPartStr = typeof part === "string",
4255:
isTag = isPartStr && !/\W/.test(part),
4256:
isPartStrNotTag = isPartStr && !isTag;
4257:
4258:
if ( isTag && !isXML ) {
4259:
part = part.toUpperCase();
4260:
}
4261:
4262:
for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4263:
if ( (elem = checkSet[i]) ) {
4264:
while ( (elem = elem.previousSibling) && ele
m.nodeType !== 1 ) {}
4265:
4266:
checkSet[i] = isPartStrNotTag || elem && ele
m.nodeName === part ?
4267:
elem || false :
4268:
elem === part;
4269:
}
4270:
}
4271:
4272:
if ( isPartStrNotTag ) {
4273:
Sizzle.filter( part, checkSet, true );
4274:
}
4275:
},
4276:
">": function(checkSet, part, isXML){
4277:
var isPartStr = typeof part === "string";
4278:
4279:
if ( isPartStr && !/\W/.test(part) ) {
4280:
part = isXML ? part : part.toUpperCase();
4281:
4282:
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4283:
var elem = checkSet[i];
4284:
if ( elem ) {
4285:
var parent = elem.parentNode;
4286:
checkSet[i] = parent.nodeName === pa
rt ? parent : false;
4287:
}
4288:
}
4289:
} else {
4290:
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4291:
var elem = checkSet[i];
4292:
if ( elem ) {
4293:
checkSet[i] = isPartStr ?
4294:
elem.parentNode :
4295:
elem.parentNode === part;
4296:
}
4297:
}
4298:
4299:
if ( isPartStr ) {

prototype.js

Tue Jan 04 14:26:58 2011

65

4300:
Sizzle.filter( part, checkSet, true );
4301:
}
4302:
}
4303:
},
4304:
"": function(checkSet, part, isXML){
4305:
var doneName = done++, checkFn = dirCheck;
4306:
4307:
if ( !/\W/.test(part) ) {
4308:
var nodeCheck = part = isXML ? part : part.toUpperCa
se();
4309:
checkFn = dirNodeCheck;
4310:
}
4311:
4312:
checkFn("parentNode", part, doneName, checkSet, nodeCheck, i
sXML);
4313:
},
4314:
"": function(checkSet, part, isXML){
4315:
var doneName = done++, checkFn = dirCheck;
4316:
4317:
if ( typeof part === "string" && !/\W/.test(part) ) {
4318:
var nodeCheck = part = isXML ? part : part.toUpperCa
se();
4319:
checkFn = dirNodeCheck;
4320:
}
4321:
4322:
checkFn("previousSibling", part, doneName, checkSet, nodeChe
ck, isXML);
4323:
}
4324:
},
4325:
find: {
4326:
ID: function(match, context, isXML){
4327:
if ( typeof context.getElementById !== "undefined" && !isXML
) {
4328:
var m = context.getElementById(match[1]);
4329:
return m ? [m] : [];
4330:
}
4331:
},
4332:
NAME: function(match, context, isXML){
4333:
if ( typeof context.getElementsByName !== "undefined" ) {
4334:
var ret = [], results = context.getElementsByName(ma
tch[1]);
4335:
4336:
for ( var i = 0, l = results.length; i < l; i++ ) {
4337:
if ( results[i].getAttribute("name") === mat
ch[1] ) {
4338:
ret.push( results[i] );
4339:
}
4340:
}
4341:
4342:
return ret.length === 0 ? null : ret;
4343:
}
4344:
},
4345:
TAG: function(match, context){
4346:
return context.getElementsByTagName(match[1]);
4347:
}
4348:
},
4349:
preFilter: {
4350:
CLASS: function(match, curLoop, inplace, result, not, isXML){
4351:
match = " " + match[1].replace(/\\/g, "") + " ";
4352:
4353:
if ( isXML ) {
4354:
return match;
4355:
}
4356:
4357:
for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4358:
if ( elem ) {
4359:
if ( not ^ (elem.className && (" " + elem.cl
assName + " ").indexOf(match) >= 0) ) {

prototype.js

Tue Jan 04 14:26:58 2011

66

4360:
if ( !inplace )
4361:
result.push( elem );
4362:
} else if ( inplace ) {
4363:
curLoop[i] = false;
4364:
}
4365:
}
4366:
}
4367:
4368:
return false;
4369:
},
4370:
ID: function(match){
4371:
return match[1].replace(/\\/g, "");
4372:
},
4373:
TAG: function(match, curLoop){
4374:
for ( var i = 0; curLoop[i] === false; i++ ){}
4375:
return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1]
.toUpperCase();
4376:
},
4377:
CHILD: function(match){
4378:
if ( match[1] == "nth" ) {
4379:
var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
4380:
match[2] == "even" && "2n" || match[2] == "o
dd" && "2n+1" ||
4381:
!/\D/.test( match[2] ) && "0n+" + match[2] |
| match[2]);
4382:
4383:
match[2] = (test[1] + (test[2] || 1)) - 0;
4384:
match[3] = test[3] - 0;
4385:
}
4386:
4387:
match[0] = done++;
4388:
4389:
return match;
4390:
},
4391:
ATTR: function(match, curLoop, inplace, result, not, isXML){
4392:
var name = match[1].replace(/\\/g, "");
4393:
4394:
if ( !isXML && Expr.attrMap[name] ) {
4395:
match[1] = Expr.attrMap[name];
4396:
}
4397:
4398:
if ( match[2] === "=" ) {
4399:
match[4] = " " + match[4] + " ";
4400:
}
4401:
4402:
return match;
4403:
},
4404:
PSEUDO: function(match, curLoop, inplace, result, not){
4405:
if ( match[1] === "not" ) {
4406:
if ( ( chunker.exec(match[3]) || "" ).length > 1 ||
/^\w/.test(match[3]) ) {
4407:
match[3] = Sizzle(match[3], null, null, curL
oop);
4408:
} else {
4409:
var ret = Sizzle.filter(match[3], curLoop, i
nplace, true ^ not);
4410:
if ( !inplace ) {
4411:
result.push.apply( result, ret );
4412:
}
4413:
return false;
4414:
}
4415:
} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CH
ILD.test( match[0] ) ) {
4416:
return true;
4417:
}
4418:
4419:
return match;
4420:
},

prototype.js
4421:
4422:
4423:
4424:
4425:
4426:
4427:
4428:
4429:
4430:
4431:
4432:
4433:
4434:
4435:
4436:
4437:
4438:
4439:
4440:
4441:
4442:
4443:
4444:
4445:
4446:
4447:
4448:
4449:
4450:
4451:
4452:
4453:
4454:
4455:
4456:
4457:
4458:
4459:
4460:
4461:
4462:
4463:
4464:
4465:
4466:
4467:
4468:
4469:
4470:
4471:
4472:
4473:
4474:
4475:
4476:
4477:
=== "BUTTON";
4478:
4479:
4480:
4481:
4482:
4483:
4484:
4485:
4486:
4487:

Tue Jan 04 14:26:58 2011

67

POS: function(match){
match.unshift( true );
return match;
}
},
filters: {
enabled: function(elem){
return elem.disabled === false && elem.type !== "hidden";
},
disabled: function(elem){
return elem.disabled === true;
},
checked: function(elem){
return elem.checked === true;
},
selected: function(elem){
elem.parentNode.selectedIndex;
return elem.selected === true;
},
parent: function(elem){
return !!elem.firstChild;
},
empty: function(elem){
return !elem.firstChild;
},
has: function(elem, i, match){
return !!Sizzle( match[3], elem ).length;
},
header: function(elem){
return /h\d/i.test( elem.nodeName );
},
text: function(elem){
return "text" === elem.type;
},
radio: function(elem){
return "radio" === elem.type;
},
checkbox: function(elem){
return "checkbox" === elem.type;
},
file: function(elem){
return "file" === elem.type;
},
password: function(elem){
return "password" === elem.type;
},
submit: function(elem){
return "submit" === elem.type;
},
image: function(elem){
return "image" === elem.type;
},
reset: function(elem){
return "reset" === elem.type;
},
button: function(elem){
return "button" === elem.type || elem.nodeName.toUpperCase()
},
input: function(elem){
return /input|select|textarea|button/i.test(elem.nodeName);
}
},
setFilters: {
first: function(elem, i){
return i === 0;
},
last: function(elem, i, match, array){

prototype.js

Tue Jan 04 14:26:58 2011

4488:
4489:
4490:
4491:
4492:
4493:
4494:
4495:
4496:
4497:
4498:
4499:
4500:
4501:
4502:
4503:
4504:
4505:
4506:
4507:
4508:
},
4509:
filter:
4510:
4511:
4512:
4513:
4514:
4515:
4516:
dexOf(match[3]) >= 0;
4517:
4518:
4519:
4520:
4521:
4522:
4523:
4524:
4525:
4526:
4527:
4528:
4529:
4530:
4531:
4532:
4533:
4534:
4535:
lse;
4536:
4537:
4538:
4539:
4540:
4541:
lse;
4542:
4543:
4544:
4545:
4546:
4547:
4548:
4549:
4550:
4551:
4552:

68

return i === array.length - 1;


},
even: function(elem, i){
return i % 2 === 0;
},
odd: function(elem, i){
return i % 2 === 1;
},
lt: function(elem, i, match){
return i < match[3] - 0;
},
gt: function(elem, i, match){
return i > match[3] - 0;
},
nth: function(elem, i, match){
return match[3] - 0 == i;
},
eq: function(elem, i, match){
return match[3] - 0 == i;
}
{
PSEUDO: function(elem, match, i, array){
var name = match[1], filter = Expr.filters[ name ];
if ( filter ) {
return filter( elem, i, match, array );
} else if ( name === "contains" ) {
return (elem.textContent || elem.innerText || "").in
} else if ( name === "not" ) {
var not = match[3];
for ( var i = 0, l = not.length; i < l; i++ ) {
if ( not[i] === elem ) {
return false;
}
}
return true;
}
},
CHILD: function(elem, match){
var type = match[1], node = elem;
switch (type) {
case only:
case first:
while ( (node = node.previousSibling) ) {
if ( node.nodeType === 1 ) return fa
}
if ( type == first) return true;
node = elem;
case last:
while ( (node = node.nextSibling) ) {
if ( node.nodeType === 1 ) return fa
}
return true;
case nth:
var first = match[2], last = match[3];
if ( first == 1 && last == 0 ) {
return true;
}
var doneName = match[0],
parent = elem.parentNode;

prototype.js

Tue Jan 04 14:26:58 2011

69

4553:
4554:
if ( parent && (parent.sizcache !== doneName
|| !elem.nodeIndex) ) {
4555:
var count = 0;
4556:
for ( node = parent.firstChild; node
; node = node.nextSibling ) {
4557:
if ( node.nodeType === 1 ) {
4558:
node.nodeIndex = ++c
ount;
4559:
}
4560:
}
4561:
parent.sizcache = doneName;
4562:
}
4563:
4564:
var diff = elem.nodeIndex - last;
4565:
if ( first == 0 ) {
4566:
return diff == 0;
4567:
} else {
4568:
return ( diff % first == 0 && diff /
first >= 0 );
4569:
}
4570:
}
4571:
},
4572:
ID: function(elem, match){
4573:
return elem.nodeType === 1 && elem.getAttribute("id") === ma
tch;
4574:
},
4575:
TAG: function(elem, match){
4576:
return (match === "*" && elem.nodeType === 1) || elem.nodeNa
me === match;
4577:
},
4578:
CLASS: function(elem, match){
4579:
return (" " + (elem.className || elem.getAttribute("class"))
+ " ")
4580:
.indexOf( match ) > -1;
4581:
},
4582:
ATTR: function(elem, match){
4583:
var name = match[1],
4584:
result = Expr.attrHandle[ name ] ?
4585:
Expr.attrHandle[ name ]( elem ) :
4586:
elem[ name ] != null ?
4587:
elem[ name ] :
4588:
elem.getAttribute( name ),
4589:
value = result + "",
4590:
type = match[2],
4591:
check = match[4];
4592:
4593:
return result == null ?
4594:
type === "!=" :
4595:
type === "=" ?
4596:
value === check :
4597:
type === "*=" ?
4598:
value.indexOf(check) >= 0 :
4599:
type === "=" ?
4600:
(" " + value + " ").indexOf(check) >= 0 :
4601:
!check ?
4602:
value && result !== false :
4603:
type === "!=" ?
4604:
value != check :
4605:
type === "^=" ?
4606:
value.indexOf(check) === 0 :
4607:
type === "$=" ?
4608:
value.substr(value.length - check.length) === check
:
4609:
type === "|=" ?
4610:
value === check || value.substr(0, check.length + 1)
=== check + "-" :
4611:
false;

prototype.js

Tue Jan 04 14:26:58 2011

70

4612:
},
4613:
POS: function(elem, match, i, array){
4614:
var name = match[2], filter = Expr.setFilters[ name ];
4615:
4616:
if ( filter ) {
4617:
return filter( elem, i, match, array );
4618:
}
4619:
}
4620:
}
4621: };
4622:
4623: var origPOS = Expr.match.POS;
4624:
4625: for ( var type in Expr.match ) {
4626:
Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?
![^\(]*\))/.source );
4627:
Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[
type ].source );
4628: }
4629:
4630: var makeArray = function(array, results) {
4631:
array = Array.prototype.slice.call( array, 0 );
4632:
4633:
if ( results ) {
4634:
results.push.apply( results, array );
4635:
return results;
4636:
}
4637:
4638:
return array;
4639: };
4640:
4641: try {
4642:
Array.prototype.slice.call( document.documentElement.childNodes, 0 );
4643:
4644: } catch(e){
4645:
makeArray = function(array, results) {
4646:
var ret = results || [];
4647:
4648:
if ( toString.call(array) === "[object Array]" ) {
4649:
Array.prototype.push.apply( ret, array );
4650:
} else {
4651:
if ( typeof array.length === "number" ) {
4652:
for ( var i = 0, l = array.length; i < l; i++ ) {
4653:
ret.push( array[i] );
4654:
}
4655:
} else {
4656:
for ( var i = 0; array[i]; i++ ) {
4657:
ret.push( array[i] );
4658:
}
4659:
}
4660:
}
4661:
4662:
return ret;
4663:
};
4664: }
4665:
4666: var sortOrder;
4667:
4668: if ( document.documentElement.compareDocumentPosition ) {
4669:
sortOrder = function( a, b ) {
4670:
if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4671:
if ( a == b ) {
4672:
hasDuplicate = true;
4673:
}
4674:
return 0;
4675:
}
4676:
4677:
var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;

prototype.js

Tue Jan 04 14:26:58 2011

71

if ( ret === 0 ) {
4678:
4679:
hasDuplicate = true;
4680:
}
4681:
return ret;
4682:
};
4683: } else if ( "sourceIndex" in document.documentElement ) {
4684:
sortOrder = function( a, b ) {
4685:
if ( !a.sourceIndex || !b.sourceIndex ) {
4686:
if ( a == b ) {
4687:
hasDuplicate = true;
4688:
}
4689:
return 0;
4690:
}
4691:
4692:
var ret = a.sourceIndex - b.sourceIndex;
4693:
if ( ret === 0 ) {
4694:
hasDuplicate = true;
4695:
}
4696:
return ret;
4697:
};
4698: } else if ( document.createRange ) {
4699:
sortOrder = function( a, b ) {
4700:
if ( !a.ownerDocument || !b.ownerDocument ) {
4701:
if ( a == b ) {
4702:
hasDuplicate = true;
4703:
}
4704:
return 0;
4705:
}
4706:
4707:
var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument
.createRange();
4708:
aRange.setStart(a, 0);
4709:
aRange.setEnd(a, 0);
4710:
bRange.setStart(b, 0);
4711:
bRange.setEnd(b, 0);
4712:
var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
4713:
if ( ret === 0 ) {
4714:
hasDuplicate = true;
4715:
}
4716:
return ret;
4717:
};
4718: }
4719:
4720: (function(){
4721:
var form = document.createElement("div"),
4722:
id = "script" + (new Date).getTime();
4723:
form.innerHTML = "<a name=" + id + "/>";
4724:
4725:
var root = document.documentElement;
4726:
root.insertBefore( form, root.firstChild );
4727:
4728:
if ( !!document.getElementById( id ) ) {
4729:
Expr.find.ID = function(match, context, isXML){
4730:
if ( typeof context.getElementById !== "undefined" && !isXML
) {
4731:
var m = context.getElementById(match[1]);
4732:
return m ? m.id === match[1] || typeof m.getAttribut
eNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined
: [];
4733:
}
4734:
};
4735:
4736:
Expr.filter.ID = function(elem, match){
4737:
var node = typeof elem.getAttributeNode !== "undefined" && e
lem.getAttributeNode("id");
4738:
return elem.nodeType === 1 && node && node.nodeValue === mat
ch;
4739:
};

prototype.js

Tue Jan 04 14:26:58 2011

72

4740:
}
4741:
4742:
root.removeChild( form );
4743:
root = form = null; // release memory in IE
4744: })();
4745:
4746: (function(){
4747:
4748:
var div = document.createElement("div");
4749:
div.appendChild( document.createComment("") );
4750:
4751:
if ( div.getElementsByTagName("*").length > 0 ) {
4752:
Expr.find.TAG = function(match, context){
4753:
var results = context.getElementsByTagName(match[1]);
4754:
4755:
if ( match[1] === "*" ) {
4756:
var tmp = [];
4757:
4758:
for ( var i = 0; results[i]; i++ ) {
4759:
if ( results[i].nodeType === 1 ) {
4760:
tmp.push( results[i] );
4761:
}
4762:
}
4763:
4764:
results = tmp;
4765:
}
4766:
4767:
return results;
4768:
};
4769:
}
4770:
4771:
div.innerHTML = "<a href=#></a>";
4772:
if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4773:
div.firstChild.getAttribute("href") !== "#" ) {
4774:
Expr.attrHandle.href = function(elem){
4775:
return elem.getAttribute("href", 2);
4776:
};
4777:
}
4778:
4779:
div = null; // release memory in IE
4780: })();
4781:
4782: if ( document.querySelectorAll ) (function(){
4783:
var oldSizzle = Sizzle, div = document.createElement("div");
4784:
div.innerHTML = "<p class=TEST></p>";
4785:
4786:
if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4787:
return;
4788:
}
4789:
4790:
Sizzle = function(query, context, extra, seed){
4791:
context = context || document;
4792:
4793:
if ( !seed && context.nodeType === 9 && !isXML(context) ) {
4794:
try {
4795:
return makeArray( context.querySelectorAll(query), e
xtra );
4796:
} catch(e){}
4797:
}
4798:
4799:
return oldSizzle(query, context, extra, seed);
4800:
};
4801:
4802:
for ( var prop in oldSizzle ) {
4803:
Sizzle[ prop ] = oldSizzle[ prop ];
4804:
}
4805:
4806:
div = null; // release memory in IE

prototype.js

Tue Jan 04 14:26:58 2011

73

4807: })();
4808:
4809: if ( document.getElementsByClassName && document.documentElement.getElementsByClassN
ame ) (function(){
4810:
var div = document.createElement("div");
4811:
div.innerHTML = "<div class=test e></div><div class=test></div>";
4812:
4813:
if ( div.getElementsByClassName("e").length === 0 )
4814:
return;
4815:
4816:
div.lastChild.className = "e";
4817:
4818:
if ( div.getElementsByClassName("e").length === 1 )
4819:
return;
4820:
4821:
Expr.order.splice(1, 0, "CLASS");
4822:
Expr.find.CLASS = function(match, context, isXML) {
4823:
if ( typeof context.getElementsByClassName !== "undefined" && !isXML
) {
4824:
return context.getElementsByClassName(match[1]);
4825:
}
4826:
};
4827:
4828:
div = null; // release memory in IE
4829: })();
4830:
4831: function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4832:
var sibDir = dir == "previousSibling" && !isXML;
4833:
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4834:
var elem = checkSet[i];
4835:
if ( elem ) {
4836:
if ( sibDir && elem.nodeType === 1 ){
4837:
elem.sizcache = doneName;
4838:
elem.sizset = i;
4839:
}
4840:
elem = elem[dir];
4841:
var match = false;
4842:
4843:
while ( elem ) {
4844:
if ( elem.sizcache === doneName ) {
4845:
match = checkSet[elem.sizset];
4846:
break;
4847:
}
4848:
4849:
if ( elem.nodeType === 1 && !isXML ){
4850:
elem.sizcache = doneName;
4851:
elem.sizset = i;
4852:
}
4853:
4854:
if ( elem.nodeName === cur ) {
4855:
match = elem;
4856:
break;
4857:
}
4858:
4859:
elem = elem[dir];
4860:
}
4861:
4862:
checkSet[i] = match;
4863:
}
4864:
}
4865: }
4866:
4867: function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4868:
var sibDir = dir == "previousSibling" && !isXML;
4869:
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4870:
var elem = checkSet[i];
4871:
if ( elem ) {
4872:
if ( sibDir && elem.nodeType === 1 ) {

prototype.js

Tue Jan 04 14:26:58 2011

74

4873:
elem.sizcache = doneName;
4874:
elem.sizset = i;
4875:
}
4876:
elem = elem[dir];
var match = false;
4877:
4878:
4879:
while ( elem ) {
4880:
if ( elem.sizcache === doneName ) {
4881:
match = checkSet[elem.sizset];
4882:
break;
4883:
}
4884:
4885:
if ( elem.nodeType === 1 ) {
4886:
if ( !isXML ) {
4887:
elem.sizcache = doneName;
4888:
elem.sizset = i;
4889:
}
4890:
if ( typeof cur !== "string" ) {
4891:
if ( elem === cur ) {
4892:
match = true;
4893:
break;
4894:
}
4895:
4896:
} else if ( Sizzle.filter( cur, [elem] ).len
gth > 0 ) {
4897:
match = elem;
4898:
break;
4899:
}
4900:
}
4901:
4902:
elem = elem[dir];
4903:
}
4904:
4905:
checkSet[i] = match;
4906:
}
4907:
}
4908: }
4909:
4910: var contains = document.compareDocumentPosition ? function(a, b){
4911:
return a.compareDocumentPosition(b) & 16;
4912: } : function(a, b){
4913:
return a !== b && (a.contains ? a.contains(b) : true);
4914: };
4915:
4916: var isXML = function(elem){
4917:
return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
4918:
!!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName
!== "HTML";
4919: };
4920:
4921: var posProcess = function(selector, context){
4922:
var tmpSet = [], later = "", match,
4923:
root = context.nodeType ? [context] : context;
4924:
4925:
while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
4926:
later += match[0];
4927:
selector = selector.replace( Expr.match.PSEUDO, "" );
4928:
}
4929:
4930:
selector = Expr.relative[selector] ? selector + "*" : selector;
4931:
4932:
for ( var i = 0, l = root.length; i < l; i++ ) {
4933:
Sizzle( selector, root[i], tmpSet );
4934:
}
4935:
4936:
return Sizzle.filter( later, tmpSet );
4937: };
4938:

prototype.js
4939:
4940:
4941:
4942:
4943:
4944:
4945:
4946:
4947:
4948:
4949:
4950:
4951:
4952:
4953:
4954:
4955:
4956:
4957:
4958:
4959:
4960:
4961:
4962:
4963:
4964:
4965:
4966:
4967:
4968:
4969:
4970:
4971:
4972:
4973:

Tue Jan 04 14:26:58 2011

75

window.Sizzle = Sizzle;
})();
;(function(engine) {
var extendElements = Prototype.Selector.extendElements;
function select(selector, scope) {
return extendElements(engine(selector, scope || document));
}
function match(element, selector) {
return engine.matches(selector, [element]).length == 1;
}
Prototype.Selector.engine = engine;
Prototype.Selector.select = select;
Prototype.Selector.match = match;
})(Sizzle);
window.Sizzle = Prototype._original_property;
delete Prototype._original_property;
var Form = {
reset: function(form) {
form = $(form);
form.reset();
return form;
},
serializeElements: function(elements, options) {
if (typeof options != object) options = { hash: !!options };
else if (Object.isUndefined(options.hash)) options.hash = true;
var key, value, submitted = false, submit = options.submit, accumulator, initial

;
4974:
4975:
if (options.hash) {
4976:
initial = {};
4977:
accumulator = function(result, key, value) {
4978:
if (key in result) {
4979:
if (!Object.isArray(result[key])) result[key] = [result[key]];
4980:
result[key].push(value);
4981:
} else result[key] = value;
4982:
return result;
4983:
};
4984:
} else {
4985:
initial = ;
4986:
accumulator = function(result, key, value) {
4987:
return result + (result ? & : ) + encodeURIComponent(key) + = + encode
URIComponent(value);
4988:
}
4989:
}
4990:
4991:
return elements.inject(initial, function(result, element) {
4992:
if (!element.disabled && element.name) {
4993:
key = element.name; value = $(element).getValue();
4994:
if (value != null && element.type != file && (element.type != submit ||
(!submitted &&
4995:
submit !== false && (!submit || key == submit) && (submitted = true))))
{
4996:
result = accumulator(result, key, value);
4997:
}
4998:
}
4999:
return result;
5000:
});
5001:
}
5002: };

prototype.js

Tue Jan 04 14:26:58 2011

76

5003:
5004: Form.Methods = {
5005:
serialize: function(form, options) {
5006:
return Form.serializeElements(Form.getElements(form), options);
5007:
},
5008:
5009:
getElements: function(form) {
5010:
var elements = $(form).getElementsByTagName(*),
5011:
element,
5012:
arr = [ ],
5013:
serializers = Form.Element.Serializers;
5014:
for (var i = 0; element = elements[i]; i++) {
5015:
arr.push(element);
5016:
}
5017:
return arr.inject([], function(elements, child) {
5018:
if (serializers[child.tagName.toLowerCase()])
5019:
elements.push(Element.extend(child));
5020:
return elements;
5021:
})
5022:
},
5023:
5024:
getInputs: function(form, typeName, name) {
5025:
form = $(form);
5026:
var inputs = form.getElementsByTagName(input);
5027:
5028:
if (!typeName && !name) return $A(inputs).map(Element.extend);
5029:
5030:
for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
5031:
var input = inputs[i];
5032:
if ((typeName && input.type != typeName) || (name && input.name != name))
5033:
continue;
5034:
matchingInputs.push(Element.extend(input));
5035:
}
5036:
5037:
return matchingInputs;
5038:
},
5039:
5040:
disable: function(form) {
5041:
form = $(form);
5042:
Form.getElements(form).invoke(disable);
5043:
return form;
5044:
},
5045:
5046:
enable: function(form) {
5047:
form = $(form);
5048:
Form.getElements(form).invoke(enable);
5049:
return form;
5050:
},
5051:
5052:
findFirstElement: function(form) {
5053:
var elements = $(form).getElements().findAll(function(element) {
5054:
return hidden != element.type && !element.disabled;
5055:
});
5056:
var firstByIndex = elements.findAll(function(element) {
5057:
return element.hasAttribute(tabIndex) && element.tabIndex >= 0;
5058:
}).sortBy(function(element) { return element.tabIndex }).first();
5059:
5060:
return firstByIndex ? firstByIndex : elements.find(function(element) {
5061:
return /^(?:input|select|textarea)$/i.test(element.tagName);
5062:
});
5063:
},
5064:
5065:
focusFirstElement: function(form) {
5066:
form = $(form);
5067:
var element = form.findFirstElement();
5068:
if (element) element.activate();
5069:
return form;
5070:
},

prototype.js
5071:
5072:
5073:
5074:
5075:
5076:
5077:
5078:
5079:
5080:
5081:
5082:
5083:
5084:
5085:
5086:
5087:
5088:
5089:
5090:
5091:
5092:
5093:
5094:
5095:
5096:
5097:
5098:
5099:
5100:
5101:
5102:
5103:
5104:
5105:
5106:
5107:
5108:
5109:
5110:
5111:
5112:
5113:
5114:
5115:
5116:
5117:
5118:
5119:
5120:
5121:
5122:
5123:
5124:
5125:
5126:
5127:
5128:
5129:
5130:
5131:
5132:
5133:
5134:
5135:
5136:
5137:
5138:

Tue Jan 04 14:26:58 2011

77

request: function(form, options) {


form = $(form), options = Object.clone(options || { });
var params = options.parameters, action = form.readAttribute(action) || ;
if (action.blank()) action = window.location.href;
options.parameters = form.serialize(true);
if (params) {
if (Object.isString(params)) params = params.toQueryParams();
Object.extend(options.parameters, params);
}
if (form.hasAttribute(method) && !options.method)
options.method = form.method;
return new Ajax.Request(action, options);
}
};
/*--------------------------------------------------------------------------*/

Form.Element = {
focus: function(element) {
$(element).focus();
return element;
},
select: function(element) {
$(element).select();
return element;
}
};
Form.Element.Methods = {
serialize: function(element) {
element = $(element);
if (!element.disabled && element.name) {
var value = element.getValue();
if (value != undefined) {
var pair = { };
pair[element.name] = value;
return Object.toQueryString(pair);
}
}
return ;
},
getValue: function(element) {
element = $(element);
var method = element.tagName.toLowerCase();
return Form.Element.Serializers[method](element);
},
setValue: function(element, value) {
element = $(element);
var method = element.tagName.toLowerCase();
Form.Element.Serializers[method](element, value);
return element;
},
clear: function(element) {
$(element).value = ;
return element;
},

prototype.js
5139:
5140:
5141:
5142:
5143:
5144:
5145:
5146:
5147:
5148:
5149:
5150:
5151:
5152:
5153:
5154:
5155:
5156:
5157:
5158:
5159:
5160:
5161:
5162:
5163:
5164:
5165:
5166:
5167:
5168:
5169:
5170:
5171:
5172:
5173:
5174:
5175:
5176:
5177:
5178:
5179:
5180:
5181:
5182:
5183:
5184:
5185:
5186:
5187:
5188:
5189:
5190:
5191:
5192:
5193:
5194:
5195:
5196:
5197:
5198:
5199:
5200:
5201:
5202:
5203:
5204:
5205:
5206:

Tue Jan 04 14:26:58 2011

78

present: function(element) {
return $(element).value != ;
},
activate: function(element) {
element = $(element);
try {
element.focus();
if (element.select && (element.tagName.toLowerCase() != input ||
!(/^(?:button|reset|submit)$/i.test(element.type))))
element.select();
} catch (e) { }
return element;
},
disable: function(element) {
element = $(element);
element.disabled = true;
return element;
},
enable: function(element) {
element = $(element);
element.disabled = false;
return element;
}
};
/*--------------------------------------------------------------------------*/
var Field = Form.Element;
var $F = Form.Element.Methods.getValue;
/*--------------------------------------------------------------------------*/
Form.Element.Serializers = (function() {
function input(element, value) {
switch (element.type.toLowerCase()) {
case checkbox:
case radio:
return inputSelector(element, value);
default:
return valueSelector(element, value);
}
}
function inputSelector(element, value) {
if (Object.isUndefined(value))
return element.checked ? element.value : null;
else element.checked = !!value;
}
function valueSelector(element, value) {
if (Object.isUndefined(value)) return element.value;
else element.value = value;
}
function select(element, value) {
if (Object.isUndefined(value))
return (element.type === select-one ? selectOne : selectMany)(element);
var opt, currentValue, single = !Object.isArray(value);
for (var i = 0, length = element.length; i < length; i++) {
opt = element.options[i];
currentValue = this.optionValue(opt);
if (single) {
if (currentValue == value) {

prototype.js
5207:
5208:
5209:
5210:
5211:
5212:
5213:
5214:
5215:
5216:
5217:
5218:
5219:
5220:
5221:
5222:
5223:
5224:
5225:
5226:
5227:
5228:
5229:
5230:
5231:
5232:
5233:
5234:
5235:
5236:
5237:
5238:
5239:
5240:
5241:
5242:
5243:
5244:
5245:
5246:
5247:
5248:
5249:
5250:
5251:
5252:
5253:
5254:
5255:
5256:
5257:
5258:
5259:
5260:
5261:
5262:
5263:
5264:
5265:
5266:
5267:
5268:
5269:
5270:
5271:
5272:
5273:
5274:

Tue Jan 04 14:26:58 2011

79

opt.selected = true;
return;
}
}
else opt.selected = value.include(currentValue);
}
}
function selectOne(element) {
var index = element.selectedIndex;
return index >= 0 ? optionValue(element.options[index]) : null;
}
function selectMany(element) {
var values, length = element.length;
if (!length) return null;
for (var i = 0, values = []; i < length; i++) {
var opt = element.options[i];
if (opt.selected) values.push(optionValue(opt));
}
return values;
}
function optionValue(opt) {
return Element.hasAttribute(opt, value) ? opt.value : opt.text;
}
return {
input:
inputSelector:
textarea:
select:
selectOne:
selectMany:
optionValue:
button:
};
})();

input,
inputSelector,
valueSelector,
select,
selectOne,
selectMany,
optionValue,
valueSelector

/*--------------------------------------------------------------------------*/

Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
initialize: function($super, element, frequency, callback) {
$super(callback, frequency);
this.element
= $(element);
this.lastValue = this.getValue();
},
execute: function() {
var value = this.getValue();
if (Object.isString(this.lastValue) && Object.isString(value) ?
this.lastValue != value : String(this.lastValue) != String(value)) {
this.callback(this.element, value);
this.lastValue = value;
}
}
});
Form.Element.Observer = Class.create(Abstract.TimedObserver, {
getValue: function() {
return Form.Element.getValue(this.element);
}
});
Form.Observer = Class.create(Abstract.TimedObserver, {
getValue: function() {

prototype.js
5275:
5276:
5277:
5278:
5279:
5280:
5281:
5282:
5283:
5284:
5285:
5286:
5287:
5288:
5289:
5290:
5291:
5292:
5293:
5294:
5295:
5296:
5297:
5298:
5299:
5300:
5301:
5302:
5303:
5304:
5305:
5306:
5307:
5308:
5309:
5310:
5311:
5312:
5313:
5314:
5315:
5316:
5317:
5318:
5319:
5320:
5321:
5322:
5323:
5324:
5325:
5326:
5327:
5328:
5329:
5330:
5331:
5332:
5333:
5334:
5335:
5336:
5337:
5338:
5339:
5340:
5341:
5342:

Tue Jan 04 14:26:58 2011

80

return Form.serialize(this.element);
}
});
/*--------------------------------------------------------------------------*/
Abstract.EventObserver = Class.create({
initialize: function(element, callback) {
this.element = $(element);
this.callback = callback;
this.lastValue = this.getValue();
if (this.element.tagName.toLowerCase() == form)
this.registerFormCallbacks();
else
this.registerCallback(this.element);
},
onElementEvent: function() {
var value = this.getValue();
if (this.lastValue != value) {
this.callback(this.element, value);
this.lastValue = value;
}
},
registerFormCallbacks: function() {
Form.getElements(this.element).each(this.registerCallback, this);
},
registerCallback: function(element) {
if (element.type) {
switch (element.type.toLowerCase()) {
case checkbox:
case radio:
Event.observe(element, click, this.onElementEvent.bind(this));
break;
default:
Event.observe(element, change, this.onElementEvent.bind(this));
break;
}
}
}
});
Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
getValue: function() {
return Form.Element.getValue(this.element);
}
});
Form.EventObserver = Class.create(Abstract.EventObserver, {
getValue: function() {
return Form.serialize(this.element);
}
});
(function() {
var Event = {
KEY_BACKSPACE: 8,
KEY_TAB:
9,
KEY_RETURN:
13,
KEY_ESC:
27,
KEY_LEFT:
37,
KEY_UP:
38,
KEY_RIGHT:
39,
KEY_DOWN:
40,
KEY_DELETE:
46,

prototype.js
5343:
5344:
5345:
5346:
5347:
5348:
5349:
5350:
5351:
5352:
5353:
5354:
5355:
5356:
5357:
5358:
5359:
5360:
5361:
5362:
5363:
5364:
5365:
5366:
5367:
5368:
5369:
5370:
5371:
5372:
5373:
5374:
5375:
5376:
5377:
5378:
5379:
5380:
5381:
5382:
5383:
5384:
5385:
5386:
5387:
5388:
5389:
5390:
5391:
5392:
5393:
5394:
5395:
5396:
5397:
5398:
5399:
5400:
5401:
5402:
5403:
5404:
5405:
5406:
5407:
5408:
5409:
5410:

Tue Jan 04 14:26:58 2011

KEY_HOME:
KEY_END:
KEY_PAGEUP:
KEY_PAGEDOWN:
KEY_INSERT:

81

36,
35,
33,
34,
45,

cache: {}
};
var docEl = document.documentElement;
var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = onmouseenter in docEl
&& onmouseleave in docEl;

var isIELegacyEvent = function(event) { return false; };


if (window.attachEvent) {
if (window.addEventListener) {
isIELegacyEvent = function(event) {
return !(event instanceof window.Event);
};
} else {
isIELegacyEvent = function(event) { return true; };
}
}
var _isButton;
function _isButtonForDOMEvents(event, code) {
return event.which ? (event.which === code + 1) : (event.button === code);
}
var legacyButtonMap = { 0: 1, 1: 4, 2: 2 };
function _isButtonForLegacyEvents(event, code) {
return event.button === legacyButtonMap[code];
}
function _isButtonForWebKit(event, code) {
switch (code) {
case 0: return event.which == 1 && !event.metaKey;
case 1: return event.which == 2 || (event.which == 1 && event.metaKey);
case 2: return event.which == 3;
default: return false;
}
}
if (window.attachEvent) {
if (!window.addEventListener) {
_isButton = _isButtonForLegacyEvents;
} else {
_isButton = function(event, code) {
return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) :
_isButtonForDOMEvents(event, code);
}
}
} else if (Prototype.Browser.WebKit) {
_isButton = _isButtonForWebKit;
} else {
_isButton = _isButtonForDOMEvents;
}
function isLeftClick(event)

{ return _isButton(event, 0) }

function isMiddleClick(event) { return _isButton(event, 1) }


function isRightClick(event)

{ return _isButton(event, 2) }

prototype.js
5411:
5412:
5413:
5414:
5415:
5416:
5417:
5418:
5419:
5420:
5421:
5422:
5423:
5424:
5425:
5426:
5427:
5428:
5429:
5430:
5431:
5432:
5433:
5434:
5435:
) {
5436:
5437:
5438:
5439:
5440:
5441:
5442:
5443:
5444:
5445:
5446:
5447:
5448:
5449:
5450:
5451:
5452:
5453:
5454:
5455:
5456:
5457:
5458:
5459:
5460:
5461:
5462:
5463:
5464:
5465:
5466:
5467:
5468:
5469:
5470:
5471:
5472:
5473:
5474:
5475:
5476:
5477:

Tue Jan 04 14:26:58 2011

82

function element(event) {
event = Event.extend(event);
var node = event.target, type = event.type,
currentTarget = event.currentTarget;
if (currentTarget && currentTarget.tagName) {
if (type === load || type === error ||
(type === click && currentTarget.tagName.toLowerCase() === input
&& currentTarget.type === radio))
node = currentTarget;
}
if (node.nodeType == Node.TEXT_NODE)
node = node.parentNode;
return Element.extend(node);
}
function findElement(event, expression) {
var element = Event.element(event);
if (!expression) return element;
while (element) {
if (Object.isElement(element) && Prototype.Selector.match(element, expression)
return Element.extend(element);
}
element = element.parentNode;
}
}
function pointer(event) {
return { x: pointerX(event), y: pointerY(event) };
}
function pointerX(event) {
var docElement = document.documentElement,
body = document.body || { scrollLeft: 0 };
return event.pageX || (event.clientX +
(docElement.scrollLeft || body.scrollLeft) (docElement.clientLeft || 0));
}
function pointerY(event) {
var docElement = document.documentElement,
body = document.body || { scrollTop: 0 };
return event.pageY || (event.clientY +
(docElement.scrollTop || body.scrollTop) (docElement.clientTop || 0));
}

function stop(event) {
Event.extend(event);
event.preventDefault();
event.stopPropagation();
event.stopped = true;
}

Event.Methods = {
isLeftClick:
isLeftClick,
isMiddleClick: isMiddleClick,
isRightClick: isRightClick,

prototype.js
5478:
5479:
5480:
5481:
5482:
5483:
5484:
5485:
5486:
5487:
5488:
5489:
5490:
5491:
5492:
5493:
5494:
5495:
5496:
5497:
5498:
5499:
5500:
5501:
5502:
5503:
5504:
5505:
5506:
5507:
5508:
5509:
5510:
5511:
5512:
5513:
5514:
5515:
5516:
5517:
5518:
5519:
5520:
5521:
5522:
5523:
5524:
5525:
5526:
5527:
5528:
5529:
5530:
5531:
5532:
5533:
5534:
5535:
5536:
5537:
5538:
5539:
5540:
5541:
5542:
5543:
5544:
5545:

Tue Jan 04 14:26:58 2011

83

element:
element,
findElement: findElement,
pointer: pointer,
pointerX: pointerX,
pointerY: pointerY,
stop: stop
};
var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
m[name] = Event.Methods[name].methodize();
return m;
});
if (window.attachEvent) {
function _relatedTarget(event) {
var element;
switch (event.type) {
case mouseover:
case mouseenter:
element = event.fromElement;
break;
case mouseout:
case mouseleave:
element = event.toElement;
break;
default:
return null;
}
return Element.extend(element);
}
var additionalMethods = {
stopPropagation: function() { this.cancelBubble = true },
preventDefault: function() { this.returnValue = false },
inspect: function() { return [object Event] }
};
Event.extend = function(event, element) {
if (!event) return false;
if (!isIELegacyEvent(event)) return event;
if (event._extendedByPrototype) return event;
event._extendedByPrototype = Prototype.emptyFunction;
var pointer = Event.pointer(event);
Object.extend(event, {
target: event.srcElement || element,
relatedTarget: _relatedTarget(event),
pageX: pointer.x,
pageY: pointer.y
});
Object.extend(event, methods);
Object.extend(event, additionalMethods);
return event;
};
} else {
Event.extend = Prototype.K;
}
if (window.addEventListener) {
Event.prototype = window.Event.prototype || document.createEvent(HTMLEvents)._

prototype.js

Tue Jan 04 14:26:58 2011

84

_proto__;
5546:
Object.extend(Event.prototype, methods);
5547:
}
5548:
function _createResponder(element, eventName, handler) {
5549:
5550:
var registry = Element.retrieve(element, prototype_event_registry);
5551:
5552:
if (Object.isUndefined(registry)) {
5553:
CACHE.push(element);
5554:
registry = Element.retrieve(element, prototype_event_registry, $H());
5555:
}
5556:
5557:
var respondersForEvent = registry.get(eventName);
5558:
if (Object.isUndefined(respondersForEvent)) {
5559:
respondersForEvent = [];
5560:
registry.set(eventName, respondersForEvent);
5561:
}
5562:
5563:
if (respondersForEvent.pluck(handler).include(handler)) return false;
5564:
5565:
var responder;
5566:
if (eventName.include(":")) {
5567:
responder = function(event) {
5568:
if (Object.isUndefined(event.eventName))
5569:
return false;
5570:
5571:
if (event.eventName !== eventName)
5572:
return false;
5573:
5574:
Event.extend(event, element);
5575:
handler.call(element, event);
5576:
};
5577:
} else {
5578:
if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
5579:
(eventName === "mouseenter" || eventName === "mouseleave")) {
5580:
if (eventName === "mouseenter" || eventName === "mouseleave") {
5581:
responder = function(event) {
5582:
Event.extend(event, element);
5583:
5584:
var parent = event.relatedTarget;
5585:
while (parent && parent !== element) {
5586:
try { parent = parent.parentNode; }
5587:
catch(e) { parent = element; }
5588:
}
5589:
5590:
if (parent === element) return;
5591:
5592:
handler.call(element, event);
5593:
};
5594:
}
5595:
} else {
5596:
responder = function(event) {
5597:
Event.extend(event, element);
5598:
handler.call(element, event);
5599:
};
5600:
}
5601:
}
5602:
5603:
responder.handler = handler;
5604:
respondersForEvent.push(responder);
5605:
return responder;
5606:
}
5607:
5608:
function _destroyCache() {
5609:
for (var i = 0, length = CACHE.length; i < length; i++) {
5610:
Event.stopObserving(CACHE[i]);
5611:
CACHE[i] = null;
5612:
}

prototype.js
5613:
5614:
5615:
5616:
5617:
5618:
5619:
5620:
5621:
5622:
5623:
5624:
5625:
5626:
5627:
5628:
5629:
5630:
5631:
5632:
5633:
5634:
5635:
5636:
5637:
5638:
5639:
5640:
5641:
5642:
5643:
5644:
5645:
5646:
5647:
5648:
5649:
5650:
5651:
5652:
5653:
5654:
5655:
5656:
5657:
5658:
5659:
5660:
5661:
5662:
5663:
5664:
5665:
5666:
5667:
5668:
5669:
5670:
5671:
5672:
5673:
5674:
5675:
5676:
5677:
5678:
5679:
5680:

Tue Jan 04 14:26:58 2011

85

}
var CACHE = [];
if (Prototype.Browser.IE)
window.attachEvent(onunload, _destroyCache);
if (Prototype.Browser.WebKit)
window.addEventListener(unload, Prototype.emptyFunction, false);

var _getDOMEventName = Prototype.K,


translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
_getDOMEventName = function(eventName) {
return (translations[eventName] || eventName);
};
}
function observe(element, eventName, handler) {
element = $(element);
var responder = _createResponder(element, eventName, handler);
if (!responder) return element;
if (eventName.include(:)) {
if (element.addEventListener)
element.addEventListener("dataavailable", responder, false);
else {
element.attachEvent("ondataavailable", responder);
element.attachEvent("onlosecapture", responder);
}
} else {
var actualEventName = _getDOMEventName(eventName);
if (element.addEventListener)
element.addEventListener(actualEventName, responder, false);
else
element.attachEvent("on" + actualEventName, responder);
}
return element;
}
function stopObserving(element, eventName, handler) {
element = $(element);
var registry = Element.retrieve(element, prototype_event_registry);
if (!registry) return element;
if (!eventName) {
registry.each( function(pair) {
var eventName = pair.key;
stopObserving(element, eventName);
});
return element;
}
var responders = registry.get(eventName);
if (!responders) return element;
if (!handler) {
responders.each(function(r) {
stopObserving(element, eventName, r.handler);
});
return element;

prototype.js
5681:
5682:
5683:
5684:
5685:
5686:
5687:
5688:
5689:
5690:
5691:
5692:
5693:
5694:
5695:
5696:
5697:
5698:
5699:
5700:
5701:
5702:
5703:
5704:
5705:
5706:
5707:
5708:
5709:
5710:
5711:
5712:
5713:
5714:
5715:
5716:
5717:
5718:
5719:
5720:
5721:
5722:
5723:
5724:
5725:
5726:
5727:
5728:
5729:
5730:
5731:
5732:
5733:
5734:
5735:
5736:
5737:
5738:
5739:
5740:
5741:
5742:
5743:
5744:
5745:
5746:
5747:
5748:

Tue Jan 04 14:26:58 2011

86

}
var i = responders.length, responder;
while (i--) {
if (responders[i].handler === handler) {
responder = responders[i];
break;
}
}
if (!responder) return element;
if (eventName.include(:)) {
if (element.removeEventListener)
element.removeEventListener("dataavailable", responder, false);
else {
element.detachEvent("ondataavailable", responder);
element.detachEvent("onlosecapture", responder);
}
} else {
var actualEventName = _getDOMEventName(eventName);
if (element.removeEventListener)
element.removeEventListener(actualEventName, responder, false);
else
element.detachEvent(on + actualEventName, responder);
}
registry.set(eventName, responders.without(responder));
return element;
}
function fire(element, eventName, memo, bubble) {
element = $(element);
if (Object.isUndefined(bubble))
bubble = true;
if (element == document && document.createEvent && !element.dispatchEvent)
element = document.documentElement;
var event;
if (document.createEvent) {
event = document.createEvent(HTMLEvents);
event.initEvent(dataavailable, bubble, true);
} else {
event = document.createEventObject();
event.eventType = bubble ? ondataavailable : onlosecapture;
}
event.eventName = eventName;
event.memo = memo || { };
if (document.createEvent)
element.dispatchEvent(event);
else
element.fireEvent(event.eventType, event);
return Event.extend(event);
}
Event.Handler = Class.create({
initialize: function(element, eventName, selector, callback) {
this.element
= $(element);
this.eventName = eventName;
this.selector = selector;
this.callback = callback;
this.handler
= this.handleEvent.bind(this);
},

prototype.js

Tue Jan 04 14:26:58 2011

87

5749:
5750:
start: function() {
5751:
Event.observe(this.element, this.eventName, this.handler);
5752:
return this;
5753:
},
5754:
5755:
stop: function() {
5756:
Event.stopObserving(this.element, this.eventName, this.handler);
5757:
return this;
5758:
},
5759:
5760:
handleEvent: function(event) {
5761:
var element = Event.findElement(event, this.selector);
5762:
if (element) this.callback.call(this.element, event, element);
5763:
}
5764:
});
5765:
5766:
function on(element, eventName, selector, callback) {
5767:
element = $(element);
5768:
if (Object.isFunction(selector) && Object.isUndefined(callback)) {
5769:
callback = selector, selector = null;
5770:
}
5771:
5772:
return new Event.Handler(element, eventName, selector, callback).start();
5773:
}
5774:
5775:
Object.extend(Event, Event.Methods);
5776:
5777:
Object.extend(Event, {
5778:
fire:
fire,
5779:
observe:
observe,
5780:
stopObserving: stopObserving,
5781:
on:
on
5782:
});
5783:
5784:
Element.addMethods({
5785:
fire:
fire,
5786:
5787:
observe:
observe,
5788:
5789:
stopObserving: stopObserving,
5790:
5791:
on:
on
5792:
});
5793:
5794:
Object.extend(document, {
5795:
fire:
fire.methodize(),
5796:
5797:
observe:
observe.methodize(),
5798:
5799:
stopObserving: stopObserving.methodize(),
5800:
5801:
on:
on.methodize(),
5802:
5803:
loaded:
false
5804:
});
5805:
5806:
if (window.Event) Object.extend(window.Event, Event);
5807:
else window.Event = Event;
5808: })();
5809:
5810: (function() {
5811:
/* Support for the DOMContentLoaded event is based on work by Dan Webb,
5812:
Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
5813:
5814:
var timer;
5815:
5816:
function fireContentLoadedEvent() {

prototype.js
5817:
5818:
5819:
5820:
5821:
5822:
5823:
5824:
5825:
5826:
5827:
5828:
5829:
5830:
5831:
5832:
5833:
5834:
5835:
5836:
5837:
5838:
5839:
5840:
5841:
5842:
5843:
5844:
5845:
5846:
5847:
5848:
5849:
5850:
5851:
5852:
5853:
5854:
5855:
5856:
5857:
5858:
5859:
5860:
5861:
5862:
5863:
5864:
5865:
5866:
5867:
5868:
5869:
5870:
5871:
5872:
5873:
5874:
5875:
5876:
5877:
5878:
5879:
5880:
5881:
5882:
5883:
5884:

Tue Jan 04 14:26:58 2011

88

if (document.loaded) return;
if (timer) window.clearTimeout(timer);
document.loaded = true;
document.fire(dom:loaded);
}
function checkReadyState() {
if (document.readyState === complete) {
document.stopObserving(readystatechange, checkReadyState);
fireContentLoadedEvent();
}
}
function pollDoScroll() {
try { document.documentElement.doScroll(left); }
catch(e) {
timer = pollDoScroll.defer();
return;
}
fireContentLoadedEvent();
}
if (document.addEventListener) {
document.addEventListener(DOMContentLoaded, fireContentLoadedEvent, false);
} else {
document.observe(readystatechange, checkReadyState);
if (window == top)
timer = pollDoScroll.defer();
}
Event.observe(window, load, fireContentLoadedEvent);
})();
Element.addMethods();
/*------------------------------- DEPRECATED -------------------------------*/
Hash.toQueryString = Object.toQueryString;
var Toggle = { display: Element.toggle };
Element.Methods.childOf = Element.Methods.descendantOf;
var Insertion = {
Before: function(element, content) {
return Element.insert(element, {before:content});
},
Top: function(element, content) {
return Element.insert(element, {top:content});
},
Bottom: function(element, content) {
return Element.insert(element, {bottom:content});
},
After: function(element, content) {
return Element.insert(element, {after:content});
}
};
var $continue = new Error("throw $continue" is deprecated, use "return" instead);
var Position = {
includeScrollOffsets: false,
prepare: function() {
this.deltaX = window.pageXOffset

prototype.js
5885:
5886:
5887:
5888:
5889:
5890:
5891:
5892:
5893:
5894:
5895:
5896:
5897:
5898:
5899:
5900:
5901:
5902:
5903:
5904:
5905:
5906:
5907:
5908:
5909:
5910:
5911:
5912:
5913:
5914:
5915:
5916:
5917:
5918:
5919:
5920:
5921:
5922:
5923:
5924:
5925:
5926:
5927:
5928:
5929:
5930:
5931:
5932:
5933:
5934:
5935:
5936:
5937:
5938:
5939:
5940:
5941:
5942:
5943:
5944:
5945:
5946:
5947:
5948:
5949:
5950:
5951:
5952:

Tue Jan 04 14:26:58 2011

||
||
||
this.deltaY =
||
||
||

89

document.documentElement.scrollLeft
document.body.scrollLeft
0;
window.pageYOffset
document.documentElement.scrollTop
document.body.scrollTop
0;

},
within: function(element, x, y) {
if (this.includeScrollOffsets)
return this.withinIncludingScrolloffsets(element, x, y);
this.xcomp = x;
this.ycomp = y;
this.offset = Element.cumulativeOffset(element);
return (y
y
x
x

>=
<
>=
<

this.offset[1]
this.offset[1]
this.offset[0]
this.offset[0]

&&
+ element.offsetHeight &&
&&
+ element.offsetWidth);

},
withinIncludingScrolloffsets: function(element, x, y) {
var offsetcache = Element.cumulativeScrollOffset(element);
this.xcomp = x + offsetcache[0] - this.deltaX;
this.ycomp = y + offsetcache[1] - this.deltaY;
this.offset = Element.cumulativeOffset(element);
return (this.ycomp
this.ycomp
this.xcomp
this.xcomp

>=
<
>=
<

this.offset[1]
this.offset[1]
this.offset[0]
this.offset[0]

&&
+ element.offsetHeight &&
&&
+ element.offsetWidth);

},
overlap: function(mode, element) {
if (!mode) return 0;
if (mode == vertical)
return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
element.offsetHeight;
if (mode == horizontal)
return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
element.offsetWidth;
},

cumulativeOffset: Element.Methods.cumulativeOffset,
positionedOffset: Element.Methods.positionedOffset,
absolutize: function(element) {
Position.prepare();
return Element.absolutize(element);
},
relativize: function(element) {
Position.prepare();
return Element.relativize(element);
},
realOffset: Element.Methods.cumulativeScrollOffset,
offsetParent: Element.Methods.getOffsetParent,
page: Element.Methods.viewportOffset,
clone: function(source, target, options) {
options = options || { };

prototype.js

Tue Jan 04 14:26:58 2011

90

return Element.clonePosition(target, source, options);


5953:
5954:
}
5955: };
5956:
5957: /*--------------------------------------------------------------------------*/
5958:
5959: if (!document.getElementsByClassName) document.getElementsByClassName = function(ins
tanceMethods){
5960:
function iter(name) {
5961:
return name.blank() ? null : "[contains(concat( , @class, ), " + name + "
)]";
5962:
}
5963:
5964:
instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
5965:
function(element, className) {
5966:
className = className.toString().strip();
5967:
var cond = /\s/.test(className) ? $w(className).map(iter).join() : iter(classN
ame);
5968:
return cond ? document._getElementsByXPath(.//* + cond, element) : [];
5969:
} : function(element, className) {
5970:
className = className.toString().strip();
5971:
var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
5972:
if (!classNames && !className) return elements;
5973:
5974:
var nodes = $(element).getElementsByTagName(*);
5975:
className = + className + ;
5976:
5977:
for (var i = 0, child, cn; child = nodes[i]; i++) {
5978:
if (child.className && (cn = + child.className + ) && (cn.include(class
Name) ||
5979:
(classNames && classNames.all(function(name) {
5980:
return !name.toString().blank() && cn.include( + name + );
5981:
}))))
5982:
elements.push(Element.extend(child));
5983:
}
5984:
return elements;
5985:
};
5986:
5987:
return function(className, parentElement) {
5988:
return $(parentElement || document.body).getElementsByClassName(className);
5989:
};
5990: }(Element.Methods);
5991:
5992: /*--------------------------------------------------------------------------*/
5993:
5994: Element.ClassNames = Class.create();
5995: Element.ClassNames.prototype = {
5996:
initialize: function(element) {
5997:
this.element = $(element);
5998:
},
5999:
6000:
_each: function(iterator) {
6001:
this.element.className.split(/\s+/).select(function(name) {
6002:
return name.length > 0;
6003:
})._each(iterator);
6004:
},
6005:
6006:
set: function(className) {
6007:
this.element.className = className;
6008:
},
6009:
6010:
add: function(classNameToAdd) {
6011:
if (this.include(classNameToAdd)) return;
6012:
this.set($A(this).concat(classNameToAdd).join( ));
6013:
},
6014:
6015:
remove: function(classNameToRemove) {
6016:
if (!this.include(classNameToRemove)) return;

prototype.js
6017:
6018:
6019:
6020:
6021:
6022:
6023:
6024:
6025:
6026:
6027:
6028:
6029:
6030:
6031:
6032:
6033:
6034:
6035:
6036:
6037:
6038:
6039:
6040:
6041:
6042:
6043:
6044:
6045:
6046:
6047:
6048:
6049:
6050:
6051:
6052:
6053:
6054:
6055:
6056:
6057:
6058:
6059:
6060:
6061:
6062:
6063:
6064:
6065:
6066:
6067:
6068:
6069:
6070:
6071:
{
6072:
6073:
6074:
6075:
6076:
6077:
6078:
6079:
6080:
6081:
6082:

Tue Jan 04 14:26:58 2011

91

this.set($A(this).without(classNameToRemove).join( ));
},
toString: function() {
return $A(this).join( );
}
};
Object.extend(Element.ClassNames.prototype, Enumerable);
/*--------------------------------------------------------------------------*/
(function() {
window.Selector = Class.create({
initialize: function(expression) {
this.expression = expression.strip();
},
findElements: function(rootElement) {
return Prototype.Selector.select(this.expression, rootElement);
},
match: function(element) {
return Prototype.Selector.match(element, this.expression);
},
toString: function() {
return this.expression;
},
inspect: function() {
return "#<Selector: " + this.expression + ">";
}
});
Object.extend(Selector, {
matchElements: function(elements, expression) {
var match = Prototype.Selector.match,
results = [];
for (var i = 0, length = elements.length; i < length; i++) {
var element = elements[i];
if (match(element, expression)) {
results.push(Element.extend(element));
}
}
return results;
},
findElement: function(elements, expression, index) {
index = index || 0;
var matchIndex = 0, element;
for (var i = 0, length = elements.length; i < length; i++) {
element = elements[i];
if (Prototype.Selector.match(element, expression) && index === matchIndex++)
return Element.extend(element);
}
}
},
findChildElements: function(element, expressions) {
var selector = expressions.toArray().join(, );
return Prototype.Selector.select(selector, element || document);
}
});
})();

Das könnte Ihnen auch gefallen