/ *
-- -
MooTools : the javascript framework
web build :
- http : //mootools.net/core/efcfcd2923b4129a00a22580c45b1d75
packager build :
- packager build Core / Class Core / Class . Extras Core / Element Core / Element . Style Core / Request . JSON Core / DOMReady
/ *
-- -
name : Core
description : The heart of MooTools .
license : MIT - style license .
copyright : Copyright ( c ) 2006 - 2010 [ Valerio Proietti ] ( http : //mad4milk.net/).
authors : The MooTools production team ( http : //mootools.net/developers/)
inspiration :
- Class implementation inspired by [ Base . js ] ( http : //dean.edwards.name/weblog/2006/03/base/) Copyright (c) 2006 Dean Edwards, [GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)
- Some functionality inspired by [ Prototype . js ] ( http : //prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/mit-license.php)
provides : [ Core , MooTools , Type , typeOf , instanceOf , Native ]
...
* /
( function ( ) {
this . MooTools = {
version : '1.3' ,
build : 'a3eed692dd85050d80168ec2c708efe901bb7db3'
} ;
// typeOf, instanceOf
var typeOf = this . typeOf = function ( item ) {
if ( item == null ) return 'null' ;
if ( item . $family ) return item . $family ( ) ;
if ( item . nodeName ) {
if ( item . nodeType == 1 ) return 'element' ;
if ( item . nodeType == 3 ) return ( /\S/ ) . test ( item . nodeValue ) ? 'textnode' : 'whitespace' ;
} else if ( typeof item . length == 'number' ) {
if ( item . callee ) return 'arguments' ;
if ( 'item' in item ) return 'collection' ;
}
return typeof item ;
} ;
var instanceOf = this . instanceOf = function ( item , object ) {
if ( item == null ) return false ;
var constructor = item . $constructor || item . constructor ;
while ( constructor ) {
if ( constructor === object ) return true ;
constructor = constructor . parent ;
}
return item instanceof object ;
} ;
// Function overloading
var Function = this . Function ;
var enumerables = true ;
for ( var i in { toString : 1 } ) enumerables = null ;
if ( enumerables ) enumerables = [ 'hasOwnProperty' , 'valueOf' , 'isPrototypeOf' , 'propertyIsEnumerable' , 'toLocaleString' , 'toString' , 'constructor' ] ;
Function . prototype . overloadSetter = function ( usePlural ) {
var self = this ;
return function ( a , b ) {
if ( a == null ) return this ;
if ( usePlural || typeof a != 'string' ) {
for ( var k in a ) self . call ( this , k , a [ k ] ) ;
if ( enumerables ) for ( var i = enumerables . length ; i -- ; ) {
k = enumerables [ i ] ;
if ( a . hasOwnProperty ( k ) ) self . call ( this , k , a [ k ] ) ;
}
} else {
self . call ( this , a , b ) ;
}
return this ;
} ;
} ;
Function . prototype . overloadGetter = function ( usePlural ) {
var self = this ;
return function ( a ) {
var args , result ;
if ( usePlural || typeof a != 'string' ) args = a ;
else if ( arguments . length > 1 ) args = arguments ;
if ( args ) {
result = { } ;
for ( var i = 0 ; i < args . length ; i ++ ) result [ args [ i ] ] = self . call ( this , args [ i ] ) ;
} else {
result = self . call ( this , a ) ;
}
return result ;
} ;
} ;
Function . prototype . extend = function ( key , value ) {
this [ key ] = value ;
} . overloadSetter ( ) ;
Function . prototype . implement = function ( key , value ) {
this . prototype [ key ] = value ;
} . overloadSetter ( ) ;
// From
var slice = Array . prototype . slice ;
Function . from = function ( item ) {
return ( typeOf ( item ) == 'function' ) ? item : function ( ) {
return item ;
} ;
} ;
Array . from = function ( item ) {
if ( item == null ) return [ ] ;
return ( Type . isEnumerable ( item ) && typeof item != 'string' ) ? ( typeOf ( item ) == 'array' ) ? item : slice . call ( item ) : [ item ] ;
} ;
Number . from = function ( item ) {
var number = parseFloat ( item ) ;
return isFinite ( number ) ? number : null ;
} ;
String . from = function ( item ) {
return item + '' ;
} ;
// hide, protect
Function . implement ( {
hide : function ( ) {
this . $hidden = true ;
return this ;
} ,
protect : function ( ) {
this . $protected = true ;
return this ;
}
} ) ;
// Type
var Type = this . Type = function ( name , object ) {
if ( name ) {
var lower = name . toLowerCase ( ) ;
var typeCheck = function ( item ) {
return ( typeOf ( item ) == lower ) ;
} ;
Type [ 'is' + name ] = typeCheck ;
if ( object != null ) {
object . prototype . $family = ( function ( ) {
return lower ;
} ) . hide ( ) ;
}
}
if ( object == null ) return null ;
object . extend ( this ) ;
object . $constructor = Type ;
object . prototype . $constructor = object ;
return object ;
} ;
var toString = Object . prototype . toString ;
Type . isEnumerable = function ( item ) {
return ( item != null && typeof item . length == 'number' && toString . call ( item ) != '[object Function]' ) ;
} ;
var hooks = { } ;
var hooksOf = function ( object ) {
var type = typeOf ( object . prototype ) ;
return hooks [ type ] || ( hooks [ type ] = [ ] ) ;
} ;
var implement = function ( name , method ) {
if ( method && method . $hidden ) return this ;
var hooks = hooksOf ( this ) ;
for ( var i = 0 ; i < hooks . length ; i ++ ) {
var hook = hooks [ i ] ;
if ( typeOf ( hook ) == 'type' ) implement . call ( hook , name , method ) ;
else hook . call ( this , name , method ) ;
}
var previous = this . prototype [ name ] ;
if ( previous == null || ! previous . $protected ) this . prototype [ name ] = method ;
if ( this [ name ] == null && typeOf ( method ) == 'function' ) extend . call ( this , name , function ( item ) {
return method . apply ( item , slice . call ( arguments , 1 ) ) ;
} ) ;
return this ;
} ;
var extend = function ( name , method ) {
if ( method && method . $hidden ) return this ;
var previous = this [ name ] ;
if ( previous == null || ! previous . $protected ) this [ name ] = method ;
return this ;
} ;
Type . implement ( {
implement : implement . overloadSetter ( ) ,
extend : extend . overloadSetter ( ) ,
alias : function ( name , existing ) {
implement . call ( this , name , this . prototype [ existing ] ) ;
} . overloadSetter ( ) ,
mirror : function ( hook ) {
hooksOf ( this ) . push ( hook ) ;
return this ;
}
} ) ;
new Type ( 'Type' , Type ) ;
// Default Types
var force = function ( name , object , methods ) {
var isType = ( object != Object ) ,
prototype = object . prototype ;
if ( isType ) object = new Type ( name , object ) ;
for ( var i = 0 , l = methods . length ; i < l ; i ++ ) {
var key = methods [ i ] ,
generic = object [ key ] ,
proto = prototype [ key ] ;
if ( generic ) generic . protect ( ) ;
if ( isType && proto ) {
delete prototype [ key ] ;
prototype [ key ] = proto . protect ( ) ;
}
}
if ( isType ) object . implement ( prototype ) ;
return force ;
} ;
force ( 'String' , String , [
'charAt' , 'charCodeAt' , 'concat' , 'indexOf' , 'lastIndexOf' , 'match' , 'quote' , 'replace' , 'search' ,
'slice' , 'split' , 'substr' , 'substring' , 'toLowerCase' , 'toUpperCase'
] ) ( 'Array' , Array , [
'pop' , 'push' , 'reverse' , 'shift' , 'sort' , 'splice' , 'unshift' , 'concat' , 'join' , 'slice' ,
'indexOf' , 'lastIndexOf' , 'filter' , 'forEach' , 'every' , 'map' , 'some' , 'reduce' , 'reduceRight'
] ) ( 'Number' , Number , [
'toExponential' , 'toFixed' , 'toLocaleString' , 'toPrecision'
] ) ( 'Function' , Function , [
'apply' , 'call' , 'bind'
] ) ( 'RegExp' , RegExp , [
'exec' , 'test'
] ) ( 'Object' , Object , [
'create' , 'defineProperty' , 'defineProperties' , 'keys' ,
'getPrototypeOf' , 'getOwnPropertyDescriptor' , 'getOwnPropertyNames' ,
'preventExtensions' , 'isExtensible' , 'seal' , 'isSealed' , 'freeze' , 'isFrozen'
] ) ( 'Date' , Date , [ 'now' ] ) ;
Object . extend = extend . overloadSetter ( ) ;
Date . extend ( 'now' , function ( ) {
return + ( new Date ) ;
} ) ;
new Type ( 'Boolean' , Boolean ) ;
// fixes NaN returning as Number
Number . prototype . $family = function ( ) {
return isFinite ( this ) ? 'number' : 'null' ;
} . hide ( ) ;
// Number.random
Number . extend ( 'random' , function ( min , max ) {
return Math . floor ( Math . random ( ) * ( max - min + 1 ) + min ) ;
} ) ;
// forEach, each
Object . extend ( 'forEach' , function ( object , fn , bind ) {
for ( var key in object ) {
if ( object . hasOwnProperty ( key ) ) fn . call ( bind , object [ key ] , key , object ) ;
}
} ) ;
Object . each = Object . forEach ;
Array . implement ( {
forEach : function ( fn , bind ) {
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
if ( i in this ) fn . call ( bind , this [ i ] , i , this ) ;
}
} ,
each : function ( fn , bind ) {
Array . forEach ( this , fn , bind ) ;
return this ;
}
} ) ;
// Array & Object cloning, Object merging and appending
var cloneOf = function ( item ) {
switch ( typeOf ( item ) ) {
case 'array' : return item . clone ( ) ;
case 'object' : return Object . clone ( item ) ;
default : return item ;
}
} ;
Array . implement ( 'clone' , function ( ) {
var i = this . length , clone = new Array ( i ) ;
while ( i -- ) clone [ i ] = cloneOf ( this [ i ] ) ;
return clone ;
} ) ;
var mergeOne = function ( source , key , current ) {
switch ( typeOf ( current ) ) {
case 'object' :
if ( typeOf ( source [ key ] ) == 'object' ) Object . merge ( source [ key ] , current ) ;
else source [ key ] = Object . clone ( current ) ;
break ;
case 'array' : source [ key ] = current . clone ( ) ; break ;
default : source [ key ] = current ;
}
return source ;
} ;
Object . extend ( {
merge : function ( source , k , v ) {
if ( typeOf ( k ) == 'string' ) return mergeOne ( source , k , v ) ;
for ( var i = 1 , l = arguments . length ; i < l ; i ++ ) {
var object = arguments [ i ] ;
for ( var key in object ) mergeOne ( source , key , object [ key ] ) ;
}
return source ;
} ,
clone : function ( object ) {
var clone = { } ;
for ( var key in object ) clone [ key ] = cloneOf ( object [ key ] ) ;
return clone ;
} ,
append : function ( original ) {
for ( var i = 1 , l = arguments . length ; i < l ; i ++ ) {
var extended = arguments [ i ] || { } ;
for ( var key in extended ) original [ key ] = extended [ key ] ;
}
return original ;
}
} ) ;
// Object-less types
[ 'Object' , 'WhiteSpace' , 'TextNode' , 'Collection' , 'Arguments' ] . each ( function ( name ) {
new Type ( name ) ;
} ) ;
// Unique ID
var UID = Date . now ( ) ;
String . extend ( 'uniqueID' , function ( ) {
return ( UID ++ ) . toString ( 36 ) ;
} ) ;
} ) ( ) ;
/ *
-- -
name : Array
description : Contains Array Prototypes like each , contains , and erase .
license : MIT - style license .
requires : Type
provides : Array
...
* /
Array . implement ( {
invoke : function ( methodName ) {
var args = Array . slice ( arguments , 1 ) ;
return this . map ( function ( item ) {
return item [ methodName ] . apply ( item , args ) ;
} ) ;
} ,
every : function ( fn , bind ) {
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
if ( ( i in this ) && ! fn . call ( bind , this [ i ] , i , this ) ) return false ;
}
return true ;
} ,
filter : function ( fn , bind ) {
var results = [ ] ;
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
if ( ( i in this ) && fn . call ( bind , this [ i ] , i , this ) ) results . push ( this [ i ] ) ;
}
return results ;
} ,
clean : function ( ) {
return this . filter ( function ( item ) {
return item != null ;
} ) ;
} ,
indexOf : function ( item , from ) {
var len = this . length ;
for ( var i = ( from < 0 ) ? Math . max ( 0 , len + from ) : from || 0 ; i < len ; i ++ ) {
if ( this [ i ] === item ) return i ;
}
return - 1 ;
} ,
map : function ( fn , bind ) {
var results = [ ] ;
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
if ( i in this ) results [ i ] = fn . call ( bind , this [ i ] , i , this ) ;
}
return results ;
} ,
some : function ( fn , bind ) {
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
if ( ( i in this ) && fn . call ( bind , this [ i ] , i , this ) ) return true ;
}
return false ;
} ,
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 ;
} ,
link : function ( object ) {
var result = { } ;
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
for ( var key in object ) {
if ( object [ key ] ( this [ i ] ) ) {
result [ key ] = this [ i ] ;
delete object [ key ] ;
break ;
}
}
}
return result ;
} ,
contains : function ( item , from ) {
return this . indexOf ( item , from ) != - 1 ;
} ,
append : function ( array ) {
this . push . apply ( this , array ) ;
return this ;
} ,
getLast : function ( ) {
return ( this . length ) ? this [ this . length - 1 ] : null ;
} ,
getRandom : function ( ) {
return ( this . length ) ? this [ Number . random ( 0 , this . length - 1 ) ] : null ;
} ,
include : function ( item ) {
if ( ! this . contains ( item ) ) this . push ( item ) ;
return this ;
} ,
combine : function ( array ) {
for ( var i = 0 , l = array . length ; i < l ; i ++ ) this . include ( array [ i ] ) ;
return this ;
} ,
erase : function ( item ) {
for ( var i = this . length ; i -- ; ) {
if ( this [ i ] === item ) this . splice ( i , 1 ) ;
}
return this ;
} ,
empty : function ( ) {
this . length = 0 ;
return this ;
} ,
flatten : function ( ) {
var array = [ ] ;
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
var type = typeOf ( this [ i ] ) ;
if ( type == 'null' ) continue ;
array = array . concat ( ( type == 'array' || type == 'collection' || type == 'arguments' || instanceOf ( this [ i ] , Array ) ) ? Array . flatten ( this [ i ] ) : this [ i ] ) ;
}
return array ;
} ,
pick : function ( ) {
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
if ( this [ i ] != null ) return this [ i ] ;
}
return null ;
} ,
hexToRgb : function ( array ) {
if ( this . length != 3 ) return null ;
var rgb = this . map ( function ( value ) {
if ( value . length == 1 ) value += value ;
return value . toInt ( 16 ) ;
} ) ;
return ( array ) ? rgb : 'rgb(' + rgb + ')' ;
} ,
rgbToHex : function ( array ) {
if ( this . length < 3 ) return null ;
if ( this . length == 4 && this [ 3 ] == 0 && ! array ) 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 ( '' ) ;
}
} ) ;
/ *
-- -
name : String
description : Contains String Prototypes like camelCase , capitalize , test , and toInt .
license : MIT - style license .
requires : Type
provides : String
...
* /
String . implement ( {
test : function ( regex , params ) {
return ( ( typeOf ( regex ) == 'regexp' ) ? regex : new RegExp ( '' + regex , params ) ) . test ( this ) ;
} ,
contains : function ( string , separator ) {
return ( separator ) ? ( separator + this + separator ) . indexOf ( separator + string + separator ) > - 1 : this . indexOf ( string ) > - 1 ;
} ,
trim : function ( ) {
return this . replace ( /^\s+|\s+$/g , '' ) ;
} ,
clean : function ( ) {
return this . replace ( /\s+/g , ' ' ) . trim ( ) ;
} ,
camelCase : function ( ) {
return this . replace ( /-\D/g , function ( match ) {
return match . charAt ( 1 ) . toUpperCase ( ) ;
} ) ;
} ,
hyphenate : function ( ) {
return this . replace ( /[A-Z]/g , function ( match ) {
return ( '-' + match . charAt ( 0 ) . toLowerCase ( ) ) ;
} ) ;
} ,
capitalize : function ( ) {
return this . replace ( /\b[a-z]/g , function ( match ) {
return match . toUpperCase ( ) ;
} ) ;
} ,
escapeRegExp : function ( ) {
return this . replace ( /([-.*+?^${}()|[\]\/\\])/g , '\\$1' ) ;
} ,
toInt : function ( base ) {
return parseInt ( this , base || 10 ) ;
} ,
toFloat : function ( ) {
return parseFloat ( this ) ;
} ,
hexToRgb : function ( array ) {
var hex = this . match ( /^#?(\w{1,2})(\w{1,2})(\w{1,2})$/ ) ;
return ( hex ) ? hex . slice ( 1 ) . hexToRgb ( array ) : null ;
} ,
rgbToHex : function ( array ) {
var rgb = this . match ( /\d{1,3}/g ) ;
return ( rgb ) ? rgb . rgbToHex ( array ) : null ;
} ,
substitute : function ( object , regexp ) {
return this . replace ( regexp || ( /\\?\{([^{}]+)\}/g ) , function ( match , name ) {
if ( match . charAt ( 0 ) == '\\' ) return match . slice ( 1 ) ;
return ( object [ name ] != null ) ? object [ name ] : '' ;
} ) ;
}
} ) ;
/ *
-- -
name : Function
description : Contains Function Prototypes like create , bind , pass , and delay .
license : MIT - style license .
requires : Type
provides : Function
...
* /
Function . extend ( {
attempt : function ( ) {
for ( var i = 0 , l = arguments . length ; i < l ; i ++ ) {
try {
return arguments [ i ] ( ) ;
} catch ( e ) { }
}
return null ;
}
} ) ;
Function . implement ( {
attempt : function ( args , bind ) {
try {
return this . apply ( bind , Array . from ( args ) ) ;
} catch ( e ) { }
return null ;
} ,
bind : function ( bind ) {
var self = this ,
args = ( arguments . length > 1 ) ? Array . slice ( arguments , 1 ) : null ;
return function ( ) {
if ( ! args && ! arguments . length ) return self . call ( bind ) ;
if ( args && arguments . length ) return self . apply ( bind , args . concat ( Array . from ( arguments ) ) ) ;
return self . apply ( bind , args || arguments ) ;
} ;
} ,
pass : function ( args , bind ) {
var self = this ;
if ( args != null ) args = Array . from ( args ) ;
return function ( ) {
return self . apply ( bind , args || arguments ) ;
} ;
} ,
delay : function ( delay , bind , args ) {
return setTimeout ( this . pass ( args , bind ) , delay ) ;
} ,
periodical : function ( periodical , bind , args ) {
return setInterval ( this . pass ( args , bind ) , periodical ) ;
}
} ) ;
/ *
-- -
name : Number
description : Contains Number Prototypes like limit , round , times , and ceil .
license : MIT - style license .
requires : Type
provides : Number
...
* /
Number . implement ( {
limit : function ( min , max ) {
return Math . min ( max , Math . max ( min , this ) ) ;
} ,
round : function ( precision ) {
precision = Math . pow ( 10 , precision || 0 ) . toFixed ( precision < 0 ? - precision : 0 ) ;
return Math . round ( this * precision ) / precision ;
} ,
times : function ( fn , bind ) {
for ( var i = 0 ; i < this ; i ++ ) fn . call ( bind , i , this ) ;
} ,
toFloat : function ( ) {
return parseFloat ( this ) ;
} ,
toInt : function ( base ) {
return parseInt ( this , base || 10 ) ;
}
} ) ;
Number . alias ( 'each' , 'times' ) ;
( function ( math ) {
var methods = { } ;
math . each ( function ( name ) {
if ( ! Number [ name ] ) methods [ name ] = function ( ) {
return Math [ name ] . apply ( null , [ this ] . concat ( Array . from ( arguments ) ) ) ;
} ;
} ) ;
Number . implement ( methods ) ;
} ) ( [ 'abs' , 'acos' , 'asin' , 'atan' , 'atan2' , 'ceil' , 'cos' , 'exp' , 'floor' , 'log' , 'max' , 'min' , 'pow' , 'sin' , 'sqrt' , 'tan' ] ) ;
/ *
-- -
name : Class
description : Contains the Class Function for easily creating , extending , and implementing reusable Classes .
license : MIT - style license .
requires : [ Array , String , Function , Number ]
provides : Class
...
* /
( function ( ) {
var Class = this . Class = new Type ( 'Class' , function ( params ) {
if ( instanceOf ( params , Function ) ) params = { initialize : params } ;
var newClass = function ( ) {
reset ( this ) ;
if ( newClass . $prototyping ) return this ;
this . $caller = null ;
var value = ( this . initialize ) ? this . initialize . apply ( this , arguments ) : this ;
this . $caller = this . caller = null ;
return value ;
} . extend ( this ) . implement ( params ) ;
newClass . $constructor = Class ;
newClass . prototype . $constructor = newClass ;
newClass . prototype . parent = parent ;
return newClass ;
} ) ;
var parent = function ( ) {
if ( ! this . $caller ) throw new Error ( 'The method "parent" cannot be called.' ) ;
var name = this . $caller . $name ,
parent = this . $caller . $owner . parent ,
previous = ( parent ) ? parent . prototype [ name ] : null ;
if ( ! previous ) throw new Error ( 'The method "' + name + '" has no parent.' ) ;
return previous . apply ( this , arguments ) ;
} ;
var reset = function ( object ) {
for ( var key in object ) {
var value = object [ key ] ;
switch ( typeOf ( value ) ) {
case 'object' :
var F = function ( ) { } ;
F . prototype = value ;
object [ key ] = reset ( new F ) ;
break ;
case 'array' : object [ key ] = value . clone ( ) ; break ;
}
}
return object ;
} ;
var wrap = function ( self , key , method ) {
if ( method . $origin ) method = method . $origin ;
var wrapper = function ( ) {
if ( method . $protected && this . $caller == null ) throw new Error ( 'The method "' + key + '" cannot be called.' ) ;
var caller = this . caller , current = this . $caller ;
this . caller = current ; this . $caller = wrapper ;
var result = method . apply ( this , arguments ) ;
this . $caller = current ; this . caller = caller ;
return result ;
} . extend ( { $owner : self , $origin : method , $name : key } ) ;
return wrapper ;
} ;
var implement = function ( key , value , retain ) {
if ( Class . Mutators . hasOwnProperty ( key ) ) {
value = Class . Mutators [ key ] . call ( this , value ) ;
if ( value == null ) return this ;
}
if ( typeOf ( value ) == 'function' ) {
if ( value . $hidden ) return this ;
this . prototype [ key ] = ( retain ) ? value : wrap ( this , key , value ) ;
} else {
Object . merge ( this . prototype , key , value ) ;
}
return this ;
} ;
var getInstance = function ( klass ) {
klass . $prototyping = true ;
var proto = new klass ;
delete klass . $prototyping ;
return proto ;
} ;
Class . implement ( 'implement' , implement . overloadSetter ( ) ) ;
Class . Mutators = {
Extends : function ( parent ) {
this . parent = parent ;
this . prototype = getInstance ( parent ) ;
} ,
Implements : function ( items ) {
Array . from ( items ) . each ( function ( item ) {
var instance = new item ;
for ( var key in instance ) implement . call ( this , key , instance [ key ] , true ) ;
} , this ) ;
}
} ;
} ) ( ) ;
/ *
-- -
name : Class . Extras
description : Contains Utility Classes that can be implemented into your own Classes to ease the execution of many common tasks .
license : MIT - style license .
requires : Class
provides : [ Class . Extras , Chain , Events , Options ]
...
* /
( function ( ) {
this . Chain = new Class ( {
$chain : [ ] ,
chain : function ( ) {
this . $chain . append ( Array . flatten ( arguments ) ) ;
return this ;
} ,
callChain : function ( ) {
return ( this . $chain . length ) ? this . $chain . shift ( ) . apply ( this , arguments ) : false ;
} ,
clearChain : function ( ) {
this . $chain . empty ( ) ;
return this ;
}
} ) ;
var removeOn = function ( string ) {
return string . replace ( /^on([A-Z])/ , function ( full , first ) {
return first . toLowerCase ( ) ;
} ) ;
} ;
this . Events = new Class ( {
$events : { } ,
addEvent : function ( type , fn , internal ) {
type = removeOn ( type ) ;
this . $events [ type ] = ( this . $events [ type ] || [ ] ) . include ( fn ) ;
if ( internal ) fn . internal = true ;
return this ;
} ,
addEvents : function ( events ) {
for ( var type in events ) this . addEvent ( type , events [ type ] ) ;
return this ;
} ,
fireEvent : function ( type , args , delay ) {
type = removeOn ( type ) ;
var events = this . $events [ type ] ;
if ( ! events ) return this ;
args = Array . from ( args ) ;
events . each ( function ( fn ) {
if ( delay ) fn . delay ( delay , this , args ) ;
else fn . apply ( this , args ) ;
} , this ) ;
return this ;
} ,
removeEvent : function ( type , fn ) {
type = removeOn ( type ) ;
var events = this . $events [ type ] ;
if ( events && ! fn . internal ) {
var index = events . indexOf ( fn ) ;
if ( index != - 1 ) delete events [ index ] ;
}
return this ;
} ,
removeEvents : function ( events ) {
var type ;
if ( typeOf ( events ) == 'object' ) {
for ( type in events ) this . removeEvent ( type , events [ type ] ) ;
return this ;
}
if ( events ) events = removeOn ( events ) ;
for ( type in this . $events ) {
if ( events && events != type ) continue ;
var fns = this . $events [ type ] ;
for ( var i = fns . length ; i -- ; ) this . removeEvent ( type , fns [ i ] ) ;
}
return this ;
}
} ) ;
this . Options = new Class ( {
setOptions : function ( ) {
var options = this . options = Object . merge . apply ( null , [ { } , this . options ] . append ( arguments ) ) ;
if ( ! this . addEvent ) return this ;
for ( var option in options ) {
if ( typeOf ( options [ option ] ) != 'function' || ! ( /^on[A-Z]/ ) . test ( option ) ) continue ;
this . addEvent ( option , options [ option ] ) ;
delete options [ option ] ;
}
return this ;
}
} ) ;
} ) ( ) ;
/ *
-- -
name : Browser
description : The Browser Object . Contains Browser initialization , Window and Document , and the Browser Hash .
license : MIT - style license .
requires : [ Array , Function , Number , String ]
provides : [ Browser , Window , Document ]
...
* /
( function ( ) {
var document = this . document ;
var window = document . window = this ;
var UID = 1 ;
this . $uid = ( window . ActiveXObject ) ? function ( item ) {
return ( item . uid || ( item . uid = [ UID ++ ] ) ) [ 0 ] ;
} : function ( item ) {
return item . uid || ( item . uid = UID ++ ) ;
} ;
$uid ( window ) ;
$uid ( document ) ;
var ua = navigator . userAgent . toLowerCase ( ) ,
platform = navigator . platform . toLowerCase ( ) ,
UA = ua . match ( /(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/ ) || [ null , 'unknown' , 0 ] ,
mode = UA [ 1 ] == 'ie' && document . documentMode ;
var Browser = this . Browser = {
extend : Function . prototype . extend ,
name : ( UA [ 1 ] == 'version' ) ? UA [ 3 ] : UA [ 1 ] ,
version : mode || parseFloat ( ( UA [ 1 ] == 'opera' && UA [ 4 ] ) ? UA [ 4 ] : UA [ 2 ] ) ,
Platform : {
name : ua . match ( /ip(?:ad|od|hone)/ ) ? 'ios' : ( ua . match ( /(?:webos|android)/ ) || platform . match ( /mac|win|linux/ ) || [ 'other' ] ) [ 0 ]
} ,
Features : {
xpath : ! ! ( document . evaluate ) ,
air : ! ! ( window . runtime ) ,
query : ! ! ( document . querySelector ) ,
json : ! ! ( window . JSON )
} ,
Plugins : { }
} ;
Browser [ Browser . name ] = true ;
Browser [ Browser . name + parseInt ( Browser . version , 10 ) ] = true ;
Browser . Platform [ Browser . Platform . name ] = true ;
// Request
Browser . Request = ( function ( ) {
var XMLHTTP = function ( ) {
return new XMLHttpRequest ( ) ;
} ;
var MSXML2 = function ( ) {
return new ActiveXObject ( 'MSXML2.XMLHTTP' ) ;
} ;
var MSXML = function ( ) {
return new ActiveXObject ( 'Microsoft.XMLHTTP' ) ;
} ;
return Function . attempt ( function ( ) {
XMLHTTP ( ) ;
return XMLHTTP ;
} , function ( ) {
MSXML2 ( ) ;
return MSXML2 ;
} , function ( ) {
MSXML ( ) ;
return MSXML ;
} ) ;
} ) ( ) ;
Browser . Features . xhr = ! ! ( Browser . Request ) ;
// Flash detection
var version = ( Function . attempt ( function ( ) {
return navigator . plugins [ 'Shockwave Flash' ] . description ;
} , function ( ) {
return new ActiveXObject ( 'ShockwaveFlash.ShockwaveFlash' ) . GetVariable ( '$version' ) ;
} ) || '0 r0' ) . match ( /\d+/g ) ;
Browser . Plugins . Flash = {
version : Number ( version [ 0 ] || '0.' + version [ 1 ] ) || 0 ,
build : Number ( version [ 2 ] ) || 0
} ;
// String scripts
Browser . exec = function ( text ) {
if ( ! text ) return text ;
if ( window . execScript ) {
window . execScript ( text ) ;
} else {
var script = document . createElement ( 'script' ) ;
script . setAttribute ( 'type' , 'text/javascript' ) ;
script . text = text ;
document . head . appendChild ( script ) ;
document . head . removeChild ( script ) ;
}
return text ;
} ;
String . implement ( 'stripScripts' , function ( exec ) {
var scripts = '' ;
var text = this . replace ( /<script[^>]*>([\s\S]*?)<\/script>/gi , function ( all , code ) {
scripts += code + '\n' ;
return '' ;
} ) ;
if ( exec === true ) Browser . exec ( scripts ) ;
else if ( typeOf ( exec ) == 'function' ) exec ( scripts , text ) ;
return text ;
} ) ;
// Window, Document
Browser . extend ( {
Document : this . Document ,
Window : this . Window ,
Element : this . Element ,
Event : this . Event
} ) ;
this . Window = this . $constructor = new Type ( 'Window' , function ( ) { } ) ;
this . $family = Function . from ( 'window' ) . hide ( ) ;
Window . mirror ( function ( name , method ) {
window [ name ] = method ;
} ) ;
this . Document = document . $constructor = new Type ( 'Document' , function ( ) { } ) ;
document . $family = Function . from ( 'document' ) . hide ( ) ;
Document . mirror ( function ( name , method ) {
document [ name ] = method ;
} ) ;
document . html = document . documentElement ;
document . head = document . getElementsByTagName ( 'head' ) [ 0 ] ;
if ( document . execCommand ) try {
document . execCommand ( "BackgroundImageCache" , false , true ) ;
} catch ( e ) { }
if ( this . attachEvent && ! this . addEventListener ) {
var unloadEvent = function ( ) {
this . detachEvent ( 'onunload' , unloadEvent ) ;
document . head = document . html = document . window = null ;
} ;
this . attachEvent ( 'onunload' , unloadEvent ) ;
}
// IE fails on collections and <select>.options (refers to <select>)
var arrayFrom = Array . from ;
try {
arrayFrom ( document . html . childNodes ) ;
} catch ( e ) {
Array . from = function ( item ) {
if ( typeof item != 'string' && Type . isEnumerable ( item ) && typeOf ( item ) != 'array' ) {
var i = item . length , array = new Array ( i ) ;
while ( i -- ) array [ i ] = item [ i ] ;
return array ;
}
return arrayFrom ( item ) ;
} ;
var prototype = Array . prototype ,
slice = prototype . slice ;
[ 'pop' , 'push' , 'reverse' , 'shift' , 'sort' , 'splice' , 'unshift' , 'concat' , 'join' , 'slice' ] . each ( function ( name ) {
var method = prototype [ name ] ;
Array [ name ] = function ( item ) {
return method . apply ( Array . from ( item ) , slice . call ( arguments , 1 ) ) ;
} ;
} ) ;
}
} ) ( ) ;
/ *
-- -
name : Slick . Parser
description : Standalone CSS3 Selector parser
provides : Slick . Parser
...
* /
( function ( ) {
var parsed ,
separatorIndex ,
combinatorIndex ,
reversed ,
cache = { } ,
reverseCache = { } ,
reUnescape = /\\/g ;
var parse = function ( expression , isReversed ) {
if ( expression == null ) return null ;
if ( expression . Slick === true ) return expression ;
expression = ( '' + expression ) . replace ( /^\s+|\s+$/g , '' ) ;
reversed = ! ! isReversed ;
var currentCache = ( reversed ) ? reverseCache : cache ;
if ( currentCache [ expression ] ) return currentCache [ expression ] ;
parsed = { Slick : true , expressions : [ ] , raw : expression , reverse : function ( ) {
return parse ( this . raw , true ) ;
} } ;
separatorIndex = - 1 ;
while ( expression != ( expression = expression . replace ( regexp , parser ) ) ) ;
parsed . length = parsed . expressions . length ;
return currentCache [ expression ] = ( reversed ) ? reverse ( parsed ) : parsed ;
} ;
var reverseCombinator = function ( combinator ) {
if ( combinator === '!' ) return ' ' ;
else if ( combinator === ' ' ) return '!' ;
else if ( ( /^!/ ) . test ( combinator ) ) return combinator . replace ( /^!/ , '' ) ;
else return '!' + combinator ;
} ;
var reverse = function ( expression ) {
var expressions = expression . expressions ;
for ( var i = 0 ; i < expressions . length ; i ++ ) {
var exp = expressions [ i ] ;
var last = { parts : [ ] , tag : '*' , combinator : reverseCombinator ( exp [ 0 ] . combinator ) } ;
for ( var j = 0 ; j < exp . length ; j ++ ) {
var cexp = exp [ j ] ;
if ( ! cexp . reverseCombinator ) cexp . reverseCombinator = ' ' ;
cexp . combinator = cexp . reverseCombinator ;
delete cexp . reverseCombinator ;
}
exp . reverse ( ) . push ( last ) ;
}
return expression ;
} ;
var escapeRegExp = function ( string ) { // Credit: XRegExp 0.6.1 (c) 2007-2008 Steven Levithan <http://stevenlevithan.com/regex/xregexp/> MIT License
return string . replace ( /[-[\]{}()*+?.\\^$|,#\s]/g , "\\$&" ) ;
} ;
var regexp = new RegExp (
/ *
#!/usr/bin/env ruby
puts "\t\t" + DATA . read . gsub ( /\(\?x\)|\s+#.*$|\s+|\\$|\\n/ , '' )
__ END__
" ( ? x ) ^ ( ? : \
\ \ s * ( , ) \ \ s * # Separator \ n \
| \ \ s * ( < combinator > + ) \ \ s * # Combinator \ n \
| ( \ \ s + ) # CombinatorChildren \ n \
| ( < unicode > + | \ \ * ) # Tag \ n \
| \ \ # ( < unicode > + ) # ID \ n \
| \ \ . ( < unicode > + ) # ClassName \ n \
| # Attribute \ n \
\ \ [ \
\ \ s * ( < unicode1 > + ) ( ? : \
\ \ s * ( [ * ^ $ ! ~ | ] ? = ) ( ? : \
\ \ s * ( ? : \
( [ \ " ' ] ? ) ( . * ? ) \ \ 9 \
) \
) \
) ? \ \ s * \
\ \ ] ( ? ! \ \ ] ) \ n \
| : + ( < unicode > + ) ( ? : \
\ \ ( ( ? : \
( ? : ( [ \ " ' ] ) ( [ ^ \ \ 12 ] * ) \ \ 12 ) | ( ( ? : \ \ ( [ ^ ) ] + \ \ ) | [ ^ ( ) ] * ) + ) \
) \ \ ) \
) ? \
) "
* /
"^(?:\\s*(,)\\s*|\\s*(<combinator>+)\\s*|(\\s+)|(<unicode>+|\\*)|\\#(<unicode>+)|\\.(<unicode>+)|\\[\\s*(<unicode1>+)(?:\\s*([*^$!~|]?=)(?:\\s*(?:([\"']?)(.*?)\\9)))?\\s*\\](?!\\])|:+(<unicode>+)(?:\\((?:(?:([\"'])([^\\12]*)\\12)|((?:\\([^)]+\\)|[^()]*)+))\\))?)"
. replace ( /<combinator>/ , '[' + escapeRegExp ( ">+~`!@$%^&={}\\;</" ) + ']' )
. replace ( /<unicode>/g , '(?:[\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])' )
. replace ( /<unicode1>/g , '(?:[:\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])' )
) ;
function parser (
rawMatch ,
separator ,
combinator ,
combinatorChildren ,
tagName ,
id ,
className ,
attributeKey ,
attributeOperator ,
attributeQuote ,
attributeValue ,
pseudoClass ,
pseudoQuote ,
pseudoClassQuotedValue ,
pseudoClassValue
) {
if ( separator || separatorIndex === - 1 ) {
parsed . expressions [ ++ separatorIndex ] = [ ] ;
combinatorIndex = - 1 ;
if ( separator ) return '' ;
}
if ( combinator || combinatorChildren || combinatorIndex === - 1 ) {
combinator = combinator || ' ' ;
var currentSeparator = parsed . expressions [ separatorIndex ] ;
if ( reversed && currentSeparator [ combinatorIndex ] )
currentSeparator [ combinatorIndex ] . reverseCombinator = reverseCombinator ( combinator ) ;
currentSeparator [ ++ combinatorIndex ] = { combinator : combinator , tag : '*' } ;
}
var currentParsed = parsed . expressions [ separatorIndex ] [ combinatorIndex ] ;
if ( tagName ) {
currentParsed . tag = tagName . replace ( reUnescape , '' ) ;
} else if ( id ) {
currentParsed . id = id . replace ( reUnescape , '' ) ;
} else if ( className ) {
className = className . replace ( reUnescape , '' ) ;
if ( ! currentParsed . classList ) currentParsed . classList = [ ] ;
if ( ! currentParsed . classes ) currentParsed . classes = [ ] ;
currentParsed . classList . push ( className ) ;
currentParsed . classes . push ( {
value : className ,
regexp : new RegExp ( '(^|\\s)' + escapeRegExp ( className ) + '(\\s|$)' )
} ) ;
} else if ( pseudoClass ) {
pseudoClassValue = pseudoClassValue || pseudoClassQuotedValue ;
pseudoClassValue = pseudoClassValue ? pseudoClassValue . replace ( reUnescape , '' ) : null ;
if ( ! currentParsed . pseudos ) currentParsed . pseudos = [ ] ;
currentParsed . pseudos . push ( {
key : pseudoClass . replace ( reUnescape , '' ) ,
value : pseudoClassValue
} ) ;
} else if ( attributeKey ) {
attributeKey = attributeKey . replace ( reUnescape , '' ) ;
attributeValue = ( attributeValue || '' ) . replace ( reUnescape , '' ) ;
var test , regexp ;
switch ( attributeOperator ) {
case '^=' : regexp = new RegExp ( '^' + escapeRegExp ( attributeValue ) ) ; break ;
case '$=' : regexp = new RegExp ( escapeRegExp ( attributeValue ) + '$' ) ; break ;
case '~=' : regexp = new RegExp ( '(^|\\s)' + escapeRegExp ( attributeValue ) + '(\\s|$)' ) ; break ;
case '|=' : regexp = new RegExp ( '^' + escapeRegExp ( attributeValue ) + '(-|$)' ) ; break ;
case '=' : test = function ( value ) {
return attributeValue == value ;
} ; break ;
case '*=' : test = function ( value ) {
return value && value . indexOf ( attributeValue ) > - 1 ;
} ; break ;
case '!=' : test = function ( value ) {
return attributeValue != value ;
} ; break ;
default : test = function ( value ) {
return ! ! value ;
} ;
}
if ( attributeValue == '' && ( /^[*$^]=$/ ) . test ( attributeOperator ) ) test = function ( ) {
return false ;
} ;
if ( ! test ) test = function ( value ) {
return value && regexp . test ( value ) ;
} ;
if ( ! currentParsed . attributes ) currentParsed . attributes = [ ] ;
currentParsed . attributes . push ( {
key : attributeKey ,
operator : attributeOperator ,
value : attributeValue ,
test : test
} ) ;
}
return '' ;
} ;
// Slick NS
var Slick = ( this . Slick || { } ) ;
Slick . parse = function ( expression ) {
return parse ( expression ) ;
} ;
Slick . escapeRegExp = escapeRegExp ;
if ( ! this . Slick ) this . Slick = Slick ;
} ) . apply ( /*<CommonJS>*/ ( typeof exports != 'undefined' ) ? exports : /*</CommonJS>*/ this ) ;
/ *
-- -
name : Slick . Finder
description : The new , superfast css selector engine .
provides : Slick . Finder
requires : Slick . Parser
...
* /
( function ( ) {
var local = { } ;
// Feature / Bug detection
local . isNativeCode = function ( fn ) {
return ( /\{\s*\[native code\]\s*\}/ ) . test ( '' + fn ) ;
} ;
local . isXML = function ( document ) {
return ( ! ! document . xmlVersion ) || ( ! ! document . xml ) || ( Object . prototype . toString . call ( document ) === '[object XMLDocument]' ) ||
( document . nodeType === 9 && document . documentElement . nodeName !== 'HTML' ) ;
} ;
local . setDocument = function ( document ) {
// convert elements / window arguments to document. if document cannot be extrapolated, the function returns.
if ( document . nodeType === 9 ) ; // document
else if ( document . ownerDocument ) document = document . ownerDocument ; // node
else if ( document . navigator ) document = document . document ; // window
else return ;
// check if it's the old document
if ( this . document === document ) return ;
this . document = document ;
var root = this . root = document . documentElement ;
this . isXMLDocument = this . isXML ( document ) ;
this . brokenStarGEBTN
= this . starSelectsClosedQSA
= this . idGetsName
= this . brokenMixedCaseQSA
= this . brokenGEBCN
= this . brokenCheckedQSA
= this . brokenEmptyAttributeQSA
= this . isHTMLDocument
= false ;
var starSelectsClosed , starSelectsComments ,
brokenSecondClassNameGEBCN , cachedGetElementsByClassName ;
var selected , id ;
var testNode = document . createElement ( 'div' ) ;
root . appendChild ( testNode ) ;
// on non-HTML documents innerHTML and getElementsById doesnt work properly
try {
id = 'slick_getbyid_test' ;
testNode . innerHTML = '<a id="' + id + '"></a>' ;
this . isHTMLDocument = ! ! document . getElementById ( id ) ;
} catch ( e ) { } ;
if ( this . isHTMLDocument ) {
testNode . style . display = 'none' ;
// IE returns comment nodes for getElementsByTagName('*') for some documents
testNode . appendChild ( document . createComment ( '' ) ) ;
starSelectsComments = ( testNode . getElementsByTagName ( '*' ) . length > 0 ) ;
// IE returns closed nodes (EG:"</foo>") for getElementsByTagName('*') for some documents
try {
testNode . innerHTML = 'foo</foo>' ;
selected = testNode . getElementsByTagName ( '*' ) ;
starSelectsClosed = ( selected && selected . length && selected [ 0 ] . nodeName . charAt ( 0 ) == '/' ) ;
} catch ( e ) { } ;
this . brokenStarGEBTN = starSelectsComments || starSelectsClosed ;
// IE 8 returns closed nodes (EG:"</foo>") for querySelectorAll('*') for some documents
if ( testNode . querySelectorAll ) try {
testNode . innerHTML = 'foo</foo>' ;
selected = testNode . querySelectorAll ( '*' ) ;
this . starSelectsClosedQSA = ( selected && selected . length && selected [ 0 ] . nodeName . charAt ( 0 ) == '/' ) ;
} catch ( e ) { } ;
// IE returns elements with the name instead of just id for getElementsById for some documents
try {
id = 'slick_id_gets_name' ;
testNode . innerHTML = '<a name="' + id + '"></a><b id="' + id + '"></b>' ;
this . idGetsName = document . getElementById ( id ) === testNode . firstChild ;
} catch ( e ) { } ;
// Safari 3.2 querySelectorAll doesnt work with mixedcase on quirksmode
try {
testNode . innerHTML = '<a class="MiXedCaSe"></a>' ;
this . brokenMixedCaseQSA = ! testNode . querySelectorAll ( '.MiXedCaSe' ) . length ;
} catch ( e ) { } ;
try {
testNode . innerHTML = '<a class="f"></a><a class="b"></a>' ;
testNode . getElementsByClassName ( 'b' ) . length ;
testNode . firstChild . className = 'b' ;
cachedGetElementsByClassName = ( testNode . getElementsByClassName ( 'b' ) . length != 2 ) ;
} catch ( e ) { } ;
// Opera 9.6 getElementsByClassName doesnt detects the class if its not the first one
try {
testNode . innerHTML = '<a class="a"></a><a class="f b a"></a>' ;
brokenSecondClassNameGEBCN = ( testNode . getElementsByClassName ( 'a' ) . length != 2 ) ;
} catch ( e ) { } ;
this . brokenGEBCN = cachedGetElementsByClassName || brokenSecondClassNameGEBCN ;
// Webkit dont return selected options on querySelectorAll
try {
testNode . innerHTML = '<select><option selected="selected">a</option></select>' ;
this . brokenCheckedQSA = ( testNode . querySelectorAll ( ':checked' ) . length == 0 ) ;
} catch ( e ) { } ;
// IE returns incorrect results for attr[*^$]="" selectors on querySelectorAll
try {
testNode . innerHTML = '<a class=""></a>' ;
this . brokenEmptyAttributeQSA = ( testNode . querySelectorAll ( '[class*=""]' ) . length != 0 ) ;
} catch ( e ) { } ;
}
root . removeChild ( testNode ) ;
testNode = null ;
// hasAttribute
this . hasAttribute = ( root && this . isNativeCode ( root . hasAttribute ) ) ? function ( node , attribute ) {
return node . hasAttribute ( attribute ) ;
} : function ( node , attribute ) {
node = node . getAttributeNode ( attribute ) ;
return ! ! ( node && ( node . specified || node . nodeValue ) ) ;
} ;
// contains
// FIXME: Add specs: local.contains should be different for xml and html documents?
this . contains = ( root && this . isNativeCode ( root . contains ) ) ? function ( context , node ) {
return context . contains ( node ) ;
} : ( root && root . compareDocumentPosition ) ? function ( context , node ) {
return context === node || ! ! ( context . compareDocumentPosition ( node ) & 16 ) ;
} : function ( context , node ) {
if ( node ) do {
if ( node === context ) return true ;
} while ( ( node = node . parentNode ) ) ;
return false ;
} ;
// document order sorting
// credits to Sizzle (http://sizzlejs.com/)
this . documentSorter = ( root . compareDocumentPosition ) ? function ( a , b ) {
if ( ! a . compareDocumentPosition || ! b . compareDocumentPosition ) return 0 ;
return a . compareDocumentPosition ( b ) & 4 ? - 1 : a === b ? 0 : 1 ;
} : ( 'sourceIndex' in root ) ? function ( a , b ) {
if ( ! a . sourceIndex || ! b . sourceIndex ) return 0 ;
return a . sourceIndex - b . sourceIndex ;
} : ( document . createRange ) ? function ( a , b ) {
if ( ! a . ownerDocument || ! b . ownerDocument ) return 0 ;
var aRange = a . ownerDocument . createRange ( ) , bRange = b . ownerDocument . createRange ( ) ;
aRange . setStart ( a , 0 ) ;
aRange . setEnd ( a , 0 ) ;
bRange . setStart ( b , 0 ) ;
bRange . setEnd ( b , 0 ) ;
return aRange . compareBoundaryPoints ( Range . START_TO_END , bRange ) ;
} : null ;
this . getUID = ( this . isHTMLDocument ) ? this . getUIDHTML : this . getUIDXML ;
} ;
// Main Method
local . search = function ( context , expression , append , first ) {
var found = this . found = ( first ) ? null : ( append || [ ] ) ;
// context checks
if ( ! context ) return found ; // No context
if ( context . navigator ) context = context . document ; // Convert the node from a window to a document
else if ( ! context . nodeType ) return found ; // Reject misc junk input
// setup
var parsed , i ;
var uniques = this . uniques = { } ;
if ( this . document !== ( context . ownerDocument || context ) ) this . setDocument ( context ) ;
// should sort if there are nodes in append and if you pass multiple expressions.
// should remove duplicates if append already has items
var shouldUniques = ! ! ( append && append . length ) ;
// avoid duplicating items already in the append array
if ( shouldUniques ) for ( i = found . length ; i -- ; ) this . uniques [ this . getUID ( found [ i ] ) ] = true ;
// expression checks
if ( typeof expression == 'string' ) { // expression is a string
// Overrides
for ( i = this . overrides . length ; i -- ; ) {
var override = this . overrides [ i ] ;
if ( override . regexp . test ( expression ) ) {
var result = override . method . call ( context , expression , found , first ) ;
if ( result === false ) continue ;
if ( result === true ) return found ;
return result ;
}
}
parsed = this . Slick . parse ( expression ) ;
if ( ! parsed . length ) return found ;
} else if ( expression == null ) { // there is no expression
return found ;
} else if ( expression . Slick ) { // expression is a parsed Slick object
parsed = expression ;
} else if ( this . contains ( context . documentElement || context , expression ) ) { // expression is a node
( found ) ? found . push ( expression ) : found = expression ;
return found ;
} else { // other junk
return found ;
}
// cache elements for the nth selectors
/*<pseudo-selectors>*/ /*<nth-pseudo-selectors>*/
this . posNTH = { } ;
this . posNTHLast = { } ;
this . posNTHType = { } ;
this . posNTHTypeLast = { } ;
/*</nth-pseudo-selectors>*/ /*</pseudo-selectors>*/
// if append is null and there is only a single selector with one expression use pushArray, else use pushUID
this . push = ( ! shouldUniques && ( first || ( parsed . length == 1 && parsed . expressions [ 0 ] . length == 1 ) ) ) ? this . pushArray : this . pushUID ;
if ( found == null ) found = [ ] ;
// default engine
var j , m , n ;
var combinator , tag , id , classList , classes , attributes , pseudos ;
var currentItems , currentExpression , currentBit , lastBit , expressions = parsed . expressions ;
search : for ( i = 0 ; ( currentExpression = expressions [ i ] ) ; i ++ ) for ( j = 0 ; ( currentBit = currentExpression [ j ] ) ; j ++ ) {
combinator = 'combinator:' + currentBit . combinator ;
if ( ! this [ combinator ] ) continue search ;
tag = ( this . isXMLDocument ) ? currentBit . tag : currentBit . tag . toUpperCase ( ) ;
id = currentBit . id ;
classList = currentBit . classList ;
classes = currentBit . classes ;
attributes = currentBit . attributes ;
pseudos = currentBit . pseudos ;
lastBit = ( j === ( currentExpression . length - 1 ) ) ;
this . bitUniques = { } ;
if ( lastBit ) {
this . uniques = uniques ;
this . found = found ;
} else {
this . uniques = { } ;
this . found = [ ] ;
}
if ( j === 0 ) {
this [ combinator ] ( context , tag , id , classes , attributes , pseudos , classList ) ;
if ( first && lastBit && found . length ) break search ;
} else {
if ( first && lastBit ) for ( m = 0 , n = currentItems . length ; m < n ; m ++ ) {
this [ combinator ] ( currentItems [ m ] , tag , id , classes , attributes , pseudos , classList ) ;
if ( found . length ) break search ;
} else for ( m = 0 , n = currentItems . length ; m < n ; m ++ ) this [ combinator ] ( currentItems [ m ] , tag , id , classes , attributes , pseudos , classList ) ;
}
currentItems = this . found ;
}
if ( shouldUniques || ( parsed . expressions . length > 1 ) ) this . sort ( found ) ;
return ( first ) ? ( found [ 0 ] || null ) : found ;
} ;
// Utils
local . uidx = 1 ;
local . uidk = 'slick:uniqueid' ;
local . getUIDXML = function ( node ) {
var uid = node . getAttribute ( this . uidk ) ;
if ( ! uid ) {
uid = this . uidx ++ ;
node . setAttribute ( this . uidk , uid ) ;
}
return uid ;
} ;
local . getUIDHTML = function ( node ) {
return node . uniqueNumber || ( node . uniqueNumber = this . uidx ++ ) ;
} ;
// sort based on the setDocument documentSorter method.
local . sort = function ( results ) {
if ( ! this . documentSorter ) return results ;
results . sort ( this . documentSorter ) ;
return results ;
} ;
/*<pseudo-selectors>*/ /*<nth-pseudo-selectors>*/
local . cacheNTH = { } ;
local . matchNTH = /^([+-]?\d*)?([a-z]+)?([+-]\d+)?$/ ;
local . parseNTHArgument = function ( argument ) {
var parsed = argument . match ( this . matchNTH ) ;
if ( ! parsed ) return false ;
var special = parsed [ 2 ] || false ;
var a = parsed [ 1 ] || 1 ;
if ( a == '-' ) a = - 1 ;
var b = + parsed [ 3 ] || 0 ;
parsed =
( special == 'n' ) ? { a : a , b : b } :
( special == 'odd' ) ? { a : 2 , b : 1 } :
( special == 'even' ) ? { a : 2 , b : 0 } : { a : 0 , b : a } ;
return ( this . cacheNTH [ argument ] = parsed ) ;
} ;
local . createNTHPseudo = function ( child , sibling , positions , ofType ) {
return function ( node , argument ) {
var uid = this . getUID ( node ) ;
if ( ! this [ positions ] [ uid ] ) {
var parent = node . parentNode ;
if ( ! parent ) return false ;
var el = parent [ child ] , count = 1 ;
if ( ofType ) {
var nodeName = node . nodeName ;
do {
if ( el . nodeName !== nodeName ) continue ;
this [ positions ] [ this . getUID ( el ) ] = count ++ ;
} while ( ( el = el [ sibling ] ) ) ;
} else {
do {
if ( el . nodeType !== 1 ) continue ;
this [ positions ] [ this . getUID ( el ) ] = count ++ ;
} while ( ( el = el [ sibling ] ) ) ;
}
}
argument = argument || 'n' ;
var parsed = this . cacheNTH [ argument ] || this . parseNTHArgument ( argument ) ;
if ( ! parsed ) return false ;
var a = parsed . a , b = parsed . b , pos = this [ positions ] [ uid ] ;
if ( a == 0 ) return b == pos ;
if ( a > 0 ) {
if ( pos < b ) return false ;
} else {
if ( b < pos ) return false ;
}
return ( ( pos - b ) % a ) == 0 ;
} ;
} ;
/*</nth-pseudo-selectors>*/ /*</pseudo-selectors>*/
local . pushArray = function ( node , tag , id , classes , attributes , pseudos ) {
if ( this . matchSelector ( node , tag , id , classes , attributes , pseudos ) ) this . found . push ( node ) ;
} ;
local . pushUID = function ( node , tag , id , classes , attributes , pseudos ) {
var uid = this . getUID ( node ) ;
if ( ! this . uniques [ uid ] && this . matchSelector ( node , tag , id , classes , attributes , pseudos ) ) {
this . uniques [ uid ] = true ;
this . found . push ( node ) ;
}
} ;
local . matchNode = function ( node , selector ) {
var parsed = this . Slick . parse ( selector ) ;
if ( ! parsed ) return true ;
// simple (single) selectors
if ( parsed . length == 1 && parsed . expressions [ 0 ] . length == 1 ) {
var exp = parsed . expressions [ 0 ] [ 0 ] ;
return this . matchSelector ( node , ( this . isXMLDocument ) ? exp . tag : exp . tag . toUpperCase ( ) , exp . id , exp . classes , exp . attributes , exp . pseudos ) ;
}
var nodes = this . search ( this . document , parsed ) ;
for ( var i = 0 , item ; item = nodes [ i ++ ] ; ) {
if ( item === node ) return true ;
}
return false ;
} ;
local . matchPseudo = function ( node , name , argument ) {
var pseudoName = 'pseudo:' + name ;
if ( this [ pseudoName ] ) return this [ pseudoName ] ( node , argument ) ;
var attribute = this . getAttribute ( node , name ) ;
return ( argument ) ? argument == attribute : ! ! attribute ;
} ;
local . matchSelector = function ( node , tag , id , classes , attributes , pseudos ) {
if ( tag ) {
if ( tag == '*' ) {
if ( node . nodeName < '@' ) return false ; // Fix for comment nodes and closed nodes
} else {
if ( node . nodeName != tag ) return false ;
}
}
if ( id && node . getAttribute ( 'id' ) != id ) return false ;
var i , part , cls ;
if ( classes ) for ( i = classes . length ; i -- ; ) {
cls = ( 'className' in node ) ? node . className : node . getAttribute ( 'class' ) ;
if ( ! ( cls && classes [ i ] . regexp . test ( cls ) ) ) return false ;
}
if ( attributes ) for ( i = attributes . length ; i -- ; ) {
part = attributes [ i ] ;
if ( part . operator ? ! part . test ( this . getAttribute ( node , part . key ) ) : ! this . hasAttribute ( node , part . key ) ) return false ;
}
if ( pseudos ) for ( i = pseudos . length ; i -- ; ) {
part = pseudos [ i ] ;
if ( ! this . matchPseudo ( node , part . key , part . value ) ) return false ;
}
return true ;
} ;
var combinators = {
' ' : function ( node , tag , id , classes , attributes , pseudos , classList ) { // all child nodes, any level
var i , item , children ;
if ( this . isHTMLDocument ) {
getById : if ( id ) {
item = this . document . getElementById ( id ) ;
if ( ( ! item && node . all ) || ( this . idGetsName && item && item . getAttributeNode ( 'id' ) . nodeValue != id ) ) {
// all[id] returns all the elements with that name or id inside node
// if theres just one it will return the element, else it will be a collection
children = node . all [ id ] ;
if ( ! children ) return ;
if ( ! children [ 0 ] ) children = [ children ] ;
for ( i = 0 ; item = children [ i ++ ] ; ) if ( item . getAttributeNode ( 'id' ) . nodeValue == id ) {
this . push ( item , tag , null , classes , attributes , pseudos ) ;
break ;
}
return ;
}
if ( ! item ) {
// if the context is in the dom we return, else we will try GEBTN, breaking the getById label
if ( this . contains ( this . document . documentElement , node ) ) return ;
else break getById ;
} else if ( this . document !== node && ! this . contains ( node , item ) ) return ;
this . push ( item , tag , null , classes , attributes , pseudos ) ;
return ;
}
getByClass : if ( classes && node . getElementsByClassName && ! this . brokenGEBCN ) {
children = node . getElementsByClassName ( classList . join ( ' ' ) ) ;
if ( ! ( children && children . length ) ) break getByClass ;
for ( i = 0 ; item = children [ i ++ ] ; ) this . push ( item , tag , id , null , attributes , pseudos ) ;
return ;
}
}
getByTag : {
children = node . getElementsByTagName ( tag ) ;
if ( ! ( children && children . length ) ) break getByTag ;
if ( ! this . brokenStarGEBTN ) tag = null ;
for ( i = 0 ; item = children [ i ++ ] ; ) this . push ( item , tag , id , classes , attributes , pseudos ) ;
}
} ,
'>' : function ( node , tag , id , classes , attributes , pseudos ) { // direct children
if ( ( node = node . firstChild ) ) do {
if ( node . nodeType === 1 ) this . push ( node , tag , id , classes , attributes , pseudos ) ;
} while ( ( node = node . nextSibling ) ) ;
} ,
'+' : function ( node , tag , id , classes , attributes , pseudos ) { // next sibling
while ( ( node = node . nextSibling ) ) if ( node . nodeType === 1 ) {
this . push ( node , tag , id , classes , attributes , pseudos ) ;
break ;
}
} ,
'^' : function ( node , tag , id , classes , attributes , pseudos ) { // first child
node = node . firstChild ;
if ( node ) {
if ( node . nodeType === 1 ) this . push ( node , tag , id , classes , attributes , pseudos ) ;
else this [ 'combinator:+' ] ( node , tag , id , classes , attributes , pseudos ) ;
}
} ,
'~' : function ( node , tag , id , classes , attributes , pseudos ) { // next siblings
while ( ( node = node . nextSibling ) ) {
if ( node . nodeType !== 1 ) continue ;
var uid = this . getUID ( node ) ;
if ( this . bitUniques [ uid ] ) break ;
this . bitUniques [ uid ] = true ;
this . push ( node , tag , id , classes , attributes , pseudos ) ;
}
} ,
'++' : function ( node , tag , id , classes , attributes , pseudos ) { // next sibling and previous sibling
this [ 'combinator:+' ] ( node , tag , id , classes , attributes , pseudos ) ;
this [ 'combinator:!+' ] ( node , tag , id , classes , attributes , pseudos ) ;
} ,
'~~' : function ( node , tag , id , classes , attributes , pseudos ) { // next siblings and previous siblings
this [ 'combinator:~' ] ( node , tag , id , classes , attributes , pseudos ) ;
this [ 'combinator:!~' ] ( node , tag , id , classes , attributes , pseudos ) ;
} ,
'!' : function ( node , tag , id , classes , attributes , pseudos ) { // all parent nodes up to document
while ( ( node = node . parentNode ) ) if ( node !== this . document ) this . push ( node , tag , id , classes , attributes , pseudos ) ;
} ,
'!>' : function ( node , tag , id , classes , attributes , pseudos ) { // direct parent (one level)
node = node . parentNode ;
if ( node !== this . document ) this . push ( node , tag , id , classes , attributes , pseudos ) ;
} ,
'!+' : function ( node , tag , id , classes , attributes , pseudos ) { // previous sibling
while ( ( node = node . previousSibling ) ) if ( node . nodeType === 1 ) {
this . push ( node , tag , id , classes , attributes , pseudos ) ;
break ;
}
} ,
'!^' : function ( node , tag , id , classes , attributes , pseudos ) { // last child
node = node . lastChild ;
if ( node ) {
if ( node . nodeType === 1 ) this . push ( node , tag , id , classes , attributes , pseudos ) ;
else this [ 'combinator:!+' ] ( node , tag , id , classes , attributes , pseudos ) ;
}
} ,
'!~' : function ( node , tag , id , classes , attributes , pseudos ) { // previous siblings
while ( ( node = node . previousSibling ) ) {
if ( node . nodeType !== 1 ) continue ;
var uid = this . getUID ( node ) ;
if ( this . bitUniques [ uid ] ) break ;
this . bitUniques [ uid ] = true ;
this . push ( node , tag , id , classes , attributes , pseudos ) ;
}
}
} ;
for ( var c in combinators ) local [ 'combinator:' + c ] = combinators [ c ] ;
var pseudos = {
/*<pseudo-selectors>*/
'empty' : function ( node ) {
var child = node . firstChild ;
return ! ( child && child . nodeType == 1 ) && ! ( node . innerText || node . textContent || '' ) . length ;
} ,
'not' : function ( node , expression ) {
return ! this . matchNode ( node , expression ) ;
} ,
'contains' : function ( node , text ) {
return ( node . innerText || node . textContent || '' ) . indexOf ( text ) > - 1 ;
} ,
'first-child' : function ( node ) {
while ( ( node = node . previousSibling ) ) if ( node . nodeType === 1 ) return false ;
return true ;
} ,
'last-child' : function ( node ) {
while ( ( node = node . nextSibling ) ) if ( node . nodeType === 1 ) return false ;
return true ;
} ,
'only-child' : function ( node ) {
var prev = node ;
while ( ( prev = prev . previousSibling ) ) if ( prev . nodeType === 1 ) return false ;
var next = node ;
while ( ( next = next . nextSibling ) ) if ( next . nodeType === 1 ) return false ;
return true ;
} ,
/*<nth-pseudo-selectors>*/
'nth-child' : local . createNTHPseudo ( 'firstChild' , 'nextSibling' , 'posNTH' ) ,
'nth-last-child' : local . createNTHPseudo ( 'lastChild' , 'previousSibling' , 'posNTHLast' ) ,
'nth-of-type' : local . createNTHPseudo ( 'firstChild' , 'nextSibling' , 'posNTHType' , true ) ,
'nth-last-of-type' : local . createNTHPseudo ( 'lastChild' , 'previousSibling' , 'posNTHTypeLast' , true ) ,
'index' : function ( node , index ) {
return this [ 'pseudo:nth-child' ] ( node , '' + index + 1 ) ;
} ,
'even' : function ( node , argument ) {
return this [ 'pseudo:nth-child' ] ( node , '2n' ) ;
} ,
'odd' : function ( node , argument ) {
return this [ 'pseudo:nth-child' ] ( node , '2n+1' ) ;
} ,
/*</nth-pseudo-selectors>*/
/*<of-type-pseudo-selectors>*/
'first-of-type' : function ( node ) {
var nodeName = node . nodeName ;
while ( ( node = node . previousSibling ) ) if ( node . nodeName === nodeName ) return false ;
return true ;
} ,
'last-of-type' : function ( node ) {
var nodeName = node . nodeName ;
while ( ( node = node . nextSibling ) ) if ( node . nodeName === nodeName ) return false ;
return true ;
} ,
'only-of-type' : function ( node ) {
var prev = node , nodeName = node . nodeName ;
while ( ( prev = prev . previousSibling ) ) if ( prev . nodeName === nodeName ) return false ;
var next = node ;
while ( ( next = next . nextSibling ) ) if ( next . nodeName === nodeName ) return false ;
return true ;
} ,
/*</of-type-pseudo-selectors>*/
// custom pseudos
'enabled' : function ( node ) {
return ( node . disabled === false ) ;
} ,
'disabled' : function ( node ) {
return ( node . disabled === true ) ;
} ,
'checked' : function ( node ) {
return node . checked || node . selected ;
} ,
'focus' : function ( node ) {
return this . isHTMLDocument && this . document . activeElement === node && ( node . href || node . type || this . hasAttribute ( node , 'tabindex' ) ) ;
} ,
'root' : function ( node ) {
return ( node === this . root ) ;
} ,
'selected' : function ( node ) {
return node . selected ;
}
/*</pseudo-selectors>*/
} ;
for ( var p in pseudos ) local [ 'pseudo:' + p ] = pseudos [ p ] ;
// attributes methods
local . attributeGetters = {
'class' : function ( ) {
return ( 'className' in this ) ? this . className : this . getAttribute ( 'class' ) ;
} ,
'for' : function ( ) {
return ( 'htmlFor' in this ) ? this . htmlFor : this . getAttribute ( 'for' ) ;
} ,
'href' : function ( ) {
return ( 'href' in this ) ? this . getAttribute ( 'href' , 2 ) : this . getAttribute ( 'href' ) ;
} ,
'style' : function ( ) {
return ( this . style ) ? this . style . cssText : this . getAttribute ( 'style' ) ;
}
} ;
local . getAttribute = function ( node , name ) {
// FIXME: check if getAttribute() will get input elements on a form on this browser
// getAttribute is faster than getAttributeNode().nodeValue
var method = this . attributeGetters [ name ] ;
if ( method ) return method . call ( node ) ;
var attributeNode = node . getAttributeNode ( name ) ;
return attributeNode ? attributeNode . nodeValue : null ;
} ;
// overrides
local . overrides = [ ] ;
local . override = function ( regexp , method ) {
this . overrides . push ( { regexp : regexp , method : method } ) ;
} ;
/*<overrides>*/
/*<query-selector-override>*/
var reEmptyAttribute = /\[.*[*$^]=(?:["']{2})?\]/ ;
local . override ( /./ , function ( expression , found , first ) { //querySelectorAll override
if ( ! this . querySelectorAll || this . nodeType != 9 || ! local . isHTMLDocument || local . brokenMixedCaseQSA ||
( local . brokenCheckedQSA && expression . indexOf ( ':checked' ) > - 1 ) ||
( local . brokenEmptyAttributeQSA && reEmptyAttribute . test ( expression ) ) || Slick . disableQSA ) return false ;
var nodes , node ;
try {
if ( first ) return this . querySelector ( expression ) || null ;
else nodes = this . querySelectorAll ( expression ) ;
} catch ( error ) {
return false ;
}
var i , hasOthers = ! ! ( found . length ) ;
if ( local . starSelectsClosedQSA ) for ( i = 0 ; node = nodes [ i ++ ] ; ) {
if ( node . nodeName > '@' && ( ! hasOthers || ! local . uniques [ local . getUIDHTML ( node ) ] ) ) found . push ( node ) ;
} else for ( i = 0 ; node = nodes [ i ++ ] ; ) {
if ( ! hasOthers || ! local . uniques [ local . getUIDHTML ( node ) ] ) found . push ( node ) ;
}
if ( hasOthers ) local . sort ( found ) ;
return true ;
} ) ;
/*</query-selector-override>*/
/*<tag-override>*/
local . override ( /^[\w-]+$|^\*$/ , function ( expression , found , first ) { // tag override
var tag = expression ;
if ( tag == '*' && local . brokenStarGEBTN ) return false ;
var nodes = this . getElementsByTagName ( tag ) ;
if ( first ) return nodes [ 0 ] || null ;
var i , node , hasOthers = ! ! ( found . length ) ;
for ( i = 0 ; node = nodes [ i ++ ] ; ) {
if ( ! hasOthers || ! local . uniques [ local . getUID ( node ) ] ) found . push ( node ) ;
}
if ( hasOthers ) local . sort ( found ) ;
return true ;
} ) ;
/*</tag-override>*/
/*<class-override>*/
local . override ( /^\.[\w-]+$/ , function ( expression , found , first ) { // class override
if ( ! local . isHTMLDocument || ( ! this . getElementsByClassName && this . querySelectorAll ) ) return false ;
var nodes , node , i , hasOthers = ! ! ( found && found . length ) , className = expression . substring ( 1 ) ;
if ( this . getElementsByClassName && ! local . brokenGEBCN ) {
nodes = this . getElementsByClassName ( className ) ;
if ( first ) return nodes [ 0 ] || null ;
for ( i = 0 ; node = nodes [ i ++ ] ; ) {
if ( ! hasOthers || ! local . uniques [ local . getUIDHTML ( node ) ] ) found . push ( node ) ;
}
} else {
var matchClass = new RegExp ( '(^|\\s)' + Slick . escapeRegExp ( className ) + '(\\s|$)' ) ;
nodes = this . getElementsByTagName ( '*' ) ;
for ( i = 0 ; node = nodes [ i ++ ] ; ) {
className = node . className ;
if ( ! className || ! matchClass . test ( className ) ) continue ;
if ( first ) return node ;
if ( ! hasOthers || ! local . uniques [ local . getUIDHTML ( node ) ] ) found . push ( node ) ;
}
}
if ( hasOthers ) local . sort ( found ) ;
return ( first ) ? null : true ;
} ) ;
/*</class-override>*/
/*<id-override>*/
local . override ( /^#[\w-]+$/ , function ( expression , found , first ) { // ID override
if ( ! local . isHTMLDocument || this . nodeType != 9 ) return false ;
var id = expression . substring ( 1 ) , el = this . getElementById ( id ) ;
if ( ! el ) return found ;
if ( local . idGetsName && el . getAttributeNode ( 'id' ) . nodeValue != id ) return false ;
if ( first ) return el || null ;
var hasOthers = ! ! ( found . length ) ;
if ( ! hasOthers || ! local . uniques [ local . getUIDHTML ( el ) ] ) found . push ( el ) ;
if ( hasOthers ) local . sort ( found ) ;
return true ;
} ) ;
/*</id-override>*/
/*</overrides>*/
if ( typeof document != 'undefined' ) local . setDocument ( document ) ;
// Slick
var Slick = local . Slick = ( this . Slick || { } ) ;
Slick . version = '0.9dev' ;
// Slick finder
Slick . search = function ( context , expression , append ) {
return local . search ( context , expression , append ) ;
} ;
Slick . find = function ( context , expression ) {
return local . search ( context , expression , null , true ) ;
} ;
// Slick containment checker
Slick . contains = function ( container , node ) {
local . setDocument ( container ) ;
return local . contains ( container , node ) ;
} ;
// Slick attribute getter
Slick . getAttribute = function ( node , name ) {
return local . getAttribute ( node , name ) ;
} ;
// Slick matcher
Slick . match = function ( node , selector ) {
if ( ! ( node && selector ) ) return false ;
if ( ! selector || selector === node ) return true ;
if ( typeof selector != 'string' ) return false ;
local . setDocument ( node ) ;
return local . matchNode ( node , selector ) ;
} ;
// Slick attribute accessor
Slick . defineAttributeGetter = function ( name , fn ) {
local . attributeGetters [ name ] = fn ;
return this ;
} ;
Slick . lookupAttributeGetter = function ( name ) {
return local . attributeGetters [ name ] ;
} ;
// Slick pseudo accessor
Slick . definePseudo = function ( name , fn ) {
local [ 'pseudo:' + name ] = function ( node , argument ) {
return fn . call ( node , argument ) ;
} ;
return this ;
} ;
Slick . lookupPseudo = function ( name ) {
var pseudo = local [ 'pseudo:' + name ] ;
if ( pseudo ) return function ( argument ) {
return pseudo . call ( this , argument ) ;
} ;
return null ;
} ;
// Slick overrides accessor
Slick . override = function ( regexp , fn ) {
local . override ( regexp , fn ) ;
return this ;
} ;
Slick . isXML = local . isXML ;
Slick . uidOf = function ( node ) {
return local . getUIDHTML ( node ) ;
} ;
if ( ! this . Slick ) this . Slick = Slick ;
} ) . apply ( /*<CommonJS>*/ ( typeof exports != 'undefined' ) ? exports : /*</CommonJS>*/ this ) ;
/ *
-- -
name : Element
description : One of the most important items in MooTools . Contains the dollar function , the dollars function , and an handful of cross - browser , time - saver methods to let you easily work with HTML Elements .
license : MIT - style license .
requires : [ Window , Document , Array , String , Function , Number , Slick . Parser , Slick . Finder ]
provides : [ Element , Elements , $ , $$ , Iframe , Selectors ]
...
* /
var Element = function ( tag , props ) {
var konstructor = Element . Constructors [ tag ] ;
if ( konstructor ) return konstructor ( props ) ;
if ( typeof tag != 'string' ) return document . id ( tag ) . set ( props ) ;
if ( ! props ) props = { } ;
if ( ! tag . test ( /^[\w-]+$/ ) ) {
var parsed = Slick . parse ( tag ) . expressions [ 0 ] [ 0 ] ;
tag = ( parsed . tag == '*' ) ? 'div' : parsed . tag ;
if ( parsed . id && props . id == null ) props . id = parsed . id ;
var attributes = parsed . attributes ;
if ( attributes ) for ( var i = 0 , l = attributes . length ; i < l ; i ++ ) {
var attr = attributes [ i ] ;
if ( attr . value != null && attr . operator == '=' && props [ attr . key ] == null )
props [ attr . key ] = attr . value ;
}
if ( parsed . classList && props [ 'class' ] == null ) props [ 'class' ] = parsed . classList . join ( ' ' ) ;
}
return document . newElement ( tag , props ) ;
} ;
if ( Browser . Element ) Element . prototype = Browser . Element . prototype ;
new Type ( 'Element' , Element ) . mirror ( function ( name ) {
if ( Array . prototype [ name ] ) return ;
var obj = { } ;
obj [ name ] = function ( ) {
var results = [ ] , args = arguments , elements = true ;
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
var element = this [ i ] , result = results [ i ] = element [ name ] . apply ( element , args ) ;
elements = ( elements && typeOf ( result ) == 'element' ) ;
}
return ( elements ) ? new Elements ( results ) : results ;
} ;
Elements . implement ( obj ) ;
} ) ;
if ( ! Browser . Element ) {
Element . parent = Object ;
Element . Prototype = { '$family' : Function . from ( 'element' ) . hide ( ) } ;
Element . mirror ( function ( name , method ) {
Element . Prototype [ name ] = method ;
} ) ;
}
Element . Constructors = { } ;
var IFrame = new Type ( 'IFrame' , function ( ) {
var params = Array . link ( arguments , {
properties : Type . isObject ,
iframe : function ( obj ) {
return ( obj != null ) ;
}
} ) ;
var props = params . properties || { } , iframe ;
if ( params . iframe ) iframe = document . id ( params . iframe ) ;
var onload = props . onload || function ( ) { } ;
delete props . onload ;
props . id = props . name = [ props . id , props . name , iframe ? ( iframe . id || iframe . name ) : 'IFrame_' + String . uniqueID ( ) ] . pick ( ) ;
iframe = new Element ( iframe || 'iframe' , props ) ;
var onLoad = function ( ) {
onload . call ( iframe . contentWindow ) ;
} ;
if ( window . frames [ props . id ] ) onLoad ( ) ;
else iframe . addListener ( 'load' , onLoad ) ;
return iframe ;
} ) ;
var Elements = this . Elements = function ( nodes ) {
if ( nodes && nodes . length ) {
var uniques = { } , node ;
for ( var i = 0 ; node = nodes [ i ++ ] ; ) {
var uid = Slick . uidOf ( node ) ;
if ( ! uniques [ uid ] ) {
uniques [ uid ] = true ;
this . push ( node ) ;
}
}
}
} ;
Elements . prototype = { length : 0 } ;
Elements . parent = Array ;
new Type ( 'Elements' , Elements ) . implement ( {
filter : function ( filter , bind ) {
if ( ! filter ) return this ;
return new Elements ( Array . filter ( this , ( typeOf ( filter ) == 'string' ) ? function ( item ) {
return item . match ( filter ) ;
} : filter , bind ) ) ;
} . protect ( ) ,
push : function ( ) {
var length = this . length ;
for ( var i = 0 , l = arguments . length ; i < l ; i ++ ) {
var item = document . id ( arguments [ i ] ) ;
if ( item ) this [ length ++ ] = item ;
}
return ( this . length = length ) ;
} . protect ( ) ,
concat : function ( ) {
var newElements = new Elements ( this ) ;
for ( var i = 0 , l = arguments . length ; i < l ; i ++ ) {
var item = arguments [ i ] ;
if ( Type . isEnumerable ( item ) ) newElements . append ( item ) ;
else newElements . push ( item ) ;
}
return newElements ;
} . protect ( ) ,
append : function ( collection ) {
for ( var i = 0 , l = collection . length ; i < l ; i ++ ) this . push ( collection [ i ] ) ;
return this ;
} . protect ( ) ,
empty : function ( ) {
while ( this . length ) delete this [ -- this . length ] ;
return this ;
} . protect ( )
} ) ;
( function ( ) {
// FF, IE
var splice = Array . prototype . splice , object = { '0' : 0 , '1' : 1 , length : 2 } ;
splice . call ( object , 1 , 1 ) ;
if ( object [ 1 ] == 1 ) Elements . implement ( 'splice' , function ( ) {
var length = this . length ;
splice . apply ( this , arguments ) ;
while ( length >= this . length ) delete this [ length -- ] ;
return this ;
} . protect ( ) ) ;
Elements . implement ( Array . prototype ) ;
Array . mirror ( Elements ) ;
/*<ltIE8>*/
var createElementAcceptsHTML ;
try {
var x = document . createElement ( '<input name=x>' ) ;
createElementAcceptsHTML = ( x . name == 'x' ) ;
} catch ( e ) { }
var escapeQuotes = function ( html ) {
return ( '' + html ) . replace ( /&/g , '&' ) . replace ( /"/g , '"' ) ;
} ;
/*</ltIE8>*/
Document . implement ( {
newElement : function ( tag , props ) {
if ( props && props . checked != null ) props . defaultChecked = props . checked ;
/*<ltIE8>*/ // Fix for readonly name and type properties in IE < 8
if ( createElementAcceptsHTML && props ) {
tag = '<' + tag ;
if ( props . name ) tag += ' name="' + escapeQuotes ( props . name ) + '"' ;
if ( props . type ) tag += ' type="' + escapeQuotes ( props . type ) + '"' ;
tag += '>' ;
delete props . name ;
delete props . type ;
}
/*</ltIE8>*/
return this . id ( this . createElement ( tag ) ) . set ( props ) ;
}
} ) ;
} ) ( ) ;
Document . implement ( {
newTextNode : function ( text ) {
return this . createTextNode ( text ) ;
} ,
getDocument : function ( ) {
return this ;
} ,
getWindow : function ( ) {
return this . window ;
} ,
id : ( function ( ) {
var types = {
string : function ( id , nocash , doc ) {
id = Slick . find ( doc , '#' + id . replace ( /(\W)/g , '\\$1' ) ) ;
return ( id ) ? types . element ( id , nocash ) : null ;
} ,
element : function ( el , nocash ) {
$uid ( el ) ;
if ( ! nocash && ! el . $family && ! ( /^object|embed$/i ) . test ( el . tagName ) ) {
Object . append ( el , Element . Prototype ) ;
}
return el ;
} ,
object : function ( obj , nocash , doc ) {
if ( obj . toElement ) return types . element ( obj . toElement ( doc ) , nocash ) ;
return null ;
}
} ;
types . textnode = types . whitespace = types . window = types . document = function ( zero ) {
return zero ;
} ;
return function ( el , nocash , doc ) {
if ( el && el . $family && el . uid ) return el ;
var type = typeOf ( el ) ;
return ( types [ type ] ) ? types [ type ] ( el , nocash , doc || document ) : null ;
} ;
} ) ( )
} ) ;
if ( window . $ == null ) Window . implement ( '$' , function ( el , nc ) {
return document . id ( el , nc , this . document ) ;
} ) ;
Window . implement ( {
getDocument : function ( ) {
return this . document ;
} ,
getWindow : function ( ) {
return this ;
}
} ) ;
[ Document , Element ] . invoke ( 'implement' , {
getElements : function ( expression ) {
return Slick . search ( this , expression , new Elements ) ;
} ,
getElement : function ( expression ) {
return document . id ( Slick . find ( this , expression ) ) ;
}
} ) ;
if ( window . $$ == null ) Window . implement ( '$$' , function ( selector ) {
if ( arguments . length == 1 ) {
if ( typeof selector == 'string' ) return Slick . search ( this . document , selector , new Elements ) ;
else if ( Type . isEnumerable ( selector ) ) return new Elements ( selector ) ;
}
return new Elements ( arguments ) ;
} ) ;
( function ( ) {
var collected = { } , storage = { } ;
var props = { input : 'checked' , option : 'selected' , textarea : 'value' } ;
var get = function ( uid ) {
return ( storage [ uid ] || ( storage [ uid ] = { } ) ) ;
} ;
var clean = function ( item ) {
if ( item . removeEvents ) item . removeEvents ( ) ;
if ( item . clearAttributes ) item . clearAttributes ( ) ;
var uid = item . uid ;
if ( uid != null ) {
delete collected [ uid ] ;
delete storage [ uid ] ;
}
return item ;
} ;
var camels = [ 'defaultValue' , 'accessKey' , 'cellPadding' , 'cellSpacing' , 'colSpan' , 'frameBorder' , 'maxLength' , 'readOnly' ,
'rowSpan' , 'tabIndex' , 'useMap'
] ;
var bools = [ 'compact' , 'nowrap' , 'ismap' , 'declare' , 'noshade' , 'checked' , 'disabled' , 'readOnly' , 'multiple' , 'selected' ,
'noresize' , 'defer'
] ;
var attributes = {
'html' : 'innerHTML' ,
'class' : 'className' ,
'for' : 'htmlFor' ,
'text' : ( function ( ) {
var temp = document . createElement ( 'div' ) ;
return ( temp . innerText == null ) ? 'textContent' : 'innerText' ;
} ) ( )
} ;
var readOnly = [ 'type' ] ;
var expandos = [ 'value' , 'defaultValue' ] ;
var uriAttrs = /^(?:href|src|usemap)$/i ;
bools = bools . associate ( bools ) ;
camels = camels . associate ( camels . map ( String . toLowerCase ) ) ;
readOnly = readOnly . associate ( readOnly ) ;
Object . append ( attributes , expandos . associate ( expandos ) ) ;
var inserters = {
before : function ( context , element ) {
var parent = element . parentNode ;
if ( parent ) parent . insertBefore ( context , element ) ;
} ,
after : function ( context , element ) {
var parent = element . parentNode ;
if ( parent ) parent . insertBefore ( context , element . nextSibling ) ;
} ,
bottom : function ( context , element ) {
element . appendChild ( context ) ;
} ,
top : function ( context , element ) {
element . insertBefore ( context , element . firstChild ) ;
}
} ;
inserters . inside = inserters . bottom ;
var injectCombinator = function ( expression , combinator ) {
if ( ! expression ) return combinator ;
expression = Slick . parse ( expression ) ;
var expressions = expression . expressions ;
for ( var i = expressions . length ; i -- ; )
expressions [ i ] [ 0 ] . combinator = combinator ;
return expression ;
} ;
Element . implement ( {
set : function ( prop , value ) {
var property = Element . Properties [ prop ] ;
( property && property . set ) ? property . set . call ( this , value ) : this . setProperty ( prop , value ) ;
} . overloadSetter ( ) ,
get : function ( prop ) {
var property = Element . Properties [ prop ] ;
return ( property && property . get ) ? property . get . apply ( this ) : this . getProperty ( prop ) ;
} . overloadGetter ( ) ,
erase : function ( prop ) {
var property = Element . Properties [ prop ] ;
( property && property . erase ) ? property . erase . apply ( this ) : this . removeProperty ( prop ) ;
return this ;
} ,
setProperty : function ( attribute , value ) {
attribute = camels [ attribute ] || attribute ;
if ( value == null ) return this . removeProperty ( attribute ) ;
var key = attributes [ attribute ] ;
( key ) ? this [ key ] = value :
( bools [ attribute ] ) ? this [ attribute ] = ! ! value : this . setAttribute ( attribute , '' + value ) ;
return this ;
} ,
setProperties : function ( attributes ) {
for ( var attribute in attributes ) this . setProperty ( attribute , attributes [ attribute ] ) ;
return this ;
} ,
getProperty : function ( attribute ) {
attribute = camels [ attribute ] || attribute ;
var key = attributes [ attribute ] || readOnly [ attribute ] ;
return ( key ) ? this [ key ] :
( bools [ attribute ] ) ? ! ! this [ attribute ] :
( uriAttrs . test ( attribute ) ? this . getAttribute ( attribute , 2 ) :
( key = this . getAttributeNode ( attribute ) ) ? key . nodeValue : null ) || null ;
} ,
getProperties : function ( ) {
var args = Array . from ( arguments ) ;
return args . map ( this . getProperty , this ) . associate ( args ) ;
} ,
removeProperty : function ( attribute ) {
attribute = camels [ attribute ] || attribute ;
var key = attributes [ attribute ] ;
( key ) ? this [ key ] = '' :
( bools [ attribute ] ) ? this [ attribute ] = false : this . removeAttribute ( attribute ) ;
return this ;
} ,
removeProperties : function ( ) {
Array . each ( arguments , this . removeProperty , this ) ;
return this ;
} ,
hasClass : function ( className ) {
return this . className . clean ( ) . contains ( className , ' ' ) ;
} ,
addClass : function ( className ) {
if ( ! this . hasClass ( className ) ) this . className = ( this . className + ' ' + className ) . clean ( ) ;
return this ;
} ,
removeClass : function ( className ) {
this . className = this . className . replace ( new RegExp ( '(^|\\s)' + className + '(?:\\s|$)' ) , '$1' ) ;
return this ;
} ,
toggleClass : function ( className , force ) {
if ( force == null ) force = ! this . hasClass ( className ) ;
return ( force ) ? this . addClass ( className ) : this . removeClass ( className ) ;
} ,
adopt : function ( ) {
var parent = this , fragment , elements = Array . flatten ( arguments ) , length = elements . length ;
if ( length > 1 ) parent = fragment = document . createDocumentFragment ( ) ;
for ( var i = 0 ; i < length ; i ++ ) {
var element = document . id ( elements [ i ] , true ) ;
if ( element ) parent . appendChild ( element ) ;
}
if ( fragment ) this . appendChild ( fragment ) ;
return this ;
} ,
appendText : function ( text , where ) {
return this . grab ( this . getDocument ( ) . newTextNode ( text ) , where ) ;
} ,
grab : function ( el , where ) {
inserters [ where || 'bottom' ] ( document . id ( el , true ) , this ) ;
return this ;
} ,
inject : function ( el , where ) {
inserters [ where || 'bottom' ] ( this , document . id ( el , true ) ) ;
return this ;
} ,
replaces : function ( el ) {
el = document . id ( el , true ) ;
el . parentNode . replaceChild ( this , el ) ;
return this ;
} ,
wraps : function ( el , where ) {
el = document . id ( el , true ) ;
return this . replaces ( el ) . grab ( el , where ) ;
} ,
getPrevious : function ( expression ) {
return document . id ( Slick . find ( this , injectCombinator ( expression , '!~' ) ) ) ;
} ,
getAllPrevious : function ( expression ) {
return Slick . search ( this , injectCombinator ( expression , '!~' ) , new Elements ) ;
} ,
getNext : function ( expression ) {
return document . id ( Slick . find ( this , injectCombinator ( expression , '~' ) ) ) ;
} ,
getAllNext : function ( expression ) {
return Slick . search ( this , injectCombinator ( expression , '~' ) , new Elements ) ;
} ,
getFirst : function ( expression ) {
return document . id ( Slick . search ( this , injectCombinator ( expression , '>' ) ) [ 0 ] ) ;
} ,
getLast : function ( expression ) {
return document . id ( Slick . search ( this , injectCombinator ( expression , '>' ) ) . getLast ( ) ) ;
} ,
getParent : function ( expression ) {
return document . id ( Slick . find ( this , injectCombinator ( expression , '!' ) ) ) ;
} ,
getParents : function ( expression ) {
return Slick . search ( this , injectCombinator ( expression , '!' ) , new Elements ) ;
} ,
getSiblings : function ( expression ) {
return Slick . search ( this , injectCombinator ( expression , '~~' ) , new Elements ) ;
} ,
getChildren : function ( expression ) {
return Slick . search ( this , injectCombinator ( expression , '>' ) , new Elements ) ;
} ,
getWindow : function ( ) {
return this . ownerDocument . window ;
} ,
getDocument : function ( ) {
return this . ownerDocument ;
} ,
getElementById : function ( id ) {
return document . id ( Slick . find ( this , '#' + ( '' + id ) . replace ( /(\W)/g , '\\$1' ) ) ) ;
} ,
getSelected : function ( ) {
this . selectedIndex ; // Safari 3.2.1
return new Elements ( Array . from ( this . options ) . filter ( function ( option ) {
return option . selected ;
} ) ) ;
} ,
toQueryString : function ( ) {
var queryString = [ ] ;
this . getElements ( 'input, select, textarea' ) . each ( function ( el ) {
var type = el . type ;
if ( ! el . name || el . disabled || type == 'submit' || type == 'reset' || type == 'file' || type == 'image' ) return ;
var value = ( el . get ( 'tag' ) == 'select' ) ? el . getSelected ( ) . map ( function ( opt ) {
// IE
return document . id ( opt ) . get ( 'value' ) ;
} ) : ( ( type == 'radio' || type == 'checkbox' ) && ! el . checked ) ? null : el . get ( 'value' ) ;
Array . from ( value ) . each ( function ( val ) {
if ( typeof val != 'undefined' ) queryString . push ( encodeURIComponent ( el . name ) + '=' + encodeURIComponent ( val ) ) ;
} ) ;
} ) ;
return queryString . join ( '&' ) ;
} ,
clone : function ( contents , keepid ) {
contents = contents !== false ;
var clone = this . cloneNode ( contents ) ;
var clean = function ( node , element ) {
if ( ! keepid ) node . removeAttribute ( 'id' ) ;
if ( Browser . ie ) {
node . clearAttributes ( ) ;
node . mergeAttributes ( element ) ;
node . removeAttribute ( 'uid' ) ;
if ( node . options ) {
var no = node . options , eo = element . options ;
for ( var j = no . length ; j -- ; ) no [ j ] . selected = eo [ j ] . selected ;
}
}
var prop = props [ element . tagName . toLowerCase ( ) ] ;
if ( prop && element [ prop ] ) node [ prop ] = element [ prop ] ;
} ;
var i ;
if ( contents ) {
var ce = clone . getElementsByTagName ( '*' ) , te = this . getElementsByTagName ( '*' ) ;
for ( i = ce . length ; i -- ; ) clean ( ce [ i ] , te [ i ] ) ;
}
clean ( clone , this ) ;
if ( Browser . ie ) {
var ts = this . getElementsByTagName ( 'object' ) ,
cs = clone . getElementsByTagName ( 'object' ) ,
tl = ts . length , cl = cs . length ;
for ( i = 0 ; i < tl && i < cl ; i ++ )
cs [ i ] . outerHTML = ts [ i ] . outerHTML ;
}
return document . id ( clone ) ;
} ,
destroy : function ( ) {
var children = clean ( this ) . getElementsByTagName ( '*' ) ;
Array . each ( children , clean ) ;
Element . dispose ( this ) ;
return null ;
} ,
empty : function ( ) {
Array . from ( this . childNodes ) . each ( Element . dispose ) ;
return this ;
} ,
dispose : function ( ) {
return ( this . parentNode ) ? this . parentNode . removeChild ( this ) : this ;
} ,
match : function ( expression ) {
return ! expression || Slick . match ( this , expression ) ;
}
} ) ;
var contains = { contains : function ( element ) {
return Slick . contains ( this , element ) ;
} } ;
if ( ! document . contains ) Document . implement ( contains ) ;
if ( ! document . createElement ( 'div' ) . contains ) Element . implement ( contains ) ;
[ Element , Window , Document ] . invoke ( 'implement' , {
addListener : function ( type , fn ) {
if ( type == 'unload' ) {
var old = fn , self = this ;
fn = function ( ) {
self . removeListener ( 'unload' , fn ) ;
old ( ) ;
} ;
} else {
collected [ this . uid ] = this ;
}
if ( this . addEventListener ) this . addEventListener ( type , fn , false ) ;
else this . attachEvent ( 'on' + type , fn ) ;
return this ;
} ,
removeListener : function ( type , fn ) {
if ( this . removeEventListener ) this . removeEventListener ( type , fn , false ) ;
else this . detachEvent ( 'on' + type , fn ) ;
return this ;
} ,
retrieve : function ( property , dflt ) {
var storage = get ( this . uid ) , prop = storage [ property ] ;
if ( dflt != null && prop == null ) prop = storage [ property ] = dflt ;
return prop != null ? prop : null ;
} ,
store : function ( property , value ) {
var storage = get ( this . uid ) ;
storage [ property ] = value ;
return this ;
} ,
eliminate : function ( property ) {
var storage = get ( this . uid ) ;
delete storage [ property ] ;
return this ;
}
} ) ;
// IE purge
if ( window . attachEvent && ! window . addEventListener ) window . addListener ( 'unload' , function ( ) {
Object . each ( collected , clean ) ;
if ( window . CollectGarbage ) CollectGarbage ( ) ;
} ) ;
} ) ( ) ;
Element . Properties = { } ;
Element . Properties . style = {
set : function ( style ) {
this . style . cssText = style ;
} ,
get : function ( ) {
return this . style . cssText ;
} ,
erase : function ( ) {
this . style . cssText = '' ;
}
} ;
Element . Properties . tag = {
get : function ( ) {
return this . tagName . toLowerCase ( ) ;
}
} ;
( function ( maxLength ) {
if ( maxLength != null ) Element . Properties . maxlength = Element . Properties . maxLength = {
get : function ( ) {
var maxlength = this . getAttribute ( 'maxLength' ) ;
return maxlength == maxLength ? null : maxlength ;
}
} ;
} ) ( document . createElement ( 'input' ) . getAttribute ( 'maxLength' ) ) ;
Element . Properties . html = ( function ( ) {
var tableTest = Function . attempt ( function ( ) {
var table = document . createElement ( 'table' ) ;
table . innerHTML = '<tr><td></td></tr>' ;
} ) ;
var wrapper = document . createElement ( 'div' ) ;
var translations = {
table : [ 1 , '<table>' , '</table>' ] ,
select : [ 1 , '<select>' , '</select>' ] ,
tbody : [ 2 , '<table><tbody>' , '</tbody></table>' ] ,
tr : [ 3 , '<table><tbody><tr>' , '</tr></tbody></table>' ]
} ;
translations . thead = translations . tfoot = translations . tbody ;
var html = {
set : function ( ) {
var html = Array . flatten ( arguments ) . join ( '' ) ;
var wrap = ( ! tableTest && translations [ this . get ( 'tag' ) ] ) ;
if ( wrap ) {
var first = wrapper ;
first . innerHTML = wrap [ 1 ] + html + wrap [ 2 ] ;
for ( var i = wrap [ 0 ] ; i -- ; ) first = first . firstChild ;
this . empty ( ) . adopt ( first . childNodes ) ;
} else {
this . innerHTML = html ;
}
}
} ;
html . erase = html . set ;
return html ;
} ) ( ) ;
/ *
-- -
name : Element . Style
description : Contains methods for interacting with the styles of Elements in a fashionable way .
license : MIT - style license .
requires : Element
provides : Element . Style
...
* /
( function ( ) {
var html = document . html ;
Element . Properties . styles = { set : function ( styles ) {
this . setStyles ( styles ) ;
} } ;
var hasOpacity = ( html . style . opacity != null ) ;
var reAlpha = /alpha\(opacity=([\d.]+)\)/i ;
var setOpacity = function ( element , opacity ) {
if ( ! element . currentStyle || ! element . currentStyle . hasLayout ) element . style . zoom = 1 ;
if ( hasOpacity ) {
element . style . opacity = opacity ;
} else {
opacity = ( opacity == 1 ) ? '' : 'alpha(opacity=' + opacity * 100 + ')' ;
var filter = element . style . filter || element . getComputedStyle ( 'filter' ) || '' ;
element . style . filter = filter . test ( reAlpha ) ? filter . replace ( reAlpha , opacity ) : filter + opacity ;
}
} ;
Element . Properties . opacity = {
set : function ( opacity ) {
var visibility = this . style . visibility ;
if ( opacity == 0 && visibility != 'hidden' ) this . style . visibility = 'hidden' ;
else if ( opacity != 0 && visibility != 'visible' ) this . style . visibility = 'visible' ;
setOpacity ( this , opacity ) ;
} ,
get : ( hasOpacity ) ? function ( ) {
var opacity = this . style . opacity || this . getComputedStyle ( 'opacity' ) ;
return ( opacity == '' ) ? 1 : opacity ;
} : function ( ) {
var opacity , filter = ( this . style . filter || this . getComputedStyle ( 'filter' ) ) ;
if ( filter ) opacity = filter . match ( reAlpha ) ;
return ( opacity == null || filter == null ) ? 1 : ( opacity [ 1 ] / 100 ) ;
}
} ;
var floatName = ( html . style . cssFloat == null ) ? 'styleFloat' : 'cssFloat' ;
Element . implement ( {
getComputedStyle : function ( property ) {
if ( this . currentStyle ) return this . currentStyle [ property . camelCase ( ) ] ;
var defaultView = Element . getDocument ( this ) . defaultView ,
computed = defaultView ? defaultView . getComputedStyle ( this , null ) : null ;
return ( computed ) ? computed . getPropertyValue ( ( property == floatName ) ? 'float' : property . hyphenate ( ) ) : null ;
} ,
setOpacity : function ( value ) {
setOpacity ( this , value ) ;
return this ;
} ,
getOpacity : function ( ) {
return this . get ( 'opacity' ) ;
} ,
setStyle : function ( property , value ) {
switch ( property ) {
case 'opacity' : return this . set ( 'opacity' , parseFloat ( value ) ) ;
case 'float' : property = floatName ;
}
property = property . camelCase ( ) ;
if ( typeOf ( value ) != 'string' ) {
var map = ( Element . Styles [ property ] || '@' ) . split ( ' ' ) ;
value = Array . from ( value ) . map ( function ( val , i ) {
if ( ! map [ i ] ) return '' ;
return ( typeOf ( val ) == 'number' ) ? map [ i ] . replace ( '@' , Math . round ( val ) ) : val ;
} ) . join ( ' ' ) ;
} else if ( value == String ( Number ( value ) ) ) {
value = Math . round ( value ) ;
}
this . style [ property ] = value ;
return this ;
} ,
getStyle : function ( property ) {
switch ( property ) {
case 'opacity' : return this . get ( 'opacity' ) ;
case 'float' : property = floatName ;
}
property = property . camelCase ( ) ;
var result = this . style [ property ] ;
if ( ! result || property == 'zIndex' ) {
result = [ ] ;
for ( var style in Element . ShortStyles ) {
if ( property != style ) continue ;
for ( var s in Element . ShortStyles [ style ] ) result . push ( this . getStyle ( s ) ) ;
return result . join ( ' ' ) ;
}
result = this . getComputedStyle ( property ) ;
}
if ( result ) {
result = String ( result ) ;
var color = result . match ( /rgba?\([\d\s,]+\)/ ) ;
if ( color ) result = result . replace ( color [ 0 ] , color [ 0 ] . rgbToHex ( ) ) ;
}
if ( Browser . opera || ( Browser . ie && isNaN ( parseFloat ( result ) ) ) ) {
if ( property . test ( /^(height|width)$/ ) ) {
var values = ( property == 'width' ) ? [ 'left' , 'right' ] : [ 'top' , 'bottom' ] , size = 0 ;
values . each ( function ( value ) {
size += this . getStyle ( 'border-' + value + '-width' ) . toInt ( ) + this . getStyle ( 'padding-' + value ) . toInt ( ) ;
} , this ) ;
return this [ 'offset' + property . capitalize ( ) ] - size + 'px' ;
}
if ( Browser . opera && String ( result ) . indexOf ( 'px' ) != - 1 ) return result ;
if ( property . test ( /(border(.+)Width|margin|padding)/ ) ) return '0px' ;
}
return result ;
} ,
setStyles : function ( styles ) {
for ( var style in styles ) this . setStyle ( style , styles [ style ] ) ;
return this ;
} ,
getStyles : function ( ) {
var result = { } ;
Array . flatten ( arguments ) . each ( function ( key ) {
result [ key ] = this . getStyle ( key ) ;
} , this ) ;
return result ;
}
} ) ;
Element . Styles = {
left : '@px' , top : '@px' , bottom : '@px' , right : '@px' ,
width : '@px' , height : '@px' , maxWidth : '@px' , maxHeight : '@px' , minWidth : '@px' , minHeight : '@px' ,
backgroundColor : 'rgb(@, @, @)' , backgroundPosition : '@px @px' , color : 'rgb(@, @, @)' ,
fontSize : '@px' , letterSpacing : '@px' , lineHeight : '@px' , clip : 'rect(@px @px @px @px)' ,
margin : '@px @px @px @px' , padding : '@px @px @px @px' , border : '@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)' ,
borderWidth : '@px @px @px @px' , borderStyle : '@ @ @ @' , borderColor : 'rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)' ,
zIndex : '@' , 'zoom' : '@' , fontWeight : '@' , textIndent : '@px' , opacity : '@'
} ;
Element . ShortStyles = { margin : { } , padding : { } , border : { } , borderWidth : { } , borderStyle : { } , borderColor : { } } ;
[ 'Top' , 'Right' , 'Bottom' , 'Left' ] . each ( function ( direction ) {
var Short = Element . ShortStyles ;
var All = Element . Styles ;
[ 'margin' , 'padding' ] . each ( function ( style ) {
var sd = style + direction ;
Short [ style ] [ sd ] = All [ sd ] = '@px' ;
} ) ;
var bd = 'border' + direction ;
Short . border [ bd ] = All [ bd ] = '@px @ rgb(@, @, @)' ;
var bdw = bd + 'Width' , bds = bd + 'Style' , bdc = bd + 'Color' ;
Short [ bd ] = { } ;
Short . borderWidth [ bdw ] = Short [ bd ] [ bdw ] = All [ bdw ] = '@px' ;
Short . borderStyle [ bds ] = Short [ bd ] [ bds ] = All [ bds ] = '@' ;
Short . borderColor [ bdc ] = Short [ bd ] [ bdc ] = All [ bdc ] = 'rgb(@, @, @)' ;
} ) ;
} ) ( ) ;
/ *
-- -
name : Object
description : Object generic methods
license : MIT - style license .
requires : Type
provides : [ Object , Hash ]
...
* /
Object . extend ( {
subset : function ( object , keys ) {
var results = { } ;
for ( var i = 0 , l = keys . length ; i < l ; i ++ ) {
var k = keys [ i ] ;
results [ k ] = object [ k ] ;
}
return results ;
} ,
map : function ( object , fn , bind ) {
var results = { } ;
for ( var key in object ) {
if ( object . hasOwnProperty ( key ) ) results [ key ] = fn . call ( bind , object [ key ] , key , object ) ;
}
return results ;
} ,
filter : function ( object , fn , bind ) {
var results = { } ;
Object . each ( object , function ( value , key ) {
if ( fn . call ( bind , value , key , object ) ) results [ key ] = value ;
} ) ;
return results ;
} ,
every : function ( object , fn , bind ) {
for ( var key in object ) {
if ( object . hasOwnProperty ( key ) && ! fn . call ( bind , object [ key ] , key ) ) return false ;
}
return true ;
} ,
some : function ( object , fn , bind ) {
for ( var key in object ) {
if ( object . hasOwnProperty ( key ) && fn . call ( bind , object [ key ] , key ) ) return true ;
}
return false ;
} ,
keys : function ( object ) {
var keys = [ ] ;
for ( var key in object ) {
if ( object . hasOwnProperty ( key ) ) keys . push ( key ) ;
}
return keys ;
} ,
values : function ( object ) {
var values = [ ] ;
for ( var key in object ) {
if ( object . hasOwnProperty ( key ) ) values . push ( object [ key ] ) ;
}
return values ;
} ,
getLength : function ( object ) {
return Object . keys ( object ) . length ;
} ,
keyOf : function ( object , value ) {
for ( var key in object ) {
if ( object . hasOwnProperty ( key ) && object [ key ] === value ) return key ;
}
return null ;
} ,
contains : function ( object , value ) {
return Object . keyOf ( object , value ) != null ;
} ,
toQueryString : function ( object , base ) {
var queryString = [ ] ;
Object . each ( object , function ( value , key ) {
if ( base ) key = base + '[' + key + ']' ;
var result ;
switch ( typeOf ( value ) ) {
case 'object' : result = Object . toQueryString ( value , key ) ; break ;
case 'array' :
var qs = { } ;
value . each ( function ( val , i ) {
qs [ i ] = val ;
} ) ;
result = Object . toQueryString ( qs , key ) ;
break ;
default : result = key + '=' + encodeURIComponent ( value ) ;
}
if ( value != null ) queryString . push ( result ) ;
} ) ;
return queryString . join ( '&' ) ;
}
} ) ;
/ *
-- -
name : Request
description : Powerful all purpose Request Class . Uses XMLHTTPRequest .
license : MIT - style license .
requires : [ Object , Element , Chain , Events , Options , Browser ]
provides : Request
...
* /
( function ( ) {
var progressSupport = ( 'onprogress' in new Browser . Request ) ;
var Request = this . Request = new Class ( {
Implements : [ Chain , Events , Options ] ,
options : { / *
onRequest : function ( ) { } ,
onLoadstart : function ( event , xhr ) { } ,
onProgress : function ( event , xhr ) { } ,
onComplete : function ( ) { } ,
onCancel : function ( ) { } ,
onSuccess : function ( responseText , responseXML ) { } ,
onFailure : function ( xhr ) { } ,
onException : function ( headerName , value ) { } ,
onTimeout : function ( ) { } ,
user : '' ,
password : '' , * /
url : '' ,
data : '' ,
headers : {
'X-Requested-With' : 'XMLHttpRequest' ,
'Accept' : 'text/javascript, text/html, application/xml, text/xml, */*'
} ,
async : true ,
format : false ,
method : 'post' ,
link : 'ignore' ,
isSuccess : null ,
emulation : true ,
urlEncoded : true ,
encoding : 'utf-8' ,
evalScripts : false ,
evalResponse : false ,
timeout : 0 ,
noCache : false
} ,
initialize : function ( options ) {
this . xhr = new Browser . Request ( ) ;
this . setOptions ( options ) ;
this . headers = this . options . headers ;
} ,
onStateChange : function ( ) {
var xhr = this . xhr ;
if ( xhr . readyState != 4 || ! this . running ) return ;
this . running = false ;
this . status = 0 ;
Function . attempt ( function ( ) {
var status = xhr . status ;
this . status = ( status == 1223 ) ? 204 : status ;
} . bind ( this ) ) ;
xhr . onreadystatechange = function ( ) { } ;
clearTimeout ( this . timer ) ;
this . response = { text : this . xhr . responseText || '' , xml : this . xhr . responseXML } ;
if ( this . options . isSuccess . call ( this , this . status ) )
this . success ( this . response . text , this . response . xml ) ;
else
this . failure ( ) ;
} ,
isSuccess : function ( ) {
var status = this . status ;
return ( status >= 200 && status < 300 ) ;
} ,
isRunning : function ( ) {
return ! ! this . running ;
} ,
processScripts : function ( text ) {
if ( this . options . evalResponse || ( /(ecma|java)script/ ) . test ( this . getHeader ( 'Content-type' ) ) ) return Browser . exec ( text ) ;
return text . stripScripts ( this . options . evalScripts ) ;
} ,
success : function ( text , xml ) {
this . onSuccess ( this . processScripts ( text ) , xml ) ;
} ,
onSuccess : function ( ) {
this . fireEvent ( 'complete' , arguments ) . fireEvent ( 'success' , arguments ) . callChain ( ) ;
} ,
failure : function ( ) {
this . onFailure ( ) ;
} ,
onFailure : function ( ) {
this . fireEvent ( 'complete' ) . fireEvent ( 'failure' , this . xhr ) ;
} ,
loadstart : function ( event ) {
this . fireEvent ( 'loadstart' , [ event , this . xhr ] ) ;
} ,
progress : function ( event ) {
this . fireEvent ( 'progress' , [ event , this . xhr ] ) ;
} ,
timeout : function ( ) {
this . fireEvent ( 'timeout' , this . xhr ) ;
} ,
setHeader : function ( name , value ) {
this . headers [ name ] = value ;
return this ;
} ,
getHeader : function ( name ) {
return Function . attempt ( function ( ) {
return this . xhr . getResponseHeader ( name ) ;
} . bind ( this ) ) ;
} ,
check : function ( ) {
if ( ! this . running ) return true ;
switch ( this . options . link ) {
case 'cancel' : this . cancel ( ) ; return true ;
case 'chain' : this . chain ( this . caller . pass ( arguments , this ) ) ; return false ;
}
return false ;
} ,
send : function ( options ) {
if ( ! this . check ( options ) ) return this ;
this . options . isSuccess = this . options . isSuccess || this . isSuccess ;
this . running = true ;
var type = typeOf ( options ) ;
if ( type == 'string' || type == 'element' ) options = { data : options } ;
var old = this . options ;
options = Object . append ( { data : old . data , url : old . url , method : old . method } , options ) ;
var data = options . data , url = String ( options . url ) , method = options . method . toLowerCase ( ) ;
switch ( typeOf ( data ) ) {
case 'element' : data = document . id ( data ) . toQueryString ( ) ; break ;
case 'object' : case 'hash' : data = Object . toQueryString ( data ) ;
}
if ( this . options . format ) {
var format = 'format=' + this . options . format ;
data = ( data ) ? format + '&' + data : format ;
}
if ( this . options . emulation && ! [ 'get' , 'post' ] . contains ( method ) ) {
var _ method = '_method=' + method ;
data = ( data ) ? _ method + '&' + data : _ method ;
method = 'post' ;
}
if ( this . options . urlEncoded && [ 'post' , 'put' ] . contains ( method ) ) {
var encoding = ( this . options . encoding ) ? '; charset=' + this . options . encoding : '' ;
this . headers [ 'Content-type' ] = 'application/x-www-form-urlencoded' + encoding ;
}
if ( ! url ) url = document . location . pathname ;
var trimPosition = url . lastIndexOf ( '/' ) ;
if ( trimPosition > - 1 && ( trimPosition = url . indexOf ( '#' ) ) > - 1 ) url = url . substr ( 0 , trimPosition ) ;
if ( this . options . noCache )
url += ( url . contains ( '?' ) ? '&' : '?' ) + String . uniqueID ( ) ;
if ( data && method == 'get' ) {
url += ( url . contains ( '?' ) ? '&' : '?' ) + data ;
data = null ;
}
var xhr = this . xhr ;
if ( progressSupport ) {
xhr . onloadstart = this . loadstart . bind ( this ) ;
xhr . onprogress = this . progress . bind ( this ) ;
}
xhr . open ( method . toUpperCase ( ) , url , this . options . async , this . options . user , this . options . password ) ;
if ( this . options . user && 'withCredentials' in xhr ) xhr . withCredentials = true ;
xhr . onreadystatechange = this . onStateChange . bind ( this ) ;
Object . each ( this . headers , function ( value , key ) {
try {
xhr . setRequestHeader ( key , value ) ;
} catch ( e ) {
this . fireEvent ( 'exception' , [ key , value ] ) ;
}
} , this ) ;
this . fireEvent ( 'request' ) ;
xhr . send ( data ) ;
if ( ! this . options . async ) this . onStateChange ( ) ;
if ( this . options . timeout ) this . timer = this . timeout . delay ( this . options . timeout , this ) ;
return this ;
} ,
cancel : function ( ) {
if ( ! this . running ) return this ;
this . running = false ;
var xhr = this . xhr ;
xhr . abort ( ) ;
clearTimeout ( this . timer ) ;
xhr . onreadystatechange = xhr . onprogress = xhr . onloadstart = function ( ) { } ;
this . xhr = new Browser . Request ( ) ;
this . fireEvent ( 'cancel' ) ;
return this ;
}
} ) ;
var methods = { } ;
[ 'get' , 'post' , 'put' , 'delete' , 'GET' , 'POST' , 'PUT' , 'DELETE' ] . each ( function ( method ) {
methods [ method ] = function ( data ) {
return this . send ( {
data : data ,
method : method
} ) ;
} ;
} ) ;
Request . implement ( methods ) ;
Element . Properties . send = {
set : function ( options ) {
var send = this . get ( 'send' ) . cancel ( ) ;
send . setOptions ( options ) ;
return this ;
} ,
get : function ( ) {
var send = this . retrieve ( 'send' ) ;
if ( ! send ) {
send = new Request ( {
data : this , link : 'cancel' , method : this . get ( 'method' ) || 'post' , url : this . get ( 'action' )
} ) ;
this . store ( 'send' , send ) ;
}
return send ;
}
} ;
Element . implement ( {
send : function ( url ) {
var sender = this . get ( 'send' ) ;
sender . send ( { data : this , url : url || sender . options . url } ) ;
return this ;
}
} ) ;
} ) ( ) ;
/ *
-- -
name : JSON
description : JSON encoder and decoder .
license : MIT - style license .
See Also : < http : //www.json.org/>
requires : [ Array , String , Number , Function ]
provides : JSON
...
* /
if ( ! this . JSON ) this . JSON = { } ;
Object . append ( JSON , {
$specialChars : { '\b' : '\\b' , '\t' : '\\t' , '\n' : '\\n' , '\f' : '\\f' , '\r' : '\\r' , '"' : '\\"' , '\\' : '\\\\' } ,
$replaceChars : function ( chr ) {
return JSON . $specialChars [ chr ] || '\\u00' + Math . floor ( chr . charCodeAt ( ) / 16 ) . toString ( 16 ) + ( chr . charCodeAt ( ) % 16 ) . toString ( 16 ) ;
} ,
encode : function ( obj ) {
switch ( typeOf ( obj ) ) {
case 'string' :
return '"' + obj . replace ( /[\x00-\x1f\\"]/g , JSON . $replaceChars ) + '"' ;
case 'array' :
return '[' + String ( obj . map ( JSON . encode ) . clean ( ) ) + ']' ;
case 'object' : case 'hash' :
var string = [ ] ;
Object . each ( obj , function ( value , key ) {
var json = JSON . encode ( value ) ;
if ( json ) string . push ( JSON . encode ( key ) + ':' + json ) ;
} ) ;
return '{' + string + '}' ;
case 'number' : case 'boolean' : return String ( obj ) ;
case 'null' : return 'null' ;
}
return null ;
} ,
decode : function ( string , secure ) {
if ( typeOf ( string ) != 'string' || ! string . length ) return null ;
if ( secure && ! ( /^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/ ) . test ( string . replace ( /\\./g , '@' ) . replace ( /"[^"\\\n\r]*"/g , '' ) ) ) return null ;
return eval ( '(' + string + ')' ) ;
}
} ) ;
/ *
-- -
name : Request . JSON
description : Extends the basic Request Class with additional methods for sending and receiving JSON data .
license : MIT - style license .
requires : [ Request , JSON ]
provides : Request . JSON
...
* /
Request . JSON = new Class ( {
Extends : Request ,
options : {
secure : true
} ,
initialize : function ( options ) {
this . parent ( options ) ;
Object . append ( this . headers , {
'Accept' : 'application/json' ,
'X-Request' : 'JSON'
} ) ;
} ,
success : function ( text ) {
var secure = this . options . secure ;
var json = this . response . json = Function . attempt ( function ( ) {
return JSON . decode ( text , secure ) ;
} ) ;
if ( json == null ) this . onFailure ( ) ;
else this . onSuccess ( json , text ) ;
}
} ) ;
/ *
-- -
name : Event
description : Contains the Event Class , to make the event object cross - browser .
license : MIT - style license .
requires : [ Window , Document , Array , Function , String , Object ]
provides : Event
...
* /
var Event = new Type ( 'Event' , function ( event , win ) {
if ( ! win ) win = window ;
var doc = win . document ;
event = event || win . event ;
if ( event . $extended ) return event ;
this . $extended = true ;
var type = event . type ,
target = event . target || event . srcElement ,
page = { } ,
client = { } ;
while ( target && target . nodeType == 3 ) target = target . parentNode ;
if ( type . indexOf ( 'key' ) != - 1 ) {
var code = event . which || event . keyCode ;
var key = Object . keyOf ( Event . Keys , code ) ;
if ( type == 'keydown' ) {
var fKey = code - 111 ;
if ( fKey > 0 && fKey < 13 ) key = 'f' + fKey ;
}
if ( ! key ) key = String . fromCharCode ( code ) . toLowerCase ( ) ;
} else if ( type . test ( /click|mouse|menu/i ) ) {
doc = ( ! doc . compatMode || doc . compatMode == 'CSS1Compat' ) ? doc . html : doc . body ;
page = {
x : ( event . pageX != null ) ? event . pageX : event . clientX + doc . scrollLeft ,
y : ( event . pageY != null ) ? event . pageY : event . clientY + doc . scrollTop
} ;
client = {
x : ( event . pageX != null ) ? event . pageX - win . pageXOffset : event . clientX ,
y : ( event . pageY != null ) ? event . pageY - win . pageYOffset : event . clientY
} ;
if ( type . test ( /DOMMouseScroll|mousewheel/ ) ) {
var wheel = ( event . wheelDelta ) ? event . wheelDelta / 120 : - ( event . detail || 0 ) / 3 ;
}
var rightClick = ( event . which == 3 ) || ( event . button == 2 ) ,
related = null ;
if ( type . test ( /over|out/ ) ) {
related = event . relatedTarget || event [ ( type == 'mouseover' ? 'from' : 'to' ) + 'Element' ] ;
var testRelated = function ( ) {
while ( related && related . nodeType == 3 ) related = related . parentNode ;
return true ;
} ;
var hasRelated = ( Browser . firefox2 ) ? testRelated . attempt ( ) : testRelated ( ) ;
related = ( hasRelated ) ? related : null ;
}
} else if ( type . test ( /gesture|touch/i ) ) {
this . rotation = event . rotation ;
this . scale = event . scale ;
this . targetTouches = event . targetTouches ;
this . changedTouches = event . changedTouches ;
var touches = this . touches = event . touches ;
if ( touches && touches [ 0 ] ) {
var touch = touches [ 0 ] ;
page = { x : touch . pageX , y : touch . pageY } ;
client = { x : touch . clientX , y : touch . clientY } ;
}
}
return Object . append ( this , {
event : event ,
type : type ,
page : page ,
client : client ,
rightClick : rightClick ,
wheel : wheel ,
relatedTarget : document . id ( related ) ,
target : document . id ( target ) ,
code : code ,
key : key ,
shift : event . shiftKey ,
control : event . ctrlKey ,
alt : event . altKey ,
meta : event . metaKey
} ) ;
} ) ;
Event . Keys = {
'enter' : 13 ,
'up' : 38 ,
'down' : 40 ,
'left' : 37 ,
'right' : 39 ,
'esc' : 27 ,
'space' : 32 ,
'backspace' : 8 ,
'tab' : 9 ,
'delete' : 46
} ;
Event . implement ( {
stop : function ( ) {
return this . stopPropagation ( ) . preventDefault ( ) ;
} ,
stopPropagation : function ( ) {
if ( this . event . stopPropagation ) this . event . stopPropagation ( ) ;
else this . event . cancelBubble = true ;
return this ;
} ,
preventDefault : function ( ) {
if ( this . event . preventDefault ) this . event . preventDefault ( ) ;
else this . event . returnValue = false ;
return this ;
}
} ) ;
/ *
-- -
name : Element . Event
description : Contains Element methods for dealing with events . This file also includes mouseenter and mouseleave custom Element Events .
license : MIT - style license .
requires : [ Element , Event ]
provides : Element . Event
...
* /
( function ( ) {
Element . Properties . events = { set : function ( events ) {
this . addEvents ( events ) ;
} } ;
[ Element , Window , Document ] . invoke ( 'implement' , {
addEvent : function ( type , fn ) {
var events = this . retrieve ( 'events' , { } ) ;
if ( ! events [ type ] ) events [ type ] = { keys : [ ] , values : [ ] } ;
if ( events [ type ] . keys . contains ( fn ) ) return this ;
events [ type ] . keys . push ( fn ) ;
var realType = type ,
custom = Element . Events [ type ] ,
condition = fn ,
self = this ;
if ( custom ) {
if ( custom . onAdd ) custom . onAdd . call ( this , fn ) ;
if ( custom . condition ) {
condition = function ( event ) {
if ( custom . condition . call ( this , event ) ) return fn . call ( this , event ) ;
return true ;
} ;
}
realType = custom . base || realType ;
}
var defn = function ( ) {
return fn . call ( self ) ;
} ;
var nativeEvent = Element . NativeEvents [ realType ] ;
if ( nativeEvent ) {
if ( nativeEvent == 2 ) {
defn = function ( event ) {
event = new Event ( event , self . getWindow ( ) ) ;
if ( condition . call ( self , event ) === false ) event . stop ( ) ;
} ;
}
this . addListener ( realType , defn ) ;
}
events [ type ] . values . push ( defn ) ;
return this ;
} ,
removeEvent : function ( type , fn ) {
var events = this . retrieve ( 'events' ) ;
if ( ! events || ! events [ type ] ) return this ;
var list = events [ type ] ;
var index = list . keys . indexOf ( fn ) ;
if ( index == - 1 ) return this ;
var value = list . values [ index ] ;
delete list . keys [ index ] ;
delete list . values [ index ] ;
var custom = Element . Events [ type ] ;
if ( custom ) {
if ( custom . onRemove ) custom . onRemove . call ( this , fn ) ;
type = custom . base || type ;
}
return ( Element . NativeEvents [ type ] ) ? this . removeListener ( type , value ) : this ;
} ,
addEvents : function ( events ) {
for ( var event in events ) this . addEvent ( event , events [ event ] ) ;
return this ;
} ,
removeEvents : function ( events ) {
var type ;
if ( typeOf ( events ) == 'object' ) {
for ( type in events ) this . removeEvent ( type , events [ type ] ) ;
return this ;
}
var attached = this . retrieve ( 'events' ) ;
if ( ! attached ) return this ;
if ( ! events ) {
for ( type in attached ) this . removeEvents ( type ) ;
this . eliminate ( 'events' ) ;
} else if ( attached [ events ] ) {
attached [ events ] . keys . each ( function ( fn ) {
this . removeEvent ( events , fn ) ;
} , this ) ;
delete attached [ events ] ;
}
return this ;
} ,
fireEvent : function ( type , args , delay ) {
var events = this . retrieve ( 'events' ) ;
if ( ! events || ! events [ type ] ) return this ;
args = Array . from ( args ) ;
events [ type ] . keys . each ( function ( fn ) {
if ( delay ) fn . delay ( delay , this , args ) ;
else fn . apply ( this , args ) ;
} , this ) ;
return this ;
} ,
cloneEvents : function ( from , type ) {
from = document . id ( from ) ;
var events = from . retrieve ( 'events' ) ;
if ( ! events ) return this ;
if ( ! type ) {
for ( var eventType in events ) this . cloneEvents ( from , eventType ) ;
} else if ( events [ type ] ) {
events [ type ] . keys . each ( function ( fn ) {
this . addEvent ( type , fn ) ;
} , this ) ;
}
return this ;
}
} ) ;
// IE9
try {
if ( typeof HTMLElement != 'undefined' )
HTMLElement . prototype . fireEvent = Element . prototype . fireEvent ;
} catch ( e ) { }
Element . NativeEvents = {
click : 2 , dblclick : 2 , mouseup : 2 , mousedown : 2 , contextmenu : 2 , //mouse buttons
mousewheel : 2 , DOMMouseScroll : 2 , //mouse wheel
mouseover : 2 , mouseout : 2 , mousemove : 2 , selectstart : 2 , selectend : 2 , //mouse movement
keydown : 2 , keypress : 2 , keyup : 2 , //keyboard
orientationchange : 2 , // mobile
touchstart : 2 , touchmove : 2 , touchend : 2 , touchcancel : 2 , // touch
gesturestart : 2 , gesturechange : 2 , gestureend : 2 , // gesture
focus : 2 , blur : 2 , change : 2 , reset : 2 , select : 2 , submit : 2 , //form elements
load : 2 , unload : 1 , beforeunload : 2 , resize : 1 , move : 1 , DOMContentLoaded : 1 , readystatechange : 1 , //window
error : 1 , abort : 1 , scroll : 1 //misc
} ;
var check = function ( event ) {
var related = event . relatedTarget ;
if ( related == null ) return true ;
if ( ! related ) return false ;
return ( related != this && related . prefix != 'xul' && typeOf ( this ) != 'document' && ! this . contains ( related ) ) ;
} ;
Element . Events = {
mouseenter : {
base : 'mouseover' ,
condition : check
} ,
mouseleave : {
base : 'mouseout' ,
condition : check
} ,
mousewheel : {
base : ( Browser . firefox ) ? 'DOMMouseScroll' : 'mousewheel'
}
} ;
} ) ( ) ;
/ *
-- -
name : DOMReady
description : Contains the custom event domready .
license : MIT - style license .
requires : [ Browser , Element , Element . Event ]
provides : [ DOMReady , DomReady ]
...
* /
( function ( window , document ) {
var ready ,
loaded ,
checks = [ ] ,
shouldPoll ,
timer ,
isFramed = true ;
// Thanks to Rich Dougherty <http://www.richdougherty.com/>
try {
isFramed = window . frameElement != null ;
} catch ( e ) { }
var domready = function ( ) {
clearTimeout ( timer ) ;
if ( ready ) return ;
Browser . loaded = ready = true ;
document . removeListener ( 'DOMContentLoaded' , domready ) . removeListener ( 'readystatechange' , check ) ;
document . fireEvent ( 'domready' ) ;
window . fireEvent ( 'domready' ) ;
} ;
var check = function ( ) {
for ( var i = checks . length ; i -- ; ) if ( checks [ i ] ( ) ) {
domready ( ) ;
return true ;
}
return false ;
} ;
var poll = function ( ) {
clearTimeout ( timer ) ;
if ( ! check ( ) ) timer = setTimeout ( poll , 10 ) ;
} ;
document . addListener ( 'DOMContentLoaded' , domready ) ;
// doScroll technique by Diego Perini http://javascript.nwbox.com/IEContentLoaded/
var testElement = document . createElement ( 'div' ) ;
if ( testElement . doScroll && ! isFramed ) {
checks . push ( function ( ) {
try {
testElement . doScroll ( ) ;
return true ;
} catch ( e ) { }
return false ;
} ) ;
shouldPoll = true ;
}
if ( document . readyState ) checks . push ( function ( ) {
var state = document . readyState ;
return ( state == 'loaded' || state == 'complete' ) ;
} ) ;
if ( 'onreadystatechange' in document ) document . addListener ( 'readystatechange' , check ) ;
else shouldPoll = true ;
if ( shouldPoll ) poll ( ) ;
Element . Events . domready = {
onAdd : function ( fn ) {
if ( ready ) fn . call ( this ) ;
}
} ;
// Make sure that domready fires before load
Element . Events . load = {
base : 'load' ,
onAdd : function ( fn ) {
if ( loaded && this == window ) fn . call ( this ) ;
} ,
condition : function ( ) {
if ( this == window ) {
domready ( ) ;
delete Element . Events . load ;
}
return true ;
}
} ;
// This is based on the custom load event
window . addEvent ( 'load' , function ( ) {
loaded = true ;
} ) ;
} ) ( window , document ) ;