| Index: benchmarks/raytrace.js
|
| ===================================================================
|
| --- benchmarks/raytrace.js (revision 1898)
|
| +++ benchmarks/raytrace.js (working copy)
|
| @@ -5,7 +5,7 @@
|
| //
|
| // It has been modified slightly by Google to work as a standalone
|
| // benchmark, but the all the computational code remains
|
| -// untouched. This file also contains a copy of the Prototype
|
| +// untouched. This file also contains a copy of parts of the Prototype
|
| // JavaScript framework which is used by the ray tracer.
|
|
|
| var RayTrace = new BenchmarkSuite('RayTrace', 932666, [
|
| @@ -13,2538 +13,40 @@
|
| ]);
|
|
|
|
|
| +// Variable used to hold a number that can be used to verify that
|
| +// the scene was ray traced correctly.
|
| var checkNumber;
|
|
|
| -// Create dummy objects if we're not running in a browser.
|
| -if (typeof document == 'undefined') {
|
| - document = { };
|
| - window = { opera: null };
|
| - navigator = { userAgent: null, appVersion: "" };
|
| -}
|
|
|
| -
|
| // ------------------------------------------------------------------------
|
| // ------------------------------------------------------------------------
|
|
|
| +// The following is a copy of parts of the Prototype JavaScript library:
|
|
|
| -/* Prototype JavaScript framework, version 1.5.0
|
| - * (c) 2005-2007 Sam Stephenson
|
| - *
|
| - * Prototype is freely distributable under the terms of an MIT-style license.
|
| - * For details, see the Prototype web site: http://prototype.conio.net/
|
| - *
|
| -/*--------------------------------------------------------------------------*/
|
| +// Prototype JavaScript framework, version 1.5.0
|
| +// (c) 2005-2007 Sam Stephenson
|
| +//
|
| +// Prototype is freely distributable under the terms of an MIT-style license.
|
| +// For details, see the Prototype web site: http://prototype.conio.net/
|
|
|
| -//--------------------
|
| -var Prototype = {
|
| - Version: '1.5.0',
|
| - BrowserFeatures: {
|
| - XPath: !!document.evaluate
|
| - },
|
|
|
| - ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
|
| - emptyFunction: function() {},
|
| - K: function(x) { return x }
|
| -}
|
| -
|
| var Class = {
|
| create: function() {
|
| return function() {
|
| this.initialize.apply(this, arguments);
|
| }
|
| }
|
| -}
|
| +};
|
|
|
| -var Abstract = new Object();
|
|
|
| Object.extend = function(destination, source) {
|
| for (var property in source) {
|
| destination[property] = source[property];
|
| }
|
| return destination;
|
| -}
|
| -
|
| -Object.extend(Object, {
|
| - inspect: function(object) {
|
| - try {
|
| - if (object === undefined) return 'undefined';
|
| - if (object === null) return 'null';
|
| - return object.inspect ? object.inspect() : object.toString();
|
| - } catch (e) {
|
| - if (e instanceof RangeError) return '...';
|
| - throw e;
|
| - }
|
| - },
|
| -
|
| - keys: function(object) {
|
| - var keys = [];
|
| - for (var property in object)
|
| - keys.push(property);
|
| - return keys;
|
| - },
|
| -
|
| - values: function(object) {
|
| - var values = [];
|
| - for (var property in object)
|
| - values.push(object[property]);
|
| - return values;
|
| - },
|
| -
|
| - clone: function(object) {
|
| - return Object.extend({}, object);
|
| - }
|
| -});
|
| -
|
| -Function.prototype.bind = function() {
|
| - var __method = this, args = $A(arguments), object = args.shift();
|
| - return function() {
|
| - return __method.apply(object, args.concat($A(arguments)));
|
| - }
|
| -}
|
| -
|
| -Function.prototype.bindAsEventListener = function(object) {
|
| - var __method = this, args = $A(arguments), object = args.shift();
|
| - return function(event) {
|
| - return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
|
| - }
|
| -}
|
| -
|
| -Object.extend(Number.prototype, {
|
| - toColorPart: function() {
|
| - var digits = this.toString(16);
|
| - if (this < 16) return '0' + digits;
|
| - return digits;
|
| - },
|
| -
|
| - succ: function() {
|
| - return this + 1;
|
| - },
|
| -
|
| - times: function(iterator) {
|
| - $R(0, this, true).each(iterator);
|
| - return this;
|
| - }
|
| -});
|
| -
|
| -var Try = {
|
| - these: function() {
|
| - var returnValue;
|
| -
|
| - for (var i = 0, length = arguments.length; i < length; i++) {
|
| - var lambda = arguments[i];
|
| - try {
|
| - returnValue = lambda();
|
| - break;
|
| - } catch (e) {}
|
| - }
|
| -
|
| - return returnValue;
|
| - }
|
| -}
|
| -
|
| -/*--------------------------------------------------------------------------*/
|
| -
|
| -var PeriodicalExecuter = Class.create();
|
| -PeriodicalExecuter.prototype = {
|
| - initialize: function(callback, frequency) {
|
| - this.callback = callback;
|
| - this.frequency = frequency;
|
| - this.currentlyExecuting = false;
|
| -
|
| - this.registerCallback();
|
| - },
|
| -
|
| - registerCallback: function() {
|
| - this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
|
| - },
|
| -
|
| - stop: function() {
|
| - if (!this.timer) return;
|
| - clearInterval(this.timer);
|
| - this.timer = null;
|
| - },
|
| -
|
| - onTimerEvent: function() {
|
| - if (!this.currentlyExecuting) {
|
| - try {
|
| - this.currentlyExecuting = true;
|
| - this.callback(this);
|
| - } finally {
|
| - this.currentlyExecuting = false;
|
| - }
|
| - }
|
| - }
|
| -}
|
| -String.interpret = function(value){
|
| - return value == null ? '' : String(value);
|
| -}
|
| -
|
| -Object.extend(String.prototype, {
|
| - gsub: function(pattern, replacement) {
|
| - var result = '', source = this, match;
|
| - replacement = arguments.callee.prepareReplacement(replacement);
|
| -
|
| - while (source.length > 0) {
|
| - if (match = source.match(pattern)) {
|
| - result += source.slice(0, match.index);
|
| - result += String.interpret(replacement(match));
|
| - source = source.slice(match.index + match[0].length);
|
| - } else {
|
| - result += source, source = '';
|
| - }
|
| - }
|
| - return result;
|
| - },
|
| -
|
| - sub: function(pattern, replacement, count) {
|
| - replacement = this.gsub.prepareReplacement(replacement);
|
| - count = count === undefined ? 1 : count;
|
| -
|
| - return this.gsub(pattern, function(match) {
|
| - if (--count < 0) return match[0];
|
| - return replacement(match);
|
| - });
|
| - },
|
| -
|
| - scan: function(pattern, iterator) {
|
| - this.gsub(pattern, iterator);
|
| - return this;
|
| - },
|
| -
|
| - truncate: function(length, truncation) {
|
| - length = length || 30;
|
| - truncation = truncation === undefined ? '...' : truncation;
|
| - return this.length > length ?
|
| - this.slice(0, length - truncation.length) + truncation : this;
|
| - },
|
| -
|
| - strip: function() {
|
| - return this.replace(/^\s+/, '').replace(/\s+$/, '');
|
| - },
|
| -
|
| - stripTags: function() {
|
| - return this.replace(/<\/?[^>]+>/gi, '');
|
| - },
|
| -
|
| - stripScripts: function() {
|
| - return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
|
| - },
|
| -
|
| - extractScripts: function() {
|
| - var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
|
| - var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
|
| - return (this.match(matchAll) || []).map(function(scriptTag) {
|
| - return (scriptTag.match(matchOne) || ['', ''])[1];
|
| - });
|
| - },
|
| -
|
| - evalScripts: function() {
|
| - return this.extractScripts().map(function(script) { return eval(script) });
|
| - },
|
| -
|
| - escapeHTML: function() {
|
| - var div = document.createElement('div');
|
| - var text = document.createTextNode(this);
|
| - div.appendChild(text);
|
| - return div.innerHTML;
|
| - },
|
| -
|
| - unescapeHTML: function() {
|
| - var div = document.createElement('div');
|
| - div.innerHTML = this.stripTags();
|
| - return div.childNodes[0] ? (div.childNodes.length > 1 ?
|
| - $A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) :
|
| - div.childNodes[0].nodeValue) : '';
|
| - },
|
| -
|
| - toQueryParams: function(separator) {
|
| - var match = this.strip().match(/([^?#]*)(#.*)?$/);
|
| - if (!match) return {};
|
| -
|
| - return match[1].split(separator || '&').inject({}, function(hash, pair) {
|
| - if ((pair = pair.split('='))[0]) {
|
| - var name = decodeURIComponent(pair[0]);
|
| - var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;
|
| -
|
| - if (hash[name] !== undefined) {
|
| - if (hash[name].constructor != Array)
|
| - hash[name] = [hash[name]];
|
| - if (value) hash[name].push(value);
|
| - }
|
| - else hash[name] = value;
|
| - }
|
| - return hash;
|
| - });
|
| - },
|
| -
|
| - toArray: function() {
|
| - return this.split('');
|
| - },
|
| -
|
| - succ: function() {
|
| - return this.slice(0, this.length - 1) +
|
| - String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
|
| - },
|
| -
|
| - camelize: function() {
|
| - var parts = this.split('-'), len = parts.length;
|
| - if (len == 1) return parts[0];
|
| -
|
| - var camelized = this.charAt(0) == '-'
|
| - ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
|
| - : parts[0];
|
| -
|
| - for (var i = 1; i < len; i++)
|
| - camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
|
| -
|
| - return camelized;
|
| - },
|
| -
|
| - capitalize: function(){
|
| - return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
|
| - },
|
| -
|
| - underscore: function() {
|
| - return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
|
| - },
|
| -
|
| - dasherize: function() {
|
| - return this.gsub(/_/,'-');
|
| - },
|
| -
|
| - inspect: function(useDoubleQuotes) {
|
| - var escapedString = this.replace(/\\/g, '\\\\');
|
| - if (useDoubleQuotes)
|
| - return '"' + escapedString.replace(/"/g, '\\"') + '"';
|
| - else
|
| - return "'" + escapedString.replace(/'/g, '\\\'') + "'";
|
| - }
|
| -});
|
| -
|
| -String.prototype.gsub.prepareReplacement = function(replacement) {
|
| - if (typeof replacement == 'function') return replacement;
|
| - var template = new Template(replacement);
|
| - return function(match) { return template.evaluate(match) };
|
| -}
|
| -
|
| -String.prototype.parseQuery = String.prototype.toQueryParams;
|
| -
|
| -var Template = Class.create();
|
| -Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
|
| -Template.prototype = {
|
| - initialize: function(template, pattern) {
|
| - this.template = template.toString();
|
| - this.pattern = pattern || Template.Pattern;
|
| - },
|
| -
|
| - evaluate: function(object) {
|
| - return this.template.gsub(this.pattern, function(match) {
|
| - var before = match[1];
|
| - if (before == '\\') return match[2];
|
| - return before + String.interpret(object[match[3]]);
|
| - });
|
| - }
|
| -}
|
| -
|
| -var $break = new Object();
|
| -var $continue = new Object();
|
| -
|
| -var Enumerable = {
|
| - each: function(iterator) {
|
| - var index = 0;
|
| - try {
|
| - this._each(function(value) {
|
| - try {
|
| - iterator(value, index++);
|
| - } catch (e) {
|
| - if (e != $continue) throw e;
|
| - }
|
| - });
|
| - } catch (e) {
|
| - if (e != $break) throw e;
|
| - }
|
| - return this;
|
| - },
|
| -
|
| - eachSlice: function(number, iterator) {
|
| - var index = -number, slices = [], array = this.toArray();
|
| - while ((index += number) < array.length)
|
| - slices.push(array.slice(index, index+number));
|
| - return slices.map(iterator);
|
| - },
|
| -
|
| - all: function(iterator) {
|
| - var result = true;
|
| - this.each(function(value, index) {
|
| - result = result && !!(iterator || Prototype.K)(value, index);
|
| - if (!result) throw $break;
|
| - });
|
| - return result;
|
| - },
|
| -
|
| - any: function(iterator) {
|
| - var result = false;
|
| - this.each(function(value, index) {
|
| - if (result = !!(iterator || Prototype.K)(value, index))
|
| - throw $break;
|
| - });
|
| - return result;
|
| - },
|
| -
|
| - collect: function(iterator) {
|
| - var results = [];
|
| - this.each(function(value, index) {
|
| - results.push((iterator || Prototype.K)(value, index));
|
| - });
|
| - return results;
|
| - },
|
| -
|
| - detect: function(iterator) {
|
| - var result;
|
| - this.each(function(value, index) {
|
| - if (iterator(value, index)) {
|
| - result = value;
|
| - throw $break;
|
| - }
|
| - });
|
| - return result;
|
| - },
|
| -
|
| - findAll: function(iterator) {
|
| - var results = [];
|
| - this.each(function(value, index) {
|
| - if (iterator(value, index))
|
| - results.push(value);
|
| - });
|
| - return results;
|
| - },
|
| -
|
| - grep: function(pattern, iterator) {
|
| - var results = [];
|
| - this.each(function(value, index) {
|
| - var stringValue = value.toString();
|
| - if (stringValue.match(pattern))
|
| - results.push((iterator || Prototype.K)(value, index));
|
| - })
|
| - return results;
|
| - },
|
| -
|
| - include: function(object) {
|
| - var found = false;
|
| - this.each(function(value) {
|
| - if (value == object) {
|
| - found = true;
|
| - throw $break;
|
| - }
|
| - });
|
| - return found;
|
| - },
|
| -
|
| - inGroupsOf: function(number, fillWith) {
|
| - fillWith = fillWith === undefined ? null : fillWith;
|
| - return this.eachSlice(number, function(slice) {
|
| - while(slice.length < number) slice.push(fillWith);
|
| - return slice;
|
| - });
|
| - },
|
| -
|
| - inject: function(memo, iterator) {
|
| - this.each(function(value, index) {
|
| - memo = iterator(memo, value, index);
|
| - });
|
| - return memo;
|
| - },
|
| -
|
| - invoke: function(method) {
|
| - var args = $A(arguments).slice(1);
|
| - return this.map(function(value) {
|
| - return value[method].apply(value, args);
|
| - });
|
| - },
|
| -
|
| - max: function(iterator) {
|
| - var result;
|
| - this.each(function(value, index) {
|
| - value = (iterator || Prototype.K)(value, index);
|
| - if (result == undefined || value >= result)
|
| - result = value;
|
| - });
|
| - return result;
|
| - },
|
| -
|
| - min: function(iterator) {
|
| - var result;
|
| - this.each(function(value, index) {
|
| - value = (iterator || Prototype.K)(value, index);
|
| - if (result == undefined || value < result)
|
| - result = value;
|
| - });
|
| - return result;
|
| - },
|
| -
|
| - partition: function(iterator) {
|
| - var trues = [], falses = [];
|
| - this.each(function(value, index) {
|
| - ((iterator || Prototype.K)(value, index) ?
|
| - trues : falses).push(value);
|
| - });
|
| - return [trues, falses];
|
| - },
|
| -
|
| - pluck: function(property) {
|
| - var results = [];
|
| - this.each(function(value, index) {
|
| - results.push(value[property]);
|
| - });
|
| - return results;
|
| - },
|
| -
|
| - reject: function(iterator) {
|
| - var results = [];
|
| - this.each(function(value, index) {
|
| - if (!iterator(value, index))
|
| - results.push(value);
|
| - });
|
| - return results;
|
| - },
|
| -
|
| - sortBy: function(iterator) {
|
| - return this.map(function(value, index) {
|
| - return {value: value, criteria: iterator(value, index)};
|
| - }).sort(function(left, right) {
|
| - var a = left.criteria, b = right.criteria;
|
| - return a < b ? -1 : a > b ? 1 : 0;
|
| - }).pluck('value');
|
| - },
|
| -
|
| - toArray: function() {
|
| - return this.map();
|
| - },
|
| -
|
| - zip: function() {
|
| - var iterator = Prototype.K, args = $A(arguments);
|
| - if (typeof args.last() == 'function')
|
| - iterator = args.pop();
|
| -
|
| - var collections = [this].concat(args).map($A);
|
| - return this.map(function(value, index) {
|
| - return iterator(collections.pluck(index));
|
| - });
|
| - },
|
| -
|
| - size: function() {
|
| - return this.toArray().length;
|
| - },
|
| -
|
| - inspect: function() {
|
| - return '#<Enumerable:' + this.toArray().inspect() + '>';
|
| - }
|
| -}
|
| -
|
| -Object.extend(Enumerable, {
|
| - map: Enumerable.collect,
|
| - find: Enumerable.detect,
|
| - select: Enumerable.findAll,
|
| - member: Enumerable.include,
|
| - entries: Enumerable.toArray
|
| -});
|
| -var $A = Array.from = function(iterable) {
|
| - if (!iterable) return [];
|
| - if (iterable.toArray) {
|
| - return iterable.toArray();
|
| - } else {
|
| - var results = [];
|
| - for (var i = 0, length = iterable.length; i < length; i++)
|
| - results.push(iterable[i]);
|
| - return results;
|
| - }
|
| -}
|
| -
|
| -Object.extend(Array.prototype, Enumerable);
|
| -
|
| -if (!Array.prototype._reverse)
|
| - Array.prototype._reverse = Array.prototype.reverse;
|
| -
|
| -Object.extend(Array.prototype, {
|
| - _each: function(iterator) {
|
| - for (var i = 0, length = this.length; i < length; i++)
|
| - iterator(this[i]);
|
| - },
|
| -
|
| - clear: function() {
|
| - this.length = 0;
|
| - return this;
|
| - },
|
| -
|
| - first: function() {
|
| - return this[0];
|
| - },
|
| -
|
| - last: function() {
|
| - return this[this.length - 1];
|
| - },
|
| -
|
| - compact: function() {
|
| - return this.select(function(value) {
|
| - return value != null;
|
| - });
|
| - },
|
| -
|
| - flatten: function() {
|
| - return this.inject([], function(array, value) {
|
| - return array.concat(value && value.constructor == Array ?
|
| - value.flatten() : [value]);
|
| - });
|
| - },
|
| -
|
| - without: function() {
|
| - var values = $A(arguments);
|
| - return this.select(function(value) {
|
| - return !values.include(value);
|
| - });
|
| - },
|
| -
|
| - indexOf: function(object) {
|
| - for (var i = 0, length = this.length; i < length; i++)
|
| - if (this[i] == object) return i;
|
| - return -1;
|
| - },
|
| -
|
| - reverse: function(inline) {
|
| - return (inline !== false ? this : this.toArray())._reverse();
|
| - },
|
| -
|
| - reduce: function() {
|
| - return this.length > 1 ? this : this[0];
|
| - },
|
| -
|
| - uniq: function() {
|
| - return this.inject([], function(array, value) {
|
| - return array.include(value) ? array : array.concat([value]);
|
| - });
|
| - },
|
| -
|
| - clone: function() {
|
| - return [].concat(this);
|
| - },
|
| -
|
| - size: function() {
|
| - return this.length;
|
| - },
|
| -
|
| - inspect: function() {
|
| - return '[' + this.map(Object.inspect).join(', ') + ']';
|
| - }
|
| -});
|
| -
|
| -Array.prototype.toArray = Array.prototype.clone;
|
| -
|
| -function $w(string){
|
| - string = string.strip();
|
| - return string ? string.split(/\s+/) : [];
|
| -}
|
| -
|
| -if(window.opera){
|
| - Array.prototype.concat = function(){
|
| - var array = [];
|
| - for(var i = 0, length = this.length; i < length; i++) array.push(this[i]);
|
| - for(var i = 0, length = arguments.length; i < length; i++) {
|
| - if(arguments[i].constructor == Array) {
|
| - for(var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
|
| - array.push(arguments[i][j]);
|
| - } else {
|
| - array.push(arguments[i]);
|
| - }
|
| - }
|
| - return array;
|
| - }
|
| -}
|
| -var Hash = function(obj) {
|
| - Object.extend(this, obj || {});
|
| };
|
|
|
| -Object.extend(Hash, {
|
| - toQueryString: function(obj) {
|
| - var parts = [];
|
|
|
| - this.prototype._each.call(obj, function(pair) {
|
| - if (!pair.key) return;
|
| -
|
| - if (pair.value && pair.value.constructor == Array) {
|
| - var values = pair.value.compact();
|
| - if (values.length < 2) pair.value = values.reduce();
|
| - else {
|
| - key = encodeURIComponent(pair.key);
|
| - values.each(function(value) {
|
| - value = value != undefined ? encodeURIComponent(value) : '';
|
| - parts.push(key + '=' + encodeURIComponent(value));
|
| - });
|
| - return;
|
| - }
|
| - }
|
| - if (pair.value == undefined) pair[1] = '';
|
| - parts.push(pair.map(encodeURIComponent).join('='));
|
| - });
|
| -
|
| - return parts.join('&');
|
| - }
|
| -});
|
| -
|
| -Object.extend(Hash.prototype, Enumerable);
|
| -Object.extend(Hash.prototype, {
|
| - _each: function(iterator) {
|
| - for (var key in this) {
|
| - var value = this[key];
|
| - if (value && value == Hash.prototype[key]) continue;
|
| -
|
| - var pair = [key, value];
|
| - pair.key = key;
|
| - pair.value = value;
|
| - iterator(pair);
|
| - }
|
| - },
|
| -
|
| - keys: function() {
|
| - return this.pluck('key');
|
| - },
|
| -
|
| - values: function() {
|
| - return this.pluck('value');
|
| - },
|
| -
|
| - merge: function(hash) {
|
| - return $H(hash).inject(this, function(mergedHash, pair) {
|
| - mergedHash[pair.key] = pair.value;
|
| - return mergedHash;
|
| - });
|
| - },
|
| -
|
| - remove: function() {
|
| - var result;
|
| - for(var i = 0, length = arguments.length; i < length; i++) {
|
| - var value = this[arguments[i]];
|
| - if (value !== undefined){
|
| - if (result === undefined) result = value;
|
| - else {
|
| - if (result.constructor != Array) result = [result];
|
| - result.push(value)
|
| - }
|
| - }
|
| - delete this[arguments[i]];
|
| - }
|
| - return result;
|
| - },
|
| -
|
| - toQueryString: function() {
|
| - return Hash.toQueryString(this);
|
| - },
|
| -
|
| - inspect: function() {
|
| - return '#<Hash:{' + this.map(function(pair) {
|
| - return pair.map(Object.inspect).join(': ');
|
| - }).join(', ') + '}>';
|
| - }
|
| -});
|
| -
|
| -function $H(object) {
|
| - if (object && object.constructor == Hash) return object;
|
| - return new Hash(object);
|
| -};
|
| -ObjectRange = Class.create();
|
| -Object.extend(ObjectRange.prototype, Enumerable);
|
| -Object.extend(ObjectRange.prototype, {
|
| - initialize: function(start, end, exclusive) {
|
| - this.start = start;
|
| - this.end = end;
|
| - this.exclusive = exclusive;
|
| - },
|
| -
|
| - _each: function(iterator) {
|
| - var value = this.start;
|
| - while (this.include(value)) {
|
| - iterator(value);
|
| - value = value.succ();
|
| - }
|
| - },
|
| -
|
| - include: function(value) {
|
| - if (value < this.start)
|
| - return false;
|
| - if (this.exclusive)
|
| - return value < this.end;
|
| - return value <= this.end;
|
| - }
|
| -});
|
| -
|
| -var $R = function(start, end, exclusive) {
|
| - return new ObjectRange(start, end, exclusive);
|
| -}
|
| -
|
| -var Ajax = {
|
| - getTransport: function() {
|
| - return Try.these(
|
| - function() {return new XMLHttpRequest()},
|
| - function() {return new ActiveXObject('Msxml2.XMLHTTP')},
|
| - function() {return new ActiveXObject('Microsoft.XMLHTTP')}
|
| - ) || false;
|
| - },
|
| -
|
| - activeRequestCount: 0
|
| -}
|
| -
|
| -Ajax.Responders = {
|
| - responders: [],
|
| -
|
| - _each: function(iterator) {
|
| - this.responders._each(iterator);
|
| - },
|
| -
|
| - register: function(responder) {
|
| - if (!this.include(responder))
|
| - this.responders.push(responder);
|
| - },
|
| -
|
| - unregister: function(responder) {
|
| - this.responders = this.responders.without(responder);
|
| - },
|
| -
|
| - dispatch: function(callback, request, transport, json) {
|
| - this.each(function(responder) {
|
| - if (typeof responder[callback] == 'function') {
|
| - try {
|
| - responder[callback].apply(responder, [request, transport, json]);
|
| - } catch (e) {}
|
| - }
|
| - });
|
| - }
|
| -};
|
| -
|
| -Object.extend(Ajax.Responders, Enumerable);
|
| -
|
| -Ajax.Responders.register({
|
| - onCreate: function() {
|
| - Ajax.activeRequestCount++;
|
| - },
|
| - onComplete: function() {
|
| - Ajax.activeRequestCount--;
|
| - }
|
| -});
|
| -
|
| -Ajax.Base = function() {};
|
| -Ajax.Base.prototype = {
|
| - setOptions: function(options) {
|
| - this.options = {
|
| - method: 'post',
|
| - asynchronous: true,
|
| - contentType: 'application/x-www-form-urlencoded',
|
| - encoding: 'UTF-8',
|
| - parameters: ''
|
| - }
|
| - Object.extend(this.options, options || {});
|
| -
|
| - this.options.method = this.options.method.toLowerCase();
|
| - if (typeof this.options.parameters == 'string')
|
| - this.options.parameters = this.options.parameters.toQueryParams();
|
| - }
|
| -}
|
| -
|
| -Ajax.Request = Class.create();
|
| -Ajax.Request.Events =
|
| - ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
|
| -
|
| -Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
|
| - _complete: false,
|
| -
|
| - initialize: function(url, options) {
|
| - this.transport = Ajax.getTransport();
|
| - this.setOptions(options);
|
| - this.request(url);
|
| - },
|
| -
|
| - request: function(url) {
|
| - this.url = url;
|
| - this.method = this.options.method;
|
| - var params = this.options.parameters;
|
| -
|
| - if (!['get', 'post'].include(this.method)) {
|
| - // simulate other verbs over post
|
| - params['_method'] = this.method;
|
| - this.method = 'post';
|
| - }
|
| -
|
| - params = Hash.toQueryString(params);
|
| - if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_='
|
| -
|
| - // when GET, append parameters to URL
|
| - if (this.method == 'get' && params)
|
| - this.url += (this.url.indexOf('?') > -1 ? '&' : '?') + params;
|
| -
|
| - try {
|
| - Ajax.Responders.dispatch('onCreate', this, this.transport);
|
| -
|
| - this.transport.open(this.method.toUpperCase(), this.url,
|
| - this.options.asynchronous);
|
| -
|
| - if (this.options.asynchronous)
|
| - setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
|
| -
|
| - this.transport.onreadystatechange = this.onStateChange.bind(this);
|
| - this.setRequestHeaders();
|
| -
|
| - var body = this.method == 'post' ? (this.options.postBody || params) : null;
|
| -
|
| - this.transport.send(body);
|
| -
|
| - /* Force Firefox to handle ready state 4 for synchronous requests */
|
| - if (!this.options.asynchronous && this.transport.overrideMimeType)
|
| - this.onStateChange();
|
| -
|
| - }
|
| - catch (e) {
|
| - this.dispatchException(e);
|
| - }
|
| - },
|
| -
|
| - onStateChange: function() {
|
| - var readyState = this.transport.readyState;
|
| - if (readyState > 1 && !((readyState == 4) && this._complete))
|
| - this.respondToReadyState(this.transport.readyState);
|
| - },
|
| -
|
| - setRequestHeaders: function() {
|
| - var headers = {
|
| - 'X-Requested-With': 'XMLHttpRequest',
|
| - 'X-Prototype-Version': Prototype.Version,
|
| - 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
|
| - };
|
| -
|
| - if (this.method == 'post') {
|
| - headers['Content-type'] = this.options.contentType +
|
| - (this.options.encoding ? '; charset=' + this.options.encoding : '');
|
| -
|
| - /* Force "Connection: close" for older Mozilla browsers to work
|
| - * around a bug where XMLHttpRequest sends an incorrect
|
| - * Content-length header. See Mozilla Bugzilla #246651.
|
| - */
|
| - if (this.transport.overrideMimeType &&
|
| - (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
|
| - headers['Connection'] = 'close';
|
| - }
|
| -
|
| - // user-defined headers
|
| - if (typeof this.options.requestHeaders == 'object') {
|
| - var extras = this.options.requestHeaders;
|
| -
|
| - if (typeof extras.push == 'function')
|
| - for (var i = 0, length = extras.length; i < length; i += 2)
|
| - headers[extras[i]] = extras[i+1];
|
| - else
|
| - $H(extras).each(function(pair) { headers[pair.key] = pair.value });
|
| - }
|
| -
|
| - for (var name in headers)
|
| - this.transport.setRequestHeader(name, headers[name]);
|
| - },
|
| -
|
| - success: function() {
|
| - return !this.transport.status
|
| - || (this.transport.status >= 200 && this.transport.status < 300);
|
| - },
|
| -
|
| - respondToReadyState: function(readyState) {
|
| - var state = Ajax.Request.Events[readyState];
|
| - var transport = this.transport, json = this.evalJSON();
|
| -
|
| - if (state == 'Complete') {
|
| - try {
|
| - this._complete = true;
|
| - (this.options['on' + this.transport.status]
|
| - || this.options['on' + (this.success() ? 'Success' : 'Failure')]
|
| - || Prototype.emptyFunction)(transport, json);
|
| - } catch (e) {
|
| - this.dispatchException(e);
|
| - }
|
| -
|
| - if ((this.getHeader('Content-type') || 'text/javascript').strip().
|
| - match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
|
| - this.evalResponse();
|
| - }
|
| -
|
| - try {
|
| - (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
|
| - Ajax.Responders.dispatch('on' + state, this, transport, json);
|
| - } catch (e) {
|
| - this.dispatchException(e);
|
| - }
|
| -
|
| - if (state == 'Complete') {
|
| - // avoid memory leak in MSIE: clean up
|
| - this.transport.onreadystatechange = Prototype.emptyFunction;
|
| - }
|
| - },
|
| -
|
| - getHeader: function(name) {
|
| - try {
|
| - return this.transport.getResponseHeader(name);
|
| - } catch (e) { return null }
|
| - },
|
| -
|
| - evalJSON: function() {
|
| - try {
|
| - var json = this.getHeader('X-JSON');
|
| - return json ? eval('(' + json + ')') : null;
|
| - } catch (e) { return null }
|
| - },
|
| -
|
| - evalResponse: function() {
|
| - try {
|
| - return eval(this.transport.responseText);
|
| - } catch (e) {
|
| - this.dispatchException(e);
|
| - }
|
| - },
|
| -
|
| - dispatchException: function(exception) {
|
| - (this.options.onException || Prototype.emptyFunction)(this, exception);
|
| - Ajax.Responders.dispatch('onException', this, exception);
|
| - }
|
| -});
|
| -
|
| -Ajax.Updater = Class.create();
|
| -
|
| -Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
|
| - initialize: function(container, url, options) {
|
| - this.container = {
|
| - success: (container.success || container),
|
| - failure: (container.failure || (container.success ? null : container))
|
| - }
|
| -
|
| - this.transport = Ajax.getTransport();
|
| - this.setOptions(options);
|
| -
|
| - var onComplete = this.options.onComplete || Prototype.emptyFunction;
|
| - this.options.onComplete = (function(transport, param) {
|
| - this.updateContent();
|
| - onComplete(transport, param);
|
| - }).bind(this);
|
| -
|
| - this.request(url);
|
| - },
|
| -
|
| - updateContent: function() {
|
| - var receiver = this.container[this.success() ? 'success' : 'failure'];
|
| - var response = this.transport.responseText;
|
| -
|
| - if (!this.options.evalScripts) response = response.stripScripts();
|
| -
|
| - if (receiver = $(receiver)) {
|
| - if (this.options.insertion)
|
| - new this.options.insertion(receiver, response);
|
| - else
|
| - receiver.update(response);
|
| - }
|
| -
|
| - if (this.success()) {
|
| - if (this.onComplete)
|
| - setTimeout(this.onComplete.bind(this), 10);
|
| - }
|
| - }
|
| -});
|
| -
|
| -Ajax.PeriodicalUpdater = Class.create();
|
| -Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
|
| - initialize: function(container, url, options) {
|
| - this.setOptions(options);
|
| - this.onComplete = this.options.onComplete;
|
| -
|
| - this.frequency = (this.options.frequency || 2);
|
| - this.decay = (this.options.decay || 1);
|
| -
|
| - this.updater = {};
|
| - this.container = container;
|
| - this.url = url;
|
| -
|
| - this.start();
|
| - },
|
| -
|
| - start: function() {
|
| - this.options.onComplete = this.updateComplete.bind(this);
|
| - this.onTimerEvent();
|
| - },
|
| -
|
| - stop: function() {
|
| - this.updater.options.onComplete = undefined;
|
| - clearTimeout(this.timer);
|
| - (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
|
| - },
|
| -
|
| - updateComplete: function(request) {
|
| - if (this.options.decay) {
|
| - this.decay = (request.responseText == this.lastText ?
|
| - this.decay * this.options.decay : 1);
|
| -
|
| - this.lastText = request.responseText;
|
| - }
|
| - this.timer = setTimeout(this.onTimerEvent.bind(this),
|
| - this.decay * this.frequency * 1000);
|
| - },
|
| -
|
| - onTimerEvent: function() {
|
| - this.updater = new Ajax.Updater(this.container, this.url, this.options);
|
| - }
|
| -});
|
| -function $(element) {
|
| - if (arguments.length > 1) {
|
| - for (var i = 0, elements = [], length = arguments.length; i < length; i++)
|
| - elements.push($(arguments[i]));
|
| - return elements;
|
| - }
|
| - if (typeof element == 'string')
|
| - element = document.getElementById(element);
|
| - return Element.extend(element);
|
| -}
|
| -
|
| -if (Prototype.BrowserFeatures.XPath) {
|
| - document._getElementsByXPath = function(expression, parentElement) {
|
| - var results = [];
|
| - var query = document.evaluate(expression, $(parentElement) || document,
|
| - null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
|
| - for (var i = 0, length = query.snapshotLength; i < length; i++)
|
| - results.push(query.snapshotItem(i));
|
| - return results;
|
| - };
|
| -}
|
| -
|
| -document.getElementsByClassName = function(className, parentElement) {
|
| - if (Prototype.BrowserFeatures.XPath) {
|
| - var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
|
| - return document._getElementsByXPath(q, parentElement);
|
| - } else {
|
| - var children = ($(parentElement) || document.body).getElementsByTagName('*');
|
| - var elements = [], child;
|
| - for (var i = 0, length = children.length; i < length; i++) {
|
| - child = children[i];
|
| - if (Element.hasClassName(child, className))
|
| - elements.push(Element.extend(child));
|
| - }
|
| - return elements;
|
| - }
|
| -};
|
| -
|
| -/*--------------------------------------------------------------------------*/
|
| -
|
| -if (!window.Element)
|
| - var Element = new Object();
|
| -
|
| -Element.extend = function(element) {
|
| - if (!element || _nativeExtensions || element.nodeType == 3) return element;
|
| -
|
| - if (!element._extended && element.tagName && element != window) {
|
| - var methods = Object.clone(Element.Methods), cache = Element.extend.cache;
|
| -
|
| - if (element.tagName == 'FORM')
|
| - Object.extend(methods, Form.Methods);
|
| - if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName))
|
| - Object.extend(methods, Form.Element.Methods);
|
| -
|
| - Object.extend(methods, Element.Methods.Simulated);
|
| -
|
| - for (var property in methods) {
|
| - var value = methods[property];
|
| - if (typeof value == 'function' && !(property in element))
|
| - element[property] = cache.findOrStore(value);
|
| - }
|
| - }
|
| -
|
| - element._extended = true;
|
| - return element;
|
| -};
|
| -
|
| -Element.extend.cache = {
|
| - findOrStore: function(value) {
|
| - return this[value] = this[value] || function() {
|
| - return value.apply(null, [this].concat($A(arguments)));
|
| - }
|
| - }
|
| -};
|
| -
|
| -Element.Methods = {
|
| - visible: function(element) {
|
| - return $(element).style.display != 'none';
|
| - },
|
| -
|
| - toggle: function(element) {
|
| - element = $(element);
|
| - Element[Element.visible(element) ? 'hide' : 'show'](element);
|
| - return element;
|
| - },
|
| -
|
| - hide: function(element) {
|
| - $(element).style.display = 'none';
|
| - return element;
|
| - },
|
| -
|
| - show: function(element) {
|
| - $(element).style.display = '';
|
| - return element;
|
| - },
|
| -
|
| - remove: function(element) {
|
| - element = $(element);
|
| - element.parentNode.removeChild(element);
|
| - return element;
|
| - },
|
| -
|
| - update: function(element, html) {
|
| - html = typeof html == 'undefined' ? '' : html.toString();
|
| - $(element).innerHTML = html.stripScripts();
|
| - setTimeout(function() {html.evalScripts()}, 10);
|
| - return element;
|
| - },
|
| -
|
| - replace: function(element, html) {
|
| - element = $(element);
|
| - html = typeof html == 'undefined' ? '' : html.toString();
|
| - if (element.outerHTML) {
|
| - element.outerHTML = html.stripScripts();
|
| - } else {
|
| - var range = element.ownerDocument.createRange();
|
| - range.selectNodeContents(element);
|
| - element.parentNode.replaceChild(
|
| - range.createContextualFragment(html.stripScripts()), element);
|
| - }
|
| - setTimeout(function() {html.evalScripts()}, 10);
|
| - return element;
|
| - },
|
| -
|
| - inspect: function(element) {
|
| - element = $(element);
|
| - var result = '<' + element.tagName.toLowerCase();
|
| - $H({'id': 'id', 'className': 'class'}).each(function(pair) {
|
| - var property = pair.first(), attribute = pair.last();
|
| - var value = (element[property] || '').toString();
|
| - if (value) result += ' ' + attribute + '=' + value.inspect(true);
|
| - });
|
| - return result + '>';
|
| - },
|
| -
|
| - recursivelyCollect: function(element, property) {
|
| - element = $(element);
|
| - var elements = [];
|
| - while (element = element[property])
|
| - if (element.nodeType == 1)
|
| - elements.push(Element.extend(element));
|
| - return elements;
|
| - },
|
| -
|
| - ancestors: function(element) {
|
| - return $(element).recursivelyCollect('parentNode');
|
| - },
|
| -
|
| - descendants: function(element) {
|
| - return $A($(element).getElementsByTagName('*'));
|
| - },
|
| -
|
| - immediateDescendants: function(element) {
|
| - if (!(element = $(element).firstChild)) return [];
|
| - while (element && element.nodeType != 1) element = element.nextSibling;
|
| - if (element) return [element].concat($(element).nextSiblings());
|
| - return [];
|
| - },
|
| -
|
| - previousSiblings: function(element) {
|
| - return $(element).recursivelyCollect('previousSibling');
|
| - },
|
| -
|
| - nextSiblings: function(element) {
|
| - return $(element).recursivelyCollect('nextSibling');
|
| - },
|
| -
|
| - siblings: function(element) {
|
| - element = $(element);
|
| - return element.previousSiblings().reverse().concat(element.nextSiblings());
|
| - },
|
| -
|
| - match: function(element, selector) {
|
| - if (typeof selector == 'string')
|
| - selector = new Selector(selector);
|
| - return selector.match($(element));
|
| - },
|
| -
|
| - up: function(element, expression, index) {
|
| - return Selector.findElement($(element).ancestors(), expression, index);
|
| - },
|
| -
|
| - down: function(element, expression, index) {
|
| - return Selector.findElement($(element).descendants(), expression, index);
|
| - },
|
| -
|
| - previous: function(element, expression, index) {
|
| - return Selector.findElement($(element).previousSiblings(), expression, index);
|
| - },
|
| -
|
| - next: function(element, expression, index) {
|
| - return Selector.findElement($(element).nextSiblings(), expression, index);
|
| - },
|
| -
|
| - getElementsBySelector: function() {
|
| - var args = $A(arguments), element = $(args.shift());
|
| - return Selector.findChildElements(element, args);
|
| - },
|
| -
|
| - getElementsByClassName: function(element, className) {
|
| - return document.getElementsByClassName(className, element);
|
| - },
|
| -
|
| - readAttribute: function(element, name) {
|
| - element = $(element);
|
| - if (document.all && !window.opera) {
|
| - var t = Element._attributeTranslations;
|
| - if (t.values[name]) return t.values[name](element, name);
|
| - if (t.names[name]) name = t.names[name];
|
| - var attribute = element.attributes[name];
|
| - if(attribute) return attribute.nodeValue;
|
| - }
|
| - return element.getAttribute(name);
|
| - },
|
| -
|
| - getHeight: function(element) {
|
| - return $(element).getDimensions().height;
|
| - },
|
| -
|
| - getWidth: function(element) {
|
| - return $(element).getDimensions().width;
|
| - },
|
| -
|
| - classNames: function(element) {
|
| - return new Element.ClassNames(element);
|
| - },
|
| -
|
| - hasClassName: function(element, className) {
|
| - if (!(element = $(element))) return;
|
| - var elementClassName = element.className;
|
| - if (elementClassName.length == 0) return false;
|
| - if (elementClassName == className ||
|
| - elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
|
| - return true;
|
| - return false;
|
| - },
|
| -
|
| - addClassName: function(element, className) {
|
| - if (!(element = $(element))) return;
|
| - Element.classNames(element).add(className);
|
| - return element;
|
| - },
|
| -
|
| - removeClassName: function(element, className) {
|
| - if (!(element = $(element))) return;
|
| - Element.classNames(element).remove(className);
|
| - return element;
|
| - },
|
| -
|
| - toggleClassName: function(element, className) {
|
| - if (!(element = $(element))) return;
|
| - Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
|
| - return element;
|
| - },
|
| -
|
| - observe: function() {
|
| - Event.observe.apply(Event, arguments);
|
| - return $A(arguments).first();
|
| - },
|
| -
|
| - stopObserving: function() {
|
| - Event.stopObserving.apply(Event, arguments);
|
| - return $A(arguments).first();
|
| - },
|
| -
|
| - // removes whitespace-only text node children
|
| - cleanWhitespace: function(element) {
|
| - element = $(element);
|
| - var node = element.firstChild;
|
| - while (node) {
|
| - var nextNode = node.nextSibling;
|
| - if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
|
| - element.removeChild(node);
|
| - node = nextNode;
|
| - }
|
| - return element;
|
| - },
|
| -
|
| - empty: function(element) {
|
| - return $(element).innerHTML.match(/^\s*$/);
|
| - },
|
| -
|
| - descendantOf: function(element, ancestor) {
|
| - element = $(element), ancestor = $(ancestor);
|
| - while (element = element.parentNode)
|
| - if (element == ancestor) return true;
|
| - return false;
|
| - },
|
| -
|
| - scrollTo: function(element) {
|
| - element = $(element);
|
| - var pos = Position.cumulativeOffset(element);
|
| - window.scrollTo(pos[0], pos[1]);
|
| - return element;
|
| - },
|
| -
|
| - getStyle: function(element, style) {
|
| - element = $(element);
|
| - if (['float','cssFloat'].include(style))
|
| - style = (typeof element.style.styleFloat != 'undefined' ? 'styleFloat' : 'cssFloat');
|
| - style = style.camelize();
|
| - var value = element.style[style];
|
| - if (!value) {
|
| - if (document.defaultView && document.defaultView.getComputedStyle) {
|
| - var css = document.defaultView.getComputedStyle(element, null);
|
| - value = css ? css[style] : null;
|
| - } else if (element.currentStyle) {
|
| - value = element.currentStyle[style];
|
| - }
|
| - }
|
| -
|
| - if((value == 'auto') && ['width','height'].include(style) && (element.getStyle('display') != 'none'))
|
| - value = element['offset'+style.capitalize()] + 'px';
|
| -
|
| - if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
|
| - if (Element.getStyle(element, 'position') == 'static') value = 'auto';
|
| - if(style == 'opacity') {
|
| - if(value) return parseFloat(value);
|
| - if(value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
|
| - if(value[1]) return parseFloat(value[1]) / 100;
|
| - return 1.0;
|
| - }
|
| - return value == 'auto' ? null : value;
|
| - },
|
| -
|
| - setStyle: function(element, style) {
|
| - element = $(element);
|
| - for (var name in style) {
|
| - var value = style[name];
|
| - if(name == 'opacity') {
|
| - if (value == 1) {
|
| - value = (/Gecko/.test(navigator.userAgent) &&
|
| - !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0;
|
| - if(/MSIE/.test(navigator.userAgent) && !window.opera)
|
| - element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
|
| - } else if(value == '') {
|
| - if(/MSIE/.test(navigator.userAgent) && !window.opera)
|
| - element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
|
| - } else {
|
| - if(value < 0.00001) value = 0;
|
| - if(/MSIE/.test(navigator.userAgent) && !window.opera)
|
| - element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
|
| - 'alpha(opacity='+value*100+')';
|
| - }
|
| - } else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
|
| - element.style[name.camelize()] = value;
|
| - }
|
| - return element;
|
| - },
|
| -
|
| - getDimensions: function(element) {
|
| - element = $(element);
|
| - var display = $(element).getStyle('display');
|
| - if (display != 'none' && display != null) // Safari bug
|
| - return {width: element.offsetWidth, height: element.offsetHeight};
|
| -
|
| - // All *Width and *Height properties give 0 on elements with display none,
|
| - // so enable the element temporarily
|
| - var els = element.style;
|
| - var originalVisibility = els.visibility;
|
| - var originalPosition = els.position;
|
| - var originalDisplay = els.display;
|
| - els.visibility = 'hidden';
|
| - els.position = 'absolute';
|
| - els.display = 'block';
|
| - var originalWidth = element.clientWidth;
|
| - var originalHeight = element.clientHeight;
|
| - els.display = originalDisplay;
|
| - els.position = originalPosition;
|
| - els.visibility = originalVisibility;
|
| - return {width: originalWidth, height: originalHeight};
|
| - },
|
| -
|
| - makePositioned: function(element) {
|
| - element = $(element);
|
| - var pos = Element.getStyle(element, 'position');
|
| - if (pos == 'static' || !pos) {
|
| - element._madePositioned = true;
|
| - element.style.position = 'relative';
|
| - // Opera returns the offset relative to the positioning context, when an
|
| - // element is position relative but top and left have not been defined
|
| - if (window.opera) {
|
| - element.style.top = 0;
|
| - element.style.left = 0;
|
| - }
|
| - }
|
| - return element;
|
| - },
|
| -
|
| - undoPositioned: function(element) {
|
| - element = $(element);
|
| - if (element._madePositioned) {
|
| - element._madePositioned = undefined;
|
| - element.style.position =
|
| - element.style.top =
|
| - element.style.left =
|
| - element.style.bottom =
|
| - element.style.right = '';
|
| - }
|
| - return element;
|
| - },
|
| -
|
| - makeClipping: function(element) {
|
| - element = $(element);
|
| - if (element._overflow) return element;
|
| - element._overflow = element.style.overflow || 'auto';
|
| - if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
|
| - element.style.overflow = 'hidden';
|
| - return element;
|
| - },
|
| -
|
| - undoClipping: function(element) {
|
| - element = $(element);
|
| - if (!element._overflow) return element;
|
| - element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
|
| - element._overflow = null;
|
| - return element;
|
| - }
|
| -};
|
| -
|
| -Object.extend(Element.Methods, {childOf: Element.Methods.descendantOf});
|
| -
|
| -Element._attributeTranslations = {};
|
| -
|
| -Element._attributeTranslations.names = {
|
| - colspan: "colSpan",
|
| - rowspan: "rowSpan",
|
| - valign: "vAlign",
|
| - datetime: "dateTime",
|
| - accesskey: "accessKey",
|
| - tabindex: "tabIndex",
|
| - enctype: "encType",
|
| - maxlength: "maxLength",
|
| - readonly: "readOnly",
|
| - longdesc: "longDesc"
|
| -};
|
| -
|
| -Element._attributeTranslations.values = {
|
| - _getAttr: function(element, attribute) {
|
| - return element.getAttribute(attribute, 2);
|
| - },
|
| -
|
| - _flag: function(element, attribute) {
|
| - return $(element).hasAttribute(attribute) ? attribute : null;
|
| - },
|
| -
|
| - style: function(element) {
|
| - return element.style.cssText.toLowerCase();
|
| - },
|
| -
|
| - title: function(element) {
|
| - var node = element.getAttributeNode('title');
|
| - return node.specified ? node.nodeValue : null;
|
| - }
|
| -};
|
| -
|
| -Object.extend(Element._attributeTranslations.values, {
|
| - href: Element._attributeTranslations.values._getAttr,
|
| - src: Element._attributeTranslations.values._getAttr,
|
| - disabled: Element._attributeTranslations.values._flag,
|
| - checked: Element._attributeTranslations.values._flag,
|
| - readonly: Element._attributeTranslations.values._flag,
|
| - multiple: Element._attributeTranslations.values._flag
|
| -});
|
| -
|
| -Element.Methods.Simulated = {
|
| - hasAttribute: function(element, attribute) {
|
| - var t = Element._attributeTranslations;
|
| - attribute = t.names[attribute] || attribute;
|
| - return $(element).getAttributeNode(attribute).specified;
|
| - }
|
| -};
|
| -
|
| -// IE is missing .innerHTML support for TABLE-related elements
|
| -if (document.all && !window.opera){
|
| - Element.Methods.update = function(element, html) {
|
| - element = $(element);
|
| - html = typeof html == 'undefined' ? '' : html.toString();
|
| - var tagName = element.tagName.toUpperCase();
|
| - if (['THEAD','TBODY','TR','TD'].include(tagName)) {
|
| - var div = document.createElement('div');
|
| - switch (tagName) {
|
| - case 'THEAD':
|
| - case 'TBODY':
|
| - div.innerHTML = '<table><tbody>' + html.stripScripts() + '</tbody></table>';
|
| - depth = 2;
|
| - break;
|
| - case 'TR':
|
| - div.innerHTML = '<table><tbody><tr>' + html.stripScripts() + '</tr></tbody></table>';
|
| - depth = 3;
|
| - break;
|
| - case 'TD':
|
| - div.innerHTML = '<table><tbody><tr><td>' + html.stripScripts() + '</td></tr></tbody></table>';
|
| - depth = 4;
|
| - }
|
| - $A(element.childNodes).each(function(node){
|
| - element.removeChild(node)
|
| - });
|
| - depth.times(function(){ div = div.firstChild });
|
| -
|
| - $A(div.childNodes).each(
|
| - function(node){ element.appendChild(node) });
|
| - } else {
|
| - element.innerHTML = html.stripScripts();
|
| - }
|
| - setTimeout(function() {html.evalScripts()}, 10);
|
| - return element;
|
| - }
|
| -};
|
| -
|
| -Object.extend(Element, Element.Methods);
|
| -
|
| -var _nativeExtensions = false;
|
| -
|
| -if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
|
| - ['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) {
|
| - var className = 'HTML' + tag + 'Element';
|
| - if(window[className]) return;
|
| - var klass = window[className] = {};
|
| - klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__;
|
| - });
|
| -
|
| -Element.addMethods = function(methods) {
|
| - Object.extend(Element.Methods, methods || {});
|
| -
|
| - function copy(methods, destination, onlyIfAbsent) {
|
| - onlyIfAbsent = onlyIfAbsent || false;
|
| - var cache = Element.extend.cache;
|
| - for (var property in methods) {
|
| - var value = methods[property];
|
| - if (!onlyIfAbsent || !(property in destination))
|
| - destination[property] = cache.findOrStore(value);
|
| - }
|
| - }
|
| -
|
| - if (typeof HTMLElement != 'undefined') {
|
| - copy(Element.Methods, HTMLElement.prototype);
|
| - copy(Element.Methods.Simulated, HTMLElement.prototype, true);
|
| - copy(Form.Methods, HTMLFormElement.prototype);
|
| - [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) {
|
| - copy(Form.Element.Methods, klass.prototype);
|
| - });
|
| - _nativeExtensions = true;
|
| - }
|
| -}
|
| -
|
| -var Toggle = new Object();
|
| -Toggle.display = Element.toggle;
|
| -
|
| -/*--------------------------------------------------------------------------*/
|
| -
|
| -Abstract.Insertion = function(adjacency) {
|
| - this.adjacency = adjacency;
|
| -}
|
| -
|
| -Abstract.Insertion.prototype = {
|
| - initialize: function(element, content) {
|
| - this.element = $(element);
|
| - this.content = content.stripScripts();
|
| -
|
| - if (this.adjacency && this.element.insertAdjacentHTML) {
|
| - try {
|
| - this.element.insertAdjacentHTML(this.adjacency, this.content);
|
| - } catch (e) {
|
| - var tagName = this.element.tagName.toUpperCase();
|
| - if (['TBODY', 'TR'].include(tagName)) {
|
| - this.insertContent(this.contentFromAnonymousTable());
|
| - } else {
|
| - throw e;
|
| - }
|
| - }
|
| - } else {
|
| - this.range = this.element.ownerDocument.createRange();
|
| - if (this.initializeRange) this.initializeRange();
|
| - this.insertContent([this.range.createContextualFragment(this.content)]);
|
| - }
|
| -
|
| - setTimeout(function() {content.evalScripts()}, 10);
|
| - },
|
| -
|
| - contentFromAnonymousTable: function() {
|
| - var div = document.createElement('div');
|
| - div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
|
| - return $A(div.childNodes[0].childNodes[0].childNodes);
|
| - }
|
| -}
|
| -
|
| -var Insertion = new Object();
|
| -
|
| -Insertion.Before = Class.create();
|
| -Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
|
| - initializeRange: function() {
|
| - this.range.setStartBefore(this.element);
|
| - },
|
| -
|
| - insertContent: function(fragments) {
|
| - fragments.each((function(fragment) {
|
| - this.element.parentNode.insertBefore(fragment, this.element);
|
| - }).bind(this));
|
| - }
|
| -});
|
| -
|
| -Insertion.Top = Class.create();
|
| -Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
|
| - initializeRange: function() {
|
| - this.range.selectNodeContents(this.element);
|
| - this.range.collapse(true);
|
| - },
|
| -
|
| - insertContent: function(fragments) {
|
| - fragments.reverse(false).each((function(fragment) {
|
| - this.element.insertBefore(fragment, this.element.firstChild);
|
| - }).bind(this));
|
| - }
|
| -});
|
| -
|
| -Insertion.Bottom = Class.create();
|
| -Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
|
| - initializeRange: function() {
|
| - this.range.selectNodeContents(this.element);
|
| - this.range.collapse(this.element);
|
| - },
|
| -
|
| - insertContent: function(fragments) {
|
| - fragments.each((function(fragment) {
|
| - this.element.appendChild(fragment);
|
| - }).bind(this));
|
| - }
|
| -});
|
| -
|
| -Insertion.After = Class.create();
|
| -Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
|
| - initializeRange: function() {
|
| - this.range.setStartAfter(this.element);
|
| - },
|
| -
|
| - insertContent: function(fragments) {
|
| - fragments.each((function(fragment) {
|
| - this.element.parentNode.insertBefore(fragment,
|
| - this.element.nextSibling);
|
| - }).bind(this));
|
| - }
|
| -});
|
| -
|
| -/*--------------------------------------------------------------------------*/
|
| -
|
| -Element.ClassNames = Class.create();
|
| -Element.ClassNames.prototype = {
|
| - initialize: function(element) {
|
| - this.element = $(element);
|
| - },
|
| -
|
| - _each: function(iterator) {
|
| - this.element.className.split(/\s+/).select(function(name) {
|
| - return name.length > 0;
|
| - })._each(iterator);
|
| - },
|
| -
|
| - set: function(className) {
|
| - this.element.className = className;
|
| - },
|
| -
|
| - add: function(classNameToAdd) {
|
| - if (this.include(classNameToAdd)) return;
|
| - this.set($A(this).concat(classNameToAdd).join(' '));
|
| - },
|
| -
|
| - remove: function(classNameToRemove) {
|
| - if (!this.include(classNameToRemove)) return;
|
| - this.set($A(this).without(classNameToRemove).join(' '));
|
| - },
|
| -
|
| - toString: function() {
|
| - return $A(this).join(' ');
|
| - }
|
| -};
|
| -
|
| -Object.extend(Element.ClassNames.prototype, Enumerable);
|
| -var Selector = Class.create();
|
| -Selector.prototype = {
|
| - initialize: function(expression) {
|
| - this.params = {classNames: []};
|
| - this.expression = expression.toString().strip();
|
| - this.parseExpression();
|
| - this.compileMatcher();
|
| - },
|
| -
|
| - parseExpression: function() {
|
| - function abort(message) { throw 'Parse error in selector: ' + message; }
|
| -
|
| - if (this.expression == '') abort('empty expression');
|
| -
|
| - var params = this.params, expr = this.expression, match, modifier, clause, rest;
|
| - while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) {
|
| - params.attributes = params.attributes || [];
|
| - params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
|
| - expr = match[1];
|
| - }
|
| -
|
| - if (expr == '*') return this.params.wildcard = true;
|
| -
|
| - while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) {
|
| - modifier = match[1], clause = match[2], rest = match[3];
|
| - switch (modifier) {
|
| - case '#': params.id = clause; break;
|
| - case '.': params.classNames.push(clause); break;
|
| - case '':
|
| - case undefined: params.tagName = clause.toUpperCase(); break;
|
| - default: abort(expr.inspect());
|
| - }
|
| - expr = rest;
|
| - }
|
| -
|
| - if (expr.length > 0) abort(expr.inspect());
|
| - },
|
| -
|
| - buildMatchExpression: function() {
|
| - var params = this.params, conditions = [], clause;
|
| -
|
| - if (params.wildcard)
|
| - conditions.push('true');
|
| - if (clause = params.id)
|
| - conditions.push('element.readAttribute("id") == ' + clause.inspect());
|
| - if (clause = params.tagName)
|
| - conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
|
| - if ((clause = params.classNames).length > 0)
|
| - for (var i = 0, length = clause.length; i < length; i++)
|
| - conditions.push('element.hasClassName(' + clause[i].inspect() + ')');
|
| - if (clause = params.attributes) {
|
| - clause.each(function(attribute) {
|
| - var value = 'element.readAttribute(' + attribute.name.inspect() + ')';
|
| - var splitValueBy = function(delimiter) {
|
| - return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
|
| - }
|
| -
|
| - switch (attribute.operator) {
|
| - case '=': conditions.push(value + ' == ' + attribute.value.inspect()); break;
|
| - case '~=': conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break;
|
| - case '|=': conditions.push(
|
| - splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect()
|
| - ); break;
|
| - case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break;
|
| - case '':
|
| - case undefined: conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')'); break;
|
| - default: throw 'Unknown operator ' + attribute.operator + ' in selector';
|
| - }
|
| - });
|
| - }
|
| -
|
| - return conditions.join(' && ');
|
| - },
|
| -
|
| - compileMatcher: function() {
|
| - this.match = new Function('element', 'if (!element.tagName) return false; \
|
| - element = $(element); \
|
| - return ' + this.buildMatchExpression());
|
| - },
|
| -
|
| - findElements: function(scope) {
|
| - var element;
|
| -
|
| - if (element = $(this.params.id))
|
| - if (this.match(element))
|
| - if (!scope || Element.childOf(element, scope))
|
| - return [element];
|
| -
|
| - scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
|
| -
|
| - var results = [];
|
| - for (var i = 0, length = scope.length; i < length; i++)
|
| - if (this.match(element = scope[i]))
|
| - results.push(Element.extend(element));
|
| -
|
| - return results;
|
| - },
|
| -
|
| - toString: function() {
|
| - return this.expression;
|
| - }
|
| -}
|
| -
|
| -Object.extend(Selector, {
|
| - matchElements: function(elements, expression) {
|
| - var selector = new Selector(expression);
|
| - return elements.select(selector.match.bind(selector)).map(Element.extend);
|
| - },
|
| -
|
| - findElement: function(elements, expression, index) {
|
| - if (typeof expression == 'number') index = expression, expression = false;
|
| - return Selector.matchElements(elements, expression || '*')[index || 0];
|
| - },
|
| -
|
| - findChildElements: function(element, expressions) {
|
| - return expressions.map(function(expression) {
|
| - return expression.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/g).inject([null], function(results, expr) {
|
| - var selector = new Selector(expr);
|
| - return results.inject([], function(elements, result) {
|
| - return elements.concat(selector.findElements(result || element));
|
| - });
|
| - });
|
| - }).flatten();
|
| - }
|
| -});
|
| -
|
| -function $$() {
|
| - return Selector.findChildElements(document, $A(arguments));
|
| -}
|
| -var Form = {
|
| - reset: function(form) {
|
| - $(form).reset();
|
| - return form;
|
| - },
|
| -
|
| - serializeElements: function(elements, getHash) {
|
| - var data = elements.inject({}, function(result, element) {
|
| - if (!element.disabled && element.name) {
|
| - var key = element.name, value = $(element).getValue();
|
| - if (value != undefined) {
|
| - if (result[key]) {
|
| - if (result[key].constructor != Array) result[key] = [result[key]];
|
| - result[key].push(value);
|
| - }
|
| - else result[key] = value;
|
| - }
|
| - }
|
| - return result;
|
| - });
|
| -
|
| - return getHash ? data : Hash.toQueryString(data);
|
| - }
|
| -};
|
| -
|
| -Form.Methods = {
|
| - serialize: function(form, getHash) {
|
| - return Form.serializeElements(Form.getElements(form), getHash);
|
| - },
|
| -
|
| - getElements: function(form) {
|
| - return $A($(form).getElementsByTagName('*')).inject([],
|
| - function(elements, child) {
|
| - if (Form.Element.Serializers[child.tagName.toLowerCase()])
|
| - elements.push(Element.extend(child));
|
| - return elements;
|
| - }
|
| - );
|
| - },
|
| -
|
| - getInputs: function(form, typeName, name) {
|
| - form = $(form);
|
| - var inputs = form.getElementsByTagName('input');
|
| -
|
| - if (!typeName && !name) return $A(inputs).map(Element.extend);
|
| -
|
| - for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
|
| - var input = inputs[i];
|
| - if ((typeName && input.type != typeName) || (name && input.name != name))
|
| - continue;
|
| - matchingInputs.push(Element.extend(input));
|
| - }
|
| -
|
| - return matchingInputs;
|
| - },
|
| -
|
| - disable: function(form) {
|
| - form = $(form);
|
| - form.getElements().each(function(element) {
|
| - element.blur();
|
| - element.disabled = 'true';
|
| - });
|
| - return form;
|
| - },
|
| -
|
| - enable: function(form) {
|
| - form = $(form);
|
| - form.getElements().each(function(element) {
|
| - element.disabled = '';
|
| - });
|
| - return form;
|
| - },
|
| -
|
| - findFirstElement: function(form) {
|
| - return $(form).getElements().find(function(element) {
|
| - return element.type != 'hidden' && !element.disabled &&
|
| - ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
|
| - });
|
| - },
|
| -
|
| - focusFirstElement: function(form) {
|
| - form = $(form);
|
| - form.findFirstElement().activate();
|
| - return form;
|
| - }
|
| -}
|
| -
|
| -Object.extend(Form, Form.Methods);
|
| -
|
| -/*--------------------------------------------------------------------------*/
|
| -
|
| -Form.Element = {
|
| - focus: function(element) {
|
| - $(element).focus();
|
| - return element;
|
| - },
|
| -
|
| - select: function(element) {
|
| - $(element).select();
|
| - return element;
|
| - }
|
| -}
|
| -
|
| -Form.Element.Methods = {
|
| - serialize: function(element) {
|
| - element = $(element);
|
| - if (!element.disabled && element.name) {
|
| - var value = element.getValue();
|
| - if (value != undefined) {
|
| - var pair = {};
|
| - pair[element.name] = value;
|
| - return Hash.toQueryString(pair);
|
| - }
|
| - }
|
| - return '';
|
| - },
|
| -
|
| - getValue: function(element) {
|
| - element = $(element);
|
| - var method = element.tagName.toLowerCase();
|
| - return Form.Element.Serializers[method](element);
|
| - },
|
| -
|
| - clear: function(element) {
|
| - $(element).value = '';
|
| - return element;
|
| - },
|
| -
|
| - present: function(element) {
|
| - return $(element).value != '';
|
| - },
|
| -
|
| - activate: function(element) {
|
| - element = $(element);
|
| - element.focus();
|
| - if (element.select && ( element.tagName.toLowerCase() != 'input' ||
|
| - !['button', 'reset', 'submit'].include(element.type) ) )
|
| - element.select();
|
| - return element;
|
| - },
|
| -
|
| - disable: function(element) {
|
| - element = $(element);
|
| - element.disabled = true;
|
| - return element;
|
| - },
|
| -
|
| - enable: function(element) {
|
| - element = $(element);
|
| - element.blur();
|
| - element.disabled = false;
|
| - return element;
|
| - }
|
| -}
|
| -
|
| -Object.extend(Form.Element, Form.Element.Methods);
|
| -var Field = Form.Element;
|
| -var $F = Form.Element.getValue;
|
| -
|
| -/*--------------------------------------------------------------------------*/
|
| -
|
| -Form.Element.Serializers = {
|
| - input: function(element) {
|
| - switch (element.type.toLowerCase()) {
|
| - case 'checkbox':
|
| - case 'radio':
|
| - return Form.Element.Serializers.inputSelector(element);
|
| - default:
|
| - return Form.Element.Serializers.textarea(element);
|
| - }
|
| - },
|
| -
|
| - inputSelector: function(element) {
|
| - return element.checked ? element.value : null;
|
| - },
|
| -
|
| - textarea: function(element) {
|
| - return element.value;
|
| - },
|
| -
|
| - select: function(element) {
|
| - return this[element.type == 'select-one' ?
|
| - 'selectOne' : 'selectMany'](element);
|
| - },
|
| -
|
| - selectOne: function(element) {
|
| - var index = element.selectedIndex;
|
| - return index >= 0 ? this.optionValue(element.options[index]) : null;
|
| - },
|
| -
|
| - selectMany: function(element) {
|
| - var values, length = element.length;
|
| - if (!length) return null;
|
| -
|
| - for (var i = 0, values = []; i < length; i++) {
|
| - var opt = element.options[i];
|
| - if (opt.selected) values.push(this.optionValue(opt));
|
| - }
|
| - return values;
|
| - },
|
| -
|
| - optionValue: function(opt) {
|
| - // extend element because hasAttribute may not be native
|
| - return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
|
| - }
|
| -}
|
| -
|
| -/*--------------------------------------------------------------------------*/
|
| -
|
| -Abstract.TimedObserver = function() {}
|
| -Abstract.TimedObserver.prototype = {
|
| - initialize: function(element, frequency, callback) {
|
| - this.frequency = frequency;
|
| - this.element = $(element);
|
| - this.callback = callback;
|
| -
|
| - this.lastValue = this.getValue();
|
| - this.registerCallback();
|
| - },
|
| -
|
| - registerCallback: function() {
|
| - setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
|
| - },
|
| -
|
| - onTimerEvent: function() {
|
| - var value = this.getValue();
|
| - var changed = ('string' == typeof this.lastValue && 'string' == typeof value
|
| - ? this.lastValue != value : String(this.lastValue) != String(value));
|
| - if (changed) {
|
| - this.callback(this.element, value);
|
| - this.lastValue = value;
|
| - }
|
| - }
|
| -}
|
| -
|
| -Form.Element.Observer = Class.create();
|
| -Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
|
| - getValue: function() {
|
| - return Form.Element.getValue(this.element);
|
| - }
|
| -});
|
| -
|
| -Form.Observer = Class.create();
|
| -Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
|
| - getValue: function() {
|
| - return Form.serialize(this.element);
|
| - }
|
| -});
|
| -
|
| -/*--------------------------------------------------------------------------*/
|
| -
|
| -Abstract.EventObserver = function() {}
|
| -Abstract.EventObserver.prototype = {
|
| - initialize: function(element, callback) {
|
| - this.element = $(element);
|
| - this.callback = callback;
|
| -
|
| - this.lastValue = this.getValue();
|
| - if (this.element.tagName.toLowerCase() == 'form')
|
| - this.registerFormCallbacks();
|
| - else
|
| - this.registerCallback(this.element);
|
| - },
|
| -
|
| - onElementEvent: function() {
|
| - var value = this.getValue();
|
| - if (this.lastValue != value) {
|
| - this.callback(this.element, value);
|
| - this.lastValue = value;
|
| - }
|
| - },
|
| -
|
| - registerFormCallbacks: function() {
|
| - Form.getElements(this.element).each(this.registerCallback.bind(this));
|
| - },
|
| -
|
| - registerCallback: function(element) {
|
| - if (element.type) {
|
| - switch (element.type.toLowerCase()) {
|
| - case 'checkbox':
|
| - case 'radio':
|
| - Event.observe(element, 'click', this.onElementEvent.bind(this));
|
| - break;
|
| - default:
|
| - Event.observe(element, 'change', this.onElementEvent.bind(this));
|
| - break;
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| -Form.Element.EventObserver = Class.create();
|
| -Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
|
| - getValue: function() {
|
| - return Form.Element.getValue(this.element);
|
| - }
|
| -});
|
| -
|
| -Form.EventObserver = Class.create();
|
| -Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
|
| - getValue: function() {
|
| - return Form.serialize(this.element);
|
| - }
|
| -});
|
| -if (!window.Event) {
|
| - var Event = new Object();
|
| -}
|
| -
|
| -Object.extend(Event, {
|
| - KEY_BACKSPACE: 8,
|
| - KEY_TAB: 9,
|
| - KEY_RETURN: 13,
|
| - KEY_ESC: 27,
|
| - KEY_LEFT: 37,
|
| - KEY_UP: 38,
|
| - KEY_RIGHT: 39,
|
| - KEY_DOWN: 40,
|
| - KEY_DELETE: 46,
|
| - KEY_HOME: 36,
|
| - KEY_END: 35,
|
| - KEY_PAGEUP: 33,
|
| - KEY_PAGEDOWN: 34,
|
| -
|
| - element: function(event) {
|
| - return event.target || event.srcElement;
|
| - },
|
| -
|
| - isLeftClick: function(event) {
|
| - return (((event.which) && (event.which == 1)) ||
|
| - ((event.button) && (event.button == 1)));
|
| - },
|
| -
|
| - pointerX: function(event) {
|
| - return event.pageX || (event.clientX +
|
| - (document.documentElement.scrollLeft || document.body.scrollLeft));
|
| - },
|
| -
|
| - pointerY: function(event) {
|
| - return event.pageY || (event.clientY +
|
| - (document.documentElement.scrollTop || document.body.scrollTop));
|
| - },
|
| -
|
| - stop: function(event) {
|
| - if (event.preventDefault) {
|
| - event.preventDefault();
|
| - event.stopPropagation();
|
| - } else {
|
| - event.returnValue = false;
|
| - event.cancelBubble = true;
|
| - }
|
| - },
|
| -
|
| - // find the first node with the given tagName, starting from the
|
| - // node the event was triggered on; traverses the DOM upwards
|
| - findElement: function(event, tagName) {
|
| - var element = Event.element(event);
|
| - while (element.parentNode && (!element.tagName ||
|
| - (element.tagName.toUpperCase() != tagName.toUpperCase())))
|
| - element = element.parentNode;
|
| - return element;
|
| - },
|
| -
|
| - observers: false,
|
| -
|
| - _observeAndCache: function(element, name, observer, useCapture) {
|
| - if (!this.observers) this.observers = [];
|
| - if (element.addEventListener) {
|
| - this.observers.push([element, name, observer, useCapture]);
|
| - element.addEventListener(name, observer, useCapture);
|
| - } else if (element.attachEvent) {
|
| - this.observers.push([element, name, observer, useCapture]);
|
| - element.attachEvent('on' + name, observer);
|
| - }
|
| - },
|
| -
|
| - unloadCache: function() {
|
| - if (!Event.observers) return;
|
| - for (var i = 0, length = Event.observers.length; i < length; i++) {
|
| - Event.stopObserving.apply(this, Event.observers[i]);
|
| - Event.observers[i][0] = null;
|
| - }
|
| - Event.observers = false;
|
| - },
|
| -
|
| - observe: function(element, name, observer, useCapture) {
|
| - element = $(element);
|
| - useCapture = useCapture || false;
|
| -
|
| - if (name == 'keypress' &&
|
| - (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
|
| - || element.attachEvent))
|
| - name = 'keydown';
|
| -
|
| - Event._observeAndCache(element, name, observer, useCapture);
|
| - },
|
| -
|
| - stopObserving: function(element, name, observer, useCapture) {
|
| - element = $(element);
|
| - useCapture = useCapture || false;
|
| -
|
| - if (name == 'keypress' &&
|
| - (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
|
| - || element.detachEvent))
|
| - name = 'keydown';
|
| -
|
| - if (element.removeEventListener) {
|
| - element.removeEventListener(name, observer, useCapture);
|
| - } else if (element.detachEvent) {
|
| - try {
|
| - element.detachEvent('on' + name, observer);
|
| - } catch (e) {}
|
| - }
|
| - }
|
| -});
|
| -
|
| -/* prevent memory leaks in IE */
|
| -if (navigator.appVersion.match(/\bMSIE\b/))
|
| - Event.observe(window, 'unload', Event.unloadCache, false);
|
| -var Position = {
|
| - // set to true if needed, warning: firefox performance problems
|
| - // NOT neeeded for page scrolling, only if draggable contained in
|
| - // scrollable elements
|
| - includeScrollOffsets: false,
|
| -
|
| - // must be called before calling withinIncludingScrolloffset, every time the
|
| - // page is scrolled
|
| - prepare: function() {
|
| - this.deltaX = window.pageXOffset
|
| - || document.documentElement.scrollLeft
|
| - || document.body.scrollLeft
|
| - || 0;
|
| - this.deltaY = window.pageYOffset
|
| - || document.documentElement.scrollTop
|
| - || document.body.scrollTop
|
| - || 0;
|
| - },
|
| -
|
| - realOffset: function(element) {
|
| - var valueT = 0, valueL = 0;
|
| - do {
|
| - valueT += element.scrollTop || 0;
|
| - valueL += element.scrollLeft || 0;
|
| - element = element.parentNode;
|
| - } while (element);
|
| - return [valueL, valueT];
|
| - },
|
| -
|
| - cumulativeOffset: function(element) {
|
| - var valueT = 0, valueL = 0;
|
| - do {
|
| - valueT += element.offsetTop || 0;
|
| - valueL += element.offsetLeft || 0;
|
| - element = element.offsetParent;
|
| - } while (element);
|
| - return [valueL, valueT];
|
| - },
|
| -
|
| - positionedOffset: function(element) {
|
| - var valueT = 0, valueL = 0;
|
| - do {
|
| - valueT += element.offsetTop || 0;
|
| - valueL += element.offsetLeft || 0;
|
| - element = element.offsetParent;
|
| - if (element) {
|
| - if(element.tagName=='BODY') break;
|
| - var p = Element.getStyle(element, 'position');
|
| - if (p == 'relative' || p == 'absolute') break;
|
| - }
|
| - } while (element);
|
| - return [valueL, valueT];
|
| - },
|
| -
|
| - offsetParent: function(element) {
|
| - if (element.offsetParent) return element.offsetParent;
|
| - if (element == document.body) return element;
|
| -
|
| - while ((element = element.parentNode) && element != document.body)
|
| - if (Element.getStyle(element, 'position') != 'static')
|
| - return element;
|
| -
|
| - return document.body;
|
| - },
|
| -
|
| - // caches x/y coordinate pair to use with overlap
|
| - within: function(element, x, y) {
|
| - if (this.includeScrollOffsets)
|
| - return this.withinIncludingScrolloffsets(element, x, y);
|
| - this.xcomp = x;
|
| - this.ycomp = y;
|
| - this.offset = this.cumulativeOffset(element);
|
| -
|
| - return (y >= this.offset[1] &&
|
| - y < this.offset[1] + element.offsetHeight &&
|
| - x >= this.offset[0] &&
|
| - x < this.offset[0] + element.offsetWidth);
|
| - },
|
| -
|
| - withinIncludingScrolloffsets: function(element, x, y) {
|
| - var offsetcache = this.realOffset(element);
|
| -
|
| - this.xcomp = x + offsetcache[0] - this.deltaX;
|
| - this.ycomp = y + offsetcache[1] - this.deltaY;
|
| - this.offset = this.cumulativeOffset(element);
|
| -
|
| - return (this.ycomp >= this.offset[1] &&
|
| - this.ycomp < this.offset[1] + element.offsetHeight &&
|
| - this.xcomp >= this.offset[0] &&
|
| - this.xcomp < this.offset[0] + element.offsetWidth);
|
| - },
|
| -
|
| - // within must be called directly before
|
| - overlap: function(mode, element) {
|
| - if (!mode) return 0;
|
| - if (mode == 'vertical')
|
| - return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
|
| - element.offsetHeight;
|
| - if (mode == 'horizontal')
|
| - return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
|
| - element.offsetWidth;
|
| - },
|
| -
|
| - page: function(forElement) {
|
| - var valueT = 0, valueL = 0;
|
| -
|
| - var element = forElement;
|
| - do {
|
| - valueT += element.offsetTop || 0;
|
| - valueL += element.offsetLeft || 0;
|
| -
|
| - // Safari fix
|
| - if (element.offsetParent==document.body)
|
| - if (Element.getStyle(element,'position')=='absolute') break;
|
| -
|
| - } while (element = element.offsetParent);
|
| -
|
| - element = forElement;
|
| - do {
|
| - if (!window.opera || element.tagName=='BODY') {
|
| - valueT -= element.scrollTop || 0;
|
| - valueL -= element.scrollLeft || 0;
|
| - }
|
| - } while (element = element.parentNode);
|
| -
|
| - return [valueL, valueT];
|
| - },
|
| -
|
| - clone: function(source, target) {
|
| - var options = Object.extend({
|
| - setLeft: true,
|
| - setTop: true,
|
| - setWidth: true,
|
| - setHeight: true,
|
| - offsetTop: 0,
|
| - offsetLeft: 0
|
| - }, arguments[2] || {})
|
| -
|
| - // find page position of source
|
| - source = $(source);
|
| - var p = Position.page(source);
|
| -
|
| - // find coordinate system to use
|
| - target = $(target);
|
| - var delta = [0, 0];
|
| - var parent = null;
|
| - // delta [0,0] will do fine with position: fixed elements,
|
| - // position:absolute needs offsetParent deltas
|
| - if (Element.getStyle(target,'position') == 'absolute') {
|
| - parent = Position.offsetParent(target);
|
| - delta = Position.page(parent);
|
| - }
|
| -
|
| - // correct by body offsets (fixes Safari)
|
| - if (parent == document.body) {
|
| - delta[0] -= document.body.offsetLeft;
|
| - delta[1] -= document.body.offsetTop;
|
| - }
|
| -
|
| - // set position
|
| - if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
|
| - if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
|
| - if(options.setWidth) target.style.width = source.offsetWidth + 'px';
|
| - if(options.setHeight) target.style.height = source.offsetHeight + 'px';
|
| - },
|
| -
|
| - absolutize: function(element) {
|
| - element = $(element);
|
| - if (element.style.position == 'absolute') return;
|
| - Position.prepare();
|
| -
|
| - var offsets = Position.positionedOffset(element);
|
| - var top = offsets[1];
|
| - var left = offsets[0];
|
| - var width = element.clientWidth;
|
| - var height = element.clientHeight;
|
| -
|
| - element._originalLeft = left - parseFloat(element.style.left || 0);
|
| - element._originalTop = top - parseFloat(element.style.top || 0);
|
| - element._originalWidth = element.style.width;
|
| - element._originalHeight = element.style.height;
|
| -
|
| - element.style.position = 'absolute';
|
| - element.style.top = top + 'px';
|
| - element.style.left = left + 'px';
|
| - element.style.width = width + 'px';
|
| - element.style.height = height + 'px';
|
| - },
|
| -
|
| - relativize: function(element) {
|
| - element = $(element);
|
| - if (element.style.position == 'relative') return;
|
| - Position.prepare();
|
| -
|
| - element.style.position = 'relative';
|
| - var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
|
| - var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
|
| -
|
| - element.style.top = top + 'px';
|
| - element.style.left = left + 'px';
|
| - element.style.height = element._originalHeight;
|
| - element.style.width = element._originalWidth;
|
| - }
|
| -}
|
| -
|
| -// Safari returns margins on body which is incorrect if the child is absolutely
|
| -// positioned. For performance reasons, redefine Position.cumulativeOffset for
|
| -// KHTML/WebKit only.
|
| -if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
|
| - Position.cumulativeOffset = function(element) {
|
| - var valueT = 0, valueL = 0;
|
| - do {
|
| - valueT += element.offsetTop || 0;
|
| - valueL += element.offsetLeft || 0;
|
| - if (element.offsetParent == document.body)
|
| - if (Element.getStyle(element, 'position') == 'absolute') break;
|
| -
|
| - element = element.offsetParent;
|
| - } while (element);
|
| -
|
| - return [valueL, valueT];
|
| - }
|
| -}
|
| -
|
| -Element.addMethods();
|
| -
|
| -
|
| // ------------------------------------------------------------------------
|
| // ------------------------------------------------------------------------
|
|
|
| @@ -3431,4 +933,3 @@
|
|
|
| raytracer.renderScene(scene, null, 0);
|
| }
|
| -
|
|
|