PageRenderTime 66ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/dom/tests/mochitest/ajax/prototype/dist/prototype.js

https://bitbucket.org/soko/mozilla-central
JavaScript | 4681 lines | 4594 code | 78 blank | 9 comment | 83 complexity | a288125ff0fb9c7f273efaebf448cc51 MD5 | raw file
Possible License(s): GPL-2.0, JSON, 0BSD, LGPL-3.0, AGPL-1.0, MIT, MPL-2.0-no-copyleft-exception, BSD-3-Clause, LGPL-2.1, Apache-2.0

Large files files are truncated, but you can click here to view the full file

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

Large files files are truncated, but you can click here to view the full file