New: Upgrade Scriptaculous to 1.8.2 and Prototype to 1.6.0.3

This commit is contained in:
Regis Houssin 2009-03-02 23:18:56 +00:00
parent 88fa56f9ca
commit 05a48da313
14 changed files with 770 additions and 630 deletions

View File

@ -23,9 +23,9 @@ FPDI_Protection 1.0.2 Apache Software License 2.0 No GPL3 only PDF encr
MagPieRss 0.72 GPL 2.0 Yes Load RSS MagPieRss 0.72 GPL 2.0 Yes Load RSS
NuSoap 0.6.5 LGPL 2.1 Yes Interfaces with third tools NuSoap 0.6.5 LGPL 2.1 Yes Interfaces with third tools
PHP_WriteExcel 0.3.0 LGPL 2.1 Yes Excel files generation PHP_WriteExcel 0.3.0 LGPL 2.1 Yes Excel files generation
Prototype 1.6.0.2 MIT License Yes Ajax library Prototype 1.6.0.3 MIT License Yes Ajax library
PWC 1.3 MIT License Yes Ajax library PWC 1.3 MIT License Yes Ajax library
Scriptaculous 1.8.1 MIT License Yes Ajax library Scriptaculous 1.8.2 MIT License Yes Ajax library
VCard 2.0 GPL 2.0 Yes Fonctions vcard VCard 2.0 GPL 2.0 Yes Fonctions vcard
For licenses compatibility informations: For licenses compatibility informations:

View File

@ -19,6 +19,7 @@ For users:
- New: Added product label in invoice exports fields. - New: Added product label in invoice exports fields.
- New: Add VAT number in export fields. - New: Add VAT number in export fields.
- New: Upgrade FPDF to 1.6 - New: Upgrade FPDF to 1.6
- New: Upgrade Scriptaculous to 1.8.2 and Prototype to 1.6.0.3
- New: Added keywords in PDF. - New: Added keywords in PDF.
- New: Add hidden option MAIN_DISABLE_PDF_COMPRESSION. - New: Add hidden option MAIN_DISABLE_PDF_COMPRESSION.
- New: Add attachments on intervention cards. - New: Add attachments on intervention cards.

View File

@ -1,3 +1,29 @@
*V1.8.2* (November 18, 2008)
* Update to Prototype 1.6.0.3
* Make sure InPlaceEditor converts HTML entities to text. [Sean Kirby]
* Fix that Builder.node did not return extended elements on IE. Closes #71 and #77.
* Fix a bug in Sortable.destroy to make sure it's called on the referenced Sortable only, which allows for the correct intialization of nested Sortables. Closes Trac #8615. [Leon Chevalier]
* Change Effect.Base#render not to use eval(), so certain JavaScript runtime environments (like Adobe AIR) that do not support eval() work. [King Maxemilian, John-David Dalton]
* Fixed a calculation error in Effect.Transitions.pulse that could lead to flickering, add easing and change it to be a normal 0 to 1 transition that can be used with any effects; Effect.Pulsate now uses its own implementation. [Thomas Fuchs]
* Fixed Effect.ScrollTo. Changeset 8686 had a typo, document.viewport.getScrollOffsets[0] is always undefined. Removed the max check as it is not a cross-browser way to get scroll height and breaks the effect. Depending on scrollTo to do the right thing. Closes #11306. [Nick Stakenburg]
* Update version check so all Prototype versions can be required, not just x.x.x. Closes #10966. [Nick Stakenburg]
* Using $$ in the loader instead of getElementsByTagName to prevent limitations. Closes #9032. [Nick Stakenburg]
* Fix some missing semicolons. [jdalton]
* Fix an issue with Effect.ScrollTo that caused Firefox to scroll to the wrong offset in some situations. Closes #10245. [nik.wakelin]
* Fixes an issue with IE ghosting on non-absolute elements. Closes #10423. [Tanrikut, tdd]
*V1.8.1* (January 3, 2008) *V1.8.1* (January 3, 2008)
* Fix Element#getStyles in IE. Closes #10563. [Tobie Langel] * Fix Element#getStyles in IE. Closes #10563. [Tobie Langel]

View File

@ -1,4 +1,4 @@
Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the

View File

@ -14,6 +14,9 @@ For more information, see http://script.aculo.us/
See the CHANGELOG file for information on what's new. See the CHANGELOG file for information on what's new.
You can follow http://twitter.com/scriptaculous if you want
to be updated as we fix bugs and add new features.
== Installation/Usage == Installation/Usage
script.aculo.us includes the Prototype JavaScript Framework script.aculo.us includes the Prototype JavaScript Framework

View File

@ -1,4 +1,4 @@
/* Prototype JavaScript framework, version 1.6.0.2 /* Prototype JavaScript framework, version 1.6.0.3
* (c) 2005-2008 Sam Stephenson * (c) 2005-2008 Sam Stephenson
* *
* Prototype is freely distributable under the terms of an MIT-style license. * Prototype is freely distributable under the terms of an MIT-style license.
@ -7,23 +7,26 @@
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
var Prototype = { var Prototype = {
Version: '1.6.0.2', Version: '1.6.0.3',
Browser: { Browser: {
IE: !!(window.attachEvent && !window.opera), IE: !!(window.attachEvent &&
Opera: !!window.opera, navigator.userAgent.indexOf('Opera') === -1),
Opera: navigator.userAgent.indexOf('Opera') > -1,
WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1, Gecko: navigator.userAgent.indexOf('Gecko') > -1 &&
navigator.userAgent.indexOf('KHTML') === -1,
MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/) MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
}, },
BrowserFeatures: { BrowserFeatures: {
XPath: !!document.evaluate, XPath: !!document.evaluate,
SelectorsAPI: !!document.querySelector,
ElementExtensions: !!window.HTMLElement, ElementExtensions: !!window.HTMLElement,
SpecificElementExtensions: SpecificElementExtensions:
document.createElement('div').__proto__ && document.createElement('div')['__proto__'] &&
document.createElement('div').__proto__ !== document.createElement('div')['__proto__'] !==
document.createElement('form').__proto__ document.createElement('form')['__proto__']
}, },
ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>', ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
@ -83,12 +86,13 @@ Class.Methods = {
var property = properties[i], value = source[property]; var property = properties[i], value = source[property];
if (ancestor && Object.isFunction(value) && if (ancestor && Object.isFunction(value) &&
value.argumentNames().first() == "$super") { value.argumentNames().first() == "$super") {
var method = value, value = Object.extend((function(m) { var method = value;
value = (function(m) {
return function() { return ancestor[m].apply(this, arguments) }; return function() { return ancestor[m].apply(this, arguments) };
})(property).wrap(method), { })(property).wrap(method);
valueOf: function() { return method },
toString: function() { return method.toString() } value.valueOf = method.valueOf.bind(method);
}); value.toString = method.toString.bind(method);
} }
this.prototype[property] = value; this.prototype[property] = value;
} }
@ -167,7 +171,7 @@ Object.extend(Object, {
}, },
isElement: function(object) { isElement: function(object) {
return object && object.nodeType == 1; return !!(object && object.nodeType == 1);
}, },
isArray: function(object) { isArray: function(object) {
@ -198,7 +202,8 @@ Object.extend(Object, {
Object.extend(Function.prototype, { Object.extend(Function.prototype, {
argumentNames: function() { argumentNames: function() {
var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip"); var names = this.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1]
.replace(/\s+/g, '').split(',');
return names.length == 1 && !names[0] ? [] : names; return names.length == 1 && !names[0] ? [] : names;
}, },
@ -232,6 +237,11 @@ Object.extend(Function.prototype, {
}, timeout); }, timeout);
}, },
defer: function() {
var args = [0.01].concat($A(arguments));
return this.delay.apply(this, args);
},
wrap: function(wrapper) { wrap: function(wrapper) {
var __method = this; var __method = this;
return function() { return function() {
@ -248,8 +258,6 @@ Object.extend(Function.prototype, {
} }
}); });
Function.prototype.defer = Function.prototype.delay.curry(0.01);
Date.prototype.toJSON = function() { Date.prototype.toJSON = function() {
return '"' + this.getUTCFullYear() + '-' + return '"' + this.getUTCFullYear() + '-' +
(this.getUTCMonth() + 1).toPaddedString(2) + '-' + (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
@ -530,7 +538,7 @@ if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.proto
return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
}, },
unescapeHTML: function() { unescapeHTML: function() {
return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>'); return this.stripTags().replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
} }
}); });
@ -547,7 +555,7 @@ Object.extend(String.prototype.escapeHTML, {
text: document.createTextNode('') text: document.createTextNode('')
}); });
with (String.prototype.escapeHTML) div.appendChild(text); String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text);
var Template = Class.create({ var Template = Class.create({
initialize: function(template, pattern) { initialize: function(template, pattern) {
@ -589,10 +597,9 @@ var $break = { };
var Enumerable = { var Enumerable = {
each: function(iterator, context) { each: function(iterator, context) {
var index = 0; var index = 0;
iterator = iterator.bind(context);
try { try {
this._each(function(value) { this._each(function(value) {
iterator(value, index++); iterator.call(context, value, index++);
}); });
} catch (e) { } catch (e) {
if (e != $break) throw e; if (e != $break) throw e;
@ -601,47 +608,46 @@ var Enumerable = {
}, },
eachSlice: function(number, iterator, context) { eachSlice: function(number, iterator, context) {
iterator = iterator ? iterator.bind(context) : Prototype.K;
var index = -number, slices = [], array = this.toArray(); var index = -number, slices = [], array = this.toArray();
if (number < 1) return array;
while ((index += number) < array.length) while ((index += number) < array.length)
slices.push(array.slice(index, index+number)); slices.push(array.slice(index, index+number));
return slices.collect(iterator, context); return slices.collect(iterator, context);
}, },
all: function(iterator, context) { all: function(iterator, context) {
iterator = iterator ? iterator.bind(context) : Prototype.K; iterator = iterator || Prototype.K;
var result = true; var result = true;
this.each(function(value, index) { this.each(function(value, index) {
result = result && !!iterator(value, index); result = result && !!iterator.call(context, value, index);
if (!result) throw $break; if (!result) throw $break;
}); });
return result; return result;
}, },
any: function(iterator, context) { any: function(iterator, context) {
iterator = iterator ? iterator.bind(context) : Prototype.K; iterator = iterator || Prototype.K;
var result = false; var result = false;
this.each(function(value, index) { this.each(function(value, index) {
if (result = !!iterator(value, index)) if (result = !!iterator.call(context, value, index))
throw $break; throw $break;
}); });
return result; return result;
}, },
collect: function(iterator, context) { collect: function(iterator, context) {
iterator = iterator ? iterator.bind(context) : Prototype.K; iterator = iterator || Prototype.K;
var results = []; var results = [];
this.each(function(value, index) { this.each(function(value, index) {
results.push(iterator(value, index)); results.push(iterator.call(context, value, index));
}); });
return results; return results;
}, },
detect: function(iterator, context) { detect: function(iterator, context) {
iterator = iterator.bind(context);
var result; var result;
this.each(function(value, index) { this.each(function(value, index) {
if (iterator(value, index)) { if (iterator.call(context, value, index)) {
result = value; result = value;
throw $break; throw $break;
} }
@ -650,17 +656,16 @@ var Enumerable = {
}, },
findAll: function(iterator, context) { findAll: function(iterator, context) {
iterator = iterator.bind(context);
var results = []; var results = [];
this.each(function(value, index) { this.each(function(value, index) {
if (iterator(value, index)) if (iterator.call(context, value, index))
results.push(value); results.push(value);
}); });
return results; return results;
}, },
grep: function(filter, iterator, context) { grep: function(filter, iterator, context) {
iterator = iterator ? iterator.bind(context) : Prototype.K; iterator = iterator || Prototype.K;
var results = []; var results = [];
if (Object.isString(filter)) if (Object.isString(filter))
@ -668,7 +673,7 @@ var Enumerable = {
this.each(function(value, index) { this.each(function(value, index) {
if (filter.match(value)) if (filter.match(value))
results.push(iterator(value, index)); results.push(iterator.call(context, value, index));
}); });
return results; return results;
}, },
@ -696,9 +701,8 @@ var Enumerable = {
}, },
inject: function(memo, iterator, context) { inject: function(memo, iterator, context) {
iterator = iterator.bind(context);
this.each(function(value, index) { this.each(function(value, index) {
memo = iterator(memo, value, index); memo = iterator.call(context, memo, value, index);
}); });
return memo; return memo;
}, },
@ -711,10 +715,10 @@ var Enumerable = {
}, },
max: function(iterator, context) { max: function(iterator, context) {
iterator = iterator ? iterator.bind(context) : Prototype.K; iterator = iterator || Prototype.K;
var result; var result;
this.each(function(value, index) { this.each(function(value, index) {
value = iterator(value, index); value = iterator.call(context, value, index);
if (result == null || value >= result) if (result == null || value >= result)
result = value; result = value;
}); });
@ -722,10 +726,10 @@ var Enumerable = {
}, },
min: function(iterator, context) { min: function(iterator, context) {
iterator = iterator ? iterator.bind(context) : Prototype.K; iterator = iterator || Prototype.K;
var result; var result;
this.each(function(value, index) { this.each(function(value, index) {
value = iterator(value, index); value = iterator.call(context, value, index);
if (result == null || value < result) if (result == null || value < result)
result = value; result = value;
}); });
@ -733,10 +737,10 @@ var Enumerable = {
}, },
partition: function(iterator, context) { partition: function(iterator, context) {
iterator = iterator ? iterator.bind(context) : Prototype.K; iterator = iterator || Prototype.K;
var trues = [], falses = []; var trues = [], falses = [];
this.each(function(value, index) { this.each(function(value, index) {
(iterator(value, index) ? (iterator.call(context, value, index) ?
trues : falses).push(value); trues : falses).push(value);
}); });
return [trues, falses]; return [trues, falses];
@ -751,19 +755,20 @@ var Enumerable = {
}, },
reject: function(iterator, context) { reject: function(iterator, context) {
iterator = iterator.bind(context);
var results = []; var results = [];
this.each(function(value, index) { this.each(function(value, index) {
if (!iterator(value, index)) if (!iterator.call(context, value, index))
results.push(value); results.push(value);
}); });
return results; return results;
}, },
sortBy: function(iterator, context) { sortBy: function(iterator, context) {
iterator = iterator.bind(context);
return this.map(function(value, index) { return this.map(function(value, index) {
return {value: value, criteria: iterator(value, index)}; return {
value: value,
criteria: iterator.call(context, value, index)
};
}).sort(function(left, right) { }).sort(function(left, right) {
var a = left.criteria, b = right.criteria; var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0; return a < b ? -1 : a > b ? 1 : 0;
@ -815,8 +820,12 @@ function $A(iterable) {
if (Prototype.Browser.WebKit) { if (Prototype.Browser.WebKit) {
$A = function(iterable) { $A = function(iterable) {
if (!iterable) return []; if (!iterable) return [];
if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') && // In Safari, only use the `toArray` method if it's not a NodeList.
iterable.toArray) return iterable.toArray(); // A NodeList is a function, has an function `item` property, and a numeric
// `length` property. Adapted from Google Doctype.
if (!(typeof iterable === 'function' && typeof iterable.length ===
'number' && typeof iterable.item === 'function') && iterable.toArray)
return iterable.toArray();
var length = iterable.length || 0, results = new Array(length); var length = iterable.length || 0, results = new Array(length);
while (length--) results[length] = iterable[length]; while (length--) results[length] = iterable[length];
return results; return results;
@ -963,8 +972,8 @@ Object.extend(Number.prototype, {
return this + 1; return this + 1;
}, },
times: function(iterator) { times: function(iterator, context) {
$R(0, this, true).each(iterator); $R(0, this, true).each(iterator, context);
return this; return this;
}, },
@ -1011,7 +1020,9 @@ var Hash = Class.create(Enumerable, (function() {
}, },
get: function(key) { get: function(key) {
return this._object[key]; // simulating poorly supported hasOwnProperty
if (this._object[key] !== Object.prototype[key])
return this._object[key];
}, },
unset: function(key) { unset: function(key) {
@ -1051,14 +1062,14 @@ var Hash = Class.create(Enumerable, (function() {
}, },
toQueryString: function() { toQueryString: function() {
return this.map(function(pair) { return this.inject([], function(results, pair) {
var key = encodeURIComponent(pair.key), values = pair.value; var key = encodeURIComponent(pair.key), values = pair.value;
if (values && typeof values == 'object') { if (values && typeof values == 'object') {
if (Object.isArray(values)) if (Object.isArray(values))
return values.map(toQueryPair.curry(key)).join('&'); return results.concat(values.map(toQueryPair.curry(key)));
} } else results.push(toQueryPair(key, values));
return toQueryPair(key, values); return results;
}).join('&'); }).join('&');
}, },
@ -1558,6 +1569,7 @@ if (!Node.ELEMENT_NODE) {
return Element.writeAttribute(cache[tagName].cloneNode(false), attributes); return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
}; };
Object.extend(this.Element, element || { }); Object.extend(this.Element, element || { });
if (element) this.Element.prototype = element.prototype;
}).call(window); }).call(window);
Element.cache = { }; Element.cache = { };
@ -1574,12 +1586,14 @@ Element.Methods = {
}, },
hide: function(element) { hide: function(element) {
$(element).style.display = 'none'; element = $(element);
element.style.display = 'none';
return element; return element;
}, },
show: function(element) { show: function(element) {
$(element).style.display = ''; element = $(element);
element.style.display = '';
return element; return element;
}, },
@ -1733,7 +1747,7 @@ Element.Methods = {
element = $(element); element = $(element);
if (arguments.length == 1) return element.firstDescendant(); if (arguments.length == 1) return element.firstDescendant();
return Object.isNumber(expression) ? element.descendants()[expression] : return Object.isNumber(expression) ? element.descendants()[expression] :
element.select(expression)[index || 0]; Element.select(element, expression)[index || 0];
}, },
previous: function(element, expression, index) { previous: function(element, expression, index) {
@ -1863,24 +1877,16 @@ Element.Methods = {
descendantOf: function(element, ancestor) { descendantOf: function(element, ancestor) {
element = $(element), ancestor = $(ancestor); element = $(element), ancestor = $(ancestor);
var originalAncestor = ancestor;
if (element.compareDocumentPosition) if (element.compareDocumentPosition)
return (element.compareDocumentPosition(ancestor) & 8) === 8; return (element.compareDocumentPosition(ancestor) & 8) === 8;
if (element.sourceIndex && !Prototype.Browser.Opera) { if (ancestor.contains)
var e = element.sourceIndex, a = ancestor.sourceIndex, return ancestor.contains(element) && ancestor !== element;
nextAncestor = ancestor.nextSibling;
if (!nextAncestor) {
do { ancestor = ancestor.parentNode; }
while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode);
}
if (nextAncestor && nextAncestor.sourceIndex)
return (e > a && e < nextAncestor.sourceIndex);
}
while (element = element.parentNode) while (element = element.parentNode)
if (element == originalAncestor) return true; if (element == ancestor) return true;
return false; return false;
}, },
@ -1895,7 +1901,7 @@ Element.Methods = {
element = $(element); element = $(element);
style = style == 'float' ? 'cssFloat' : style.camelize(); style = style == 'float' ? 'cssFloat' : style.camelize();
var value = element.style[style]; var value = element.style[style];
if (!value) { if (!value || value == 'auto') {
var css = document.defaultView.getComputedStyle(element, null); var css = document.defaultView.getComputedStyle(element, null);
value = css ? css[style] : null; value = css ? css[style] : null;
} }
@ -1934,7 +1940,7 @@ Element.Methods = {
getDimensions: function(element) { getDimensions: function(element) {
element = $(element); element = $(element);
var display = $(element).getStyle('display'); var display = element.getStyle('display');
if (display != 'none' && display != null) // Safari bug if (display != 'none' && display != null) // Safari bug
return {width: element.offsetWidth, height: element.offsetHeight}; return {width: element.offsetWidth, height: element.offsetHeight};
@ -1963,7 +1969,7 @@ Element.Methods = {
element.style.position = 'relative'; element.style.position = 'relative';
// Opera returns the offset relative to the positioning context, when an // Opera returns the offset relative to the positioning context, when an
// element is position relative but top and left have not been defined // element is position relative but top and left have not been defined
if (window.opera) { if (Prototype.Browser.Opera) {
element.style.top = 0; element.style.top = 0;
element.style.left = 0; element.style.left = 0;
} }
@ -2018,7 +2024,7 @@ Element.Methods = {
valueL += element.offsetLeft || 0; valueL += element.offsetLeft || 0;
element = element.offsetParent; element = element.offsetParent;
if (element) { if (element) {
if (element.tagName == 'BODY') break; if (element.tagName.toUpperCase() == 'BODY') break;
var p = Element.getStyle(element, 'position'); var p = Element.getStyle(element, 'position');
if (p !== 'static') break; if (p !== 'static') break;
} }
@ -2028,7 +2034,7 @@ Element.Methods = {
absolutize: function(element) { absolutize: function(element) {
element = $(element); element = $(element);
if (element.getStyle('position') == 'absolute') return; if (element.getStyle('position') == 'absolute') return element;
// Position.prepare(); // To be done manually by Scripty when it needs it. // Position.prepare(); // To be done manually by Scripty when it needs it.
var offsets = element.positionedOffset(); var offsets = element.positionedOffset();
@ -2052,7 +2058,7 @@ Element.Methods = {
relativize: function(element) { relativize: function(element) {
element = $(element); element = $(element);
if (element.getStyle('position') == 'relative') return; if (element.getStyle('position') == 'relative') return element;
// Position.prepare(); // To be done manually by Scripty when it needs it. // Position.prepare(); // To be done manually by Scripty when it needs it.
element.style.position = 'relative'; element.style.position = 'relative';
@ -2103,7 +2109,7 @@ Element.Methods = {
element = forElement; element = forElement;
do { do {
if (!Prototype.Browser.Opera || element.tagName == 'BODY') { if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {
valueT -= element.scrollTop || 0; valueT -= element.scrollTop || 0;
valueL -= element.scrollLeft || 0; valueL -= element.scrollLeft || 0;
} }
@ -2218,6 +2224,9 @@ else if (Prototype.Browser.IE) {
Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap( Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
function(proceed, element) { function(proceed, element) {
element = $(element); element = $(element);
// IE throws an error if element is not in document
try { element.offsetParent }
catch(e) { return $(document.body) }
var position = element.getStyle('position'); var position = element.getStyle('position');
if (position !== 'static') return proceed(element); if (position !== 'static') return proceed(element);
element.setStyle({ position: 'relative' }); element.setStyle({ position: 'relative' });
@ -2231,6 +2240,8 @@ else if (Prototype.Browser.IE) {
Element.Methods[method] = Element.Methods[method].wrap( Element.Methods[method] = Element.Methods[method].wrap(
function(proceed, element) { function(proceed, element) {
element = $(element); element = $(element);
try { element.offsetParent }
catch(e) { return Element._returnOffset(0,0) }
var position = element.getStyle('position'); var position = element.getStyle('position');
if (position !== 'static') return proceed(element); if (position !== 'static') return proceed(element);
// Trigger hasLayout on the offset parent so that IE6 reports // Trigger hasLayout on the offset parent so that IE6 reports
@ -2246,6 +2257,14 @@ else if (Prototype.Browser.IE) {
); );
}); });
Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap(
function(proceed, element) {
try { element.offsetParent }
catch(e) { return Element._returnOffset(0,0) }
return proceed(element);
}
);
Element.Methods.getStyle = function(element, style) { Element.Methods.getStyle = function(element, style) {
element = $(element); element = $(element);
style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize(); style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
@ -2337,7 +2356,7 @@ else if (Prototype.Browser.IE) {
Element._attributeTranslations.has = {}; Element._attributeTranslations.has = {};
$w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
'encType maxLength readOnly longDesc').each(function(attr) { 'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
Element._attributeTranslations.write.names[attr.toLowerCase()] = attr; Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
Element._attributeTranslations.has[attr.toLowerCase()] = attr; Element._attributeTranslations.has[attr.toLowerCase()] = attr;
}); });
@ -2390,7 +2409,7 @@ else if (Prototype.Browser.WebKit) {
(value < 0.00001) ? 0 : value; (value < 0.00001) ? 0 : value;
if (value == 1) if (value == 1)
if(element.tagName == 'IMG' && element.width) { if(element.tagName.toUpperCase() == 'IMG' && element.width) {
element.width++; element.width--; element.width++; element.width--;
} else try { } else try {
var n = document.createTextNode(' '); var n = document.createTextNode(' ');
@ -2521,7 +2540,7 @@ Element.Methods.Simulated = {
hasAttribute: function(element, attribute) { hasAttribute: function(element, attribute) {
attribute = Element._attributeTranslations.has[attribute] || attribute; attribute = Element._attributeTranslations.has[attribute] || attribute;
var node = $(element).getAttributeNode(attribute); var node = $(element).getAttributeNode(attribute);
return node && node.specified; return !!(node && node.specified);
} }
}; };
@ -2530,9 +2549,9 @@ Element.Methods.ByTag = { };
Object.extend(Element, Element.Methods); Object.extend(Element, Element.Methods);
if (!Prototype.BrowserFeatures.ElementExtensions && if (!Prototype.BrowserFeatures.ElementExtensions &&
document.createElement('div').__proto__) { document.createElement('div')['__proto__']) {
window.HTMLElement = { }; window.HTMLElement = { };
window.HTMLElement.prototype = document.createElement('div').__proto__; window.HTMLElement.prototype = document.createElement('div')['__proto__'];
Prototype.BrowserFeatures.ElementExtensions = true; Prototype.BrowserFeatures.ElementExtensions = true;
} }
@ -2547,7 +2566,7 @@ Element.extend = (function() {
element.nodeType != 1 || element == window) return element; element.nodeType != 1 || element == window) return element;
var methods = Object.clone(Methods), var methods = Object.clone(Methods),
tagName = element.tagName, property, value; tagName = element.tagName.toUpperCase(), property, value;
// extend methods for specific tags // extend methods for specific tags
if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
@ -2643,7 +2662,7 @@ Element.addMethods = function(methods) {
if (window[klass]) return window[klass]; if (window[klass]) return window[klass];
window[klass] = { }; window[klass] = { };
window[klass].prototype = document.createElement(tagName).__proto__; window[klass].prototype = document.createElement(tagName)['__proto__'];
return window[klass]; return window[klass];
} }
@ -2669,12 +2688,18 @@ Element.addMethods = function(methods) {
document.viewport = { document.viewport = {
getDimensions: function() { getDimensions: function() {
var dimensions = { }; var dimensions = { }, B = Prototype.Browser;
var B = Prototype.Browser;
$w('width height').each(function(d) { $w('width height').each(function(d) {
var D = d.capitalize(); var D = d.capitalize();
dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] : if (B.WebKit && !document.evaluate) {
(B.Opera) ? document.body['client' + D] : document.documentElement['client' + D]; // Safari <3.0 needs self.innerWidth/Height
dimensions[d] = self['inner' + D];
} else if (B.Opera && parseFloat(window.opera.version()) < 9.5) {
// Opera <9.5 needs document.body.clientWidth/Height
dimensions[d] = document.body['client' + D]
} else {
dimensions[d] = document.documentElement['client' + D];
}
}); });
return dimensions; return dimensions;
}, },
@ -2693,14 +2718,24 @@ document.viewport = {
window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
} }
}; };
/* Portions of the Selector class are derived from Jack Slocum’s DomQuery, /* Portions of the Selector class are derived from Jack Slocum's DomQuery,
* part of YUI-Ext version 0.40, distributed under the terms of an MIT-style * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
* license. Please see http://www.yui-ext.com/ for more information. */ * license. Please see http://www.yui-ext.com/ for more information. */
var Selector = Class.create({ var Selector = Class.create({
initialize: function(expression) { initialize: function(expression) {
this.expression = expression.strip(); this.expression = expression.strip();
this.compileMatcher();
if (this.shouldUseSelectorsAPI()) {
this.mode = 'selectorsAPI';
} else if (this.shouldUseXPath()) {
this.mode = 'xpath';
this.compileXPathMatcher();
} else {
this.mode = "normal";
this.compileMatcher();
}
}, },
shouldUseXPath: function() { shouldUseXPath: function() {
@ -2715,16 +2750,29 @@ var Selector = Class.create({
// XPath can't do namespaced attributes, nor can it read // XPath can't do namespaced attributes, nor can it read
// the "checked" property from DOM nodes // the "checked" property from DOM nodes
if ((/(\[[\w-]*?:|:checked)/).test(this.expression)) if ((/(\[[\w-]*?:|:checked)/).test(e))
return false; return false;
return true; return true;
}, },
compileMatcher: function() { shouldUseSelectorsAPI: function() {
if (this.shouldUseXPath()) if (!Prototype.BrowserFeatures.SelectorsAPI) return false;
return this.compileXPathMatcher();
if (!Selector._div) Selector._div = new Element('div');
// Make sure the browser treats the selector as valid. Test on an
// isolated element to minimize cost of this check.
try {
Selector._div.querySelector(this.expression);
} catch(e) {
return false;
}
return true;
},
compileMatcher: function() {
var e = this.expression, ps = Selector.patterns, h = Selector.handlers, var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
c = Selector.criteria, le, p, m; c = Selector.criteria, le, p, m;
@ -2742,7 +2790,7 @@ var Selector = Class.create({
p = ps[i]; p = ps[i];
if (m = e.match(p)) { if (m = e.match(p)) {
this.matcher.push(Object.isFunction(c[i]) ? c[i](m) : this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
new Template(c[i]).evaluate(m)); new Template(c[i]).evaluate(m));
e = e.replace(m[0], ''); e = e.replace(m[0], '');
break; break;
} }
@ -2781,8 +2829,27 @@ var Selector = Class.create({
findElements: function(root) { findElements: function(root) {
root = root || document; root = root || document;
if (this.xpath) return document._getElementsByXPath(this.xpath, root); var e = this.expression, results;
return this.matcher(root);
switch (this.mode) {
case 'selectorsAPI':
// querySelectorAll queries document-wide, then filters to descendants
// of the context element. That's not what we want.
// Add an explicit context to the selector if necessary.
if (root !== document) {
var oldId = root.id, id = $(root).identify();
e = "#" + id + " " + e;
}
results = $A(root.querySelectorAll(e)).map(Element.extend);
root.id = oldId;
return results;
case 'xpath':
return document._getElementsByXPath(this.xpath, root);
default:
return this.matcher(root);
}
}, },
match: function(element) { match: function(element) {
@ -2873,10 +2940,10 @@ Object.extend(Selector, {
'first-child': '[not(preceding-sibling::*)]', 'first-child': '[not(preceding-sibling::*)]',
'last-child': '[not(following-sibling::*)]', 'last-child': '[not(following-sibling::*)]',
'only-child': '[not(preceding-sibling::* or following-sibling::*)]', 'only-child': '[not(preceding-sibling::* or following-sibling::*)]',
'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]", 'empty': "[count(*) = 0 and (count(text()) = 0)]",
'checked': "[@checked]", 'checked': "[@checked]",
'disabled': "[@disabled]", 'disabled': "[(@disabled) and (@type!='hidden')]",
'enabled': "[not(@disabled)]", 'enabled': "[not(@disabled) and (@type!='hidden')]",
'not': function(m) { 'not': function(m) {
var e = m[6], p = Selector.patterns, var e = m[6], p = Selector.patterns,
x = Selector.xpath, le, v; x = Selector.xpath, le, v;
@ -2968,7 +3035,7 @@ Object.extend(Selector, {
className: /^\.([\w\-\*]+)(\b|$)/, className: /^\.([\w\-\*]+)(\b|$)/,
pseudo: pseudo:
/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/, /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,
attrPresence: /^\[([\w]+)\]/, attrPresence: /^\[((?:[\w]+:)?[\w]+)\]/,
attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
}, },
@ -3081,7 +3148,7 @@ Object.extend(Selector, {
nextElementSibling: function(node) { nextElementSibling: function(node) {
while (node = node.nextSibling) while (node = node.nextSibling)
if (node.nodeType == 1) return node; if (node.nodeType == 1) return node;
return null; return null;
}, },
@ -3270,7 +3337,7 @@ Object.extend(Selector, {
'empty': function(nodes, value, root) { 'empty': function(nodes, value, root) {
for (var i = 0, results = [], node; node = nodes[i]; i++) { for (var i = 0, results = [], node; node = nodes[i]; i++) {
// IE treats comments as element nodes // IE treats comments as element nodes
if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue; if (node.tagName == '!' || node.firstChild) continue;
results.push(node); results.push(node);
} }
return results; return results;
@ -3288,7 +3355,8 @@ Object.extend(Selector, {
'enabled': function(nodes, value, root) { 'enabled': function(nodes, value, root) {
for (var i = 0, results = [], node; node = nodes[i]; i++) for (var i = 0, results = [], node; node = nodes[i]; i++)
if (!node.disabled) results.push(node); if (!node.disabled && (!node.type || node.type !== 'hidden'))
results.push(node);
return results; return results;
}, },
@ -3308,11 +3376,14 @@ Object.extend(Selector, {
operators: { operators: {
'=': function(nv, v) { return nv == v; }, '=': function(nv, v) { return nv == v; },
'!=': function(nv, v) { return nv != v; }, '!=': function(nv, v) { return nv != v; },
'^=': function(nv, v) { return nv.startsWith(v); }, '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); },
'$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); },
'*=': function(nv, v) { return nv == v || nv && nv.include(v); },
'$=': function(nv, v) { return nv.endsWith(v); }, '$=': function(nv, v) { return nv.endsWith(v); },
'*=': function(nv, v) { return nv.include(v); }, '*=': function(nv, v) { return nv.include(v); },
'~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); }, '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
'|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); } '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() +
'-').include('-' + (v || "").toUpperCase() + '-'); }
}, },
split: function(expression) { split: function(expression) {
@ -3386,7 +3457,7 @@ var Form = {
var data = elements.inject({ }, function(result, element) { var data = elements.inject({ }, function(result, element) {
if (!element.disabled && element.name) { if (!element.disabled && element.name) {
key = element.name; value = $(element).getValue(); key = element.name; value = $(element).getValue();
if (value != null && (element.type != 'submit' || (!submitted && if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
submit !== false && (!submit || key == submit) && (submitted = true)))) { submit !== false && (!submit || key == submit) && (submitted = true)))) {
if (key in result) { if (key in result) {
// a key is already present; construct an array of values // a key is already present; construct an array of values
@ -3547,7 +3618,6 @@ Form.Element.Methods = {
disable: function(element) { disable: function(element) {
element = $(element); element = $(element);
element.blur();
element.disabled = true; element.disabled = true;
return element; return element;
}, },
@ -3587,22 +3657,22 @@ Form.Element.Serializers = {
else element.value = value; else element.value = value;
}, },
select: function(element, index) { select: function(element, value) {
if (Object.isUndefined(index)) if (Object.isUndefined(value))
return this[element.type == 'select-one' ? return this[element.type == 'select-one' ?
'selectOne' : 'selectMany'](element); 'selectOne' : 'selectMany'](element);
else { else {
var opt, value, single = !Object.isArray(index); var opt, currentValue, single = !Object.isArray(value);
for (var i = 0, length = element.length; i < length; i++) { for (var i = 0, length = element.length; i < length; i++) {
opt = element.options[i]; opt = element.options[i];
value = this.optionValue(opt); currentValue = this.optionValue(opt);
if (single) { if (single) {
if (value == index) { if (currentValue == value) {
opt.selected = true; opt.selected = true;
return; return;
} }
} }
else opt.selected = index.include(value); else opt.selected = value.include(currentValue);
} }
} }
}, },
@ -3773,8 +3843,23 @@ Event.Methods = (function() {
isRightClick: function(event) { return isButton(event, 2) }, isRightClick: function(event) { return isButton(event, 2) },
element: function(event) { element: function(event) {
var node = Event.extend(event).target; event = Event.extend(event);
return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
var node = event.target,
type = event.type,
currentTarget = event.currentTarget;
if (currentTarget && currentTarget.tagName) {
// Firefox screws up the "click" event when moving between radio buttons
// via arrow keys. It also screws up the "load" and "error" events on images,
// reporting the document as the target instead of the original image.
if (type === 'load' || type === 'error' ||
(type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
&& currentTarget.type === 'radio'))
node = currentTarget;
}
if (node.nodeType == Node.TEXT_NODE) node = node.parentNode;
return Element.extend(node);
}, },
findElement: function(event, expression) { findElement: function(event, expression) {
@ -3785,11 +3870,15 @@ Event.Methods = (function() {
}, },
pointer: function(event) { pointer: function(event) {
var docElement = document.documentElement,
body = document.body || { scrollLeft: 0, scrollTop: 0 };
return { return {
x: event.pageX || (event.clientX + x: event.pageX || (event.clientX +
(document.documentElement.scrollLeft || document.body.scrollLeft)), (docElement.scrollLeft || body.scrollLeft) -
(docElement.clientLeft || 0)),
y: event.pageY || (event.clientY + y: event.pageY || (event.clientY +
(document.documentElement.scrollTop || document.body.scrollTop)) (docElement.scrollTop || body.scrollTop) -
(docElement.clientTop || 0))
}; };
}, },
@ -3834,7 +3923,7 @@ Event.extend = (function() {
}; };
} else { } else {
Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__; Event.prototype = Event.prototype || document.createEvent("HTMLEvents")['__proto__'];
Object.extend(Event.prototype, methods); Object.extend(Event.prototype, methods);
return Prototype.K; return Prototype.K;
} }
@ -3899,10 +3988,20 @@ Object.extend(Event, (function() {
cache[id][eventName] = null; cache[id][eventName] = null;
} }
// Internet Explorer needs to remove event handlers on page unload
// in order to avoid memory leaks.
if (window.attachEvent) { if (window.attachEvent) {
window.attachEvent("onunload", destroyCache); window.attachEvent("onunload", destroyCache);
} }
// Safari has a dummy event handler on page unload so that it won't
// use its bfcache. Safari <= 3.1 has an issue with restoring the "document"
// object when page is returned to via the back button using its bfcache.
if (Prototype.Browser.WebKit) {
window.addEventListener('unload', Prototype.emptyFunction, false);
}
return { return {
observe: function(element, eventName, handler) { observe: function(element, eventName, handler) {
element = $(element); element = $(element);

View File

@ -1,6 +1,6 @@
// script.aculo.us builder.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008 // script.aculo.us builder.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// //
// script.aculo.us is freely distributable under the terms of an MIT-style license. // script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/ // For details, see the script.aculo.us web site: http://script.aculo.us/
@ -26,7 +26,7 @@ var Builder = {
// due to a Firefox bug // due to a Firefox bug
node: function(elementName) { node: function(elementName) {
elementName = elementName.toUpperCase(); elementName = elementName.toUpperCase();
// try innerHTML approach // try innerHTML approach
var parentTag = this.NODEMAP[elementName] || 'div'; var parentTag = this.NODEMAP[elementName] || 'div';
var parentElement = document.createElement(parentTag); var parentElement = document.createElement(parentTag);
@ -34,14 +34,14 @@ var Builder = {
parentElement.innerHTML = "<" + elementName + "></" + elementName + ">"; parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
} catch(e) {} } catch(e) {}
var element = parentElement.firstChild || null; var element = parentElement.firstChild || null;
// see if browser added wrapping tags // see if browser added wrapping tags
if(element && (element.tagName.toUpperCase() != elementName)) if(element && (element.tagName.toUpperCase() != elementName))
element = element.getElementsByTagName(elementName)[0]; element = element.getElementsByTagName(elementName)[0];
// fallback to createElement approach // fallback to createElement approach
if(!element) element = document.createElement(elementName); if(!element) element = document.createElement(elementName);
// abort if nothing could be created // abort if nothing could be created
if(!element) return; if(!element) return;
@ -62,19 +62,19 @@ var Builder = {
// workaround firefox 1.0.X bug // workaround firefox 1.0.X bug
if(!element) { if(!element) {
element = document.createElement(elementName); element = document.createElement(elementName);
for(attr in arguments[1]) for(attr in arguments[1])
element[attr == 'class' ? 'className' : attr] = arguments[1][attr]; element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
} }
if(element.tagName.toUpperCase() != elementName) if(element.tagName.toUpperCase() != elementName)
element = parentElement.getElementsByTagName(elementName)[0]; element = parentElement.getElementsByTagName(elementName)[0];
} }
} }
// text, or array of children // text, or array of children
if(arguments[2]) if(arguments[2])
this._children(element, arguments[2]); this._children(element, arguments[2]);
return element; return $(element);
}, },
_text: function(text) { _text: function(text) {
return document.createTextNode(text); return document.createTextNode(text);
@ -100,7 +100,7 @@ var Builder = {
if(typeof children=='object') { // array can hold nodes and text if(typeof children=='object') { // array can hold nodes and text
children.flatten().each( function(e) { children.flatten().each( function(e) {
if(typeof e=='object') if(typeof e=='object')
element.appendChild(e) element.appendChild(e);
else else
if(Builder._isStringOrNumber(e)) if(Builder._isStringOrNumber(e))
element.appendChild(Builder._text(e)); element.appendChild(Builder._text(e));
@ -117,20 +117,20 @@ var Builder = {
$(element).update(html.strip()); $(element).update(html.strip());
return element.down(); return element.down();
}, },
dump: function(scope) { dump: function(scope) {
if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope
var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " + var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " +
"BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " + "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " +
"FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+ "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+
"KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+ "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+
"PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+ "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+
"TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/); "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);
tags.each( function(tag){ tags.each( function(tag){
scope[tag] = function() { scope[tag] = function() {
return Builder.node.apply(Builder, [tag].concat($A(arguments))); return Builder.node.apply(Builder, [tag].concat($A(arguments)));
} };
}); });
} }
} };

View File

@ -1,24 +1,24 @@
// script.aculo.us controls.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008 // script.aculo.us controls.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan) // (c) 2005-2008 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
// (c) 2005-2007 Jon Tirsen (http://www.tirsen.com) // (c) 2005-2008 Jon Tirsen (http://www.tirsen.com)
// Contributors: // Contributors:
// Richard Livsey // Richard Livsey
// Rahul Bhargava // Rahul Bhargava
// Rob Wills // Rob Wills
// //
// script.aculo.us is freely distributable under the terms of an MIT-style license. // script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/ // For details, see the script.aculo.us web site: http://script.aculo.us/
// Autocompleter.Base handles all the autocompletion functionality // Autocompleter.Base handles all the autocompletion functionality
// that's independent of the data source for autocompletion. This // that's independent of the data source for autocompletion. This
// includes drawing the autocompletion menu, observing keyboard // includes drawing the autocompletion menu, observing keyboard
// and mouse events, and similar. // and mouse events, and similar.
// //
// Specific autocompleters need to provide, at the very least, // Specific autocompleters need to provide, at the very least,
// a getUpdatedChoices function that will be invoked every time // a getUpdatedChoices function that will be invoked every time
// the text inside the monitored textbox changes. This method // the text inside the monitored textbox changes. This method
// should get the text for which to provide autocompletion by // should get the text for which to provide autocompletion by
// invoking this.getToken(), NOT by directly accessing // invoking this.getToken(), NOT by directly accessing
// this.element.value. This is to allow incremental tokenized // this.element.value. This is to allow incremental tokenized
@ -32,23 +32,23 @@
// will incrementally autocomplete with a comma as the token. // will incrementally autocomplete with a comma as the token.
// Additionally, ',' in the above example can be replaced with // Additionally, ',' in the above example can be replaced with
// a token array, e.g. { tokens: [',', '\n'] } which // a token array, e.g. { tokens: [',', '\n'] } which
// enables autocompletion on multiple tokens. This is most // enables autocompletion on multiple tokens. This is most
// useful when one of the tokens is \n (a newline), as it // useful when one of the tokens is \n (a newline), as it
// allows smart autocompletion after linebreaks. // allows smart autocompletion after linebreaks.
if(typeof Effect == 'undefined') if(typeof Effect == 'undefined')
throw("controls.js requires including script.aculo.us' effects.js library"); throw("controls.js requires including script.aculo.us' effects.js library");
var Autocompleter = { } var Autocompleter = { };
Autocompleter.Base = Class.create({ Autocompleter.Base = Class.create({
baseInitialize: function(element, update, options) { baseInitialize: function(element, update, options) {
element = $(element) element = $(element);
this.element = element; this.element = element;
this.update = $(update); this.update = $(update);
this.hasFocus = false; this.hasFocus = false;
this.changed = false; this.changed = false;
this.active = false; this.active = false;
this.index = 0; this.index = 0;
this.entryCount = 0; this.entryCount = 0;
this.oldElementValue = this.element.value; this.oldElementValue = this.element.value;
@ -61,28 +61,28 @@ Autocompleter.Base = Class.create({
this.options.tokens = this.options.tokens || []; this.options.tokens = this.options.tokens || [];
this.options.frequency = this.options.frequency || 0.4; this.options.frequency = this.options.frequency || 0.4;
this.options.minChars = this.options.minChars || 1; this.options.minChars = this.options.minChars || 1;
this.options.onShow = this.options.onShow || this.options.onShow = this.options.onShow ||
function(element, update){ function(element, update){
if(!update.style.position || update.style.position=='absolute') { if(!update.style.position || update.style.position=='absolute') {
update.style.position = 'absolute'; update.style.position = 'absolute';
Position.clone(element, update, { Position.clone(element, update, {
setHeight: false, setHeight: false,
offsetTop: element.offsetHeight offsetTop: element.offsetHeight
}); });
} }
Effect.Appear(update,{duration:0.15}); Effect.Appear(update,{duration:0.15});
}; };
this.options.onHide = this.options.onHide || this.options.onHide = this.options.onHide ||
function(element, update){ new Effect.Fade(update,{duration:0.15}) }; function(element, update){ new Effect.Fade(update,{duration:0.15}) };
if(typeof(this.options.tokens) == 'string') if(typeof(this.options.tokens) == 'string')
this.options.tokens = new Array(this.options.tokens); this.options.tokens = new Array(this.options.tokens);
// Force carriage returns as token delimiters anyway // Force carriage returns as token delimiters anyway
if (!this.options.tokens.include('\n')) if (!this.options.tokens.include('\n'))
this.options.tokens.push('\n'); this.options.tokens.push('\n');
this.observer = null; this.observer = null;
this.element.setAttribute('autocomplete','off'); this.element.setAttribute('autocomplete','off');
Element.hide(this.update); Element.hide(this.update);
@ -93,10 +93,10 @@ Autocompleter.Base = Class.create({
show: function() { show: function() {
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update); if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
if(!this.iefix && if(!this.iefix &&
(Prototype.Browser.IE) && (Prototype.Browser.IE) &&
(Element.getStyle(this.update, 'position')=='absolute')) { (Element.getStyle(this.update, 'position')=='absolute')) {
new Insertion.After(this.update, new Insertion.After(this.update,
'<iframe id="' + this.update.id + '_iefix" '+ '<iframe id="' + this.update.id + '_iefix" '+
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' + 'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
'src="javascript:false;" frameborder="0" scrolling="no"></iframe>'); 'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
@ -104,7 +104,7 @@ Autocompleter.Base = Class.create({
} }
if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50); if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
}, },
fixIEOverlapping: function() { fixIEOverlapping: function() {
Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)}); Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
this.iefix.style.zIndex = 1; this.iefix.style.zIndex = 1;
@ -152,15 +152,15 @@ Autocompleter.Base = Class.create({
Event.stop(event); Event.stop(event);
return; return;
} }
else else
if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
(Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return; (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
this.changed = true; this.changed = true;
this.hasFocus = true; this.hasFocus = true;
if(this.observer) clearTimeout(this.observer); if(this.observer) clearTimeout(this.observer);
this.observer = this.observer =
setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
}, },
@ -172,35 +172,35 @@ Autocompleter.Base = Class.create({
onHover: function(event) { onHover: function(event) {
var element = Event.findElement(event, 'LI'); var element = Event.findElement(event, 'LI');
if(this.index != element.autocompleteIndex) if(this.index != element.autocompleteIndex)
{ {
this.index = element.autocompleteIndex; this.index = element.autocompleteIndex;
this.render(); this.render();
} }
Event.stop(event); Event.stop(event);
}, },
onClick: function(event) { onClick: function(event) {
var element = Event.findElement(event, 'LI'); var element = Event.findElement(event, 'LI');
this.index = element.autocompleteIndex; this.index = element.autocompleteIndex;
this.selectEntry(); this.selectEntry();
this.hide(); this.hide();
}, },
onBlur: function(event) { onBlur: function(event) {
// needed to make click events working // needed to make click events working
setTimeout(this.hide.bind(this), 250); setTimeout(this.hide.bind(this), 250);
this.hasFocus = false; this.hasFocus = false;
this.active = false; this.active = false;
}, },
render: function() { render: function() {
if(this.entryCount > 0) { if(this.entryCount > 0) {
for (var i = 0; i < this.entryCount; i++) for (var i = 0; i < this.entryCount; i++)
this.index==i ? this.index==i ?
Element.addClassName(this.getEntry(i),"selected") : Element.addClassName(this.getEntry(i),"selected") :
Element.removeClassName(this.getEntry(i),"selected"); Element.removeClassName(this.getEntry(i),"selected");
if(this.hasFocus) { if(this.hasFocus) {
this.show(); this.show();
this.active = true; this.active = true;
} }
@ -209,27 +209,27 @@ Autocompleter.Base = Class.create({
this.hide(); this.hide();
} }
}, },
markPrevious: function() { markPrevious: function() {
if(this.index > 0) this.index-- if(this.index > 0) this.index--;
else this.index = this.entryCount-1; else this.index = this.entryCount-1;
this.getEntry(this.index).scrollIntoView(true); this.getEntry(this.index).scrollIntoView(true);
}, },
markNext: function() { markNext: function() {
if(this.index < this.entryCount-1) this.index++ if(this.index < this.entryCount-1) this.index++;
else this.index = 0; else this.index = 0;
this.getEntry(this.index).scrollIntoView(false); this.getEntry(this.index).scrollIntoView(false);
}, },
getEntry: function(index) { getEntry: function(index) {
return this.update.firstChild.childNodes[index]; return this.update.firstChild.childNodes[index];
}, },
getCurrentEntry: function() { getCurrentEntry: function() {
return this.getEntry(this.index); return this.getEntry(this.index);
}, },
selectEntry: function() { selectEntry: function() {
this.active = false; this.active = false;
this.updateElement(this.getCurrentEntry()); this.updateElement(this.getCurrentEntry());
@ -246,7 +246,7 @@ Autocompleter.Base = Class.create({
if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select); if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
} else } else
value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
var bounds = this.getTokenBounds(); var bounds = this.getTokenBounds();
if (bounds[0] != -1) { if (bounds[0] != -1) {
var newValue = this.element.value.substr(0, bounds[0]); var newValue = this.element.value.substr(0, bounds[0]);
@ -259,7 +259,7 @@ Autocompleter.Base = Class.create({
} }
this.oldElementValue = this.element.value; this.oldElementValue = this.element.value;
this.element.focus(); this.element.focus();
if (this.options.afterUpdateElement) if (this.options.afterUpdateElement)
this.options.afterUpdateElement(this.element, selectedElement); this.options.afterUpdateElement(this.element, selectedElement);
}, },
@ -271,20 +271,20 @@ Autocompleter.Base = Class.create({
Element.cleanWhitespace(this.update.down()); Element.cleanWhitespace(this.update.down());
if(this.update.firstChild && this.update.down().childNodes) { if(this.update.firstChild && this.update.down().childNodes) {
this.entryCount = this.entryCount =
this.update.down().childNodes.length; this.update.down().childNodes.length;
for (var i = 0; i < this.entryCount; i++) { for (var i = 0; i < this.entryCount; i++) {
var entry = this.getEntry(i); var entry = this.getEntry(i);
entry.autocompleteIndex = i; entry.autocompleteIndex = i;
this.addObservers(entry); this.addObservers(entry);
} }
} else { } else {
this.entryCount = 0; this.entryCount = 0;
} }
this.stopIndicator(); this.stopIndicator();
this.index = 0; this.index = 0;
if(this.entryCount==1 && this.options.autoSelect) { if(this.entryCount==1 && this.options.autoSelect) {
this.selectEntry(); this.selectEntry();
this.hide(); this.hide();
@ -300,7 +300,7 @@ Autocompleter.Base = Class.create({
}, },
onObserverEvent: function() { onObserverEvent: function() {
this.changed = false; this.changed = false;
this.tokenBounds = null; this.tokenBounds = null;
if(this.getToken().length>=this.options.minChars) { if(this.getToken().length>=this.options.minChars) {
this.getUpdatedChoices(); this.getUpdatedChoices();
@ -353,16 +353,16 @@ Ajax.Autocompleter = Class.create(Autocompleter.Base, {
getUpdatedChoices: function() { getUpdatedChoices: function() {
this.startIndicator(); this.startIndicator();
var entry = encodeURIComponent(this.options.paramName) + '=' + var entry = encodeURIComponent(this.options.paramName) + '=' +
encodeURIComponent(this.getToken()); encodeURIComponent(this.getToken());
this.options.parameters = this.options.callback ? this.options.parameters = this.options.callback ?
this.options.callback(this.element, entry) : entry; this.options.callback(this.element, entry) : entry;
if(this.options.defaultParams) if(this.options.defaultParams)
this.options.parameters += '&' + this.options.defaultParams; this.options.parameters += '&' + this.options.defaultParams;
new Ajax.Request(this.url, this.options); new Ajax.Request(this.url, this.options);
}, },
@ -384,7 +384,7 @@ Ajax.Autocompleter = Class.create(Autocompleter.Base, {
// - choices - How many autocompletion choices to offer // - choices - How many autocompletion choices to offer
// //
// - partialSearch - If false, the autocompleter will match entered // - partialSearch - If false, the autocompleter will match entered
// text only at the beginning of strings in the // text only at the beginning of strings in the
// autocomplete array. Defaults to true, which will // autocomplete array. Defaults to true, which will
// match text at the beginning of any *word* in the // match text at the beginning of any *word* in the
// strings in the autocomplete array. If you want to // strings in the autocomplete array. If you want to
@ -401,7 +401,7 @@ Ajax.Autocompleter = Class.create(Autocompleter.Base, {
// - ignoreCase - Whether to ignore case when autocompleting. // - ignoreCase - Whether to ignore case when autocompleting.
// Defaults to true. // Defaults to true.
// //
// It's possible to pass in a custom function as the 'selector' // It's possible to pass in a custom function as the 'selector'
// option, if you prefer to write your own autocompletion logic. // option, if you prefer to write your own autocompletion logic.
// In that case, the other options above will not apply unless // In that case, the other options above will not apply unless
// you support them. // you support them.
@ -429,20 +429,20 @@ Autocompleter.Local = Class.create(Autocompleter.Base, {
var entry = instance.getToken(); var entry = instance.getToken();
var count = 0; var count = 0;
for (var i = 0; i < instance.options.array.length && for (var i = 0; i < instance.options.array.length &&
ret.length < instance.options.choices ; i++) { ret.length < instance.options.choices ; i++) {
var elem = instance.options.array[i]; var elem = instance.options.array[i];
var foundPos = instance.options.ignoreCase ? var foundPos = instance.options.ignoreCase ?
elem.toLowerCase().indexOf(entry.toLowerCase()) : elem.toLowerCase().indexOf(entry.toLowerCase()) :
elem.indexOf(entry); elem.indexOf(entry);
while (foundPos != -1) { while (foundPos != -1) {
if (foundPos == 0 && elem.length != entry.length) { if (foundPos == 0 && elem.length != entry.length) {
ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" + ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
elem.substr(entry.length) + "</li>"); elem.substr(entry.length) + "</li>");
break; break;
} else if (entry.length >= instance.options.partialChars && } else if (entry.length >= instance.options.partialChars &&
instance.options.partialSearch && foundPos != -1) { instance.options.partialSearch && foundPos != -1) {
if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) { if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" + partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
@ -452,14 +452,14 @@ Autocompleter.Local = Class.create(Autocompleter.Base, {
} }
} }
foundPos = instance.options.ignoreCase ? foundPos = instance.options.ignoreCase ?
elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
elem.indexOf(entry, foundPos + 1); elem.indexOf(entry, foundPos + 1);
} }
} }
if (partial.length) if (partial.length)
ret = ret.concat(partial.slice(0, instance.options.choices - ret.length)) ret = ret.concat(partial.slice(0, instance.options.choices - ret.length));
return "<ul>" + ret.join('') + "</ul>"; return "<ul>" + ret.join('') + "</ul>";
} }
}, options || { }); }, options || { });
@ -476,7 +476,7 @@ Field.scrollFreeActivate = function(field) {
setTimeout(function() { setTimeout(function() {
Field.activate(field); Field.activate(field);
}, 1); }, 1);
} };
Ajax.InPlaceEditor = Class.create({ Ajax.InPlaceEditor = Class.create({
initialize: function(element, url, options) { initialize: function(element, url, options) {
@ -606,7 +606,7 @@ Ajax.InPlaceEditor = Class.create({
this.triggerCallback('onEnterHover'); this.triggerCallback('onEnterHover');
}, },
getText: function() { getText: function() {
return this.element.innerHTML; return this.element.innerHTML.unescapeHTML();
}, },
handleAJAXFailure: function(transport) { handleAJAXFailure: function(transport) {
this.triggerCallback('onFailure', transport); this.triggerCallback('onFailure', transport);
@ -782,7 +782,7 @@ Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
onSuccess: function(transport) { onSuccess: function(transport) {
var js = transport.responseText.strip(); var js = transport.responseText.strip();
if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
throw 'Server returned an invalid collection representation.'; throw('Server returned an invalid collection representation.');
this._collection = eval(js); this._collection = eval(js);
this.checkForExternalText(); this.checkForExternalText();
}.bind(this), }.bind(this),
@ -939,7 +939,7 @@ Ajax.InPlaceCollectionEditor.DefaultOptions = {
loadingCollectionText: 'Loading options...' loadingCollectionText: 'Loading options...'
}; };
// Delayed observer, like Form.Element.Observer, // Delayed observer, like Form.Element.Observer,
// but waits for delay after last key input // but waits for delay after last key input
// Ideal for live-search fields // Ideal for live-search fields
@ -949,7 +949,7 @@ Form.Element.DelayedObserver = Class.create({
this.element = $(element); this.element = $(element);
this.callback = callback; this.callback = callback;
this.timer = null; this.timer = null;
this.lastValue = $F(this.element); this.lastValue = $F(this.element);
Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this)); Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
}, },
delayedListener: function(event) { delayedListener: function(event) {
@ -962,4 +962,4 @@ Form.Element.DelayedObserver = Class.create({
this.timer = null; this.timer = null;
this.callback(this.element, $F(this.element)); this.callback(this.element, $F(this.element));
} }
}); });

View File

@ -1,8 +1,8 @@
// script.aculo.us dragdrop.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008 // script.aculo.us dragdrop.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) // (c) 2005-2008 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
// //
// script.aculo.us is freely distributable under the terms of an MIT-style license. // script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/ // For details, see the script.aculo.us web site: http://script.aculo.us/
@ -34,7 +34,7 @@ var Droppables = {
options._containers.push($(containment)); options._containers.push($(containment));
} }
} }
if(options.accept) options.accept = [options.accept].flatten(); if(options.accept) options.accept = [options.accept].flatten();
Element.makePositioned(element); // fix IE Element.makePositioned(element); // fix IE
@ -42,34 +42,34 @@ var Droppables = {
this.drops.push(options); this.drops.push(options);
}, },
findDeepestChild: function(drops) { findDeepestChild: function(drops) {
deepest = drops[0]; deepest = drops[0];
for (i = 1; i < drops.length; ++i) for (i = 1; i < drops.length; ++i)
if (Element.isParent(drops[i].element, deepest.element)) if (Element.isParent(drops[i].element, deepest.element))
deepest = drops[i]; deepest = drops[i];
return deepest; return deepest;
}, },
isContained: function(element, drop) { isContained: function(element, drop) {
var containmentNode; var containmentNode;
if(drop.tree) { if(drop.tree) {
containmentNode = element.treeNode; containmentNode = element.treeNode;
} else { } else {
containmentNode = element.parentNode; containmentNode = element.parentNode;
} }
return drop._containers.detect(function(c) { return containmentNode == c }); return drop._containers.detect(function(c) { return containmentNode == c });
}, },
isAffected: function(point, element, drop) { isAffected: function(point, element, drop) {
return ( return (
(drop.element!=element) && (drop.element!=element) &&
((!drop._containers) || ((!drop._containers) ||
this.isContained(element, drop)) && this.isContained(element, drop)) &&
((!drop.accept) || ((!drop.accept) ||
(Element.classNames(element).detect( (Element.classNames(element).detect(
function(v) { return drop.accept.include(v) } ) )) && function(v) { return drop.accept.include(v) } ) )) &&
Position.within(drop.element, point[0], point[1]) ); Position.within(drop.element, point[0], point[1]) );
}, },
@ -89,12 +89,12 @@ var Droppables = {
show: function(point, element) { show: function(point, element) {
if(!this.drops.length) return; if(!this.drops.length) return;
var drop, affected = []; var drop, affected = [];
this.drops.each( function(drop) { this.drops.each( function(drop) {
if(Droppables.isAffected(point, element, drop)) if(Droppables.isAffected(point, element, drop))
affected.push(drop); affected.push(drop);
}); });
if(affected.length>0) if(affected.length>0)
drop = Droppables.findDeepestChild(affected); drop = Droppables.findDeepestChild(affected);
@ -103,7 +103,7 @@ var Droppables = {
Position.within(drop.element, point[0], point[1]); Position.within(drop.element, point[0], point[1]);
if(drop.onHover) if(drop.onHover)
drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
if (drop != this.last_active) Droppables.activate(drop); if (drop != this.last_active) Droppables.activate(drop);
} }
}, },
@ -114,8 +114,8 @@ var Droppables = {
if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
if (this.last_active.onDrop) { if (this.last_active.onDrop) {
this.last_active.onDrop(element, this.last_active.element, event); this.last_active.onDrop(element, this.last_active.element, event);
return true; return true;
} }
}, },
@ -123,25 +123,25 @@ var Droppables = {
if(this.last_active) if(this.last_active)
this.deactivate(this.last_active); this.deactivate(this.last_active);
} }
} };
var Draggables = { var Draggables = {
drags: [], drags: [],
observers: [], observers: [],
register: function(draggable) { register: function(draggable) {
if(this.drags.length == 0) { if(this.drags.length == 0) {
this.eventMouseUp = this.endDrag.bindAsEventListener(this); this.eventMouseUp = this.endDrag.bindAsEventListener(this);
this.eventMouseMove = this.updateDrag.bindAsEventListener(this); this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
this.eventKeypress = this.keyPress.bindAsEventListener(this); this.eventKeypress = this.keyPress.bindAsEventListener(this);
Event.observe(document, "mouseup", this.eventMouseUp); Event.observe(document, "mouseup", this.eventMouseUp);
Event.observe(document, "mousemove", this.eventMouseMove); Event.observe(document, "mousemove", this.eventMouseMove);
Event.observe(document, "keypress", this.eventKeypress); Event.observe(document, "keypress", this.eventKeypress);
} }
this.drags.push(draggable); this.drags.push(draggable);
}, },
unregister: function(draggable) { unregister: function(draggable) {
this.drags = this.drags.reject(function(d) { return d==draggable }); this.drags = this.drags.reject(function(d) { return d==draggable });
if(this.drags.length == 0) { if(this.drags.length == 0) {
@ -150,24 +150,24 @@ var Draggables = {
Event.stopObserving(document, "keypress", this.eventKeypress); Event.stopObserving(document, "keypress", this.eventKeypress);
} }
}, },
activate: function(draggable) { activate: function(draggable) {
if(draggable.options.delay) { if(draggable.options.delay) {
this._timeout = setTimeout(function() { this._timeout = setTimeout(function() {
Draggables._timeout = null; Draggables._timeout = null;
window.focus(); window.focus();
Draggables.activeDraggable = draggable; Draggables.activeDraggable = draggable;
}.bind(this), draggable.options.delay); }.bind(this), draggable.options.delay);
} else { } else {
window.focus(); // allows keypress events if window isn't currently focused, fails for Safari window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
this.activeDraggable = draggable; this.activeDraggable = draggable;
} }
}, },
deactivate: function() { deactivate: function() {
this.activeDraggable = null; this.activeDraggable = null;
}, },
updateDrag: function(event) { updateDrag: function(event) {
if(!this.activeDraggable) return; if(!this.activeDraggable) return;
var pointer = [Event.pointerX(event), Event.pointerY(event)]; var pointer = [Event.pointerX(event), Event.pointerY(event)];
@ -175,36 +175,36 @@ var Draggables = {
// the same coordinates, prevent needless redrawing (moz bug?) // the same coordinates, prevent needless redrawing (moz bug?)
if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return; if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
this._lastPointer = pointer; this._lastPointer = pointer;
this.activeDraggable.updateDrag(event, pointer); this.activeDraggable.updateDrag(event, pointer);
}, },
endDrag: function(event) { endDrag: function(event) {
if(this._timeout) { if(this._timeout) {
clearTimeout(this._timeout); clearTimeout(this._timeout);
this._timeout = null; this._timeout = null;
} }
if(!this.activeDraggable) return; if(!this.activeDraggable) return;
this._lastPointer = null; this._lastPointer = null;
this.activeDraggable.endDrag(event); this.activeDraggable.endDrag(event);
this.activeDraggable = null; this.activeDraggable = null;
}, },
keyPress: function(event) { keyPress: function(event) {
if(this.activeDraggable) if(this.activeDraggable)
this.activeDraggable.keyPress(event); this.activeDraggable.keyPress(event);
}, },
addObserver: function(observer) { addObserver: function(observer) {
this.observers.push(observer); this.observers.push(observer);
this._cacheObserverCallbacks(); this._cacheObserverCallbacks();
}, },
removeObserver: function(element) { // element instead of observer fixes mem leaks removeObserver: function(element) { // element instead of observer fixes mem leaks
this.observers = this.observers.reject( function(o) { return o.element==element }); this.observers = this.observers.reject( function(o) { return o.element==element });
this._cacheObserverCallbacks(); this._cacheObserverCallbacks();
}, },
notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag' notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag'
if(this[eventName+'Count'] > 0) if(this[eventName+'Count'] > 0)
this.observers.each( function(o) { this.observers.each( function(o) {
@ -212,7 +212,7 @@ var Draggables = {
}); });
if(draggable.options[eventName]) draggable.options[eventName](draggable, event); if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
}, },
_cacheObserverCallbacks: function() { _cacheObserverCallbacks: function() {
['onStart','onEnd','onDrag'].each( function(eventName) { ['onStart','onEnd','onDrag'].each( function(eventName) {
Draggables[eventName+'Count'] = Draggables.observers.select( Draggables[eventName+'Count'] = Draggables.observers.select(
@ -220,7 +220,7 @@ var Draggables = {
).length; ).length;
}); });
} }
} };
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
@ -236,12 +236,12 @@ var Draggable = Class.create({
}, },
endeffect: function(element) { endeffect: function(element) {
var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0; var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0;
new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
queue: {scope:'_draggable', position:'end'}, queue: {scope:'_draggable', position:'end'},
afterFinish: function(){ afterFinish: function(){
Draggable._dragging[element] = false Draggable._dragging[element] = false
} }
}); });
}, },
zindex: 1000, zindex: 1000,
revert: false, revert: false,
@ -252,57 +252,57 @@ var Draggable = Class.create({
snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] } snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] }
delay: 0 delay: 0
}; };
if(!arguments[1] || Object.isUndefined(arguments[1].endeffect)) if(!arguments[1] || Object.isUndefined(arguments[1].endeffect))
Object.extend(defaults, { Object.extend(defaults, {
starteffect: function(element) { starteffect: function(element) {
element._opacity = Element.getOpacity(element); element._opacity = Element.getOpacity(element);
Draggable._dragging[element] = true; Draggable._dragging[element] = true;
new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
} }
}); });
var options = Object.extend(defaults, arguments[1] || { }); var options = Object.extend(defaults, arguments[1] || { });
this.element = $(element); this.element = $(element);
if(options.handle && Object.isString(options.handle)) if(options.handle && Object.isString(options.handle))
this.handle = this.element.down('.'+options.handle, 0); this.handle = this.element.down('.'+options.handle, 0);
if(!this.handle) this.handle = $(options.handle); if(!this.handle) this.handle = $(options.handle);
if(!this.handle) this.handle = this.element; if(!this.handle) this.handle = this.element;
if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) { if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
options.scroll = $(options.scroll); options.scroll = $(options.scroll);
this._isScrollChild = Element.childOf(this.element, options.scroll); this._isScrollChild = Element.childOf(this.element, options.scroll);
} }
Element.makePositioned(this.element); // fix IE Element.makePositioned(this.element); // fix IE
this.options = options; this.options = options;
this.dragging = false; this.dragging = false;
this.eventMouseDown = this.initDrag.bindAsEventListener(this); this.eventMouseDown = this.initDrag.bindAsEventListener(this);
Event.observe(this.handle, "mousedown", this.eventMouseDown); Event.observe(this.handle, "mousedown", this.eventMouseDown);
Draggables.register(this); Draggables.register(this);
}, },
destroy: function() { destroy: function() {
Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
Draggables.unregister(this); Draggables.unregister(this);
}, },
currentDelta: function() { currentDelta: function() {
return([ return([
parseInt(Element.getStyle(this.element,'left') || '0'), parseInt(Element.getStyle(this.element,'left') || '0'),
parseInt(Element.getStyle(this.element,'top') || '0')]); parseInt(Element.getStyle(this.element,'top') || '0')]);
}, },
initDrag: function(event) { initDrag: function(event) {
if(!Object.isUndefined(Draggable._dragging[this.element]) && if(!Object.isUndefined(Draggable._dragging[this.element]) &&
Draggable._dragging[this.element]) return; Draggable._dragging[this.element]) return;
if(Event.isLeftClick(event)) { if(Event.isLeftClick(event)) {
// abort on form elements, fixes a Firefox issue // abort on form elements, fixes a Firefox issue
var src = Event.element(event); var src = Event.element(event);
if((tag_name = src.tagName.toUpperCase()) && ( if((tag_name = src.tagName.toUpperCase()) && (
@ -311,34 +311,34 @@ var Draggable = Class.create({
tag_name=='OPTION' || tag_name=='OPTION' ||
tag_name=='BUTTON' || tag_name=='BUTTON' ||
tag_name=='TEXTAREA')) return; tag_name=='TEXTAREA')) return;
var pointer = [Event.pointerX(event), Event.pointerY(event)]; var pointer = [Event.pointerX(event), Event.pointerY(event)];
var pos = Position.cumulativeOffset(this.element); var pos = Position.cumulativeOffset(this.element);
this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
Draggables.activate(this); Draggables.activate(this);
Event.stop(event); Event.stop(event);
} }
}, },
startDrag: function(event) { startDrag: function(event) {
this.dragging = true; this.dragging = true;
if(!this.delta) if(!this.delta)
this.delta = this.currentDelta(); this.delta = this.currentDelta();
if(this.options.zindex) { if(this.options.zindex) {
this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
this.element.style.zIndex = this.options.zindex; this.element.style.zIndex = this.options.zindex;
} }
if(this.options.ghosting) { if(this.options.ghosting) {
this._clone = this.element.cloneNode(true); this._clone = this.element.cloneNode(true);
this.element._originallyAbsolute = (this.element.getStyle('position') == 'absolute'); this._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
if (!this.element._originallyAbsolute) if (!this._originallyAbsolute)
Position.absolutize(this.element); Position.absolutize(this.element);
this.element.parentNode.insertBefore(this._clone, this.element); this.element.parentNode.insertBefore(this._clone, this.element);
} }
if(this.options.scroll) { if(this.options.scroll) {
if (this.options.scroll == window) { if (this.options.scroll == window) {
var where = this._getWindowScroll(this.options.scroll); var where = this._getWindowScroll(this.options.scroll);
@ -349,28 +349,28 @@ var Draggable = Class.create({
this.originalScrollTop = this.options.scroll.scrollTop; this.originalScrollTop = this.options.scroll.scrollTop;
} }
} }
Draggables.notify('onStart', this, event); Draggables.notify('onStart', this, event);
if(this.options.starteffect) this.options.starteffect(this.element); if(this.options.starteffect) this.options.starteffect(this.element);
}, },
updateDrag: function(event, pointer) { updateDrag: function(event, pointer) {
if(!this.dragging) this.startDrag(event); if(!this.dragging) this.startDrag(event);
if(!this.options.quiet){ if(!this.options.quiet){
Position.prepare(); Position.prepare();
Droppables.show(pointer, this.element); Droppables.show(pointer, this.element);
} }
Draggables.notify('onDrag', this, event); Draggables.notify('onDrag', this, event);
this.draw(pointer); this.draw(pointer);
if(this.options.change) this.options.change(this); if(this.options.change) this.options.change(this);
if(this.options.scroll) { if(this.options.scroll) {
this.stopScrolling(); this.stopScrolling();
var p; var p;
if (this.options.scroll == window) { if (this.options.scroll == window) {
with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; } with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
@ -388,16 +388,16 @@ var Draggable = Class.create({
if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity); if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
this.startScrolling(speed); this.startScrolling(speed);
} }
// fix AppleWebKit rendering // fix AppleWebKit rendering
if(Prototype.Browser.WebKit) window.scrollBy(0,0); if(Prototype.Browser.WebKit) window.scrollBy(0,0);
Event.stop(event); Event.stop(event);
}, },
finishDrag: function(event, success) { finishDrag: function(event, success) {
this.dragging = false; this.dragging = false;
if(this.options.quiet){ if(this.options.quiet){
Position.prepare(); Position.prepare();
var pointer = [Event.pointerX(event), Event.pointerY(event)]; var pointer = [Event.pointerX(event), Event.pointerY(event)];
@ -405,24 +405,24 @@ var Draggable = Class.create({
} }
if(this.options.ghosting) { if(this.options.ghosting) {
if (!this.element._originallyAbsolute) if (!this._originallyAbsolute)
Position.relativize(this.element); Position.relativize(this.element);
delete this.element._originallyAbsolute; delete this._originallyAbsolute;
Element.remove(this._clone); Element.remove(this._clone);
this._clone = null; this._clone = null;
} }
var dropped = false; var dropped = false;
if(success) { if(success) {
dropped = Droppables.fire(event, this.element); dropped = Droppables.fire(event, this.element);
if (!dropped) dropped = false; if (!dropped) dropped = false;
} }
if(dropped && this.options.onDropped) this.options.onDropped(this.element); if(dropped && this.options.onDropped) this.options.onDropped(this.element);
Draggables.notify('onEnd', this, event); Draggables.notify('onEnd', this, event);
var revert = this.options.revert; var revert = this.options.revert;
if(revert && Object.isFunction(revert)) revert = revert(this.element); if(revert && Object.isFunction(revert)) revert = revert(this.element);
var d = this.currentDelta(); var d = this.currentDelta();
if(revert && this.options.reverteffect) { if(revert && this.options.reverteffect) {
if (dropped == 0 || revert != 'failure') if (dropped == 0 || revert != 'failure')
@ -435,67 +435,67 @@ var Draggable = Class.create({
if(this.options.zindex) if(this.options.zindex)
this.element.style.zIndex = this.originalZ; this.element.style.zIndex = this.originalZ;
if(this.options.endeffect) if(this.options.endeffect)
this.options.endeffect(this.element); this.options.endeffect(this.element);
Draggables.deactivate(this); Draggables.deactivate(this);
Droppables.reset(); Droppables.reset();
}, },
keyPress: function(event) { keyPress: function(event) {
if(event.keyCode!=Event.KEY_ESC) return; if(event.keyCode!=Event.KEY_ESC) return;
this.finishDrag(event, false); this.finishDrag(event, false);
Event.stop(event); Event.stop(event);
}, },
endDrag: function(event) { endDrag: function(event) {
if(!this.dragging) return; if(!this.dragging) return;
this.stopScrolling(); this.stopScrolling();
this.finishDrag(event, true); this.finishDrag(event, true);
Event.stop(event); Event.stop(event);
}, },
draw: function(point) { draw: function(point) {
var pos = Position.cumulativeOffset(this.element); var pos = Position.cumulativeOffset(this.element);
if(this.options.ghosting) { if(this.options.ghosting) {
var r = Position.realOffset(this.element); var r = Position.realOffset(this.element);
pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY; pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
} }
var d = this.currentDelta(); var d = this.currentDelta();
pos[0] -= d[0]; pos[1] -= d[1]; pos[0] -= d[0]; pos[1] -= d[1];
if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) { if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft; pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop; pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
} }
var p = [0,1].map(function(i){ var p = [0,1].map(function(i){
return (point[i]-pos[i]-this.offset[i]) return (point[i]-pos[i]-this.offset[i])
}.bind(this)); }.bind(this));
if(this.options.snap) { if(this.options.snap) {
if(Object.isFunction(this.options.snap)) { if(Object.isFunction(this.options.snap)) {
p = this.options.snap(p[0],p[1],this); p = this.options.snap(p[0],p[1],this);
} else { } else {
if(Object.isArray(this.options.snap)) { if(Object.isArray(this.options.snap)) {
p = p.map( function(v, i) { p = p.map( function(v, i) {
return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this)) return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this));
} else { } else {
p = p.map( function(v) { p = p.map( function(v) {
return (v/this.options.snap).round()*this.options.snap }.bind(this)) return (v/this.options.snap).round()*this.options.snap }.bind(this));
} }
}} }}
var style = this.element.style; var style = this.element.style;
if((!this.options.constraint) || (this.options.constraint=='horizontal')) if((!this.options.constraint) || (this.options.constraint=='horizontal'))
style.left = p[0] + "px"; style.left = p[0] + "px";
if((!this.options.constraint) || (this.options.constraint=='vertical')) if((!this.options.constraint) || (this.options.constraint=='vertical'))
style.top = p[1] + "px"; style.top = p[1] + "px";
if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
}, },
stopScrolling: function() { stopScrolling: function() {
if(this.scrollInterval) { if(this.scrollInterval) {
clearInterval(this.scrollInterval); clearInterval(this.scrollInterval);
@ -503,14 +503,14 @@ var Draggable = Class.create({
Draggables._lastScrollPointer = null; Draggables._lastScrollPointer = null;
} }
}, },
startScrolling: function(speed) { startScrolling: function(speed) {
if(!(speed[0] || speed[1])) return; if(!(speed[0] || speed[1])) return;
this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed]; this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
this.lastScrolled = new Date(); this.lastScrolled = new Date();
this.scrollInterval = setInterval(this.scroll.bind(this), 10); this.scrollInterval = setInterval(this.scroll.bind(this), 10);
}, },
scroll: function() { scroll: function() {
var current = new Date(); var current = new Date();
var delta = current - this.lastScrolled; var delta = current - this.lastScrolled;
@ -526,7 +526,7 @@ var Draggable = Class.create({
this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000; this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000; this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
} }
Position.prepare(); Position.prepare();
Droppables.show(Draggables._lastPointer, this.element); Droppables.show(Draggables._lastPointer, this.element);
Draggables.notify('onDrag', this); Draggables.notify('onDrag', this);
@ -540,10 +540,10 @@ var Draggable = Class.create({
Draggables._lastScrollPointer[1] = 0; Draggables._lastScrollPointer[1] = 0;
this.draw(Draggables._lastScrollPointer); this.draw(Draggables._lastScrollPointer);
} }
if(this.options.change) this.options.change(this); if(this.options.change) this.options.change(this);
}, },
_getWindowScroll: function(w) { _getWindowScroll: function(w) {
var T, L, W, H; var T, L, W, H;
with (w.document) { with (w.document) {
@ -562,7 +562,7 @@ var Draggable = Class.create({
H = documentElement.clientHeight; H = documentElement.clientHeight;
} else { } else {
W = body.offsetWidth; W = body.offsetWidth;
H = body.offsetHeight H = body.offsetHeight;
} }
} }
return { top: T, left: L, width: W, height: H }; return { top: T, left: L, width: W, height: H };
@ -579,11 +579,11 @@ var SortableObserver = Class.create({
this.observer = observer; this.observer = observer;
this.lastValue = Sortable.serialize(this.element); this.lastValue = Sortable.serialize(this.element);
}, },
onStart: function() { onStart: function() {
this.lastValue = Sortable.serialize(this.element); this.lastValue = Sortable.serialize(this.element);
}, },
onEnd: function() { onEnd: function() {
Sortable.unmark(); Sortable.unmark();
if(this.lastValue != Sortable.serialize(this.element)) if(this.lastValue != Sortable.serialize(this.element))
@ -593,11 +593,11 @@ var SortableObserver = Class.create({
var Sortable = { var Sortable = {
SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/, SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
sortables: { }, sortables: { },
_findRootElement: function(element) { _findRootElement: function(element) {
while (element.tagName.toUpperCase() != "BODY") { while (element.tagName.toUpperCase() != "BODY") {
if(element.id && Sortable.sortables[element.id]) return element; if(element.id && Sortable.sortables[element.id]) return element;
element = element.parentNode; element = element.parentNode;
} }
@ -608,22 +608,23 @@ var Sortable = {
if(!element) return; if(!element) return;
return Sortable.sortables[element.id]; return Sortable.sortables[element.id];
}, },
destroy: function(element){ destroy: function(element){
var s = Sortable.options(element); element = $(element);
var s = Sortable.sortables[element.id];
if(s) { if(s) {
Draggables.removeObserver(s.element); Draggables.removeObserver(s.element);
s.droppables.each(function(d){ Droppables.remove(d) }); s.droppables.each(function(d){ Droppables.remove(d) });
s.draggables.invoke('destroy'); s.draggables.invoke('destroy');
delete Sortable.sortables[s.element.id]; delete Sortable.sortables[s.element.id];
} }
}, },
create: function(element) { create: function(element) {
element = $(element); element = $(element);
var options = Object.extend({ var options = Object.extend({
element: element, element: element,
tag: 'li', // assumes li children, override with tag: 'tagname' tag: 'li', // assumes li children, override with tag: 'tagname'
dropOnEmpty: false, dropOnEmpty: false,
@ -637,17 +638,17 @@ var Sortable = {
delay: 0, delay: 0,
hoverclass: null, hoverclass: null,
ghosting: false, ghosting: false,
quiet: false, quiet: false,
scroll: false, scroll: false,
scrollSensitivity: 20, scrollSensitivity: 20,
scrollSpeed: 15, scrollSpeed: 15,
format: this.SERIALIZE_RULE, format: this.SERIALIZE_RULE,
// these take arrays of elements or ids and can be // these take arrays of elements or ids and can be
// used for better initialization performance // used for better initialization performance
elements: false, elements: false,
handles: false, handles: false,
onChange: Prototype.emptyFunction, onChange: Prototype.emptyFunction,
onUpdate: Prototype.emptyFunction onUpdate: Prototype.emptyFunction
}, arguments[1] || { }); }, arguments[1] || { });
@ -684,24 +685,24 @@ var Sortable = {
if(options.zindex) if(options.zindex)
options_for_draggable.zindex = options.zindex; options_for_draggable.zindex = options.zindex;
// build options for the droppables // build options for the droppables
var options_for_droppable = { var options_for_droppable = {
overlap: options.overlap, overlap: options.overlap,
containment: options.containment, containment: options.containment,
tree: options.tree, tree: options.tree,
hoverclass: options.hoverclass, hoverclass: options.hoverclass,
onHover: Sortable.onHover onHover: Sortable.onHover
} };
var options_for_tree = { var options_for_tree = {
onHover: Sortable.onEmptyHover, onHover: Sortable.onEmptyHover,
overlap: options.overlap, overlap: options.overlap,
containment: options.containment, containment: options.containment,
hoverclass: options.hoverclass hoverclass: options.hoverclass
} };
// fix for gecko engine // fix for gecko engine
Element.cleanWhitespace(element); Element.cleanWhitespace(element);
options.draggables = []; options.draggables = [];
options.droppables = []; options.droppables = [];
@ -714,14 +715,14 @@ var Sortable = {
(options.elements || this.findElements(element, options) || []).each( function(e,i) { (options.elements || this.findElements(element, options) || []).each( function(e,i) {
var handle = options.handles ? $(options.handles[i]) : var handle = options.handles ? $(options.handles[i]) :
(options.handle ? $(e).select('.' + options.handle)[0] : e); (options.handle ? $(e).select('.' + options.handle)[0] : e);
options.draggables.push( options.draggables.push(
new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
Droppables.add(e, options_for_droppable); Droppables.add(e, options_for_droppable);
if(options.tree) e.treeNode = element; if(options.tree) e.treeNode = element;
options.droppables.push(e); options.droppables.push(e);
}); });
if(options.tree) { if(options.tree) {
(Sortable.findTreeElements(element, options) || []).each( function(e) { (Sortable.findTreeElements(element, options) || []).each( function(e) {
Droppables.add(e, options_for_tree); Droppables.add(e, options_for_tree);
@ -743,7 +744,7 @@ var Sortable = {
return Element.findChildren( return Element.findChildren(
element, options.only, options.tree ? true : false, options.tag); element, options.only, options.tree ? true : false, options.tag);
}, },
findTreeElements: function(element, options) { findTreeElements: function(element, options) {
return Element.findChildren( return Element.findChildren(
element, options.only, options.tree ? true : false, options.treeTag); element, options.only, options.tree ? true : false, options.treeTag);
@ -760,7 +761,7 @@ var Sortable = {
var oldParentNode = element.parentNode; var oldParentNode = element.parentNode;
element.style.visibility = "hidden"; // fix gecko rendering element.style.visibility = "hidden"; // fix gecko rendering
dropon.parentNode.insertBefore(element, dropon); dropon.parentNode.insertBefore(element, dropon);
if(dropon.parentNode!=oldParentNode) if(dropon.parentNode!=oldParentNode)
Sortable.options(oldParentNode).onChange(element); Sortable.options(oldParentNode).onChange(element);
Sortable.options(dropon.parentNode).onChange(element); Sortable.options(dropon.parentNode).onChange(element);
} }
@ -771,26 +772,26 @@ var Sortable = {
var oldParentNode = element.parentNode; var oldParentNode = element.parentNode;
element.style.visibility = "hidden"; // fix gecko rendering element.style.visibility = "hidden"; // fix gecko rendering
dropon.parentNode.insertBefore(element, nextElement); dropon.parentNode.insertBefore(element, nextElement);
if(dropon.parentNode!=oldParentNode) if(dropon.parentNode!=oldParentNode)
Sortable.options(oldParentNode).onChange(element); Sortable.options(oldParentNode).onChange(element);
Sortable.options(dropon.parentNode).onChange(element); Sortable.options(dropon.parentNode).onChange(element);
} }
} }
}, },
onEmptyHover: function(element, dropon, overlap) { onEmptyHover: function(element, dropon, overlap) {
var oldParentNode = element.parentNode; var oldParentNode = element.parentNode;
var droponOptions = Sortable.options(dropon); var droponOptions = Sortable.options(dropon);
if(!Element.isParent(dropon, element)) { if(!Element.isParent(dropon, element)) {
var index; var index;
var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only}); var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
var child = null; var child = null;
if(children) { if(children) {
var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap); var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
for (index = 0; index < children.length; index += 1) { for (index = 0; index < children.length; index += 1) {
if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) { if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
offset -= Element.offsetSize (children[index], droponOptions.overlap); offset -= Element.offsetSize (children[index], droponOptions.overlap);
@ -803,9 +804,9 @@ var Sortable = {
} }
} }
} }
dropon.insertBefore(element, child); dropon.insertBefore(element, child);
Sortable.options(oldParentNode).onChange(element); Sortable.options(oldParentNode).onChange(element);
droponOptions.onChange(element); droponOptions.onChange(element);
} }
@ -818,34 +819,34 @@ var Sortable = {
mark: function(dropon, position) { mark: function(dropon, position) {
// mark on ghosting only // mark on ghosting only
var sortable = Sortable.options(dropon.parentNode); var sortable = Sortable.options(dropon.parentNode);
if(sortable && !sortable.ghosting) return; if(sortable && !sortable.ghosting) return;
if(!Sortable._marker) { if(!Sortable._marker) {
Sortable._marker = Sortable._marker =
($('dropmarker') || Element.extend(document.createElement('DIV'))). ($('dropmarker') || Element.extend(document.createElement('DIV'))).
hide().addClassName('dropmarker').setStyle({position:'absolute'}); hide().addClassName('dropmarker').setStyle({position:'absolute'});
document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
} }
var offsets = Position.cumulativeOffset(dropon); var offsets = Position.cumulativeOffset(dropon);
Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'}); Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
if(position=='after') if(position=='after')
if(sortable.overlap == 'horizontal') if(sortable.overlap == 'horizontal')
Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'}); Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
else else
Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'}); Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
Sortable._marker.show(); Sortable._marker.show();
}, },
_tree: function(element, options, parent) { _tree: function(element, options, parent) {
var children = Sortable.findElements(element, options) || []; var children = Sortable.findElements(element, options) || [];
for (var i = 0; i < children.length; ++i) { for (var i = 0; i < children.length; ++i) {
var match = children[i].id.match(options.format); var match = children[i].id.match(options.format);
if (!match) continue; if (!match) continue;
var child = { var child = {
id: encodeURIComponent(match ? match[1] : null), id: encodeURIComponent(match ? match[1] : null),
element: element, element: element,
@ -853,16 +854,16 @@ var Sortable = {
children: [], children: [],
position: parent.children.length, position: parent.children.length,
container: $(children[i]).down(options.treeTag) container: $(children[i]).down(options.treeTag)
} };
/* Get the element containing the children and recurse over it */ /* Get the element containing the children and recurse over it */
if (child.container) if (child.container)
this._tree(child.container, options, child) this._tree(child.container, options, child);
parent.children.push (child); parent.children.push (child);
} }
return parent; return parent;
}, },
tree: function(element) { tree: function(element) {
@ -875,15 +876,15 @@ var Sortable = {
name: element.id, name: element.id,
format: sortableOptions.format format: sortableOptions.format
}, arguments[1] || { }); }, arguments[1] || { });
var root = { var root = {
id: null, id: null,
parent: null, parent: null,
children: [], children: [],
container: element, container: element,
position: 0 position: 0
} };
return Sortable._tree(element, options, root); return Sortable._tree(element, options, root);
}, },
@ -899,7 +900,7 @@ var Sortable = {
sequence: function(element) { sequence: function(element) {
element = $(element); element = $(element);
var options = Object.extend(this.options(element), arguments[1] || { }); var options = Object.extend(this.options(element), arguments[1] || { });
return $(this.findElements(element, options) || []).map( function(item) { return $(this.findElements(element, options) || []).map( function(item) {
return item.id.match(options.format) ? item.id.match(options.format)[1] : ''; return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
}); });
@ -908,14 +909,14 @@ var Sortable = {
setSequence: function(element, new_sequence) { setSequence: function(element, new_sequence) {
element = $(element); element = $(element);
var options = Object.extend(this.options(element), arguments[2] || { }); var options = Object.extend(this.options(element), arguments[2] || { });
var nodeMap = { }; var nodeMap = { };
this.findElements(element, options).each( function(n) { this.findElements(element, options).each( function(n) {
if (n.id.match(options.format)) if (n.id.match(options.format))
nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode]; nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
n.parentNode.removeChild(n); n.parentNode.removeChild(n);
}); });
new_sequence.each(function(ident) { new_sequence.each(function(ident) {
var n = nodeMap[ident]; var n = nodeMap[ident];
if (n) { if (n) {
@ -924,16 +925,16 @@ var Sortable = {
} }
}); });
}, },
serialize: function(element) { serialize: function(element) {
element = $(element); element = $(element);
var options = Object.extend(Sortable.options(element), arguments[1] || { }); var options = Object.extend(Sortable.options(element), arguments[1] || { });
var name = encodeURIComponent( var name = encodeURIComponent(
(arguments[1] && arguments[1].name) ? arguments[1].name : element.id); (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
if (options.tree) { if (options.tree) {
return Sortable.tree(element, arguments[1]).children.map( function (item) { return Sortable.tree(element, arguments[1]).children.map( function (item) {
return [name + Sortable._constructIndex(item) + "[id]=" + return [name + Sortable._constructIndex(item) + "[id]=" +
encodeURIComponent(item.id)].concat(item.children.map(arguments.callee)); encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
}).flatten().join('&'); }).flatten().join('&');
} else { } else {
@ -942,16 +943,16 @@ var Sortable = {
}).join('&'); }).join('&');
} }
} }
} };
// Returns true if child is contained within element // Returns true if child is contained within element
Element.isParent = function(child, element) { Element.isParent = function(child, element) {
if (!child.parentNode || child == element) return false; if (!child.parentNode || child == element) return false;
if (child.parentNode == element) return true; if (child.parentNode == element) return true;
return Element.isParent(child.parentNode, element); return Element.isParent(child.parentNode, element);
} };
Element.findChildren = function(element, only, recursive, tagName) { Element.findChildren = function(element, only, recursive, tagName) {
if(!element.hasChildNodes()) return null; if(!element.hasChildNodes()) return null;
tagName = tagName.toUpperCase(); tagName = tagName.toUpperCase();
if(only) only = [only].flatten(); if(only) only = [only].flatten();
@ -967,8 +968,8 @@ Element.findChildren = function(element, only, recursive, tagName) {
}); });
return (elements.length>0 ? elements.flatten() : []); return (elements.length>0 ? elements.flatten() : []);
} };
Element.offsetSize = function (element, type) { Element.offsetSize = function (element, type) {
return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')]; return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
} };

View File

@ -1,50 +1,50 @@
// script.aculo.us effects.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008 // script.aculo.us effects.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// Contributors: // Contributors:
// Justin Palmer (http://encytemedia.com/) // Justin Palmer (http://encytemedia.com/)
// Mark Pilgrim (http://diveintomark.org/) // Mark Pilgrim (http://diveintomark.org/)
// Martin Bialasinki // Martin Bialasinki
// //
// script.aculo.us is freely distributable under the terms of an MIT-style license. // script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/ // For details, see the script.aculo.us web site: http://script.aculo.us/
// converts rgb() and #xxx to #xxxxxx format, // converts rgb() and #xxx to #xxxxxx format,
// returns self (or first argument) if not convertable // returns self (or first argument) if not convertable
String.prototype.parseColor = function() { String.prototype.parseColor = function() {
var color = '#'; var color = '#';
if (this.slice(0,4) == 'rgb(') { if (this.slice(0,4) == 'rgb(') {
var cols = this.slice(4,this.length-1).split(','); var cols = this.slice(4,this.length-1).split(',');
var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
} else { } else {
if (this.slice(0,1) == '#') { 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==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
if (this.length==7) color = this.toLowerCase(); if (this.length==7) color = this.toLowerCase();
} }
} }
return (color.length==7 ? color : (arguments[0] || this)); return (color.length==7 ? color : (arguments[0] || this));
}; };
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
Element.collectTextNodes = function(element) { Element.collectTextNodes = function(element) {
return $A($(element).childNodes).collect( function(node) { return $A($(element).childNodes).collect( function(node) {
return (node.nodeType==3 ? node.nodeValue : return (node.nodeType==3 ? node.nodeValue :
(node.hasChildNodes() ? Element.collectTextNodes(node) : '')); (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
}).flatten().join(''); }).flatten().join('');
}; };
Element.collectTextNodesIgnoreClass = function(element, className) { Element.collectTextNodesIgnoreClass = function(element, className) {
return $A($(element).childNodes).collect( function(node) { return $A($(element).childNodes).collect( function(node) {
return (node.nodeType==3 ? node.nodeValue : return (node.nodeType==3 ? node.nodeValue :
((node.hasChildNodes() && !Element.hasClassName(node,className)) ? ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
Element.collectTextNodesIgnoreClass(node, className) : '')); Element.collectTextNodesIgnoreClass(node, className) : ''));
}).flatten().join(''); }).flatten().join('');
}; };
Element.setContentZoom = function(element, percent) { Element.setContentZoom = function(element, percent) {
element = $(element); element = $(element);
element.setStyle({fontSize: (percent/100) + 'em'}); element.setStyle({fontSize: (percent/100) + 'em'});
if (Prototype.Browser.WebKit) window.scrollBy(0,0); if (Prototype.Browser.WebKit) window.scrollBy(0,0);
return element; return element;
}; };
@ -72,28 +72,23 @@ var Effect = {
Transitions: { Transitions: {
linear: Prototype.K, linear: Prototype.K,
sinoidal: function(pos) { sinoidal: function(pos) {
return (-Math.cos(pos*Math.PI)/2) + 0.5; return (-Math.cos(pos*Math.PI)/2) + .5;
}, },
reverse: function(pos) { reverse: function(pos) {
return 1-pos; return 1-pos;
}, },
flicker: function(pos) { flicker: function(pos) {
var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
return pos > 1 ? 1 : pos; return pos > 1 ? 1 : pos;
}, },
wobble: function(pos) { wobble: function(pos) {
return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
}, },
pulse: function(pos, pulses) { pulse: function(pos, pulses) {
pulses = pulses || 5; return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
return (
((pos % (1/pulses)) * pulses).round() == 0 ?
((pos * pulses * 2) - (pos * pulses * 2).floor()) :
1 - ((pos * pulses * 2) - (pos * pulses * 2).floor())
);
}, },
spring: function(pos) { spring: function(pos) {
return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
}, },
none: function(pos) { none: function(pos) {
return 0; return 0;
@ -114,14 +109,14 @@ var Effect = {
tagifyText: function(element) { tagifyText: function(element) {
var tagifyStyle = 'position:relative'; var tagifyStyle = 'position:relative';
if (Prototype.Browser.IE) tagifyStyle += ';zoom:1'; if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
element = $(element); element = $(element);
$A(element.childNodes).each( function(child) { $A(element.childNodes).each( function(child) {
if (child.nodeType==3) { if (child.nodeType==3) {
child.nodeValue.toArray().each( function(character) { child.nodeValue.toArray().each( function(character) {
element.insertBefore( element.insertBefore(
new Element('span', {style: tagifyStyle}).update( new Element('span', {style: tagifyStyle}).update(
character == ' ' ? String.fromCharCode(160) : character), character == ' ' ? String.fromCharCode(160) : character),
child); child);
}); });
Element.remove(child); Element.remove(child);
@ -130,13 +125,13 @@ var Effect = {
}, },
multiple: function(element, effect) { multiple: function(element, effect) {
var elements; var elements;
if (((typeof element == 'object') || if (((typeof element == 'object') ||
Object.isFunction(element)) && Object.isFunction(element)) &&
(element.length)) (element.length))
elements = element; elements = element;
else else
elements = $(element).childNodes; elements = $(element).childNodes;
var options = Object.extend({ var options = Object.extend({
speed: 0.1, speed: 0.1,
delay: 0.0 delay: 0.0
@ -158,7 +153,7 @@ var Effect = {
var options = Object.extend({ var options = Object.extend({
queue: { position:'end', scope:(element.id || 'global'), limit: 1 } queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
}, arguments[2] || { }); }, arguments[2] || { });
Effect[element.visible() ? Effect[element.visible() ?
Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options); Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
} }
}; };
@ -170,20 +165,20 @@ Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;
Effect.ScopedQueue = Class.create(Enumerable, { Effect.ScopedQueue = Class.create(Enumerable, {
initialize: function() { initialize: function() {
this.effects = []; this.effects = [];
this.interval = null; this.interval = null;
}, },
_each: function(iterator) { _each: function(iterator) {
this.effects._each(iterator); this.effects._each(iterator);
}, },
add: function(effect) { add: function(effect) {
var timestamp = new Date().getTime(); var timestamp = new Date().getTime();
var position = Object.isString(effect.options.queue) ? var position = Object.isString(effect.options.queue) ?
effect.options.queue : effect.options.queue.position; effect.options.queue : effect.options.queue.position;
switch(position) { switch(position) {
case 'front': case 'front':
// move unstarted effects after this effect // move unstarted effects after this effect
this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) { this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
e.startOn += effect.finishOn; e.startOn += effect.finishOn;
e.finishOn += effect.finishOn; e.finishOn += effect.finishOn;
@ -197,13 +192,13 @@ Effect.ScopedQueue = Class.create(Enumerable, {
timestamp = this.effects.pluck('finishOn').max() || timestamp; timestamp = this.effects.pluck('finishOn').max() || timestamp;
break; break;
} }
effect.startOn += timestamp; effect.startOn += timestamp;
effect.finishOn += timestamp; effect.finishOn += timestamp;
if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit)) if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
this.effects.push(effect); this.effects.push(effect);
if (!this.interval) if (!this.interval)
this.interval = setInterval(this.loop.bind(this), 15); this.interval = setInterval(this.loop.bind(this), 15);
}, },
@ -216,7 +211,7 @@ Effect.ScopedQueue = Class.create(Enumerable, {
}, },
loop: function() { loop: function() {
var timePos = new Date().getTime(); var timePos = new Date().getTime();
for(var i=0, len=this.effects.length;i<len;i++) for(var i=0, len=this.effects.length;i<len;i++)
this.effects[i] && this.effects[i].loop(timePos); this.effects[i] && this.effects[i].loop(timePos);
} }
}); });
@ -225,7 +220,7 @@ Effect.Queues = {
instances: $H(), instances: $H(),
get: function(queueName) { get: function(queueName) {
if (!Object.isString(queueName)) return queueName; if (!Object.isString(queueName)) return queueName;
return this.instances.get(queueName) || return this.instances.get(queueName) ||
this.instances.set(queueName, new Effect.ScopedQueue()); this.instances.set(queueName, new Effect.ScopedQueue());
} }
@ -250,23 +245,35 @@ Effect.Base = Class.create({
this.fromToDelta = this.options.to-this.options.from; this.fromToDelta = this.options.to-this.options.from;
this.totalTime = this.finishOn-this.startOn; this.totalTime = this.finishOn-this.startOn;
this.totalFrames = this.options.fps*this.options.duration; this.totalFrames = this.options.fps*this.options.duration;
eval('this.render = function(pos){ '+ this.render = (function() {
'if (this.state=="idle"){this.state="running";'+ function dispatch(effect, eventName) {
codeForEvent(this.options,'beforeSetup')+ if (effect.options[eventName + 'Internal'])
(this.setup ? 'this.setup();':'')+ effect.options[eventName + 'Internal'](effect);
codeForEvent(this.options,'afterSetup')+ if (effect.options[eventName])
'};if (this.state=="running"){'+ effect.options[eventName](effect);
'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+ }
'this.position=pos;'+
codeForEvent(this.options,'beforeUpdate')+ return function(pos) {
(this.update ? 'this.update(pos);':'')+ if (this.state === "idle") {
codeForEvent(this.options,'afterUpdate')+ 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'); this.event('beforeStart');
if (!this.options.sync) if (!this.options.sync)
Effect.Queues.get(Object.isString(this.options.queue) ? Effect.Queues.get(Object.isString(this.options.queue) ?
'global' : this.options.queue.scope).add(this); 'global' : this.options.queue.scope).add(this);
}, },
loop: function(timePos) { loop: function(timePos) {
@ -275,9 +282,9 @@ Effect.Base = Class.create({
this.render(1.0); this.render(1.0);
this.cancel(); this.cancel();
this.event('beforeFinish'); this.event('beforeFinish');
if (this.finish) this.finish(); if (this.finish) this.finish();
this.event('afterFinish'); this.event('afterFinish');
return; return;
} }
var pos = (timePos - this.startOn) / this.totalTime, var pos = (timePos - this.startOn) / this.totalTime,
frame = (pos * this.totalFrames).round(); frame = (pos * this.totalFrames).round();
@ -289,7 +296,7 @@ Effect.Base = Class.create({
}, },
cancel: function() { cancel: function() {
if (!this.options.sync) if (!this.options.sync)
Effect.Queues.get(Object.isString(this.options.queue) ? Effect.Queues.get(Object.isString(this.options.queue) ?
'global' : this.options.queue.scope).remove(this); 'global' : this.options.queue.scope).remove(this);
this.state = 'finished'; this.state = 'finished';
}, },
@ -327,10 +334,10 @@ Effect.Parallel = Class.create(Effect.Base, {
Effect.Tween = Class.create(Effect.Base, { Effect.Tween = Class.create(Effect.Base, {
initialize: function(object, from, to) { initialize: function(object, from, to) {
object = Object.isString(object) ? $(object) : object; object = Object.isString(object) ? $(object) : object;
var args = $A(arguments), method = args.last(), var args = $A(arguments), method = args.last(),
options = args.length == 5 ? args[3] : null; options = args.length == 5 ? args[3] : null;
this.method = Object.isFunction(method) ? method.bind(object) : this.method = Object.isFunction(method) ? method.bind(object) :
Object.isFunction(object[method]) ? object[method].bind(object) : Object.isFunction(object[method]) ? object[method].bind(object) :
function(value) { object[method] = value }; function(value) { object[method] = value };
this.start(Object.extend({ from: from, to: to }, options || { })); this.start(Object.extend({ from: from, to: to }, options || { }));
}, },
@ -394,7 +401,7 @@ Effect.Move = Class.create(Effect.Base, {
// for backwards compatibility // for backwards compatibility
Effect.MoveBy = function(element, toTop, toLeft) { Effect.MoveBy = function(element, toTop, toLeft) {
return new Effect.Move(element, return new Effect.Move(element,
Object.extend({ x: toLeft, y: toTop }, arguments[3] || { })); Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
}; };
@ -416,15 +423,15 @@ Effect.Scale = Class.create(Effect.Base, {
setup: function() { setup: function() {
this.restoreAfterFinish = this.options.restoreAfterFinish || false; this.restoreAfterFinish = this.options.restoreAfterFinish || false;
this.elementPositioning = this.element.getStyle('position'); this.elementPositioning = this.element.getStyle('position');
this.originalStyle = { }; this.originalStyle = { };
['top','left','width','height','fontSize'].each( function(k) { ['top','left','width','height','fontSize'].each( function(k) {
this.originalStyle[k] = this.element.style[k]; this.originalStyle[k] = this.element.style[k];
}.bind(this)); }.bind(this));
this.originalTop = this.element.offsetTop; this.originalTop = this.element.offsetTop;
this.originalLeft = this.element.offsetLeft; this.originalLeft = this.element.offsetLeft;
var fontSize = this.element.getStyle('font-size') || '100%'; var fontSize = this.element.getStyle('font-size') || '100%';
['em','px','%','pt'].each( function(fontSizeType) { ['em','px','%','pt'].each( function(fontSizeType) {
if (fontSize.indexOf(fontSizeType)>0) { if (fontSize.indexOf(fontSizeType)>0) {
@ -432,9 +439,9 @@ Effect.Scale = Class.create(Effect.Base, {
this.fontSizeType = fontSizeType; this.fontSizeType = fontSizeType;
} }
}.bind(this)); }.bind(this));
this.factor = (this.options.scaleTo - this.options.scaleFrom)/100; this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
this.dims = null; this.dims = null;
if (this.options.scaleMode=='box') if (this.options.scaleMode=='box')
this.dims = [this.element.offsetHeight, this.element.offsetWidth]; this.dims = [this.element.offsetHeight, this.element.offsetWidth];
@ -509,17 +516,16 @@ Effect.Highlight = Class.create(Effect.Base, {
Effect.ScrollTo = function(element) { Effect.ScrollTo = function(element) {
var options = arguments[1] || { }, var options = arguments[1] || { },
scrollOffsets = document.viewport.getScrollOffsets(), scrollOffsets = document.viewport.getScrollOffsets(),
elementOffsets = $(element).cumulativeOffset(), elementOffsets = $(element).cumulativeOffset();
max = (window.height || document.body.scrollHeight) - document.viewport.getHeight();
if (options.offset) elementOffsets[1] += options.offset; if (options.offset) elementOffsets[1] += options.offset;
return new Effect.Tween(null, return new Effect.Tween(null,
scrollOffsets.top, scrollOffsets.top,
elementOffsets[1] > max ? max : elementOffsets[1], elementOffsets[1],
options, options,
function(p){ scrollTo(scrollOffsets.left, p.round()) } function(p){ scrollTo(scrollOffsets.left, p.round()); }
); );
}; };
@ -531,9 +537,9 @@ Effect.Fade = function(element) {
var options = Object.extend({ var options = Object.extend({
from: element.getOpacity() || 1.0, from: element.getOpacity() || 1.0,
to: 0.0, to: 0.0,
afterFinishInternal: function(effect) { afterFinishInternal: function(effect) {
if (effect.options.to!=0) return; if (effect.options.to!=0) return;
effect.element.hide().setStyle({opacity: oldOpacity}); effect.element.hide().setStyle({opacity: oldOpacity});
} }
}, arguments[1] || { }); }, arguments[1] || { });
return new Effect.Opacity(element,options); return new Effect.Opacity(element,options);
@ -549,15 +555,15 @@ Effect.Appear = function(element) {
effect.element.forceRerendering(); effect.element.forceRerendering();
}, },
beforeSetup: function(effect) { beforeSetup: function(effect) {
effect.element.setOpacity(effect.options.from).show(); effect.element.setOpacity(effect.options.from).show();
}}, arguments[1] || { }); }}, arguments[1] || { });
return new Effect.Opacity(element,options); return new Effect.Opacity(element,options);
}; };
Effect.Puff = function(element) { Effect.Puff = function(element) {
element = $(element); element = $(element);
var oldStyle = { var oldStyle = {
opacity: element.getInlineOpacity(), opacity: element.getInlineOpacity(),
position: element.getStyle('position'), position: element.getStyle('position'),
top: element.style.top, top: element.style.top,
left: element.style.left, left: element.style.left,
@ -565,12 +571,12 @@ Effect.Puff = function(element) {
height: element.style.height height: element.style.height
}; };
return new Effect.Parallel( return new Effect.Parallel(
[ new Effect.Scale(element, 200, [ new Effect.Scale(element, 200,
{ sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
Object.extend({ duration: 1.0, Object.extend({ duration: 1.0,
beforeSetupInternal: function(effect) { beforeSetupInternal: function(effect) {
Position.absolutize(effect.effects[0].element) Position.absolutize(effect.effects[0].element);
}, },
afterFinishInternal: function(effect) { afterFinishInternal: function(effect) {
effect.effects[0].element.hide().setStyle(oldStyle); } effect.effects[0].element.hide().setStyle(oldStyle); }
@ -582,12 +588,12 @@ Effect.BlindUp = function(element) {
element = $(element); element = $(element);
element.makeClipping(); element.makeClipping();
return new Effect.Scale(element, 0, return new Effect.Scale(element, 0,
Object.extend({ scaleContent: false, Object.extend({ scaleContent: false,
scaleX: false, scaleX: false,
restoreAfterFinish: true, restoreAfterFinish: true,
afterFinishInternal: function(effect) { afterFinishInternal: function(effect) {
effect.element.hide().undoClipping(); effect.element.hide().undoClipping();
} }
}, arguments[1] || { }) }, arguments[1] || { })
); );
}; };
@ -595,15 +601,15 @@ Effect.BlindUp = function(element) {
Effect.BlindDown = function(element) { Effect.BlindDown = function(element) {
element = $(element); element = $(element);
var elementDimensions = element.getDimensions(); var elementDimensions = element.getDimensions();
return new Effect.Scale(element, 100, Object.extend({ return new Effect.Scale(element, 100, Object.extend({
scaleContent: false, scaleContent: false,
scaleX: false, scaleX: false,
scaleFrom: 0, scaleFrom: 0,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true, restoreAfterFinish: true,
afterSetup: function(effect) { afterSetup: function(effect) {
effect.element.makeClipping().setStyle({height: '0px'}).show(); effect.element.makeClipping().setStyle({height: '0px'}).show();
}, },
afterFinishInternal: function(effect) { afterFinishInternal: function(effect) {
effect.element.undoClipping(); effect.element.undoClipping();
} }
@ -618,16 +624,16 @@ Effect.SwitchOff = function(element) {
from: 0, from: 0,
transition: Effect.Transitions.flicker, transition: Effect.Transitions.flicker,
afterFinishInternal: function(effect) { afterFinishInternal: function(effect) {
new Effect.Scale(effect.element, 1, { new Effect.Scale(effect.element, 1, {
duration: 0.3, scaleFromCenter: true, duration: 0.3, scaleFromCenter: true,
scaleX: false, scaleContent: false, restoreAfterFinish: true, scaleX: false, scaleContent: false, restoreAfterFinish: true,
beforeSetup: function(effect) { beforeSetup: function(effect) {
effect.element.makePositioned().makeClipping(); effect.element.makePositioned().makeClipping();
}, },
afterFinishInternal: function(effect) { afterFinishInternal: function(effect) {
effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity}); effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
} }
}) });
} }
}, arguments[1] || { })); }, arguments[1] || { }));
}; };
@ -639,16 +645,16 @@ Effect.DropOut = function(element) {
left: element.getStyle('left'), left: element.getStyle('left'),
opacity: element.getInlineOpacity() }; opacity: element.getInlineOpacity() };
return new Effect.Parallel( return new Effect.Parallel(
[ new Effect.Move(element, {x: 0, y: 100, sync: true }), [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
new Effect.Opacity(element, { sync: true, to: 0.0 }) ], new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
Object.extend( Object.extend(
{ duration: 0.5, { duration: 0.5,
beforeSetup: function(effect) { beforeSetup: function(effect) {
effect.effects[0].element.makePositioned(); effect.effects[0].element.makePositioned();
}, },
afterFinishInternal: function(effect) { afterFinishInternal: function(effect) {
effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle); effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
} }
}, arguments[1] || { })); }, arguments[1] || { }));
}; };
@ -676,7 +682,7 @@ Effect.Shake = function(element) {
new Effect.Move(effect.element, new Effect.Move(effect.element,
{ x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) { { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
effect.element.undoPositioned().setStyle(oldStyle); effect.element.undoPositioned().setStyle(oldStyle);
}}) }}) }}) }}) }}) }}); }}); }}); }}); }}); }}); }});
}; };
Effect.SlideDown = function(element) { Effect.SlideDown = function(element) {
@ -684,9 +690,9 @@ Effect.SlideDown = function(element) {
// SlideDown need to have the content of the element wrapped in a container element with fixed height! // SlideDown need to have the content of the element wrapped in a container element with fixed height!
var oldInnerBottom = element.down().getStyle('bottom'); var oldInnerBottom = element.down().getStyle('bottom');
var elementDimensions = element.getDimensions(); var elementDimensions = element.getDimensions();
return new Effect.Scale(element, 100, Object.extend({ return new Effect.Scale(element, 100, Object.extend({
scaleContent: false, scaleContent: false,
scaleX: false, scaleX: false,
scaleFrom: window.opera ? 0 : 1, scaleFrom: window.opera ? 0 : 1,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true, restoreAfterFinish: true,
@ -694,11 +700,11 @@ Effect.SlideDown = function(element) {
effect.element.makePositioned(); effect.element.makePositioned();
effect.element.down().makePositioned(); effect.element.down().makePositioned();
if (window.opera) effect.element.setStyle({top: ''}); if (window.opera) effect.element.setStyle({top: ''});
effect.element.makeClipping().setStyle({height: '0px'}).show(); effect.element.makeClipping().setStyle({height: '0px'}).show();
}, },
afterUpdateInternal: function(effect) { afterUpdateInternal: function(effect) {
effect.element.down().setStyle({bottom: effect.element.down().setStyle({bottom:
(effect.dims[0] - effect.element.clientHeight) + 'px' }); (effect.dims[0] - effect.element.clientHeight) + 'px' });
}, },
afterFinishInternal: function(effect) { afterFinishInternal: function(effect) {
effect.element.undoClipping().undoPositioned(); effect.element.undoClipping().undoPositioned();
@ -712,8 +718,8 @@ Effect.SlideUp = function(element) {
var oldInnerBottom = element.down().getStyle('bottom'); var oldInnerBottom = element.down().getStyle('bottom');
var elementDimensions = element.getDimensions(); var elementDimensions = element.getDimensions();
return new Effect.Scale(element, window.opera ? 0 : 1, return new Effect.Scale(element, window.opera ? 0 : 1,
Object.extend({ scaleContent: false, Object.extend({ scaleContent: false,
scaleX: false, scaleX: false,
scaleMode: 'box', scaleMode: 'box',
scaleFrom: 100, scaleFrom: 100,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
@ -723,7 +729,7 @@ Effect.SlideUp = function(element) {
effect.element.down().makePositioned(); effect.element.down().makePositioned();
if (window.opera) effect.element.setStyle({top: ''}); if (window.opera) effect.element.setStyle({top: ''});
effect.element.makeClipping().show(); effect.element.makeClipping().show();
}, },
afterUpdateInternal: function(effect) { afterUpdateInternal: function(effect) {
effect.element.down().setStyle({bottom: effect.element.down().setStyle({bottom:
(effect.dims[0] - effect.element.clientHeight) + 'px' }); (effect.dims[0] - effect.element.clientHeight) + 'px' });
@ -736,15 +742,15 @@ Effect.SlideUp = function(element) {
); );
}; };
// Bug in opera makes the TD containing this element expand for a instance after finish // Bug in opera makes the TD containing this element expand for a instance after finish
Effect.Squish = function(element) { Effect.Squish = function(element) {
return new Effect.Scale(element, window.opera ? 1 : 0, { return new Effect.Scale(element, window.opera ? 1 : 0, {
restoreAfterFinish: true, restoreAfterFinish: true,
beforeSetup: function(effect) { beforeSetup: function(effect) {
effect.element.makeClipping(); effect.element.makeClipping();
}, },
afterFinishInternal: function(effect) { afterFinishInternal: function(effect) {
effect.element.hide().undoClipping(); effect.element.hide().undoClipping();
} }
}); });
}; };
@ -764,13 +770,13 @@ Effect.Grow = function(element) {
width: element.style.width, width: element.style.width,
opacity: element.getInlineOpacity() }; opacity: element.getInlineOpacity() };
var dims = element.getDimensions(); var dims = element.getDimensions();
var initialMoveX, initialMoveY; var initialMoveX, initialMoveY;
var moveX, moveY; var moveX, moveY;
switch (options.direction) { switch (options.direction) {
case 'top-left': case 'top-left':
initialMoveX = initialMoveY = moveX = moveY = 0; initialMoveX = initialMoveY = moveX = moveY = 0;
break; break;
case 'top-right': case 'top-right':
initialMoveX = dims.width; initialMoveX = dims.width;
@ -795,11 +801,11 @@ Effect.Grow = function(element) {
moveY = -dims.height / 2; moveY = -dims.height / 2;
break; break;
} }
return new Effect.Move(element, { return new Effect.Move(element, {
x: initialMoveX, x: initialMoveX,
y: initialMoveY, y: initialMoveY,
duration: 0.01, duration: 0.01,
beforeSetup: function(effect) { beforeSetup: function(effect) {
effect.element.hide().makeClipping().makePositioned(); effect.element.hide().makeClipping().makePositioned();
}, },
@ -808,17 +814,17 @@ Effect.Grow = function(element) {
[ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }), [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }), new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
new Effect.Scale(effect.element, 100, { new Effect.Scale(effect.element, 100, {
scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true}) sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
], Object.extend({ ], Object.extend({
beforeSetup: function(effect) { beforeSetup: function(effect) {
effect.effects[0].element.setStyle({height: '0px'}).show(); effect.effects[0].element.setStyle({height: '0px'}).show();
}, },
afterFinishInternal: function(effect) { afterFinishInternal: function(effect) {
effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
} }
}, options) }, options)
) );
} }
}); });
}; };
@ -840,7 +846,7 @@ Effect.Shrink = function(element) {
var dims = element.getDimensions(); var dims = element.getDimensions();
var moveX, moveY; var moveX, moveY;
switch (options.direction) { switch (options.direction) {
case 'top-left': case 'top-left':
moveX = moveY = 0; moveX = moveY = 0;
@ -857,19 +863,19 @@ Effect.Shrink = function(element) {
moveX = dims.width; moveX = dims.width;
moveY = dims.height; moveY = dims.height;
break; break;
case 'center': case 'center':
moveX = dims.width / 2; moveX = dims.width / 2;
moveY = dims.height / 2; moveY = dims.height / 2;
break; break;
} }
return new Effect.Parallel( return new Effect.Parallel(
[ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }), [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}), new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }) new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
], Object.extend({ ], Object.extend({
beforeStartInternal: function(effect) { beforeStartInternal: function(effect) {
effect.effects[0].element.makePositioned().makeClipping(); effect.effects[0].element.makePositioned().makeClipping();
}, },
afterFinishInternal: function(effect) { afterFinishInternal: function(effect) {
effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); } effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
@ -879,12 +885,14 @@ Effect.Shrink = function(element) {
Effect.Pulsate = function(element) { Effect.Pulsate = function(element) {
element = $(element); element = $(element);
var options = arguments[1] || { }; var options = arguments[1] || { },
var oldOpacity = element.getInlineOpacity(); oldOpacity = element.getInlineOpacity(),
var transition = options.transition || Effect.Transitions.sinoidal; transition = options.transition || Effect.Transitions.linear,
var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) }; reverser = function(pos){
reverser.bind(transition); return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5);
return new Effect.Opacity(element, };
return new Effect.Opacity(element,
Object.extend(Object.extend({ duration: 2.0, from: 0, Object.extend(Object.extend({ duration: 2.0, from: 0,
afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); } afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
}, options), {transition: reverser})); }, options), {transition: reverser}));
@ -898,12 +906,12 @@ Effect.Fold = function(element) {
width: element.style.width, width: element.style.width,
height: element.style.height }; height: element.style.height };
element.makeClipping(); element.makeClipping();
return new Effect.Scale(element, 5, Object.extend({ return new Effect.Scale(element, 5, Object.extend({
scaleContent: false, scaleContent: false,
scaleX: false, scaleX: false,
afterFinishInternal: function(effect) { afterFinishInternal: function(effect) {
new Effect.Scale(element, 1, { new Effect.Scale(element, 1, {
scaleContent: false, scaleContent: false,
scaleY: false, scaleY: false,
afterFinishInternal: function(effect) { afterFinishInternal: function(effect) {
effect.element.hide().undoClipping().setStyle(oldStyle); effect.element.hide().undoClipping().setStyle(oldStyle);
@ -918,7 +926,7 @@ Effect.Morph = Class.create(Effect.Base, {
var options = Object.extend({ var options = Object.extend({
style: { } style: { }
}, arguments[1] || { }); }, arguments[1] || { });
if (!Object.isString(options.style)) this.style = $H(options.style); if (!Object.isString(options.style)) this.style = $H(options.style);
else { else {
if (options.style.include(':')) if (options.style.include(':'))
@ -936,18 +944,18 @@ Effect.Morph = Class.create(Effect.Base, {
effect.transforms.each(function(transform) { effect.transforms.each(function(transform) {
effect.element.style[transform.style] = ''; effect.element.style[transform.style] = '';
}); });
} };
} }
} }
this.start(options); this.start(options);
}, },
setup: function(){ setup: function(){
function parseColor(color){ function parseColor(color){
if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff'; if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
color = color.parseColor(); color = color.parseColor();
return $R(0,2).map(function(i){ return $R(0,2).map(function(i){
return parseInt( color.slice(i*2+1,i*2+3), 16 ) return parseInt( color.slice(i*2+1,i*2+3), 16 );
}); });
} }
this.transforms = this.style.map(function(pair){ this.transforms = this.style.map(function(pair){
@ -967,9 +975,9 @@ Effect.Morph = Class.create(Effect.Base, {
} }
var originalValue = this.element.getStyle(property); var originalValue = this.element.getStyle(property);
return { return {
style: property.camelize(), style: property.camelize(),
originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
targetValue: unit=='color' ? parseColor(value) : value, targetValue: unit=='color' ? parseColor(value) : value,
unit: unit unit: unit
}; };
@ -980,13 +988,13 @@ Effect.Morph = Class.create(Effect.Base, {
transform.unit != 'color' && transform.unit != 'color' &&
(isNaN(transform.originalValue) || isNaN(transform.targetValue)) (isNaN(transform.originalValue) || isNaN(transform.targetValue))
) )
) );
}); });
}, },
update: function(position) { update: function(position) {
var style = { }, transform, i = this.transforms.length; var style = { }, transform, i = this.transforms.length;
while(i--) while(i--)
style[(transform = this.transforms[i]).style] = style[(transform = this.transforms[i]).style] =
transform.unit=='color' ? '#'+ transform.unit=='color' ? '#'+
(Math.round(transform.originalValue[0]+ (Math.round(transform.originalValue[0]+
(transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() + (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
@ -995,7 +1003,7 @@ Effect.Morph = Class.create(Effect.Base, {
(Math.round(transform.originalValue[2]+ (Math.round(transform.originalValue[2]+
(transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() : (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
(transform.originalValue + (transform.originalValue +
(transform.targetValue - transform.originalValue) * position).toFixed(3) + (transform.targetValue - transform.originalValue) * position).toFixed(3) +
(transform.unit === null ? '' : transform.unit); (transform.unit === null ? '' : transform.unit);
this.element.setStyle(style, true); this.element.setStyle(style, true);
} }
@ -1032,7 +1040,7 @@ Effect.Transform = Class.create({
}); });
Element.CSS_PROPERTIES = $w( Element.CSS_PROPERTIES = $w(
'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' + 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
'borderRightColor borderRightStyle borderRightWidth borderSpacing ' + 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
'borderTopColor borderTopStyle borderTopWidth bottom clip color ' + 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
@ -1041,7 +1049,7 @@ Element.CSS_PROPERTIES = $w(
'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' + 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' + 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
'right textIndent top width wordSpacing zIndex'); 'right textIndent top width wordSpacing zIndex');
Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/; Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
String.__parseStyleElement = document.createElement('div'); String.__parseStyleElement = document.createElement('div');
@ -1053,11 +1061,11 @@ String.prototype.parseStyle = function(){
String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>'; String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
style = String.__parseStyleElement.childNodes[0].style; style = String.__parseStyleElement.childNodes[0].style;
} }
Element.CSS_PROPERTIES.each(function(property){ Element.CSS_PROPERTIES.each(function(property){
if (style[property]) styleRules.set(property, style[property]); if (style[property]) styleRules.set(property, style[property]);
}); });
if (Prototype.Browser.IE && this.include('opacity')) if (Prototype.Browser.IE && this.include('opacity'))
styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]); styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
@ -1083,7 +1091,7 @@ if (document.defaultView && document.defaultView.getComputedStyle) {
if (!styles.opacity) styles.opacity = element.getOpacity(); if (!styles.opacity) styles.opacity = element.getOpacity();
return styles; return styles;
}; };
}; }
Effect.Methods = { Effect.Methods = {
morph: function(element, style) { morph: function(element, style) {
@ -1092,7 +1100,7 @@ Effect.Methods = {
return element; return element;
}, },
visualEffect: function(element, effect, options) { visualEffect: function(element, effect, options) {
element = $(element) element = $(element);
var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1); var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
new Effect[klass](element, options); new Effect[klass](element, options);
return element; return element;
@ -1106,17 +1114,17 @@ Effect.Methods = {
$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+ $w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
'pulsate shake puff squish switchOff dropOut').each( 'pulsate shake puff squish switchOff dropOut').each(
function(effect) { function(effect) {
Effect.Methods[effect] = function(element, options){ Effect.Methods[effect] = function(element, options){
element = $(element); element = $(element);
Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options); Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
return element; return element;
} };
} }
); );
$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( $w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
function(f) { Effect.Methods[f] = Element[f]; } function(f) { Effect.Methods[f] = Element[f]; }
); );
Element.addMethods(Effect.Methods); Element.addMethods(Effect.Methods);

View File

@ -1,7 +1,7 @@
// script.aculo.us scriptaculous.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008 // script.aculo.us scriptaculous.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the // a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including // "Software"), to deal in the Software without restriction, including
@ -9,7 +9,7 @@
// distribute, sublicense, and/or sell copies of the Software, and to // distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to // permit persons to whom the Software is furnished to do so, subject to
// the following conditions: // the following conditions:
// //
// The above copyright notice and this permission notice shall be // The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. // included in all copies or substantial portions of the Software.
// //
@ -24,35 +24,37 @@
// For details, see the script.aculo.us web site: http://script.aculo.us/ // For details, see the script.aculo.us web site: http://script.aculo.us/
var Scriptaculous = { var Scriptaculous = {
Version: '1.8.1', Version: '1.8.2',
require: function(libraryName) { require: function(libraryName) {
// inserting via DOM fails in Safari 2.0, so brute force approach // inserting via DOM fails in Safari 2.0, so brute force approach
document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>'); document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
}, },
REQUIRED_PROTOTYPE: '1.6.0', REQUIRED_PROTOTYPE: '1.6.0.3',
load: function() { load: function() {
function convertVersionString(versionString){ function convertVersionString(versionString) {
var r = versionString.split('.'); var v = versionString.replace(/_.*|\./g, '');
return parseInt(r[0])*100000 + parseInt(r[1])*1000 + parseInt(r[2]); v = parseInt(v + '0'.times(4-v.length));
return versionString.indexOf('_') > -1 ? v-1 : v;
} }
if((typeof Prototype=='undefined') || if((typeof Prototype=='undefined') ||
(typeof Element == 'undefined') || (typeof Element == 'undefined') ||
(typeof Element.Methods=='undefined') || (typeof Element.Methods=='undefined') ||
(convertVersionString(Prototype.Version) < (convertVersionString(Prototype.Version) <
convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE))) convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
throw("script.aculo.us requires the Prototype JavaScript framework >= " + throw("script.aculo.us requires the Prototype JavaScript framework >= " +
Scriptaculous.REQUIRED_PROTOTYPE); Scriptaculous.REQUIRED_PROTOTYPE);
$A(document.getElementsByTagName("script")).findAll( function(s) { var js = /scriptaculous\.js(\?.*)?$/;
return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/)) $$('head script[src]').findAll(function(s) {
}).each( function(s) { return s.src.match(js);
var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,''); }).each(function(s) {
var includes = s.src.match(/\?.*load=([a-z,]*)/); var path = s.src.replace(js, ''),
includes = s.src.match(/\?.*load=([a-z,]*)/);
(includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each( (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
function(include) { Scriptaculous.require(path+include+'.js') }); function(include) { Scriptaculous.require(path+include+'.js') });
}); });
} }
} };
Scriptaculous.load(); Scriptaculous.load();

View File

@ -1,6 +1,6 @@
// script.aculo.us slider.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008 // script.aculo.us slider.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
// Copyright (c) 2005-2007 Marty Haught, Thomas Fuchs // Copyright (c) 2005-2008 Marty Haught, Thomas Fuchs
// //
// script.aculo.us is freely distributable under the terms of an MIT-style license. // script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/ // For details, see the script.aculo.us web site: http://script.aculo.us/
@ -16,13 +16,13 @@ if (!Control) var Control = { };
Control.Slider = Class.create({ Control.Slider = Class.create({
initialize: function(handle, track, options) { initialize: function(handle, track, options) {
var slider = this; var slider = this;
if (Object.isArray(handle)) { if (Object.isArray(handle)) {
this.handles = handle.collect( function(e) { return $(e) }); this.handles = handle.collect( function(e) { return $(e) });
} else { } else {
this.handles = [$(handle)]; this.handles = [$(handle)];
} }
this.track = $(track); this.track = $(track);
this.options = options || { }; this.options = options || { };
@ -30,7 +30,7 @@ Control.Slider = Class.create({
this.increment = this.options.increment || 1; this.increment = this.options.increment || 1;
this.step = parseInt(this.options.step || '1'); this.step = parseInt(this.options.step || '1');
this.range = this.options.range || $R(0,1); this.range = this.options.range || $R(0,1);
this.value = 0; // assure backwards compat this.value = 0; // assure backwards compat
this.values = this.handles.map( function() { return 0 }); this.values = this.handles.map( function() { return 0 });
this.spans = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false; this.spans = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
@ -45,13 +45,13 @@ Control.Slider = Class.create({
// Will be used to align the handle onto the track, if necessary // Will be used to align the handle onto the track, if necessary
this.alignX = parseInt(this.options.alignX || '0'); this.alignX = parseInt(this.options.alignX || '0');
this.alignY = parseInt(this.options.alignY || '0'); this.alignY = parseInt(this.options.alignY || '0');
this.trackLength = this.maximumOffset() - this.minimumOffset(); this.trackLength = this.maximumOffset() - this.minimumOffset();
this.handleLength = this.isVertical() ? this.handleLength = this.isVertical() ?
(this.handles[0].offsetHeight != 0 ? (this.handles[0].offsetHeight != 0 ?
this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) : this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) :
(this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth : (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth :
this.handles[0].style.width.replace(/px$/,"")); this.handles[0].style.width.replace(/px$/,""));
this.active = false; this.active = false;
@ -75,20 +75,20 @@ Control.Slider = Class.create({
this.handles.each( function(h,i) { this.handles.each( function(h,i) {
i = slider.handles.length-1-i; i = slider.handles.length-1-i;
slider.setValue(parseFloat( slider.setValue(parseFloat(
(Object.isArray(slider.options.sliderValue) ? (Object.isArray(slider.options.sliderValue) ?
slider.options.sliderValue[i] : slider.options.sliderValue) || slider.options.sliderValue[i] : slider.options.sliderValue) ||
slider.range.start), i); slider.range.start), i);
h.makePositioned().observe("mousedown", slider.eventMouseDown); h.makePositioned().observe("mousedown", slider.eventMouseDown);
}); });
this.track.observe("mousedown", this.eventMouseDown); this.track.observe("mousedown", this.eventMouseDown);
document.observe("mouseup", this.eventMouseUp); document.observe("mouseup", this.eventMouseUp);
document.observe("mousemove", this.eventMouseMove); document.observe("mousemove", this.eventMouseMove);
this.initialized = true; this.initialized = true;
}, },
dispose: function() { dispose: function() {
var slider = this; var slider = this;
Event.stopObserving(this.track, "mousedown", this.eventMouseDown); Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
Event.stopObserving(document, "mouseup", this.eventMouseUp); Event.stopObserving(document, "mouseup", this.eventMouseUp);
Event.stopObserving(document, "mousemove", this.eventMouseMove); Event.stopObserving(document, "mousemove", this.eventMouseMove);
@ -101,12 +101,12 @@ Control.Slider = Class.create({
}, },
setEnabled: function(){ setEnabled: function(){
this.disabled = false; this.disabled = false;
}, },
getNearestValue: function(value){ getNearestValue: function(value){
if (this.allowedValues){ if (this.allowedValues){
if (value >= this.allowedValues.max()) return(this.allowedValues.max()); if (value >= this.allowedValues.max()) return(this.allowedValues.max());
if (value <= this.allowedValues.min()) return(this.allowedValues.min()); if (value <= this.allowedValues.min()) return(this.allowedValues.min());
var offset = Math.abs(this.allowedValues[0] - value); var offset = Math.abs(this.allowedValues[0] - value);
var newValue = this.allowedValues[0]; var newValue = this.allowedValues[0];
this.allowedValues.each( function(v) { this.allowedValues.each( function(v) {
@ -114,7 +114,7 @@ Control.Slider = Class.create({
if (currentOffset <= offset){ if (currentOffset <= offset){
newValue = v; newValue = v;
offset = currentOffset; offset = currentOffset;
} }
}); });
return newValue; return newValue;
} }
@ -138,28 +138,28 @@ Control.Slider = Class.create({
sliderValue = this.getNearestValue(sliderValue); sliderValue = this.getNearestValue(sliderValue);
this.values[handleIdx] = sliderValue; this.values[handleIdx] = sliderValue;
this.value = this.values[0]; // assure backwards compat this.value = this.values[0]; // assure backwards compat
this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] = this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] =
this.translateToPx(sliderValue); this.translateToPx(sliderValue);
this.drawSpans(); this.drawSpans();
if (!this.dragging || !this.event) this.updateFinished(); if (!this.dragging || !this.event) this.updateFinished();
}, },
setValueBy: function(delta, handleIdx) { setValueBy: function(delta, handleIdx) {
this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta, this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta,
handleIdx || this.activeHandleIdx || 0); handleIdx || this.activeHandleIdx || 0);
}, },
translateToPx: function(value) { translateToPx: function(value) {
return Math.round( return Math.round(
((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) * ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) *
(value - this.range.start)) + "px"; (value - this.range.start)) + "px";
}, },
translateToValue: function(offset) { translateToValue: function(offset) {
return ((offset/(this.trackLength-this.handleLength) * return ((offset/(this.trackLength-this.handleLength) *
(this.range.end-this.range.start)) + this.range.start); (this.range.end-this.range.start)) + this.range.start);
}, },
getRange: function(range) { getRange: function(range) {
var v = this.values.sortBy(Prototype.K); var v = this.values.sortBy(Prototype.K);
range = range || 0; range = range || 0;
return $R(v[range],v[range+1]); return $R(v[range],v[range+1]);
}, },
@ -167,12 +167,12 @@ Control.Slider = Class.create({
return(this.isVertical() ? this.alignY : this.alignX); return(this.isVertical() ? this.alignY : this.alignX);
}, },
maximumOffset: function(){ maximumOffset: function(){
return(this.isVertical() ? return(this.isVertical() ?
(this.track.offsetHeight != 0 ? this.track.offsetHeight : (this.track.offsetHeight != 0 ? this.track.offsetHeight :
this.track.style.height.replace(/px$/,"")) - this.alignY : this.track.style.height.replace(/px$/,"")) - this.alignY :
(this.track.offsetWidth != 0 ? this.track.offsetWidth : (this.track.offsetWidth != 0 ? this.track.offsetWidth :
this.track.style.width.replace(/px$/,"")) - this.alignX); this.track.style.width.replace(/px$/,"")) - this.alignX);
}, },
isVertical: function(){ isVertical: function(){
return (this.axis == 'vertical'); return (this.axis == 'vertical');
}, },
@ -184,7 +184,7 @@ Control.Slider = Class.create({
this.setSpan(this.options.startSpan, this.setSpan(this.options.startSpan,
$R(0, this.values.length>1 ? this.getRange(0).min() : this.value )); $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
if (this.options.endSpan) if (this.options.endSpan)
this.setSpan(this.options.endSpan, this.setSpan(this.options.endSpan,
$R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum)); $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
}, },
setSpan: function(span, range) { setSpan: function(span, range) {
@ -204,14 +204,14 @@ Control.Slider = Class.create({
if (Event.isLeftClick(event)) { if (Event.isLeftClick(event)) {
if (!this.disabled){ if (!this.disabled){
this.active = true; this.active = true;
var handle = Event.element(event); var handle = Event.element(event);
var pointer = [Event.pointerX(event), Event.pointerY(event)]; var pointer = [Event.pointerX(event), Event.pointerY(event)];
var track = handle; var track = handle;
if (track==this.track) { if (track==this.track) {
var offsets = Position.cumulativeOffset(this.track); var offsets = Position.cumulativeOffset(this.track);
this.event = event; this.event = event;
this.setValue(this.translateToValue( this.setValue(this.translateToValue(
(this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2) (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
)); ));
var offsets = Position.cumulativeOffset(this.activeHandle); var offsets = Position.cumulativeOffset(this.activeHandle);
@ -219,14 +219,14 @@ Control.Slider = Class.create({
this.offsetY = (pointer[1] - offsets[1]); this.offsetY = (pointer[1] - offsets[1]);
} else { } else {
// find the handle (prevents issues with Safari) // find the handle (prevents issues with Safari)
while((this.handles.indexOf(handle) == -1) && handle.parentNode) while((this.handles.indexOf(handle) == -1) && handle.parentNode)
handle = handle.parentNode; handle = handle.parentNode;
if (this.handles.indexOf(handle)!=-1) { if (this.handles.indexOf(handle)!=-1) {
this.activeHandle = handle; this.activeHandle = handle;
this.activeHandleIdx = this.handles.indexOf(this.activeHandle); this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
this.updateStyles(); this.updateStyles();
var offsets = Position.cumulativeOffset(this.activeHandle); var offsets = Position.cumulativeOffset(this.activeHandle);
this.offsetX = (pointer[0] - offsets[0]); this.offsetX = (pointer[0] - offsets[0]);
this.offsetY = (pointer[1] - offsets[1]); this.offsetY = (pointer[1] - offsets[1]);
@ -261,15 +261,15 @@ Control.Slider = Class.create({
} }
this.active = false; this.active = false;
this.dragging = false; this.dragging = false;
}, },
finishDrag: function(event, success) { finishDrag: function(event, success) {
this.active = false; this.active = false;
this.dragging = false; this.dragging = false;
this.updateFinished(); this.updateFinished();
}, },
updateFinished: function() { updateFinished: function() {
if (this.initialized && this.options.onChange) if (this.initialized && this.options.onChange)
this.options.onChange(this.values.length>1 ? this.values : this.value, this); this.options.onChange(this.values.length>1 ? this.values : this.value, this);
this.event = null; this.event = null;
} }
}); });

View File

@ -1,6 +1,6 @@
// script.aculo.us sound.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008 // script.aculo.us sound.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// //
// Based on code created by Jules Gravinese (http://www.webveteran.com/) // Based on code created by Jules Gravinese (http://www.webveteran.com/)
// //
@ -23,23 +23,23 @@ Sound = {
var options = Object.extend({ var options = Object.extend({
track: 'global', url: url, replace: false track: 'global', url: url, replace: false
}, arguments[1] || {}); }, arguments[1] || {});
if(options.replace && this.tracks[options.track]) { if(options.replace && this.tracks[options.track]) {
$R(0, this.tracks[options.track].id).each(function(id){ $R(0, this.tracks[options.track].id).each(function(id){
var sound = $('sound_'+options.track+'_'+id); var sound = $('sound_'+options.track+'_'+id);
sound.Stop && sound.Stop(); sound.Stop && sound.Stop();
sound.remove(); sound.remove();
}) });
this.tracks[options.track] = null; this.tracks[options.track] = null;
} }
if(!this.tracks[options.track]) if(!this.tracks[options.track])
this.tracks[options.track] = { id: 0 } this.tracks[options.track] = { id: 0 };
else else
this.tracks[options.track].id++; this.tracks[options.track].id++;
options.id = this.tracks[options.track].id; options.id = this.tracks[options.track].id;
$$('body')[0].insert( $$('body')[0].insert(
Prototype.Browser.IE ? new Element('bgsound',{ Prototype.Browser.IE ? new Element('bgsound',{
id: 'sound_'+options.track+'_'+options.id, id: 'sound_'+options.track+'_'+options.id,
src: options.url, loop: 1, autostart: true src: options.url, loop: 1, autostart: true
@ -49,7 +49,7 @@ Sound = {
if(Prototype.Browser.Gecko && navigator.userAgent.indexOf("Win") > 0){ if(Prototype.Browser.Gecko && navigator.userAgent.indexOf("Win") > 0){
if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('QuickTime') != -1 })) if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('QuickTime') != -1 }))
Sound.template = new Template('<object id="sound_#{track}_#{id}" width="0" height="0" type="audio/mpeg" data="#{url}"/>') Sound.template = new Template('<object id="sound_#{track}_#{id}" width="0" height="0" type="audio/mpeg" data="#{url}"/>');
else else
Sound.play = function(){} Sound.play = function(){};
} }

View File

@ -1,8 +1,8 @@
// script.aculo.us unittest.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008 // script.aculo.us unittest.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// (c) 2005-2007 Jon Tirsen (http://www.tirsen.com) // (c) 2005-2008 Jon Tirsen (http://www.tirsen.com)
// (c) 2005-2007 Michael Schuerig (http://www.schuerig.de/michael/) // (c) 2005-2008 Michael Schuerig (http://www.schuerig.de/michael/)
// //
// script.aculo.us is freely distributable under the terms of an MIT-style license. // script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/ // For details, see the script.aculo.us web site: http://script.aculo.us/
@ -32,8 +32,8 @@ Event.simulateMouse = function(element, eventName) {
this.mark.style.left = options.pointerX + "px"; this.mark.style.left = options.pointerX + "px";
this.mark.style.width = "5px"; this.mark.style.width = "5px";
this.mark.style.height = "5px;"; this.mark.style.height = "5px;";
this.mark.style.borderTop = "1px solid red;" this.mark.style.borderTop = "1px solid red;";
this.mark.style.borderLeft = "1px solid red;" this.mark.style.borderLeft = "1px solid red;";
if(this.step) if(this.step)
alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options)); alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options));
@ -67,7 +67,7 @@ Event.simulateKeys = function(element, command) {
} }
}; };
var Test = {} var Test = {};
Test.Unit = {}; Test.Unit = {};
// security exception workaround // security exception workaround
@ -117,7 +117,7 @@ Test.Unit.Logger.prototype = {
'<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' + '<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' +
'<tbody id="loglines"></tbody>' + '<tbody id="loglines"></tbody>' +
'</table>'; '</table>';
this.logsummary = $('logsummary') this.logsummary = $('logsummary');
this.loglines = $('loglines'); this.loglines = $('loglines');
}, },
_toHTML: function(txt) { _toHTML: function(txt) {
@ -125,15 +125,15 @@ Test.Unit.Logger.prototype = {
}, },
addLinksToResults: function(){ addLinksToResults: function(){
$$("tr.failed .nameCell").each( function(td){ // todo: limit to children of this.log $$("tr.failed .nameCell").each( function(td){ // todo: limit to children of this.log
td.title = "Run only this test" td.title = "Run only this test";
Event.observe(td, 'click', function(){ window.location.search = "?tests=" + td.innerHTML;}); Event.observe(td, 'click', function(){ window.location.search = "?tests=" + td.innerHTML;});
}); });
$$("tr.passed .nameCell").each( function(td){ // todo: limit to children of this.log $$("tr.passed .nameCell").each( function(td){ // todo: limit to children of this.log
td.title = "Run all tests" td.title = "Run all tests";
Event.observe(td, 'click', function(){ window.location.search = "";}); Event.observe(td, 'click', function(){ window.location.search = "";});
}); });
} }
} };
Test.Unit.Runner = Class.create(); Test.Unit.Runner = Class.create();
Test.Unit.Runner.prototype = { Test.Unit.Runner.prototype = {
@ -246,7 +246,7 @@ Test.Unit.Runner.prototype = {
failures + " failures, " + failures + " failures, " +
errors + " errors"); errors + " errors");
} }
} };
Test.Unit.Assertions = Class.create(); Test.Unit.Assertions = Class.create();
Test.Unit.Assertions.prototype = { Test.Unit.Assertions.prototype = {
@ -331,7 +331,7 @@ Test.Unit.Assertions.prototype = {
catch(e) { this.error(e); } catch(e) { this.error(e); }
}, },
assertNull: function(obj) { assertNull: function(obj) {
var message = arguments[1] || 'assertNull' var message = arguments[1] || 'assertNull';
try { (obj==null) ? this.pass() : try { (obj==null) ? this.pass() :
this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); } this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); }
catch(e) { this.error(e); } catch(e) { this.error(e); }
@ -461,7 +461,7 @@ Test.Unit.Assertions.prototype = {
iterations + ' iterations in ' + (timeTaken/1000)+'s' ); iterations + ' iterations in ' + (timeTaken/1000)+'s' );
return timeTaken; return timeTaken;
} }
} };
Test.Unit.Testcase = Class.create(); Test.Unit.Testcase = Class.create();
Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), { Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), {
@ -526,7 +526,7 @@ Test.setupBDDExtensionMethods = function(){
}; };
var makeAssertion = function(assertion, args, object) { var makeAssertion = function(assertion, args, object) {
this[assertion].apply(this,(args || []).concat([object])); this[assertion].apply(this,(args || []).concat([object]));
} };
Test.BDDMethods = {}; Test.BDDMethods = {};
$H(METHODMAP).each(function(pair) { $H(METHODMAP).each(function(pair) {
@ -539,7 +539,7 @@ Test.setupBDDExtensionMethods = function(){
[Array.prototype, String.prototype, Number.prototype, Boolean.prototype].each( [Array.prototype, String.prototype, Number.prototype, Boolean.prototype].each(
function(p){ Object.extend(p, Test.BDDMethods) } function(p){ Object.extend(p, Test.BDDMethods) }
); );
} };
Test.context = function(name, spec, log){ Test.context = function(name, spec, log){
Test.setupBDDExtensionMethods(); Test.setupBDDExtensionMethods();