1
0

mootools-core-1.3.2-full-nocompat.js 134 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515
  1. /*
  2. ---
  3. MooTools: the javascript framework
  4. web build:
  5. - http://mootools.net/core/7c56cfef9dddcf170a5d68e3fb61cfd7
  6. packager build:
  7. - packager build Core/Core Core/Array Core/String Core/Number Core/Function Core/Object Core/Event Core/Browser Core/Class Core/Class.Extras Core/Slick.Parser Core/Slick.Finder Core/Element Core/Element.Style Core/Element.Event Core/Element.Dimensions Core/Fx Core/Fx.CSS Core/Fx.Tween Core/Fx.Morph Core/Fx.Transitions Core/Request Core/Request.HTML Core/Request.JSON Core/Cookie Core/JSON Core/DOMReady Core/Swiff
  8. /*
  9. ---
  10. name: Core
  11. description: The heart of MooTools.
  12. license: MIT-style license.
  13. copyright: Copyright (c) 2006-2010 [Valerio Proietti](http://mad4milk.net/).
  14. authors: The MooTools production team (http://mootools.net/developers/)
  15. inspiration:
  16. - 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)
  17. - Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/mit-license.php)
  18. provides: [Core, MooTools, Type, typeOf, instanceOf, Native]
  19. ...
  20. */
  21. (function(){
  22. this.MooTools = {
  23. version: '1.3.2',
  24. build: 'c9f1ff10e9e7facb65e9481049ed1b450959d587'
  25. };
  26. // typeOf, instanceOf
  27. var typeOf = this.typeOf = function(item){
  28. if (item == null) return 'null';
  29. if (item.$family) return item.$family();
  30. if (item.nodeName){
  31. if (item.nodeType == 1) return 'element';
  32. if (item.nodeType == 3) return (/\S/).test(item.nodeValue) ? 'textnode' : 'whitespace';
  33. } else if (typeof item.length == 'number'){
  34. if (item.callee) return 'arguments';
  35. if ('item' in item) return 'collection';
  36. }
  37. return typeof item;
  38. };
  39. var instanceOf = this.instanceOf = function(item, object){
  40. if (item == null) return false;
  41. var constructor = item.$constructor || item.constructor;
  42. while (constructor){
  43. if (constructor === object) return true;
  44. constructor = constructor.parent;
  45. }
  46. return item instanceof object;
  47. };
  48. // Function overloading
  49. var Function = this.Function;
  50. var enumerables = true;
  51. for (var i in {toString: 1}) enumerables = null;
  52. if (enumerables) enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'constructor'];
  53. Function.prototype.overloadSetter = function(usePlural){
  54. var self = this;
  55. return function(a, b){
  56. if (a == null) return this;
  57. if (usePlural || typeof a != 'string'){
  58. for (var k in a) self.call(this, k, a[k]);
  59. if (enumerables) for (var i = enumerables.length; i--;){
  60. k = enumerables[i];
  61. if (a.hasOwnProperty(k)) self.call(this, k, a[k]);
  62. }
  63. } else {
  64. self.call(this, a, b);
  65. }
  66. return this;
  67. };
  68. };
  69. Function.prototype.overloadGetter = function(usePlural){
  70. var self = this;
  71. return function(a){
  72. var args, result;
  73. if (usePlural || typeof a != 'string') args = a;
  74. else if (arguments.length > 1) args = arguments;
  75. if (args){
  76. result = {};
  77. for (var i = 0; i < args.length; i++) result[args[i]] = self.call(this, args[i]);
  78. } else {
  79. result = self.call(this, a);
  80. }
  81. return result;
  82. };
  83. };
  84. Function.prototype.extend = function(key, value){
  85. this[key] = value;
  86. }.overloadSetter();
  87. Function.prototype.implement = function(key, value){
  88. this.prototype[key] = value;
  89. }.overloadSetter();
  90. // From
  91. var slice = Array.prototype.slice;
  92. Function.from = function(item){
  93. return (typeOf(item) == 'function') ? item : function(){
  94. return item;
  95. };
  96. };
  97. Array.from = function(item){
  98. if (item == null) return [];
  99. return (Type.isEnumerable(item) && typeof item != 'string') ? (typeOf(item) == 'array') ? item : slice.call(item) : [item];
  100. };
  101. Number.from = function(item){
  102. var number = parseFloat(item);
  103. return isFinite(number) ? number : null;
  104. };
  105. String.from = function(item){
  106. return item + '';
  107. };
  108. // hide, protect
  109. Function.implement({
  110. hide: function(){
  111. this.$hidden = true;
  112. return this;
  113. },
  114. protect: function(){
  115. this.$protected = true;
  116. return this;
  117. }
  118. });
  119. // Type
  120. var Type = this.Type = function(name, object){
  121. if (name){
  122. var lower = name.toLowerCase();
  123. var typeCheck = function(item){
  124. return (typeOf(item) == lower);
  125. };
  126. Type['is' + name] = typeCheck;
  127. if (object != null){
  128. object.prototype.$family = (function(){
  129. return lower;
  130. }).hide();
  131. }
  132. }
  133. if (object == null) return null;
  134. object.extend(this);
  135. object.$constructor = Type;
  136. object.prototype.$constructor = object;
  137. return object;
  138. };
  139. var toString = Object.prototype.toString;
  140. Type.isEnumerable = function(item){
  141. return (item != null && typeof item.length == 'number' && toString.call(item) != '[object Function]' );
  142. };
  143. var hooks = {};
  144. var hooksOf = function(object){
  145. var type = typeOf(object.prototype);
  146. return hooks[type] || (hooks[type] = []);
  147. };
  148. var implement = function(name, method){
  149. if (method && method.$hidden) return;
  150. var hooks = hooksOf(this);
  151. for (var i = 0; i < hooks.length; i++){
  152. var hook = hooks[i];
  153. if (typeOf(hook) == 'type') implement.call(hook, name, method);
  154. else hook.call(this, name, method);
  155. }
  156. var previous = this.prototype[name];
  157. if (previous == null || !previous.$protected) this.prototype[name] = method;
  158. if (this[name] == null && typeOf(method) == 'function') extend.call(this, name, function(item){
  159. return method.apply(item, slice.call(arguments, 1));
  160. });
  161. };
  162. var extend = function(name, method){
  163. if (method && method.$hidden) return;
  164. var previous = this[name];
  165. if (previous == null || !previous.$protected) this[name] = method;
  166. };
  167. Type.implement({
  168. implement: implement.overloadSetter(),
  169. extend: extend.overloadSetter(),
  170. alias: function(name, existing){
  171. implement.call(this, name, this.prototype[existing]);
  172. }.overloadSetter(),
  173. mirror: function(hook){
  174. hooksOf(this).push(hook);
  175. return this;
  176. }
  177. });
  178. new Type('Type', Type);
  179. // Default Types
  180. var force = function(name, object, methods){
  181. var isType = (object != Object),
  182. prototype = object.prototype;
  183. if (isType) object = new Type(name, object);
  184. for (var i = 0, l = methods.length; i < l; i++){
  185. var key = methods[i],
  186. generic = object[key],
  187. proto = prototype[key];
  188. if (generic) generic.protect();
  189. if (isType && proto){
  190. delete prototype[key];
  191. prototype[key] = proto.protect();
  192. }
  193. }
  194. if (isType) object.implement(prototype);
  195. return force;
  196. };
  197. force('String', String, [
  198. 'charAt', 'charCodeAt', 'concat', 'indexOf', 'lastIndexOf', 'match', 'quote', 'replace', 'search',
  199. 'slice', 'split', 'substr', 'substring', 'toLowerCase', 'toUpperCase'
  200. ])('Array', Array, [
  201. 'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice',
  202. 'indexOf', 'lastIndexOf', 'filter', 'forEach', 'every', 'map', 'some', 'reduce', 'reduceRight'
  203. ])('Number', Number, [
  204. 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision'
  205. ])('Function', Function, [
  206. 'apply', 'call', 'bind'
  207. ])('RegExp', RegExp, [
  208. 'exec', 'test'
  209. ])('Object', Object, [
  210. 'create', 'defineProperty', 'defineProperties', 'keys',
  211. 'getPrototypeOf', 'getOwnPropertyDescriptor', 'getOwnPropertyNames',
  212. 'preventExtensions', 'isExtensible', 'seal', 'isSealed', 'freeze', 'isFrozen'
  213. ])('Date', Date, ['now']);
  214. Object.extend = extend.overloadSetter();
  215. Date.extend('now', function(){
  216. return +(new Date);
  217. });
  218. new Type('Boolean', Boolean);
  219. // fixes NaN returning as Number
  220. Number.prototype.$family = function(){
  221. return isFinite(this) ? 'number' : 'null';
  222. }.hide();
  223. // Number.random
  224. Number.extend('random', function(min, max){
  225. return Math.floor(Math.random() * (max - min + 1) + min);
  226. });
  227. // forEach, each
  228. var hasOwnProperty = Object.prototype.hasOwnProperty;
  229. Object.extend('forEach', function(object, fn, bind){
  230. for (var key in object){
  231. if (hasOwnProperty.call(object, key)) fn.call(bind, object[key], key, object);
  232. }
  233. });
  234. Object.each = Object.forEach;
  235. Array.implement({
  236. forEach: function(fn, bind){
  237. for (var i = 0, l = this.length; i < l; i++){
  238. if (i in this) fn.call(bind, this[i], i, this);
  239. }
  240. },
  241. each: function(fn, bind){
  242. Array.forEach(this, fn, bind);
  243. return this;
  244. }
  245. });
  246. // Array & Object cloning, Object merging and appending
  247. var cloneOf = function(item){
  248. switch (typeOf(item)){
  249. case 'array': return item.clone();
  250. case 'object': return Object.clone(item);
  251. default: return item;
  252. }
  253. };
  254. Array.implement('clone', function(){
  255. var i = this.length, clone = new Array(i);
  256. while (i--) clone[i] = cloneOf(this[i]);
  257. return clone;
  258. });
  259. var mergeOne = function(source, key, current){
  260. switch (typeOf(current)){
  261. case 'object':
  262. if (typeOf(source[key]) == 'object') Object.merge(source[key], current);
  263. else source[key] = Object.clone(current);
  264. break;
  265. case 'array': source[key] = current.clone(); break;
  266. default: source[key] = current;
  267. }
  268. return source;
  269. };
  270. Object.extend({
  271. merge: function(source, k, v){
  272. if (typeOf(k) == 'string') return mergeOne(source, k, v);
  273. for (var i = 1, l = arguments.length; i < l; i++){
  274. var object = arguments[i];
  275. for (var key in object) mergeOne(source, key, object[key]);
  276. }
  277. return source;
  278. },
  279. clone: function(object){
  280. var clone = {};
  281. for (var key in object) clone[key] = cloneOf(object[key]);
  282. return clone;
  283. },
  284. append: function(original){
  285. for (var i = 1, l = arguments.length; i < l; i++){
  286. var extended = arguments[i] || {};
  287. for (var key in extended) original[key] = extended[key];
  288. }
  289. return original;
  290. }
  291. });
  292. // Object-less types
  293. ['Object', 'WhiteSpace', 'TextNode', 'Collection', 'Arguments'].each(function(name){
  294. new Type(name);
  295. });
  296. // Unique ID
  297. var UID = Date.now();
  298. String.extend('uniqueID', function(){
  299. return (UID++).toString(36);
  300. });
  301. })();
  302. /*
  303. ---
  304. name: Array
  305. description: Contains Array Prototypes like each, contains, and erase.
  306. license: MIT-style license.
  307. requires: Type
  308. provides: Array
  309. ...
  310. */
  311. Array.implement({
  312. /*<!ES5>*/
  313. every: function(fn, bind){
  314. for (var i = 0, l = this.length; i < l; i++){
  315. if ((i in this) && !fn.call(bind, this[i], i, this)) return false;
  316. }
  317. return true;
  318. },
  319. filter: function(fn, bind){
  320. var results = [];
  321. for (var i = 0, l = this.length; i < l; i++){
  322. if ((i in this) && fn.call(bind, this[i], i, this)) results.push(this[i]);
  323. }
  324. return results;
  325. },
  326. indexOf: function(item, from){
  327. var len = this.length;
  328. for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){
  329. if (this[i] === item) return i;
  330. }
  331. return -1;
  332. },
  333. map: function(fn, bind){
  334. var results = [];
  335. for (var i = 0, l = this.length; i < l; i++){
  336. if (i in this) results[i] = fn.call(bind, this[i], i, this);
  337. }
  338. return results;
  339. },
  340. some: function(fn, bind){
  341. for (var i = 0, l = this.length; i < l; i++){
  342. if ((i in this) && fn.call(bind, this[i], i, this)) return true;
  343. }
  344. return false;
  345. },
  346. /*</!ES5>*/
  347. clean: function(){
  348. return this.filter(function(item){
  349. return item != null;
  350. });
  351. },
  352. invoke: function(methodName){
  353. var args = Array.slice(arguments, 1);
  354. return this.map(function(item){
  355. return item[methodName].apply(item, args);
  356. });
  357. },
  358. associate: function(keys){
  359. var obj = {}, length = Math.min(this.length, keys.length);
  360. for (var i = 0; i < length; i++) obj[keys[i]] = this[i];
  361. return obj;
  362. },
  363. link: function(object){
  364. var result = {};
  365. for (var i = 0, l = this.length; i < l; i++){
  366. for (var key in object){
  367. if (object[key](this[i])){
  368. result[key] = this[i];
  369. delete object[key];
  370. break;
  371. }
  372. }
  373. }
  374. return result;
  375. },
  376. contains: function(item, from){
  377. return this.indexOf(item, from) != -1;
  378. },
  379. append: function(array){
  380. this.push.apply(this, array);
  381. return this;
  382. },
  383. getLast: function(){
  384. return (this.length) ? this[this.length - 1] : null;
  385. },
  386. getRandom: function(){
  387. return (this.length) ? this[Number.random(0, this.length - 1)] : null;
  388. },
  389. include: function(item){
  390. if (!this.contains(item)) this.push(item);
  391. return this;
  392. },
  393. combine: function(array){
  394. for (var i = 0, l = array.length; i < l; i++) this.include(array[i]);
  395. return this;
  396. },
  397. erase: function(item){
  398. for (var i = this.length; i--;){
  399. if (this[i] === item) this.splice(i, 1);
  400. }
  401. return this;
  402. },
  403. empty: function(){
  404. this.length = 0;
  405. return this;
  406. },
  407. flatten: function(){
  408. var array = [];
  409. for (var i = 0, l = this.length; i < l; i++){
  410. var type = typeOf(this[i]);
  411. if (type == 'null') continue;
  412. array = array.concat((type == 'array' || type == 'collection' || type == 'arguments' || instanceOf(this[i], Array)) ? Array.flatten(this[i]) : this[i]);
  413. }
  414. return array;
  415. },
  416. pick: function(){
  417. for (var i = 0, l = this.length; i < l; i++){
  418. if (this[i] != null) return this[i];
  419. }
  420. return null;
  421. },
  422. hexToRgb: function(array){
  423. if (this.length != 3) return null;
  424. var rgb = this.map(function(value){
  425. if (value.length == 1) value += value;
  426. return value.toInt(16);
  427. });
  428. return (array) ? rgb : 'rgb(' + rgb + ')';
  429. },
  430. rgbToHex: function(array){
  431. if (this.length < 3) return null;
  432. if (this.length == 4 && this[3] == 0 && !array) return 'transparent';
  433. var hex = [];
  434. for (var i = 0; i < 3; i++){
  435. var bit = (this[i] - 0).toString(16);
  436. hex.push((bit.length == 1) ? '0' + bit : bit);
  437. }
  438. return (array) ? hex : '#' + hex.join('');
  439. }
  440. });
  441. /*
  442. ---
  443. name: String
  444. description: Contains String Prototypes like camelCase, capitalize, test, and toInt.
  445. license: MIT-style license.
  446. requires: Type
  447. provides: String
  448. ...
  449. */
  450. String.implement({
  451. test: function(regex, params){
  452. return ((typeOf(regex) == 'regexp') ? regex : new RegExp('' + regex, params)).test(this);
  453. },
  454. contains: function(string, separator){
  455. return (separator) ? (separator + this + separator).indexOf(separator + string + separator) > -1 : this.indexOf(string) > -1;
  456. },
  457. trim: function(){
  458. return this.replace(/^\s+|\s+$/g, '');
  459. },
  460. clean: function(){
  461. return this.replace(/\s+/g, ' ').trim();
  462. },
  463. camelCase: function(){
  464. return this.replace(/-\D/g, function(match){
  465. return match.charAt(1).toUpperCase();
  466. });
  467. },
  468. hyphenate: function(){
  469. return this.replace(/[A-Z]/g, function(match){
  470. return ('-' + match.charAt(0).toLowerCase());
  471. });
  472. },
  473. capitalize: function(){
  474. return this.replace(/\b[a-z]/g, function(match){
  475. return match.toUpperCase();
  476. });
  477. },
  478. escapeRegExp: function(){
  479. return this.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
  480. },
  481. toInt: function(base){
  482. return parseInt(this, base || 10);
  483. },
  484. toFloat: function(){
  485. return parseFloat(this);
  486. },
  487. hexToRgb: function(array){
  488. var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
  489. return (hex) ? hex.slice(1).hexToRgb(array) : null;
  490. },
  491. rgbToHex: function(array){
  492. var rgb = this.match(/\d{1,3}/g);
  493. return (rgb) ? rgb.rgbToHex(array) : null;
  494. },
  495. substitute: function(object, regexp){
  496. return this.replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name){
  497. if (match.charAt(0) == '\\') return match.slice(1);
  498. return (object[name] != null) ? object[name] : '';
  499. });
  500. }
  501. });
  502. /*
  503. ---
  504. name: Number
  505. description: Contains Number Prototypes like limit, round, times, and ceil.
  506. license: MIT-style license.
  507. requires: Type
  508. provides: Number
  509. ...
  510. */
  511. Number.implement({
  512. limit: function(min, max){
  513. return Math.min(max, Math.max(min, this));
  514. },
  515. round: function(precision){
  516. precision = Math.pow(10, precision || 0).toFixed(precision < 0 ? -precision : 0);
  517. return Math.round(this * precision) / precision;
  518. },
  519. times: function(fn, bind){
  520. for (var i = 0; i < this; i++) fn.call(bind, i, this);
  521. },
  522. toFloat: function(){
  523. return parseFloat(this);
  524. },
  525. toInt: function(base){
  526. return parseInt(this, base || 10);
  527. }
  528. });
  529. Number.alias('each', 'times');
  530. (function(math){
  531. var methods = {};
  532. math.each(function(name){
  533. if (!Number[name]) methods[name] = function(){
  534. return Math[name].apply(null, [this].concat(Array.from(arguments)));
  535. };
  536. });
  537. Number.implement(methods);
  538. })(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']);
  539. /*
  540. ---
  541. name: Function
  542. description: Contains Function Prototypes like create, bind, pass, and delay.
  543. license: MIT-style license.
  544. requires: Type
  545. provides: Function
  546. ...
  547. */
  548. Function.extend({
  549. attempt: function(){
  550. for (var i = 0, l = arguments.length; i < l; i++){
  551. try {
  552. return arguments[i]();
  553. } catch (e){}
  554. }
  555. return null;
  556. }
  557. });
  558. Function.implement({
  559. attempt: function(args, bind){
  560. try {
  561. return this.apply(bind, Array.from(args));
  562. } catch (e){}
  563. return null;
  564. },
  565. /*<!ES5>*/
  566. bind: function(bind){
  567. var self = this,
  568. args = (arguments.length > 1) ? Array.slice(arguments, 1) : null;
  569. return function(){
  570. if (!args && !arguments.length) return self.call(bind);
  571. if (args && arguments.length) return self.apply(bind, args.concat(Array.from(arguments)));
  572. return self.apply(bind, args || arguments);
  573. };
  574. },
  575. /*</!ES5>*/
  576. pass: function(args, bind){
  577. var self = this;
  578. if (args != null) args = Array.from(args);
  579. return function(){
  580. return self.apply(bind, args || arguments);
  581. };
  582. },
  583. delay: function(delay, bind, args){
  584. return setTimeout(this.pass((args == null ? [] : args), bind), delay);
  585. },
  586. periodical: function(periodical, bind, args){
  587. return setInterval(this.pass((args == null ? [] : args), bind), periodical);
  588. }
  589. });
  590. /*
  591. ---
  592. name: Object
  593. description: Object generic methods
  594. license: MIT-style license.
  595. requires: Type
  596. provides: [Object, Hash]
  597. ...
  598. */
  599. (function(){
  600. var hasOwnProperty = Object.prototype.hasOwnProperty;
  601. Object.extend({
  602. subset: function(object, keys){
  603. var results = {};
  604. for (var i = 0, l = keys.length; i < l; i++){
  605. var k = keys[i];
  606. if (k in object) results[k] = object[k];
  607. }
  608. return results;
  609. },
  610. map: function(object, fn, bind){
  611. var results = {};
  612. for (var key in object){
  613. if (hasOwnProperty.call(object, key)) results[key] = fn.call(bind, object[key], key, object);
  614. }
  615. return results;
  616. },
  617. filter: function(object, fn, bind){
  618. var results = {};
  619. for (var key in object){
  620. var value = object[key];
  621. if (hasOwnProperty.call(object, key) && fn.call(bind, value, key, object)) results[key] = value;
  622. }
  623. return results;
  624. },
  625. every: function(object, fn, bind){
  626. for (var key in object){
  627. if (hasOwnProperty.call(object, key) && !fn.call(bind, object[key], key)) return false;
  628. }
  629. return true;
  630. },
  631. some: function(object, fn, bind){
  632. for (var key in object){
  633. if (hasOwnProperty.call(object, key) && fn.call(bind, object[key], key)) return true;
  634. }
  635. return false;
  636. },
  637. keys: function(object){
  638. var keys = [];
  639. for (var key in object){
  640. if (hasOwnProperty.call(object, key)) keys.push(key);
  641. }
  642. return keys;
  643. },
  644. values: function(object){
  645. var values = [];
  646. for (var key in object){
  647. if (hasOwnProperty.call(object, key)) values.push(object[key]);
  648. }
  649. return values;
  650. },
  651. getLength: function(object){
  652. return Object.keys(object).length;
  653. },
  654. keyOf: function(object, value){
  655. for (var key in object){
  656. if (hasOwnProperty.call(object, key) && object[key] === value) return key;
  657. }
  658. return null;
  659. },
  660. contains: function(object, value){
  661. return Object.keyOf(object, value) != null;
  662. },
  663. toQueryString: function(object, base){
  664. var queryString = [];
  665. Object.each(object, function(value, key){
  666. if (base) key = base + '[' + key + ']';
  667. var result;
  668. switch (typeOf(value)){
  669. case 'object': result = Object.toQueryString(value, key); break;
  670. case 'array':
  671. var qs = {};
  672. value.each(function(val, i){
  673. qs[i] = val;
  674. });
  675. result = Object.toQueryString(qs, key);
  676. break;
  677. default: result = key + '=' + encodeURIComponent(value);
  678. }
  679. if (value != null) queryString.push(result);
  680. });
  681. return queryString.join('&');
  682. }
  683. });
  684. })();
  685. /*
  686. ---
  687. name: Browser
  688. description: The Browser Object. Contains Browser initialization, Window and Document, and the Browser Hash.
  689. license: MIT-style license.
  690. requires: [Array, Function, Number, String]
  691. provides: [Browser, Window, Document]
  692. ...
  693. */
  694. (function(){
  695. var document = this.document;
  696. var window = document.window = this;
  697. var UID = 1;
  698. this.$uid = (window.ActiveXObject) ? function(item){
  699. return (item.uid || (item.uid = [UID++]))[0];
  700. } : function(item){
  701. return item.uid || (item.uid = UID++);
  702. };
  703. $uid(window);
  704. $uid(document);
  705. var ua = navigator.userAgent.toLowerCase(),
  706. platform = navigator.platform.toLowerCase(),
  707. UA = ua.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/) || [null, 'unknown', 0],
  708. mode = UA[1] == 'ie' && document.documentMode;
  709. var Browser = this.Browser = {
  710. extend: Function.prototype.extend,
  711. name: (UA[1] == 'version') ? UA[3] : UA[1],
  712. version: mode || parseFloat((UA[1] == 'opera' && UA[4]) ? UA[4] : UA[2]),
  713. Platform: {
  714. name: ua.match(/ip(?:ad|od|hone)/) ? 'ios' : (ua.match(/(?:webos|android)/) || platform.match(/mac|win|linux/) || ['other'])[0]
  715. },
  716. Features: {
  717. xpath: !!(document.evaluate),
  718. air: !!(window.runtime),
  719. query: !!(document.querySelector),
  720. json: !!(window.JSON)
  721. },
  722. Plugins: {}
  723. };
  724. Browser[Browser.name] = true;
  725. Browser[Browser.name + parseInt(Browser.version, 10)] = true;
  726. Browser.Platform[Browser.Platform.name] = true;
  727. // Request
  728. Browser.Request = (function(){
  729. var XMLHTTP = function(){
  730. return new XMLHttpRequest();
  731. };
  732. var MSXML2 = function(){
  733. return new ActiveXObject('MSXML2.XMLHTTP');
  734. };
  735. var MSXML = function(){
  736. return new ActiveXObject('Microsoft.XMLHTTP');
  737. };
  738. return Function.attempt(function(){
  739. XMLHTTP();
  740. return XMLHTTP;
  741. }, function(){
  742. MSXML2();
  743. return MSXML2;
  744. }, function(){
  745. MSXML();
  746. return MSXML;
  747. });
  748. })();
  749. Browser.Features.xhr = !!(Browser.Request);
  750. // Flash detection
  751. var version = (Function.attempt(function(){
  752. return navigator.plugins['Shockwave Flash'].description;
  753. }, function(){
  754. return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
  755. }) || '0 r0').match(/\d+/g);
  756. Browser.Plugins.Flash = {
  757. version: Number(version[0] || '0.' + version[1]) || 0,
  758. build: Number(version[2]) || 0
  759. };
  760. // String scripts
  761. Browser.exec = function(text){
  762. if (!text) return text;
  763. if (window.execScript){
  764. window.execScript(text);
  765. } else {
  766. var script = document.createElement('script');
  767. script.setAttribute('type', 'text/javascript');
  768. script.text = text;
  769. document.head.appendChild(script);
  770. document.head.removeChild(script);
  771. }
  772. return text;
  773. };
  774. String.implement('stripScripts', function(exec){
  775. var scripts = '';
  776. var text = this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(all, code){
  777. scripts += code + '\n';
  778. return '';
  779. });
  780. if (exec === true) Browser.exec(scripts);
  781. else if (typeOf(exec) == 'function') exec(scripts, text);
  782. return text;
  783. });
  784. // Window, Document
  785. Browser.extend({
  786. Document: this.Document,
  787. Window: this.Window,
  788. Element: this.Element,
  789. Event: this.Event
  790. });
  791. this.Window = this.$constructor = new Type('Window', function(){});
  792. this.$family = Function.from('window').hide();
  793. Window.mirror(function(name, method){
  794. window[name] = method;
  795. });
  796. this.Document = document.$constructor = new Type('Document', function(){});
  797. document.$family = Function.from('document').hide();
  798. Document.mirror(function(name, method){
  799. document[name] = method;
  800. });
  801. document.html = document.documentElement;
  802. if (!document.head) document.head = document.getElementsByTagName('head')[0];
  803. if (document.execCommand) try {
  804. document.execCommand("BackgroundImageCache", false, true);
  805. } catch (e){}
  806. /*<ltIE9>*/
  807. if (this.attachEvent && !this.addEventListener){
  808. var unloadEvent = function(){
  809. this.detachEvent('onunload', unloadEvent);
  810. document.head = document.html = document.window = null;
  811. };
  812. this.attachEvent('onunload', unloadEvent);
  813. }
  814. // IE fails on collections and <select>.options (refers to <select>)
  815. var arrayFrom = Array.from;
  816. try {
  817. arrayFrom(document.html.childNodes);
  818. } catch(e){
  819. Array.from = function(item){
  820. if (typeof item != 'string' && Type.isEnumerable(item) && typeOf(item) != 'array'){
  821. var i = item.length, array = new Array(i);
  822. while (i--) array[i] = item[i];
  823. return array;
  824. }
  825. return arrayFrom(item);
  826. };
  827. var prototype = Array.prototype,
  828. slice = prototype.slice;
  829. ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice'].each(function(name){
  830. var method = prototype[name];
  831. Array[name] = function(item){
  832. return method.apply(Array.from(item), slice.call(arguments, 1));
  833. };
  834. });
  835. }
  836. /*</ltIE9>*/
  837. })();
  838. /*
  839. ---
  840. name: Event
  841. description: Contains the Event Class, to make the event object cross-browser.
  842. license: MIT-style license.
  843. requires: [Window, Document, Array, Function, String, Object]
  844. provides: Event
  845. ...
  846. */
  847. var Event = new Type('Event', function(event, win){
  848. if (!win) win = window;
  849. var doc = win.document;
  850. event = event || win.event;
  851. if (event.$extended) return event;
  852. this.$extended = true;
  853. var type = event.type,
  854. target = event.target || event.srcElement,
  855. page = {},
  856. client = {},
  857. related = null,
  858. rightClick, wheel, code, key;
  859. while (target && target.nodeType == 3) target = target.parentNode;
  860. if (type.indexOf('key') != -1){
  861. code = event.which || event.keyCode;
  862. key = Object.keyOf(Event.Keys, code);
  863. if (type == 'keydown'){
  864. var fKey = code - 111;
  865. if (fKey > 0 && fKey < 13) key = 'f' + fKey;
  866. }
  867. if (!key) key = String.fromCharCode(code).toLowerCase();
  868. } else if ((/click|mouse|menu/i).test(type)){
  869. doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
  870. page = {
  871. x: (event.pageX != null) ? event.pageX : event.clientX + doc.scrollLeft,
  872. y: (event.pageY != null) ? event.pageY : event.clientY + doc.scrollTop
  873. };
  874. client = {
  875. x: (event.pageX != null) ? event.pageX - win.pageXOffset : event.clientX,
  876. y: (event.pageY != null) ? event.pageY - win.pageYOffset : event.clientY
  877. };
  878. if ((/DOMMouseScroll|mousewheel/).test(type)){
  879. wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
  880. }
  881. rightClick = (event.which == 3) || (event.button == 2);
  882. if ((/over|out/).test(type)){
  883. related = event.relatedTarget || event[(type == 'mouseover' ? 'from' : 'to') + 'Element'];
  884. var testRelated = function(){
  885. while (related && related.nodeType == 3) related = related.parentNode;
  886. return true;
  887. };
  888. var hasRelated = (Browser.firefox2) ? testRelated.attempt() : testRelated();
  889. related = (hasRelated) ? related : null;
  890. }
  891. } else if ((/gesture|touch/i).test(type)){
  892. this.rotation = event.rotation;
  893. this.scale = event.scale;
  894. this.targetTouches = event.targetTouches;
  895. this.changedTouches = event.changedTouches;
  896. var touches = this.touches = event.touches;
  897. if (touches && touches[0]){
  898. var touch = touches[0];
  899. page = {x: touch.pageX, y: touch.pageY};
  900. client = {x: touch.clientX, y: touch.clientY};
  901. }
  902. }
  903. return Object.append(this, {
  904. event: event,
  905. type: type,
  906. page: page,
  907. client: client,
  908. rightClick: rightClick,
  909. wheel: wheel,
  910. relatedTarget: document.id(related),
  911. target: document.id(target),
  912. code: code,
  913. key: key,
  914. shift: event.shiftKey,
  915. control: event.ctrlKey,
  916. alt: event.altKey,
  917. meta: event.metaKey
  918. });
  919. });
  920. Event.Keys = {
  921. 'enter': 13,
  922. 'up': 38,
  923. 'down': 40,
  924. 'left': 37,
  925. 'right': 39,
  926. 'esc': 27,
  927. 'space': 32,
  928. 'backspace': 8,
  929. 'tab': 9,
  930. 'delete': 46
  931. };
  932. Event.implement({
  933. stop: function(){
  934. return this.stopPropagation().preventDefault();
  935. },
  936. stopPropagation: function(){
  937. if (this.event.stopPropagation) this.event.stopPropagation();
  938. else this.event.cancelBubble = true;
  939. return this;
  940. },
  941. preventDefault: function(){
  942. if (this.event.preventDefault) this.event.preventDefault();
  943. else this.event.returnValue = false;
  944. return this;
  945. }
  946. });
  947. /*
  948. ---
  949. name: Class
  950. description: Contains the Class Function for easily creating, extending, and implementing reusable Classes.
  951. license: MIT-style license.
  952. requires: [Array, String, Function, Number]
  953. provides: Class
  954. ...
  955. */
  956. (function(){
  957. var Class = this.Class = new Type('Class', function(params){
  958. if (instanceOf(params, Function)) params = {initialize: params};
  959. var newClass = function(){
  960. reset(this);
  961. if (newClass.$prototyping) return this;
  962. this.$caller = null;
  963. var value = (this.initialize) ? this.initialize.apply(this, arguments) : this;
  964. this.$caller = this.caller = null;
  965. return value;
  966. }.extend(this).implement(params);
  967. newClass.$constructor = Class;
  968. newClass.prototype.$constructor = newClass;
  969. newClass.prototype.parent = parent;
  970. return newClass;
  971. });
  972. var parent = function(){
  973. if (!this.$caller) throw new Error('The method "parent" cannot be called.');
  974. var name = this.$caller.$name,
  975. parent = this.$caller.$owner.parent,
  976. previous = (parent) ? parent.prototype[name] : null;
  977. if (!previous) throw new Error('The method "' + name + '" has no parent.');
  978. return previous.apply(this, arguments);
  979. };
  980. var reset = function(object){
  981. for (var key in object){
  982. var value = object[key];
  983. switch (typeOf(value)){
  984. case 'object':
  985. var F = function(){};
  986. F.prototype = value;
  987. object[key] = reset(new F);
  988. break;
  989. case 'array': object[key] = value.clone(); break;
  990. }
  991. }
  992. return object;
  993. };
  994. var wrap = function(self, key, method){
  995. if (method.$origin) method = method.$origin;
  996. var wrapper = function(){
  997. if (method.$protected && this.$caller == null) throw new Error('The method "' + key + '" cannot be called.');
  998. var caller = this.caller, current = this.$caller;
  999. this.caller = current; this.$caller = wrapper;
  1000. var result = method.apply(this, arguments);
  1001. this.$caller = current; this.caller = caller;
  1002. return result;
  1003. }.extend({$owner: self, $origin: method, $name: key});
  1004. return wrapper;
  1005. };
  1006. var implement = function(key, value, retain){
  1007. if (Class.Mutators.hasOwnProperty(key)){
  1008. value = Class.Mutators[key].call(this, value);
  1009. if (value == null) return this;
  1010. }
  1011. if (typeOf(value) == 'function'){
  1012. if (value.$hidden) return this;
  1013. this.prototype[key] = (retain) ? value : wrap(this, key, value);
  1014. } else {
  1015. Object.merge(this.prototype, key, value);
  1016. }
  1017. return this;
  1018. };
  1019. var getInstance = function(klass){
  1020. klass.$prototyping = true;
  1021. var proto = new klass;
  1022. delete klass.$prototyping;
  1023. return proto;
  1024. };
  1025. Class.implement('implement', implement.overloadSetter());
  1026. Class.Mutators = {
  1027. Extends: function(parent){
  1028. this.parent = parent;
  1029. this.prototype = getInstance(parent);
  1030. },
  1031. Implements: function(items){
  1032. Array.from(items).each(function(item){
  1033. var instance = new item;
  1034. for (var key in instance) implement.call(this, key, instance[key], true);
  1035. }, this);
  1036. }
  1037. };
  1038. })();
  1039. /*
  1040. ---
  1041. name: Class.Extras
  1042. description: Contains Utility Classes that can be implemented into your own Classes to ease the execution of many common tasks.
  1043. license: MIT-style license.
  1044. requires: Class
  1045. provides: [Class.Extras, Chain, Events, Options]
  1046. ...
  1047. */
  1048. (function(){
  1049. this.Chain = new Class({
  1050. $chain: [],
  1051. chain: function(){
  1052. this.$chain.append(Array.flatten(arguments));
  1053. return this;
  1054. },
  1055. callChain: function(){
  1056. return (this.$chain.length) ? this.$chain.shift().apply(this, arguments) : false;
  1057. },
  1058. clearChain: function(){
  1059. this.$chain.empty();
  1060. return this;
  1061. }
  1062. });
  1063. var removeOn = function(string){
  1064. return string.replace(/^on([A-Z])/, function(full, first){
  1065. return first.toLowerCase();
  1066. });
  1067. };
  1068. this.Events = new Class({
  1069. $events: {},
  1070. addEvent: function(type, fn, internal){
  1071. type = removeOn(type);
  1072. this.$events[type] = (this.$events[type] || []).include(fn);
  1073. if (internal) fn.internal = true;
  1074. return this;
  1075. },
  1076. addEvents: function(events){
  1077. for (var type in events) this.addEvent(type, events[type]);
  1078. return this;
  1079. },
  1080. fireEvent: function(type, args, delay){
  1081. type = removeOn(type);
  1082. var events = this.$events[type];
  1083. if (!events) return this;
  1084. args = Array.from(args);
  1085. events.each(function(fn){
  1086. if (delay) fn.delay(delay, this, args);
  1087. else fn.apply(this, args);
  1088. }, this);
  1089. return this;
  1090. },
  1091. removeEvent: function(type, fn){
  1092. type = removeOn(type);
  1093. var events = this.$events[type];
  1094. if (events && !fn.internal){
  1095. var index = events.indexOf(fn);
  1096. if (index != -1) delete events[index];
  1097. }
  1098. return this;
  1099. },
  1100. removeEvents: function(events){
  1101. var type;
  1102. if (typeOf(events) == 'object'){
  1103. for (type in events) this.removeEvent(type, events[type]);
  1104. return this;
  1105. }
  1106. if (events) events = removeOn(events);
  1107. for (type in this.$events){
  1108. if (events && events != type) continue;
  1109. var fns = this.$events[type];
  1110. for (var i = fns.length; i--;) if (i in fns){
  1111. this.removeEvent(type, fns[i]);
  1112. }
  1113. }
  1114. return this;
  1115. }
  1116. });
  1117. this.Options = new Class({
  1118. setOptions: function(){
  1119. var options = this.options = Object.merge.apply(null, [{}, this.options].append(arguments));
  1120. if (this.addEvent) for (var option in options){
  1121. if (typeOf(options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue;
  1122. this.addEvent(option, options[option]);
  1123. delete options[option];
  1124. }
  1125. return this;
  1126. }
  1127. });
  1128. })();
  1129. /*
  1130. ---
  1131. name: Slick.Parser
  1132. description: Standalone CSS3 Selector parser
  1133. provides: Slick.Parser
  1134. ...
  1135. */
  1136. ;(function(){
  1137. var parsed,
  1138. separatorIndex,
  1139. combinatorIndex,
  1140. reversed,
  1141. cache = {},
  1142. reverseCache = {},
  1143. reUnescape = /\\/g;
  1144. var parse = function(expression, isReversed){
  1145. if (expression == null) return null;
  1146. if (expression.Slick === true) return expression;
  1147. expression = ('' + expression).replace(/^\s+|\s+$/g, '');
  1148. reversed = !!isReversed;
  1149. var currentCache = (reversed) ? reverseCache : cache;
  1150. if (currentCache[expression]) return currentCache[expression];
  1151. parsed = {
  1152. Slick: true,
  1153. expressions: [],
  1154. raw: expression,
  1155. reverse: function(){
  1156. return parse(this.raw, true);
  1157. }
  1158. };
  1159. separatorIndex = -1;
  1160. while (expression != (expression = expression.replace(regexp, parser)));
  1161. parsed.length = parsed.expressions.length;
  1162. return currentCache[parsed.raw] = (reversed) ? reverse(parsed) : parsed;
  1163. };
  1164. var reverseCombinator = function(combinator){
  1165. if (combinator === '!') return ' ';
  1166. else if (combinator === ' ') return '!';
  1167. else if ((/^!/).test(combinator)) return combinator.replace(/^!/, '');
  1168. else return '!' + combinator;
  1169. };
  1170. var reverse = function(expression){
  1171. var expressions = expression.expressions;
  1172. for (var i = 0; i < expressions.length; i++){
  1173. var exp = expressions[i];
  1174. var last = {parts: [], tag: '*', combinator: reverseCombinator(exp[0].combinator)};
  1175. for (var j = 0; j < exp.length; j++){
  1176. var cexp = exp[j];
  1177. if (!cexp.reverseCombinator) cexp.reverseCombinator = ' ';
  1178. cexp.combinator = cexp.reverseCombinator;
  1179. delete cexp.reverseCombinator;
  1180. }
  1181. exp.reverse().push(last);
  1182. }
  1183. return expression;
  1184. };
  1185. var escapeRegExp = function(string){// Credit: XRegExp 0.6.1 (c) 2007-2008 Steven Levithan <http://stevenlevithan.com/regex/xregexp/> MIT License
  1186. return string.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, function(match){
  1187. return '\\' + match;
  1188. });
  1189. };
  1190. var regexp = new RegExp(
  1191. /*
  1192. #!/usr/bin/env ruby
  1193. puts "\t\t" + DATA.read.gsub(/\(\?x\)|\s+#.*$|\s+|\\$|\\n/,'')
  1194. __END__
  1195. "(?x)^(?:\
  1196. \\s* ( , ) \\s* # Separator \n\
  1197. | \\s* ( <combinator>+ ) \\s* # Combinator \n\
  1198. | ( \\s+ ) # CombinatorChildren \n\
  1199. | ( <unicode>+ | \\* ) # Tag \n\
  1200. | \\# ( <unicode>+ ) # ID \n\
  1201. | \\. ( <unicode>+ ) # ClassName \n\
  1202. | # Attribute \n\
  1203. \\[ \
  1204. \\s* (<unicode1>+) (?: \
  1205. \\s* ([*^$!~|]?=) (?: \
  1206. \\s* (?:\
  1207. ([\"']?)(.*?)\\9 \
  1208. )\
  1209. ) \
  1210. )? \\s* \
  1211. \\](?!\\]) \n\
  1212. | :+ ( <unicode>+ )(?:\
  1213. \\( (?:\
  1214. (?:([\"'])([^\\12]*)\\12)|((?:\\([^)]+\\)|[^()]*)+)\
  1215. ) \\)\
  1216. )?\
  1217. )"
  1218. */
  1219. "^(?:\\s*(,)\\s*|\\s*(<combinator>+)\\s*|(\\s+)|(<unicode>+|\\*)|\\#(<unicode>+)|\\.(<unicode>+)|\\[\\s*(<unicode1>+)(?:\\s*([*^$!~|]?=)(?:\\s*(?:([\"']?)(.*?)\\9)))?\\s*\\](?!\\])|(:+)(<unicode>+)(?:\\((?:(?:([\"'])([^\\13]*)\\13)|((?:\\([^)]+\\)|[^()]*)+))\\))?)"
  1220. .replace(/<combinator>/, '[' + escapeRegExp(">+~`!@$%^&={}\\;</") + ']')
  1221. .replace(/<unicode>/g, '(?:[\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])')
  1222. .replace(/<unicode1>/g, '(?:[:\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])')
  1223. );
  1224. function parser(
  1225. rawMatch,
  1226. separator,
  1227. combinator,
  1228. combinatorChildren,
  1229. tagName,
  1230. id,
  1231. className,
  1232. attributeKey,
  1233. attributeOperator,
  1234. attributeQuote,
  1235. attributeValue,
  1236. pseudoMarker,
  1237. pseudoClass,
  1238. pseudoQuote,
  1239. pseudoClassQuotedValue,
  1240. pseudoClassValue
  1241. ){
  1242. if (separator || separatorIndex === -1){
  1243. parsed.expressions[++separatorIndex] = [];
  1244. combinatorIndex = -1;
  1245. if (separator) return '';
  1246. }
  1247. if (combinator || combinatorChildren || combinatorIndex === -1){
  1248. combinator = combinator || ' ';
  1249. var currentSeparator = parsed.expressions[separatorIndex];
  1250. if (reversed && currentSeparator[combinatorIndex])
  1251. currentSeparator[combinatorIndex].reverseCombinator = reverseCombinator(combinator);
  1252. currentSeparator[++combinatorIndex] = {combinator: combinator, tag: '*'};
  1253. }
  1254. var currentParsed = parsed.expressions[separatorIndex][combinatorIndex];
  1255. if (tagName){
  1256. currentParsed.tag = tagName.replace(reUnescape, '');
  1257. } else if (id){
  1258. currentParsed.id = id.replace(reUnescape, '');
  1259. } else if (className){
  1260. className = className.replace(reUnescape, '');
  1261. if (!currentParsed.classList) currentParsed.classList = [];
  1262. if (!currentParsed.classes) currentParsed.classes = [];
  1263. currentParsed.classList.push(className);
  1264. currentParsed.classes.push({
  1265. value: className,
  1266. regexp: new RegExp('(^|\\s)' + escapeRegExp(className) + '(\\s|$)')
  1267. });
  1268. } else if (pseudoClass){
  1269. pseudoClassValue = pseudoClassValue || pseudoClassQuotedValue;
  1270. pseudoClassValue = pseudoClassValue ? pseudoClassValue.replace(reUnescape, '') : null;
  1271. if (!currentParsed.pseudos) currentParsed.pseudos = [];
  1272. currentParsed.pseudos.push({
  1273. key: pseudoClass.replace(reUnescape, ''),
  1274. value: pseudoClassValue,
  1275. type: pseudoMarker.length == 1 ? 'class' : 'element'
  1276. });
  1277. } else if (attributeKey){
  1278. attributeKey = attributeKey.replace(reUnescape, '');
  1279. attributeValue = (attributeValue || '').replace(reUnescape, '');
  1280. var test, regexp;
  1281. switch (attributeOperator){
  1282. case '^=' : regexp = new RegExp( '^'+ escapeRegExp(attributeValue) ); break;
  1283. case '$=' : regexp = new RegExp( escapeRegExp(attributeValue) +'$' ); break;
  1284. case '~=' : regexp = new RegExp( '(^|\\s)'+ escapeRegExp(attributeValue) +'(\\s|$)' ); break;
  1285. case '|=' : regexp = new RegExp( '^'+ escapeRegExp(attributeValue) +'(-|$)' ); break;
  1286. case '=' : test = function(value){
  1287. return attributeValue == value;
  1288. }; break;
  1289. case '*=' : test = function(value){
  1290. return value && value.indexOf(attributeValue) > -1;
  1291. }; break;
  1292. case '!=' : test = function(value){
  1293. return attributeValue != value;
  1294. }; break;
  1295. default : test = function(value){
  1296. return !!value;
  1297. };
  1298. }
  1299. if (attributeValue == '' && (/^[*$^]=$/).test(attributeOperator)) test = function(){
  1300. return false;
  1301. };
  1302. if (!test) test = function(value){
  1303. return value && regexp.test(value);
  1304. };
  1305. if (!currentParsed.attributes) currentParsed.attributes = [];
  1306. currentParsed.attributes.push({
  1307. key: attributeKey,
  1308. operator: attributeOperator,
  1309. value: attributeValue,
  1310. test: test
  1311. });
  1312. }
  1313. return '';
  1314. };
  1315. // Slick NS
  1316. var Slick = (this.Slick || {});
  1317. Slick.parse = function(expression){
  1318. return parse(expression);
  1319. };
  1320. Slick.escapeRegExp = escapeRegExp;
  1321. if (!this.Slick) this.Slick = Slick;
  1322. }).apply(/*<CommonJS>*/(typeof exports != 'undefined') ? exports : /*</CommonJS>*/this);
  1323. /*
  1324. ---
  1325. name: Slick.Finder
  1326. description: The new, superfast css selector engine.
  1327. provides: Slick.Finder
  1328. requires: Slick.Parser
  1329. ...
  1330. */
  1331. ;(function(){
  1332. var local = {},
  1333. featuresCache = {},
  1334. toString = Object.prototype.toString;
  1335. // Feature / Bug detection
  1336. local.isNativeCode = function(fn){
  1337. return (/\{\s*\[native code\]\s*\}/).test('' + fn);
  1338. };
  1339. local.isXML = function(document){
  1340. return (!!document.xmlVersion) || (!!document.xml) || (toString.call(document) == '[object XMLDocument]') ||
  1341. (document.nodeType == 9 && document.documentElement.nodeName != 'HTML');
  1342. };
  1343. local.setDocument = function(document){
  1344. // convert elements / window arguments to document. if document cannot be extrapolated, the function returns.
  1345. var nodeType = document.nodeType;
  1346. if (nodeType == 9); // document
  1347. else if (nodeType) document = document.ownerDocument; // node
  1348. else if (document.navigator) document = document.document; // window
  1349. else return;
  1350. // check if it's the old document
  1351. if (this.document === document) return;
  1352. this.document = document;
  1353. // check if we have done feature detection on this document before
  1354. var root = document.documentElement,
  1355. rootUid = this.getUIDXML(root),
  1356. features = featuresCache[rootUid],
  1357. feature;
  1358. if (features){
  1359. for (feature in features){
  1360. this[feature] = features[feature];
  1361. }
  1362. return;
  1363. }
  1364. features = featuresCache[rootUid] = {};
  1365. features.root = root;
  1366. features.isXMLDocument = this.isXML(document);
  1367. features.brokenStarGEBTN
  1368. = features.starSelectsClosedQSA
  1369. = features.idGetsName
  1370. = features.brokenMixedCaseQSA
  1371. = features.brokenGEBCN
  1372. = features.brokenCheckedQSA
  1373. = features.brokenEmptyAttributeQSA
  1374. = features.isHTMLDocument
  1375. = features.nativeMatchesSelector
  1376. = false;
  1377. var starSelectsClosed, starSelectsComments,
  1378. brokenSecondClassNameGEBCN, cachedGetElementsByClassName,
  1379. brokenFormAttributeGetter;
  1380. var selected, id = 'slick_uniqueid';
  1381. var testNode = document.createElement('div');
  1382. var testRoot = document.body || document.getElementsByTagName('body')[0] || root;
  1383. testRoot.appendChild(testNode);
  1384. // on non-HTML documents innerHTML and getElementsById doesnt work properly
  1385. try {
  1386. testNode.innerHTML = '<a id="'+id+'"></a>';
  1387. features.isHTMLDocument = !!document.getElementById(id);
  1388. } catch(e){};
  1389. if (features.isHTMLDocument){
  1390. testNode.style.display = 'none';
  1391. // IE returns comment nodes for getElementsByTagName('*') for some documents
  1392. testNode.appendChild(document.createComment(''));
  1393. starSelectsComments = (testNode.getElementsByTagName('*').length > 1);
  1394. // IE returns closed nodes (EG:"</foo>") for getElementsByTagName('*') for some documents
  1395. try {
  1396. testNode.innerHTML = 'foo</foo>';
  1397. selected = testNode.getElementsByTagName('*');
  1398. starSelectsClosed = (selected && !!selected.length && selected[0].nodeName.charAt(0) == '/');
  1399. } catch(e){};
  1400. features.brokenStarGEBTN = starSelectsComments || starSelectsClosed;
  1401. // IE returns elements with the name instead of just id for getElementsById for some documents
  1402. try {
  1403. testNode.innerHTML = '<a name="'+ id +'"></a><b id="'+ id +'"></b>';
  1404. features.idGetsName = document.getElementById(id) === testNode.firstChild;
  1405. } catch(e){};
  1406. if (testNode.getElementsByClassName){
  1407. // Safari 3.2 getElementsByClassName caches results
  1408. try {
  1409. testNode.innerHTML = '<a class="f"></a><a class="b"></a>';
  1410. testNode.getElementsByClassName('b').length;
  1411. testNode.firstChild.className = 'b';
  1412. cachedGetElementsByClassName = (testNode.getElementsByClassName('b').length != 2);
  1413. } catch(e){};
  1414. // Opera 9.6 getElementsByClassName doesnt detects the class if its not the first one
  1415. try {
  1416. testNode.innerHTML = '<a class="a"></a><a class="f b a"></a>';
  1417. brokenSecondClassNameGEBCN = (testNode.getElementsByClassName('a').length != 2);
  1418. } catch(e){};
  1419. features.brokenGEBCN = cachedGetElementsByClassName || brokenSecondClassNameGEBCN;
  1420. }
  1421. if (testNode.querySelectorAll){
  1422. // IE 8 returns closed nodes (EG:"</foo>") for querySelectorAll('*') for some documents
  1423. try {
  1424. testNode.innerHTML = 'foo</foo>';
  1425. selected = testNode.querySelectorAll('*');
  1426. features.starSelectsClosedQSA = (selected && !!selected.length && selected[0].nodeName.charAt(0) == '/');
  1427. } catch(e){};
  1428. // Safari 3.2 querySelectorAll doesnt work with mixedcase on quirksmode
  1429. try {
  1430. testNode.innerHTML = '<a class="MiX"></a>';
  1431. features.brokenMixedCaseQSA = !testNode.querySelectorAll('.MiX').length;
  1432. } catch(e){};
  1433. // Webkit and Opera dont return selected options on querySelectorAll
  1434. try {
  1435. testNode.innerHTML = '<select><option selected="selected">a</option></select>';
  1436. features.brokenCheckedQSA = (testNode.querySelectorAll(':checked').length == 0);
  1437. } catch(e){};
  1438. // IE returns incorrect results for attr[*^$]="" selectors on querySelectorAll
  1439. try {
  1440. testNode.innerHTML = '<a class=""></a>';
  1441. features.brokenEmptyAttributeQSA = (testNode.querySelectorAll('[class*=""]').length != 0);
  1442. } catch(e){};
  1443. }
  1444. // IE6-7, if a form has an input of id x, form.getAttribute(x) returns a reference to the input
  1445. try {
  1446. testNode.innerHTML = '<form action="s"><input id="action"/></form>';
  1447. brokenFormAttributeGetter = (testNode.firstChild.getAttribute('action') != 's');
  1448. } catch(e){};
  1449. // native matchesSelector function
  1450. features.nativeMatchesSelector = root.matchesSelector || /*root.msMatchesSelector ||*/ root.mozMatchesSelector || root.webkitMatchesSelector;
  1451. if (features.nativeMatchesSelector) try {
  1452. // if matchesSelector trows errors on incorrect sintaxes we can use it
  1453. features.nativeMatchesSelector.call(root, ':slick');
  1454. features.nativeMatchesSelector = null;
  1455. } catch(e){};
  1456. }
  1457. try {
  1458. root.slick_expando = 1;
  1459. delete root.slick_expando;
  1460. features.getUID = this.getUIDHTML;
  1461. } catch(e) {
  1462. features.getUID = this.getUIDXML;
  1463. }
  1464. testRoot.removeChild(testNode);
  1465. testNode = selected = testRoot = null;
  1466. // getAttribute
  1467. features.getAttribute = (features.isHTMLDocument && brokenFormAttributeGetter) ? function(node, name){
  1468. var method = this.attributeGetters[name];
  1469. if (method) return method.call(node);
  1470. var attributeNode = node.getAttributeNode(name);
  1471. return (attributeNode) ? attributeNode.nodeValue : null;
  1472. } : function(node, name){
  1473. var method = this.attributeGetters[name];
  1474. return (method) ? method.call(node) : node.getAttribute(name);
  1475. };
  1476. // hasAttribute
  1477. features.hasAttribute = (root && this.isNativeCode(root.hasAttribute)) ? function(node, attribute) {
  1478. return node.hasAttribute(attribute);
  1479. } : function(node, attribute) {
  1480. node = node.getAttributeNode(attribute);
  1481. return !!(node && (node.specified || node.nodeValue));
  1482. };
  1483. // contains
  1484. // FIXME: Add specs: local.contains should be different for xml and html documents?
  1485. features.contains = (root && this.isNativeCode(root.contains)) ? function(context, node){
  1486. return context.contains(node);
  1487. } : (root && root.compareDocumentPosition) ? function(context, node){
  1488. return context === node || !!(context.compareDocumentPosition(node) & 16);
  1489. } : function(context, node){
  1490. if (node) do {
  1491. if (node === context) return true;
  1492. } while ((node = node.parentNode));
  1493. return false;
  1494. };
  1495. // document order sorting
  1496. // credits to Sizzle (http://sizzlejs.com/)
  1497. features.documentSorter = (root.compareDocumentPosition) ? function(a, b){
  1498. if (!a.compareDocumentPosition || !b.compareDocumentPosition) return 0;
  1499. return a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
  1500. } : ('sourceIndex' in root) ? function(a, b){
  1501. if (!a.sourceIndex || !b.sourceIndex) return 0;
  1502. return a.sourceIndex - b.sourceIndex;
  1503. } : (document.createRange) ? function(a, b){
  1504. if (!a.ownerDocument || !b.ownerDocument) return 0;
  1505. var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
  1506. aRange.setStart(a, 0);
  1507. aRange.setEnd(a, 0);
  1508. bRange.setStart(b, 0);
  1509. bRange.setEnd(b, 0);
  1510. return aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
  1511. } : null ;
  1512. root = null;
  1513. for (feature in features){
  1514. this[feature] = features[feature];
  1515. }
  1516. };
  1517. // Main Method
  1518. var reSimpleSelector = /^([#.]?)((?:[\w-]+|\*))$/,
  1519. reEmptyAttribute = /\[.+[*$^]=(?:""|'')?\]/,
  1520. qsaFailExpCache = {};
  1521. local.search = function(context, expression, append, first){
  1522. var found = this.found = (first) ? null : (append || []);
  1523. if (!context) return found;
  1524. else if (context.navigator) context = context.document; // Convert the node from a window to a document
  1525. else if (!context.nodeType) return found;
  1526. // setup
  1527. var parsed, i,
  1528. uniques = this.uniques = {},
  1529. hasOthers = !!(append && append.length),
  1530. contextIsDocument = (context.nodeType == 9);
  1531. if (this.document !== (contextIsDocument ? context : context.ownerDocument)) this.setDocument(context);
  1532. // avoid duplicating items already in the append array
  1533. if (hasOthers) for (i = found.length; i--;) uniques[this.getUID(found[i])] = true;
  1534. // expression checks
  1535. if (typeof expression == 'string'){ // expression is a string
  1536. /*<simple-selectors-override>*/
  1537. var simpleSelector = expression.match(reSimpleSelector);
  1538. simpleSelectors: if (simpleSelector) {
  1539. var symbol = simpleSelector[1],
  1540. name = simpleSelector[2],
  1541. node, nodes;
  1542. if (!symbol){
  1543. if (name == '*' && this.brokenStarGEBTN) break simpleSelectors;
  1544. nodes = context.getElementsByTagName(name);
  1545. if (first) return nodes[0] || null;
  1546. for (i = 0; node = nodes[i++];){
  1547. if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
  1548. }
  1549. } else if (symbol == '#'){
  1550. if (!this.isHTMLDocument || !contextIsDocument) break simpleSelectors;
  1551. node = context.getElementById(name);
  1552. if (!node) return found;
  1553. if (this.idGetsName && node.getAttributeNode('id').nodeValue != name) break simpleSelectors;
  1554. if (first) return node || null;
  1555. if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
  1556. } else if (symbol == '.'){
  1557. if (!this.isHTMLDocument || ((!context.getElementsByClassName || this.brokenGEBCN) && context.querySelectorAll)) break simpleSelectors;
  1558. if (context.getElementsByClassName && !this.brokenGEBCN){
  1559. nodes = context.getElementsByClassName(name);
  1560. if (first) return nodes[0] || null;
  1561. for (i = 0; node = nodes[i++];){
  1562. if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
  1563. }
  1564. } else {
  1565. var matchClass = new RegExp('(^|\\s)'+ Slick.escapeRegExp(name) +'(\\s|$)');
  1566. nodes = context.getElementsByTagName('*');
  1567. for (i = 0; node = nodes[i++];){
  1568. className = node.className;
  1569. if (!(className && matchClass.test(className))) continue;
  1570. if (first) return node;
  1571. if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
  1572. }
  1573. }
  1574. }
  1575. if (hasOthers) this.sort(found);
  1576. return (first) ? null : found;
  1577. }
  1578. /*</simple-selectors-override>*/
  1579. /*<query-selector-override>*/
  1580. querySelector: if (context.querySelectorAll) {
  1581. if (!this.isHTMLDocument
  1582. || qsaFailExpCache[expression]
  1583. //TODO: only skip when expression is actually mixed case
  1584. || this.brokenMixedCaseQSA
  1585. || (this.brokenCheckedQSA && expression.indexOf(':checked') > -1)
  1586. || (this.brokenEmptyAttributeQSA && reEmptyAttribute.test(expression))
  1587. || (!contextIsDocument //Abort when !contextIsDocument and...
  1588. // there are multiple expressions in the selector
  1589. // since we currently only fix non-document rooted QSA for single expression selectors
  1590. && expression.indexOf(',') > -1
  1591. )
  1592. || Slick.disableQSA
  1593. ) break querySelector;
  1594. var _expression = expression, _context = context;
  1595. if (!contextIsDocument){
  1596. // non-document rooted QSA
  1597. // credits to Andrew Dupont
  1598. var currentId = _context.getAttribute('id'), slickid = 'slickid__';
  1599. _context.setAttribute('id', slickid);
  1600. _expression = '#' + slickid + ' ' + _expression;
  1601. context = _context.parentNode;
  1602. }
  1603. try {
  1604. if (first) return context.querySelector(_expression) || null;
  1605. else nodes = context.querySelectorAll(_expression);
  1606. } catch(e) {
  1607. qsaFailExpCache[expression] = 1;
  1608. break querySelector;
  1609. } finally {
  1610. if (!contextIsDocument){
  1611. if (currentId) _context.setAttribute('id', currentId);
  1612. else _context.removeAttribute('id');
  1613. context = _context;
  1614. }
  1615. }
  1616. if (this.starSelectsClosedQSA) for (i = 0; node = nodes[i++];){
  1617. if (node.nodeName > '@' && !(hasOthers && uniques[this.getUID(node)])) found.push(node);
  1618. } else for (i = 0; node = nodes[i++];){
  1619. if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
  1620. }
  1621. if (hasOthers) this.sort(found);
  1622. return found;
  1623. }
  1624. /*</query-selector-override>*/
  1625. parsed = this.Slick.parse(expression);
  1626. if (!parsed.length) return found;
  1627. } else if (expression == null){ // there is no expression
  1628. return found;
  1629. } else if (expression.Slick){ // expression is a parsed Slick object
  1630. parsed = expression;
  1631. } else if (this.contains(context.documentElement || context, expression)){ // expression is a node
  1632. (found) ? found.push(expression) : found = expression;
  1633. return found;
  1634. } else { // other junk
  1635. return found;
  1636. }
  1637. /*<pseudo-selectors>*//*<nth-pseudo-selectors>*/
  1638. // cache elements for the nth selectors
  1639. this.posNTH = {};
  1640. this.posNTHLast = {};
  1641. this.posNTHType = {};
  1642. this.posNTHTypeLast = {};
  1643. /*</nth-pseudo-selectors>*//*</pseudo-selectors>*/
  1644. // if append is null and there is only a single selector with one expression use pushArray, else use pushUID
  1645. this.push = (!hasOthers && (first || (parsed.length == 1 && parsed.expressions[0].length == 1))) ? this.pushArray : this.pushUID;
  1646. if (found == null) found = [];
  1647. // default engine
  1648. var j, m, n;
  1649. var combinator, tag, id, classList, classes, attributes, pseudos;
  1650. var currentItems, currentExpression, currentBit, lastBit, expressions = parsed.expressions;
  1651. search: for (i = 0; (currentExpression = expressions[i]); i++) for (j = 0; (currentBit = currentExpression[j]); j++){
  1652. combinator = 'combinator:' + currentBit.combinator;
  1653. if (!this[combinator]) continue search;
  1654. tag = (this.isXMLDocument) ? currentBit.tag : currentBit.tag.toUpperCase();
  1655. id = currentBit.id;
  1656. classList = currentBit.classList;
  1657. classes = currentBit.classes;
  1658. attributes = currentBit.attributes;
  1659. pseudos = currentBit.pseudos;
  1660. lastBit = (j === (currentExpression.length - 1));
  1661. this.bitUniques = {};
  1662. if (lastBit){
  1663. this.uniques = uniques;
  1664. this.found = found;
  1665. } else {
  1666. this.uniques = {};
  1667. this.found = [];
  1668. }
  1669. if (j === 0){
  1670. this[combinator](context, tag, id, classes, attributes, pseudos, classList);
  1671. if (first && lastBit && found.length) break search;
  1672. } else {
  1673. if (first && lastBit) for (m = 0, n = currentItems.length; m < n; m++){
  1674. this[combinator](currentItems[m], tag, id, classes, attributes, pseudos, classList);
  1675. if (found.length) break search;
  1676. } else for (m = 0, n = currentItems.length; m < n; m++) this[combinator](currentItems[m], tag, id, classes, attributes, pseudos, classList);
  1677. }
  1678. currentItems = this.found;
  1679. }
  1680. // should sort if there are nodes in append and if you pass multiple expressions.
  1681. if (hasOthers || (parsed.expressions.length > 1)) this.sort(found);
  1682. return (first) ? (found[0] || null) : found;
  1683. };
  1684. // Utils
  1685. local.uidx = 1;
  1686. local.uidk = 'slick-uniqueid';
  1687. local.getUIDXML = function(node){
  1688. var uid = node.getAttribute(this.uidk);
  1689. if (!uid){
  1690. uid = this.uidx++;
  1691. node.setAttribute(this.uidk, uid);
  1692. }
  1693. return uid;
  1694. };
  1695. local.getUIDHTML = function(node){
  1696. return node.uniqueNumber || (node.uniqueNumber = this.uidx++);
  1697. };
  1698. // sort based on the setDocument documentSorter method.
  1699. local.sort = function(results){
  1700. if (!this.documentSorter) return results;
  1701. results.sort(this.documentSorter);
  1702. return results;
  1703. };
  1704. /*<pseudo-selectors>*//*<nth-pseudo-selectors>*/
  1705. local.cacheNTH = {};
  1706. local.matchNTH = /^([+-]?\d*)?([a-z]+)?([+-]\d+)?$/;
  1707. local.parseNTHArgument = function(argument){
  1708. var parsed = argument.match(this.matchNTH);
  1709. if (!parsed) return false;
  1710. var special = parsed[2] || false;
  1711. var a = parsed[1] || 1;
  1712. if (a == '-') a = -1;
  1713. var b = +parsed[3] || 0;
  1714. parsed =
  1715. (special == 'n') ? {a: a, b: b} :
  1716. (special == 'odd') ? {a: 2, b: 1} :
  1717. (special == 'even') ? {a: 2, b: 0} : {a: 0, b: a};
  1718. return (this.cacheNTH[argument] = parsed);
  1719. };
  1720. local.createNTHPseudo = function(child, sibling, positions, ofType){
  1721. return function(node, argument){
  1722. var uid = this.getUID(node);
  1723. if (!this[positions][uid]){
  1724. var parent = node.parentNode;
  1725. if (!parent) return false;
  1726. var el = parent[child], count = 1;
  1727. if (ofType){
  1728. var nodeName = node.nodeName;
  1729. do {
  1730. if (el.nodeName != nodeName) continue;
  1731. this[positions][this.getUID(el)] = count++;
  1732. } while ((el = el[sibling]));
  1733. } else {
  1734. do {
  1735. if (el.nodeType != 1) continue;
  1736. this[positions][this.getUID(el)] = count++;
  1737. } while ((el = el[sibling]));
  1738. }
  1739. }
  1740. argument = argument || 'n';
  1741. var parsed = this.cacheNTH[argument] || this.parseNTHArgument(argument);
  1742. if (!parsed) return false;
  1743. var a = parsed.a, b = parsed.b, pos = this[positions][uid];
  1744. if (a == 0) return b == pos;
  1745. if (a > 0){
  1746. if (pos < b) return false;
  1747. } else {
  1748. if (b < pos) return false;
  1749. }
  1750. return ((pos - b) % a) == 0;
  1751. };
  1752. };
  1753. /*</nth-pseudo-selectors>*//*</pseudo-selectors>*/
  1754. local.pushArray = function(node, tag, id, classes, attributes, pseudos){
  1755. if (this.matchSelector(node, tag, id, classes, attributes, pseudos)) this.found.push(node);
  1756. };
  1757. local.pushUID = function(node, tag, id, classes, attributes, pseudos){
  1758. var uid = this.getUID(node);
  1759. if (!this.uniques[uid] && this.matchSelector(node, tag, id, classes, attributes, pseudos)){
  1760. this.uniques[uid] = true;
  1761. this.found.push(node);
  1762. }
  1763. };
  1764. local.matchNode = function(node, selector){
  1765. if (this.isHTMLDocument && this.nativeMatchesSelector){
  1766. try {
  1767. return this.nativeMatchesSelector.call(node, selector.replace(/\[([^=]+)=\s*([^'"\]]+?)\s*\]/g, '[$1="$2"]'));
  1768. } catch(matchError) {}
  1769. }
  1770. var parsed = this.Slick.parse(selector);
  1771. if (!parsed) return true;
  1772. // simple (single) selectors
  1773. var expressions = parsed.expressions, reversedExpressions, simpleExpCounter = 0, i;
  1774. for (i = 0; (currentExpression = expressions[i]); i++){
  1775. if (currentExpression.length == 1){
  1776. var exp = currentExpression[0];
  1777. if (this.matchSelector(node, (this.isXMLDocument) ? exp.tag : exp.tag.toUpperCase(), exp.id, exp.classes, exp.attributes, exp.pseudos)) return true;
  1778. simpleExpCounter++;
  1779. }
  1780. }
  1781. if (simpleExpCounter == parsed.length) return false;
  1782. var nodes = this.search(this.document, parsed), item;
  1783. for (i = 0; item = nodes[i++];){
  1784. if (item === node) return true;
  1785. }
  1786. return false;
  1787. };
  1788. local.matchPseudo = function(node, name, argument){
  1789. var pseudoName = 'pseudo:' + name;
  1790. if (this[pseudoName]) return this[pseudoName](node, argument);
  1791. var attribute = this.getAttribute(node, name);
  1792. return (argument) ? argument == attribute : !!attribute;
  1793. };
  1794. local.matchSelector = function(node, tag, id, classes, attributes, pseudos){
  1795. if (tag){
  1796. var nodeName = (this.isXMLDocument) ? node.nodeName : node.nodeName.toUpperCase();
  1797. if (tag == '*'){
  1798. if (nodeName < '@') return false; // Fix for comment nodes and closed nodes
  1799. } else {
  1800. if (nodeName != tag) return false;
  1801. }
  1802. }
  1803. if (id && node.getAttribute('id') != id) return false;
  1804. var i, part, cls;
  1805. if (classes) for (i = classes.length; i--;){
  1806. cls = node.getAttribute('class') || node.className;
  1807. if (!(cls && classes[i].regexp.test(cls))) return false;
  1808. }
  1809. if (attributes) for (i = attributes.length; i--;){
  1810. part = attributes[i];
  1811. if (part.operator ? !part.test(this.getAttribute(node, part.key)) : !this.hasAttribute(node, part.key)) return false;
  1812. }
  1813. if (pseudos) for (i = pseudos.length; i--;){
  1814. part = pseudos[i];
  1815. if (!this.matchPseudo(node, part.key, part.value)) return false;
  1816. }
  1817. return true;
  1818. };
  1819. var combinators = {
  1820. ' ': function(node, tag, id, classes, attributes, pseudos, classList){ // all child nodes, any level
  1821. var i, item, children;
  1822. if (this.isHTMLDocument){
  1823. getById: if (id){
  1824. item = this.document.getElementById(id);
  1825. if ((!item && node.all) || (this.idGetsName && item && item.getAttributeNode('id').nodeValue != id)){
  1826. // all[id] returns all the elements with that name or id inside node
  1827. // if theres just one it will return the element, else it will be a collection
  1828. children = node.all[id];
  1829. if (!children) return;
  1830. if (!children[0]) children = [children];
  1831. for (i = 0; item = children[i++];){
  1832. var idNode = item.getAttributeNode('id');
  1833. if (idNode && idNode.nodeValue == id){
  1834. this.push(item, tag, null, classes, attributes, pseudos);
  1835. break;
  1836. }
  1837. }
  1838. return;
  1839. }
  1840. if (!item){
  1841. // if the context is in the dom we return, else we will try GEBTN, breaking the getById label
  1842. if (this.contains(this.root, node)) return;
  1843. else break getById;
  1844. } else if (this.document !== node && !this.contains(node, item)) return;
  1845. this.push(item, tag, null, classes, attributes, pseudos);
  1846. return;
  1847. }
  1848. getByClass: if (classes && node.getElementsByClassName && !this.brokenGEBCN){
  1849. children = node.getElementsByClassName(classList.join(' '));
  1850. if (!(children && children.length)) break getByClass;
  1851. for (i = 0; item = children[i++];) this.push(item, tag, id, null, attributes, pseudos);
  1852. return;
  1853. }
  1854. }
  1855. getByTag: {
  1856. children = node.getElementsByTagName(tag);
  1857. if (!(children && children.length)) break getByTag;
  1858. if (!this.brokenStarGEBTN) tag = null;
  1859. for (i = 0; item = children[i++];) this.push(item, tag, id, classes, attributes, pseudos);
  1860. }
  1861. },
  1862. '>': function(node, tag, id, classes, attributes, pseudos){ // direct children
  1863. if ((node = node.firstChild)) do {
  1864. if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos);
  1865. } while ((node = node.nextSibling));
  1866. },
  1867. '+': function(node, tag, id, classes, attributes, pseudos){ // next sibling
  1868. while ((node = node.nextSibling)) if (node.nodeType == 1){
  1869. this.push(node, tag, id, classes, attributes, pseudos);
  1870. break;
  1871. }
  1872. },
  1873. '^': function(node, tag, id, classes, attributes, pseudos){ // first child
  1874. node = node.firstChild;
  1875. if (node){
  1876. if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos);
  1877. else this['combinator:+'](node, tag, id, classes, attributes, pseudos);
  1878. }
  1879. },
  1880. '~': function(node, tag, id, classes, attributes, pseudos){ // next siblings
  1881. while ((node = node.nextSibling)){
  1882. if (node.nodeType != 1) continue;
  1883. var uid = this.getUID(node);
  1884. if (this.bitUniques[uid]) break;
  1885. this.bitUniques[uid] = true;
  1886. this.push(node, tag, id, classes, attributes, pseudos);
  1887. }
  1888. },
  1889. '++': function(node, tag, id, classes, attributes, pseudos){ // next sibling and previous sibling
  1890. this['combinator:+'](node, tag, id, classes, attributes, pseudos);
  1891. this['combinator:!+'](node, tag, id, classes, attributes, pseudos);
  1892. },
  1893. '~~': function(node, tag, id, classes, attributes, pseudos){ // next siblings and previous siblings
  1894. this['combinator:~'](node, tag, id, classes, attributes, pseudos);
  1895. this['combinator:!~'](node, tag, id, classes, attributes, pseudos);
  1896. },
  1897. '!': function(node, tag, id, classes, attributes, pseudos){ // all parent nodes up to document
  1898. while ((node = node.parentNode)) if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos);
  1899. },
  1900. '!>': function(node, tag, id, classes, attributes, pseudos){ // direct parent (one level)
  1901. node = node.parentNode;
  1902. if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos);
  1903. },
  1904. '!+': function(node, tag, id, classes, attributes, pseudos){ // previous sibling
  1905. while ((node = node.previousSibling)) if (node.nodeType == 1){
  1906. this.push(node, tag, id, classes, attributes, pseudos);
  1907. break;
  1908. }
  1909. },
  1910. '!^': function(node, tag, id, classes, attributes, pseudos){ // last child
  1911. node = node.lastChild;
  1912. if (node){
  1913. if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos);
  1914. else this['combinator:!+'](node, tag, id, classes, attributes, pseudos);
  1915. }
  1916. },
  1917. '!~': function(node, tag, id, classes, attributes, pseudos){ // previous siblings
  1918. while ((node = node.previousSibling)){
  1919. if (node.nodeType != 1) continue;
  1920. var uid = this.getUID(node);
  1921. if (this.bitUniques[uid]) break;
  1922. this.bitUniques[uid] = true;
  1923. this.push(node, tag, id, classes, attributes, pseudos);
  1924. }
  1925. }
  1926. };
  1927. for (var c in combinators) local['combinator:' + c] = combinators[c];
  1928. var pseudos = {
  1929. /*<pseudo-selectors>*/
  1930. 'empty': function(node){
  1931. var child = node.firstChild;
  1932. return !(child && child.nodeType == 1) && !(node.innerText || node.textContent || '').length;
  1933. },
  1934. 'not': function(node, expression){
  1935. return !this.matchNode(node, expression);
  1936. },
  1937. 'contains': function(node, text){
  1938. return (node.innerText || node.textContent || '').indexOf(text) > -1;
  1939. },
  1940. 'first-child': function(node){
  1941. while ((node = node.previousSibling)) if (node.nodeType == 1) return false;
  1942. return true;
  1943. },
  1944. 'last-child': function(node){
  1945. while ((node = node.nextSibling)) if (node.nodeType == 1) return false;
  1946. return true;
  1947. },
  1948. 'only-child': function(node){
  1949. var prev = node;
  1950. while ((prev = prev.previousSibling)) if (prev.nodeType == 1) return false;
  1951. var next = node;
  1952. while ((next = next.nextSibling)) if (next.nodeType == 1) return false;
  1953. return true;
  1954. },
  1955. /*<nth-pseudo-selectors>*/
  1956. 'nth-child': local.createNTHPseudo('firstChild', 'nextSibling', 'posNTH'),
  1957. 'nth-last-child': local.createNTHPseudo('lastChild', 'previousSibling', 'posNTHLast'),
  1958. 'nth-of-type': local.createNTHPseudo('firstChild', 'nextSibling', 'posNTHType', true),
  1959. 'nth-last-of-type': local.createNTHPseudo('lastChild', 'previousSibling', 'posNTHTypeLast', true),
  1960. 'index': function(node, index){
  1961. return this['pseudo:nth-child'](node, '' + index + 1);
  1962. },
  1963. 'even': function(node){
  1964. return this['pseudo:nth-child'](node, '2n');
  1965. },
  1966. 'odd': function(node){
  1967. return this['pseudo:nth-child'](node, '2n+1');
  1968. },
  1969. /*</nth-pseudo-selectors>*/
  1970. /*<of-type-pseudo-selectors>*/
  1971. 'first-of-type': function(node){
  1972. var nodeName = node.nodeName;
  1973. while ((node = node.previousSibling)) if (node.nodeName == nodeName) return false;
  1974. return true;
  1975. },
  1976. 'last-of-type': function(node){
  1977. var nodeName = node.nodeName;
  1978. while ((node = node.nextSibling)) if (node.nodeName == nodeName) return false;
  1979. return true;
  1980. },
  1981. 'only-of-type': function(node){
  1982. var prev = node, nodeName = node.nodeName;
  1983. while ((prev = prev.previousSibling)) if (prev.nodeName == nodeName) return false;
  1984. var next = node;
  1985. while ((next = next.nextSibling)) if (next.nodeName == nodeName) return false;
  1986. return true;
  1987. },
  1988. /*</of-type-pseudo-selectors>*/
  1989. // custom pseudos
  1990. 'enabled': function(node){
  1991. return !node.disabled;
  1992. },
  1993. 'disabled': function(node){
  1994. return node.disabled;
  1995. },
  1996. 'checked': function(node){
  1997. return node.checked || node.selected;
  1998. },
  1999. 'focus': function(node){
  2000. return this.isHTMLDocument && this.document.activeElement === node && (node.href || node.type || this.hasAttribute(node, 'tabindex'));
  2001. },
  2002. 'root': function(node){
  2003. return (node === this.root);
  2004. },
  2005. 'selected': function(node){
  2006. return node.selected;
  2007. }
  2008. /*</pseudo-selectors>*/
  2009. };
  2010. for (var p in pseudos) local['pseudo:' + p] = pseudos[p];
  2011. // attributes methods
  2012. local.attributeGetters = {
  2013. 'class': function(){
  2014. return this.getAttribute('class') || this.className;
  2015. },
  2016. 'for': function(){
  2017. return ('htmlFor' in this) ? this.htmlFor : this.getAttribute('for');
  2018. },
  2019. 'href': function(){
  2020. return ('href' in this) ? this.getAttribute('href', 2) : this.getAttribute('href');
  2021. },
  2022. 'style': function(){
  2023. return (this.style) ? this.style.cssText : this.getAttribute('style');
  2024. },
  2025. 'tabindex': function(){
  2026. var attributeNode = this.getAttributeNode('tabindex');
  2027. return (attributeNode && attributeNode.specified) ? attributeNode.nodeValue : null;
  2028. },
  2029. 'type': function(){
  2030. return this.getAttribute('type');
  2031. }
  2032. };
  2033. // Slick
  2034. var Slick = local.Slick = (this.Slick || {});
  2035. Slick.version = '1.1.5';
  2036. // Slick finder
  2037. Slick.search = function(context, expression, append){
  2038. return local.search(context, expression, append);
  2039. };
  2040. Slick.find = function(context, expression){
  2041. return local.search(context, expression, null, true);
  2042. };
  2043. // Slick containment checker
  2044. Slick.contains = function(container, node){
  2045. local.setDocument(container);
  2046. return local.contains(container, node);
  2047. };
  2048. // Slick attribute getter
  2049. Slick.getAttribute = function(node, name){
  2050. return local.getAttribute(node, name);
  2051. };
  2052. // Slick matcher
  2053. Slick.match = function(node, selector){
  2054. if (!(node && selector)) return false;
  2055. if (!selector || selector === node) return true;
  2056. local.setDocument(node);
  2057. return local.matchNode(node, selector);
  2058. };
  2059. // Slick attribute accessor
  2060. Slick.defineAttributeGetter = function(name, fn){
  2061. local.attributeGetters[name] = fn;
  2062. return this;
  2063. };
  2064. Slick.lookupAttributeGetter = function(name){
  2065. return local.attributeGetters[name];
  2066. };
  2067. // Slick pseudo accessor
  2068. Slick.definePseudo = function(name, fn){
  2069. local['pseudo:' + name] = function(node, argument){
  2070. return fn.call(node, argument);
  2071. };
  2072. return this;
  2073. };
  2074. Slick.lookupPseudo = function(name){
  2075. var pseudo = local['pseudo:' + name];
  2076. if (pseudo) return function(argument){
  2077. return pseudo.call(this, argument);
  2078. };
  2079. return null;
  2080. };
  2081. // Slick overrides accessor
  2082. Slick.override = function(regexp, fn){
  2083. local.override(regexp, fn);
  2084. return this;
  2085. };
  2086. Slick.isXML = local.isXML;
  2087. Slick.uidOf = function(node){
  2088. return local.getUIDHTML(node);
  2089. };
  2090. if (!this.Slick) this.Slick = Slick;
  2091. }).apply(/*<CommonJS>*/(typeof exports != 'undefined') ? exports : /*</CommonJS>*/this);
  2092. /*
  2093. ---
  2094. name: Element
  2095. 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.
  2096. license: MIT-style license.
  2097. requires: [Window, Document, Array, String, Function, Number, Slick.Parser, Slick.Finder]
  2098. provides: [Element, Elements, $, $$, Iframe, Selectors]
  2099. ...
  2100. */
  2101. var Element = function(tag, props){
  2102. var konstructor = Element.Constructors[tag];
  2103. if (konstructor) return konstructor(props);
  2104. if (typeof tag != 'string') return document.id(tag).set(props);
  2105. if (!props) props = {};
  2106. if (!(/^[\w-]+$/).test(tag)){
  2107. var parsed = Slick.parse(tag).expressions[0][0];
  2108. tag = (parsed.tag == '*') ? 'div' : parsed.tag;
  2109. if (parsed.id && props.id == null) props.id = parsed.id;
  2110. var attributes = parsed.attributes;
  2111. if (attributes) for (var i = 0, l = attributes.length; i < l; i++){
  2112. var attr = attributes[i];
  2113. if (props[attr.key] != null) continue;
  2114. if (attr.value != null && attr.operator == '=') props[attr.key] = attr.value;
  2115. else if (!attr.value && !attr.operator) props[attr.key] = true;
  2116. }
  2117. if (parsed.classList && props['class'] == null) props['class'] = parsed.classList.join(' ');
  2118. }
  2119. return document.newElement(tag, props);
  2120. };
  2121. if (Browser.Element) Element.prototype = Browser.Element.prototype;
  2122. new Type('Element', Element).mirror(function(name){
  2123. if (Array.prototype[name]) return;
  2124. var obj = {};
  2125. obj[name] = function(){
  2126. var results = [], args = arguments, elements = true;
  2127. for (var i = 0, l = this.length; i < l; i++){
  2128. var element = this[i], result = results[i] = element[name].apply(element, args);
  2129. elements = (elements && typeOf(result) == 'element');
  2130. }
  2131. return (elements) ? new Elements(results) : results;
  2132. };
  2133. Elements.implement(obj);
  2134. });
  2135. if (!Browser.Element){
  2136. Element.parent = Object;
  2137. Element.Prototype = {'$family': Function.from('element').hide()};
  2138. Element.mirror(function(name, method){
  2139. Element.Prototype[name] = method;
  2140. });
  2141. }
  2142. Element.Constructors = {};
  2143. var IFrame = new Type('IFrame', function(){
  2144. var params = Array.link(arguments, {
  2145. properties: Type.isObject,
  2146. iframe: function(obj){
  2147. return (obj != null);
  2148. }
  2149. });
  2150. var props = params.properties || {}, iframe;
  2151. if (params.iframe) iframe = document.id(params.iframe);
  2152. var onload = props.onload || function(){};
  2153. delete props.onload;
  2154. props.id = props.name = [props.id, props.name, iframe ? (iframe.id || iframe.name) : 'IFrame_' + String.uniqueID()].pick();
  2155. iframe = new Element(iframe || 'iframe', props);
  2156. var onLoad = function(){
  2157. onload.call(iframe.contentWindow);
  2158. };
  2159. if (window.frames[props.id]) onLoad();
  2160. else iframe.addListener('load', onLoad);
  2161. return iframe;
  2162. });
  2163. var Elements = this.Elements = function(nodes){
  2164. if (nodes && nodes.length){
  2165. var uniques = {}, node;
  2166. for (var i = 0; node = nodes[i++];){
  2167. var uid = Slick.uidOf(node);
  2168. if (!uniques[uid]){
  2169. uniques[uid] = true;
  2170. this.push(node);
  2171. }
  2172. }
  2173. }
  2174. };
  2175. Elements.prototype = {length: 0};
  2176. Elements.parent = Array;
  2177. new Type('Elements', Elements).implement({
  2178. filter: function(filter, bind){
  2179. if (!filter) return this;
  2180. return new Elements(Array.filter(this, (typeOf(filter) == 'string') ? function(item){
  2181. return item.match(filter);
  2182. } : filter, bind));
  2183. }.protect(),
  2184. push: function(){
  2185. var length = this.length;
  2186. for (var i = 0, l = arguments.length; i < l; i++){
  2187. var item = document.id(arguments[i]);
  2188. if (item) this[length++] = item;
  2189. }
  2190. return (this.length = length);
  2191. }.protect(),
  2192. unshift: function(){
  2193. var items = [];
  2194. for (var i = 0, l = arguments.length; i < l; i++){
  2195. var item = document.id(arguments[i]);
  2196. if (item) items.push(item);
  2197. }
  2198. return Array.prototype.unshift.apply(this, items);
  2199. }.protect(),
  2200. concat: function(){
  2201. var newElements = new Elements(this);
  2202. for (var i = 0, l = arguments.length; i < l; i++){
  2203. var item = arguments[i];
  2204. if (Type.isEnumerable(item)) newElements.append(item);
  2205. else newElements.push(item);
  2206. }
  2207. return newElements;
  2208. }.protect(),
  2209. append: function(collection){
  2210. for (var i = 0, l = collection.length; i < l; i++) this.push(collection[i]);
  2211. return this;
  2212. }.protect(),
  2213. empty: function(){
  2214. while (this.length) delete this[--this.length];
  2215. return this;
  2216. }.protect()
  2217. });
  2218. (function(){
  2219. // FF, IE
  2220. var splice = Array.prototype.splice, object = {'0': 0, '1': 1, length: 2};
  2221. splice.call(object, 1, 1);
  2222. if (object[1] == 1) Elements.implement('splice', function(){
  2223. var length = this.length;
  2224. splice.apply(this, arguments);
  2225. while (length >= this.length) delete this[length--];
  2226. return this;
  2227. }.protect());
  2228. Elements.implement(Array.prototype);
  2229. Array.mirror(Elements);
  2230. /*<ltIE8>*/
  2231. var createElementAcceptsHTML;
  2232. try {
  2233. var x = document.createElement('<input name=x>');
  2234. createElementAcceptsHTML = (x.name == 'x');
  2235. } catch(e){}
  2236. var escapeQuotes = function(html){
  2237. return ('' + html).replace(/&/g, '&amp;').replace(/"/g, '&quot;');
  2238. };
  2239. /*</ltIE8>*/
  2240. Document.implement({
  2241. newElement: function(tag, props){
  2242. if (props && props.checked != null) props.defaultChecked = props.checked;
  2243. /*<ltIE8>*/// Fix for readonly name and type properties in IE < 8
  2244. if (createElementAcceptsHTML && props){
  2245. tag = '<' + tag;
  2246. if (props.name) tag += ' name="' + escapeQuotes(props.name) + '"';
  2247. if (props.type) tag += ' type="' + escapeQuotes(props.type) + '"';
  2248. tag += '>';
  2249. delete props.name;
  2250. delete props.type;
  2251. }
  2252. /*</ltIE8>*/
  2253. return this.id(this.createElement(tag)).set(props);
  2254. }
  2255. });
  2256. })();
  2257. Document.implement({
  2258. newTextNode: function(text){
  2259. return this.createTextNode(text);
  2260. },
  2261. getDocument: function(){
  2262. return this;
  2263. },
  2264. getWindow: function(){
  2265. return this.window;
  2266. },
  2267. id: (function(){
  2268. var types = {
  2269. string: function(id, nocash, doc){
  2270. id = Slick.find(doc, '#' + id.replace(/(\W)/g, '\\$1'));
  2271. return (id) ? types.element(id, nocash) : null;
  2272. },
  2273. element: function(el, nocash){
  2274. $uid(el);
  2275. if (!nocash && !el.$family && !(/^(?:object|embed)$/i).test(el.tagName)){
  2276. Object.append(el, Element.Prototype);
  2277. }
  2278. return el;
  2279. },
  2280. object: function(obj, nocash, doc){
  2281. if (obj.toElement) return types.element(obj.toElement(doc), nocash);
  2282. return null;
  2283. }
  2284. };
  2285. types.textnode = types.whitespace = types.window = types.document = function(zero){
  2286. return zero;
  2287. };
  2288. return function(el, nocash, doc){
  2289. if (el && el.$family && el.uid) return el;
  2290. var type = typeOf(el);
  2291. return (types[type]) ? types[type](el, nocash, doc || document) : null;
  2292. };
  2293. })()
  2294. });
  2295. if (window.$ == null) Window.implement('$', function(el, nc){
  2296. return document.id(el, nc, this.document);
  2297. });
  2298. Window.implement({
  2299. getDocument: function(){
  2300. return this.document;
  2301. },
  2302. getWindow: function(){
  2303. return this;
  2304. }
  2305. });
  2306. [Document, Element].invoke('implement', {
  2307. getElements: function(expression){
  2308. return Slick.search(this, expression, new Elements);
  2309. },
  2310. getElement: function(expression){
  2311. return document.id(Slick.find(this, expression));
  2312. }
  2313. });
  2314. if (window.$$ == null) Window.implement('$$', function(selector){
  2315. if (arguments.length == 1){
  2316. if (typeof selector == 'string') return Slick.search(this.document, selector, new Elements);
  2317. else if (Type.isEnumerable(selector)) return new Elements(selector);
  2318. }
  2319. return new Elements(arguments);
  2320. });
  2321. (function(){
  2322. var collected = {}, storage = {};
  2323. var formProps = {input: 'checked', option: 'selected', textarea: 'value'};
  2324. var get = function(uid){
  2325. return (storage[uid] || (storage[uid] = {}));
  2326. };
  2327. var clean = function(item){
  2328. var uid = item.uid;
  2329. if (item.removeEvents) item.removeEvents();
  2330. if (item.clearAttributes) item.clearAttributes();
  2331. if (uid != null){
  2332. delete collected[uid];
  2333. delete storage[uid];
  2334. }
  2335. return item;
  2336. };
  2337. var camels = ['defaultValue', 'accessKey', 'cellPadding', 'cellSpacing', 'colSpan', 'frameBorder', 'maxLength', 'readOnly',
  2338. 'rowSpan', 'tabIndex', 'useMap'
  2339. ];
  2340. var bools = ['compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked', 'disabled', 'readOnly', 'multiple', 'selected',
  2341. 'noresize', 'defer', 'defaultChecked'
  2342. ];
  2343. var attributes = {
  2344. 'html': 'innerHTML',
  2345. 'class': 'className',
  2346. 'for': 'htmlFor',
  2347. 'text': (function(){
  2348. var temp = document.createElement('div');
  2349. return (temp.textContent == null) ? 'innerText' : 'textContent';
  2350. })()
  2351. };
  2352. var readOnly = ['type'];
  2353. var expandos = ['value', 'defaultValue'];
  2354. var uriAttrs = /^(?:href|src|usemap)$/i;
  2355. bools = bools.associate(bools);
  2356. camels = camels.associate(camels.map(String.toLowerCase));
  2357. readOnly = readOnly.associate(readOnly);
  2358. Object.append(attributes, expandos.associate(expandos));
  2359. var inserters = {
  2360. before: function(context, element){
  2361. var parent = element.parentNode;
  2362. if (parent) parent.insertBefore(context, element);
  2363. },
  2364. after: function(context, element){
  2365. var parent = element.parentNode;
  2366. if (parent) parent.insertBefore(context, element.nextSibling);
  2367. },
  2368. bottom: function(context, element){
  2369. element.appendChild(context);
  2370. },
  2371. top: function(context, element){
  2372. element.insertBefore(context, element.firstChild);
  2373. }
  2374. };
  2375. inserters.inside = inserters.bottom;
  2376. var injectCombinator = function(expression, combinator){
  2377. if (!expression) return combinator;
  2378. expression = Object.clone(Slick.parse(expression));
  2379. var expressions = expression.expressions;
  2380. for (var i = expressions.length; i--;)
  2381. expressions[i][0].combinator = combinator;
  2382. return expression;
  2383. };
  2384. Element.implement({
  2385. set: function(prop, value){
  2386. var property = Element.Properties[prop];
  2387. (property && property.set) ? property.set.call(this, value) : this.setProperty(prop, value);
  2388. }.overloadSetter(),
  2389. get: function(prop){
  2390. var property = Element.Properties[prop];
  2391. return (property && property.get) ? property.get.apply(this) : this.getProperty(prop);
  2392. }.overloadGetter(),
  2393. erase: function(prop){
  2394. var property = Element.Properties[prop];
  2395. (property && property.erase) ? property.erase.apply(this) : this.removeProperty(prop);
  2396. return this;
  2397. },
  2398. setProperty: function(attribute, value){
  2399. attribute = camels[attribute] || attribute;
  2400. if (value == null) return this.removeProperty(attribute);
  2401. var key = attributes[attribute];
  2402. (key) ? this[key] = value :
  2403. (bools[attribute]) ? this[attribute] = !!value : this.setAttribute(attribute, '' + value);
  2404. return this;
  2405. },
  2406. setProperties: function(attributes){
  2407. for (var attribute in attributes) this.setProperty(attribute, attributes[attribute]);
  2408. return this;
  2409. },
  2410. getProperty: function(attribute){
  2411. attribute = camels[attribute] || attribute;
  2412. var key = attributes[attribute] || readOnly[attribute];
  2413. return (key) ? this[key] :
  2414. (bools[attribute]) ? !!this[attribute] :
  2415. (uriAttrs.test(attribute) ? this.getAttribute(attribute, 2) :
  2416. (key = this.getAttributeNode(attribute)) ? key.nodeValue : null) || null;
  2417. },
  2418. getProperties: function(){
  2419. var args = Array.from(arguments);
  2420. return args.map(this.getProperty, this).associate(args);
  2421. },
  2422. removeProperty: function(attribute){
  2423. attribute = camels[attribute] || attribute;
  2424. var key = attributes[attribute];
  2425. (key) ? this[key] = '' :
  2426. (bools[attribute]) ? this[attribute] = false : this.removeAttribute(attribute);
  2427. return this;
  2428. },
  2429. removeProperties: function(){
  2430. Array.each(arguments, this.removeProperty, this);
  2431. return this;
  2432. },
  2433. hasClass: function(className){
  2434. return this.className.clean().contains(className, ' ');
  2435. },
  2436. addClass: function(className){
  2437. if (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean();
  2438. return this;
  2439. },
  2440. removeClass: function(className){
  2441. this.className = this.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1');
  2442. return this;
  2443. },
  2444. toggleClass: function(className, force){
  2445. if (force == null) force = !this.hasClass(className);
  2446. return (force) ? this.addClass(className) : this.removeClass(className);
  2447. },
  2448. adopt: function(){
  2449. var parent = this, fragment, elements = Array.flatten(arguments), length = elements.length;
  2450. if (length > 1) parent = fragment = document.createDocumentFragment();
  2451. for (var i = 0; i < length; i++){
  2452. var element = document.id(elements[i], true);
  2453. if (element) parent.appendChild(element);
  2454. }
  2455. if (fragment) this.appendChild(fragment);
  2456. return this;
  2457. },
  2458. appendText: function(text, where){
  2459. return this.grab(this.getDocument().newTextNode(text), where);
  2460. },
  2461. grab: function(el, where){
  2462. inserters[where || 'bottom'](document.id(el, true), this);
  2463. return this;
  2464. },
  2465. inject: function(el, where){
  2466. inserters[where || 'bottom'](this, document.id(el, true));
  2467. return this;
  2468. },
  2469. replaces: function(el){
  2470. el = document.id(el, true);
  2471. el.parentNode.replaceChild(this, el);
  2472. return this;
  2473. },
  2474. wraps: function(el, where){
  2475. el = document.id(el, true);
  2476. return this.replaces(el).grab(el, where);
  2477. },
  2478. getPrevious: function(expression){
  2479. return document.id(Slick.find(this, injectCombinator(expression, '!~')));
  2480. },
  2481. getAllPrevious: function(expression){
  2482. return Slick.search(this, injectCombinator(expression, '!~'), new Elements);
  2483. },
  2484. getNext: function(expression){
  2485. return document.id(Slick.find(this, injectCombinator(expression, '~')));
  2486. },
  2487. getAllNext: function(expression){
  2488. return Slick.search(this, injectCombinator(expression, '~'), new Elements);
  2489. },
  2490. getFirst: function(expression){
  2491. return document.id(Slick.search(this, injectCombinator(expression, '>'))[0]);
  2492. },
  2493. getLast: function(expression){
  2494. return document.id(Slick.search(this, injectCombinator(expression, '>')).getLast());
  2495. },
  2496. getParent: function(expression){
  2497. return document.id(Slick.find(this, injectCombinator(expression, '!')));
  2498. },
  2499. getParents: function(expression){
  2500. return Slick.search(this, injectCombinator(expression, '!'), new Elements);
  2501. },
  2502. getSiblings: function(expression){
  2503. return Slick.search(this, injectCombinator(expression, '~~'), new Elements);
  2504. },
  2505. getChildren: function(expression){
  2506. return Slick.search(this, injectCombinator(expression, '>'), new Elements);
  2507. },
  2508. getWindow: function(){
  2509. return this.ownerDocument.window;
  2510. },
  2511. getDocument: function(){
  2512. return this.ownerDocument;
  2513. },
  2514. getElementById: function(id){
  2515. return document.id(Slick.find(this, '#' + ('' + id).replace(/(\W)/g, '\\$1')));
  2516. },
  2517. getSelected: function(){
  2518. this.selectedIndex; // Safari 3.2.1
  2519. return new Elements(Array.from(this.options).filter(function(option){
  2520. return option.selected;
  2521. }));
  2522. },
  2523. toQueryString: function(){
  2524. var queryString = [];
  2525. this.getElements('input, select, textarea').each(function(el){
  2526. var type = el.type;
  2527. if (!el.name || el.disabled || type == 'submit' || type == 'reset' || type == 'file' || type == 'image') return;
  2528. var value = (el.get('tag') == 'select') ? el.getSelected().map(function(opt){
  2529. // IE
  2530. return document.id(opt).get('value');
  2531. }) : ((type == 'radio' || type == 'checkbox') && !el.checked) ? null : el.get('value');
  2532. Array.from(value).each(function(val){
  2533. if (typeof val != 'undefined') queryString.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(val));
  2534. });
  2535. });
  2536. return queryString.join('&');
  2537. },
  2538. destroy: function(){
  2539. var children = clean(this).getElementsByTagName('*');
  2540. Array.each(children, clean);
  2541. Element.dispose(this);
  2542. return null;
  2543. },
  2544. empty: function(){
  2545. Array.from(this.childNodes).each(Element.dispose);
  2546. return this;
  2547. },
  2548. dispose: function(){
  2549. return (this.parentNode) ? this.parentNode.removeChild(this) : this;
  2550. },
  2551. match: function(expression){
  2552. return !expression || Slick.match(this, expression);
  2553. }
  2554. });
  2555. var cleanClone = function(node, element, keepid){
  2556. if (!keepid) node.setAttributeNode(document.createAttribute('id'));
  2557. if (node.clearAttributes){
  2558. node.clearAttributes();
  2559. node.mergeAttributes(element);
  2560. node.removeAttribute('uid');
  2561. if (node.options){
  2562. var no = node.options, eo = element.options;
  2563. for (var i = no.length; i--;) no[i].selected = eo[i].selected;
  2564. }
  2565. }
  2566. var prop = formProps[element.tagName.toLowerCase()];
  2567. if (prop && element[prop]) node[prop] = element[prop];
  2568. };
  2569. Element.implement('clone', function(contents, keepid){
  2570. contents = contents !== false;
  2571. var clone = this.cloneNode(contents), i;
  2572. if (contents){
  2573. var ce = clone.getElementsByTagName('*'), te = this.getElementsByTagName('*');
  2574. for (i = ce.length; i--;) cleanClone(ce[i], te[i], keepid);
  2575. }
  2576. cleanClone(clone, this, keepid);
  2577. if (Browser.ie){
  2578. var co = clone.getElementsByTagName('object'), to = this.getElementsByTagName('object');
  2579. for (i = co.length; i--;) co[i].outerHTML = to[i].outerHTML;
  2580. }
  2581. return document.id(clone);
  2582. });
  2583. var contains = {contains: function(element){
  2584. return Slick.contains(this, element);
  2585. }};
  2586. if (!document.contains) Document.implement(contains);
  2587. if (!document.createElement('div').contains) Element.implement(contains);
  2588. [Element, Window, Document].invoke('implement', {
  2589. addListener: function(type, fn){
  2590. if (type == 'unload'){
  2591. var old = fn, self = this;
  2592. fn = function(){
  2593. self.removeListener('unload', fn);
  2594. old();
  2595. };
  2596. } else {
  2597. collected[$uid(this)] = this;
  2598. }
  2599. if (this.addEventListener) this.addEventListener(type, fn, !!arguments[2]);
  2600. else this.attachEvent('on' + type, fn);
  2601. return this;
  2602. },
  2603. removeListener: function(type, fn){
  2604. if (this.removeEventListener) this.removeEventListener(type, fn, !!arguments[2]);
  2605. else this.detachEvent('on' + type, fn);
  2606. return this;
  2607. },
  2608. retrieve: function(property, dflt){
  2609. var storage = get($uid(this)), prop = storage[property];
  2610. if (dflt != null && prop == null) prop = storage[property] = dflt;
  2611. return prop != null ? prop : null;
  2612. },
  2613. store: function(property, value){
  2614. var storage = get($uid(this));
  2615. storage[property] = value;
  2616. return this;
  2617. },
  2618. eliminate: function(property){
  2619. var storage = get($uid(this));
  2620. delete storage[property];
  2621. return this;
  2622. }
  2623. });
  2624. /*<ltIE9>*/
  2625. if (window.attachEvent && !window.addEventListener) window.addListener('unload', function(){
  2626. Object.each(collected, clean);
  2627. if (window.CollectGarbage) CollectGarbage();
  2628. });
  2629. /*</ltIE9>*/
  2630. })();
  2631. Element.Properties = {};
  2632. Element.Properties.style = {
  2633. set: function(style){
  2634. this.style.cssText = style;
  2635. },
  2636. get: function(){
  2637. return this.style.cssText;
  2638. },
  2639. erase: function(){
  2640. this.style.cssText = '';
  2641. }
  2642. };
  2643. Element.Properties.tag = {
  2644. get: function(){
  2645. return this.tagName.toLowerCase();
  2646. }
  2647. };
  2648. /*<ltIE9>*/
  2649. (function(maxLength){
  2650. if (maxLength != null) Element.Properties.maxlength = Element.Properties.maxLength = {
  2651. get: function(){
  2652. var maxlength = this.getAttribute('maxLength');
  2653. return maxlength == maxLength ? null : maxlength;
  2654. }
  2655. };
  2656. })(document.createElement('input').getAttribute('maxLength'));
  2657. /*</ltIE9>*/
  2658. /*<!webkit>*/
  2659. Element.Properties.html = (function(){
  2660. var tableTest = Function.attempt(function(){
  2661. var table = document.createElement('table');
  2662. table.innerHTML = '<tr><td></td></tr>';
  2663. });
  2664. var wrapper = document.createElement('div');
  2665. var translations = {
  2666. table: [1, '<table>', '</table>'],
  2667. select: [1, '<select>', '</select>'],
  2668. tbody: [2, '<table><tbody>', '</tbody></table>'],
  2669. tr: [3, '<table><tbody><tr>', '</tr></tbody></table>']
  2670. };
  2671. translations.thead = translations.tfoot = translations.tbody;
  2672. var html = {
  2673. set: function(){
  2674. var html = Array.flatten(arguments).join('');
  2675. var wrap = (!tableTest && translations[this.get('tag')]);
  2676. if (wrap){
  2677. var first = wrapper;
  2678. first.innerHTML = wrap[1] + html + wrap[2];
  2679. for (var i = wrap[0]; i--;) first = first.firstChild;
  2680. this.empty().adopt(first.childNodes);
  2681. } else {
  2682. this.innerHTML = html;
  2683. }
  2684. }
  2685. };
  2686. html.erase = html.set;
  2687. return html;
  2688. })();
  2689. /*</!webkit>*/
  2690. /*
  2691. ---
  2692. name: Element.Style
  2693. description: Contains methods for interacting with the styles of Elements in a fashionable way.
  2694. license: MIT-style license.
  2695. requires: Element
  2696. provides: Element.Style
  2697. ...
  2698. */
  2699. (function(){
  2700. var html = document.html;
  2701. Element.Properties.styles = {set: function(styles){
  2702. this.setStyles(styles);
  2703. }};
  2704. var hasOpacity = (html.style.opacity != null);
  2705. var reAlpha = /alpha\(opacity=([\d.]+)\)/i;
  2706. var setOpacity = function(element, opacity){
  2707. if (!element.currentStyle || !element.currentStyle.hasLayout) element.style.zoom = 1;
  2708. if (hasOpacity){
  2709. element.style.opacity = opacity;
  2710. } else {
  2711. opacity = (opacity * 100).limit(0, 100).round();
  2712. opacity = (opacity == 100) ? '' : 'alpha(opacity=' + opacity + ')';
  2713. var filter = element.style.filter || element.getComputedStyle('filter') || '';
  2714. element.style.filter = reAlpha.test(filter) ? filter.replace(reAlpha, opacity) : filter + opacity;
  2715. }
  2716. };
  2717. Element.Properties.opacity = {
  2718. set: function(opacity){
  2719. var visibility = this.style.visibility;
  2720. if (opacity == 0 && visibility != 'hidden') this.style.visibility = 'hidden';
  2721. else if (opacity != 0 && visibility != 'visible') this.style.visibility = 'visible';
  2722. setOpacity(this, opacity);
  2723. },
  2724. get: (hasOpacity) ? function(){
  2725. var opacity = this.style.opacity || this.getComputedStyle('opacity');
  2726. return (opacity == '') ? 1 : opacity;
  2727. } : function(){
  2728. var opacity, filter = (this.style.filter || this.getComputedStyle('filter'));
  2729. if (filter) opacity = filter.match(reAlpha);
  2730. return (opacity == null || filter == null) ? 1 : (opacity[1] / 100);
  2731. }
  2732. };
  2733. var floatName = (html.style.cssFloat == null) ? 'styleFloat' : 'cssFloat';
  2734. Element.implement({
  2735. getComputedStyle: function(property){
  2736. if (this.currentStyle) return this.currentStyle[property.camelCase()];
  2737. var defaultView = Element.getDocument(this).defaultView,
  2738. computed = defaultView ? defaultView.getComputedStyle(this, null) : null;
  2739. return (computed) ? computed.getPropertyValue((property == floatName) ? 'float' : property.hyphenate()) : null;
  2740. },
  2741. setOpacity: function(value){
  2742. setOpacity(this, value);
  2743. return this;
  2744. },
  2745. getOpacity: function(){
  2746. return this.get('opacity');
  2747. },
  2748. setStyle: function(property, value){
  2749. switch (property){
  2750. case 'opacity': return this.set('opacity', parseFloat(value));
  2751. case 'float': property = floatName;
  2752. }
  2753. property = property.camelCase();
  2754. if (typeOf(value) != 'string'){
  2755. var map = (Element.Styles[property] || '@').split(' ');
  2756. value = Array.from(value).map(function(val, i){
  2757. if (!map[i]) return '';
  2758. return (typeOf(val) == 'number') ? map[i].replace('@', Math.round(val)) : val;
  2759. }).join(' ');
  2760. } else if (value == String(Number(value))){
  2761. value = Math.round(value);
  2762. }
  2763. this.style[property] = value;
  2764. return this;
  2765. },
  2766. getStyle: function(property){
  2767. switch (property){
  2768. case 'opacity': return this.get('opacity');
  2769. case 'float': property = floatName;
  2770. }
  2771. property = property.camelCase();
  2772. var result = this.style[property];
  2773. if (!result || property == 'zIndex'){
  2774. result = [];
  2775. for (var style in Element.ShortStyles){
  2776. if (property != style) continue;
  2777. for (var s in Element.ShortStyles[style]) result.push(this.getStyle(s));
  2778. return result.join(' ');
  2779. }
  2780. result = this.getComputedStyle(property);
  2781. }
  2782. if (result){
  2783. result = String(result);
  2784. var color = result.match(/rgba?\([\d\s,]+\)/);
  2785. if (color) result = result.replace(color[0], color[0].rgbToHex());
  2786. }
  2787. if (Browser.opera || (Browser.ie && isNaN(parseFloat(result)))){
  2788. if ((/^(height|width)$/).test(property)){
  2789. var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom'], size = 0;
  2790. values.each(function(value){
  2791. size += this.getStyle('border-' + value + '-width').toInt() + this.getStyle('padding-' + value).toInt();
  2792. }, this);
  2793. return this['offset' + property.capitalize()] - size + 'px';
  2794. }
  2795. if (Browser.opera && String(result).indexOf('px') != -1) return result;
  2796. if ((/^border(.+)Width|margin|padding/).test(property)) return '0px';
  2797. }
  2798. return result;
  2799. },
  2800. setStyles: function(styles){
  2801. for (var style in styles) this.setStyle(style, styles[style]);
  2802. return this;
  2803. },
  2804. getStyles: function(){
  2805. var result = {};
  2806. Array.flatten(arguments).each(function(key){
  2807. result[key] = this.getStyle(key);
  2808. }, this);
  2809. return result;
  2810. }
  2811. });
  2812. Element.Styles = {
  2813. left: '@px', top: '@px', bottom: '@px', right: '@px',
  2814. width: '@px', height: '@px', maxWidth: '@px', maxHeight: '@px', minWidth: '@px', minHeight: '@px',
  2815. backgroundColor: 'rgb(@, @, @)', backgroundPosition: '@px @px', color: 'rgb(@, @, @)',
  2816. fontSize: '@px', letterSpacing: '@px', lineHeight: '@px', clip: 'rect(@px @px @px @px)',
  2817. margin: '@px @px @px @px', padding: '@px @px @px @px', border: '@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)',
  2818. borderWidth: '@px @px @px @px', borderStyle: '@ @ @ @', borderColor: 'rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)',
  2819. zIndex: '@', 'zoom': '@', fontWeight: '@', textIndent: '@px', opacity: '@'
  2820. };
  2821. Element.ShortStyles = {margin: {}, padding: {}, border: {}, borderWidth: {}, borderStyle: {}, borderColor: {}};
  2822. ['Top', 'Right', 'Bottom', 'Left'].each(function(direction){
  2823. var Short = Element.ShortStyles;
  2824. var All = Element.Styles;
  2825. ['margin', 'padding'].each(function(style){
  2826. var sd = style + direction;
  2827. Short[style][sd] = All[sd] = '@px';
  2828. });
  2829. var bd = 'border' + direction;
  2830. Short.border[bd] = All[bd] = '@px @ rgb(@, @, @)';
  2831. var bdw = bd + 'Width', bds = bd + 'Style', bdc = bd + 'Color';
  2832. Short[bd] = {};
  2833. Short.borderWidth[bdw] = Short[bd][bdw] = All[bdw] = '@px';
  2834. Short.borderStyle[bds] = Short[bd][bds] = All[bds] = '@';
  2835. Short.borderColor[bdc] = Short[bd][bdc] = All[bdc] = 'rgb(@, @, @)';
  2836. });
  2837. })();
  2838. /*
  2839. ---
  2840. name: Element.Event
  2841. description: Contains Element methods for dealing with events. This file also includes mouseenter and mouseleave custom Element Events.
  2842. license: MIT-style license.
  2843. requires: [Element, Event]
  2844. provides: Element.Event
  2845. ...
  2846. */
  2847. (function(){
  2848. Element.Properties.events = {set: function(events){
  2849. this.addEvents(events);
  2850. }};
  2851. [Element, Window, Document].invoke('implement', {
  2852. addEvent: function(type, fn){
  2853. var events = this.retrieve('events', {});
  2854. if (!events[type]) events[type] = {keys: [], values: []};
  2855. if (events[type].keys.contains(fn)) return this;
  2856. events[type].keys.push(fn);
  2857. var realType = type,
  2858. custom = Element.Events[type],
  2859. condition = fn,
  2860. self = this;
  2861. if (custom){
  2862. if (custom.onAdd) custom.onAdd.call(this, fn);
  2863. if (custom.condition){
  2864. condition = function(event){
  2865. if (custom.condition.call(this, event)) return fn.call(this, event);
  2866. return true;
  2867. };
  2868. }
  2869. realType = custom.base || realType;
  2870. }
  2871. var defn = function(){
  2872. return fn.call(self);
  2873. };
  2874. var nativeEvent = Element.NativeEvents[realType];
  2875. if (nativeEvent){
  2876. if (nativeEvent == 2){
  2877. defn = function(event){
  2878. event = new Event(event, self.getWindow());
  2879. if (condition.call(self, event) === false) event.stop();
  2880. };
  2881. }
  2882. this.addListener(realType, defn, arguments[2]);
  2883. }
  2884. events[type].values.push(defn);
  2885. return this;
  2886. },
  2887. removeEvent: function(type, fn){
  2888. var events = this.retrieve('events');
  2889. if (!events || !events[type]) return this;
  2890. var list = events[type];
  2891. var index = list.keys.indexOf(fn);
  2892. if (index == -1) return this;
  2893. var value = list.values[index];
  2894. delete list.keys[index];
  2895. delete list.values[index];
  2896. var custom = Element.Events[type];
  2897. if (custom){
  2898. if (custom.onRemove) custom.onRemove.call(this, fn);
  2899. type = custom.base || type;
  2900. }
  2901. return (Element.NativeEvents[type]) ? this.removeListener(type, value, arguments[2]) : this;
  2902. },
  2903. addEvents: function(events){
  2904. for (var event in events) this.addEvent(event, events[event]);
  2905. return this;
  2906. },
  2907. removeEvents: function(events){
  2908. var type;
  2909. if (typeOf(events) == 'object'){
  2910. for (type in events) this.removeEvent(type, events[type]);
  2911. return this;
  2912. }
  2913. var attached = this.retrieve('events');
  2914. if (!attached) return this;
  2915. if (!events){
  2916. for (type in attached) this.removeEvents(type);
  2917. this.eliminate('events');
  2918. } else if (attached[events]){
  2919. attached[events].keys.each(function(fn){
  2920. this.removeEvent(events, fn);
  2921. }, this);
  2922. delete attached[events];
  2923. }
  2924. return this;
  2925. },
  2926. fireEvent: function(type, args, delay){
  2927. var events = this.retrieve('events');
  2928. if (!events || !events[type]) return this;
  2929. args = Array.from(args);
  2930. events[type].keys.each(function(fn){
  2931. if (delay) fn.delay(delay, this, args);
  2932. else fn.apply(this, args);
  2933. }, this);
  2934. return this;
  2935. },
  2936. cloneEvents: function(from, type){
  2937. from = document.id(from);
  2938. var events = from.retrieve('events');
  2939. if (!events) return this;
  2940. if (!type){
  2941. for (var eventType in events) this.cloneEvents(from, eventType);
  2942. } else if (events[type]){
  2943. events[type].keys.each(function(fn){
  2944. this.addEvent(type, fn);
  2945. }, this);
  2946. }
  2947. return this;
  2948. }
  2949. });
  2950. Element.NativeEvents = {
  2951. click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, //mouse buttons
  2952. mousewheel: 2, DOMMouseScroll: 2, //mouse wheel
  2953. mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, //mouse movement
  2954. keydown: 2, keypress: 2, keyup: 2, //keyboard
  2955. orientationchange: 2, // mobile
  2956. touchstart: 2, touchmove: 2, touchend: 2, touchcancel: 2, // touch
  2957. gesturestart: 2, gesturechange: 2, gestureend: 2, // gesture
  2958. focus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, //form elements
  2959. load: 2, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, //window
  2960. error: 1, abort: 1, scroll: 1 //misc
  2961. };
  2962. var check = function(event){
  2963. var related = event.relatedTarget;
  2964. if (related == null) return true;
  2965. if (!related) return false;
  2966. return (related != this && related.prefix != 'xul' && typeOf(this) != 'document' && !this.contains(related));
  2967. };
  2968. Element.Events = {
  2969. mouseenter: {
  2970. base: 'mouseover',
  2971. condition: check
  2972. },
  2973. mouseleave: {
  2974. base: 'mouseout',
  2975. condition: check
  2976. },
  2977. mousewheel: {
  2978. base: (Browser.firefox) ? 'DOMMouseScroll' : 'mousewheel'
  2979. }
  2980. };
  2981. })();
  2982. /*
  2983. ---
  2984. name: Element.Dimensions
  2985. description: Contains methods to work with size, scroll, or positioning of Elements and the window object.
  2986. license: MIT-style license.
  2987. credits:
  2988. - Element positioning based on the [qooxdoo](http://qooxdoo.org/) code and smart browser fixes, [LGPL License](http://www.gnu.org/licenses/lgpl.html).
  2989. - Viewport dimensions based on [YUI](http://developer.yahoo.com/yui/) code, [BSD License](http://developer.yahoo.com/yui/license.html).
  2990. requires: [Element, Element.Style]
  2991. provides: [Element.Dimensions]
  2992. ...
  2993. */
  2994. (function(){
  2995. var element = document.createElement('div'),
  2996. child = document.createElement('div');
  2997. element.style.height = '0';
  2998. element.appendChild(child);
  2999. var brokenOffsetParent = (child.offsetParent === element);
  3000. element = child = null;
  3001. var isOffset = function(el){
  3002. return styleString(el, 'position') != 'static' || isBody(el);
  3003. };
  3004. var isOffsetStatic = function(el){
  3005. return isOffset(el) || (/^(?:table|td|th)$/i).test(el.tagName);
  3006. };
  3007. Element.implement({
  3008. scrollTo: function(x, y){
  3009. if (isBody(this)){
  3010. this.getWindow().scrollTo(x, y);
  3011. } else {
  3012. this.scrollLeft = x;
  3013. this.scrollTop = y;
  3014. }
  3015. return this;
  3016. },
  3017. getSize: function(){
  3018. if (isBody(this)) return this.getWindow().getSize();
  3019. return {x: this.offsetWidth, y: this.offsetHeight};
  3020. },
  3021. getScrollSize: function(){
  3022. if (isBody(this)) return this.getWindow().getScrollSize();
  3023. return {x: this.scrollWidth, y: this.scrollHeight};
  3024. },
  3025. getScroll: function(){
  3026. if (isBody(this)) return this.getWindow().getScroll();
  3027. return {x: this.scrollLeft, y: this.scrollTop};
  3028. },
  3029. getScrolls: function(){
  3030. var element = this.parentNode, position = {x: 0, y: 0};
  3031. while (element && !isBody(element)){
  3032. position.x += element.scrollLeft;
  3033. position.y += element.scrollTop;
  3034. element = element.parentNode;
  3035. }
  3036. return position;
  3037. },
  3038. getOffsetParent: brokenOffsetParent ? function(){
  3039. var element = this;
  3040. if (isBody(element) || styleString(element, 'position') == 'fixed') return null;
  3041. var isOffsetCheck = (styleString(element, 'position') == 'static') ? isOffsetStatic : isOffset;
  3042. while ((element = element.parentNode)){
  3043. if (isOffsetCheck(element)) return element;
  3044. }
  3045. return null;
  3046. } : function(){
  3047. var element = this;
  3048. if (isBody(element) || styleString(element, 'position') == 'fixed') return null;
  3049. try {
  3050. return element.offsetParent;
  3051. } catch(e) {}
  3052. return null;
  3053. },
  3054. getOffsets: function(){
  3055. if (this.getBoundingClientRect && !Browser.Platform.ios){
  3056. var bound = this.getBoundingClientRect(),
  3057. html = document.id(this.getDocument().documentElement),
  3058. htmlScroll = html.getScroll(),
  3059. elemScrolls = this.getScrolls(),
  3060. isFixed = (styleString(this, 'position') == 'fixed');
  3061. return {
  3062. x: bound.left.toInt() + elemScrolls.x + ((isFixed) ? 0 : htmlScroll.x) - html.clientLeft,
  3063. y: bound.top.toInt() + elemScrolls.y + ((isFixed) ? 0 : htmlScroll.y) - html.clientTop
  3064. };
  3065. }
  3066. var element = this, position = {x: 0, y: 0};
  3067. if (isBody(this)) return position;
  3068. while (element && !isBody(element)){
  3069. position.x += element.offsetLeft;
  3070. position.y += element.offsetTop;
  3071. if (Browser.firefox){
  3072. if (!borderBox(element)){
  3073. position.x += leftBorder(element);
  3074. position.y += topBorder(element);
  3075. }
  3076. var parent = element.parentNode;
  3077. if (parent && styleString(parent, 'overflow') != 'visible'){
  3078. position.x += leftBorder(parent);
  3079. position.y += topBorder(parent);
  3080. }
  3081. } else if (element != this && Browser.safari){
  3082. position.x += leftBorder(element);
  3083. position.y += topBorder(element);
  3084. }
  3085. element = element.offsetParent;
  3086. }
  3087. if (Browser.firefox && !borderBox(this)){
  3088. position.x -= leftBorder(this);
  3089. position.y -= topBorder(this);
  3090. }
  3091. return position;
  3092. },
  3093. getPosition: function(relative){
  3094. if (isBody(this)) return {x: 0, y: 0};
  3095. var offset = this.getOffsets(),
  3096. scroll = this.getScrolls();
  3097. var position = {
  3098. x: offset.x - scroll.x,
  3099. y: offset.y - scroll.y
  3100. };
  3101. if (relative && (relative = document.id(relative))){
  3102. var relativePosition = relative.getPosition();
  3103. return {x: position.x - relativePosition.x - leftBorder(relative), y: position.y - relativePosition.y - topBorder(relative)};
  3104. }
  3105. return position;
  3106. },
  3107. getCoordinates: function(element){
  3108. if (isBody(this)) return this.getWindow().getCoordinates();
  3109. var position = this.getPosition(element),
  3110. size = this.getSize();
  3111. var obj = {
  3112. left: position.x,
  3113. top: position.y,
  3114. width: size.x,
  3115. height: size.y
  3116. };
  3117. obj.right = obj.left + obj.width;
  3118. obj.bottom = obj.top + obj.height;
  3119. return obj;
  3120. },
  3121. computePosition: function(obj){
  3122. return {
  3123. left: obj.x - styleNumber(this, 'margin-left'),
  3124. top: obj.y - styleNumber(this, 'margin-top')
  3125. };
  3126. },
  3127. setPosition: function(obj){
  3128. return this.setStyles(this.computePosition(obj));
  3129. }
  3130. });
  3131. [Document, Window].invoke('implement', {
  3132. getSize: function(){
  3133. var doc = getCompatElement(this);
  3134. return {x: doc.clientWidth, y: doc.clientHeight};
  3135. },
  3136. getScroll: function(){
  3137. var win = this.getWindow(), doc = getCompatElement(this);
  3138. return {x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop};
  3139. },
  3140. getScrollSize: function(){
  3141. var doc = getCompatElement(this),
  3142. min = this.getSize(),
  3143. body = this.getDocument().body;
  3144. return {x: Math.max(doc.scrollWidth, body.scrollWidth, min.x), y: Math.max(doc.scrollHeight, body.scrollHeight, min.y)};
  3145. },
  3146. getPosition: function(){
  3147. return {x: 0, y: 0};
  3148. },
  3149. getCoordinates: function(){
  3150. var size = this.getSize();
  3151. return {top: 0, left: 0, bottom: size.y, right: size.x, height: size.y, width: size.x};
  3152. }
  3153. });
  3154. // private methods
  3155. var styleString = Element.getComputedStyle;
  3156. function styleNumber(element, style){
  3157. return styleString(element, style).toInt() || 0;
  3158. }
  3159. function borderBox(element){
  3160. return styleString(element, '-moz-box-sizing') == 'border-box';
  3161. }
  3162. function topBorder(element){
  3163. return styleNumber(element, 'border-top-width');
  3164. }
  3165. function leftBorder(element){
  3166. return styleNumber(element, 'border-left-width');
  3167. }
  3168. function isBody(element){
  3169. return (/^(?:body|html)$/i).test(element.tagName);
  3170. }
  3171. function getCompatElement(element){
  3172. var doc = element.getDocument();
  3173. return (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
  3174. }
  3175. })();
  3176. //aliases
  3177. Element.alias({position: 'setPosition'}); //compatability
  3178. [Window, Document, Element].invoke('implement', {
  3179. getHeight: function(){
  3180. return this.getSize().y;
  3181. },
  3182. getWidth: function(){
  3183. return this.getSize().x;
  3184. },
  3185. getScrollTop: function(){
  3186. return this.getScroll().y;
  3187. },
  3188. getScrollLeft: function(){
  3189. return this.getScroll().x;
  3190. },
  3191. getScrollHeight: function(){
  3192. return this.getScrollSize().y;
  3193. },
  3194. getScrollWidth: function(){
  3195. return this.getScrollSize().x;
  3196. },
  3197. getTop: function(){
  3198. return this.getPosition().y;
  3199. },
  3200. getLeft: function(){
  3201. return this.getPosition().x;
  3202. }
  3203. });
  3204. /*
  3205. ---
  3206. name: Fx
  3207. description: Contains the basic animation logic to be extended by all other Fx Classes.
  3208. license: MIT-style license.
  3209. requires: [Chain, Events, Options]
  3210. provides: Fx
  3211. ...
  3212. */
  3213. (function(){
  3214. var Fx = this.Fx = new Class({
  3215. Implements: [Chain, Events, Options],
  3216. options: {
  3217. /*
  3218. onStart: nil,
  3219. onCancel: nil,
  3220. onComplete: nil,
  3221. */
  3222. fps: 60,
  3223. unit: false,
  3224. duration: 500,
  3225. frames: null,
  3226. frameSkip: true,
  3227. link: 'ignore'
  3228. },
  3229. initialize: function(options){
  3230. this.subject = this.subject || this;
  3231. this.setOptions(options);
  3232. },
  3233. getTransition: function(){
  3234. return function(p){
  3235. return -(Math.cos(Math.PI * p) - 1) / 2;
  3236. };
  3237. },
  3238. step: function(now){
  3239. if (this.options.frameSkip){
  3240. var diff = (this.time != null) ? (now - this.time) : 0, frames = diff / this.frameInterval;
  3241. this.time = now;
  3242. this.frame += frames;
  3243. } else {
  3244. this.frame++;
  3245. }
  3246. if (this.frame < this.frames){
  3247. var delta = this.transition(this.frame / this.frames);
  3248. this.set(this.compute(this.from, this.to, delta));
  3249. } else {
  3250. this.frame = this.frames;
  3251. this.set(this.compute(this.from, this.to, 1));
  3252. this.stop();
  3253. }
  3254. },
  3255. set: function(now){
  3256. return now;
  3257. },
  3258. compute: function(from, to, delta){
  3259. return Fx.compute(from, to, delta);
  3260. },
  3261. check: function(){
  3262. if (!this.isRunning()) return true;
  3263. switch (this.options.link){
  3264. case 'cancel': this.cancel(); return true;
  3265. case 'chain': this.chain(this.caller.pass(arguments, this)); return false;
  3266. }
  3267. return false;
  3268. },
  3269. start: function(from, to){
  3270. if (!this.check(from, to)) return this;
  3271. this.from = from;
  3272. this.to = to;
  3273. this.frame = (this.options.frameSkip) ? 0 : -1;
  3274. this.time = null;
  3275. this.transition = this.getTransition();
  3276. var frames = this.options.frames, fps = this.options.fps, duration = this.options.duration;
  3277. this.duration = Fx.Durations[duration] || duration.toInt();
  3278. this.frameInterval = 1000 / fps;
  3279. this.frames = frames || Math.round(this.duration / this.frameInterval);
  3280. this.fireEvent('start', this.subject);
  3281. pushInstance.call(this, fps);
  3282. return this;
  3283. },
  3284. stop: function(){
  3285. if (this.isRunning()){
  3286. this.time = null;
  3287. pullInstance.call(this, this.options.fps);
  3288. if (this.frames == this.frame){
  3289. this.fireEvent('complete', this.subject);
  3290. if (!this.callChain()) this.fireEvent('chainComplete', this.subject);
  3291. } else {
  3292. this.fireEvent('stop', this.subject);
  3293. }
  3294. }
  3295. return this;
  3296. },
  3297. cancel: function(){
  3298. if (this.isRunning()){
  3299. this.time = null;
  3300. pullInstance.call(this, this.options.fps);
  3301. this.frame = this.frames;
  3302. this.fireEvent('cancel', this.subject).clearChain();
  3303. }
  3304. return this;
  3305. },
  3306. pause: function(){
  3307. if (this.isRunning()){
  3308. this.time = null;
  3309. pullInstance.call(this, this.options.fps);
  3310. }
  3311. return this;
  3312. },
  3313. resume: function(){
  3314. if ((this.frame < this.frames) && !this.isRunning()) pushInstance.call(this, this.options.fps);
  3315. return this;
  3316. },
  3317. isRunning: function(){
  3318. var list = instances[this.options.fps];
  3319. return list && list.contains(this);
  3320. }
  3321. });
  3322. Fx.compute = function(from, to, delta){
  3323. return (to - from) * delta + from;
  3324. };
  3325. Fx.Durations = {'short': 250, 'normal': 500, 'long': 1000};
  3326. // global timers
  3327. var instances = {}, timers = {};
  3328. var loop = function(){
  3329. var now = Date.now();
  3330. for (var i = this.length; i--;){
  3331. var instance = this[i];
  3332. if (instance) instance.step(now);
  3333. }
  3334. };
  3335. var pushInstance = function(fps){
  3336. var list = instances[fps] || (instances[fps] = []);
  3337. list.push(this);
  3338. if (!timers[fps]) timers[fps] = loop.periodical(Math.round(1000 / fps), list);
  3339. };
  3340. var pullInstance = function(fps){
  3341. var list = instances[fps];
  3342. if (list){
  3343. list.erase(this);
  3344. if (!list.length && timers[fps]){
  3345. delete instances[fps];
  3346. timers[fps] = clearInterval(timers[fps]);
  3347. }
  3348. }
  3349. };
  3350. })();
  3351. /*
  3352. ---
  3353. name: Fx.CSS
  3354. description: Contains the CSS animation logic. Used by Fx.Tween, Fx.Morph, Fx.Elements.
  3355. license: MIT-style license.
  3356. requires: [Fx, Element.Style]
  3357. provides: Fx.CSS
  3358. ...
  3359. */
  3360. Fx.CSS = new Class({
  3361. Extends: Fx,
  3362. //prepares the base from/to object
  3363. prepare: function(element, property, values){
  3364. values = Array.from(values);
  3365. if (values[1] == null){
  3366. values[1] = values[0];
  3367. values[0] = element.getStyle(property);
  3368. }
  3369. var parsed = values.map(this.parse);
  3370. return {from: parsed[0], to: parsed[1]};
  3371. },
  3372. //parses a value into an array
  3373. parse: function(value){
  3374. value = Function.from(value)();
  3375. value = (typeof value == 'string') ? value.split(' ') : Array.from(value);
  3376. return value.map(function(val){
  3377. val = String(val);
  3378. var found = false;
  3379. Object.each(Fx.CSS.Parsers, function(parser, key){
  3380. if (found) return;
  3381. var parsed = parser.parse(val);
  3382. if (parsed || parsed === 0) found = {value: parsed, parser: parser};
  3383. });
  3384. found = found || {value: val, parser: Fx.CSS.Parsers.String};
  3385. return found;
  3386. });
  3387. },
  3388. //computes by a from and to prepared objects, using their parsers.
  3389. compute: function(from, to, delta){
  3390. var computed = [];
  3391. (Math.min(from.length, to.length)).times(function(i){
  3392. computed.push({value: from[i].parser.compute(from[i].value, to[i].value, delta), parser: from[i].parser});
  3393. });
  3394. computed.$family = Function.from('fx:css:value');
  3395. return computed;
  3396. },
  3397. //serves the value as settable
  3398. serve: function(value, unit){
  3399. if (typeOf(value) != 'fx:css:value') value = this.parse(value);
  3400. var returned = [];
  3401. value.each(function(bit){
  3402. returned = returned.concat(bit.parser.serve(bit.value, unit));
  3403. });
  3404. return returned;
  3405. },
  3406. //renders the change to an element
  3407. render: function(element, property, value, unit){
  3408. element.setStyle(property, this.serve(value, unit));
  3409. },
  3410. //searches inside the page css to find the values for a selector
  3411. search: function(selector){
  3412. if (Fx.CSS.Cache[selector]) return Fx.CSS.Cache[selector];
  3413. var to = {}, selectorTest = new RegExp('^' + selector.escapeRegExp() + '$');
  3414. Array.each(document.styleSheets, function(sheet, j){
  3415. var href = sheet.href;
  3416. if (href && href.contains('://') && !href.contains(document.domain)) return;
  3417. var rules = sheet.rules || sheet.cssRules;
  3418. Array.each(rules, function(rule, i){
  3419. if (!rule.style) return;
  3420. var selectorText = (rule.selectorText) ? rule.selectorText.replace(/^\w+/, function(m){
  3421. return m.toLowerCase();
  3422. }) : null;
  3423. if (!selectorText || !selectorTest.test(selectorText)) return;
  3424. Object.each(Element.Styles, function(value, style){
  3425. if (!rule.style[style] || Element.ShortStyles[style]) return;
  3426. value = String(rule.style[style]);
  3427. to[style] = ((/^rgb/).test(value)) ? value.rgbToHex() : value;
  3428. });
  3429. });
  3430. });
  3431. return Fx.CSS.Cache[selector] = to;
  3432. }
  3433. });
  3434. Fx.CSS.Cache = {};
  3435. Fx.CSS.Parsers = {
  3436. Color: {
  3437. parse: function(value){
  3438. if (value.match(/^#[0-9a-f]{3,6}$/i)) return value.hexToRgb(true);
  3439. return ((value = value.match(/(\d+),\s*(\d+),\s*(\d+)/))) ? [value[1], value[2], value[3]] : false;
  3440. },
  3441. compute: function(from, to, delta){
  3442. return from.map(function(value, i){
  3443. return Math.round(Fx.compute(from[i], to[i], delta));
  3444. });
  3445. },
  3446. serve: function(value){
  3447. return value.map(Number);
  3448. }
  3449. },
  3450. Number: {
  3451. parse: parseFloat,
  3452. compute: Fx.compute,
  3453. serve: function(value, unit){
  3454. return (unit) ? value + unit : value;
  3455. }
  3456. },
  3457. String: {
  3458. parse: Function.from(false),
  3459. compute: function(zero, one){
  3460. return one;
  3461. },
  3462. serve: function(zero){
  3463. return zero;
  3464. }
  3465. }
  3466. };
  3467. /*
  3468. ---
  3469. name: Fx.Tween
  3470. description: Formerly Fx.Style, effect to transition any CSS property for an element.
  3471. license: MIT-style license.
  3472. requires: Fx.CSS
  3473. provides: [Fx.Tween, Element.fade, Element.highlight]
  3474. ...
  3475. */
  3476. Fx.Tween = new Class({
  3477. Extends: Fx.CSS,
  3478. initialize: function(element, options){
  3479. this.element = this.subject = document.id(element);
  3480. this.parent(options);
  3481. },
  3482. set: function(property, now){
  3483. if (arguments.length == 1){
  3484. now = property;
  3485. property = this.property || this.options.property;
  3486. }
  3487. this.render(this.element, property, now, this.options.unit);
  3488. return this;
  3489. },
  3490. start: function(property, from, to){
  3491. if (!this.check(property, from, to)) return this;
  3492. var args = Array.flatten(arguments);
  3493. this.property = this.options.property || args.shift();
  3494. var parsed = this.prepare(this.element, this.property, args);
  3495. return this.parent(parsed.from, parsed.to);
  3496. }
  3497. });
  3498. Element.Properties.tween = {
  3499. set: function(options){
  3500. this.get('tween').cancel().setOptions(options);
  3501. return this;
  3502. },
  3503. get: function(){
  3504. var tween = this.retrieve('tween');
  3505. if (!tween){
  3506. tween = new Fx.Tween(this, {link: 'cancel'});
  3507. this.store('tween', tween);
  3508. }
  3509. return tween;
  3510. }
  3511. };
  3512. Element.implement({
  3513. tween: function(property, from, to){
  3514. this.get('tween').start(arguments);
  3515. return this;
  3516. },
  3517. fade: function(how){
  3518. var fade = this.get('tween'), o = 'opacity', toggle;
  3519. how = [how, 'toggle'].pick();
  3520. switch (how){
  3521. case 'in': fade.start(o, 1); break;
  3522. case 'out': fade.start(o, 0); break;
  3523. case 'show': fade.set(o, 1); break;
  3524. case 'hide': fade.set(o, 0); break;
  3525. case 'toggle':
  3526. var flag = this.retrieve('fade:flag', this.get('opacity') == 1);
  3527. fade.start(o, (flag) ? 0 : 1);
  3528. this.store('fade:flag', !flag);
  3529. toggle = true;
  3530. break;
  3531. default: fade.start(o, arguments);
  3532. }
  3533. if (!toggle) this.eliminate('fade:flag');
  3534. return this;
  3535. },
  3536. highlight: function(start, end){
  3537. if (!end){
  3538. end = this.retrieve('highlight:original', this.getStyle('background-color'));
  3539. end = (end == 'transparent') ? '#fff' : end;
  3540. }
  3541. var tween = this.get('tween');
  3542. tween.start('background-color', start || '#ffff88', end).chain(function(){
  3543. this.setStyle('background-color', this.retrieve('highlight:original'));
  3544. tween.callChain();
  3545. }.bind(this));
  3546. return this;
  3547. }
  3548. });
  3549. /*
  3550. ---
  3551. name: Fx.Morph
  3552. 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.
  3553. license: MIT-style license.
  3554. requires: Fx.CSS
  3555. provides: Fx.Morph
  3556. ...
  3557. */
  3558. Fx.Morph = new Class({
  3559. Extends: Fx.CSS,
  3560. initialize: function(element, options){
  3561. this.element = this.subject = document.id(element);
  3562. this.parent(options);
  3563. },
  3564. set: function(now){
  3565. if (typeof now == 'string') now = this.search(now);
  3566. for (var p in now) this.render(this.element, p, now[p], this.options.unit);
  3567. return this;
  3568. },
  3569. compute: function(from, to, delta){
  3570. var now = {};
  3571. for (var p in from) now[p] = this.parent(from[p], to[p], delta);
  3572. return now;
  3573. },
  3574. start: function(properties){
  3575. if (!this.check(properties)) return this;
  3576. if (typeof properties == 'string') properties = this.search(properties);
  3577. var from = {}, to = {};
  3578. for (var p in properties){
  3579. var parsed = this.prepare(this.element, p, properties[p]);
  3580. from[p] = parsed.from;
  3581. to[p] = parsed.to;
  3582. }
  3583. return this.parent(from, to);
  3584. }
  3585. });
  3586. Element.Properties.morph = {
  3587. set: function(options){
  3588. this.get('morph').cancel().setOptions(options);
  3589. return this;
  3590. },
  3591. get: function(){
  3592. var morph = this.retrieve('morph');
  3593. if (!morph){
  3594. morph = new Fx.Morph(this, {link: 'cancel'});
  3595. this.store('morph', morph);
  3596. }
  3597. return morph;
  3598. }
  3599. };
  3600. Element.implement({
  3601. morph: function(props){
  3602. this.get('morph').start(props);
  3603. return this;
  3604. }
  3605. });
  3606. /*
  3607. ---
  3608. name: Fx.Transitions
  3609. description: Contains a set of advanced transitions to be used with any of the Fx Classes.
  3610. license: MIT-style license.
  3611. credits:
  3612. - Easing Equations by Robert Penner, <http://www.robertpenner.com/easing/>, modified and optimized to be used with MooTools.
  3613. requires: Fx
  3614. provides: Fx.Transitions
  3615. ...
  3616. */
  3617. Fx.implement({
  3618. getTransition: function(){
  3619. var trans = this.options.transition || Fx.Transitions.Sine.easeInOut;
  3620. if (typeof trans == 'string'){
  3621. var data = trans.split(':');
  3622. trans = Fx.Transitions;
  3623. trans = trans[data[0]] || trans[data[0].capitalize()];
  3624. if (data[1]) trans = trans['ease' + data[1].capitalize() + (data[2] ? data[2].capitalize() : '')];
  3625. }
  3626. return trans;
  3627. }
  3628. });
  3629. Fx.Transition = function(transition, params){
  3630. params = Array.from(params);
  3631. var easeIn = function(pos){
  3632. return transition(pos, params);
  3633. };
  3634. return Object.append(easeIn, {
  3635. easeIn: easeIn,
  3636. easeOut: function(pos){
  3637. return 1 - transition(1 - pos, params);
  3638. },
  3639. easeInOut: function(pos){
  3640. return (pos <= 0.5 ? transition(2 * pos, params) : (2 - transition(2 * (1 - pos), params))) / 2;
  3641. }
  3642. });
  3643. };
  3644. Fx.Transitions = {
  3645. linear: function(zero){
  3646. return zero;
  3647. }
  3648. };
  3649. Fx.Transitions.extend = function(transitions){
  3650. for (var transition in transitions) Fx.Transitions[transition] = new Fx.Transition(transitions[transition]);
  3651. };
  3652. Fx.Transitions.extend({
  3653. Pow: function(p, x){
  3654. return Math.pow(p, x && x[0] || 6);
  3655. },
  3656. Expo: function(p){
  3657. return Math.pow(2, 8 * (p - 1));
  3658. },
  3659. Circ: function(p){
  3660. return 1 - Math.sin(Math.acos(p));
  3661. },
  3662. Sine: function(p){
  3663. return 1 - Math.cos(p * Math.PI / 2);
  3664. },
  3665. Back: function(p, x){
  3666. x = x && x[0] || 1.618;
  3667. return Math.pow(p, 2) * ((x + 1) * p - x);
  3668. },
  3669. Bounce: function(p){
  3670. var value;
  3671. for (var a = 0, b = 1; 1; a += b, b /= 2){
  3672. if (p >= (7 - 4 * a) / 11){
  3673. value = b * b - Math.pow((11 - 6 * a - 11 * p) / 4, 2);
  3674. break;
  3675. }
  3676. }
  3677. return value;
  3678. },
  3679. Elastic: function(p, x){
  3680. return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x && x[0] || 1) / 3);
  3681. }
  3682. });
  3683. ['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i){
  3684. Fx.Transitions[transition] = new Fx.Transition(function(p){
  3685. return Math.pow(p, i + 2);
  3686. });
  3687. });
  3688. /*
  3689. ---
  3690. name: Request
  3691. description: Powerful all purpose Request Class. Uses XMLHTTPRequest.
  3692. license: MIT-style license.
  3693. requires: [Object, Element, Chain, Events, Options, Browser]
  3694. provides: Request
  3695. ...
  3696. */
  3697. (function(){
  3698. var empty = function(){},
  3699. progressSupport = ('onprogress' in new Browser.Request);
  3700. var Request = this.Request = new Class({
  3701. Implements: [Chain, Events, Options],
  3702. options: {/*
  3703. onRequest: function(){},
  3704. onLoadstart: function(event, xhr){},
  3705. onProgress: function(event, xhr){},
  3706. onComplete: function(){},
  3707. onCancel: function(){},
  3708. onSuccess: function(responseText, responseXML){},
  3709. onFailure: function(xhr){},
  3710. onException: function(headerName, value){},
  3711. onTimeout: function(){},
  3712. user: '',
  3713. password: '',*/
  3714. url: '',
  3715. data: '',
  3716. headers: {
  3717. 'X-Requested-With': 'XMLHttpRequest',
  3718. 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
  3719. },
  3720. async: true,
  3721. format: false,
  3722. method: 'post',
  3723. link: 'ignore',
  3724. isSuccess: null,
  3725. emulation: true,
  3726. urlEncoded: true,
  3727. encoding: 'utf-8',
  3728. evalScripts: false,
  3729. evalResponse: false,
  3730. timeout: 0,
  3731. noCache: false
  3732. },
  3733. initialize: function(options){
  3734. this.xhr = new Browser.Request();
  3735. this.setOptions(options);
  3736. this.headers = this.options.headers;
  3737. },
  3738. onStateChange: function(){
  3739. var xhr = this.xhr;
  3740. if (xhr.readyState != 4 || !this.running) return;
  3741. this.running = false;
  3742. this.status = 0;
  3743. Function.attempt(function(){
  3744. var status = xhr.status;
  3745. this.status = (status == 1223) ? 204 : status;
  3746. }.bind(this));
  3747. xhr.onreadystatechange = empty;
  3748. if (progressSupport) xhr.onprogress = xhr.onloadstart = empty;
  3749. clearTimeout(this.timer);
  3750. this.response = {text: this.xhr.responseText || '', xml: this.xhr.responseXML};
  3751. if (this.options.isSuccess.call(this, this.status))
  3752. this.success(this.response.text, this.response.xml);
  3753. else
  3754. this.failure();
  3755. },
  3756. isSuccess: function(){
  3757. var status = this.status;
  3758. return (status >= 200 && status < 300);
  3759. },
  3760. isRunning: function(){
  3761. return !!this.running;
  3762. },
  3763. processScripts: function(text){
  3764. if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type'))) return Browser.exec(text);
  3765. return text.stripScripts(this.options.evalScripts);
  3766. },
  3767. success: function(text, xml){
  3768. this.onSuccess(this.processScripts(text), xml);
  3769. },
  3770. onSuccess: function(){
  3771. this.fireEvent('complete', arguments).fireEvent('success', arguments).callChain();
  3772. },
  3773. failure: function(){
  3774. this.onFailure();
  3775. },
  3776. onFailure: function(){
  3777. this.fireEvent('complete').fireEvent('failure', this.xhr);
  3778. },
  3779. loadstart: function(event){
  3780. this.fireEvent('loadstart', [event, this.xhr]);
  3781. },
  3782. progress: function(event){
  3783. this.fireEvent('progress', [event, this.xhr]);
  3784. },
  3785. timeout: function(){
  3786. this.fireEvent('timeout', this.xhr);
  3787. },
  3788. setHeader: function(name, value){
  3789. this.headers[name] = value;
  3790. return this;
  3791. },
  3792. getHeader: function(name){
  3793. return Function.attempt(function(){
  3794. return this.xhr.getResponseHeader(name);
  3795. }.bind(this));
  3796. },
  3797. check: function(){
  3798. if (!this.running) return true;
  3799. switch (this.options.link){
  3800. case 'cancel': this.cancel(); return true;
  3801. case 'chain': this.chain(this.caller.pass(arguments, this)); return false;
  3802. }
  3803. return false;
  3804. },
  3805. send: function(options){
  3806. if (!this.check(options)) return this;
  3807. this.options.isSuccess = this.options.isSuccess || this.isSuccess;
  3808. this.running = true;
  3809. var type = typeOf(options);
  3810. if (type == 'string' || type == 'element') options = {data: options};
  3811. var old = this.options;
  3812. options = Object.append({data: old.data, url: old.url, method: old.method}, options);
  3813. var data = options.data, url = String(options.url), method = options.method.toLowerCase();
  3814. switch (typeOf(data)){
  3815. case 'element': data = document.id(data).toQueryString(); break;
  3816. case 'object': case 'hash': data = Object.toQueryString(data);
  3817. }
  3818. if (this.options.format){
  3819. var format = 'format=' + this.options.format;
  3820. data = (data) ? format + '&' + data : format;
  3821. }
  3822. if (this.options.emulation && !['get', 'post'].contains(method)){
  3823. var _method = '_method=' + method;
  3824. data = (data) ? _method + '&' + data : _method;
  3825. method = 'post';
  3826. }
  3827. if (this.options.urlEncoded && ['post', 'put'].contains(method)){
  3828. var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : '';
  3829. this.headers['Content-type'] = 'application/x-www-form-urlencoded' + encoding;
  3830. }
  3831. if (!url) url = document.location.pathname;
  3832. var trimPosition = url.lastIndexOf('/');
  3833. if (trimPosition > -1 && (trimPosition = url.indexOf('#')) > -1) url = url.substr(0, trimPosition);
  3834. if (this.options.noCache)
  3835. url += (url.contains('?') ? '&' : '?') + String.uniqueID();
  3836. if (data && method == 'get'){
  3837. url += (url.contains('?') ? '&' : '?') + data;
  3838. data = null;
  3839. }
  3840. var xhr = this.xhr;
  3841. if (progressSupport){
  3842. xhr.onloadstart = this.loadstart.bind(this);
  3843. xhr.onprogress = this.progress.bind(this);
  3844. }
  3845. xhr.open(method.toUpperCase(), url, this.options.async, this.options.user, this.options.password);
  3846. if (this.options.user && 'withCredentials' in xhr) xhr.withCredentials = true;
  3847. xhr.onreadystatechange = this.onStateChange.bind(this);
  3848. Object.each(this.headers, function(value, key){
  3849. try {
  3850. xhr.setRequestHeader(key, value);
  3851. } catch (e){
  3852. this.fireEvent('exception', [key, value]);
  3853. }
  3854. }, this);
  3855. this.fireEvent('request');
  3856. xhr.send(data);
  3857. if (!this.options.async) this.onStateChange();
  3858. if (this.options.timeout) this.timer = this.timeout.delay(this.options.timeout, this);
  3859. return this;
  3860. },
  3861. cancel: function(){
  3862. if (!this.running) return this;
  3863. this.running = false;
  3864. var xhr = this.xhr;
  3865. xhr.abort();
  3866. clearTimeout(this.timer);
  3867. xhr.onreadystatechange = empty;
  3868. if (progressSupport) xhr.onprogress = xhr.onloadstart = empty;
  3869. this.xhr = new Browser.Request();
  3870. this.fireEvent('cancel');
  3871. return this;
  3872. }
  3873. });
  3874. var methods = {};
  3875. ['get', 'post', 'put', 'delete', 'GET', 'POST', 'PUT', 'DELETE'].each(function(method){
  3876. methods[method] = function(data){
  3877. var object = {
  3878. method: method
  3879. };
  3880. if (data != null) object.data = data;
  3881. return this.send(object);
  3882. };
  3883. });
  3884. Request.implement(methods);
  3885. Element.Properties.send = {
  3886. set: function(options){
  3887. var send = this.get('send').cancel();
  3888. send.setOptions(options);
  3889. return this;
  3890. },
  3891. get: function(){
  3892. var send = this.retrieve('send');
  3893. if (!send){
  3894. send = new Request({
  3895. data: this, link: 'cancel', method: this.get('method') || 'post', url: this.get('action')
  3896. });
  3897. this.store('send', send);
  3898. }
  3899. return send;
  3900. }
  3901. };
  3902. Element.implement({
  3903. send: function(url){
  3904. var sender = this.get('send');
  3905. sender.send({data: this, url: url || sender.options.url});
  3906. return this;
  3907. }
  3908. });
  3909. })();
  3910. /*
  3911. ---
  3912. name: Request.HTML
  3913. description: Extends the basic Request Class with additional methods for interacting with HTML responses.
  3914. license: MIT-style license.
  3915. requires: [Element, Request]
  3916. provides: Request.HTML
  3917. ...
  3918. */
  3919. Request.HTML = new Class({
  3920. Extends: Request,
  3921. options: {
  3922. update: false,
  3923. append: false,
  3924. evalScripts: true,
  3925. filter: false,
  3926. headers: {
  3927. Accept: 'text/html, application/xml, text/xml, */*'
  3928. }
  3929. },
  3930. success: function(text){
  3931. var options = this.options, response = this.response;
  3932. response.html = text.stripScripts(function(script){
  3933. response.javascript = script;
  3934. });
  3935. var match = response.html.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
  3936. if (match) response.html = match[1];
  3937. var temp = new Element('div').set('html', response.html);
  3938. response.tree = temp.childNodes;
  3939. response.elements = temp.getElements('*');
  3940. if (options.filter) response.tree = response.elements.filter(options.filter);
  3941. if (options.update) document.id(options.update).empty().set('html', response.html);
  3942. else if (options.append) document.id(options.append).adopt(temp.getChildren());
  3943. if (options.evalScripts) Browser.exec(response.javascript);
  3944. this.onSuccess(response.tree, response.elements, response.html, response.javascript);
  3945. }
  3946. });
  3947. Element.Properties.load = {
  3948. set: function(options){
  3949. var load = this.get('load').cancel();
  3950. load.setOptions(options);
  3951. return this;
  3952. },
  3953. get: function(){
  3954. var load = this.retrieve('load');
  3955. if (!load){
  3956. load = new Request.HTML({data: this, link: 'cancel', update: this, method: 'get'});
  3957. this.store('load', load);
  3958. }
  3959. return load;
  3960. }
  3961. };
  3962. Element.implement({
  3963. load: function(){
  3964. this.get('load').send(Array.link(arguments, {data: Type.isObject, url: Type.isString}));
  3965. return this;
  3966. }
  3967. });
  3968. /*
  3969. ---
  3970. name: JSON
  3971. description: JSON encoder and decoder.
  3972. license: MIT-style license.
  3973. See Also: <http://www.json.org/>
  3974. requires: [Array, String, Number, Function]
  3975. provides: JSON
  3976. ...
  3977. */
  3978. if (typeof JSON == 'undefined') this.JSON = {};
  3979. (function(){
  3980. var special = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'};
  3981. var escape = function(chr){
  3982. return special[chr] || '\\u' + ('0000' + chr.charCodeAt(0).toString(16)).slice(-4);
  3983. };
  3984. JSON.validate = function(string){
  3985. string = string.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
  3986. replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
  3987. replace(/(?:^|:|,)(?:\s*\[)+/g, '');
  3988. return (/^[\],:{}\s]*$/).test(string);
  3989. };
  3990. JSON.encode = JSON.stringify ? function(obj){
  3991. return JSON.stringify(obj);
  3992. } : function(obj){
  3993. if (obj && obj.toJSON) obj = obj.toJSON();
  3994. switch (typeOf(obj)){
  3995. case 'string':
  3996. return '"' + obj.replace(/[\x00-\x1f\\"]/g, escape) + '"';
  3997. case 'array':
  3998. return '[' + obj.map(JSON.encode).clean() + ']';
  3999. case 'object': case 'hash':
  4000. var string = [];
  4001. Object.each(obj, function(value, key){
  4002. var json = JSON.encode(value);
  4003. if (json) string.push(JSON.encode(key) + ':' + json);
  4004. });
  4005. return '{' + string + '}';
  4006. case 'number': case 'boolean': return '' + obj;
  4007. case 'null': return 'null';
  4008. }
  4009. return null;
  4010. };
  4011. JSON.decode = function(string, secure){
  4012. if (!string || typeOf(string) != 'string') return null;
  4013. if (secure || JSON.secure){
  4014. if (JSON.parse) return JSON.parse(string);
  4015. if (!JSON.validate(string)) throw new Error('JSON could not decode the input; security is enabled and the value is not secure.');
  4016. }
  4017. return eval('(' + string + ')');
  4018. };
  4019. })();
  4020. /*
  4021. ---
  4022. name: Request.JSON
  4023. description: Extends the basic Request Class with additional methods for sending and receiving JSON data.
  4024. license: MIT-style license.
  4025. requires: [Request, JSON]
  4026. provides: Request.JSON
  4027. ...
  4028. */
  4029. Request.JSON = new Class({
  4030. Extends: Request,
  4031. options: {
  4032. /*onError: function(text, error){},*/
  4033. secure: true
  4034. },
  4035. initialize: function(options){
  4036. this.parent(options);
  4037. Object.append(this.headers, {
  4038. 'Accept': 'application/json',
  4039. 'X-Request': 'JSON'
  4040. });
  4041. },
  4042. success: function(text){
  4043. var json;
  4044. try {
  4045. json = this.response.json = JSON.decode(text, this.options.secure);
  4046. } catch (error){
  4047. this.fireEvent('error', [text, error]);
  4048. return;
  4049. }
  4050. if (json == null) this.onFailure();
  4051. else this.onSuccess(json, text);
  4052. }
  4053. });
  4054. /*
  4055. ---
  4056. name: Cookie
  4057. description: Class for creating, reading, and deleting browser Cookies.
  4058. license: MIT-style license.
  4059. credits:
  4060. - Based on the functions by Peter-Paul Koch (http://quirksmode.org).
  4061. requires: [Options, Browser]
  4062. provides: Cookie
  4063. ...
  4064. */
  4065. var Cookie = new Class({
  4066. Implements: Options,
  4067. options: {
  4068. path: '/',
  4069. domain: false,
  4070. duration: false,
  4071. secure: false,
  4072. document: document,
  4073. encode: true
  4074. },
  4075. initialize: function(key, options){
  4076. this.key = key;
  4077. this.setOptions(options);
  4078. },
  4079. write: function(value){
  4080. if (this.options.encode) value = encodeURIComponent(value);
  4081. if (this.options.domain) value += '; domain=' + this.options.domain;
  4082. if (this.options.path) value += '; path=' + this.options.path;
  4083. if (this.options.duration){
  4084. var date = new Date();
  4085. date.setTime(date.getTime() + this.options.duration * 24 * 60 * 60 * 1000);
  4086. value += '; expires=' + date.toGMTString();
  4087. }
  4088. if (this.options.secure) value += '; secure';
  4089. this.options.document.cookie = this.key + '=' + value;
  4090. return this;
  4091. },
  4092. read: function(){
  4093. var value = this.options.document.cookie.match('(?:^|;)\\s*' + this.key.escapeRegExp() + '=([^;]*)');
  4094. return (value) ? decodeURIComponent(value[1]) : null;
  4095. },
  4096. dispose: function(){
  4097. new Cookie(this.key, Object.merge({}, this.options, {duration: -1})).write('');
  4098. return this;
  4099. }
  4100. });
  4101. Cookie.write = function(key, value, options){
  4102. return new Cookie(key, options).write(value);
  4103. };
  4104. Cookie.read = function(key){
  4105. return new Cookie(key).read();
  4106. };
  4107. Cookie.dispose = function(key, options){
  4108. return new Cookie(key, options).dispose();
  4109. };
  4110. /*
  4111. ---
  4112. name: DOMReady
  4113. description: Contains the custom event domready.
  4114. license: MIT-style license.
  4115. requires: [Browser, Element, Element.Event]
  4116. provides: [DOMReady, DomReady]
  4117. ...
  4118. */
  4119. (function(window, document){
  4120. var ready,
  4121. loaded,
  4122. checks = [],
  4123. shouldPoll,
  4124. timer,
  4125. testElement = document.createElement('div');
  4126. var domready = function(){
  4127. clearTimeout(timer);
  4128. if (ready) return;
  4129. Browser.loaded = ready = true;
  4130. document.removeListener('DOMContentLoaded', domready).removeListener('readystatechange', check);
  4131. document.fireEvent('domready');
  4132. window.fireEvent('domready');
  4133. };
  4134. var check = function(){
  4135. for (var i = checks.length; i--;) if (checks[i]()){
  4136. domready();
  4137. return true;
  4138. }
  4139. return false;
  4140. };
  4141. var poll = function(){
  4142. clearTimeout(timer);
  4143. if (!check()) timer = setTimeout(poll, 10);
  4144. };
  4145. document.addListener('DOMContentLoaded', domready);
  4146. /*<ltIE8>*/
  4147. // doScroll technique by Diego Perini http://javascript.nwbox.com/IEContentLoaded/
  4148. // testElement.doScroll() throws when the DOM is not ready, only in the top window
  4149. var doScrollWorks = function(){
  4150. try {
  4151. testElement.doScroll();
  4152. return true;
  4153. } catch (e){}
  4154. return false;
  4155. }
  4156. // If doScroll works already, it can't be used to determine domready
  4157. // e.g. in an iframe
  4158. if (testElement.doScroll && !doScrollWorks()){
  4159. checks.push(doScrollWorks);
  4160. shouldPoll = true;
  4161. }
  4162. /*</ltIE8>*/
  4163. if (document.readyState) checks.push(function(){
  4164. var state = document.readyState;
  4165. return (state == 'loaded' || state == 'complete');
  4166. });
  4167. if ('onreadystatechange' in document) document.addListener('readystatechange', check);
  4168. else shouldPoll = true;
  4169. if (shouldPoll) poll();
  4170. Element.Events.domready = {
  4171. onAdd: function(fn){
  4172. if (ready) fn.call(this);
  4173. }
  4174. };
  4175. // Make sure that domready fires before load
  4176. Element.Events.load = {
  4177. base: 'load',
  4178. onAdd: function(fn){
  4179. if (loaded && this == window) fn.call(this);
  4180. },
  4181. condition: function(){
  4182. if (this == window){
  4183. domready();
  4184. delete Element.Events.load;
  4185. }
  4186. return true;
  4187. }
  4188. };
  4189. // This is based on the custom load event
  4190. window.addEvent('load', function(){
  4191. loaded = true;
  4192. });
  4193. })(window, document);
  4194. /*
  4195. ---
  4196. name: Swiff
  4197. description: Wrapper for embedding SWF movies. Supports External Interface Communication.
  4198. license: MIT-style license.
  4199. credits:
  4200. - Flash detection & Internet Explorer + Flash Player 9 fix inspired by SWFObject.
  4201. requires: [Options, Object, Element]
  4202. provides: Swiff
  4203. ...
  4204. */
  4205. (function(){
  4206. var Swiff = this.Swiff = new Class({
  4207. Implements: Options,
  4208. options: {
  4209. id: null,
  4210. height: 1,
  4211. width: 1,
  4212. container: null,
  4213. properties: {},
  4214. params: {
  4215. quality: 'high',
  4216. allowScriptAccess: 'always',
  4217. wMode: 'window',
  4218. swLiveConnect: true
  4219. },
  4220. callBacks: {},
  4221. vars: {}
  4222. },
  4223. toElement: function(){
  4224. return this.object;
  4225. },
  4226. initialize: function(path, options){
  4227. this.instance = 'Swiff_' + String.uniqueID();
  4228. this.setOptions(options);
  4229. options = this.options;
  4230. var id = this.id = options.id || this.instance;
  4231. var container = document.id(options.container);
  4232. Swiff.CallBacks[this.instance] = {};
  4233. var params = options.params, vars = options.vars, callBacks = options.callBacks;
  4234. var properties = Object.append({height: options.height, width: options.width}, options.properties);
  4235. var self = this;
  4236. for (var callBack in callBacks){
  4237. Swiff.CallBacks[this.instance][callBack] = (function(option){
  4238. return function(){
  4239. return option.apply(self.object, arguments);
  4240. };
  4241. })(callBacks[callBack]);
  4242. vars[callBack] = 'Swiff.CallBacks.' + this.instance + '.' + callBack;
  4243. }
  4244. params.flashVars = Object.toQueryString(vars);
  4245. if (Browser.ie){
  4246. properties.classid = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';
  4247. params.movie = path;
  4248. } else {
  4249. properties.type = 'application/x-shockwave-flash';
  4250. }
  4251. properties.data = path;
  4252. var build = '<object id="' + id + '"';
  4253. for (var property in properties) build += ' ' + property + '="' + properties[property] + '"';
  4254. build += '>';
  4255. for (var param in params){
  4256. if (params[param]) build += '<param name="' + param + '" value="' + params[param] + '" />';
  4257. }
  4258. build += '</object>';
  4259. this.object = ((container) ? container.empty() : new Element('div')).set('html', build).firstChild;
  4260. },
  4261. replaces: function(element){
  4262. element = document.id(element, true);
  4263. element.parentNode.replaceChild(this.toElement(), element);
  4264. return this;
  4265. },
  4266. inject: function(element){
  4267. document.id(element, true).appendChild(this.toElement());
  4268. return this;
  4269. },
  4270. remote: function(){
  4271. return Swiff.remote.apply(Swiff, [this.toElement()].append(arguments));
  4272. }
  4273. });
  4274. Swiff.CallBacks = {};
  4275. Swiff.remote = function(obj, fn){
  4276. var rs = obj.CallFunction('<invoke name="' + fn + '" returntype="javascript">' + __flash__argumentsToXML(arguments, 2) + '</invoke>');
  4277. return eval(rs);
  4278. };
  4279. })();