Skip to content

Instantly share code, notes, and snippets.

@sibelius
Created March 8, 2023 19:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sibelius/0ce00f76c6ff8c94c3874b3d4b331ad8 to your computer and use it in GitHub Desktop.
Save sibelius/0ce00f76c6ff8c94c3874b3d4b331ad8 to your computer and use it in GitHub Desktop.
prototype.js amoptimization
const Prototype = {
Version: '1.7',
Browser: (function () {
const ua = navigator.userAgent;
const isOpera =
Object.prototype.toString.call(window.opera) == '[object Opera]';
return {
IE: !!window.attachEvent && !isOpera,
Opera: isOpera,
WebKit: ua.indexOf('AppleWebKit/') > -1,
Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
MobileSafari: /Apple.*Mobile/.test(ua),
};
})(),
BrowserFeatures: {
XPath: !!document.evaluate,
SelectorsAPI: !!document.querySelector,
ElementExtensions: (function () {
const constructor = window.Element || window.HTMLElement;
return !!(constructor && constructor.prototype);
})(),
SpecificElementExtensions: (function () {
if (typeof window.HTMLDivElement !== 'undefined') {return true;}
let div = document.createElement('div'),
form = document.createElement('form'),
isSupported = false;
if (div['__proto__'] && div['__proto__'] !== form['__proto__'])
{isSupported = true;}
div = form = null;
return isSupported;
})(),
},
ScriptFragment: '<script[^>]*>([\\S\\s]*?)\x3c/script>',
JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
emptyFunction: function () {},
K: function (x) {
return x;
},
};
if (Prototype.Browser.MobileSafari)
{Prototype.BrowserFeatures.SpecificElementExtensions = false;}
const Abstract = {};
const Try = {
these: function () {
let returnValue;
for (let i = 0, length = arguments.length; i < length; i++) {
const lambda = arguments[i];
try {
returnValue = lambda();
break;
} catch (e) {}
}
return returnValue;
},
};
var Class = (function () {
const IS_DONTENUM_BUGGY = (function () {
for (const p in { toString: 1 }) {if (p === 'toString') {return false;}}
return true;
})();
function subclass() {}
function create() {
let parent = null,
properties = $A(arguments);
if (Object.isFunction(properties[0])) {parent = properties.shift();}
function klass() {
this.initialize.apply(this, arguments);
}
Object.extend(klass, Class.Methods);
klass.superclass = parent;
klass.subclasses = [];
if (parent) {
subclass.prototype = parent.prototype;
klass.prototype = new subclass();
parent.subclasses.push(klass);
}
for (let i = 0, length = properties.length; i < length; i++)
{klass.addMethods(properties[i]);}
if (!klass.prototype.initialize)
{klass.prototype.initialize = Prototype.emptyFunction;}
klass.prototype.constructor = klass;
return klass;
}
function addMethods(source) {
const ancestor = this.superclass && this.superclass.prototype,
properties = Object.keys(source);
if (IS_DONTENUM_BUGGY) {
if (source.toString != Object.prototype.toString)
{properties.push('toString');}
if (source.valueOf != Object.prototype.valueOf)
{properties.push('valueOf');}
}
for (let i = 0, length = properties.length; i < length; i++) {
let property = properties[i],
value = source[property];
if (
ancestor &&
Object.isFunction(value) &&
value.argumentNames()[0] == '$super'
) {
const method = value;
value = (function (m) {
return function () {
return ancestor[m].apply(this, arguments);
};
})(property).wrap(method);
value.valueOf = method.valueOf.bind(method);
value.toString = method.toString.bind(method);
}
this.prototype[property] = value;
}
return this;
}
return { create: create, Methods: { addMethods: addMethods } };
})();
(function () {
const _toString = Object.prototype.toString,
NULL_TYPE = 'Null',
UNDEFINED_TYPE = 'Undefined',
BOOLEAN_TYPE = 'Boolean',
NUMBER_TYPE = 'Number',
STRING_TYPE = 'String',
OBJECT_TYPE = 'Object',
FUNCTION_CLASS = '[object Function]',
BOOLEAN_CLASS = '[object Boolean]',
NUMBER_CLASS = '[object Number]',
STRING_CLASS = '[object String]',
ARRAY_CLASS = '[object Array]',
DATE_CLASS = '[object Date]',
NATIVE_JSON_STRINGIFY_SUPPORT =
window.JSON &&
typeof JSON.stringify === 'function' &&
JSON.stringify(0) === '0' &&
typeof JSON.stringify(Prototype.K) === 'undefined';
function Type(o) {
switch (o) {
case null:
return NULL_TYPE;
case void 0:
return UNDEFINED_TYPE;
}
const type = typeof o;
switch (type) {
case 'boolean':
return BOOLEAN_TYPE;
case 'number':
return NUMBER_TYPE;
case 'string':
return STRING_TYPE;
}
return OBJECT_TYPE;
}
function extend(destination, source) {
for (const property in source) {destination[property] = source[property];}
return destination;
}
function inspect(object) {
try {
if (isUndefined(object)) {return 'undefined';}
if (object === null) {return 'null';}
return object.inspect ? object.inspect() : String(object);
} catch (e) {
if (e instanceof RangeError) {return '...';}
throw e;
}
}
function toJSON(value) {
return Str('', { '': value }, []);
}
function Str(key, holder, stack) {
let value = holder[key],
type = typeof value;
if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function')
{value = value.toJSON(key);}
const _class = _toString.call(value);
switch (_class) {
case NUMBER_CLASS:
case BOOLEAN_CLASS:
case STRING_CLASS:
value = value.valueOf();
}
switch (value) {
case null:
return 'null';
case true:
return 'true';
case false:
return 'false';
}
type = typeof value;
switch (type) {
case 'string':
return value.inspect(true);
case 'number':
return isFinite(value) ? String(value) : 'null';
case 'object':
for (var i = 0, length = stack.length; i < length; i++)
{if (stack[i] === value) {throw new TypeError();}}
stack.push(value);
var partial = [];
if (_class === ARRAY_CLASS) {
for (var i = 0, length = value.length; i < length; i++) {
var str = Str(i, value, stack);
partial.push(typeof str === 'undefined' ? 'null' : str);
}
partial = '[' + partial.join(',') + ']';
} else {
const keys = Object.keys(value);
for (var i = 0, length = keys.length; i < length; i++) {
var key = keys[i],
str = Str(key, value, stack);
if (typeof str !== 'undefined')
{partial.push(key.inspect(true) + ':' + str);}
}
partial = '{' + partial.join(',') + '}';
}
stack.pop();
return partial;
}
}
function stringify(object) {
return JSON.stringify(object);
}
function toQueryString(object) {
return $H(object).toQueryString();
}
function toHTML(object) {
return object && object.toHTML ? object.toHTML() : String.interpret(object);
}
function keys(object) {
if (Type(object) !== OBJECT_TYPE) {throw new TypeError();}
const results = [];
for (const property in object)
{if (object.hasOwnProperty(property)) {results.push(property);}}
return results;
}
function values(object) {
const results = [];
for (const property in object) {results.push(object[property]);}
return results;
}
function clone(object) {
return extend({}, object);
}
function isElement(object) {
return !!(object && object.nodeType == 1);
}
function isArray(object) {
return _toString.call(object) === ARRAY_CLASS;
}
const hasNativeIsArray =
typeof Array.isArray == 'function' &&
Array.isArray([]) &&
!Array.isArray({});
if (hasNativeIsArray) {isArray = Array.isArray;}
function isHash(object) {
return object instanceof Hash;
}
function isFunction(object) {
return _toString.call(object) === FUNCTION_CLASS;
}
function isString(object) {
return _toString.call(object) === STRING_CLASS;
}
function isNumber(object) {
return _toString.call(object) === NUMBER_CLASS;
}
function isDate(object) {
return _toString.call(object) === DATE_CLASS;
}
function isUndefined(object) {
return typeof object === 'undefined';
}
extend(Object, {
extend: extend,
inspect: inspect,
toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
toQueryString: toQueryString,
toHTML: toHTML,
keys: Object.keys || keys,
values: values,
clone: clone,
isElement: isElement,
isArray: isArray,
isHash: isHash,
isFunction: isFunction,
isString: isString,
isNumber: isNumber,
isDate: isDate,
isUndefined: isUndefined,
});
})();
Object.extend(
Function.prototype,
(function () {
const slice = Array.prototype.slice;
function update(array, args) {
let arrayLength = array.length,
length = args.length;
while (length--) {array[arrayLength + length] = args[length];}
return array;
}
function merge(array, args) {
array = slice.call(array, 0);
return update(array, args);
}
function argumentNames() {
const names = this.toString()
.match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
.replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
.replace(/\s+/g, '')
.split(',');
return names.length == 1 && !names[0] ? [] : names;
}
function bind(context) {
if (arguments.length < 2 && Object.isUndefined(arguments[0])) {return this;}
const __method = this,
args = slice.call(arguments, 1);
return function () {
const a = merge(args, arguments);
return __method.apply(context, a);
};
}
function bindAsEventListener(context) {
const __method = this,
args = slice.call(arguments, 1);
return function (event) {
const a = update([event || window.event], args);
return __method.apply(context, a);
};
}
function curry() {
if (!arguments.length) {return this;}
const __method = this,
args = slice.call(arguments, 0);
return function () {
const a = merge(args, arguments);
return __method.apply(this, a);
};
}
function delay(timeout) {
const __method = this,
args = slice.call(arguments, 1);
timeout = timeout * 1e3;
return window.setTimeout(function () {
return __method.apply(__method, args);
}, timeout);
}
function defer() {
const args = update([0.01], arguments);
return this.delay.apply(this, args);
}
function wrap(wrapper) {
const __method = this;
return function () {
const a = update([__method.bind(this)], arguments);
return wrapper.apply(this, a);
};
}
function methodize() {
if (this._methodized) {return this._methodized;}
const __method = this;
return (this._methodized = function () {
const a = update([this], arguments);
return __method.apply(null, a);
});
}
return {
argumentNames: argumentNames,
bind: bind,
bindAsEventListener: bindAsEventListener,
curry: curry,
delay: delay,
defer: defer,
wrap: wrap,
methodize: methodize,
};
})(),
);
(function (proto) {
function toISOString() {
return (
this.getUTCFullYear() +
'-' +
(this.getUTCMonth() + 1).toPaddedString(2) +
'-' +
this.getUTCDate().toPaddedString(2) +
'T' +
this.getUTCHours().toPaddedString(2) +
':' +
this.getUTCMinutes().toPaddedString(2) +
':' +
this.getUTCSeconds().toPaddedString(2) +
'Z'
);
}
function toJSON() {
return this.toISOString();
}
if (!proto.toISOString) {proto.toISOString = toISOString;}
if (!proto.toJSON) {proto.toJSON = toJSON;}
})(Date.prototype);
RegExp.prototype.match = RegExp.prototype.test;
RegExp.escape = function (str) {
return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
};
const PeriodicalExecuter = Class.create({
initialize: function (callback, frequency) {
this.callback = callback;
this.frequency = frequency;
this.currentlyExecuting = false;
this.registerCallback();
},
registerCallback: function () {
this.timer = setInterval(
this.onTimerEvent.bind(this),
this.frequency * 1e3,
);
},
execute: function () {
this.callback(this);
},
stop: function () {
if (!this.timer) {return;}
clearInterval(this.timer);
this.timer = null;
},
onTimerEvent: function () {
if (!this.currentlyExecuting)
{try {
this.currentlyExecuting = true;
this.execute();
this.currentlyExecuting = false;
} catch (e) {
this.currentlyExecuting = false;
throw e;
}}
},
});
Object.extend(String, {
interpret: function (value) {
return value == null ? '' : String(value);
},
specialChar: {
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'\\': '\\\\',
},
});
Object.extend(
String.prototype,
(function () {
const NATIVE_JSON_PARSE_SUPPORT =
window.JSON &&
typeof JSON.parse === 'function' &&
JSON.parse('{"test": true}').test;
function prepareReplacement(replacement) {
if (Object.isFunction(replacement)) {return replacement;}
const template = new Template(replacement);
return function (match) {
return template.evaluate(match);
};
}
function gsub(pattern, replacement) {
let result = '',
source = this,
match;
replacement = prepareReplacement(replacement);
if (Object.isString(pattern)) {pattern = RegExp.escape(pattern);}
if (!(pattern.length || pattern.source)) {
replacement = replacement('');
return replacement + source.split('').join(replacement) + replacement;
}
while (source.length > 0)
{if ((match = source.match(pattern))) {
result += source.slice(0, match.index);
result += String.interpret(replacement(match));
source = source.slice(match.index + match[0].length);
} else {(result += source), (source = '');}}
return result;
}
function sub(pattern, replacement, count) {
replacement = prepareReplacement(replacement);
count = Object.isUndefined(count) ? 1 : count;
return this.gsub(pattern, function (match) {
if (--count < 0) {return match[0];}
return replacement(match);
});
}
function scan(pattern, iterator) {
this.gsub(pattern, iterator);
return String(this);
}
function truncate(length, truncation) {
length = length || 30;
truncation = Object.isUndefined(truncation) ? '...' : truncation;
return this.length > length
? this.slice(0, length - truncation.length) + truncation
: String(this);
}
function strip() {
return this.replace(/^\s+/, '').replace(/\s+$/, '');
}
function stripTags() {
return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
}
function stripScripts() {
return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
}
function extractScripts() {
const matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
matchOne = new RegExp(Prototype.ScriptFragment, 'im');
return (this.match(matchAll) || []).map(function (scriptTag) {
return (scriptTag.match(matchOne) || ['', ''])[1];
});
}
function evalScripts() {
return this.extractScripts().map(function (script) {
return eval(script);
});
}
function escapeHTML() {
return this.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
}
function unescapeHTML() {
return this.stripTags()
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&amp;/g, '&');
}
function toQueryParams(separator) {
const match = this.strip().match(/([^?#]*)(#.*)?$/);
if (!match) {return {};}
return match[1].split(separator || '&').inject({}, function (hash, pair) {
if ((pair = pair.split('='))[0]) {
let key = decodeURIComponent(pair.shift()),
value = pair.length > 1 ? pair.join('=') : pair[0];
if (value != undefined) {value = decodeURIComponent(value);}
if (key in hash) {
if (!Object.isArray(hash[key])) {hash[key] = [hash[key]];}
hash[key].push(value);
} else {hash[key] = value;}
}
return hash;
});
}
function toArray() {
return this.split('');
}
function succ() {
return (
this.slice(0, this.length - 1) +
String.fromCharCode(this.charCodeAt(this.length - 1) + 1)
);
}
function times(count) {
return count < 1 ? '' : new Array(count + 1).join(this);
}
function camelize() {
return this.replace(/-+(.)?/g, function (match, chr) {
return chr ? chr.toUpperCase() : '';
});
}
function capitalize() {
return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
}
function underscore() {
return this.replace(/::/g, '/')
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
.replace(/([a-z\d])([A-Z])/g, '$1_$2')
.replace(/-/g, '_')
.toLowerCase();
}
function dasherize() {
return this.replace(/_/g, '-');
}
function inspect(useDoubleQuotes) {
const escapedString = this.replace(/[\x00-\x1f\\]/g, function (character) {
if (character in String.specialChar)
{return String.specialChar[character];}
return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
});
if (useDoubleQuotes)
{return '"' + escapedString.replace(/"/g, '\\"') + '"';}
return "'" + escapedString.replace(/'/g, "\\'") + "'";
}
function unfilterJSON(filter) {
return this.replace(filter || Prototype.JSONFilter, '$1');
}
function isJSON() {
let str = this;
if (str.blank()) {return false;}
str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
str = str.replace(
/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
']',
);
str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
return /^[\],:{}\s]*$/.test(str);
}
function evalJSON(sanitize) {
let json = this.unfilterJSON(),
cx =
/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
if (cx.test(json))
{json = json.replace(cx, function (a) {
return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});}
try {
if (!sanitize || json.isJSON()) {return eval('(' + json + ')');}
} catch (e) {}
throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
}
function parseJSON() {
const json = this.unfilterJSON();
return JSON.parse(json);
}
function include(pattern) {
return this.indexOf(pattern) > -1;
}
function startsWith(pattern) {
return this.lastIndexOf(pattern, 0) === 0;
}
function endsWith(pattern) {
const d = this.length - pattern.length;
return d >= 0 && this.indexOf(pattern, d) === d;
}
function empty() {
return this == '';
}
function blank() {
return /^\s*$/.test(this);
}
function interpolate(object, pattern) {
return new Template(this, pattern).evaluate(object);
}
return {
gsub: gsub,
sub: sub,
scan: scan,
truncate: truncate,
strip: String.prototype.trim || strip,
stripTags: stripTags,
stripScripts: stripScripts,
extractScripts: extractScripts,
evalScripts: evalScripts,
escapeHTML: escapeHTML,
unescapeHTML: unescapeHTML,
toQueryParams: toQueryParams,
parseQuery: toQueryParams,
toArray: toArray,
succ: succ,
times: times,
camelize: camelize,
capitalize: capitalize,
underscore: underscore,
dasherize: dasherize,
inspect: inspect,
unfilterJSON: unfilterJSON,
isJSON: isJSON,
evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
include: include,
startsWith: startsWith,
endsWith: endsWith,
empty: empty,
blank: blank,
interpolate: interpolate,
};
})(),
);
var Template = Class.create({
initialize: function (template, pattern) {
this.template = template.toString();
this.pattern = pattern || Template.Pattern;
},
evaluate: function (object) {
if (object && Object.isFunction(object.toTemplateReplacements))
{object = object.toTemplateReplacements();}
return this.template.gsub(this.pattern, function (match) {
if (object == null) {return match[1] + '';}
const before = match[1] || '';
if (before == '\\') {return match[2];}
let ctx = object,
expr = match[3],
pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
match = pattern.exec(expr);
if (match == null) {return before;}
while (match != null) {
const comp = match[1].startsWith('[')
? match[2].replace(/\\\\]/g, ']')
: match[1];
ctx = ctx[comp];
if (null == ctx || '' == match[3]) {break;}
expr = expr.substring(
'[' == match[3] ? match[1].length : match[0].length,
);
match = pattern.exec(expr);
}
return before + String.interpret(ctx);
});
},
});
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
const $break = {};
const Enumerable = (function () {
function each(iterator, context) {
let index = 0;
try {
this._each(function (value) {
iterator.call(context, value, index++);
});
} catch (e) {
if (e != $break) {throw e;}
}
return this;
}
function eachSlice(number, iterator, context) {
let index = -number,
slices = [],
array = this.toArray();
if (number < 1) {return array;}
while ((index += number) < array.length)
{slices.push(array.slice(index, index + number));}
return slices.collect(iterator, context);
}
function all(iterator, context) {
iterator = iterator || Prototype.K;
let result = true;
this.each(function (value, index) {
result = result && !!iterator.call(context, value, index);
if (!result) {throw $break;}
});
return result;
}
function any(iterator, context) {
iterator = iterator || Prototype.K;
let result = false;
this.each(function (value, index) {
if ((result = !!iterator.call(context, value, index))) {throw $break;}
});
return result;
}
function collect(iterator, context) {
iterator = iterator || Prototype.K;
const results = [];
this.each(function (value, index) {
results.push(iterator.call(context, value, index));
});
return results;
}
function detect(iterator, context) {
let result;
this.each(function (value, index) {
if (iterator.call(context, value, index)) {
result = value;
throw $break;
}
});
return result;
}
function findAll(iterator, context) {
const results = [];
this.each(function (value, index) {
if (iterator.call(context, value, index)) {results.push(value);}
});
return results;
}
function grep(filter, iterator, context) {
iterator = iterator || Prototype.K;
const results = [];
if (Object.isString(filter)) {filter = new RegExp(RegExp.escape(filter));}
this.each(function (value, index) {
if (filter.match(value))
{results.push(iterator.call(context, value, index));}
});
return results;
}
function include(object) {
if (Object.isFunction(this.indexOf))
{if (this.indexOf(object) != -1) {return true;}}
let found = false;
this.each(function (value) {
if (value == object) {
found = true;
throw $break;
}
});
return found;
}
function inGroupsOf(number, fillWith) {
fillWith = Object.isUndefined(fillWith) ? null : fillWith;
return this.eachSlice(number, function (slice) {
while (slice.length < number) {slice.push(fillWith);}
return slice;
});
}
function inject(memo, iterator, context) {
this.each(function (value, index) {
memo = iterator.call(context, memo, value, index);
});
return memo;
}
function invoke(method) {
const args = $A(arguments).slice(1);
return this.map(function (value) {
return value[method].apply(value, args);
});
}
function max(iterator, context) {
iterator = iterator || Prototype.K;
let result;
this.each(function (value, index) {
value = iterator.call(context, value, index);
if (result == null || value >= result) {result = value;}
});
return result;
}
function min(iterator, context) {
iterator = iterator || Prototype.K;
let result;
this.each(function (value, index) {
value = iterator.call(context, value, index);
if (result == null || value < result) {result = value;}
});
return result;
}
function partition(iterator, context) {
iterator = iterator || Prototype.K;
const trues = [],
falses = [];
this.each(function (value, index) {
(iterator.call(context, value, index) ? trues : falses).push(value);
});
return [trues, falses];
}
function pluck(property) {
const results = [];
this.each(function (value) {
results.push(value[property]);
});
return results;
}
function reject(iterator, context) {
const results = [];
this.each(function (value, index) {
if (!iterator.call(context, value, index)) {results.push(value);}
});
return results;
}
function sortBy(iterator, context) {
return this.map(function (value, index) {
return { value: value, criteria: iterator.call(context, value, index) };
})
.sort(function (left, right) {
const a = left.criteria,
b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
})
.pluck('value');
}
// this breaks our plugin
function toArray() {
try {
return this.map();
} catch (err) {
return [];
}
}
function zip() {
let iterator = Prototype.K,
args = $A(arguments);
if (Object.isFunction(args.last())) {iterator = args.pop();}
const collections = [this].concat(args).map($A);
return this.map(function (value, index) {
return iterator(collections.pluck(index));
});
}
function size() {
return this.toArray().length;
}
function inspect() {
return '#<Enumerable:' + this.toArray().inspect() + '>';
}
return {
each: each,
eachSlice: eachSlice,
all: all,
every: all,
any: any,
some: any,
collect: collect,
map: collect,
detect: detect,
findAll: findAll,
select: findAll,
filter: findAll,
grep: grep,
include: include,
member: include,
inGroupsOf: inGroupsOf,
inject: inject,
invoke: invoke,
max: max,
min: min,
partition: partition,
pluck: pluck,
reject: reject,
sortBy: sortBy,
toArray: toArray,
entries: toArray,
zip: zip,
size: size,
inspect: inspect,
find: detect,
};
})();
function $A(iterable) {
if (!iterable) {return [];}
if ('toArray' in Object(iterable)) {return iterable.toArray();}
let length = iterable.length || 0,
results = new Array(length);
while (length--) {results[length] = iterable[length];}
return results;
}
function $w(string) {
if (!Object.isString(string)) {return [];}
string = string.strip();
return string ? string.split(/\s+/) : [];
}
Array.from = $A;
(function () {
let arrayProto = Array.prototype,
slice = arrayProto.slice,
_each = arrayProto.forEach;
function each(iterator, context) {
for (let i = 0, length = this.length >>> 0; i < length; i++)
{if (i in this) {iterator.call(context, this[i], i, this);}}
}
if (!_each) {_each = each;}
function clear() {
this.length = 0;
return this;
}
function first() {
return this[0];
}
function last() {
return this[this.length - 1];
}
function compact() {
return this.select(function (value) {
return value != null;
});
}
function flatten() {
return this.inject([], function (array, value) {
if (Object.isArray(value)) {return array.concat(value.flatten());}
array.push(value);
return array;
});
}
function without() {
const values = slice.call(arguments, 0);
return this.select(function (value) {
return !values.include(value);
});
}
function reverse(inline) {
return (inline === false ? this.toArray() : this)._reverse();
}
function uniq(sorted) {
return this.inject([], function (array, value, index) {
if (
0 == index ||
(sorted ? array.last() != value : !array.include(value))
)
{array.push(value);}
return array;
});
}
function intersect(array) {
return this.uniq().findAll(function (item) {
return array.detect(function (value) {
return item === value;
});
});
}
function clone() {
return slice.call(this, 0);
}
function size() {
return this.length;
}
function inspect() {
return '[' + this.map(Object.inspect).join(', ') + ']';
}
function indexOf(item, i) {
i || (i = 0);
const length = this.length;
if (i < 0) {i = length + i;}
for (; i < length; i++) {if (this[i] === item) {return i;}}
return -1;
}
function lastIndexOf(item, i) {
i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
const n = this.slice(0, i).reverse().indexOf(item);
return n < 0 ? n : i - n - 1;
}
function concat() {
let array = slice.call(this, 0),
item;
for (let i = 0, length = arguments.length; i < length; i++) {
item = arguments[i];
if (Object.isArray(item) && !('callee' in item))
{for (let j = 0, arrayLength = item.length; j < arrayLength; j++)
{array.push(item[j]);}}
else {array.push(item);}
}
return array;
}
Object.extend(arrayProto, Enumerable);
if (!arrayProto._reverse) {arrayProto._reverse = arrayProto.reverse;}
Object.extend(arrayProto, {
_each: _each,
clear: clear,
first: first,
last: last,
compact: compact,
flatten: flatten,
without: without,
reverse: reverse,
uniq: uniq,
intersect: intersect,
clone: clone,
toArray: clone,
size: size,
inspect: inspect,
});
const CONCAT_ARGUMENTS_BUGGY = (function () {
return [].concat(arguments)[0][0] !== 1;
})(1, 2);
if (CONCAT_ARGUMENTS_BUGGY) {arrayProto.concat = concat;}
if (!arrayProto.indexOf) {arrayProto.indexOf = indexOf;}
if (!arrayProto.lastIndexOf) {arrayProto.lastIndexOf = lastIndexOf;}
})();
function $H(object) {
return new Hash(object);
}
var Hash = Class.create(
Enumerable,
(function () {
function initialize(object) {
this._object = Object.isHash(object)
? object.toObject()
: Object.clone(object);
}
function _each(iterator) {
for (const key in this._object) {
const value = this._object[key],
pair = [key, value];
pair.key = key;
pair.value = value;
iterator(pair);
}
}
function set(key, value) {
return (this._object[key] = value);
}
function get(key) {
if (this._object[key] !== Object.prototype[key]) {return this._object[key];}
}
function unset(key) {
const value = this._object[key];
delete this._object[key];
return value;
}
function toObject() {
return Object.clone(this._object);
}
function keys() {
return this.pluck('key');
}
function values() {
return this.pluck('value');
}
function index(value) {
const match = this.detect(function (pair) {
return pair.value === value;
});
return match && match.key;
}
function merge(object) {
return this.clone().update(object);
}
function update(object) {
return new Hash(object).inject(this, function (result, pair) {
result.set(pair.key, pair.value);
return result;
});
}
function toQueryPair(key, value) {
if (Object.isUndefined(value)) {return key;}
return key + '=' + encodeURIComponent(String.interpret(value));
}
function toQueryString() {
return this.inject([], function (results, pair) {
const key = encodeURIComponent(pair.key),
values = pair.value;
if (values && typeof values == 'object') {
if (Object.isArray(values)) {
const queryValues = [];
for (var i = 0, len = values.length, value; i < len; i++) {
value = values[i];
queryValues.push(toQueryPair(key, value));
}
return results.concat(queryValues);
}
} else {results.push(toQueryPair(key, values));}
return results;
}).join('&');
}
function inspect() {
return (
'#<Hash:{' +
this.map(function (pair) {
return pair.map(Object.inspect).join(': ');
}).join(', ') +
'}>'
);
}
function clone() {
return new Hash(this);
}
return {
initialize: initialize,
_each: _each,
set: set,
get: get,
unset: unset,
toObject: toObject,
toTemplateReplacements: toObject,
keys: keys,
values: values,
index: index,
merge: merge,
update: update,
toQueryString: toQueryString,
inspect: inspect,
toJSON: toObject,
clone: clone,
};
})(),
);
Hash.from = $H;
Object.extend(
Number.prototype,
(function () {
function toColorPart() {
return this.toPaddedString(2, 16);
}
function succ() {
return this + 1;
}
function times(iterator, context) {
$R(0, this, true).each(iterator, context);
return this;
}
function toPaddedString(length, radix) {
const string = this.toString(radix || 10);
return '0'.times(length - string.length) + string;
}
function abs() {
return Math.abs(this);
}
function round() {
return Math.round(this);
}
function ceil() {
return Math.ceil(this);
}
function floor() {
return Math.floor(this);
}
return {
toColorPart: toColorPart,
succ: succ,
times: times,
toPaddedString: toPaddedString,
abs: abs,
round: round,
ceil: ceil,
floor: floor,
};
})(),
);
function $R(start, end, exclusive) {
return new ObjectRange(start, end, exclusive);
}
var ObjectRange = Class.create(
Enumerable,
(function () {
function initialize(start, end, exclusive) {
this.start = start;
this.end = end;
this.exclusive = exclusive;
}
function _each(iterator) {
let value = this.start;
while (this.include(value)) {
iterator(value);
value = value.succ();
}
}
function include(value) {
if (value < this.start) {return false;}
if (this.exclusive) {return value < this.end;}
return value <= this.end;
}
return { initialize: initialize, _each: _each, include: include };
})(),
);
const Ajax = {
getTransport: function () {
return (
Try.these(
function () {
return new XMLHttpRequest();
},
function () {
return new ActiveXObject('Msxml2.XMLHTTP');
},
function () {
return new ActiveXObject('Microsoft.XMLHTTP');
},
) || false
);
},
activeRequestCount: 0,
};
Ajax.Responders = {
responders: [],
_each: function (iterator) {
this.responders._each(iterator);
},
register: function (responder) {
if (!this.include(responder)) {this.responders.push(responder);}
},
unregister: function (responder) {
this.responders = this.responders.without(responder);
},
dispatch: function (callback, request, transport, json) {
this.each(function (responder) {
if (Object.isFunction(responder[callback]))
{try {
responder[callback].apply(responder, [request, transport, json]);
} catch (e) {}}
});
},
};
Object.extend(Ajax.Responders, Enumerable);
Ajax.Responders.register({
onCreate: function () {
Ajax.activeRequestCount++;
},
onComplete: function () {
Ajax.activeRequestCount--;
},
});
Ajax.Base = Class.create({
initialize: function (options) {
this.options = {
method: 'post',
asynchronous: true,
contentType: 'application/x-www-form-urlencoded',
encoding: 'UTF-8',
parameters: '',
evalJSON: true,
evalJS: true,
};
Object.extend(this.options, options || {});
this.options.method = this.options.method.toLowerCase();
if (Object.isHash(this.options.parameters))
{this.options.parameters = this.options.parameters.toObject();}
},
});
Ajax.Request = Class.create(Ajax.Base, {
_complete: false,
initialize: function ($super, url, options) {
$super(options);
this.transport = Ajax.getTransport();
this.request(url);
},
request: function (url) {
this.url = url;
this.method = this.options.method;
let params = Object.isString(this.options.parameters)
? this.options.parameters
: Object.toQueryString(this.options.parameters);
if (!['get', 'post'].include(this.method)) {
params += (params ? '&' : '') + '_method=' + this.method;
this.method = 'post';
}
if (params && this.method === 'get')
{this.url += (this.url.include('?') ? '&' : '?') + params;}
this.parameters = params.toQueryParams();
try {
const response = new Ajax.Response(this);
if (this.options.onCreate) {this.options.onCreate(response);}
Ajax.Responders.dispatch('onCreate', this, response);
this.transport.open(
this.method.toUpperCase(),
this.url,
this.options.asynchronous,
);
if (this.options.asynchronous)
{this.respondToReadyState.bind(this).defer(1);}
this.transport.onreadystatechange = this.onStateChange.bind(this);
this.setRequestHeaders();
this.body =
this.method == 'post' ? this.options.postBody || params : null;
this.transport.send(this.body);
if (!this.options.asynchronous && this.transport.overrideMimeType)
{this.onStateChange();}
} catch (e) {
this.dispatchException(e);
}
},
onStateChange: function () {
const readyState = this.transport.readyState;
if (readyState > 1 && !(readyState == 4 && this._complete))
{this.respondToReadyState(this.transport.readyState);}
},
setRequestHeaders: function () {
const 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 : '');
if (
this.transport.overrideMimeType &&
(navigator.userAgent.match(/Gecko\/(\d{4})/) || [0, 2005])[1] < 2005
)
{headers['Connection'] = 'close';}
}
if (typeof this.options.requestHeaders == 'object') {
const extras = this.options.requestHeaders;
if (Object.isFunction(extras.push))
{for (let 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 (const name in headers)
{this.transport.setRequestHeader(name, headers[name]);}
},
success: function () {
const status = this.getStatus();
return !status || (status >= 200 && status < 300) || status == 304;
},
getStatus: function () {
try {
if (this.transport.status === 1223) {return 204;}
return this.transport.status || 0;
} catch (e) {
return 0;
}
},
respondToReadyState: function (readyState) {
const state = Ajax.Request.Events[readyState],
response = new Ajax.Response(this);
if (state == 'Complete') {
try {
this._complete = true;
(
this.options['on' + response.status] ||
this.options['on' + (this.success() ? 'Success' : 'Failure')] ||
Prototype.emptyFunction
)(response, response.headerJSON);
} catch (e) {
this.dispatchException(e);
}
const contentType = response.getHeader('Content-type');
if (
this.options.evalJS == 'force' ||
(this.options.evalJS &&
this.isSameOrigin() &&
contentType &&
contentType.match(
/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i,
))
)
{this.evalResponse();}
}
try {
(this.options['on' + state] || Prototype.emptyFunction)(
response,
response.headerJSON,
);
Ajax.Responders.dispatch(
'on' + state,
this,
response,
response.headerJSON,
);
} catch (e$0) {
this.dispatchException(e$0);
}
if (state == 'Complete')
{this.transport.onreadystatechange = Prototype.emptyFunction;}
},
isSameOrigin: function () {
const m = this.url.match(/^\s*https?:\/\/[^\/]*/);
return (
!m ||
m[0] ==
'#{protocol}//#{domain}#{port}'.interpolate({
protocol: location.protocol,
domain: document.domain,
port: location.port ? ':' + location.port : '',
})
);
},
getHeader: function (name) {
try {
return this.transport.getResponseHeader(name) || null;
} catch (e) {
return null;
}
},
evalResponse: function () {
try {
return eval((this.transport.responseText || '').unfilterJSON());
} catch (e) {
this.dispatchException(e);
}
},
dispatchException: function (exception) {
(this.options.onException || Prototype.emptyFunction)(this, exception);
Ajax.Responders.dispatch('onException', this, exception);
},
});
Ajax.Request.Events = [
'Uninitialized',
'Loading',
'Loaded',
'Interactive',
'Complete',
];
Ajax.Response = Class.create({
initialize: function (request) {
this.request = request;
const transport = (this.transport = request.transport),
readyState = (this.readyState = transport.readyState);
if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
this.status = this.getStatus();
this.statusText = this.getStatusText();
this.responseText = String.interpret(transport.responseText);
this.headerJSON = this._getHeaderJSON();
}
if (readyState == 4) {
const xml = transport.responseXML;
this.responseXML = Object.isUndefined(xml) ? null : xml;
this.responseJSON = this._getResponseJSON();
}
},
status: 0,
statusText: '',
getStatus: Ajax.Request.prototype.getStatus,
getStatusText: function () {
try {
return this.transport.statusText || '';
} catch (e) {
return '';
}
},
getHeader: Ajax.Request.prototype.getHeader,
getAllHeaders: function () {
try {
return this.getAllResponseHeaders();
} catch (e) {
return null;
}
},
getResponseHeader: function (name) {
return this.transport.getResponseHeader(name);
},
getAllResponseHeaders: function () {
return this.transport.getAllResponseHeaders();
},
_getHeaderJSON: function () {
let json = this.getHeader('X-JSON');
if (!json) {return null;}
json = decodeURIComponent(escape(json));
try {
return json.evalJSON(
this.request.options.sanitizeJSON || !this.request.isSameOrigin(),
);
} catch (e) {
this.request.dispatchException(e);
}
},
_getResponseJSON: function () {
const options = this.request.options;
if (
!options.evalJSON ||
(options.evalJSON != 'force' &&
!(this.getHeader('Content-type') || '').include('application/json')) ||
this.responseText.blank()
)
{return null;}
try {
return this.responseText.evalJSON(
options.sanitizeJSON || !this.request.isSameOrigin(),
);
} catch (e) {
this.request.dispatchException(e);
}
},
});
Ajax.Updater = Class.create(Ajax.Request, {
initialize: function ($super, container, url, options) {
this.container = {
success: container.success || container,
failure: container.failure || (container.success ? null : container),
};
options = Object.clone(options);
const onComplete = options.onComplete;
options.onComplete = function (response, json) {
this.updateContent(response.responseText);
if (Object.isFunction(onComplete)) {onComplete(response, json);}
}.bind(this);
$super(url, options);
},
updateContent: function (responseText) {
let receiver = this.container[this.success() ? 'success' : 'failure'],
options = this.options;
if (!options.evalScripts) {responseText = responseText.stripScripts();}
if ((receiver = $(receiver)))
{if (options.insertion)
{if (Object.isString(options.insertion)) {
const insertion = {};
insertion[options.insertion] = responseText;
receiver.insert(insertion);
} else {options.insertion(receiver, responseText);}}
else {receiver.update(responseText);}}
},
});
Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
initialize: function ($super, container, url, options) {
$super(options);
this.onComplete = this.options.onComplete;
this.frequency = this.options.frequency || 2;
this.decay = this.options.decay || 1;
this.updater = {};
this.container = container;
this.url = url;
this.start();
},
start: function () {
this.options.onComplete = this.updateComplete.bind(this);
this.onTimerEvent();
},
stop: function () {
this.updater.options.onComplete = undefined;
clearTimeout(this.timer);
(this.onComplete || Prototype.emptyFunction).apply(this, arguments);
},
updateComplete: function (response) {
if (this.options.decay) {
this.decay =
response.responseText == this.lastText
? this.decay * this.options.decay
: 1;
this.lastText = response.responseText;
}
this.timer = this.onTimerEvent
.bind(this)
.delay(this.decay * this.frequency);
},
onTimerEvent: function () {
this.updater = new Ajax.Updater(this.container, this.url, this.options);
},
});
function $(element) {
if (arguments.length > 1) {
for (var i = 0, elements = [], length = arguments.length; i < length; i++)
{elements.push($(arguments[i]));}
return elements;
}
if (Object.isString(element)) {element = document.getElementById(element);}
return Element.extend(element);
}
if (Prototype.BrowserFeatures.XPath)
{document._getElementsByXPath = function (expression, parentElement) {
const results = [];
const query = document.evaluate(
expression,
$(parentElement) || document,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null,
);
for (let i = 0, length = query.snapshotLength; i < length; i++)
{results.push(Element.extend(query.snapshotItem(i)));}
return results;
};}
if (!Node) {var Node = {};}
if (!Node.ELEMENT_NODE)
{Object.extend(Node, {
ELEMENT_NODE: 1,
ATTRIBUTE_NODE: 2,
TEXT_NODE: 3,
CDATA_SECTION_NODE: 4,
ENTITY_REFERENCE_NODE: 5,
ENTITY_NODE: 6,
PROCESSING_INSTRUCTION_NODE: 7,
COMMENT_NODE: 8,
DOCUMENT_NODE: 9,
DOCUMENT_TYPE_NODE: 10,
DOCUMENT_FRAGMENT_NODE: 11,
NOTATION_NODE: 12,
});}
(function (global) {
function shouldUseCache(tagName, attributes) {
if (tagName === 'select') {return false;}
if ('type' in attributes) {return false;}
return true;
}
const HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function () {
try {
const el = document.createElement('<input name="x">');
return el.tagName.toLowerCase() === 'input' && el.name === 'x';
} catch (err) {
return false;
}
})();
const element = global.Element;
global.Element = function (tagName, attributes) {
attributes = attributes || {};
tagName = tagName.toLowerCase();
const cache = Element.cache;
if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) {
tagName = '<' + tagName + ' name="' + attributes.name + '">';
delete attributes.name;
return Element.writeAttribute(
document.createElement(tagName),
attributes,
);
}
if (!cache[tagName])
{cache[tagName] = Element.extend(document.createElement(tagName));}
const node = shouldUseCache(tagName, attributes)
? cache[tagName].cloneNode(false)
: document.createElement(tagName);
return Element.writeAttribute(node, attributes);
};
Object.extend(global.Element, element || {});
if (element) {global.Element.prototype = element.prototype;}
})(this);
Element.idCounter = 1;
Element.cache = {};
Element._purgeElement = function (element) {
const uid = element._prototypeUID;
if (uid) {
Element.stopObserving(element);
element._prototypeUID = void 0;
delete Element.Storage[uid];
}
};
Element.Methods = {
visible: function (element) {
return $(element).style.display != 'none';
},
toggle: function (element) {
element = $(element);
Element[Element.visible(element) ? 'hide' : 'show'](element);
return element;
},
hide: function (element) {
element = $(element);
element.style.display = 'none';
return element;
},
show: function (element) {
element = $(element);
element.style.display = '';
return element;
},
remove: function (element) {
element = $(element);
element.parentNode.removeChild(element);
return element;
},
update: (function () {
const SELECT_ELEMENT_INNERHTML_BUGGY = (function () {
let el = document.createElement('select'),
isBuggy = true;
el.innerHTML = '<option value="test">test</option>';
if (el.options && el.options[0])
{isBuggy = el.options[0].nodeName.toUpperCase() !== 'OPTION';}
el = null;
return isBuggy;
})();
const TABLE_ELEMENT_INNERHTML_BUGGY = (function () {
try {
let el = document.createElement('table');
if (el && el.tBodies) {
el.innerHTML = '<tbody><tr><td>test</td></tr></tbody>';
const isBuggy = typeof el.tBodies[0] == 'undefined';
el = null;
return isBuggy;
}
} catch (e) {
return true;
}
})();
const LINK_ELEMENT_INNERHTML_BUGGY = (function () {
try {
let el = document.createElement('div');
el.innerHTML = '<link>';
const isBuggy = el.childNodes.length === 0;
el = null;
return isBuggy;
} catch (e) {
return true;
}
})();
const ANY_INNERHTML_BUGGY =
SELECT_ELEMENT_INNERHTML_BUGGY ||
TABLE_ELEMENT_INNERHTML_BUGGY ||
LINK_ELEMENT_INNERHTML_BUGGY;
const SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
let s = document.createElement('script'),
isBuggy = false;
try {
s.appendChild(document.createTextNode(''));
isBuggy =
!s.firstChild || (s.firstChild && s.firstChild.nodeType !== 3);
} catch (e) {
isBuggy = true;
}
s = null;
return isBuggy;
})();
function update(element, content) {
element = $(element);
const purgeElement = Element._purgeElement;
let descendants = element.getElementsByTagName('*'),
i = descendants.length;
while (i--) {purgeElement(descendants[i]);}
if (content && content.toElement) {content = content.toElement();}
if (Object.isElement(content)) {return element.update().insert(content);}
content = Object.toHTML(content);
const tagName = element.tagName.toUpperCase();
if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
element.text = content;
return element;
}
if (ANY_INNERHTML_BUGGY)
{if (tagName in Element._insertionTranslations.tags) {
while (element.firstChild) {element.removeChild(element.firstChild);}
Element._getContentFromAnonymousElement(
tagName,
content.stripScripts(),
).each(function (node) {
element.appendChild(node);
});
} else if (
LINK_ELEMENT_INNERHTML_BUGGY &&
Object.isString(content) &&
content.indexOf('<link') > -1
) {
while (element.firstChild) {element.removeChild(element.firstChild);}
const nodes = Element._getContentFromAnonymousElement(
tagName,
content.stripScripts(),
true,
);
nodes.each(function (node) {
element.appendChild(node);
});
} else {element.innerHTML = content.stripScripts();}}
else {element.innerHTML = content.stripScripts();}
content.evalScripts.bind(content).defer();
return element;
}
return update;
})(),
replace: function (element, content) {
element = $(element);
if (content && content.toElement) {content = content.toElement();}
else if (!Object.isElement(content)) {
content = Object.toHTML(content);
const range = element.ownerDocument.createRange();
range.selectNode(element);
content.evalScripts.bind(content).defer();
content = range.createContextualFragment(content.stripScripts());
}
element.parentNode.replaceChild(content, element);
return element;
},
insert: function (element, insertions) {
element = $(element);
if (
Object.isString(insertions) ||
Object.isNumber(insertions) ||
Object.isElement(insertions) ||
(insertions && (insertions.toElement || insertions.toHTML))
)
{insertions = { bottom: insertions };}
let content, insert, tagName, childNodes;
for (let position in insertions) {
content = insertions[position];
position = position.toLowerCase();
insert = Element._insertionTranslations[position];
if (content && content.toElement) {content = content.toElement();}
if (Object.isElement(content)) {
insert(element, content);
continue;
}
content = Object.toHTML(content);
tagName = (
position == 'before' || position == 'after'
? element.parentNode
: element
).tagName.toUpperCase();
childNodes = Element._getContentFromAnonymousElement(
tagName,
content.stripScripts(),
);
if (position == 'top' || position == 'after') {childNodes.reverse();}
childNodes.each(insert.curry(element));
content.evalScripts.bind(content).defer();
}
return element;
},
wrap: function (element, wrapper, attributes) {
element = $(element);
if (Object.isElement(wrapper)) {$(wrapper).writeAttribute(attributes || {});}
else if (Object.isString(wrapper))
{wrapper = new Element(wrapper, attributes);}
else {wrapper = new Element('div', wrapper);}
if (element.parentNode) {element.parentNode.replaceChild(wrapper, element);}
wrapper.appendChild(element);
return wrapper;
},
inspect: function (element) {
element = $(element);
let result = '<' + element.tagName.toLowerCase();
$H({ id: 'id', className: 'class' }).each(function (pair) {
const property = pair.first(),
attribute = pair.last(),
value = (element[property] || '').toString();
if (value) {result += ' ' + attribute + '=' + value.inspect(true);}
});
return result + '>';
},
recursivelyCollect: function (element, property, maximumLength) {
element = $(element);
maximumLength = maximumLength || -1;
const elements = [];
while ((element = element[property])) {
if (element.nodeType == 1) {elements.push(Element.extend(element));}
if (elements.length == maximumLength) {break;}
}
return elements;
},
ancestors: function (element) {
return Element.recursivelyCollect(element, 'parentNode');
},
descendants: function (element) {
return Element.select(element, '*');
},
firstDescendant: function (element) {
element = $(element).firstChild;
while (element && element.nodeType != 1) {element = element.nextSibling;}
return $(element);
},
immediateDescendants: function (element) {
let results = [],
child = $(element).firstChild;
while (child) {
if (child.nodeType === 1) {results.push(Element.extend(child));}
child = child.nextSibling;
}
return results;
},
previousSiblings: function (element, maximumLength) {
return Element.recursivelyCollect(element, 'previousSibling');
},
nextSiblings: function (element) {
return Element.recursivelyCollect(element, 'nextSibling');
},
siblings: function (element) {
element = $(element);
return Element.previousSiblings(element)
.reverse()
.concat(Element.nextSiblings(element));
},
match: function (element, selector) {
element = $(element);
if (Object.isString(selector))
{return Prototype.Selector.match(element, selector);}
return selector.match(element);
},
up: function (element, expression, index) {
element = $(element);
if (arguments.length == 1) {return $(element.parentNode);}
const ancestors = Element.ancestors(element);
return Object.isNumber(expression)
? ancestors[expression]
: Prototype.Selector.find(ancestors, expression, index);
},
down: function (element, expression, index) {
element = $(element);
if (arguments.length == 1) {return Element.firstDescendant(element);}
return Object.isNumber(expression)
? Element.descendants(element)[expression]
: Element.select(element, expression)[index || 0];
},
previous: function (element, expression, index) {
element = $(element);
if (Object.isNumber(expression)) {(index = expression), (expression = false);}
if (!Object.isNumber(index)) {index = 0;}
if (expression)
{return Prototype.Selector.find(
element.previousSiblings(),
expression,
index,
);}
else {return element.recursivelyCollect('previousSibling', index + 1)[index];}
},
next: function (element, expression, index) {
element = $(element);
if (Object.isNumber(expression)) {(index = expression), (expression = false);}
if (!Object.isNumber(index)) {index = 0;}
if (expression)
{return Prototype.Selector.find(element.nextSiblings(), expression, index);}
else {
const maximumLength = Object.isNumber(index) ? index + 1 : 1;
return element.recursivelyCollect('nextSibling', index + 1)[index];
}
},
select: function (element) {
element = $(element);
const expressions = Array.prototype.slice.call(arguments, 1).join(', ');
return Prototype.Selector.select(expressions, element);
},
adjacent: function (element) {
element = $(element);
const expressions = Array.prototype.slice.call(arguments, 1).join(', ');
return Prototype.Selector.select(expressions, element.parentNode).without(
element,
);
},
identify: function (element) {
element = $(element);
let id = Element.readAttribute(element, 'id');
if (id) {return id;}
do {id = 'anonymous_element_' + Element.idCounter++;}
while ($(id));
Element.writeAttribute(element, 'id', id);
return id;
},
readAttribute: function (element, name) {
element = $(element);
if (Prototype.Browser.IE) {
const t = Element._attributeTranslations.read;
if (t.values[name]) {return t.values[name](element, name);}
if (t.names[name]) {name = t.names[name];}
if (name.include(':'))
{return !element.attributes || !element.attributes[name]
? null
: element.attributes[name].value;}
}
return element.getAttribute(name);
},
writeAttribute: function (element, name, value) {
element = $(element);
let attributes = {},
t = Element._attributeTranslations.write;
if (typeof name == 'object') {attributes = name;}
else {attributes[name] = Object.isUndefined(value) ? true : value;}
for (const attr in attributes) {
name = t.names[attr] || attr;
value = attributes[attr];
if (t.values[attr]) {name = t.values[attr](element, value);}
if (value === false || value === null) {element.removeAttribute(name);}
else if (value === true) {element.setAttribute(name, name);}
else {element.setAttribute(name, value);}
}
return element;
},
getHeight: function (element) {
return Element.getDimensions(element).height;
},
getWidth: function (element) {
return Element.getDimensions(element).width;
},
classNames: function (element) {
return new Element.ClassNames(element);
},
hasClassName: function (element, className) {
if (!(element = $(element))) {return;}
const elementClassName = element.className;
return (
elementClassName.length > 0 &&
(elementClassName == className ||
new RegExp('(^|\\s)' + className + '(\\s|$)').test(elementClassName))
);
},
addClassName: function (element, className) {
if (!(element = $(element))) {return;}
if (!Element.hasClassName(element, className))
{element.className += (element.className ? ' ' : '') + className;}
return element;
},
removeClassName: function (element, className) {
if (!(element = $(element))) {return;}
element.className = element.className
.replace(new RegExp('(^|\\s+)' + className + '(\\s+|$)'), ' ')
.strip();
return element;
},
toggleClassName: function (element, className) {
if (!(element = $(element))) {return;}
return Element[
Element.hasClassName(element, className)
? 'removeClassName'
: 'addClassName'
](element, className);
},
cleanWhitespace: function (element) {
element = $(element);
let node = element.firstChild;
while (node) {
const nextNode = node.nextSibling;
if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
{element.removeChild(node);}
node = nextNode;
}
return element;
},
empty: function (element) {
return $(element).innerHTML.blank();
},
descendantOf: function (element, ancestor) {
(element = $(element)), (ancestor = $(ancestor));
if (element.compareDocumentPosition)
{return (element.compareDocumentPosition(ancestor) & 8) === 8;}
if (ancestor.contains)
{return ancestor.contains(element) && ancestor !== element;}
while ((element = element.parentNode)) {if (element == ancestor) {return true;}}
return false;
},
scrollTo: function (element) {
element = $(element);
const pos = Element.cumulativeOffset(element);
window.scrollTo(pos[0], pos[1]);
return element;
},
getStyle: function (element, style) {
element = $(element);
style = style == 'float' ? 'cssFloat' : style.camelize();
let value = element.style[style];
if (!value || value == 'auto') {
const css = document.defaultView.getComputedStyle(element, null);
value = css ? css[style] : null;
}
if (style == 'opacity') {return value ? parseFloat(value) : 1;}
return value == 'auto' ? null : value;
},
getOpacity: function (element) {
return $(element).getStyle('opacity');
},
setStyle: function (element, styles) {
element = $(element);
let elementStyle = element.style,
match;
if (Object.isString(styles)) {
element.style.cssText += ';' + styles;
return styles.include('opacity')
? element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1])
: element;
}
for (const property in styles)
{if (property == 'opacity') {element.setOpacity(styles[property]);}
else
{elementStyle[
property == 'float' || property == 'cssFloat'
? Object.isUndefined(elementStyle.styleFloat)
? 'cssFloat'
: 'styleFloat'
: property
] = styles[property];}}
return element;
},
setOpacity: function (element, value) {
element = $(element);
element.style.opacity =
value == 1 || value === '' ? '' : value < 1e-5 ? 0 : value;
return element;
},
makePositioned: function (element) {
element = $(element);
const pos = Element.getStyle(element, 'position');
if (pos == 'static' || !pos) {
element._madePositioned = true;
element.style.position = 'relative';
if (Prototype.Browser.Opera) {
element.style.top = 0;
element.style.left = 0;
}
}
return element;
},
undoPositioned: function (element) {
element = $(element);
if (element._madePositioned) {
element._madePositioned = undefined;
element.style.position =
element.style.top =
element.style.left =
element.style.bottom =
element.style.right =
'';
}
return element;
},
makeClipping: function (element) {
element = $(element);
if (element._overflow) {return element;}
element._overflow = Element.getStyle(element, 'overflow') || 'auto';
if (element._overflow !== '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;
},
clonePosition: function (element, source) {
const options = Object.extend(
{
setLeft: true,
setTop: true,
setWidth: true,
setHeight: true,
offsetTop: 0,
offsetLeft: 0,
},
arguments[2] || {},
);
source = $(source);
let p = Element.viewportOffset(source),
delta = [0, 0],
parent = null;
element = $(element);
if (Element.getStyle(element, 'position') == 'absolute') {
parent = Element.getOffsetParent(element);
delta = Element.viewportOffset(parent);
}
if (parent == document.body) {
delta[0] -= document.body.offsetLeft;
delta[1] -= document.body.offsetTop;
}
if (options.setLeft)
{element.style.left = p[0] - delta[0] + options.offsetLeft + 'px';}
if (options.setTop)
{element.style.top = p[1] - delta[1] + options.offsetTop + 'px';}
if (options.setWidth) {element.style.width = source.offsetWidth + 'px';}
if (options.setHeight) {element.style.height = source.offsetHeight + 'px';}
return element;
},
};
Object.extend(Element.Methods, {
getElementsBySelector: Element.Methods.select,
childElements: Element.Methods.immediateDescendants,
});
Element._attributeTranslations = {
write: { names: { className: 'class', htmlFor: 'for' }, values: {} },
};
if (Prototype.Browser.Opera) {
Element.Methods.getStyle = Element.Methods.getStyle.wrap(function (
proceed,
element,
style,
) {
switch (style) {
case 'height':
case 'width':
if (!Element.visible(element)) {return null;}
var dim = parseInt(proceed(element, style), 10);
if (dim !== element['offset' + style.capitalize()]) {return dim + 'px';}
var properties;
if (style === 'height')
{properties = [
'border-top-width',
'padding-top',
'padding-bottom',
'border-bottom-width',
];}
else
{properties = [
'border-left-width',
'padding-left',
'padding-right',
'border-right-width',
];}
return (
properties.inject(dim, function (memo, property) {
const val = proceed(element, property);
return val === null ? memo : memo - parseInt(val, 10);
}) + 'px'
);
default:
return proceed(element, style);
}
});
Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(function (
proceed,
element,
attribute,
) {
if (attribute === 'title') {return element.title;}
return proceed(element, attribute);
});
} else if (Prototype.Browser.IE) {
Element.Methods.getStyle = function (element, style) {
element = $(element);
style =
style == 'float' || style == 'cssFloat' ? 'styleFloat' : style.camelize();
let value = element.style[style];
if (!value && element.currentStyle) {value = element.currentStyle[style];}
if (style == 'opacity') {
if (
(value = (element.getStyle('filter') || '').match(
/alpha\(opacity=(.*)\)/,
))
)
{if (value[1]) {return parseFloat(value[1]) / 100;}}
return 1;
}
if (value == 'auto') {
if (
(style == 'width' || style == 'height') &&
element.getStyle('display') != 'none'
)
{return element['offset' + style.capitalize()] + 'px';}
return null;
}
return value;
};
Element.Methods.setOpacity = function (element, value) {
function stripAlpha(filter) {
return filter.replace(/alpha\([^\)]*\)/gi, '');
}
element = $(element);
const currentStyle = element.currentStyle;
if (
(currentStyle && !currentStyle.hasLayout) ||
(!currentStyle && element.style.zoom == 'normal')
)
{element.style.zoom = 1;}
let filter = element.getStyle('filter'),
style = element.style;
if (value == 1 || value === '') {
(filter = stripAlpha(filter))
? (style.filter = filter)
: style.removeAttribute('filter');
return element;
} else if (value < 1e-5) {value = 0;}
style.filter = stripAlpha(filter) + 'alpha(opacity=' + value * 100 + ')';
return element;
};
Element._attributeTranslations = (function () {
let classProp = 'className',
forProp = 'for',
el = document.createElement('div');
el.setAttribute(classProp, 'x');
if (el.className !== 'x') {
el.setAttribute('class', 'x');
if (el.className === 'x') {classProp = 'class';}
}
el = null;
el = document.createElement('label');
el.setAttribute(forProp, 'x');
if (el.htmlFor !== 'x') {
el.setAttribute('htmlFor', 'x');
if (el.htmlFor === 'x') {forProp = 'htmlFor';}
}
el = null;
return {
read: {
names: {
class: classProp,
className: classProp,
for: forProp,
htmlFor: forProp,
},
values: {
_getAttr: function (element, attribute) {
return element.getAttribute(attribute);
},
_getAttr2: function (element, attribute) {
return element.getAttribute(attribute, 2);
},
_getAttrNode: function (element, attribute) {
const node = element.getAttributeNode(attribute);
return node ? node.value : '';
},
_getEv: (function () {
let el = document.createElement('div'),
f;
el.onclick = Prototype.emptyFunction;
const value = el.getAttribute('onclick');
if (String(value).indexOf('{') > -1)
{f = function (element, attribute) {
attribute = element.getAttribute(attribute);
if (!attribute) {return null;}
attribute = attribute.toString();
attribute = attribute.split('{')[1];
attribute = attribute.split('}')[0];
return attribute.strip();
};}
else if (value === '')
{f = function (element, attribute) {
attribute = element.getAttribute(attribute);
if (!attribute) {return null;}
return attribute.strip();
};}
el = null;
return f;
})(),
_flag: function (element, attribute) {
return $(element).hasAttribute(attribute) ? attribute : null;
},
style: function (element) {
return element.style.cssText.toLowerCase();
},
title: function (element) {
return element.title;
},
},
},
};
})();
Element._attributeTranslations.write = {
names: Object.extend(
{ cellpadding: 'cellPadding', cellspacing: 'cellSpacing' },
Element._attributeTranslations.read.names,
),
values: {
checked: function (element, value) {
element.checked = !!value;
},
style: function (element, value) {
element.style.cssText = value ? value : '';
},
},
};
Element._attributeTranslations.has = {};
$w(
'colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
'encType maxLength readOnly longDesc frameBorder',
).each(function (attr) {
Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
Element._attributeTranslations.has[attr.toLowerCase()] = attr;
});
(function (v) {
Object.extend(v, {
href: v._getAttr2,
src: v._getAttr2,
type: v._getAttr,
action: v._getAttrNode,
disabled: v._flag,
checked: v._flag,
readonly: v._flag,
multiple: v._flag,
onload: v._getEv,
onunload: v._getEv,
onclick: v._getEv,
ondblclick: v._getEv,
onmousedown: v._getEv,
onmouseup: v._getEv,
onmouseover: v._getEv,
onmousemove: v._getEv,
onmouseout: v._getEv,
onfocus: v._getEv,
onblur: v._getEv,
onkeypress: v._getEv,
onkeydown: v._getEv,
onkeyup: v._getEv,
onsubmit: v._getEv,
onreset: v._getEv,
onselect: v._getEv,
onchange: v._getEv,
});
})(Element._attributeTranslations.read.values);
if (Prototype.BrowserFeatures.ElementExtensions)
{(function () {
function _descendants(element) {
const nodes = element.getElementsByTagName('*'),
results = [];
for (var i = 0, node; (node = nodes[i]); i++)
{if (node.tagName !== '!') {results.push(node);}}
return results;
}
Element.Methods.down = function (element, expression, index) {
element = $(element);
if (arguments.length == 1) {return element.firstDescendant();}
return Object.isNumber(expression)
? _descendants(element)[expression]
: Element.select(element, expression)[index || 0];
};
})();}
} else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent))
{Element.Methods.setOpacity = function (element, value) {
element = $(element);
element.style.opacity =
value == 1 ? 0.999999 : value === '' ? '' : value < 1e-5 ? 0 : value;
return element;
};}
else if (Prototype.Browser.WebKit)
{Element.Methods.setOpacity = function (element, value) {
element = $(element);
element.style.opacity =
value == 1 || value === '' ? '' : value < 1e-5 ? 0 : value;
if (value == 1)
{if (element.tagName.toUpperCase() == 'IMG' && element.width) {
element.width++;
element.width--;
} else
{try {
const n = document.createTextNode(' ');
element.appendChild(n);
element.removeChild(n);
} catch (e) {}}}
return element;
};}
if ('outerHTML' in document.documentElement)
{Element.Methods.replace = function (element, content) {
element = $(element);
if (content && content.toElement) {content = content.toElement();}
if (Object.isElement(content)) {
element.parentNode.replaceChild(content, element);
return element;
}
content = Object.toHTML(content);
const parent = element.parentNode,
tagName = parent.tagName.toUpperCase();
if (Element._insertionTranslations.tags[tagName]) {
const nextSibling = element.next(),
fragments = Element._getContentFromAnonymousElement(
tagName,
content.stripScripts(),
);
parent.removeChild(element);
if (nextSibling)
{fragments.each(function (node) {
parent.insertBefore(node, nextSibling);
});}
else
{fragments.each(function (node) {
parent.appendChild(node);
});}
} else {element.outerHTML = content.stripScripts();}
content.evalScripts.bind(content).defer();
return element;
};}
Element._returnOffset = function (l, t) {
const result = [l, t];
result.left = l;
result.top = t;
return result;
};
Element._getContentFromAnonymousElement = function (tagName, html, force) {
let div = new Element('div'),
t = Element._insertionTranslations.tags[tagName];
let workaround = false;
if (t) {workaround = true;}
else if (force) {
workaround = true;
t = ['', '', 0];
}
if (workaround) {
div.innerHTML = '&nbsp;' + t[0] + html + t[1];
div.removeChild(div.firstChild);
for (let i = t[2]; i--; ) {div = div.firstChild;}
} else {div.innerHTML = html;}
return $A(div.childNodes);
};
Element._insertionTranslations = {
before: function (element, node) {
element.parentNode.insertBefore(node, element);
},
top: function (element, node) {
element.insertBefore(node, element.firstChild);
},
bottom: function (element, node) {
element.appendChild(node);
},
after: function (element, node) {
element.parentNode.insertBefore(node, element.nextSibling);
},
tags: {
TABLE: ['<table>', '</table>', 1],
TBODY: ['<table><tbody>', '</tbody></table>', 2],
TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3],
TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
SELECT: ['<select>', '</select>', 1],
},
};
(function () {
const tags = Element._insertionTranslations.tags;
Object.extend(tags, { THEAD: tags.TBODY, TFOOT: tags.TBODY, TH: tags.TD });
})();
Element.Methods.Simulated = {
hasAttribute: function (element, attribute) {
attribute = Element._attributeTranslations.has[attribute] || attribute;
const node = $(element).getAttributeNode(attribute);
return !!(node && node.specified);
},
};
Element.Methods.ByTag = {};
Object.extend(Element, Element.Methods);
(function (div) {
if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) {
window.HTMLElement = {};
window.HTMLElement.prototype = div['__proto__'];
Prototype.BrowserFeatures.ElementExtensions = true;
}
div = null;
})(document.createElement('div'));
Element.extend = (function () {
function checkDeficiency(tagName) {
if (typeof window.Element != 'undefined') {
const proto = window.Element.prototype;
if (proto) {
let id = '_' + (Math.random() + '').slice(2),
el = document.createElement(tagName);
proto[id] = 'x';
const isBuggy = el[id] !== 'x';
delete proto[id];
el = null;
return isBuggy;
}
}
return false;
}
function extendElementWith(element, methods) {
for (const property in methods) {
const value = methods[property];
if (Object.isFunction(value) && !(property in element))
{element[property] = value.methodize();}
}
}
const HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object');
if (Prototype.BrowserFeatures.SpecificElementExtensions) {
if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY)
{return function (element) {
if (element && typeof element._extendedByPrototype == 'undefined') {
const t = element.tagName;
if (t && /^(?:object|applet|embed)$/i.test(t)) {
extendElementWith(element, Element.Methods);
extendElementWith(element, Element.Methods.Simulated);
extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
}
}
return element;
};}
return Prototype.K;
}
const Methods = {},
ByTag = Element.Methods.ByTag;
const extend = Object.extend(
function (element) {
if (
!element ||
typeof element._extendedByPrototype != 'undefined' ||
element.nodeType != 1 ||
element == window
)
{return element;}
const methods = Object.clone(Methods),
tagName = element.tagName.toUpperCase();
if (ByTag[tagName]) {Object.extend(methods, ByTag[tagName]);}
extendElementWith(element, methods);
element._extendedByPrototype = Prototype.emptyFunction;
return element;
},
{
refresh: function () {
if (!Prototype.BrowserFeatures.ElementExtensions) {
Object.extend(Methods, Element.Methods);
Object.extend(Methods, Element.Methods.Simulated);
}
},
},
);
extend.refresh();
return extend;
})();
if (document.documentElement.hasAttribute)
{Element.hasAttribute = function (element, attribute) {
return element.hasAttribute(attribute);
};}
else {Element.hasAttribute = Element.Methods.Simulated.hasAttribute;}
Element.addMethods = function (methods) {
const F = Prototype.BrowserFeatures,
T = Element.Methods.ByTag;
if (!methods) {
Object.extend(Form, Form.Methods);
Object.extend(Form.Element, Form.Element.Methods);
Object.extend(Element.Methods.ByTag, {
FORM: Object.clone(Form.Methods),
INPUT: Object.clone(Form.Element.Methods),
SELECT: Object.clone(Form.Element.Methods),
TEXTAREA: Object.clone(Form.Element.Methods),
BUTTON: Object.clone(Form.Element.Methods),
});
}
if (arguments.length == 2) {
var tagName = methods;
methods = arguments[1];
}
if (!tagName) {Object.extend(Element.Methods, methods || {});}
else if (Object.isArray(tagName)) {tagName.each(extend);}
else {extend(tagName);}
function extend(tagName) {
tagName = tagName.toUpperCase();
if (!Element.Methods.ByTag[tagName]) {Element.Methods.ByTag[tagName] = {};}
Object.extend(Element.Methods.ByTag[tagName], methods);
}
function copy(methods, destination, onlyIfAbsent) {
onlyIfAbsent = onlyIfAbsent || false;
for (const property in methods) {
const value = methods[property];
if (!Object.isFunction(value)) {continue;}
if (!onlyIfAbsent || !(property in destination))
{destination[property] = value.methodize();}
}
}
function findDOMClass(tagName) {
let klass;
const trans = {
OPTGROUP: 'OptGroup',
TEXTAREA: 'TextArea',
P: 'Paragraph',
FIELDSET: 'FieldSet',
UL: 'UList',
OL: 'OList',
DL: 'DList',
DIR: 'Directory',
H1: 'Heading',
H2: 'Heading',
H3: 'Heading',
H4: 'Heading',
H5: 'Heading',
H6: 'Heading',
Q: 'Quote',
INS: 'Mod',
DEL: 'Mod',
A: 'Anchor',
IMG: 'Image',
CAPTION: 'TableCaption',
COL: 'TableCol',
COLGROUP: 'TableCol',
THEAD: 'TableSection',
TFOOT: 'TableSection',
TBODY: 'TableSection',
TR: 'TableRow',
TH: 'TableCell',
TD: 'TableCell',
FRAMESET: 'FrameSet',
IFRAME: 'IFrame',
};
if (trans[tagName]) {klass = 'HTML' + trans[tagName] + 'Element';}
if (window[klass]) {return window[klass];}
klass = 'HTML' + tagName + 'Element';
if (window[klass]) {return window[klass];}
klass = 'HTML' + tagName.capitalize() + 'Element';
if (window[klass]) {return window[klass];}
let element = document.createElement(tagName),
proto = element['__proto__'] || element.constructor.prototype;
element = null;
return proto;
}
const elementPrototype = window.HTMLElement
? HTMLElement.prototype
: Element.prototype;
if (F.ElementExtensions) {
copy(Element.Methods, elementPrototype);
copy(Element.Methods.Simulated, elementPrototype, true);
}
if (F.SpecificElementExtensions)
{for (const tag in Element.Methods.ByTag) {
const klass = findDOMClass(tag);
if (Object.isUndefined(klass)) {continue;}
copy(T[tag], klass.prototype);
}}
Object.extend(Element, Element.Methods);
delete Element.ByTag;
if (Element.extend.refresh) {Element.extend.refresh();}
Element.cache = {};
};
document.viewport = {
getDimensions: function () {
return { width: this.getWidth(), height: this.getHeight() };
},
getScrollOffsets: function () {
return Element._returnOffset(
window.pageXOffset ||
document.documentElement.scrollLeft ||
document.body.scrollLeft,
window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop,
);
},
};
(function (viewport) {
let B = Prototype.Browser,
doc = document,
element,
property = {};
function getRootElement() {
if (B.WebKit && !doc.evaluate) {return document;}
if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
{return document.body;}
return document.documentElement;
}
function define(D) {
if (!element) {element = getRootElement();}
property[D] = 'client' + D;
viewport['get' + D] = function () {
return element[property[D]];
};
return viewport['get' + D]();
}
viewport.getWidth = define.curry('Width');
viewport.getHeight = define.curry('Height');
})(document.viewport);
Element.Storage = { UID: 1 };
Element.addMethods({
getStorage: function (element) {
if (!(element = $(element))) {return;}
let uid;
if (element === window) {uid = 0;}
else {
if (typeof element._prototypeUID === 'undefined')
{element._prototypeUID = Element.Storage.UID++;}
uid = element._prototypeUID;
}
if (!Element.Storage[uid]) {Element.Storage[uid] = $H();}
return Element.Storage[uid];
},
store: function (element, key, value) {
if (!(element = $(element))) {return;}
if (arguments.length === 2) {Element.getStorage(element).update(key);}
else {Element.getStorage(element).set(key, value);}
return element;
},
retrieve: function (element, key, defaultValue) {
if (!(element = $(element))) {return;}
let hash = Element.getStorage(element),
value = hash.get(key);
if (Object.isUndefined(value)) {
hash.set(key, defaultValue);
value = defaultValue;
}
return value;
},
clone: function (element, deep) {
if (!(element = $(element))) {return;}
const clone = element.cloneNode(deep);
clone._prototypeUID = void 0;
if (deep) {
let descendants = Element.select(clone, '*'),
i = descendants.length;
while (i--) {descendants[i]._prototypeUID = void 0;}
}
return Element.extend(clone);
},
purge: function (element) {
if (!(element = $(element))) {return;}
const purgeElement = Element._purgeElement;
purgeElement(element);
let descendants = element.getElementsByTagName('*'),
i = descendants.length;
while (i--) {purgeElement(descendants[i]);}
return null;
},
});
(function () {
function toDecimal(pctString) {
const match = pctString.match(/^(\d+)%?$/i);
if (!match) {return null;}
return Number(match[1]) / 100;
}
function getPixelValue(value, property, context) {
let element = null;
if (Object.isElement(value)) {
element = value;
value = element.getStyle(property);
}
if (value === null) {return null;}
if (/^(?:-)?\d+(\.\d+)?(px)?$/i.test(value))
{return window.parseFloat(value);}
const isPercentage = value.include('%'),
isViewport = context === document.viewport;
if (
/\d/.test(value) &&
element &&
element.runtimeStyle &&
!(isPercentage && isViewport)
) {
const style = element.style.left,
rStyle = element.runtimeStyle.left;
element.runtimeStyle.left = element.currentStyle.left;
element.style.left = value || 0;
value = element.style.pixelLeft;
element.style.left = style;
element.runtimeStyle.left = rStyle;
return value;
}
if (element && isPercentage) {
context = context || element.parentNode;
const decimal = toDecimal(value);
let whole = null;
const position = element.getStyle('position');
const isHorizontal =
property.include('left') ||
property.include('right') ||
property.include('width');
const isVertical =
property.include('top') ||
property.include('bottom') ||
property.include('height');
if (context === document.viewport)
{if (isHorizontal) {whole = document.viewport.getWidth();}
else {
if (isVertical) {whole = document.viewport.getHeight();}
}}
else if (isHorizontal) {whole = $(context).measure('width');}
else if (isVertical) {whole = $(context).measure('height');}
return whole === null ? 0 : whole * decimal;
}
return 0;
}
function toCSSPixels(number) {
if (Object.isString(number) && number.endsWith('px')) {return number;}
return number + 'px';
}
function isDisplayed(element) {
const originalElement = element;
while (element && element.parentNode) {
const display = element.getStyle('display');
if (display === 'none') {return false;}
element = $(element.parentNode);
}
return true;
}
let hasLayout = Prototype.K;
if ('currentStyle' in document.documentElement)
{hasLayout = function (element) {
if (!element.currentStyle.hasLayout) {element.style.zoom = 1;}
return element;
};}
function cssNameFor(key) {
if (key.include('border')) {key = key + '-width';}
return key.camelize();
}
Element.Layout = Class.create(Hash, {
initialize: function ($super, element, preCompute) {
$super();
this.element = $(element);
Element.Layout.PROPERTIES.each(function (property) {
this._set(property, null);
}, this);
if (preCompute) {
this._preComputing = true;
this._begin();
Element.Layout.PROPERTIES.each(this._compute, this);
this._end();
this._preComputing = false;
}
},
_set: function (property, value) {
return Hash.prototype.set.call(this, property, value);
},
set: function (property, value) {
throw 'Properties of Element.Layout are read-only.';
},
get: function ($super, property) {
const value = $super(property);
return value === null ? this._compute(property) : value;
},
_begin: function () {
if (this._prepared) {return;}
const element = this.element;
if (isDisplayed(element)) {
this._prepared = true;
return;
}
const originalStyles = {
position: element.style.position || '',
width: element.style.width || '',
visibility: element.style.visibility || '',
display: element.style.display || '',
};
element.store('prototype_original_styles', originalStyles);
let position = element.getStyle('position'),
width = element.getStyle('width');
if (width === '0px' || width === null) {
element.style.display = 'block';
width = element.getStyle('width');
}
const context =
position === 'fixed' ? document.viewport : element.parentNode;
element.setStyle({
position: 'absolute',
visibility: 'hidden',
display: 'block',
});
const positionedWidth = element.getStyle('width');
let newWidth;
if (width && positionedWidth === width)
{newWidth = getPixelValue(element, 'width', context);}
else if (position === 'absolute' || position === 'fixed')
{newWidth = getPixelValue(element, 'width', context);}
else {
const parent = element.parentNode,
pLayout = $(parent).getLayout();
newWidth =
pLayout.get('width') -
this.get('margin-left') -
this.get('border-left') -
this.get('padding-left') -
this.get('padding-right') -
this.get('border-right') -
this.get('margin-right');
}
element.setStyle({ width: newWidth + 'px' });
this._prepared = true;
},
_end: function () {
const element = this.element;
const originalStyles = element.retrieve('prototype_original_styles');
element.store('prototype_original_styles', null);
element.setStyle(originalStyles);
this._prepared = false;
},
_compute: function (property) {
const COMPUTATIONS = Element.Layout.COMPUTATIONS;
if (!(property in COMPUTATIONS)) {throw 'Property not found.';}
return this._set(
property,
COMPUTATIONS[property].call(this, this.element),
);
},
toObject: function () {
const args = $A(arguments);
const keys =
args.length === 0
? Element.Layout.PROPERTIES
: args.join(' ').split(' ');
const obj = {};
keys.each(function (key) {
if (!Element.Layout.PROPERTIES.include(key)) {return;}
const value = this.get(key);
if (value != null) {obj[key] = value;}
}, this);
return obj;
},
toHash: function () {
const obj = this.toObject.apply(this, arguments);
return new Hash(obj);
},
toCSS: function () {
const args = $A(arguments);
const keys =
args.length === 0
? Element.Layout.PROPERTIES
: args.join(' ').split(' ');
const css = {};
keys.each(function (key) {
if (!Element.Layout.PROPERTIES.include(key)) {return;}
if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) {return;}
const value = this.get(key);
if (value != null) {css[cssNameFor(key)] = value + 'px';}
}, this);
return css;
},
inspect: function () {
return '#<Element.Layout>';
},
});
Object.extend(Element.Layout, {
PROPERTIES: $w(
'height width top left right bottom border-left border-right border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height',
),
COMPOSITE_PROPERTIES: $w(
'padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height',
),
COMPUTATIONS: {
height: function (element) {
if (!this._preComputing) {this._begin();}
const bHeight = this.get('border-box-height');
if (bHeight <= 0) {
if (!this._preComputing) {this._end();}
return 0;
}
const bTop = this.get('border-top'),
bBottom = this.get('border-bottom');
const pTop = this.get('padding-top'),
pBottom = this.get('padding-bottom');
if (!this._preComputing) {this._end();}
return bHeight - bTop - bBottom - pTop - pBottom;
},
width: function (element) {
if (!this._preComputing) {this._begin();}
const bWidth = this.get('border-box-width');
if (bWidth <= 0) {
if (!this._preComputing) {this._end();}
return 0;
}
const bLeft = this.get('border-left'),
bRight = this.get('border-right');
const pLeft = this.get('padding-left'),
pRight = this.get('padding-right');
if (!this._preComputing) {this._end();}
return bWidth - bLeft - bRight - pLeft - pRight;
},
'padding-box-height': function (element) {
const height = this.get('height'),
pTop = this.get('padding-top'),
pBottom = this.get('padding-bottom');
return height + pTop + pBottom;
},
'padding-box-width': function (element) {
const width = this.get('width'),
pLeft = this.get('padding-left'),
pRight = this.get('padding-right');
return width + pLeft + pRight;
},
'border-box-height': function (element) {
if (!this._preComputing) {this._begin();}
const height = element.offsetHeight;
if (!this._preComputing) {this._end();}
return height;
},
'border-box-width': function (element) {
if (!this._preComputing) {this._begin();}
const width = element.offsetWidth;
if (!this._preComputing) {this._end();}
return width;
},
'margin-box-height': function (element) {
const bHeight = this.get('border-box-height'),
mTop = this.get('margin-top'),
mBottom = this.get('margin-bottom');
if (bHeight <= 0) {return 0;}
return bHeight + mTop + mBottom;
},
'margin-box-width': function (element) {
const bWidth = this.get('border-box-width'),
mLeft = this.get('margin-left'),
mRight = this.get('margin-right');
if (bWidth <= 0) {return 0;}
return bWidth + mLeft + mRight;
},
top: function (element) {
const offset = element.positionedOffset();
return offset.top;
},
bottom: function (element) {
const offset = element.positionedOffset(),
parent = element.getOffsetParent(),
pHeight = parent.measure('height');
const mHeight = this.get('border-box-height');
return pHeight - mHeight - offset.top;
},
left: function (element) {
const offset = element.positionedOffset();
return offset.left;
},
right: function (element) {
const offset = element.positionedOffset(),
parent = element.getOffsetParent(),
pWidth = parent.measure('width');
const mWidth = this.get('border-box-width');
return pWidth - mWidth - offset.left;
},
'padding-top': function (element) {
return getPixelValue(element, 'paddingTop');
},
'padding-bottom': function (element) {
return getPixelValue(element, 'paddingBottom');
},
'padding-left': function (element) {
return getPixelValue(element, 'paddingLeft');
},
'padding-right': function (element) {
return getPixelValue(element, 'paddingRight');
},
'border-top': function (element) {
return getPixelValue(element, 'borderTopWidth');
},
'border-bottom': function (element) {
return getPixelValue(element, 'borderBottomWidth');
},
'border-left': function (element) {
return getPixelValue(element, 'borderLeftWidth');
},
'border-right': function (element) {
return getPixelValue(element, 'borderRightWidth');
},
'margin-top': function (element) {
return getPixelValue(element, 'marginTop');
},
'margin-bottom': function (element) {
return getPixelValue(element, 'marginBottom');
},
'margin-left': function (element) {
return getPixelValue(element, 'marginLeft');
},
'margin-right': function (element) {
return getPixelValue(element, 'marginRight');
},
},
});
if ('getBoundingClientRect' in document.documentElement)
{Object.extend(Element.Layout.COMPUTATIONS, {
right: function (element) {
const parent = hasLayout(element.getOffsetParent());
const rect = element.getBoundingClientRect(),
pRect = parent.getBoundingClientRect();
return (pRect.right - rect.right).round();
},
bottom: function (element) {
const parent = hasLayout(element.getOffsetParent());
const rect = element.getBoundingClientRect(),
pRect = parent.getBoundingClientRect();
return (pRect.bottom - rect.bottom).round();
},
});}
Element.Offset = Class.create({
initialize: function (left, top) {
this.left = left.round();
this.top = top.round();
this[0] = this.left;
this[1] = this.top;
},
relativeTo: function (offset) {
return new Element.Offset(this.left - offset.left, this.top - offset.top);
},
inspect: function () {
return '#<Element.Offset left: #{left} top: #{top}>'.interpolate(this);
},
toString: function () {
return '[#{left}, #{top}]'.interpolate(this);
},
toArray: function () {
return [this.left, this.top];
},
});
function getLayout(element, preCompute) {
return new Element.Layout(element, preCompute);
}
function measure(element, property) {
return $(element).getLayout().get(property);
}
function getDimensions(element) {
element = $(element);
const display = Element.getStyle(element, 'display');
if (display && display !== 'none')
{return { width: element.offsetWidth, height: element.offsetHeight };}
const style = element.style;
const originalStyles = {
visibility: style.visibility,
position: style.position,
display: style.display,
};
const newStyles = { visibility: 'hidden', display: 'block' };
if (originalStyles.position !== 'fixed') {newStyles.position = 'absolute';}
Element.setStyle(element, newStyles);
const dimensions = {
width: element.offsetWidth,
height: element.offsetHeight,
};
Element.setStyle(element, originalStyles);
return dimensions;
}
function getOffsetParent(element) {
element = $(element);
if (
isDocument(element) ||
isDetached(element) ||
isBody(element) ||
isHtml(element)
)
{return $(document.body);}
const isInline = Element.getStyle(element, 'display') === 'inline';
if (!isInline && element.offsetParent) {return $(element.offsetParent);}
while ((element = element.parentNode) && element !== document.body)
{if (Element.getStyle(element, 'position') !== 'static')
{return isHtml(element) ? $(document.body) : $(element);}}
return $(document.body);
}
function cumulativeOffset(element) {
element = $(element);
let valueT = 0,
valueL = 0;
if (element.parentNode) {
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
element = element.offsetParent;
} while (element);
}
return new Element.Offset(valueL, valueT);
}
function positionedOffset(element) {
element = $(element);
const layout = element.getLayout();
let valueT = 0,
valueL = 0;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
element = element.offsetParent;
if (element) {
if (isBody(element)) {break;}
const p = Element.getStyle(element, 'position');
if (p !== 'static') {break;}
}
} while (element);
valueL -= layout.get('margin-top');
valueT -= layout.get('margin-left');
return new Element.Offset(valueL, valueT);
}
function cumulativeScrollOffset(element) {
let valueT = 0,
valueL = 0;
do {
valueT += element.scrollTop || 0;
valueL += element.scrollLeft || 0;
element = element.parentNode;
} while (element);
return new Element.Offset(valueL, valueT);
}
function viewportOffset(forElement) {
element = $(element);
let valueT = 0,
valueL = 0,
docBody = document.body;
var element = forElement;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
if (
element.offsetParent == docBody &&
Element.getStyle(element, 'position') == 'absolute'
)
{break;}
} while ((element = element.offsetParent));
element = forElement;
do
{if (element != docBody) {
valueT -= element.scrollTop || 0;
valueL -= element.scrollLeft || 0;
}}
while ((element = element.parentNode));
return new Element.Offset(valueL, valueT);
}
function absolutize(element) {
element = $(element);
if (Element.getStyle(element, 'position') === 'absolute') {return element;}
const offsetParent = getOffsetParent(element);
const eOffset = element.viewportOffset(),
pOffset = offsetParent.viewportOffset();
const offset = eOffset.relativeTo(pOffset);
const layout = element.getLayout();
element.store('prototype_absolutize_original_styles', {
left: element.getStyle('left'),
top: element.getStyle('top'),
width: element.getStyle('width'),
height: element.getStyle('height'),
});
element.setStyle({
position: 'absolute',
top: offset.top + 'px',
left: offset.left + 'px',
width: layout.get('width') + 'px',
height: layout.get('height') + 'px',
});
return element;
}
function relativize(element) {
element = $(element);
if (Element.getStyle(element, 'position') === 'relative') {return element;}
const originalStyles = element.retrieve(
'prototype_absolutize_original_styles',
);
if (originalStyles) {element.setStyle(originalStyles);}
return element;
}
if (Prototype.Browser.IE) {
getOffsetParent = getOffsetParent.wrap(function (proceed, element) {
element = $(element);
if (
isDocument(element) ||
isDetached(element) ||
isBody(element) ||
isHtml(element)
)
{return $(document.body);}
const position = element.getStyle('position');
if (position !== 'static') {return proceed(element);}
element.setStyle({ position: 'relative' });
const value = proceed(element);
element.setStyle({ position: position });
return value;
});
positionedOffset = positionedOffset.wrap(function (proceed, element) {
element = $(element);
if (!element.parentNode) {return new Element.Offset(0, 0);}
const position = element.getStyle('position');
if (position !== 'static') {return proceed(element);}
const offsetParent = element.getOffsetParent();
if (offsetParent && offsetParent.getStyle('position') === 'fixed')
{hasLayout(offsetParent);}
element.setStyle({ position: 'relative' });
const value = proceed(element);
element.setStyle({ position: position });
return value;
});
} else if (Prototype.Browser.Webkit)
{cumulativeOffset = function (element) {
element = $(element);
let valueT = 0,
valueL = 0;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
if (element.offsetParent == document.body)
{if (Element.getStyle(element, 'position') == 'absolute') {break;}}
element = element.offsetParent;
} while (element);
return new Element.Offset(valueL, valueT);
};}
Element.addMethods({
getLayout: getLayout,
measure: measure,
getDimensions: getDimensions,
getOffsetParent: getOffsetParent,
cumulativeOffset: cumulativeOffset,
positionedOffset: positionedOffset,
cumulativeScrollOffset: cumulativeScrollOffset,
viewportOffset: viewportOffset,
absolutize: absolutize,
relativize: relativize,
});
function isBody(element) {
return element.nodeName.toUpperCase() === 'BODY';
}
function isHtml(element) {
return element.nodeName.toUpperCase() === 'HTML';
}
function isDocument(element) {
return element.nodeType === Node.DOCUMENT_NODE;
}
function isDetached(element) {
return (
element !== document.body && !Element.descendantOf(element, document.body)
);
}
if ('getBoundingClientRect' in document.documentElement)
{Element.addMethods({
viewportOffset: function (element) {
element = $(element);
if (isDetached(element)) {return new Element.Offset(0, 0);}
const rect = element.getBoundingClientRect(),
docEl = document.documentElement;
return new Element.Offset(
rect.left - docEl.clientLeft,
rect.top - docEl.clientTop,
);
},
});}
})();
window.$$ = function () {
const expression = $A(arguments).join(', ');
return Prototype.Selector.select(expression, document);
};
Prototype.Selector = (function () {
function select() {
throw new Error('Method "Prototype.Selector.select" must be defined.');
}
function match() {
throw new Error('Method "Prototype.Selector.match" must be defined.');
}
function find(elements, expression, index) {
index = index || 0;
let match = Prototype.Selector.match,
length = elements.length,
matchIndex = 0,
i;
for (i = 0; i < length; i++)
{if (match(elements[i], expression) && index == matchIndex++)
{return Element.extend(elements[i]);}}
}
function extendElements(elements) {
for (let i = 0, length = elements.length; i < length; i++)
{Element.extend(elements[i]);}
return elements;
}
const K = Prototype.K;
return {
select: select,
match: match,
find: find,
extendElements: Element.extend === K ? K : extendElements,
extendElement: Element.extend,
};
})();
Prototype._original_property = window.Sizzle;
(function () {
let chunker =
/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
done = 0,
toString = Object.prototype.toString,
hasDuplicate = false,
baseHasDuplicate = true;
[0, 0].sort(function () {
baseHasDuplicate = false;
return 0;
});
let Sizzle = function (selector, context, results, seed) {
results = results || [];
const origContext = (context = context || document);
if (context.nodeType !== 1 && context.nodeType !== 9) {return [];}
if (!selector || typeof selector !== 'string') {return results;}
let parts = [],
m,
set,
checkSet,
check,
mode,
extra,
prune = true,
contextXML = isXML(context),
soFar = selector;
while ((chunker.exec(''), (m = chunker.exec(soFar))) !== null) {
soFar = m[3];
parts.push(m[1]);
if (m[2]) {
extra = m[3];
break;
}
}
if (parts.length > 1 && origPOS.exec(selector))
{if (parts.length === 2 && Expr.relative[parts[0]])
{set = posProcess(parts[0] + parts[1], context);}
else {
set = Expr.relative[parts[0]]
? [context]
: Sizzle(parts.shift(), context);
while (parts.length) {
selector = parts.shift();
if (Expr.relative[selector]) {selector += parts.shift();}
set = posProcess(selector, set);
}
}}
else {
if (
!seed &&
parts.length > 1 &&
context.nodeType === 9 &&
!contextXML &&
Expr.match.ID.test(parts[0]) &&
!Expr.match.ID.test(parts[parts.length - 1])
) {
var ret = Sizzle.find(parts.shift(), context, contextXML);
context = ret.expr ? Sizzle.filter(ret.expr, ret.set)[0] : ret.set[0];
}
if (context) {
var ret = seed
? { expr: parts.pop(), set: makeArray(seed) }
: Sizzle.find(
parts.pop(),
parts.length === 1 &&
(parts[0] === '~' || parts[0] === '+') &&
context.parentNode
? context.parentNode
: context,
contextXML,
);
set = ret.expr ? Sizzle.filter(ret.expr, ret.set) : ret.set;
if (parts.length > 0) {checkSet = makeArray(set);}
else {prune = false;}
while (parts.length) {
var cur = parts.pop(),
pop = cur;
if (!Expr.relative[cur]) {cur = '';}
else {pop = parts.pop();}
if (pop == null) {pop = context;}
Expr.relative[cur](checkSet, pop, contextXML);
}
} else {checkSet = parts = [];}
}
if (!checkSet) {checkSet = set;}
if (!checkSet)
{throw 'Syntax error, unrecognized expression: ' + (cur || selector);}
if (toString.call(checkSet) === '[object Array]')
{if (!prune) {results.push.apply(results, checkSet);}
else if (context && context.nodeType === 1)
{for (var i = 0; checkSet[i] != null; i++) {
if (
checkSet[i] &&
(checkSet[i] === true ||
(checkSet[i].nodeType === 1 && contains(context, checkSet[i])))
)
{results.push(set[i]);}
}}
else
{for (var i = 0; checkSet[i] != null; i++) {
if (checkSet[i] && checkSet[i].nodeType === 1) {results.push(set[i]);}
}}}
else {makeArray(checkSet, results);}
if (extra) {
Sizzle(extra, origContext, results, seed);
Sizzle.uniqueSort(results);
}
return results;
};
Sizzle.uniqueSort = function (results) {
if (sortOrder) {
hasDuplicate = baseHasDuplicate;
results.sort(sortOrder);
if (hasDuplicate)
{for (let i = 1; i < results.length; i++)
{if (results[i] === results[i - 1]) {results.splice(i--, 1);}}}
}
return results;
};
Sizzle.matches = function (expr, set) {
return Sizzle(expr, null, null, set);
};
Sizzle.find = function (expr, context, isXML) {
var set, match;
if (!expr) {return [];}
for (let i = 0, l = Expr.order.length; i < l; i++) {
var type = Expr.order[i],
match;
if ((match = Expr.leftMatch[type].exec(expr))) {
const left = match[1];
match.splice(1, 1);
if (left.substr(left.length - 1) !== '\\') {
match[1] = (match[1] || '').replace(/\\/g, '');
set = Expr.find[type](match, context, isXML);
if (set != null) {
expr = expr.replace(Expr.match[type], '');
break;
}
}
}
}
if (!set) {set = context.getElementsByTagName('*');}
return { set: set, expr: expr };
};
Sizzle.filter = function (expr, set, inplace, not) {
let old = expr,
result = [],
curLoop = set,
match,
anyFound,
isXMLFilter = set && set[0] && isXML(set[0]);
while (expr && set.length) {
for (const type in Expr.filter)
{if ((match = Expr.match[type].exec(expr)) != null) {
var filter = Expr.filter[type],
found,
item;
anyFound = false;
if (curLoop == result) {result = [];}
if (Expr.preFilter[type]) {
match = Expr.preFilter[type](
match,
curLoop,
inplace,
result,
not,
isXMLFilter,
);
if (!match) {anyFound = found = true;}
else if (match === true) {continue;}
}
if (match)
{for (let i = 0; (item = curLoop[i]) != null; i++)
{if (item) {
found = filter(item, match, i, curLoop);
const pass = not ^ !!found;
if (inplace && found != null)
{if (pass) {anyFound = true;}
else {curLoop[i] = false;}}
else if (pass) {
result.push(item);
anyFound = true;
}
}}}
if (found !== undefined) {
if (!inplace) {curLoop = result;}
expr = expr.replace(Expr.match[type], '');
if (!anyFound) {return [];}
break;
}
}}
if (expr == old)
{if (anyFound == null)
{throw 'Syntax error, unrecognized expression: ' + expr;}
else {break;}}
old = expr;
}
return curLoop;
};
var Expr = (Sizzle.selectors = {
order: ['ID', 'NAME', 'TAG'],
match: {
ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
PSEUDO:
/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/,
},
leftMatch: {},
attrMap: { class: 'className', for: 'htmlFor' },
attrHandle: {
href: function (elem) {
return elem.getAttribute('href');
},
},
relative: {
'+': function (checkSet, part, isXML) {
const isPartStr = typeof part === 'string',
isTag = isPartStr && !/\W/.test(part),
isPartStrNotTag = isPartStr && !isTag;
if (isTag && !isXML) {part = part.toUpperCase();}
for (var i = 0, l = checkSet.length, elem; i < l; i++)
{if ((elem = checkSet[i])) {
while ((elem = elem.previousSibling) && elem.nodeType !== 1){;}
checkSet[i] =
isPartStrNotTag || (elem && elem.nodeName === part)
? elem || false
: elem === part;
}}
if (isPartStrNotTag) {Sizzle.filter(part, checkSet, true);}
},
'>': function (checkSet, part, isXML) {
const isPartStr = typeof part === 'string';
if (isPartStr && !/\W/.test(part)) {
part = isXML ? part : part.toUpperCase();
for (var i = 0, l = checkSet.length; i < l; i++) {
var elem = checkSet[i];
if (elem) {
const parent = elem.parentNode;
checkSet[i] = parent.nodeName === part ? parent : false;
}
}
} else {
for (var i = 0, l = checkSet.length; i < l; i++) {
var elem = checkSet[i];
if (elem)
{checkSet[i] = isPartStr
? elem.parentNode
: elem.parentNode === part;}
}
if (isPartStr) {Sizzle.filter(part, checkSet, true);}
}
},
'': function (checkSet, part, isXML) {
let doneName = done++,
checkFn = dirCheck;
if (!/\W/.test(part)) {
var nodeCheck = (part = isXML ? part : part.toUpperCase());
checkFn = dirNodeCheck;
}
checkFn('parentNode', part, doneName, checkSet, nodeCheck, isXML);
},
'~': function (checkSet, part, isXML) {
let doneName = done++,
checkFn = dirCheck;
if (typeof part === 'string' && !/\W/.test(part)) {
var nodeCheck = (part = isXML ? part : part.toUpperCase());
checkFn = dirNodeCheck;
}
checkFn('previousSibling', part, doneName, checkSet, nodeCheck, isXML);
},
},
find: {
ID: function (match, context, isXML) {
if (typeof context.getElementById !== 'undefined' && !isXML) {
const m = context.getElementById(match[1]);
return m ? [m] : [];
}
},
NAME: function (match, context, isXML) {
if (typeof context.getElementsByName !== 'undefined') {
const ret = [],
results = context.getElementsByName(match[1]);
for (let i = 0, l = results.length; i < l; i++)
{if (results[i].getAttribute('name') === match[1])
{ret.push(results[i]);}}
return ret.length === 0 ? null : ret;
}
},
TAG: function (match, context) {
return context.getElementsByTagName(match[1]);
},
},
preFilter: {
CLASS: function (match, curLoop, inplace, result, not, isXML) {
match = ' ' + match[1].replace(/\\/g, '') + ' ';
if (isXML) {return match;}
for (var i = 0, elem; (elem = curLoop[i]) != null; i++)
{if (elem)
{if (
not ^
(elem.className &&
(' ' + elem.className + ' ').indexOf(match) >= 0)
) {
if (!inplace) {result.push(elem);}
} else if (inplace) {curLoop[i] = false;}}}
return false;
},
ID: function (match) {
return match[1].replace(/\\/g, '');
},
TAG: function (match, curLoop) {
for (var i = 0; curLoop[i] === false; i++){;}
return curLoop[i] && isXML(curLoop[i])
? match[1]
: match[1].toUpperCase();
},
CHILD: function (match) {
if (match[1] == 'nth') {
const test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
(match[2] == 'even' && '2n') ||
(match[2] == 'odd' && '2n+1') ||
(!/\D/.test(match[2]) && '0n+' + match[2]) ||
match[2],
);
match[2] = test[1] + (test[2] || 1) - 0;
match[3] = test[3] - 0;
}
match[0] = done++;
return match;
},
ATTR: function (match, curLoop, inplace, result, not, isXML) {
const name = match[1].replace(/\\/g, '');
if (!isXML && Expr.attrMap[name]) {match[1] = Expr.attrMap[name];}
if (match[2] === '~=') {match[4] = ' ' + match[4] + ' ';}
return match;
},
PSEUDO: function (match, curLoop, inplace, result, not) {
if (match[1] === 'not')
{if ((chunker.exec(match[3]) || '').length > 1 || /^\w/.test(match[3]))
{match[3] = Sizzle(match[3], null, null, curLoop);}
else {
const ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
if (!inplace) {result.push.apply(result, ret);}
return false;
}}
else if (
Expr.match.POS.test(match[0]) ||
Expr.match.CHILD.test(match[0])
)
{return true;}
return match;
},
POS: function (match) {
match.unshift(true);
return match;
},
},
filters: {
enabled: function (elem) {
return elem.disabled === false && elem.type !== 'hidden';
},
disabled: function (elem) {
return elem.disabled === true;
},
checked: function (elem) {
return elem.checked === true;
},
selected: function (elem) {
elem.parentNode.selectedIndex;
return elem.selected === true;
},
parent: function (elem) {
return !!elem.firstChild;
},
empty: function (elem) {
return !elem.firstChild;
},
has: function (elem, i, match) {
return !!Sizzle(match[3], elem).length;
},
header: function (elem) {
return /h\d/i.test(elem.nodeName);
},
text: function (elem) {
return 'text' === elem.type;
},
radio: function (elem) {
return 'radio' === elem.type;
},
checkbox: function (elem) {
return 'checkbox' === elem.type;
},
file: function (elem) {
return 'file' === elem.type;
},
password: function (elem) {
return 'password' === elem.type;
},
submit: function (elem) {
return 'submit' === elem.type;
},
image: function (elem) {
return 'image' === elem.type;
},
reset: function (elem) {
return 'reset' === elem.type;
},
button: function (elem) {
return (
'button' === elem.type || elem.nodeName.toUpperCase() === 'BUTTON'
);
},
input: function (elem) {
return /input|select|textarea|button/i.test(elem.nodeName);
},
},
setFilters: {
first: function (elem, i) {
return i === 0;
},
last: function (elem, i, match, array) {
return i === array.length - 1;
},
even: function (elem, i) {
return i % 2 === 0;
},
odd: function (elem, i) {
return i % 2 === 1;
},
lt: function (elem, i, match) {
return i < match[3] - 0;
},
gt: function (elem, i, match) {
return i > match[3] - 0;
},
nth: function (elem, i, match) {
return match[3] - 0 == i;
},
eq: function (elem, i, match) {
return match[3] - 0 == i;
},
},
filter: {
PSEUDO: function (elem, match, i, array) {
const name = match[1],
filter = Expr.filters[name];
if (filter) {return filter(elem, i, match, array);}
else if (name === 'contains')
{return (
(elem.textContent || elem.innerText || '').indexOf(match[3]) >= 0
);}
else if (name === 'not') {
const not = match[3];
for (var i = 0, l = not.length; i < l; i++)
{if (not[i] === elem) {return false;}}
return true;
}
},
CHILD: function (elem, match) {
let type = match[1],
node = elem;
switch (type) {
case 'only':
case 'first':
while ((node = node.previousSibling))
{if (node.nodeType === 1) {return false;}}
if (type == 'first') {return true;}
node = elem;
case 'last':
while ((node = node.nextSibling))
{if (node.nodeType === 1) {return false;}}
return true;
case 'nth':
var first = match[2],
last = match[3];
if (first == 1 && last == 0) {return true;}
var doneName = match[0],
parent = elem.parentNode;
if (parent && (parent.sizcache !== doneName || !elem.nodeIndex)) {
let count = 0;
for (node = parent.firstChild; node; node = node.nextSibling)
{if (node.nodeType === 1) {node.nodeIndex = ++count;}}
parent.sizcache = doneName;
}
var diff = elem.nodeIndex - last;
if (first == 0) {return diff == 0;}
else {return diff % first == 0 && diff / first >= 0;}
}
},
ID: function (elem, match) {
return elem.nodeType === 1 && elem.getAttribute('id') === match;
},
TAG: function (elem, match) {
return (
(match === '*' && elem.nodeType === 1) || elem.nodeName === match
);
},
CLASS: function (elem, match) {
return (
(' ' + (elem.className || elem.getAttribute('class')) + ' ').indexOf(
match,
) > -1
);
},
ATTR: function (elem, match) {
const name = match[1],
result = Expr.attrHandle[name]
? Expr.attrHandle[name](elem)
: elem[name] != null
? elem[name]
: elem.getAttribute(name),
value = result + '',
type = match[2],
check = match[4];
return result == null
? type === '!='
: type === '='
? value === check
: type === '*='
? value.indexOf(check) >= 0
: type === '~='
? (' ' + value + ' ').indexOf(check) >= 0
: !check
? value && result !== false
: type === '!='
? value != check
: type === '^='
? value.indexOf(check) === 0
: type === '$='
? value.substr(value.length - check.length) === check
: type === '|='
? value === check || value.substr(0, check.length + 1) === check + '-'
: false;
},
POS: function (elem, match, i, array) {
const name = match[2],
filter = Expr.setFilters[name];
if (filter) {return filter(elem, i, match, array);}
},
},
});
var origPOS = Expr.match.POS;
for (const type in Expr.match) {
Expr.match[type] = new RegExp(
Expr.match[type].source + /(?![^\[]*\])(?![^\(]*\))/.source,
);
Expr.leftMatch[type] = new RegExp(
/(^(?:.|\r|\n)*?)/.source + Expr.match[type].source,
);
}
var makeArray = function (array, results) {
array = Array.prototype.slice.call(array, 0);
if (results) {
results.push.apply(results, array);
return results;
}
return array;
};
try {
Array.prototype.slice.call(document.documentElement.childNodes, 0);
} catch (e) {
makeArray = function (array, results) {
const ret = results || [];
if (toString.call(array) === '[object Array]')
{Array.prototype.push.apply(ret, array);}
else if (typeof array.length === 'number')
{for (var i = 0, l = array.length; i < l; i++) {ret.push(array[i]);}}
else {for (var i = 0; array[i]; i++) {ret.push(array[i]);}}
return ret;
};
}
let sortOrder;
if (document.documentElement.compareDocumentPosition)
{sortOrder = function (a, b) {
if (!a.compareDocumentPosition || !b.compareDocumentPosition) {
if (a == b) {hasDuplicate = true;}
return 0;
}
const ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
if (ret === 0) {hasDuplicate = true;}
return ret;
};}
else if ('sourceIndex' in document.documentElement)
{sortOrder = function (a, b) {
if (!a.sourceIndex || !b.sourceIndex) {
if (a == b) {hasDuplicate = true;}
return 0;
}
const ret = a.sourceIndex - b.sourceIndex;
if (ret === 0) {hasDuplicate = true;}
return ret;
};}
else if (document.createRange)
{sortOrder = function (a, b) {
if (!a.ownerDocument || !b.ownerDocument) {
if (a == b) {hasDuplicate = true;}
return 0;
}
const aRange = a.ownerDocument.createRange(),
bRange = b.ownerDocument.createRange();
aRange.setStart(a, 0);
aRange.setEnd(a, 0);
bRange.setStart(b, 0);
bRange.setEnd(b, 0);
const ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
if (ret === 0) {hasDuplicate = true;}
return ret;
};}
(function () {
let form = document.createElement('div'),
id = 'script' + new Date().getTime();
form.innerHTML = "<a name='" + id + "'/>";
let root = document.documentElement;
root.insertBefore(form, root.firstChild);
if (!!document.getElementById(id)) {
Expr.find.ID = function (match, context, isXML) {
if (typeof context.getElementById !== 'undefined' && !isXML) {
const m = context.getElementById(match[1]);
return m
? m.id === match[1] ||
(typeof m.getAttributeNode !== 'undefined' &&
m.getAttributeNode('id').nodeValue === match[1])
? [m]
: undefined
: [];
}
};
Expr.filter.ID = function (elem, match) {
const node =
typeof elem.getAttributeNode !== 'undefined' &&
elem.getAttributeNode('id');
return elem.nodeType === 1 && node && node.nodeValue === match;
};
}
root.removeChild(form);
root = form = null;
})();
(function () {
let div = document.createElement('div');
div.appendChild(document.createComment(''));
if (div.getElementsByTagName('*').length > 0)
{Expr.find.TAG = function (match, context) {
let results = context.getElementsByTagName(match[1]);
if (match[1] === '*') {
const tmp = [];
for (let i = 0; results[i]; i++)
{if (results[i].nodeType === 1) {tmp.push(results[i]);}}
results = tmp;
}
return results;
};}
div.innerHTML = "<a href='#'></a>";
if (
div.firstChild &&
typeof div.firstChild.getAttribute !== 'undefined' &&
div.firstChild.getAttribute('href') !== '#'
)
{Expr.attrHandle.href = function (elem) {
return elem.getAttribute('href', 2);
};}
div = null;
})();
if (document.querySelectorAll)
{(function () {
let oldSizzle = Sizzle,
div = document.createElement('div');
div.innerHTML = "<p class='TEST'></p>";
if (div.querySelectorAll && div.querySelectorAll('.TEST').length === 0)
{return;}
Sizzle = function (query, context, extra, seed) {
context = context || document;
if (!seed && context.nodeType === 9 && !isXML(context))
{try {
return makeArray(context.querySelectorAll(query), extra);
} catch (e$1) {}}
return oldSizzle(query, context, extra, seed);
};
for (const prop in oldSizzle) {Sizzle[prop] = oldSizzle[prop];}
div = null;
})();}
if (
document.getElementsByClassName &&
document.documentElement.getElementsByClassName
)
{(function () {
let div = document.createElement('div');
div.innerHTML = "<div class='test e'></div><div class='test'></div>";
if (div.getElementsByClassName('e').length === 0) {return;}
div.lastChild.className = 'e';
if (div.getElementsByClassName('e').length === 1) {return;}
Expr.order.splice(1, 0, 'CLASS');
Expr.find.CLASS = function (match, context, isXML) {
if (typeof context.getElementsByClassName !== 'undefined' && !isXML)
{return context.getElementsByClassName(match[1]);}
};
div = null;
})();}
function dirNodeCheck(dir, cur, doneName, checkSet, nodeCheck, isXML) {
const sibDir = dir == 'previousSibling' && !isXML;
for (let i = 0, l = checkSet.length; i < l; i++) {
let elem = checkSet[i];
if (elem) {
if (sibDir && elem.nodeType === 1) {
elem.sizcache = doneName;
elem.sizset = i;
}
elem = elem[dir];
let match = false;
while (elem) {
if (elem.sizcache === doneName) {
match = checkSet[elem.sizset];
break;
}
if (elem.nodeType === 1 && !isXML) {
elem.sizcache = doneName;
elem.sizset = i;
}
if (elem.nodeName === cur) {
match = elem;
break;
}
elem = elem[dir];
}
checkSet[i] = match;
}
}
}
function dirCheck(dir, cur, doneName, checkSet, nodeCheck, isXML) {
const sibDir = dir == 'previousSibling' && !isXML;
for (let i = 0, l = checkSet.length; i < l; i++) {
let elem = checkSet[i];
if (elem) {
if (sibDir && elem.nodeType === 1) {
elem.sizcache = doneName;
elem.sizset = i;
}
elem = elem[dir];
let match = false;
while (elem) {
if (elem.sizcache === doneName) {
match = checkSet[elem.sizset];
break;
}
if (elem.nodeType === 1) {
if (!isXML) {
elem.sizcache = doneName;
elem.sizset = i;
}
if (typeof cur !== 'string') {
if (elem === cur) {
match = true;
break;
}
} else if (Sizzle.filter(cur, [elem]).length > 0) {
match = elem;
break;
}
}
elem = elem[dir];
}
checkSet[i] = match;
}
}
}
var contains = document.compareDocumentPosition
? function (a, b) {
return a.compareDocumentPosition(b) & 16;
}
: function (a, b) {
return a !== b && (a.contains ? a.contains(b) : true);
};
var isXML = function (elem) {
return (
(elem.nodeType === 9 && elem.documentElement.nodeName !== 'HTML') ||
(!!elem.ownerDocument &&
elem.ownerDocument.documentElement.nodeName !== 'HTML')
);
};
var posProcess = function (selector, context) {
let tmpSet = [],
later = '',
match,
root = context.nodeType ? [context] : context;
while ((match = Expr.match.PSEUDO.exec(selector))) {
later += match[0];
selector = selector.replace(Expr.match.PSEUDO, '');
}
selector = Expr.relative[selector] ? selector + '*' : selector;
for (let i = 0, l = root.length; i < l; i++)
{Sizzle(selector, root[i], tmpSet);}
return Sizzle.filter(later, tmpSet);
};
window.Sizzle = Sizzle;
})();
(function (engine) {
const extendElements = Prototype.Selector.extendElements;
function select(selector, scope) {
return extendElements(engine(selector, scope || document));
}
function match(element, selector) {
return engine.matches(selector, [element]).length == 1;
}
Prototype.Selector.engine = engine;
Prototype.Selector.select = select;
Prototype.Selector.match = match;
})(Sizzle);
window.Sizzle = Prototype._original_property;
delete Prototype._original_property;
var Form = {
reset: function (form) {
form = $(form);
form.reset();
return form;
},
serializeElements: function (elements, options) {
if (typeof options != 'object') {options = { hash: !!options };}
else if (Object.isUndefined(options.hash)) {options.hash = true;}
let key,
value,
submitted = false,
submit = options.submit,
accumulator,
initial;
if (options.hash) {
initial = {};
accumulator = function (result, key, value) {
if (key in result) {
if (!Object.isArray(result[key])) {result[key] = [result[key]];}
result[key].push(value);
} else {result[key] = value;}
return result;
};
} else {
initial = '';
accumulator = function (result, key, value) {
return (
result +
(result ? '&' : '') +
encodeURIComponent(key) +
'=' +
encodeURIComponent(value)
);
};
}
return elements.inject(initial, function (result, element) {
if (!element.disabled && element.name) {
key = element.name;
value = $(element).getValue();
if (
value != null &&
element.type != 'file' &&
(element.type != 'submit' ||
(!submitted &&
submit !== false &&
(!submit || key == submit) &&
(submitted = true)))
)
{result = accumulator(result, key, value);}
}
return result;
});
},
};
Form.Methods = {
serialize: function (form, options) {
return Form.serializeElements(Form.getElements(form), options);
},
getElements: function (form) {
let elements = $(form).getElementsByTagName('*'),
element,
arr = [],
serializers = Form.Element.Serializers;
for (let i = 0; (element = elements[i]); i++) {arr.push(element);}
return arr.inject([], function (elements, child) {
if (serializers[child.tagName.toLowerCase()])
{elements.push(Element.extend(child));}
return elements;
});
},
getInputs: function (form, typeName, name) {
form = $(form);
const inputs = form.getElementsByTagName('input');
if (!typeName && !name) {return $A(inputs).map(Element.extend);}
for (
var i = 0, matchingInputs = [], length = inputs.length;
i < length;
i++
) {
const 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(form).invoke('disable');
return form;
},
enable: function (form) {
form = $(form);
Form.getElements(form).invoke('enable');
return form;
},
findFirstElement: function (form) {
const elements = $(form)
.getElements()
.findAll(function (element) {
return 'hidden' != element.type && !element.disabled;
});
const firstByIndex = elements
.findAll(function (element) {
return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
})
.sortBy(function (element) {
return element.tabIndex;
})
.first();
return firstByIndex
? firstByIndex
: elements.find(function (element) {
return /^(?:input|select|textarea)$/i.test(element.tagName);
});
},
focusFirstElement: function (form) {
form = $(form);
const element = form.findFirstElement();
if (element) {element.activate();}
return form;
},
request: function (form, options) {
(form = $(form)), (options = Object.clone(options || {}));
let params = options.parameters,
action = form.readAttribute('action') || '';
if (action.blank()) {action = window.location.href;}
options.parameters = form.serialize(true);
if (params) {
if (Object.isString(params)) {params = params.toQueryParams();}
Object.extend(options.parameters, params);
}
if (form.hasAttribute('method') && !options.method)
{options.method = form.method;}
return new Ajax.Request(action, options);
},
};
Form.Element = {
focus: function (element) {
$(element).focus();
return element;
},
select: function (element) {
$(element).select();
return element;
},
};
Form.Element.Methods = {
serialize: function (element) {
element = $(element);
if (!element.disabled && element.name) {
const value = element.getValue();
if (value != undefined) {
const pair = {};
pair[element.name] = value;
return Object.toQueryString(pair);
}
}
return '';
},
getValue: function (element) {
element = $(element);
const method = element.tagName.toLowerCase();
return Form.Element.Serializers[method](element);
},
setValue: function (element, value) {
element = $(element);
const method = element.tagName.toLowerCase();
Form.Element.Serializers[method](element, value);
return element;
},
clear: function (element) {
$(element).value = '';
return element;
},
present: function (element) {
return $(element).value != '';
},
activate: function (element) {
element = $(element);
try {
element.focus();
if (
element.select &&
(element.tagName.toLowerCase() != 'input' ||
!/^(?:button|reset|submit)$/i.test(element.type))
)
{element.select();}
} catch (e) {}
return element;
},
disable: function (element) {
element = $(element);
element.disabled = true;
return element;
},
enable: function (element) {
element = $(element);
element.disabled = false;
return element;
},
};
const Field = Form.Element;
const $F = Form.Element.Methods.getValue;
Form.Element.Serializers = (function () {
function input(element, value) {
switch (element.type.toLowerCase()) {
case 'checkbox':
case 'radio':
return inputSelector(element, value);
default:
return valueSelector(element, value);
}
}
function inputSelector(element, value) {
if (Object.isUndefined(value))
{return element.checked ? element.value : null;}
else {element.checked = !!value;}
}
function valueSelector(element, value) {
if (Object.isUndefined(value)) {return element.value;}
else {element.value = value;}
}
function select(element, value) {
if (Object.isUndefined(value))
{return (element.type === 'select-one' ? selectOne : selectMany)(element);}
let opt,
currentValue,
single = !Object.isArray(value);
for (let i = 0, length = element.length; i < length; i++) {
opt = element.options[i];
currentValue = this.optionValue(opt);
if (single) {
if (currentValue == value) {
opt.selected = true;
return;
}
} else {opt.selected = value.include(currentValue);}
}
}
function selectOne(element) {
const index = element.selectedIndex;
return index >= 0 ? optionValue(element.options[index]) : null;
}
function selectMany(element) {
var values,
length = element.length;
if (!length) {return null;}
for (var i = 0, values = []; i < length; i++) {
const opt = element.options[i];
if (opt.selected) {values.push(optionValue(opt));}
}
return values;
}
function optionValue(opt) {
return Element.hasAttribute(opt, 'value') ? opt.value : opt.text;
}
return {
input: input,
inputSelector: inputSelector,
textarea: valueSelector,
select: select,
selectOne: selectOne,
selectMany: selectMany,
optionValue: optionValue,
button: valueSelector,
};
})();
Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
initialize: function ($super, element, frequency, callback) {
$super(callback, frequency);
this.element = $(element);
this.lastValue = this.getValue();
},
execute: function () {
const value = this.getValue();
if (
Object.isString(this.lastValue) && Object.isString(value)
? this.lastValue != value
: String(this.lastValue) != String(value)
) {
this.callback(this.element, value);
this.lastValue = value;
}
},
});
Form.Element.Observer = Class.create(Abstract.TimedObserver, {
getValue: function () {
return Form.Element.getValue(this.element);
},
});
Form.Observer = Class.create(Abstract.TimedObserver, {
getValue: function () {
return Form.serialize(this.element);
},
});
Abstract.EventObserver = Class.create({
initialize: function (element, callback) {
this.element = $(element);
this.callback = callback;
this.lastValue = this.getValue();
if (this.element.tagName.toLowerCase() == 'form')
{this.registerFormCallbacks();}
else {this.registerCallback(this.element);}
},
onElementEvent: function () {
const value = this.getValue();
if (this.lastValue != value) {
this.callback(this.element, value);
this.lastValue = value;
}
},
registerFormCallbacks: function () {
Form.getElements(this.element).each(this.registerCallback, this);
},
registerCallback: function (element) {
if (element.type)
{switch (element.type.toLowerCase()) {
case 'checkbox':
case 'radio':
Event.observe(element, 'click', this.onElementEvent.bind(this));
break;
default:
Event.observe(element, 'change', this.onElementEvent.bind(this));
break;
}}
},
});
Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
getValue: function () {
return Form.Element.getValue(this.element);
},
});
Form.EventObserver = Class.create(Abstract.EventObserver, {
getValue: function () {
return Form.serialize(this.element);
},
});
(function () {
const 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,
KEY_INSERT: 45,
cache: {},
};
const docEl = document.documentElement;
const MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED =
'onmouseenter' in docEl && 'onmouseleave' in docEl;
let isIELegacyEvent = function (event) {
return false;
};
if (window.attachEvent)
{if (window.addEventListener)
{isIELegacyEvent = function (event) {
return !(event instanceof window.Event);
};}
else
{isIELegacyEvent = function (event) {
return true;
};}}
let _isButton;
function _isButtonForDOMEvents(event, code) {
return event.which ? event.which === code + 1 : event.button === code;
}
const legacyButtonMap = { 0: 1, 1: 4, 2: 2 };
function _isButtonForLegacyEvents(event, code) {
return event.button === legacyButtonMap[code];
}
function _isButtonForWebKit(event, code) {
switch (code) {
case 0:
return event.which == 1 && !event.metaKey;
case 1:
return event.which == 2 || (event.which == 1 && event.metaKey);
case 2:
return event.which == 3;
default:
return false;
}
}
if (window.attachEvent)
{if (!window.addEventListener) {_isButton = _isButtonForLegacyEvents;}
else
{_isButton = function (event, code) {
return isIELegacyEvent(event)
? _isButtonForLegacyEvents(event, code)
: _isButtonForDOMEvents(event, code);
};}}
else if (Prototype.Browser.WebKit) {_isButton = _isButtonForWebKit;}
else {_isButton = _isButtonForDOMEvents;}
function isLeftClick(event) {
return _isButton(event, 0);
}
function isMiddleClick(event) {
return _isButton(event, 1);
}
function isRightClick(event) {
return _isButton(event, 2);
}
function element(event) {
event = Event.extend(event);
let node = event.target,
type = event.type,
currentTarget = event.currentTarget;
if (currentTarget && currentTarget.tagName)
{if (
type === 'load' ||
type === 'error' ||
(type === 'click' &&
currentTarget.tagName.toLowerCase() === 'input' &&
currentTarget.type === 'radio')
)
{node = currentTarget;}}
if (node.nodeType == Node.TEXT_NODE) {node = node.parentNode;}
return Element.extend(node);
}
function findElement(event, expression) {
let element = Event.element(event);
if (!expression) {return element;}
while (element) {
if (
Object.isElement(element) &&
Prototype.Selector.match(element, expression)
)
{return Element.extend(element);}
element = element.parentNode;
}
}
function pointer(event) {
return { x: pointerX(event), y: pointerY(event) };
}
function pointerX(event) {
const docElement = document.documentElement,
body = document.body || { scrollLeft: 0 };
return (
event.pageX ||
event.clientX +
(docElement.scrollLeft || body.scrollLeft) -
(docElement.clientLeft || 0)
);
}
function pointerY(event) {
const docElement = document.documentElement,
body = document.body || { scrollTop: 0 };
return (
event.pageY ||
event.clientY +
(docElement.scrollTop || body.scrollTop) -
(docElement.clientTop || 0)
);
}
function stop(event) {
Event.extend(event);
event.preventDefault();
event.stopPropagation();
event.stopped = true;
}
Event.Methods = {
isLeftClick: isLeftClick,
isMiddleClick: isMiddleClick,
isRightClick: isRightClick,
element: element,
findElement: findElement,
pointer: pointer,
pointerX: pointerX,
pointerY: pointerY,
stop: stop,
};
const methods = Object.keys(Event.Methods).inject({}, function (m, name) {
m[name] = Event.Methods[name].methodize();
return m;
});
if (window.attachEvent) {
const _relatedTarget = function (event) {
let element;
switch (event.type) {
case 'mouseover':
case 'mouseenter':
element = event.fromElement;
break;
case 'mouseout':
case 'mouseleave':
element = event.toElement;
break;
default:
return null;
}
return Element.extend(element);
};
const additionalMethods = {
stopPropagation: function () {
this.cancelBubble = true;
},
preventDefault: function () {
this.returnValue = false;
},
inspect: function () {
return '[object Event]';
},
};
Event.extend = function (event, element) {
if (!event) {return false;}
if (!isIELegacyEvent(event)) {return event;}
if (event._extendedByPrototype) {return event;}
event._extendedByPrototype = Prototype.emptyFunction;
const pointer = Event.pointer(event);
Object.extend(event, {
target: event.srcElement || element,
relatedTarget: _relatedTarget(event),
pageX: pointer.x,
pageY: pointer.y,
});
Object.extend(event, methods);
Object.extend(event, additionalMethods);
return event;
};
} else {Event.extend = Prototype.K;}
if (window.addEventListener) {
Event.prototype =
window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
Object.extend(Event.prototype, methods);
}
function _createResponder(element, eventName, handler) {
let registry = Element.retrieve(element, 'prototype_event_registry');
if (Object.isUndefined(registry)) {
CACHE.push(element);
registry = Element.retrieve(element, 'prototype_event_registry', $H());
}
let respondersForEvent = registry.get(eventName);
if (Object.isUndefined(respondersForEvent)) {
respondersForEvent = [];
registry.set(eventName, respondersForEvent);
}
if (respondersForEvent.pluck('handler').include(handler)) {return false;}
let responder;
if (eventName.include(':'))
{responder = function (event) {
if (Object.isUndefined(event.eventName)) {return false;}
if (event.eventName !== eventName) {return false;}
Event.extend(event, element);
handler.call(element, event);
};}
else if (
!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
(eventName === 'mouseenter' || eventName === 'mouseleave')
) {
if (eventName === 'mouseenter' || eventName === 'mouseleave')
{responder = function (event) {
Event.extend(event, element);
let parent = event.relatedTarget;
while (parent && parent !== element)
{try {
parent = parent.parentNode;
} catch (e) {
parent = element;
}}
if (parent === element) {return;}
handler.call(element, event);
};}
} else
{responder = function (event) {
Event.extend(event, element);
handler.call(element, event);
};}
responder.handler = handler;
respondersForEvent.push(responder);
return responder;
}
function _destroyCache() {
for (let i = 0, length = CACHE.length; i < length; i++) {
Event.stopObserving(CACHE[i]);
CACHE[i] = null;
}
}
var CACHE = [];
if (Prototype.Browser.IE) {window.attachEvent('onunload', _destroyCache);}
if (Prototype.Browser.WebKit)
{window.addEventListener('unload', Prototype.emptyFunction, false);}
let _getDOMEventName = Prototype.K,
translations = { mouseenter: 'mouseover', mouseleave: 'mouseout' };
if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED)
{_getDOMEventName = function (eventName) {
return translations[eventName] || eventName;
};}
function observe(element, eventName, handler) {
element = $(element);
const responder = _createResponder(element, eventName, handler);
if (!responder) {return element;}
if (eventName.include(':'))
{if (element.addEventListener)
{element.addEventListener('dataavailable', responder, false);}
else {
element.attachEvent('ondataavailable', responder);
element.attachEvent('onlosecapture', responder);
}}
else {
const actualEventName = _getDOMEventName(eventName);
if (element.addEventListener)
{element.addEventListener(actualEventName, responder, false);}
else {element.attachEvent('on' + actualEventName, responder);}
}
return element;
}
function stopObserving(element, eventName, handler) {
element = $(element);
const registry = Element.retrieve(element, 'prototype_event_registry');
if (!registry) {return element;}
if (!eventName) {
registry.each(function (pair) {
const eventName = pair.key;
stopObserving(element, eventName);
});
return element;
}
const responders = registry.get(eventName);
if (!responders) {return element;}
if (!handler) {
responders.each(function (r) {
stopObserving(element, eventName, r.handler);
});
return element;
}
let i = responders.length,
responder;
while (i--)
{if (responders[i].handler === handler) {
responder = responders[i];
break;
}}
if (!responder) {return element;}
if (eventName.include(':'))
{if (element.removeEventListener)
{element.removeEventListener('dataavailable', responder, false);}
else {
element.detachEvent('ondataavailable', responder);
element.detachEvent('onlosecapture', responder);
}}
else {
const actualEventName = _getDOMEventName(eventName);
if (element.removeEventListener)
{element.removeEventListener(actualEventName, responder, false);}
else {element.detachEvent('on' + actualEventName, responder);}
}
registry.set(eventName, responders.without(responder));
return element;
}
function fire(element, eventName, memo, bubble) {
element = $(element);
if (Object.isUndefined(bubble)) {bubble = true;}
if (element == document && document.createEvent && !element.dispatchEvent)
{element = document.documentElement;}
let event;
if (document.createEvent) {
event = document.createEvent('HTMLEvents');
event.initEvent('dataavailable', bubble, true);
} else {
event = document.createEventObject();
event.eventType = bubble ? 'ondataavailable' : 'onlosecapture';
}
event.eventName = eventName;
event.memo = memo || {};
if (document.createEvent) {element.dispatchEvent(event);}
else {element.fireEvent(event.eventType, event);}
return Event.extend(event);
}
Event.Handler = Class.create({
initialize: function (element, eventName, selector, callback) {
this.element = $(element);
this.eventName = eventName;
this.selector = selector;
this.callback = callback;
this.handler = this.handleEvent.bind(this);
},
start: function () {
Event.observe(this.element, this.eventName, this.handler);
return this;
},
stop: function () {
Event.stopObserving(this.element, this.eventName, this.handler);
return this;
},
handleEvent: function (event) {
const element = Event.findElement(event, this.selector);
if (element) {this.callback.call(this.element, event, element);}
},
});
function on(element, eventName, selector, callback) {
element = $(element);
if (Object.isFunction(selector) && Object.isUndefined(callback))
{(callback = selector), (selector = null);}
return new Event.Handler(element, eventName, selector, callback).start();
}
Object.extend(Event, Event.Methods);
Object.extend(Event, {
fire: fire,
observe: observe,
stopObserving: stopObserving,
on: on,
});
Element.addMethods({
fire: fire,
observe: observe,
stopObserving: stopObserving,
on: on,
});
Object.extend(document, {
fire: fire.methodize(),
observe: observe.methodize(),
stopObserving: stopObserving.methodize(),
on: on.methodize(),
loaded: false,
});
if (window.Event) {Object.extend(window.Event, Event);}
else {window.Event = Event;}
})();
(function () {
let timer;
function fireContentLoadedEvent() {
if (document.loaded) {return;}
if (timer) {window.clearTimeout(timer);}
document.loaded = true;
document.fire('dom:loaded');
}
function checkReadyState() {
if (document.readyState === 'complete') {
document.stopObserving('readystatechange', checkReadyState);
fireContentLoadedEvent();
}
}
function pollDoScroll() {
try {
document.documentElement.doScroll('left');
} catch (e) {
timer = pollDoScroll.defer();
return;
}
fireContentLoadedEvent();
}
if (document.addEventListener)
{document.addEventListener(
'DOMContentLoaded',
fireContentLoadedEvent,
false,
);}
else {
document.observe('readystatechange', checkReadyState);
if (window == top) {timer = pollDoScroll.defer();}
}
Event.observe(window, 'load', fireContentLoadedEvent);
})();
Element.addMethods();
Hash.toQueryString = Object.toQueryString;
const Toggle = { display: Element.toggle };
Element.Methods.childOf = Element.Methods.descendantOf;
const Insertion = {
Before: function (element, content) {
return Element.insert(element, { before: content });
},
Top: function (element, content) {
return Element.insert(element, { top: content });
},
Bottom: function (element, content) {
return Element.insert(element, { bottom: content });
},
After: function (element, content) {
return Element.insert(element, { after: content });
},
};
const $continue = new Error(
'"throw $continue" is deprecated, use "return" instead',
);
var Position = {
includeScrollOffsets: false,
prepare: function () {
this.deltaX =
window.pageXOffset ||
document.documentElement.scrollLeft ||
document.body.scrollLeft ||
0;
this.deltaY =
window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop ||
0;
},
within: function (element, x, y) {
if (this.includeScrollOffsets)
{return this.withinIncludingScrolloffsets(element, x, y);}
this.xcomp = x;
this.ycomp = y;
this.offset = Element.cumulativeOffset(element);
return (
y >= this.offset[1] &&
y < this.offset[1] + element.offsetHeight &&
x >= this.offset[0] &&
x < this.offset[0] + element.offsetWidth
);
},
withinIncludingScrolloffsets: function (element, x, y) {
const offsetcache = Element.cumulativeScrollOffset(element);
this.xcomp = x + offsetcache[0] - this.deltaX;
this.ycomp = y + offsetcache[1] - this.deltaY;
this.offset = Element.cumulativeOffset(element);
return (
this.ycomp >= this.offset[1] &&
this.ycomp < this.offset[1] + element.offsetHeight &&
this.xcomp >= this.offset[0] &&
this.xcomp < this.offset[0] + element.offsetWidth
);
},
overlap: function (mode, element) {
if (!mode) {return 0;}
if (mode == 'vertical')
{return (
(this.offset[1] + element.offsetHeight - this.ycomp) /
element.offsetHeight
);}
if (mode == 'horizontal')
{return (
(this.offset[0] + element.offsetWidth - this.xcomp) /
element.offsetWidth
);}
},
cumulativeOffset: Element.Methods.cumulativeOffset,
positionedOffset: Element.Methods.positionedOffset,
absolutize: function (element) {
Position.prepare();
return Element.absolutize(element);
},
relativize: function (element) {
Position.prepare();
return Element.relativize(element);
},
realOffset: Element.Methods.cumulativeScrollOffset,
offsetParent: Element.Methods.getOffsetParent,
page: Element.Methods.viewportOffset,
clone: function (source, target, options) {
options = options || {};
return Element.clonePosition(target, source, options);
},
};
if (!document.getElementsByClassName)
{document.getElementsByClassName = (function (instanceMethods) {
function iter(name) {
return name.blank()
? null
: "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
}
instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath
? function (element, className) {
className = className.toString().strip();
const cond = /\s/.test(className)
? $w(className).map(iter).join('')
: iter(className);
return cond
? document._getElementsByXPath('.//*' + cond, element)
: [];
}
: function (element, className) {
className = className.toString().strip();
const elements = [],
classNames = /\s/.test(className) ? $w(className) : null;
if (!classNames && !className) {return elements;}
const nodes = $(element).getElementsByTagName('*');
className = ' ' + className + ' ';
for (var i = 0, child, cn; (child = nodes[i]); i++)
{if (
child.className &&
(cn = ' ' + child.className + ' ') &&
(cn.include(className) ||
(classNames &&
classNames.all(function (name) {
return (
!name.toString().blank() && cn.include(' ' + name + ' ')
);
})))
)
{elements.push(Element.extend(child));}}
return elements;
};
return function (className, parentElement) {
return $(parentElement || document.body).getElementsByClassName(
className,
);
};
})(Element.Methods);}
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);
(function () {
window.Selector = Class.create({
initialize: function (expression) {
this.expression = expression.strip();
},
findElements: function (rootElement) {
return Prototype.Selector.select(this.expression, rootElement);
},
match: function (element) {
return Prototype.Selector.match(element, this.expression);
},
toString: function () {
return this.expression;
},
inspect: function () {
return '#<Selector: ' + this.expression + '>';
},
});
Object.extend(Selector, {
matchElements: function (elements, expression) {
const match = Prototype.Selector.match,
results = [];
for (let i = 0, length = elements.length; i < length; i++) {
const element = elements[i];
if (match(element, expression)) {results.push(Element.extend(element));}
}
return results;
},
findElement: function (elements, expression, index) {
index = index || 0;
let matchIndex = 0,
element;
for (let i = 0, length = elements.length; i < length; i++) {
element = elements[i];
if (
Prototype.Selector.match(element, expression) &&
index === matchIndex++
)
{return Element.extend(element);}
}
},
findChildElements: function (element, expressions) {
const selector = expressions.toArray().join(', ');
return Prototype.Selector.select(selector, element || document);
},
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment