view release on metacpan or search on metacpan
share/static/alice.js view on Meta::CPAN
})(),
SpecificElementExtensions: (function() {
if (typeof window.HTMLDivElement !== 'undefined')
return true;
var 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]*?)<\/script>',
JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
emptyFunction: function() { },
K: function(x) { return x }
};
if (Prototype.Browser.MobileSafari)
Prototype.BrowserFeatures.SpecificElementExtensions = false;
/* Based on Alex Arnell's inheritance implementation. */
var Class = (function() {
var IS_DONTENUM_BUGGY = (function(){
for (var p in { toString: 1 }) {
if (p === 'toString') return false;
}
return true;
})();
function subclass() {};
function create() {
var 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 (var 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) {
var 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 (var i = 0, length = properties.length; i < length; i++) {
var property = properties[i], value = source[property];
if (ancestor && Object.isFunction(value) &&
value.argumentNames()[0] == "$super") {
var 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() {
var _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;
}
var 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 (var 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) {
var value = holder[key],
type = typeof value;
if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
var _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 {
var 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(); }
var results = [];
for (var property in object) {
if (object.hasOwnProperty(property)) {
results.push(property);
}
}
return results;
}
function values(object) {
var results = [];
for (var 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;
}
var 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() {
var slice = Array.prototype.slice;
function update(array, args) {
var 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() {
var 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;
var __method = this, args = slice.call(arguments, 1);
return function() {
var a = merge(args, arguments);
return __method.apply(context, a);
}
}
function bindAsEventListener(context) {
var __method = this, args = slice.call(arguments, 1);
return function(event) {
var a = update([event || window.event], args);
return __method.apply(context, a);
}
}
function curry() {
if (!arguments.length) return this;
var __method = this, args = slice.call(arguments, 0);
return function() {
var a = merge(args, arguments);
return __method.apply(this, a);
}
}
function delay(timeout) {
var __method = this, args = slice.call(arguments, 1);
timeout = timeout * 1000;
return window.setTimeout(function() {
return __method.apply(__method, args);
}, timeout);
}
function defer() {
var args = update([0.01], arguments);
return this.delay.apply(this, args);
}
function wrap(wrapper) {
var __method = this;
return function() {
var a = update([__method.bind(this)], arguments);
return wrapper.apply(this, a);
}
}
function methodize() {
if (this._methodized) return this._methodized;
var __method = this;
return this._methodized = function() {
var 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) + ':' +
share/static/alice.js view on Meta::CPAN
registerCallback: function() {
this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
},
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() {
var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
typeof JSON.parse === 'function' &&
JSON.parse('{"test": true}').test;
function prepareReplacement(replacement) {
if (Object.isFunction(replacement)) return replacement;
var template = new Template(replacement);
return function(match) { return template.evaluate(match) };
}
function gsub(pattern, replacement) {
var 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() {
var 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,'&').replace(/</g,'<').replace(/>/g,'>');
}
function unescapeHTML() {
return this.stripTags().replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&');
}
function toQueryParams(separator) {
var match = this.strip().match(/([^?#]*)(#.*)?$/);
if (!match) return { };
return match[1].split(separator || '&').inject({ }, function(hash, pair) {
if ((pair = pair.split('='))[0]) {
var 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) {
var 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() {
var 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) {
var 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() {
var 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) {
var 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] + '');
var before = match[1] || '';
if (before == '\\') return match[2];
var ctx = object, expr = match[3],
pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
match = pattern.exec(expr);
if (match == null) return before;
while (match != null) {
var 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)(#\{(.*?)\})/;
var $break = { };
var Enumerable = (function() {
function each(iterator, context) {
var 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) {
var 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;
var 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;
var 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;
var results = [];
this.each(function(value, index) {
results.push(iterator.call(context, value, index));
});
return results;
}
function detect(iterator, context) {
var result;
this.each(function(value, index) {
if (iterator.call(context, value, index)) {
result = value;
throw $break;
}
});
return result;
}
function findAll(iterator, context) {
var 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;
var 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;
var 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) {
var args = $A(arguments).slice(1);
return this.map(function(value) {
return value[method].apply(value, args);
});
}
function max(iterator, context) {
iterator = iterator || Prototype.K;
var 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;
var 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;
var trues = [], falses = [];
this.each(function(value, index) {
(iterator.call(context, value, index) ?
trues : falses).push(value);
});
return [trues, falses];
}
function pluck(property) {
var results = [];
this.each(function(value) {
results.push(value[property]);
});
return results;
}
function reject(iterator, context) {
var 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) {
var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
}).pluck('value');
}
function toArray() {
return this.map();
}
function zip() {
var iterator = Prototype.K, args = $A(arguments);
if (Object.isFunction(args.last()))
iterator = args.pop();
var 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();
var 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() {
var arrayProto = Array.prototype,
slice = arrayProto.slice,
_each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
function each(iterator, context) {
for (var 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() {
var 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);
var 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;
var n = this.slice(0, i).reverse().indexOf(item);
return (n < 0) ? n : i - n - 1;
}
function concat() {
var array = slice.call(this, 0), item;
for (var i = 0, length = arguments.length; i < length; i++) {
item = arguments[i];
if (Object.isArray(item) && !('callee' in item)) {
for (var 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
});
var 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 (var key in this._object) {
var 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) {
var 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) {
var 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) {
var key = encodeURIComponent(pair.key), values = pair.value;
if (values && typeof values == 'object') {
if (Object.isArray(values)) {
var 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) {
var 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) {
var 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
};
})());
var Abstract = { };
var Try = {
these: function() {
var returnValue;
for (var i = 0, length = arguments.length; i < length; i++) {
var lambda = arguments[i];
try {
returnValue = lambda();
break;
} catch (e) { }
}
return returnValue;
}
};
var 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',
share/static/alice.js view on Meta::CPAN
var 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 {
var 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);
/* Force Firefox to handle ready state 4 for synchronous requests */
if (!this.options.asynchronous && this.transport.overrideMimeType)
this.onStateChange();
}
catch (e) {
this.dispatchException(e);
}
},
onStateChange: function() {
var readyState = this.transport.readyState;
if (readyState > 1 && !((readyState == 4) && this._complete))
this.respondToReadyState(this.transport.readyState);
},
setRequestHeaders: function() {
var headers = {
'X-Requested-With': 'XMLHttpRequest',
'X-Prototype-Version': Prototype.Version,
'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
};
if (this.method == 'post') {
headers['Content-type'] = this.options.contentType +
(this.options.encoding ? '; charset=' + this.options.encoding : '');
/* Force "Connection: close" for older Mozilla browsers to work
* around a bug where XMLHttpRequest sends an incorrect
* Content-length header. See Mozilla Bugzilla #246651.
*/
if (this.transport.overrideMimeType &&
(navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
headers['Connection'] = 'close';
}
if (typeof this.options.requestHeaders == 'object') {
var extras = this.options.requestHeaders;
if (Object.isFunction(extras.push))
for (var i = 0, length = extras.length; i < length; i += 2)
headers[extras[i]] = extras[i+1];
else
$H(extras).each(function(pair) { headers[pair.key] = pair.value });
}
for (var name in headers)
this.transport.setRequestHeader(name, headers[name]);
},
success: function() {
var 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) {
var 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);
}
var 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) {
this.dispatchException(e);
}
if (state == 'Complete') {
this.transport.onreadystatechange = Prototype.emptyFunction;
}
},
isSameOrigin: function() {
var 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 : ''
}));
share/static/alice.js view on Meta::CPAN
options = this.options;
if (!options.evalScripts) responseText = responseText.stripScripts();
if (receiver = $(receiver)) {
if (options.insertion) {
if (Object.isString(options.insertion)) {
var 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) {
var results = [];
var query = document.evaluate(expression, $(parentElement) || document,
null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0, length = query.snapshotLength; i < length; i++)
results.push(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;
}
var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
try {
var el = document.createElement('<input name="x">');
return el.tagName.toLowerCase() === 'input' && el.name === 'x';
}
catch(err) {
return false;
}
})();
var element = global.Element;
global.Element = function(tagName, attributes) {
attributes = attributes || { };
tagName = tagName.toLowerCase();
var 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));
share/static/alice.js view on Meta::CPAN
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(){
var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
var 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;
})();
var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
try {
var el = document.createElement("table");
if (el && el.tBodies) {
el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
var isBuggy = typeof el.tBodies[0] == "undefined";
el = null;
return isBuggy;
}
} catch (e) {
return true;
}
})();
var LINK_ELEMENT_INNERHTML_BUGGY = (function() {
try {
var el = document.createElement('div');
el.innerHTML = "<link>";
var isBuggy = (el.childNodes.length === 0);
el = null;
return isBuggy;
} catch(e) {
return true;
}
})();
var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY ||
TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY;
var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
var 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);
var purgeElement = Element._purgeElement;
var 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);
var 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);
}
var 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);
var range = element.ownerDocument.createRange();
range.selectNode(element);
content.evalScripts.bind(content).defer();
content = range.createContextualFragment(content.stripScripts());
}
element.parentNode.replaceChild(content, element);
return element;
share/static/alice.js view on Meta::CPAN
for (var 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);
var result = '<' + element.tagName.toLowerCase();
$H({'id': 'id', 'className': 'class'}).each(function(pair) {
var 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;
var 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) {
var 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);
var 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 {
var maximumLength = Object.isNumber(index) ? index + 1 : 1;
return element.recursivelyCollect("nextSibling", index + 1)[index];
}
},
select: function(element) {
element = $(element);
var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
return Prototype.Selector.select(expressions, element);
},
adjacent: function(element) {
element = $(element);
var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
return Prototype.Selector.select(expressions, element.parentNode).without(element);
},
identify: function(element) {
element = $(element);
var 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) {
var 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);
var attributes = { }, t = Element._attributeTranslations.write;
if (typeof name == 'object') attributes = name;
else attributes[name] = Object.isUndefined(value) ? true : value;
for (var 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;
var 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);
var node = element.firstChild;
while (node) {
var nextNode = node.nextSibling;
if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
element.removeChild(node);
node = nextNode;
}
return element;
},
empty: function(element) {
return $(element).innerHTML.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);
var pos = Element.cumulativeOffset(element);
window.scrollTo(pos[0], pos[1]);
return element;
},
share/static/alice.js view on Meta::CPAN
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) {
var nodes = element.getElementsByTagName('*'), results = [];
for (var i = 0, node; node = nodes[i]; i++)
if (node.tagName !== "!") // Filter out comment nodes.
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 < 0.00001) ? 0 : value;
return element;
};
}
else if (Prototype.Browser.WebKit) {
Element.Methods.setOpacity = function(element, value) {
element = $(element);
element.style.opacity = (value == 1 || value === '') ? '' :
(value < 0.00001) ? 0 : value;
if (value == 1)
if (element.tagName.toUpperCase() == 'IMG' && element.width) {
element.width++; element.width--;
} else try {
var 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);
var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
if (Element._insertionTranslations.tags[tagName]) {
var 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();
share/static/alice.js view on Meta::CPAN
}
return element;
}
}
return Prototype.K;
}
var Methods = { }, ByTag = Element.Methods.ByTag;
var extend = Object.extend(function(element) {
if (!element || typeof element._extendedByPrototype != 'undefined' ||
element.nodeType != 1 || element == window) return element;
var 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) {
var 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 (var property in methods) {
var value = methods[property];
if (!Object.isFunction(value)) continue;
if (!onlyIfAbsent || !(property in destination))
destination[property] = value.methodize();
}
}
function findDOMClass(tagName) {
var klass;
var 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];
var element = document.createElement(tagName),
proto = element['__proto__'] || element.constructor.prototype;
element = null;
return proto;
}
var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
Element.prototype;
if (F.ElementExtensions) {
copy(Element.Methods, elementPrototype);
copy(Element.Methods.Simulated, elementPrototype, true);
share/static/alice.js view on Meta::CPAN
return Element._returnOffset(
window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
}
};
(function(viewport) {
var 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;
var 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;
var 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;
var clone = element.cloneNode(deep);
clone._prototypeUID = void 0;
if (deep) {
var 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;
var purgeElement = Element._purgeElement;
purgeElement(element);
var descendants = element.getElementsByTagName('*'),
i = descendants.length;
while (i--) purgeElement(descendants[i]);
return null;
}
});
(function() {
function toDecimal(pctString) {
var match = pctString.match(/^(\d+)%?$/i);
if (!match) return null;
return (Number(match[1]) / 100);
}
function getPixelValue(value, property, context) {
var 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);
}
var isPercentage = value.include('%'), isViewport = (context === document.viewport);
if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) {
var 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;
var decimal = toDecimal(value);
var whole = null;
var position = element.getStyle('position');
var isHorizontal = property.include('left') || property.include('right') ||
property.include('width');
var 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();
share/static/alice.js view on Meta::CPAN
var position = element.getStyle('position'),
width = element.getStyle('width');
if (width === "0px" || width === null) {
element.style.display = 'block';
width = element.getStyle('width');
}
var context = (position === 'fixed') ? document.viewport :
element.parentNode;
element.setStyle({
position: 'absolute',
visibility: 'hidden',
display: 'block'
});
var positionedWidth = element.getStyle('width');
var newWidth;
if (width && (positionedWidth === width)) {
newWidth = getPixelValue(element, 'width', context);
} else if (position === 'absolute' || position === 'fixed') {
newWidth = getPixelValue(element, 'width', context);
} else {
var 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() {
var element = this.element;
var originalStyles = element.retrieve('prototype_original_styles');
element.store('prototype_original_styles', null);
element.setStyle(originalStyles);
this._prepared = false;
},
_compute: function(property) {
var COMPUTATIONS = Element.Layout.COMPUTATIONS;
if (!(property in COMPUTATIONS)) {
throw "Property not found.";
}
return this._set(property, COMPUTATIONS[property].call(this, this.element));
},
toObject: function() {
var args = $A(arguments);
var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
args.join(' ').split(' ');
var obj = {};
keys.each( function(key) {
if (!Element.Layout.PROPERTIES.include(key)) return;
var value = this.get(key);
if (value != null) obj[key] = value;
}, this);
return obj;
},
toHash: function() {
var obj = this.toObject.apply(this, arguments);
return new Hash(obj);
},
toCSS: function() {
var args = $A(arguments);
var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
args.join(' ').split(' ');
var css = {};
keys.each( function(key) {
if (!Element.Layout.PROPERTIES.include(key)) return;
if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return;
var 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 bord...
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();
var bHeight = this.get('border-box-height');
if (bHeight <= 0) {
if (!this._preComputing) this._end();
return 0;
}
var bTop = this.get('border-top'),
bBottom = this.get('border-bottom');
var 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();
var bWidth = this.get('border-box-width');
if (bWidth <= 0) {
if (!this._preComputing) this._end();
return 0;
}
var bLeft = this.get('border-left'),
bRight = this.get('border-right');
var pLeft = this.get('padding-left'),
pRight = this.get('padding-right');
if (!this._preComputing) this._end();
share/static/alice.js view on Meta::CPAN
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);
var rect = element.getBoundingClientRect(),
docEl = document.documentElement;
return new Element.Offset(rect.left - docEl.clientLeft,
rect.top - docEl.clientTop);
}
});
}
})();
window.$$ = function() {
var 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;
var 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 (var i = 0, length = elements.length; i < length; i++) {
Element.extend(elements[i]);
}
return elements;
}
var K = Prototype.K;
return {
select: select,
match: match,
find: find,
extendElements: (Element.extend === K) ? K : extendElements,
extendElement: Element.extend
};
})();
/*!
* Sizzle CSS Selector Engine - v1.0
* Copyright 2009, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
* More information: http://sizzlejs.com/
*/
(function(){
var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
done = 0,
toString = Object.prototype.toString,
hasDuplicate = false,
baseHasDuplicate = true;
[0, 0].sort(function(){
baseHasDuplicate = false;
return 0;
});
var Sizzle = function(selector, context, results, seed) {
results = results || [];
var origContext = context = context || document;
if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
return [];
}
if ( !selector || typeof selector !== "string" ) {
return results;
}
var 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 ( var 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 ( var i = 0, l = Expr.order.length; i < l; i++ ) {
var type = Expr.order[i], match;
if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
var 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){
var old = expr, result = [], curLoop = set, match, anyFound,
isXMLFilter = set && set[0] && isXML(set[0]);
while ( expr && set.length ) {
for ( var 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 ( var i = 0; (item = curLoop[i]) != null; i++ ) {
if ( item ) {
found = filter( item, match, i, curLoop );
var 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){
var 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){
var 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 ) {
var 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){
var 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){
var 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 ) {
var m = context.getElementById(match[1]);
return m ? [m] : [];
}
},
NAME: function(match, context, isXML){
if ( typeof context.getElementsByName !== "undefined" ) {
var ret = [], results = context.getElementsByName(match[1]);
for ( var 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" ) {
var 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){
var 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 {
var 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){
var 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" ) {
var 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){
var 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) ) {
var 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){
var 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){
var name = match[2], filter = Expr.setFilters[ name ];
if ( filter ) {
return filter( elem, i, match, array );
}
}
}
};
var origPOS = Expr.match.POS;
for ( var 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) {
var 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;
};
}
var sortOrder;
if ( document.documentElement.compareDocumentPosition ) {
sortOrder = function( a, b ) {
if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
if ( a == b ) {
hasDuplicate = true;
}
return 0;
}
var 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;
}
var 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;
}
var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
aRange.setStart(a, 0);
aRange.setEnd(a, 0);
bRange.setStart(b, 0);
bRange.setEnd(b, 0);
var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
if ( ret === 0 ) {
hasDuplicate = true;
}
return ret;
};
}
(function(){
var form = document.createElement("div"),
id = "script" + (new Date).getTime();
form.innerHTML = "<a name='" + id + "'/>";
var 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 ) {
var 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){
var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
return elem.nodeType === 1 && node && node.nodeValue === match;
};
}
root.removeChild( form );
root = form = null; // release memory in IE
})();
(function(){
var div = document.createElement("div");
div.appendChild( document.createComment("") );
if ( div.getElementsByTagName("*").length > 0 ) {
Expr.find.TAG = function(match, context){
var results = context.getElementsByTagName(match[1]);
if ( match[1] === "*" ) {
var tmp = [];
for ( var 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; // release memory in IE
})();
if ( document.querySelectorAll ) (function(){
var 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){}
}
return oldSizzle(query, context, extra, seed);
};
for ( var prop in oldSizzle ) {
Sizzle[ prop ] = oldSizzle[ prop ];
}
div = null; // release memory in IE
})();
if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
var 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; // release memory in IE
})();
function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
var sibDir = dir == "previousSibling" && !isXML;
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
var elem = checkSet[i];
if ( elem ) {
if ( sibDir && elem.nodeType === 1 ){
elem.sizcache = doneName;
elem.sizset = i;
}
elem = elem[dir];
var 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 ) {
var sibDir = dir == "previousSibling" && !isXML;
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
var elem = checkSet[i];
if ( elem ) {
if ( sibDir && elem.nodeType === 1 ) {
elem.sizcache = doneName;
elem.sizset = i;
}
elem = elem[dir];
var 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){
var 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 ( var i = 0, l = root.length; i < l; i++ ) {
Sizzle( selector, root[i], tmpSet );
}
return Sizzle.filter( later, tmpSet );
};
window.Sizzle = Sizzle;
})();
Prototype._original_property = window.Sizzle;
;(function(engine) {
var 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;
var 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) {
var elements = $(form).getElementsByTagName('*'),
element,
arr = [ ],
serializers = Form.Element.Serializers;
for (var 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);
var inputs = form.getElementsByTagName('input');
if (!typeName && !name) return $A(inputs).map(Element.extend);
for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
var input = inputs[i];
if ((typeName && input.type != typeName) || (name && input.name != name))
continue;
matchingInputs.push(Element.extend(input));
}
return matchingInputs;
},
disable: function(form) {
form = $(form);
Form.getElements(form).invoke('disable');
return form;
},
enable: function(form) {
form = $(form);
Form.getElements(form).invoke('enable');
return form;
},
findFirstElement: function(form) {
var elements = $(form).getElements().findAll(function(element) {
return 'hidden' != element.type && !element.disabled;
});
var 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);
var element = form.findFirstElement();
if (element) element.activate();
return form;
},
request: function(form, options) {
form = $(form), options = Object.clone(options || { });
var 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);
}
};
share/static/alice.js view on Meta::CPAN
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;
}
};
/*--------------------------------------------------------------------------*/
var Field = Form.Element;
var $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);
var opt, currentValue, single = !Object.isArray(value);
for (var 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) {
var 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++) {
var 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() {
var 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;
share/static/alice.js view on Meta::CPAN
function _createResponder(element, eventName, handler) {
var registry = Element.retrieve(element, 'prototype_event_registry');
if (Object.isUndefined(registry)) {
CACHE.push(element);
registry = Element.retrieve(element, 'prototype_event_registry', $H());
}
var respondersForEvent = registry.get(eventName);
if (Object.isUndefined(respondersForEvent)) {
respondersForEvent = [];
registry.set(eventName, respondersForEvent);
}
if (respondersForEvent.pluck('handler').include(handler)) return false;
var 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);
var 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 (var 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);
var _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);
var 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 {
var 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);
var registry = Element.retrieve(element, 'prototype_event_registry');
if (!registry) return element;
if (!eventName) {
registry.each( function(pair) {
var eventName = pair.key;
stopObserving(element, eventName);
});
return element;
}
var responders = registry.get(eventName);
if (!responders) return element;
if (!handler) {
responders.each(function(r) {
stopObserving(element, eventName, r.handler);
});
return element;
}
var 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 {
var 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;
var 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);
share/static/alice.js view on Meta::CPAN
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();
var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
} : function(element, className) {
className = className.toString().strip();
var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
if (!classNames && !className) return elements;
var 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) {
var match = Prototype.Selector.match,
results = [];
for (var i = 0, length = elements.length; i < length; i++) {
var element = elements[i];
if (match(element, expression)) {
results.push(Element.extend(element));
}
}
return results;
},
findElement: function(elements, expression, index) {
index = index || 0;
var matchIndex = 0, element;
for (var 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) {
var selector = expressions.toArray().join(', ');
return Prototype.Selector.select(selector, element || document);
}
});
})();
String.prototype.parseColor = function() {
var color = '#';
if (this.slice(0,4) == 'rgb(') {
var cols = this.slice(4,this.length-1).split(',');
var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
} else {
if (this.slice(0,1) == '#') {
if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
if (this.length==7) color = this.toLowerCase();
}
}
return (color.length==7 ? color : (arguments[0] || this));
};
/*--------------------------------------------------------------------------*/
Element.collectTextNodes = function(element) {
return $A($(element).childNodes).collect( function(node) {
return (node.nodeType==3 ? node.nodeValue :
(node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
}).flatten().join('');
};
Element.collectTextNodesIgnoreClass = function(element, className) {
return $A($(element).childNodes).collect( function(node) {
return (node.nodeType==3 ? node.nodeValue :
((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
Element.collectTextNodesIgnoreClass(node, className) : ''));
}).flatten().join('');
};
Element.setContentZoom = function(element, percent) {
element = $(element);
element.setStyle({fontSize: (percent/100) + 'em'});
if (Prototype.Browser.WebKit) window.scrollBy(0,0);
return element;
};
Element.getInlineOpacity = function(element){
return $(element).style.opacity || '';
};
Element.forceRerendering = function(element) {
try {
element = $(element);
var n = document.createTextNode(' ');
element.appendChild(n);
element.removeChild(n);
} catch(e) { }
};
/*--------------------------------------------------------------------------*/
var Effect = {
_elementDoesNotExistError: {
name: 'ElementDoesNotExistError',
message: 'The specified DOM element does not exist, but is required for this effect to operate'
},
Transitions: {
linear: Prototype.K,
sinoidal: function(pos) {
return (-Math.cos(pos*Math.PI)/2) + .5;
},
reverse: function(pos) {
return 1-pos;
},
flicker: function(pos) {
var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
return pos > 1 ? 1 : pos;
},
wobble: function(pos) {
return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
},
pulse: function(pos, pulses) {
return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
},
spring: function(pos) {
return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
},
none: function(pos) {
return 0;
},
full: function(pos) {
return 1;
}
},
DefaultOptions: {
duration: 1.0, // seconds
fps: 100, // 100= assume 66fps max.
sync: false, // true for combining
from: 0.0,
to: 1.0,
delay: 0.0,
queue: 'parallel'
},
tagifyText: function(element) {
var tagifyStyle = 'position:relative';
if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
element = $(element);
$A(element.childNodes).each( function(child) {
if (child.nodeType==3) {
child.nodeValue.toArray().each( function(character) {
element.insertBefore(
new Element('span', {style: tagifyStyle}).update(
character == ' ' ? String.fromCharCode(160) : character),
child);
});
Element.remove(child);
}
});
},
multiple: function(element, effect) {
var elements;
if (((typeof element == 'object') ||
Object.isFunction(element)) &&
(element.length))
elements = element;
else
elements = $(element).childNodes;
var options = Object.extend({
speed: 0.1,
delay: 0.0
}, arguments[2] || { });
var masterDelay = options.delay;
$A(elements).each( function(element, index) {
new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
});
},
PAIRS: {
'slide': ['SlideDown','SlideUp'],
'blind': ['BlindDown','BlindUp'],
'appear': ['Appear','Fade']
},
toggle: function(element, effect, options) {
element = $(element);
effect = (effect || 'appear').toLowerCase();
return Effect[ Effect.PAIRS[ effect ][ element.visible() ? 1 : 0 ] ](element, Object.extend({
queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
}, options || {}));
}
};
Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;
/* ------------- core effects ------------- */
Effect.ScopedQueue = Class.create(Enumerable, {
initialize: function() {
this.effects = [];
this.interval = null;
},
_each: function(iterator) {
this.effects._each(iterator);
},
add: function(effect) {
var timestamp = new Date().getTime();
var position = Object.isString(effect.options.queue) ?
effect.options.queue : effect.options.queue.position;
switch(position) {
case 'front':
this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
e.startOn += effect.finishOn;
e.finishOn += effect.finishOn;
});
break;
case 'with-last':
timestamp = this.effects.pluck('startOn').max() || timestamp;
break;
case 'end':
timestamp = this.effects.pluck('finishOn').max() || timestamp;
break;
}
effect.startOn += timestamp;
effect.finishOn += timestamp;
if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
this.effects.push(effect);
if (!this.interval)
this.interval = setInterval(this.loop.bind(this), 15);
},
remove: function(effect) {
this.effects = this.effects.reject(function(e) { return e==effect });
if (this.effects.length == 0) {
clearInterval(this.interval);
this.interval = null;
}
},
loop: function() {
var timePos = new Date().getTime();
for(var i=0, len=this.effects.length;i<len;i++)
this.effects[i] && this.effects[i].loop(timePos);
}
});
Effect.Queues = {
instances: $H(),
get: function(queueName) {
if (!Object.isString(queueName)) return queueName;
return this.instances.get(queueName) ||
this.instances.set(queueName, new Effect.ScopedQueue());
}
};
Effect.Queue = Effect.Queues.get('global');
Effect.Base = Class.create({
position: null,
start: function(options) {
if (options && options.transition === false) options.transition = Effect.Transitions.linear;
this.options = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
this.currentFrame = 0;
this.state = 'idle';
this.startOn = this.options.delay*1000;
this.finishOn = this.startOn+(this.options.duration*1000);
this.fromToDelta = this.options.to-this.options.from;
this.totalTime = this.finishOn-this.startOn;
this.totalFrames = this.options.fps*this.options.duration;
this.render = (function() {
function dispatch(effect, eventName) {
if (effect.options[eventName + 'Internal'])
effect.options[eventName + 'Internal'](effect);
if (effect.options[eventName])
effect.options[eventName](effect);
}
return function(pos) {
if (this.state === "idle") {
this.state = "running";
dispatch(this, 'beforeSetup');
if (this.setup) this.setup();
dispatch(this, 'afterSetup');
}
if (this.state === "running") {
pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from;
this.position = pos;
dispatch(this, 'beforeUpdate');
if (this.update) this.update(pos);
dispatch(this, 'afterUpdate');
}
};
})();
this.event('beforeStart');
if (!this.options.sync)
Effect.Queues.get(Object.isString(this.options.queue) ?
'global' : this.options.queue.scope).add(this);
},
loop: function(timePos) {
if (timePos >= this.startOn) {
if (timePos >= this.finishOn) {
this.render(1.0);
this.cancel();
this.event('beforeFinish');
if (this.finish) this.finish();
this.event('afterFinish');
return;
}
var pos = (timePos - this.startOn) / this.totalTime,
frame = (pos * this.totalFrames).round();
if (frame > this.currentFrame) {
this.render(pos);
this.currentFrame = frame;
}
}
},
cancel: function() {
if (!this.options.sync)
Effect.Queues.get(Object.isString(this.options.queue) ?
'global' : this.options.queue.scope).remove(this);
this.state = 'finished';
},
event: function(eventName) {
if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
if (this.options[eventName]) this.options[eventName](this);
},
inspect: function() {
var data = $H();
for(property in this)
if (!Object.isFunction(this[property])) data.set(property, this[property]);
return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
}
});
Effect.Parallel = Class.create(Effect.Base, {
initialize: function(effects) {
this.effects = effects || [];
this.start(arguments[1]);
},
update: function(position) {
this.effects.invoke('render', position);
},
finish: function(position) {
this.effects.each( function(effect) {
effect.render(1.0);
effect.cancel();
effect.event('beforeFinish');
if (effect.finish) effect.finish(position);
effect.event('afterFinish');
});
}
});
Effect.Tween = Class.create(Effect.Base, {
initialize: function(object, from, to) {
object = Object.isString(object) ? $(object) : object;
var args = $A(arguments), method = args.last(),
options = args.length == 5 ? args[3] : null;
this.method = Object.isFunction(method) ? method.bind(object) :
Object.isFunction(object[method]) ? object[method].bind(object) :
function(value) { object[method] = value };
this.start(Object.extend({ from: from, to: to }, options || { }));
},
update: function(position) {
this.method(position);
}
});
Effect.Event = Class.create(Effect.Base, {
initialize: function() {
this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
},
update: Prototype.emptyFunction
});
Effect.Opacity = Class.create(Effect.Base, {
initialize: function(element) {
this.element = $(element);
if (!this.element) throw(Effect._elementDoesNotExistError);
if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
this.element.setStyle({zoom: 1});
var options = Object.extend({
from: this.element.getOpacity() || 0.0,
to: 1.0
}, arguments[1] || { });
this.start(options);
},
update: function(position) {
this.element.setOpacity(position);
}
});
Effect.Move = Class.create(Effect.Base, {
initialize: function(element) {
this.element = $(element);
if (!this.element) throw(Effect._elementDoesNotExistError);
var options = Object.extend({
x: 0,
y: 0,
mode: 'relative'
}, arguments[1] || { });
this.start(options);
},
setup: function() {
this.element.makePositioned();
this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
this.originalTop = parseFloat(this.element.getStyle('top') || '0');
if (this.options.mode == 'absolute') {
this.options.x = this.options.x - this.originalLeft;
this.options.y = this.options.y - this.originalTop;
}
},
update: function(position) {
this.element.setStyle({
left: (this.options.x * position + this.originalLeft).round() + 'px',
top: (this.options.y * position + this.originalTop).round() + 'px'
});
}
share/static/alice.js view on Meta::CPAN
scaleContent: false,
scaleY: false,
afterFinishInternal: function(effect) {
effect.element.hide().undoClipping().setStyle(oldStyle);
} });
}}, arguments[1] || { }));
};
Effect.Morph = Class.create(Effect.Base, {
initialize: function(element) {
this.element = $(element);
if (!this.element) throw(Effect._elementDoesNotExistError);
var options = Object.extend({
style: { }
}, arguments[1] || { });
if (!Object.isString(options.style)) this.style = $H(options.style);
else {
if (options.style.include(':'))
this.style = options.style.parseStyle();
else {
this.element.addClassName(options.style);
this.style = $H(this.element.getStyles());
this.element.removeClassName(options.style);
var css = this.element.getStyles();
this.style = this.style.reject(function(style) {
return style.value == css[style.key];
});
options.afterFinishInternal = function(effect) {
effect.element.addClassName(effect.options.style);
effect.transforms.each(function(transform) {
effect.element.style[transform.style] = '';
});
};
}
}
this.start(options);
},
setup: function(){
function parseColor(color){
if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
color = color.parseColor();
return $R(0,2).map(function(i){
return parseInt( color.slice(i*2+1,i*2+3), 16 );
});
}
this.transforms = this.style.map(function(pair){
var property = pair[0], value = pair[1], unit = null;
if (value.parseColor('#zzzzzz') != '#zzzzzz') {
value = value.parseColor();
unit = 'color';
} else if (property == 'opacity') {
value = parseFloat(value);
if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
this.element.setStyle({zoom: 1});
} else if (Element.CSS_LENGTH.test(value)) {
var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
value = parseFloat(components[1]);
unit = (components.length == 3) ? components[2] : null;
}
var originalValue = this.element.getStyle(property);
return {
style: property.camelize(),
originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
targetValue: unit=='color' ? parseColor(value) : value,
unit: unit
};
}.bind(this)).reject(function(transform){
return (
(transform.originalValue == transform.targetValue) ||
(
transform.unit != 'color' &&
(isNaN(transform.originalValue) || isNaN(transform.targetValue))
)
);
});
},
update: function(position) {
var style = { }, transform, i = this.transforms.length;
while(i--)
style[(transform = this.transforms[i]).style] =
transform.unit=='color' ? '#'+
(Math.round(transform.originalValue[0]+
(transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
(Math.round(transform.originalValue[1]+
(transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
(Math.round(transform.originalValue[2]+
(transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
(transform.originalValue +
(transform.targetValue - transform.originalValue) * position).toFixed(3) +
(transform.unit === null ? '' : transform.unit);
this.element.setStyle(style, true);
}
});
Effect.Transform = Class.create({
initialize: function(tracks){
this.tracks = [];
this.options = arguments[1] || { };
this.addTracks(tracks);
},
addTracks: function(tracks){
tracks.each(function(track){
track = $H(track);
var data = track.values().first();
this.tracks.push($H({
ids: track.keys().first(),
effect: Effect.Morph,
options: { style: data }
}));
}.bind(this));
return this;
},
play: function(){
return new Effect.Parallel(
this.tracks.map(function(track){
var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
var elements = [$(ids) || $$(ids)].flatten();
return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
}).flatten(),
this.options
);
}
});
Element.CSS_PROPERTIES = $w(
'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
'fontSize fontWeight height left letterSpacing lineHeight ' +
'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
'right textIndent top width wordSpacing zIndex');
Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
String.__parseStyleElement = document.createElement('div');
share/static/alice.js view on Meta::CPAN
return element;
}
};
$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
'pulsate shake puff squish switchOff dropOut').each(
function(effect) {
Effect.Methods[effect] = function(element, options){
element = $(element);
Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
return element;
};
}
);
$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
function(f) { Effect.Methods[f] = Element[f]; }
);
Element.addMethods(Effect.Methods);
if(Object.isUndefined(Effect))
throw("dragdrop.js requires including script.aculo.us' effects.js library");
var Droppables = {
drops: [],
remove: function(element) {
this.drops = this.drops.reject(function(d) { return d.element==$(element) });
},
add: function(element) {
element = $(element);
var options = Object.extend({
greedy: true,
hoverclass: null,
tree: false
}, arguments[1] || { });
if(options.containment) {
options._containers = [];
var containment = options.containment;
if(Object.isArray(containment)) {
containment.each( function(c) { options._containers.push($(c)) });
} else {
options._containers.push($(containment));
}
}
if(options.accept) options.accept = [options.accept].flatten();
Element.makePositioned(element); // fix IE
options.element = element;
this.drops.push(options);
},
findDeepestChild: function(drops) {
deepest = drops[0];
for (i = 1; i < drops.length; ++i)
if (Element.isParent(drops[i].element, deepest.element))
deepest = drops[i];
return deepest;
},
isContained: function(element, drop) {
var containmentNode;
if(drop.tree) {
containmentNode = element.treeNode;
} else {
containmentNode = element.parentNode;
}
return drop._containers.detect(function(c) { return containmentNode == c });
},
isAffected: function(point, element, drop) {
return (
(drop.element!=element) &&
((!drop._containers) ||
this.isContained(element, drop)) &&
((!drop.accept) ||
(Element.classNames(element).detect(
function(v) { return drop.accept.include(v) } ) )) &&
Position.within(drop.element, point[0], point[1]) );
},
deactivate: function(drop) {
if(drop.hoverclass)
Element.removeClassName(drop.element, drop.hoverclass);
this.last_active = null;
},
activate: function(drop) {
if(drop.hoverclass)
Element.addClassName(drop.element, drop.hoverclass);
this.last_active = drop;
},
show: function(point, element) {
if(!this.drops.length) return;
var drop, affected = [];
this.drops.each( function(drop) {
if(Droppables.isAffected(point, element, drop))
affected.push(drop);
});
if(affected.length>0)
drop = Droppables.findDeepestChild(affected);
if(this.last_active && this.last_active != drop) this.deactivate(this.last_active);
if (drop) {
Position.within(drop.element, point[0], point[1]);
if(drop.onHover)
drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
if (drop != this.last_active) Droppables.activate(drop);
}
},
fire: function(event, element) {
if(!this.last_active) return;
Position.prepare();
if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
if (this.last_active.onDrop) {
this.last_active.onDrop(element, this.last_active.element, event);
return true;
}
},
reset: function() {
if(this.last_active)
this.deactivate(this.last_active);
}
};
var Draggables = {
drags: [],
observers: [],
register: function(draggable) {
if(this.drags.length == 0) {
this.eventMouseUp = this.endDrag.bindAsEventListener(this);
this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
this.eventKeypress = this.keyPress.bindAsEventListener(this);
Event.observe(document, "mouseup", this.eventMouseUp);
Event.observe(document, "mousemove", this.eventMouseMove);
Event.observe(document, "keypress", this.eventKeypress);
}
this.drags.push(draggable);
},
unregister: function(draggable) {
this.drags = this.drags.reject(function(d) { return d==draggable });
if(this.drags.length == 0) {
Event.stopObserving(document, "mouseup", this.eventMouseUp);
Event.stopObserving(document, "mousemove", this.eventMouseMove);
Event.stopObserving(document, "keypress", this.eventKeypress);
}
},
activate: function(draggable) {
if(draggable.options.delay) {
this._timeout = setTimeout(function() {
Draggables._timeout = null;
window.focus();
Draggables.activeDraggable = draggable;
}.bind(this), draggable.options.delay);
} else {
window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
this.activeDraggable = draggable;
}
},
deactivate: function() {
this.activeDraggable = null;
},
updateDrag: function(event) {
if(!this.activeDraggable) return;
var pointer = [Event.pointerX(event), Event.pointerY(event)];
if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
this._lastPointer = pointer;
this.activeDraggable.updateDrag(event, pointer);
},
endDrag: function(event) {
if(this._timeout) {
clearTimeout(this._timeout);
this._timeout = null;
}
if(!this.activeDraggable) return;
this._lastPointer = null;
this.activeDraggable.endDrag(event);
this.activeDraggable = null;
},
keyPress: function(event) {
if(this.activeDraggable)
this.activeDraggable.keyPress(event);
},
addObserver: function(observer) {
this.observers.push(observer);
this._cacheObserverCallbacks();
},
removeObserver: function(element) { // element instead of observer fixes mem leaks
this.observers = this.observers.reject( function(o) { return o.element==element });
this._cacheObserverCallbacks();
},
notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag'
if(this[eventName+'Count'] > 0)
this.observers.each( function(o) {
if(o[eventName]) o[eventName](eventName, draggable, event);
});
if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
},
_cacheObserverCallbacks: function() {
['onStart','onEnd','onDrag'].each( function(eventName) {
Draggables[eventName+'Count'] = Draggables.observers.select(
function(o) { return o[eventName]; }
).length;
});
}
};
/*--------------------------------------------------------------------------*/
var Draggable = Class.create({
initialize: function(element) {
var defaults = {
handle: false,
reverteffect: function(element, top_offset, left_offset) {
var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
queue: {scope:'_draggable', position:'end'}
});
},
endeffect: function(element) {
var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0;
new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
queue: {scope:'_draggable', position:'end'},
afterFinish: function(){
Draggable._dragging[element] = false
}
});
},
zindex: 1000,
revert: false,
quiet: false,
scroll: false,
scrollSensitivity: 20,
scrollSpeed: 15,
snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] }
delay: 0
};
if(!arguments[1] || Object.isUndefined(arguments[1].endeffect))
Object.extend(defaults, {
starteffect: function(element) {
element._opacity = Element.getOpacity(element);
Draggable._dragging[element] = true;
new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
}
});
var options = Object.extend(defaults, arguments[1] || { });
this.element = $(element);
if(options.handle && Object.isString(options.handle))
this.handle = this.element.down('.'+options.handle, 0);
if(!this.handle) this.handle = $(options.handle);
if(!this.handle) this.handle = this.element;
if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
options.scroll = $(options.scroll);
this._isScrollChild = Element.childOf(this.element, options.scroll);
}
Element.makePositioned(this.element); // fix IE
share/static/alice.js view on Meta::CPAN
}
this.sortables[element.identify()] = options;
Draggables.addObserver(new SortableObserver(element, options.onUpdate));
},
findElements: function(element, options) {
return Element.findChildren(
element, options.only, options.tree ? true : false, options.tag);
},
findTreeElements: function(element, options) {
return Element.findChildren(
element, options.only, options.tree ? true : false, options.treeTag);
},
onHover: function(element, dropon, overlap) {
if(Element.isParent(dropon, element)) return;
if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) {
return;
} else if(overlap>0.5) {
Sortable.mark(dropon, 'before');
if(dropon.previousSibling != element) {
var oldParentNode = element.parentNode;
element.style.visibility = "hidden"; // fix gecko rendering
dropon.parentNode.insertBefore(element, dropon);
if(dropon.parentNode!=oldParentNode)
Sortable.options(oldParentNode).onChange(element);
Sortable.options(dropon.parentNode).onChange(element);
}
} else {
Sortable.mark(dropon, 'after');
var nextElement = dropon.nextSibling || null;
if(nextElement != element) {
var oldParentNode = element.parentNode;
element.style.visibility = "hidden"; // fix gecko rendering
dropon.parentNode.insertBefore(element, nextElement);
if(dropon.parentNode!=oldParentNode)
Sortable.options(oldParentNode).onChange(element);
Sortable.options(dropon.parentNode).onChange(element);
}
}
},
onEmptyHover: function(element, dropon, overlap) {
var oldParentNode = element.parentNode;
var droponOptions = Sortable.options(dropon);
if(!Element.isParent(dropon, element)) {
var index;
var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
var child = null;
if(children) {
var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
for (index = 0; index < children.length; index += 1) {
if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
offset -= Element.offsetSize (children[index], droponOptions.overlap);
} else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
child = index + 1 < children.length ? children[index + 1] : null;
break;
} else {
child = children[index];
break;
}
}
}
dropon.insertBefore(element, child);
Sortable.options(oldParentNode).onChange(element);
droponOptions.onChange(element);
}
},
unmark: function() {
if(Sortable._marker) Sortable._marker.hide();
},
mark: function(dropon, position) {
var sortable = Sortable.options(dropon.parentNode);
if(sortable && !sortable.ghosting) return;
if(!Sortable._marker) {
Sortable._marker =
($('dropmarker') || Element.extend(document.createElement('DIV'))).
hide().addClassName('dropmarker').setStyle({position:'absolute'});
document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
}
var offsets = dropon.cumulativeOffset();
Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
if(position=='after')
if(sortable.overlap == 'horizontal')
Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
else
Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
Sortable._marker.show();
},
_tree: function(element, options, parent) {
var children = Sortable.findElements(element, options) || [];
for (var i = 0; i < children.length; ++i) {
var match = children[i].id.match(options.format);
if (!match) continue;
var child = {
id: encodeURIComponent(match ? match[1] : null),
element: element,
parent: parent,
children: [],
position: parent.children.length,
container: $(children[i]).down(options.treeTag)
};
/* Get the element containing the children and recurse over it */
if (child.container)
this._tree(child.container, options, child);
parent.children.push (child);
}
return parent;
},
tree: function(element) {
element = $(element);
var sortableOptions = this.options(element);
var options = Object.extend({
tag: sortableOptions.tag,
treeTag: sortableOptions.treeTag,
only: sortableOptions.only,
name: element.id,
format: sortableOptions.format
}, arguments[1] || { });
var root = {
id: null,
parent: null,
children: [],
container: element,
position: 0
};
return Sortable._tree(element, options, root);
},
/* Construct a [i] index for a particular node */
_constructIndex: function(node) {
var index = '';
do {
if (node.id) index = '[' + node.position + ']' + index;
} while ((node = node.parent) != null);
return index;
},
sequence: function(element) {
element = $(element);
var options = Object.extend(this.options(element), arguments[1] || { });
return $(this.findElements(element, options) || []).map( function(item) {
return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
});
},
setSequence: function(element, new_sequence) {
element = $(element);
var options = Object.extend(this.options(element), arguments[2] || { });
var nodeMap = { };
this.findElements(element, options).each( function(n) {
if (n.id.match(options.format))
nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
n.parentNode.removeChild(n);
});
new_sequence.each(function(ident) {
var n = nodeMap[ident];
if (n) {
n[1].appendChild(n[0]);
delete nodeMap[ident];
}
});
},
serialize: function(element) {
element = $(element);
var options = Object.extend(Sortable.options(element), arguments[1] || { });
var name = encodeURIComponent(
(arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
if (options.tree) {
return Sortable.tree(element, arguments[1]).children.map( function (item) {
return [name + Sortable._constructIndex(item) + "[id]=" +
encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
}).flatten().join('&');
} else {
return Sortable.sequence(element, arguments[1]).map( function(item) {
return name + "[]=" + encodeURIComponent(item);
}).join('&');
}
}
};
Element.isParent = function(child, element) {
if (!child.parentNode || child == element) return false;
if (child.parentNode == element) return true;
return Element.isParent(child.parentNode, element);
};
Element.findChildren = function(element, only, recursive, tagName) {
if(!element.hasChildNodes()) return null;
tagName = tagName.toUpperCase();
if(only) only = [only].flatten();
var elements = [];
$A(element.childNodes).each( function(e) {
if(e.tagName && e.tagName.toUpperCase()==tagName &&
(!only || (Element.classNames(e).detect(function(v) { return only.include(v) }))))
elements.push(e);
if(recursive) {
var grandchildren = Element.findChildren(e, only, recursive, tagName);
if(grandchildren) elements.push(grandchildren);
}
});
return (elements.length>0 ? elements.flatten() : []);
};
Element.offsetSize = function (element, type) {
return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
};
/**
* http://www.openjs.com/scripts/events/keyboard_shortcuts/
* Version : 2.01.B
* By Binny V A
* License : BSD
*/
shortcut = {
'all_shortcuts':{},//All the shortcuts are stored in this array
'add': function(shortcut_combination,callback,opt) {
var default_options = {
'type':'keydown',
'propagate':false,
'disable_in_input':false,
'target':document,
'keycode':false
}
if(!opt) opt = default_options;
else {
for(var dfo in default_options) {
if(typeof opt[dfo] == 'undefined') opt[dfo] = default_options[dfo];
}
}
var ele = opt.target;
if(typeof opt.target == 'string') ele = document.getElementById(opt.target);
var ths = this;
shortcut_combination = shortcut_combination.toLowerCase();
var func = function(e) {
e = e || window.event;
if(opt['disable_in_input']) { //Don't enable shortcut keys in Input, Textarea fields
var element;
if(e.target) element=e.target;
else if(e.srcElement) element=e.srcElement;
if(element.nodeType==3) element=element.parentNode;
if(element.tagName == 'INPUT' || element.tagName == 'TEXTAREA') return;
}
if (e.keyCode) code = e.keyCode;
else if (e.which) code = e.which;
var character = String.fromCharCode(code).toLowerCase();
if(code == 188) character=","; //If the user presses , when the type is onkeydown
if(code == 190) character="."; //If the user presses , when the type is onkeydown
var keys = shortcut_combination.split("+");
var kp = 0;
var shift_nums = {
"`":"~",
"1":"!",
"2":"@",
"3":"#",
share/static/alice.js view on Meta::CPAN
'enter':13,
'backspace':8,
'scrolllock':145,
'scroll_lock':145,
'scroll':145,
'capslock':20,
'caps_lock':20,
'caps':20,
'numlock':144,
'num_lock':144,
'num':144,
'pause':19,
'break':19,
'insert':45,
'home':36,
'delete':46,
'end':35,
'pageup':33,
'page_up':33,
'pu':33,
'pagedown':34,
'page_down':34,
'pd':34,
'left':37,
'up':38,
'right':39,
'down':40,
'f1':112,
'f2':113,
'f3':114,
'f4':115,
'f5':116,
'f6':117,
'f7':118,
'f8':119,
'f9':120,
'f10':121,
'f11':122,
'f12':123
}
var modifiers = {
shift: { wanted:false, pressed:false},
ctrl : { wanted:false, pressed:false},
alt : { wanted:false, pressed:false},
meta : { wanted:false, pressed:false} //Meta is Mac specific
};
if(e.ctrlKey) modifiers.ctrl.pressed = true;
if(e.shiftKey) modifiers.shift.pressed = true;
if(e.altKey) modifiers.alt.pressed = true;
if(e.metaKey) modifiers.meta.pressed = true;
for(var i=0; k=keys[i],i<keys.length; i++) {
if(k == 'ctrl' || k == 'control') {
kp++;
modifiers.ctrl.wanted = true;
} else if(k == 'shift') {
kp++;
modifiers.shift.wanted = true;
} else if(k == 'alt') {
kp++;
modifiers.alt.wanted = true;
} else if(k == 'meta') {
kp++;
modifiers.meta.wanted = true;
} else if(k.length > 1) { //If it is a special key
if(special_keys[k] == code) kp++;
} else if(opt['keycode']) {
if(opt['keycode'] == code) kp++;
} else { //The special keys did not match
if(character == k) kp++;
else {
if(shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase
character = shift_nums[character];
if(character == k) kp++;
}
}
}
}
if(kp == keys.length &&
modifiers.ctrl.pressed == modifiers.ctrl.wanted &&
modifiers.shift.pressed == modifiers.shift.wanted &&
modifiers.alt.pressed == modifiers.alt.wanted &&
modifiers.meta.pressed == modifiers.meta.wanted) {
callback(e);
if(!opt['propagate']) { //Stop the event
e.cancelBubble = true;
e.returnValue = false;
if (e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
return false;
}
}
}
this.all_shortcuts[shortcut_combination] = {
'callback':func,
'target':ele,
'event': opt['type']
};
if(ele.addEventListener) ele.addEventListener(opt['type'], func, false);
else if(ele.attachEvent) ele.attachEvent('on'+opt['type'], func);
else ele['on'+opt['type']] = func;
},
'remove':function(shortcut_combination) {
shortcut_combination = shortcut_combination.toLowerCase();
var binding = this.all_shortcuts[shortcut_combination];
delete(this.all_shortcuts[shortcut_combination])
if(!binding) return;
var type = binding['event'];
var ele = binding['target'];
var callback = binding['callback'];
if(ele.detachEvent) ele.detachEvent('on'+type, callback);
else if(ele.removeEventListener) ele.removeEventListener(type, callback, false);
else ele['on'+type] = false;
}
};
function str_repeat(i, m) {
for (var o = []; m > 0; o[--m] = i);
return o.join('');
}
function sprintf() {
var i = 0, a, f = arguments[i++], o = [], m, p, c, x, s = '';
while (f) {
if (m = /^[^\x25]+/.exec(f)) {
o.push(m[0]);
}
else if (m = /^\x25{2}/.exec(f)) {
o.push('%');
}
else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(f)) {
if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) {
throw('Too few arguments.');
}
if (/[^s]/.test(m[7]) && (typeof(a) != 'number')) {
throw('Expecting number but found ' + typeof(a));
}
switch (m[7]) {
case 'b': a = a.toString(2); break;
case 'c': a = String.fromCharCode(a); break;
case 'd': a = parseInt(a); break;
case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break;
case 'f': a = m[6] ? parseFloat(a).toFixed(m[6]) : parseFloat(a); break;
case 'o': a = a.toString(8); break;
case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break;
case 'u': a = Math.abs(a); break;
case 'x': a = a.toString(16); break;
case 'X': a = a.toString(16).toUpperCase(); break;
}
a = (/[def]/.test(m[7]) && m[2] && a >= 0 ? '+'+ a : a);
c = m[3] ? m[3] == '0' ? '0' : m[3].charAt(1) : ' ';
x = m[5] - String(a).length - s.length;
p = m[5] ? str_repeat(c, x) : '';
o.push(s + (m[4] ? a + p : p + a));
}
else {
throw('Huh ?!');
}
f = f.substring(m[0].length);
}
return o.join('');
}
/* WysiHat - WYSIWYG JavaScript framework, version 0.2.1
* (c) 2008-2010 Joshua Peek
*
* WysiHat is freely distributable under the terms of an MIT-style license.
*--------------------------------------------------------------------------*/
var WysiHat = {};
WysiHat.Editor = {
attach: function(textarea) {
var editArea;
textarea = $(textarea);
var id = textarea.id + '_editor';
if (editArea = $(id)) return editArea;
editArea = new Element('div', {
'id': id,
'class': 'editor',
'contentEditable': 'true'
});
editArea.update(WysiHat.Formatting.getBrowserMarkupFrom(textarea.value));
Object.extend(editArea, WysiHat.Commands);
textarea.insert({before: editArea});
textarea.hide();
return editArea;
}
};
WysiHat.BrowserFeatures = (function() {
function createTmpIframe(callback) {
var frame, frameDocument;
frame = new Element('iframe');
frame.setStyle({
position: 'absolute',
left: '-1000px'
});
frame.onFrameLoaded(function() {
if (typeof frame.contentDocument !== 'undefined') {
frameDocument = frame.contentDocument;
} else if (typeof frame.contentWindow !== 'undefined' && typeof frame.contentWindow.document !== 'undefined') {
frameDocument = frame.contentWindow.document;
}
frameDocument.designMode = 'on';
callback(frameDocument);
frame.remove();
});
share/static/alice.js view on Meta::CPAN
}
function detectIndentType(document) {
document.body.innerHTML = 'tab';
document.execCommand('indent', false, null);
var tagName;
element = document.body.childNodes[0];
if (element && element.tagName)
tagName = element.tagName.toLowerCase();
features.indentInsertsBlockquote = (tagName == 'blockquote');
}
features.run = function run() {
if (features.finished) return;
createTmpIframe(function(document) {
detectParagraphType(document);
detectIndentType(document);
features.finished = true;
});
}
return features;
})();
/* IE Selection and Range classes
*
* Original created by Tim Cameron Ryan
* http://github.com/timcameronryan/IERange
* Copyright (c) 2009 Tim Cameron Ryan
* Released under the MIT/X License
*
* Modified by Joshua Peek
*/
if (!window.getSelection) {
var DOMUtils = {
isDataNode: function(node) {
try {
return node && node.nodeValue !== null && node.data !== null;
} catch (e) {
return false;
}
},
isAncestorOf: function(parent, node) {
if (!parent) return false;
return !DOMUtils.isDataNode(parent) &&
(parent.contains(DOMUtils.isDataNode(node) ? node.parentNode : node) ||
node.parentNode == parent);
},
isAncestorOrSelf: function(root, node) {
return DOMUtils.isAncestorOf(root, node) || root == node;
},
findClosestAncestor: function(root, node) {
if (DOMUtils.isAncestorOf(root, node))
while (node && node.parentNode != root)
node = node.parentNode;
return node;
},
getNodeLength: function(node) {
return DOMUtils.isDataNode(node) ? node.length : node.childNodes.length;
},
splitDataNode: function(node, offset) {
if (!DOMUtils.isDataNode(node))
return false;
var newNode = node.cloneNode(false);
node.deleteData(offset, node.length);
newNode.deleteData(0, offset);
node.parentNode.insertBefore(newNode, node.nextSibling);
}
};
window.Range = (function() {
function Range(document) {
this._document = document;
this.startContainer = this.endContainer = document.body;
this.endOffset = DOMUtils.getNodeLength(document.body);
}
Range.START_TO_START = 0;
Range.START_TO_END = 1;
Range.END_TO_END = 2;
Range.END_TO_START = 3;
function findChildPosition(node) {
for (var i = 0; node = node.previousSibling; i++)
continue;
return i;
}
Range.prototype = {
startContainer: null,
startOffset: 0,
endContainer: null,
endOffset: 0,
commonAncestorContainer: null,
collapsed: false,
_document: null,
_toTextRange: function() {
function adoptEndPoint(textRange, domRange, bStart) {
var container = domRange[bStart ? 'startContainer' : 'endContainer'];
var offset = domRange[bStart ? 'startOffset' : 'endOffset'], textOffset = 0;
var anchorNode = DOMUtils.isDataNode(container) ? container : container.childNodes[offset];
var anchorParent = DOMUtils.isDataNode(container) ? container.parentNode : container;
if (container.nodeType == 3 || container.nodeType == 4)
textOffset = offset;
var cursorNode = domRange._document.createElement('a');
if (anchorNode)
anchorParent.insertBefore(cursorNode, anchorNode);
else
anchorParent.appendChild(cursorNode);
var cursor = domRange._document.body.createTextRange();
cursor.moveToElementText(cursorNode);
cursorNode.parentNode.removeChild(cursorNode);
textRange.setEndPoint(bStart ? 'StartToStart' : 'EndToStart', cursor);
textRange[bStart ? 'moveStart' : 'moveEnd']('character', textOffset);
}
var textRange = this._document.body.createTextRange();
adoptEndPoint(textRange, this, true);
adoptEndPoint(textRange, this, false);
return textRange;
},
share/static/alice.js view on Meta::CPAN
containerB = sourceRange.endContainer;
offsetB = sourceRange.endOffset;
break;
}
return containerA.sourceIndex < containerB.sourceIndex ? -1 :
containerA.sourceIndex == containerB.sourceIndex ?
offsetA < offsetB ? -1 : offsetA == offsetB ? 0 : 1
: 1;
},
cloneRange: function() {
var range = new Range(this._document);
range.setStart(this.startContainer, this.startOffset);
range.setEnd(this.endContainer, this.endOffset);
return range;
},
detach: function() {
},
toString: function() {
return this._toTextRange().text;
},
createContextualFragment: function(tagString) {
var content = (DOMUtils.isDataNode(this.startContainer) ? this.startContainer.parentNode : this.startContainer).cloneNode(false);
content.innerHTML = tagString;
for (var fragment = this._document.createDocumentFragment(); content.firstChild; )
fragment.appendChild(content.firstChild);
return fragment;
}
};
function RangeIterator(range) {
this.range = range;
if (range.collapsed)
return;
var root = range.commonAncestorContainer;
this._next = range.startContainer == root && !DOMUtils.isDataNode(range.startContainer) ?
range.startContainer.childNodes[range.startOffset] :
DOMUtils.findClosestAncestor(root, range.startContainer);
this._end = range.endContainer == root && !DOMUtils.isDataNode(range.endContainer) ?
range.endContainer.childNodes[range.endOffset] :
DOMUtils.findClosestAncestor(root, range.endContainer).nextSibling;
}
RangeIterator.prototype = {
range: null,
_current: null,
_next: null,
_end: null,
hasNext: function() {
return !!this._next;
},
next: function() {
var current = this._current = this._next;
this._next = this._current && this._current.nextSibling != this._end ?
this._current.nextSibling : null;
if (DOMUtils.isDataNode(this._current)) {
if (this.range.endContainer == this._current)
(current = current.cloneNode(true)).deleteData(this.range.endOffset, current.length - this.range.endOffset);
if (this.range.startContainer == this._current)
(current = current.cloneNode(true)).deleteData(0, this.range.startOffset);
}
return current;
},
remove: function() {
if (DOMUtils.isDataNode(this._current) &&
(this.range.startContainer == this._current || this.range.endContainer == this._current)) {
var start = this.range.startContainer == this._current ? this.range.startOffset : 0;
var end = this.range.endContainer == this._current ? this.range.endOffset : this._current.length;
this._current.deleteData(start, end - start);
} else
this._current.parentNode.removeChild(this._current);
},
hasPartialSubtree: function() {
return !DOMUtils.isDataNode(this._current) &&
(DOMUtils.isAncestorOrSelf(this._current, this.range.startContainer) ||
DOMUtils.isAncestorOrSelf(this._current, this.range.endContainer));
},
getSubtreeIterator: function() {
var subRange = new Range(this.range._document);
subRange.selectNodeContents(this._current);
if (DOMUtils.isAncestorOrSelf(this._current, this.range.startContainer))
subRange.setStart(this.range.startContainer, this.range.startOffset);
if (DOMUtils.isAncestorOrSelf(this._current, this.range.endContainer))
subRange.setEnd(this.range.endContainer, this.range.endOffset);
return new RangeIterator(subRange);
}
};
return Range;
})();
window.Range._fromTextRange = function(textRange, document) {
function adoptBoundary(domRange, textRange, bStart) {
var cursorNode = document.createElement('a'), cursor = textRange.duplicate();
cursor.collapse(bStart);
var parent = cursor.parentElement();
do {
parent.insertBefore(cursorNode, cursorNode.previousSibling);
cursor.moveToElementText(cursorNode);
} while (cursor.compareEndPoints(bStart ? 'StartToStart' : 'StartToEnd', textRange) > 0 && cursorNode.previousSibling);
if (cursor.compareEndPoints(bStart ? 'StartToStart' : 'StartToEnd', textRange) == -1 && cursorNode.nextSibling) {
cursor.setEndPoint(bStart ? 'EndToStart' : 'EndToEnd', textRange);
domRange[bStart ? 'setStart' : 'setEnd'](cursorNode.nextSibling, cursor.text.length);
} else {
domRange[bStart ? 'setStartBefore' : 'setEndBefore'](cursorNode);
}
cursorNode.parentNode.removeChild(cursorNode);
}
var domRange = new Range(document);
adoptBoundary(domRange, textRange, true);
adoptBoundary(domRange, textRange, false);
return domRange;
}
document.createRange = function() {
return new Range(document);
};
window.Selection = (function() {
function Selection(document) {
this._document = document;
var selection = this;
document.attachEvent('onselectionchange', function() {
selection._selectionChangeHandler();
});
}
Selection.prototype = {
rangeCount: 0,
_document: null,
_selectionChangeHandler: function() {
this.rangeCount = this._selectionExists(this._document.selection.createRange()) ? 1 : 0;
},
_selectionExists: function(textRange) {
return textRange.compareEndPoints('StartToEnd', textRange) != 0 ||
textRange.parentElement().isContentEditable;
},
addRange: function(range) {
var selection = this._document.selection.createRange(), textRange = range._toTextRange();
if (!this._selectionExists(selection)) {
textRange.select();
} else {
if (textRange.compareEndPoints('StartToStart', selection) == -1)
if (textRange.compareEndPoints('StartToEnd', selection) > -1 &&
textRange.compareEndPoints('EndToEnd', selection) == -1)
selection.setEndPoint('StartToStart', textRange);
else
if (textRange.compareEndPoints('EndToStart', selection) < 1 &&
textRange.compareEndPoints('EndToEnd', selection) > -1)
selection.setEndPoint('EndToEnd', textRange);
selection.select();
}
},
removeAllRanges: function() {
this._document.selection.empty();
},
getRangeAt: function(index) {
var textRange = this._document.selection.createRange();
if (this._selectionExists(textRange))
return Range._fromTextRange(textRange, this._document);
share/static/alice.js view on Meta::CPAN
function setBookmark() {
var bookmark = $('bookmark');
if (bookmark) bookmark.remove();
bookmark = new Element('span', { 'id': 'bookmark' }).update(" ");
var parent = new Element('div');
parent.appendChild(bookmark);
var range = this._document.selection.createRange();
range.collapse();
range.pasteHTML(parent.innerHTML);
}
function moveToBookmark() {
var bookmark = $('bookmark');
if (!bookmark) return;
var range = this._document.selection.createRange();
range.moveToElementText(bookmark);
range.collapse();
range.select();
bookmark.remove();
}
return {
setBookmark: setBookmark,
moveToBookmark: moveToBookmark
}
})());
} else {
Object.extend(Selection.prototype, (function() {
function setBookmark() {
var bookmark = $('bookmark');
if (bookmark) bookmark.remove();
bookmark = new Element('span', { 'id': 'bookmark' }).update(" ");
this.getRangeAt(0).insertNode(bookmark);
}
function moveToBookmark() {
var bookmark = $('bookmark');
if (!bookmark) return;
var range = document.createRange();
range.setStartBefore(bookmark);
this.removeAllRanges();
this.addRange(range);
bookmark.remove();
}
return {
setBookmark: setBookmark,
moveToBookmark: moveToBookmark
}
})());
}
(function() {
function cloneWithAllowedAttributes(element, allowedAttributes) {
var result = new Element(element.tagName), length = allowedAttributes.length, i;
element = $(element);
for (i = 0; i < allowedAttributes.length; i++) {
attribute = allowedAttributes[i];
if (element.hasAttribute(attribute)) {
result.writeAttribute(attribute, element.readAttribute(attribute));
}
}
return result;
}
function withEachChildNodeOf(element, callback) {
var nodes = $A(element.childNodes), length = nodes.length, i;
for (i = 0; i < length; i++) callback(nodes[i]);
}
function sanitizeNode(node, tagsToRemove, tagsToAllow, tagsToSkip) {
var parentNode = node.parentNode;
switch (node.nodeType) {
case Node.ELEMENT_NODE:
var tagName = node.tagName.toLowerCase();
if (tagsToSkip) {
var newNode = node.cloneNode(false);
withEachChildNodeOf(node, function(childNode) {
newNode.appendChild(childNode);
sanitizeNode(childNode, tagsToRemove, tagsToAllow, tagsToSkip);
});
parentNode.insertBefore(newNode, node);
} else if (tagName in tagsToAllow) {
var newNode = cloneWithAllowedAttributes(node, tagsToAllow[tagName]);
withEachChildNodeOf(node, function(childNode) {
newNode.appendChild(childNode);
sanitizeNode(childNode, tagsToRemove, tagsToAllow, tagsToSkip);
});
parentNode.insertBefore(newNode, node);
} else if (!(tagName in tagsToRemove)) {
withEachChildNodeOf(node, function(childNode) {
parentNode.insertBefore(childNode, node);
sanitizeNode(childNode, tagsToRemove, tagsToAllow, tagsToSkip);
});
}
case Node.COMMENT_NODE:
parentNode.removeChild(node);
}
}
Element.addMethods({
sanitizeContents: function(element, options) {
element = $(element);
var tagsToRemove = {};
(options.remove || "").split(",").each(function(tagName) {
tagsToRemove[tagName.strip()] = true;
});
var tagsToAllow = {};
(options.allow || "").split(",").each(function(selector) {
var parts = selector.strip().split(/[\[\]]/);
var tagName = parts[0], allowedAttributes = parts.slice(1).grep(/./);
tagsToAllow[tagName] = allowedAttributes;
});
var tagsToSkip = options.skip;
withEachChildNodeOf(element, function(childNode) {
sanitizeNode(childNode, tagsToRemove, tagsToAllow, tagsToSkip);
});
return element;
share/static/alice.js view on Meta::CPAN
while (element.nodeType == Node.TEXT_NODE)
element = element.parentNode;
$(element).fire("selection:change");
}
};
document.on("mouseup", selectionChangeHandler);
document.on("keyup", selectionChangeHandler);
}
});
WysiHat.Formatting = (function() {
var ACCUMULATING_LINE = {};
var EXPECTING_LIST_ITEM = {};
var ACCUMULATING_LIST_ITEM = {};
return {
getBrowserMarkupFrom: function(applicationMarkup) {
var container = new Element("div").update(applicationMarkup);
function spanify(element, style) {
element.replace(
'<span style="' + style +
'" class="Apple-style-span">' +
element.innerHTML + '</span>'
);
}
function convertStrongsToSpans() {
container.select("strong").each(function(element) {
spanify(element, "font-weight: bold");
});
}
function convertEmsToSpans() {
container.select("em").each(function(element) {
spanify(element, "font-style: italic");
});
}
function convertDivsToParagraphs() {
container.select("div").each(function(element) {
element.replace("<p>" + element.innerHTML + "</p>");
});
}
if (Prototype.Browser.WebKit || Prototype.Browser.Gecko) {
convertStrongsToSpans();
convertEmsToSpans();
} else if (Prototype.Browser.IE || Prototype.Browser.Opera) {
convertDivsToParagraphs();
}
return container.innerHTML;
},
getApplicationMarkupFrom: function(element) {
var mode = ACCUMULATING_LINE, result, container, line, lineContainer, previousAccumulation;
function walk(nodes) {
var length = nodes.length, node, tagName, i;
for (i = 0; i < length; i++) {
node = nodes[i];
if (node.nodeType == Node.ELEMENT_NODE) {
tagName = node.tagName.toLowerCase();
open(tagName, node);
walk(node.childNodes);
close(tagName);
} else if (node.nodeType == Node.TEXT_NODE) {
read(node.nodeValue);
}
}
}
function open(tagName, node) {
if (mode == ACCUMULATING_LINE) {
if (isBlockElement(tagName)) {
if (isEmptyParagraph(node)) {
accumulate(new Element("br"));
}
flush();
if (isListElement(tagName)) {
container = insertList(tagName);
mode = EXPECTING_LIST_ITEM;
}
} else if (isLineBreak(tagName)) {
if (isLineBreak(getPreviouslyAccumulatedTagName())) {
previousAccumulation.parentNode.removeChild(previousAccumulation);
flush();
}
accumulate(node.cloneNode(false));
if (!previousAccumulation.previousNode) flush();
} else {
accumulateInlineElement(tagName, node);
}
} else if (mode == EXPECTING_LIST_ITEM) {
if (isListItemElement(tagName)) {
mode = ACCUMULATING_LIST_ITEM;
}
} else if (mode == ACCUMULATING_LIST_ITEM) {
if (isLineBreak(tagName)) {
accumulate(node.cloneNode(false));
} else if (!isBlockElement(tagName)) {
accumulateInlineElement(tagName, node);
}
}
}
function close(tagName) {
if (mode == ACCUMULATING_LINE) {
if (isLineElement(tagName)) {
flush();
}
if (line != lineContainer) {
lineContainer = lineContainer.parentNode;
}
} else if (mode == EXPECTING_LIST_ITEM) {
if (isListElement(tagName)) {
container = result;
mode = ACCUMULATING_LINE;
}
} else if (mode == ACCUMULATING_LIST_ITEM) {
if (isListItemElement(tagName)) {
flush();
mode = EXPECTING_LIST_ITEM;
}
if (line != lineContainer) {
lineContainer = lineContainer.parentNode;
}
}
}
function isBlockElement(tagName) {
return isLineElement(tagName) || isListElement(tagName);
}
function isLineElement(tagName) {
return tagName == "p" || tagName == "div";
}
function isListElement(tagName) {
return tagName == "ol" || tagName == "ul";
}
function isListItemElement(tagName) {
return tagName == "li";
}
function isLineBreak(tagName) {
return tagName == "br";
}
function isEmptyParagraph(node) {
return node.tagName.toLowerCase() == "p" && node.childNodes.length == 0;
}
function read(value) {
accumulate(document.createTextNode(value));
}
function accumulateInlineElement(tagName, node) {
var element = node.cloneNode(false);
if (tagName == "span") {
if ($(node).getStyle("fontWeight") == "bold") {
element = new Element("strong");
} else if ($(node).getStyle("fontStyle") == "italic") {
element = new Element("em");
}
}
accumulate(element);
lineContainer = element;
}
function accumulate(node) {
if (mode != EXPECTING_LIST_ITEM) {
if (!line) line = lineContainer = createLine();
previousAccumulation = node;
lineContainer.appendChild(node);
}
}
function getPreviouslyAccumulatedTagName() {
if (previousAccumulation && previousAccumulation.nodeType == Node.ELEMENT_NODE) {
return previousAccumulation.tagName.toLowerCase();
}
}
function flush() {
if (line && line.childNodes.length) {
container.appendChild(line);
line = lineContainer = null;
}
}
function createLine() {
if (mode == ACCUMULATING_LINE) {
return new Element("div");
} else if (mode == ACCUMULATING_LIST_ITEM) {
return new Element("li");
}
}
function insertList(tagName) {
var list = new Element(tagName);
result.appendChild(list);
return list;
}
result = container = new Element("div");
walk(element.childNodes);
flush();
return result.innerHTML;
}
};
})();
WysiHat.Toolbar = Class.create((function() {
function initialize(editor) {
this.editor = editor;
this.element = this.createToolbarElement();
}
function createToolbarElement() {
var toolbar = new Element('div', { 'class': 'editor_toolbar' });
this.editor.insert({before: toolbar});
return toolbar;
}
function addButtonSet(set) {
$A(set).each(function(button){
this.addButton(button);
}.bind(this));
}
function addButton(options, handler) {
options = $H(options);
if (!options.get('name'))
options.set('name', options.get('label').toLowerCase());
var name = options.get('name');
var button = this.createButtonElement(this.element, options);
var handler = this.buttonHandler(name, options);
this.observeButtonClick(button, handler);
var handler = this.buttonStateHandler(name, options);
this.observeStateChanges(button, name, handler);
}
share/static/alice.js view on Meta::CPAN
}
function observeButtonClick(element, handler) {
element.on('click', function(event) {
handler(this.editor);
event.stop();
}.bind(this));
}
function buttonStateHandler(name, options) {
if (options.query)
return options.query;
else if (options.get('query'))
return options.get('query');
else
return function(editor) { return editor.queryCommandState(name); };
}
function observeStateChanges(element, name, handler) {
var previousState;
this.editor.on("selection:change", function(event) {
var state = handler(this.editor);
if (state != previousState) {
previousState = state;
this.updateButtonState(element, name, state);
}
}.bind(this));
}
function updateButtonState(element, name, state) {
if (state)
element.addClassName('selected');
else
element.removeClassName('selected');
}
return {
initialize: initialize,
createToolbarElement: createToolbarElement,
addButtonSet: addButtonSet,
addButton: addButton,
createButtonElement: createButtonElement,
buttonHandler: buttonHandler,
observeButtonClick: observeButtonClick,
buttonStateHandler: buttonStateHandler,
observeStateChanges: observeStateChanges,
updateButtonState: updateButtonState
};
})());
WysiHat.Toolbar.ButtonSets = {};
WysiHat.Toolbar.ButtonSets.Basic = $A([
{ label: "Bold" },
{ label: "Underline" },
{ label: "Italic" }
]);
/* SWFObject v2.2 <http://code.google.com/p/swfobject/>
is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
*/
var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,...
(function() {
if (window.WebSocket && !window.WEB_SOCKET_FORCE_FLASH) return;
var logger;
if (window.WEB_SOCKET_LOGGER) {
logger = WEB_SOCKET_LOGGER;
} else if (window.console && window.console.log && window.console.error) {
logger = window.console;
} else {
logger = {log: function(){ }, error: function(){ }};
}
if (swfobject.getFlashPlayerVersion().major < 10) {
logger.error("Flash Player >= 10.0.0 is required.");
return;
}
if (location.protocol == "file:") {
logger.error(
"WARNING: web-socket-js doesn't work in file:///... URL " +
"unless you set Flash Security Settings properly. " +
"Open the page via Web server i.e. http://...");
}
/**
* This class represents a faux web socket.
* @param {string} url
* @param {array or string} protocols
* @param {string} proxyHost
* @param {int} proxyPort
* @param {string} headers
*/
WebSocket = function(url, protocols, proxyHost, proxyPort, headers) {
var self = this;
self.__id = WebSocket.__nextId++;
WebSocket.__instances[self.__id] = self;
self.readyState = WebSocket.CONNECTING;
self.bufferedAmount = 0;
self.__events = {};
if (!protocols) {
protocols = [];
} else if (typeof protocols == "string") {
protocols = [protocols];
}
self.__createTask = setTimeout(function() {
WebSocket.__addTask(function() {
self.__createTask = null;
WebSocket.__flash.create(
self.__id, url, protocols, proxyHost || null, proxyPort || 0, headers || null);
});
}, 0);
};
/**
* Send data to the web socket.
* @param {string} data The data to send to the socket.
* @return {boolean} True for success, false for failure.
*/
WebSocket.prototype.send = function(data) {
if (this.readyState == WebSocket.CONNECTING) {
throw "INVALID_STATE_ERR: Web Socket connection has not been established";
}
var result = WebSocket.__flash.send(this.__id, encodeURIComponent(data));
if (result < 0) { // success
return true;
} else {
this.bufferedAmount += result;
return false;
}
};
/**
* Close this web socket gracefully.
*/
WebSocket.prototype.close = function() {
if (this.__createTask) {
clearTimeout(this.__createTask);
this.__createTask = null;
this.readyState = WebSocket.CLOSED;
return;
}
if (this.readyState == WebSocket.CLOSED || this.readyState == WebSocket.CLOSING) {
return;
}
this.readyState = WebSocket.CLOSING;
WebSocket.__flash.close(this.__id);
};
/**
* Implementation of {@link <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration">DOM 2 EventTarget Interface</a>}
*
* @param {string} type
* @param {function} listener
* @param {boolean} useCapture
* @return void
*/
WebSocket.prototype.addEventListener = function(type, listener, useCapture) {
if (!(type in this.__events)) {
this.__events[type] = [];
}
this.__events[type].push(listener);
};
/**
* Implementation of {@link <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration">DOM 2 EventTarget Interface</a>}
*
* @param {string} type
* @param {function} listener
* @param {boolean} useCapture
* @return void
*/
WebSocket.prototype.removeEventListener = function(type, listener, useCapture) {
if (!(type in this.__events)) return;
var events = this.__events[type];
for (var i = events.length - 1; i >= 0; --i) {
if (events[i] === listener) {
events.splice(i, 1);
break;
}
}
};
/**
* Implementation of {@link <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration">DOM 2 EventTarget Interface</a>}
*
* @param {Event} event
* @return void
*/
WebSocket.prototype.dispatchEvent = function(event) {
var events = this.__events[event.type] || [];
for (var i = 0; i < events.length; ++i) {
events[i](event);
}
var handler = this["on" + event.type];
if (handler) handler.apply(this, [event]);
};
/**
* Handles an event from Flash.
* @param {Object} flashEvent
*/
WebSocket.prototype.__handleEvent = function(flashEvent) {
if ("readyState" in flashEvent) {
this.readyState = flashEvent.readyState;
}
if ("protocol" in flashEvent) {
this.protocol = flashEvent.protocol;
}
var jsEvent;
if (flashEvent.type == "open" || flashEvent.type == "error") {
jsEvent = this.__createSimpleEvent(flashEvent.type);
} else if (flashEvent.type == "close") {
jsEvent = this.__createSimpleEvent("close");
jsEvent.wasClean = flashEvent.wasClean ? true : false;
jsEvent.code = flashEvent.code;
jsEvent.reason = flashEvent.reason;
} else if (flashEvent.type == "message") {
var data = decodeURIComponent(flashEvent.message);
jsEvent = this.__createMessageEvent("message", data);
} else {
throw "unknown event type: " + flashEvent.type;
}
this.dispatchEvent(jsEvent);
};
WebSocket.prototype.__createSimpleEvent = function(type) {
if (document.createEvent && window.Event) {
var event = document.createEvent("Event");
event.initEvent(type, false, false);
return event;
} else {
return {type: type, bubbles: false, cancelable: false};
}
};
WebSocket.prototype.__createMessageEvent = function(type, data) {
if (document.createEvent && window.MessageEvent && !window.opera) {
var event = document.createEvent("MessageEvent");
event.initMessageEvent("message", false, false, data, null, null, window, null);
return event;
} else {
return {type: type, data: data, bubbles: false, cancelable: false};
}
};
/**
* Define the WebSocket readyState enumeration.
share/static/alice.js view on Meta::CPAN
if (WebSocket.__swfLocation) {
window.WEB_SOCKET_SWF_LOCATION = WebSocket.__swfLocation;
}
if (!window.WEB_SOCKET_SWF_LOCATION) {
logger.error("[WebSocket] set WEB_SOCKET_SWF_LOCATION to location of WebSocketMain.swf");
return;
}
if (!window.WEB_SOCKET_SUPPRESS_CROSS_DOMAIN_SWF_ERROR &&
!WEB_SOCKET_SWF_LOCATION.match(/(^|\/)WebSocketMainInsecure\.swf(\?.*)?$/) &&
WEB_SOCKET_SWF_LOCATION.match(/^\w+:\/\/([^\/]+)/)) {
var swfHost = RegExp.$1;
if (location.host != swfHost) {
logger.error(
"[WebSocket] You must host HTML and WebSocketMain.swf in the same host " +
"('" + location.host + "' != '" + swfHost + "'). " +
"See also 'How to host HTML file and SWF file in different domains' section " +
"in README.md. If you use WebSocketMainInsecure.swf, you can suppress this message " +
"by WEB_SOCKET_SUPPRESS_CROSS_DOMAIN_SWF_ERROR = true;");
}
}
var container = document.createElement("div");
container.id = "webSocketContainer";
container.style.position = "absolute";
if (WebSocket.__isFlashLite()) {
container.style.left = "0px";
container.style.top = "0px";
} else {
container.style.left = "-100px";
container.style.top = "-100px";
}
var holder = document.createElement("div");
holder.id = "webSocketFlash";
container.appendChild(holder);
document.body.appendChild(container);
swfobject.embedSWF(
WEB_SOCKET_SWF_LOCATION,
"webSocketFlash",
"1" /* width */,
"1" /* height */,
"10.0.0" /* SWF version */,
null,
null,
{hasPriority: true, swliveconnect : true, allowScriptAccess: "always"},
null,
function(e) {
if (!e.success) {
logger.error("[WebSocket] swfobject.embedSWF failed");
}
});
};
/**
* Called by Flash to notify JS that it's fully loaded and ready
* for communication.
*/
WebSocket.__onFlashInitialized = function() {
setTimeout(function() {
WebSocket.__flash = document.getElementById("webSocketFlash");
WebSocket.__flash.setCallerUrl(location.href);
WebSocket.__flash.setDebug(!!window.WEB_SOCKET_DEBUG);
for (var i = 0; i < WebSocket.__tasks.length; ++i) {
WebSocket.__tasks[i]();
}
WebSocket.__tasks = [];
}, 0);
};
/**
* Called by Flash to notify WebSockets events are fired.
*/
WebSocket.__onFlashEvent = function() {
setTimeout(function() {
try {
var events = WebSocket.__flash.receiveEvents();
for (var i = 0; i < events.length; ++i) {
WebSocket.__instances[events[i].webSocketId].__handleEvent(events[i]);
}
} catch (e) {
logger.error(e);
}
}, 0);
return true;
};
WebSocket.__log = function(message) {
logger.log(decodeURIComponent(message));
};
WebSocket.__error = function(message) {
logger.error(decodeURIComponent(message));
};
WebSocket.__addTask = function(task) {
if (WebSocket.__flash) {
task();
} else {
WebSocket.__tasks.push(task);
}
};
/**
* Test if the browser is running flash lite.
* @return {boolean} True if flash lite is running, false otherwise.
*/
WebSocket.__isFlashLite = function() {
if (!window.navigator || !window.navigator.mimeTypes) {
return false;
}
var mimeType = window.navigator.mimeTypes["application/x-shockwave-flash"];
if (!mimeType || !mimeType.enabledPlugin || !mimeType.enabledPlugin.filename) {
return false;
}
return mimeType.enabledPlugin.filename.match(/flashlite/i) ? true : false;
};
if (!window.WEB_SOCKET_DISABLE_AUTO_INITIALIZATION) {
if (window.addEventListener) {
window.addEventListener("load", function(){
WebSocket.__initialize();
}, false);
} else {
window.attachEvent("onload", function(){
WebSocket.__initialize();
});
}
}
})();
var Alice = { };
Object.extend(Alice, {
RE: {
img: /^http[^\s]*\.(?:jpe?g|gif|png|bmp|svg)[^\/]*$/i,
audio: /^http[^\s]*\.(?:wav|mp3|ogg|aiff?|m4[ar])[^\/]*$/i,
url: /(https?:\/\/[^\s<"]*)/ig
},
cleanupCopy: function(node) {
if (!node.select("li.message").length) return;
var lines = [];
node.select("li.message").each(function(line) {
var left = line.down("div.left span.nick");
var message = line.down("div.msg");
var clean = [];
if (left) {
var nick = left.innerHTML.stripTags();
nick = nick.replace(/^\s+/, "");
nick = nick.replace(/\s+$/, "");
clean.push("<"+nick+">");
}
if (message) {
var body = message.innerHTML.stripTags();
body = body.replace(/^\s+/, "");
body = body.replace(/\s+$/, "");
clean.push(body);
}
if (clean.length) lines.push(
clean.join(" ").replace(/\n/g, "").escapeHTML());
});
node.update(lines.join("<br>"));
node.cleanWhitespace();
},
epochToLocal: function(epoch, format) {
var date = new Date(parseInt(epoch) * 1000);
if (!date) return epoch;
var hours = date.getHours();
if (format == "12") {
var ap;
if (hours >= 12) {
if (hours > 12) hours -= 12;
ap = "p";
} else {
ap = "a"
}
return sprintf("%d:%02d%s", hours, date.getMinutes(), ap);
}
return sprintf("%02d:%02d", hours, date.getMinutes());
},
makeLinksClickable: function(elem) {
var children = elem.childNodes;
var length = children.length;
for (var i=0; i < length; i++) {
var node = children[i];
if (node.nodeName != "#text") {
Alice.makeLinksClickable(node);
}
else if (node.nodeValue.match(Alice.RE.url)) {
var span = new Element("SPAN");
span.innerHTML = node.nodeValue.escapeHTML().replace(
Alice.RE.url, '<a href="$1" target="_blank" rel="noreferrer">$1</a>');
node.parentNode.replaceChild(span, node);
}
}
},
growlNotify: function(message) {
if (window.fluid) {
window.fluid.showGrowlNotification({
title: message.subject,
description: message.body,
priority: 1,
sticky: false,
identifier: message.msgid
});
}
else if (window.webkitNotifications) {
if (window.webkitNotifications.checkPermission() == 0) {
var popup = window.webkitNotifications.createNotification(
"http://static.usealice.org/image/alice.png",
message.subject,
message.body
);
popup.ondisplay = function() {
setTimeout(function () {popup.cancel();}, 5000);
};
popup.show();
}
}
},
isSpecialKey: function(keyCode) {
var special_keys = [
16,27,9,32,13,8,145,20,144,19,45,36,46,35,33,34,37,38,39,
40,17,18,91,112,113,114,115,116,117,118,119,120,121,122,123,
224
];
return special_keys.indexOf(keyCode) > -1;
},
playAudio: function(image, audio) {
image.src = '/static/image/pause.png';
if (! audio) {
var url = image.nextSibling.href;
audio = new Audio(url);
audio.addEventListener('ended', function () {
image.src = '/static/image/play.png';
image.onclick = function () { Alice.playAudio(image, audio) };
});
}
audio.play();
image.onclick = function() {
audio.pause();
this.src = '/static/image/play.png';
this.onclick = function () { Alice.playAudio(this, audio) };
};
},
joinChannel: function() {
var network = $('join_network').value;
var channel = $('join_channel').value;
if (!network || !channel) {
alert("Must select a channel and network!");
return;
}
var win = alice.activeWindow();
alice.connection.sendMessage({
source: win.id,
msg: "/join -"+network+" "+channel
});
alice.input.disabled = false;
$('join').remove();
},
tabsets: {
addSet: function () {
var name = prompt("Please enter a name for this tab set.");
if (name && !Alice.tabsets.hasTabset(name)) {
Alice.tabsets.clearActive();
$('sets').insert('<li class="active">'+name.escapeHTML()+'</li>');
var list = $('empty_tabset').clone(true).addClassName('active').show();
list.id = null;
$('tabset_data').insert(list);
}
else {
alert("Invalid tab set name.");
}
},
hasTabset: function (name) {
var sets = $$('#sets li');
for (var i=0; i < sets.length; i++) {
if (sets[i].innerHTML == name) {
return true;
}
}
return false;
},
submit: function (params) {
new Ajax.Request("/savetabsets", {
method: "post",
parameters: Object.toQueryString(params),
onSuccess: function(transport){
$('tabset_menu').replace(transport.responseText);
Alice.tabsets.remove()
}
});
return false;
},
params: function () {
var values = Alice.tabsets.values();
return Alice.tabsets.sets().inject({}, function(acc, set, index) {
acc[set] = values[index];
return acc;
});
},
sets: function () {
if (!$('sets')) return [];
return $('sets').select('li').map(function(li) {return li.innerHTML.unescapeHTML()});
},
values: function () {
if (!$('tabset_data')) return [];
return $$('#tabset_data ul').map(function(ul) {
var windows = ul.select('input').filter(function(input) {
return input.checked;
}).map(function(input){return input.name});
return windows.length ? windows : 'empty';
});
},
remove: function () {
alice.input.disabled = false;
$('tabsets').remove();
},
clearActive: function () {
$('tabset_data').select('.active').invoke('removeClassName', 'active');
$('sets').select('.active').invoke('removeClassName', 'active');
},
removeSet: function () {
$('tabsets').down('.active').remove();
$('tabset_data').down('.active').remove();
},
focusIndex: function (i) {
Alice.tabsets.clearActive();
$('tabset_data').select('ul')[i].addClassName('active');
$('sets').select('li')[i].addClassName('active');
},
focusSet: function (e) {
var li = e.findElement('li');
if (li) {
Alice.tabsets.focusIndex(li.previousSiblings().length);
}
},
},
prefs: {
addHighlight: function (alias) {
var channel = prompt("Enter a word to highlight.");
if (channel)
$('highlights').insert("<option value=\""+channel+"\">"+channel+"</option>");
return false;
},
removeHighlights: function (alias) {
$A($('highlights').options).each(function (option) {
if (option.selected) option.remove()});
return false;
},
addNick: function (nick) {
var nick = prompt("Enter a nick.");
if (nick)
$('monospace_nicks').insert("<option value=\""+nick+"\">"+nick+"</option>");
return false;
},
removeNicks: function (nick) {
$A($('monospace_nicks').options).each(function (option) {
if (option.selected) option.remove()});
return false;
},
remove: function() {
alice.input.disabled = false;
$('prefs').remove();
},
submit: function(form) {
var options = {highlights: [], monospace_nicks: []};
["images", "animate", "avatars", "alerts", "audio"].each(function (pref) {
options[pref] = $(pref).checked ? "show" : "hide";
});
$A($("highlights").options).each(function(option) {
options.highlights.push(option.value);
});
$A($("monospace_nicks").options).each(function(option) {
options.monospace_nicks.push(option.value);
});
["style", "timeformat", "quitmsg"].each(function(pref) {
options[pref] = $(pref).value;
});
Alice.prefs.remove();
new Ajax.Request('/save', {
method: 'get',
parameters: options,
onSuccess: function(){
share/static/alice.js view on Meta::CPAN
setTimeout(this.fetchOembeds.bind(this), 1000 * 60 * 5);
if (cb) cb();
}
}.bind(this);
req.send();
},
embed: function(a, win) {
var params = {
url: a.href,
maxheight: 300,
};
var req = new XMLHttpRequest();
req.open("GET", "https://www.noembed.com/embed?" + Object.toQueryString(params));
req.onreadystatechange = function(){
if (req.readyState == 4) {
var data = req.responseText.evalJSON();
this.embedContent(a, win, data);
}
}.bind(this);
req.send();
},
embedContent: function(a, win, data) {
if (!data || !data.html) return;
var html = data.html;
var elem = new Element("DIV", {"class": "oembed"});
if (data.provider_name == "Twitter") {
var position = win.captureScrollPosition();
elem.setStyle({display: "block"});
elem.update(html);
a.replace(elem);
win.scrollToPosition(position);
Alice.makeLinksClickable(elem);
return;
}
var position = win.captureScrollPosition();
a.update(data.title);
a.insert({
after: '<sup class="external"><a target="_blank" href="'+data.url+'">'
+data.provider_name+'</a></sup>'
});
a.up("div.msg").insert(elem);
win.scrollToPosition(position);
a.observe('click', function(e) {
e.stop();
var position = win.captureScrollPosition();
if (elem.innerHTML) {
elem.innerHTML = "";
elem.style.display = "none";
return;
}
elem.style.display = "block";
elem.innerHTML = html;
Alice.makeLinksClickable(elem);
var images = elem.select("img");
if (images.length) {
images.each(function(img) {
img.observe("load", function(e) {
win.scrollToPosition(position);
img.stopObserving(img, "load");
});
});
}
win.scrollToPosition(position);
});
},
actionHandlers: {
join: function (action) {
var win = this.getWindow(action['window'].id);
if (!win) {
this.insertWindow(action['window'].id, action.html);
win = this.openWindow(action['window']);
this.updateOverflowMenus();
if (this.selectedSet && !this.currentSetContains(win)) {
if (confirm("You joined "+win.title+" which is not in the '"+this.selectedSet+"' set. Do you want to add it?")) {
this.tabsets[this.selectedSet].push(win.id);
win.show();
Alice.tabsets.submit(this.tabsets);
}
else {
win.hide();
}
}
}
else {
win.enable();
}
},
part: function (action) {
this.closeWindow(action['window'].id);
},
trim: function (action) {
var win = this.getWindow(action['window'].id);
if (win) {
win.messageLimit = action['lines'];
win.trimMessages();
}
},
nicks: function (action) {
var win = this.getWindow(action['window'].id);
if (win) win.updateNicks(action.nicks);
},
alert: function (action) {
this.activeWindow().showAlert(action['body']);
},
clear: function (action) {
var win = this.getWindow(action['window'].id);
if (win) win.clearMessages();
},
announce: function (action) {
this.activeWindow().announce(action['body']);
},
connect: function (action) {
if ($('servers')) {
Alice.connections.connectServer(action.network);
share/static/alice.js view on Meta::CPAN
$('windows').insert(transport.responseText);
Alice.tabsets.focusIndex(0);
}.bind(this));
},
windows: function () {
return this.window_map.values();
},
nth_window: function(n) {
var tab = this.tabs.down('.visible:not(.info_tab)', n - 1);
if (tab) {
var m = tab.id.match(/([^_]+)_tab/);
if (m) {
return this.window_map.get(m[1]);
}
}
},
info_window: function(n) {
return this.windows().find(function(win) {
if (win.type == "info") return win;
});
},
openWindow: function(serialized, msgid) {
if (!msgid) msgid = this.msgid();
var win = new Alice.Window(this, serialized, msgid);
this.addWindow(win);
return win;
},
addWindow: function(win) {
this.window_map.set(win.id, win);
if (window.fluid)
window.fluid.addDockMenuItem(win.title, win.focus.bind(win));
},
removeWindow: function(win) {
this.tabs_layout = this.tabs.getLayout();
this.windows().invoke("updateTabLayout");
if (win.active) this.focusLast();
if (window.fluid)
window.fluid.removeDockMenuItem(win.title);
if (win.id == this.previousFocus.id) {
this.previousFocus = 0;
}
this.window_map.unset(win.id);
this.connection.closeWindow(win);
win = null;
},
getWindow: function(windowId) {
return this.window_map.get(windowId);
},
activeWindow: function() {
var windows = this.windows();
for (var i=0; i < windows.length; i++) {
if (windows[i].active) return windows[i];
}
for (var i=0; i < windows.length; i++) {
if (windows[i].type != "info") return windows[i];
}
if (windows[0]) return windows[0];
},
addFilters: function(list) {
this.message_filters = this.message_filters.concat(list);
},
applyFilters: function(li, win) {
if (li.hasClassName("filtered")) return;
var length = this.base_filters.length;
for (var i=0; i < length; i++) {
this.base_filters[i].call(this, li, win);
}
li.addClassName("filtered");
if (li.hasClassName("message")) {
var msg = li.down("div.msg");
var length = this.message_filters.length;
for (var i=0; i < length; i++) {
var stop = this.message_filters[i].call(this, msg, win);
if (stop) return;
}
}
},
nextWindow: function() {
var active = this.activeWindow();
var nextTab = active.tab.next('.visible');
if (!nextTab) nextTab = this.tabs.down('.visible');
if (!nextTab) return;
var id = nextTab.id.replace('_tab','');
if (id != active.id) {
var win = this.getWindow(id);
win.focus();
return win;
}
},
updateOverflowMenus: function() {
var left = $('tab_menu_left');
var right = $('tab_menu_right');
left.removeClassName("unread");
left.removeClassName("highlight");
right.removeClassName("unread");
right.removeClassName("highlight");
var left_menu = left.down('ul');
var right_menu = right.down('ul');
left_menu.innerHTML = "";
right_menu.innerHTML = "";
this.windows().each(function(win) {
if (!win.visible) return;
var pos = win.getTabPosition();
if (pos.left) {
var classes = win.statuses;
classes.each(function(c){left.addClassName(c)});
left_menu.innerHTML += sprintf('<li rel="%s" class="%s"><span>%s</span></a>', win.id, classes.join(" "), win.title)
}
else if (pos.right) {
var classes = win.statuses;
classes.each(function(c){right.addClassName(c)});
right_menu.innerHTML += sprintf('<li rel="%s" class="%s"><span>%s</span></a>', win.id, classes.join(" "), win.title)
}
}.bind(this));
this.toggleMenu(left, !!left_menu.innerHTML);
this.toggleMenu(right, !!right_menu.innerHTML);
},
toggleMenu: function(menu, active) {
share/static/alice.js view on Meta::CPAN
if (li) {
li.addClassName(classname);
menu.addClassName(classname);
return true;
}
return false;
});
},
unHighlightChannelSelect: function(id) {
['tab_menu_left', 'tab_menu_right'].find(function(menu) {
menu = $(menu);
var li = menu.down('li[rel='+id+']');
if (li) {
li.removeClassName("unread");
li.removeClassName("highlight");
["unread", "highlight"].each(function(c) {
if (!menu.select('li').any(function(li) {return li.hasClassName(c)})) {
menu.removeClassName(c);
}
});
return true;
}
return false;
});
},
handleAction: function(action) {
if (this.actionHandlers[action.event]) {
this.actionHandlers[action.event].call(this,action);
}
},
displayMessage: function(message) {
var win = this.getWindow(message['window'].id);
if (win) {
win.addMessage(message);
} else {
this.connection.requestWindow(
message['window'].title, message['window'].id, message
);
}
},
displayChunk: function(message) {
var win = this.getWindow(message['window'].id);
if (win) {
win.addChunk(message);
}
},
focusHash: function(hash) {
if (!hash) hash = window.location.hash;
if (hash) {
hash = decodeURI(hash);
hash = hash.replace(/^#/, "");
if (hash.substr(0,1) != "/") {
var name = hash.match(/^([^\/]+)/)[0];
hash = hash.substr(name.length);
if (this.tabsets[name]) {
if (this.selectedSet != name) this.showSet(name);
}
else {
window.location.hash = hash;
window.location = window.location.toString();
return false;
}
}
var windows = this.windows();
for (var i = 0; i < windows.length; i++) {
var win = windows[i];
if (win.hashtag == hash) {
if (!win.active) win.focus();
return true;
}
}
}
return false;
},
tabShift: function() {
return this.tabs_layout.get('left');
},
tabsWidth: function() {
return this.tabs_width;
},
freeze: function() {
$('windows').setStyle({
width: document.viewport.getWidth()+"px",
right: "auto",
});
},
thaw: function() {
$('windows').setStyle({
width: "auto",
right: "0px",
});
},
shiftTabs: function(shift) {
var current = this.tabShift();
var left = current + shift;
var time = Math.min(Math.max(0.1, Math.abs(shift) / 100), 0.5);
this.tabs.style.webkitTransitionDuration = time+"s";
this.tabs.setStyle({left: left+"px"});
this.tabs_layout = this.tabs.getLayout();
},
shiftEnd: function(e) {
this.tabs_layout = this.tabs.getLayout();
this.updateOverflowMenus();
},
makeSortable: function() {
Sortable.create('tabs', {
overlap: 'horizontal',
constraint: 'horizontal',
format: /(.+)/,
only: ["info_tab", "channel_tab", "privmsg_tab"],
onUpdate: function (res) {
var tabs = res.childElements();
var order = tabs.collect(function(t){
var m = t.id.match(/([^_]+)_tab/);
if (m) return m[1]
});
if (order.length) this.connection.sendTabOrder(order);
setTimeout(function(){
this.windows().invoke("updateTabLayout");
this.activeWindow().shiftTab();
}.bind(this), 100);
}.bind(this)
});
},
addMissed: function() {
if (!window.fluid) return;
window.fluid.dockBadge ? window.fluid.dockBadge++ :
window.fluid.dockBadge = 1;
},
clearMissed: function() {
if (!window.fluid) return;
window.fluid.dockBadge = "";
},
ready: function() {
this.freeze();
setTimeout(this.updateOverflowMenus.bind(this), 1000);
this.fetchOembeds(function() {
this.connection.connect(function() {
this.focusHash() || this.activeWindow().focus();
}.bind(this));
}.bind(this));
},
log: function () {
var win = this.activeWindow();
for (var i=0; i < arguments.length; i++) {
if (window.console && window.console.log) {
console.log(arguments[i]);
}
if (this.options.debug == "true") {
if (win) {
win.addMessage({
html: '<li class="message monospace"><div class="left">console</div><div class="msg">'+arguments[i].toString()+'</div></li>'
});
}
}
}
},
msgid: function() {
var ids = this.windows().map(function(w){return w.msgid});
return Math.max.apply(Math, ids);
},
setSource: function(id) {
$('source').value = id;
},
showSet: function(name) {
var ids = this.tabsets[name];
if (ids) {
var elem = $('tabset_menu').select('li').find(function(li) {
return li.innerHTML.unescapeHTML() == name;
});
elem.up('ul').select('li').invoke('removeClassName', 'selectedset');
elem.addClassName('selectedset');
this.windows().each(function(win) {
ids.indexOf(win.id) >= 0 || win.type == "privmsg" ? win.show() : win.hide();
});
this.selectSet(name);
var active = this.activeWindow();
if (!active.visible) {
active = this.nextWindow();
}
if (active) active.shiftTab();
setTimeout(this.updateOverflowMenus.bind(this), 2000);
}
},
selectSet: function(name) {
var hash = window.location.hash;
hash = hash.replace(/^[^\/]*/, name);
window.location.hash = hash;
window.location = window.location.toString();
this.selectedSet = name;
},
clearSet: function(elem) {
elem.up('ul').select('li').invoke('removeClassName', 'selectedset');
elem.addClassName('selectedset');
this.windows().invoke("show");
share/static/alice.js view on Meta::CPAN
gotoLogin: function() {
window.location = "/login";
},
connect: function(cb) {
if (this.reconnect_count > 3) {
this.aborting = true;
this.changeStatus("ok");
if (this.type == "websocket") {
this.application.activeWindow().showAlert("WebSocket connection failed, falling back...");
this.application.connection = new Alice.Connection.XHR(this.application);
this.application.connection.connect();
return;
}
this.application.activeWindow().showAlert("Alice server is not responding (<a href='javascript:alice.connection.reconnect()'>reconnect</a>)");
return;
}
this.pings = [];
this.closeConnection();
this.len = 0;
this.reconnect_count++;
this.changeStatus("loading");
this._connect(cb);
},
changeStatus: function(classname) {
$('connection_status').className = classname;
},
reconnect: function () {
this.reconnecting = true;
this.reconnect_count = 0;
this.connect();
},
handleException: function(request, exception) {
this.application.log("encountered an error with stream.");
this.application.log(exception);
this.connected = false;
if (!this.aborting)
setTimeout(this.connect.bind(this), 2000);
else
this.changeStatus("ok");
},
handleComplete: function(transport) {
this.application.log("connection was closed cleanly.");
this.connected = false;
if (!this.aborting)
setTimeout(this.connect.bind(this), 2000);
else
this.changeStatus("ok");
},
processQueue: function(data) {
try {
var queue = data.queue;
var length = queue.length;
for (var i=0; i<length; i++) {
if (queue[i].type == "identify") {
this.id = queue[i].id;
}
else if (queue[i].type == "action")
this.application.handleAction(queue[i]);
else if (queue[i].type == "message") {
if (queue[i].timestamp)
queue[i].timestamp = Alice.epochToLocal(queue[i].timestamp, this.application.options.timeformat);
this.application.displayMessage(queue[i]);
}
else if (queue[i].type == "chunk") {
this.application.displayChunk(queue[i]);
}
}
}
catch (e) {
this.application.log(e.toString());
}
},
get: function(path, callback) {
new Ajax.Request(path, {
method: 'get',
on401: this.gotoLogin,
onSuccess: callback
});
},
sendTabOrder: function (windows) {
new Ajax.Request('/tabs', {
method: 'post',
on401: this.gotoLogin,
parameters: {tabs: windows}
});
},
requestChunk: function (win, limit, max) {
if (!this.connected) return;
this.sendMessage({
source: win,
msg: "/chunk " + limit + " " + max,
});
}
};
Alice.Connection.WebSocket = Class.create(Alice.Connection, {
initialize: function(application) {
this.type = "websocket";
this.application = application;
this.connected = false;
this.aborting = false;
this.request = null;
this.reconnect_count = 0;
this.reconnecting = false;
},
_connect: function(cb) {
var now = new Date();
this.application.log("opening new websocket stream");
this.changeStatus("ok");
var parameters = Object.toQueryString({
share/static/alice.js view on Meta::CPAN
});
Alice.Connection.XHR = Class.create(Alice.Connection, {
initialize: function(application) {
this.type = "xhr";
this.pings = [];
this.pingLimit = 10;
this.seperator = "--xalicex\n";
this.len = 0;
this.application = application;
this.connected = false;
this.aborting = false;
this.request = null;
this.reconnect_count = 0;
this.reconnecting = false;
},
_connect: function(cb) {
setTimeout(function () {
var now = new Date();
this.application.log("opening new xhr stream");
this.changeStatus("ok");
this.request = new Ajax.Request('/stream', {
method: 'get',
parameters: {
t: now.getTime() / 1000,
tab: this.application.activeWindow().id
},
on401: this.gotoLogin,
on500: this.gotoLogin,
on502: this.gotoLogin,
on503: this.gotoLogin,
onException: this.handleException.bind(this),
onInteractive: function(transport) {
if (!this.connected) {
this.connected = true;
setTimeout(cb, 0);
}
this.handleUpdate(transport);
}.bind(this),
onComplete: this.handleComplete.bind(this)
});
}.bind(this), this.application.loadDelay);
},
handleUpdate: function(transport) {
if (this.reconnecting) {
this.application.activeWindow().showHappyAlert("Reconnected to the Alice server");
this.reconnecting = false;
}
this.reconnect_count = 0;
var time = new Date();
var data = transport.responseText.slice(this.len);
var start, end;
start = data.indexOf(this.seperator);
if (start > -1) {
start += this.seperator.length;
end = data.indexOf(this.seperator, start);
if (end == -1) return;
}
else return;
this.len += (end + this.seperator.length) - start;
data = data.slice(start, end);
var data = data.evalJSON();
this.processQueue(data);
if (data.time) {
var lag = this.addPing(time / 1000 - data.time);
if (lag > 5) {
this.application.log("lag is over 5s, reconnecting.");
this.connect();
}
}
},
addPing: function(ping) {
this.pings.push(ping);
if (this.pings.length > this.pingLimit)
this.pings.shift();
var lag = this.lag();
return lag;
},
lag: function() {
if (!this.pings.length) return 0;
return this.pings.inject(0, function (acc, n) {return acc + n}) / this.pings.length;
},
sendMessage: function(form) {
if (!this.connected) return false;
var params;
if (form.nodeName && form.nodeName == "FORM") {
params = Form.serialize(form);
}
else {
params = form;
}
params['stream'] = this.id;
new Ajax.Request('/say', {
method: 'post',
parameters: params,
on401: this.gotoLogin,
onException: function (request, exception) {
alert("There was an error sending a message.");
}
});
return true;
},
closeConnection: function() {
this.aborting = true;
if (this.request && this.request.transport)
this.request.transport.abort();
this.aborting = false;
},
closeWindow: function(win) {
new Ajax.Request('/say', {
method: 'post',
on401: this.gotoLogin,
parameters: {
source: win.id,
msg: "/close",
stream: this.id
}
});
},
requestWindow: function(title, windowId, message) {
new Ajax.Request('/say', {
method: 'post',
parameters: {
source: windowId,
msg: "/create " + title,
stream: this.id
},
on401: this.gotoLogin,
onSuccess: function (transport) {
this.handleUpdate(transport);
if (message) {
setTimeout(function() {
this.application.displayMessage(message)
share/static/alice.js view on Meta::CPAN
this.tab.removeClassName("unread");
this.tab.removeClassName("highlight");
this.statuses = [];
this.application.unHighlightChannelSelect(this.id);
},
markUnread: function(classname) {
var classes = ["unread"];
if (classname) classes.push(classname);
classes.each(function(c){this.tab.addClassName(c)}.bind(this));
this.application.highlightChannelSelect(this.id, classes);
this.statuses = classes;
},
disable: function () {
this.markRead();
this.tab.addClassName('disabled');
},
enable: function () {
this.tab.removeClassName('disabled');
},
close: function(event) {
this.tab.remove();
this.element.remove();
this.application.removeWindow(this);
},
showHappyAlert: function (message) {
this.messages.insert(
"<li class='event happynotice'><div class='msg'>"+message+"</div></li>"
);
this.scrollToPosition(0);
},
showAlert: function (message) {
this.messages.insert(
"<li class='event notice'><div class='msg'>"+message+"</div></li>"
);
this.scrollToPosition(0);
},
announce: function (message) {
message = message.escapeHTML();
this.messages.insert(
"<li class='message monospaced announce'><div class='msg'>"+message+"</div></li>"
);
this.scrollToPosition(0);
},
trimMessages: function() {
this.messages.select("li").reverse().slice(this.messageLimit).invoke("remove");
},
addChunk: function(chunk) {
if (chunk.nicks) this.updateNicks(chunk.nicks);
clearTimeout(this.scrollListener);
if (chunk.range.length == 0) {
this.scrollBackEmpty = true;
this.tab.removeClassName("loading");
return;
}
var position = this.captureScrollPosition();
if (chunk['range'][0] > this.msgid) {
this.messages.insert({"bottom": chunk['html']});
this.trimMessages();
this.msgid = chunk['range'][1];
}
else {
this.bulk_insert = true;
this.messages.insert({"top": chunk['html']});
}
this.messages.select("li:not(.filtered)").each(function (li) {
this.application.applyFilters(li, this);
}.bind(this));
this.bulk_insert = false;
this.scrollToPosition(position);
setTimeout(function(){this.removeClassName("loading")}.bind(this.tab), 1000);
this.scrollListener = setTimeout(this.checkScrollBack.bind(this), 1000);
},
addMessage: function(message) {
if (!message.html || message.msgid <= this.msgid) return;
if (message.msgid) this.msgid = message.msgid;
if (message.nicks) this.updateNicks(message.nicks);
var position = this.captureScrollPosition();
this.messages.insert(message.html);
this.trimMessages();
this.scrollToPosition(position);
var li = this.messages.select("li").last();
this.application.applyFilters(li, this);
this.scrollToPosition(position);
if (message.event == "topic") {
this.topic = message.body;
if (this.active) this.application.displayTopic(this.topic);
}
this.element.redraw();
this.promoteNick(message.nick);
},
promoteNick: function(nick) {
if (this.nicks_order.last() == nick) return;
var index = this.nicks_order.indexOf(nick);
if (index > -1) this.nicks_order.splice(index, 1);
share/static/alice.js view on Meta::CPAN
getValue: function() {
if (this.editor) {
return this.editor.innerHTML;
}
return this.textarea.getValue();
},
onKeyPress: function(event) {
if (event.keyCode != Event.KEY_TAB) {
this.completion = false;
this.element.stopObserving("keypress");
}
},
uncancelNextFocus: function() {
this.skipThisFocus = false;
},
cancelNextFocus: function() {
this.skipThisFocus = true;
},
focus: function(force) {
if (this.disabled) return;
if (!force) {
if (this.focused) return;
if (this.skipThisFocus) {
this.skipThisFocus = false;
return;
}
}
this.focused = true;
if (this.editor) {
var selection = window.getSelection();
selection.removeAllRanges();
if (this.range) {
selection.addRange(this.range);
} else {
var text = document.createTextNode("");
this.editor.appendChild(text);
selection.selectNode(text);
this.range = selection.getRangeAt(0);
}
this.editor.focus();
} else {
this.textarea.focus();
}
},
onBlur: function(e) {
this.focused = false;
},
previousCommand: function() {
if (this.index-- == -1) {
this.index = this.history.length - 1;
this.stash();
}
this.update();
},
nextCommand: function() {
if (this.index++ == -1) {
this.stash();
} else if (this.index == this.history.length) {
this.index = -1;
}
this.update();
},
newLine: function() {
this.application.log("newLine");
},
send: function() {
var msg = this.getValue();
if (msg.length > 1024*2) {
alert("That message is way too long, dude.");
return;
}
if (this.editor) this.textarea.value = msg;
var success = this.application.connection.sendMessage(this.textarea.form);
if (success) {
this.history.push(msg);
this.setValue("");
if (this.editor) this.editor.update();
this.index = -1;
this.stash();
this.update();
this.focus(1);
}
else {
alert("Could not send message, not connected!");
}
},
completeNickname: function(prev) {
if (this.disabled) return;
if (!this.completion) {
this.completion = new Alice.Completion(this.application.activeWindow().getNicknames(), this.editor);
this.element.observe("keypress", this.onKeyPress.bind(this));
}
if (prev)
this.completion.prev();
else
this.completion.next();
},
stopCompletion: function() {
if (this.completion) {
this.completion.restore();
this.completion = false;
this.element.stopObserving("keypress");
}
},
stash: function() {
this.buffer = this.getValue();
},
update: function() {
this.setValue(this.getCommand(this.index));
},
getCommand: function(index) {
if (index == -1) {
return this.buffer;
} else {
return this.history[index];
}
},
resize: function() {
(function() {
var height = this.getContentHeight();
if (height == 0) {
this.element.setStyle({ height: null, top: 0 });
} else if (height <= 150) {
this.element.setStyle({ height: height + "px", top: "0px" });
}
}).bind(this).defer();
},
getContentHeight: function() {
var element = new Element("div").setStyle({
position: "absolute",
visibility: "hidden",
left: "-" + this.element.getWidth() + "px",
width: this.element.getWidth() - 7 + "px",
fontFamily: this.element.getStyle("fontFamily"),
fontSize: this.element.getStyle("fontSize"),
lineHeight: this.element.getStyle("lineHeight"),
whiteSpace: "pre-wrap",
wordWrap: "break-word"
});
if (this.editor) element.addClassName("editor");
var value = this.getValue();
element.update(value.replace(/\n$/, "\n\n").replace("\n", "<br>"));
$(document.body).insert(element);
var height = element.getHeight();
element.remove();
return height;
},
canContentEditable: function() {
var element = new Element("div", {contentEditable: "true"});
return ! (element.contentEditable == null || this.application.isMobile || Prototype.Browser.IE);
},
updateRange: function (e) {
var selection = window.getSelection();
if (selection.rangeCount > 0) {
var range = selection.getRangeAt(0);
this.range = range;
}
},
pasteHandler: function(e) {
if (!e.clipboardData) return;
var items = e.clipboardData.items;
if (items) {
var output = "";
for (var i=0; i < items.length; i++) {
var blob = items[i].getAsFile();
if (blob && blob.type.match(/image/)) {
e.stop();
var fd = new FormData();
fd.append("image", blob);
fd.append("key", "f1f60f1650a07bfe5f402f35205dffd4");
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://api.imgur.com/2/upload.json");
xhr.onload = function() {
var url = xhr.responseText.evalJSON();
this.editor.insertHTML(url.upload.links.original);
this.updateRange();
}.bind(this);
xhr.send(fd);
return;
}
}
}
var text = e.clipboardData.getData("Text");
if (text) {
e.preventDefault();
text = text.escapeHTML().replace(/\n+/g, "<br>\n");
this.editor.insertHTML(text);
this.updateRange();
return;
}
var url = e.clipboardData.getData("URL");
if (url) {
e.preventDefault();
this.editor.insertHTML(url);
this.updateRange();
return;
}
}
});
Alice.Keyboard = Class.create({
initialize: function(application) {
this.application = application;
this.isMac = navigator.platform.match(/mac/i);
this.lastCycle = 0;
this.cycleDelay = 300;
this.enable();
if (!this.application.isMobile) {
this.shortcut("Cmd+C", { propagate: true });
this.shortcut("Ctrl+C", { propagate: true });
this.shortcut("Cmd+B");
this.shortcut("Cmd+I");
this.shortcut("Cmd+Shift+U");
this.shortcut("Opt+Up");
this.shortcut("Opt+Down");
this.shortcut("Cmd+Shift+M");
this.shortcut("Cmd+Shift+J");
this.shortcut("Cmd+Shift+K");
this.shortcut("Cmd+K");
this.shortcut("Cmd+Shift+Left");
this.shortcut("Cmd+Shift+Right");
share/static/alice.js view on Meta::CPAN
},
enable: function() {
this.enabled = true;
},
disable: function() {
this.enabled = false;
}
});
Alice.Completion = Class.create({
initialize: function(candidates, editor) {
var range = this.getRange();
if (!range) return;
this.element = range.startContainer;
this.editor = editor;
if (this.element == this.editor) {
this.addTextNode();
}
this.value = this.element.data || "";
this.index = range.startOffset;
this.findStem();
this.matches = this.matchAgainst(candidates);
this.matchIndex = -1;
},
addTextNode: function() {
this.editor.innerHTML = "";
var node = document.createTextNode("");
this.editor.appendChild(node);
var selection = window.getSelection();
selection.removeAllRanges();
selection.selectNode(node);
range = selection.getRangeAt(0);
this.element = node;
},
getRange: function() {
var selection = window.getSelection();
if (selection.rangeCount > 0) {
return selection.getRangeAt(0);
}
if (document.createRange) {
return document.createRange();
}
return null;
},
setRange: function(range) {
if (!range) return;
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
},
next: function() {
if (!this.matches.length) return;
if (++this.matchIndex == this.matches.length) this.matchIndex = 0;
this.complete();
},
prev: function() {
if (!this.matches.length) return;
if (--this.matchIndex <= 0) this.matchIndex = this.matches.length - 1;
this.complete();
},
complete: function() {
var match = this.matches[this.matchIndex];
match += this.leftOffset == 0 ? ":\u00a0" : "\u00a0";
this.restore(match, this.leftOffset + match.length);
},
restore: function(stem, index) {
if (!this.element.parentNode)
this.addTextNode();
this.element.data = this.stemLeft + (stem || this.stem) + this.stemRight;
this.setCursorToIndex(Object.isUndefined(index) ? this.index : index);
},
setCursorToIndex: function(index) {
var range = this.getRange();
range.setStart(this.element, index);
range.setEnd(this.element, index);
this.setRange(range);
},
findStem: function() {
var left = [], right = [], chr, index, length = this.value.length;
for (index = this.index - 1; index >= 0; index--) {
chr = this.value.charAt(index);
if (!Alice.Completion.PATTERN.test(chr)) break;
left.unshift(chr);
}
for (index = this.index; index < length; index++) {
chr = this.value.charAt(index);
if (!Alice.Completion.PATTERN.test(chr)) break;
right.push(chr);
}
this.stem = left.concat(right).join("");
this.stemLeft = this.value.substr(0, this.index - left.length);
this.stemRight = this.value.substr(this.index + right.length);
this.leftOffset = this.index - left.length;
},
matchAgainst: function(candidates) {
return candidates.grep(new RegExp("^" + RegExp.escape(this.stem), "i"));
}
});
Alice.Completion.PATTERN = /[A-Za-z0-9\[\\\]^_{|}-]/;
if (window == window.parent) {
document.observe("dom:loaded", function () {
var alice = new Alice.Application();
window.alice = alice;
$('helpclose').observe("click", function () { $('help').hide(); });
$('nicklist_toggle').observe("click", function () { alice.toggleNicklist() });
$$('.dropdown').each(function (menu) {
menu.observe(alice.supportsTouch ? "touchstart" : "mousedown", function (e) {
e.stop();
var element = e.element('.dropdown');
if (element.hasClassName("dropdown")) {
if (menu.hasClassName("open")) {
menu.removeClassName("open");
}
else {
$$(".dropdown.open").invoke("removeClassName", "open");
menu.addClassName("open");
}
}
});
});
document.observe(alice.supportsTouch ? "touchend" : "mouseup", function (e) {
if (e.findElement('.dropdown')) return;
$$('.dropdown.open').invoke("removeClassName", "open");
});
if (alice.isMobile) {
$('nicklist_toggle').addClassName('visible');
}
else {
window.onkeydown = function (e) {
if (!alice.input.disabled && !Alice.isSpecialKey(e.which))
alice.input.focus();
};
var windows = $('windows');
var toggle = $('nicklist_toggle');
var resize = function () {
var active = alice.activeWindow();
var position = active.captureScrollPosition();
var end = function(){
alice.freeze();
alice.tabs_width = $('tabs_container').getWidth();
alice.updateOverflowMenus();