Mercurial > hg > soundsoftware-site
comparison .svn/pristine/16/1665bbb2717b49de68649a3ba32e9deb6f26e40f.svn-base @ 909:cbb26bc654de redmine-1.3
Update to Redmine 1.3-stable branch (Redmine SVN rev 8964)
author | Chris Cannam |
---|---|
date | Fri, 24 Feb 2012 19:09:32 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
908:c6c2cbd0afee | 909:cbb26bc654de |
---|---|
1 /* Prototype JavaScript framework, version 1.7 | |
2 * (c) 2005-2010 Sam Stephenson | |
3 * | |
4 * Prototype is freely distributable under the terms of an MIT-style license. | |
5 * For details, see the Prototype web site: http://www.prototypejs.org/ | |
6 * | |
7 *--------------------------------------------------------------------------*/ | |
8 | |
9 var Prototype = { | |
10 | |
11 Version: '1.7', | |
12 | |
13 Browser: (function(){ | |
14 var ua = navigator.userAgent; | |
15 var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]'; | |
16 return { | |
17 IE: !!window.attachEvent && !isOpera, | |
18 Opera: isOpera, | |
19 WebKit: ua.indexOf('AppleWebKit/') > -1, | |
20 Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1, | |
21 MobileSafari: /Apple.*Mobile/.test(ua) | |
22 } | |
23 })(), | |
24 | |
25 BrowserFeatures: { | |
26 XPath: !!document.evaluate, | |
27 | |
28 SelectorsAPI: !!document.querySelector, | |
29 | |
30 ElementExtensions: (function() { | |
31 var constructor = window.Element || window.HTMLElement; | |
32 return !!(constructor && constructor.prototype); | |
33 })(), | |
34 SpecificElementExtensions: (function() { | |
35 if (typeof window.HTMLDivElement !== 'undefined') | |
36 return true; | |
37 | |
38 var div = document.createElement('div'), | |
39 form = document.createElement('form'), | |
40 isSupported = false; | |
41 | |
42 if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) { | |
43 isSupported = true; | |
44 } | |
45 | |
46 div = form = null; | |
47 | |
48 return isSupported; | |
49 })() | |
50 }, | |
51 | |
52 ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>', | |
53 JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, | |
54 | |
55 emptyFunction: function() { }, | |
56 | |
57 K: function(x) { return x } | |
58 }; | |
59 | |
60 if (Prototype.Browser.MobileSafari) | |
61 Prototype.BrowserFeatures.SpecificElementExtensions = false; | |
62 | |
63 | |
64 var Abstract = { }; | |
65 | |
66 | |
67 var Try = { | |
68 these: function() { | |
69 var returnValue; | |
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 Arnell's 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]; | |
137 if (ancestor && Object.isFunction(value) && | |
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); | |
205 } catch (e) { | |
206 if (e instanceof RangeError) return '...'; | |
207 throw e; | |
208 } | |
209 } | |
210 | |
211 function toJSON(value) { | |
212 return Str('', { '': value }, []); | |
213 } | |
214 | |
215 function Str(key, holder, stack) { | |
216 var value = holder[key], | |
217 type = typeof value; | |
218 | |
219 if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') { | |
220 value = value.toJSON(key); | |
221 } | |
222 | |
223 var _class = _toString.call(value); | |
224 | |
225 switch (_class) { | |
226 case NUMBER_CLASS: | |
227 case BOOLEAN_CLASS: | |
228 case STRING_CLASS: | |
229 value = value.valueOf(); | |
230 } | |
231 | |
232 switch (value) { | |
233 case null: return 'null'; | |
234 case true: return 'true'; | |
235 case false: return 'false'; | |
236 } | |
237 | |
238 type = typeof value; | |
239 switch (type) { | |
240 case 'string': | |
241 return value.inspect(true); | |
242 case 'number': | |
243 return isFinite(value) ? String(value) : 'null'; | |
244 case 'object': | |
245 | |
246 for (var i = 0, length = stack.length; i < length; i++) { | |
247 if (stack[i] === value) { throw new TypeError(); } | |
248 } | |
249 stack.push(value); | |
250 | |
251 var partial = []; | |
252 if (_class === ARRAY_CLASS) { | |
253 for (var i = 0, length = value.length; i < length; i++) { | |
254 var str = Str(i, value, stack); | |
255 partial.push(typeof str === 'undefined' ? 'null' : str); | |
256 } | |
257 partial = '[' + partial.join(',') + ']'; | |
258 } else { | |
259 var keys = Object.keys(value); | |
260 for (var i = 0, length = keys.length; i < length; i++) { | |
261 var key = keys[i], str = Str(key, value, stack); | |
262 if (typeof str !== "undefined") { | |
263 partial.push(key.inspect(true)+ ':' + str); | |
264 } | |
265 } | |
266 partial = '{' + partial.join(',') + '}'; | |
267 } | |
268 stack.pop(); | |
269 return partial; | |
270 } | |
271 } | |
272 | |
273 function stringify(object) { | |
274 return JSON.stringify(object); | |
275 } | |
276 | |
277 function toQueryString(object) { | |
278 return $H(object).toQueryString(); | |
279 } | |
280 | |
281 function toHTML(object) { | |
282 return object && object.toHTML ? object.toHTML() : String.interpret(object); | |
283 } | |
284 | |
285 function keys(object) { | |
286 if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); } | |
287 var results = []; | |
288 for (var property in object) { | |
289 if (object.hasOwnProperty(property)) { | |
290 results.push(property); | |
291 } | |
292 } | |
293 return results; | |
294 } | |
295 | |
296 function values(object) { | |
297 var results = []; | |
298 for (var property in object) | |
299 results.push(object[property]); | |
300 return results; | |
301 } | |
302 | |
303 function clone(object) { | |
304 return extend({ }, object); | |
305 } | |
306 | |
307 function isElement(object) { | |
308 return !!(object && object.nodeType == 1); | |
309 } | |
310 | |
311 function isArray(object) { | |
312 return _toString.call(object) === ARRAY_CLASS; | |
313 } | |
314 | |
315 var hasNativeIsArray = (typeof Array.isArray == 'function') | |
316 && Array.isArray([]) && !Array.isArray({}); | |
317 | |
318 if (hasNativeIsArray) { | |
319 isArray = Array.isArray; | |
320 } | |
321 | |
322 function isHash(object) { | |
323 return object instanceof Hash; | |
324 } | |
325 | |
326 function isFunction(object) { | |
327 return _toString.call(object) === FUNCTION_CLASS; | |
328 } | |
329 | |
330 function isString(object) { | |
331 return _toString.call(object) === STRING_CLASS; | |
332 } | |
333 | |
334 function isNumber(object) { | |
335 return _toString.call(object) === NUMBER_CLASS; | |
336 } | |
337 | |
338 function isDate(object) { | |
339 return _toString.call(object) === DATE_CLASS; | |
340 } | |
341 | |
342 function isUndefined(object) { | |
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); | |
409 } | |
410 } | |
411 | |
412 function delay(timeout) { | |
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); | |
477 | |
478 | |
479 RegExp.prototype.match = RegExp.prototype.test; | |
480 | |
481 RegExp.escape = function(str) { | |
482 return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); | |
483 }; | |
484 var PeriodicalExecuter = Class.create({ | |
485 initialize: function(callback, frequency) { | |
486 this.callback = callback; | |
487 this.frequency = frequency; | |
488 this.currentlyExecuting = false; | |
489 | |
490 this.registerCallback(); | |
491 }, | |
492 | |
493 registerCallback: function() { | |
494 this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); | |
495 }, | |
496 | |
497 execute: function() { | |
498 this.callback(this); | |
499 }, | |
500 | |
501 stop: function() { | |
502 if (!this.timer) return; | |
503 clearInterval(this.timer); | |
504 this.timer = null; | |
505 }, | |
506 | |
507 onTimerEvent: function() { | |
508 if (!this.currentlyExecuting) { | |
509 try { | |
510 this.currentlyExecuting = true; | |
511 this.execute(); | |
512 this.currentlyExecuting = false; | |
513 } catch(e) { | |
514 this.currentlyExecuting = false; | |
515 throw e; | |
516 } | |
517 } | |
518 } | |
519 }); | |
520 Object.extend(String, { | |
521 interpret: function(value) { | |
522 return value == null ? '' : String(value); | |
523 }, | |
524 specialChar: { | |
525 '\b': '\\b', | |
526 '\t': '\\t', | |
527 '\n': '\\n', | |
528 '\f': '\\f', | |
529 '\r': '\\r', | |
530 '\\': '\\\\' | |
531 } | |
532 }); | |
533 | |
534 Object.extend(String.prototype, (function() { | |
535 var NATIVE_JSON_PARSE_SUPPORT = window.JSON && | |
536 typeof JSON.parse === 'function' && | |
537 JSON.parse('{"test": true}').test; | |
538 | |
539 function prepareReplacement(replacement) { | |
540 if (Object.isFunction(replacement)) return replacement; | |
541 var template = new Template(replacement); | |
542 return function(match) { return template.evaluate(match) }; | |
543 } | |
544 | |
545 function gsub(pattern, replacement) { | |
546 var result = '', source = this, match; | |
547 replacement = prepareReplacement(replacement); | |
548 | |
549 if (Object.isString(pattern)) | |
550 pattern = RegExp.escape(pattern); | |
551 | |
552 if (!(pattern.length || pattern.source)) { | |
553 replacement = replacement(''); | |
554 return replacement + source.split('').join(replacement) + replacement; | |
555 } | |
556 | |
557 while (source.length > 0) { | |
558 if (match = source.match(pattern)) { | |
559 result += source.slice(0, match.index); | |
560 result += String.interpret(replacement(match)); | |
561 source = source.slice(match.index + match[0].length); | |
562 } else { | |
563 result += source, source = ''; | |
564 } | |
565 } | |
566 return result; | |
567 } | |
568 | |
569 function sub(pattern, replacement, count) { | |
570 replacement = prepareReplacement(replacement); | |
571 count = Object.isUndefined(count) ? 1 : count; | |
572 | |
573 return this.gsub(pattern, function(match) { | |
574 if (--count < 0) return match[0]; | |
575 return replacement(match); | |
576 }); | |
577 } | |
578 | |
579 function scan(pattern, iterator) { | |
580 this.gsub(pattern, iterator); | |
581 return String(this); | |
582 } | |
583 | |
584 function truncate(length, truncation) { | |
585 length = length || 30; | |
586 truncation = Object.isUndefined(truncation) ? '...' : truncation; | |
587 return this.length > length ? | |
588 this.slice(0, length - truncation.length) + truncation : String(this); | |
589 } | |
590 | |
591 function strip() { | |
592 return this.replace(/^\s+/, '').replace(/\s+$/, ''); | |
593 } | |
594 | |
595 function stripTags() { | |
596 return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, ''); | |
597 } | |
598 | |
599 function stripScripts() { | |
600 return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); | |
601 } | |
602 | |
603 function extractScripts() { | |
604 var matchAll = new RegExp(Prototype.ScriptFragment, 'img'), | |
605 matchOne = new RegExp(Prototype.ScriptFragment, 'im'); | |
606 return (this.match(matchAll) || []).map(function(scriptTag) { | |
607 return (scriptTag.match(matchOne) || ['', ''])[1]; | |
608 }); | |
609 } | |
610 | |
611 function evalScripts() { | |
612 return this.extractScripts().map(function(script) { return eval(script) }); | |
613 } | |
614 | |
615 function escapeHTML() { | |
616 return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); | |
617 } | |
618 | |
619 function unescapeHTML() { | |
620 return this.stripTags().replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&'); | |
621 } | |
622 | |
623 | |
624 function toQueryParams(separator) { | |
625 var match = this.strip().match(/([^?#]*)(#.*)?$/); | |
626 if (!match) return { }; | |
627 | |
628 return match[1].split(separator || '&').inject({ }, function(hash, pair) { | |
629 if ((pair = pair.split('='))[0]) { | |
630 var key = decodeURIComponent(pair.shift()), | |
631 value = pair.length > 1 ? pair.join('=') : pair[0]; | |
632 | |
633 if (value != undefined) value = decodeURIComponent(value); | |
634 | |
635 if (key in hash) { | |
636 if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; | |
637 hash[key].push(value); | |
638 } | |
639 else hash[key] = value; | |
640 } | |
641 return hash; | |
642 }); | |
643 } | |
644 | |
645 function toArray() { | |
646 return this.split(''); | |
647 } | |
648 | |
649 function succ() { | |
650 return this.slice(0, this.length - 1) + | |
651 String.fromCharCode(this.charCodeAt(this.length - 1) + 1); | |
652 } | |
653 | |
654 function times(count) { | |
655 return count < 1 ? '' : new Array(count + 1).join(this); | |
656 } | |
657 | |
658 function camelize() { | |
659 return this.replace(/-+(.)?/g, function(match, chr) { | |
660 return chr ? chr.toUpperCase() : ''; | |
661 }); | |
662 } | |
663 | |
664 function capitalize() { | |
665 return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); | |
666 } | |
667 | |
668 function underscore() { | |
669 return this.replace(/::/g, '/') | |
670 .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') | |
671 .replace(/([a-z\d])([A-Z])/g, '$1_$2') | |
672 .replace(/-/g, '_') | |
673 .toLowerCase(); | |
674 } | |
675 | |
676 function dasherize() { | |
677 return this.replace(/_/g, '-'); | |
678 } | |
679 | |
680 function inspect(useDoubleQuotes) { | |
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); | |
746 } | |
747 | |
748 return { | |
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, ']') : match[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); | |
813 }); | |
814 } | |
815 }); | |
816 Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; | |
817 | |
818 var $break = { }; | |
819 | |
820 var Enumerable = (function() { | |
821 function each(iterator, context) { | |
822 var index = 0; | |
823 try { | |
824 this._each(function(value) { | |
825 iterator.call(context, value, index++); | |
826 }); | |
827 } catch (e) { | |
828 if (e != $break) throw e; | |
829 } | |
830 return this; | |
831 } | |
832 | |
833 function eachSlice(number, iterator, context) { | |
834 var index = -number, slices = [], array = this.toArray(); | |
835 if (number < 1) return array; | |
836 while ((index += number) < array.length) | |
837 slices.push(array.slice(index, index+number)); | |
838 return slices.collect(iterator, context); | |
839 } | |
840 | |
841 function all(iterator, context) { | |
842 iterator = iterator || Prototype.K; | |
843 var result = true; | |
844 this.each(function(value, index) { | |
845 result = result && !!iterator.call(context, value, index); | |
846 if (!result) throw $break; | |
847 }); | |
848 return result; | |
849 } | |
850 | |
851 function any(iterator, context) { | |
852 iterator = iterator || Prototype.K; | |
853 var result = false; | |
854 this.each(function(value, index) { | |
855 if (result = !!iterator.call(context, value, index)) | |
856 throw $break; | |
857 }); | |
858 return result; | |
859 } | |
860 | |
861 function collect(iterator, context) { | |
862 iterator = iterator || Prototype.K; | |
863 var results = []; | |
864 this.each(function(value, index) { | |
865 results.push(iterator.call(context, value, index)); | |
866 }); | |
867 return results; | |
868 } | |
869 | |
870 function detect(iterator, context) { | |
871 var result; | |
872 this.each(function(value, index) { | |
873 if (iterator.call(context, value, index)) { | |
874 result = value; | |
875 throw $break; | |
876 } | |
877 }); | |
878 return result; | |
879 } | |
880 | |
881 function findAll(iterator, context) { | |
882 var results = []; | |
883 this.each(function(value, index) { | |
884 if (iterator.call(context, value, index)) | |
885 results.push(value); | |
886 }); | |
887 return results; | |
888 } | |
889 | |
890 function grep(filter, iterator, context) { | |
891 iterator = iterator || Prototype.K; | |
892 var results = []; | |
893 | |
894 if (Object.isString(filter)) | |
895 filter = new RegExp(RegExp.escape(filter)); | |
896 | |
897 this.each(function(value, index) { | |
898 if (filter.match(value)) | |
899 results.push(iterator.call(context, value, index)); | |
900 }); | |
901 return results; | |
902 } | |
903 | |
904 function include(object) { | |
905 if (Object.isFunction(this.indexOf)) | |
906 if (this.indexOf(object) != -1) return true; | |
907 | |
908 var found = false; | |
909 this.each(function(value) { | |
910 if (value == object) { | |
911 found = true; | |
912 throw $break; | |
913 } | |
914 }); | |
915 return found; | |
916 } | |
917 | |
918 function inGroupsOf(number, fillWith) { | |
919 fillWith = Object.isUndefined(fillWith) ? null : fillWith; | |
920 return this.eachSlice(number, function(slice) { | |
921 while(slice.length < number) slice.push(fillWith); | |
922 return slice; | |
923 }); | |
924 } | |
925 | |
926 function inject(memo, iterator, context) { | |
927 this.each(function(value, index) { | |
928 memo = iterator.call(context, memo, value, index); | |
929 }); | |
930 return memo; | |
931 } | |
932 | |
933 function invoke(method) { | |
934 var args = $A(arguments).slice(1); | |
935 return this.map(function(value) { | |
936 return value[method].apply(value, args); | |
937 }); | |
938 } | |
939 | |
940 function max(iterator, context) { | |
941 iterator = iterator || Prototype.K; | |
942 var result; | |
943 this.each(function(value, index) { | |
944 value = iterator.call(context, value, index); | |
945 if (result == null || value >= result) | |
946 result = value; | |
947 }); | |
948 return result; | |
949 } | |
950 | |
951 function min(iterator, context) { | |
952 iterator = iterator || Prototype.K; | |
953 var result; | |
954 this.each(function(value, index) { | |
955 value = iterator.call(context, value, index); | |
956 if (result == null || value < result) | |
957 result = value; | |
958 }); | |
959 return result; | |
960 } | |
961 | |
962 function partition(iterator, context) { | |
963 iterator = iterator || Prototype.K; | |
964 var trues = [], falses = []; | |
965 this.each(function(value, index) { | |
966 (iterator.call(context, value, index) ? | |
967 trues : falses).push(value); | |
968 }); | |
969 return [trues, falses]; | |
970 } | |
971 | |
972 function pluck(property) { | |
973 var results = []; | |
974 this.each(function(value) { | |
975 results.push(value[property]); | |
976 }); | |
977 return results; | |
978 } | |
979 | |
980 function reject(iterator, context) { | |
981 var results = []; | |
982 this.each(function(value, index) { | |
983 if (!iterator.call(context, value, index)) | |
984 results.push(value); | |
985 }); | |
986 return results; | |
987 } | |
988 | |
989 function sortBy(iterator, context) { | |
990 return this.map(function(value, index) { | |
991 return { | |
992 value: value, | |
993 criteria: iterator.call(context, value, index) | |
994 }; | |
995 }).sort(function(left, right) { | |
996 var a = left.criteria, b = right.criteria; | |
997 return a < b ? -1 : a > b ? 1 : 0; | |
998 }).pluck('value'); | |
999 } | |
1000 | |
1001 function toArray() { | |
1002 return this.map(); | |
1003 } | |
1004 | |
1005 function zip() { | |
1006 var iterator = Prototype.K, args = $A(arguments); | |
1007 if (Object.isFunction(args.last())) | |
1008 iterator = args.pop(); | |
1009 | |
1010 var collections = [this].concat(args).map($A); | |
1011 return this.map(function(value, index) { | |
1012 return iterator(collections.pluck(index)); | |
1013 }); | |
1014 } | |
1015 | |
1016 function size() { | |
1017 return this.toArray().length; | |
1018 } | |
1019 | |
1020 function inspect() { | |
1021 return '#<Enumerable:' + this.toArray().inspect() + '>'; | |
1022 } | |
1023 | |
1024 | |
1025 | |
1026 | |
1027 | |
1028 | |
1029 | |
1030 | |
1031 | |
1032 return { | |
1033 each: each, | |
1034 eachSlice: eachSlice, | |
1035 all: all, | |
1036 every: all, | |
1037 any: any, | |
1038 some: any, | |
1039 collect: collect, | |
1040 map: collect, | |
1041 detect: detect, | |
1042 findAll: findAll, | |
1043 select: findAll, | |
1044 filter: findAll, | |
1045 grep: grep, | |
1046 include: include, | |
1047 member: include, | |
1048 inGroupsOf: inGroupsOf, | |
1049 inject: inject, | |
1050 invoke: invoke, | |
1051 max: max, | |
1052 min: min, | |
1053 partition: partition, | |
1054 pluck: pluck, | |
1055 reject: reject, | |
1056 sortBy: sortBy, | |
1057 toArray: toArray, | |
1058 entries: toArray, | |
1059 zip: zip, | |
1060 size: size, | |
1061 inspect: inspect, | |
1062 find: detect | |
1063 }; | |
1064 })(); | |
1065 | |
1066 function $A(iterable) { | |
1067 if (!iterable) return []; | |
1068 if ('toArray' in Object(iterable)) return iterable.toArray(); | |
1069 var length = iterable.length || 0, results = new Array(length); | |
1070 while (length--) results[length] = iterable[length]; | |
1071 return results; | |
1072 } | |
1073 | |
1074 | |
1075 function $w(string) { | |
1076 if (!Object.isString(string)) return []; | |
1077 string = string.strip(); | |
1078 return string ? string.split(/\s+/) : []; | |
1079 } | |
1080 | |
1081 Array.from = $A; | |
1082 | |
1083 | |
1084 (function() { | |
1085 var arrayProto = Array.prototype, | |
1086 slice = arrayProto.slice, | |
1087 _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available | |
1088 | |
1089 function each(iterator, context) { | |
1090 for (var i = 0, length = this.length >>> 0; i < length; i++) { | |
1091 if (i in this) iterator.call(context, this[i], i, this); | |
1092 } | |
1093 } | |
1094 if (!_each) _each = each; | |
1095 | |
1096 function clear() { | |
1097 this.length = 0; | |
1098 return this; | |
1099 } | |
1100 | |
1101 function first() { | |
1102 return this[0]; | |
1103 } | |
1104 | |
1105 function last() { | |
1106 return this[this.length - 1]; | |
1107 } | |
1108 | |
1109 function compact() { | |
1110 return this.select(function(value) { | |
1111 return value != null; | |
1112 }); | |
1113 } | |
1114 | |
1115 function flatten() { | |
1116 return this.inject([], function(array, value) { | |
1117 if (Object.isArray(value)) | |
1118 return array.concat(value.flatten()); | |
1119 array.push(value); | |
1120 return array; | |
1121 }); | |
1122 } | |
1123 | |
1124 function without() { | |
1125 var values = slice.call(arguments, 0); | |
1126 return this.select(function(value) { | |
1127 return !values.include(value); | |
1128 }); | |
1129 } | |
1130 | |
1131 function reverse(inline) { | |
1132 return (inline === false ? this.toArray() : this)._reverse(); | |
1133 } | |
1134 | |
1135 function uniq(sorted) { | |
1136 return this.inject([], function(array, value, index) { | |
1137 if (0 == index || (sorted ? array.last() != value : !array.include(value))) | |
1138 array.push(value); | |
1139 return array; | |
1140 }); | |
1141 } | |
1142 | |
1143 function intersect(array) { | |
1144 return this.uniq().findAll(function(item) { | |
1145 return array.detect(function(value) { return item === value }); | |
1146 }); | |
1147 } | |
1148 | |
1149 | |
1150 function clone() { | |
1151 return slice.call(this, 0); | |
1152 } | |
1153 | |
1154 function size() { | |
1155 return this.length; | |
1156 } | |
1157 | |
1158 function inspect() { | |
1159 return '[' + this.map(Object.inspect).join(', ') + ']'; | |
1160 } | |
1161 | |
1162 function indexOf(item, i) { | |
1163 i || (i = 0); | |
1164 var length = this.length; | |
1165 if (i < 0) i = length + i; | |
1166 for (; i < length; i++) | |
1167 if (this[i] === item) return i; | |
1168 return -1; | |
1169 } | |
1170 | |
1171 function lastIndexOf(item, i) { | |
1172 i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; | |
1173 var n = this.slice(0, i).reverse().indexOf(item); | |
1174 return (n < 0) ? n : i - n - 1; | |
1175 } | |
1176 | |
1177 function concat() { | |
1178 var array = slice.call(this, 0), item; | |
1179 for (var i = 0, length = arguments.length; i < length; i++) { | |
1180 item = arguments[i]; | |
1181 if (Object.isArray(item) && !('callee' in item)) { | |
1182 for (var j = 0, arrayLength = item.length; j < arrayLength; j++) | |
1183 array.push(item[j]); | |
1184 } else { | |
1185 array.push(item); | |
1186 } | |
1187 } | |
1188 return array; | |
1189 } | |
1190 | |
1191 Object.extend(arrayProto, Enumerable); | |
1192 | |
1193 if (!arrayProto._reverse) | |
1194 arrayProto._reverse = arrayProto.reverse; | |
1195 | |
1196 Object.extend(arrayProto, { | |
1197 _each: _each, | |
1198 clear: clear, | |
1199 first: first, | |
1200 last: last, | |
1201 compact: compact, | |
1202 flatten: flatten, | |
1203 without: without, | |
1204 reverse: reverse, | |
1205 uniq: uniq, | |
1206 intersect: intersect, | |
1207 clone: clone, | |
1208 toArray: clone, | |
1209 size: size, | |
1210 inspect: inspect | |
1211 }); | |
1212 | |
1213 var CONCAT_ARGUMENTS_BUGGY = (function() { | |
1214 return [].concat(arguments)[0][0] !== 1; | |
1215 })(1,2) | |
1216 | |
1217 if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat; | |
1218 | |
1219 if (!arrayProto.indexOf) arrayProto.indexOf = indexOf; | |
1220 if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf; | |
1221 })(); | |
1222 function $H(object) { | |
1223 return new Hash(object); | |
1224 }; | |
1225 | |
1226 var Hash = Class.create(Enumerable, (function() { | |
1227 function initialize(object) { | |
1228 this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); | |
1229 } | |
1230 | |
1231 | |
1232 function _each(iterator) { | |
1233 for (var key in this._object) { | |
1234 var value = this._object[key], pair = [key, value]; | |
1235 pair.key = key; | |
1236 pair.value = value; | |
1237 iterator(pair); | |
1238 } | |
1239 } | |
1240 | |
1241 function set(key, value) { | |
1242 return this._object[key] = value; | |
1243 } | |
1244 | |
1245 function get(key) { | |
1246 if (this._object[key] !== Object.prototype[key]) | |
1247 return this._object[key]; | |
1248 } | |
1249 | |
1250 function unset(key) { | |
1251 var value = this._object[key]; | |
1252 delete this._object[key]; | |
1253 return value; | |
1254 } | |
1255 | |
1256 function toObject() { | |
1257 return Object.clone(this._object); | |
1258 } | |
1259 | |
1260 | |
1261 | |
1262 function keys() { | |
1263 return this.pluck('key'); | |
1264 } | |
1265 | |
1266 function values() { | |
1267 return this.pluck('value'); | |
1268 } | |
1269 | |
1270 function index(value) { | |
1271 var match = this.detect(function(pair) { | |
1272 return pair.value === value; | |
1273 }); | |
1274 return match && match.key; | |
1275 } | |
1276 | |
1277 function merge(object) { | |
1278 return this.clone().update(object); | |
1279 } | |
1280 | |
1281 function update(object) { | |
1282 return new Hash(object).inject(this, function(result, pair) { | |
1283 result.set(pair.key, pair.value); | |
1284 return result; | |
1285 }); | |
1286 } | |
1287 | |
1288 function toQueryPair(key, value) { | |
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 | |
1356 function toPaddedString(length, radix) { | |
1357 var string = this.toString(radix || 10); | |
1358 return '0'.times(length - string.length) + string; | |
1359 } | |
1360 | |
1361 function abs() { | |
1362 return Math.abs(this); | |
1363 } | |
1364 | |
1365 function round() { | |
1366 return Math.round(this); | |
1367 } | |
1368 | |
1369 function ceil() { | |
1370 return Math.ceil(this); | |
1371 } | |
1372 | |
1373 function floor() { | |
1374 return Math.floor(this); | |
1375 } | |
1376 | |
1377 return { | |
1378 toColorPart: toColorPart, | |
1379 succ: succ, | |
1380 times: times, | |
1381 toPaddedString: toPaddedString, | |
1382 abs: abs, | |
1383 round: round, | |
1384 ceil: ceil, | |
1385 floor: floor | |
1386 }; | |
1387 })()); | |
1388 | |
1389 function $R(start, end, exclusive) { | |
1390 return new ObjectRange(start, end, exclusive); | |
1391 } | |
1392 | |
1393 var ObjectRange = Class.create(Enumerable, (function() { | |
1394 function initialize(start, end, exclusive) { | |
1395 this.start = start; | |
1396 this.end = end; | |
1397 this.exclusive = exclusive; | |
1398 } | |
1399 | |
1400 function _each(iterator) { | |
1401 var value = this.start; | |
1402 while (this.include(value)) { | |
1403 iterator(value); | |
1404 value = value.succ(); | |
1405 } | |
1406 } | |
1407 | |
1408 function include(value) { | |
1409 if (value < this.start) | |
1410 return false; | |
1411 if (this.exclusive) | |
1412 return value < this.end; | |
1413 return value <= this.end; | |
1414 } | |
1415 | |
1416 return { | |
1417 initialize: initialize, | |
1418 _each: _each, | |
1419 include: include | |
1420 }; | |
1421 })()); | |
1422 | |
1423 | |
1424 | |
1425 var Ajax = { | |
1426 getTransport: function() { | |
1427 return Try.these( | |
1428 function() {return new XMLHttpRequest()}, | |
1429 function() {return new ActiveXObject('Msxml2.XMLHTTP')}, | |
1430 function() {return new ActiveXObject('Microsoft.XMLHTTP')} | |
1431 ) || false; | |
1432 }, | |
1433 | |
1434 activeRequestCount: 0 | |
1435 }; | |
1436 | |
1437 Ajax.Responders = { | |
1438 responders: [], | |
1439 | |
1440 _each: function(iterator) { | |
1441 this.responders._each(iterator); | |
1442 }, | |
1443 | |
1444 register: function(responder) { | |
1445 if (!this.include(responder)) | |
1446 this.responders.push(responder); | |
1447 }, | |
1448 | |
1449 unregister: function(responder) { | |
1450 this.responders = this.responders.without(responder); | |
1451 }, | |
1452 | |
1453 dispatch: function(callback, request, transport, json) { | |
1454 this.each(function(responder) { | |
1455 if (Object.isFunction(responder[callback])) { | |
1456 try { | |
1457 responder[callback].apply(responder, [request, transport, json]); | |
1458 } catch (e) { } | |
1459 } | |
1460 }); | |
1461 } | |
1462 }; | |
1463 | |
1464 Object.extend(Ajax.Responders, Enumerable); | |
1465 | |
1466 Ajax.Responders.register({ | |
1467 onCreate: function() { Ajax.activeRequestCount++ }, | |
1468 onComplete: function() { Ajax.activeRequestCount-- } | |
1469 }); | |
1470 Ajax.Base = Class.create({ | |
1471 initialize: function(options) { | |
1472 this.options = { | |
1473 method: 'post', | |
1474 asynchronous: true, | |
1475 contentType: 'application/x-www-form-urlencoded', | |
1476 encoding: 'UTF-8', | |
1477 parameters: '', | |
1478 evalJSON: true, | |
1479 evalJS: true | |
1480 }; | |
1481 Object.extend(this.options, options || { }); | |
1482 | |
1483 this.options.method = this.options.method.toLowerCase(); | |
1484 | |
1485 if (Object.isHash(this.options.parameters)) | |
1486 this.options.parameters = this.options.parameters.toObject(); | |
1487 } | |
1488 }); | |
1489 Ajax.Request = Class.create(Ajax.Base, { | |
1490 _complete: false, | |
1491 | |
1492 initialize: function($super, url, options) { | |
1493 $super(options); | |
1494 this.transport = Ajax.getTransport(); | |
1495 this.request(url); | |
1496 }, | |
1497 | |
1498 request: function(url) { | |
1499 this.url = url; | |
1500 this.method = this.options.method; | |
1501 var params = Object.isString(this.options.parameters) ? | |
1502 this.options.parameters : | |
1503 Object.toQueryString(this.options.parameters); | |
1504 | |
1505 if (!['get', 'post'].include(this.method)) { | |
1506 params += (params ? '&' : '') + "_method=" + this.method; | |
1507 this.method = 'post'; | |
1508 } | |
1509 | |
1510 if (params && this.method === 'get') { | |
1511 this.url += (this.url.include('?') ? '&' : '?') + params; | |
1512 } | |
1513 | |
1514 this.parameters = params.toQueryParams(); | |
1515 | |
1516 try { | |
1517 var response = new Ajax.Response(this); | |
1518 if (this.options.onCreate) this.options.onCreate(response); | |
1519 Ajax.Responders.dispatch('onCreate', this, response); | |
1520 | |
1521 this.transport.open(this.method.toUpperCase(), this.url, | |
1522 this.options.asynchronous); | |
1523 | |
1524 if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1); | |
1525 | |
1526 this.transport.onreadystatechange = this.onStateChange.bind(this); | |
1527 this.setRequestHeaders(); | |
1528 | |
1529 this.body = this.method == 'post' ? (this.options.postBody || params) : null; | |
1530 this.transport.send(this.body); | |
1531 | |
1532 /* Force Firefox to handle ready state 4 for synchronous requests */ | |
1533 if (!this.options.asynchronous && this.transport.overrideMimeType) | |
1534 this.onStateChange(); | |
1535 | |
1536 } | |
1537 catch (e) { | |
1538 this.dispatchException(e); | |
1539 } | |
1540 }, | |
1541 | |
1542 onStateChange: function() { | |
1543 var readyState = this.transport.readyState; | |
1544 if (readyState > 1 && !((readyState == 4) && this._complete)) | |
1545 this.respondToReadyState(this.transport.readyState); | |
1546 }, | |
1547 | |
1548 setRequestHeaders: function() { | |
1549 var headers = { | |
1550 'X-Requested-With': 'XMLHttpRequest', | |
1551 'X-Prototype-Version': Prototype.Version, | |
1552 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' | |
1553 }; | |
1554 | |
1555 if (this.method == 'post') { | |
1556 headers['Content-type'] = this.options.contentType + | |
1557 (this.options.encoding ? '; charset=' + this.options.encoding : ''); | |
1558 | |
1559 /* Force "Connection: close" for older Mozilla browsers to work | |
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.headerJSON); | |
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 | |
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 || ''; | |
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(); | |
1762 | |
1763 if (receiver = $(receiver)) { | |
1764 if (options.insertion) { | |
1765 if (Object.isString(options.insertion)) { | |
1766 var insertion = { }; insertion[options.insertion] = responseText; | |
1767 receiver.insert(insertion); | |
1768 } | |
1769 else options.insertion(receiver, responseText); | |
1770 } | |
1771 else receiver.update(responseText); | |
1772 } | |
1773 } | |
1774 }); | |
1775 | |
1776 Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { | |
1777 initialize: function($super, container, url, options) { | |
1778 $super(options); | |
1779 this.onComplete = this.options.onComplete; | |
1780 | |
1781 this.frequency = (this.options.frequency || 2); | |
1782 this.decay = (this.options.decay || 1); | |
1783 | |
1784 this.updater = { }; | |
1785 this.container = container; | |
1786 this.url = url; | |
1787 | |
1788 this.start(); | |
1789 }, | |
1790 | |
1791 start: function() { | |
1792 this.options.onComplete = this.updateComplete.bind(this); | |
1793 this.onTimerEvent(); | |
1794 }, | |
1795 | |
1796 stop: function() { | |
1797 this.updater.options.onComplete = undefined; | |
1798 clearTimeout(this.timer); | |
1799 (this.onComplete || Prototype.emptyFunction).apply(this, arguments); | |
1800 }, | |
1801 | |
1802 updateComplete: function(response) { | |
1803 if (this.options.decay) { | |
1804 this.decay = (response.responseText == this.lastText ? | |
1805 this.decay * this.options.decay : 1); | |
1806 | |
1807 this.lastText = response.responseText; | |
1808 } | |
1809 this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency); | |
1810 }, | |
1811 | |
1812 onTimerEvent: function() { | |
1813 this.updater = new Ajax.Updater(this.container, this.url, this.options); | |
1814 } | |
1815 }); | |
1816 | |
1817 | |
1818 function $(element) { | |
1819 if (arguments.length > 1) { | |
1820 for (var i = 0, elements = [], length = arguments.length; i < length; i++) | |
1821 elements.push($(arguments[i])); | |
1822 return elements; | |
1823 } | |
1824 if (Object.isString(element)) | |
1825 element = document.getElementById(element); | |
1826 return Element.extend(element); | |
1827 } | |
1828 | |
1829 if (Prototype.BrowserFeatures.XPath) { | |
1830 document._getElementsByXPath = function(expression, parentElement) { | |
1831 var results = []; | |
1832 var query = document.evaluate(expression, $(parentElement) || document, | |
1833 null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); | |
1834 for (var i = 0, length = query.snapshotLength; i < length; i++) | |
1835 results.push(Element.extend(query.snapshotItem(i))); | |
1836 return results; | |
1837 }; | |
1838 } | |
1839 | |
1840 /*--------------------------------------------------------------------------*/ | |
1841 | |
1842 if (!Node) var Node = { }; | |
1843 | |
1844 if (!Node.ELEMENT_NODE) { | |
1845 Object.extend(Node, { | |
1846 ELEMENT_NODE: 1, | |
1847 ATTRIBUTE_NODE: 2, | |
1848 TEXT_NODE: 3, | |
1849 CDATA_SECTION_NODE: 4, | |
1850 ENTITY_REFERENCE_NODE: 5, | |
1851 ENTITY_NODE: 6, | |
1852 PROCESSING_INSTRUCTION_NODE: 7, | |
1853 COMMENT_NODE: 8, | |
1854 DOCUMENT_NODE: 9, | |
1855 DOCUMENT_TYPE_NODE: 10, | |
1856 DOCUMENT_FRAGMENT_NODE: 11, | |
1857 NOTATION_NODE: 12 | |
1858 }); | |
1859 } | |
1860 | |
1861 | |
1862 | |
1863 (function(global) { | |
1864 function shouldUseCache(tagName, attributes) { | |
1865 if (tagName === 'select') return false; | |
1866 if ('type' in attributes) return false; | |
1867 return true; | |
1868 } | |
1869 | |
1870 var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){ | |
1871 try { | |
1872 var el = document.createElement('<input name="x">'); | |
1873 return el.tagName.toLowerCase() === 'input' && el.name === 'x'; | |
1874 } | |
1875 catch(err) { | |
1876 return false; | |
1877 } | |
1878 })(); | |
1879 | |
1880 var element = global.Element; | |
1881 | |
1882 global.Element = function(tagName, attributes) { | |
1883 attributes = attributes || { }; | |
1884 tagName = tagName.toLowerCase(); | |
1885 var cache = Element.cache; | |
1886 | |
1887 if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) { | |
1888 tagName = '<' + tagName + ' name="' + attributes.name + '">'; | |
1889 delete attributes.name; | |
1890 return Element.writeAttribute(document.createElement(tagName), attributes); | |
1891 } | |
1892 | |
1893 if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName)); | |
1894 | |
1895 var node = shouldUseCache(tagName, attributes) ? | |
1896 cache[tagName].cloneNode(false) : document.createElement(tagName); | |
1897 | |
1898 return Element.writeAttribute(node, attributes); | |
1899 }; | |
1900 | |
1901 Object.extend(global.Element, element || { }); | |
1902 if (element) global.Element.prototype = element.prototype; | |
1903 | |
1904 })(this); | |
1905 | |
1906 Element.idCounter = 1; | |
1907 Element.cache = { }; | |
1908 | |
1909 Element._purgeElement = function(element) { | |
1910 var uid = element._prototypeUID; | |
1911 if (uid) { | |
1912 Element.stopObserving(element); | |
1913 element._prototypeUID = void 0; | |
1914 delete Element.Storage[uid]; | |
1915 } | |
1916 } | |
1917 | |
1918 Element.Methods = { | |
1919 visible: function(element) { | |
1920 return $(element).style.display != 'none'; | |
1921 }, | |
1922 | |
1923 toggle: function(element) { | |
1924 element = $(element); | |
1925 Element[Element.visible(element) ? 'hide' : 'show'](element); | |
1926 return element; | |
1927 }, | |
1928 | |
1929 hide: function(element) { | |
1930 element = $(element); | |
1931 element.style.display = 'none'; | |
1932 return element; | |
1933 }, | |
1934 | |
1935 show: function(element) { | |
1936 element = $(element); | |
1937 element.style.display = ''; | |
1938 return element; | |
1939 }, | |
1940 | |
1941 remove: function(element) { | |
1942 element = $(element); | |
1943 element.parentNode.removeChild(element); | |
1944 return element; | |
1945 }, | |
1946 | |
1947 update: (function(){ | |
1948 | |
1949 var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){ | |
1950 var el = document.createElement("select"), | |
1951 isBuggy = true; | |
1952 el.innerHTML = "<option value=\"test\">test</option>"; | |
1953 if (el.options && el.options[0]) { | |
1954 isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION"; | |
1955 } | |
1956 el = null; | |
1957 return isBuggy; | |
1958 })(); | |
1959 | |
1960 var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){ | |
1961 try { | |
1962 var el = document.createElement("table"); | |
1963 if (el && el.tBodies) { | |
1964 el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>"; | |
1965 var isBuggy = typeof el.tBodies[0] == "undefined"; | |
1966 el = null; | |
1967 return isBuggy; | |
1968 } | |
1969 } catch (e) { | |
1970 return true; | |
1971 } | |
1972 })(); | |
1973 | |
1974 var LINK_ELEMENT_INNERHTML_BUGGY = (function() { | |
1975 try { | |
1976 var el = document.createElement('div'); | |
1977 el.innerHTML = "<link>"; | |
1978 var isBuggy = (el.childNodes.length === 0); | |
1979 el = null; | |
1980 return isBuggy; | |
1981 } catch(e) { | |
1982 return true; | |
1983 } | |
1984 })(); | |
1985 | |
1986 var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY || | |
1987 TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY; | |
1988 | |
1989 var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () { | |
1990 var s = document.createElement("script"), | |
1991 isBuggy = false; | |
1992 try { | |
1993 s.appendChild(document.createTextNode("")); | |
1994 isBuggy = !s.firstChild || | |
1995 s.firstChild && s.firstChild.nodeType !== 3; | |
1996 } catch (e) { | |
1997 isBuggy = true; | |
1998 } | |
1999 s = null; | |
2000 return isBuggy; | |
2001 })(); | |
2002 | |
2003 | |
2004 function update(element, content) { | |
2005 element = $(element); | |
2006 var purgeElement = Element._purgeElement; | |
2007 | |
2008 var descendants = element.getElementsByTagName('*'), | |
2009 i = descendants.length; | |
2010 while (i--) purgeElement(descendants[i]); | |
2011 | |
2012 if (content && content.toElement) | |
2013 content = content.toElement(); | |
2014 | |
2015 if (Object.isElement(content)) | |
2016 return element.update().insert(content); | |
2017 | |
2018 content = Object.toHTML(content); | |
2019 | |
2020 var tagName = element.tagName.toUpperCase(); | |
2021 | |
2022 if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) { | |
2023 element.text = content; | |
2024 return element; | |
2025 } | |
2026 | |
2027 if (ANY_INNERHTML_BUGGY) { | |
2028 if (tagName in Element._insertionTranslations.tags) { | |
2029 while (element.firstChild) { | |
2030 element.removeChild(element.firstChild); | |
2031 } | |
2032 Element._getContentFromAnonymousElement(tagName, content.stripScripts()) | |
2033 .each(function(node) { | |
2034 element.appendChild(node) | |
2035 }); | |
2036 } else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf('<link') > -1) { | |
2037 while (element.firstChild) { | |
2038 element.removeChild(element.firstChild); | |
2039 } | |
2040 var nodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts(), 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 || insertions.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.stripScripts()); | |
2098 | |
2099 if (position == 'top' || position == 'after') childNodes.reverse(); | |
2100 childNodes.each(insert.curry(element)); | |
2101 | |
2102 content.evalScripts.bind(content).defer(); | |
2103 } | |
2104 | |
2105 return element; | |
2106 }, | |
2107 | |
2108 wrap: function(element, wrapper, attributes) { | |
2109 element = $(element); | |
2110 if (Object.isElement(wrapper)) | |
2111 $(wrapper).writeAttribute(attributes || { }); | |
2112 else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes); | |
2113 else wrapper = new Element('div', wrapper); | |
2114 if (element.parentNode) | |
2115 element.parentNode.replaceChild(wrapper, element); | |
2116 wrapper.appendChild(element); | |
2117 return wrapper; | |
2118 }, | |
2119 | |
2120 inspect: function(element) { | |
2121 element = $(element); | |
2122 var result = '<' + element.tagName.toLowerCase(); | |
2123 $H({'id': 'id', 'className': 'class'}).each(function(pair) { | |
2124 var property = pair.first(), | |
2125 attribute = pair.last(), | |
2126 value = (element[property] || '').toString(); | |
2127 if (value) result += ' ' + attribute + '=' + value.inspect(true); | |
2128 }); | |
2129 return result + '>'; | |
2130 }, | |
2131 | |
2132 recursivelyCollect: function(element, property, maximumLength) { | |
2133 element = $(element); | |
2134 maximumLength = maximumLength || -1; | |
2135 var elements = []; | |
2136 | |
2137 while (element = element[property]) { | |
2138 if (element.nodeType == 1) | |
2139 elements.push(Element.extend(element)); | |
2140 if (elements.length == maximumLength) | |
2141 break; | |
2142 } | |
2143 | |
2144 return elements; | |
2145 }, | |
2146 | |
2147 ancestors: function(element) { | |
2148 return Element.recursivelyCollect(element, 'parentNode'); | |
2149 }, | |
2150 | |
2151 descendants: function(element) { | |
2152 return Element.select(element, "*"); | |
2153 }, | |
2154 | |
2155 firstDescendant: function(element) { | |
2156 element = $(element).firstChild; | |
2157 while (element && element.nodeType != 1) element = element.nextSibling; | |
2158 return $(element); | |
2159 }, | |
2160 | |
2161 immediateDescendants: function(element) { | |
2162 var results = [], child = $(element).firstChild; | |
2163 while (child) { | |
2164 if (child.nodeType === 1) { | |
2165 results.push(Element.extend(child)); | |
2166 } | |
2167 child = child.nextSibling; | |
2168 } | |
2169 return results; | |
2170 }, | |
2171 | |
2172 previousSiblings: function(element, maximumLength) { | |
2173 return Element.recursivelyCollect(element, 'previousSibling'); | |
2174 }, | |
2175 | |
2176 nextSiblings: function(element) { | |
2177 return Element.recursivelyCollect(element, 'nextSibling'); | |
2178 }, | |
2179 | |
2180 siblings: function(element) { | |
2181 element = $(element); | |
2182 return Element.previousSiblings(element).reverse() | |
2183 .concat(Element.nextSiblings(element)); | |
2184 }, | |
2185 | |
2186 match: function(element, selector) { | |
2187 element = $(element); | |
2188 if (Object.isString(selector)) | |
2189 return Prototype.Selector.match(element, selector); | |
2190 return selector.match(element); | |
2191 }, | |
2192 | |
2193 up: function(element, expression, index) { | |
2194 element = $(element); | |
2195 if (arguments.length == 1) return $(element.parentNode); | |
2196 var ancestors = Element.ancestors(element); | |
2197 return Object.isNumber(expression) ? ancestors[expression] : | |
2198 Prototype.Selector.find(ancestors, expression, index); | |
2199 }, | |
2200 | |
2201 down: function(element, expression, index) { | |
2202 element = $(element); | |
2203 if (arguments.length == 1) return Element.firstDescendant(element); | |
2204 return Object.isNumber(expression) ? Element.descendants(element)[expression] : | |
2205 Element.select(element, expression)[index || 0]; | |
2206 }, | |
2207 | |
2208 previous: function(element, expression, index) { | |
2209 element = $(element); | |
2210 if (Object.isNumber(expression)) index = expression, expression = false; | |
2211 if (!Object.isNumber(index)) index = 0; | |
2212 | |
2213 if (expression) { | |
2214 return Prototype.Selector.find(element.previousSiblings(), expression, index); | |
2215 } else { | |
2216 return element.recursivelyCollect("previousSibling", index + 1)[index]; | |
2217 } | |
2218 }, | |
2219 | |
2220 next: function(element, expression, index) { | |
2221 element = $(element); | |
2222 if (Object.isNumber(expression)) index = expression, expression = false; | |
2223 if (!Object.isNumber(index)) index = 0; | |
2224 | |
2225 if (expression) { | |
2226 return Prototype.Selector.find(element.nextSiblings(), expression, index); | |
2227 } else { | |
2228 var maximumLength = Object.isNumber(index) ? index + 1 : 1; | |
2229 return element.recursivelyCollect("nextSibling", index + 1)[index]; | |
2230 } | |
2231 }, | |
2232 | |
2233 | |
2234 select: function(element) { | |
2235 element = $(element); | |
2236 var expressions = Array.prototype.slice.call(arguments, 1).join(', '); | |
2237 return Prototype.Selector.select(expressions, element); | |
2238 }, | |
2239 | |
2240 adjacent: function(element) { | |
2241 element = $(element); | |
2242 var expressions = Array.prototype.slice.call(arguments, 1).join(', '); | |
2243 return Prototype.Selector.select(expressions, element.parentNode).without(element); | |
2244 }, | |
2245 | |
2246 identify: function(element) { | |
2247 element = $(element); | |
2248 var id = Element.readAttribute(element, 'id'); | |
2249 if (id) return id; | |
2250 do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id)); | |
2251 Element.writeAttribute(element, 'id', id); | |
2252 return id; | |
2253 }, | |
2254 | |
2255 readAttribute: function(element, name) { | |
2256 element = $(element); | |
2257 if (Prototype.Browser.IE) { | |
2258 var t = Element._attributeTranslations.read; | |
2259 if (t.values[name]) return t.values[name](element, name); | |
2260 if (t.names[name]) name = t.names[name]; | |
2261 if (name.include(':')) { | |
2262 return (!element.attributes || !element.attributes[name]) ? null : | |
2263 element.attributes[name].value; | |
2264 } | |
2265 } | |
2266 return element.getAttribute(name); | |
2267 }, | |
2268 | |
2269 writeAttribute: function(element, name, value) { | |
2270 element = $(element); | |
2271 var attributes = { }, t = Element._attributeTranslations.write; | |
2272 | |
2273 if (typeof name == 'object') attributes = name; | |
2274 else attributes[name] = Object.isUndefined(value) ? true : value; | |
2275 | |
2276 for (var attr in attributes) { | |
2277 name = t.names[attr] || attr; | |
2278 value = attributes[attr]; | |
2279 if (t.values[attr]) name = t.values[attr](element, value); | |
2280 if (value === false || value === null) | |
2281 element.removeAttribute(name); | |
2282 else if (value === true) | |
2283 element.setAttribute(name, name); | |
2284 else element.setAttribute(name, value); | |
2285 } | |
2286 return element; | |
2287 }, | |
2288 | |
2289 getHeight: function(element) { | |
2290 return Element.getDimensions(element).height; | |
2291 }, | |
2292 | |
2293 getWidth: function(element) { | |
2294 return Element.getDimensions(element).width; | |
2295 }, | |
2296 | |
2297 classNames: function(element) { | |
2298 return new Element.ClassNames(element); | |
2299 }, | |
2300 | |
2301 hasClassName: function(element, className) { | |
2302 if (!(element = $(element))) return; | |
2303 var elementClassName = element.className; | |
2304 return (elementClassName.length > 0 && (elementClassName == className || | |
2305 new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName))); | |
2306 }, | |
2307 | |
2308 addClassName: function(element, className) { | |
2309 if (!(element = $(element))) return; | |
2310 if (!Element.hasClassName(element, className)) | |
2311 element.className += (element.className ? ' ' : '') + className; | |
2312 return element; | |
2313 }, | |
2314 | |
2315 removeClassName: function(element, className) { | |
2316 if (!(element = $(element))) return; | |
2317 element.className = element.className.replace( | |
2318 new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); | |
2319 return element; | |
2320 }, | |
2321 | |
2322 toggleClassName: function(element, className) { | |
2323 if (!(element = $(element))) return; | |
2324 return Element[Element.hasClassName(element, className) ? | |
2325 'removeClassName' : 'addClassName'](element, className); | |
2326 }, | |
2327 | |
2328 cleanWhitespace: function(element) { | |
2329 element = $(element); | |
2330 var node = element.firstChild; | |
2331 while (node) { | |
2332 var nextNode = node.nextSibling; | |
2333 if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) | |
2334 element.removeChild(node); | |
2335 node = nextNode; | |
2336 } | |
2337 return element; | |
2338 }, | |
2339 | |
2340 empty: function(element) { | |
2341 return $(element).innerHTML.blank(); | |
2342 }, | |
2343 | |
2344 descendantOf: function(element, ancestor) { | |
2345 element = $(element), ancestor = $(ancestor); | |
2346 | |
2347 if (element.compareDocumentPosition) | |
2348 return (element.compareDocumentPosition(ancestor) & 8) === 8; | |
2349 | |
2350 if (ancestor.contains) | |
2351 return ancestor.contains(element) && ancestor !== element; | |
2352 | |
2353 while (element = element.parentNode) | |
2354 if (element == ancestor) return true; | |
2355 | |
2356 return false; | |
2357 }, | |
2358 | |
2359 scrollTo: function(element) { | |
2360 element = $(element); | |
2361 var pos = Element.cumulativeOffset(element); | |
2362 window.scrollTo(pos[0], pos[1]); | |
2363 return element; | |
2364 }, | |
2365 | |
2366 getStyle: function(element, style) { | |
2367 element = $(element); | |
2368 style = style == 'float' ? 'cssFloat' : style.camelize(); | |
2369 var value = element.style[style]; | |
2370 if (!value || value == 'auto') { | |
2371 var css = document.defaultView.getComputedStyle(element, null); | |
2372 value = css ? css[style] : null; | |
2373 } | |
2374 if (style == 'opacity') return value ? parseFloat(value) : 1.0; | |
2375 return value == 'auto' ? null : value; | |
2376 }, | |
2377 | |
2378 getOpacity: function(element) { | |
2379 return $(element).getStyle('opacity'); | |
2380 }, | |
2381 | |
2382 setStyle: function(element, styles) { | |
2383 element = $(element); | |
2384 var elementStyle = element.style, match; | |
2385 if (Object.isString(styles)) { | |
2386 element.style.cssText += ';' + styles; | |
2387 return styles.include('opacity') ? | |
2388 element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element; | |
2389 } | |
2390 for (var property in styles) | |
2391 if (property == 'opacity') element.setOpacity(styles[property]); | |
2392 else | |
2393 elementStyle[(property == 'float' || property == 'cssFloat') ? | |
2394 (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') : | |
2395 property] = styles[property]; | |
2396 | |
2397 return element; | |
2398 }, | |
2399 | |
2400 setOpacity: function(element, value) { | |
2401 element = $(element); | |
2402 element.style.opacity = (value == 1 || value === '') ? '' : | |
2403 (value < 0.00001) ? 0 : value; | |
2404 return element; | |
2405 }, | |
2406 | |
2407 makePositioned: function(element) { | |
2408 element = $(element); | |
2409 var pos = Element.getStyle(element, 'position'); | |
2410 if (pos == 'static' || !pos) { | |
2411 element._madePositioned = true; | |
2412 element.style.position = 'relative'; | |
2413 if (Prototype.Browser.Opera) { | |
2414 element.style.top = 0; | |
2415 element.style.left = 0; | |
2416 } | |
2417 } | |
2418 return element; | |
2419 }, | |
2420 | |
2421 undoPositioned: function(element) { | |
2422 element = $(element); | |
2423 if (element._madePositioned) { | |
2424 element._madePositioned = undefined; | |
2425 element.style.position = | |
2426 element.style.top = | |
2427 element.style.left = | |
2428 element.style.bottom = | |
2429 element.style.right = ''; | |
2430 } | |
2431 return element; | |
2432 }, | |
2433 | |
2434 makeClipping: function(element) { | |
2435 element = $(element); | |
2436 if (element._overflow) return element; | |
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.offsetLeft) + 'px'; | |
2477 if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + '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) { | |
2501 Element.Methods.getStyle = Element.Methods.getStyle.wrap( | |
2502 function(proceed, element, style) { | |
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.camelize(); | |
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')) | |
2567 element.style.zoom = 1; | |
2568 | |
2569 var filter = element.getStyle('filter'), style = element.style; | |
2570 if (value == 1 || value === '') { | |
2571 (filter = stripAlpha(filter)) ? | |
2572 style.filter = filter : style.removeAttribute('filter'); | |
2573 return element; | |
2574 } else if (value < 0.00001) value = 0; | |
2575 style.filter = stripAlpha(filter) + | |
2576 'alpha(opacity=' + (value * 100) + ')'; | |
2577 return element; | |
2578 }; | |
2579 | |
2580 Element._attributeTranslations = (function(){ | |
2581 | |
2582 var classProp = 'className', | |
2583 forProp = 'for', | |
2584 el = document.createElement('div'); | |
2585 | |
2586 el.setAttribute(classProp, 'x'); | |
2587 | |
2588 if (el.className !== 'x') { | |
2589 el.setAttribute('class', 'x'); | |
2590 if (el.className === 'x') { | |
2591 classProp = 'class'; | |
2592 } | |
2593 } | |
2594 el = null; | |
2595 | |
2596 el = document.createElement('label'); | |
2597 el.setAttribute(forProp, 'x'); | |
2598 if (el.htmlFor !== 'x') { | |
2599 el.setAttribute('htmlFor', 'x'); | |
2600 if (el.htmlFor === 'x') { | |
2601 forProp = 'htmlFor'; | |
2602 } | |
2603 } | |
2604 el = null; | |
2605 | |
2606 return { | |
2607 read: { | |
2608 names: { | |
2609 'class': classProp, | |
2610 'className': classProp, | |
2611 'for': forProp, | |
2612 'htmlFor': forProp | |
2613 }, | |
2614 values: { | |
2615 _getAttr: function(element, attribute) { | |
2616 return element.getAttribute(attribute); | |
2617 }, | |
2618 _getAttr2: function(element, attribute) { | |
2619 return element.getAttribute(attribute, 2); | |
2620 }, | |
2621 _getAttrNode: function(element, attribute) { | |
2622 var node = element.getAttributeNode(attribute); | |
2623 return node ? node.value : ""; | |
2624 }, | |
2625 _getEv: (function(){ | |
2626 | |
2627 var el = document.createElement('div'), f; | |
2628 el.onclick = Prototype.emptyFunction; | |
2629 var value = el.getAttribute('onclick'); | |
2630 | |
2631 if (String(value).indexOf('{') > -1) { | |
2632 f = function(element, attribute) { | |
2633 attribute = element.getAttribute(attribute); | |
2634 if (!attribute) return null; | |
2635 attribute = attribute.toString(); | |
2636 attribute = attribute.split('{')[1]; | |
2637 attribute = attribute.split('}')[0]; | |
2638 return attribute.strip(); | |
2639 }; | |
2640 } | |
2641 else if (value === '') { | |
2642 f = function(element, attribute) { | |
2643 attribute = element.getAttribute(attribute); | |
2644 if (!attribute) return null; | |
2645 return attribute.strip(); | |
2646 }; | |
2647 } | |
2648 el = null; | |
2649 return f; | |
2650 })(), | |
2651 _flag: function(element, attribute) { | |
2652 return $(element).hasAttribute(attribute) ? attribute : null; | |
2653 }, | |
2654 style: function(element) { | |
2655 return element.style.cssText.toLowerCase(); | |
2656 }, | |
2657 title: function(element) { | |
2658 return element.title; | |
2659 } | |
2660 } | |
2661 } | |
2662 } | |
2663 })(); | |
2664 | |
2665 Element._attributeTranslations.write = { | |
2666 names: Object.extend({ | |
2667 cellpadding: 'cellPadding', | |
2668 cellspacing: 'cellSpacing' | |
2669 }, Element._attributeTranslations.read.names), | |
2670 values: { | |
2671 checked: function(element, value) { | |
2672 element.checked = !!value; | |
2673 }, | |
2674 | |
2675 style: function(element, value) { | |
2676 element.style.cssText = value ? value : ''; | |
2677 } | |
2678 } | |
2679 }; | |
2680 | |
2681 Element._attributeTranslations.has = {}; | |
2682 | |
2683 $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + | |
2684 'encType maxLength readOnly longDesc frameBorder').each(function(attr) { | |
2685 Element._attributeTranslations.write.names[attr.toLowerCase()] = attr; | |
2686 Element._attributeTranslations.has[attr.toLowerCase()] = attr; | |
2687 }); | |
2688 | |
2689 (function(v) { | |
2690 Object.extend(v, { | |
2691 href: v._getAttr2, | |
2692 src: v._getAttr2, | |
2693 type: v._getAttr, | |
2694 action: v._getAttrNode, | |
2695 disabled: v._flag, | |
2696 checked: v._flag, | |
2697 readonly: v._flag, | |
2698 multiple: v._flag, | |
2699 onload: v._getEv, | |
2700 onunload: v._getEv, | |
2701 onclick: v._getEv, | |
2702 ondblclick: v._getEv, | |
2703 onmousedown: v._getEv, | |
2704 onmouseup: v._getEv, | |
2705 onmouseover: v._getEv, | |
2706 onmousemove: v._getEv, | |
2707 onmouseout: v._getEv, | |
2708 onfocus: v._getEv, | |
2709 onblur: v._getEv, | |
2710 onkeypress: v._getEv, | |
2711 onkeydown: v._getEv, | |
2712 onkeyup: v._getEv, | |
2713 onsubmit: v._getEv, | |
2714 onreset: v._getEv, | |
2715 onselect: v._getEv, | |
2716 onchange: v._getEv | |
2717 }); | |
2718 })(Element._attributeTranslations.read.values); | |
2719 | |
2720 if (Prototype.BrowserFeatures.ElementExtensions) { | |
2721 (function() { | |
2722 function _descendants(element) { | |
2723 var nodes = element.getElementsByTagName('*'), results = []; | |
2724 for (var i = 0, node; node = nodes[i]; i++) | |
2725 if (node.tagName !== "!") // Filter out comment nodes. | |
2726 results.push(node); | |
2727 return results; | |
2728 } | |
2729 | |
2730 Element.Methods.down = function(element, expression, index) { | |
2731 element = $(element); | |
2732 if (arguments.length == 1) return element.firstDescendant(); | |
2733 return Object.isNumber(expression) ? _descendants(element)[expression] : | |
2734 Element.select(element, expression)[index || 0]; | |
2735 } | |
2736 })(); | |
2737 } | |
2738 | |
2739 } | |
2740 | |
2741 else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) { | |
2742 Element.Methods.setOpacity = function(element, value) { | |
2743 element = $(element); | |
2744 element.style.opacity = (value == 1) ? 0.999999 : | |
2745 (value === '') ? '' : (value < 0.00001) ? 0 : value; | |
2746 return element; | |
2747 }; | |
2748 } | |
2749 | |
2750 else if (Prototype.Browser.WebKit) { | |
2751 Element.Methods.setOpacity = function(element, value) { | |
2752 element = $(element); | |
2753 element.style.opacity = (value == 1 || value === '') ? '' : | |
2754 (value < 0.00001) ? 0 : value; | |
2755 | |
2756 if (value == 1) | |
2757 if (element.tagName.toUpperCase() == 'IMG' && element.width) { | |
2758 element.width++; element.width--; | |
2759 } else try { | |
2760 var n = document.createTextNode(' '); | |
2761 element.appendChild(n); | |
2762 element.removeChild(n); | |
2763 } catch (e) { } | |
2764 | |
2765 return element; | |
2766 }; | |
2767 } | |
2768 | |
2769 if ('outerHTML' in document.documentElement) { | |
2770 Element.Methods.replace = function(element, content) { | |
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.stripScripts()); | |
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 = ' ' + 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); | |
2838 }, | |
2839 after: function(element, node) { | |
2840 element.parentNode.insertBefore(node, element.nextSibling); | |
2841 }, | |
2842 tags: { | |
2843 TABLE: ['<table>', '</table>', 1], | |
2844 TBODY: ['<table><tbody>', '</tbody></table>', 2], | |
2845 TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3], | |
2846 TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4], | |
2847 SELECT: ['<select>', '</select>', 1] | |
2848 } | |
2849 }; | |
2850 | |
2851 (function() { | |
2852 var tags = Element._insertionTranslations.tags; | |
2853 Object.extend(tags, { | |
2854 THEAD: tags.TBODY, | |
2855 TFOOT: tags.TBODY, | |
2856 TH: tags.TD | |
2857 }); | |
2858 })(); | |
2859 | |
2860 Element.Methods.Simulated = { | |
2861 hasAttribute: function(element, attribute) { | |
2862 attribute = Element._attributeTranslations.has[attribute] || attribute; | |
2863 var node = $(element).getAttributeNode(attribute); | |
2864 return !!(node && node.specified); | |
2865 } | |
2866 }; | |
2867 | |
2868 Element.Methods.ByTag = { }; | |
2869 | |
2870 Object.extend(Element, Element.Methods); | |
2871 | |
2872 (function(div) { | |
2873 | |
2874 if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) { | |
2875 window.HTMLElement = { }; | |
2876 window.HTMLElement.prototype = div['__proto__']; | |
2877 Prototype.BrowserFeatures.ElementExtensions = true; | |
2878 } | |
2879 | |
2880 div = null; | |
2881 | |
2882 })(document.createElement('div')); | |
2883 | |
2884 Element.extend = (function() { | |
2885 | |
2886 function checkDeficiency(tagName) { | |
2887 if (typeof window.Element != 'undefined') { | |
2888 var proto = window.Element.prototype; | |
2889 if (proto) { | |
2890 var id = '_' + (Math.random()+'').slice(2), | |
2891 el = document.createElement(tagName); | |
2892 proto[id] = 'x'; | |
2893 var isBuggy = (el[id] !== 'x'); | |
2894 delete proto[id]; | |
2895 el = null; | |
2896 return isBuggy; | |
2897 } | |
2898 } | |
2899 return false; | |
2900 } | |
2901 | |
2902 function extendElementWith(element, methods) { | |
2903 for (var property in methods) { | |
2904 var value = methods[property]; | |
2905 if (Object.isFunction(value) && !(property in element)) | |
2906 element[property] = value.methodize(); | |
2907 } | |
2908 } | |
2909 | |
2910 var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object'); | |
2911 | |
2912 if (Prototype.BrowserFeatures.SpecificElementExtensions) { | |
2913 if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) { | |
2914 return function(element) { | |
2915 if (element && typeof element._extendedByPrototype == 'undefined') { | |
2916 var t = element.tagName; | |
2917 if (t && (/^(?:object|applet|embed)$/i.test(t))) { | |
2918 extendElementWith(element, Element.Methods); | |
2919 extendElementWith(element, Element.Methods.Simulated); | |
2920 extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]); | |
2921 } | |
2922 } | |
2923 return element; | |
2924 } | |
2925 } | |
2926 return Prototype.K; | |
2927 } | |
2928 | |
2929 var Methods = { }, ByTag = Element.Methods.ByTag; | |
2930 | |
2931 var extend = Object.extend(function(element) { | |
2932 if (!element || typeof element._extendedByPrototype != 'undefined' || | |
2933 element.nodeType != 1 || element == window) return element; | |
2934 | |
2935 var methods = Object.clone(Methods), | |
2936 tagName = element.tagName.toUpperCase(); | |
2937 | |
2938 if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); | |
2939 | |
2940 extendElementWith(element, methods); | |
2941 | |
2942 element._extendedByPrototype = Prototype.emptyFunction; | |
2943 return element; | |
2944 | |
2945 }, { | |
2946 refresh: function() { | |
2947 if (!Prototype.BrowserFeatures.ElementExtensions) { | |
2948 Object.extend(Methods, Element.Methods); | |
2949 Object.extend(Methods, Element.Methods.Simulated); | |
2950 } | |
2951 } | |
2952 }); | |
2953 | |
2954 extend.refresh(); | |
2955 return extend; | |
2956 })(); | |
2957 | |
2958 if (document.documentElement.hasAttribute) { | |
2959 Element.hasAttribute = function(element, attribute) { | |
2960 return element.hasAttribute(attribute); | |
2961 }; | |
2962 } | |
2963 else { | |
2964 Element.hasAttribute = Element.Methods.Simulated.hasAttribute; | |
2965 } | |
2966 | |
2967 Element.addMethods = function(methods) { | |
2968 var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; | |
2969 | |
2970 if (!methods) { | |
2971 Object.extend(Form, Form.Methods); | |
2972 Object.extend(Form.Element, Form.Element.Methods); | |
2973 Object.extend(Element.Methods.ByTag, { | |
2974 "FORM": Object.clone(Form.Methods), | |
2975 "INPUT": Object.clone(Form.Element.Methods), | |
2976 "SELECT": Object.clone(Form.Element.Methods), | |
2977 "TEXTAREA": Object.clone(Form.Element.Methods), | |
2978 "BUTTON": Object.clone(Form.Element.Methods) | |
2979 }); | |
2980 } | |
2981 | |
2982 if (arguments.length == 2) { | |
2983 var tagName = methods; | |
2984 methods = arguments[1]; | |
2985 } | |
2986 | |
2987 if (!tagName) Object.extend(Element.Methods, methods || { }); | |
2988 else { | |
2989 if (Object.isArray(tagName)) tagName.each(extend); | |
2990 else extend(tagName); | |
2991 } | |
2992 | |
2993 function extend(tagName) { | |
2994 tagName = tagName.toUpperCase(); | |
2995 if (!Element.Methods.ByTag[tagName]) | |
2996 Element.Methods.ByTag[tagName] = { }; | |
2997 Object.extend(Element.Methods.ByTag[tagName], methods); | |
2998 } | |
2999 | |
3000 function copy(methods, destination, onlyIfAbsent) { | |
3001 onlyIfAbsent = onlyIfAbsent || false; | |
3002 for (var property in methods) { | |
3003 var value = methods[property]; | |
3004 if (!Object.isFunction(value)) continue; | |
3005 if (!onlyIfAbsent || !(property in destination)) | |
3006 destination[property] = value.methodize(); | |
3007 } | |
3008 } | |
3009 | |
3010 function findDOMClass(tagName) { | |
3011 var klass; | |
3012 var trans = { | |
3013 "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", | |
3014 "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList", | |
3015 "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading", | |
3016 "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", | |
3017 "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION": | |
3018 "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD": | |
3019 "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR": | |
3020 "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": | |
3021 "FrameSet", "IFRAME": "IFrame" | |
3022 }; | |
3023 if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; | |
3024 if (window[klass]) return window[klass]; | |
3025 klass = 'HTML' + tagName + 'Element'; | |
3026 if (window[klass]) return window[klass]; | |
3027 klass = 'HTML' + tagName.capitalize() + 'Element'; | |
3028 if (window[klass]) return window[klass]; | |
3029 | |
3030 var element = document.createElement(tagName), | |
3031 proto = element['__proto__'] || element.constructor.prototype; | |
3032 | |
3033 element = null; | |
3034 return proto; | |
3035 } | |
3036 | |
3037 var elementPrototype = window.HTMLElement ? HTMLElement.prototype : | |
3038 Element.prototype; | |
3039 | |
3040 if (F.ElementExtensions) { | |
3041 copy(Element.Methods, elementPrototype); | |
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.scrollLeft, | |
3070 window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); | |
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) { | |
3108 if (!(element = $(element))) return; | |
3109 | |
3110 var uid; | |
3111 if (element === window) { | |
3112 uid = 0; | |
3113 } else { | |
3114 if (typeof element._prototypeUID === "undefined") | |
3115 element._prototypeUID = Element.Storage.UID++; | |
3116 uid = element._prototypeUID; | |
3117 } | |
3118 | |
3119 if (!Element.Storage[uid]) | |
3120 Element.Storage[uid] = $H(); | |
3121 | |
3122 return Element.Storage[uid]; | |
3123 }, | |
3124 | |
3125 store: function(element, key, value) { | |
3126 if (!(element = $(element))) return; | |
3127 | |
3128 if (arguments.length === 2) { | |
3129 Element.getStorage(element).update(key); | |
3130 } else { | |
3131 Element.getStorage(element).set(key, value); | |
3132 } | |
3133 | |
3134 return element; | |
3135 }, | |
3136 | |
3137 retrieve: function(element, key, defaultValue) { | |
3138 if (!(element = $(element))) return; | |
3139 var hash = Element.getStorage(element), value = hash.get(key); | |
3140 | |
3141 if (Object.isUndefined(value)) { | |
3142 hash.set(key, defaultValue); | |
3143 value = defaultValue; | |
3144 } | |
3145 | |
3146 return value; | |
3147 }, | |
3148 | |
3149 clone: function(element, deep) { | |
3150 if (!(element = $(element))) return; | |
3151 var clone = element.cloneNode(deep); | |
3152 clone._prototypeUID = void 0; | |
3153 if (deep) { | |
3154 var descendants = Element.select(clone, '*'), | |
3155 i = descendants.length; | |
3156 while (i--) { | |
3157 descendants[i]._prototypeUID = void 0; | |
3158 } | |
3159 } | |
3160 return Element.extend(clone); | |
3161 }, | |
3162 | |
3163 purge: function(element) { | |
3164 if (!(element = $(element))) return; | |
3165 var purgeElement = Element._purgeElement; | |
3166 | |
3167 purgeElement(element); | |
3168 | |
3169 var descendants = element.getElementsByTagName('*'), | |
3170 i = descendants.length; | |
3171 | |
3172 while (i--) purgeElement(descendants[i]); | |
3173 | |
3174 return null; | |
3175 } | |
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.viewport); | |
3202 | |
3203 if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) { | |
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 } | |
3242 | |
3243 return 0; | |
3244 } | |
3245 | |
3246 function toCSSPixels(number) { | |
3247 if (Object.isString(number) && number.endsWith('px')) { | |
3248 return number; | |
3249 } | |
3250 return number + 'px'; | |
3251 } | |
3252 | |
3253 function isDisplayed(element) { | |
3254 var originalElement = element; | |
3255 while (element && element.parentNode) { | |
3256 var display = element.getStyle('display'); | |
3257 if (display === 'none') { | |
3258 return false; | |
3259 } | |
3260 element = $(element.parentNode); | |
3261 } | |
3262 return true; | |
3263 } | |
3264 | |
3265 var hasLayout = Prototype.K; | |
3266 if ('currentStyle' in document.documentElement) { | |
3267 hasLayout = function(element) { | |
3268 if (!element.currentStyle.hasLayout) { | |
3269 element.style.zoom = 1; | |
3270 } | |
3271 return element; | |
3272 }; | |
3273 } | |
3274 | |
3275 function cssNameFor(key) { | |
3276 if (key.include('border')) key = key + '-width'; | |
3277 return key.camelize(); | |
3278 } | |
3279 | |
3280 Element.Layout = Class.create(Hash, { | |
3281 initialize: function($super, element, preCompute) { | |
3282 $super(); | |
3283 this.element = $(element); | |
3284 | |
3285 Element.Layout.PROPERTIES.each( function(property) { | |
3286 this._set(property, null); | |
3287 }, this); | |
3288 | |
3289 if (preCompute) { | |
3290 this._preComputing = true; | |
3291 this._begin(); | |
3292 Element.Layout.PROPERTIES.each( this._compute, this ); | |
3293 this._end(); | |
3294 this._preComputing = false; | |
3295 } | |
3296 }, | |
3297 | |
3298 _set: function(property, value) { | |
3299 return Hash.prototype.set.call(this, property, value); | |
3300 }, | |
3301 | |
3302 set: function(property, value) { | |
3303 throw "Properties of Element.Layout are read-only."; | |
3304 }, | |
3305 | |
3306 get: function($super, property) { | |
3307 var value = $super(property); | |
3308 return value === null ? this._compute(property) : value; | |
3309 }, | |
3310 | |
3311 _begin: function() { | |
3312 if (this._prepared) return; | |
3313 | |
3314 var element = this.element; | |
3315 if (isDisplayed(element)) { | |
3316 this._prepared = true; | |
3317 return; | |
3318 } | |
3319 | |
3320 var originalStyles = { | |
3321 position: element.style.position || '', | |
3322 width: element.style.width || '', | |
3323 visibility: element.style.visibility || '', | |
3324 display: element.style.display || '' | |
3325 }; | |
3326 | |
3327 element.store('prototype_original_styles', originalStyles); | |
3328 | |
3329 var position = element.getStyle('position'), | |
3330 width = element.getStyle('width'); | |
3331 | |
3332 if (width === "0px" || width === null) { | |
3333 element.style.display = 'block'; | |
3334 width = element.getStyle('width'); | |
3335 } | |
3336 | |
3337 var context = (position === 'fixed') ? document.viewport : | |
3338 element.parentNode; | |
3339 | |
3340 element.setStyle({ | |
3341 position: 'absolute', | |
3342 visibility: 'hidden', | |
3343 display: 'block' | |
3344 }); | |
3345 | |
3346 var positionedWidth = element.getStyle('width'); | |
3347 | |
3348 var newWidth; | |
3349 if (width && (positionedWidth === width)) { | |
3350 newWidth = getPixelValue(element, 'width', context); | |
3351 } else if (position === 'absolute' || position === 'fixed') { | |
3352 newWidth = getPixelValue(element, 'width', context); | |
3353 } else { | |
3354 var parent = element.parentNode, pLayout = $(parent).getLayout(); | |
3355 | |
3356 newWidth = pLayout.get('width') - | |
3357 this.get('margin-left') - | |
3358 this.get('border-left') - | |
3359 this.get('padding-left') - | |
3360 this.get('padding-right') - | |
3361 this.get('border-right') - | |
3362 this.get('margin-right'); | |
3363 } | |
3364 | |
3365 element.setStyle({ width: newWidth + 'px' }); | |
3366 | |
3367 this._prepared = true; | |
3368 }, | |
3369 | |
3370 _end: function() { | |
3371 var element = this.element; | |
3372 var originalStyles = element.retrieve('prototype_original_styles'); | |
3373 element.store('prototype_original_styles', null); | |
3374 element.setStyle(originalStyles); | |
3375 this._prepared = false; | |
3376 }, | |
3377 | |
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 border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-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'), | |
3442 bBottom = this.get('border-bottom'); | |
3443 | |
3444 var pTop = this.get('padding-top'), | |
3445 pBottom = this.get('padding-bottom'); | |
3446 | |
3447 if (!this._preComputing) this._end(); | |
3448 | |
3449 return bHeight - bTop - bBottom - pTop - pBottom; | |
3450 }, | |
3451 | |
3452 'width': function(element) { | |
3453 if (!this._preComputing) this._begin(); | |
3454 | |
3455 var bWidth = this.get('border-box-width'); | |
3456 if (bWidth <= 0) { | |
3457 if (!this._preComputing) this._end(); | |
3458 return 0; | |
3459 } | |
3460 | |
3461 var bLeft = this.get('border-left'), | |
3462 bRight = this.get('border-right'); | |
3463 | |
3464 var pLeft = this.get('padding-left'), | |
3465 pRight = this.get('padding-right'); | |
3466 | |
3467 if (!this._preComputing) this._end(); | |
3468 | |
3469 return bWidth - bLeft - bRight - pLeft - pRight; | |
3470 }, | |
3471 | |
3472 'padding-box-height': function(element) { | |
3473 var height = this.get('height'), | |
3474 pTop = this.get('padding-top'), | |
3475 pBottom = this.get('padding-bottom'); | |
3476 | |
3477 return height + pTop + pBottom; | |
3478 }, | |
3479 | |
3480 'padding-box-width': function(element) { | |
3481 var width = this.get('width'), | |
3482 pLeft = this.get('padding-left'), | |
3483 pRight = this.get('padding-right'); | |
3484 | |
3485 return width + pLeft + pRight; | |
3486 }, | |
3487 | |
3488 'border-box-height': function(element) { | |
3489 if (!this._preComputing) this._begin(); | |
3490 var height = element.offsetHeight; | |
3491 if (!this._preComputing) this._end(); | |
3492 return height; | |
3493 }, | |
3494 | |
3495 'border-box-width': function(element) { | |
3496 if (!this._preComputing) this._begin(); | |
3497 var width = element.offsetWidth; | |
3498 if (!this._preComputing) this._end(); | |
3499 return width; | |
3500 }, | |
3501 | |
3502 'margin-box-height': function(element) { | |
3503 var bHeight = this.get('border-box-height'), | |
3504 mTop = this.get('margin-top'), | |
3505 mBottom = this.get('margin-bottom'); | |
3506 | |
3507 if (bHeight <= 0) return 0; | |
3508 | |
3509 return bHeight + mTop + mBottom; | |
3510 }, | |
3511 | |
3512 'margin-box-width': function(element) { | |
3513 var bWidth = this.get('border-box-width'), | |
3514 mLeft = this.get('margin-left'), | |
3515 mRight = this.get('margin-right'); | |
3516 | |
3517 if (bWidth <= 0) return 0; | |
3518 | |
3519 return bWidth + mLeft + mRight; | |
3520 }, | |
3521 | |
3522 'top': function(element) { | |
3523 var offset = element.positionedOffset(); | |
3524 return offset.top; | |
3525 }, | |
3526 | |
3527 'bottom': function(element) { | |
3528 var offset = element.positionedOffset(), | |
3529 parent = element.getOffsetParent(), | |
3530 pHeight = parent.measure('height'); | |
3531 | |
3532 var mHeight = this.get('border-box-height'); | |
3533 | |
3534 return pHeight - mHeight - offset.top; | |
3535 }, | |
3536 | |
3537 'left': function(element) { | |
3538 var offset = element.positionedOffset(); | |
3539 return offset.left; | |
3540 }, | |
3541 | |
3542 'right': function(element) { | |
3543 var offset = element.positionedOffset(), | |
3544 parent = element.getOffsetParent(), | |
3545 pWidth = parent.measure('width'); | |
3546 | |
3547 var mWidth = this.get('border-box-width'); | |
3548 | |
3549 return pWidth - mWidth - offset.left; | |
3550 }, | |
3551 | |
3552 'padding-top': function(element) { | |
3553 return getPixelValue(element, 'paddingTop'); | |
3554 }, | |
3555 | |
3556 'padding-bottom': function(element) { | |
3557 return getPixelValue(element, 'paddingBottom'); | |
3558 }, | |
3559 | |
3560 'padding-left': function(element) { | |
3561 return getPixelValue(element, 'paddingLeft'); | |
3562 }, | |
3563 | |
3564 'padding-right': function(element) { | |
3565 return getPixelValue(element, 'paddingRight'); | |
3566 }, | |
3567 | |
3568 'border-top': function(element) { | |
3569 return getPixelValue(element, 'borderTopWidth'); | |
3570 }, | |
3571 | |
3572 'border-bottom': function(element) { | |
3573 return getPixelValue(element, 'borderBottomWidth'); | |
3574 }, | |
3575 | |
3576 'border-left': function(element) { | |
3577 return getPixelValue(element, 'borderLeftWidth'); | |
3578 }, | |
3579 | |
3580 'border-right': function(element) { | |
3581 return getPixelValue(element, 'borderRightWidth'); | |
3582 }, | |
3583 | |
3584 'margin-top': function(element) { | |
3585 return getPixelValue(element, 'marginTop'); | |
3586 }, | |
3587 | |
3588 'margin-bottom': function(element) { | |
3589 return getPixelValue(element, 'marginBottom'); | |
3590 }, | |
3591 | |
3592 'margin-left': function(element) { | |
3593 return getPixelValue(element, 'marginLeft'); | |
3594 }, | |
3595 | |
3596 'margin-right': function(element) { | |
3597 return getPixelValue(element, 'marginRight'); | |
3598 } | |
3599 } | |
3600 }); | |
3601 | |
3602 if ('getBoundingClientRect' in document.documentElement) { | |
3603 Object.extend(Element.Layout.COMPUTATIONS, { | |
3604 'right': function(element) { | |
3605 var parent = hasLayout(element.getOffsetParent()); | |
3606 var rect = element.getBoundingClientRect(), | |
3607 pRect = parent.getBoundingClientRect(); | |
3608 | |
3609 return (pRect.right - rect.right).round(); | |
3610 }, | |
3611 | |
3612 'bottom': function(element) { | |
3613 var parent = hasLayout(element.getOffsetParent()); | |
3614 var rect = element.getBoundingClientRect(), | |
3615 pRect = parent.getBoundingClientRect(); | |
3616 | |
3617 return (pRect.bottom - rect.bottom).round(); | |
3618 } | |
3619 }); | |
3620 } | |
3621 | |
3622 Element.Offset = Class.create({ | |
3623 initialize: function(left, top) { | |
3624 this.left = left.round(); | |
3625 this.top = top.round(); | |
3626 | |
3627 this[0] = this.left; | |
3628 this[1] = this.top; | |
3629 }, | |
3630 | |
3631 relativeTo: function(offset) { | |
3632 return new Element.Offset( | |
3633 this.left - offset.left, | |
3634 this.top - offset.top | |
3635 ); | |
3636 }, | |
3637 | |
3638 inspect: function() { | |
3639 return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this); | |
3640 }, | |
3641 | |
3642 toString: function() { | |
3643 return "[#{left}, #{top}]".interpolate(this); | |
3644 }, | |
3645 | |
3646 toArray: function() { | |
3647 return [this.left, this.top]; | |
3648 } | |
3649 }); | |
3650 | |
3651 function getLayout(element, preCompute) { | |
3652 return new Element.Layout(element, preCompute); | |
3653 } | |
3654 | |
3655 function measure(element, property) { | |
3656 return $(element).getLayout().get(property); | |
3657 } | |
3658 | |
3659 function getDimensions(element) { | |
3660 element = $(element); | |
3661 var display = Element.getStyle(element, 'display'); | |
3662 | |
3663 if (display && display !== 'none') { | |
3664 return { width: element.offsetWidth, height: element.offsetHeight }; | |
3665 } | |
3666 | |
3667 var style = element.style; | |
3668 var originalStyles = { | |
3669 visibility: style.visibility, | |
3670 position: style.position, | |
3671 display: style.display | |
3672 }; | |
3673 | |
3674 var newStyles = { | |
3675 visibility: 'hidden', | |
3676 display: 'block' | |
3677 }; | |
3678 | |
3679 if (originalStyles.position !== 'fixed') | |
3680 newStyles.position = 'absolute'; | |
3681 | |
3682 Element.setStyle(element, newStyles); | |
3683 | |
3684 var dimensions = { | |
3685 width: element.offsetWidth, | |
3686 height: element.offsetHeight | |
3687 }; | |
3688 | |
3689 Element.setStyle(element, originalStyles); | |
3690 | |
3691 return dimensions; | |
3692 } | |
3693 | |
3694 function getOffsetParent(element) { | |
3695 element = $(element); | |
3696 | |
3697 if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element)) | |
3698 return $(document.body); | |
3699 | |
3700 var isInline = (Element.getStyle(element, 'display') === 'inline'); | |
3701 if (!isInline && element.offsetParent) return $(element.offsetParent); | |
3702 | |
3703 while ((element = element.parentNode) && element !== document.body) { | |
3704 if (Element.getStyle(element, 'position') !== 'static') { | |
3705 return isHtml(element) ? $(document.body) : $(element); | |
3706 } | |
3707 } | |
3708 | |
3709 return $(document.body); | |
3710 } | |
3711 | |
3712 | |
3713 function cumulativeOffset(element) { | |
3714 element = $(element); | |
3715 var valueT = 0, valueL = 0; | |
3716 if (element.parentNode) { | |
3717 do { | |
3718 valueT += element.offsetTop || 0; | |
3719 valueL += element.offsetLeft || 0; | |
3720 element = element.offsetParent; | |
3721 } while (element); | |
3722 } | |
3723 return new Element.Offset(valueL, valueT); | |
3724 } | |
3725 | |
3726 function positionedOffset(element) { | |
3727 element = $(element); | |
3728 | |
3729 var layout = element.getLayout(); | |
3730 | |
3731 var valueT = 0, valueL = 0; | |
3732 do { | |
3733 valueT += element.offsetTop || 0; | |
3734 valueL += element.offsetLeft || 0; | |
3735 element = element.offsetParent; | |
3736 if (element) { | |
3737 if (isBody(element)) break; | |
3738 var p = Element.getStyle(element, 'position'); | |
3739 if (p !== 'static') break; | |
3740 } | |
3741 } while (element); | |
3742 | |
3743 valueL -= layout.get('margin-top'); | |
3744 valueT -= layout.get('margin-left'); | |
3745 | |
3746 return new Element.Offset(valueL, valueT); | |
3747 } | |
3748 | |
3749 function cumulativeScrollOffset(element) { | |
3750 var valueT = 0, valueL = 0; | |
3751 do { | |
3752 valueT += element.scrollTop || 0; | |
3753 valueL += element.scrollLeft || 0; | |
3754 element = element.parentNode; | |
3755 } while (element); | |
3756 return new Element.Offset(valueL, valueT); | |
3757 } | |
3758 | |
3759 function viewportOffset(forElement) { | |
3760 element = $(element); | |
3761 var valueT = 0, valueL = 0, docBody = document.body; | |
3762 | |
3763 var element = forElement; | |
3764 do { | |
3765 valueT += element.offsetTop || 0; | |
3766 valueL += element.offsetLeft || 0; | |
3767 if (element.offsetParent == docBody && | |
3768 Element.getStyle(element, 'position') == 'absolute') break; | |
3769 } while (element = element.offsetParent); | |
3770 | |
3771 element = forElement; | |
3772 do { | |
3773 if (element != docBody) { | |
3774 valueT -= element.scrollTop || 0; | |
3775 valueL -= element.scrollLeft || 0; | |
3776 } | |
3777 } while (element = element.parentNode); | |
3778 return new Element.Offset(valueL, valueT); | |
3779 } | |
3780 | |
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'); | |
3848 if (position !== 'static') return proceed(element); | |
3849 | |
3850 var offsetParent = element.getOffsetParent(); | |
3851 if (offsetParent && offsetParent.getStyle('position') === 'fixed') | |
3852 hasLayout(offsetParent); | |
3853 | |
3854 element.setStyle({ position: 'relative' }); | |
3855 var value = proceed(element); | |
3856 element.setStyle({ position: position }); | |
3857 return value; | |
3858 }); | |
3859 } else if (Prototype.Browser.Webkit) { | |
3860 cumulativeOffset = function(element) { | |
3861 element = $(element); | |
3862 var valueT = 0, valueL = 0; | |
3863 do { | |
3864 valueT += element.offsetTop || 0; | |
3865 valueL += element.offsetLeft || 0; | |
3866 if (element.offsetParent == document.body) | |
3867 if (Element.getStyle(element, 'position') == 'absolute') break; | |
3868 | |
3869 element = element.offsetParent; | |
3870 } while (element); | |
3871 | |
3872 return new Element.Offset(valueL, valueT); | |
3873 }; | |
3874 } | |
3875 | |
3876 | |
3877 Element.addMethods({ | |
3878 getLayout: getLayout, | |
3879 measure: measure, | |
3880 getDimensions: getDimensions, | |
3881 getOffsetParent: getOffsetParent, | |
3882 cumulativeOffset: cumulativeOffset, | |
3883 positionedOffset: positionedOffset, | |
3884 cumulativeScrollOffset: cumulativeScrollOffset, | |
3885 viewportOffset: viewportOffset, | |
3886 absolutize: absolutize, | |
3887 relativize: relativize | |
3888 }); | |
3889 | |
3890 function isBody(element) { | |
3891 return element.nodeName.toUpperCase() === 'BODY'; | |
3892 } | |
3893 | |
3894 function isHtml(element) { | |
3895 return element.nodeName.toUpperCase() === 'HTML'; | |
3896 } | |
3897 | |
3898 function isDocument(element) { | |
3899 return element.nodeType === Node.DOCUMENT_NODE; | |
3900 } | |
3901 | |
3902 function isDetached(element) { | |
3903 return element !== document.body && | |
3904 !Element.descendantOf(element, document.body); | |
3905 } | |
3906 | |
3907 if ('getBoundingClientRect' in document.documentElement) { | |
3908 Element.addMethods({ | |
3909 viewportOffset: function(element) { | |
3910 element = $(element); | |
3911 if (isDetached(element)) return new Element.Offset(0, 0); | |
3912 | |
3913 var rect = element.getBoundingClientRect(), | |
3914 docEl = document.documentElement; | |
3915 return new Element.Offset(rect.left - docEl.clientLeft, | |
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; | |
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, contextXML = 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 && !contextXML && | |
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 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); | |
4039 set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set; | |
4040 | |
4041 if ( parts.length > 0 ) { | |
4042 checkSet = makeArray(set); | |
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 || checkSet[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++ ) { | |
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, curLoop, inplace, result, not, isXMLFilter ); | |
4172 | |
4173 if ( !match ) { | |
4174 anyFound = found = true; | |
4175 } else if ( match === true ) { | |
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 != null ) { | |
4187 if ( pass ) { | |
4188 anyFound = true; | |
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: " + expr; | |
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*(['"]*)(.*?)\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) && elem.nodeType !== 1 ) {} | |
4265 | |
4266 checkSet[i] = isPartStrNotTag || elem && elem.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 === part ? 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 ) { | |
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.toUpperCase(); | |
4309 checkFn = dirNodeCheck; | |
4310 } | |
4311 | |
4312 checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML); | |
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.toUpperCase(); | |
4319 checkFn = dirNodeCheck; | |
4320 } | |
4321 | |
4322 checkFn("previousSibling", part, doneName, checkSet, nodeCheck, 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(match[1]); | |
4335 | |
4336 for ( var i = 0, l = results.length; i < l; i++ ) { | |
4337 if ( results[i].getAttribute("name") === match[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.className + " ").indexOf(match) >= 0) ) { | |
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] == "odd" && "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, curLoop); | |
4408 } else { | |
4409 var ret = Sizzle.filter(match[3], curLoop, inplace, 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.CHILD.test( match[0] ) ) { | |
4416 return true; | |
4417 } | |
4418 | |
4419 return match; | |
4420 }, | |
4421 POS: function(match){ | |
4422 match.unshift( true ); | |
4423 return match; | |
4424 } | |
4425 }, | |
4426 filters: { | |
4427 enabled: function(elem){ | |
4428 return elem.disabled === false && elem.type !== "hidden"; | |
4429 }, | |
4430 disabled: function(elem){ | |
4431 return elem.disabled === true; | |
4432 }, | |
4433 checked: function(elem){ | |
4434 return elem.checked === true; | |
4435 }, | |
4436 selected: function(elem){ | |
4437 elem.parentNode.selectedIndex; | |
4438 return elem.selected === true; | |
4439 }, | |
4440 parent: function(elem){ | |
4441 return !!elem.firstChild; | |
4442 }, | |
4443 empty: function(elem){ | |
4444 return !elem.firstChild; | |
4445 }, | |
4446 has: function(elem, i, match){ | |
4447 return !!Sizzle( match[3], elem ).length; | |
4448 }, | |
4449 header: function(elem){ | |
4450 return /h\d/i.test( elem.nodeName ); | |
4451 }, | |
4452 text: function(elem){ | |
4453 return "text" === elem.type; | |
4454 }, | |
4455 radio: function(elem){ | |
4456 return "radio" === elem.type; | |
4457 }, | |
4458 checkbox: function(elem){ | |
4459 return "checkbox" === elem.type; | |
4460 }, | |
4461 file: function(elem){ | |
4462 return "file" === elem.type; | |
4463 }, | |
4464 password: function(elem){ | |
4465 return "password" === elem.type; | |
4466 }, | |
4467 submit: function(elem){ | |
4468 return "submit" === elem.type; | |
4469 }, | |
4470 image: function(elem){ | |
4471 return "image" === elem.type; | |
4472 }, | |
4473 reset: function(elem){ | |
4474 return "reset" === elem.type; | |
4475 }, | |
4476 button: function(elem){ | |
4477 return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON"; | |
4478 }, | |
4479 input: function(elem){ | |
4480 return /input|select|textarea|button/i.test(elem.nodeName); | |
4481 } | |
4482 }, | |
4483 setFilters: { | |
4484 first: function(elem, i){ | |
4485 return i === 0; | |
4486 }, | |
4487 last: function(elem, i, match, array){ | |
4488 return i === array.length - 1; | |
4489 }, | |
4490 even: function(elem, i){ | |
4491 return i % 2 === 0; | |
4492 }, | |
4493 odd: function(elem, i){ | |
4494 return i % 2 === 1; | |
4495 }, | |
4496 lt: function(elem, i, match){ | |
4497 return i < match[3] - 0; | |
4498 }, | |
4499 gt: function(elem, i, match){ | |
4500 return i > match[3] - 0; | |
4501 }, | |
4502 nth: function(elem, i, match){ | |
4503 return match[3] - 0 == i; | |
4504 }, | |
4505 eq: function(elem, i, match){ | |
4506 return match[3] - 0 == i; | |
4507 } | |
4508 }, | |
4509 filter: { | |
4510 PSEUDO: function(elem, match, i, array){ | |
4511 var name = match[1], filter = Expr.filters[ name ]; | |
4512 | |
4513 if ( filter ) { | |
4514 return filter( elem, i, match, array ); | |
4515 } else if ( name === "contains" ) { | |
4516 return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0; | |
4517 } else if ( name === "not" ) { | |
4518 var not = match[3]; | |
4519 | |
4520 for ( var i = 0, l = not.length; i < l; i++ ) { | |
4521 if ( not[i] === elem ) { | |
4522 return false; | |
4523 } | |
4524 } | |
4525 | |
4526 return true; | |
4527 } | |
4528 }, | |
4529 CHILD: function(elem, match){ | |
4530 var type = match[1], node = elem; | |
4531 switch (type) { | |
4532 case 'only': | |
4533 case 'first': | |
4534 while ( (node = node.previousSibling) ) { | |
4535 if ( node.nodeType === 1 ) return false; | |
4536 } | |
4537 if ( type == 'first') return true; | |
4538 node = elem; | |
4539 case 'last': | |
4540 while ( (node = node.nextSibling) ) { | |
4541 if ( node.nodeType === 1 ) return false; | |
4542 } | |
4543 return true; | |
4544 case 'nth': | |
4545 var first = match[2], last = match[3]; | |
4546 | |
4547 if ( first == 1 && last == 0 ) { | |
4548 return true; | |
4549 } | |
4550 | |
4551 var doneName = match[0], | |
4552 parent = elem.parentNode; | |
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 = ++count; | |
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") === match; | |
4574 }, | |
4575 TAG: function(elem, match){ | |
4576 return (match === "*" && elem.nodeType === 1) || elem.nodeName === 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; | |
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; | |
4678 if ( ret === 0 ) { | |
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.getAttributeNode !== "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" && elem.getAttributeNode("id"); | |
4738 return elem.nodeType === 1 && node && node.nodeValue === match; | |
4739 }; | |
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), extra ); | |
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 | |
4807 })(); | |
4808 | |
4809 if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (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 ) { | |
4873 elem.sizcache = doneName; | |
4874 elem.sizset = i; | |
4875 } | |
4876 elem = elem[dir]; | |
4877 var match = false; | |
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] ).length > 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 | |
4939 | |
4940 window.Sizzle = Sizzle; | |
4941 | |
4942 })(); | |
4943 | |
4944 ;(function(engine) { | |
4945 var extendElements = Prototype.Selector.extendElements; | |
4946 | |
4947 function select(selector, scope) { | |
4948 return extendElements(engine(selector, scope || document)); | |
4949 } | |
4950 | |
4951 function match(element, selector) { | |
4952 return engine.matches(selector, [element]).length == 1; | |
4953 } | |
4954 | |
4955 Prototype.Selector.engine = engine; | |
4956 Prototype.Selector.select = select; | |
4957 Prototype.Selector.match = match; | |
4958 })(Sizzle); | |
4959 | |
4960 window.Sizzle = Prototype._original_property; | |
4961 delete Prototype._original_property; | |
4962 | |
4963 var Form = { | |
4964 reset: function(form) { | |
4965 form = $(form); | |
4966 form.reset(); | |
4967 return form; | |
4968 }, | |
4969 | |
4970 serializeElements: function(elements, options) { | |
4971 if (typeof options != 'object') options = { hash: !!options }; | |
4972 else if (Object.isUndefined(options.hash)) options.hash = true; | |
4973 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) + '=' + encodeURIComponent(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 }; | |
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 }, | |
5071 | |
5072 request: function(form, options) { | |
5073 form = $(form), options = Object.clone(options || { }); | |
5074 | |
5075 var params = options.parameters, action = form.readAttribute('action') || ''; | |
5076 if (action.blank()) action = window.location.href; | |
5077 options.parameters = form.serialize(true); | |
5078 | |
5079 if (params) { | |
5080 if (Object.isString(params)) params = params.toQueryParams(); | |
5081 Object.extend(options.parameters, params); | |
5082 } | |
5083 | |
5084 if (form.hasAttribute('method') && !options.method) | |
5085 options.method = form.method; | |
5086 | |
5087 return new Ajax.Request(action, options); | |
5088 } | |
5089 }; | |
5090 | |
5091 /*--------------------------------------------------------------------------*/ | |
5092 | |
5093 | |
5094 Form.Element = { | |
5095 focus: function(element) { | |
5096 $(element).focus(); | |
5097 return element; | |
5098 }, | |
5099 | |
5100 select: function(element) { | |
5101 $(element).select(); | |
5102 return element; | |
5103 } | |
5104 }; | |
5105 | |
5106 Form.Element.Methods = { | |
5107 | |
5108 serialize: function(element) { | |
5109 element = $(element); | |
5110 if (!element.disabled && element.name) { | |
5111 var value = element.getValue(); | |
5112 if (value != undefined) { | |
5113 var pair = { }; | |
5114 pair[element.name] = value; | |
5115 return Object.toQueryString(pair); | |
5116 } | |
5117 } | |
5118 return ''; | |
5119 }, | |
5120 | |
5121 getValue: function(element) { | |
5122 element = $(element); | |
5123 var method = element.tagName.toLowerCase(); | |
5124 return Form.Element.Serializers[method](element); | |
5125 }, | |
5126 | |
5127 setValue: function(element, value) { | |
5128 element = $(element); | |
5129 var method = element.tagName.toLowerCase(); | |
5130 Form.Element.Serializers[method](element, value); | |
5131 return element; | |
5132 }, | |
5133 | |
5134 clear: function(element) { | |
5135 $(element).value = ''; | |
5136 return element; | |
5137 }, | |
5138 | |
5139 present: function(element) { | |
5140 return $(element).value != ''; | |
5141 }, | |
5142 | |
5143 activate: function(element) { | |
5144 element = $(element); | |
5145 try { | |
5146 element.focus(); | |
5147 if (element.select && (element.tagName.toLowerCase() != 'input' || | |
5148 !(/^(?:button|reset|submit)$/i.test(element.type)))) | |
5149 element.select(); | |
5150 } catch (e) { } | |
5151 return element; | |
5152 }, | |
5153 | |
5154 disable: function(element) { | |
5155 element = $(element); | |
5156 element.disabled = true; | |
5157 return element; | |
5158 }, | |
5159 | |
5160 enable: function(element) { | |
5161 element = $(element); | |
5162 element.disabled = false; | |
5163 return element; | |
5164 } | |
5165 }; | |
5166 | |
5167 /*--------------------------------------------------------------------------*/ | |
5168 | |
5169 var Field = Form.Element; | |
5170 | |
5171 var $F = Form.Element.Methods.getValue; | |
5172 | |
5173 /*--------------------------------------------------------------------------*/ | |
5174 | |
5175 Form.Element.Serializers = (function() { | |
5176 function input(element, value) { | |
5177 switch (element.type.toLowerCase()) { | |
5178 case 'checkbox': | |
5179 case 'radio': | |
5180 return inputSelector(element, value); | |
5181 default: | |
5182 return valueSelector(element, value); | |
5183 } | |
5184 } | |
5185 | |
5186 function inputSelector(element, value) { | |
5187 if (Object.isUndefined(value)) | |
5188 return element.checked ? element.value : null; | |
5189 else element.checked = !!value; | |
5190 } | |
5191 | |
5192 function valueSelector(element, value) { | |
5193 if (Object.isUndefined(value)) return element.value; | |
5194 else element.value = value; | |
5195 } | |
5196 | |
5197 function select(element, value) { | |
5198 if (Object.isUndefined(value)) | |
5199 return (element.type === 'select-one' ? selectOne : selectMany)(element); | |
5200 | |
5201 var opt, currentValue, single = !Object.isArray(value); | |
5202 for (var i = 0, length = element.length; i < length; i++) { | |
5203 opt = element.options[i]; | |
5204 currentValue = this.optionValue(opt); | |
5205 if (single) { | |
5206 if (currentValue == value) { | |
5207 opt.selected = true; | |
5208 return; | |
5209 } | |
5210 } | |
5211 else opt.selected = value.include(currentValue); | |
5212 } | |
5213 } | |
5214 | |
5215 function selectOne(element) { | |
5216 var index = element.selectedIndex; | |
5217 return index >= 0 ? optionValue(element.options[index]) : null; | |
5218 } | |
5219 | |
5220 function selectMany(element) { | |
5221 var values, length = element.length; | |
5222 if (!length) return null; | |
5223 | |
5224 for (var i = 0, values = []; i < length; i++) { | |
5225 var opt = element.options[i]; | |
5226 if (opt.selected) values.push(optionValue(opt)); | |
5227 } | |
5228 return values; | |
5229 } | |
5230 | |
5231 function optionValue(opt) { | |
5232 return Element.hasAttribute(opt, 'value') ? opt.value : opt.text; | |
5233 } | |
5234 | |
5235 return { | |
5236 input: input, | |
5237 inputSelector: inputSelector, | |
5238 textarea: valueSelector, | |
5239 select: select, | |
5240 selectOne: selectOne, | |
5241 selectMany: selectMany, | |
5242 optionValue: optionValue, | |
5243 button: valueSelector | |
5244 }; | |
5245 })(); | |
5246 | |
5247 /*--------------------------------------------------------------------------*/ | |
5248 | |
5249 | |
5250 Abstract.TimedObserver = Class.create(PeriodicalExecuter, { | |
5251 initialize: function($super, element, frequency, callback) { | |
5252 $super(callback, frequency); | |
5253 this.element = $(element); | |
5254 this.lastValue = this.getValue(); | |
5255 }, | |
5256 | |
5257 execute: function() { | |
5258 var value = this.getValue(); | |
5259 if (Object.isString(this.lastValue) && Object.isString(value) ? | |
5260 this.lastValue != value : String(this.lastValue) != String(value)) { | |
5261 this.callback(this.element, value); | |
5262 this.lastValue = value; | |
5263 } | |
5264 } | |
5265 }); | |
5266 | |
5267 Form.Element.Observer = Class.create(Abstract.TimedObserver, { | |
5268 getValue: function() { | |
5269 return Form.Element.getValue(this.element); | |
5270 } | |
5271 }); | |
5272 | |
5273 Form.Observer = Class.create(Abstract.TimedObserver, { | |
5274 getValue: function() { | |
5275 return Form.serialize(this.element); | |
5276 } | |
5277 }); | |
5278 | |
5279 /*--------------------------------------------------------------------------*/ | |
5280 | |
5281 Abstract.EventObserver = Class.create({ | |
5282 initialize: function(element, callback) { | |
5283 this.element = $(element); | |
5284 this.callback = callback; | |
5285 | |
5286 this.lastValue = this.getValue(); | |
5287 if (this.element.tagName.toLowerCase() == 'form') | |
5288 this.registerFormCallbacks(); | |
5289 else | |
5290 this.registerCallback(this.element); | |
5291 }, | |
5292 | |
5293 onElementEvent: function() { | |
5294 var value = this.getValue(); | |
5295 if (this.lastValue != value) { | |
5296 this.callback(this.element, value); | |
5297 this.lastValue = value; | |
5298 } | |
5299 }, | |
5300 | |
5301 registerFormCallbacks: function() { | |
5302 Form.getElements(this.element).each(this.registerCallback, this); | |
5303 }, | |
5304 | |
5305 registerCallback: function(element) { | |
5306 if (element.type) { | |
5307 switch (element.type.toLowerCase()) { | |
5308 case 'checkbox': | |
5309 case 'radio': | |
5310 Event.observe(element, 'click', this.onElementEvent.bind(this)); | |
5311 break; | |
5312 default: | |
5313 Event.observe(element, 'change', this.onElementEvent.bind(this)); | |
5314 break; | |
5315 } | |
5316 } | |
5317 } | |
5318 }); | |
5319 | |
5320 Form.Element.EventObserver = Class.create(Abstract.EventObserver, { | |
5321 getValue: function() { | |
5322 return Form.Element.getValue(this.element); | |
5323 } | |
5324 }); | |
5325 | |
5326 Form.EventObserver = Class.create(Abstract.EventObserver, { | |
5327 getValue: function() { | |
5328 return Form.serialize(this.element); | |
5329 } | |
5330 }); | |
5331 (function() { | |
5332 | |
5333 var Event = { | |
5334 KEY_BACKSPACE: 8, | |
5335 KEY_TAB: 9, | |
5336 KEY_RETURN: 13, | |
5337 KEY_ESC: 27, | |
5338 KEY_LEFT: 37, | |
5339 KEY_UP: 38, | |
5340 KEY_RIGHT: 39, | |
5341 KEY_DOWN: 40, | |
5342 KEY_DELETE: 46, | |
5343 KEY_HOME: 36, | |
5344 KEY_END: 35, | |
5345 KEY_PAGEUP: 33, | |
5346 KEY_PAGEDOWN: 34, | |
5347 KEY_INSERT: 45, | |
5348 | |
5349 cache: {} | |
5350 }; | |
5351 | |
5352 var docEl = document.documentElement; | |
5353 var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl | |
5354 && 'onmouseleave' in docEl; | |
5355 | |
5356 | |
5357 | |
5358 var isIELegacyEvent = function(event) { return false; }; | |
5359 | |
5360 if (window.attachEvent) { | |
5361 if (window.addEventListener) { | |
5362 isIELegacyEvent = function(event) { | |
5363 return !(event instanceof window.Event); | |
5364 }; | |
5365 } else { | |
5366 isIELegacyEvent = function(event) { return true; }; | |
5367 } | |
5368 } | |
5369 | |
5370 var _isButton; | |
5371 | |
5372 function _isButtonForDOMEvents(event, code) { | |
5373 return event.which ? (event.which === code + 1) : (event.button === code); | |
5374 } | |
5375 | |
5376 var legacyButtonMap = { 0: 1, 1: 4, 2: 2 }; | |
5377 function _isButtonForLegacyEvents(event, code) { | |
5378 return event.button === legacyButtonMap[code]; | |
5379 } | |
5380 | |
5381 function _isButtonForWebKit(event, code) { | |
5382 switch (code) { | |
5383 case 0: return event.which == 1 && !event.metaKey; | |
5384 case 1: return event.which == 2 || (event.which == 1 && event.metaKey); | |
5385 case 2: return event.which == 3; | |
5386 default: return false; | |
5387 } | |
5388 } | |
5389 | |
5390 if (window.attachEvent) { | |
5391 if (!window.addEventListener) { | |
5392 _isButton = _isButtonForLegacyEvents; | |
5393 } else { | |
5394 _isButton = function(event, code) { | |
5395 return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) : | |
5396 _isButtonForDOMEvents(event, code); | |
5397 } | |
5398 } | |
5399 } else if (Prototype.Browser.WebKit) { | |
5400 _isButton = _isButtonForWebKit; | |
5401 } else { | |
5402 _isButton = _isButtonForDOMEvents; | |
5403 } | |
5404 | |
5405 function isLeftClick(event) { return _isButton(event, 0) } | |
5406 | |
5407 function isMiddleClick(event) { return _isButton(event, 1) } | |
5408 | |
5409 function isRightClick(event) { return _isButton(event, 2) } | |
5410 | |
5411 function element(event) { | |
5412 event = Event.extend(event); | |
5413 | |
5414 var node = event.target, type = event.type, | |
5415 currentTarget = event.currentTarget; | |
5416 | |
5417 if (currentTarget && currentTarget.tagName) { | |
5418 if (type === 'load' || type === 'error' || | |
5419 (type === 'click' && currentTarget.tagName.toLowerCase() === 'input' | |
5420 && currentTarget.type === 'radio')) | |
5421 node = currentTarget; | |
5422 } | |
5423 | |
5424 if (node.nodeType == Node.TEXT_NODE) | |
5425 node = node.parentNode; | |
5426 | |
5427 return Element.extend(node); | |
5428 } | |
5429 | |
5430 function findElement(event, expression) { | |
5431 var element = Event.element(event); | |
5432 | |
5433 if (!expression) return element; | |
5434 while (element) { | |
5435 if (Object.isElement(element) && Prototype.Selector.match(element, expression)) { | |
5436 return Element.extend(element); | |
5437 } | |
5438 element = element.parentNode; | |
5439 } | |
5440 } | |
5441 | |
5442 function pointer(event) { | |
5443 return { x: pointerX(event), y: pointerY(event) }; | |
5444 } | |
5445 | |
5446 function pointerX(event) { | |
5447 var docElement = document.documentElement, | |
5448 body = document.body || { scrollLeft: 0 }; | |
5449 | |
5450 return event.pageX || (event.clientX + | |
5451 (docElement.scrollLeft || body.scrollLeft) - | |
5452 (docElement.clientLeft || 0)); | |
5453 } | |
5454 | |
5455 function pointerY(event) { | |
5456 var docElement = document.documentElement, | |
5457 body = document.body || { scrollTop: 0 }; | |
5458 | |
5459 return event.pageY || (event.clientY + | |
5460 (docElement.scrollTop || body.scrollTop) - | |
5461 (docElement.clientTop || 0)); | |
5462 } | |
5463 | |
5464 | |
5465 function stop(event) { | |
5466 Event.extend(event); | |
5467 event.preventDefault(); | |
5468 event.stopPropagation(); | |
5469 | |
5470 event.stopped = true; | |
5471 } | |
5472 | |
5473 | |
5474 Event.Methods = { | |
5475 isLeftClick: isLeftClick, | |
5476 isMiddleClick: isMiddleClick, | |
5477 isRightClick: isRightClick, | |
5478 | |
5479 element: element, | |
5480 findElement: findElement, | |
5481 | |
5482 pointer: pointer, | |
5483 pointerX: pointerX, | |
5484 pointerY: pointerY, | |
5485 | |
5486 stop: stop | |
5487 }; | |
5488 | |
5489 var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { | |
5490 m[name] = Event.Methods[name].methodize(); | |
5491 return m; | |
5492 }); | |
5493 | |
5494 if (window.attachEvent) { | |
5495 function _relatedTarget(event) { | |
5496 var element; | |
5497 switch (event.type) { | |
5498 case 'mouseover': | |
5499 case 'mouseenter': | |
5500 element = event.fromElement; | |
5501 break; | |
5502 case 'mouseout': | |
5503 case 'mouseleave': | |
5504 element = event.toElement; | |
5505 break; | |
5506 default: | |
5507 return null; | |
5508 } | |
5509 return Element.extend(element); | |
5510 } | |
5511 | |
5512 var additionalMethods = { | |
5513 stopPropagation: function() { this.cancelBubble = true }, | |
5514 preventDefault: function() { this.returnValue = false }, | |
5515 inspect: function() { return '[object Event]' } | |
5516 }; | |
5517 | |
5518 Event.extend = function(event, element) { | |
5519 if (!event) return false; | |
5520 | |
5521 if (!isIELegacyEvent(event)) return event; | |
5522 | |
5523 if (event._extendedByPrototype) return event; | |
5524 event._extendedByPrototype = Prototype.emptyFunction; | |
5525 | |
5526 var pointer = Event.pointer(event); | |
5527 | |
5528 Object.extend(event, { | |
5529 target: event.srcElement || element, | |
5530 relatedTarget: _relatedTarget(event), | |
5531 pageX: pointer.x, | |
5532 pageY: pointer.y | |
5533 }); | |
5534 | |
5535 Object.extend(event, methods); | |
5536 Object.extend(event, additionalMethods); | |
5537 | |
5538 return event; | |
5539 }; | |
5540 } else { | |
5541 Event.extend = Prototype.K; | |
5542 } | |
5543 | |
5544 if (window.addEventListener) { | |
5545 Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__; | |
5546 Object.extend(Event.prototype, methods); | |
5547 } | |
5548 | |
5549 function _createResponder(element, eventName, handler) { | |
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 } | |
5613 } | |
5614 | |
5615 var CACHE = []; | |
5616 | |
5617 if (Prototype.Browser.IE) | |
5618 window.attachEvent('onunload', _destroyCache); | |
5619 | |
5620 if (Prototype.Browser.WebKit) | |
5621 window.addEventListener('unload', Prototype.emptyFunction, false); | |
5622 | |
5623 | |
5624 var _getDOMEventName = Prototype.K, | |
5625 translations = { mouseenter: "mouseover", mouseleave: "mouseout" }; | |
5626 | |
5627 if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) { | |
5628 _getDOMEventName = function(eventName) { | |
5629 return (translations[eventName] || eventName); | |
5630 }; | |
5631 } | |
5632 | |
5633 function observe(element, eventName, handler) { | |
5634 element = $(element); | |
5635 | |
5636 var responder = _createResponder(element, eventName, handler); | |
5637 | |
5638 if (!responder) return element; | |
5639 | |
5640 if (eventName.include(':')) { | |
5641 if (element.addEventListener) | |
5642 element.addEventListener("dataavailable", responder, false); | |
5643 else { | |
5644 element.attachEvent("ondataavailable", responder); | |
5645 element.attachEvent("onlosecapture", responder); | |
5646 } | |
5647 } else { | |
5648 var actualEventName = _getDOMEventName(eventName); | |
5649 | |
5650 if (element.addEventListener) | |
5651 element.addEventListener(actualEventName, responder, false); | |
5652 else | |
5653 element.attachEvent("on" + actualEventName, responder); | |
5654 } | |
5655 | |
5656 return element; | |
5657 } | |
5658 | |
5659 function stopObserving(element, eventName, handler) { | |
5660 element = $(element); | |
5661 | |
5662 var registry = Element.retrieve(element, 'prototype_event_registry'); | |
5663 if (!registry) return element; | |
5664 | |
5665 if (!eventName) { | |
5666 registry.each( function(pair) { | |
5667 var eventName = pair.key; | |
5668 stopObserving(element, eventName); | |
5669 }); | |
5670 return element; | |
5671 } | |
5672 | |
5673 var responders = registry.get(eventName); | |
5674 if (!responders) return element; | |
5675 | |
5676 if (!handler) { | |
5677 responders.each(function(r) { | |
5678 stopObserving(element, eventName, r.handler); | |
5679 }); | |
5680 return element; | |
5681 } | |
5682 | |
5683 var i = responders.length, responder; | |
5684 while (i--) { | |
5685 if (responders[i].handler === handler) { | |
5686 responder = responders[i]; | |
5687 break; | |
5688 } | |
5689 } | |
5690 if (!responder) return element; | |
5691 | |
5692 if (eventName.include(':')) { | |
5693 if (element.removeEventListener) | |
5694 element.removeEventListener("dataavailable", responder, false); | |
5695 else { | |
5696 element.detachEvent("ondataavailable", responder); | |
5697 element.detachEvent("onlosecapture", responder); | |
5698 } | |
5699 } else { | |
5700 var actualEventName = _getDOMEventName(eventName); | |
5701 if (element.removeEventListener) | |
5702 element.removeEventListener(actualEventName, responder, false); | |
5703 else | |
5704 element.detachEvent('on' + actualEventName, responder); | |
5705 } | |
5706 | |
5707 registry.set(eventName, responders.without(responder)); | |
5708 | |
5709 return element; | |
5710 } | |
5711 | |
5712 function fire(element, eventName, memo, bubble) { | |
5713 element = $(element); | |
5714 | |
5715 if (Object.isUndefined(bubble)) | |
5716 bubble = true; | |
5717 | |
5718 if (element == document && document.createEvent && !element.dispatchEvent) | |
5719 element = document.documentElement; | |
5720 | |
5721 var event; | |
5722 if (document.createEvent) { | |
5723 event = document.createEvent('HTMLEvents'); | |
5724 event.initEvent('dataavailable', bubble, true); | |
5725 } else { | |
5726 event = document.createEventObject(); | |
5727 event.eventType = bubble ? 'ondataavailable' : 'onlosecapture'; | |
5728 } | |
5729 | |
5730 event.eventName = eventName; | |
5731 event.memo = memo || { }; | |
5732 | |
5733 if (document.createEvent) | |
5734 element.dispatchEvent(event); | |
5735 else | |
5736 element.fireEvent(event.eventType, event); | |
5737 | |
5738 return Event.extend(event); | |
5739 } | |
5740 | |
5741 Event.Handler = Class.create({ | |
5742 initialize: function(element, eventName, selector, callback) { | |
5743 this.element = $(element); | |
5744 this.eventName = eventName; | |
5745 this.selector = selector; | |
5746 this.callback = callback; | |
5747 this.handler = this.handleEvent.bind(this); | |
5748 }, | |
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() { | |
5817 if (document.loaded) return; | |
5818 if (timer) window.clearTimeout(timer); | |
5819 document.loaded = true; | |
5820 document.fire('dom:loaded'); | |
5821 } | |
5822 | |
5823 function checkReadyState() { | |
5824 if (document.readyState === 'complete') { | |
5825 document.stopObserving('readystatechange', checkReadyState); | |
5826 fireContentLoadedEvent(); | |
5827 } | |
5828 } | |
5829 | |
5830 function pollDoScroll() { | |
5831 try { document.documentElement.doScroll('left'); } | |
5832 catch(e) { | |
5833 timer = pollDoScroll.defer(); | |
5834 return; | |
5835 } | |
5836 fireContentLoadedEvent(); | |
5837 } | |
5838 | |
5839 if (document.addEventListener) { | |
5840 document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false); | |
5841 } else { | |
5842 document.observe('readystatechange', checkReadyState); | |
5843 if (window == top) | |
5844 timer = pollDoScroll.defer(); | |
5845 } | |
5846 | |
5847 Event.observe(window, 'load', fireContentLoadedEvent); | |
5848 })(); | |
5849 | |
5850 Element.addMethods(); | |
5851 | |
5852 /*------------------------------- DEPRECATED -------------------------------*/ | |
5853 | |
5854 Hash.toQueryString = Object.toQueryString; | |
5855 | |
5856 var Toggle = { display: Element.toggle }; | |
5857 | |
5858 Element.Methods.childOf = Element.Methods.descendantOf; | |
5859 | |
5860 var Insertion = { | |
5861 Before: function(element, content) { | |
5862 return Element.insert(element, {before:content}); | |
5863 }, | |
5864 | |
5865 Top: function(element, content) { | |
5866 return Element.insert(element, {top:content}); | |
5867 }, | |
5868 | |
5869 Bottom: function(element, content) { | |
5870 return Element.insert(element, {bottom:content}); | |
5871 }, | |
5872 | |
5873 After: function(element, content) { | |
5874 return Element.insert(element, {after:content}); | |
5875 } | |
5876 }; | |
5877 | |
5878 var $continue = new Error('"throw $continue" is deprecated, use "return" instead'); | |
5879 | |
5880 var Position = { | |
5881 includeScrollOffsets: false, | |
5882 | |
5883 prepare: function() { | |
5884 this.deltaX = window.pageXOffset | |
5885 || document.documentElement.scrollLeft | |
5886 || document.body.scrollLeft | |
5887 || 0; | |
5888 this.deltaY = window.pageYOffset | |
5889 || document.documentElement.scrollTop | |
5890 || document.body.scrollTop | |
5891 || 0; | |
5892 }, | |
5893 | |
5894 within: function(element, x, y) { | |
5895 if (this.includeScrollOffsets) | |
5896 return this.withinIncludingScrolloffsets(element, x, y); | |
5897 this.xcomp = x; | |
5898 this.ycomp = y; | |
5899 this.offset = Element.cumulativeOffset(element); | |
5900 | |
5901 return (y >= this.offset[1] && | |
5902 y < this.offset[1] + element.offsetHeight && | |
5903 x >= this.offset[0] && | |
5904 x < this.offset[0] + element.offsetWidth); | |
5905 }, | |
5906 | |
5907 withinIncludingScrolloffsets: function(element, x, y) { | |
5908 var offsetcache = Element.cumulativeScrollOffset(element); | |
5909 | |
5910 this.xcomp = x + offsetcache[0] - this.deltaX; | |
5911 this.ycomp = y + offsetcache[1] - this.deltaY; | |
5912 this.offset = Element.cumulativeOffset(element); | |
5913 | |
5914 return (this.ycomp >= this.offset[1] && | |
5915 this.ycomp < this.offset[1] + element.offsetHeight && | |
5916 this.xcomp >= this.offset[0] && | |
5917 this.xcomp < this.offset[0] + element.offsetWidth); | |
5918 }, | |
5919 | |
5920 overlap: function(mode, element) { | |
5921 if (!mode) return 0; | |
5922 if (mode == 'vertical') | |
5923 return ((this.offset[1] + element.offsetHeight) - this.ycomp) / | |
5924 element.offsetHeight; | |
5925 if (mode == 'horizontal') | |
5926 return ((this.offset[0] + element.offsetWidth) - this.xcomp) / | |
5927 element.offsetWidth; | |
5928 }, | |
5929 | |
5930 | |
5931 cumulativeOffset: Element.Methods.cumulativeOffset, | |
5932 | |
5933 positionedOffset: Element.Methods.positionedOffset, | |
5934 | |
5935 absolutize: function(element) { | |
5936 Position.prepare(); | |
5937 return Element.absolutize(element); | |
5938 }, | |
5939 | |
5940 relativize: function(element) { | |
5941 Position.prepare(); | |
5942 return Element.relativize(element); | |
5943 }, | |
5944 | |
5945 realOffset: Element.Methods.cumulativeScrollOffset, | |
5946 | |
5947 offsetParent: Element.Methods.getOffsetParent, | |
5948 | |
5949 page: Element.Methods.viewportOffset, | |
5950 | |
5951 clone: function(source, target, options) { | |
5952 options = options || { }; | |
5953 return Element.clonePosition(target, source, options); | |
5954 } | |
5955 }; | |
5956 | |
5957 /*--------------------------------------------------------------------------*/ | |
5958 | |
5959 if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){ | |
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(className); | |
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(className) || | |
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; | |
6017 this.set($A(this).without(classNameToRemove).join(' ')); | |
6018 }, | |
6019 | |
6020 toString: function() { | |
6021 return $A(this).join(' '); | |
6022 } | |
6023 }; | |
6024 | |
6025 Object.extend(Element.ClassNames.prototype, Enumerable); | |
6026 | |
6027 /*--------------------------------------------------------------------------*/ | |
6028 | |
6029 (function() { | |
6030 window.Selector = Class.create({ | |
6031 initialize: function(expression) { | |
6032 this.expression = expression.strip(); | |
6033 }, | |
6034 | |
6035 findElements: function(rootElement) { | |
6036 return Prototype.Selector.select(this.expression, rootElement); | |
6037 }, | |
6038 | |
6039 match: function(element) { | |
6040 return Prototype.Selector.match(element, this.expression); | |
6041 }, | |
6042 | |
6043 toString: function() { | |
6044 return this.expression; | |
6045 }, | |
6046 | |
6047 inspect: function() { | |
6048 return "#<Selector: " + this.expression + ">"; | |
6049 } | |
6050 }); | |
6051 | |
6052 Object.extend(Selector, { | |
6053 matchElements: function(elements, expression) { | |
6054 var match = Prototype.Selector.match, | |
6055 results = []; | |
6056 | |
6057 for (var i = 0, length = elements.length; i < length; i++) { | |
6058 var element = elements[i]; | |
6059 if (match(element, expression)) { | |
6060 results.push(Element.extend(element)); | |
6061 } | |
6062 } | |
6063 return results; | |
6064 }, | |
6065 | |
6066 findElement: function(elements, expression, index) { | |
6067 index = index || 0; | |
6068 var matchIndex = 0, element; | |
6069 for (var i = 0, length = elements.length; i < length; i++) { | |
6070 element = elements[i]; | |
6071 if (Prototype.Selector.match(element, expression) && index === matchIndex++) { | |
6072 return Element.extend(element); | |
6073 } | |
6074 } | |
6075 }, | |
6076 | |
6077 findChildElements: function(element, expressions) { | |
6078 var selector = expressions.toArray().join(', '); | |
6079 return Prototype.Selector.select(selector, element || document); | |
6080 } | |
6081 }); | |
6082 })(); |