/public/prototype.js

http://github.com/mtravers/wuwei · JavaScript · 6081 lines · 5622 code · 440 blank · 19 comment · 520 complexity · 007ae2fe795811f80cedf92fdb591c1b MD5 · raw file

Large files are truncated click here to view the full file

  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. var Prototype = {
  9. Version: '1.7',
  10. Browser: (function(){
  11. var ua = navigator.userAgent;
  12. var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
  13. return {
  14. IE: !!window.attachEvent && !isOpera,
  15. Opera: isOpera,
  16. WebKit: ua.indexOf('AppleWebKit/') > -1,
  17. Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
  18. MobileSafari: /Apple.*Mobile/.test(ua)
  19. }
  20. })(),
  21. BrowserFeatures: {
  22. XPath: !!document.evaluate,
  23. SelectorsAPI: !!document.querySelector,
  24. ElementExtensions: (function() {
  25. var constructor = window.Element || window.HTMLElement;
  26. return !!(constructor && constructor.prototype);
  27. })(),
  28. SpecificElementExtensions: (function() {
  29. if (typeof window.HTMLDivElement !== 'undefined')
  30. return true;
  31. var div = document.createElement('div'),
  32. form = document.createElement('form'),
  33. isSupported = false;
  34. if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
  35. isSupported = true;
  36. }
  37. div = form = null;
  38. return isSupported;
  39. })()
  40. },
  41. ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
  42. JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
  43. emptyFunction: function() { },
  44. K: function(x) { return x }
  45. };
  46. if (Prototype.Browser.MobileSafari)
  47. Prototype.BrowserFeatures.SpecificElementExtensions = false;
  48. /* Based on Alex Arnell's inheritance implementation. */
  49. var Class = (function() {
  50. var IS_DONTENUM_BUGGY = (function(){
  51. for (var p in { toString: 1 }) {
  52. if (p === 'toString') return false;
  53. }
  54. return true;
  55. })();
  56. function subclass() {};
  57. function create() {
  58. var parent = null, properties = $A(arguments);
  59. if (Object.isFunction(properties[0]))
  60. parent = properties.shift();
  61. function klass() {
  62. this.initialize.apply(this, arguments);
  63. }
  64. Object.extend(klass, Class.Methods);
  65. klass.superclass = parent;
  66. klass.subclasses = [];
  67. if (parent) {
  68. subclass.prototype = parent.prototype;
  69. klass.prototype = new subclass;
  70. parent.subclasses.push(klass);
  71. }
  72. for (var i = 0, length = properties.length; i < length; i++)
  73. klass.addMethods(properties[i]);
  74. if (!klass.prototype.initialize)
  75. klass.prototype.initialize = Prototype.emptyFunction;
  76. klass.prototype.constructor = klass;
  77. return klass;
  78. }
  79. function addMethods(source) {
  80. var ancestor = this.superclass && this.superclass.prototype,
  81. properties = Object.keys(source);
  82. if (IS_DONTENUM_BUGGY) {
  83. if (source.toString != Object.prototype.toString)
  84. properties.push("toString");
  85. if (source.valueOf != Object.prototype.valueOf)
  86. properties.push("valueOf");
  87. }
  88. for (var i = 0, length = properties.length; i < length; i++) {
  89. var property = properties[i], value = source[property];
  90. if (ancestor && Object.isFunction(value) &&
  91. value.argumentNames()[0] == "$super") {
  92. var method = value;
  93. value = (function(m) {
  94. return function() { return ancestor[m].apply(this, arguments); };
  95. })(property).wrap(method);
  96. value.valueOf = method.valueOf.bind(method);
  97. value.toString = method.toString.bind(method);
  98. }
  99. this.prototype[property] = value;
  100. }
  101. return this;
  102. }
  103. return {
  104. create: create,
  105. Methods: {
  106. addMethods: addMethods
  107. }
  108. };
  109. })();
  110. (function() {
  111. var _toString = Object.prototype.toString,
  112. NULL_TYPE = 'Null',
  113. UNDEFINED_TYPE = 'Undefined',
  114. BOOLEAN_TYPE = 'Boolean',
  115. NUMBER_TYPE = 'Number',
  116. STRING_TYPE = 'String',
  117. OBJECT_TYPE = 'Object',
  118. FUNCTION_CLASS = '[object Function]',
  119. BOOLEAN_CLASS = '[object Boolean]',
  120. NUMBER_CLASS = '[object Number]',
  121. STRING_CLASS = '[object String]',
  122. ARRAY_CLASS = '[object Array]',
  123. DATE_CLASS = '[object Date]',
  124. NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
  125. typeof JSON.stringify === 'function' &&
  126. JSON.stringify(0) === '0' &&
  127. typeof JSON.stringify(Prototype.K) === 'undefined';
  128. function Type(o) {
  129. switch(o) {
  130. case null: return NULL_TYPE;
  131. case (void 0): return UNDEFINED_TYPE;
  132. }
  133. var type = typeof o;
  134. switch(type) {
  135. case 'boolean': return BOOLEAN_TYPE;
  136. case 'number': return NUMBER_TYPE;
  137. case 'string': return STRING_TYPE;
  138. }
  139. return OBJECT_TYPE;
  140. }
  141. function extend(destination, source) {
  142. for (var property in source)
  143. destination[property] = source[property];
  144. return destination;
  145. }
  146. function inspect(object) {
  147. try {
  148. if (isUndefined(object)) return 'undefined';
  149. if (object === null) return 'null';
  150. return object.inspect ? object.inspect() : String(object);
  151. } catch (e) {
  152. if (e instanceof RangeError) return '...';
  153. throw e;
  154. }
  155. }
  156. function toJSON(value) {
  157. return Str('', { '': value }, []);
  158. }
  159. function Str(key, holder, stack) {
  160. var value = holder[key],
  161. type = typeof value;
  162. if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') {
  163. value = value.toJSON(key);
  164. }
  165. var _class = _toString.call(value);
  166. switch (_class) {
  167. case NUMBER_CLASS:
  168. case BOOLEAN_CLASS:
  169. case STRING_CLASS:
  170. value = value.valueOf();
  171. }
  172. switch (value) {
  173. case null: return 'null';
  174. case true: return 'true';
  175. case false: return 'false';
  176. }
  177. type = typeof value;
  178. switch (type) {
  179. case 'string':
  180. return value.inspect(true);
  181. case 'number':
  182. return isFinite(value) ? String(value) : 'null';
  183. case 'object':
  184. for (var i = 0, length = stack.length; i < length; i++) {
  185. if (stack[i] === value) { throw new TypeError(); }
  186. }
  187. stack.push(value);
  188. var partial = [];
  189. if (_class === ARRAY_CLASS) {
  190. for (var i = 0, length = value.length; i < length; i++) {
  191. var str = Str(i, value, stack);
  192. partial.push(typeof str === 'undefined' ? 'null' : str);
  193. }
  194. partial = '[' + partial.join(',') + ']';
  195. } else {
  196. var keys = Object.keys(value);
  197. for (var i = 0, length = keys.length; i < length; i++) {
  198. var key = keys[i], str = Str(key, value, stack);
  199. if (typeof str !== "undefined") {
  200. partial.push(key.inspect(true)+ ':' + str);
  201. }
  202. }
  203. partial = '{' + partial.join(',') + '}';
  204. }
  205. stack.pop();
  206. return partial;
  207. }
  208. }
  209. function stringify(object) {
  210. return JSON.stringify(object);
  211. }
  212. function toQueryString(object) {
  213. return $H(object).toQueryString();
  214. }
  215. function toHTML(object) {
  216. return object && object.toHTML ? object.toHTML() : String.interpret(object);
  217. }
  218. function keys(object) {
  219. if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
  220. var results = [];
  221. for (var property in object) {
  222. if (object.hasOwnProperty(property)) {
  223. results.push(property);
  224. }
  225. }
  226. return results;
  227. }
  228. function values(object) {
  229. var results = [];
  230. for (var property in object)
  231. results.push(object[property]);
  232. return results;
  233. }
  234. function clone(object) {
  235. return extend({ }, object);
  236. }
  237. function isElement(object) {
  238. return !!(object && object.nodeType == 1);
  239. }
  240. function isArray(object) {
  241. return _toString.call(object) === ARRAY_CLASS;
  242. }
  243. var hasNativeIsArray = (typeof Array.isArray == 'function')
  244. && Array.isArray([]) && !Array.isArray({});
  245. if (hasNativeIsArray) {
  246. isArray = Array.isArray;
  247. }
  248. function isHash(object) {
  249. return object instanceof Hash;
  250. }
  251. function isFunction(object) {
  252. return _toString.call(object) === FUNCTION_CLASS;
  253. }
  254. function isString(object) {
  255. return _toString.call(object) === STRING_CLASS;
  256. }
  257. function isNumber(object) {
  258. return _toString.call(object) === NUMBER_CLASS;
  259. }
  260. function isDate(object) {
  261. return _toString.call(object) === DATE_CLASS;
  262. }
  263. function isUndefined(object) {
  264. return typeof object === "undefined";
  265. }
  266. extend(Object, {
  267. extend: extend,
  268. inspect: inspect,
  269. toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
  270. toQueryString: toQueryString,
  271. toHTML: toHTML,
  272. keys: Object.keys || keys,
  273. values: values,
  274. clone: clone,
  275. isElement: isElement,
  276. isArray: isArray,
  277. isHash: isHash,
  278. isFunction: isFunction,
  279. isString: isString,
  280. isNumber: isNumber,
  281. isDate: isDate,
  282. isUndefined: isUndefined
  283. });
  284. })();
  285. Object.extend(Function.prototype, (function() {
  286. var slice = Array.prototype.slice;
  287. function update(array, args) {
  288. var arrayLength = array.length, length = args.length;
  289. while (length--) array[arrayLength + length] = args[length];
  290. return array;
  291. }
  292. function merge(array, args) {
  293. array = slice.call(array, 0);
  294. return update(array, args);
  295. }
  296. function argumentNames() {
  297. var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
  298. .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
  299. .replace(/\s+/g, '').split(',');
  300. return names.length == 1 && !names[0] ? [] : names;
  301. }
  302. function bind(context) {
  303. if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
  304. var __method = this, args = slice.call(arguments, 1);
  305. return function() {
  306. var a = merge(args, arguments);
  307. return __method.apply(context, a);
  308. }
  309. }
  310. function bindAsEventListener(context) {
  311. var __method = this, args = slice.call(arguments, 1);
  312. return function(event) {
  313. var a = update([event || window.event], args);
  314. return __method.apply(context, a);
  315. }
  316. }
  317. function curry() {
  318. if (!arguments.length) return this;
  319. var __method = this, args = slice.call(arguments, 0);
  320. return function() {
  321. var a = merge(args, arguments);
  322. return __method.apply(this, a);
  323. }
  324. }
  325. function delay(timeout) {
  326. var __method = this, args = slice.call(arguments, 1);
  327. timeout = timeout * 1000;
  328. return window.setTimeout(function() {
  329. return __method.apply(__method, args);
  330. }, timeout);
  331. }
  332. function defer() {
  333. var args = update([0.01], arguments);
  334. return this.delay.apply(this, args);
  335. }
  336. function wrap(wrapper) {
  337. var __method = this;
  338. return function() {
  339. var a = update([__method.bind(this)], arguments);
  340. return wrapper.apply(this, a);
  341. }
  342. }
  343. function methodize() {
  344. if (this._methodized) return this._methodized;
  345. var __method = this;
  346. return this._methodized = function() {
  347. var a = update([this], arguments);
  348. return __method.apply(null, a);
  349. };
  350. }
  351. return {
  352. argumentNames: argumentNames,
  353. bind: bind,
  354. bindAsEventListener: bindAsEventListener,
  355. curry: curry,
  356. delay: delay,
  357. defer: defer,
  358. wrap: wrap,
  359. methodize: methodize
  360. }
  361. })());
  362. (function(proto) {
  363. function toISOString() {
  364. return this.getUTCFullYear() + '-' +
  365. (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
  366. this.getUTCDate().toPaddedString(2) + 'T' +
  367. this.getUTCHours().toPaddedString(2) + ':' +
  368. this.getUTCMinutes().toPaddedString(2) + ':' +
  369. this.getUTCSeconds().toPaddedString(2) + 'Z';
  370. }
  371. function toJSON() {
  372. return this.toISOString();
  373. }
  374. if (!proto.toISOString) proto.toISOString = toISOString;
  375. if (!proto.toJSON) proto.toJSON = toJSON;
  376. })(Date.prototype);
  377. RegExp.prototype.match = RegExp.prototype.test;
  378. RegExp.escape = function(str) {
  379. return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
  380. };
  381. var PeriodicalExecuter = Class.create({
  382. initialize: function(callback, frequency) {
  383. this.callback = callback;
  384. this.frequency = frequency;
  385. this.currentlyExecuting = false;
  386. this.registerCallback();
  387. },
  388. registerCallback: function() {
  389. this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
  390. },
  391. execute: function() {
  392. this.callback(this);
  393. },
  394. stop: function() {
  395. if (!this.timer) return;
  396. clearInterval(this.timer);
  397. this.timer = null;
  398. },
  399. onTimerEvent: function() {
  400. if (!this.currentlyExecuting) {
  401. try {
  402. this.currentlyExecuting = true;
  403. this.execute();
  404. this.currentlyExecuting = false;
  405. } catch(e) {
  406. this.currentlyExecuting = false;
  407. throw e;
  408. }
  409. }
  410. }
  411. });
  412. Object.extend(String, {
  413. interpret: function(value) {
  414. return value == null ? '' : String(value);
  415. },
  416. specialChar: {
  417. '\b': '\\b',
  418. '\t': '\\t',
  419. '\n': '\\n',
  420. '\f': '\\f',
  421. '\r': '\\r',
  422. '\\': '\\\\'
  423. }
  424. });
  425. Object.extend(String.prototype, (function() {
  426. var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
  427. typeof JSON.parse === 'function' &&
  428. JSON.parse('{"test": true}').test;
  429. function prepareReplacement(replacement) {
  430. if (Object.isFunction(replacement)) return replacement;
  431. var template = new Template(replacement);
  432. return function(match) { return template.evaluate(match) };
  433. }
  434. function gsub(pattern, replacement) {
  435. var result = '', source = this, match;
  436. replacement = prepareReplacement(replacement);
  437. if (Object.isString(pattern))
  438. pattern = RegExp.escape(pattern);
  439. if (!(pattern.length || pattern.source)) {
  440. replacement = replacement('');
  441. return replacement + source.split('').join(replacement) + replacement;
  442. }
  443. while (source.length > 0) {
  444. if (match = source.match(pattern)) {
  445. result += source.slice(0, match.index);
  446. result += String.interpret(replacement(match));
  447. source = source.slice(match.index + match[0].length);
  448. } else {
  449. result += source, source = '';
  450. }
  451. }
  452. return result;
  453. }
  454. function sub(pattern, replacement, count) {
  455. replacement = prepareReplacement(replacement);
  456. count = Object.isUndefined(count) ? 1 : count;
  457. return this.gsub(pattern, function(match) {
  458. if (--count < 0) return match[0];
  459. return replacement(match);
  460. });
  461. }
  462. function scan(pattern, iterator) {
  463. this.gsub(pattern, iterator);
  464. return String(this);
  465. }
  466. function truncate(length, truncation) {
  467. length = length || 30;
  468. truncation = Object.isUndefined(truncation) ? '...' : truncation;
  469. return this.length > length ?
  470. this.slice(0, length - truncation.length) + truncation : String(this);
  471. }
  472. function strip() {
  473. return this.replace(/^\s+/, '').replace(/\s+$/, '');
  474. }
  475. function stripTags() {
  476. return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
  477. }
  478. function stripScripts() {
  479. return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
  480. }
  481. function extractScripts() {
  482. var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
  483. matchOne = new RegExp(Prototype.ScriptFragment, 'im');
  484. return (this.match(matchAll) || []).map(function(scriptTag) {
  485. return (scriptTag.match(matchOne) || ['', ''])[1];
  486. });
  487. }
  488. function evalScripts() {
  489. return this.extractScripts().map(function(script) { return eval(script) });
  490. }
  491. function escapeHTML() {
  492. return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
  493. }
  494. function unescapeHTML() {
  495. return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
  496. }
  497. function toQueryParams(separator) {
  498. var match = this.strip().match(/([^?#]*)(#.*)?$/);
  499. if (!match) return { };
  500. return match[1].split(separator || '&').inject({ }, function(hash, pair) {
  501. if ((pair = pair.split('='))[0]) {
  502. var key = decodeURIComponent(pair.shift()),
  503. value = pair.length > 1 ? pair.join('=') : pair[0];
  504. if (value != undefined) value = decodeURIComponent(value);
  505. if (key in hash) {
  506. if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
  507. hash[key].push(value);
  508. }
  509. else hash[key] = value;
  510. }
  511. return hash;
  512. });
  513. }
  514. function toArray() {
  515. return this.split('');
  516. }
  517. function succ() {
  518. return this.slice(0, this.length - 1) +
  519. String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
  520. }
  521. function times(count) {
  522. return count < 1 ? '' : new Array(count + 1).join(this);
  523. }
  524. function camelize() {
  525. return this.replace(/-+(.)?/g, function(match, chr) {
  526. return chr ? chr.toUpperCase() : '';
  527. });
  528. }
  529. function capitalize() {
  530. return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
  531. }
  532. function underscore() {
  533. return this.replace(/::/g, '/')
  534. .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
  535. .replace(/([a-z\d])([A-Z])/g, '$1_$2')
  536. .replace(/-/g, '_')
  537. .toLowerCase();
  538. }
  539. function dasherize() {
  540. return this.replace(/_/g, '-');
  541. }
  542. function inspect(useDoubleQuotes) {
  543. var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
  544. if (character in String.specialChar) {
  545. return String.specialChar[character];
  546. }
  547. return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
  548. });
  549. if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
  550. return "'" + escapedString.replace(/'/g, '\\\'') + "'";
  551. }
  552. function unfilterJSON(filter) {
  553. return this.replace(filter || Prototype.JSONFilter, '$1');
  554. }
  555. function isJSON() {
  556. var str = this;
  557. if (str.blank()) return false;
  558. str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
  559. str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
  560. str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
  561. return (/^[\],:{}\s]*$/).test(str);
  562. }
  563. function evalJSON(sanitize) {
  564. var json = this.unfilterJSON(),
  565. cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
  566. if (cx.test(json)) {
  567. json = json.replace(cx, function (a) {
  568. return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
  569. });
  570. }
  571. try {
  572. if (!sanitize || json.isJSON()) return eval('(' + json + ')');
  573. } catch (e) { }
  574. throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
  575. }
  576. function parseJSON() {
  577. var json = this.unfilterJSON();
  578. return JSON.parse(json);
  579. }
  580. function include(pattern) {
  581. return this.indexOf(pattern) > -1;
  582. }
  583. function startsWith(pattern) {
  584. return this.lastIndexOf(pattern, 0) === 0;
  585. }
  586. function endsWith(pattern) {
  587. var d = this.length - pattern.length;
  588. return d >= 0 && this.indexOf(pattern, d) === d;
  589. }
  590. function empty() {
  591. return this == '';
  592. }
  593. function blank() {
  594. return /^\s*$/.test(this);
  595. }
  596. function interpolate(object, pattern) {
  597. return new Template(this, pattern).evaluate(object);
  598. }
  599. return {
  600. gsub: gsub,
  601. sub: sub,
  602. scan: scan,
  603. truncate: truncate,
  604. strip: String.prototype.trim || strip,
  605. stripTags: stripTags,
  606. stripScripts: stripScripts,
  607. extractScripts: extractScripts,
  608. evalScripts: evalScripts,
  609. escapeHTML: escapeHTML,
  610. unescapeHTML: unescapeHTML,
  611. toQueryParams: toQueryParams,
  612. parseQuery: toQueryParams,
  613. toArray: toArray,
  614. succ: succ,
  615. times: times,
  616. camelize: camelize,
  617. capitalize: capitalize,
  618. underscore: underscore,
  619. dasherize: dasherize,
  620. inspect: inspect,
  621. unfilterJSON: unfilterJSON,
  622. isJSON: isJSON,
  623. evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
  624. include: include,
  625. startsWith: startsWith,
  626. endsWith: endsWith,
  627. empty: empty,
  628. blank: blank,
  629. interpolate: interpolate
  630. };
  631. })());
  632. var Template = Class.create({
  633. initialize: function(template, pattern) {
  634. this.template = template.toString();
  635. this.pattern = pattern || Template.Pattern;
  636. },
  637. evaluate: function(object) {
  638. if (object && Object.isFunction(object.toTemplateReplacements))
  639. object = object.toTemplateReplacements();
  640. return this.template.gsub(this.pattern, function(match) {
  641. if (object == null) return (match[1] + '');
  642. var before = match[1] || '';
  643. if (before == '\\') return match[2];
  644. var ctx = object, expr = match[3],
  645. pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
  646. match = pattern.exec(expr);
  647. if (match == null) return before;
  648. while (match != null) {
  649. var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
  650. ctx = ctx[comp];
  651. if (null == ctx || '' == match[3]) break;
  652. expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
  653. match = pattern.exec(expr);
  654. }
  655. return before + String.interpret(ctx);
  656. });
  657. }
  658. });
  659. Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
  660. var $break = { };
  661. var Enumerable = (function() {
  662. function each(iterator, context) {
  663. var index = 0;
  664. try {
  665. this._each(function(value) {
  666. iterator.call(context, value, index++);
  667. });
  668. } catch (e) {
  669. if (e != $break) throw e;
  670. }
  671. return this;
  672. }
  673. function eachSlice(number, iterator, context) {
  674. var index = -number, slices = [], array = this.toArray();
  675. if (number < 1) return array;
  676. while ((index += number) < array.length)
  677. slices.push(array.slice(index, index+number));
  678. return slices.collect(iterator, context);
  679. }
  680. function all(iterator, context) {
  681. iterator = iterator || Prototype.K;
  682. var result = true;
  683. this.each(function(value, index) {
  684. result = result && !!iterator.call(context, value, index);
  685. if (!result) throw $break;
  686. });
  687. return result;
  688. }
  689. function any(iterator, context) {
  690. iterator = iterator || Prototype.K;
  691. var result = false;
  692. this.each(function(value, index) {
  693. if (result = !!iterator.call(context, value, index))
  694. throw $break;
  695. });
  696. return result;
  697. }
  698. function collect(iterator, context) {
  699. iterator = iterator || Prototype.K;
  700. var results = [];
  701. this.each(function(value, index) {
  702. results.push(iterator.call(context, value, index));
  703. });
  704. return results;
  705. }
  706. function detect(iterator, context) {
  707. var result;
  708. this.each(function(value, index) {
  709. if (iterator.call(context, value, index)) {
  710. result = value;
  711. throw $break;
  712. }
  713. });
  714. return result;
  715. }
  716. function findAll(iterator, context) {
  717. var results = [];
  718. this.each(function(value, index) {
  719. if (iterator.call(context, value, index))
  720. results.push(value);
  721. });
  722. return results;
  723. }
  724. function grep(filter, iterator, context) {
  725. iterator = iterator || Prototype.K;
  726. var results = [];
  727. if (Object.isString(filter))
  728. filter = new RegExp(RegExp.escape(filter));
  729. this.each(function(value, index) {
  730. if (filter.match(value))
  731. results.push(iterator.call(context, value, index));
  732. });
  733. return results;
  734. }
  735. function include(object) {
  736. if (Object.isFunction(this.indexOf))
  737. if (this.indexOf(object) != -1) return true;
  738. var found = false;
  739. this.each(function(value) {
  740. if (value == object) {
  741. found = true;
  742. throw $break;
  743. }
  744. });
  745. return found;
  746. }
  747. function inGroupsOf(number, fillWith) {
  748. fillWith = Object.isUndefined(fillWith) ? null : fillWith;
  749. return this.eachSlice(number, function(slice) {
  750. while(slice.length < number) slice.push(fillWith);
  751. return slice;
  752. });
  753. }
  754. function inject(memo, iterator, context) {
  755. this.each(function(value, index) {
  756. memo = iterator.call(context, memo, value, index);
  757. });
  758. return memo;
  759. }
  760. function invoke(method) {
  761. var args = $A(arguments).slice(1);
  762. return this.map(function(value) {
  763. return value[method].apply(value, args);
  764. });
  765. }
  766. function max(iterator, context) {
  767. iterator = iterator || Prototype.K;
  768. var result;
  769. this.each(function(value, index) {
  770. value = iterator.call(context, value, index);
  771. if (result == null || value >= result)
  772. result = value;
  773. });
  774. return result;
  775. }
  776. function min(iterator, context) {
  777. iterator = iterator || Prototype.K;
  778. var result;
  779. this.each(function(value, index) {
  780. value = iterator.call(context, value, index);
  781. if (result == null || value < result)
  782. result = value;
  783. });
  784. return result;
  785. }
  786. function partition(iterator, context) {
  787. iterator = iterator || Prototype.K;
  788. var trues = [], falses = [];
  789. this.each(function(value, index) {
  790. (iterator.call(context, value, index) ?
  791. trues : falses).push(value);
  792. });
  793. return [trues, falses];
  794. }
  795. function pluck(property) {
  796. var results = [];
  797. this.each(function(value) {
  798. results.push(value[property]);
  799. });
  800. return results;
  801. }
  802. function reject(iterator, context) {
  803. var results = [];
  804. this.each(function(value, index) {
  805. if (!iterator.call(context, value, index))
  806. results.push(value);
  807. });
  808. return results;
  809. }
  810. function sortBy(iterator, context) {
  811. return this.map(function(value, index) {
  812. return {
  813. value: value,
  814. criteria: iterator.call(context, value, index)
  815. };
  816. }).sort(function(left, right) {
  817. var a = left.criteria, b = right.criteria;
  818. return a < b ? -1 : a > b ? 1 : 0;
  819. }).pluck('value');
  820. }
  821. function toArray() {
  822. return this.map();
  823. }
  824. function zip() {
  825. var iterator = Prototype.K, args = $A(arguments);
  826. if (Object.isFunction(args.last()))
  827. iterator = args.pop();
  828. var collections = [this].concat(args).map($A);
  829. return this.map(function(value, index) {
  830. return iterator(collections.pluck(index));
  831. });
  832. }
  833. function size() {
  834. return this.toArray().length;
  835. }
  836. function inspect() {
  837. return '#<Enumerable:' + this.toArray().inspect() + '>';
  838. }
  839. return {
  840. each: each,
  841. eachSlice: eachSlice,
  842. all: all,
  843. every: all,
  844. any: any,
  845. some: any,
  846. collect: collect,
  847. map: collect,
  848. detect: detect,
  849. findAll: findAll,
  850. select: findAll,
  851. filter: findAll,
  852. grep: grep,
  853. include: include,
  854. member: include,
  855. inGroupsOf: inGroupsOf,
  856. inject: inject,
  857. invoke: invoke,
  858. max: max,
  859. min: min,
  860. partition: partition,
  861. pluck: pluck,
  862. reject: reject,
  863. sortBy: sortBy,
  864. toArray: toArray,
  865. entries: toArray,
  866. zip: zip,
  867. size: size,
  868. inspect: inspect,
  869. find: detect
  870. };
  871. })();
  872. function $A(iterable) {
  873. if (!iterable) return [];
  874. if ('toArray' in Object(iterable)) return iterable.toArray();
  875. var length = iterable.length || 0, results = new Array(length);
  876. while (length--) results[length] = iterable[length];
  877. return results;
  878. }
  879. function $w(string) {
  880. if (!Object.isString(string)) return [];
  881. string = string.strip();
  882. return string ? string.split(/\s+/) : [];
  883. }
  884. Array.from = $A;
  885. (function() {
  886. var arrayProto = Array.prototype,
  887. slice = arrayProto.slice,
  888. _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
  889. function each(iterator, context) {
  890. for (var i = 0, length = this.length >>> 0; i < length; i++) {
  891. if (i in this) iterator.call(context, this[i], i, this);
  892. }
  893. }
  894. if (!_each) _each = each;
  895. function clear() {
  896. this.length = 0;
  897. return this;
  898. }
  899. function first() {
  900. return this[0];
  901. }
  902. function last() {
  903. return this[this.length - 1];
  904. }
  905. function compact() {
  906. return this.select(function(value) {
  907. return value != null;
  908. });
  909. }
  910. function flatten() {
  911. return this.inject([], function(array, value) {
  912. if (Object.isArray(value))
  913. return array.concat(value.flatten());
  914. array.push(value);
  915. return array;
  916. });
  917. }
  918. function without() {
  919. var values = slice.call(arguments, 0);
  920. return this.select(function(value) {
  921. return !values.include(value);
  922. });
  923. }
  924. function reverse(inline) {
  925. return (inline === false ? this.toArray() : this)._reverse();
  926. }
  927. function uniq(sorted) {
  928. return this.inject([], function(array, value, index) {
  929. if (0 == index || (sorted ? array.last() != value : !array.include(value)))
  930. array.push(value);
  931. return array;
  932. });
  933. }
  934. function intersect(array) {
  935. return this.uniq().findAll(function(item) {
  936. return array.detect(function(value) { return item === value });
  937. });
  938. }
  939. function clone() {
  940. return slice.call(this, 0);
  941. }
  942. function size() {
  943. return this.length;
  944. }
  945. function inspect() {
  946. return '[' + this.map(Object.inspect).join(', ') + ']';
  947. }
  948. function indexOf(item, i) {
  949. i || (i = 0);
  950. var length = this.length;
  951. if (i < 0) i = length + i;
  952. for (; i < length; i++)
  953. if (this[i] === item) return i;
  954. return -1;
  955. }
  956. function lastIndexOf(item, i) {
  957. i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
  958. var n = this.slice(0, i).reverse().indexOf(item);
  959. return (n < 0) ? n : i - n - 1;
  960. }
  961. function concat() {
  962. var array = slice.call(this, 0), item;
  963. for (var i = 0, length = arguments.length; i < length; i++) {
  964. item = arguments[i];
  965. if (Object.isArray(item) && !('callee' in item)) {
  966. for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
  967. array.push(item[j]);
  968. } else {
  969. array.push(item);
  970. }
  971. }
  972. return array;
  973. }
  974. Object.extend(arrayProto, Enumerable);
  975. if (!arrayProto._reverse)
  976. arrayProto._reverse = arrayProto.reverse;
  977. Object.extend(arrayProto, {
  978. _each: _each,
  979. clear: clear,
  980. first: first,
  981. last: last,
  982. compact: compact,
  983. flatten: flatten,
  984. without: without,
  985. reverse: reverse,
  986. uniq: uniq,
  987. intersect: intersect,
  988. clone: clone,
  989. toArray: clone,
  990. size: size,
  991. inspect: inspect
  992. });
  993. var CONCAT_ARGUMENTS_BUGGY = (function() {
  994. return [].concat(arguments)[0][0] !== 1;
  995. })(1,2)
  996. if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
  997. if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
  998. if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
  999. })();
  1000. function $H(object) {
  1001. return new Hash(object);
  1002. };
  1003. var Hash = Class.create(Enumerable, (function() {
  1004. function initialize(object) {
  1005. this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
  1006. }
  1007. function _each(iterator) {
  1008. for (var key in this._object) {
  1009. var value = this._object[key], pair = [key, value];
  1010. pair.key = key;
  1011. pair.value = value;
  1012. iterator(pair);
  1013. }
  1014. }
  1015. function set(key, value) {
  1016. return this._object[key] = value;
  1017. }
  1018. function get(key) {
  1019. if (this._object[key] !== Object.prototype[key])
  1020. return this._object[key];
  1021. }
  1022. function unset(key) {
  1023. var value = this._object[key];
  1024. delete this._object[key];
  1025. return value;
  1026. }
  1027. function toObject() {
  1028. return Object.clone(this._object);
  1029. }
  1030. function keys() {
  1031. return this.pluck('key');
  1032. }
  1033. function values() {
  1034. return this.pluck('value');
  1035. }
  1036. function index(value) {
  1037. var match = this.detect(function(pair) {
  1038. return pair.value === value;
  1039. });
  1040. return match && match.key;
  1041. }
  1042. function merge(object) {
  1043. return this.clone().update(object);
  1044. }
  1045. function update(object) {
  1046. return new Hash(object).inject(this, function(result, pair) {
  1047. result.set(pair.key, pair.value);
  1048. return result;
  1049. });
  1050. }
  1051. function toQueryPair(key, value) {
  1052. if (Object.isUndefined(value)) return key;
  1053. return key + '=' + encodeURIComponent(String.interpret(value));
  1054. }
  1055. function toQueryString() {
  1056. return this.inject([], function(results, pair) {
  1057. var key = encodeURIComponent(pair.key), values = pair.value;
  1058. if (values && typeof values == 'object') {
  1059. if (Object.isArray(values)) {
  1060. var queryValues = [];
  1061. for (var i = 0, len = values.length, value; i < len; i++) {
  1062. value = values[i];
  1063. queryValues.push(toQueryPair(key, value));
  1064. }
  1065. return results.concat(queryValues);
  1066. }
  1067. } else results.push(toQueryPair(key, values));
  1068. return results;
  1069. }).join('&');
  1070. }
  1071. function inspect() {
  1072. return '#<Hash:{' + this.map(function(pair) {
  1073. return pair.map(Object.inspect).join(': ');
  1074. }).join(', ') + '}>';
  1075. }
  1076. function clone() {
  1077. return new Hash(this);
  1078. }
  1079. return {
  1080. initialize: initialize,
  1081. _each: _each,
  1082. set: set,
  1083. get: get,
  1084. unset: unset,
  1085. toObject: toObject,
  1086. toTemplateReplacements: toObject,
  1087. keys: keys,
  1088. values: values,
  1089. index: index,
  1090. merge: merge,
  1091. update: update,
  1092. toQueryString: toQueryString,
  1093. inspect: inspect,
  1094. toJSON: toObject,
  1095. clone: clone
  1096. };
  1097. })());
  1098. Hash.from = $H;
  1099. Object.extend(Number.prototype, (function() {
  1100. function toColorPart() {
  1101. return this.toPaddedString(2, 16);
  1102. }
  1103. function succ() {
  1104. return this + 1;
  1105. }
  1106. function times(iterator, context) {
  1107. $R(0, this, true).each(iterator, context);
  1108. return this;
  1109. }
  1110. function toPaddedString(length, radix) {
  1111. var string = this.toString(radix || 10);
  1112. return '0'.times(length - string.length) + string;
  1113. }
  1114. function abs() {
  1115. return Math.abs(this);
  1116. }
  1117. function round() {
  1118. return Math.round(this);
  1119. }
  1120. function ceil() {
  1121. return Math.ceil(this);
  1122. }
  1123. function floor() {
  1124. return Math.floor(this);
  1125. }
  1126. return {
  1127. toColorPart: toColorPart,
  1128. succ: succ,
  1129. times: times,
  1130. toPaddedString: toPaddedString,
  1131. abs: abs,
  1132. round: round,
  1133. ceil: ceil,
  1134. floor: floor
  1135. };
  1136. })());
  1137. function $R(start, end, exclusive) {
  1138. return new ObjectRange(start, end, exclusive);
  1139. }
  1140. var ObjectRange = Class.create(Enumerable, (function() {
  1141. function initialize(start, end, exclusive) {
  1142. this.start = start;
  1143. this.end = end;
  1144. this.exclusive = exclusive;
  1145. }
  1146. function _each(iterator) {
  1147. var value = this.start;
  1148. while (this.include(value)) {
  1149. iterator(value);
  1150. value = value.succ();
  1151. }
  1152. }
  1153. function include(value) {
  1154. if (value < this.start)
  1155. return false;
  1156. if (this.exclusive)
  1157. return value < this.end;
  1158. return value <= this.end;
  1159. }
  1160. return {
  1161. initialize: initialize,
  1162. _each: _each,
  1163. include: include
  1164. };
  1165. })());
  1166. var Abstract = { };
  1167. var Try = {
  1168. these: function() {
  1169. var returnValue;
  1170. for (var i = 0, length = arguments.length; i < length; i++) {
  1171. var lambda = arguments[i];
  1172. try {
  1173. returnValue = lambda();
  1174. break;
  1175. } catch (e) { }
  1176. }
  1177. return returnValue;
  1178. }
  1179. };
  1180. var Ajax = {
  1181. getTransport: function() {
  1182. return Try.these(
  1183. function() {return new XMLHttpRequest()},
  1184. function() {return new ActiveXObject('Msxml2.XMLHTTP')},
  1185. function() {return new ActiveXObject('Microsoft.XMLHTTP')}
  1186. ) || false;
  1187. },
  1188. activeRequestCount: 0
  1189. };
  1190. Ajax.Responders = {
  1191. responders: [],
  1192. _each: function(iterator) {
  1193. this.responders._each(iterator);
  1194. },
  1195. register: function(responder) {
  1196. if (!this.include(responder))
  1197. this.responders.push(responder);
  1198. },
  1199. unregister: function(responder) {
  1200. this.responders = this.responders.without(responder);
  1201. },
  1202. dispatch: function(callback, request, transport, json) {
  1203. this.each(function(responder) {
  1204. if (Object.isFunction(responder[callback])) {
  1205. try {
  1206. responder[callback].apply(responder, [request, transport, json]);
  1207. } catch (e) { }
  1208. }
  1209. });
  1210. }
  1211. };
  1212. Object.extend(Ajax.Responders, Enumerable);
  1213. Ajax.Responders.register({
  1214. onCreate: function() { Ajax.activeRequestCount++ },
  1215. onComplete: function() { Ajax.activeRequestCount-- }
  1216. });
  1217. Ajax.Base = Class.create({
  1218. initialize: function(options) {
  1219. this.options = {
  1220. method: 'post',
  1221. asynchronous: true,
  1222. contentType: 'application/x-www-form-urlencoded',
  1223. encoding: 'UTF-8',
  1224. parameters: '',
  1225. evalJSON: true,
  1226. evalJS: true
  1227. };
  1228. Object.extend(this.options, options || { });
  1229. this.options.method = this.options.method.toLowerCase();
  1230. if (Object.isHash(this.options.parameters))
  1231. this.options.parameters = this.options.parameters.toObject();
  1232. }
  1233. });
  1234. Ajax.Request = Class.create(Ajax.Base, {
  1235. _complete: false,
  1236. initialize: function($super, url, options) {
  1237. $super(options);
  1238. this.transport = Ajax.getTransport();
  1239. this.request(url);
  1240. },
  1241. request: function(url) {
  1242. this.url = url;
  1243. this.method = this.options.method;
  1244. var params = Object.isString(this.options.parameters) ?
  1245. this.options.parameters :
  1246. Object.toQueryString(this.options.parameters);
  1247. if (!['get', 'post'].include(this.method)) {
  1248. params += (params ? '&' : '') + "_method=" + this.method;
  1249. this.method = 'post';
  1250. }
  1251. if (params && this.method === 'get') {
  1252. this.url += (this.url.include('?') ? '&' : '?') + params;
  1253. }
  1254. this.parameters = params.toQueryParams();
  1255. try {
  1256. var response = new Ajax.Response(this);
  1257. if (this.options.onCreate) this.options.onCreate(response);
  1258. Ajax.Responders.dispatch('onCreate', this, response);
  1259. this.transport.open(this.method.toUpperCase(), this.url,
  1260. this.options.asynchronous);
  1261. if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
  1262. this.transport.onreadystatechange = this.onStateChange.bind(this);
  1263. this.setRequestHeaders();
  1264. this.body = this.method == 'post' ? (this.options.postBody || params) : null;
  1265. this.transport.send(this.body);
  1266. /* Force Firefox to handle ready state 4 for synchronous requests */
  1267. if (!this.options.asynchronous && this.transport.overrideMimeType)
  1268. this.onStateChange();
  1269. }
  1270. catch (e) {
  1271. this.dispatchException(e);
  1272. }
  1273. },
  1274. onStateChange: function() {
  1275. var readyState = this.transport.readyState;
  1276. if (readyState > 1 && !((readyState == 4) && this._complete))
  1277. this.respondToReadyState(this.transport.readyState);
  1278. },
  1279. setRequestHeaders: function() {
  1280. var headers = {
  1281. 'X-Requested-With': 'XMLHttpRequest',
  1282. 'X-Prototype-Version': Prototype.Version,
  1283. 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
  1284. };
  1285. if (this.method == 'post') {
  1286. headers['Content-type'] = this.options.contentType +
  1287. (this.options.encoding ? '; charset=' + this.options.encoding : '');
  1288. /* Force "Connection: close" for older Mozilla browsers to work
  1289. * around a bug where XMLHttpRequest sends an incorrect
  1290. * Content-length header. See Mozilla Bugzilla #246651.
  1291. */
  1292. if (this.transport.overrideMimeType &&
  1293. (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
  1294. headers['Connection'] = 'close';
  1295. }
  1296. if (typeof this.options.requestHeaders == 'object') {
  1297. var extras = this.options.requestHeaders;
  1298. if (Object.isFunction(extras.push))
  1299. for (var i = 0, length = extras.length; i < length; i += 2)
  1300. headers[extras[i]] = extras[i+1];
  1301. else
  1302. $H(extras).each(function(pair) { headers[pair.key] = pair.value });
  1303. }
  1304. for (var name in headers)
  1305. this.transport.setRequestHeader(name, headers[name]);
  1306. },
  1307. success: function() {
  1308. var status = this.getStatus();
  1309. return !status || (status >= 200 && status < 300) || status == 304;
  1310. },
  1311. getStatus: function() {
  1312. try {
  1313. if (this.transport.status === 1223) return 204;
  1314. return this.transport.status || 0;
  1315. } catch (e) { return 0 }
  1316. },
  1317. respondToReadyState: function(readyState) {
  1318. var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
  1319. if (state == 'Complete') {
  1320. try {
  1321. this._complete = true;
  1322. (this.options['on' + response.status]
  1323. || this.options['on' + (this.success() ? 'Success' : 'Failure')]
  1324. || Prototype.emptyFunction)(response, response.headerJSON);
  1325. } catch (e) {
  1326. this.dispatchException(e);
  1327. }
  1328. var contentType = response.getHeader('Content-type');
  1329. if (this.options.evalJS == 'force'
  1330. || (this.options.evalJS && this.isSameOrigin() && contentType
  1331. && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
  1332. this.evalResponse();
  1333. }
  1334. try {
  1335. (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
  1336. Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
  1337. } catch (e) {
  1338. this.dispatchException(e);
  1339. }
  1340. if (state == 'Complete') {
  1341. this.transport.onreadystatechange = Prototype.emptyFunction;
  1342. }
  1343. },
  1344. isSameOrigin: function() {
  1345. var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
  1346. return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
  1347. protocol: location.protocol,
  1348. domain: document.domain,
  1349. port: location.port ? ':' + location.port : ''
  1350. }));
  1351. },
  1352. getHeader: function(name) {
  1353. try {
  1354. return this.transport.getResponseHeader(name) || null;
  1355. } catch (e) { return null; }
  1356. },
  1357. evalResponse: function() {
  1358. try {
  1359. return eval((this.transport.responseText || '').unfilterJSON());
  1360. } catch (e) {
  1361. this.dispatchException(e);
  1362. }
  1363. },
  1364. dispatchException: function(exception) {
  1365. (this.options.onException || Prototype.emptyFunction)(this, exception);
  1366. Ajax.Responders.dispatch('onException', this, exception);
  1367. }
  1368. });
  1369. Ajax.Request.Events =
  1370. ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
  1371. Ajax.Response = Class.create({
  1372. initialize: function(request){
  1373. this.request = request;
  1374. var transport = this.transport = request.transport,
  1375. readyState = this.readyState = transport.readyState;
  1376. if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
  1377. this.status = this.getStatus();
  1378. this.statusText = this.getStatusText();
  1379. this.responseText = String.interpret(transport.responseText);
  1380. this.headerJSON = this._getHeaderJSON();
  1381. }
  1382. if (readyState == 4) {
  1383. var xml = transport.responseXML;
  1384. this.responseXML = Object.isUndefined(xml) ? null : xml;
  1385. this.responseJSON = this._getResponseJSON();
  1386. }
  1387. },
  1388. status: 0,
  1389. statusText: '',
  1390. getStatus: Ajax.Request.prototype.getStatus,
  1391. getStatusText: function() {
  1392. try {
  1393. return this.transport.statusText || '';
  1394. } catch (e) { return '' }
  1395. },
  1396. getHeader: Ajax.Request.prototype.getHeader,
  1397. getAllHeaders: function() {
  1398. try {
  1399. return this.getAllResponseHeaders();
  1400. } catch (e) { return null }
  1401. },
  1402. getResponseHeader: function(name) {
  1403. return this.transport.getResponseHeader(name);
  1404. },
  1405. getAllResponseHeaders: function() {
  1406. return this.transport.getAllResponseHeaders();
  1407. },
  1408. _getHeaderJSON: function() {
  1409. var json = this.getHeader('X-JSON');
  1410. if (!json) return null;
  1411. json = decodeURIComponent(escape(json));
  1412. try {
  1413. return json.evalJSON(this.request.options.sanitizeJSON ||
  1414. !this.request.isSameOrigin());
  1415. } catch (e) {
  1416. this.request.dispatchException(e);
  1417. }
  1418. },
  1419. _getResponseJSON: function() {
  1420. var options = this.request.options;
  1421. if (!options.evalJSON || (options.evalJSON != 'force' &&
  1422. !(this.getHeader('Content-type') || '').include('application/json')) ||
  1423. this.responseText.blank())
  1424. return null;
  1425. try {
  1426. return this.responseText.evalJSON(options.sanitizeJSON ||
  1427. !this.request.isSameOrigin());
  1428. } catch (e) {
  1429. this.request.dispatchException(e);
  1430. }
  1431. }
  1432. });
  1433. Ajax.Updater = Class.create(Ajax.Request, {
  1434. initialize: function($super, container, url, options) {
  1435. this.container = {
  1436. success: (container.success || container),
  1437. failure: (container.failure || (container.success ? null : container))
  1438. };
  1439. options = Object.clone(options);
  1440. var onComplete = options.onComplete;
  1441. options.onComplete = (function(response, json) {
  1442. this.updateContent(response.responseText);
  1443. if (Object.isFunction(onComplete)) onComplete(response, json);
  1444. }).bind(this);
  1445. $super(url, options);
  1446. },
  1447. updateContent: function(responseText) {
  1448. var receiver = this.container[this.success() ? 'success' : 'failure'],
  1449. options = this.options;
  1450. if (!options.evalScripts) responseText = responseText.stripScripts();
  1451. if (receiver = $(receiver)) {
  1452. if (options.insertion) {
  1453. if (Object.isString(options.insertion)) {
  1454. var insertion = { }; insertion[options.insertion] = responseText;
  1455. receiver.insert(insertion);
  1456. }
  1457. else options.insertion(receiver, responseText);
  1458. }
  1459. else receiver.update(responseText);
  1460. }
  1461. }
  1462. });
  1463. Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
  1464. initialize: function($super, container, url, options) {
  1465. $super(options);
  1466. this.onComplete = this.options.onComplete;
  1467. this.frequency = (this.options.frequency || 2);
  1468. this.decay = (this.options.decay || 1);
  1469. this.updater = { };
  1470. this.container = container;
  1471. this.url = url;
  1472. this.start();
  1473. },
  1474. start: function() {
  1475. this.options.onComplete = this.updateComplete.bind(this);
  1476. this.onTimerEvent();
  1477. },
  1478. stop: function() {
  1479. this.updater.options.onComplete = undefined;
  1480. clearTimeout(this.timer);
  1481. (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
  1482. },
  1483. updateComplete: function(response) {
  1484. if (this.options.decay) {
  1485. this.decay = (response.responseText == this.lastText ?
  1486. this.decay * this.options.decay : 1);
  1487. this.lastText = response.responseText;
  1488. }
  1489. this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
  1490. },
  1491. onTimerEvent: function() {
  1492. this.updater = new Ajax.Updater(this.container, this.url, this.options);
  1493. }
  1494. });
  1495. function $(element) {
  1496. if (arguments.length > 1) {
  1497. for (var i = 0, elements = [], length = arguments.length; i < length; i++)
  1498. elements.push($(arguments[i]));
  1499. return elements;
  1500. }
  1501. if (Object.isString(element))
  1502. element = document.getElementById(element);
  1503. return Element.extend(element);
  1504. }
  1505. if (Prototype.BrowserFeatures.XPath) {
  1506. document._getElementsByXPath = function(expression, parentElement) {
  1507. var results = [];
  1508. var query = document.evaluate(expression, $(parentElement) || document,
  1509. null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  1510. for (var i = 0, length = query.snapshotLength; i < length; i++)
  1511. results.push(Element.extend(query.snapshotItem(i)));
  1512. return results;
  1513. };
  1514. }
  1515. /*--------------------------------------------------------------------------*/
  1516. if (!Node) var Node = { };
  1517. if (!Node.ELEMENT_NODE) {
  1518. Object.extend(Node, {
  1519. ELEMENT_NODE: 1,
  1520. ATTRIBUTE_NODE: 2,
  1521. TEXT_NODE: 3,
  1522. CDATA_SECTION_NODE: 4,
  1523. ENTITY_REFERENCE_NODE: 5,
  1524. ENTITY_NODE: 6,
  1525. PROCESSING_INSTRUCTION_NODE: 7,
  1526. COMMENT_NODE: 8,
  1527. DOCUMENT_NODE: 9,
  1528. DOCUMENT_TYPE_NODE: 10,
  1529. DOCUMENT_FRAGMENT_NODE: 11,
  1530. NOTATION_NODE: 12
  1531. });
  1532. }
  1533. (function(global) {
  1534. function shouldUseCache(tagName, attributes) {
  1535. if (tagName === 'select') return false;
  1536. if ('type' in attributes) return false;
  1537. return true;
  1538. }
  1539. var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
  1540. try {
  1541. var el = document.createElement('<input name="x">');
  1542. return el.tagName.toLowerCase() === 'input' && el.name === 'x';
  1543. }
  1544. catch(err) {
  1545. return false;
  1546. }
  1547. })();
  1548. var element = global.Element;
  1549. global.Element = function(tagName, attributes) {
  1550. attributes = attributes || { };
  1551. tagName = tagName.toLowerCase();
  1552. var cache = Element.cache;
  1553. if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) {
  1554. tagName = '<' + tagName + ' name="' + attributes.name + '">';
  1555. delete attributes.name;
  1556. return Element.writeAttribute(document.createElement(tagName), attributes);
  1557. }
  1558. if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
  1559. var node = shouldUseCache(tagName, attributes) ?
  1560. cache[tagName].cloneNode(false) : document.createElement(tagName);
  1561. return Element.writeAttribute(node, attributes);
  1562. };
  1563. Object.extend(global.Element, element || { });
  1564. if (element) global.Element.prototype = element.prototype;
  1565. })(this);
  1566. Element.idCounter = 1;
  1567. Element.cache = { };
  1568. Element._purgeElement = function(element) {
  1569. var uid = element._prototypeUID;
  1570. if (uid) {
  1571. Element.stopObserving(element);
  1572. element._prototypeUID = void 0;
  1573. delete Element.Storage[uid];
  1574. }
  1575. }
  1576. Element.Methods = {
  1577. visible: function(element) {
  1578. return $(element).style.display != 'none';
  1579. },
  1580. toggle: function(element) {
  1581. element = $(element);
  1582. Element[Element.visible(element) ? 'hide' : 'show'](element);
  1583. return element;
  1584. },
  1585. hide: function(element) {
  1586. element = $(element);
  1587. ele