/* Script: Moo.js My Object Oriented javascript. Author: Valerio Proietti, License: MIT-style license. Credits: - Class is slightly based on Base.js (c) 2006 Dean Edwards, License - Some functions are based on those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license - Documentation by Aaron Newton (aaron.newton [at] cnet [dot] com) and Valerio Proietti. */ /* Class: Class The base class object of the framework. Arguments: properties - the collection of properties that apply to the class. Creates a new class, its initialize method will fire upon class instantiation. Example: (start code) var Cat = new Class({ initialize: function(name){ this.name = name; } }); var myCat = new Cat('Micia'); alert myCat.name; //alerts 'Micia' (end) */ var Class = function(properties){ var klass = function(){ if (this.initialize && arguments[0] != 'noinit') return this.initialize.apply(this, arguments); else return this; }; for (var property in this) klass[property] = this[property]; klass.prototype = properties; return klass; }; /* Property: empty Returns an empty function */ Class.empty = function(){}; Class.prototype = { /* Property: extend Returns the copy of the Class extended with the passed in properties. Arguments: properties - the properties to add to the base class in this new Class. Example: (start code) var Animal = new Class({ initialize: function(age){ this.age = age; } }); var Cat = Animal.extend({ initialize: function(name, age){ this.parent(age); //will call the previous initialize; this.name = name; } }); var myCat = new Cat('Micia', 20); alert myCat.name; //alerts 'Micia' alert myCat.age; //alerts 20 (end) */ extend: function(properties){ var pr0t0typ3 = new this('noinit'); var parentize = function(previous, current){ if (!previous.apply || !current.apply) return false; return function(){ this.parent = previous; return current.apply(this, arguments); }; }; for (var property in properties){ var previous = pr0t0typ3[property]; var current = properties[property]; if (previous && previous != current) current = parentize(previous, current) || current; pr0t0typ3[property] = current; } return new Class(pr0t0typ3); }, /* Property: implement Implements the passed in properties to the base Class prototypes, altering the base class, unlike . Arguments: properties - the properties to add to the base class. Example: (start code) var Animal = new Class({ initialize: function(age){ this.age = age; } }); Animal.implement({ setName: function(name){ this.name = name } }); var myAnimal = new Animal(20); myAnimal.setName('Micia'); alert(myAnimal.name); //alerts 'Micia' (end) */ implement: function(properties){ for (var property in properties) this.prototype[property] = properties[property]; } }; /* Section: Object related Functions */ /* Function: Object.extend Copies all the properties from the second passed object to the first passed Object. If you do myWhatever.extend = Object.extend the first parameter will become myWhatever, and your extend function will only need one parameter. Example: (start code) var firstOb = { 'name': 'John', 'lastName': 'Doe' }; var secondOb = { 'age': '20', 'sex': 'male', 'lastName': 'Dorian' }; Object.extend(firstOb, secondOb); //firstOb will become: { 'name': 'John', 'lastName': 'Dorian', 'age': '20', 'sex': 'male' }; (end) Returns: The first object, extended. */ Object.extend = function(){ var args = arguments; args = (args[1]) ? [args[0], args[1]] : [this, args[0]]; for (var property in args[1]) args[0][property] = args[1][property]; return args[0]; }; /* Function: Object.Native Will add a .extend method to the objects passed as a parameter, equivalent to Arguments: a number of classes/native javascript objects */ Object.Native = function(){ for (var i = 0; i < arguments.length; i++) arguments[i].extend = Class.prototype.implement; }; new Object.Native(Function, Array, String, Number, Class); /* Script: Utility.js Contains Utility functions Author: Valerio Proietti, License: MIT-style license. */ //htmlelement mapping if (typeof HTMLElement == 'undefined'){ var HTMLElement = Class.empty; HTMLElement.prototype = {}; } /* Function: $type Returns the type of object that matches the element passed in. Arguments: obj - the object to inspect. Example: >var myString = 'hello'; >$type(myString); //returns "string" Returns: 'element' - if obj is a DOM element node 'textnode' - if obj is a DOM text node 'whitespace' - if obj is a DOM whitespace node 'array' - if obj is an array 'object' - if obj is an object 'string' - if obj is a string 'number' - if obj is a number 'boolean' - if obj is a boolean 'function' - if obj is a function false - (boolean) if the object is not defined or none of the above. */ function $type(obj){ if (obj === null || obj === undefined) return false; var type = typeof obj; if (type == 'object'){ if (obj instanceof HTMLElement) return 'element'; if (obj instanceof Array) return 'array'; if (obj.nodeName){ switch (obj.nodeType){ case 1: return 'element'; case 3: return obj.nodeValue.test('\\S') ? 'textnode' : 'whitespace'; } } } return type; }; /* Function: $chk Returns true if the passed in value/object exists or is 0, otherwise returns false. Useful to accept zeroes. */ function $chk(obj){ return !!(obj || obj === 0); }; /* Function: $pick Returns the first object if defined, otherwise returns the second. */ function $pick(obj, picked){ return ($type(obj)) ? obj : picked; }; /* Function: $random Returns a random integer number between the two passed in values. Arguments: min - integer, the minimum value (inclusive). max - integer, the maximum value (inclusive). Returns: a random integer between min and max. */ function $random(min, max){ return Math.floor(Math.random() * (max - min + 1) + min); }; /* Function: $clear clears a timeout or an Interval. Returns: null Arguments: timer - the setInterval or setTimeout to clear. Example: >var myTimer = myFunction.delay(5000); //wait 5 seconds and execute my function. >myTimer = $clear(myTimer); //nevermind See also: , */ function $clear(timer){ clearTimeout(timer); clearInterval(timer); return null; }; /* Section: Browser Detection */ /* Properties: window.ie - will be set to true if the current browser is internet explorer (any). window.ie6 - will be set to true if the current browser is internet explorer 6. window.ie7 - will be set to true if the current browser is internet explorer 7. window.khtml - will be set to true if the current browser is Safari/Konqueror. window.gecko - will be set to true if the current browser is Mozilla/Gecko. */ if (window.ActiveXObject) window.ie = window[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true; else if (document.childNodes && !document.all && !navigator.taintEnabled) window.khtml = true; else if (document.getBoxObjectFor != null) window.gecko = true; /* Script: Array.js Contains Array prototypes and the function <$A>; Author: Valerio Proietti, License: MIT-style license. */ /* Class: Array A collection of The Array Object prototype methods. */ //emulated methods /* Property: forEach Iterates through an array; This method is only available for browsers without native *forEach* support. For more info see */ Array.prototype.forEach = Array.prototype.forEach || function(fn, bind){ for (var i = 0; i < this.length; i++) fn.call(bind, this[i], i, this); }; /* Property: map This method is provided only for browsers without native *map* support. For more info see */ Array.prototype.map = Array.prototype.map || function(fn, bind){ var results = []; for (var i = 0; i < this.length; i++) results[i] = fn.call(bind, this[i], i, this); return results; }; /* Property: every This method is provided only for browsers without native *every* support. For more info see */ Array.prototype.every = Array.prototype.every || function(fn, bind){ for (var i = 0; i < this.length; i++){ if (!fn.call(bind, this[i], i, this)) return false; } return true; }; /* Property: some This method is provided only for browsers without native *some* support. For more info see */ Array.prototype.some = Array.prototype.some || function(fn, bind){ for (var i = 0; i < this.length; i++){ if (fn.call(bind, this[i], i, this)) return true; } return false; }; /* Property: indexOf This method is provided only for browsers without native *indexOf* support. For more info see */ Array.prototype.indexOf = Array.prototype.indexOf || function(item, from){ from = from || 0; if (from < 0) from = Math.max(0, this.length + from); while (from < this.length){ if(this[from] === item) return from; from++; } return -1; }; //custom methods Array.extend({ /* Property: each Same as . Arguments: fn - the function to execute with each item in the array bind - optional, the object that the "this" of the function will refer to. Example: >var Animals = ['Cat', 'Dog', 'Coala']; >Animals.forEach(function(animal){ > document.write(animal) >}); */ each: Array.prototype.forEach, /* Property: copy Copy the array and returns it. Returns: an Array Example: >var letters = ["a","b","c"]; >var copy = ["a","b","c"].copy(); */ copy: function(){ var newArray = []; for (var i = 0; i < this.length; i++) newArray[i] = this[i]; return newArray; }, /* Property: remove Removes all occurrences of an item from the array. Arguments: item - the item to remove Returns: the Array with all occurrences of the item removed. Example: >["1","2","3","2"].remove("2") // ["1","3"]; */ remove: function(item){ var i = 0; while (i < this.length){ if (this[i] == item) this.splice(i, 1); else i++; } return this; }, /* Property: test Tests an array for the presence of an item. Arguments: item - the item to search for in the array. from - 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. Returns: true - the item was found false - it wasn't Example: >["a","b","c"].test("a"); // true >["a","b","c"].test("d"); // false */ test: function(item, from){ return this.indexOf(item, from) != -1; }, /* Property: extend Extends an array with another Arguments: newArray - the array to extend ours with Example: >var Animals = ['Cat', 'Dog', 'Coala']; >Animals.extend(['Lizard']); >//Animals is now: ['Cat', 'Dog', 'Coala', 'Lizard']; */ extend: function(newArray){ for (var i = 0; i < newArray.length; i++) this.push(newArray[i]); return this; }, /* Property: associate Creates an object with key-value pairs based on the array of keywords passed in and the current content of the array. Arguments: keys - the array of keywords. Example: (start code) var Animals = ['Cat', 'Dog', 'Coala', 'Lizard']; var Speech = ['Miao', 'Bau', 'Fruuu', 'Mute']; var Speeches = Animals.associate(speech); //Speeches['Miao'] is now Cat. //Speeches['Bau'] is now Dog. //... (end) */ associate: function(keys){ var obj = {}, length = Math.min(this.length, keys.length); for (var i = 0; i < length; i++) obj[keys[i]] = this[i]; return obj; } }); /* Section: Utility Functions */ /* Function: $A() Same as , but as function. Useful to apply Array prototypes to iterable objects, as a collection of DOM elements or the arguments object. Example: (start code) function myFunction(){ $A(arguments).each(argument, function(){ alert(argument); }); }; //the above will alert all the arguments passed to the function myFunction. (end) */ function $A(array){ return Array.prototype.copy.call(array); }; /* Function: $each use to iterate through iterables that are not regular arrays, such as builtin getElementsByTagName calls, or arguments of a function. Arguments: iterable - an iterable element. function - function to apply to the iterable. bind - optional, the 'this' of the function will refer to this object. */ function $each(iterable, fn, bind){ return Array.prototype.forEach.call(iterable, fn, bind); }; /* Script: String.js Contains String prototypes and Number prototypes. Author: Valerio Proietti, License: MIT-style license. */ /* Class: String A collection of The String Object prototype methods. */ String.extend({ /* Property: test Tests a string with a regular expression. Arguments: regex - the regular expression you want to match the string with params - optional, any parameters you want to pass to the regex ('g' has no effect) Returns: true if a match for the regular expression is found in the string, false if not. See Example: >"I like cookies".test("cookie"); // returns true >"I like cookies".test("COOKIE", "i") // ignore case, returns true >"I like cookies".test("cake"); // returns false */ test: function(regex, params){ return new RegExp(regex, params).test(this); }, /* Property: toInt parses a string to an integer. Returns: either an int or "NaN" if the string is not a number. Example: >var value = "10px".toInt(); // value is 10 */ toInt: function(){ return parseInt(this); }, toFloat: function(){ return parseFloat(this); }, /* Property: camelCase Converts a hiphenated string to a camelcase string. Example: >"I-like-cookies".camelCase(); //"ILikeCookies" Returns: the camel cased string */ camelCase: function(){ return this.replace(/-\D/g, function(match){ return match.charAt(1).toUpperCase(); }); }, /* Property: hyphenate Converts a camelCased string to a hyphen-ated string. Example: >"ILikeCookies".hyphenate(); //"I-like-cookies" */ hyphenate: function(){ return this.replace(/\w[A-Z]/g, function(match){ return (match.charAt(0)+'-'+match.charAt(1).toLowerCase()); }); }, /* Property: capitalize Converts the first letter in each word of a string to Uppercase. Example: >"i like cookies".capitalize(); //"I Like Cookies" Returns: the capitalized string */ capitalize: function(){ return this.toLowerCase().replace(/\b[a-z]/g, function(match){ return match.toUpperCase(); }); }, /* Property: trim Trims the leading and trailing spaces off a string. Example: >" i like cookies ".trim() //"i like cookies" Returns: the trimmed string */ trim: function(){ return this.replace(/^\s+|\s+$/g, ''); }, /* Property: clean trims () a string AND removes all the double spaces in a string. Returns: the cleaned string Example: >" i like cookies \n\n".clean() //"i like cookies" */ clean: function(){ return this.replace(/\s{2,}/g, ' ').trim(); }, /* Property: rgbToHex Converts an RGB value to hexidecimal. The string must be in the format of "rgb(255, 255, 255)" or "rgba(255, 255, 255, 1)"; Arguments: array - boolean value, defaults to false. Use true if you want the array ['FF', '33', '00'] as output instead of #FF3300 Returns: hex string or array. returns transparent if the fourth value of rgba in input string is 0, Example: >"rgb(17,34,51)".rgbToHex(); //"#112233" >"rgba(17,34,51,0)".rgbToHex(); //"transparent" >"rgb(17,34,51)".rgbToHex(true); //[11,22,33] */ rgbToHex: function(array){ var rgb = this.match(/\d{1,3}/g); return (rgb) ? rgb.rgbToHex(array) : false; }, /* Property: hexToRgb Converts a hexidecimal color value to RGB. Input string must be the hex color value (with or without the hash). Also accepts triplets ('333'); Arguments: array - boolean value, defaults to false. Use true if you want the array ['255', '255', '255'] as output instead of "rgb(255,255,255)"; Returns: rgb string or array. Example: >"#112233".hexToRgb(); //"rgb(17,34,51)" >"#112233".hexToRgb(true); //[17,34,51] */ hexToRgb: function(array){ var hex = this.match('^#?(\\w{1,2})(\\w{1,2})(\\w{1,2})$'); return (hex) ? hex.hexToRgb(array) : false; } }); Array.extend({ rgbToHex: function(array){ if (this.length < 3) return false; if (this[3] && this[3] == 0) return 'transparent'; var hex = []; for (var i = 0; i < 3; i++){ var bit = (this[i]-0).toString(16); hex.push(bit.length == 1 ? '0'+bit : bit); } return array ? hex : '#'+hex.join(''); }, hexToRgb: function(array){ if (this.length != 4) return false; var rgb = []; for (var i = 1; i < 4; i++){ if (this[i].length == 1) this[i] += this[i]; rgb.push(parseInt(this[i], 16)); } return array ? rgb : 'rgb('+rgb.join(',')+')'; } }); /* Class: Number contains the internal method toInt. */ Number.extend({ /* Property: toInt Returns this number; useful because toInt must work on both Strings and Numbers. */ toInt: function(){ return parseInt(this); }, toFloat: function(){ return parseFloat(this); } }); /* Script: Function.js Contains Function prototypes and utility functions . Author: Valerio Proietti, License: MIT-style license. Credits: - Some functions are inspired by those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license */ /* Class: Function A collection of The Function Object prototype methods. */ Function.extend({ create: function(options){ var fn = this; options = Object.extend({ 'bind': fn, 'event': false, 'arguments': null, 'delay': false, 'periodical': false, 'attempt': false }, options || {}); if (options.arguments != null && typeof options.arguments != 'undefined' && !(options.arguments instanceof Array)) options.arguments = [options.arguments]; return function(event){ var args = options.arguments || arguments; if (options.event){ event = (options.event === true) ? event || window.event : new options.event(event); args = [event].concat(args); } var returns = function(){ return fn.apply(options.bind, args); }; if (options.delay) return setTimeout(returns, options.delay); if (options.periodical) return setInterval(returns, options.periodical); if (options.attempt){ try { var result = returns(); } catch(err){ result = err; } finally { return result; } } else return returns(); }; }, /* Property: pass Shortcut to create closures with arguments and bind. Returns: a function. Arguments: args - the arguments passed. must be an array if arguments > 1 bind - optional, the object that the "this" of the function will refer to. Example: >myFunction.pass([arg1, arg2], myElement); */ pass: function(args, bind){ return this.create({'arguments': args, 'bind': bind}); }, /* Property: attempt Tries to execute the function, returns either the function results or the error. Arguments: args - the arguments passed. must be an array if arguments > 1 bind - optional, the object that the "this" of the function will refer to. Example: >myFunction.attempt([arg1, arg2], myElement); */ attempt: function(args, bind){ return this.create({'arguments': args, 'bind': bind, 'attempt': true})(); }, /* Property: bind method to easily create closures with "this" altered. Arguments: bind - optional, the object that the "this" of the function will refer to. args - optional, the arguments passed. must be an array if arguments > 1 Returns: a function. Example: >function myFunction(){ > this.setStyle('color', 'red'); > // note that 'this' here refers to myFunction, not an element > // we'll need to bind this function to the element we want to alter >}; >var myBoundFunction = myFunction.bind(myElement); >myBoundFunction(); // this will make the element myElement red. */ bind: function(bind, args){ return this.create({'bind': bind, 'arguments': args}); }, /* Property: bindAsEventListener cross browser method to pass event firer Arguments: bind - optional, the object that the "this" of the function will refer to. args - optional, the arguments passed. must be an array if arguments > 1 Returns: a function with the parameter bind as its "this" and as a pre-passed argument event or window.event, depending on the browser. Example: >function myFunction(event){ > alert(event.clientx) //returns the coordinates of the mouse.. >}; >myElement.onclick = myFunction.bindAsEventListener(myElement); */ bindAsEventListener: function(bind, args){ return this.create({'bind': bind, 'event': true, 'arguments': args}); }, /* Property: delay Delays the execution of a function by a specified duration. Arguments: ms - the duration to wait in milliseconds bind - optional, the object that the "this" of the function will refer to. args - optional, the arguments passed. must be an array if arguments > 1 Example: >myFunction.delay(50, myElement) //wait 50 milliseconds, then call myFunction and bind myElement to it >(function(){alert('one second later...')}).delay(1000); //wait a second and alert */ delay: function(ms, bind, args){ return this.create({'delay': ms, 'bind': bind, 'arguments': args})(); }, /* Property: periodical Executes a function in the specified intervals of time Arguments: ms - the duration of the intervals between executions. bind - optional, the object that the "this" of the function will refer to. args - optional, the arguments passed. must be an array if arguments > 1 */ periodical: function(ms, bind, args){ return this.create({'periodical': ms, 'bind': bind, 'arguments': args})(); } }); /* Script: Element.js Contains useful Element prototypes, to be used with the dollar function <$>. Author: Valerio Proietti, License: MIT-style license. Credits: - Some functions are inspired by those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license */ /* Class: Element Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. */ var Element = new Class({ /* Property: initialize Creates a new element of the type passed in. Arguments: el - the tag name for the element you wish to create. Example: >var div = new Element('div'); */ initialize: function(el){ if ($type(el) == 'string') el = document.createElement(el); return $(el); } }); /* Function: $() returns the element passed in with all the Element prototypes applied. Arguments: el - a reference to an actual element or a string representing the id of an element Example: >$('myElement') // gets a DOM element by id with all the Element prototypes applied. >var div = document.getElementById('myElement'); >$(div) //returns an Element also with all the mootools extentions applied. You'll use this when you aren't sure if a variable is an actual element or an id, as well as just shorthand for document.getElementById(). Returns: a DOM element or false (if no id was found). Note: you need to call $ on an element only once to get all the prototypes. But its no harm to call it multiple times, as it will detect if it has been already extended. */ function $(el){ if (!el) return false; if (el._element_extended_ || [window, document].test(el)) return el; if ($type(el) == 'string') el = document.getElementById(el); if ($type(el) != 'element') return false; if (['object', 'embed'].test(el.tagName.toLowerCase()) || el.extend) return el; el._element_extended_ = true; Garbage.collect(el); el.extend = Object.extend; if (!(el instanceof HTMLElement)) el.extend(Element.prototype); return el; }; //elements class var Elements = new Class({}); new Object.Native(Elements); document.getElementsBySelector = document.getElementsByTagName; /* Function: $$() Selects, and extends DOM elements. Arguments: HTMLCollection(document.getElementsByTagName, element.childNodes), an array of elements, a string. Note: if you loaded , $$ will also accept CSS Selectors. Example: >$$('a') //an array of all anchor tags on the page >$$('a', 'b') //an array of all anchor and bold tags on the page >$$('#myElement') //array containing only the element with id = myElement. (only with ) >$$('#myElement a.myClass') //an array of all anchor tags with the class "myClass" within the DOM element with id "myElement" (only with ) Returns: array - array of all the dom elements matched */ function $$(){ if (!arguments) return false; if (arguments.length == 1){ if (!arguments[0]) return false; if (arguments[0]._elements_extended_) return arguments[0]; } var elements = []; $each(arguments, function(selector){ switch ($type(selector)){ case 'element': elements.push($(selector)); break; case 'string': selector = document.getElementsBySelector(selector); default: if (selector.length){ $each(selector, function(el){ if ($(el)) elements.push(el); }); } } }); elements._elements_extended_ = true; return Object.extend(elements, new Elements); }; Elements.Multi = function(property){ return function(){ var args = arguments; var items = []; var elements = true; $each(this, function(el){ var returns = el[property].apply(el, args); if ($type(returns) != 'element') elements = false; items.push(returns); }); if (elements) items = $$(items); return items; }; }; Element.extend = function(properties){ for (var property in properties){ HTMLElement.prototype[property] = properties[property]; Element.prototype[property] = properties[property]; Elements.prototype[property] = Elements.Multi(property); } }; Element.extend({ inject: function(el, where){ el = $(el) || new Element(el); switch (where){ case "before": $(el.parentNode).insertBefore(this, el); break; case "after": if (!el.getNext()) $(el.parentNode).appendChild(this); else $(el.parentNode).insertBefore(this, el.getNext()); break; case "inside": el.appendChild(this); } return this; }, /* Property: injectBefore Inserts the Element before the passed element. Parameteres: el - a string representing the element to be injected in (myElementId, or div), or an element reference. If you pass div or another tag, the element will be created. Example: >html: >
>
>js: >$('mySecondElement').injectBefore('myElement'); >resulting html: >
>
*/ injectBefore: function(el){ return this.inject(el, 'before'); }, /* Property: injectAfter Same as , but inserts the element after. */ injectAfter: function(el){ return this.inject(el, 'after'); }, /* Property: injectInside Same as , but inserts the element inside. */ injectInside: function(el){ return this.inject(el, 'inside'); }, /* Property: adopt Inserts the passed element inside the Element. Works as but in reverse. Parameteres: el - a string representing the element to be injected in (myElementId, or div), or an element reference. If you pass div or another tag, the element will be created. */ adopt: function(el){ this.appendChild($(el) || new Element(el)); return this; }, /* Property: remove Removes the Element from the DOM. Example: >$('myElement').remove() //bye bye */ remove: function(){ this.parentNode.removeChild(this); return this; }, /* Property: clone Clones the Element and returns the cloned one. Returns: the cloned element Example: >var clone = $('myElement').clone().injectAfter('myElement'); >//clones the Element and append the clone after the Element. */ clone: function(contents){ var el = this.cloneNode(contents !== false); return $(el); }, /* Property: replaceWith Replaces the Element with an element passed. Parameteres: el - a string representing the element to be injected in (myElementId, or div), or an element reference. If you pass div or another tag, the element will be created. Returns: the passed in element Example: >$('myOldElement').replaceWith($('myNewElement')); //$('myOldElement') is gone, and $('myNewElement') is in its place. */ replaceWith: function(el){ el = $(el) || new Element(el); this.parentNode.replaceChild(el, this); return el; }, /* Property: appendText Appends text node to a DOM element. Arguments: text - the text to append. Example: >
hey
>$('myElement').appendText(' howdy'); //myElement innerHTML is now "hey howdy" */ appendText: function(text){ if (window.ie){ switch(this.getTag()){ case 'style': this.styleSheet.cssText = text; return this; case 'script': this.setProperty('text', text); return this; } } this.appendChild(document.createTextNode(text)); return this; }, /* Property: hasClass Tests the Element to see if it has the passed in className. Returns: true - the Element has the class false - it doesn't Arguments: className - the class name to test. Example: >
>$('myElement').hasClass('testClass'); //returns true */ hasClass: function(className){ return this.className.test('(?:^|\\s+)' + className + '(?:\\s+|$)'); }, /* Property: addClass Adds the passed in class to the Element, if the element doesnt already have it. Arguments: className - the class name to add Example: >
>$('myElement').addClass('newClass'); //
*/ addClass: function(className){ if (!this.hasClass(className)) this.className = (this.className+' '+className).clean(); return this; }, /* Property: removeClass works like , but removes the class from the element. */ removeClass: function(className){ if (this.hasClass(className)) this.className = this.className.replace(className, '').clean(); return this; }, /* Property: toggleClass Adds or removes the passed in class name to the element, depending on if it's present or not. Arguments: className - the class to add or remove Example: >
>$('myElement').toggleClass('myClass'); >
>$('myElement').toggleClass('myClass'); >
*/ toggleClass: function(className){ return this.hasClass(className) ? this.removeClass(className) : this.addClass(className); }, /* Property: setStyle Sets a css property to the Element. Arguments: property - the property to set value - the value to which to set it Example: >$('myElement').setStyle('width', '300px'); //the width is now 300px */ setStyle: function(property, value){ if (property == 'opacity') this.setOpacity(parseFloat(value)); else this.style[property.camelCase()] = (value.push) ? value.rgbToHex() : value; return this; }, /* Property: setStyles Applies a collection of styles to the Element. Arguments: source - an object or string containing all the styles to apply Examples: >$('myElement').setStyles({ > border: '1px solid #000', > width: '300px', > height: '400px' >}); OR >$('myElement').setStyle('border: 1px solid #000; width: 300px; height: 400px;'); */ setStyles: function(source){ switch ($type(source)){ case 'object': for (var property in source) this.setStyle(property, source[property]); break; case 'string': if (window.ie) this.cssText = source; else this.setAttribute('style', source); } return this; }, /* Property: setOpacity Sets the opacity of the Element, and sets also visibility == "hidden" if opacity == 0, and visibility = "visible" if opacity == 1. Arguments: opacity - Accepts numbers from 0 to 1. Example: >$('myElement').setOpacity(0.5) //make it 50% transparent */ setOpacity: function(opacity){ if (opacity == 0){ if(this.style.visibility != "hidden") this.style.visibility = "hidden"; } else { if(this.style.visibility != "visible") this.style.visibility = "visible"; } if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom = 1; if (window.ie) this.style.filter = "alpha(opacity=" + opacity*100 + ")"; this.style.opacity = this.opacity = opacity; return this; }, /* Property: getStyle Returns the style of the Element given the property passed in. Arguments: property - the css style property you want to retrieve Example: >$('myElement').getStyle('width'); //returns "400px" >//but you can also use >$('myElement').getStyle('width').toInt(); //returns "400" Returns: the style as a string */ getStyle: function(property){ property = property.camelCase(); var style = this.style[property] || false; if (!$chk(style)){ if (property == 'opacity') return $chk(this.opacity) ? this.opacity : 1; if (['margin', 'padding'].test(property)){ return [this.getStyle(property+'-top') || 0, this.getStyle(property+'-right') || 0, this.getStyle(property+'-bottom') || 0, this.getStyle(property+'-left') || 0].join(' '); } if (document.defaultView) style = document.defaultView.getComputedStyle(this, null).getPropertyValue(property.hyphenate()); else if (this.currentStyle) style = this.currentStyle[property]; } return (style && property.test('color', 'i') && style.test('rgb')) ? style.rgbToHex() : style; }, /* Property: addEvent Attaches an event listener to a DOM element. Arguments: type - the event to monitor ('click', 'load', etc) without the prefix 'on'. fn - the function to execute Example: >$('myElement').addEvent('click', function(){alert('clicked!')}); */ addEvent: function(type, fn){ this.events = this.events || {}; this.events[type] = this.events[type] || {'keys': [], 'values': []}; if (!this.events[type].keys){ this.events[type].keys = []; } if (!this.events[type].values){ this.events[type].values = []; } if (!this.events[type].keys.test(fn)){ this.events[type].keys.push(fn); if (this.addEventListener){ this.addEventListener((type == 'mousewheel' && window.gecko) ? 'DOMMouseScroll' : type, fn, false); } else { fn = fn.bind(this); this.attachEvent('on'+type, fn); this.events[type].values.push(fn); } } return this; }, addEvents: function(source){ if (source){ for (var type in source) this.addEvent(type, source[type]); } return this; }, /* Property: removeEvent Works as Element.addEvent, but instead removes the previously added event listener. */ removeEvent: function(type, fn){ if (this.events && this.events[type]){ var pos = this.events[type].keys.indexOf(fn); if (pos == -1) return this; var key = this.events[type].keys.splice(pos,1)[0]; if (this.removeEventListener){ this.removeEventListener((type == 'mousewheel' && window.gecko) ? 'DOMMouseScroll' : type, key, false); } else { this.detachEvent('on'+type, this.events[type].values.splice(pos,1)[0]); } } return this; }, /* Property: removeEvents removes all events of a certain type from an element. if no argument is passed in, removes all events. */ removeEvents: function(type){ if (this.events){ if (type){ if (this.events[type]){ this.events[type].keys.each(function(fn){ this.removeEvent(type, fn); }, this); this.events[type] = null; } } else { for (var evType in this.events) this.removeEvents(evType); this.events = null; } } return this; }, /* Property: fireEvent executes all events of the specified type present in the element. */ fireEvent: function(type, args){ if (this.events && this.events[type]){ args = args || []; if ($type(args) != 'array') args = [args]; this.events[type].keys.each(function(fn){ fn.apply(this, args); }, this); } }, getBrother: function(what){ var el = this[what+'Sibling']; while ($type(el) == 'whitespace') el = el[what+'Sibling']; return $(el); }, /* Property: getPrevious Returns the previousSibling of the Element, excluding text nodes. Example: >$('myElement').getPrevious(); //get the previous DOM element from myElement Returns: the sibling element or undefined if none found. */ getPrevious: function(){ return this.getBrother('previous'); }, /* Property: getNext Works as Element.getPrevious, but tries to find the nextSibling. */ getNext: function(){ return this.getBrother('next'); }, /* Property: getFirst Works as , but tries to find the firstChild. */ getFirst: function(){ var el = this.firstChild; while ($type(el) == 'whitespace') el = el.nextSibling; return $(el); }, /* Property: getLast Works as , but tries to find the lastChild. */ getLast: function(){ var el = this.lastChild; while ($type(el) == 'whitespace') el = el.previousSibling; return $(el); }, /* Property: getParent returns the $(element.parentNode) */ getParent: function(){ return $(this.parentNode); }, /* Property: getChildren returns all the $(element.childNodes), excluding text nodes. Returns as . */ getChildren: function(){ return $$(this.childNodes); }, /* Property: setProperty Sets an attribute for the Element. Arguments: property - the property to assign the value passed in value - the value to assign to the property passed in Example: >$('myImage').setProperty('src', 'whatever.gif'); //myImage now points to whatever.gif for its source */ setProperty: function(property, value){ switch (property){ case 'class': this.className = value; break; case 'style': this.setStyles(value); break; case 'name': if (window.ie6){ var el = $(document.createElement('<'+this.getTag()+' name="'+value+'" />')); $each(this.attributes, function(attribute){ if (attribute.name != 'name') el.setProperty(attribute.name, attribute.value); }); if (this.parentNode) this.replaceWith(el); return el; } default: this.setAttribute(property, value); } return this; }, /* Property: setProperties Sets numerous attributes for the Element. Arguments: source - an object with key/value pairs. Example: >$('myElement').setProperties({ > src: 'whatever.gif', > alt: 'whatever dude' >}); >whatever dude */ setProperties: function(source){ for (var property in source) this.setProperty(property, source[property]); return this; }, /* Property: setHTML Sets the innerHTML of the Element. Arguments: html - the new innerHTML for the element. Example: >$('myElement').setHTML(newHTML) //the innerHTML of myElement is now = newHTML */ setHTML: function(html){ this.innerHTML = html; return this; }, /* Property: getProperty Gets the an attribute of the Element. Arguments: property - the attribute to retrieve Example: >$('myImage').getProperty('src') // returns whatever.gif Returns: the value, or an empty string */ getProperty: function(property){ return (property == 'class') ? this.className : this.getAttribute(property); }, /* Property: getTag Returns the tagName of the element in lower case. Example: >$('myImage').getTag() // returns 'img' Returns: The tag name in lower case */ getTag: function(){ return this.tagName.toLowerCase(); }, getOffsets: function(){ var el = this, offsetLeft = 0, offsetTop = 0; do { offsetLeft += el.offsetLeft || 0; offsetTop += el.offsetTop || 0; el = el.offsetParent; } while (el); return {'x': offsetLeft, 'y': offsetTop}; }, /* Property: scrollTo scrolls the element to the specified coordinated (if the element has an overflow) Arguments: x - the x coordinate y - the y coordinate Example: >$('myElement').scrollTo(0, 100) */ scrollTo: function(x, y){ this.scrollLeft = x; this.scrollTop = y; }, /* Property: getSize return an Object representing the size/scroll values of the element. Example: (start code) $('myElement').getSize(); (end) Returns: (start code) { 'scroll': {'x': 100, 'y': 100}, 'size': {'x': 200, 'y': 400}, 'scrollSize': {'x': 300, 'y': 500} } (end) */ getSize: function(){ return { 'scroll': {'x': this.scrollLeft, 'y': this.scrollTop}, 'size': {'x': this.offsetWidth, 'y': this.offsetHeight}, 'scrollSize': {'x': this.scrollWidth, 'y': this.scrollHeight} }; }, /* Property: getTop Returns the distance from the top of the window to the Element. */ getTop: function(){ return this.getOffsets().y; }, /* Property: getLeft Returns the distance from the left of the window to the Element. */ getLeft: function(){ return this.getOffsets().x; }, /* Property: getPosition Returns an object with width, height, left, right, top, and bottom, representing the values of the Element Example: (start code) var myValues = $('myElement').getPosition(); (end) Returns: (start code) { width: 200, height: 300, left: 100, top: 50, right: 300, bottom: 350 } (end) */ getPosition: function(){ var offs = this.getOffsets(); var obj = { 'width': this.offsetWidth, 'height': this.offsetHeight, 'left': offs.x, 'top': offs.y }; obj.right = obj.left + obj.width; obj.bottom = obj.top + obj.height; return obj; }, /* Property: getValue Returns the value of the Element, if its tag is textarea, select or input. no multiple select support. */ getValue: function(){ switch (this.getTag()){ case 'select': if (this.selectedIndex != -1) return this.options[this.selectedIndex].value; break; case 'input': if (!(this.checked && ['checkbox', 'radio'].test(this.type)) && !['hidden', 'text', 'password'].test(this.type)) break; case 'textarea': return this.value; } return false; } }); var Window = window; window.addEvent = document.addEvent = Element.prototype.addEvent; window.removeEvent = document.removeEvent = Element.prototype.removeEvent; var Garbage = { elements: [], collect: function(element){ Garbage.elements.push(element); }, trash: function(){ window.removeEvent('unload', Garbage.trash); Garbage.elements.each(function(el){ el.removeEvents(); for (var p in Element.prototype) HTMLElement[p] = window[p] = document[p] = el[p] = null; el.extend = null; }); } }; window.addEvent('unload', Garbage.trash); /* Script: Event.js Event class Author: Valerio Proietti, , Michael Jackson, License: MIT-style license. */ /* Class: Event Cross browser methods to manage events. Arguments: event - the event Properties: shift - true if the user pressed the shift control - true if the user pressed the control alt - true if the user pressed the alt meta - true if the user pressed the meta key code - the keycode of the key pressed page.x - the x position of the mouse, relative to the full window page.y - the y position of the mouse, relative to the full window client.x - the x position of the mouse, relative to the viewport client.y - the y position of the mouse, relative to the viewport 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. target - the event target relatedTarget - the event related target Example: (start code) $('myLink').onkeydown = function(event){ var event = new Event(event); //event is now the Event class. alert(event.key); //returns the lowercase letter pressed alert(event.shift); //returns true if the key pressed is shift if (event.key == 's' && event.control) alert('document saved'); }; (end) */ var Event = new Class({ initialize: function(event){ this.event = event || window.event; this.type = this.event.type; this.target = this.event.target || this.event.srcElement; if (this.target.nodeType == 3) this.target = this.target.parentNode; // Safari this.shift = this.event.shiftKey; this.control = this.event.ctrlKey; this.alt = this.event.altKey; this.meta = this.event.metaKey; if (['DOMMouseScroll', 'mousewheel'].test(this.type)){ this.wheel = this.event.wheelDelta ? (this.event.wheelDelta / (window.opera ? -120 : 120)) : -(this.event.detail || 0) / 3; } else if (this.type.test('key')){ this.code = this.event.which || this.event.keyCode; for (var name in Event.keys){ if (Event.keys[name] == this.code) var special = name; } this.key = special || String.fromCharCode(this.code).toLowerCase(); } else if (this.type.test('mouse') || this.type == 'click'){ this.page = { 'x': this.event.pageX || this.event.clientX + document.documentElement.scrollLeft, 'y': this.event.pageY || this.event.clientY + document.documentElement.scrollTop }; this.client = { 'x': this.event.pageX ? this.event.pageX - window.pageXOffset : this.event.clientX, 'y': this.event.pageY ? this.event.pageY - window.pageYOffset : this.event.clientY }; this.rightClick = (this.event.which == 3) || (this.event.button == 2); switch (this.type){ case 'mouseover': this.relatedTarget = this.event.relatedTarget || this.event.fromElement; break; case 'mouseout': this.relatedTarget = this.event.relatedTarget || this.event.toElement; } } }, /* Property: stop cross browser method to stop an event */ stop: function() { this.stopPropagation(); this.preventDefault(); return this; }, /* Property: stopPropagation cross browser method to stop the propagation of an event */ stopPropagation: function(){ if (this.event.stopPropagation) this.event.stopPropagation(); else this.event.cancelBubble = true; return this; }, /* Property: preventDefault cross browser method to prevent the default action of the event */ preventDefault: function(){ if (this.event.preventDefault) this.event.preventDefault(); else this.event.returnValue = false; return this; } }); Event.keys = { 'enter': 13, 'up': 38, 'down': 40, 'left': 37, 'right': 39, 'esc': 27, 'space': 32, 'backspace': 8, 'delete': 46 }; Function.extend({ /* Property: bindWithEvent automatically passes mootools Event Class. Arguments: bind - optional, the object that the "this" of the function will refer to. Returns: a function with the parameter bind as its "this" and as a pre-passed argument event or window.event, depending on the browser. Example: >function myFunction(event){ > alert(event.clientx) //returns the coordinates of the mouse.. >}; >myElement.onclick = myFunction.bindWithEvent(myElement); */ bindWithEvent: function(bind, args){ return this.create({'bind': bind, 'arguments': args, 'event': Event}); } }); /* Script: Common.js Contains common implementations for custom classes. In Mootools is implemented in and . Author: Valerio Proietti, License: MIT-style license. */ /* Class: Chain An "Utility" Class. Its methods can be implemented with into any . Currently implemented in and . In for example, is used to execute a list of function, one after another, once the effect is completed. The functions will not be fired all togheter, but one every completion, to create custom complex animations. Example: (start code) var myFx = new Fx.Style('element', 'opacity'); myFx.start(1,0).chain(function(){ myFx.start(0,1); }).chain(function(){ myFx.start(1,0); }).chain(function(){ myFx.start(0,1); }); //the element will appear and disappear three times (end) */ var Chain = new Class({ /* Property: chain adds a function to the Chain instance stack. Arguments: fn - the function to append. */ chain: function(fn){ this.chains = this.chains || []; this.chains.push(fn); return this; }, /* Property: callChain Executes the first function of the Chain instance stack, then removes it. The first function will then become the second. */ callChain: function(){ if (this.chains && this.chains.length) this.chains.splice(0, 1)[0].delay(10, this); }, /* Property: clearChain Clears the stack of a Chain instance. */ clearChain: function(){ this.chains = []; } }); /* Class: Events An "Utility" Class. Its methods can be implemented with into any . In Class, for example, is used to give the possibility add any number of functions to the Effects events, like onComplete, onStart, onCancel Example: (start code) var myFx = new Fx.Style('element', 'opacity').addEvent('onComplete', function(){ alert('the effect is completed'); }).addEvent('onComplete', function(){ alert('I told you the effect is completed'); }); myFx.start(0,1); //upon completion it will display the 2 alerts, in order. (end) */ var Events = new Class({ /* Property: addEvent adds an event to the stack of events of the Class instance. */ addEvent: function(type, fn){ if (fn != Class.empty){ this.events = this.events || {}; this.events[type] = this.events[type] || []; if (!this.events[type].test(fn)) this.events[type].push(fn); } return this; }, /* Property: fireEvent fires all events of the specified type in the Class instance. */ fireEvent: function(type, args, delay){ if (this.events && this.events[type]){ this.events[type].each(function(fn){ fn.create({'bind': this, 'delay': delay, 'arguments': args})(); }, this); } return this; }, /* Property: removeEvent removes an event from the stack of events of the Class instance. */ removeEvent: function(type, fn){ if (this.events && this.events[type]) this.events[type].remove(fn); return this; } }); /* Class: Options An "Utility" Class. Its methods can be implemented with into any . Used to automate the options settings, also adding Class when the option begins with on. */ var Options = new Class({ /* Property: setOptions sets this.options Arguments: defaults - the default set of options options - the user entered options. can be empty too. Note: if your Class has implemented, every option beginning with on, followed by a capital letter (onComplete) becomes an Class instance event. */ setOptions: function(defaults, options){ this.options = Object.extend(defaults, options); if (this.addEvent){ for (var option in this.options){ if (($type(this.options[option]) == 'function') && option.test('^on[A-Z]')) this.addEvent(option, this.options[option]); } } return this; } }); /* Script: Dom.js Css Query related function and extensions Author: Valerio Proietti, License: MIT-style license. */ /* Section: Utility Functions */ /* Function: $E Selects a single (i.e. the first found) Element based on the selector passed in and an optional filter element. Arguments: selector - the css selector to match filter - optional; a DOM element to limit the scope of the selector match; defaults to document. Example: >$E('a', 'myElement') //find the first anchor tag inside the DOM element with id 'myElement' Returns: a DOM element - the first element that matches the selector */ function $E(selector, filter){ return ($(filter) || document).getElement(selector); }; /* Function: $ES Returns a collection of Elements that match the selector passed in limited to the scope of the optional filter. See Also: for an alternate syntax. Returns: an array of dom elements that match the selector within the filter Arguments: selector - css selector to match filter - optional; a DOM element to limit the scope of the selector match; defaults to document. Examples: >$ES("a") //gets all the anchor tags; synonymous with $$("a") >$ES('a','myElement') //get all the anchor tags within $('myElement') */ function $ES(selector, filter){ return ($(filter) || document).getElementsBySelector(selector); }; /* Class: Element Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. */ Element.extend({ /* Property: getElements Gets all the elements within an element that match the given (single) selector. Arguments: selector - the css selector to match Example: >$('myElement').getElements('a'); // get all anchors within myElement Credits: Say thanks to Christophe Beyls for the new regular expression that rules getElements, a big step forward in terms of speed. */ getElements: function(selector){ var filters = []; selector.clean().split(' ').each(function(sel, i){ var param = sel.match('^(\\w*|\\*)(?:#([\\w_-]+)|\\.([\\w_-]+))?(?:\\[["\']?(\\w+)["\']?(?:([\\*\\^\\$]?=)["\']?(\\w*)["\']?)?\\])?$'); //PARAM ARRAY: 0 = full string: 1 = tag; 2 = id; 3 = class; 4 = attribute; 5 = operator; 6 = value; if (!param) return; param[1] = param[1] || '*'; if (i == 0){ if (param[2]){ var el = this.getElementById(param[2]); if (!el || ((param[1] != '*') && (Element.prototype.getTag.call(el) != param[1]))) return; filters = [el]; } else { filters = $A(this.getElementsByTagName(param[1])); } } else { filters = Elements.prototype.filterByTagName.call(filters, param[1]); if (param[2]) filters = Elements.prototype.filterById.call(filters, param[2]); } if (param[3]) filters = Elements.prototype.filterByClassName.call(filters, param[3]); if (param[4]) filters = Elements.prototype.filterByAttribute.call(filters, param[4], param[6], param[5]); }, this); return $$(filters); }, /* Property: getElementById Targets an element with the specified id found inside the Element. Does not overwrite document.getElementById. Arguments: id - the id of the element to find. */ getElementById: function(id){ var el = document.getElementById(id); if (!el) return false; for (var parent = el.parentNode; parent != this; parent = parent.parentNode){ if (!parent) return false; } return el; }, /* Property: getElement Same as , but returns only the first. Alternate syntax for <$E>, where filter is the Element. */ getElement: function(selector){ return this.getElementsBySelector(selector)[0]; }, /* Property: getElementsBySelector Same as , but allows for comma separated selectors, as in css. Alternate syntax for <$$>, where filter is the Element. */ getElementsBySelector: function(selector){ var els = []; selector.split(',').each(function(sel){ els.extend(this.getElements(sel)); }, this); return $$(els); } }); document.extend = Object.extend; /* Section: document related functions */ document.extend({ /* Function: document.getElementsByClassName Returns all the elements that match a specific class name. Here for compatibility purposes. can also be written: document.getElements('.className'), or $$('.className') */ getElementsByClassName: function(className){ return document.getElements('.'+className); }, getElement: Element.prototype.getElement, getElements: Element.prototype.getElements, getElementsBySelector: Element.prototype.getElementsBySelector }); /* Class: Elements Methods for dom queries arrays, as <$$>. */ Elements.extend({ //internal methods filterById: function(id, tag){ var found = []; this.each(function(el){ if (el.id == id) found.push(el); }); return found; }, filterByClassName: function(className){ var found = []; this.each(function(el){ if (Element.prototype.hasClass.call(el, className)) found.push(el); }); return found; }, filterByTagName: function(tagName){ var found = []; this.each(function(el){ found.extend(el.getElementsByTagName(tagName)); }); return found; }, filterByAttribute: function(name, value, operator){ var found = []; this.each(function(el){ var att = el.getAttribute(name); if (!att) return found; if (!operator) return found.push(el); switch (operator){ case '*=': if (att.test(value)) found.push(el); break; case '=': if (att == value) found.push(el); break; case '^=': if (att.test('^'+value)) found.push(el); break; case '$=': if (att.test(value+'$')) found.push(el); } return found; }); return found; } }); /* Script: Hash.js Contains the class Hash. Author: Christophe Beyls License: MIT-style license. */ /* Class: Hash It wraps an object that it uses internally as a map. The user must use put(), get(), and remove() to add/change, retrieve and remove values, it must not access the internal object directly. With this implementation, null values are not allowed. Example: (start code) var hash = new Hash({a: 'hi', b: 'world', c: 'howdy'}); hash.remove('b'); // b is removed. hash.set('c', 'hello'); hash.get('c'); // returns 'hello' hash.length // returns 2 (a and b) (end) */ var Hash = new Class({ length: 0, initialize: function(obj) { this.obj = {}; for (var property in obj) { this.obj[property] = obj[property]; this.length++; } }, get: function(key) { return this.obj[key]; }, set: function(key, value) { if (value == null) return false; if (this.obj[key] == undefined) this.length++; this.obj[key] = value; return this; }, remove: function(key) { if (this.obj[key] == undefined) return false; var obj = {}; this.length--; for (var property in this.obj){ if (property != key) obj[property] = this.obj[property]; } this.obj = obj; return this; }, each: function(fn, bind) { for (var property in this.obj) fn.call(bind || this, property, this.obj[property]); }, extend: function(obj){ this.initialize(Object.extend(this.obj, obj)); return this; }, empty: function() { return (this.length == 0); }, keys: function() { var keys = []; for (var property in this.obj) keys.push(property); return keys; }, values: function() { var values = []; for (var property in this.obj) values.push(this.obj[property]); return values; } }); /* Function: $H Shortcut to create an Hash from an Object. */ function $H(obj) { return new Hash(obj); }; /* Script: Color.js Contains the Color class. Author: Michael Jackson License: MIT-style license. */ /* Class: Color Creates a new Color Object, which is an array with some color specific methods. Example: (start code) var black = new Color('#000'); var purple = new Color([255,0,255]); // mix black with white and purple, each time at 10% of the new color var darkpurple = black.mix('#fff', purple, 10); $('myDiv').setStyle('background-color', darkpurple); (end) */ var Color = new Class({ initialize: function(color){ if (color.mix && color.invert) return color; var rgb = (color.push) ? color : color.hexToRgb(true); return Object.extend(rgb, Color.prototype); }, mix: function(){ var colors = $A(arguments); var alpha = 50; if ($type(colors[colors.length-1]) == 'number') alpha = colors.pop(); var rgb = this.copy(); colors.each(function(color){ color = new Color(color); for (var i = 0; i < 3; i++) rgb[i] = Math.round((rgb[i] / 100 * (100 - alpha)) + (color[i] / 100 * alpha)); }); return new Color(rgb); }, invert: function(){ var rgb = []; for (var i = 0; i < 3; i++) rgb.push(255 - this[i]); return new Color(rgb); } }); function $C(color){ return new Color(color); }; /* Script: Window.Base.js Contains Window.onDomReady and Window.disableImageCache License: MIT-style license. */ /* Class: Window Cross browser methods to get the window size, onDomReady method. */ window.extend = Object.extend; window.extend({ /* Function: window.disableImageCache Disables background image chache for internex explorer, to prevent flickering. To be called if you have effects with background images, and they flicker. Example: Window.disableImageCache(); */ disableImageCache: function(){ if (this.ie6) try {document.execCommand("BackgroundImageCache", false, true);} catch (e){}; }, addEvent: function(type, fn){ if (type == 'domready'){ if (this.loaded) fn(); else if (!this.events || !this.events.domready){ var domReady = function(){ if (this.loaded) return; this.loaded = true; if (this.timer) this.timer = $clear(this.timer); Element.prototype.fireEvent.call(this, 'domready'); this.events.domready = null; }.bind(this); if (document.readyState && this.khtml){ //safari and konqueror this.timer = function(){ if (['loaded','complete'].test(document.readyState)) domReady(); }.periodical(50); } else if (document.readyState && this.ie){ //ie document.write("