2017-11-23 00:46:02 +08:00
/* MooTools: the javascript framework. license: MIT-style license. copyright: Copyright (c) 2006-2017 [Valerio Proietti](https://mootools.net/).*/
/ * !
Web Build : https : //mootools.net/core/builder/e426a9ae7167c5807b173d5deff673fc
2015-04-13 06:52:01 +08:00
* /
2011-06-21 17:19:10 +08:00
/ *
-- -
name : Core
description : The heart of MooTools .
license : MIT - style license .
2017-11-23 00:46:02 +08:00
copyright : Copyright ( c ) 2006 - 2015 [ Valerio Proietti ] ( https : //github.com/kamicane/).
2011-06-21 17:19:10 +08:00
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 ]
...
* /
2017-11-23 00:46:02 +08:00
/*! MooTools: the javascript framework. license: MIT-style license. copyright: Copyright (c) 2006-2015 [Valerio Proietti](https://github.com/kamicane/).*/
2011-06-21 17:19:10 +08:00
( function ( ) {
this . MooTools = {
2017-11-23 00:46:02 +08:00
version : '1.6.0' ,
build : '529422872adfff401b901b8b6c7ca5114ee95e2b'
2011-06-21 17:19:10 +08:00
} ;
// typeOf, instanceOf
var typeOf = this . typeOf = function ( item ) {
if ( item == null ) return 'null' ;
2015-04-13 06:52:01 +08:00
if ( item . $family != null ) return item . $family ( ) ;
2011-06-21 17:19:10 +08: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' ) {
2017-11-23 00:46:02 +08:00
if ( 'callee' in item ) return 'arguments' ;
2011-06-21 17:19:10 +08:00
if ( 'item' in item ) return 'collection' ;
}
return typeof item ;
} ;
var instanceOf = this . instanceOf = function ( item , object ) {
if ( item == null ) return false ;
var constructor = item . $constructor || item . constructor ;
while ( constructor ) {
if ( constructor === object ) return true ;
constructor = constructor . parent ;
}
2015-04-13 06:52:01 +08:00
/*<ltIE8>*/
if ( ! item . hasOwnProperty ) return false ;
/*</ltIE8>*/
2011-06-21 17:19:10 +08:00
return item instanceof object ;
} ;
2017-11-23 00:46:02 +08:00
var hasOwnProperty = Object . prototype . hasOwnProperty ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
/*<ltIE8>*/
2011-06-21 17:19:10 +08:00
var enumerables = true ;
for ( var i in { toString : 1 } ) enumerables = null ;
if ( enumerables ) enumerables = [ 'hasOwnProperty' , 'valueOf' , 'isPrototypeOf' , 'propertyIsEnumerable' , 'toLocaleString' , 'toString' , 'constructor' ] ;
2017-11-23 00:46:02 +08:00
function forEachObjectEnumberableKey ( object , fn , bind ) {
if ( enumerables ) for ( var i = enumerables . length ; i -- ; ) {
var k = enumerables [ i ] ;
// signature has key-value, so overloadSetter can directly pass the
// method function, without swapping arguments.
if ( hasOwnProperty . call ( object , k ) ) fn . call ( bind , k , object [ k ] ) ;
}
}
/*</ltIE8>*/
// Function overloading
var Function = this . Function ;
2011-06-21 17:19:10 +08:00
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 ] ) ;
2017-11-23 00:46:02 +08:00
/*<ltIE8>*/
forEachObjectEnumberableKey ( a , self , this ) ;
/*</ltIE8>*/
2011-06-21 17:19:10 +08:00
} else {
self . call ( this , a , b ) ;
}
return this ;
} ;
} ;
Function . prototype . overloadGetter = function ( usePlural ) {
var self = this ;
return function ( a ) {
var args , result ;
2015-04-13 06:52:01 +08:00
if ( typeof a != 'string' ) args = a ;
2011-06-21 17:19:10 +08:00
else if ( arguments . length > 1 ) args = arguments ;
2015-04-13 06:52:01 +08:00
else if ( usePlural ) args = [ a ] ;
2011-06-21 17:19:10 +08:00
if ( args ) {
result = { } ;
for ( var i = 0 ; i < args . length ; i ++ ) result [ args [ i ] ] = self . call ( this , args [ i ] ) ;
} else {
result = self . call ( this , a ) ;
}
return result ;
} ;
} ;
Function . prototype . extend = function ( key , value ) {
this [ key ] = value ;
} . overloadSetter ( ) ;
Function . prototype . implement = function ( key , value ) {
this . prototype [ key ] = value ;
} . overloadSetter ( ) ;
// From
var slice = Array . prototype . slice ;
2017-11-23 00:46:02 +08:00
Array . convert = function ( item ) {
if ( item == null ) return [ ] ;
return ( Type . isEnumerable ( item ) && typeof item != 'string' ) ? ( typeOf ( item ) == 'array' ) ? item : slice . call ( item ) : [ item ] ;
} ;
Function . convert = function ( item ) {
2011-06-21 17:19:10 +08:00
return ( typeOf ( item ) == 'function' ) ? item : function ( ) {
return item ;
} ;
} ;
2017-11-23 00:46:02 +08:00
Number . convert = function ( item ) {
2011-06-21 17:19:10 +08:00
var number = parseFloat ( item ) ;
return isFinite ( number ) ? number : null ;
} ;
2017-11-23 00:46:02 +08:00
String . convert = function ( item ) {
2011-06-21 17:19:10 +08:00
return item + '' ;
} ;
2017-11-23 00:46:02 +08:00
Function . from = Function . convert ;
Number . from = Number . convert ;
String . from = String . convert ;
2011-06-21 17:19:10 +08:00
// hide, protect
Function . implement ( {
hide : function ( ) {
this . $hidden = true ;
return this ;
} ,
protect : function ( ) {
this . $protected = true ;
return this ;
}
} ) ;
// Type
var Type = this . Type = function ( name , object ) {
if ( name ) {
var lower = name . toLowerCase ( ) ;
var typeCheck = function ( item ) {
return ( typeOf ( item ) == lower ) ;
} ;
Type [ 'is' + name ] = typeCheck ;
if ( object != null ) {
object . prototype . $family = ( function ( ) {
return lower ;
} ) . hide ( ) ;
2017-11-23 00:46:02 +08:00
2011-06-21 17:19:10 +08:00
}
}
if ( object == null ) return null ;
object . extend ( this ) ;
object . $constructor = Type ;
object . prototype . $constructor = object ;
return object ;
} ;
var toString = Object . prototype . toString ;
Type . isEnumerable = function ( item ) {
return ( item != null && typeof item . length == 'number' && toString . call ( item ) != '[object Function]' ) ;
} ;
var hooks = { } ;
var hooksOf = function ( object ) {
var type = typeOf ( object . prototype ) ;
return hooks [ type ] || ( hooks [ type ] = [ ] ) ;
} ;
var implement = function ( name , method ) {
if ( method && method . $hidden ) return ;
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 ) ;
}
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08: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 ) ) ;
} ) ;
} ;
var extend = function ( name , method ) {
if ( method && method . $hidden ) return ;
var previous = this [ name ] ;
if ( previous == null || ! previous . $protected ) this [ name ] = method ;
} ;
Type . implement ( {
implement : implement . overloadSetter ( ) ,
extend : extend . overloadSetter ( ) ,
alias : function ( name , existing ) {
implement . call ( this , name , this . prototype [ existing ] ) ;
} . overloadSetter ( ) ,
mirror : function ( hook ) {
hooksOf ( this ) . push ( hook ) ;
return this ;
}
} ) ;
new Type ( 'Type' , Type ) ;
// Default Types
var force = function ( name , object , methods ) {
var isType = ( object != Object ) ,
prototype = object . prototype ;
if ( isType ) object = new Type ( name , object ) ;
for ( var i = 0 , l = methods . length ; i < l ; i ++ ) {
var key = methods [ i ] ,
generic = object [ key ] ,
proto = prototype [ key ] ;
if ( generic ) generic . protect ( ) ;
2015-04-13 06:52:01 +08:00
if ( isType && proto ) object . implement ( key , proto . protect ( ) ) ;
2011-06-21 17:19:10 +08:00
}
2015-04-13 06:52:01 +08:00
if ( isType ) {
var methodsEnumerable = prototype . propertyIsEnumerable ( methods [ 0 ] ) ;
object . forEachMethod = function ( fn ) {
if ( ! methodsEnumerable ) for ( var i = 0 , l = methods . length ; i < l ; i ++ ) {
fn . call ( prototype , prototype [ methods [ i ] ] , methods [ i ] ) ;
}
2017-11-23 00:46:02 +08:00
for ( var key in prototype ) fn . call ( prototype , prototype [ key ] , key ) ;
2015-04-13 06:52:01 +08:00
} ;
}
2011-06-21 17:19:10 +08:00
return force ;
} ;
force ( 'String' , String , [
2017-11-23 00:46:02 +08:00
'charAt' , 'charCodeAt' , 'concat' , 'contains' , 'indexOf' , 'lastIndexOf' , 'match' , 'quote' , 'replace' , 'search' ,
2015-04-13 06:52:01 +08:00
'slice' , 'split' , 'substr' , 'substring' , 'trim' , 'toLowerCase' , 'toUpperCase'
2011-06-21 17:19:10 +08:00
] ) ( 'Array' , Array , [
'pop' , 'push' , 'reverse' , 'shift' , 'sort' , 'splice' , 'unshift' , 'concat' , 'join' , 'slice' ,
2017-11-23 00:46:02 +08:00
'indexOf' , 'lastIndexOf' , 'filter' , 'forEach' , 'every' , 'map' , 'some' , 'reduce' , 'reduceRight' , 'contains'
2011-06-21 17:19:10 +08:00
] ) ( 'Number' , Number , [
'toExponential' , 'toFixed' , 'toLocaleString' , 'toPrecision'
] ) ( 'Function' , Function , [
'apply' , 'call' , 'bind'
] ) ( 'RegExp' , RegExp , [
'exec' , 'test'
] ) ( 'Object' , Object , [
'create' , 'defineProperty' , 'defineProperties' , 'keys' ,
'getPrototypeOf' , 'getOwnPropertyDescriptor' , 'getOwnPropertyNames' ,
'preventExtensions' , 'isExtensible' , 'seal' , 'isSealed' , 'freeze' , 'isFrozen'
] ) ( 'Date' , Date , [ 'now' ] ) ;
Object . extend = extend . overloadSetter ( ) ;
Date . extend ( 'now' , function ( ) {
return + ( new Date ) ;
} ) ;
new Type ( 'Boolean' , Boolean ) ;
// fixes NaN returning as Number
Number . prototype . $family = function ( ) {
return isFinite ( this ) ? 'number' : 'null' ;
} . hide ( ) ;
// Number.random
Number . extend ( 'random' , function ( min , max ) {
return Math . floor ( Math . random ( ) * ( max - min + 1 ) + min ) ;
} ) ;
2017-11-23 00:46:02 +08:00
// forEach, each, keys
2011-06-21 17:19:10 +08:00
Array . implement ( {
2017-11-23 00:46:02 +08:00
/*<!ES5>*/
2011-06-21 17:19:10 +08:00
forEach : function ( fn , bind ) {
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
if ( i in this ) fn . call ( bind , this [ i ] , i , this ) ;
}
} ,
2017-11-23 00:46:02 +08:00
/*</!ES5>*/
2011-06-21 17:19:10 +08:00
each : function ( fn , bind ) {
Array . forEach ( this , fn , bind ) ;
return this ;
}
} ) ;
2017-11-23 00:46:02 +08:00
Object . extend ( {
keys : function ( object ) {
var keys = [ ] ;
for ( var k in object ) {
if ( hasOwnProperty . call ( object , k ) ) keys . push ( k ) ;
}
/*<ltIE8>*/
forEachObjectEnumberableKey ( object , function ( k ) {
keys . push ( k ) ;
} ) ;
/*</ltIE8>*/
return keys ;
} ,
forEach : function ( object , fn , bind ) {
Object . keys ( object ) . forEach ( function ( key ) {
fn . call ( bind , object [ key ] , key , object ) ;
} ) ;
}
} ) ;
Object . each = Object . forEach ;
2011-06-21 17:19:10 +08:00
// Array & Object cloning, Object merging and appending
var cloneOf = function ( item ) {
switch ( typeOf ( item ) ) {
case 'array' : return item . clone ( ) ;
case 'object' : return Object . clone ( item ) ;
default : return item ;
}
} ;
Array . implement ( 'clone' , function ( ) {
var i = this . length , clone = new Array ( i ) ;
while ( i -- ) clone [ i ] = cloneOf ( this [ i ] ) ;
return clone ;
} ) ;
var mergeOne = function ( source , key , current ) {
switch ( typeOf ( current ) ) {
case 'object' :
if ( typeOf ( source [ key ] ) == 'object' ) Object . merge ( source [ key ] , current ) ;
else source [ key ] = Object . clone ( current ) ;
2017-11-23 00:46:02 +08:00
break ;
2011-06-21 17:19:10 +08:00
case 'array' : source [ key ] = current . clone ( ) ; break ;
default : source [ key ] = current ;
}
return source ;
} ;
Object . extend ( {
merge : function ( source , k , v ) {
if ( typeOf ( k ) == 'string' ) return mergeOne ( source , k , v ) ;
for ( var i = 1 , l = arguments . length ; i < l ; i ++ ) {
var object = arguments [ i ] ;
for ( var key in object ) mergeOne ( source , key , object [ key ] ) ;
}
return source ;
} ,
clone : function ( object ) {
var clone = { } ;
for ( var key in object ) clone [ key ] = cloneOf ( object [ key ] ) ;
return clone ;
} ,
append : function ( original ) {
for ( var i = 1 , l = arguments . length ; i < l ; i ++ ) {
var extended = arguments [ i ] || { } ;
for ( var key in extended ) original [ key ] = extended [ key ] ;
}
return original ;
}
} ) ;
// Object-less types
[ 'Object' , 'WhiteSpace' , 'TextNode' , 'Collection' , 'Arguments' ] . each ( function ( name ) {
new Type ( name ) ;
} ) ;
// Unique ID
var UID = Date . now ( ) ;
String . extend ( 'uniqueID' , function ( ) {
return ( UID ++ ) . toString ( 36 ) ;
} ) ;
2015-05-10 06:23:01 +08:00
2011-06-21 17:19:10 +08:00
} ) ( ) ;
/ *
-- -
name : Array
description : Contains Array Prototypes like each , contains , and erase .
license : MIT - style license .
2017-11-23 00:46:02 +08:00
requires : [ Type ]
2011-06-21 17:19:10 +08:00
provides : Array
...
* /
Array . implement ( {
/*<!ES5>*/
every : function ( fn , bind ) {
2015-04-13 06:52:01 +08:00
for ( var i = 0 , l = this . length >>> 0 ; i < l ; i ++ ) {
2011-06-21 17:19:10 +08:00
if ( ( i in this ) && ! fn . call ( bind , this [ i ] , i , this ) ) return false ;
}
return true ;
} ,
filter : function ( fn , bind ) {
var results = [ ] ;
2015-04-13 06:52:01 +08:00
for ( var value , i = 0 , l = this . length >>> 0 ; i < l ; i ++ ) if ( i in this ) {
value = this [ i ] ;
if ( fn . call ( bind , value , i , this ) ) results . push ( value ) ;
2011-06-21 17:19:10 +08:00
}
return results ;
} ,
indexOf : function ( item , from ) {
2015-04-13 06:52:01 +08:00
var length = this . length >>> 0 ;
for ( var i = ( from < 0 ) ? Math . max ( 0 , length + from ) : from || 0 ; i < length ; i ++ ) {
2011-06-21 17:19:10 +08:00
if ( this [ i ] === item ) return i ;
}
return - 1 ;
} ,
map : function ( fn , bind ) {
2015-04-13 06:52:01 +08:00
var length = this . length >>> 0 , results = Array ( length ) ;
for ( var i = 0 ; i < length ; i ++ ) {
2011-06-21 17:19:10 +08:00
if ( i in this ) results [ i ] = fn . call ( bind , this [ i ] , i , this ) ;
}
return results ;
} ,
some : function ( fn , bind ) {
2015-04-13 06:52:01 +08:00
for ( var i = 0 , l = this . length >>> 0 ; i < l ; i ++ ) {
2011-06-21 17:19:10 +08:00
if ( ( i in this ) && fn . call ( bind , this [ i ] , i , this ) ) return true ;
}
return false ;
} ,
/*</!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 ) ;
} ) ;
} ,
associate : function ( keys ) {
var obj = { } , length = Math . min ( this . length , keys . length ) ;
for ( var i = 0 ; i < length ; i ++ ) obj [ keys [ i ] ] = this [ i ] ;
return obj ;
} ,
link : function ( object ) {
var result = { } ;
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
for ( var key in object ) {
if ( object [ key ] ( this [ i ] ) ) {
result [ key ] = this [ i ] ;
delete object [ key ] ;
break ;
}
}
}
return result ;
} ,
contains : function ( item , from ) {
return this . indexOf ( item , from ) != - 1 ;
} ,
append : function ( array ) {
this . push . apply ( this , array ) ;
return this ;
} ,
getLast : function ( ) {
return ( this . length ) ? this [ this . length - 1 ] : null ;
} ,
getRandom : function ( ) {
return ( this . length ) ? this [ Number . random ( 0 , this . length - 1 ) ] : null ;
} ,
include : function ( item ) {
if ( ! this . contains ( item ) ) this . push ( item ) ;
return this ;
} ,
combine : function ( array ) {
for ( var i = 0 , l = array . length ; i < l ; i ++ ) this . include ( array [ i ] ) ;
return this ;
} ,
erase : function ( item ) {
for ( var i = this . length ; i -- ; ) {
if ( this [ i ] === item ) this . splice ( i , 1 ) ;
}
return this ;
} ,
empty : function ( ) {
this . length = 0 ;
return this ;
} ,
flatten : function ( ) {
var array = [ ] ;
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
var type = typeOf ( this [ i ] ) ;
if ( type == 'null' ) continue ;
array = array . concat ( ( type == 'array' || type == 'collection' || type == 'arguments' || instanceOf ( this [ i ] , Array ) ) ? Array . flatten ( this [ i ] ) : this [ i ] ) ;
}
return array ;
} ,
pick : function ( ) {
for ( var i = 0 , l = this . length ; i < l ; i ++ ) {
if ( this [ i ] != null ) return this [ i ] ;
}
return null ;
} ,
hexToRgb : function ( array ) {
if ( this . length != 3 ) return null ;
var rgb = this . map ( function ( value ) {
if ( value . length == 1 ) value += value ;
2017-11-23 00:46:02 +08:00
return parseInt ( value , 16 ) ;
2011-06-21 17:19:10 +08:00
} ) ;
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 ( '' ) ;
}
} ) ;
/ *
-- -
2017-11-23 00:46:02 +08:00
name : Function
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
description : Contains Function Prototypes like create , bind , pass , and delay .
2011-06-21 17:19:10 +08:00
license : MIT - style license .
requires : Type
2017-11-23 00:46:02 +08:00
provides : Function
2011-06-21 17:19:10 +08:00
...
* /
2017-11-23 00:46:02 +08:00
Function . extend ( {
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
attempt : function ( ) {
for ( var i = 0 , l = arguments . length ; i < l ; i ++ ) {
try {
return arguments [ i ] ( ) ;
} catch ( e ) { }
}
return null ;
}
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
} ) ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
Function . implement ( {
2015-04-13 06:52:01 +08:00
2017-11-23 00:46:02 +08:00
attempt : function ( args , bind ) {
try {
return this . apply ( bind , Array . convert ( args ) ) ;
} catch ( e ) { }
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
return null ;
2011-06-21 17:19:10 +08:00
} ,
2017-11-23 00:46:02 +08:00
/*<!ES5-bind>*/
bind : function ( that ) {
var self = this ,
args = arguments . length > 1 ? Array . slice ( arguments , 1 ) : null ,
F = function ( ) { } ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
var bound = function ( ) {
var context = that , length = arguments . length ;
if ( this instanceof bound ) {
F . prototype = self . prototype ;
context = new F ;
}
var result = ( ! args && ! length )
? self . call ( context )
: self . apply ( context , args && length ? args . concat ( Array . slice ( arguments ) ) : args || arguments ) ;
return context == that ? result : context ;
} ;
return bound ;
2015-05-10 06:23:01 +08:00
} ,
2017-11-23 00:46:02 +08:00
/*</!ES5-bind>*/
2015-05-10 06:23:01 +08:00
2017-11-23 00:46:02 +08:00
pass : function ( args , bind ) {
var self = this ;
if ( args != null ) args = Array . convert ( args ) ;
return function ( ) {
return self . apply ( bind , args || arguments ) ;
} ;
2015-05-10 06:23:01 +08:00
} ,
2017-11-23 00:46:02 +08:00
delay : function ( delay , bind , args ) {
return setTimeout ( this . pass ( ( args == null ? [ ] : args ) , bind ) , delay ) ;
2015-05-10 06:23:01 +08:00
} ,
2017-11-23 00:46:02 +08:00
periodical : function ( periodical , bind , args ) {
return setInterval ( this . pass ( ( args == null ? [ ] : args ) , bind ) , periodical ) ;
2011-06-21 17:19:10 +08:00
}
} ) ;
2017-11-23 00:46:02 +08:00
2011-06-21 17:19:10 +08:00
/ *
-- -
name : Number
description : Contains Number Prototypes like limit , round , times , and ceil .
license : MIT - style license .
requires : Type
provides : Number
...
* /
Number . implement ( {
limit : function ( min , max ) {
return Math . min ( max , Math . max ( min , this ) ) ;
} ,
round : function ( precision ) {
precision = Math . pow ( 10 , precision || 0 ) . toFixed ( precision < 0 ? - precision : 0 ) ;
return Math . round ( this * precision ) / precision ;
} ,
times : function ( fn , bind ) {
for ( var i = 0 ; i < this ; i ++ ) fn . call ( bind , i , this ) ;
} ,
toFloat : function ( ) {
return parseFloat ( this ) ;
} ,
toInt : function ( base ) {
return parseInt ( this , base || 10 ) ;
}
} ) ;
Number . alias ( 'each' , 'times' ) ;
( function ( math ) {
2017-11-23 00:46:02 +08:00
var methods = { } ;
math . each ( function ( name ) {
if ( ! Number [ name ] ) methods [ name ] = function ( ) {
return Math [ name ] . apply ( null , [ this ] . concat ( Array . convert ( arguments ) ) ) ;
} ;
} ) ;
Number . implement ( methods ) ;
} ) ( [ 'abs' , 'acos' , 'asin' , 'atan' , 'atan2' , 'ceil' , 'cos' , 'exp' , 'floor' , 'log' , 'max' , 'min' , 'pow' , 'sin' , 'sqrt' , 'tan' ] ) ;
2015-05-10 06:23:01 +08:00
2011-06-21 17:19:10 +08:00
/ *
-- -
2017-11-23 00:46:02 +08:00
name : String
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
description : Contains String Prototypes like camelCase , capitalize , test , and toInt .
2011-06-21 17:19:10 +08:00
license : MIT - style license .
2017-11-23 00:46:02 +08:00
requires : [ Type , Array ]
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
provides : String
2011-06-21 17:19:10 +08:00
...
* /
2017-11-23 00:46:02 +08:00
String . implement ( {
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
//<!ES6>
contains : function ( string , index ) {
return ( index ? String ( this ) . slice ( index ) : String ( this ) ) . indexOf ( string ) > - 1 ;
} ,
//</!ES6>
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
test : function ( regex , params ) {
return ( ( typeOf ( regex ) == 'regexp' ) ? regex : new RegExp ( '' + regex , params ) ) . test ( this ) ;
} ,
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
trim : function ( ) {
return String ( this ) . replace ( /^\s+|\s+$/g , '' ) ;
} ,
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
clean : function ( ) {
return String ( this ) . replace ( /\s+/g , ' ' ) . trim ( ) ;
2011-06-21 17:19:10 +08:00
} ,
2017-11-23 00:46:02 +08:00
camelCase : function ( ) {
return String ( this ) . replace ( /-\D/g , function ( match ) {
return match . charAt ( 1 ) . toUpperCase ( ) ;
2015-04-13 06:52:01 +08:00
} ) ;
2015-05-10 06:23:01 +08:00
} ,
2017-11-23 00:46:02 +08:00
hyphenate : function ( ) {
return String ( this ) . replace ( /[A-Z]/g , function ( match ) {
return ( '-' + match . charAt ( 0 ) . toLowerCase ( ) ) ;
} ) ;
2015-05-10 06:23:01 +08:00
} ,
2017-11-23 00:46:02 +08:00
capitalize : function ( ) {
return String ( this ) . replace ( /\b[a-z]/g , function ( match ) {
return match . toUpperCase ( ) ;
} ) ;
2015-05-10 06:23:01 +08:00
} ,
2017-11-23 00:46:02 +08:00
escapeRegExp : function ( ) {
return String ( this ) . replace ( /([-.*+?^${}()|[\]\/\\])/g , '\\$1' ) ;
2015-05-10 06:23:01 +08:00
} ,
2017-11-23 00:46:02 +08:00
toInt : function ( base ) {
return parseInt ( this , base || 10 ) ;
2015-05-10 06:23:01 +08:00
} ,
2017-11-23 00:46:02 +08:00
toFloat : function ( ) {
return parseFloat ( this ) ;
2015-05-10 06:23:01 +08:00
} ,
2017-11-23 00:46:02 +08:00
hexToRgb : function ( array ) {
var hex = String ( this ) . match ( /^#?(\w{1,2})(\w{1,2})(\w{1,2})$/ ) ;
return ( hex ) ? hex . slice ( 1 ) . hexToRgb ( array ) : null ;
2015-05-10 06:23:01 +08:00
} ,
2017-11-23 00:46:02 +08:00
rgbToHex : function ( array ) {
var rgb = String ( this ) . match ( /\d{1,3}/g ) ;
return ( rgb ) ? rgb . rgbToHex ( array ) : null ;
2015-05-10 06:23:01 +08:00
} ,
2017-11-23 00:46:02 +08:00
substitute : function ( object , regexp ) {
return String ( this ) . replace ( regexp || ( /\\?\{([^{}]+)\}/g ) , function ( match , name ) {
if ( match . charAt ( 0 ) == '\\' ) return match . slice ( 1 ) ;
return ( object [ name ] != null ) ? object [ name ] : '' ;
} ) ;
2015-05-10 06:23:01 +08:00
}
} ) ;
2011-06-21 17:19:10 +08:00
/ *
-- -
2015-04-13 06:52:01 +08:00
name : Browser
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
description : The Browser Object . Contains Browser initialization , Window and Document , and the Browser Hash .
2011-06-21 17:19:10 +08:00
license : MIT - style license .
2015-04-13 06:52:01 +08:00
requires : [ Array , Function , Number , String ]
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
provides : [ Browser , Window , Document ]
2011-06-21 17:19:10 +08:00
...
* /
( function ( ) {
2015-04-13 06:52:01 +08:00
var document = this . document ;
var window = document . window = this ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
var parse = function ( ua , platform ) {
ua = ua . toLowerCase ( ) ;
platform = ( platform ? platform . toLowerCase ( ) : '' ) ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
// chrome is included in the edge UA, so need to check for edge first,
// before checking if it's chrome.
var UA = ua . match ( /(edge)[\s\/:]([\w\d\.]+)/ ) ;
if ( ! UA ) {
UA = ua . match ( /(opera|ie|firefox|chrome|trident|crios|version)[\s\/:]([\w\d\.]+)?.*?(safari|(?:rv[\s\/:]|version[\s\/:])([\w\d\.]+)|$)/ ) || [ null , 'unknown' , 0 ] ;
}
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
if ( UA [ 1 ] == 'trident' ) {
UA [ 1 ] = 'ie' ;
if ( UA [ 4 ] ) UA [ 2 ] = UA [ 4 ] ;
} else if ( UA [ 1 ] == 'crios' ) {
UA [ 1 ] = 'chrome' ;
}
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
platform = ua . match ( /ip(?:ad|od|hone)/ ) ? 'ios' : ( ua . match ( /(?:webos|android)/ ) || ua . match ( /mac|win|linux/ ) || [ 'other' ] ) [ 0 ] ;
if ( platform == 'win' ) platform = 'windows' ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
return {
extend : Function . prototype . extend ,
name : ( UA [ 1 ] == 'version' ) ? UA [ 3 ] : UA [ 1 ] ,
version : parseFloat ( ( UA [ 1 ] == 'opera' && UA [ 4 ] ) ? UA [ 4 ] : UA [ 2 ] ) ,
platform : platform
} ;
} ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
var Browser = this . Browser = parse ( navigator . userAgent , navigator . platform ) ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
if ( Browser . name == 'ie' && document . documentMode ) {
Browser . version = document . documentMode ;
}
Browser . extend ( {
2015-04-13 06:52:01 +08:00
Features : {
xpath : ! ! ( document . evaluate ) ,
air : ! ! ( window . runtime ) ,
query : ! ! ( document . querySelector ) ,
json : ! ! ( window . JSON )
2011-06-21 17:19:10 +08:00
} ,
2017-11-23 00:46:02 +08:00
parseUA : parse
} ) ;
2011-06-21 17:19:10 +08:00
2015-05-10 06:23:01 +08:00
2011-06-21 17:19:10 +08:00
// Request
Browser . Request = ( function ( ) {
var XMLHTTP = function ( ) {
return new XMLHttpRequest ( ) ;
} ;
var MSXML2 = function ( ) {
return new ActiveXObject ( 'MSXML2.XMLHTTP' ) ;
} ;
var MSXML = function ( ) {
return new ActiveXObject ( 'Microsoft.XMLHTTP' ) ;
} ;
return Function . attempt ( function ( ) {
XMLHTTP ( ) ;
return XMLHTTP ;
} , function ( ) {
MSXML2 ( ) ;
return MSXML2 ;
} , function ( ) {
MSXML ( ) ;
return MSXML ;
} ) ;
} ) ( ) ;
Browser . Features . xhr = ! ! ( Browser . Request ) ;
// String scripts
Browser . exec = function ( text ) {
if ( ! text ) return text ;
if ( window . execScript ) {
window . execScript ( text ) ;
} else {
var script = document . createElement ( 'script' ) ;
script . setAttribute ( 'type' , 'text/javascript' ) ;
script . text = text ;
document . head . appendChild ( script ) ;
document . head . removeChild ( script ) ;
}
return text ;
} ;
String . implement ( 'stripScripts' , function ( exec ) {
var scripts = '' ;
var text = this . replace ( /<script[^>]*>([\s\S]*?)<\/script>/gi , function ( all , code ) {
scripts += code + '\n' ;
return '' ;
} ) ;
if ( exec === true ) Browser . exec ( scripts ) ;
else if ( typeOf ( exec ) == 'function' ) exec ( scripts , text ) ;
return text ;
} ) ;
// Window, Document
Browser . extend ( {
Document : this . Document ,
Window : this . Window ,
2017-11-23 00:46:02 +08:00
Element : this . Element ,
Event : this . Event
} ) ;
2015-05-10 06:23:01 +08:00
2017-11-23 00:46:02 +08:00
this . Window = this . $constructor = new Type ( 'Window' , function ( ) { } ) ;
this . $family = Function . convert ( 'window' ) . hide ( ) ;
2015-05-10 06:23:01 +08:00
2017-11-23 00:46:02 +08:00
Window . mirror ( function ( name , method ) {
window [ name ] = method ;
2015-05-10 06:23:01 +08:00
} ) ;
2017-11-23 00:46:02 +08:00
this . Document = document . $constructor = new Type ( 'Document' , function ( ) { } ) ;
2015-05-10 06:23:01 +08:00
2017-11-23 00:46:02 +08:00
document . $family = Function . convert ( 'document' ) . hide ( ) ;
2015-05-10 06:23:01 +08:00
2017-11-23 00:46:02 +08:00
Document . mirror ( function ( name , method ) {
document [ name ] = method ;
2015-05-10 06:23:01 +08:00
} ) ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
document . html = document . documentElement ;
if ( ! document . head ) document . head = document . getElementsByTagName ( 'head' ) [ 0 ] ;
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 ;
window = this . Window = document = null ;
} ;
this . attachEvent ( 'onunload' , unloadEvent ) ;
}
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
// IE fails on collections and <select>.options (refers to <select>)
var arrayFrom = Array . convert ;
try {
arrayFrom ( document . html . childNodes ) ;
} catch ( e ) {
Array . convert = 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 ) ;
} ;
2015-05-10 06:23:01 +08:00
2017-11-23 00:46:02 +08:00
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 . convert ( item ) , slice . call ( arguments , 1 ) ) ;
} ;
} ) ;
}
/*</ltIE9>*/
2015-05-10 06:23:01 +08:00
2017-11-23 00:46:02 +08:00
} ) ( ) ;
2015-05-10 06:23:01 +08:00
2011-06-21 17:19:10 +08: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
...
* /
( function ( ) {
var Class = this . Class = new Type ( 'Class' , function ( params ) {
if ( instanceOf ( params , Function ) ) params = { initialize : params } ;
var newClass = function ( ) {
reset ( this ) ;
if ( newClass . $prototyping ) return this ;
this . $caller = null ;
2017-11-23 00:46:02 +08:00
this . $family = null ;
2011-06-21 17:19:10 +08:00
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 ) ;
2017-11-23 00:46:02 +08:00
break ;
2011-06-21 17:19:10 +08:00
case 'array' : object [ key ] = value . clone ( ) ; break ;
}
}
return object ;
} ;
var wrap = function ( self , key , method ) {
if ( method . $origin ) method = method . $origin ;
var wrapper = function ( ) {
if ( method . $protected && this . $caller == null ) throw new Error ( 'The method "' + key + '" cannot be called.' ) ;
var caller = this . caller , current = this . $caller ;
this . caller = current ; this . $caller = wrapper ;
var result = method . apply ( this , arguments ) ;
this . $caller = current ; this . caller = caller ;
return result ;
} . extend ( { $owner : self , $origin : method , $name : key } ) ;
return wrapper ;
} ;
var implement = function ( key , value , retain ) {
if ( Class . Mutators . hasOwnProperty ( key ) ) {
value = Class . Mutators [ key ] . call ( this , value ) ;
if ( value == null ) return this ;
}
if ( typeOf ( value ) == 'function' ) {
if ( value . $hidden ) return this ;
this . prototype [ key ] = ( retain ) ? value : wrap ( this , key , value ) ;
} else {
Object . merge ( this . prototype , key , value ) ;
}
return this ;
} ;
var getInstance = function ( klass ) {
klass . $prototyping = true ;
var proto = new klass ;
delete klass . $prototyping ;
return proto ;
} ;
Class . implement ( 'implement' , implement . overloadSetter ( ) ) ;
Class . Mutators = {
Extends : function ( parent ) {
this . parent = parent ;
this . prototype = getInstance ( parent ) ;
} ,
Implements : function ( items ) {
2017-11-23 00:46:02 +08:00
Array . convert ( items ) . each ( function ( item ) {
2011-06-21 17:19:10 +08:00
var instance = new item ;
for ( var key in instance ) implement . call ( this , key , instance [ key ] , true ) ;
} , this ) ;
}
} ;
} ) ( ) ;
/ *
-- -
name : Class . Extras
description : Contains Utility Classes that can be implemented into your own Classes to ease the execution of many common tasks .
license : MIT - style license .
requires : Class
provides : [ Class . Extras , Chain , Events , Options ]
...
* /
( function ( ) {
this . Chain = new Class ( {
$chain : [ ] ,
chain : function ( ) {
this . $chain . append ( Array . flatten ( arguments ) ) ;
return this ;
} ,
callChain : function ( ) {
return ( this . $chain . length ) ? this . $chain . shift ( ) . apply ( this , arguments ) : false ;
} ,
clearChain : function ( ) {
this . $chain . empty ( ) ;
return this ;
}
} ) ;
var removeOn = function ( string ) {
return string . replace ( /^on([A-Z])/ , function ( full , first ) {
return first . toLowerCase ( ) ;
} ) ;
} ;
this . Events = new Class ( {
$events : { } ,
addEvent : function ( type , fn , internal ) {
type = removeOn ( type ) ;
2017-11-23 00:46:02 +08:00
2011-06-21 17:19:10 +08:00
this . $events [ type ] = ( this . $events [ type ] || [ ] ) . include ( fn ) ;
if ( internal ) fn . internal = true ;
return this ;
} ,
addEvents : function ( events ) {
for ( var type in events ) this . addEvent ( type , events [ type ] ) ;
return this ;
} ,
fireEvent : function ( type , args , delay ) {
type = removeOn ( type ) ;
var events = this . $events [ type ] ;
if ( ! events ) return this ;
2017-11-23 00:46:02 +08:00
args = Array . convert ( args ) ;
2011-06-21 17:19:10 +08:00
events . each ( function ( fn ) {
if ( delay ) fn . delay ( delay , this , args ) ;
else fn . apply ( this , args ) ;
} , this ) ;
return this ;
} ,
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
removeEvent : function ( type , fn ) {
type = removeOn ( type ) ;
var events = this . $events [ type ] ;
if ( events && ! fn . internal ) {
2017-11-23 00:46:02 +08:00
var index = events . indexOf ( fn ) ;
2011-06-21 17:19:10 +08:00
if ( index != - 1 ) delete events [ index ] ;
}
return this ;
} ,
removeEvents : function ( events ) {
var type ;
if ( typeOf ( events ) == 'object' ) {
for ( type in events ) this . removeEvent ( type , events [ type ] ) ;
return this ;
}
if ( events ) events = removeOn ( events ) ;
for ( type in this . $events ) {
if ( events && events != type ) continue ;
var fns = this . $events [ type ] ;
for ( var i = fns . length ; i -- ; ) if ( i in fns ) {
this . removeEvent ( type , fns [ i ] ) ;
}
}
return this ;
}
} ) ;
this . Options = new Class ( {
setOptions : function ( ) {
var options = this . options = Object . merge . apply ( null , [ { } , this . options ] . append ( arguments ) ) ;
if ( this . addEvent ) for ( var option in options ) {
if ( typeOf ( options [ option ] ) != 'function' || ! ( /^on[A-Z]/ ) . test ( option ) ) continue ;
2015-05-10 06:23:01 +08:00
this . addEvent ( option , options [ option ] ) ;
delete options [ option ] ;
}
return this ;
2015-04-13 06:52:01 +08:00
}
} ) ;
} ) ( ) ;
2017-11-23 00:46:02 +08:00
/ *
-- -
name : Class . Thenable
description : Contains a Utility Class that can be implemented into your own Classes to make them "thenable" .
license : MIT - style license .
requires : Class
provides : [ Class . Thenable ]
...
* /
( function ( ) {
var STATE _PENDING = 0 ,
STATE _FULFILLED = 1 ,
STATE _REJECTED = 2 ;
var Thenable = Class . Thenable = new Class ( {
$thenableState : STATE _PENDING ,
$thenableResult : null ,
$thenableReactions : [ ] ,
resolve : function ( value ) {
resolve ( this , value ) ;
return this ;
} ,
reject : function ( reason ) {
reject ( this , reason ) ;
return this ;
} ,
getThenableState : function ( ) {
switch ( this . $thenableState ) {
case STATE _PENDING :
return 'pending' ;
case STATE _FULFILLED :
return 'fulfilled' ;
case STATE _REJECTED :
return 'rejected' ;
}
} ,
resetThenable : function ( reason ) {
reject ( this , reason ) ;
reset ( this ) ;
return this ;
} ,
then : function ( onFulfilled , onRejected ) {
if ( typeof onFulfilled !== 'function' ) onFulfilled = 'Identity' ;
if ( typeof onRejected !== 'function' ) onRejected = 'Thrower' ;
var thenable = new Thenable ( ) ;
this . $thenableReactions . push ( {
thenable : thenable ,
fulfillHandler : onFulfilled ,
rejectHandler : onRejected
} ) ;
if ( this . $thenableState !== STATE _PENDING ) {
react ( this ) ;
}
return thenable ;
} ,
'catch' : function ( onRejected ) {
return this . then ( null , onRejected ) ;
}
} ) ;
Thenable . extend ( {
resolve : function ( value ) {
var thenable ;
if ( value instanceof Thenable ) {
thenable = value ;
} else {
thenable = new Thenable ( ) ;
resolve ( thenable , value ) ;
}
return thenable ;
} ,
reject : function ( reason ) {
var thenable = new Thenable ( ) ;
reject ( thenable , reason ) ;
return thenable ;
}
} ) ;
// Private functions
function resolve ( thenable , value ) {
if ( thenable . $thenableState === STATE _PENDING ) {
if ( thenable === value ) {
reject ( thenable , new TypeError ( 'Tried to resolve a thenable with itself.' ) ) ;
} else if ( value && ( typeof value === 'object' || typeof value === 'function' ) ) {
var then ;
try {
then = value . then ;
} catch ( exception ) {
reject ( thenable , exception ) ;
}
if ( typeof then === 'function' ) {
var resolved = false ;
defer ( function ( ) {
try {
then . call (
value ,
function ( nextValue ) {
if ( ! resolved ) {
resolved = true ;
resolve ( thenable , nextValue ) ;
}
} ,
function ( reason ) {
if ( ! resolved ) {
resolved = true ;
reject ( thenable , reason ) ;
}
}
) ;
} catch ( exception ) {
if ( ! resolved ) {
resolved = true ;
reject ( thenable , exception ) ;
}
}
} ) ;
} else {
fulfill ( thenable , value ) ;
}
} else {
fulfill ( thenable , value ) ;
}
}
}
function fulfill ( thenable , value ) {
if ( thenable . $thenableState === STATE _PENDING ) {
thenable . $thenableResult = value ;
thenable . $thenableState = STATE _FULFILLED ;
react ( thenable ) ;
}
}
function reject ( thenable , reason ) {
if ( thenable . $thenableState === STATE _PENDING ) {
thenable . $thenableResult = reason ;
thenable . $thenableState = STATE _REJECTED ;
react ( thenable ) ;
}
}
function reset ( thenable ) {
if ( thenable . $thenableState !== STATE _PENDING ) {
thenable . $thenableResult = null ;
thenable . $thenableState = STATE _PENDING ;
}
}
function react ( thenable ) {
var state = thenable . $thenableState ,
result = thenable . $thenableResult ,
reactions = thenable . $thenableReactions ,
type ;
if ( state === STATE _FULFILLED ) {
thenable . $thenableReactions = [ ] ;
type = 'fulfillHandler' ;
} else if ( state == STATE _REJECTED ) {
thenable . $thenableReactions = [ ] ;
type = 'rejectHandler' ;
}
if ( type ) {
defer ( handle . pass ( [ result , reactions , type ] ) ) ;
}
}
function handle ( result , reactions , type ) {
for ( var i = 0 , l = reactions . length ; i < l ; ++ i ) {
var reaction = reactions [ i ] ,
handler = reaction [ type ] ;
if ( handler === 'Identity' ) {
resolve ( reaction . thenable , result ) ;
} else if ( handler === 'Thrower' ) {
reject ( reaction . thenable , result ) ;
} else {
try {
resolve ( reaction . thenable , handler ( result ) ) ;
} catch ( exception ) {
reject ( reaction . thenable , exception ) ;
}
}
}
}
var defer ;
if ( typeof process !== 'undefined' && typeof process . nextTick === 'function' ) {
defer = process . nextTick ;
} else if ( typeof setImmediate !== 'undefined' ) {
defer = setImmediate ;
} else {
defer = function ( fn ) {
setTimeout ( fn , 0 ) ;
} ;
}
} ) ( ) ;
/ *
-- -
name : Object
description : Object generic methods
license : MIT - style license .
requires : Type
provides : [ Object , Hash ]
...
* /
( function ( ) {
Object . extend ( {
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 ] ;
}
return results ;
} ,
map : function ( object , fn , bind ) {
var results = { } ;
var keys = Object . keys ( object ) ;
for ( var i = 0 ; i < keys . length ; i ++ ) {
var key = keys [ i ] ;
results [ key ] = fn . call ( bind , object [ key ] , key , object ) ;
}
return results ;
} ,
filter : function ( object , fn , bind ) {
var results = { } ;
var keys = Object . keys ( object ) ;
for ( var i = 0 ; i < keys . length ; i ++ ) {
var key = keys [ i ] , value = object [ key ] ;
if ( fn . call ( bind , value , key , object ) ) results [ key ] = value ;
}
return results ;
} ,
every : function ( object , fn , bind ) {
var keys = Object . keys ( object ) ;
for ( var i = 0 ; i < keys . length ; i ++ ) {
var key = keys [ i ] ;
if ( ! fn . call ( bind , object [ key ] , key ) ) return false ;
}
return true ;
} ,
some : function ( object , fn , bind ) {
var keys = Object . keys ( object ) ;
for ( var i = 0 ; i < keys . length ; i ++ ) {
var key = keys [ i ] ;
if ( fn . call ( bind , object [ key ] , key ) ) return true ;
}
return false ;
} ,
values : function ( object ) {
var values = [ ] ;
var keys = Object . keys ( object ) ;
for ( var i = 0 ; i < keys . length ; i ++ ) {
var k = keys [ i ] ;
values . push ( object [ k ] ) ;
}
return values ;
} ,
getLength : function ( object ) {
return Object . keys ( object ) . length ;
} ,
keyOf : function ( object , value ) {
var keys = Object . keys ( object ) ;
for ( var i = 0 ; i < keys . length ; i ++ ) {
var key = keys [ i ] ;
if ( object [ key ] === value ) return key ;
}
return null ;
} ,
contains : function ( object , value ) {
return Object . keyOf ( object , value ) != null ;
} ,
toQueryString : function ( object , base ) {
var queryString = [ ] ;
Object . each ( object , function ( value , key ) {
if ( base ) key = base + '[' + key + ']' ;
var result ;
switch ( typeOf ( value ) ) {
case 'object' : result = Object . toQueryString ( value , key ) ; break ;
case 'array' :
var qs = { } ;
value . each ( function ( val , i ) {
qs [ i ] = val ;
} ) ;
result = Object . toQueryString ( qs , key ) ;
break ;
default : result = key + '=' + encodeURIComponent ( value ) ;
}
if ( value != null ) queryString . push ( result ) ;
} ) ;
return queryString . join ( '&' ) ;
}
} ) ;
} ) ( ) ;
2015-04-13 06:52:01 +08:00
/ *
-- -
name : Slick . Parser
description : Standalone CSS3 Selector parser
provides : Slick . Parser
...
* /
; ( function ( ) {
var parsed ,
separatorIndex ,
combinatorIndex ,
reversed ,
cache = { } ,
reverseCache = { } ,
reUnescape = /\\/g ;
var parse = function ( expression , isReversed ) {
if ( expression == null ) return null ;
if ( expression . Slick === true ) return expression ;
expression = ( '' + expression ) . replace ( /^\s+|\s+$/g , '' ) ;
reversed = ! ! isReversed ;
var currentCache = ( reversed ) ? reverseCache : cache ;
if ( currentCache [ expression ] ) return currentCache [ expression ] ;
parsed = {
Slick : true ,
expressions : [ ] ,
raw : expression ,
reverse : function ( ) {
return parse ( this . raw , true ) ;
}
} ;
separatorIndex = - 1 ;
while ( expression != ( expression = expression . replace ( regexp , parser ) ) ) ;
parsed . length = parsed . expressions . length ;
return currentCache [ parsed . raw ] = ( reversed ) ? reverse ( parsed ) : parsed ;
} ;
var reverseCombinator = function ( combinator ) {
if ( combinator === '!' ) return ' ' ;
else if ( combinator === ' ' ) return '!' ;
else if ( ( /^!/ ) . test ( combinator ) ) return combinator . replace ( /^!/ , '' ) ;
else return '!' + combinator ;
} ;
var reverse = function ( expression ) {
var expressions = expression . expressions ;
for ( var i = 0 ; i < expressions . length ; i ++ ) {
var exp = expressions [ i ] ;
var last = { parts : [ ] , tag : '*' , combinator : reverseCombinator ( exp [ 0 ] . combinator ) } ;
for ( var j = 0 ; j < exp . length ; j ++ ) {
var cexp = exp [ j ] ;
if ( ! cexp . reverseCombinator ) cexp . reverseCombinator = ' ' ;
cexp . combinator = cexp . reverseCombinator ;
delete cexp . reverseCombinator ;
}
exp . reverse ( ) . push ( last ) ;
}
return expression ;
} ;
var escapeRegExp = function ( string ) { // Credit: XRegExp 0.6.1 (c) 2007-2008 Steven Levithan <http://stevenlevithan.com/regex/xregexp/> MIT License
return string . replace ( /[-[\]{}()*+?.\\^$|,#\s]/g , function ( match ) {
return '\\' + match ;
2011-06-21 17:19:10 +08: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)|((?:\\([^)]+\\)|[^()]*)+))\\))?)"
2017-11-23 00:46:02 +08:00
. replace ( /<combinator>/ , '[' + escapeRegExp ( '>+~`!@$%^&={}\\;</' ) + ']' )
2011-06-21 17:19:10 +08:00
. 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 '' ;
}
if ( combinator || combinatorChildren || combinatorIndex === - 1 ) {
combinator = combinator || ' ' ;
var currentSeparator = parsed . expressions [ separatorIndex ] ;
if ( reversed && currentSeparator [ combinatorIndex ] )
currentSeparator [ combinatorIndex ] . reverseCombinator = reverseCombinator ( combinator ) ;
currentSeparator [ ++ combinatorIndex ] = { combinator : combinator , tag : '*' } ;
}
var currentParsed = parsed . expressions [ separatorIndex ] [ combinatorIndex ] ;
if ( tagName ) {
currentParsed . tag = tagName . replace ( reUnescape , '' ) ;
} else if ( id ) {
currentParsed . id = id . replace ( reUnescape , '' ) ;
} else if ( className ) {
className = className . replace ( reUnescape , '' ) ;
if ( ! currentParsed . classList ) currentParsed . classList = [ ] ;
if ( ! currentParsed . classes ) currentParsed . classes = [ ] ;
currentParsed . classList . push ( className ) ;
currentParsed . classes . push ( {
value : className ,
regexp : new RegExp ( '(^|\\s)' + escapeRegExp ( className ) + '(\\s|$)' )
} ) ;
} else if ( pseudoClass ) {
pseudoClassValue = pseudoClassValue || pseudoClassQuotedValue ;
pseudoClassValue = pseudoClassValue ? pseudoClassValue . replace ( reUnescape , '' ) : null ;
if ( ! currentParsed . pseudos ) currentParsed . pseudos = [ ] ;
currentParsed . pseudos . push ( {
key : pseudoClass . replace ( reUnescape , '' ) ,
value : pseudoClassValue ,
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 ;
} ;
}
if ( attributeValue == '' && ( /^[*$^]=$/ ) . test ( attributeOperator ) ) test = function ( ) {
return false ;
} ;
if ( ! test ) test = function ( value ) {
return value && regexp . test ( value ) ;
} ;
if ( ! currentParsed . attributes ) currentParsed . attributes = [ ] ;
currentParsed . attributes . push ( {
key : attributeKey ,
operator : attributeOperator ,
value : attributeValue ,
test : test
} ) ;
}
return '' ;
} ;
// Slick NS
var Slick = ( this . Slick || { } ) ;
Slick . parse = function ( expression ) {
return parse ( expression ) ;
} ;
Slick . escapeRegExp = escapeRegExp ;
if ( ! this . Slick ) this . Slick = Slick ;
} ) . apply ( /*<CommonJS>*/ ( typeof exports != 'undefined' ) ? exports : /*</CommonJS>*/ this ) ;
/ *
-- -
name : Slick . Finder
description : The new , superfast css selector engine .
provides : Slick . Finder
requires : Slick . Parser
...
* /
; ( function ( ) {
var local = { } ,
featuresCache = { } ,
toString = Object . prototype . toString ;
// Feature / Bug detection
local . isNativeCode = function ( fn ) {
return ( /\{\s*\[native code\]\s*\}/ ) . test ( '' + fn ) ;
} ;
local . isXML = function ( document ) {
return ( ! ! document . xmlVersion ) || ( ! ! document . xml ) || ( toString . call ( document ) == '[object XMLDocument]' ) ||
( document . nodeType == 9 && document . documentElement . nodeName != 'HTML' ) ;
} ;
local . setDocument = function ( document ) {
// convert elements / window arguments to document. if document cannot be extrapolated, the function returns.
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 ;
// check if it's the old document
if ( this . document === document ) return ;
this . document = document ;
// check if we have done feature detection on this document before
var root = document . documentElement ,
rootUid = this . getUIDXML ( root ) ,
features = featuresCache [ rootUid ] ,
feature ;
if ( features ) {
for ( feature in features ) {
this [ feature ] = features [ feature ] ;
}
return ;
}
features = featuresCache [ rootUid ] = { } ;
features . root = root ;
features . isXMLDocument = this . isXML ( document ) ;
features . brokenStarGEBTN
= features . starSelectsClosedQSA
= features . idGetsName
= features . brokenMixedCaseQSA
= features . brokenGEBCN
= features . brokenCheckedQSA
= features . brokenEmptyAttributeQSA
= features . isHTMLDocument
= features . nativeMatchesSelector
= false ;
var starSelectsClosed , starSelectsComments ,
brokenSecondClassNameGEBCN , cachedGetElementsByClassName ,
brokenFormAttributeGetter ;
var selected , id = 'slick_uniqueid' ;
var testNode = document . createElement ( 'div' ) ;
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
var testRoot = document . body || document . getElementsByTagName ( 'body' ) [ 0 ] || root ;
testRoot . appendChild ( testNode ) ;
// on non-HTML documents innerHTML and getElementsById doesnt work properly
try {
testNode . innerHTML = '<a id="' + id + '"></a>' ;
features . isHTMLDocument = ! ! document . getElementById ( id ) ;
2017-11-23 00:46:02 +08:00
} catch ( e ) { }
2011-06-21 17:19:10 +08:00
if ( features . isHTMLDocument ) {
testNode . style . display = 'none' ;
// 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 ) == '/' ) ;
2017-11-23 00:46:02 +08:00
} catch ( e ) { } ;
2011-06-21 17:19:10 +08:00
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 ;
2017-11-23 00:46:02 +08:00
} catch ( e ) { }
2011-06-21 17:19:10 +08:00
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 ) ;
2017-11-23 00:46:02 +08:00
} catch ( e ) { } ;
2011-06-21 17:19:10 +08:00
// 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 ) ;
2017-11-23 00:46:02 +08:00
} catch ( e ) { }
2011-06-21 17:19:10 +08:00
features . brokenGEBCN = cachedGetElementsByClassName || brokenSecondClassNameGEBCN ;
}
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
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 ) == '/' ) ;
2017-11-23 00:46:02 +08:00
} catch ( e ) { }
2011-06-21 17:19:10 +08:00
// Safari 3.2 querySelectorAll doesnt work with mixedcase on quirksmode
try {
testNode . innerHTML = '<a class="MiX"></a>' ;
features . brokenMixedCaseQSA = ! testNode . querySelectorAll ( '.MiX' ) . length ;
2017-11-23 00:46:02 +08:00
} catch ( e ) { }
2011-06-21 17:19:10 +08:00
// 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 ) ;
2017-11-23 00:46:02 +08:00
} catch ( e ) { } ;
2011-06-21 17:19:10 +08:00
// IE returns incorrect results for attr[*^$]="" selectors on querySelectorAll
try {
testNode . innerHTML = '<a class=""></a>' ;
features . brokenEmptyAttributeQSA = ( testNode . querySelectorAll ( '[class*=""]' ) . length != 0 ) ;
2017-11-23 00:46:02 +08:00
} catch ( e ) { }
2011-06-21 17:19:10 +08: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' ) ;
2017-11-23 00:46:02 +08:00
} catch ( e ) { }
2011-06-21 17:19:10 +08:00
// native matchesSelector function
2017-11-23 00:46:02 +08:00
features . nativeMatchesSelector = root . matches || /*root.msMatchesSelector ||*/ root . mozMatchesSelector || root . webkitMatchesSelector ;
2011-06-21 17:19:10 +08:00
if ( features . nativeMatchesSelector ) try {
// if matchesSelector trows errors on incorrect sintaxes we can use it
features . nativeMatchesSelector . call ( root , ':slick' ) ;
features . nativeMatchesSelector = null ;
2017-11-23 00:46:02 +08:00
} catch ( e ) { }
2011-06-21 17:19:10 +08:00
}
try {
root . slick _expando = 1 ;
delete root . slick _expando ;
features . getUID = this . getUIDHTML ;
2017-11-23 00:46:02 +08:00
} catch ( e ) {
2011-06-21 17:19:10 +08:00
features . getUID = this . getUIDXML ;
}
testRoot . removeChild ( testNode ) ;
testNode = selected = testRoot = null ;
// getAttribute
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
2017-11-23 00:46:02 +08:00
features . hasAttribute = ( root && this . isNativeCode ( root . hasAttribute ) ) ? function ( node , attribute ) {
2011-06-21 17:19:10 +08:00
return node . hasAttribute ( attribute ) ;
2017-11-23 00:46:02 +08:00
} : function ( node , attribute ) {
2011-06-21 17:19:10 +08:00
node = node . getAttributeNode ( attribute ) ;
return ! ! ( node && ( node . specified || node . nodeValue ) ) ;
} ;
// contains
// FIXME: Add specs: local.contains should be different for xml and html documents?
2015-04-13 06:52:01 +08:00
var nativeRootContains = root && this . isNativeCode ( root . contains ) ,
nativeDocumentContains = document && this . isNativeCode ( document . contains ) ;
features . contains = ( nativeRootContains && nativeDocumentContains ) ? function ( context , node ) {
2011-06-21 17:19:10 +08:00
return context . contains ( node ) ;
2015-04-13 06:52:01 +08:00
} : ( nativeRootContains && ! nativeDocumentContains ) ? function ( context , node ) {
// IE8 does not have .contains on document.
return context === node || ( ( context === document ) ? document . documentElement : context ) . contains ( node ) ;
2011-06-21 17:19:10 +08:00
} : ( root && root . compareDocumentPosition ) ? function ( context , node ) {
return context === node || ! ! ( context . compareDocumentPosition ( node ) & 16 ) ;
} : function ( context , node ) {
if ( node ) do {
if ( node === context ) return true ;
} while ( ( node = node . parentNode ) ) ;
return false ;
} ;
// document order sorting
// credits to Sizzle (http://sizzlejs.com/)
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 ) ;
2017-11-23 00:46:02 +08:00
} : null ;
2011-06-21 17:19:10 +08:00
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 || [ ] ) ;
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08: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
2017-11-23 00:46:02 +08:00
var parsed , i , node , nodes ,
2011-06-21 17:19:10 +08:00
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 ) ;
2017-11-23 00:46:02 +08:00
simpleSelectors : if ( simpleSelector ) {
2011-06-21 17:19:10 +08:00
var symbol = simpleSelector [ 1 ] ,
2017-11-23 00:46:02 +08:00
name = simpleSelector [ 2 ] ;
2011-06-21 17:19:10 +08:00
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 ) ;
}
}
}
if ( hasOthers ) this . sort ( found ) ;
return ( first ) ? null : found ;
}
/*</simple-selectors-override>*/
/*<query-selector-override>*/
2017-11-23 00:46:02 +08:00
querySelector : if ( context . querySelectorAll ) {
2011-06-21 17:19:10 +08:00
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 ;
2017-11-23 00:46:02 +08:00
var _expression = expression , _context = context , currentId ;
2011-06-21 17:19:10 +08:00
if ( ! contextIsDocument ) {
// non-document rooted QSA
// credits to Andrew Dupont
2017-11-23 00:46:02 +08:00
currentId = _context . getAttribute ( 'id' ) , slickid = 'slickid__' ;
2011-06-21 17:19:10 +08:00
_context . setAttribute ( 'id' , slickid ) ;
_expression = '#' + slickid + ' ' + _expression ;
context = _context . parentNode ;
}
try {
if ( first ) return context . querySelector ( _expression ) || null ;
else nodes = context . querySelectorAll ( _expression ) ;
2017-11-23 00:46:02 +08:00
} catch ( e ) {
2011-06-21 17:19:10 +08:00
qsaFailExpCache [ expression ] = 1 ;
break querySelector ;
} finally {
if ( ! contextIsDocument ) {
if ( currentId ) _context . setAttribute ( 'id' , currentId ) ;
else _context . removeAttribute ( 'id' ) ;
context = _context ;
}
}
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 ) ;
}
if ( hasOthers ) this . sort ( found ) ;
return found ;
}
/*</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 ] ) ) ;
}
}
argument = argument || 'n' ;
var parsed = this . cacheNTH [ argument ] || this . parseNTHArgument ( argument ) ;
if ( ! parsed ) return false ;
var a = parsed . a , b = parsed . b , pos = this [ positions ] [ uid ] ;
if ( a == 0 ) return b == pos ;
if ( a > 0 ) {
if ( pos < b ) return false ;
} else {
if ( b < pos ) return false ;
}
return ( ( pos - b ) % a ) == 0 ;
} ;
} ;
/*</nth-pseudo-selectors>*/ /*</pseudo-selectors>*/
local . pushArray = function ( node , tag , id , classes , attributes , pseudos ) {
if ( this . matchSelector ( node , tag , id , classes , attributes , pseudos ) ) this . found . push ( node ) ;
} ;
local . pushUID = function ( node , tag , id , classes , attributes , pseudos ) {
var uid = this . getUID ( node ) ;
if ( ! this . uniques [ uid ] && this . matchSelector ( node , tag , id , classes , attributes , pseudos ) ) {
this . uniques [ uid ] = true ;
this . found . push ( node ) ;
}
} ;
local . matchNode = function ( node , selector ) {
if ( this . isHTMLDocument && this . nativeMatchesSelector ) {
try {
return this . nativeMatchesSelector . call ( node , selector . replace ( /\[([^=]+)=\s*([^'"\]]+?)\s*\]/g , '[$1="$2"]' ) ) ;
2017-11-23 00:46:02 +08:00
} catch ( matchError ) { }
2011-06-21 17:19:10 +08:00
}
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
var parsed = this . Slick . parse ( selector ) ;
if ( ! parsed ) return true ;
// simple (single) selectors
2017-11-23 00:46:02 +08:00
var expressions = parsed . expressions , simpleExpCounter = 0 , i , currentExpression ;
2011-06-21 17:19:10 +08:00
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 -- ; ) {
2015-04-13 06:52:01 +08:00
cls = this . getAttribute ( node , 'class' ) ;
2011-06-21 17:19:10 +08:00
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 ;
}
2015-04-13 06:52:01 +08:00
}
2011-06-21 17:19:10 +08:00
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 ) ;
}
} ,
'>' : function ( node , tag , id , classes , attributes , pseudos ) { // direct children
if ( ( node = node . firstChild ) ) do {
if ( node . nodeType == 1 ) this . push ( node , tag , id , classes , attributes , pseudos ) ;
} while ( ( node = node . nextSibling ) ) ;
} ,
'+' : function ( node , tag , id , classes , attributes , pseudos ) { // next sibling
while ( ( node = node . nextSibling ) ) if ( node . nodeType == 1 ) {
this . push ( node , tag , id , classes , attributes , pseudos ) ;
break ;
}
} ,
'^' : function ( node , tag , id , classes , attributes , pseudos ) { // first child
node = node . firstChild ;
if ( node ) {
if ( node . nodeType == 1 ) this . push ( node , tag , id , classes , attributes , pseudos ) ;
else this [ 'combinator:+' ] ( node , tag , id , classes , attributes , pseudos ) ;
}
} ,
'~' : function ( node , tag , id , classes , attributes , pseudos ) { // next siblings
while ( ( node = node . nextSibling ) ) {
if ( node . nodeType != 1 ) continue ;
var uid = this . getUID ( node ) ;
if ( this . bitUniques [ uid ] ) break ;
this . bitUniques [ uid ] = true ;
this . push ( node , tag , id , classes , attributes , pseudos ) ;
}
} ,
'++' : function ( node , tag , id , classes , attributes , pseudos ) { // next sibling and previous sibling
this [ 'combinator:+' ] ( node , tag , id , classes , attributes , pseudos ) ;
this [ 'combinator:!+' ] ( node , tag , id , classes , attributes , pseudos ) ;
} ,
'~~' : function ( node , tag , id , classes , attributes , pseudos ) { // next siblings and previous siblings
this [ 'combinator:~' ] ( node , tag , id , classes , attributes , pseudos ) ;
this [ 'combinator:!~' ] ( node , tag , id , classes , attributes , pseudos ) ;
} ,
'!' : function ( node , tag , id , classes , attributes , pseudos ) { // all parent nodes up to document
while ( ( node = node . parentNode ) ) if ( node !== this . document ) this . push ( node , tag , id , classes , attributes , pseudos ) ;
} ,
'!>' : function ( node , tag , id , classes , attributes , pseudos ) { // direct parent (one level)
node = node . parentNode ;
if ( node !== this . document ) this . push ( node , tag , id , classes , attributes , pseudos ) ;
} ,
'!+' : function ( node , tag , id , classes , attributes , pseudos ) { // previous sibling
while ( ( node = node . previousSibling ) ) if ( node . nodeType == 1 ) {
this . push ( node , tag , id , classes , attributes , pseudos ) ;
break ;
}
} ,
'!^' : function ( node , tag , id , classes , attributes , pseudos ) { // last child
node = node . lastChild ;
if ( node ) {
if ( node . nodeType == 1 ) this . push ( node , tag , id , classes , attributes , pseudos ) ;
else this [ 'combinator:!+' ] ( node , tag , id , classes , attributes , pseudos ) ;
}
} ,
'!~' : function ( node , tag , id , classes , attributes , pseudos ) { // previous siblings
while ( ( node = node . previousSibling ) ) {
if ( node . nodeType != 1 ) continue ;
var uid = this . getUID ( node ) ;
if ( this . bitUniques [ uid ] ) break ;
this . bitUniques [ uid ] = true ;
this . push ( node , tag , id , classes , attributes , pseudos ) ;
}
}
} ;
for ( var c in combinators ) local [ 'combinator:' + c ] = combinators [ c ] ;
var pseudos = {
/*<pseudo-selectors>*/
'empty' : function ( node ) {
var child = node . firstChild ;
return ! ( child && child . nodeType == 1 ) && ! ( node . innerText || node . textContent || '' ) . length ;
} ,
'not' : function ( node , expression ) {
return ! this . matchNode ( node , expression ) ;
} ,
'contains' : function ( node , text ) {
return ( node . innerText || node . textContent || '' ) . indexOf ( text ) > - 1 ;
} ,
'first-child' : function ( node ) {
while ( ( node = node . previousSibling ) ) if ( node . nodeType == 1 ) return false ;
return true ;
} ,
'last-child' : function ( node ) {
while ( ( node = node . nextSibling ) ) if ( node . nodeType == 1 ) return false ;
return true ;
} ,
'only-child' : function ( node ) {
var prev = node ;
while ( ( prev = prev . previousSibling ) ) if ( prev . nodeType == 1 ) return false ;
var next = node ;
while ( ( next = next . nextSibling ) ) if ( next . nodeType == 1 ) return false ;
return true ;
} ,
/*<nth-pseudo-selectors>*/
'nth-child' : local . createNTHPseudo ( 'firstChild' , 'nextSibling' , 'posNTH' ) ,
'nth-last-child' : local . createNTHPseudo ( 'lastChild' , 'previousSibling' , 'posNTHLast' ) ,
'nth-of-type' : local . createNTHPseudo ( 'firstChild' , 'nextSibling' , 'posNTHType' , true ) ,
'nth-last-of-type' : local . createNTHPseudo ( 'lastChild' , 'previousSibling' , 'posNTHTypeLast' , true ) ,
'index' : function ( node , index ) {
2015-04-13 06:52:01 +08:00
return this [ 'pseudo:nth-child' ] ( node , '' + ( index + 1 ) ) ;
2011-06-21 17:19:10 +08:00
} ,
'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 ) ;
} ,
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
'selected' : function ( node ) {
return node . selected ;
}
/*</pseudo-selectors>*/
} ;
for ( var p in pseudos ) local [ 'pseudo:' + p ] = pseudos [ p ] ;
// attributes methods
2015-04-13 06:52:01 +08:00
var attributeGetters = local . attributeGetters = {
2011-06-21 17:19:10 +08:00
'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' ) ;
} ,
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
'tabindex' : function ( ) {
var attributeNode = this . getAttributeNode ( 'tabindex' ) ;
return ( attributeNode && attributeNode . specified ) ? attributeNode . nodeValue : null ;
} ,
'type' : function ( ) {
return this . getAttribute ( 'type' ) ;
2015-04-13 06:52:01 +08:00
} ,
'maxlength' : function ( ) {
var attributeNode = this . getAttributeNode ( 'maxLength' ) ;
return ( attributeNode && attributeNode . specified ) ? attributeNode . nodeValue : null ;
2011-06-21 17:19:10 +08:00
}
} ;
2015-04-13 06:52:01 +08:00
attributeGetters . MAXLENGTH = attributeGetters . maxLength = attributeGetters . maxlength ;
2011-06-21 17:19:10 +08:00
// Slick
var Slick = local . Slick = ( this . Slick || { } ) ;
2015-04-13 06:52:01 +08:00
Slick . version = '1.1.7' ;
2011-06-21 17:19:10 +08:00
// 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 ) {
2015-04-13 06:52:01 +08:00
local . setDocument ( node ) ;
2011-06-21 17:19:10 +08:00
return local . getAttribute ( node , name ) ;
} ;
2015-04-13 06:52:01 +08:00
Slick . hasAttribute = function ( node , name ) {
local . setDocument ( node ) ;
return local . hasAttribute ( node , name ) ;
} ;
2011-06-21 17:19:10 +08:00
// 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 ) ;
/ *
-- -
name : Element
description : One of the most important items in MooTools . Contains the dollar function , the dollars function , and an handful of cross - browser , time - saver methods to let you easily work with HTML Elements .
license : MIT - style license .
2015-04-13 06:52:01 +08:00
requires : [ Window , Document , Array , String , Function , Object , Number , Slick . Parser , Slick . Finder ]
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
provides : [ Element , Elements , $ , $$ , IFrame , Selectors ]
2011-06-21 17:19:10 +08:00
...
* /
2017-11-23 00:46:02 +08:00
var Element = this . Element = function ( tag , props ) {
2011-06-21 17:19:10 +08:00
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 ;
2015-04-13 06:52:01 +08:00
if ( attributes ) for ( var attr , i = 0 , l = attributes . length ; i < l ; i ++ ) {
attr = attributes [ i ] ;
2011-06-21 17:19:10 +08:00
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 ) ;
} ;
2015-04-13 06:52:01 +08:00
if ( Browser . Element ) {
Element . prototype = Browser . Element . prototype ;
// IE8 and IE9 require the wrapping.
Element . prototype . _fireEvent = ( function ( fireEvent ) {
return function ( type , event ) {
return fireEvent . call ( this , type , event ) ;
} ;
} ) ( Element . prototype . fireEvent ) ;
}
2011-06-21 17:19:10 +08:00
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 ;
2015-04-13 06:52:01 +08:00
Element . Prototype = {
'$constructor' : Element ,
2017-11-23 00:46:02 +08:00
'$family' : Function . convert ( 'element' ) . hide ( )
2015-04-13 06:52:01 +08:00
} ;
2011-06-21 17:19:10 +08:00
Element . mirror ( function ( name , method ) {
Element . Prototype [ name ] = method ;
} ) ;
}
Element . Constructors = { } ;
2015-05-10 06:23:01 +08:00
2011-06-21 17:19:10 +08:00
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 ( )
} ) ;
2015-05-10 06:23:01 +08:00
2011-06-21 17:19:10 +08:00
( 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 ;
2015-04-13 06:52:01 +08:00
var result = splice . apply ( this , arguments ) ;
2011-06-21 17:19:10 +08:00
while ( length >= this . length ) delete this [ length -- ] ;
2015-04-13 06:52:01 +08:00
return result ;
2011-06-21 17:19:10 +08:00
} . protect ( ) ) ;
2015-04-13 06:52:01 +08:00
Array . forEachMethod ( function ( method , name ) {
Elements . implement ( name , method ) ;
} ) ;
2011-06-21 17:19:10 +08:00
Array . mirror ( Elements ) ;
/*<ltIE8>*/
var createElementAcceptsHTML ;
try {
2017-11-23 00:46:02 +08:00
createElementAcceptsHTML = ( document . createElement ( '<input name=x>' ) . name == 'x' ) ;
2015-04-13 06:52:01 +08:00
} catch ( e ) { }
2011-06-21 17:19:10 +08:00
var escapeQuotes = function ( html ) {
return ( '' + html ) . replace ( /&/g , '&' ) . replace ( /"/g , '"' ) ;
} ;
/*</ltIE8>*/
2017-11-23 00:46:02 +08:00
/*<ltIE9>*/
// #2479 - IE8 Cannot set HTML of style element
var canChangeStyleHTML = ( function ( ) {
var div = document . createElement ( 'style' ) ,
flag = false ;
try {
div . innerHTML = '#justTesing{margin: 0px;}' ;
flag = ! ! div . innerHTML ;
} catch ( e ) { }
return flag ;
} ) ( ) ;
/*</ltIE9>*/
2011-06-21 17:19:10 +08:00
Document . implement ( {
newElement : function ( tag , props ) {
2017-11-23 00:46:02 +08:00
if ( props ) {
if ( props . checked != null ) props . defaultChecked = props . checked ;
if ( ( props . type == 'checkbox' || props . type == 'radio' ) && props . value == null ) props . value = 'on' ;
/*<ltIE9>*/ // IE needs the type to be set before changing content of style element
if ( ! canChangeStyleHTML && tag == 'style' ) {
var styleElement = document . createElement ( 'style' ) ;
styleElement . setAttribute ( 'type' , 'text/css' ) ;
if ( props . type ) delete props . type ;
return this . id ( styleElement ) . set ( props ) ;
}
/*</ltIE9>*/
/*<ltIE8>*/ // Fix for readonly name and type properties in IE < 8
if ( createElementAcceptsHTML ) {
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>*/
2015-05-10 06:23:01 +08:00
}
2011-06-21 17:19:10 +08:00
return this . id ( this . createElement ( tag ) ) . set ( props ) ;
}
} ) ;
} ) ( ) ;
2015-04-13 06:52:01 +08:00
( function ( ) {
Slick . uidOf ( window ) ;
Slick . uidOf ( document ) ;
2011-06-21 17:19:10 +08:00
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 ) {
2015-04-13 06:52:01 +08:00
Slick . uidOf ( el ) ;
2011-06-21 17:19:10 +08:00
if ( ! nocash && ! el . $family && ! ( /^(?:object|embed)$/i ) . test ( el . tagName ) ) {
2015-04-13 06:52:01 +08:00
var fireEvent = el . fireEvent ;
// wrapping needed in IE7, or else crash
el . _fireEvent = function ( type , event ) {
return fireEvent ( type , event ) ;
} ;
2011-06-21 17:19:10 +08:00
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 ) {
2015-04-13 06:52:01 +08:00
if ( el && el . $family && el . uniqueNumber ) return el ;
2011-06-21 17:19:10 +08:00
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 ) ) ;
}
} ) ;
2015-04-13 06:52:01 +08:00
var contains = { contains : function ( element ) {
return Slick . contains ( this , element ) ;
} } ;
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
if ( ! document . contains ) Document . implement ( contains ) ;
if ( ! document . createElement ( 'div' ) . contains ) Element . implement ( contains ) ;
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
// tree walking
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
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 ;
2011-06-21 17:19:10 +08:00
} ;
2015-04-13 06:52:01 +08:00
Object . forEach ( {
getNext : '~' ,
getPrevious : '!~' ,
getParent : '!'
} , function ( combinator , method ) {
Element . implement ( method , function ( expression ) {
return this . getElement ( injectCombinator ( expression , combinator ) ) ;
} ) ;
} ) ;
Object . forEach ( {
getAllNext : '~' ,
getAllPrevious : '!~' ,
getSiblings : '~~' ,
getChildren : '>' ,
getParents : '!'
} , function ( combinator , method ) {
Element . implement ( method , function ( expression ) {
return this . getElements ( injectCombinator ( expression , combinator ) ) ;
} ) ;
} ) ;
Element . implement ( {
getFirst : function ( expression ) {
return document . id ( Slick . search ( this , injectCombinator ( expression , '>' ) ) [ 0 ] ) ;
} ,
getLast : function ( expression ) {
return document . id ( Slick . search ( this , injectCombinator ( expression , '>' ) ) . getLast ( ) ) ;
} ,
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' ) ) ) ;
} ,
match : function ( expression ) {
return ! expression || Slick . match ( this , expression ) ;
2011-06-21 17:19:10 +08:00
}
2015-04-13 06:52:01 +08:00
} ) ;
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
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 ) ;
} ) ;
// Inserters
2011-06-21 17:19:10 +08:00
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 ;
2015-04-13 06:52:01 +08:00
// getProperty / setProperty
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
var propertyGetters = { } , propertySetters = { } ;
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
// properties
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
var properties = { } ;
Array . forEach ( [
'type' , 'value' , 'defaultValue' , 'accessKey' , 'cellPadding' , 'cellSpacing' , 'colSpan' ,
'frameBorder' , 'rowSpan' , 'tabIndex' , 'useMap'
] , function ( property ) {
properties [ property . toLowerCase ( ) ] = property ;
} ) ;
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
properties . html = 'innerHTML' ;
properties . text = ( document . createElement ( 'div' ) . textContent == null ) ? 'innerText' : 'textContent' ;
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
Object . forEach ( properties , function ( real , key ) {
propertySetters [ key ] = function ( node , value ) {
node [ real ] = value ;
} ;
propertyGetters [ key ] = function ( node ) {
return node [ real ] ;
} ;
} ) ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
/*<ltIE9>*/
propertySetters . text = ( function ( ) {
return function ( node , value ) {
if ( node . get ( 'tag' ) == 'style' ) node . set ( 'html' , value ) ;
else node [ properties . text ] = value ;
} ;
} ) ( propertySetters . text ) ;
propertyGetters . text = ( function ( getter ) {
return function ( node ) {
return ( node . get ( 'tag' ) == 'style' ) ? node . innerHTML : getter ( node ) ;
} ;
} ) ( propertyGetters . text ) ;
/*</ltIE9>*/
2015-04-13 06:52:01 +08:00
// Booleans
var bools = [
'compact' , 'nowrap' , 'ismap' , 'declare' , 'noshade' , 'checked' ,
'disabled' , 'readOnly' , 'multiple' , 'selected' , 'noresize' ,
'defer' , 'defaultChecked' , 'autofocus' , 'controls' , 'autoplay' ,
'loop'
] ;
var booleans = { } ;
Array . forEach ( bools , function ( bool ) {
var lower = bool . toLowerCase ( ) ;
booleans [ lower ] = bool ;
propertySetters [ lower ] = function ( node , value ) {
node [ bool ] = ! ! value ;
} ;
propertyGetters [ lower ] = function ( node ) {
return ! ! node [ bool ] ;
} ;
} ) ;
// Special cases
Object . append ( propertySetters , {
'class' : function ( node , value ) {
( 'className' in node ) ? node . className = ( value || '' ) : node . setAttribute ( 'class' , value ) ;
} ,
'for' : function ( node , value ) {
( 'htmlFor' in node ) ? node . htmlFor = value : node . setAttribute ( 'for' , value ) ;
} ,
'style' : function ( node , value ) {
( node . style ) ? node . style . cssText = value : node . setAttribute ( 'style' , value ) ;
2011-06-21 17:19:10 +08:00
} ,
2015-04-13 06:52:01 +08:00
'value' : function ( node , value ) {
node . value = ( value != null ) ? value : '' ;
}
} ) ;
propertyGetters [ 'class' ] = function ( node ) {
return ( 'className' in node ) ? node . className || null : node . getAttribute ( 'class' ) ;
} ;
/* <webkit> */
var el = document . createElement ( 'button' ) ;
// IE sets type as readonly and throws
2017-11-23 00:46:02 +08:00
try { el . type = 'button' ; } catch ( e ) { }
2015-04-13 06:52:01 +08:00
if ( el . type != 'button' ) propertySetters . type = function ( node , value ) {
node . setAttribute ( 'type' , value ) ;
} ;
el = null ;
/* </webkit> */
/*<IE>*/
2017-11-23 00:46:02 +08:00
/*<ltIE9>*/
// #2479 - IE8 Cannot set HTML of style element
var canChangeStyleHTML = ( function ( ) {
var div = document . createElement ( 'style' ) ,
flag = false ;
try {
div . innerHTML = '#justTesing{margin: 0px;}' ;
flag = ! ! div . innerHTML ;
} catch ( e ) { }
return flag ;
} ) ( ) ;
/*</ltIE9>*/
var input = document . createElement ( 'input' ) , volatileInputValue , html5InputSupport ;
// #2178
2015-04-13 06:52:01 +08:00
input . value = 't' ;
input . type = 'submit' ;
2017-11-23 00:46:02 +08:00
volatileInputValue = input . value != 't' ;
// #2443 - IE throws "Invalid Argument" when trying to use html5 input types
try {
input . value = '' ;
input . type = 'email' ;
html5InputSupport = input . type == 'email' ;
} catch ( e ) { }
2015-05-10 06:23:01 +08:00
input = null ;
2017-11-23 00:46:02 +08:00
if ( volatileInputValue || ! html5InputSupport ) propertySetters . type = function ( node , type ) {
try {
var value = node . value ;
node . type = type ;
node . value = value ;
} catch ( e ) { }
} ;
2015-04-13 06:52:01 +08:00
/*</IE>*/
/* getProperty, setProperty */
/* <ltIE9> */
var pollutesGetAttribute = ( function ( div ) {
div . random = 'attribute' ;
return ( div . getAttribute ( 'random' ) == 'attribute' ) ;
} ) ( document . createElement ( 'div' ) ) ;
2017-11-23 00:46:02 +08:00
var hasCloneBug = ( function ( test ) {
test . innerHTML = '<object><param name="should_fix" value="the unknown" /></object>' ;
return test . cloneNode ( true ) . firstChild . childNodes . length != 1 ;
} ) ( document . createElement ( 'div' ) ) ;
/* </ltIE9> */
var hasClassList = ! ! document . createElement ( 'div' ) . classList ;
var classes = function ( className ) {
var classNames = ( className || '' ) . clean ( ) . split ( ' ' ) , uniques = { } ;
return classNames . filter ( function ( className ) {
if ( className !== '' && ! uniques [ className ] ) return uniques [ className ] = className ;
} ) ;
} ;
var addToClassList = function ( name ) {
this . classList . add ( name ) ;
} ;
var removeFromClassList = function ( name ) {
this . classList . remove ( name ) ;
} ;
2015-04-13 06:52:01 +08:00
Element . implement ( {
setProperty : function ( name , value ) {
var setter = propertySetters [ name . toLowerCase ( ) ] ;
if ( setter ) {
setter ( this , value ) ;
} else {
/* <ltIE9> */
2017-11-23 00:46:02 +08:00
var attributeWhiteList ;
if ( pollutesGetAttribute ) attributeWhiteList = this . retrieve ( '$attributeWhiteList' , { } ) ;
2015-04-13 06:52:01 +08:00
/* </ltIE9> */
if ( value == null ) {
this . removeAttribute ( name ) ;
/* <ltIE9> */
if ( pollutesGetAttribute ) delete attributeWhiteList [ name ] ;
/* </ltIE9> */
} else {
this . setAttribute ( name , '' + value ) ;
/* <ltIE9> */
if ( pollutesGetAttribute ) attributeWhiteList [ name ] = true ;
/* </ltIE9> */
}
}
2011-06-21 17:19:10 +08:00
return this ;
} ,
setProperties : function ( attributes ) {
for ( var attribute in attributes ) this . setProperty ( attribute , attributes [ attribute ] ) ;
return this ;
} ,
2015-04-13 06:52:01 +08:00
getProperty : function ( name ) {
var getter = propertyGetters [ name . toLowerCase ( ) ] ;
if ( getter ) return getter ( this ) ;
/* <ltIE9> */
if ( pollutesGetAttribute ) {
var attr = this . getAttributeNode ( name ) , attributeWhiteList = this . retrieve ( '$attributeWhiteList' , { } ) ;
if ( ! attr ) return null ;
if ( attr . expando && ! attributeWhiteList [ name ] ) {
var outer = this . outerHTML ;
// segment by the opening tag and find mention of attribute name
if ( outer . substr ( 0 , outer . search ( /\/?['"]?>(?![^<]*<['"])/ ) ) . indexOf ( name ) < 0 ) return null ;
attributeWhiteList [ name ] = true ;
}
}
/* </ltIE9> */
var result = Slick . getAttribute ( this , name ) ;
return ( ! result && ! Slick . hasAttribute ( this , name ) ) ? null : result ;
2011-06-21 17:19:10 +08:00
} ,
getProperties : function ( ) {
2017-11-23 00:46:02 +08:00
var args = Array . convert ( arguments ) ;
2011-06-21 17:19:10 +08:00
return args . map ( this . getProperty , this ) . associate ( args ) ;
} ,
2015-04-13 06:52:01 +08:00
removeProperty : function ( name ) {
return this . setProperty ( name , null ) ;
2011-06-21 17:19:10 +08:00
} ,
removeProperties : function ( ) {
Array . each ( arguments , this . removeProperty , this ) ;
return this ;
} ,
2015-04-13 06:52:01 +08:00
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 ;
} ,
2017-11-23 00:46:02 +08:00
hasClass : hasClassList ? function ( className ) {
return this . classList . contains ( className ) ;
} : function ( className ) {
return classes ( this . className ) . contains ( className ) ;
2011-06-21 17:19:10 +08:00
} ,
2017-11-23 00:46:02 +08:00
addClass : hasClassList ? function ( className ) {
classes ( className ) . forEach ( addToClassList , this ) ;
return this ;
} : function ( className ) {
this . className = classes ( className + ' ' + this . className ) . join ( ' ' ) ;
2011-06-21 17:19:10 +08:00
return this ;
} ,
2017-11-23 00:46:02 +08:00
removeClass : hasClassList ? function ( className ) {
classes ( className ) . forEach ( removeFromClassList , this ) ;
return this ;
} : function ( className ) {
var classNames = classes ( this . className ) ;
classes ( className ) . forEach ( classNames . erase , classNames ) ;
this . className = classNames . join ( ' ' ) ;
2011-06-21 17:19:10 +08:00
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 ) ;
} ,
getSelected : function ( ) {
this . selectedIndex ; // Safari 3.2.1
2017-11-23 00:46:02 +08:00
return new Elements ( Array . convert ( this . options ) . filter ( function ( option ) {
2011-06-21 17:19:10 +08:00
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' ) ;
2017-11-23 00:46:02 +08:00
Array . convert ( value ) . each ( function ( val ) {
2011-06-21 17:19:10 +08:00
if ( typeof val != 'undefined' ) queryString . push ( encodeURIComponent ( el . name ) + '=' + encodeURIComponent ( val ) ) ;
} ) ;
} ) ;
return queryString . join ( '&' ) ;
2015-04-13 06:52:01 +08:00
}
} ) ;
2017-11-23 00:46:02 +08:00
// appendHTML
var appendInserters = {
before : 'beforeBegin' ,
after : 'afterEnd' ,
bottom : 'beforeEnd' ,
top : 'afterBegin' ,
inside : 'beforeEnd'
} ;
Element . implement ( 'appendHTML' , ( 'insertAdjacentHTML' in document . createElement ( 'div' ) ) ? function ( html , where ) {
this . insertAdjacentHTML ( appendInserters [ where || 'bottom' ] , html ) ;
return this ;
} : function ( html , where ) {
var temp = new Element ( 'div' , { html : html } ) ,
children = temp . childNodes ,
fragment = temp . firstChild ;
if ( ! fragment ) return this ;
if ( children . length > 1 ) {
fragment = document . createDocumentFragment ( ) ;
for ( var i = 0 , l = children . length ; i < l ; i ++ ) {
fragment . appendChild ( children [ i ] ) ;
}
}
inserters [ where || 'bottom' ] ( fragment , this ) ;
return this ;
} ) ;
2015-04-13 06:52:01 +08:00
var collected = { } , storage = { } ;
var get = function ( uid ) {
return ( storage [ uid ] || ( storage [ uid ] = { } ) ) ;
} ;
var clean = function ( item ) {
var uid = item . uniqueNumber ;
if ( item . removeEvents ) item . removeEvents ( ) ;
if ( item . clearAttributes ) item . clearAttributes ( ) ;
if ( uid != null ) {
delete collected [ uid ] ;
delete storage [ uid ] ;
}
return item ;
} ;
var formProps = { input : 'checked' , option : 'selected' , textarea : 'value' } ;
Element . implement ( {
2011-06-21 17:19:10 +08:00
destroy : function ( ) {
var children = clean ( this ) . getElementsByTagName ( '*' ) ;
Array . each ( children , clean ) ;
Element . dispose ( this ) ;
return null ;
} ,
empty : function ( ) {
2017-11-23 00:46:02 +08:00
Array . convert ( this . childNodes ) . each ( Element . dispose ) ;
2011-06-21 17:19:10 +08:00
return this ;
} ,
dispose : function ( ) {
return ( this . parentNode ) ? this . parentNode . removeChild ( this ) : this ;
} ,
2015-04-13 06:52:01 +08:00
clone : function ( contents , keepid ) {
contents = contents !== false ;
var clone = this . cloneNode ( contents ) , ce = [ clone ] , te = [ this ] , i ;
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
if ( contents ) {
2017-11-23 00:46:02 +08:00
ce . append ( Array . convert ( clone . getElementsByTagName ( '*' ) ) ) ;
te . append ( Array . convert ( this . getElementsByTagName ( '*' ) ) ) ;
2011-06-21 17:19:10 +08:00
}
2015-04-13 06:52:01 +08:00
for ( i = ce . length ; i -- ; ) {
var node = ce [ i ] , element = te [ i ] ;
if ( ! keepid ) node . removeAttribute ( 'id' ) ;
/*<ltIE9>*/
if ( node . clearAttributes ) {
node . clearAttributes ( ) ;
node . mergeAttributes ( element ) ;
node . removeAttribute ( 'uniqueNumber' ) ;
if ( node . options ) {
var no = node . options , eo = element . options ;
for ( var j = no . length ; j -- ; ) no [ j ] . selected = eo [ j ] . selected ;
}
}
/*</ltIE9>*/
var prop = formProps [ element . tagName . toLowerCase ( ) ] ;
if ( prop && element [ prop ] ) node [ prop ] = element [ prop ] ;
}
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
/*<ltIE9>*/
2017-11-23 00:46:02 +08:00
if ( hasCloneBug ) {
2015-04-13 06:52:01 +08:00
var co = clone . getElementsByTagName ( 'object' ) , to = this . getElementsByTagName ( 'object' ) ;
for ( i = co . length ; i -- ; ) co [ i ] . outerHTML = to [ i ] . outerHTML ;
}
/*</ltIE9>*/
return document . id ( clone ) ;
2011-06-21 17:19:10 +08:00
}
} ) ;
[ Element , Window , Document ] . invoke ( 'implement' , {
addListener : function ( type , fn ) {
2017-11-23 00:46:02 +08:00
if ( window . attachEvent && ! window . addEventListener ) {
2015-04-13 06:52:01 +08:00
collected [ Slick . uidOf ( this ) ] = this ;
2011-06-21 17:19:10 +08:00
}
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 ) {
2015-04-13 06:52:01 +08:00
var storage = get ( Slick . uidOf ( this ) ) , prop = storage [ property ] ;
2011-06-21 17:19:10 +08:00
if ( dflt != null && prop == null ) prop = storage [ property ] = dflt ;
return prop != null ? prop : null ;
} ,
store : function ( property , value ) {
2015-04-13 06:52:01 +08:00
var storage = get ( Slick . uidOf ( this ) ) ;
2011-06-21 17:19:10 +08:00
storage [ property ] = value ;
return this ;
} ,
eliminate : function ( property ) {
2015-04-13 06:52:01 +08:00
var storage = get ( Slick . uidOf ( this ) ) ;
2011-06-21 17:19:10 +08:00
delete storage [ property ] ;
return this ;
}
} ) ;
/*<ltIE9>*/
2017-11-23 00:46:02 +08:00
if ( window . attachEvent && ! window . addEventListener ) {
var gc = function ( ) {
Object . each ( collected , clean ) ;
if ( window . CollectGarbage ) CollectGarbage ( ) ;
window . removeListener ( 'unload' , gc ) ;
} ;
window . addListener ( 'unload' , gc ) ;
}
2011-06-21 17:19:10 +08:00
/*</ltIE9>*/
Element . Properties = { } ;
2015-05-10 06:23:01 +08:00
2011-06-21 17:19:10 +08:00
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 ( ) ;
}
} ;
2015-04-13 06:52:01 +08:00
Element . Properties . html = {
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
set : function ( html ) {
if ( html == null ) html = '' ;
else if ( typeOf ( html ) == 'array' ) html = html . join ( '' ) ;
2015-05-10 06:23:01 +08:00
2017-11-23 00:46:02 +08:00
/*<ltIE9>*/
if ( this . styleSheet && ! canChangeStyleHTML ) this . styleSheet . cssText = html ;
else /*</ltIE9>*/ this . innerHTML = html ;
} ,
2015-04-13 06:52:01 +08:00
erase : function ( ) {
2017-11-23 00:46:02 +08:00
this . set ( 'html' , '' ) ;
2015-04-13 06:52:01 +08:00
}
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
} ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
var supportsHTML5Elements = true , supportsTableInnerHTML = true , supportsTRInnerHTML = true ;
2015-04-13 06:52:01 +08:00
/*<ltIE9>*/
// technique by jdbarlett - http://jdbartlett.com/innershiv/
var div = document . createElement ( 'div' ) ;
2017-11-23 00:46:02 +08:00
var fragment ;
2015-04-13 06:52:01 +08:00
div . innerHTML = '<nav></nav>' ;
2017-11-23 00:46:02 +08:00
supportsHTML5Elements = ( div . childNodes . length == 1 ) ;
2015-04-13 06:52:01 +08:00
if ( ! supportsHTML5Elements ) {
2017-11-23 00:46:02 +08:00
var tags = 'abbr article aside audio canvas datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video' . split ( ' ' ) ;
fragment = document . createDocumentFragment ( ) , l = tags . length ;
2015-04-13 06:52:01 +08:00
while ( l -- ) fragment . createElement ( tags [ l ] ) ;
}
div = null ;
/*</ltIE9>*/
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
/*<IE>*/
2017-11-23 00:46:02 +08:00
supportsTableInnerHTML = Function . attempt ( function ( ) {
2015-04-13 06:52:01 +08:00
var table = document . createElement ( 'table' ) ;
table . innerHTML = '<tr><td></td></tr>' ;
return true ;
} ) ;
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
/*<ltFF4>*/
var tr = document . createElement ( 'tr' ) , html = '<td></td>' ;
tr . innerHTML = html ;
2017-11-23 00:46:02 +08:00
supportsTRInnerHTML = ( tr . innerHTML == html ) ;
2015-04-13 06:52:01 +08:00
tr = null ;
/*</ltFF4>*/
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
if ( ! supportsTableInnerHTML || ! supportsTRInnerHTML || ! supportsHTML5Elements ) {
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
Element . Properties . html . set = ( function ( set ) {
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
var translations = {
table : [ 1 , '<table>' , '</table>' ] ,
select : [ 1 , '<select>' , '</select>' ] ,
tbody : [ 2 , '<table><tbody>' , '</tbody></table>' ] ,
tr : [ 3 , '<table><tbody><tr>' , '</tr></tbody></table>' ]
} ;
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
translations . thead = translations . tfoot = translations . tbody ;
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
return function ( html ) {
2017-11-23 00:46:02 +08:00
/*<ltIE9>*/
if ( this . styleSheet ) return set . call ( this , html ) ;
/*</ltIE9>*/
2015-04-13 06:52:01 +08:00
var wrap = translations [ this . get ( 'tag' ) ] ;
if ( ! wrap && ! supportsHTML5Elements ) wrap = [ 0 , '' , '' ] ;
if ( ! wrap ) return set . call ( this , html ) ;
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
var level = wrap [ 0 ] , wrapper = document . createElement ( 'div' ) , target = wrapper ;
if ( ! supportsHTML5Elements ) fragment . appendChild ( wrapper ) ;
wrapper . innerHTML = [ wrap [ 1 ] , html , wrap [ 2 ] ] . flatten ( ) . join ( '' ) ;
while ( level -- ) target = target . firstChild ;
this . empty ( ) . adopt ( target . childNodes ) ;
if ( ! supportsHTML5Elements ) fragment . removeChild ( wrapper ) ;
wrapper = null ;
} ;
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
} ) ( Element . Properties . html . set ) ;
}
/*</IE>*/
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
/*<ltIE9>*/
var testForm = document . createElement ( 'form' ) ;
testForm . innerHTML = '<select><option>s</option></select>' ;
if ( testForm . firstChild . value != 's' ) Element . Properties . value = {
set : function ( value ) {
var tag = this . get ( 'tag' ) ;
if ( tag != 'select' ) return this . setProperty ( 'value' , value ) ;
var options = this . getElements ( 'option' ) ;
2017-11-23 00:46:02 +08:00
value = String ( value ) ;
2015-04-13 06:52:01 +08:00
for ( var i = 0 ; i < options . length ; i ++ ) {
var option = options [ i ] ,
attr = option . getAttributeNode ( 'value' ) ,
optionValue = ( attr && attr . specified ) ? option . value : option . get ( 'text' ) ;
2017-11-23 00:46:02 +08:00
if ( optionValue === value ) return option . selected = true ;
2015-04-13 06:52:01 +08:00
}
} ,
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
get : function ( ) {
var option = this , tag = option . get ( 'tag' ) ;
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
if ( tag != 'select' && tag != 'option' ) return this . getProperty ( 'value' ) ;
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
if ( tag == 'select' && ! ( option = option . getSelected ( ) [ 0 ] ) ) return '' ;
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
var attr = option . getAttributeNode ( 'value' ) ;
return ( attr && attr . specified ) ? option . value : option . get ( 'text' ) ;
}
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
} ;
testForm = null ;
/*</ltIE9>*/
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
/*<IE>*/
if ( document . createElement ( 'div' ) . getAttributeNode ( 'id' ) ) Element . Properties . id = {
set : function ( id ) {
this . id = this . getAttributeNode ( 'id' ) . value = id ;
2011-06-21 17:19:10 +08:00
} ,
2015-04-13 06:52:01 +08:00
get : function ( ) {
return this . id || null ;
} ,
erase : function ( ) {
this . id = this . getAttributeNode ( 'id' ) . value = '' ;
2011-06-21 17:19:10 +08:00
}
} ;
2015-04-13 06:52:01 +08:00
/*</IE>*/
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
} ) ( ) ;
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
/ *
-- -
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
name : Event
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
description : Contains the Event Type , to make the event object cross - browser .
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
license : MIT - style license .
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
requires : [ Window , Document , Array , Function , String , Object ]
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
provides : Event
2015-04-13 06:52:01 +08:00
...
* /
( function ( ) {
2017-11-23 00:46:02 +08:00
var _keys = { } ;
var normalizeWheelSpeed = function ( event ) {
var normalized ;
if ( event . wheelDelta ) {
normalized = event . wheelDelta % 120 == 0 ? event . wheelDelta / 120 : event . wheelDelta / 12 ;
} else {
var rawAmount = event . deltaY || event . detail || 0 ;
normalized = - ( rawAmount % 3 == 0 ? rawAmount / 3 : rawAmount * 10 ) ;
}
return normalized ;
2015-05-10 06:23:01 +08:00
} ;
2017-11-23 00:46:02 +08:00
var DOMEvent = this . DOMEvent = new Type ( 'DOMEvent' , function ( event , win ) {
if ( ! win ) win = window ;
event = event || win . event ;
if ( event . $extended ) return event ;
this . event = event ;
this . $extended = true ;
this . shift = event . shiftKey ;
this . control = event . ctrlKey ;
this . alt = event . altKey ;
this . meta = event . metaKey ;
var type = this . type = event . type ;
var target = event . target || event . srcElement ;
while ( target && target . nodeType == 3 ) target = target . parentNode ;
this . target = document . id ( target ) ;
2015-05-10 06:23:01 +08:00
2017-11-23 00:46:02 +08:00
if ( type . indexOf ( 'key' ) == 0 ) {
var code = this . code = ( event . which || event . keyCode ) ;
if ( ! this . shift || type != 'keypress' ) this . key = _keys [ code ] ;
if ( type == 'keydown' || type == 'keyup' ) {
if ( code > 111 && code < 124 ) this . key = 'f' + ( code - 111 ) ;
else if ( code > 95 && code < 106 ) this . key = code - 96 ;
2015-05-10 06:23:01 +08:00
}
2017-11-23 00:46:02 +08:00
if ( this . key == null ) this . key = String . fromCharCode ( code ) . toLowerCase ( ) ;
} else if ( type == 'click' || type == 'dblclick' || type == 'contextmenu' || type == 'wheel' || type == 'DOMMouseScroll' || type . indexOf ( 'mouse' ) == 0 ) {
var doc = win . document ;
doc = ( ! doc . compatMode || doc . compatMode == 'CSS1Compat' ) ? doc . html : doc . body ;
this . page = {
x : ( event . pageX != null ) ? event . pageX : event . clientX + doc . scrollLeft ,
y : ( event . pageY != null ) ? event . pageY : event . clientY + doc . scrollTop
} ;
this . client = {
x : ( event . pageX != null ) ? event . pageX - win . pageXOffset : event . clientX ,
y : ( event . pageY != null ) ? event . pageY - win . pageYOffset : event . clientY
} ;
if ( type == 'DOMMouseScroll' || type == 'wheel' || type == 'mousewheel' ) this . wheel = normalizeWheelSpeed ( event ) ;
this . rightClick = ( event . which == 3 || event . button == 2 ) ;
if ( type == 'mouseover' || type == 'mouseout' || type == 'mouseenter' || type == 'mouseleave' ) {
var overTarget = type == 'mouseover' || type == 'mouseenter' ;
var related = event . relatedTarget || event [ ( overTarget ? 'from' : 'to' ) + 'Element' ] ;
while ( related && related . nodeType == 3 ) related = related . parentNode ;
this . relatedTarget = document . id ( related ) ;
2015-05-10 06:23:01 +08:00
}
2017-11-23 00:46:02 +08:00
} else if ( type . indexOf ( 'touch' ) == 0 || type . indexOf ( 'gesture' ) == 0 ) {
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 ] ;
this . page = { x : touch . pageX , y : touch . pageY } ;
this . client = { x : touch . clientX , y : touch . clientY } ;
2011-06-21 17:19:10 +08:00
}
2015-04-13 06:52:01 +08:00
}
2017-11-23 00:46:02 +08:00
if ( ! this . client ) this . client = { } ;
if ( ! this . page ) this . page = { } ;
2015-04-13 06:52:01 +08:00
} ) ;
2017-11-23 00:46:02 +08:00
DOMEvent . implement ( {
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
stop : function ( ) {
return this . preventDefault ( ) . stopPropagation ( ) ;
} ,
2015-05-10 06:23:01 +08:00
2017-11-23 00:46:02 +08:00
stopPropagation : function ( ) {
if ( this . event . stopPropagation ) this . event . stopPropagation ( ) ;
else this . event . cancelBubble = true ;
2011-06-21 17:19:10 +08:00
return this ;
} ,
2017-11-23 00:46:02 +08:00
preventDefault : function ( ) {
if ( this . event . preventDefault ) this . event . preventDefault ( ) ;
else this . event . returnValue = false ;
return this ;
2011-06-21 17:19:10 +08:00
}
} ) ;
2017-11-23 00:46:02 +08:00
DOMEvent . defineKey = function ( code , key ) {
_keys [ code ] = key ;
return this ;
2011-06-21 17:19:10 +08:00
} ;
2017-11-23 00:46:02 +08:00
DOMEvent . defineKeys = DOMEvent . defineKey . overloadSetter ( true ) ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
DOMEvent . defineKeys ( {
'38' : 'up' , '40' : 'down' , '37' : 'left' , '39' : 'right' ,
'27' : 'esc' , '32' : 'space' , '8' : 'backspace' , '9' : 'tab' ,
'46' : 'delete' , '13' : 'enter'
} ) ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
} ) ( ) ;
2015-05-10 06:23:01 +08:00
2011-06-21 17:19:10 +08:00
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
/ *
-- -
name : Element . Event
2015-04-13 06:52:01 +08:00
description : Contains Element methods for dealing with events . This file also includes mouseenter and mouseleave custom Element Events , if necessary .
2011-06-21 17:19:10 +08:00
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 ) {
2015-04-13 06:52:01 +08:00
if ( custom . onAdd ) custom . onAdd . call ( this , fn , type ) ;
2011-06-21 17:19:10 +08:00
if ( custom . condition ) {
condition = function ( event ) {
2015-04-13 06:52:01 +08:00
if ( custom . condition . call ( this , event , type ) ) return fn . call ( this , event ) ;
2011-06-21 17:19:10 +08:00
return true ;
} ;
}
2017-11-23 00:46:02 +08:00
if ( custom . base ) realType = Function . convert ( custom . base ) . call ( this , type ) ;
2011-06-21 17:19:10 +08:00
}
var defn = function ( ) {
return fn . call ( self ) ;
} ;
var nativeEvent = Element . NativeEvents [ realType ] ;
if ( nativeEvent ) {
if ( nativeEvent == 2 ) {
defn = function ( event ) {
2015-04-13 06:52:01 +08:00
event = new DOMEvent ( event , self . getWindow ( ) ) ;
2011-06-21 17:19:10 +08:00
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 ) {
2015-04-13 06:52:01 +08:00
if ( custom . onRemove ) custom . onRemove . call ( this , fn , type ) ;
2017-11-23 00:46:02 +08:00
if ( custom . base ) type = Function . convert ( custom . base ) . call ( this , type ) ;
2011-06-21 17:19:10 +08:00
}
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 ;
} ,
2015-04-13 06:52:01 +08:00
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 ;
2017-11-23 00:46:02 +08:00
args = Array . convert ( args ) ;
2015-04-13 06:52:01 +08:00
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
2017-11-23 00:46:02 +08:00
wheel : 2 , mousewheel : 2 , DOMMouseScroll : 2 , //mouse wheel
2015-04-13 06:52:01 +08:00
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 , paste : 2 , input : 2 , //form elements
load : 2 , unload : 1 , beforeunload : 2 , resize : 1 , move : 1 , DOMContentLoaded : 1 , readystatechange : 1 , //window
2017-11-23 00:46:02 +08:00
hashchange : 1 , popstate : 2 , pageshow : 2 , pagehide : 2 , // history
error : 1 , abort : 1 , scroll : 1 , message : 2 //misc
2015-04-13 06:52:01 +08:00
} ;
2017-11-23 00:46:02 +08:00
Element . Events = {
mousewheel : {
base : 'onwheel' in document ? 'wheel' : 'onmousewheel' in document ? 'mousewheel' : 'DOMMouseScroll'
}
} ;
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 ) ) ;
} ;
2015-04-13 06:52:01 +08:00
if ( 'onmouseenter' in document . documentElement ) {
Element . NativeEvents . mouseenter = Element . NativeEvents . mouseleave = 2 ;
2017-11-23 00:46:02 +08:00
Element . MouseenterCheck = check ;
2015-04-13 06:52:01 +08:00
} else {
Element . Events . mouseenter = {
base : 'mouseover' ,
condition : check
} ;
Element . Events . mouseleave = {
base : 'mouseout' ,
condition : check
} ;
}
/*<ltIE9>*/
if ( ! window . addEventListener ) {
Element . NativeEvents . propertychange = 2 ;
Element . Events . change = {
base : function ( ) {
var type = this . type ;
2017-11-23 00:46:02 +08:00
return ( this . get ( 'tag' ) == 'input' && ( type == 'radio' || type == 'checkbox' ) ) ? 'propertychange' : 'change' ;
2015-04-13 06:52:01 +08:00
} ,
condition : function ( event ) {
2017-11-23 00:46:02 +08:00
return event . type != 'propertychange' || event . event . propertyName == 'checked' ;
2015-04-13 06:52:01 +08:00
}
2017-11-23 00:46:02 +08:00
} ;
2015-04-13 06:52:01 +08:00
}
/*</ltIE9>*/
} ) ( ) ;
/ *
-- -
name : Element . Delegation
description : Extends the Element native object to include the delegate method for more efficient event management .
license : MIT - style license .
requires : [ Element . Event ]
provides : [ Element . Delegation ]
...
* /
( function ( ) {
var eventListenerSupport = ! ! window . addEventListener ;
Element . NativeEvents . focusin = Element . NativeEvents . focusout = 2 ;
var bubbleUp = function ( self , match , fn , event , target ) {
while ( target && target != self ) {
if ( match ( target , event ) ) return fn . call ( target , event , target ) ;
target = document . id ( target . parentNode ) ;
}
} ;
var map = {
mouseenter : {
2017-11-23 00:46:02 +08:00
base : 'mouseover' ,
condition : Element . MouseenterCheck
2015-04-13 06:52:01 +08:00
} ,
mouseleave : {
2017-11-23 00:46:02 +08:00
base : 'mouseout' ,
condition : Element . MouseenterCheck
2015-04-13 06:52:01 +08:00
} ,
focus : {
base : 'focus' + ( eventListenerSupport ? '' : 'in' ) ,
capture : true
} ,
blur : {
base : eventListenerSupport ? 'blur' : 'focusout' ,
capture : true
}
} ;
/*<ltIE9>*/
var _key = '$delegation:' ;
var formObserver = function ( type ) {
return {
base : 'focusin' ,
remove : function ( self , uid ) {
var list = self . retrieve ( _key + type + 'listeners' , { } ) [ uid ] ;
if ( list && list . forms ) for ( var i = list . forms . length ; i -- ; ) {
2017-11-23 00:46:02 +08:00
// the form may have been destroyed, so it won't have the
// removeEvent method anymore. In that case the event was
// removed as well.
if ( list . forms [ i ] . removeEvent ) list . forms [ i ] . removeEvent ( type , list . fns [ i ] ) ;
2015-04-13 06:52:01 +08:00
}
} ,
listen : function ( self , match , fn , event , target , uid ) {
var form = ( target . get ( 'tag' ) == 'form' ) ? target : event . target . getParent ( 'form' ) ;
if ( ! form ) return ;
var listeners = self . retrieve ( _key + type + 'listeners' , { } ) ,
listener = listeners [ uid ] || { forms : [ ] , fns : [ ] } ,
forms = listener . forms , fns = listener . fns ;
if ( forms . indexOf ( form ) != - 1 ) return ;
forms . push ( form ) ;
var _fn = function ( event ) {
bubbleUp ( self , match , fn , event , target ) ;
} ;
form . addEvent ( type , _fn ) ;
fns . push ( _fn ) ;
listeners [ uid ] = listener ;
self . store ( _key + type + 'listeners' , listeners ) ;
}
} ;
} ;
var inputObserver = function ( type ) {
return {
base : 'focusin' ,
listen : function ( self , match , fn , event , target ) {
var events = { blur : function ( ) {
this . removeEvents ( events ) ;
} } ;
events [ type ] = function ( event ) {
bubbleUp ( self , match , fn , event , target ) ;
} ;
event . target . addEvents ( events ) ;
}
} ;
} ;
if ( ! eventListenerSupport ) Object . append ( map , {
submit : formObserver ( 'submit' ) ,
reset : formObserver ( 'reset' ) ,
change : inputObserver ( 'change' ) ,
select : inputObserver ( 'select' )
} ) ;
/*</ltIE9>*/
var proto = Element . prototype ,
addEvent = proto . addEvent ,
removeEvent = proto . removeEvent ;
var relay = function ( old , method ) {
return function ( type , fn , useCapture ) {
if ( type . indexOf ( ':relay' ) == - 1 ) return old . call ( this , type , fn , useCapture ) ;
var parsed = Slick . parse ( type ) . expressions [ 0 ] [ 0 ] ;
if ( parsed . pseudos [ 0 ] . key != 'relay' ) return old . call ( this , type , fn , useCapture ) ;
var newType = parsed . tag ;
parsed . pseudos . slice ( 1 ) . each ( function ( pseudo ) {
newType += ':' + pseudo . key + ( pseudo . value ? '(' + pseudo . value + ')' : '' ) ;
} ) ;
old . call ( this , type , fn ) ;
return method . call ( this , newType , parsed . pseudos [ 0 ] . value , fn ) ;
} ;
} ;
var delegation = {
2015-05-10 06:23:01 +08:00
addEvent : function ( type , match , fn ) {
var storage = this . retrieve ( '$delegates' , { } ) , stored = storage [ type ] ;
if ( stored ) for ( var _uid in stored ) {
if ( stored [ _uid ] . fn == fn && stored [ _uid ] . match == match ) return this ;
2015-04-13 06:52:01 +08:00
}
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
var _type = type , _match = match , _fn = fn , _map = map [ type ] || { } ;
type = _map . base || _type ;
match = function ( target ) {
return Slick . match ( target , _match ) ;
} ;
var elementEvent = Element . Events [ _type ] ;
if ( _map . condition || elementEvent && elementEvent . condition ) {
var _ _match = match , condition = _map . condition || elementEvent . condition ;
match = function ( target , event ) {
return _ _match ( target , event ) && condition . call ( target , event , type ) ;
} ;
}
var self = this , uid = String . uniqueID ( ) ;
var delegator = _map . listen ? function ( event , target ) {
if ( ! target && event && event . target ) target = event . target ;
if ( target ) _map . listen ( self , match , fn , event , target , uid ) ;
} : function ( event , target ) {
if ( ! target && event && event . target ) target = event . target ;
if ( target ) bubbleUp ( self , match , fn , event , target ) ;
} ;
if ( ! stored ) stored = { } ;
stored [ uid ] = {
match : _match ,
fn : _fn ,
delegator : delegator
} ;
storage [ _type ] = stored ;
return addEvent . call ( this , type , delegator , _map . capture ) ;
} ,
removeEvent : function ( type , match , fn , _uid ) {
var storage = this . retrieve ( '$delegates' , { } ) , stored = storage [ type ] ;
if ( ! stored ) return this ;
if ( _uid ) {
var _type = type , delegator = stored [ _uid ] . delegator , _map = map [ type ] || { } ;
type = _map . base || _type ;
if ( _map . remove ) _map . remove ( this , _uid ) ;
delete stored [ _uid ] ;
storage [ _type ] = stored ;
return removeEvent . call ( this , type , delegator , _map . capture ) ;
}
var _ _uid , s ;
if ( fn ) for ( _ _uid in stored ) {
s = stored [ _ _uid ] ;
if ( s . match == match && s . fn == fn ) return delegation . removeEvent . call ( this , type , match , fn , _ _uid ) ;
} else for ( _ _uid in stored ) {
s = stored [ _ _uid ] ;
if ( s . match == match ) delegation . removeEvent . call ( this , type , match , s . fn , _ _uid ) ;
}
return this ;
}
} ;
[ Element , Window , Document ] . invoke ( 'implement' , {
addEvent : relay ( addEvent , delegation . addEvent ) ,
removeEvent : relay ( removeEvent , delegation . removeEvent )
} ) ;
} ) ( ) ;
/ *
-- -
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 , el ;
//<ltIE9>
// Check for oldIE, which does not remove styles when they're set to null
el = document . createElement ( 'div' ) ;
el . style . color = 'red' ;
el . style . color = null ;
var doesNotRemoveStyles = el . style . color == 'red' ;
// check for oldIE, which returns border* shorthand styles in the wrong order (color-width-style instead of width-style-color)
var border = '1px solid #123abc' ;
el . style . border = border ;
var returnsBordersInWrongOrder = el . style . border != border ;
el = null ;
//</ltIE9>
var hasGetComputedStyle = ! ! window . getComputedStyle ,
supportBorderRadius = document . createElement ( 'div' ) . style . borderRadius != null ;
Element . Properties . styles = { set : function ( styles ) {
this . setStyles ( styles ) ;
} } ;
var hasOpacity = ( html . style . opacity != null ) ,
hasFilter = ( html . style . filter != null ) ,
reAlpha = /alpha\(opacity=([\d.]+)\)/i ;
var setVisibility = function ( element , opacity ) {
element . store ( '$opacity' , opacity ) ;
element . style . visibility = opacity > 0 || opacity == null ? 'visible' : 'hidden' ;
} ;
//<ltIE9>
var setFilter = function ( element , regexp , value ) {
var style = element . style ,
filter = style . filter || element . getComputedStyle ( 'filter' ) || '' ;
style . filter = ( regexp . test ( filter ) ? filter . replace ( regexp , value ) : filter + ' ' + value ) . trim ( ) ;
if ( ! style . filter ) style . removeAttribute ( 'filter' ) ;
} ;
//</ltIE9>
var setOpacity = ( hasOpacity ? function ( element , opacity ) {
element . style . opacity = opacity ;
} : ( hasFilter ? function ( element , opacity ) {
if ( ! element . currentStyle || ! element . currentStyle . hasLayout ) element . style . zoom = 1 ;
if ( opacity == null || opacity == 1 ) {
setFilter ( element , reAlpha , '' ) ;
if ( opacity == 1 && getOpacity ( element ) != 1 ) setFilter ( element , reAlpha , 'alpha(opacity=100)' ) ;
} else {
setFilter ( element , reAlpha , 'alpha(opacity=' + ( opacity * 100 ) . limit ( 0 , 100 ) . round ( ) + ')' ) ;
}
} : setVisibility ) ) ;
var getOpacity = ( hasOpacity ? function ( element ) {
var opacity = element . style . opacity || element . getComputedStyle ( 'opacity' ) ;
return ( opacity == '' ) ? 1 : opacity . toFloat ( ) ;
} : ( hasFilter ? function ( element ) {
var filter = ( element . style . filter || element . getComputedStyle ( 'filter' ) ) ,
opacity ;
if ( filter ) opacity = filter . match ( reAlpha ) ;
return ( opacity == null || filter == null ) ? 1 : ( opacity [ 1 ] / 100 ) ;
} : function ( element ) {
var opacity = element . retrieve ( '$opacity' ) ;
if ( opacity == null ) opacity = ( element . style . visibility == 'hidden' ? 0 : 1 ) ;
return opacity ;
} ) ) ;
var floatName = ( html . style . cssFloat == null ) ? 'styleFloat' : 'cssFloat' ,
namedPositions = { left : '0%' , top : '0%' , center : '50%' , right : '100%' , bottom : '100%' } ,
hasBackgroundPositionXY = ( html . style . backgroundPositionX != null ) ,
prefixPattern = /^-(ms)-/ ;
var camelCase = function ( property ) {
return property . replace ( prefixPattern , '$1-' ) . camelCase ( ) ;
} ;
//<ltIE9>
var removeStyle = function ( style , property ) {
if ( property == 'backgroundPosition' ) {
style . removeAttribute ( property + 'X' ) ;
property += 'Y' ;
}
style . removeAttribute ( property ) ;
} ;
//</ltIE9>
Element . implement ( {
getComputedStyle : function ( property ) {
if ( ! hasGetComputedStyle && this . currentStyle ) return this . currentStyle [ camelCase ( property ) ] ;
var defaultView = Element . getDocument ( this ) . defaultView ,
computed = defaultView ? defaultView . getComputedStyle ( this , null ) : null ;
return ( computed ) ? computed . getPropertyValue ( ( property == floatName ) ? 'float' : property . hyphenate ( ) ) : '' ;
} ,
setStyle : function ( property , value ) {
if ( property == 'opacity' ) {
if ( value != null ) value = parseFloat ( value ) ;
setOpacity ( this , value ) ;
return this ;
}
property = camelCase ( property == 'float' ? floatName : property ) ;
if ( typeOf ( value ) != 'string' ) {
var map = ( Element . Styles [ property ] || '@' ) . split ( ' ' ) ;
value = Array . convert ( 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 ;
//<ltIE9>
if ( ( value == '' || value == null ) && doesNotRemoveStyles && this . style . removeAttribute ) {
removeStyle ( this . style , property ) ;
}
//</ltIE9>
return this ;
} ,
getStyle : function ( property ) {
if ( property == 'opacity' ) return getOpacity ( this ) ;
property = camelCase ( property == 'float' ? floatName : property ) ;
if ( supportBorderRadius && property . indexOf ( 'borderRadius' ) != - 1 ) {
return [ 'borderTopLeftRadius' , 'borderTopRightRadius' , 'borderBottomRightRadius' , 'borderBottomLeftRadius' ] . map ( function ( corner ) {
return this . style [ corner ] || '0px' ;
} , this ) . join ( ' ' ) ;
}
var result = this . style [ property ] ;
if ( ! result || property == 'zIndex' ) {
if ( Element . ShortStyles . hasOwnProperty ( property ) ) {
result = [ ] ;
for ( var s in Element . ShortStyles [ property ] ) result . push ( this . getStyle ( s ) ) ;
return result . join ( ' ' ) ;
}
result = this . getComputedStyle ( property ) ;
}
if ( hasBackgroundPositionXY && /^backgroundPosition[XY]?$/ . test ( property ) ) {
return result . replace ( /(top|right|bottom|left)/g , function ( position ) {
return namedPositions [ position ] ;
} ) || '0px' ;
}
if ( ! result && property == 'backgroundPosition' ) return '0px 0px' ;
if ( result ) {
result = String ( result ) ;
var color = result . match ( /rgba?\([\d\s,]+\)/ ) ;
if ( color ) result = result . replace ( color [ 0 ] , color [ 0 ] . rgbToHex ( ) ) ;
}
if ( ! hasGetComputedStyle && ! this . style [ property ] ) {
if ( ( /^(height|width)$/ ) . test ( property ) && ! ( /px$/ . test ( result ) ) ) {
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 ( ( /^border(.+)Width|margin|padding/ ) . test ( property ) && isNaN ( parseFloat ( result ) ) ) {
return '0px' ;
}
}
//<ltIE9>
if ( returnsBordersInWrongOrder && /^border(Top|Right|Bottom|Left)?$/ . test ( property ) && /^#/ . test ( result ) ) {
return result . replace ( /^(.+)\s(.+)\s(.+)$/ , '$2 $3 $1' ) ;
}
//</ltIE9>
return result ;
} ,
2015-04-13 06:52:01 +08:00
2017-11-23 00:46:02 +08:00
setStyles : function ( styles ) {
for ( var style in styles ) this . setStyle ( style , styles [ style ] ) ;
return this ;
} ,
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
getStyles : function ( ) {
var result = { } ;
Array . flatten ( arguments ) . each ( function ( key ) {
result [ key ] = this . getStyle ( key ) ;
} , this ) ;
return result ;
}
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
} ) ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
Element . Styles = {
left : '@px' , top : '@px' , bottom : '@px' , right : '@px' ,
width : '@px' , height : '@px' , maxWidth : '@px' , maxHeight : '@px' , minWidth : '@px' , minHeight : '@px' ,
backgroundColor : 'rgb(@, @, @)' , backgroundSize : '@px' , 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 : '@' , borderRadius : '@px @px @px @px'
} ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
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(@, @, @)' ;
2015-04-13 06:52:01 +08:00
} ) ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
if ( hasBackgroundPositionXY ) Element . ShortStyles . backgroundPosition = { backgroundPositionX : '@' , backgroundPositionY : '@' } ;
2011-06-21 17:19:10 +08:00
} ) ( ) ;
/ *
-- -
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 ;
2017-11-23 00:46:02 +08:00
var heightComponents = [ 'height' , 'paddingTop' , 'paddingBottom' , 'borderTopWidth' , 'borderBottomWidth' ] ,
widthComponents = [ 'width' , 'paddingLeft' , 'paddingRight' , 'borderLeftWidth' , 'borderRightWidth' ] ;
var svgCalculateSize = function ( el ) {
var gCS = window . getComputedStyle ( el ) ,
bounds = { x : 0 , y : 0 } ;
heightComponents . each ( function ( css ) {
bounds . y += parseFloat ( gCS [ css ] ) ;
} ) ;
widthComponents . each ( function ( css ) {
bounds . x += parseFloat ( gCS [ css ] ) ;
} ) ;
return bounds ;
} ;
2011-06-21 17:19:10 +08:00
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 ( ) ;
2017-11-23 00:46:02 +08:00
//<ltIE9>
// This if clause is because IE8- cannot calculate getBoundingClientRect of elements with visibility hidden.
if ( ! window . getComputedStyle ) return { x : this . offsetWidth , y : this . offsetHeight } ;
//</ltIE9>
// This svg section under, calling `svgCalculateSize()`, can be removed when FF fixed the svg size bug.
// Bug info: https://bugzilla.mozilla.org/show_bug.cgi?id=530985
if ( this . get ( 'tag' ) == 'svg' ) return svgCalculateSize ( this ) ;
try {
var bounds = this . getBoundingClientRect ( ) ;
return { x : bounds . width , y : bounds . height } ;
} catch ( e ) {
return { x : 0 , y : 0 } ;
}
2011-06-21 17:19:10 +08:00
} ,
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 ;
2017-11-23 00:46:02 +08:00
} catch ( e ) { }
2011-06-21 17:19:10 +08:00
return null ;
} ,
getOffsets : function ( ) {
2017-11-23 00:46:02 +08:00
var hasGetBoundingClientRect = this . getBoundingClientRect ;
if ( hasGetBoundingClientRect ) {
2011-06-21 17:19:10 +08:00
var bound = this . getBoundingClientRect ( ) ,
html = document . id ( this . getDocument ( ) . documentElement ) ,
htmlScroll = html . getScroll ( ) ,
elemScrolls = this . getScrolls ( ) ,
isFixed = ( styleString ( this , 'position' ) == 'fixed' ) ;
return {
2017-11-23 00:46:02 +08:00
x : bound . left . toFloat ( ) + elemScrolls . x + ( ( isFixed ) ? 0 : htmlScroll . x ) - html . clientLeft ,
y : bound . top . toFloat ( ) + elemScrolls . y + ( ( isFixed ) ? 0 : htmlScroll . y ) - html . clientTop
2011-06-21 17:19:10 +08:00
} ;
}
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 ;
element = element . offsetParent ;
}
2017-11-23 00:46:02 +08:00
2011-06-21 17:19:10 +08:00
return position ;
} ,
getPosition : function ( relative ) {
var offset = this . getOffsets ( ) ,
scroll = this . getScrolls ( ) ;
var position = {
x : offset . x - scroll . x ,
y : offset . y - scroll . y
} ;
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
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' )
} ;
} ,
setPosition : function ( obj ) {
return this . setStyles ( this . computePosition ( obj ) ) ;
}
} ) ;
[ Document , Window ] . invoke ( 'implement' , {
getSize : function ( ) {
var doc = getCompatElement ( this ) ;
return { x : doc . clientWidth , y : doc . clientHeight } ;
} ,
getScroll : function ( ) {
var win = this . getWindow ( ) , doc = getCompatElement ( this ) ;
return { x : win . pageXOffset || doc . scrollLeft , y : win . pageYOffset || doc . scrollTop } ;
} ,
getScrollSize : function ( ) {
var doc = getCompatElement ( this ) ,
min = this . getSize ( ) ,
body = this . getDocument ( ) . body ;
return { x : Math . max ( doc . scrollWidth , body . scrollWidth , min . x ) , y : Math . max ( doc . scrollHeight , body . scrollHeight , min . y ) } ;
} ,
getPosition : function ( ) {
return { x : 0 , y : 0 } ;
} ,
getCoordinates : function ( ) {
var size = this . getSize ( ) ;
return { top : 0 , left : 0 , bottom : size . y , right : size . x , height : size . y , width : size . x } ;
}
} ) ;
// private methods
var styleString = Element . getComputedStyle ;
function styleNumber ( element , style ) {
return styleString ( element , style ) . toInt ( ) || 0 ;
}
2017-11-23 00:46:02 +08:00
2011-06-21 17:19:10 +08:00
function topBorder ( element ) {
return styleNumber ( element , 'border-top-width' ) ;
}
function leftBorder ( element ) {
return styleNumber ( element , 'border-left-width' ) ;
}
function isBody ( element ) {
return ( /^(?:body|html)$/i ) . test ( element . tagName ) ;
}
function getCompatElement ( element ) {
var doc = element . getDocument ( ) ;
return ( ! doc . compatMode || doc . compatMode == 'CSS1Compat' ) ? doc . html : doc . body ;
}
} ) ( ) ;
//aliases
Element . alias ( { position : 'setPosition' } ) ; //compatability
[ Window , Document , Element ] . invoke ( 'implement' , {
getHeight : function ( ) {
return this . getSize ( ) . y ;
} ,
getWidth : function ( ) {
return this . getSize ( ) . x ;
} ,
getScrollTop : function ( ) {
return this . getScroll ( ) . y ;
} ,
getScrollLeft : function ( ) {
return this . getScroll ( ) . x ;
} ,
getScrollHeight : function ( ) {
return this . getScrollSize ( ) . y ;
} ,
getScrollWidth : function ( ) {
return this . getScrollSize ( ) . x ;
} ,
getTop : function ( ) {
return this . getPosition ( ) . y ;
} ,
getLeft : function ( ) {
return this . getPosition ( ) . x ;
}
} ) ;
/ *
-- -
name : Fx
description : Contains the basic animation logic to be extended by all other Fx Classes .
license : MIT - style license .
2017-11-23 00:46:02 +08:00
requires : [ Chain , Events , Options , Class . Thenable ]
2011-06-21 17:19:10 +08:00
provides : Fx
...
* /
( function ( ) {
var Fx = this . Fx = new Class ( {
2017-11-23 00:46:02 +08:00
Implements : [ Chain , Events , Options , Class . Thenable ] ,
2011-06-21 17:19:10 +08:00
options : {
/ *
onStart : nil ,
onCancel : nil ,
onComplete : nil ,
* /
fps : 60 ,
unit : false ,
duration : 500 ,
frames : null ,
frameSkip : true ,
link : 'ignore'
} ,
initialize : function ( options ) {
this . subject = this . subject || this ;
this . setOptions ( options ) ;
} ,
getTransition : function ( ) {
return function ( p ) {
return - ( Math . cos ( Math . PI * p ) - 1 ) / 2 ;
} ;
} ,
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 ++ ;
}
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
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 ( ) ;
}
} ,
set : function ( now ) {
return now ;
} ,
compute : function ( from , to , delta ) {
return Fx . compute ( from , to , delta ) ;
} ,
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 ;
}
return false ;
} ,
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 ) ;
2017-11-23 00:46:02 +08:00
if ( this . getThenableState ( ) !== 'pending' ) {
this . resetThenable ( this . subject ) ;
}
2011-06-21 17:19:10 +08:00
this . fireEvent ( 'start' , this . subject ) ;
pushInstance . call ( this , fps ) ;
return this ;
} ,
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
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 ) ;
}
2017-11-23 00:46:02 +08:00
this . resolve ( this . subject === this ? null : this . subject ) ;
2011-06-21 17:19:10 +08:00
}
return this ;
} ,
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
cancel : function ( ) {
if ( this . isRunning ( ) ) {
this . time = null ;
pullInstance . call ( this , this . options . fps ) ;
this . frame = this . frames ;
this . fireEvent ( 'cancel' , this . subject ) . clearChain ( ) ;
2017-11-23 00:46:02 +08:00
this . reject ( this . subject ) ;
2011-06-21 17:19:10 +08:00
}
return this ;
} ,
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
pause : function ( ) {
if ( this . isRunning ( ) ) {
this . time = null ;
pullInstance . call ( this , this . options . fps ) ;
}
return this ;
} ,
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
resume : function ( ) {
2017-11-23 00:46:02 +08:00
if ( this . isPaused ( ) ) pushInstance . call ( this , this . options . fps ) ;
2011-06-21 17:19:10 +08:00
return this ;
} ,
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
isRunning : function ( ) {
var list = instances [ this . options . fps ] ;
return list && list . contains ( this ) ;
2017-11-23 00:46:02 +08:00
} ,
isPaused : function ( ) {
return ( this . frame < this . frames ) && ! this . isRunning ( ) ;
2011-06-21 17:19:10 +08:00
}
} ) ;
Fx . compute = function ( from , to , delta ) {
return ( to - from ) * delta + from ;
} ;
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 ] ) ;
}
}
} ;
} ) ( ) ;
/ *
-- -
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 ]
provides : Fx . CSS
...
* /
Fx . CSS = new Class ( {
Extends : Fx ,
//prepares the base from/to object
prepare : function ( element , property , values ) {
2017-11-23 00:46:02 +08:00
values = Array . convert ( values ) ;
2015-04-13 06:52:01 +08:00
var from = values [ 0 ] , to = values [ 1 ] ;
if ( to == null ) {
to = from ;
from = element . getStyle ( property ) ;
var unit = this . options . unit ;
// adapted from: https://github.com/ryanmorr/fx/blob/master/fx.js#L299
2017-11-23 00:46:02 +08:00
if ( unit && from && typeof from == 'string' && from . slice ( - unit . length ) != unit && parseFloat ( from ) != 0 ) {
2015-04-13 06:52:01 +08:00
element . setStyle ( property , to + unit ) ;
var value = element . getComputedStyle ( property ) ;
// IE and Opera support pixelLeft or pixelWidth
if ( ! ( /px$/ . test ( value ) ) ) {
value = element . style [ ( 'pixel-' + property ) . camelCase ( ) ] ;
if ( value == null ) {
// adapted from Dean Edwards' http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
var left = element . style . left ;
element . style . left = to + unit ;
value = element . style . pixelLeft ;
element . style . left = left ;
}
}
from = ( to || 1 ) / ( parseFloat ( value ) || 1 ) * ( parseFloat ( from ) || 0 ) ;
element . setStyle ( property , from + unit ) ;
}
2011-06-21 17:19:10 +08:00
}
2015-04-13 06:52:01 +08:00
return { from : this . parse ( from ) , to : this . parse ( to ) } ;
2011-06-21 17:19:10 +08:00
} ,
//parses a value into an array
parse : function ( value ) {
2017-11-23 00:46:02 +08:00
value = Function . convert ( value ) ( ) ;
value = ( typeof value == 'string' ) ? value . split ( ' ' ) : Array . convert ( value ) ;
2011-06-21 17:19:10 +08:00
return value . map ( function ( val ) {
val = String ( val ) ;
var found = false ;
2017-11-23 00:46:02 +08:00
Object . each ( Fx . CSS . Parsers , function ( parser ) {
2011-06-21 17:19:10 +08:00
if ( found ) return ;
var parsed = parser . parse ( val ) ;
if ( parsed || parsed === 0 ) found = { value : parsed , parser : parser } ;
} ) ;
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 } ) ;
} ) ;
2017-11-23 00:46:02 +08:00
computed . $family = Function . convert ( 'fx:css:value' ) ;
2011-06-21 17:19:10 +08:00
return computed ;
} ,
//serves the value as settable
serve : function ( value , unit ) {
if ( typeOf ( value ) != 'fx:css:value' ) value = this . parse ( value ) ;
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 ] ;
var to = { } , selectorTest = new RegExp ( '^' + selector . escapeRegExp ( ) + '$' ) ;
2017-11-23 00:46:02 +08:00
var searchStyles = function ( rules ) {
Array . each ( rules , function ( rule ) {
if ( rule . media ) {
searchStyles ( rule . rules || rule . cssRules ) ;
return ;
}
2011-06-21 17:19:10 +08:00
if ( ! rule . style ) return ;
var selectorText = ( rule . selectorText ) ? rule . selectorText . replace ( /^\w+/ , function ( m ) {
return m . toLowerCase ( ) ;
} ) : null ;
if ( ! selectorText || ! selectorTest . test ( selectorText ) ) return ;
Object . each ( Element . Styles , function ( value , style ) {
if ( ! rule . style [ style ] || Element . ShortStyles [ style ] ) return ;
value = String ( rule . style [ style ] ) ;
2015-04-13 06:52:01 +08:00
to [ style ] = ( ( /^rgb/ ) . test ( value ) ) ? value . rgbToHex ( ) : value ;
} ) ;
} ) ;
2017-11-23 00:46:02 +08:00
} ;
Array . each ( document . styleSheets , function ( sheet ) {
var href = sheet . href ;
if ( href && href . indexOf ( '://' ) > - 1 && href . indexOf ( document . domain ) == - 1 ) return ;
var rules = sheet . rules || sheet . cssRules ;
searchStyles ( rules ) ;
2015-04-13 06:52:01 +08:00
} ) ;
return Fx . CSS . Cache [ selector ] = to ;
2011-06-21 17:19:10 +08:00
}
2017-11-23 00:46:02 +08:00
} ) ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
Fx . CSS . Cache = { } ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
Fx . CSS . Parsers = {
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 ) ;
}
2011-06-21 17:19:10 +08:00
} ,
2017-11-23 00:46:02 +08:00
Number : {
parse : parseFloat ,
compute : Fx . compute ,
serve : function ( value , unit ) {
return ( unit ) ? value + unit : value ;
2011-06-21 17:19:10 +08:00
}
} ,
2017-11-23 00:46:02 +08:00
String : {
parse : Function . convert ( false ) ,
compute : function ( zero , one ) {
return one ;
} ,
serve : function ( zero ) {
return zero ;
2011-06-21 17:19:10 +08:00
}
}
2017-11-23 00:46:02 +08:00
} ;
2011-06-21 17:19:10 +08: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 .
requires : Fx . CSS
provides : Fx . Morph
...
* /
Fx . Morph = new Class ( {
Extends : Fx . CSS ,
initialize : function ( element , options ) {
this . element = this . subject = document . id ( element ) ;
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 ) {
if ( ! this . check ( properties ) ) return this ;
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 ) {
this . get ( 'morph' ) . cancel ( ) . setOptions ( options ) ;
return this ;
} ,
get : function ( ) {
var morph = this . retrieve ( 'morph' ) ;
if ( ! morph ) {
morph = new Fx . Morph ( this , { link : 'cancel' } ) ;
this . store ( 'morph' , morph ) ;
}
return morph ;
}
} ;
Element . implement ( {
morph : function ( props ) {
this . get ( 'morph' ) . start ( props ) ;
return this ;
}
} ) ;
/ *
-- -
name : Fx . Transitions
description : Contains a set of advanced transitions to be used with any of the Fx Classes .
license : MIT - style license .
credits :
- Easing Equations by Robert Penner , < http : //www.robertpenner.com/easing/>, modified and optimized to be used with MooTools.
requires : Fx
provides : Fx . Transitions
...
* /
Fx . implement ( {
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 ( ) : '' ) ] ;
}
return trans ;
}
} ) ;
Fx . Transition = function ( transition , params ) {
2017-11-23 00:46:02 +08:00
params = Array . convert ( params ) ;
2011-06-21 17:19:10 +08:00
var easeIn = function ( pos ) {
return transition ( pos , params ) ;
} ;
return Object . append ( easeIn , {
easeIn : easeIn ,
easeOut : function ( pos ) {
return 1 - transition ( 1 - pos , params ) ;
} ,
easeInOut : function ( pos ) {
return ( pos <= 0.5 ? transition ( 2 * pos , params ) : ( 2 - transition ( 2 * ( 1 - pos ) , params ) ) ) / 2 ;
}
} ) ;
} ;
Fx . Transitions = {
linear : function ( zero ) {
return zero ;
}
} ;
2015-05-10 06:23:01 +08:00
2011-06-21 17:19:10 +08: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 ) {
return Math . pow ( p , x && x [ 0 ] || 6 ) ;
} ,
Expo : function ( p ) {
return Math . pow ( 2 , 8 * ( p - 1 ) ) ;
} ,
Circ : function ( p ) {
return 1 - Math . sin ( Math . acos ( p ) ) ;
} ,
Sine : function ( p ) {
return 1 - Math . cos ( p * Math . PI / 2 ) ;
} ,
Back : function ( p , x ) {
x = x && x [ 0 ] || 1.618 ;
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 ) {
value = b * b - Math . pow ( ( 11 - 6 * a - 11 * p ) / 4 , 2 ) ;
break ;
}
}
return value ;
} ,
Elastic : function ( p , x ) {
return Math . pow ( 2 , 10 * -- p ) * Math . cos ( 20 * p * Math . PI * ( x && x [ 0 ] || 1 ) / 3 ) ;
}
} ) ;
[ 'Quad' , 'Cubic' , 'Quart' , 'Quint' ] . each ( function ( transition , i ) {
Fx . Transitions [ transition ] = new Fx . Transition ( function ( p ) {
return Math . pow ( p , i + 2 ) ;
} ) ;
} ) ;
2017-11-23 00:46:02 +08: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 ]
...
* /
Fx . Tween = new Class ( {
Extends : Fx . CSS ,
initialize : function ( element , options ) {
this . element = this . subject = document . id ( element ) ;
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 ) {
if ( ! this . check ( property , from , to ) ) return this ;
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 ) {
this . get ( 'tween' ) . cancel ( ) . setOptions ( options ) ;
return this ;
} ,
get : function ( ) {
var tween = this . retrieve ( 'tween' ) ;
if ( ! tween ) {
tween = new Fx . Tween ( this , { link : 'cancel' } ) ;
this . store ( 'tween' , tween ) ;
}
return tween ;
}
} ;
Element . implement ( {
tween : function ( property , from , to ) {
this . get ( 'tween' ) . start ( property , from , to ) ;
return this ;
} ,
fade : function ( ) {
var fade = this . get ( 'tween' ) , method , args = [ 'opacity' ] . append ( arguments ) , toggle ;
if ( args [ 1 ] == null ) args [ 1 ] = 'toggle' ;
switch ( args [ 1 ] ) {
case 'in' : method = 'start' ; args [ 1 ] = 1 ; break ;
case 'out' : method = 'start' ; args [ 1 ] = 0 ; break ;
case 'show' : method = 'set' ; args [ 1 ] = 1 ; break ;
case 'hide' : method = 'set' ; args [ 1 ] = 0 ; break ;
case 'toggle' :
var flag = this . retrieve ( 'fade:flag' , this . getStyle ( 'opacity' ) == 1 ) ;
method = 'start' ;
args [ 1 ] = flag ? 0 : 1 ;
this . store ( 'fade:flag' , ! flag ) ;
toggle = true ;
break ;
default : method = 'start' ;
}
if ( ! toggle ) this . eliminate ( 'fade:flag' ) ;
fade [ method ] . apply ( fade , args ) ;
var to = args [ args . length - 1 ] ;
if ( method == 'set' ) {
this . setStyle ( 'visibility' , to == 0 ? 'hidden' : 'visible' ) ;
} else if ( to != 0 ) {
if ( fade . $chain . length ) {
fade . chain ( function ( ) {
this . element . setStyle ( 'visibility' , 'visible' ) ;
this . callChain ( ) ;
} ) ;
} else {
this . setStyle ( 'visibility' , 'visible' ) ;
}
} else {
fade . chain ( function ( ) {
if ( this . element . getStyle ( 'opacity' ) ) return ;
this . element . setStyle ( 'visibility' , 'hidden' ) ;
this . callChain ( ) ;
} ) ;
}
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-21 17:19:10 +08:00
/ *
-- -
name : Request
description : Powerful all purpose Request Class . Uses XMLHTTPRequest .
license : MIT - style license .
2017-11-23 00:46:02 +08:00
requires : [ Object , Element , Chain , Events , Options , Class . Thenable , Browser ]
2011-06-21 17:19:10 +08:00
provides : Request
...
* /
( function ( ) {
var empty = function ( ) { } ,
progressSupport = ( 'onprogress' in new Browser . Request ) ;
var Request = this . Request = new Class ( {
2017-11-23 00:46:02 +08:00
Implements : [ Chain , Events , Options , Class . Thenable ] ,
2011-06-21 17:19:10 +08: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 : '' ,
2017-11-23 00:46:02 +08:00
password : '' ,
withCredentials : false , * /
2011-06-21 17:19:10 +08: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 ,
evalResponse : false ,
timeout : 0 ,
noCache : false
} ,
initialize : function ( options ) {
this . xhr = new Browser . Request ( ) ;
this . setOptions ( options ) ;
this . headers = this . options . headers ;
} ,
onStateChange : function ( ) {
var xhr = this . xhr ;
if ( xhr . readyState != 4 || ! this . running ) return ;
this . running = false ;
this . status = 0 ;
Function . attempt ( function ( ) {
var status = xhr . status ;
this . status = ( status == 1223 ) ? 204 : status ;
} . bind ( this ) ) ;
xhr . onreadystatechange = empty ;
if ( progressSupport ) xhr . onprogress = xhr . onloadstart = empty ;
2017-11-23 00:46:02 +08:00
if ( this . timer ) {
clearTimeout ( this . timer ) ;
delete this . timer ;
}
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
this . response = { text : this . xhr . responseText || '' , xml : this . xhr . responseXML } ;
if ( this . options . isSuccess . call ( this , this . status ) )
this . success ( this . response . text , this . response . xml ) ;
else
this . failure ( ) ;
} ,
isSuccess : function ( ) {
var status = this . status ;
return ( status >= 200 && status < 300 ) ;
} ,
isRunning : function ( ) {
return ! ! this . running ;
} ,
processScripts : function ( text ) {
if ( this . options . evalResponse || ( /(ecma|java)script/ ) . test ( this . getHeader ( 'Content-type' ) ) ) return Browser . exec ( text ) ;
return text . stripScripts ( this . options . evalScripts ) ;
} ,
success : function ( text , xml ) {
this . onSuccess ( this . processScripts ( text ) , xml ) ;
2017-11-23 00:46:02 +08:00
this . resolve ( { text : text , xml : xml } ) ;
2011-06-21 17:19:10 +08:00
} ,
onSuccess : function ( ) {
this . fireEvent ( 'complete' , arguments ) . fireEvent ( 'success' , arguments ) . callChain ( ) ;
} ,
failure : function ( ) {
this . onFailure ( ) ;
2017-11-23 00:46:02 +08:00
this . reject ( { reason : 'failure' , xhr : this . xhr } ) ;
2011-06-21 17:19:10 +08:00
} ,
onFailure : function ( ) {
this . fireEvent ( 'complete' ) . fireEvent ( 'failure' , this . xhr ) ;
} ,
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
loadstart : function ( event ) {
this . fireEvent ( 'loadstart' , [ event , this . xhr ] ) ;
} ,
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
progress : function ( event ) {
this . fireEvent ( 'progress' , [ event , this . xhr ] ) ;
} ,
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
timeout : function ( ) {
this . fireEvent ( 'timeout' , this . xhr ) ;
2017-11-23 00:46:02 +08:00
this . reject ( { reason : 'timeout' , xhr : this . xhr } ) ;
2011-06-21 17:19:10 +08:00
} ,
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 ;
} ,
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
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 ;
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
var trimPosition = url . lastIndexOf ( '/' ) ;
if ( trimPosition > - 1 && ( trimPosition = url . indexOf ( '#' ) ) > - 1 ) url = url . substr ( 0 , trimPosition ) ;
if ( this . options . noCache )
2017-11-23 00:46:02 +08:00
url += ( url . indexOf ( '?' ) > - 1 ? '&' : '?' ) + String . uniqueID ( ) ;
2011-06-21 17:19:10 +08:00
2017-11-23 00:46:02 +08:00
if ( data && ( method == 'get' || method == 'delete' ) ) {
url += ( url . indexOf ( '?' ) > - 1 ? '&' : '?' ) + data ;
2011-06-21 17:19:10 +08:00
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 ) ;
2017-11-23 00:46:02 +08:00
if ( ( this . options . withCredentials ) && 'withCredentials' in xhr ) xhr . withCredentials = true ;
2015-04-13 06:52:01 +08:00
2011-06-21 17:19:10 +08:00
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 ] ) ;
2017-11-23 00:46:02 +08:00
this . reject ( { reason : 'exception' , xhr : xhr , exception : e } ) ;
2011-06-21 17:19:10 +08:00
}
} , this ) ;
2017-11-23 00:46:02 +08:00
if ( this . getThenableState ( ) !== 'pending' ) {
this . resetThenable ( { reason : 'send' } ) ;
}
2011-06-21 17:19:10 +08:00
this . fireEvent ( 'request' ) ;
xhr . send ( data ) ;
if ( ! this . options . async ) this . onStateChange ( ) ;
2015-04-13 06:52:01 +08:00
else if ( this . options . timeout ) this . timer = this . timeout . delay ( this . options . timeout , this ) ;
2011-06-21 17:19:10 +08:00
return this ;
} ,
cancel : function ( ) {
if ( ! this . running ) return this ;
this . running = false ;
var xhr = this . xhr ;
xhr . abort ( ) ;
2017-11-23 00:46:02 +08:00
if ( this . timer ) {
clearTimeout ( this . timer ) ;
delete this . timer ;
}
2011-06-21 17:19:10 +08:00
xhr . onreadystatechange = empty ;
if ( progressSupport ) xhr . onprogress = xhr . onloadstart = empty ;
this . xhr = new Browser . Request ( ) ;
this . fireEvent ( 'cancel' ) ;
2017-11-23 00:46:02 +08:00
this . reject ( { reason : 'cancel' , xhr : xhr } ) ;
2011-06-21 17:19:10 +08:00
return this ;
}
} ) ;
var methods = { } ;
2017-11-23 00:46:02 +08:00
[ 'get' , 'post' , 'put' , 'delete' , 'patch' , 'head' , 'GET' , 'POST' , 'PUT' , 'DELETE' , 'PATCH' , 'HEAD' ] . each ( function ( method ) {
2011-06-21 17:19:10 +08:00
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 ;
2015-04-13 06:52:01 +08:00
response . elements = temp . getElements ( options . filter || '*' ) ;
if ( options . filter ) response . tree = response . elements ;
if ( options . update ) {
var update = document . id ( options . update ) . empty ( ) ;
if ( options . filter ) update . adopt ( response . elements ) ;
else update . set ( 'html' , response . html ) ;
} else if ( options . append ) {
var append = document . id ( options . append ) ;
if ( options . filter ) response . elements . reverse ( ) . inject ( append ) ;
else append . adopt ( temp . getChildren ( ) ) ;
}
2011-06-21 17:19:10 +08:00
if ( options . evalScripts ) Browser . exec ( response . javascript ) ;
this . onSuccess ( response . tree , response . elements , response . html , response . javascript ) ;
2017-11-23 00:46:02 +08:00
this . resolve ( { tree : response . tree , elements : response . elements , html : response . html , javascript : response . javascript } ) ;
2011-06-21 17:19:10 +08:00
}
} ) ;
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 .
2015-04-13 06:52:01 +08:00
SeeAlso : < http : //www.json.org/>
2011-06-21 17:19:10 +08:00
requires : [ Array , String , Number , Function ]
provides : JSON
...
* /
if ( typeof JSON == 'undefined' ) this . JSON = { } ;
2015-05-10 06:23:01 +08:00
2011-06-21 17:19:10 +08:00
( 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 ;
} ;
2017-11-23 00:46:02 +08:00
JSON . secure = true ;
2011-06-21 17:19:10 +08:00
JSON . decode = function ( string , secure ) {
if ( ! string || typeOf ( string ) != 'string' ) return null ;
2015-05-10 06:23:01 +08:00
2017-11-23 00:46:02 +08:00
if ( secure == null ) secure = JSON . secure ;
if ( secure ) {
2011-06-21 17:19:10 +08:00
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 ( {
Extends : Request ,
options : {
/*onError: function(text, error){},*/
secure : true
} ,
initialize : function ( options ) {
this . parent ( options ) ;
Object . append ( this . headers , {
'Accept' : 'application/json' ,
'X-Request' : 'JSON'
} ) ;
} ,
success : function ( text ) {
var json ;
try {
json = this . response . json = JSON . decode ( text , this . options . secure ) ;
} catch ( error ) {
this . fireEvent ( 'error' , [ text , error ] ) ;
return ;
}
2017-11-23 00:46:02 +08:00
if ( json == null ) {
this . failure ( ) ;
} else {
this . onSuccess ( json , text ) ;
this . resolve ( { json : json , text : text } ) ;
}
2011-06-21 17:19:10 +08:00
}
} ) ;
/ *
-- -
name : Cookie
description : Class for creating , reading , and deleting browser Cookies .
license : MIT - style license .
credits :
- Based on the functions by Peter - Paul Koch ( http : //quirksmode.org).
requires : [ Options , Browser ]
provides : Cookie
...
* /
var Cookie = new Class ( {
Implements : Options ,
options : {
path : '/' ,
domain : false ,
duration : false ,
secure : false ,
document : document ,
2017-11-23 00:46:02 +08:00
encode : true ,
httpOnly : false
2011-06-21 17:19:10 +08:00
} ,
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' ;
2017-11-23 00:46:02 +08:00
if ( this . options . httpOnly ) value += '; HttpOnly' ;
2011-06-21 17:19:10 +08:00
this . options . document . cookie = this . key + '=' + value ;
return this ;
} ,
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 ( '' ) ;
return this ;
}
} ) ;
Cookie . write = function ( key , value , options ) {
return new Cookie ( key , options ) . write ( value ) ;
} ;
Cookie . read = function ( key ) {
return new Cookie ( key ) . read ( ) ;
} ;
Cookie . dispose = function ( key , options ) {
return new Cookie ( key , options ) . dispose ( ) ;
} ;
/ *
-- -
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 ) ;
2017-11-23 00:46:02 +08:00
if ( ! ready ) {
Browser . loaded = ready = true ;
document . removeListener ( 'DOMContentLoaded' , domready ) . removeListener ( 'readystatechange' , check ) ;
document . fireEvent ( 'domready' ) ;
window . fireEvent ( 'domready' ) ;
}
// cleanup scope vars
document = window = testElement = null ;
2011-06-21 17:19:10 +08:00
} ;
var check = function ( ) {
for ( var i = checks . length ; i -- ; ) if ( checks [ i ] ( ) ) {
domready ( ) ;
return true ;
}
return false ;
} ;
var poll = function ( ) {
clearTimeout ( timer ) ;
if ( ! check ( ) ) timer = setTimeout ( poll , 10 ) ;
} ;
document . addListener ( 'DOMContentLoaded' , domready ) ;
/*<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 ;
2015-04-13 06:52:01 +08:00
} ;
2011-06-21 17:19:10 +08:00
// 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 ;
}
} ;
// This is based on the custom load event
window . addEvent ( 'load' , function ( ) {
loaded = true ;
} ) ;
} ) ( window , document ) ;