2008-07-05 22:28:49 +02:00
/ *
2011-06-24 15:38:56 +02:00
-- -
MooTools : the javascript framework
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
web build :
- http : //mootools.net/core/7c56cfef9dddcf170a5d68e3fb61cfd7
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
packager build :
- packager build Core / Core Core / Array Core / String Core / Number Core / Function Core / Object Core / Event Core / Browser Core / Class Core / Class . Extras Core / Slick . Parser Core / Slick . Finder Core / Element Core / Element . Style Core / Element . Event Core / Element . Dimensions Core / Fx Core / Fx . CSS Core / Fx . Tween Core / Fx . Morph Core / Fx . Transitions Core / Request Core / Request . HTML Core / Request . JSON Core / Cookie Core / JSON Core / DOMReady Core / Swiff
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
/ *
-- -
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 ]
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
...
2008-07-05 22:28:49 +02:00
* /
2011-06-24 15:38:56 +02:00
( function ( ) {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . MooTools = {
version : '1.3.2' ,
build : 'c9f1ff10e9e7facb65e9481049ed1b450959d587'
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
// typeOf, instanceOf
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var typeOf = this . typeOf = function ( item ) {
if ( item == null ) return 'null' ;
if ( item . $family ) return item . $family ( ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
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' ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
return typeof item ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
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 ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
// 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 ;
2008-07-05 22:28:49 +02:00
} ;
} ;
2011-06-24 15:38:56 +02:00
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 ;
2008-07-05 22:28:49 +02:00
} ;
} ;
2011-06-24 15:38:56 +02:00
Function . prototype . extend = function ( key , value ) {
this [ key ] = value ;
} . overloadSetter ( ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Function . prototype . implement = function ( key , value ) {
this . prototype [ key ] = value ;
} . overloadSetter ( ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
// From
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var slice = Array . prototype . slice ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Function . from = function ( item ) {
return ( typeOf ( item ) == 'function' ) ? item : function ( ) {
return item ;
} ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
Array . from = function ( item ) {
if ( item == null ) return [ ] ;
return ( Type . isEnumerable ( item ) && typeof item != 'string' ) ? ( typeOf ( item ) == 'array' ) ? item : slice . call ( item ) : [ item ] ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
Number . from = function ( item ) {
var number = parseFloat ( item ) ;
return isFinite ( number ) ? number : null ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
String . from = function ( item ) {
return item + '' ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
// hide, protect
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Function . implement ( {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
hide : function ( ) {
this . $hidden = true ;
return this ;
} ,
protect : function ( ) {
this . $protected = true ;
return this ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
} ) ;
// 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 ( ) ;
//<1.2compat>
object . type = typeCheck ;
//</1.2compat>
2008-07-05 22:28:49 +02:00
}
}
2011-06-24 15:38:56 +02:00
if ( object == null ) return null ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
object . extend ( this ) ;
object . $constructor = Type ;
object . prototype . $constructor = object ;
return object ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
var toString = Object . prototype . toString ;
Type . isEnumerable = function ( item ) {
return ( item != null && typeof item . length == 'number' && toString . call ( item ) != '[object Function]' ) ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
var hooks = { } ;
var hooksOf = function ( object ) {
var type = typeOf ( object . prototype ) ;
return hooks [ type ] || ( hooks [ type ] = [ ] ) ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
var implement = function ( name , method ) {
if ( method && method . $hidden ) return ;
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 ) ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
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 ) ) ;
} ) ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
var extend = function ( name , method ) {
if ( method && method . $hidden ) return ;
var previous = this [ name ] ;
if ( previous == null || ! previous . $protected ) this [ name ] = method ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
Type . implement ( {
implement : implement . overloadSetter ( ) ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
extend : extend . overloadSetter ( ) ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
alias : function ( name , existing ) {
implement . call ( this , name , this . prototype [ existing ] ) ;
} . overloadSetter ( ) ,
mirror : function ( hook ) {
hooksOf ( this ) . push ( hook ) ;
2008-07-05 22:28:49 +02:00
return this ;
}
} ) ;
2011-06-24 15:38:56 +02:00
new Type ( 'Type' , Type ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
// 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 ( ) ;
2008-07-05 22:28:49 +02:00
}
}
2011-06-24 15:38:56 +02:00
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 ) ;
2008-07-05 22:28:49 +02:00
} ) ;
2011-06-24 15:38:56 +02:00
new Type ( 'Boolean' , Boolean ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
// 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
var hasOwnProperty = Object . prototype . hasOwnProperty ;
Object . extend ( 'forEach' , function ( object , fn , bind ) {
for ( var key in object ) {
if ( hasOwnProperty . call ( object , key ) ) fn . call ( bind , object [ key ] , key , object ) ;
}
} ) ;
Object . each = Object . forEach ;
2008-07-05 22:28:49 +02:00
Array . implement ( {
forEach : function ( fn , bind ) {
2011-06-24 15:38:56 +02:00
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 ;
2008-07-05 22:28:49 +02:00
}
} ) ;
2011-06-24 15:38:56 +02:00
// Array & Object cloning, Object merging and appending
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var cloneOf = function ( item ) {
switch ( typeOf ( item ) ) {
case 'array' : return item . clone ( ) ;
case 'object' : return Object . clone ( item ) ;
default : return item ;
2008-07-05 22:28:49 +02:00
}
} ;
2011-06-24 15:38:56 +02:00
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 ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
Object . extend ( {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
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 ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
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 ;
}
2008-07-05 22:28:49 +02:00
} ) ;
2011-06-24 15:38:56 +02:00
// Object-less types
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
[ 'Object' , 'WhiteSpace' , 'TextNode' , 'Collection' , 'Arguments' ] . each ( function ( name ) {
new Type ( name ) ;
} ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
// Unique ID
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var UID = Date . now ( ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
String . extend ( 'uniqueID' , function ( ) {
return ( UID ++ ) . toString ( 36 ) ;
} ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
//<1.2compat>
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var Hash = this . Hash = new Type ( 'Hash' , function ( object ) {
if ( typeOf ( object ) == 'hash' ) object = Object . clone ( object . getClean ( ) ) ;
for ( var key in object ) this [ key ] = object [ key ] ;
return this ;
} ) ;
Hash . implement ( {
forEach : function ( fn , bind ) {
Object . forEach ( this , fn , bind ) ;
} ,
getClean : function ( ) {
var clean = { } ;
for ( var key in this ) {
if ( this . hasOwnProperty ( key ) ) clean [ key ] = this [ key ] ;
}
return clean ;
} ,
getLength : function ( ) {
var length = 0 ;
for ( var key in this ) {
if ( this . hasOwnProperty ( key ) ) length ++ ;
}
return length ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
} ) ;
Hash . alias ( 'each' , 'forEach' ) ;
Object . type = Type . isObject ;
var Native = this . Native = function ( properties ) {
return new Type ( properties . name , properties . initialize ) ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
Native . type = Type . type ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Native . implement = function ( objects , methods ) {
for ( var i = 0 ; i < objects . length ; i ++ ) objects [ i ] . implement ( methods ) ;
return Native ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
var arrayType = Array . type ;
Array . type = function ( item ) {
return instanceOf ( item , Array ) || arrayType ( item ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . $A = function ( item ) {
return Array . from ( item ) . slice ( ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . $arguments = function ( i ) {
return function ( ) {
return arguments [ i ] ;
} ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . $chk = function ( obj ) {
return ! ! ( obj || obj === 0 ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . $clear = function ( timer ) {
clearTimeout ( timer ) ;
clearInterval ( timer ) ;
return null ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . $defined = function ( obj ) {
return ( obj != null ) ;
} ;
this . $each = function ( iterable , fn , bind ) {
var type = typeOf ( iterable ) ;
( ( type == 'arguments' || type == 'collection' || type == 'array' || type == 'elements' ) ? Array : Object ) . each ( iterable , fn , bind ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . $empty = function ( ) { } ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . $extend = function ( original , extended ) {
return Object . append ( original , extended ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . $H = function ( object ) {
return new Hash ( object ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . $merge = function ( ) {
var args = Array . slice ( arguments ) ;
args . unshift ( { } ) ;
return Object . merge . apply ( null , args ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . $lambda = Function . from ;
this . $mixin = Object . merge ;
this . $random = Number . random ;
this . $splat = Array . from ;
this . $time = Date . now ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . $type = function ( object ) {
var type = typeOf ( object ) ;
if ( type == 'elements' ) return 'array' ;
return ( type == 'null' ) ? false : type ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . $unlink = function ( object ) {
switch ( typeOf ( object ) ) {
case 'object' : return Object . clone ( object ) ;
case 'array' : return Array . clone ( object ) ;
case 'hash' : return new Hash ( object ) ;
default : return object ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
//</1.2compat>
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
} ) ( ) ;
2008-07-05 22:28:49 +02:00
/ *
2011-06-24 15:38:56 +02:00
-- -
name : Array
description : Contains Array Prototypes like each , contains , and erase .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
license : MIT - style license .
requires : Type
provides : Array
...
2008-07-05 22:28:49 +02:00
* /
Array . implement ( {
2011-06-24 15:38:56 +02:00
/*<!ES5>*/
2008-07-05 22:28:49 +02:00
every : function ( fn , bind ) {
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
2011-06-24 15:38:56 +02:00
if ( ( i in this ) && ! fn . call ( bind , this [ i ] , i , this ) ) return false ;
2008-07-05 22:28:49 +02:00
}
return true ;
} ,
filter : function ( fn , bind ) {
var results = [ ] ;
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
2011-06-24 15:38:56 +02:00
if ( ( i in this ) && fn . call ( bind , this [ i ] , i , this ) ) results . push ( this [ i ] ) ;
2008-07-05 22:28:49 +02:00
}
return results ;
} ,
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 = [ ] ;
2011-06-24 15:38:56 +02:00
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
if ( i in this ) results [ i ] = fn . call ( bind , this [ i ] , i , this ) ;
}
2008-07-05 22:28:49 +02:00
return results ;
} ,
some : function ( fn , bind ) {
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
2011-06-24 15:38:56 +02:00
if ( ( i in this ) && fn . call ( bind , this [ i ] , i , this ) ) return true ;
2008-07-05 22:28:49 +02:00
}
return false ;
} ,
2011-06-24 15:38:56 +02:00
/*</!ES5>*/
clean : function ( ) {
return this . filter ( function ( item ) {
return item != null ;
} ) ;
} ,
invoke : function ( methodName ) {
var args = Array . slice ( arguments , 1 ) ;
return this . map ( function ( item ) {
return item [ methodName ] . apply ( item , args ) ;
} ) ;
} ,
2008-07-05 22:28:49 +02:00
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 ;
} ,
2011-06-24 15:38:56 +02:00
append : function ( array ) {
this . push . apply ( this , array ) ;
2008-07-05 22:28:49 +02:00
return this ;
} ,
getLast : function ( ) {
return ( this . length ) ? this [ this . length - 1 ] : null ;
} ,
getRandom : function ( ) {
2011-06-24 15:38:56 +02:00
return ( this . length ) ? this [ Number . random ( 0 , this . length - 1 ) ] : null ;
2008-07-05 22:28:49 +02:00
} ,
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 ) {
2011-06-24 15:38:56 +02:00
for ( var i = this . length ; i -- ; ) {
2008-07-05 22:28:49 +02:00
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 ++ ) {
2011-06-24 15:38:56 +02:00
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 ] ) ;
2008-07-05 22:28:49 +02:00
}
return array ;
} ,
2011-06-24 15:38:56 +02:00
pick : function ( ) {
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
if ( this [ i ] != null ) return this [ i ] ;
}
return null ;
} ,
2008-07-05 22:28:49 +02:00
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 ( '' ) ;
}
} ) ;
2011-06-24 15:38:56 +02:00
//<1.2compat>
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Array . alias ( 'extend' , 'append' ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var $pick = function ( ) {
return Array . from ( arguments ) . pick ( ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
//</1.2compat>
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
/ *
-- -
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
name : String
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
description : Contains String Prototypes like camelCase , capitalize , test , and toInt .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
license : MIT - style license .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
requires : Type
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
provides : String
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
...
2008-07-05 22:28:49 +02:00
* /
String . implement ( {
test : function ( regex , params ) {
2011-06-24 15:38:56 +02:00
return ( ( typeOf ( regex ) == 'regexp' ) ? regex : new RegExp ( '' + regex , params ) ) . test ( this ) ;
2008-07-05 22:28:49 +02:00
} ,
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 ) {
2011-06-24 15:38:56 +02:00
return this . replace ( regexp || ( /\\?\{([^{}]+)\}/g ) , function ( match , name ) {
2008-07-05 22:28:49 +02:00
if ( match . charAt ( 0 ) == '\\' ) return match . slice ( 1 ) ;
2011-06-24 15:38:56 +02:00
return ( object [ name ] != null ) ? object [ name ] : '' ;
2008-07-05 22:28:49 +02:00
} ) ;
}
} ) ;
2011-06-24 15:38:56 +02:00
2008-07-05 22:28:49 +02:00
/ *
2011-06-24 15:38:56 +02:00
-- -
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
name : Number
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
description : Contains Number Prototypes like limit , round , times , and ceil .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
license : MIT - style license .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
requires : Type
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
provides : Number
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
...
* /
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Number . implement ( {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
limit : function ( min , max ) {
return Math . min ( max , Math . max ( min , this ) ) ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
round : function ( precision ) {
precision = Math . pow ( 10 , precision || 0 ) . toFixed ( precision < 0 ? - precision : 0 ) ;
return Math . round ( this * precision ) / precision ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
times : function ( fn , bind ) {
for ( var i = 0 ; i < this ; i ++ ) fn . call ( bind , i , this ) ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
toFloat : function ( ) {
return parseFloat ( this ) ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
toInt : function ( base ) {
return parseInt ( this , base || 10 ) ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
} ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Number . alias ( 'each' , 'times' ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
( 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' ] ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
/ *
-- -
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
name : Function
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
description : Contains Function Prototypes like create , bind , pass , and delay .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
license : MIT - style license .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
requires : Type
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
provides : Function
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
...
* /
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Function . extend ( {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
attempt : function ( ) {
for ( var i = 0 , l = arguments . length ; i < l ; i ++ ) {
try {
return arguments [ i ] ( ) ;
} catch ( e ) { }
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
return null ;
2008-07-05 22:28:49 +02:00
}
} ) ;
2011-06-24 15:38:56 +02:00
Function . implement ( {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
attempt : function ( args , bind ) {
try {
return this . apply ( bind , Array . from ( args ) ) ;
} catch ( e ) { }
return null ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
/*<!ES5>*/
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 ) ;
} ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
/*</!ES5>*/
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
pass : function ( args , bind ) {
var self = this ;
if ( args != null ) args = Array . from ( args ) ;
return function ( ) {
return self . apply ( bind , args || arguments ) ;
} ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
delay : function ( delay , bind , args ) {
return setTimeout ( this . pass ( ( args == null ? [ ] : args ) , bind ) , delay ) ;
} ,
periodical : function ( periodical , bind , args ) {
return setInterval ( this . pass ( ( args == null ? [ ] : args ) , bind ) , periodical ) ;
2008-07-05 22:28:49 +02:00
}
} ) ;
2011-06-24 15:38:56 +02:00
//<1.2compat>
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
delete Function . prototype . bind ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Function . implement ( {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
create : function ( options ) {
var self = this ;
options = options || { } ;
return function ( event ) {
var args = options . arguments ;
args = ( args != null ) ? Array . from ( args ) : Array . slice ( arguments , ( options . event ) ? 1 : 0 ) ;
if ( options . event ) args = [ event || window . event ] . extend ( args ) ;
var returns = function ( ) {
return self . apply ( options . bind || null , args ) ;
} ;
if ( options . delay ) return setTimeout ( returns , options . delay ) ;
if ( options . periodical ) return setInterval ( returns , options . periodical ) ;
if ( options . attempt ) return Function . attempt ( returns ) ;
return returns ( ) ;
} ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
bind : function ( bind , args ) {
var self = this ;
if ( args != null ) args = Array . from ( args ) ;
return function ( ) {
return self . apply ( bind , args || arguments ) ;
} ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
bindWithEvent : function ( bind , args ) {
var self = this ;
if ( args != null ) args = Array . from ( args ) ;
return function ( event ) {
return self . apply ( bind , ( args == null ) ? arguments : [ event ] . concat ( args ) ) ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
run : function ( args , bind ) {
return this . apply ( bind , Array . from ( args ) ) ;
2008-07-05 22:28:49 +02:00
}
} ) ;
2011-06-24 15:38:56 +02:00
var $try = Function . attempt ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
//</1.2compat>
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
/ *
-- -
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
name : Object
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
description : Object generic methods
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
license : MIT - style license .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
requires : Type
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
provides : [ Object , Hash ]
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
...
* /
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
( function ( ) {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var hasOwnProperty = Object . prototype . hasOwnProperty ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Object . extend ( {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
subset : function ( object , keys ) {
var results = { } ;
for ( var i = 0 , l = keys . length ; i < l ; i ++ ) {
var k = keys [ i ] ;
if ( k in object ) results [ k ] = object [ k ] ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
return results ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
map : function ( object , fn , bind ) {
var results = { } ;
for ( var key in object ) {
if ( hasOwnProperty . call ( object , key ) ) results [ key ] = fn . call ( bind , object [ key ] , key , object ) ;
}
return results ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
filter : function ( object , fn , bind ) {
var results = { } ;
for ( var key in object ) {
var value = object [ key ] ;
if ( hasOwnProperty . call ( object , key ) && fn . call ( bind , value , key , object ) ) results [ key ] = value ;
}
return results ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
every : function ( object , fn , bind ) {
for ( var key in object ) {
if ( hasOwnProperty . call ( object , key ) && ! fn . call ( bind , object [ key ] , key ) ) return false ;
}
return true ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
some : function ( object , fn , bind ) {
for ( var key in object ) {
if ( hasOwnProperty . call ( object , key ) && fn . call ( bind , object [ key ] , key ) ) return true ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
return false ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
keys : function ( object ) {
var keys = [ ] ;
for ( var key in object ) {
if ( hasOwnProperty . call ( object , key ) ) keys . push ( key ) ;
}
return keys ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
values : function ( object ) {
var values = [ ] ;
for ( var key in object ) {
if ( hasOwnProperty . call ( object , key ) ) values . push ( object [ key ] ) ;
}
return values ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
getLength : function ( object ) {
return Object . keys ( object ) . length ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
keyOf : function ( object , value ) {
for ( var key in object ) {
if ( hasOwnProperty . call ( object , key ) && object [ key ] === value ) return key ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
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 ( '&' ) ;
2008-07-05 22:28:49 +02:00
}
} ) ;
2011-06-24 15:38:56 +02:00
} ) ( ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
//<1.2compat>
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Hash . implement ( {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
has : Object . prototype . hasOwnProperty ,
keyOf : function ( value ) {
return Object . keyOf ( this , value ) ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
hasValue : function ( value ) {
return Object . contains ( this , value ) ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
extend : function ( properties ) {
Hash . each ( properties || { } , function ( value , key ) {
Hash . set ( this , key , value ) ;
} , this ) ;
2008-07-05 22:28:49 +02:00
return this ;
} ,
2011-06-24 15:38:56 +02:00
combine : function ( properties ) {
Hash . each ( properties || { } , function ( value , key ) {
Hash . include ( this , key , value ) ;
} , this ) ;
return this ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
erase : function ( key ) {
if ( this . hasOwnProperty ( key ) ) delete this [ key ] ;
return this ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
get : function ( key ) {
return ( this . hasOwnProperty ( key ) ) ? this [ key ] : null ;
} ,
set : function ( key , value ) {
if ( ! this [ key ] || this . hasOwnProperty ( key ) ) this [ key ] = value ;
return this ;
} ,
empty : function ( ) {
Hash . each ( this , function ( value , key ) {
delete this [ key ] ;
} , this ) ;
return this ;
} ,
include : function ( key , value ) {
if ( this [ key ] == null ) this [ key ] = value ;
return this ;
} ,
map : function ( fn , bind ) {
return new Hash ( Object . map ( this , fn , bind ) ) ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
filter : function ( fn , bind ) {
return new Hash ( Object . filter ( this , fn , bind ) ) ;
} ,
every : function ( fn , bind ) {
return Object . every ( this , fn , bind ) ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
some : function ( fn , bind ) {
return Object . some ( this , fn , bind ) ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
getKeys : function ( ) {
return Object . keys ( this ) ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
getValues : function ( ) {
return Object . values ( this ) ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
toQueryString : function ( base ) {
return Object . toQueryString ( this , base ) ;
2008-07-05 22:28:49 +02:00
}
} ) ;
2011-06-24 15:38:56 +02:00
Hash . extend = Object . append ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Hash . alias ( { indexOf : 'keyOf' , contains : 'hasValue' } ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
//</1.2compat>
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
/ *
-- -
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
name : Browser
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
description : The Browser Object . Contains Browser initialization , Window and Document , and the Browser Hash .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
license : MIT - style license .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
requires : [ Array , Function , Number , String ]
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
provides : [ Browser , Window , Document ]
...
* /
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
( function ( ) {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var document = this . document ;
var window = document . window = this ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var UID = 1 ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . $uid = ( window . ActiveXObject ) ? function ( item ) {
return ( item . uid || ( item . uid = [ UID ++ ] ) ) [ 0 ] ;
} : function ( item ) {
return item . uid || ( item . uid = UID ++ ) ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
$uid ( window ) ;
$uid ( document ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
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 ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var Browser = this . Browser = {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
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 ]
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
Features : {
xpath : ! ! ( document . evaluate ) ,
air : ! ! ( window . runtime ) ,
query : ! ! ( document . querySelector ) ,
json : ! ! ( window . JSON )
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Plugins : { }
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
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 ( ) ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
var MSXML2 = function ( ) {
return new ActiveXObject ( 'MSXML2.XMLHTTP' ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var MSXML = function ( ) {
return new ActiveXObject ( 'Microsoft.XMLHTTP' ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
return Function . attempt ( function ( ) {
XMLHTTP ( ) ;
return XMLHTTP ;
} , function ( ) {
MSXML2 ( ) ;
return MSXML2 ;
} , function ( ) {
MSXML ( ) ;
return MSXML ;
} ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
} ) ( ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Browser . Features . xhr = ! ! ( Browser . Request ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
// Flash detection
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var version = ( Function . attempt ( function ( ) {
return navigator . plugins [ 'Shockwave Flash' ] . description ;
} , function ( ) {
return new ActiveXObject ( 'ShockwaveFlash.ShockwaveFlash' ) . GetVariable ( '$version' ) ;
} ) || '0 r0' ) . match ( /\d+/g ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Browser . Plugins . Flash = {
version : Number ( version [ 0 ] || '0.' + version [ 1 ] ) || 0 ,
build : Number ( version [ 2 ] ) || 0
} ;
// String scripts
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
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 ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
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 ;
} ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
// Window, Document
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Browser . extend ( {
Document : this . Document ,
Window : this . Window ,
Element : this . Element ,
Event : this . Event
} ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . Window = this . $constructor = new Type ( 'Window' , function ( ) { } ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . $family = Function . from ( 'window' ) . hide ( ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Window . mirror ( function ( name , method ) {
window [ name ] = method ;
2008-07-05 22:28:49 +02:00
} ) ;
2011-06-24 15:38:56 +02:00
this . Document = document . $constructor = new Type ( 'Document' , function ( ) { } ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
document . $family = Function . from ( 'document' ) . hide ( ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Document . mirror ( function ( name , method ) {
document [ name ] = method ;
} ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
document . html = document . documentElement ;
if ( ! document . head ) document . head = document . getElementsByTagName ( 'head' ) [ 0 ] ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
if ( document . execCommand ) try {
document . execCommand ( "BackgroundImageCache" , false , true ) ;
} catch ( e ) { }
/*<ltIE9>*/
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 ) ) ;
} ;
2008-07-05 22:28:49 +02:00
} ) ;
2011-06-24 15:38:56 +02:00
}
/*</ltIE9>*/
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
//<1.2compat>
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
if ( Browser . Platform . ios ) Browser . Platform . ipod = true ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Browser . Engine = { } ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var setEngine = function ( name , version ) {
Browser . Engine . name = name ;
Browser . Engine [ name + version ] = true ;
Browser . Engine . version = version ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
if ( Browser . ie ) {
Browser . Engine . trident = true ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
switch ( Browser . version ) {
case 6 : setEngine ( 'trident' , 4 ) ; break ;
case 7 : setEngine ( 'trident' , 5 ) ; break ;
case 8 : setEngine ( 'trident' , 6 ) ;
}
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
if ( Browser . firefox ) {
Browser . Engine . gecko = true ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
if ( Browser . version >= 3 ) setEngine ( 'gecko' , 19 ) ;
else setEngine ( 'gecko' , 18 ) ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
if ( Browser . safari || Browser . chrome ) {
Browser . Engine . webkit = true ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
switch ( Browser . version ) {
case 2 : setEngine ( 'webkit' , 419 ) ; break ;
case 3 : setEngine ( 'webkit' , 420 ) ; break ;
case 4 : setEngine ( 'webkit' , 525 ) ;
}
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
if ( Browser . opera ) {
Browser . Engine . presto = true ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
if ( Browser . version >= 9.6 ) setEngine ( 'presto' , 960 ) ;
else if ( Browser . version >= 9.5 ) setEngine ( 'presto' , 950 ) ;
else setEngine ( 'presto' , 925 ) ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
if ( Browser . name == 'unknown' ) {
switch ( ( ua . match ( /(?:webkit|khtml|gecko)/ ) || [ ] ) [ 0 ] ) {
case 'webkit' :
case 'khtml' :
Browser . Engine . webkit = true ;
break ;
case 'gecko' :
Browser . Engine . gecko = true ;
}
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . $exec = Browser . exec ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
//</1.2compat>
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
} ) ( ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
/ *
-- -
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
name : Event
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
description : Contains the Event Class , to make the event object cross - browser .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
license : MIT - style license .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
requires : [ Window , Document , Array , Function , String , Object ]
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
provides : Event
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
...
* /
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
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 = { } ,
related = null ,
rightClick , wheel , code , key ;
while ( target && target . nodeType == 3 ) target = target . parentNode ;
if ( type . indexOf ( 'key' ) != - 1 ) {
code = event . which || event . keyCode ;
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 ( ( /click|mouse|menu/i ) . test ( type ) ) {
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 ( ( /DOMMouseScroll|mousewheel/ ) . test ( type ) ) {
wheel = ( event . wheelDelta ) ? event . wheelDelta / 120 : - ( event . detail || 0 ) / 3 ;
}
rightClick = ( event . which == 3 ) || ( event . button == 2 ) ;
if ( ( /over|out/ ) . test ( type ) ) {
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 ( ( /gesture|touch/i ) . test ( type ) ) {
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 } ;
}
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
return Object . append ( this , {
event : event ,
type : type ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
page : page ,
client : client ,
rightClick : rightClick ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
wheel : wheel ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
relatedTarget : document . id ( related ) ,
target : document . id ( target ) ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
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
} ;
//<1.2compat>
Event . Keys = new Hash ( Event . Keys ) ;
//</1.2compat>
Event . implement ( {
stop : function ( ) {
return this . stopPropagation ( ) . preventDefault ( ) ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
stopPropagation : function ( ) {
if ( this . event . stopPropagation ) this . event . stopPropagation ( ) ;
else this . event . cancelBubble = true ;
2008-07-05 22:28:49 +02:00
return this ;
} ,
2011-06-24 15:38:56 +02:00
preventDefault : function ( ) {
if ( this . event . preventDefault ) this . event . preventDefault ( ) ;
else this . event . returnValue = false ;
2008-07-05 22:28:49 +02:00
return this ;
}
} ) ;
2011-06-24 15:38:56 +02:00
/ *
-- -
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
...
* /
2008-07-05 22:28:49 +02:00
( function ( ) {
2011-06-24 15:38:56 +02:00
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 ;
2008-07-05 22:28:49 +02:00
}
}
2011-06-24 15:38:56 +02:00
return object ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
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 ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var implement = function ( key , value , retain ) {
if ( Class . Mutators . hasOwnProperty ( key ) ) {
value = Class . Mutators [ key ] . call ( this , value ) ;
if ( value == null ) return this ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
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 ) ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
return this ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var getInstance = function ( klass ) {
klass . $prototyping = true ;
var proto = new klass ;
delete klass . $prototyping ;
return proto ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Class . implement ( 'implement' , implement . overloadSetter ( ) ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Class . Mutators = {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Extends : function ( parent ) {
this . parent = parent ;
this . prototype = getInstance ( parent ) ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
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 ) ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
} ;
2008-07-05 22:28:49 +02:00
} ) ( ) ;
2011-06-24 15:38:56 +02:00
/ *
-- -
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
name : Class . Extras
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
description : Contains Utility Classes that can be implemented into your own Classes to ease the execution of many common tasks .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
license : MIT - style license .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
requires : Class
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
provides : [ Class . Extras , Chain , Events , Options ]
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
...
* /
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
( function ( ) {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . Chain = new Class ( {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
$chain : [ ] ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
chain : function ( ) {
this . $chain . append ( Array . flatten ( arguments ) ) ;
2008-07-05 22:28:49 +02:00
return this ;
} ,
2011-06-24 15:38:56 +02:00
callChain : function ( ) {
return ( this . $chain . length ) ? this . $chain . shift ( ) . apply ( this , arguments ) : false ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
clearChain : function ( ) {
this . $chain . empty ( ) ;
2008-07-05 22:28:49 +02:00
return this ;
}
} ) ;
2011-06-24 15:38:56 +02:00
var removeOn = function ( string ) {
return string . replace ( /^on([A-Z])/ , function ( full , first ) {
return first . toLowerCase ( ) ;
} ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . Events = new Class ( {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
$events : { } ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
addEvent : function ( type , fn , internal ) {
type = removeOn ( type ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
/*<1.2compat>*/
if ( fn == $empty ) return this ;
/*</1.2compat>*/
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . $events [ type ] = ( this . $events [ type ] || [ ] ) . include ( fn ) ;
if ( internal ) fn . internal = true ;
return this ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
addEvents : function ( events ) {
for ( var type in events ) this . addEvent ( type , events [ type ] ) ;
return this ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
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 ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
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 ] ;
2008-07-05 22:28:49 +02:00
}
return this ;
} ,
2011-06-24 15:38:56 +02:00
removeEvents : function ( events ) {
var type ;
if ( typeOf ( events ) == 'object' ) {
for ( type in events ) this . removeEvent ( type , events [ type ] ) ;
return this ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
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 -- ; ) if ( i in fns ) {
this . removeEvent ( type , fns [ i ] ) ;
2008-07-05 22:28:49 +02:00
}
}
return this ;
}
} ) ;
2011-06-24 15:38:56 +02:00
this . Options = new Class ( {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
setOptions : function ( ) {
var options = this . options = Object . merge . apply ( null , [ { } , this . options ] . append ( arguments ) ) ;
if ( this . addEvent ) 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 ;
}
2008-07-05 22:28:49 +02:00
} ) ;
2011-06-24 15:38:56 +02:00
} ) ( ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
/ *
-- -
name : Slick . Parser
description : Standalone CSS3 Selector parser
provides : Slick . Parser
...
2008-07-05 22:28:49 +02:00
* /
2011-06-24 15:38:56 +02:00
; ( 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 [ parsed . raw ] = ( reversed ) ? reverse ( parsed ) : parsed ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var reverseCombinator = function ( combinator ) {
if ( combinator === '!' ) return ' ' ;
else if ( combinator === ' ' ) return '!' ;
else if ( ( /^!/ ) . test ( combinator ) ) return combinator . replace ( /^!/ , '' ) ;
else return '!' + combinator ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
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 ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
exp . reverse ( ) . push ( last ) ;
}
return expression ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
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 , function ( match ) {
return '\\' + match ;
} ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
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>+)(?:\\((?:(?:([\"'])([^\\13]*)\\13)|((?:\\([^)]+\\)|[^()]*)+))\\))?)"
. 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 ,
pseudoMarker ,
pseudoClass ,
pseudoQuote ,
pseudoClassQuotedValue ,
pseudoClassValue
) {
if ( separator || separatorIndex === - 1 ) {
parsed . expressions [ ++ separatorIndex ] = [ ] ;
combinatorIndex = - 1 ;
if ( separator ) return '' ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
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 : '*' } ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var currentParsed = parsed . expressions [ separatorIndex ] [ combinatorIndex ] ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
if ( tagName ) {
currentParsed . tag = tagName . replace ( reUnescape , '' ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
} else if ( id ) {
currentParsed . id = id . replace ( reUnescape , '' ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
} 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 ,
type : pseudoMarker . length == 1 ? 'class' : 'element'
} ) ;
} 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 ;
} ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
if ( attributeValue == '' && ( /^[*$^]=$/ ) . test ( attributeOperator ) ) test = function ( ) {
return false ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
if ( ! test ) test = function ( value ) {
return value && regexp . test ( value ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
if ( ! currentParsed . attributes ) currentParsed . attributes = [ ] ;
currentParsed . attributes . push ( {
key : attributeKey ,
operator : attributeOperator ,
value : attributeValue ,
test : test
} ) ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
return '' ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
// Slick NS
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var Slick = ( this . Slick || { } ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Slick . parse = function ( expression ) {
return parse ( expression ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Slick . escapeRegExp = escapeRegExp ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
if ( ! this . Slick ) this . Slick = Slick ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
} ) . apply ( /*<CommonJS>*/ ( typeof exports != 'undefined' ) ? exports : /*</CommonJS>*/ this ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
/ *
-- -
name : Slick . Finder
description : The new , superfast css selector engine .
provides : Slick . Finder
requires : Slick . Parser
...
* /
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
; ( function ( ) {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var local = { } ,
featuresCache = { } ,
toString = Object . prototype . toString ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
// Feature / Bug detection
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
local . isNativeCode = function ( fn ) {
return ( /\{\s*\[native code\]\s*\}/ ) . test ( '' + fn ) ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
local . isXML = function ( document ) {
return ( ! ! document . xmlVersion ) || ( ! ! document . xml ) || ( toString . call ( document ) == '[object XMLDocument]' ) ||
( document . nodeType == 9 && document . documentElement . nodeName != 'HTML' ) ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
local . setDocument = function ( document ) {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
// convert elements / window arguments to document. if document cannot be extrapolated, the function returns.
var nodeType = document . nodeType ;
if ( nodeType == 9 ) ; // document
else if ( nodeType ) document = document . ownerDocument ; // node
else if ( document . navigator ) document = document . document ; // window
else return ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
// check if it's the old document
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
if ( this . document === document ) return ;
this . document = document ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
// check if we have done feature detection on this document before
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var root = document . documentElement ,
rootUid = this . getUIDXML ( root ) ,
features = featuresCache [ rootUid ] ,
feature ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
if ( features ) {
for ( feature in features ) {
this [ feature ] = features [ feature ] ;
}
return ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
features = featuresCache [ rootUid ] = { } ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
features . root = root ;
features . isXMLDocument = this . isXML ( document ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
features . brokenStarGEBTN
= features . starSelectsClosedQSA
= features . idGetsName
= features . brokenMixedCaseQSA
= features . brokenGEBCN
= features . brokenCheckedQSA
= features . brokenEmptyAttributeQSA
= features . isHTMLDocument
= features . nativeMatchesSelector
= false ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var starSelectsClosed , starSelectsComments ,
brokenSecondClassNameGEBCN , cachedGetElementsByClassName ,
brokenFormAttributeGetter ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var selected , id = 'slick_uniqueid' ;
var testNode = document . createElement ( 'div' ) ;
var testRoot = document . body || document . getElementsByTagName ( 'body' ) [ 0 ] || root ;
testRoot . appendChild ( testNode ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
// on non-HTML documents innerHTML and getElementsById doesnt work properly
try {
testNode . innerHTML = '<a id="' + id + '"></a>' ;
features . isHTMLDocument = ! ! document . getElementById ( id ) ;
} catch ( e ) { } ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
if ( features . isHTMLDocument ) {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
testNode . style . display = 'none' ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
// IE returns comment nodes for getElementsByTagName('*') for some documents
testNode . appendChild ( document . createComment ( '' ) ) ;
starSelectsComments = ( testNode . getElementsByTagName ( '*' ) . length > 1 ) ;
// 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 ) { } ;
features . brokenStarGEBTN = starSelectsComments || starSelectsClosed ;
// IE returns elements with the name instead of just id for getElementsById for some documents
try {
testNode . innerHTML = '<a name="' + id + '"></a><b id="' + id + '"></b>' ;
features . idGetsName = document . getElementById ( id ) === testNode . firstChild ;
} catch ( e ) { } ;
if ( testNode . getElementsByClassName ) {
// Safari 3.2 getElementsByClassName caches results
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 ) { } ;
features . brokenGEBCN = cachedGetElementsByClassName || brokenSecondClassNameGEBCN ;
}
if ( testNode . querySelectorAll ) {
// IE 8 returns closed nodes (EG:"</foo>") for querySelectorAll('*') for some documents
try {
testNode . innerHTML = 'foo</foo>' ;
selected = testNode . querySelectorAll ( '*' ) ;
features . starSelectsClosedQSA = ( selected && ! ! selected . length && selected [ 0 ] . nodeName . charAt ( 0 ) == '/' ) ;
} catch ( e ) { } ;
// Safari 3.2 querySelectorAll doesnt work with mixedcase on quirksmode
try {
testNode . innerHTML = '<a class="MiX"></a>' ;
features . brokenMixedCaseQSA = ! testNode . querySelectorAll ( '.MiX' ) . length ;
} catch ( e ) { } ;
// Webkit and Opera dont return selected options on querySelectorAll
try {
testNode . innerHTML = '<select><option selected="selected">a</option></select>' ;
features . brokenCheckedQSA = ( testNode . querySelectorAll ( ':checked' ) . length == 0 ) ;
} catch ( e ) { } ;
// IE returns incorrect results for attr[*^$]="" selectors on querySelectorAll
try {
testNode . innerHTML = '<a class=""></a>' ;
features . brokenEmptyAttributeQSA = ( testNode . querySelectorAll ( '[class*=""]' ) . length != 0 ) ;
} catch ( e ) { } ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
// IE6-7, if a form has an input of id x, form.getAttribute(x) returns a reference to the input
try {
testNode . innerHTML = '<form action="s"><input id="action"/></form>' ;
brokenFormAttributeGetter = ( testNode . firstChild . getAttribute ( 'action' ) != 's' ) ;
} catch ( e ) { } ;
// native matchesSelector function
features . nativeMatchesSelector = root . matchesSelector || /*root.msMatchesSelector ||*/ root . mozMatchesSelector || root . webkitMatchesSelector ;
if ( features . nativeMatchesSelector ) try {
// if matchesSelector trows errors on incorrect sintaxes we can use it
features . nativeMatchesSelector . call ( root , ':slick' ) ;
features . nativeMatchesSelector = null ;
} catch ( e ) { } ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
try {
root . slick _expando = 1 ;
delete root . slick _expando ;
features . getUID = this . getUIDHTML ;
} catch ( e ) {
features . getUID = this . getUIDXML ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
testRoot . removeChild ( testNode ) ;
testNode = selected = testRoot = null ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
// getAttribute
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
features . getAttribute = ( features . isHTMLDocument && brokenFormAttributeGetter ) ? function ( node , name ) {
var method = this . attributeGetters [ name ] ;
if ( method ) return method . call ( node ) ;
var attributeNode = node . getAttributeNode ( name ) ;
return ( attributeNode ) ? attributeNode . nodeValue : null ;
} : function ( node , name ) {
var method = this . attributeGetters [ name ] ;
return ( method ) ? method . call ( node ) : node . getAttribute ( name ) ;
} ;
// hasAttribute
features . 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?
features . 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 ) ) ;
2008-07-05 22:28:49 +02:00
return false ;
2011-06-24 15:38:56 +02:00
} ;
// document order sorting
// credits to Sizzle (http://sizzlejs.com/)
features . 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 ;
root = null ;
for ( feature in features ) {
this [ feature ] = features [ feature ] ;
}
} ;
// Main Method
var reSimpleSelector = /^([#.]?)((?:[\w-]+|\*))$/ ,
reEmptyAttribute = /\[.+[*$^]=(?:""|'')?\]/ ,
qsaFailExpCache = { } ;
local . search = function ( context , expression , append , first ) {
var found = this . found = ( first ) ? null : ( append || [ ] ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
if ( ! context ) return found ;
else if ( context . navigator ) context = context . document ; // Convert the node from a window to a document
else if ( ! context . nodeType ) return found ;
// setup
var parsed , i ,
uniques = this . uniques = { } ,
hasOthers = ! ! ( append && append . length ) ,
contextIsDocument = ( context . nodeType == 9 ) ;
if ( this . document !== ( contextIsDocument ? context : context . ownerDocument ) ) this . setDocument ( context ) ;
// avoid duplicating items already in the append array
if ( hasOthers ) for ( i = found . length ; i -- ; ) uniques [ this . getUID ( found [ i ] ) ] = true ;
// expression checks
if ( typeof expression == 'string' ) { // expression is a string
/*<simple-selectors-override>*/
var simpleSelector = expression . match ( reSimpleSelector ) ;
simpleSelectors : if ( simpleSelector ) {
var symbol = simpleSelector [ 1 ] ,
name = simpleSelector [ 2 ] ,
node , nodes ;
if ( ! symbol ) {
if ( name == '*' && this . brokenStarGEBTN ) break simpleSelectors ;
nodes = context . getElementsByTagName ( name ) ;
if ( first ) return nodes [ 0 ] || null ;
for ( i = 0 ; node = nodes [ i ++ ] ; ) {
if ( ! ( hasOthers && uniques [ this . getUID ( node ) ] ) ) found . push ( node ) ;
}
} else if ( symbol == '#' ) {
if ( ! this . isHTMLDocument || ! contextIsDocument ) break simpleSelectors ;
node = context . getElementById ( name ) ;
if ( ! node ) return found ;
if ( this . idGetsName && node . getAttributeNode ( 'id' ) . nodeValue != name ) break simpleSelectors ;
if ( first ) return node || null ;
if ( ! ( hasOthers && uniques [ this . getUID ( node ) ] ) ) found . push ( node ) ;
} else if ( symbol == '.' ) {
if ( ! this . isHTMLDocument || ( ( ! context . getElementsByClassName || this . brokenGEBCN ) && context . querySelectorAll ) ) break simpleSelectors ;
if ( context . getElementsByClassName && ! this . brokenGEBCN ) {
nodes = context . getElementsByClassName ( name ) ;
if ( first ) return nodes [ 0 ] || null ;
for ( i = 0 ; node = nodes [ i ++ ] ; ) {
if ( ! ( hasOthers && uniques [ this . getUID ( node ) ] ) ) found . push ( node ) ;
}
} else {
var matchClass = new RegExp ( '(^|\\s)' + Slick . escapeRegExp ( name ) + '(\\s|$)' ) ;
nodes = context . getElementsByTagName ( '*' ) ;
for ( i = 0 ; node = nodes [ i ++ ] ; ) {
className = node . className ;
if ( ! ( className && matchClass . test ( className ) ) ) continue ;
if ( first ) return node ;
if ( ! ( hasOthers && uniques [ this . getUID ( node ) ] ) ) found . push ( node ) ;
}
}
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
if ( hasOthers ) this . sort ( found ) ;
return ( first ) ? null : found ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
/*</simple-selectors-override>*/
/*<query-selector-override>*/
querySelector : if ( context . querySelectorAll ) {
if ( ! this . isHTMLDocument
|| qsaFailExpCache [ expression ]
//TODO: only skip when expression is actually mixed case
|| this . brokenMixedCaseQSA
|| ( this . brokenCheckedQSA && expression . indexOf ( ':checked' ) > - 1 )
|| ( this . brokenEmptyAttributeQSA && reEmptyAttribute . test ( expression ) )
|| ( ! contextIsDocument //Abort when !contextIsDocument and...
// there are multiple expressions in the selector
// since we currently only fix non-document rooted QSA for single expression selectors
&& expression . indexOf ( ',' ) > - 1
)
|| Slick . disableQSA
) break querySelector ;
var _expression = expression , _context = context ;
if ( ! contextIsDocument ) {
// non-document rooted QSA
// credits to Andrew Dupont
var currentId = _context . getAttribute ( 'id' ) , slickid = 'slickid__' ;
_context . setAttribute ( 'id' , slickid ) ;
_expression = '#' + slickid + ' ' + _expression ;
context = _context . parentNode ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
try {
if ( first ) return context . querySelector ( _expression ) || null ;
else nodes = context . querySelectorAll ( _expression ) ;
} catch ( e ) {
qsaFailExpCache [ expression ] = 1 ;
break querySelector ;
} finally {
if ( ! contextIsDocument ) {
if ( currentId ) _context . setAttribute ( 'id' , currentId ) ;
else _context . removeAttribute ( 'id' ) ;
context = _context ;
}
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
if ( this . starSelectsClosedQSA ) for ( i = 0 ; node = nodes [ i ++ ] ; ) {
if ( node . nodeName > '@' && ! ( hasOthers && uniques [ this . getUID ( node ) ] ) ) found . push ( node ) ;
} else for ( i = 0 ; node = nodes [ i ++ ] ; ) {
if ( ! ( hasOthers && uniques [ this . getUID ( node ) ] ) ) found . push ( node ) ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
if ( hasOthers ) this . sort ( found ) ;
return found ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
/*</query-selector-override>*/
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 ;
}
/*<pseudo-selectors>*/ /*<nth-pseudo-selectors>*/
// cache elements for the nth 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 = ( ! hasOthers && ( 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 ;
}
// should sort if there are nodes in append and if you pass multiple expressions.
if ( hasOthers || ( 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 ] ) ) ;
2008-07-05 22:28:49 +02:00
}
}
2011-06-24 15:38:56 +02:00
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 ) ;
2008-07-05 22:28:49 +02:00
}
} ;
2011-06-24 15:38:56 +02:00
local . matchNode = function ( node , selector ) {
if ( this . isHTMLDocument && this . nativeMatchesSelector ) {
try {
return this . nativeMatchesSelector . call ( node , selector . replace ( /\[([^=]+)=\s*([^'"\]]+?)\s*\]/g , '[$1="$2"]' ) ) ;
} catch ( matchError ) { }
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var parsed = this . Slick . parse ( selector ) ;
if ( ! parsed ) return true ;
// simple (single) selectors
var expressions = parsed . expressions , reversedExpressions , simpleExpCounter = 0 , i ;
for ( i = 0 ; ( currentExpression = expressions [ i ] ) ; i ++ ) {
if ( currentExpression . length == 1 ) {
var exp = currentExpression [ 0 ] ;
if ( this . matchSelector ( node , ( this . isXMLDocument ) ? exp . tag : exp . tag . toUpperCase ( ) , exp . id , exp . classes , exp . attributes , exp . pseudos ) ) return true ;
simpleExpCounter ++ ;
}
}
if ( simpleExpCounter == parsed . length ) return false ;
var nodes = this . search ( this . document , parsed ) , item ;
for ( i = 0 ; 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 ) {
var nodeName = ( this . isXMLDocument ) ? node . nodeName : node . nodeName . toUpperCase ( ) ;
if ( tag == '*' ) {
if ( nodeName < '@' ) return false ; // Fix for comment nodes and closed nodes
} else {
if ( nodeName != tag ) return false ;
}
}
if ( id && node . getAttribute ( 'id' ) != id ) return false ;
var i , part , cls ;
if ( classes ) for ( i = classes . length ; i -- ; ) {
cls = node . getAttribute ( 'class' ) || node . className ;
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 ++ ] ; ) {
var idNode = item . getAttributeNode ( 'id' ) ;
if ( idNode && idNode . 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 . root , 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 ) ;
2008-07-05 22:28:49 +02:00
}
} ,
2011-06-24 15:38:56 +02:00
'>' : 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 ;
2008-07-05 22:28:49 +02:00
}
} ,
2011-06-24 15:38:56 +02:00
'^' : 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 ) ;
2008-07-05 22:28:49 +02:00
}
} ,
2011-06-24 15:38:56 +02:00
'~' : 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 ) ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
'++' : 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 ) ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
'~~' : 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 ) ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
'!' : 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 ) ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
'!>' : 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 ) ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
'!+' : 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 ) ;
2008-07-05 22:28:49 +02:00
}
}
2011-06-24 15:38:56 +02:00
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
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 ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
'not' : function ( node , expression ) {
return ! this . matchNode ( node , expression ) ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
'contains' : function ( node , text ) {
return ( node . innerText || node . textContent || '' ) . indexOf ( text ) > - 1 ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
'first-child' : function ( node ) {
while ( ( node = node . previousSibling ) ) if ( node . nodeType == 1 ) return false ;
return true ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
'last-child' : function ( node ) {
while ( ( node = node . nextSibling ) ) if ( node . nodeType == 1 ) return false ;
2008-07-05 22:28:49 +02:00
return true ;
} ,
2011-06-24 15:38:56 +02:00
'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 ;
2008-07-05 22:28:49 +02:00
return true ;
} ,
2011-06-24 15:38:56 +02:00
/*<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 ) {
return this [ 'pseudo:nth-child' ] ( node , '2n' ) ;
} ,
'odd' : function ( node ) {
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 ;
} ,
'disabled' : function ( node ) {
return node . disabled ;
} ,
'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 ) ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
'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 this . getAttribute ( 'class' ) || this . className ;
} ,
'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' ) ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
'tabindex' : function ( ) {
var attributeNode = this . getAttributeNode ( 'tabindex' ) ;
return ( attributeNode && attributeNode . specified ) ? attributeNode . nodeValue : null ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
'type' : function ( ) {
return this . getAttribute ( 'type' ) ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
} ;
// Slick
var Slick = local . Slick = ( this . Slick || { } ) ;
Slick . version = '1.1.5' ;
// 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 ;
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 ) ;
2008-07-05 22:28:49 +02:00
/ *
2011-06-24 15:38:56 +02:00
-- -
name : Element
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
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 ]
...
2008-07-05 22:28:49 +02:00
* /
2011-06-24 15:38:56 +02:00
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 ( ! ( /^[\w-]+$/ ) . test ( tag ) ) {
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 ( props [ attr . key ] != null ) continue ;
if ( attr . value != null && attr . operator == '=' ) props [ attr . key ] = attr . value ;
else if ( ! attr . value && ! attr . operator ) props [ attr . key ] = true ;
}
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 = { } ;
//<1.2compat>
Element . Constructors = new Hash ;
//</1.2compat>
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 ( ) ,
unshift : function ( ) {
var items = [ ] ;
for ( var i = 0 , l = arguments . length ; i < l ; i ++ ) {
var item = document . id ( arguments [ i ] ) ;
if ( item ) items . push ( item ) ;
}
return Array . prototype . unshift . apply ( this , items ) ;
} . 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 ( )
} ) ;
//<1.2compat>
Elements . alias ( 'extend' , 'append' ) ;
//</1.2compat>
( 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 ) ) ;
}
} ) ;
//<1.2compat>
( function ( search , find , match ) {
this . Selectors = { } ;
var pseudos = this . Selectors . Pseudo = new Hash ( ) ;
var addSlickPseudos = function ( ) {
for ( var name in pseudos ) if ( pseudos . hasOwnProperty ( name ) ) {
Slick . definePseudo ( name , pseudos [ name ] ) ;
delete pseudos [ name ] ;
}
} ;
Slick . search = function ( context , expression , append ) {
addSlickPseudos ( ) ;
return search . call ( this , context , expression , append ) ;
} ;
Slick . find = function ( context , expression ) {
addSlickPseudos ( ) ;
return find . call ( this , context , expression ) ;
} ;
Slick . match = function ( node , selector ) {
addSlickPseudos ( ) ;
return match . call ( this , node , selector ) ;
} ;
} ) ( Slick . search , Slick . find , Slick . match ) ;
if ( window . $$ == null ) Window . implement ( '$$' , function ( selector ) {
var elements = new Elements ;
if ( arguments . length == 1 && typeof selector == 'string' ) return Slick . search ( this . document , selector , elements ) ;
var args = Array . flatten ( arguments ) ;
for ( var i = 0 , l = args . length ; i < l ; i ++ ) {
var item = args [ i ] ;
switch ( typeOf ( item ) ) {
case 'element' : elements . push ( item ) ; break ;
case 'string' : Slick . search ( this . document , item , elements ) ;
}
}
return elements ;
} ) ;
//</1.2compat>
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 formProps = { input : 'checked' , option : 'selected' , textarea : 'value' } ;
var get = function ( uid ) {
return ( storage [ uid ] || ( storage [ uid ] = { } ) ) ;
} ;
var clean = function ( item ) {
var uid = item . uid ;
if ( item . removeEvents ) item . removeEvents ( ) ;
if ( item . clearAttributes ) item . clearAttributes ( ) ;
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' , 'defaultChecked'
] ;
var attributes = {
'html' : 'innerHTML' ,
'class' : 'className' ,
'for' : 'htmlFor' ,
'text' : ( function ( ) {
var temp = document . createElement ( 'div' ) ;
return ( temp . textContent == null ) ? 'innerText' : 'textContent' ;
} ) ( )
} ;
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 ;
//<1.2compat>
Object . each ( inserters , function ( inserter , where ) {
where = where . capitalize ( ) ;
var methods = { } ;
methods [ 'inject' + where ] = function ( el ) {
inserter ( this , document . id ( el , true ) ) ;
return this ;
} ;
methods [ 'grab' + where ] = function ( el ) {
inserter ( document . id ( el , true ) , this ) ;
return this ;
} ;
Element . implement ( methods ) ;
} ) ;
//</1.2compat>
var injectCombinator = function ( expression , combinator ) {
if ( ! expression ) return combinator ;
expression = Object . clone ( 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 ( '&' ) ;
} ,
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 cleanClone = function ( node , element , keepid ) {
if ( ! keepid ) node . setAttributeNode ( document . createAttribute ( 'id' ) ) ;
if ( node . clearAttributes ) {
node . clearAttributes ( ) ;
node . mergeAttributes ( element ) ;
node . removeAttribute ( 'uid' ) ;
if ( node . options ) {
var no = node . options , eo = element . options ;
for ( var i = no . length ; i -- ; ) no [ i ] . selected = eo [ i ] . selected ;
}
}
var prop = formProps [ element . tagName . toLowerCase ( ) ] ;
if ( prop && element [ prop ] ) node [ prop ] = element [ prop ] ;
} ;
Element . implement ( 'clone' , function ( contents , keepid ) {
contents = contents !== false ;
var clone = this . cloneNode ( contents ) , i ;
if ( contents ) {
var ce = clone . getElementsByTagName ( '*' ) , te = this . getElementsByTagName ( '*' ) ;
for ( i = ce . length ; i -- ; ) cleanClone ( ce [ i ] , te [ i ] , keepid ) ;
}
cleanClone ( clone , this , keepid ) ;
if ( Browser . ie ) {
var co = clone . getElementsByTagName ( 'object' ) , to = this . getElementsByTagName ( 'object' ) ;
for ( i = co . length ; i -- ; ) co [ i ] . outerHTML = to [ i ] . outerHTML ;
}
return document . id ( clone ) ;
} ) ;
var contains = { contains : function ( element ) {
return Slick . contains ( this , element ) ;
} } ;
if ( ! document . contains ) Document . implement ( contains ) ;
if ( ! document . createElement ( 'div' ) . contains ) Element . implement ( contains ) ;
//<1.2compat>
Element . implement ( 'hasChild' , function ( element ) {
return this !== element && this . contains ( element ) ;
} ) ;
//</1.2compat>
[ 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 [ $uid ( this ) ] = this ;
}
if ( this . addEventListener ) this . addEventListener ( type , fn , ! ! arguments [ 2 ] ) ;
else this . attachEvent ( 'on' + type , fn ) ;
return this ;
} ,
removeListener : function ( type , fn ) {
if ( this . removeEventListener ) this . removeEventListener ( type , fn , ! ! arguments [ 2 ] ) ;
else this . detachEvent ( 'on' + type , fn ) ;
return this ;
} ,
retrieve : function ( property , dflt ) {
var storage = get ( $uid ( this ) ) , prop = storage [ property ] ;
if ( dflt != null && prop == null ) prop = storage [ property ] = dflt ;
return prop != null ? prop : null ;
} ,
store : function ( property , value ) {
var storage = get ( $uid ( this ) ) ;
storage [ property ] = value ;
return this ;
} ,
eliminate : function ( property ) {
var storage = get ( $uid ( this ) ) ;
delete storage [ property ] ;
return this ;
}
} ) ;
/*<ltIE9>*/
if ( window . attachEvent && ! window . addEventListener ) window . addListener ( 'unload' , function ( ) {
Object . each ( collected , clean ) ;
if ( window . CollectGarbage ) CollectGarbage ( ) ;
} ) ;
/*</ltIE9>*/
} ) ( ) ;
Element . Properties = { } ;
//<1.2compat>
Element . Properties = new Hash ;
//</1.2compat>
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 ( ) ;
}
} ;
/*<ltIE9>*/
( 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' ) ) ;
/*</ltIE9>*/
/*<!webkit>*/
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 ;
} ) ( ) ;
/*</!webkit>*/
/ *
-- -
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 * 100 ) . limit ( 0 , 100 ) . round ( ) ;
opacity = ( opacity == 100 ) ? '' : 'alpha(opacity=' + opacity + ')' ;
var filter = element . style . filter || element . getComputedStyle ( 'filter' ) || '' ;
element . style . filter = reAlpha . test ( filter ) ? 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 ( ( /^(height|width)$/ ) . test ( property ) ) {
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 ( ( /^border(.+)Width|margin|padding/ ) . test ( property ) ) 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 : '@'
} ;
//<1.2compat>
Element . Styles = new Hash ( Element . Styles ) ;
//</1.2compat>
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 : 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 , arguments [ 2 ] ) ;
}
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 , arguments [ 2 ] ) : 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 ;
}
} ) ;
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'
}
} ;
//<1.2compat>
Element . Events = new Hash ( Element . Events ) ;
//</1.2compat>
} ) ( ) ;
/ *
-- -
name : Element . Dimensions
description : Contains methods to work with size , scroll , or positioning of Elements and the window object .
license : MIT - style license .
credits :
- Element positioning based on the [ qooxdoo ] ( http : //qooxdoo.org/) code and smart browser fixes, [LGPL License](http://www.gnu.org/licenses/lgpl.html).
- Viewport dimensions based on [ YUI ] ( http : //developer.yahoo.com/yui/) code, [BSD License](http://developer.yahoo.com/yui/license.html).
requires : [ Element , Element . Style ]
provides : [ Element . Dimensions ]
...
* /
( function ( ) {
var element = document . createElement ( 'div' ) ,
child = document . createElement ( 'div' ) ;
element . style . height = '0' ;
element . appendChild ( child ) ;
var brokenOffsetParent = ( child . offsetParent === element ) ;
element = child = null ;
var isOffset = function ( el ) {
return styleString ( el , 'position' ) != 'static' || isBody ( el ) ;
} ;
var isOffsetStatic = function ( el ) {
return isOffset ( el ) || ( /^(?:table|td|th)$/i ) . test ( el . tagName ) ;
} ;
Element . implement ( {
scrollTo : function ( x , y ) {
if ( isBody ( this ) ) {
this . getWindow ( ) . scrollTo ( x , y ) ;
} else {
this . scrollLeft = x ;
this . scrollTop = y ;
}
return this ;
} ,
getSize : function ( ) {
if ( isBody ( this ) ) return this . getWindow ( ) . getSize ( ) ;
return { x : this . offsetWidth , y : this . offsetHeight } ;
} ,
getScrollSize : function ( ) {
if ( isBody ( this ) ) return this . getWindow ( ) . getScrollSize ( ) ;
return { x : this . scrollWidth , y : this . scrollHeight } ;
} ,
getScroll : function ( ) {
if ( isBody ( this ) ) return this . getWindow ( ) . getScroll ( ) ;
return { x : this . scrollLeft , y : this . scrollTop } ;
} ,
getScrolls : function ( ) {
var element = this . parentNode , position = { x : 0 , y : 0 } ;
while ( element && ! isBody ( element ) ) {
position . x += element . scrollLeft ;
position . y += element . scrollTop ;
element = element . parentNode ;
}
return position ;
} ,
getOffsetParent : brokenOffsetParent ? function ( ) {
var element = this ;
if ( isBody ( element ) || styleString ( element , 'position' ) == 'fixed' ) return null ;
var isOffsetCheck = ( styleString ( element , 'position' ) == 'static' ) ? isOffsetStatic : isOffset ;
while ( ( element = element . parentNode ) ) {
if ( isOffsetCheck ( element ) ) return element ;
}
return null ;
} : function ( ) {
var element = this ;
if ( isBody ( element ) || styleString ( element , 'position' ) == 'fixed' ) return null ;
try {
return element . offsetParent ;
} catch ( e ) { }
return null ;
} ,
getOffsets : function ( ) {
if ( this . getBoundingClientRect && ! Browser . Platform . ios ) {
var bound = this . getBoundingClientRect ( ) ,
html = document . id ( this . getDocument ( ) . documentElement ) ,
htmlScroll = html . getScroll ( ) ,
elemScrolls = this . getScrolls ( ) ,
isFixed = ( styleString ( this , 'position' ) == 'fixed' ) ;
return {
x : bound . left . toInt ( ) + elemScrolls . x + ( ( isFixed ) ? 0 : htmlScroll . x ) - html . clientLeft ,
y : bound . top . toInt ( ) + elemScrolls . y + ( ( isFixed ) ? 0 : htmlScroll . y ) - html . clientTop
} ;
}
var element = this , position = { x : 0 , y : 0 } ;
if ( isBody ( this ) ) return position ;
while ( element && ! isBody ( element ) ) {
position . x += element . offsetLeft ;
position . y += element . offsetTop ;
if ( Browser . firefox ) {
if ( ! borderBox ( element ) ) {
position . x += leftBorder ( element ) ;
position . y += topBorder ( element ) ;
}
var parent = element . parentNode ;
if ( parent && styleString ( parent , 'overflow' ) != 'visible' ) {
position . x += leftBorder ( parent ) ;
position . y += topBorder ( parent ) ;
}
} else if ( element != this && Browser . safari ) {
position . x += leftBorder ( element ) ;
position . y += topBorder ( element ) ;
}
element = element . offsetParent ;
}
if ( Browser . firefox && ! borderBox ( this ) ) {
position . x -= leftBorder ( this ) ;
position . y -= topBorder ( this ) ;
}
return position ;
} ,
getPosition : function ( relative ) {
if ( isBody ( this ) ) return { x : 0 , y : 0 } ;
var offset = this . getOffsets ( ) ,
scroll = this . getScrolls ( ) ;
var position = {
x : offset . x - scroll . x ,
y : offset . y - scroll . y
} ;
if ( relative && ( relative = document . id ( relative ) ) ) {
var relativePosition = relative . getPosition ( ) ;
return { x : position . x - relativePosition . x - leftBorder ( relative ) , y : position . y - relativePosition . y - topBorder ( relative ) } ;
}
return position ;
} ,
getCoordinates : function ( element ) {
if ( isBody ( this ) ) return this . getWindow ( ) . getCoordinates ( ) ;
var position = this . getPosition ( element ) ,
size = this . getSize ( ) ;
var obj = {
left : position . x ,
top : position . y ,
width : size . x ,
height : size . y
} ;
obj . right = obj . left + obj . width ;
obj . bottom = obj . top + obj . height ;
return obj ;
} ,
computePosition : function ( obj ) {
return {
left : obj . x - styleNumber ( this , 'margin-left' ) ,
top : obj . y - styleNumber ( this , 'margin-top' )
} ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
setPosition : function ( obj ) {
return this . setStyles ( this . computePosition ( obj ) ) ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
} ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
[ Document , Window ] . invoke ( 'implement' , {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
getSize : function ( ) {
var doc = getCompatElement ( this ) ;
return { x : doc . clientWidth , y : doc . clientHeight } ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
getScroll : function ( ) {
var win = this . getWindow ( ) , doc = getCompatElement ( this ) ;
return { x : win . pageXOffset || doc . scrollLeft , y : win . pageYOffset || doc . scrollTop } ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
getScrollSize : function ( ) {
var doc = getCompatElement ( this ) ,
min = this . getSize ( ) ,
body = this . getDocument ( ) . body ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
return { x : Math . max ( doc . scrollWidth , body . scrollWidth , min . x ) , y : Math . max ( doc . scrollHeight , body . scrollHeight , min . y ) } ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
getPosition : function ( ) {
return { x : 0 , y : 0 } ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
getCoordinates : function ( ) {
var size = this . getSize ( ) ;
return { top : 0 , left : 0 , bottom : size . y , right : size . x , height : size . y , width : size . x } ;
2008-07-05 22:28:49 +02:00
}
} ) ;
2011-06-24 15:38:56 +02:00
// private methods
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var styleString = Element . getComputedStyle ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
function styleNumber ( element , style ) {
return styleString ( element , style ) . toInt ( ) || 0 ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
function borderBox ( element ) {
return styleString ( element , '-moz-box-sizing' ) == 'border-box' ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
function topBorder ( element ) {
return styleNumber ( element , 'border-top-width' ) ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
function leftBorder ( element ) {
return styleNumber ( element , 'border-left-width' ) ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
function isBody ( element ) {
return ( /^(?:body|html)$/i ) . test ( element . tagName ) ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
function getCompatElement ( element ) {
var doc = element . getDocument ( ) ;
return ( ! doc . compatMode || doc . compatMode == 'CSS1Compat' ) ? doc . html : doc . body ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
} ) ( ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
//aliases
Element . alias ( { position : 'setPosition' } ) ; //compatability
[ Window , Document , Element ] . invoke ( 'implement' , {
getHeight : function ( ) {
return this . getSize ( ) . y ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
getWidth : function ( ) {
return this . getSize ( ) . x ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
getScrollTop : function ( ) {
return this . getScroll ( ) . y ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
getScrollLeft : function ( ) {
return this . getScroll ( ) . x ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
getScrollHeight : function ( ) {
return this . getScrollSize ( ) . y ;
} ,
getScrollWidth : function ( ) {
return this . getScrollSize ( ) . x ;
} ,
getTop : function ( ) {
return this . getPosition ( ) . y ;
} ,
getLeft : function ( ) {
return this . getPosition ( ) . x ;
2008-07-05 22:28:49 +02:00
}
} ) ;
2011-06-24 15:38:56 +02:00
/ *
-- -
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
name : Fx
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
description : Contains the basic animation logic to be extended by all other Fx Classes .
license : MIT - style license .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
requires : [ Chain , Events , Options ]
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
provides : Fx
...
2008-07-05 22:28:49 +02:00
* /
2011-06-24 15:38:56 +02:00
( function ( ) {
var Fx = this . Fx = new Class ( {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Implements : [ Chain , Events , Options ] ,
2008-07-05 22:28:49 +02:00
options : {
2011-06-24 15:38:56 +02:00
/ *
onStart : nil ,
onCancel : nil ,
onComplete : nil ,
* /
fps : 60 ,
unit : false ,
duration : 500 ,
frames : null ,
frameSkip : true ,
link : 'ignore'
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
initialize : function ( options ) {
this . subject = this . subject || this ;
this . setOptions ( options ) ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
getTransition : function ( ) {
return function ( p ) {
return - ( Math . cos ( Math . PI * p ) - 1 ) / 2 ;
} ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
step : function ( now ) {
if ( this . options . frameSkip ) {
var diff = ( this . time != null ) ? ( now - this . time ) : 0 , frames = diff / this . frameInterval ;
this . time = now ;
this . frame += frames ;
} else {
this . frame ++ ;
}
if ( this . frame < this . frames ) {
var delta = this . transition ( this . frame / this . frames ) ;
this . set ( this . compute ( this . from , this . to , delta ) ) ;
} else {
this . frame = this . frames ;
this . set ( this . compute ( this . from , this . to , 1 ) ) ;
this . stop ( ) ;
}
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
set : function ( now ) {
return now ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
compute : function ( from , to , delta ) {
return Fx . compute ( from , to , delta ) ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
check : function ( ) {
if ( ! this . isRunning ( ) ) return true ;
switch ( this . options . link ) {
case 'cancel' : this . cancel ( ) ; return true ;
case 'chain' : this . chain ( this . caller . pass ( arguments , this ) ) ; return false ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
return false ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
start : function ( from , to ) {
if ( ! this . check ( from , to ) ) return this ;
this . from = from ;
this . to = to ;
this . frame = ( this . options . frameSkip ) ? 0 : - 1 ;
this . time = null ;
this . transition = this . getTransition ( ) ;
var frames = this . options . frames , fps = this . options . fps , duration = this . options . duration ;
this . duration = Fx . Durations [ duration ] || duration . toInt ( ) ;
this . frameInterval = 1000 / fps ;
this . frames = frames || Math . round ( this . duration / this . frameInterval ) ;
this . fireEvent ( 'start' , this . subject ) ;
pushInstance . call ( this , fps ) ;
return this ;
} ,
stop : function ( ) {
if ( this . isRunning ( ) ) {
this . time = null ;
pullInstance . call ( this , this . options . fps ) ;
if ( this . frames == this . frame ) {
this . fireEvent ( 'complete' , this . subject ) ;
if ( ! this . callChain ( ) ) this . fireEvent ( 'chainComplete' , this . subject ) ;
} else {
this . fireEvent ( 'stop' , this . subject ) ;
}
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
return this ;
} ,
cancel : function ( ) {
if ( this . isRunning ( ) ) {
this . time = null ;
pullInstance . call ( this , this . options . fps ) ;
this . frame = this . frames ;
this . fireEvent ( 'cancel' , this . subject ) . clearChain ( ) ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
return this ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
pause : function ( ) {
if ( this . isRunning ( ) ) {
this . time = null ;
pullInstance . call ( this , this . options . fps ) ;
}
2008-07-05 22:28:49 +02:00
return this ;
} ,
2011-06-24 15:38:56 +02:00
resume : function ( ) {
if ( ( this . frame < this . frames ) && ! this . isRunning ( ) ) pushInstance . call ( this , this . options . fps ) ;
2008-07-05 22:28:49 +02:00
return this ;
} ,
2011-06-24 15:38:56 +02:00
isRunning : function ( ) {
var list = instances [ this . options . fps ] ;
return list && list . contains ( this ) ;
2008-07-05 22:28:49 +02:00
}
} ) ;
2011-06-24 15:38:56 +02:00
Fx . compute = function ( from , to , delta ) {
return ( to - from ) * delta + from ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Fx . Durations = { 'short' : 250 , 'normal' : 500 , 'long' : 1000 } ;
// global timers
var instances = { } , timers = { } ;
var loop = function ( ) {
var now = Date . now ( ) ;
for ( var i = this . length ; i -- ; ) {
var instance = this [ i ] ;
if ( instance ) instance . step ( now ) ;
}
} ;
var pushInstance = function ( fps ) {
var list = instances [ fps ] || ( instances [ fps ] = [ ] ) ;
list . push ( this ) ;
if ( ! timers [ fps ] ) timers [ fps ] = loop . periodical ( Math . round ( 1000 / fps ) , list ) ;
} ;
var pullInstance = function ( fps ) {
var list = instances [ fps ] ;
if ( list ) {
list . erase ( this ) ;
if ( ! list . length && timers [ fps ] ) {
delete instances [ fps ] ;
timers [ fps ] = clearInterval ( timers [ fps ] ) ;
}
}
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
} ) ( ) ;
2008-07-05 22:28:49 +02:00
/ *
2011-06-24 15:38:56 +02:00
-- -
name : Fx . CSS
description : Contains the CSS animation logic . Used by Fx . Tween , Fx . Morph , Fx . Elements .
license : MIT - style license .
requires : [ Fx , Element . Style ]
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
provides : Fx . CSS
...
2008-07-05 22:28:49 +02:00
* /
Fx . CSS = new Class ( {
Extends : Fx ,
//prepares the base from/to object
prepare : function ( element , property , values ) {
2011-06-24 15:38:56 +02:00
values = Array . from ( values ) ;
if ( values [ 1 ] == null ) {
2008-07-05 22:28:49 +02:00
values [ 1 ] = values [ 0 ] ;
values [ 0 ] = element . getStyle ( property ) ;
}
var parsed = values . map ( this . parse ) ;
return { from : parsed [ 0 ] , to : parsed [ 1 ] } ;
} ,
//parses a value into an array
parse : function ( value ) {
2011-06-24 15:38:56 +02:00
value = Function . from ( value ) ( ) ;
value = ( typeof value == 'string' ) ? value . split ( ' ' ) : Array . from ( value ) ;
2008-07-05 22:28:49 +02:00
return value . map ( function ( val ) {
val = String ( val ) ;
var found = false ;
2011-06-24 15:38:56 +02:00
Object . each ( Fx . CSS . Parsers , function ( parser , key ) {
2008-07-05 22:28:49 +02:00
if ( found ) return ;
var parsed = parser . parse ( val ) ;
2011-06-24 15:38:56 +02:00
if ( parsed || parsed === 0 ) found = { value : parsed , parser : parser } ;
2008-07-05 22:28:49 +02:00
} ) ;
found = found || { value : val , parser : Fx . CSS . Parsers . String } ;
return found ;
} ) ;
} ,
//computes by a from and to prepared objects, using their parsers.
compute : function ( from , to , delta ) {
var computed = [ ] ;
( Math . min ( from . length , to . length ) ) . times ( function ( i ) {
computed . push ( { value : from [ i ] . parser . compute ( from [ i ] . value , to [ i ] . value , delta ) , parser : from [ i ] . parser } ) ;
} ) ;
2011-06-24 15:38:56 +02:00
computed . $family = Function . from ( 'fx:css:value' ) ;
2008-07-05 22:28:49 +02:00
return computed ;
} ,
//serves the value as settable
serve : function ( value , unit ) {
2011-06-24 15:38:56 +02:00
if ( typeOf ( value ) != 'fx:css:value' ) value = this . parse ( value ) ;
2008-07-05 22:28:49 +02:00
var returned = [ ] ;
value . each ( function ( bit ) {
returned = returned . concat ( bit . parser . serve ( bit . value , unit ) ) ;
} ) ;
return returned ;
} ,
//renders the change to an element
render : function ( element , property , value , unit ) {
element . setStyle ( property , this . serve ( value , unit ) ) ;
} ,
//searches inside the page css to find the values for a selector
search : function ( selector ) {
if ( Fx . CSS . Cache [ selector ] ) return Fx . CSS . Cache [ selector ] ;
2011-06-24 15:38:56 +02:00
var to = { } , selectorTest = new RegExp ( '^' + selector . escapeRegExp ( ) + '$' ) ;
2008-07-05 22:28:49 +02:00
Array . each ( document . styleSheets , function ( sheet , j ) {
var href = sheet . href ;
if ( href && href . contains ( '://' ) && ! href . contains ( document . domain ) ) return ;
var rules = sheet . rules || sheet . cssRules ;
Array . each ( rules , function ( rule , i ) {
if ( ! rule . style ) return ;
var selectorText = ( rule . selectorText ) ? rule . selectorText . replace ( /^\w+/ , function ( m ) {
return m . toLowerCase ( ) ;
} ) : null ;
2011-06-24 15:38:56 +02:00
if ( ! selectorText || ! selectorTest . test ( selectorText ) ) return ;
Object . each ( Element . Styles , function ( value , style ) {
2008-07-05 22:28:49 +02:00
if ( ! rule . style [ style ] || Element . ShortStyles [ style ] ) return ;
value = String ( rule . style [ style ] ) ;
2011-06-24 15:38:56 +02:00
to [ style ] = ( ( /^rgb/ ) . test ( value ) ) ? value . rgbToHex ( ) : value ;
2008-07-05 22:28:49 +02:00
} ) ;
} ) ;
} ) ;
return Fx . CSS . Cache [ selector ] = to ;
}
} ) ;
Fx . CSS . Cache = { } ;
2011-06-24 15:38:56 +02:00
Fx . CSS . Parsers = {
2008-07-05 22:28:49 +02:00
Color : {
parse : function ( value ) {
if ( value . match ( /^#[0-9a-f]{3,6}$/i ) ) return value . hexToRgb ( true ) ;
return ( ( value = value . match ( /(\d+),\s*(\d+),\s*(\d+)/ ) ) ) ? [ value [ 1 ] , value [ 2 ] , value [ 3 ] ] : false ;
} ,
compute : function ( from , to , delta ) {
return from . map ( function ( value , i ) {
return Math . round ( Fx . compute ( from [ i ] , to [ i ] , delta ) ) ;
} ) ;
} ,
serve : function ( value ) {
return value . map ( Number ) ;
}
} ,
Number : {
parse : parseFloat ,
compute : Fx . compute ,
serve : function ( value , unit ) {
return ( unit ) ? value + unit : value ;
}
} ,
String : {
2011-06-24 15:38:56 +02:00
parse : Function . from ( false ) ,
compute : function ( zero , one ) {
return one ;
} ,
serve : function ( zero ) {
return zero ;
}
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
} ;
//<1.2compat>
Fx . CSS . Parsers = new Hash ( Fx . CSS . Parsers ) ;
//</1.2compat>
2008-07-05 22:28:49 +02:00
/ *
2011-06-24 15:38:56 +02:00
-- -
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
name : Fx . Tween
description : Formerly Fx . Style , effect to transition any CSS property for an element .
license : MIT - style license .
requires : Fx . CSS
provides : [ Fx . Tween , Element . fade , Element . highlight ]
...
2008-07-05 22:28:49 +02:00
* /
Fx . Tween = new Class ( {
Extends : Fx . CSS ,
initialize : function ( element , options ) {
2011-06-24 15:38:56 +02:00
this . element = this . subject = document . id ( element ) ;
2008-07-05 22:28:49 +02:00
this . parent ( options ) ;
} ,
set : function ( property , now ) {
if ( arguments . length == 1 ) {
now = property ;
property = this . property || this . options . property ;
}
this . render ( this . element , property , now , this . options . unit ) ;
return this ;
} ,
start : function ( property , from , to ) {
2011-06-24 15:38:56 +02:00
if ( ! this . check ( property , from , to ) ) return this ;
2008-07-05 22:28:49 +02:00
var args = Array . flatten ( arguments ) ;
this . property = this . options . property || args . shift ( ) ;
var parsed = this . prepare ( this . element , this . property , args ) ;
return this . parent ( parsed . from , parsed . to ) ;
}
} ) ;
Element . Properties . tween = {
set : function ( options ) {
2011-06-24 15:38:56 +02:00
this . get ( 'tween' ) . cancel ( ) . setOptions ( options ) ;
return this ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
get : function ( ) {
var tween = this . retrieve ( 'tween' ) ;
if ( ! tween ) {
tween = new Fx . Tween ( this , { link : 'cancel' } ) ;
this . store ( 'tween' , tween ) ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
return tween ;
2008-07-05 22:28:49 +02:00
}
} ;
Element . implement ( {
tween : function ( property , from , to ) {
this . get ( 'tween' ) . start ( arguments ) ;
return this ;
} ,
fade : function ( how ) {
var fade = this . get ( 'tween' ) , o = 'opacity' , toggle ;
2011-06-24 15:38:56 +02:00
how = [ how , 'toggle' ] . pick ( ) ;
2008-07-05 22:28:49 +02:00
switch ( how ) {
case 'in' : fade . start ( o , 1 ) ; break ;
case 'out' : fade . start ( o , 0 ) ; break ;
case 'show' : fade . set ( o , 1 ) ; break ;
case 'hide' : fade . set ( o , 0 ) ; break ;
case 'toggle' :
var flag = this . retrieve ( 'fade:flag' , this . get ( 'opacity' ) == 1 ) ;
fade . start ( o , ( flag ) ? 0 : 1 ) ;
this . store ( 'fade:flag' , ! flag ) ;
toggle = true ;
break ;
default : fade . start ( o , arguments ) ;
}
if ( ! toggle ) this . eliminate ( 'fade:flag' ) ;
return this ;
} ,
highlight : function ( start , end ) {
if ( ! end ) {
end = this . retrieve ( 'highlight:original' , this . getStyle ( 'background-color' ) ) ;
end = ( end == 'transparent' ) ? '#fff' : end ;
}
var tween = this . get ( 'tween' ) ;
tween . start ( 'background-color' , start || '#ffff88' , end ) . chain ( function ( ) {
this . setStyle ( 'background-color' , this . retrieve ( 'highlight:original' ) ) ;
tween . callChain ( ) ;
} . bind ( this ) ) ;
return this ;
}
} ) ;
/ *
2011-06-24 15:38:56 +02:00
-- -
name : Fx . Morph
description : Formerly Fx . Styles , effect to transition any number of CSS properties for an element using an object of rules , or CSS based selector rules .
license : MIT - style license .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
requires : Fx . CSS
provides : Fx . Morph
...
2008-07-05 22:28:49 +02:00
* /
Fx . Morph = new Class ( {
Extends : Fx . CSS ,
initialize : function ( element , options ) {
2011-06-24 15:38:56 +02:00
this . element = this . subject = document . id ( element ) ;
2008-07-05 22:28:49 +02:00
this . parent ( options ) ;
} ,
set : function ( now ) {
if ( typeof now == 'string' ) now = this . search ( now ) ;
for ( var p in now ) this . render ( this . element , p , now [ p ] , this . options . unit ) ;
return this ;
} ,
compute : function ( from , to , delta ) {
var now = { } ;
for ( var p in from ) now [ p ] = this . parent ( from [ p ] , to [ p ] , delta ) ;
return now ;
} ,
start : function ( properties ) {
2011-06-24 15:38:56 +02:00
if ( ! this . check ( properties ) ) return this ;
2008-07-05 22:28:49 +02:00
if ( typeof properties == 'string' ) properties = this . search ( properties ) ;
var from = { } , to = { } ;
for ( var p in properties ) {
var parsed = this . prepare ( this . element , p , properties [ p ] ) ;
from [ p ] = parsed . from ;
to [ p ] = parsed . to ;
}
return this . parent ( from , to ) ;
}
} ) ;
Element . Properties . morph = {
set : function ( options ) {
2011-06-24 15:38:56 +02:00
this . get ( 'morph' ) . cancel ( ) . setOptions ( options ) ;
return this ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
get : function ( ) {
var morph = this . retrieve ( 'morph' ) ;
if ( ! morph ) {
morph = new Fx . Morph ( this , { link : 'cancel' } ) ;
this . store ( 'morph' , morph ) ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
return morph ;
2008-07-05 22:28:49 +02:00
}
} ;
Element . implement ( {
morph : function ( props ) {
this . get ( 'morph' ) . start ( props ) ;
return this ;
}
2011-06-24 15:38:56 +02:00
} ) ;
/ *
-- -
name : Fx . Transitions
description : Contains a set of advanced transitions to be used with any of the Fx Classes .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
license : MIT - style license .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
credits :
- Easing Equations by Robert Penner , < http : //www.robertpenner.com/easing/>, modified and optimized to be used with MooTools.
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
requires : Fx
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
provides : Fx . Transitions
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
...
* /
Fx . implement ( {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
getTransition : function ( ) {
var trans = this . options . transition || Fx . Transitions . Sine . easeInOut ;
if ( typeof trans == 'string' ) {
var data = trans . split ( ':' ) ;
trans = Fx . Transitions ;
trans = trans [ data [ 0 ] ] || trans [ data [ 0 ] . capitalize ( ) ] ;
if ( data [ 1 ] ) trans = trans [ 'ease' + data [ 1 ] . capitalize ( ) + ( data [ 2 ] ? data [ 2 ] . capitalize ( ) : '' ) ] ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
return trans ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
} ) ;
2008-07-05 22:28:49 +02:00
Fx . Transition = function ( transition , params ) {
2011-06-24 15:38:56 +02:00
params = Array . from ( params ) ;
var easeIn = function ( pos ) {
return transition ( pos , params ) ;
} ;
return Object . append ( easeIn , {
easeIn : easeIn ,
2008-07-05 22:28:49 +02:00
easeOut : function ( pos ) {
return 1 - transition ( 1 - pos , params ) ;
} ,
easeInOut : function ( pos ) {
2011-06-24 15:38:56 +02:00
return ( pos <= 0.5 ? transition ( 2 * pos , params ) : ( 2 - transition ( 2 * ( 1 - pos ) , params ) ) ) / 2 ;
2008-07-05 22:28:49 +02:00
}
} ) ;
} ;
2011-06-24 15:38:56 +02:00
Fx . Transitions = {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
linear : function ( zero ) {
return zero ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
} ;
//<1.2compat>
Fx . Transitions = new Hash ( Fx . Transitions ) ;
//</1.2compat>
2008-07-05 22:28:49 +02:00
Fx . Transitions . extend = function ( transitions ) {
for ( var transition in transitions ) Fx . Transitions [ transition ] = new Fx . Transition ( transitions [ transition ] ) ;
} ;
Fx . Transitions . extend ( {
Pow : function ( p , x ) {
2011-06-24 15:38:56 +02:00
return Math . pow ( p , x && x [ 0 ] || 6 ) ;
2008-07-05 22:28:49 +02:00
} ,
Expo : function ( p ) {
return Math . pow ( 2 , 8 * ( p - 1 ) ) ;
} ,
Circ : function ( p ) {
return 1 - Math . sin ( Math . acos ( p ) ) ;
} ,
Sine : function ( p ) {
2011-06-24 15:38:56 +02:00
return 1 - Math . cos ( p * Math . PI / 2 ) ;
2008-07-05 22:28:49 +02:00
} ,
Back : function ( p , x ) {
2011-06-24 15:38:56 +02:00
x = x && x [ 0 ] || 1.618 ;
2008-07-05 22:28:49 +02:00
return Math . pow ( p , 2 ) * ( ( x + 1 ) * p - x ) ;
} ,
Bounce : function ( p ) {
var value ;
for ( var a = 0 , b = 1 ; 1 ; a += b , b /= 2 ) {
if ( p >= ( 7 - 4 * a ) / 11 ) {
2011-06-24 15:38:56 +02:00
value = b * b - Math . pow ( ( 11 - 6 * a - 11 * p ) / 4 , 2 ) ;
2008-07-05 22:28:49 +02:00
break ;
}
}
return value ;
} ,
Elastic : function ( p , x ) {
2011-06-24 15:38:56 +02:00
return Math . pow ( 2 , 10 * -- p ) * Math . cos ( 20 * p * Math . PI * ( x && x [ 0 ] || 1 ) / 3 ) ;
2008-07-05 22:28:49 +02:00
}
} ) ;
[ 'Quad' , 'Cubic' , 'Quart' , 'Quint' ] . each ( function ( transition , i ) {
Fx . Transitions [ transition ] = new Fx . Transition ( function ( p ) {
2011-06-24 15:38:56 +02:00
return Math . pow ( p , i + 2 ) ;
2008-07-05 22:28:49 +02:00
} ) ;
} ) ;
/ *
2011-06-24 15:38:56 +02:00
-- -
name : Request
description : Powerful all purpose Request Class . Uses XMLHTTPRequest .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
license : MIT - style license .
requires : [ Object , Element , Chain , Events , Options , Browser ]
provides : Request
...
2008-07-05 22:28:49 +02:00
* /
2011-06-24 15:38:56 +02:00
( function ( ) {
var empty = function ( ) { } ,
progressSupport = ( 'onprogress' in new Browser . Request ) ;
var Request = this . Request = new Class ( {
2008-07-05 22:28:49 +02:00
Implements : [ Chain , Events , Options ] ,
2011-06-24 15:38:56 +02:00
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 : '' , * /
2008-07-05 22:28:49 +02:00
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 ,
2011-06-24 15:38:56 +02:00
evalResponse : false ,
timeout : 0 ,
noCache : false
2008-07-05 22:28:49 +02:00
} ,
initialize : function ( options ) {
this . xhr = new Browser . Request ( ) ;
this . setOptions ( options ) ;
2011-06-24 15:38:56 +02:00
this . headers = this . options . headers ;
2008-07-05 22:28:49 +02:00
} ,
onStateChange : function ( ) {
2011-06-24 15:38:56 +02:00
var xhr = this . xhr ;
if ( xhr . readyState != 4 || ! this . running ) return ;
2008-07-05 22:28:49 +02:00
this . running = false ;
this . status = 0 ;
2011-06-24 15:38:56 +02:00
Function . attempt ( function ( ) {
var status = xhr . status ;
this . status = ( status == 1223 ) ? 204 : status ;
2008-07-05 22:28:49 +02:00
} . bind ( this ) ) ;
2011-06-24 15:38:56 +02:00
xhr . onreadystatechange = empty ;
if ( progressSupport ) xhr . onprogress = xhr . onloadstart = empty ;
clearTimeout ( this . timer ) ;
this . response = { text : this . xhr . responseText || '' , xml : this . xhr . responseXML } ;
if ( this . options . isSuccess . call ( this , this . status ) )
2008-07-05 22:28:49 +02:00
this . success ( this . response . text , this . response . xml ) ;
2011-06-24 15:38:56 +02:00
else
2008-07-05 22:28:49 +02:00
this . failure ( ) ;
} ,
isSuccess : function ( ) {
2011-06-24 15:38:56 +02:00
var status = this . status ;
return ( status >= 200 && status < 300 ) ;
} ,
isRunning : function ( ) {
return ! ! this . running ;
2008-07-05 22:28:49 +02:00
} ,
processScripts : function ( text ) {
2011-06-24 15:38:56 +02:00
if ( this . options . evalResponse || ( /(ecma|java)script/ ) . test ( this . getHeader ( 'Content-type' ) ) ) return Browser . exec ( text ) ;
2008-07-05 22:28:49 +02:00
return text . stripScripts ( this . options . evalScripts ) ;
} ,
success : function ( text , xml ) {
this . onSuccess ( this . processScripts ( text ) , xml ) ;
} ,
2011-06-24 15:38:56 +02:00
2008-07-05 22:28:49 +02:00
onSuccess : function ( ) {
this . fireEvent ( 'complete' , arguments ) . fireEvent ( 'success' , arguments ) . callChain ( ) ;
} ,
2011-06-24 15:38:56 +02:00
2008-07-05 22:28:49 +02:00
failure : function ( ) {
this . onFailure ( ) ;
} ,
onFailure : function ( ) {
this . fireEvent ( 'complete' ) . fireEvent ( 'failure' , this . xhr ) ;
} ,
2011-06-24 15:38:56 +02:00
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 = empty ;
if ( progressSupport ) xhr . onprogress = xhr . onloadstart = empty ;
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 ) {
var object = {
method : method
} ;
if ( data != null ) object . data = data ;
return this . send ( object ) ;
} ;
} ) ;
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 : Request . HTML
description : Extends the basic Request Class with additional methods for interacting with HTML responses .
license : MIT - style license .
requires : [ Element , Request ]
provides : Request . HTML
...
* /
Request . HTML = new Class ( {
Extends : Request ,
options : {
update : false ,
append : false ,
evalScripts : true ,
filter : false ,
headers : {
Accept : 'text/html, application/xml, text/xml, */*'
}
} ,
success : function ( text ) {
var options = this . options , response = this . response ;
response . html = text . stripScripts ( function ( script ) {
response . javascript = script ;
} ) ;
var match = response . html . match ( /<body[^>]*>([\s\S]*?)<\/body>/i ) ;
if ( match ) response . html = match [ 1 ] ;
var temp = new Element ( 'div' ) . set ( 'html' , response . html ) ;
response . tree = temp . childNodes ;
response . elements = temp . getElements ( '*' ) ;
if ( options . filter ) response . tree = response . elements . filter ( options . filter ) ;
if ( options . update ) document . id ( options . update ) . empty ( ) . set ( 'html' , response . html ) ;
else if ( options . append ) document . id ( options . append ) . adopt ( temp . getChildren ( ) ) ;
if ( options . evalScripts ) Browser . exec ( response . javascript ) ;
this . onSuccess ( response . tree , response . elements , response . html , response . javascript ) ;
}
} ) ;
Element . Properties . load = {
set : function ( options ) {
var load = this . get ( 'load' ) . cancel ( ) ;
load . setOptions ( options ) ;
return this ;
} ,
get : function ( ) {
var load = this . retrieve ( 'load' ) ;
if ( ! load ) {
load = new Request . HTML ( { data : this , link : 'cancel' , update : this , method : 'get' } ) ;
this . store ( 'load' , load ) ;
}
return load ;
}
} ;
Element . implement ( {
load : function ( ) {
this . get ( 'load' ) . send ( Array . link ( arguments , { data : Type . isObject , url : Type . isString } ) ) ;
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 ( typeof JSON == 'undefined' ) this . JSON = { } ;
//<1.2compat>
JSON = new Hash ( {
stringify : JSON . stringify ,
parse : JSON . parse
} ) ;
//</1.2compat>
( function ( ) {
var special = { '\b' : '\\b' , '\t' : '\\t' , '\n' : '\\n' , '\f' : '\\f' , '\r' : '\\r' , '"' : '\\"' , '\\' : '\\\\' } ;
var escape = function ( chr ) {
return special [ chr ] || '\\u' + ( '0000' + chr . charCodeAt ( 0 ) . toString ( 16 ) ) . slice ( - 4 ) ;
} ;
JSON . validate = function ( string ) {
string = string . replace ( /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g , '@' ) .
replace ( /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g , ']' ) .
replace ( /(?:^|:|,)(?:\s*\[)+/g , '' ) ;
return ( /^[\],:{}\s]*$/ ) . test ( string ) ;
} ;
JSON . encode = JSON . stringify ? function ( obj ) {
return JSON . stringify ( obj ) ;
} : function ( obj ) {
if ( obj && obj . toJSON ) obj = obj . toJSON ( ) ;
switch ( typeOf ( obj ) ) {
case 'string' :
return '"' + obj . replace ( /[\x00-\x1f\\"]/g , escape ) + '"' ;
case 'array' :
return '[' + 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 '' + obj ;
case 'null' : return 'null' ;
}
return null ;
} ;
JSON . decode = function ( string , secure ) {
if ( ! string || typeOf ( string ) != 'string' ) return null ;
if ( secure || JSON . secure ) {
if ( JSON . parse ) return JSON . parse ( string ) ;
if ( ! JSON . validate ( string ) ) throw new Error ( 'JSON could not decode the input; security is enabled and the value is not secure.' ) ;
}
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 ( {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Extends : Request ,
options : {
/*onError: function(text, error){},*/
secure : true
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
initialize : function ( options ) {
this . parent ( options ) ;
Object . append ( this . headers , {
'Accept' : 'application/json' ,
'X-Request' : 'JSON'
} ) ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
success : function ( text ) {
var json ;
try {
json = this . response . json = JSON . decode ( text , this . options . secure ) ;
} catch ( error ) {
this . fireEvent ( 'error' , [ text , error ] ) ;
return ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
if ( json == null ) this . onFailure ( ) ;
else this . onSuccess ( json , text ) ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
} ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
/ *
-- -
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
name : Cookie
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
description : Class for creating , reading , and deleting browser Cookies .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
license : MIT - style license .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
credits :
- Based on the functions by Peter - Paul Koch ( http : //quirksmode.org).
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
requires : [ Options , Browser ]
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
provides : Cookie
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
...
* /
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var Cookie = new Class ( {
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Implements : Options ,
options : {
path : '/' ,
domain : false ,
duration : false ,
secure : false ,
document : document ,
encode : true
} ,
initialize : function ( key , options ) {
this . key = key ;
this . setOptions ( options ) ;
} ,
write : function ( value ) {
if ( this . options . encode ) value = encodeURIComponent ( value ) ;
if ( this . options . domain ) value += '; domain=' + this . options . domain ;
if ( this . options . path ) value += '; path=' + this . options . path ;
if ( this . options . duration ) {
var date = new Date ( ) ;
date . setTime ( date . getTime ( ) + this . options . duration * 24 * 60 * 60 * 1000 ) ;
value += '; expires=' + date . toGMTString ( ) ;
}
if ( this . options . secure ) value += '; secure' ;
this . options . document . cookie = this . key + '=' + value ;
2008-07-05 22:28:49 +02:00
return this ;
} ,
2011-06-24 15:38:56 +02:00
read : function ( ) {
var value = this . options . document . cookie . match ( '(?:^|;)\\s*' + this . key . escapeRegExp ( ) + '=([^;]*)' ) ;
return ( value ) ? decodeURIComponent ( value [ 1 ] ) : null ;
} ,
dispose : function ( ) {
new Cookie ( this . key , Object . merge ( { } , this . options , { duration : - 1 } ) ) . write ( '' ) ;
2008-07-05 22:28:49 +02:00
return this ;
}
} ) ;
2011-06-24 15:38:56 +02:00
Cookie . write = function ( key , value , options ) {
return new Cookie ( key , options ) . write ( value ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Cookie . read = function ( key ) {
return new Cookie ( key ) . read ( ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Cookie . dispose = function ( key , options ) {
return new Cookie ( key , options ) . dispose ( ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
/ *
-- -
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 ,
testElement = document . createElement ( 'div' ) ;
var domready = function ( ) {
clearTimeout ( timer ) ;
if ( ready ) return ;
Browser . loaded = ready = true ;
document . removeListener ( 'DOMContentLoaded' , domready ) . removeListener ( 'readystatechange' , check ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
document . fireEvent ( 'domready' ) ;
window . fireEvent ( 'domready' ) ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var check = function ( ) {
for ( var i = checks . length ; i -- ; ) if ( checks [ i ] ( ) ) {
domready ( ) ;
return true ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
return false ;
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var poll = function ( ) {
clearTimeout ( timer ) ;
if ( ! check ( ) ) timer = setTimeout ( poll , 10 ) ;
2008-07-05 22:28:49 +02:00
} ;
2011-06-24 15:38:56 +02:00
document . addListener ( 'DOMContentLoaded' , domready ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
/*<ltIE8>*/
// doScroll technique by Diego Perini http://javascript.nwbox.com/IEContentLoaded/
// testElement.doScroll() throws when the DOM is not ready, only in the top window
var doScrollWorks = function ( ) {
try {
testElement . doScroll ( ) ;
return true ;
} catch ( e ) { }
return false ;
}
// If doScroll works already, it can't be used to determine domready
// e.g. in an iframe
if ( testElement . doScroll && ! doScrollWorks ( ) ) {
checks . push ( doScrollWorks ) ;
shouldPoll = true ;
}
/*</ltIE8>*/
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 ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
} ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
// This is based on the custom load event
window . addEvent ( 'load' , function ( ) {
loaded = true ;
2008-07-05 22:28:49 +02:00
} ) ;
2011-06-24 15:38:56 +02:00
} ) ( window , document ) ;
2008-07-05 22:28:49 +02:00
/ *
2011-06-24 15:38:56 +02:00
-- -
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
name : Swiff
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
description : Wrapper for embedding SWF movies . Supports External Interface Communication .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
license : MIT - style license .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
credits :
- Flash detection & Internet Explorer + Flash Player 9 fix inspired by SWFObject .
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
requires : [ Options , Object , Element ]
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
provides : Swiff
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
...
* /
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
( function ( ) {
var Swiff = this . Swiff = new Class ( {
Implements : Options ,
options : {
id : null ,
height : 1 ,
width : 1 ,
container : null ,
properties : { } ,
params : {
quality : 'high' ,
allowScriptAccess : 'always' ,
wMode : 'window' ,
swLiveConnect : true
} ,
callBacks : { } ,
vars : { }
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
toElement : function ( ) {
return this . object ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
initialize : function ( path , options ) {
this . instance = 'Swiff_' + String . uniqueID ( ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
this . setOptions ( options ) ;
options = this . options ;
var id = this . id = options . id || this . instance ;
var container = document . id ( options . container ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
Swiff . CallBacks [ this . instance ] = { } ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var params = options . params , vars = options . vars , callBacks = options . callBacks ;
var properties = Object . append ( { height : options . height , width : options . width } , options . properties ) ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var self = this ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
for ( var callBack in callBacks ) {
Swiff . CallBacks [ this . instance ] [ callBack ] = ( function ( option ) {
return function ( ) {
return option . apply ( self . object , arguments ) ;
} ;
} ) ( callBacks [ callBack ] ) ;
vars [ callBack ] = 'Swiff.CallBacks.' + this . instance + '.' + callBack ;
}
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
params . flashVars = Object . toQueryString ( vars ) ;
if ( Browser . ie ) {
properties . classid = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' ;
params . movie = path ;
} else {
properties . type = 'application/x-shockwave-flash' ;
}
properties . data = path ;
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
var build = '<object id="' + id + '"' ;
for ( var property in properties ) build += ' ' + property + '="' + properties [ property ] + '"' ;
build += '>' ;
for ( var param in params ) {
if ( params [ param ] ) build += '<param name="' + param + '" value="' + params [ param ] + '" />' ;
}
build += '</object>' ;
this . object = ( ( container ) ? container . empty ( ) : new Element ( 'div' ) ) . set ( 'html' , build ) . firstChild ;
} ,
2008-07-05 22:28:49 +02:00
2011-06-24 15:38:56 +02:00
replaces : function ( element ) {
element = document . id ( element , true ) ;
element . parentNode . replaceChild ( this . toElement ( ) , element ) ;
return this ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
inject : function ( element ) {
document . id ( element , true ) . appendChild ( this . toElement ( ) ) ;
return this ;
2008-07-05 22:28:49 +02:00
} ,
2011-06-24 15:38:56 +02:00
remote : function ( ) {
return Swiff . remote . apply ( Swiff , [ this . toElement ( ) ] . append ( arguments ) ) ;
2008-07-05 22:28:49 +02:00
}
2011-06-24 15:38:56 +02:00
} ) ;
Swiff . CallBacks = { } ;
Swiff . remote = function ( obj , fn ) {
var rs = obj . CallFunction ( '<invoke name="' + fn + '" returntype="javascript">' + _ _flash _ _argumentsToXML ( arguments , 2 ) + '</invoke>' ) ;
return eval ( rs ) ;
} ;
} ) ( ) ;