3
Mootools - My Object Oriented javascript.
9
copyright (c) 2007 Valerio Proietti, <http://mad4milk.net>
12
- Class is slightly based on Base.js <http://dean.edwards.name/weblog/2006/03/base/> (c) 2006 Dean Edwards, License <http://creativecommons.org/licenses/LGPL/2.1/>
13
- Some functions are inspired by those found in prototype.js <http://prototype.conio.net/> (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license
14
- Documentation by Aaron Newton (aaron.newton [at] cnet [dot] com) and Valerio Proietti.
21
/* Section: Core Functions */
25
Returns true if the passed in value/object is defined, that means is not null or undefined.
28
obj - object to inspect
31
function $defined(obj){
32
return (obj != undefined);
37
Returns the type of object that matches the element passed in.
40
obj - the object to inspect.
43
>var myString = 'hello';
44
>$type(myString); //returns "string"
47
'element' - if obj is a DOM element node
48
'textnode' - if obj is a DOM text node
49
'whitespace' - if obj is a DOM whitespace node
50
'arguments' - if obj is an arguments object
51
'object' - if obj is an object
52
'string' - if obj is a string
53
'number' - if obj is a number
54
'boolean' - if obj is a boolean
55
'function' - if obj is a function
56
'regexp' - if obj is a regular expression
57
'class' - if obj is a Class. (created with new Class, or the extend of another class).
58
'collection' - if obj is a native htmlelements collection, such as childNodes, getElementsByTagName .. etc.
59
false - (boolean) if the object is not defined or none of the above.
63
if (!$defined(obj)) return false;
64
if (obj.htmlElement) return 'element';
65
var type = typeof obj;
66
if (type == 'object' && obj.nodeName){
68
case 1: return 'element';
69
case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
72
if (type == 'object' || type == 'function'){
73
switch(obj.constructor){
74
case Array: return 'array';
75
case RegExp: return 'regexp';
76
case Class: return 'class';
78
if (typeof obj.length == 'number'){
79
if (obj.item) return 'collection';
80
if (obj.callee) return 'arguments';
88
merges a number of objects recursively without referencing them or their sub-objects.
91
any number of objects.
94
>var mergedObj = $merge(obj1, obj2, obj3);
95
>//obj1, obj2, and obj3 are unaltered
100
for (var i = 0; i < arguments.length; i++){
101
for (var property in arguments[i]){
102
var ap = arguments[i][property];
103
var mp = mix[property];
104
if (mp && $type(ap) == 'object' && $type(mp) == 'object') mix[property] = $merge(mp, ap);
105
else mix[property] = ap;
113
Copies all the properties from the second passed object to the first passed Object.
114
If you do myWhatever.extend = $extend the first parameter will become myWhatever, and your extend function will only need one parameter.
127
$extend(firstOb, secondOb);
128
//firstOb will become:
131
'lastName': 'Dorian',
138
The first object, extended.
141
var $extend = function(){
142
var args = arguments;
143
if (!args[1]) args = [this, args[0]];
144
for (var property in args[1]) args[0][property] = args[1][property];
150
Will add a .extend method to the objects passed as a parameter, but the property passed in will be copied to the object's prototype only if non previously existent.
151
Its handy if you dont want the .extend method of an object to overwrite existing methods.
152
Used automatically in MooTools to implement Array/String/Function/Number methods to browser that dont support them whitout manual checking.
155
a number of classes/native javascript objects
159
var $native = function(){
160
for (var i = 0, l = arguments.length; i < l; i++){
161
arguments[i].extend = function(props){
162
for (var prop in props){
163
if (!this.prototype[prop]) this.prototype[prop] = props[prop];
164
if (!this[prop]) this[prop] = $native.generic(prop);
170
$native.generic = function(prop){
171
return function(bind){
172
return this.prototype[prop].apply(bind, Array.prototype.slice.call(arguments, 1));
176
$native(Function, Array, String, Number);
180
Returns true if the passed in value/object exists or is 0, otherwise returns false.
181
Useful to accept zeroes.
184
obj - object to inspect
188
return !!(obj || obj === 0);
193
Returns the first object if defined, otherwise returns the second.
197
picked - the default to return
202
alert($pick(msg, 'no meessage supplied'));
207
function $pick(obj, picked){
208
return $defined(obj) ? obj : picked;
213
Returns a random integer number between the two passed in values.
216
min - integer, the minimum value (inclusive).
217
max - integer, the maximum value (inclusive).
220
a random integer between min and max.
223
function $random(min, max){
224
return Math.floor(Math.random() * (max - min + 1) + min);
229
Returns the current timestamp
236
return new Date().getTime();
241
clears a timeout or an Interval.
247
timer - the setInterval or setTimeout to clear.
250
>var myTimer = myFunction.delay(5000); //wait 5 seconds and execute my function.
251
>myTimer = $clear(myTimer); //nevermind
254
<Function.delay>, <Function.periodical>
257
function $clear(timer){
259
clearInterval(timer);
265
Abstract class, to be used as singleton. Will add .extend to any object
271
the object with an .extend property, equivalent to <$extend>.
274
var Abstract = function(obj){
276
obj.extend = $extend;
282
var Window = new Abstract(window);
283
var Document = new Abstract(document);
284
document.head = document.getElementsByTagName('head')[0];
288
Some properties are attached to the window object by the browser detection.
291
browser detection is entirely object-based. We dont sniff.
294
window.ie - will be set to true if the current browser is internet explorer (any).
295
window.ie6 - will be set to true if the current browser is internet explorer 6.
296
window.ie7 - will be set to true if the current browser is internet explorer 7.
297
window.gecko - will be set to true if the current browser is Mozilla/Gecko.
298
window.webkit - will be set to true if the current browser is Safari/Konqueror.
299
window.webkit419 - will be set to true if the current browser is Safari2 / webkit till version 419.
300
window.webkit420 - will be set to true if the current browser is Safari3 (Webkit SVN Build) / webkit over version 419.
301
window.opera - is set to true by opera itself.
304
window.xpath = !!(document.evaluate);
305
if (window.ActiveXObject) window.ie = window[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true;
306
else if (document.childNodes && !document.all && !navigator.taintEnabled) window.webkit = window[window.xpath ? 'webkit420' : 'webkit419'] = true;
307
else if (document.getBoxObjectFor != null) window.gecko = true;
311
window.khtml = window.webkit;
313
Object.extend = $extend;
315
/*end compatibility*/
319
if (typeof HTMLElement == 'undefined'){
320
var HTMLElement = function(){};
321
if (window.webkit) document.createElement("iframe"); //fixes safari
322
HTMLElement.prototype = (window.webkit) ? window["[[DOMElement.prototype]]"] : {};
324
HTMLElement.prototype.htmlElement = function(){};
326
//enables background image cache for internet explorer 6
328
if (window.ie6) try {document.execCommand("BackgroundImageCache", false, true);} catch(e){};
332
Contains the Class Function, aims to ease the creation of reusable Classes.
340
The base class object of the <http://mootools.net> framework.
341
Creates a new class, its initialize method will fire upon class instantiation.
342
Initialize wont fire on instantiation when you pass *null*.
345
properties - the collection of properties that apply to the class.
349
var Cat = new Class({
350
initialize: function(name){
354
var myCat = new Cat('Micia');
355
alert(myCat.name); //alerts 'Micia'
359
var Class = function(properties){
360
var klass = function(){
361
return (arguments[0] !== null && this.initialize && $type(this.initialize) == 'function') ? this.initialize.apply(this, arguments) : this;
363
$extend(klass, this);
364
klass.prototype = properties;
365
klass.constructor = Class;
371
Returns an empty function
374
Class.empty = function(){};
380
Returns the copy of the Class extended with the passed in properties.
383
properties - the properties to add to the base class in this new Class.
387
var Animal = new Class({
388
initialize: function(age){
392
var Cat = Animal.extend({
393
initialize: function(name, age){
394
this.parent(age); //will call the previous initialize;
398
var myCat = new Cat('Micia', 20);
399
alert(myCat.name); //alerts 'Micia'
400
alert(myCat.age); //alerts 20
404
extend: function(properties){
405
var proto = new this(null);
406
for (var property in properties){
407
var pp = proto[property];
408
proto[property] = Class.Merge(pp, properties[property]);
410
return new Class(proto);
415
Implements the passed in properties to the base Class prototypes, altering the base class, unlike <Class.extend>.
418
properties - the properties to add to the base class.
422
var Animal = new Class({
423
initialize: function(age){
428
setName: function(name){
432
var myAnimal = new Animal(20);
433
myAnimal.setName('Micia');
434
alert(myAnimal.name); //alerts 'Micia'
438
implement: function(){
439
for (var i = 0, l = arguments.length; i < l; i++) $extend(this.prototype, arguments[i]);
446
Class.Merge = function(previous, current){
447
if (previous && previous != current){
448
var type = $type(current);
449
if (type != $type(previous)) return current;
452
var merged = function(){
453
this.parent = arguments.callee.parent;
454
return current.apply(this, arguments);
456
merged.parent = previous;
458
case 'object': return $merge(previous, current);
465
Script: Class.Extras.js
466
Contains common implementations for custom classes. In Mootools is implemented in <Ajax>, <XHR> and <Fx.Base> and many more.
474
An "Utility" Class. Its methods can be implemented with <Class.implement> into any <Class>.
475
Currently implemented in <Fx.Base>, <XHR> and <Ajax>. In <Fx.Base> for example, is used to execute a list of function, one after another, once the effect is completed.
476
The functions will not be fired all togheter, but one every completion, to create custom complex animations.
480
var myFx = new Fx.Style('element', 'opacity');
482
myFx.start(1,0).chain(function(){
489
//the element will appear and disappear three times
493
var Chain = new Class({
497
adds a function to the Chain instance stack.
500
fn - the function to append.
504
this.chains = this.chains || [];
505
this.chains.push(fn);
511
Executes the first function of the Chain instance stack, then removes it. The first function will then become the second.
514
callChain: function(){
515
if (this.chains && this.chains.length) this.chains.shift().delay(10, this);
520
Clears the stack of a Chain instance.
523
clearChain: function(){
531
An "Utility" Class. Its methods can be implemented with <Class.implement> into any <Class>.
532
In <Fx.Base> Class, for example, is used to give the possibility add any number of functions to the Effects events, like onComplete, onStart, onCancel.
533
Events in a Class that implements <Events> can be either added as an option, or with addEvent. Never with .options.onEventName.
537
var myFx = new Fx.Style('element', 'opacity').addEvent('onComplete', function(){
538
alert('the effect is completed');
539
}).addEvent('onComplete', function(){
540
alert('I told you the effect is completed');
544
//upon completion it will display the 2 alerts, in order.
548
This class can be implemented into other classes to add the functionality to them.
549
Goes well with the <Options> class.
553
var Widget = new Class({
554
initialize: function(){},
556
this.fireEvent('onComplete');
559
Widget.implement(new Events);
561
var myWidget = new Widget();
562
myWidget.addEvent('onComplete', myfunction);
566
var Events = new Class({
570
adds an event to the stack of events of the Class instance.
573
type - string; the event name (e.g. 'onComplete')
574
fn - function to execute
577
addEvent: function(type, fn){
578
if (fn != Class.empty){
579
this.$events = this.$events || {};
580
this.$events[type] = this.$events[type] || [];
581
this.$events[type].include(fn);
588
fires all events of the specified type in the Class instance.
591
type - string; the event name (e.g. 'onComplete')
592
args - array or single object; arguments to pass to the function; if more than one argument, must be an array
593
delay - (integer) delay (in ms) to wait to execute the event
597
var Widget = new Class({
598
initialize: function(arg1, arg2){
600
this.fireEvent("onInitialize", [arg1, arg2], 50);
603
Widget.implement(new Events);
607
fireEvent: function(type, args, delay){
608
if (this.$events && this.$events[type]){
609
this.$events[type].each(function(fn){
610
fn.create({'bind': this, 'delay': delay, 'arguments': args})();
617
Property: removeEvent
618
removes an event from the stack of events of the Class instance.
621
type - string; the event name (e.g. 'onComplete')
622
fn - function that was added
625
removeEvent: function(type, fn){
626
if (this.$events && this.$events[type]) this.$events[type].remove(fn);
634
An "Utility" Class. Its methods can be implemented with <Class.implement> into any <Class>.
635
Used to automate the options settings, also adding Class <Events> when the option begins with on.
639
var Widget = new Class({
647
initialize: function(options){
648
this.setOptions(options);
651
Widget.implement(new Options);
653
var myWidget = new Widget({
659
//myWidget.options = {color: #f00, size: {width: 200, height: 100}}
663
var Options = new Class({
670
defaults - object; the default set of options
671
options - object; the user entered options. can be empty too.
674
if your Class has <Events> implemented, every option beginning with on, followed by a capital letter (onComplete) becomes an Class instance event.
677
setOptions: function(){
678
this.options = $merge.apply(null, [this.options].extend(arguments));
680
for (var option in this.options){
681
if ($type(this.options[option] == 'function') && (/^on[A-Z]/).test(option)) this.addEvent(option, this.options[option]);
691
Contains Array prototypes, <$A>, <$each>
699
A collection of The Array Object prototype methods.
708
Iterates through an array; This method is only available for browsers without native *forEach* support.
709
For more info see <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:forEach>
711
*forEach* executes the provided function (callback) once for each element present in the array. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values.
714
fn - function to execute with each item in the array; passed the item and the index of that item in the array
715
bind - the object to bind "this" to (see <Function.bind>)
718
>['apple','banana','lemon'].each(function(item, index){
719
> alert(index + " = " + item); //alerts "0 = apple" etc.
720
>}, bindObj); //optional second arg for binding, not used here
723
forEach: function(fn, bind){
724
for (var i = 0, j = this.length; i < j; i++) fn.call(bind, this[i], i, this);
729
This method is provided only for browsers without native *filter* support.
730
For more info see <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:filter>
732
*filter* calls a provided callback function once for each element in an array, and constructs a new array of all the values for which callback returns a true value. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. Array elements which do not pass the callback test are simply skipped, and are not included in the new array.
735
fn - function to execute with each item in the array; passed the item and the index of that item in the array
736
bind - the object to bind "this" to (see <Function.bind>)
739
>var biggerThanTwenty = [10,3,25,100].filter(function(item, index){
742
>//biggerThanTwenty = [25,100]
745
filter: function(fn, bind){
747
for (var i = 0, j = this.length; i < j; i++){
748
if (fn.call(bind, this[i], i, this)) results.push(this[i]);
755
This method is provided only for browsers without native *map* support.
756
For more info see <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:map>
758
*map* calls a provided callback function once for each element in an array, in order, and constructs a new array from the results. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values.
761
fn - function to execute with each item in the array; passed the item and the index of that item in the array
762
bind - the object to bind "this" to (see <Function.bind>)
765
>var timesTwo = [1,2,3].map(function(item, index){
768
>//timesTwo = [2,4,6];
771
map: function(fn, bind){
773
for (var i = 0, j = this.length; i < j; i++) results[i] = fn.call(bind, this[i], i, this);
779
This method is provided only for browsers without native *every* support.
780
For more info see <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every>
782
*every* executes the provided callback function once for each element present in the array until it finds one where callback returns a false value. If such an element is found, the every method immediately returns false. Otherwise, if callback returned a true value for all elements, every will return true. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values.
785
fn - function to execute with each item in the array; passed the item and the index of that item in the array
786
bind - the object to bind "this" to (see <Function.bind>)
789
>var areAllBigEnough = [10,4,25,100].every(function(item, index){
792
>//areAllBigEnough = false
795
every: function(fn, bind){
796
for (var i = 0, j = this.length; i < j; i++){
797
if (!fn.call(bind, this[i], i, this)) return false;
804
This method is provided only for browsers without native *some* support.
805
For more info see <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some>
807
*some* executes the callback function once for each element present in the array until it finds one where callback returns a true value. If such an element is found, some immediately returns true. Otherwise, some returns false. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values.
810
fn - function to execute with each item in the array; passed the item and the index of that item in the array
811
bind - the object to bind "this" to (see <Function.bind>)
814
>var isAnyBigEnough = [10,4,25,100].some(function(item, index){
817
>//isAnyBigEnough = true
820
some: function(fn, bind){
821
for (var i = 0, j = this.length; i < j; i++){
822
if (fn.call(bind, this[i], i, this)) return true;
829
This method is provided only for browsers without native *indexOf* support.
830
For more info see <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf>
832
*indexOf* compares a search element to elements of the Array using strict equality (the same method used by the ===, or triple-equals, operator).
835
item - any type of object; element to locate in the array
836
from - integer; optional; the index of the array at which to begin the search (defaults to 0)
839
>['apple','lemon','banana'].indexOf('lemon'); //returns 1
840
>['apple','lemon'].indexOf('banana'); //returns -1
843
indexOf: function(item, from){
844
var len = this.length;
845
for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){
846
if (this[i] === item) return i;
853
Same as <Array.forEach>.
856
fn - function to execute with each item in the array; passed the item and the index of that item in the array
857
bind - optional, the object that the "this" of the function will refer to.
860
>var Animals = ['Cat', 'Dog', 'Coala'];
861
>Animals.each(function(animal){
862
> document.write(animal)
868
returns a copy of the array.
871
a new array which is a copy of the current one.
874
start - integer; optional; the index where to start the copy, default is 0. If negative, it is taken as the offset from the end of the array.
875
length - integer; optional; the number of elements to copy. By default, copies all elements from start to the end of the array.
878
>var letters = ["a","b","c"];
879
>var copy = letters.copy(); // ["a","b","c"] (new instance)
882
copy: function(start, length){
884
if (start < 0) start = this.length + start;
885
length = length || (this.length - start);
887
for (var i = 0; i < length; i++) newArray[i] = this[start++];
893
Removes all occurrences of an item from the array.
896
item - the item to remove
899
the Array with all occurrences of the item removed.
902
>["1","2","3","2"].remove("2") // ["1","3"];
905
remove: function(item){
907
var len = this.length;
909
if (this[i] === item){
921
Tests an array for the presence of an item.
924
item - the item to search for in the array.
925
from - integer; optional; the index at which to begin the search, default is 0. If negative, it is taken as the offset from the end of the array.
928
true - the item was found
932
>["a","b","c"].contains("a"); // true
933
>["a","b","c"].contains("d"); // false
936
contains: function(item, from){
937
return this.indexOf(item, from) != -1;
942
Creates an object with key-value pairs based on the array of keywords passed in
943
and the current content of the array.
946
keys - the array of keywords.
950
var Animals = ['Cat', 'Dog', 'Coala', 'Lizard'];
951
var Speech = ['Miao', 'Bau', 'Fruuu', 'Mute'];
952
var Speeches = Animals.associate(Speech);
953
//Speeches['Miao'] is now Cat.
954
//Speeches['Bau'] is now Dog.
959
associate: function(keys){
960
var obj = {}, length = Math.min(this.length, keys.length);
961
for (var i = 0; i < length; i++) obj[keys[i]] = this[i];
967
Extends an array with another one.
970
array - the array to extend ours with
973
>var Animals = ['Cat', 'Dog', 'Coala'];
974
>Animals.extend(['Lizard']);
975
>//Animals is now: ['Cat', 'Dog', 'Coala', 'Lizard'];
978
extend: function(array){
979
for (var i = 0, j = array.length; i < j; i++) this.push(array[i]);
985
merges an array in another array, without duplicates. (case- and type-sensitive)
988
array - the array to merge from.
991
>['Cat','Dog'].merge(['Dog','Coala']); //returns ['Cat','Dog','Coala']
994
merge: function(array){
995
for (var i = 0, l = array.length; i < l; i++) this.include(array[i]);
1001
includes the passed in element in the array, only if its not already present. (case- and type-sensitive)
1004
item - item to add to the array (if not present)
1007
>['Cat','Dog'].include('Dog'); //returns ['Cat','Dog']
1008
>['Cat','Dog'].include('Coala'); //returns ['Cat','Dog','Coala']
1011
include: function(item){
1012
if (!this.contains(item)) this.push(item);
1018
returns a random item in the Array
1021
getRandom: function(){
1022
return this[$random(0, this.length - 1)] || null;
1027
returns the last item in the Array
1030
getLast: function(){
1031
return this[this.length - 1] || null;
1038
Array.prototype.each = Array.prototype.forEach;
1039
Array.each = Array.forEach;
1041
/* Section: Utility Functions */
1045
Same as <Array.copy>, but as function.
1046
Useful to apply Array prototypes to iterable objects, as a collection of DOM elements or the arguments object.
1050
function myFunction(){
1051
$A(arguments).each(argument, function(){
1055
//the above will alert all the arguments passed to the function myFunction.
1060
return Array.copy(array);
1065
Use to iterate through iterables that are not regular arrays, such as builtin getElementsByTagName calls, arguments of a function, or an object.
1068
iterable - an iterable element or an objct.
1069
function - function to apply to the iterable.
1070
bind - optional, the 'this' of the function will refer to this object.
1073
The function argument will be passed the following arguments.
1075
item - the current item in the iterator being procesed
1076
index - integer; the index of the item, or key in case of an object.
1080
$each(['Sun','Mon','Tue'], function(day, index){
1081
alert('name:' + day + ', index: ' + index);
1083
//alerts "name: Sun, index: 0", "name: Mon, index: 1", etc.
1085
$each({first: "Sunday", second: "Monday", third: "Tuesday"}, function(value, key){
1086
alert("the " + key + " day of the week is " + value);
1088
//alerts "the first day of the week is Sunday",
1089
//"the second day of the week is Monday", etc.
1093
function $each(iterable, fn, bind){
1094
if (iterable && typeof iterable.length == 'number' && $type(iterable) != 'object'){
1095
Array.forEach(iterable, fn, bind);
1097
for (var name in iterable) fn.call(bind || iterable, iterable[name], name);
1103
Array.prototype.test = Array.prototype.contains;
1105
/*end compatibility*/
1109
Contains String prototypes.
1117
A collection of The String Object prototype methods.
1124
Tests a string with a regular expression.
1127
regex - a string or regular expression object, the regular expression you want to match the string with
1128
params - optional, if first parameter is a string, any parameters you want to pass to the regex ('g' has no effect)
1131
true if a match for the regular expression is found in the string, false if not.
1132
See <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:RegExp:test>
1135
>"I like cookies".test("cookie"); // returns true
1136
>"I like cookies".test("COOKIE", "i") // ignore case, returns true
1137
>"I like cookies".test("cake"); // returns false
1140
test: function(regex, params){
1141
return (($type(regex) == 'string') ? new RegExp(regex, params) : regex).test(this);
1146
parses a string to an integer.
1149
either an int or "NaN" if the string is not a number.
1152
>var value = "10px".toInt(); // value is 10
1156
return parseInt(this, 10);
1161
parses a string to an float.
1164
either a float or "NaN" if the string is not a number.
1167
>var value = "10.848".toFloat(); // value is 10.848
1170
toFloat: function(){
1171
return parseFloat(this);
1176
Converts a hiphenated string to a camelcase string.
1179
>"I-like-cookies".camelCase(); //"ILikeCookies"
1182
the camel cased string
1185
camelCase: function(){
1186
return this.replace(/-\D/g, function(match){
1187
return match.charAt(1).toUpperCase();
1193
Converts a camelCased string to a hyphen-ated string.
1196
>"ILikeCookies".hyphenate(); //"I-like-cookies"
1199
hyphenate: function(){
1200
return this.replace(/\w[A-Z]/g, function(match){
1201
return (match.charAt(0) + '-' + match.charAt(1).toLowerCase());
1206
Property: capitalize
1207
Converts the first letter in each word of a string to Uppercase.
1210
>"i like cookies".capitalize(); //"I Like Cookies"
1213
the capitalized string
1216
capitalize: function(){
1217
return this.replace(/\b[a-z]/g, function(match){
1218
return match.toUpperCase();
1224
Trims the leading and trailing spaces off a string.
1227
>" i like cookies ".trim() //"i like cookies"
1234
return this.replace(/^\s+|\s+$/g, '');
1239
trims (<String.trim>) a string AND removes all the double spaces in a string.
1245
>" i like cookies \n\n".clean() //"i like cookies"
1249
return this.replace(/\s{2,}/g, ' ').trim();
1254
Converts an RGB value to hexidecimal. The string must be in the format of "rgb(255,255,255)" or "rgba(255,255,255,1)";
1257
array - boolean value, defaults to false. Use true if you want the array ['FF','33','00'] as output instead of "#FF3300"
1260
hex string or array. returns "transparent" if the output is set as string and the fourth value of rgba in input string is 0.
1263
>"rgb(17,34,51)".rgbToHex(); //"#112233"
1264
>"rgba(17,34,51,0)".rgbToHex(); //"transparent"
1265
>"rgb(17,34,51)".rgbToHex(true); //['11','22','33']
1268
rgbToHex: function(array){
1269
var rgb = this.match(/\d{1,3}/g);
1270
return (rgb) ? rgb.rgbToHex(array) : false;
1275
Converts a hexidecimal color value to RGB. Input string must be the hex color value (with or without the hash). Also accepts triplets ('333');
1278
array - boolean value, defaults to false. Use true if you want the array [255,255,255] as output instead of "rgb(255,255,255)";
1281
rgb string or array.
1284
>"#112233".hexToRgb(); //"rgb(17,34,51)"
1285
>"#112233".hexToRgb(true); //[17,34,51]
1288
hexToRgb: function(array){
1289
var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
1290
return (hex) ? hex.slice(1).hexToRgb(array) : false;
1295
checks if the passed in string is contained in the String. also accepts an optional second parameter, to check if the string is contained in a list of separated values.
1298
>'a b c'.contains('c', ' '); //true
1299
>'a bc'.contains('bc'); //true
1300
>'a bc'.contains('b', ' '); //false
1303
contains: function(string, s){
1304
return (s) ? (s + this + s).indexOf(s + string + s) > -1 : this.indexOf(string) > -1;
1308
Property: escapeRegExp
1309
Returns string with escaped regular expression characters
1312
>var search = 'animals.sheeps[1]'.escapeRegExp(); // search is now 'animals\.sheeps\[1\]'
1318
escapeRegExp: function(){
1319
return this.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
1328
see <String.rgbToHex>, but as an array method.
1331
rgbToHex: function(array){
1332
if (this.length < 3) return false;
1333
if (this.length == 4 && this[3] == 0 && !array) return 'transparent';
1335
for (var i = 0; i < 3; i++){
1336
var bit = (this[i] - 0).toString(16);
1337
hex.push((bit.length == 1) ? '0' + bit : bit);
1339
return array ? hex : '#' + hex.join('');
1344
same as <String.hexToRgb>, but as an array method.
1347
hexToRgb: function(array){
1348
if (this.length != 3) return false;
1350
for (var i = 0; i < 3; i++){
1351
rgb.push(parseInt((this[i].length == 1) ? this[i] + this[i] : this[i], 16));
1353
return array ? rgb : 'rgb(' + rgb.join(',') + ')';
1360
Contains Function prototypes and utility functions .
1366
- Some functions are inspired by those found in prototype.js <http://prototype.conio.net/> (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license
1371
A collection of The Function Object prototype methods.
1378
Main function to create closures.
1384
options - An Options object.
1387
bind - The object that the "this" of the function will refer to. Default is the current function.
1388
event - If set to true, the function will act as an event listener and receive an event as first argument.
1389
If set to a class name, the function will receive a new instance of this class (with the event passed as argument's constructor) as first argument.
1391
arguments - A single argument or array of arguments that will be passed to the function when called.
1393
If both the event and arguments options are set, the event is passed as first argument and the arguments array will follow.
1395
Default is no custom arguments, the function will receive the standard arguments when called.
1397
delay - Numeric value: if set, the returned function will delay the actual execution by this amount of milliseconds and return a timer handle when called.
1398
Default is no delay.
1399
periodical - Numeric value: if set, the returned function will periodically perform the actual execution with this specified interval and return a timer handle when called.
1400
Default is no periodical execution.
1401
attempt - If set to true, the returned function will try to execute and return either the results or false on error. Default is false.
1404
create: function(options){
1411
'periodical': false,
1414
if ($chk(options.arguments) && $type(options.arguments) != 'array') options.arguments = [options.arguments];
1415
return function(event){
1418
event = event || window.event;
1419
args = [(options.event === true) ? event : new options.event(event)];
1420
if (options.arguments) args.extend(options.arguments);
1422
else args = options.arguments || arguments;
1423
var returns = function(){
1424
return fn.apply($pick(options.bind, fn), args);
1426
if (options.delay) return setTimeout(returns, options.delay);
1427
if (options.periodical) return setInterval(returns, options.periodical);
1428
if (options.attempt) try {return returns();} catch(err){return false;};
1435
Shortcut to create closures with arguments and bind.
1441
args - the arguments passed. must be an array if arguments > 1
1442
bind - optional, the object that the "this" of the function will refer to.
1445
>myFunction.pass([arg1, arg2], myElement);
1448
pass: function(args, bind){
1449
return this.create({'arguments': args, 'bind': bind});
1454
Tries to execute the function, returns either the result of the function or false on error.
1457
args - the arguments passed. must be an array if arguments > 1
1458
bind - optional, the object that the "this" of the function will refer to.
1461
>myFunction.attempt([arg1, arg2], myElement);
1464
attempt: function(args, bind){
1465
return this.create({'arguments': args, 'bind': bind, 'attempt': true})();
1470
method to easily create closures with "this" altered.
1473
bind - optional, the object that the "this" of the function will refer to.
1474
args - optional, the arguments passed. must be an array if arguments > 1
1480
>function myFunction(){
1481
> this.setStyle('color', 'red');
1482
> // note that 'this' here refers to myFunction, not an element
1483
> // we'll need to bind this function to the element we want to alter
1485
>var myBoundFunction = myFunction.bind(myElement);
1486
>myBoundFunction(); // this will make the element myElement red.
1489
bind: function(bind, args){
1490
return this.create({'bind': bind, 'arguments': args});
1494
Property: bindAsEventListener
1495
cross browser method to pass event firer
1498
bind - optional, the object that the "this" of the function will refer to.
1499
args - optional, the arguments passed. must be an array if arguments > 1
1502
a function with the parameter bind as its "this" and as a pre-passed argument event or window.event, depending on the browser.
1505
>function myFunction(event){
1506
> alert(event.clientx) //returns the coordinates of the mouse..
1508
>myElement.onclick = myFunction.bindAsEventListener(myElement);
1511
bindAsEventListener: function(bind, args){
1512
return this.create({'bind': bind, 'event': true, 'arguments': args});
1517
Delays the execution of a function by a specified duration.
1520
delay - the duration to wait in milliseconds.
1521
bind - optional, the object that the "this" of the function will refer to.
1522
args - optional, the arguments passed. must be an array if arguments > 1
1525
>myFunction.delay(50, myElement) //wait 50 milliseconds, then call myFunction and bind myElement to it
1526
>(function(){alert('one second later...')}).delay(1000); //wait a second and alert
1529
delay: function(delay, bind, args){
1530
return this.create({'delay': delay, 'bind': bind, 'arguments': args})();
1534
Property: periodical
1535
Executes a function in the specified intervals of time
1538
interval - the duration of the intervals between executions.
1539
bind - optional, the object that the "this" of the function will refer to.
1540
args - optional, the arguments passed. must be an array if arguments > 1
1543
periodical: function(interval, bind, args){
1544
return this.create({'periodical': interval, 'bind': bind, 'arguments': args})();
1551
Contains the Number prototypes.
1559
A collection of The Number Object prototype methods.
1566
Returns this number; useful because toInt must work on both Strings and Numbers.
1570
return parseInt(this);
1575
Returns this number as a float; useful because toFloat must work on both Strings and Numbers.
1578
toFloat: function(){
1579
return parseFloat(this);
1587
min - number, minimum value
1588
max - number, maximum value
1591
the number in the given limits.
1594
>(12).limit(2, 6.5) // returns 6.5
1595
>(-4).limit(2, 6.5) // returns 2
1596
>(4.3).limit(2, 6.5) // returns 4.3
1599
limit: function(min, max){
1600
return Math.min(max, Math.max(min, this));
1605
Returns the number rounded to specified precision.
1608
precision - integer, number of digits after the decimal point. Can also be negative or zero (default).
1611
>12.45.round() // returns 12
1612
>12.45.round(1) // returns 12.5
1613
>12.45.round(-1) // returns 10
1619
round: function(precision){
1620
precision = Math.pow(10, precision || 0);
1621
return Math.round(this * precision) / precision;
1626
Executes a passed in function the specified number of times
1629
function - the function to be executed on each iteration of the loop
1635
times: function(fn){
1636
for (var i = 0; i < this; i++) fn(i);
1643
Contains useful Element prototypes, to be used with the dollar function <$>.
1649
- Some functions are inspired by those found in prototype.js <http://prototype.conio.net/> (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license
1654
Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
1657
var Element = new Class({
1660
Property: initialize
1661
Creates a new element of the type passed in.
1664
el - string; the tag name for the element you wish to create. you can also pass in an element reference, in which case it will be extended.
1665
props - object; the properties you want to add to your element.
1666
Accepts the same keys as <Element.setProperties>, but also allows events and styles
1669
the key styles will be used as setStyles, the key events will be used as addEvents. any other key is used as setProperty.
1676
'border': '1px solid black'
1679
'click': function(){
1682
'mousedown': function(){
1686
'class': 'myClassSuperClass',
1687
'href': 'http://mad4milk.net'
1693
initialize: function(el, props){
1694
if ($type(el) == 'string'){
1695
if (window.ie && props && (props.name || props.type)){
1696
var name = (props.name) ? ' name="' + props.name + '"' : '';
1697
var type = (props.type) ? ' type="' + props.type + '"' : '';
1700
el = '<' + el + name + type + '>';
1702
el = document.createElement(el);
1705
return (!props || !el) ? el : el.set(props);
1712
- Every dom function such as <$$>, or in general every function that returns a collection of nodes in mootools, returns them as an Elements class.
1713
- The purpose of the Elements class is to allow <Element> methods to work also on <Elements> array.
1714
- Elements is also an Array, so it accepts all the <Array> methods.
1715
- Every node of the Elements instance is already extended with <$>.
1718
>$$('myselector').each(function(el){
1722
some iterations here, $$('myselector') is also an array.
1724
>$$('myselector').setStyle('color', 'red');
1725
every element returned by $$('myselector') also accepts <Element> methods, in this example every element will be made red.
1728
var Elements = new Class({
1730
initialize: function(elements){
1731
return (elements) ? $extend(elements, this) : this;
1736
Elements.extend = function(props){
1737
for (var prop in props){
1738
this.prototype[prop] = props[prop];
1739
this[prop] = $native.generic(prop);
1744
Section: Utility Functions
1747
returns the element passed in with all the Element prototypes applied.
1750
el - a reference to an actual element or a string representing the id of an element
1753
>$('myElement') // gets a DOM element by id with all the Element prototypes applied.
1754
>var div = document.getElementById('myElement');
1755
>$(div) //returns an Element also with all the mootools extentions applied.
1757
You'll use this when you aren't sure if a variable is an actual element or an id, as
1758
well as just shorthand for document.getElementById().
1761
a DOM element or false (if no id was found).
1764
you need to call $ on an element only once to get all the prototypes.
1765
But its no harm to call it multiple times, as it will detect if it has been already extended.
1769
if (!el) return null;
1770
if (el.htmlElement) return Garbage.collect(el);
1771
if ([window, document].contains(el)) return el;
1772
var type = $type(el);
1773
if (type == 'string'){
1774
el = document.getElementById(el);
1775
type = (el) ? 'element' : false;
1777
if (type != 'element') return null;
1778
if (el.htmlElement) return Garbage.collect(el);
1779
if (['object', 'embed'].contains(el.tagName.toLowerCase())) return el;
1780
$extend(el, Element.prototype);
1781
el.htmlElement = function(){};
1782
return Garbage.collect(el);
1787
Selects, and extends DOM elements. Elements arrays returned with $$ will also accept all the <Element> methods.
1788
The return type of element methods run through $$ is always an array. If the return array is only made by elements,
1789
$$ will be applied automatically.
1792
HTML Collections, arrays of elements, arrays of strings as element ids, elements, strings as selectors.
1793
Any number of the above as arguments are accepted.
1796
if you load <Element.Selectors.js>, $$ will also accept CSS Selectors, otherwise the only selectors supported are tag names.
1799
>$$('a') //an array of all anchor tags on the page
1800
>$$('a', 'b') //an array of all anchor and bold tags on the page
1801
>$$('#myElement') //array containing only the element with id = myElement. (only with <Element.Selectors.js>)
1802
>$$('#myElement a.myClass') //an array of all anchor tags with the class "myClass"
1803
>//within the DOM element with id "myElement" (only with <Element.Selectors.js>)
1804
>$$(myelement, myelement2, 'a', ['myid', myid2, 'myid3'], document.getElementsByTagName('div')) //an array containing:
1805
>// the element referenced as myelement if existing,
1806
>// the element referenced as myelement2 if existing,
1807
>// all the elements with a as tag in the page,
1808
>// the element with id = myid if existing
1809
>// the element with id = myid2 if existing
1810
>// the element with id = myid3 if existing
1811
>// all the elements with div as tag in the page
1814
array - array of all the dom elements matched, extended with <$>. Returns as <Elements>.
1817
document.getElementsBySelector = document.getElementsByTagName;
1821
for (var i = 0, j = arguments.length; i < j; i++){
1822
var selector = arguments[i];
1823
switch($type(selector)){
1824
case 'element': elements.push(selector);
1825
case 'boolean': break;
1827
case 'string': selector = document.getElementsBySelector(selector, true);
1828
default: elements.extend(selector);
1831
return $$.unique(elements);
1834
$$.unique = function(array){
1836
for (var i = 0, l = array.length; i < l; i++){
1837
if (array[i].$included) continue;
1838
var element = $(array[i]);
1839
if (element && !element.$included){
1840
element.$included = true;
1841
elements.push(element);
1844
for (var n = 0, d = elements.length; n < d; n++) elements[n].$included = null;
1845
return new Elements(elements);
1848
Elements.Multi = function(property){
1850
var args = arguments;
1852
var elements = true;
1853
for (var i = 0, j = this.length, returns; i < j; i++){
1854
returns = this[i][property].apply(this[i], args);
1855
if ($type(returns) != 'element') elements = false;
1856
items.push(returns);
1858
return (elements) ? $$.unique(items) : items;
1862
Element.extend = function(properties){
1863
for (var property in properties){
1864
HTMLElement.prototype[property] = properties[property];
1865
Element.prototype[property] = properties[property];
1866
Element[property] = $native.generic(property);
1867
var elementsProperty = (Array.prototype[property]) ? property + 'Elements' : property;
1868
Elements.prototype[elementsProperty] = Elements.Multi(property);
1874
Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
1881
you can set events, styles and properties with this shortcut. same as calling new Element.
1884
set: function(props){
1885
for (var prop in props){
1886
var val = props[prop];
1888
case 'styles': this.setStyles(val); break;
1889
case 'events': if (this.addEvents) this.addEvents(val); break;
1890
case 'properties': this.setProperties(val); break;
1891
default: this.setProperty(prop, val);
1897
inject: function(el, where){
1900
case 'before': el.parentNode.insertBefore(this, el); break;
1902
var next = el.getNext();
1903
if (!next) el.parentNode.appendChild(this);
1904
else el.parentNode.insertBefore(this, next);
1907
var first = el.firstChild;
1909
el.insertBefore(this, first);
1912
default: el.appendChild(this);
1918
Property: injectBefore
1919
Inserts the Element before the passed element.
1922
el - an element reference or the id of the element to be injected in.
1926
><div id="myElement"></div>
1927
><div id="mySecondElement"></div>
1929
>$('mySecondElement').injectBefore('myElement');
1931
><div id="mySecondElement"></div>
1932
><div id="myElement"></div>
1935
injectBefore: function(el){
1936
return this.inject(el, 'before');
1940
Property: injectAfter
1941
Same as <Element.injectBefore>, but inserts the element after.
1944
injectAfter: function(el){
1945
return this.inject(el, 'after');
1949
Property: injectInside
1950
Same as <Element.injectBefore>, but inserts the element inside.
1953
injectInside: function(el){
1954
return this.inject(el, 'bottom');
1959
Same as <Element.injectInside>, but inserts the element inside, at the top.
1962
injectTop: function(el){
1963
return this.inject(el, 'top');
1968
Inserts the passed elements inside the Element.
1971
accepts elements references, element ids as string, selectors ($$('stuff')) / array of elements, array of ids as strings and collections.
1976
$each(arguments, function(argument){
1977
elements = elements.concat(argument);
1979
$$(elements).inject(this);
1985
Removes the Element from the DOM.
1988
>$('myElement').remove() //bye bye
1992
return this.parentNode.removeChild(this);
1997
Clones the Element and returns the cloned one.
2000
contents - boolean, when true the Element is cloned with childNodes, default true
2006
>var clone = $('myElement').clone().injectAfter('myElement');
2007
>//clones the Element and append the clone after the Element.
2010
clone: function(contents){
2011
var el = $(this.cloneNode(contents !== false));
2012
if (!el.$events) return el;
2014
for (var type in this.$events) el.$events[type] = {
2015
'keys': $A(this.$events[type].keys),
2016
'values': $A(this.$events[type].values)
2018
return el.removeEvents();
2022
Property: replaceWith
2023
Replaces the Element with an element passed.
2026
el - a string representing the element to be injected in (myElementId, or div), or an element reference.
2027
If you pass div or another tag, the element will be created.
2030
the passed in element
2033
>$('myOldElement').replaceWith($('myNewElement')); //$('myOldElement') is gone, and $('myNewElement') is in its place.
2036
replaceWith: function(el){
2038
this.parentNode.replaceChild(el, this);
2043
Property: appendText
2044
Appends text node to a DOM element.
2047
text - the text to append.
2050
><div id="myElement">hey</div>
2051
>$('myElement').appendText(' howdy'); //myElement innerHTML is now "hey howdy"
2054
appendText: function(text){
2055
this.appendChild(document.createTextNode(text));
2061
Tests the Element to see if it has the passed in className.
2064
true - the Element has the class
2068
className - string; the class name to test.
2071
><div id="myElement" class="testClass"></div>
2072
>$('myElement').hasClass('testClass'); //returns true
2075
hasClass: function(className){
2076
return this.className.contains(className, ' ');
2081
Adds the passed in class to the Element, if the element doesnt already have it.
2084
className - string; the class name to add
2087
><div id="myElement" class="testClass"></div>
2088
>$('myElement').addClass('newClass'); //<div id="myElement" class="testClass newClass"></div>
2091
addClass: function(className){
2092
if (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean();
2097
Property: removeClass
2098
Works like <Element.addClass>, but removes the class from the element.
2101
removeClass: function(className){
2102
this.className = this.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1').clean();
2107
Property: toggleClass
2108
Adds or removes the passed in class name to the element, depending on if it's present or not.
2111
className - the class to add or remove
2114
><div id="myElement" class="myClass"></div>
2115
>$('myElement').toggleClass('myClass');
2116
><div id="myElement" class=""></div>
2117
>$('myElement').toggleClass('myClass');
2118
><div id="myElement" class="myClass"></div>
2121
toggleClass: function(className){
2122
return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
2127
Sets a css property to the Element.
2130
property - the property to set
2131
value - the value to which to set it; for numeric values that require "px" you can pass an integer
2134
>$('myElement').setStyle('width', '300px'); //the width is now 300px
2135
>$('myElement').setStyle('width', 300); //the width is now 300px
2138
setStyle: function(property, value){
2140
case 'opacity': return this.setOpacity(parseFloat(value));
2141
case 'float': property = (window.ie) ? 'styleFloat' : 'cssFloat';
2143
property = property.camelCase();
2144
switch($type(value)){
2145
case 'number': if (!['zIndex', 'zoom'].contains(property)) value += 'px'; break;
2146
case 'array': value = 'rgb(' + value.join(',') + ')';
2148
this.style[property] = value;
2154
Applies a collection of styles to the Element.
2157
source - an object or string containing all the styles to apply. When its a string it overrides old style.
2160
>$('myElement').setStyles({
2161
> border: '1px solid #000',
2168
>$('myElement').setStyles('border: 1px solid #000; width: 300px; height: 400px;');
2171
setStyles: function(source){
2172
switch($type(source)){
2173
case 'object': Element.setMany(this, 'setStyle', source); break;
2174
case 'string': this.style.cssText = source;
2180
Property: setOpacity
2181
Sets the opacity of the Element, and sets also visibility == "hidden" if opacity == 0, and visibility = "visible" if opacity > 0.
2184
opacity - float; Accepts values from 0 to 1.
2187
>$('myElement').setOpacity(0.5) //make it 50% transparent
2190
setOpacity: function(opacity){
2192
if (this.style.visibility != "hidden") this.style.visibility = "hidden";
2194
if (this.style.visibility != "visible") this.style.visibility = "visible";
2196
if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom = 1;
2197
if (window.ie) this.style.filter = (opacity == 1) ? '' : "alpha(opacity=" + opacity * 100 + ")";
2198
this.style.opacity = this.$tmp.opacity = opacity;
2204
Returns the style of the Element given the property passed in.
2207
property - the css style property you want to retrieve
2210
>$('myElement').getStyle('width'); //returns "400px"
2211
>//but you can also use
2212
>$('myElement').getStyle('width').toInt(); //returns 400
2215
the style as a string
2218
getStyle: function(property){
2219
property = property.camelCase();
2220
var result = this.style[property];
2222
if (property == 'opacity') return this.$tmp.opacity;
2224
for (var style in Element.Styles){
2225
if (property == style){
2226
Element.Styles[style].each(function(s){
2227
var style = this.getStyle(s);
2228
result.push(parseInt(style) ? style : '0px');
2230
if (property == 'border'){
2231
var every = result.every(function(bit){
2232
return (bit == result[0]);
2234
return (every) ? result[0] : false;
2236
return result.join(' ');
2239
if (property.contains('border')){
2240
if (Element.Styles.border.contains(property)){
2241
return ['Width', 'Style', 'Color'].map(function(p){
2242
return this.getStyle(property + p);
2244
} else if (Element.borderShort.contains(property)){
2245
return ['Top', 'Right', 'Bottom', 'Left'].map(function(p){
2246
return this.getStyle('border' + p + property.replace('border', ''));
2250
if (document.defaultView) result = document.defaultView.getComputedStyle(this, null).getPropertyValue(property.hyphenate());
2251
else if (this.currentStyle) result = this.currentStyle[property];
2253
if (window.ie) result = Element.fixStyle(property, result, this);
2254
if (result && property.test(/color/i) && result.contains('rgb')){
2255
return result.split('rgb').splice(1,4).map(function(color){
2256
return color.rgbToHex();
2264
Returns an object of styles of the Element for each argument passed in.
2266
properties - strings; any number of style properties
2268
>$('myElement').getStyles('width','height','padding');
2269
>//returns an object like:
2270
>{width: "10px", height: "10px", padding: "10px 0px 10px 0px"}
2273
getStyles: function(){
2274
return Element.getMany(this, 'getStyle', arguments);
2277
walk: function(brother, start){
2278
brother += 'Sibling';
2279
var el = (start) ? this[start] : this[brother];
2280
while (el && $type(el) != 'element') el = el[brother];
2285
Property: getPrevious
2286
Returns the previousSibling of the Element, excluding text nodes.
2289
>$('myElement').getPrevious(); //get the previous DOM element from myElement
2292
the sibling element or undefined if none found.
2295
getPrevious: function(){
2296
return this.walk('previous');
2301
Works as Element.getPrevious, but tries to find the nextSibling.
2304
getNext: function(){
2305
return this.walk('next');
2310
Works as <Element.getPrevious>, but tries to find the firstChild.
2313
getFirst: function(){
2314
return this.walk('next', 'firstChild');
2319
Works as <Element.getPrevious>, but tries to find the lastChild.
2322
getLast: function(){
2323
return this.walk('previous', 'lastChild');
2328
returns the $(element.parentNode)
2331
getParent: function(){
2332
return $(this.parentNode);
2336
Property: getChildren
2337
returns all the $(element.childNodes), excluding text nodes. Returns as <Elements>.
2340
getChildren: function(){
2341
return $$(this.childNodes);
2346
returns true if the passed in element is a child of the $(element).
2349
hasChild: function(el){
2350
return !!$A(this.getElementsByTagName('*')).contains(el);
2354
Property: getProperty
2355
Gets the an attribute of the Element.
2358
property - string; the attribute to retrieve
2361
>$('myImage').getProperty('src') // returns whatever.gif
2364
the value, or an empty string
2367
getProperty: function(property){
2368
var index = Element.Properties[property];
2369
if (index) return this[index];
2370
var flag = Element.PropertiesIFlag[property] || 0;
2371
if (!window.ie || flag) return this.getAttribute(property, flag);
2372
var node = this.attributes[property];
2373
return (node) ? node.nodeValue : null;
2377
Property: removeProperty
2378
Removes an attribute from the Element
2381
property - string; the attribute to remove
2384
removeProperty: function(property){
2385
var index = Element.Properties[property];
2386
if (index) this[index] = '';
2387
else this.removeAttribute(property);
2392
Property: getProperties
2393
same as <Element.getStyles>, but for properties
2396
getProperties: function(){
2397
return Element.getMany(this, 'getProperty', arguments);
2401
Property: setProperty
2402
Sets an attribute for the Element.
2405
property - string; the property to assign the value passed in
2406
value - the value to assign to the property passed in
2409
>$('myImage').setProperty('src', 'whatever.gif'); //myImage now points to whatever.gif for its source
2412
setProperty: function(property, value){
2413
var index = Element.Properties[property];
2414
if (index) this[index] = value;
2415
else this.setAttribute(property, value);
2420
Property: setProperties
2421
Sets numerous attributes for the Element.
2424
source - an object with key/value pairs.
2428
$('myElement').setProperties({
2429
src: 'whatever.gif',
2430
alt: 'whatever dude'
2432
<img src="whatever.gif" alt="whatever dude">
2436
setProperties: function(source){
2437
return Element.setMany(this, 'setProperty', source);
2442
Sets the innerHTML of the Element.
2445
html - string; the new innerHTML for the element.
2448
>$('myElement').setHTML(newHTML) //the innerHTML of myElement is now = newHTML
2451
setHTML: function(){
2452
this.innerHTML = $A(arguments).join('');
2458
Sets the inner text of the Element.
2461
text - string; the new text content for the element.
2464
>$('myElement').setText('some text') //the text of myElement is now = 'some text'
2467
setText: function(text){
2468
var tag = this.getTag();
2469
if (['style', 'script'].contains(tag)){
2471
if (tag == 'style') this.styleSheet.cssText = text;
2472
else if (tag == 'script') this.setProperty('text', text);
2475
this.removeChild(this.firstChild);
2476
return this.appendText(text);
2479
this[$defined(this.innerText) ? 'innerText' : 'textContent'] = text;
2485
Gets the inner text of the Element.
2488
getText: function(){
2489
var tag = this.getTag();
2490
if (['style', 'script'].contains(tag)){
2492
if (tag == 'style') return this.styleSheet.cssText;
2493
else if (tag == 'script') return this.getProperty('text');
2495
return this.innerHTML;
2498
return ($pick(this.innerText, this.textContent));
2503
Returns the tagName of the element in lower case.
2506
>$('myImage').getTag() // returns 'img'
2509
The tag name in lower case
2513
return this.tagName.toLowerCase();
2518
Empties an element of all its children.
2521
>$('myDiv').empty() // empties the Div and returns it
2528
Garbage.trash(this.getElementsByTagName('*'));
2529
return this.setHTML('');
2534
Element.fixStyle = function(property, result, element){
2535
if ($chk(parseInt(result))) return result;
2536
if (['height', 'width'].contains(property)){
2537
var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom'];
2539
values.each(function(value){
2540
size += element.getStyle('border-' + value + '-width').toInt() + element.getStyle('padding-' + value).toInt();
2542
return element['offset' + property.capitalize()] - size + 'px';
2543
} else if (property.test(/border(.+)Width|margin|padding/)){
2549
Element.Styles = {'border': [], 'padding': [], 'margin': []};
2550
['Top', 'Right', 'Bottom', 'Left'].each(function(direction){
2551
for (var style in Element.Styles) Element.Styles[style].push(style + direction);
2554
Element.borderShort = ['borderWidth', 'borderStyle', 'borderColor'];
2556
Element.getMany = function(el, method, keys){
2558
$each(keys, function(key){
2559
result[key] = el[method](key);
2564
Element.setMany = function(el, method, pairs){
2565
for (var key in pairs) el[method](key, pairs[key]);
2569
Element.Properties = new Abstract({
2570
'class': 'className', 'for': 'htmlFor', 'colspan': 'colSpan', 'rowspan': 'rowSpan',
2571
'accesskey': 'accessKey', 'tabindex': 'tabIndex', 'maxlength': 'maxLength',
2572
'readonly': 'readOnly', 'frameborder': 'frameBorder', 'value': 'value',
2573
'disabled': 'disabled', 'checked': 'checked', 'multiple': 'multiple', 'selected': 'selected'
2575
Element.PropertiesIFlag = {
2581
addListener: function(type, fn){
2582
if (this.addEventListener) this.addEventListener(type, fn, false);
2583
else this.attachEvent('on' + type, fn);
2587
removeListener: function(type, fn){
2588
if (this.removeEventListener) this.removeEventListener(type, fn, false);
2589
else this.detachEvent('on' + type, fn);
2595
window.extend(Element.Methods.Listeners);
2596
document.extend(Element.Methods.Listeners);
2597
Element.extend(Element.Methods.Listeners);
2603
collect: function(el){
2605
Garbage.elements.push(el);
2606
el.$tmp = {'opacity': 1};
2611
trash: function(elements){
2612
for (var i = 0, j = elements.length, el; i < j; i++){
2613
if (!(el = elements[i]) || !el.$tmp) continue;
2614
if (el.$events) el.fireEvent('trash').removeEvents();
2615
for (var p in el.$tmp) el.$tmp[p] = null;
2616
for (var d in Element.prototype) el[d] = null;
2617
Garbage.elements[Garbage.elements.indexOf(el)] = null;
2618
el.htmlElement = el.$tmp = el = null;
2620
Garbage.elements.remove(null);
2624
Garbage.collect(window);
2625
Garbage.collect(document);
2626
Garbage.trash(Garbage.elements);
2631
window.addListener('beforeunload', function(){
2632
window.addListener('unload', Garbage.empty);
2633
if (window.ie) window.addListener('unload', CollectGarbage);
2637
Script: Element.Event.js
2638
Contains the Event Class, Element methods to deal with Element events, custom Events, and the Function prototype bindWithEvent.
2646
Cross browser methods to manage events.
2652
shift - true if the user pressed the shift
2653
control - true if the user pressed the control
2654
alt - true if the user pressed the alt
2655
meta - true if the user pressed the meta key
2656
wheel - the amount of third button scrolling
2657
code - the keycode of the key pressed
2658
page.x - the x position of the mouse, relative to the full window
2659
page.y - the y position of the mouse, relative to the full window
2660
client.x - the x position of the mouse, relative to the viewport
2661
client.y - the y position of the mouse, relative to the viewport
2662
key - the key pressed as a lowercase string. key also returns 'enter', 'up', 'down', 'left', 'right', 'space', 'backspace', 'delete', 'esc'. Handy for these special keys.
2663
target - the event target
2664
relatedTarget - the event related target
2668
$('myLink').onkeydown = function(event){
2669
var event = new Event(event);
2670
//event is now the Event class.
2671
alert(event.key); //returns the lowercase letter pressed
2672
alert(event.shift); //returns true if the key pressed is shift
2673
if (event.key == 's' && event.control) alert('document saved');
2678
var Event = new Class({
2680
initialize: function(event){
2681
if (event && event.$extended) return event;
2682
this.$extended = true;
2683
event = event || window.event;
2685
this.type = event.type;
2686
this.target = event.target || event.srcElement;
2687
if (this.target.nodeType == 3) this.target = this.target.parentNode;
2688
this.shift = event.shiftKey;
2689
this.control = event.ctrlKey;
2690
this.alt = event.altKey;
2691
this.meta = event.metaKey;
2692
if (['DOMMouseScroll', 'mousewheel'].contains(this.type)){
2693
this.wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
2694
} else if (this.type.contains('key')){
2695
this.code = event.which || event.keyCode;
2696
for (var name in Event.keys){
2697
if (Event.keys[name] == this.code){
2702
if (this.type == 'keydown'){
2703
var fKey = this.code - 111;
2704
if (fKey > 0 && fKey < 13) this.key = 'f' + fKey;
2706
this.key = this.key || String.fromCharCode(this.code).toLowerCase();
2707
} else if (this.type.test(/(click|mouse|menu)/)){
2709
'x': event.pageX || event.clientX + document.documentElement.scrollLeft,
2710
'y': event.pageY || event.clientY + document.documentElement.scrollTop
2713
'x': event.pageX ? event.pageX - window.pageXOffset : event.clientX,
2714
'y': event.pageY ? event.pageY - window.pageYOffset : event.clientY
2716
this.rightClick = (event.which == 3) || (event.button == 2);
2718
case 'mouseover': this.relatedTarget = event.relatedTarget || event.fromElement; break;
2719
case 'mouseout': this.relatedTarget = event.relatedTarget || event.toElement;
2721
this.fixRelatedTarget();
2728
cross browser method to stop an event
2732
return this.stopPropagation().preventDefault();
2736
Property: stopPropagation
2737
cross browser method to stop the propagation of an event
2740
stopPropagation: function(){
2741
if (this.event.stopPropagation) this.event.stopPropagation();
2742
else this.event.cancelBubble = true;
2747
Property: preventDefault
2748
cross browser method to prevent the default action of the event
2751
preventDefault: function(){
2752
if (this.event.preventDefault) this.event.preventDefault();
2753
else this.event.returnValue = false;
2761
relatedTarget: function(){
2762
if (this.relatedTarget && this.relatedTarget.nodeType == 3) this.relatedTarget = this.relatedTarget.parentNode;
2765
relatedTargetGecko: function(){
2766
try {Event.fix.relatedTarget.call(this);} catch(e){this.relatedTarget = this.target;}
2771
Event.prototype.fixRelatedTarget = (window.gecko) ? Event.fix.relatedTargetGecko : Event.fix.relatedTarget;
2775
you can add additional Event keys codes this way:
2779
Event.keys.whatever = 80;
2780
$(myelement).addEvent(keydown, function(event){
2781
event = new Event(event);
2782
if (event.key == 'whatever') console.log(whatever key clicked).
2787
Event.keys = new Abstract({
2802
Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
2805
Element.Methods.Events = {
2809
Attaches an event listener to a DOM element.
2812
type - the event to monitor ('click', 'load', etc) without the prefix 'on'.
2813
fn - the function to execute
2816
>$('myElement').addEvent('click', function(){alert('clicked!')});
2819
addEvent: function(type, fn){
2820
this.$events = this.$events || {};
2821
this.$events[type] = this.$events[type] || {'keys': [], 'values': []};
2822
if (this.$events[type].keys.contains(fn)) return this;
2823
this.$events[type].keys.push(fn);
2824
var realType = type;
2825
var custom = Element.Events[type];
2827
if (custom.add) custom.add.call(this, fn);
2828
if (custom.map) fn = custom.map;
2829
if (custom.type) realType = custom.type;
2831
if (!this.addEventListener) fn = fn.create({'bind': this, 'event': true});
2832
this.$events[type].values.push(fn);
2833
return (Element.NativeEvents.contains(realType)) ? this.addListener(realType, fn) : this;
2837
Property: removeEvent
2838
Works as Element.addEvent, but instead removes the previously added event listener.
2841
removeEvent: function(type, fn){
2842
if (!this.$events || !this.$events[type]) return this;
2843
var pos = this.$events[type].keys.indexOf(fn);
2844
if (pos == -1) return this;
2845
var key = this.$events[type].keys.splice(pos,1)[0];
2846
var value = this.$events[type].values.splice(pos,1)[0];
2847
var custom = Element.Events[type];
2849
if (custom.remove) custom.remove.call(this, fn);
2850
if (custom.type) type = custom.type;
2852
return (Element.NativeEvents.contains(type)) ? this.removeListener(type, value) : this;
2857
As <addEvent>, but accepts an object and add multiple events at once.
2860
addEvents: function(source){
2861
return Element.setMany(this, 'addEvent', source);
2865
Property: removeEvents
2866
removes all events of a certain type from an element. if no argument is passed in, removes all events.
2869
type - string; the event name (e.g. 'click')
2872
removeEvents: function(type){
2873
if (!this.$events) return this;
2875
for (var evType in this.$events) this.removeEvents(evType);
2876
this.$events = null;
2877
} else if (this.$events[type]){
2878
this.$events[type].keys.each(function(fn){
2879
this.removeEvent(type, fn);
2881
this.$events[type] = null;
2888
executes all events of the specified type present in the element.
2891
type - string; the event name (e.g. 'click')
2892
args - array or single object; arguments to pass to the function; if more than one argument, must be an array
2893
delay - (integer) delay (in ms) to wait to execute the event
2896
fireEvent: function(type, args, delay){
2897
if (this.$events && this.$events[type]){
2898
this.$events[type].keys.each(function(fn){
2899
fn.create({'bind': this, 'delay': delay, 'arguments': args})();
2906
Property: cloneEvents
2907
Clones all events from an element to this element.
2910
from - element, copy all events from this element
2911
type - optional, copies only events of this type
2914
cloneEvents: function(from, type){
2915
if (!from.$events) return this;
2917
for (var evType in from.$events) this.cloneEvents(from, evType);
2918
} else if (from.$events[type]){
2919
from.$events[type].keys.each(function(fn){
2920
this.addEvent(type, fn);
2928
window.extend(Element.Methods.Events);
2929
document.extend(Element.Methods.Events);
2930
Element.extend(Element.Methods.Events);
2932
/* Section: Custom Events */
2934
Element.Events = new Abstract({
2938
In addition to the standard javascript events (load, mouseover, mouseout, click, etc.) <Event.js> contains two custom events
2939
this event fires when the mouse enters the area of the dom element; will not be fired again if the mouse crosses over children of the element (unlike mouseover)
2943
>$(myElement).addEvent('mouseenter', myFunction);
2948
map: function(event){
2949
event = new Event(event);
2950
if (event.relatedTarget != this && !this.hasChild(event.relatedTarget)) this.fireEvent('mouseenter', event);
2956
this event fires when the mouse exits the area of the dom element; will not be fired again if the mouse crosses over children of the element (unlike mouseout)
2960
>$(myElement).addEvent('mouseleave', myFunction);
2965
map: function(event){
2966
event = new Event(event);
2967
if (event.relatedTarget != this && !this.hasChild(event.relatedTarget)) this.fireEvent('mouseleave', event);
2972
type: (window.gecko) ? 'DOMMouseScroll' : 'mousewheel'
2977
Element.NativeEvents = [
2978
'click', 'dblclick', 'mouseup', 'mousedown', //mouse buttons
2979
'mousewheel', 'DOMMouseScroll', //mouse wheel
2980
'mouseover', 'mouseout', 'mousemove', //mouse movement
2981
'keydown', 'keypress', 'keyup', //keys
2982
'load', 'unload', 'beforeunload', 'resize', 'move', //window
2983
'focus', 'blur', 'change', 'submit', 'reset', 'select', //forms elements
2984
'error', 'abort', 'contextmenu', 'scroll' //misc
2989
A collection of The Function Object prototype methods.
2995
Property: bindWithEvent
2996
automatically passes MooTools Event Class.
2999
bind - optional, the object that the "this" of the function will refer to.
3000
args - optional, an argument to pass to the function; if more than one argument, it must be an array of arguments.
3003
a function with the parameter bind as its "this" and as a pre-passed argument event or window.event, depending on the browser.
3006
>function myFunction(event){
3007
> alert(event.client.x) //returns the coordinates of the mouse..
3009
>myElement.addEvent('click', myFunction.bindWithEvent(myElement));
3012
bindWithEvent: function(bind, args){
3013
return this.create({'bind': bind, 'arguments': args, 'event': Event});
3020
Script: Element.Filters.js
3021
add Filters capability to <Elements>.
3029
A collection of methods to be used with <$$> elements collections.
3035
Property: filterByTag
3036
Filters the collection by a specified tag name.
3037
Returns a new Elements collection, while the original remains untouched.
3040
filterByTag: function(tag){
3041
return new Elements(this.filter(function(el){
3042
return (Element.getTag(el) == tag);
3047
Property: filterByClass
3048
Filters the collection by a specified class name.
3049
Returns a new Elements collection, while the original remains untouched.
3052
filterByClass: function(className, nocash){
3053
var elements = this.filter(function(el){
3054
return (el.className && el.className.contains(className, ' '));
3056
return (nocash) ? elements : new Elements(elements);
3060
Property: filterById
3061
Filters the collection by a specified ID.
3062
Returns a new Elements collection, while the original remains untouched.
3065
filterById: function(id, nocash){
3066
var elements = this.filter(function(el){
3067
return (el.id == id);
3069
return (nocash) ? elements : new Elements(elements);
3073
Property: filterByAttribute
3074
Filters the collection by a specified attribute.
3075
Returns a new Elements collection, while the original remains untouched.
3078
name - the attribute name.
3079
operator - optional, the attribute operator.
3080
value - optional, the attribute value, only valid if the operator is specified.
3083
filterByAttribute: function(name, operator, value, nocash){
3084
var elements = this.filter(function(el){
3085
var current = Element.getProperty(el, name);
3086
if (!current) return false;
3087
if (!operator) return true;
3089
case '=': return (current == value);
3090
case '*=': return (current.contains(value));
3091
case '^=': return (current.substr(0, value.length) == value);
3092
case '$=': return (current.substr(current.length - value.length) == value);
3093
case '!=': return (current != value);
3094
case '~=': return current.contains(value, ' ');
3098
return (nocash) ? elements : new Elements(elements);
3104
Script: Element.Selectors.js
3105
Css Query related functions and <Element> extensions
3111
/* Section: Utility Functions */
3115
Selects a single (i.e. the first found) Element based on the selector passed in and an optional filter element.
3116
Returns as <Element>.
3119
selector - string; the css selector to match
3120
filter - optional; a DOM element to limit the scope of the selector match; defaults to document.
3123
>$E('a', 'myElement') //find the first anchor tag inside the DOM element with id 'myElement'
3126
a DOM element - the first element that matches the selector
3129
function $E(selector, filter){
3130
return ($(filter) || document).getElement(selector);
3135
Returns a collection of Elements that match the selector passed in limited to the scope of the optional filter.
3136
See Also: <Element.getElements> for an alternate syntax.
3137
Returns as <Elements>.
3140
an array of dom elements that match the selector within the filter
3143
selector - string; css selector to match
3144
filter - optional; a DOM element to limit the scope of the selector match; defaults to document.
3147
>$ES("a") //gets all the anchor tags; synonymous with $$("a")
3148
>$ES('a','myElement') //get all the anchor tags within $('myElement')
3151
function $ES(selector, filter){
3152
return ($(filter) || document).getElementsBySelector(selector);
3157
'regexp': /^(\w*|\*)(?:#([\w-]+)|\.([\w-]+))?(?:\[(\w+)(?:([!*^$]?=)["']?([^"'\]]*)["']?)?])?$/,
3161
getParam: function(items, context, param, i){
3162
var temp = [context.namespaceURI ? 'xhtml:' : '', param[1]];
3163
if (param[2]) temp.push('[@id="', param[2], '"]');
3164
if (param[3]) temp.push('[contains(concat(" ", @class, " "), " ', param[3], ' ")]');
3166
if (param[5] && param[6]){
3168
case '*=': temp.push('[contains(@', param[4], ', "', param[6], '")]'); break;
3169
case '^=': temp.push('[starts-with(@', param[4], ', "', param[6], '")]'); break;
3170
case '$=': temp.push('[substring(@', param[4], ', string-length(@', param[4], ') - ', param[6].length, ' + 1) = "', param[6], '"]'); break;
3171
case '=': temp.push('[@', param[4], '="', param[6], '"]'); break;
3172
case '!=': temp.push('[@', param[4], '!="', param[6], '"]');
3175
temp.push('[@', param[4], ']');
3178
items.push(temp.join(''));
3182
getItems: function(items, context, nocash){
3184
var xpath = document.evaluate('.//' + items.join('//'), context, $$.shared.resolver, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
3185
for (var i = 0, j = xpath.snapshotLength; i < j; i++) elements.push(xpath.snapshotItem(i));
3186
return (nocash) ? elements : new Elements(elements.map($));
3193
getParam: function(items, context, param, i){
3196
var el = context.getElementById(param[2]);
3197
if (!el || ((param[1] != '*') && (Element.getTag(el) != param[1]))) return false;
3200
items = $A(context.getElementsByTagName(param[1]));
3203
items = $$.shared.getElementsByTagName(items, param[1]);
3204
if (param[2]) items = Elements.filterById(items, param[2], true);
3206
if (param[3]) items = Elements.filterByClass(items, param[3], true);
3207
if (param[4]) items = Elements.filterByAttribute(items, param[4], param[5], param[6], true);
3211
getItems: function(items, context, nocash){
3212
return (nocash) ? items : $$.unique(items);
3217
resolver: function(prefix){
3218
return (prefix == 'xhtml') ? 'http://www.w3.org/1999/xhtml' : false;
3221
getElementsByTagName: function(context, tagName){
3223
for (var i = 0, j = context.length; i < j; i++) found.extend(context[i].getElementsByTagName(tagName));
3229
$$.shared.method = (window.xpath) ? 'xpath' : 'normal';
3233
Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
3236
Element.Methods.Dom = {
3239
Property: getElements
3240
Gets all the elements within an element that match the given (single) selector.
3241
Returns as <Elements>.
3244
selector - string; the css selector to match
3247
>$('myElement').getElements('a'); // get all anchors within myElement
3248
>$('myElement').getElements('input[name=dialog]') //get all input tags with name 'dialog'
3249
>$('myElement').getElements('input[name$=log]') //get all input tags with names ending with 'log'
3252
Supports these operators in attribute selectors:
3257
- != : is not equal to
3259
Xpath is used automatically for compliant browsers.
3262
getElements: function(selector, nocash){
3264
selector = selector.trim().split(' ');
3265
for (var i = 0, j = selector.length; i < j; i++){
3266
var sel = selector[i];
3267
var param = sel.match($$.shared.regexp);
3269
param[1] = param[1] || '*';
3270
var temp = $$.shared[$$.shared.method].getParam(items, this, param, i);
3274
return $$.shared[$$.shared.method].getItems(items, this, nocash);
3278
Property: getElement
3279
Same as <Element.getElements>, but returns only the first. Alternate syntax for <$E>, where filter is the Element.
3280
Returns as <Element>.
3283
selector - string; css selector
3286
getElement: function(selector){
3287
return $(this.getElements(selector, true)[0] || false);
3291
Property: getElementsBySelector
3292
Same as <Element.getElements>, but allows for comma separated selectors, as in css. Alternate syntax for <$$>, where filter is the Element.
3293
Returns as <Elements>.
3296
selector - string; css selector
3299
getElementsBySelector: function(selector, nocash){
3301
selector = selector.split(',');
3302
for (var i = 0, j = selector.length; i < j; i++) elements = elements.concat(this.getElements(selector[i], true));
3303
return (nocash) ? elements : $$.unique(elements);
3311
Property: getElementById
3312
Targets an element with the specified id found inside the Element. Does not overwrite document.getElementById.
3315
id - string; the id of the element to find.
3318
getElementById: function(id){
3319
var el = document.getElementById(id);
3320
if (!el) return false;
3321
for (var parent = el.parentNode; parent != this; parent = parent.parentNode){
3322
if (!parent) return false;
3327
getElementsByClassName: function(className){
3328
return this.getElements('.' + className);
3331
/*end compatibility*/
3335
document.extend(Element.Methods.Dom);
3336
Element.extend(Element.Methods.Dom);
3339
Script: Element.Form.js
3340
Contains Element prototypes to deal with Forms and their elements.
3348
Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
3355
Returns the value of the Element, if its tag is textarea, select or input. getValue called on a multiple select will return an array.
3358
getValue: function(){
3359
switch(this.getTag()){
3362
$each(this.options, function(option){
3363
if (option.selected) values.push($pick(option.value, option.text));
3365
return (this.multiple) ? values : values[0];
3366
case 'input': if (!(this.checked && ['checkbox', 'radio'].contains(this.type)) && !['hidden', 'text', 'password'].contains(this.type)) break;
3367
case 'textarea': return this.value;
3372
getFormElements: function(){
3373
return $$(this.getElementsByTagName('input'), this.getElementsByTagName('select'), this.getElementsByTagName('textarea'));
3377
Property: toQueryString
3378
Reads the children inputs of the Element and generates a query string, based on their values. Used internally in <Ajax>
3382
<form id="myForm" action="submit.php">
3383
<input name="email" value="bob@bob.com">
3384
<input name="zipCode" value="90210">
3388
$('myForm').toQueryString()
3393
email=bob@bob.com&zipCode=90210
3396
toQueryString: function(){
3397
var queryString = [];
3398
this.getFormElements().each(function(el){
3400
var value = el.getValue();
3401
if (value === false || !name || el.disabled) return;
3402
var qs = function(val){
3403
queryString.push(name + '=' + encodeURIComponent(val));
3405
if ($type(value) == 'array') value.each(qs);
3408
return queryString.join('&');
3414
Script: Element.Dimensions.js
3415
Contains Element prototypes to deal with Element size and position in space.
3418
The functions in this script require n XHTML doctype.
3426
Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
3433
Scrolls the element to the specified coordinated (if the element has an overflow)
3436
x - the x coordinate
3437
y - the y coordinate
3440
>$('myElement').scrollTo(0, 100)
3443
scrollTo: function(x, y){
3444
this.scrollLeft = x;
3450
Return an Object representing the size/scroll values of the element.
3454
$('myElement').getSize();
3460
'scroll': {'x': 100, 'y': 100},
3461
'size': {'x': 200, 'y': 400},
3462
'scrollSize': {'x': 300, 'y': 500}
3467
getSize: function(){
3469
'scroll': {'x': this.scrollLeft, 'y': this.scrollTop},
3470
'size': {'x': this.offsetWidth, 'y': this.offsetHeight},
3471
'scrollSize': {'x': this.scrollWidth, 'y': this.scrollHeight}
3476
Property: getPosition
3477
Returns the real offsets of the element.
3480
overflown - optional, an array of nested scrolling containers for scroll offset calculation, use this if your element is inside any element containing scrollbars
3483
>$('element').getPosition();
3489
getPosition: function(overflown){
3490
overflown = overflown || [];
3491
var el = this, left = 0, top = 0;
3493
left += el.offsetLeft || 0;
3494
top += el.offsetTop || 0;
3495
el = el.offsetParent;
3497
overflown.each(function(element){
3498
left -= element.scrollLeft || 0;
3499
top -= element.scrollTop || 0;
3501
return {'x': left, 'y': top};
3506
Returns the distance from the top of the window to the Element.
3509
overflown - optional, an array of nested scrolling containers, see Element::getPosition
3512
getTop: function(overflown){
3513
return this.getPosition(overflown).y;
3518
Returns the distance from the left of the window to the Element.
3521
overflown - optional, an array of nested scrolling containers, see Element::getPosition
3524
getLeft: function(overflown){
3525
return this.getPosition(overflown).x;
3529
Property: getCoordinates
3530
Returns an object with width, height, left, right, top, and bottom, representing the values of the Element
3533
overflown - optional, an array of nested scrolling containers, see Element::getPosition
3537
var myValues = $('myElement').getCoordinates();
3553
getCoordinates: function(overflown){
3554
var position = this.getPosition(overflown);
3556
'width': this.offsetWidth,
3557
'height': this.offsetHeight,
3561
obj.right = obj.left + obj.width;
3562
obj.bottom = obj.top + obj.height;
3569
Script: Window.DomReady.js
3570
Contains the custom event domready, for window.
3576
/* Section: Custom Events */
3580
executes a function when the dom tree is loaded, without waiting for images. Only works when called from window.
3583
(c) Dean Edwards/Matthias Miller/John Resig, remastered for MooTools.
3586
fn - the function to execute when the DOM is ready
3589
> window.addEvent('domready', function(){
3590
> alert('the dom is ready');
3594
Element.Events.domready = {
3601
var domReady = function(){
3602
if (window.loaded) return;
3603
window.loaded = true;
3604
window.timer = $clear(window.timer);
3605
this.fireEvent('domready');
3607
if (document.readyState && window.webkit){
3608
window.timer = function(){
3609
if (['loaded','complete'].contains(document.readyState)) domReady();
3611
} else if (document.readyState && window.ie){
3612
if (!$('ie_ready')){
3613
var src = (window.location.protocol == 'https:') ? '://0' : 'javascript:void(0)';
3614
document.write('<script id="ie_ready" defer src="' + src + '"><\/script>');
3615
$('ie_ready').onreadystatechange = function(){
3616
if (this.readyState == 'complete') domReady();
3620
window.addListener("load", domReady);
3621
document.addListener("DOMContentLoaded", domReady);
3629
window.onDomReady = function(fn){
3630
return this.addEvent('domready', fn);
3633
/*end compatibility*/
3636
Script: Window.Size.js
3637
Window cross-browser dimensions methods.
3640
The Functions in this script require an XHTML doctype.
3648
Cross browser methods to get various window dimensions.
3649
Warning: All these methods require that the browser operates in strict mode, not quirks mode.
3656
Returns an integer representing the width of the browser window (without the scrollbar).
3659
getWidth: function(){
3660
if (this.webkit419) return this.innerWidth;
3661
if (this.opera) return document.body.clientWidth;
3662
return document.documentElement.clientWidth;
3667
Returns an integer representing the height of the browser window (without the scrollbar).
3670
getHeight: function(){
3671
if (this.webkit419) return this.innerHeight;
3672
if (this.opera) return document.body.clientHeight;
3673
return document.documentElement.clientHeight;
3677
Property: getScrollWidth
3678
Returns an integer representing the scrollWidth of the window.
3679
This value is equal to or bigger than <getWidth>.
3682
<http://developer.mozilla.org/en/docs/DOM:element.scrollWidth>
3685
getScrollWidth: function(){
3686
if (this.ie) return Math.max(document.documentElement.offsetWidth, document.documentElement.scrollWidth);
3687
if (this.webkit) return document.body.scrollWidth;
3688
return document.documentElement.scrollWidth;
3692
Property: getScrollHeight
3693
Returns an integer representing the scrollHeight of the window.
3694
This value is equal to or bigger than <getHeight>.
3697
<http://developer.mozilla.org/en/docs/DOM:element.scrollHeight>
3700
getScrollHeight: function(){
3701
if (this.ie) return Math.max(document.documentElement.offsetHeight, document.documentElement.scrollHeight);
3702
if (this.webkit) return document.body.scrollHeight;
3703
return document.documentElement.scrollHeight;
3707
Property: getScrollLeft
3708
Returns an integer representing the scrollLeft of the window (the number of pixels the window has scrolled from the left).
3711
<http://developer.mozilla.org/en/docs/DOM:element.scrollLeft>
3714
getScrollLeft: function(){
3715
return this.pageXOffset || document.documentElement.scrollLeft;
3719
Property: getScrollTop
3720
Returns an integer representing the scrollTop of the window (the number of pixels the window has scrolled from the top).
3723
<http://developer.mozilla.org/en/docs/DOM:element.scrollTop>
3726
getScrollTop: function(){
3727
return this.pageYOffset || document.documentElement.scrollTop;
3732
Same as <Element.getSize>
3735
getSize: function(){
3737
'size': {'x': this.getWidth(), 'y': this.getHeight()},
3738
'scrollSize': {'x': this.getScrollWidth(), 'y': this.getScrollHeight()},
3739
'scroll': {'x': this.getScrollLeft(), 'y': this.getScrollTop()}
3744
getPosition: function(){return {'x': 0, 'y': 0};}
3750
Contains <Fx.Base>, the foundamentals of the MooTools Effects.
3760
Base class for the Effects.
3763
transition - the equation to use for the effect see <Fx.Transitions>; default is <Fx.Transitions.Sine.easeInOut>
3764
duration - the duration of the effect in ms; 500 is the default.
3765
unit - the unit is 'px' by default (other values include things like 'em' for fonts or '%').
3766
wait - boolean: to wait or not to wait for a current transition to end before running another of the same instance. defaults to true.
3767
fps - the frames per second for the transition; default is 50
3770
onStart - the function to execute as the effect begins; nothing (<Class.empty>) by default.
3771
onComplete - the function to execute after the effect has processed; nothing (<Class.empty>) by default.
3772
onCancel - the function to execute when you manually stop the effect.
3775
Fx.Base = new Class({
3778
onStart: Class.empty,
3779
onComplete: Class.empty,
3780
onCancel: Class.empty,
3781
transition: function(p){
3782
return -(Math.cos(Math.PI * p) - 1) / 2;
3790
initialize: function(options){
3791
this.element = this.element || null;
3792
this.setOptions(options);
3793
if (this.options.initialize) this.options.initialize.call(this);
3798
if (time < this.time + this.options.duration){
3799
this.delta = this.options.transition((time - this.time) / this.options.duration);
3805
this.fireEvent('onComplete', this.element, 10);
3812
Immediately sets the value with no transition.
3815
to - the point to jump to
3818
>var myFx = new Fx.Style('myElement', 'opacity').set(0); //will make it immediately transparent
3828
this.now = this.compute(this.from, this.to);
3831
compute: function(from, to){
3832
return (to - from) * this.delta + from;
3837
Executes an effect from one position to the other.
3840
from - integer: staring value
3841
to - integer: the ending value
3844
>var myFx = new Fx.Style('myElement', 'opacity').start(0,1); //display a transition from transparent to opaque.
3847
start: function(from, to){
3848
if (!this.options.wait) this.stop();
3849
else if (this.timer) return this;
3852
this.change = this.to - this.from;
3853
this.time = $time();
3854
this.timer = this.step.periodical(Math.round(1000 / this.options.fps), this);
3855
this.fireEvent('onStart', this.element);
3861
Stops the transition.
3864
stop: function(end){
3865
if (!this.timer) return this;
3866
this.timer = $clear(this.timer);
3867
if (!end) this.fireEvent('onCancel', this.element);
3871
custom: function(from, to){
3872
return this.start(from, to);
3875
clearTimer: function(end){
3876
return this.stop(end);
3879
/*end compatibility*/
3883
Fx.Base.implement(new Chain, new Events, new Options);
3887
Css parsing class for effects. Required by <Fx.Style>, <Fx.Styles>, <Fx.Elements>. No documentation needed, as its used internally.
3895
select: function(property, to){
3896
if (property.test(/color/i)) return this.Color;
3897
var type = $type(to);
3898
if ((type == 'array') || (type == 'string' && to.contains(' '))) return this.Multi;
3902
parse: function(el, property, fromTo){
3903
if (!fromTo.push) fromTo = [fromTo];
3904
var from = fromTo[0], to = fromTo[1];
3907
from = el.getStyle(property);
3909
var css = this.select(property, to);
3910
return {'from': css.parse(from), 'to': css.parse(to), 'css': css};
3917
parse: function(value){
3918
return parseFloat(value);
3921
getNow: function(from, to, fx){
3922
return fx.compute(from, to);
3925
getValue: function(value, unit, property){
3926
if (unit == 'px' && property != 'opacity') value = Math.round(value);
3927
return value + unit;
3934
parse: function(value){
3935
return value.push ? value : value.split(' ').map(function(v){
3936
return parseFloat(v);
3940
getNow: function(from, to, fx){
3942
for (var i = 0; i < from.length; i++) now[i] = fx.compute(from[i], to[i]);
3946
getValue: function(value, unit, property){
3947
if (unit == 'px' && property != 'opacity') value = value.map(Math.round);
3948
return value.join(unit + ' ') + unit;
3955
parse: function(value){
3956
return value.push ? value : value.hexToRgb(true);
3959
getNow: function(from, to, fx){
3961
for (var i = 0; i < from.length; i++) now[i] = Math.round(fx.compute(from[i], to[i]));
3965
getValue: function(value){
3966
return 'rgb(' + value.join(',') + ')';
3981
The Style effect, used to transition any css property from one value to another. Includes colors.
3982
Colors must be in hex format.
3983
Inherits methods, properties, options and events from <Fx.Base>.
3986
el - the $(element) to apply the style transition to
3987
property - the property to transition
3988
options - the Fx.Base options (see: <Fx.Base>)
3991
>var marginChange = new Fx.Style('myElement', 'margin-top', {duration:500});
3992
>marginChange.start(10, 100);
3995
Fx.Style = Fx.Base.extend({
3997
initialize: function(el, property, options){
3998
this.element = $(el);
3999
this.property = property;
4000
this.parent(options);
4005
Same as <Fx.Base.set> (0); hides the element immediately without transition.
4013
this.now = this.css.getNow(this.from, this.to, this);
4018
Sets the element's css property (specified at instantiation) to the specified value immediately.
4022
var marginChange = new Fx.Style('myElement', 'margin-top', {duration:500});
4023
marginChange.set(10); //margin-top is set to 10px immediately
4028
this.css = Fx.CSS.select(this.property, to);
4029
return this.parent(this.css.parse(to));
4034
Displays the transition to the value/values passed in
4037
from - (integer; optional) the starting position for the transition
4038
to - (integer) the ending position for the transition
4041
If you provide only one argument, the transition will use the current css value for its starting value.
4045
var marginChange = new Fx.Style('myElement', 'margin-top', {duration:500});
4046
marginChange.start(10); //tries to read current margin top value and goes from current to 10
4050
start: function(from, to){
4051
if (this.timer && this.options.wait) return this;
4052
var parsed = Fx.CSS.parse(this.element, this.property, [from, to]);
4053
this.css = parsed.css;
4054
return this.parent(parsed.from, parsed.to);
4057
increase: function(){
4058
this.element.setStyle(this.property, this.css.getValue(this.now, this.options.unit, this.property));
4065
Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
4072
Applies an <Fx.Style> to the Element; This a shortcut for <Fx.Style>.
4075
property - (string) the css property to alter
4076
options - (object; optional) key/value set of options (see <Fx.Style>)
4079
>var myEffect = $('myElement').effect('height', {duration: 1000, transition: Fx.Transitions.linear});
4080
>myEffect.start(10, 100);
4082
>$('myElement').effect('height', {duration: 1000, transition: Fx.Transitions.linear}).start(10,100);
4085
effect: function(property, options){
4086
return new Fx.Style(this, property, options);
4092
Script: Fx.Styles.js
4093
Contains <Fx.Styles>
4101
Allows you to animate multiple css properties at once;
4102
Colors must be in hex format.
4103
Inherits methods, properties, options and events from <Fx.Base>.
4106
el - the $(element) to apply the styles transition to
4107
options - the fx options (see: <Fx.Base>)
4111
var myEffects = new Fx.Styles('myElement', {duration: 1000, transition: Fx.Transitions.linear});
4113
//height from 10 to 100 and width from 900 to 300
4115
'height': [10, 100],
4119
//or height from current height to 100 and width from current width to 300
4127
Fx.Styles = Fx.Base.extend({
4129
initialize: function(el, options){
4130
this.element = $(el);
4131
this.parent(options);
4135
for (var p in this.from) this.now[p] = this.css[p].getNow(this.from[p], this.to[p], this);
4142
this.css[p] = Fx.CSS.select(p, to[p]);
4143
parsed[p] = this.css[p].parse(to[p]);
4145
return this.parent(parsed);
4150
Executes a transition for any number of css properties in tandem.
4153
obj - an object containing keys that specify css properties to alter and values that specify either the from/to values (as an array) or just the end value (an integer).
4159
start: function(obj){
4160
if (this.timer && this.options.wait) return this;
4163
var from = {}, to = {};
4165
var parsed = Fx.CSS.parse(this.element, p, obj[p]);
4166
from[p] = parsed.from;
4168
this.css[p] = parsed.css;
4170
return this.parent(from, to);
4173
increase: function(){
4174
for (var p in this.now) this.element.setStyle(p, this.css[p].getValue(this.now[p], this.options.unit, p));
4181
Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
4188
Applies an <Fx.Styles> to the Element; This a shortcut for <Fx.Styles>.
4191
>var myEffects = $(myElement).effects({duration: 1000, transition: Fx.Transitions.Sine.easeInOut});
4192
>myEffects.start({'height': [10, 100], 'width': [900, 300]});
4195
effects: function(options){
4196
return new Fx.Styles(this, options);
4202
Script: Fx.Elements.js
4203
Contains <Fx.Elements>
4211
Fx.Elements allows you to apply any number of styles transitions to a selection of elements. Includes colors (must be in hex format).
4212
Inherits methods, properties, options and events from <Fx.Base>.
4215
elements - a collection of elements the effects will be applied to.
4216
options - same as <Fx.Base> options.
4219
Fx.Elements = Fx.Base.extend({
4221
initialize: function(elements, options){
4222
this.elements = $$(elements);
4223
this.parent(options);
4227
for (var i in this.from){
4228
var iFrom = this.from[i], iTo = this.to[i], iCss = this.css[i], iNow = this.now[i] = {};
4229
for (var p in iFrom) iNow[p] = iCss[p].getNow(iFrom[p], iTo[p], this);
4237
var iTo = to[i], iCss = this.css[i] = {}, iParsed = parsed[i] = {};
4239
iCss[p] = Fx.CSS.select(p, iTo[p]);
4240
iParsed[p] = iCss[p].parse(iTo[p]);
4243
return this.parent(parsed);
4248
Applies the passed in style transitions to each object named (see example). Each item in the collection is refered to as a numerical string ("1" for instance). The first item is "0", the second "1", etc.
4252
var myElementsEffects = new Fx.Elements($$('a'));
4253
myElementsEffects.start({
4254
'0': { //let's change the first element's opacity and width
4258
'4': { //and the fifth one's opacity
4259
'opacity': [0.2, 0.5]
4265
start: function(obj){
4266
if (this.timer && this.options.wait) return this;
4269
var from = {}, to = {};
4271
var iProps = obj[i], iFrom = from[i] = {}, iTo = to[i] = {}, iCss = this.css[i] = {};
4272
for (var p in iProps){
4273
var parsed = Fx.CSS.parse(this.elements[i], p, iProps[p]);
4274
iFrom[p] = parsed.from;
4276
iCss[p] = parsed.css;
4279
return this.parent(from, to);
4282
increase: function(){
4283
for (var i in this.now){
4284
var iNow = this.now[i], iCss = this.css[i];
4285
for (var p in iNow) this.elements[i].setStyle(p, iCss[p].getValue(iNow[p], this.options.unit, p));
4292
Script: Fx.Scroll.js
4293
Contains <Fx.Scroll>
4301
Scroll any element with an overflow, including the window element.
4302
Inherits methods, properties, options and events from <Fx.Base>.
4305
Fx.Scroll requires an XHTML doctype.
4308
element - the element to scroll
4309
options - optional, see Options below.
4312
all the Fx.Base options and events, plus:
4313
offset - the distance for the scrollTo point/element. an Object with x/y properties.
4314
overflown - an array of nested scrolling containers, see <Element.getPosition>
4317
Fx.Scroll = Fx.Base.extend({
4321
offset: {'x': 0, 'y': 0},
4325
initialize: function(element, options){
4327
this.element = $(element);
4328
this.bound = {'stop': this.stop.bind(this, false)};
4329
this.parent(options);
4330
if (this.options.wheelStops){
4331
this.addEvent('onStart', function(){
4332
document.addEvent('mousewheel', this.bound.stop);
4334
this.addEvent('onComplete', function(){
4335
document.removeEvent('mousewheel', this.bound.stop);
4341
for (var i = 0; i < 2; i++) this.now[i] = this.compute(this.from[i], this.to[i]);
4346
Scrolls the chosen element to the x/y coordinates.
4349
x - the x coordinate to scroll the element to
4350
y - the y coordinate to scroll the element to
4353
scrollTo: function(x, y){
4354
if (this.timer && this.options.wait) return this;
4355
var el = this.element.getSize();
4356
var values = {'x': x, 'y': y};
4357
for (var z in el.size){
4358
var max = el.scrollSize[z] - el.size[z];
4359
if ($chk(values[z])) values[z] = ($type(values[z]) == 'number') ? values[z].limit(0, max) : max;
4360
else values[z] = el.scroll[z];
4361
values[z] += this.options.offset[z];
4363
return this.start([el.scroll.x, el.scroll.y], [values.x, values.y]);
4368
Scrolls the chosen element to its maximum top.
4372
return this.scrollTo(false, 0);
4377
Scrolls the chosen element to its maximum bottom.
4380
toBottom: function(){
4381
return this.scrollTo(false, 'full');
4386
Scrolls the chosen element to its maximum left.
4390
return this.scrollTo(0, false);
4395
Scrolls the chosen element to its maximum right.
4398
toRight: function(){
4399
return this.scrollTo('full', false);
4404
Scrolls the specified element to the position the passed in element is found.
4407
el - the $(element) to scroll the window to
4410
toElement: function(el){
4411
var parent = this.element.getPosition(this.options.overflown);
4412
var target = $(el).getPosition(this.options.overflown);
4413
return this.scrollTo(target.x - parent.x, target.y - parent.y);
4416
increase: function(){
4417
this.element.scrollTo(this.now[0], this.now[1]);
4432
The slide effect; slides an element in horizontally or vertically, the contents will fold inside.
4433
Inherits methods, properties, options and events from <Fx.Base>.
4436
Fx.Slide requires an XHTML doctype.
4439
mode - set it to vertical or horizontal. Defaults to vertical.
4440
options - all the <Fx.Base> options
4444
var mySlider = new Fx.Slide('myElement', {duration: 500});
4445
mySlider.toggle() //toggle the slider up and down.
4449
Fx.Slide = Fx.Base.extend({
4455
initialize: function(el, options){
4456
this.element = $(el);
4457
this.wrapper = new Element('div', {'styles': $extend(this.element.getStyles('margin'), {'overflow': 'hidden'})}).injectAfter(this.element).adopt(this.element);
4458
this.element.setStyle('margin', 0);
4459
this.setOptions(options);
4461
this.parent(this.options);
4463
this.addEvent('onComplete', function(){
4464
this.open = (this.now[0] === 0);
4466
if (window.webkit419) this.addEvent('onComplete', function(){
4467
if (this.open) this.element.remove().inject(this.wrapper);
4472
for (var i = 0; i < 2; i++) this.now[i] = this.compute(this.from[i], this.to[i]);
4475
vertical: function(){
4476
this.margin = 'margin-top';
4477
this.layout = 'height';
4478
this.offset = this.element.offsetHeight;
4481
horizontal: function(){
4482
this.margin = 'margin-left';
4483
this.layout = 'width';
4484
this.offset = this.element.offsetWidth;
4489
Slides the elements in view horizontally or vertically.
4492
mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
4495
slideIn: function(mode){
4496
this[mode || this.options.mode]();
4497
return this.start([this.element.getStyle(this.margin).toInt(), this.wrapper.getStyle(this.layout).toInt()], [0, this.offset]);
4502
Sides the elements out of view horizontally or vertically.
4505
mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
4508
slideOut: function(mode){
4509
this[mode || this.options.mode]();
4510
return this.start([this.element.getStyle(this.margin).toInt(), this.wrapper.getStyle(this.layout).toInt()], [-this.offset, 0]);
4515
Hides the element without a transition.
4518
mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
4521
hide: function(mode){
4522
this[mode || this.options.mode]();
4524
return this.set([-this.offset, 0]);
4529
Shows the element without a transition.
4532
mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
4535
show: function(mode){
4536
this[mode || this.options.mode]();
4538
return this.set([0, this.offset]);
4543
Slides in or Out the element, depending on its state
4546
mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
4550
toggle: function(mode){
4551
if (this.wrapper.offsetHeight == 0 || this.wrapper.offsetWidth == 0) return this.slideIn(mode);
4552
return this.slideOut(mode);
4555
increase: function(){
4556
this.element.setStyle(this.margin, this.now[0] + this.options.unit);
4557
this.wrapper.setStyle(this.layout, this.now[1] + this.options.unit);
4563
Script: Fx.Transitions.js
4564
Effects transitions, to be used with all the effects.
4570
Easing Equations by Robert Penner, <http://www.robertpenner.com/easing/>, modified & optimized to be used with mootools.
4574
Class: Fx.Transitions
4575
A collection of tweening transitions for use with the <Fx.Base> classes.
4578
>//Elastic.easeOut with default values:
4579
>new Fx.Style('margin', {transition: Fx.Transitions.Elastic.easeOut});
4580
>//Elastic.easeOut with user-defined value for elasticity.
4581
> var myTransition = new Fx.Transition(Fx.Transitions.Elastic, 3);
4582
>new Fx.Style('margin', {transition: myTransition.easeOut});
4585
http://www.robertpenner.com/easing/
4588
Fx.Transition = function(transition, params){
4589
params = params || [];
4590
if ($type(params) != 'array') params = [params];
4591
return $extend(transition, {
4592
easeIn: function(pos){
4593
return transition(pos, params);
4595
easeOut: function(pos){
4596
return 1 - transition(1 - pos, params);
4598
easeInOut: function(pos){
4599
return (pos <= 0.5) ? transition(2 * pos, params) / 2 : (2 - transition(2 * (1 - pos), params)) / 2;
4604
Fx.Transitions = new Abstract({
4608
displays a linear transition.
4614
linear: function(p){
4620
Fx.Transitions.extend = function(transitions){
4621
for (var transition in transitions){
4622
Fx.Transitions[transition] = new Fx.Transition(transitions[transition]);
4624
Fx.Transitions.compat(transition);
4625
/*end compatibility*/
4631
Fx.Transitions.compat = function(transition){
4632
['In', 'Out', 'InOut'].each(function(easeType){
4633
Fx.Transitions[transition.toLowerCase() + easeType] = Fx.Transitions[transition]['ease' + easeType];
4637
/*end compatibility*/
4639
Fx.Transitions.extend({
4643
displays a quadratic transition. Must be used as Quad.easeIn or Quad.easeOut or Quad.easeInOut
4653
displays a cubicular transition. Must be used as Cubic.easeIn or Cubic.easeOut or Cubic.easeInOut
4663
displays a quartetic transition. Must be used as Quart.easeIn or Quart.easeOut or Quart.easeInOut
4673
displays a quintic transition. Must be used as Quint.easeIn or Quint.easeOut or Quint.easeInOut
4683
Used to generate Quad, Cubic, Quart and Quint.
4690
Pow: function(p, x){
4691
return Math.pow(p, x[0] || 6);
4696
displays a exponential transition. Must be used as Expo.easeIn or Expo.easeOut or Expo.easeInOut
4703
return Math.pow(2, 8 * (p - 1));
4708
displays a circular transition. Must be used as Circ.easeIn or Circ.easeOut or Circ.easeInOut
4715
return 1 - Math.sin(Math.acos(p));
4721
displays a sineousidal transition. Must be used as Sine.easeIn or Sine.easeOut or Sine.easeInOut
4728
return 1 - Math.sin((1 - p) * Math.PI / 2);
4733
makes the transition go back, then all forth. Must be used as Back.easeIn or Back.easeOut or Back.easeInOut
4739
Back: function(p, x){
4741
return Math.pow(p, 2) * ((x + 1) * p - x);
4746
makes the transition bouncy. Must be used as Bounce.easeIn or Bounce.easeOut or Bounce.easeInOut
4752
Bounce: function(p){
4754
for (var a = 0, b = 1; 1; a += b, b /= 2){
4755
if (p >= (7 - 4 * a) / 11){
4756
value = - Math.pow((11 - 6 * a - 11 * p) / 4, 2) + b * b;
4765
Elastic curve. Must be used as Elastic.easeIn or Elastic.easeOut or Elastic.easeInOut
4771
Elastic: function(p, x){
4772
return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x[0] || 1) / 3);
4777
['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i){
4778
Fx.Transitions[transition] = new Fx.Transition(function(p){
4779
return Math.pow(p, [i + 2]);
4783
Fx.Transitions.compat(transition);
4784
/*end compatibility*/
4788
Script: Drag.Base.js
4789
Contains <Drag.Base>, <Element.makeResizable>
4799
Modify two css properties of an element based on the position of the mouse.
4802
Drag.Base requires an XHTML doctype.
4805
el - the $(element) to apply the transformations to.
4806
options - optional. The options object.
4809
handle - the $(element) to act as the handle for the draggable element. defaults to the $(element) itself.
4810
modifiers - an object. see Modifiers Below.
4811
limit - an object, see Limit below.
4812
grid - optional, distance in px for snap-to-grid dragging
4813
snap - optional, the distance you have to drag before the element starts to respond to the drag. defaults to false
4816
x - string, the style you want to modify when the mouse moves in an horizontal direction. defaults to 'left'
4817
y - string, the style you want to modify when the mouse moves in a vertical direction. defaults to 'top'
4820
x - array with start and end limit relative to modifiers.x
4821
y - array with start and end limit relative to modifiers.y
4824
onStart - optional, function to execute when the user starts to drag (on mousedown);
4825
onComplete - optional, function to execute when the user completes the drag.
4826
onDrag - optional, function to execute at every step of the drag
4829
Drag.Base = new Class({
4834
onStart: Class.empty,
4835
onBeforeStart: Class.empty,
4836
onComplete: Class.empty,
4837
onSnap: Class.empty,
4838
onDrag: Class.empty,
4840
modifiers: {x: 'left', y: 'top'},
4845
initialize: function(el, options){
4846
this.setOptions(options);
4847
this.element = $(el);
4848
this.handle = $(this.options.handle) || this.element;
4849
this.mouse = {'now': {}, 'pos': {}};
4850
this.value = {'start': {}, 'now': {}};
4852
'start': this.start.bindWithEvent(this),
4853
'check': this.check.bindWithEvent(this),
4854
'drag': this.drag.bindWithEvent(this),
4855
'stop': this.stop.bind(this)
4858
if (this.options.initialize) this.options.initialize.call(this);
4862
this.handle.addEvent('mousedown', this.bound.start);
4867
this.handle.removeEvent('mousedown', this.bound.start);
4871
start: function(event){
4872
this.fireEvent('onBeforeStart', this.element);
4873
this.mouse.start = event.page;
4874
var limit = this.options.limit;
4875
this.limit = {'x': [], 'y': []};
4876
for (var z in this.options.modifiers){
4877
if (!this.options.modifiers[z]) continue;
4878
this.value.now[z] = this.element.getStyle(this.options.modifiers[z]).toInt();
4879
this.mouse.pos[z] = event.page[z] - this.value.now[z];
4880
if (limit && limit[z]){
4881
for (var i = 0; i < 2; i++){
4882
if ($chk(limit[z][i])) this.limit[z][i] = ($type(limit[z][i]) == 'function') ? limit[z][i]() : limit[z][i];
4886
if ($type(this.options.grid) == 'number') this.options.grid = {'x': this.options.grid, 'y': this.options.grid};
4887
document.addListener('mousemove', this.bound.check);
4888
document.addListener('mouseup', this.bound.stop);
4889
this.fireEvent('onStart', this.element);
4893
check: function(event){
4894
var distance = Math.round(Math.sqrt(Math.pow(event.page.x - this.mouse.start.x, 2) + Math.pow(event.page.y - this.mouse.start.y, 2)));
4895
if (distance > this.options.snap){
4896
document.removeListener('mousemove', this.bound.check);
4897
document.addListener('mousemove', this.bound.drag);
4899
this.fireEvent('onSnap', this.element);
4904
drag: function(event){
4906
this.mouse.now = event.page;
4907
for (var z in this.options.modifiers){
4908
if (!this.options.modifiers[z]) continue;
4909
this.value.now[z] = this.mouse.now[z] - this.mouse.pos[z];
4911
if ($chk(this.limit[z][1]) && (this.value.now[z] > this.limit[z][1])){
4912
this.value.now[z] = this.limit[z][1];
4914
} else if ($chk(this.limit[z][0]) && (this.value.now[z] < this.limit[z][0])){
4915
this.value.now[z] = this.limit[z][0];
4919
if (this.options.grid[z]) this.value.now[z] -= (this.value.now[z] % this.options.grid[z]);
4920
this.element.setStyle(this.options.modifiers[z], this.value.now[z] + this.options.unit);
4922
this.fireEvent('onDrag', this.element);
4927
document.removeListener('mousemove', this.bound.check);
4928
document.removeListener('mousemove', this.bound.drag);
4929
document.removeListener('mouseup', this.bound.stop);
4930
this.fireEvent('onComplete', this.element);
4935
Drag.Base.implement(new Events, new Options);
4939
Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
4945
Property: makeResizable
4946
Makes an element resizable (by dragging) with the supplied options.
4949
options - see <Drag.Base> for acceptable options.
4952
makeResizable: function(options){
4953
return new Drag.Base(this, $merge({modifiers: {x: 'width', y: 'height'}}, options));
4959
Script: Drag.Move.js
4960
Contains <Drag.Move>, <Element.makeDraggable>
4968
Extends <Drag.Base>, has additional functionality for dragging an element, support snapping and droppables.
4969
Drag.move supports either position absolute or relative. If no position is found, absolute will be set.
4970
Inherits methods, properties, options and events from <Drag.Base>.
4973
Drag.Move requires an XHTML doctype.
4976
el - the $(element) to apply the drag to.
4977
options - optional. see Options below.
4980
all the drag.Base options, plus:
4981
container - an element, will fill automatically limiting options based on the $(element) size and position. defaults to false (no limiting)
4982
droppables - an array of elements you can drop your draggable to.
4983
overflown - an array of nested scrolling containers, see Element::getPosition
4986
Drag.Move = Drag.Base.extend({
4994
initialize: function(el, options){
4995
this.setOptions(options);
4996
this.element = $(el);
4997
this.droppables = $$(this.options.droppables);
4998
this.container = $(this.options.container);
4999
this.position = {'element': this.element.getStyle('position'), 'container': false};
5000
if (this.container) this.position.container = this.container.getStyle('position');
5001
if (!['relative', 'absolute', 'fixed'].contains(this.position.element)) this.position.element = 'absolute';
5002
var top = this.element.getStyle('top').toInt();
5003
var left = this.element.getStyle('left').toInt();
5004
if (this.position.element == 'absolute' && !['relative', 'absolute', 'fixed'].contains(this.position.container)){
5005
top = $chk(top) ? top : this.element.getTop(this.options.overflown);
5006
left = $chk(left) ? left : this.element.getLeft(this.options.overflown);
5008
top = $chk(top) ? top : 0;
5009
left = $chk(left) ? left : 0;
5011
this.element.setStyles({'top': top, 'left': left, 'position': this.position.element});
5012
this.parent(this.element);
5015
start: function(event){
5017
if (this.container){
5018
var cont = this.container.getCoordinates();
5019
var el = this.element.getCoordinates();
5020
if (this.position.element == 'absolute' && !['relative', 'absolute', 'fixed'].contains(this.position.container)){
5021
this.options.limit = {
5022
'x': [cont.left, cont.right - el.width],
5023
'y': [cont.top, cont.bottom - el.height]
5026
this.options.limit = {
5027
'y': [0, cont.height - el.height],
5028
'x': [0, cont.width - el.width]
5035
drag: function(event){
5037
var overed = this.out ? false : this.droppables.filter(this.checkAgainst, this).getLast();
5038
if (this.overed != overed){
5039
if (this.overed) this.overed.fireEvent('leave', [this.element, this]);
5040
this.overed = overed ? overed.fireEvent('over', [this.element, this]) : null;
5045
checkAgainst: function(el){
5046
el = el.getCoordinates(this.options.overflown);
5047
var now = this.mouse.now;
5048
return (now.x > el.left && now.x < el.right && now.y < el.bottom && now.y > el.top);
5052
if (this.overed && !this.out) this.overed.fireEvent('drop', [this.element, this]);
5053
else this.element.fireEvent('emptydrop', this);
5062
Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
5068
Property: makeDraggable
5069
Makes an element draggable with the supplied options.
5072
options - see <Drag.Move> and <Drag.Base> for acceptable options.
5075
makeDraggable: function(options){
5076
return new Drag.Move(this, options);
5083
Contains the basic XMLHttpRequest Class Wrapper.
5091
Basic XMLHttpRequest Wrapper.
5094
options - an object with options names as keys. See options below.
5097
method - 'post' or 'get' - the protocol for the request; optional, defaults to 'post'.
5098
async - boolean: asynchronous option; true uses asynchronous requests. Defaults to true.
5099
encoding - the encoding, defaults to utf-8.
5100
autoCancel - cancels the already running request if another one is sent. defaults to false.
5101
headers - accepts an object, that will be set to request headers.
5104
onRequest - function to execute when the XHR request is fired.
5105
onSuccess - function to execute when the XHR request completes.
5106
onStateChange - function to execute when the state of the XMLHttpRequest changes.
5107
onFailure - function to execute when the state of the XMLHttpRequest changes.
5110
running - true if the request is running.
5111
response - object, text and xml as keys. You can access this property in the onSuccess event.
5114
>var myXHR = new XHR({method: 'get'}).send('http://site.com/requestHandler.php', 'name=john&lastname=dorian');
5117
var XHR = new Class({
5122
onRequest: Class.empty,
5123
onSuccess: Class.empty,
5124
onFailure: Class.empty,
5131
setTransport: function(){
5132
this.transport = (window.XMLHttpRequest) ? new XMLHttpRequest() : (window.ie ? new ActiveXObject('Microsoft.XMLHTTP') : false);
5136
initialize: function(options){
5137
this.setTransport().setOptions(options);
5138
this.options.isSuccess = this.options.isSuccess || this.isSuccess;
5140
if (this.options.urlEncoded && this.options.method == 'post'){
5141
var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : '';
5142
this.setHeader('Content-type', 'application/x-www-form-urlencoded' + encoding);
5144
if (this.options.initialize) this.options.initialize.call(this);
5147
onStateChange: function(){
5148
if (this.transport.readyState != 4 || !this.running) return;
5149
this.running = false;
5151
try {status = this.transport.status;} catch(e){};
5152
if (this.options.isSuccess.call(this, status)) this.onSuccess();
5153
else this.onFailure();
5154
this.transport.onreadystatechange = Class.empty;
5157
isSuccess: function(status){
5158
return ((status >= 200) && (status < 300));
5161
onSuccess: function(){
5163
'text': this.transport.responseText,
5164
'xml': this.transport.responseXML
5166
this.fireEvent('onSuccess', [this.response.text, this.response.xml]);
5170
onFailure: function(){
5171
this.fireEvent('onFailure', this.transport);
5176
Add/modify an header for the request. It will not override headers from the options.
5179
>var myXhr = new XHR(url, {method: 'get', headers: {'X-Request': 'JSON'}});
5180
>myXhr.setHeader('Last-Modified','Sat, 1 Jan 2005 05:00:00 GMT');
5183
setHeader: function(name, value){
5184
this.headers[name] = value;
5190
Opens the XHR connection and sends the data. Data has to be null or a string.
5193
>var myXhr = new XHR({method: 'post'});
5194
>myXhr.send(url, querystring);
5196
>var syncXhr = new XHR({async: false, method: 'post'});
5197
>syncXhr.send(url, null);
5201
send: function(url, data){
5202
if (this.options.autoCancel) this.cancel();
5203
else if (this.running) return this;
5204
this.running = true;
5205
if (data && this.options.method == 'get'){
5206
url = url + (url.contains('?') ? '&' : '?') + data;
5209
this.transport.open(this.options.method.toUpperCase(), url, this.options.async);
5210
this.transport.onreadystatechange = this.onStateChange.bind(this);
5211
if ((this.options.method == 'post') && this.transport.overrideMimeType) this.setHeader('Connection', 'close');
5212
$extend(this.headers, this.options.headers);
5213
for (var type in this.headers) try {this.transport.setRequestHeader(type, this.headers[type]);} catch(e){};
5214
this.fireEvent('onRequest');
5215
this.transport.send($pick(data, null));
5221
Cancels the running request. No effect if the request is not running.
5224
>var myXhr = new XHR({method: 'get'}).send(url);
5229
if (!this.running) return this;
5230
this.running = false;
5231
this.transport.abort();
5232
this.transport.onreadystatechange = Class.empty;
5233
this.setTransport();
5234
this.fireEvent('onCancel');
5240
XHR.implement(new Chain, new Events, new Options);
5244
Contains the <Ajax> class. Also contains methods to generate querystings from forms and Objects.
5247
Loosely based on the version from prototype.js <http://prototype.conio.net>
5255
An Ajax class, For all your asynchronous needs.
5256
Inherits methods, properties, options and events from <XHR>.
5259
url - the url pointing to the server-side script.
5260
options - optional, an object containing options.
5263
data - you can write parameters here. Can be a querystring, an object or a Form element.
5264
update - $(element) to insert the response text of the XHR into, upon completion of the request.
5265
evalScripts - boolean; default is false. Execute scripts in the response text onComplete. When the response is javascript the whole response is evaluated.
5266
evalResponse - boolean; default is false. Force global evalulation of the whole response, no matter what content-type it is.
5269
onComplete - function to execute when the ajax request completes.
5272
>var myAjax = new Ajax(url, {method: 'get'}).request();
5275
var Ajax = XHR.extend({
5280
onComplete: Class.empty,
5285
initialize: function(url, options){
5286
this.addEvent('onSuccess', this.onComplete);
5287
this.setOptions(options);
5289
this.options.data = this.options.data || this.options.postBody;
5290
/*end compatibility*/
5291
if (!['post', 'get'].contains(this.options.method)){
5292
this._method = '_method=' + this.options.method;
5293
this.options.method = 'post';
5296
this.setHeader('X-Requested-With', 'XMLHttpRequest');
5297
this.setHeader('Accept', 'text/javascript, text/html, application/xml, text/xml, */*');
5301
onComplete: function(){
5302
if (this.options.update) $(this.options.update).empty().setHTML(this.response.text);
5303
if (this.options.evalScripts || this.options.evalResponse) this.evalScripts();
5304
this.fireEvent('onComplete', [this.response.text, this.response.xml], 20);
5309
Executes the ajax request.
5312
>var myAjax = new Ajax(url, {method: 'get'});
5317
>new Ajax(url, {method: 'get'}).request();
5320
request: function(data){
5321
data = data || this.options.data;
5322
switch($type(data)){
5323
case 'element': data = $(data).toQueryString(); break;
5324
case 'object': data = Object.toQueryString(data);
5326
if (this._method) data = (data) ? [this._method, data].join('&') : this._method;
5327
return this.send(this.url, data);
5331
Property: evalScripts
5332
Executes scripts in the response text
5335
evalScripts: function(){
5336
var script, scripts;
5337
if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type'))) scripts = this.response.text;
5340
var regexp = /<script[^>]*>([\s\S]*?)<\/script>/gi;
5341
while ((script = regexp.exec(this.response.text))) scripts.push(script[1]);
5342
scripts = scripts.join('\n');
5344
if (scripts) (window.execScript) ? window.execScript(scripts) : window.setTimeout(scripts, 0);
5349
Returns the given response header or null
5352
getHeader: function(name){
5353
try {return this.transport.getResponseHeader(name);} catch(e){};
5359
/* Section: Object related Functions */
5362
Function: Object.toQueryString
5363
Generates a querystring from key/pair values in an object
5366
source - the object to generate the querystring from.
5372
>Object.toQueryString({apple: "red", lemon: "yellow"}); //returns "apple=red&lemon=yellow"
5375
Object.toQueryString = function(source){
5376
var queryString = [];
5377
for (var property in source) queryString.push(encodeURIComponent(property) + '=' + encodeURIComponent(source[property]));
5378
return queryString.join('&');
5383
Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
5390
Sends a form with an ajax post request
5393
options - option collection for ajax request. See <Ajax> for the options list.
5396
The Ajax Class Instance
5400
<form id="myForm" action="submit.php">
5401
<input name="email" value="bob@bob.com">
5402
<input name="zipCode" value="90210">
5410
send: function(options){
5411
return new Ajax(this.getProperty('action'), $merge({data: this.toQueryString()}, options, {method: 'post'})).request();
5418
A cookie reader/creator
5421
based on the functions by Peter-Paul Koch (http://quirksmode.org)
5426
Class for creating, getting, and removing cookies.
5429
var Cookie = new Abstract({
5440
Sets a cookie in the browser.
5443
key - the key (name) for the cookie
5444
value - the value to set, cannot contain semicolons
5445
options - an object representing the Cookie options. See Options below. Default values are stored in Cookie.options.
5448
domain - the domain the Cookie belongs to. If you want to share the cookie with pages located on a different domain, you have to set this value. Defaults to the current domain.
5449
path - the path the Cookie belongs to. If you want to share the cookie with pages located in a different path, you have to set this value, for example to "/" to share the cookie with all pages on the domain. Defaults to the current path.
5450
duration - the duration of the Cookie before it expires, in days.
5451
If set to false or 0, the cookie will be a session cookie that expires when the browser is closed. This is default.
5452
secure - Stored cookie information can be accessed only from a secure environment.
5455
An object with the options, the key and the value. You can give it as first parameter to Cookie.remove.
5458
>Cookie.set('username', 'Harald'); // session cookie (duration is false), or ...
5459
>Cookie.set('username', 'JackBauer', {duration: 1}); // save this for 1 day
5463
set: function(key, value, options){
5464
options = $merge(this.options, options);
5465
value = encodeURIComponent(value);
5466
if (options.domain) value += '; domain=' + options.domain;
5467
if (options.path) value += '; path=' + options.path;
5468
if (options.duration){
5469
var date = new Date();
5470
date.setTime(date.getTime() + options.duration * 24 * 60 * 60 * 1000);
5471
value += '; expires=' + date.toGMTString();
5473
if (options.secure) value += '; secure';
5474
document.cookie = key + '=' + value;
5475
return $extend(options, {'key': key, 'value': value});
5480
Gets the value of a cookie.
5483
key - the name of the cookie you wish to retrieve.
5486
The cookie string value, or false if not found.
5489
>Cookie.get("username") //returns JackBauer
5493
var value = document.cookie.match('(?:^|;)\\s*' + key.escapeRegExp() + '=([^;]*)');
5494
return value ? decodeURIComponent(value[1]) : false;
5499
Removes a cookie from the browser.
5502
cookie - the name of the cookie to remove or a previous cookie (for domains)
5503
options - optional. you can also pass the domain and path here. Same as options in <Cookie.set>
5506
>Cookie.remove('username') //bye-bye JackBauer, cya in 24 hours
5508
>var myCookie = Cookie.set('username', 'Aaron', {domain: 'mootools.net'}); // Cookie.set returns an object with all values need to remove the cookie
5509
>Cookie.remove(myCookie);
5512
remove: function(cookie, options){
5513
if ($type(cookie) == 'object') this.set(cookie.key, '', $merge(cookie, {duration: -1}));
5514
else this.set(cookie, '', $merge(options, {duration: -1}));
5521
Simple Json parser and Stringyfier, See: <http://www.json.org/>
5529
Simple Json parser and Stringyfier, See: <http://www.json.org/>
5536
Converts an object to a string, to be passed in server-side scripts as a parameter. Although its not normal usage for this class, this method can also be used to convert functions and arrays to strings.
5539
obj - the object to convert to string
5546
Json.toString({apple: 'red', lemon: 'yellow'}); '{"apple":"red","lemon":"yellow"}'
5550
toString: function(obj){
5553
return '"' + obj.replace(/(["\\])/g, '\\$1') + '"';
5555
return '[' + obj.map(Json.toString).join(',') + ']';
5558
for (var property in obj) string.push(Json.toString(property) + ':' + Json.toString(obj[property]));
5559
return '{' + string.join(',') + '}';
5561
if (isFinite(obj)) break;
5570
converts a json string to an javascript Object.
5573
str - the string to evaluate. if its not a string, it returns false.
5574
secure - optionally, performs syntax check on json string. Defaults to false.
5577
Json test regexp is by Douglas Crockford <http://crockford.org>.
5580
>var myObject = Json.evaluate('{"apple":"red","lemon":"yellow"}');
5581
>//myObject will become {apple: 'red', lemon: 'yellow'}
5584
evaluate: function(str, secure){
5585
return (($type(str) != 'string') || (secure && !str.test(/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/))) ? null : eval('(' + str + ')');
5591
Script: Json.Remote.js
5592
Contains <Json.Remote>.
5600
Wrapped XHR with automated sending and receiving of Javascript Objects in Json Format.
5601
Inherits methods, properties, options and events from <XHR>.
5604
url - the url you want to send your object to.
5605
options - see <XHR> options
5608
this code will send user information based on name/last name
5610
var jSonRequest = new Json.Remote("http://site.com/tellMeAge.php", {onComplete: function(person){
5611
alert(person.age); //is 25 years
5612
alert(person.height); //is 170 cm
5613
alert(person.weight); //is 120 kg
5614
}}).send({'name': 'John', 'lastName': 'Doe'});
5618
Json.Remote = XHR.extend({
5620
initialize: function(url, options){
5622
this.addEvent('onSuccess', this.onComplete);
5623
this.parent(options);
5624
this.setHeader('X-Request', 'JSON');
5627
send: function(obj){
5628
return this.parent(this.url, 'json=' + Json.toString(obj));
5631
onComplete: function(){
5632
this.fireEvent('onComplete', [Json.evaluate(this.response.text, this.options.secure)]);
5639
provides dynamic loading for images, css and javascript files.
5645
var Asset = new Abstract({
5648
Property: javascript
5649
Injects a javascript file in the page.
5652
source - the path of the javascript file
5653
properties - some additional attributes you might want to add to the script element
5656
> new Asset.javascript('/scripts/myScript.js', {id: 'myScript'});
5659
javascript: function(source, properties){
5660
properties = $merge({
5661
'onload': Class.empty
5663
var script = new Element('script', {'src': source}).addEvents({
5664
'load': properties.onload,
5665
'readystatechange': function(){
5666
if (this.readyState == 'complete') this.fireEvent('load');
5669
delete properties.onload;
5670
return script.setProperties(properties).inject(document.head);
5675
Injects a css file in the page.
5678
source - the path of the css file
5679
properties - some additional attributes you might want to add to the link element
5682
> new Asset.css('/css/myStyle.css', {id: 'myStyle', title: 'myStyle'});
5685
css: function(source, properties){
5686
return new Element('link', $merge({
5687
'rel': 'stylesheet', 'media': 'screen', 'type': 'text/css', 'href': source
5688
}, properties)).inject(document.head);
5693
Preloads an image and returns the img element. does not inject it to the page.
5696
source - the path of the image file
5697
properties - some additional attributes you might want to add to the img element
5700
> new Asset.image('/images/myImage.png', {id: 'myImage', title: 'myImage', onload: myFunction});
5703
the img element. you can inject it anywhere you want with <Element.injectInside>/<Element.injectAfter>/<Element.injectBefore>
5706
image: function(source, properties){
5707
properties = $merge({
5708
'onload': Class.empty,
5709
'onabort': Class.empty,
5710
'onerror': Class.empty
5712
var image = new Image();
5714
var element = new Element('img', {'src': source});
5715
['load', 'abort', 'error'].each(function(type){
5716
var event = properties['on' + type];
5717
delete properties['on' + type];
5718
element.addEvent(type, function(){
5719
this.removeEvent(type, arguments.callee);
5723
if (image.width && image.height) element.fireEvent('load', element, 1);
5724
return element.setProperties(properties);
5729
Preloads an array of images (as strings) and returns an array of img elements. does not inject them to the page.
5732
sources - array, the paths of the image files
5733
options - object, see below
5736
onComplete - a function to execute when all image files are loaded in the browser's cache
5737
onProgress - a function to execute when one image file is loaded in the browser's cache
5741
new Asset.images(['/images/myImage.png', '/images/myImage2.gif'], {
5742
onComplete: function(){
5743
alert('all images loaded!');
5749
the img elements as $$. you can inject them anywhere you want with <Element.injectInside>/<Element.injectAfter>/<Element.injectBefore>
5752
images: function(sources, options){
5754
onComplete: Class.empty,
5755
onProgress: Class.empty
5757
if (!sources.push) sources = [sources];
5760
sources.each(function(source){
5761
var img = new Asset.image(source, {
5762
'onload': function(){
5763
options.onProgress.call(this, counter);
5765
if (counter == sources.length) options.onComplete();
5770
return new Elements(images);
5777
Contains the class Hash.
5785
It wraps an object that it uses internally as a map. The user must use set(), get(), and remove() to add/change, retrieve and remove values, it must not access the internal object directly. null/undefined values are allowed.
5788
Each hash instance has the length property.
5791
obj - an object to convert into a Hash instance.
5795
var hash = new Hash({a: 'hi', b: 'world', c: 'howdy'});
5796
hash.remove('b'); // b is removed.
5797
hash.set('c', 'hello');
5798
hash.get('c'); // returns 'hello'
5799
hash.length // returns 2 (a and c)
5803
var Hash = new Class({
5807
initialize: function(object){
5808
this.obj = object || {};
5814
Retrieves a value from the hash.
5824
return (this.hasKey(key)) ? this.obj[key] : null;
5829
Check the presence of a specified key-value pair in the hash.
5835
True if the Hash contains a value for the specified key, otherwise false
5838
hasKey: function(key){
5839
return (key in this.obj);
5844
Adds a key-value pair to the hash or replaces a previous value associated with the key.
5851
set: function(key, value){
5852
if (!this.hasKey(key)) this.length++;
5853
this.obj[key] = value;
5857
setLength: function(){
5859
for (var p in this.obj) this.length++;
5865
Removes a key-value pair from the hash.
5871
remove: function(key){
5872
if (this.hasKey(key)){
5873
delete this.obj[key];
5881
Calls a function for each key-value pair. The first argument passed to the function will be the value, the second one will be the key, like $each.
5884
fn - The function to call for each key-value pair
5885
bind - Optional, the object that will be referred to as "this" in the function
5888
each: function(fn, bind){
5889
$each(this.obj, fn, bind);
5894
Extends the current hash with an object containing key-value pairs. Values for duplicate keys will be replaced by the new ones.
5897
obj - An object containing key-value pairs
5900
extend: function(obj){
5901
$extend(this.obj, obj);
5902
return this.setLength();
5907
Merges the current hash with multiple objects.
5911
this.obj = $merge.apply(null, [this.obj].extend(arguments));
5912
return this.setLength();
5917
Empties all hash values properties and values.
5928
Returns an array containing all the keys, in the same order as the values returned by <Hash.values>.
5931
An array containing all the keys of the hash
5936
for (var property in this.obj) keys.push(property);
5942
Returns an array containing all the values, in the same order as the keys returned by <Hash.keys>.
5945
An array containing all the values of the hash
5950
for (var property in this.obj) values.push(this.obj[property]);
5956
/* Section: Utility Functions */
5960
Shortcut to create a Hash from an Object.
5964
return new Hash(obj);
5968
Script: Hash.Cookie.js
5969
Stores and loads an Hash as a cookie using Json format.
5974
Inherits all the methods from <Hash>, additional methods are save and load.
5975
Hash json string has a limit of 4kb (4096byte), so be careful with your Hash size.
5976
Creating a new instance automatically loads the data from the Cookie into the Hash.
5977
If the Hash is emptied, the cookie is also removed.
5980
name - the key (name) for the cookie
5981
options - options are identical to <Cookie> and are simply passed along to it.
5982
In addition, it has the autoSave option, to save the cookie at every operation. defaults to true.
5986
var fruits = new Hash.Cookie('myCookieName', {duration: 3600});
5991
fruits.set('melon', 'green');
5992
fruits.get('lemon'); // yellow
5994
// ... on another page ... values load automatically
5996
var fruits = new Hash.Cookie('myCookieName', {duration: 365});
5997
fruits.get('melon'); // green
5999
fruits.erase(); // delete cookie
6003
Hash.Cookie = Hash.extend({
6005
initialize: function(name, options){
6007
this.options = $extend({'autoSave': true}, options || {});
6013
Saves the Hash to the cookie. If the hash is empty, removes the cookie.
6016
Returns false when the JSON string cookie is too long (4kb), otherwise true.
6020
var login = new Hash.Cookie('userstatus', {autoSave: false});
6024
'credentials': [4, 7, 9]
6026
login.set('last_message', 'User logged in!');
6028
login.save(); // finally save the Hash
6033
if (this.length == 0){
6034
Cookie.remove(this.name, this.options);
6037
var str = Json.toString(this.obj);
6038
if (str.length > 4096) return false; //cookie would be truncated!
6039
Cookie.set(this.name, str, this.options);
6045
Loads the cookie and assigns it to the Hash.
6049
this.obj = Json.evaluate(Cookie.get(this.name), true) || {};
6055
Hash.Cookie.Methods = {};
6056
['extend', 'set', 'merge', 'empty', 'remove'].each(function(method){
6057
Hash.Cookie.Methods[method] = function(){
6058
Hash.prototype[method].apply(this, arguments);
6059
if (this.options.autoSave) this.save();
6063
Hash.Cookie.implement(Hash.Cookie.Methods);
6067
Contains the Color class.
6075
Creates a new Color Object, which is an array with some color specific methods.
6077
color - the hex, the RGB array or the HSB array of the color to create. For HSB colors, you need to specify the second argument.
6078
type - a string representing the type of the color to create. needs to be specified if you intend to create the color with HSB values, or an array of HEX values. Can be 'rgb', 'hsb' or 'hex'.
6082
var black = new Color('#000');
6083
var purple = new Color([255,0,255]);
6084
// mix black with white and purple, each time at 10% of the new color
6085
var darkpurple = black.mix('#fff', purple, 10);
6086
$('myDiv').setStyle('background-color', darkpurple);
6090
var Color = new Class({
6092
initialize: function(color, type){
6093
type = type || (color.push ? 'rgb' : 'hex');
6098
hsb = rgb.rgbToHsb();
6101
rgb = color.hsbToRgb();
6105
rgb = color.hexToRgb(true);
6106
hsb = rgb.rgbToHsb();
6109
rgb.hex = rgb.rgbToHex();
6110
return $extend(rgb, Color.prototype);
6115
Mixes two or more colors with the Color.
6118
color - a color to mix. you can use as arguments how many colors as you want to mix with the original one.
6119
alpha - if you use a number as the last argument, it will be threated as the amount of the color to mix.
6123
var colors = $A(arguments);
6124
var alpha = ($type(colors[colors.length - 1]) == 'number') ? colors.pop() : 50;
6125
var rgb = this.copy();
6126
colors.each(function(color){
6127
color = new Color(color);
6128
for (var i = 0; i < 3; i++) rgb[i] = Math.round((rgb[i] / 100 * (100 - alpha)) + (color[i] / 100 * alpha));
6130
return new Color(rgb, 'rgb');
6139
return new Color(this.map(function(value){
6146
Modifies the hue of the Color, and returns a new one.
6149
value - the hue to set
6152
setHue: function(value){
6153
return new Color([value, this.hsb[1], this.hsb[2]], 'hsb');
6157
Property: setSaturation
6158
Changes the saturation of the Color, and returns a new one.
6161
percent - the percentage of the saturation to set
6164
setSaturation: function(percent){
6165
return new Color([this.hsb[0], percent, this.hsb[2]], 'hsb');
6169
Property: setBrightness
6170
Changes the brightness of the Color, and returns a new one.
6173
percent - the percentage of the brightness to set
6176
setBrightness: function(percent){
6177
return new Color([this.hsb[0], this.hsb[1], percent], 'hsb');
6182
/* Section: Utility Functions */
6186
Shortcut to create a new color, based on red, green, blue values.
6189
r - (integer) red value (0-255)
6190
g - (integer) green value (0-255)
6191
b - (integer) blue value (0-255)
6195
function $RGB(r, g, b){
6196
return new Color([r, g, b], 'rgb');
6201
Shortcut to create a new color, based on hue, saturation, brightness values.
6204
h - (integer) hue value (0-100)
6205
s - (integer) saturation value (0-100)
6206
b - (integer) brightness value (0-100)
6209
function $HSB(h, s, b){
6210
return new Color([h, s, b], 'hsb');
6215
A collection of The Array Object prototype methods.
6222
Converts a RGB array to an HSB array.
6228
rgbToHsb: function(){
6229
var red = this[0], green = this[1], blue = this[2];
6230
var hue, saturation, brightness;
6231
var max = Math.max(red, green, blue), min = Math.min(red, green, blue);
6232
var delta = max - min;
6233
brightness = max / 255;
6234
saturation = (max != 0) ? delta / max : 0;
6235
if (saturation == 0){
6238
var rr = (max - red) / delta;
6239
var gr = (max - green) / delta;
6240
var br = (max - blue) / delta;
6241
if (red == max) hue = br - gr;
6242
else if (green == max) hue = 2 + rr - br;
6243
else hue = 4 + gr - rr;
6247
return [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100)];
6252
Converts an HSB array to an RGB array.
6258
hsbToRgb: function(){
6259
var br = Math.round(this[2] / 100 * 255);
6261
return [br, br, br];
6263
var hue = this[0] % 360;
6265
var p = Math.round((this[2] * (100 - this[1])) / 10000 * 255);
6266
var q = Math.round((this[2] * (6000 - this[1] * f)) / 600000 * 255);
6267
var t = Math.round((this[2] * (6000 - this[1] * (60 - f))) / 600000 * 255);
6268
switch(Math.floor(hue / 60)){
6269
case 0: return [br, t, p];
6270
case 1: return [q, br, p];
6271
case 2: return [p, br, t];
6272
case 3: return [p, q, br];
6273
case 4: return [t, p, br];
6274
case 5: return [br, p, q];
6284
Contains the <Scroller>.
6292
The Scroller is a class to scroll any element with an overflow (including the window) when the mouse cursor reaches certain buondaries of that element.
6293
You must call its start method to start listening to mouse movements.
6296
The Scroller requires an XHTML doctype.
6299
element - required, the element to scroll.
6300
options - optional, see options below, and <Fx.Base> options.
6303
area - integer, the necessary boundaries to make the element scroll.
6304
velocity - integer, velocity ratio, the modifier for the window scrolling speed.
6307
onChange - optionally, when the mouse reaches some boundaries, you can choose to alter some other values, instead of the scrolling offsets.
6308
Automatically passes as parameters x and y values.
6311
var Scroller = new Class({
6316
onChange: function(x, y){
6317
this.element.scrollTo(x, y);
6321
initialize: function(element, options){
6322
this.setOptions(options);
6323
this.element = $(element);
6324
this.mousemover = ([window, document].contains(element)) ? $(document.body) : this.element;
6329
The scroller starts listening to mouse movements.
6333
this.coord = this.getCoords.bindWithEvent(this);
6334
this.mousemover.addListener('mousemove', this.coord);
6339
The scroller stops listening to mouse movements.
6343
this.mousemover.removeListener('mousemove', this.coord);
6344
this.timer = $clear(this.timer);
6347
getCoords: function(event){
6348
this.page = (this.element == window) ? event.client : event.page;
6349
if (!this.timer) this.timer = this.scroll.periodical(50, this);
6353
var el = this.element.getSize();
6354
var pos = this.element.getPosition();
6356
var change = {'x': 0, 'y': 0};
6357
for (var z in this.page){
6358
if (this.page[z] < (this.options.area + pos[z]) && el.scroll[z] != 0)
6359
change[z] = (this.page[z] - this.options.area - pos[z]) * this.options.velocity;
6360
else if (this.page[z] + this.options.area > (el.size[z] + pos[z]) && el.scroll[z] + el.size[z] != el.scrollSize[z])
6361
change[z] = (this.page[z] - el.size[z] + this.options.area - pos[z]) * this.options.velocity;
6363
if (change.y || change.x) this.fireEvent('onChange', [el.scroll.x + change.x, el.scroll.y + change.y]);
6368
Scroller.implement(new Events, new Options);
6380
Creates a slider with two elements: a knob and a container. Returns the values.
6383
The Slider requires an XHTML doctype.
6386
element - the knob container
6388
options - see Options below
6391
steps - the number of steps for your slider.
6392
mode - either 'horizontal' or 'vertical'. defaults to horizontal.
6393
offset - relative offset for knob position. default to 0.
6396
onChange - a function to fire when the value changes.
6397
onComplete - a function to fire when you're done dragging.
6398
onTick - optionally, you can alter the onTick behavior, for example displaying an effect of the knob moving to the desired position.
6399
Passes as parameter the new position.
6402
var Slider = new Class({
6405
onChange: Class.empty,
6406
onComplete: Class.empty,
6407
onTick: function(pos){
6408
this.knob.setStyle(this.p, pos);
6415
initialize: function(el, knob, options){
6416
this.element = $(el);
6417
this.knob = $(knob);
6418
this.setOptions(options);
6419
this.previousChange = -1;
6420
this.previousEnd = -1;
6422
this.element.addEvent('mousedown', this.clickedElement.bindWithEvent(this));
6424
switch(this.options.mode){
6428
mod = {'x': 'left', 'y': false};
6429
offset = 'offsetWidth';
6434
mod = {'x': false, 'y': 'top'};
6435
offset = 'offsetHeight';
6437
this.max = this.element[offset] - this.knob[offset] + (this.options.offset * 2);
6438
this.half = this.knob[offset]/2;
6439
this.getPos = this.element['get' + this.p.capitalize()].bind(this.element);
6440
this.knob.setStyle('position', 'relative').setStyle(this.p, - this.options.offset);
6442
lim[this.z] = [- this.options.offset, this.max - this.options.offset];
6443
this.drag = new Drag.Base(this.knob, {
6447
onStart: function(){
6453
onComplete: function(){
6458
if (this.options.initialize) this.options.initialize.call(this);
6463
The slider will get the step you pass.
6469
set: function(step){
6470
this.step = step.limit(0, this.options.steps);
6473
this.fireEvent('onTick', this.toPosition(this.step));
6477
clickedElement: function(event){
6478
var position = event.page[this.z] - this.getPos() - this.half;
6479
position = position.limit(-this.options.offset, this.max -this.options.offset);
6480
this.step = this.toStep(position);
6483
this.fireEvent('onTick', position);
6486
draggedKnob: function(){
6487
this.step = this.toStep(this.drag.value.now[this.z]);
6491
checkStep: function(){
6492
if (this.previousChange != this.step){
6493
this.previousChange = this.step;
6494
this.fireEvent('onChange', this.step);
6499
if (this.previousEnd !== this.step){
6500
this.previousEnd = this.step;
6501
this.fireEvent('onComplete', this.step + '');
6505
toStep: function(position){
6506
return Math.round((position + this.options.offset) / this.max * this.options.steps);
6509
toPosition: function(step){
6510
return this.max * step / this.options.steps;
6515
Slider.implement(new Events);
6516
Slider.implement(new Options);
6519
Script: SmoothScroll.js
6520
Contains <SmoothScroll>
6528
Auto targets all the anchors in a page and display a smooth scrolling effect upon clicking them.
6529
Inherits methods, properties, options and events from <Fx.Scroll>.
6532
SmoothScroll requires an XHTML doctype.
6535
options - the Fx.Scroll options (see: <Fx.Scroll>) plus links, a collection of elements you want your smoothscroll on. Defaults to document.links.
6538
>new SmoothScroll();
6541
var SmoothScroll = Fx.Scroll.extend({
6543
initialize: function(options){
6544
this.parent(window, options);
6545
this.links = (this.options.links) ? $$(this.options.links) : $$(document.links);
6546
var location = window.location.href.match(/^[^#]*/)[0] + '#';
6547
this.links.each(function(link){
6548
if (link.href.indexOf(location) != 0) return;
6549
var anchor = link.href.substr(location.length);
6550
if (anchor && $(anchor)) this.useLink(link, anchor);
6552
if (!window.webkit419) this.addEvent('onComplete', function(){
6553
window.location.hash = this.anchor;
6557
useLink: function(link, anchor){
6558
link.addEvent('click', function(event){
6559
this.anchor = anchor;
6560
this.toElement(anchor);
6562
}.bindWithEvent(this));
6568
Script: Sortables.js
6569
Contains <Sortables> Class.
6577
Creates an interface for <Drag.Base> and drop, resorting of a list.
6580
The Sortables require an XHTML doctype.
6583
list - required, the list that will become sortable.
6584
options - an Object, see options below.
6587
handles - a collection of elements to be used for drag handles. defaults to the elements.
6590
onStart - function executed when the item starts dragging
6591
onComplete - function executed when the item ends dragging
6594
var Sortables = new Class({
6598
onStart: Class.empty,
6599
onComplete: Class.empty,
6602
onDragStart: function(element, ghost){
6603
ghost.setStyle('opacity', 0.7);
6604
element.setStyle('opacity', 0.7);
6606
onDragComplete: function(element, ghost){
6607
element.setStyle('opacity', 1);
6609
this.trash.remove();
6613
initialize: function(list, options){
6614
this.setOptions(options);
6615
this.list = $(list);
6616
this.elements = this.list.getChildren();
6617
this.handles = (this.options.handles) ? $$(this.options.handles) : this.elements;
6620
'moveGhost': this.moveGhost.bindWithEvent(this)
6622
for (var i = 0, l = this.handles.length; i < l; i++){
6623
this.bound.start[i] = this.start.bindWithEvent(this, this.elements[i]);
6626
if (this.options.initialize) this.options.initialize.call(this);
6627
this.bound.move = this.move.bindWithEvent(this);
6628
this.bound.end = this.end.bind(this);
6632
this.handles.each(function(handle, i){
6633
handle.addEvent('mousedown', this.bound.start[i]);
6638
this.handles.each(function(handle, i){
6639
handle.removeEvent('mousedown', this.bound.start[i]);
6643
start: function(event, el){
6645
this.coordinates = this.list.getCoordinates();
6646
if (this.options.ghost){
6647
var position = el.getPosition();
6648
this.offset = event.page.y - position.y;
6649
this.trash = new Element('div').inject(document.body);
6650
this.ghost = el.clone().inject(this.trash).setStyles({
6651
'position': 'absolute',
6653
'top': event.page.y - this.offset
6655
document.addListener('mousemove', this.bound.moveGhost);
6656
this.fireEvent('onDragStart', [el, this.ghost]);
6658
document.addListener('mousemove', this.bound.move);
6659
document.addListener('mouseup', this.bound.end);
6660
this.fireEvent('onStart', el);
6664
moveGhost: function(event){
6665
var value = event.page.y - this.offset;
6666
value = value.limit(this.coordinates.top, this.coordinates.bottom - this.ghost.offsetHeight);
6667
this.ghost.setStyle('top', value);
6671
move: function(event){
6672
var now = event.page.y;
6673
this.previous = this.previous || now;
6674
var up = ((this.previous - now) > 0);
6675
var prev = this.active.getPrevious();
6676
var next = this.active.getNext();
6677
if (prev && up && now < prev.getCoordinates().bottom) this.active.injectBefore(prev);
6678
if (next && !up && now > next.getCoordinates().top) this.active.injectAfter(next);
6679
this.previous = now;
6682
serialize: function(converter){
6683
return this.list.getChildren().map(converter || function(el){
6684
return this.elements.indexOf(el);
6689
this.previous = null;
6690
document.removeListener('mousemove', this.bound.move);
6691
document.removeListener('mouseup', this.bound.end);
6692
if (this.options.ghost){
6693
document.removeListener('mousemove', this.bound.moveGhost);
6694
this.fireEvent('onDragComplete', [this.active, this.ghost]);
6696
this.fireEvent('onComplete', this.active);
6701
Sortables.implement(new Events, new Options);
6705
Tooltips, BubbleTips, whatever they are, they will appear on mouseover
6711
The idea behind Tips.js is based on Bubble Tooltips (<http://web-graphics.com/mtarchive/001717.php>) by Alessandro Fulcitiniti <http://web-graphics.com>
6716
Display a tip on any element with a title and/or href.
6719
Tips requires an XHTML doctype.
6722
elements - a collection of elements to apply the tooltips to on mouseover.
6723
options - an object. See options Below.
6726
maxTitleChars - the maximum number of characters to display in the title of the tip. defaults to 30.
6727
showDelay - the delay the onShow method is called. (defaults to 100 ms)
6728
hideDelay - the delay the onHide method is called. (defaults to 100 ms)
6730
className - the prefix for your tooltip classNames. defaults to 'tool'.
6732
the whole tooltip will have as classname: tool-tip
6734
the title will have as classname: tool-title
6736
the text will have as classname: tool-text
6738
offsets - the distance of your tooltip from the mouse. an Object with x/y properties.
6739
fixed - if set to true, the toolTip will not follow the mouse.
6742
onShow - optionally you can alter the default onShow behaviour with this option (like displaying a fade in effect);
6743
onHide - optionally you can alter the default onHide behaviour with this option (like displaying a fade out effect);
6747
<img src="/images/i.png" title="The body of the tooltip is stored in the title" class="toolTipImg"/>
6749
var myTips = new Tips($$('.toolTipImg'), {
6750
maxTitleChars: 50 //I like my captions a little long
6756
The title of the element will always be used as the tooltip body. If you put :: on your title, the text before :: will become the tooltip title.
6759
var Tips = new Class({
6762
onShow: function(tip){
6763
tip.setStyle('visibility', 'visible');
6765
onHide: function(tip){
6766
tip.setStyle('visibility', 'hidden');
6772
offsets: {'x': 16, 'y': 16},
6776
initialize: function(elements, options){
6777
this.setOptions(options);
6778
this.toolTip = new Element('div', {
6779
'class': this.options.className + '-tip',
6781
'position': 'absolute',
6784
'visibility': 'hidden'
6786
}).inject(document.body);
6787
this.wrapper = new Element('div').inject(this.toolTip);
6788
$$(elements).each(this.build, this);
6789
if (this.options.initialize) this.options.initialize.call(this);
6792
build: function(el){
6793
el.$tmp.myTitle = (el.href && el.getTag() == 'a') ? el.href.replace('http://', '') : (el.rel || false);
6795
var dual = el.title.split('::');
6796
if (dual.length > 1){
6797
el.$tmp.myTitle = dual[0].trim();
6798
el.$tmp.myText = dual[1].trim();
6800
el.$tmp.myText = el.title;
6802
el.removeAttribute('title');
6804
el.$tmp.myText = false;
6806
if (el.$tmp.myTitle && el.$tmp.myTitle.length > this.options.maxTitleChars) el.$tmp.myTitle = el.$tmp.myTitle.substr(0, this.options.maxTitleChars - 1) + "…";
6807
el.addEvent('mouseenter', function(event){
6809
if (!this.options.fixed) this.locate(event);
6810
else this.position(el);
6812
if (!this.options.fixed) el.addEvent('mousemove', this.locate.bindWithEvent(this));
6813
var end = this.end.bind(this);
6814
el.addEvent('mouseleave', end);
6815
el.addEvent('trash', end);
6818
start: function(el){
6819
this.wrapper.empty();
6820
if (el.$tmp.myTitle){
6821
this.title = new Element('span').inject(new Element('div', {'class': this.options.className + '-title'}).inject(this.wrapper)).setHTML(el.$tmp.myTitle);
6823
if (el.$tmp.myText){
6824
this.text = new Element('span').inject(new Element('div', {'class': this.options.className + '-text'}).inject(this.wrapper)).setHTML(el.$tmp.myText);
6827
this.timer = this.show.delay(this.options.showDelay, this);
6830
end: function(event){
6832
this.timer = this.hide.delay(this.options.hideDelay, this);
6835
position: function(element){
6836
var pos = element.getPosition();
6837
this.toolTip.setStyles({
6838
'left': pos.x + this.options.offsets.x,
6839
'top': pos.y + this.options.offsets.y
6843
locate: function(event){
6844
var win = {'x': window.getWidth(), 'y': window.getHeight()};
6845
var scroll = {'x': window.getScrollLeft(), 'y': window.getScrollTop()};
6846
var tip = {'x': this.toolTip.offsetWidth, 'y': this.toolTip.offsetHeight};
6847
var prop = {'x': 'left', 'y': 'top'};
6848
for (var z in prop){
6849
var pos = event.page[z] + this.options.offsets[z];
6850
if ((pos + tip[z] - scroll[z]) > win[z]) pos = event.page[z] - this.options.offsets[z] - tip[z];
6851
this.toolTip.setStyle(prop[z], pos);
6856
if (this.options.timeout) this.timer = this.hide.delay(this.options.timeout, this);
6857
this.fireEvent('onShow', [this.toolTip]);
6861
this.fireEvent('onHide', [this.toolTip]);
6866
Tips.implement(new Events, new Options);
6870
For Grouping Classes or Elements Events. The Event added to the Group will fire when all of the events of the items of the group are fired.
6881
List of Class instances
6885
xhr1 = new Ajax('data.js', {evalScript: true});
6886
xhr2 = new Ajax('abstraction.js', {evalScript: true});
6887
xhr3 = new Ajax('template.js', {evalScript: true});
6889
var group = new Group(xhr1, xhr2, xhr3);
6890
group.addEvent('onComplete', function(){
6891
alert('All Scripts loaded');
6901
var Group = new Class({
6903
initialize: function(){
6904
this.instances = $A(arguments);
6911
adds an event to the stack of events of the Class instances.
6914
type - string; the event name (e.g. 'onComplete')
6915
fn - function to execute when all instances fired this event
6918
addEvent: function(type, fn){
6919
this.checker[type] = this.checker[type] || {};
6920
this.events[type] = this.events[type] || [];
6921
if (this.events[type].contains(fn)) return false;
6922
else this.events[type].push(fn);
6923
this.instances.each(function(instance, i){
6924
instance.addEvent(type, this.check.bind(this, [type, instance, i]));
6929
check: function(type, instance, i){
6930
this.checker[type][i] = true;
6931
var every = this.instances.every(function(current, j){
6932
return this.checker[type][j] || false;
6935
this.checker[type] = {};
6936
this.events[type].each(function(event){
6937
event.call(this, this.instances, instance);
6944
Script: Accordion.js
6945
Contains <Accordion>
6953
The Accordion class creates a group of elements that are toggled when their handles are clicked. When one elements toggles in, the others toggles back.
6954
Inherits methods, properties, options and events from <Fx.Elements>.
6957
The Accordion requires an XHTML doctype.
6960
togglers - required, a collection of elements, the elements handlers that will be clickable.
6961
elements - required, a collection of elements the transitions will be applied to.
6962
options - optional, see options below, and <Fx.Base> options and events.
6965
show - integer, the Index of the element to show at start.
6966
display - integer, the Index of the element to show at start (with a transition). defaults to 0.
6967
fixedHeight - integer, if you want the elements to have a fixed height. defaults to false.
6968
fixedWidth - integer, if you want the elements to have a fixed width. defaults to false.
6969
height - boolean, will add a height transition to the accordion if true. defaults to true.
6970
opacity - boolean, will add an opacity transition to the accordion if true. defaults to true.
6971
width - boolean, will add a width transition to the accordion if true. defaults to false, css mastery is required to make this work!
6972
alwaysHide - boolean, will allow to hide all elements if true, instead of always keeping one element shown. defaults to false.
6975
onActive - function to execute when an element starts to show
6976
onBackground - function to execute when an element starts to hide
6979
var Accordion = Fx.Elements.extend({
6982
onActive: Class.empty,
6983
onBackground: Class.empty,
6995
initialize: function(){
6996
var options, togglers, elements, container;
6997
$each(arguments, function(argument, i){
6998
switch($type(argument)){
6999
case 'object': options = argument; break;
7000
case 'element': container = $(argument); break;
7002
var temp = $$(argument);
7003
if (!togglers) togglers = temp;
7004
else elements = temp;
7007
this.togglers = togglers || [];
7008
this.elements = elements || [];
7009
this.container = $(container);
7010
this.setOptions(options);
7012
if (this.options.alwaysHide) this.options.wait = true;
7013
if ($chk(this.options.show)){
7014
this.options.display = false;
7015
this.previous = this.options.show;
7017
if (this.options.start){
7018
this.options.display = false;
7019
this.options.show = false;
7022
if (this.options.opacity) this.effects.opacity = 'fullOpacity';
7023
if (this.options.width) this.effects.width = this.options.fixedWidth ? 'fullWidth' : 'offsetWidth';
7024
if (this.options.height) this.effects.height = this.options.fixedHeight ? 'fullHeight' : 'scrollHeight';
7025
for (var i = 0, l = this.togglers.length; i < l; i++) this.addSection(this.togglers[i], this.elements[i]);
7026
this.elements.each(function(el, i){
7027
if (this.options.show === i){
7028
this.fireEvent('onActive', [this.togglers[i], el]);
7030
for (var fx in this.effects) el.setStyle(fx, 0);
7033
this.parent(this.elements);
7034
if ($chk(this.options.display)) this.display(this.options.display);
7038
Property: addSection
7039
Dynamically adds a new section into the accordion at the specified position.
7042
toggler - (dom element) the element that toggles the accordion section open.
7043
element - (dom element) the element that stretches open when the toggler is clicked.
7044
pos - (integer) the index where these objects are to be inserted within the accordion.
7047
addSection: function(toggler, element, pos){
7048
toggler = $(toggler);
7049
element = $(element);
7050
var test = this.togglers.contains(toggler);
7051
var len = this.togglers.length;
7052
this.togglers.include(toggler);
7053
this.elements.include(element);
7054
if (len && (!test || pos)){
7055
pos = $pick(pos, len - 1);
7056
toggler.injectBefore(this.togglers[pos]);
7057
element.injectAfter(toggler);
7058
} else if (this.container && !test){
7059
toggler.inject(this.container);
7060
element.inject(this.container);
7062
var idx = this.togglers.indexOf(toggler);
7063
toggler.addEvent('click', this.display.bind(this, idx));
7064
if (this.options.height) element.setStyles({'padding-top': 0, 'border-top': 'none', 'padding-bottom': 0, 'border-bottom': 'none'});
7065
if (this.options.width) element.setStyles({'padding-left': 0, 'border-left': 'none', 'padding-right': 0, 'border-right': 'none'});
7066
element.fullOpacity = 1;
7067
if (this.options.fixedWidth) element.fullWidth = this.options.fixedWidth;
7068
if (this.options.fixedHeight) element.fullHeight = this.options.fixedHeight;
7069
element.setStyle('overflow', 'hidden');
7071
for (var fx in this.effects) element.setStyle(fx, 0);
7078
Shows a specific section and hides all others. Useful when triggering an accordion from outside.
7081
index - integer, the index of the item to show, or the actual element to show.
7084
display: function(index){
7085
index = ($type(index) == 'element') ? this.elements.indexOf(index) : index;
7086
if ((this.timer && this.options.wait) || (index === this.previous && !this.options.alwaysHide)) return this;
7087
this.previous = index;
7089
this.elements.each(function(el, i){
7091
var hide = (i != index) || (this.options.alwaysHide && (el.offsetHeight > 0));
7092
this.fireEvent(hide ? 'onBackground' : 'onActive', [this.togglers[i], el]);
7093
for (var fx in this.effects) obj[i][fx] = hide ? 0 : el[this.effects[fx]];
7095
return this.start(obj);
7098
showThisHideOpen: function(index){return this.display(index);}
7102
Fx.Accordion = Accordion;