1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583 |
- /**
- * Slideshow JS Bundle
- */
- YUI.add('fl-event-move', function(Y) {
- /**
- * Adds gesturemovevertical, gesturemoveverticalend, gesturemovehorizontal
- * and gesturemovehorizontalend events.
- *
- * @module fl-event-move
- */
- var _eventBase = {
- _isEndEvent: false,
- on: function(node, subscriber, ce)
- {
- if(this.type.indexOf('end') > -1) {
- this._isEndEvent = true;
- }
- subscriber._direction = this.type.replace('gesturemove', '').replace('end', '');
- if(window.navigator.msPointerEnabled) {
- subscriber._startHandle = node.on('MSPointerDown', this._onStart, this, node, subscriber, ce);
- subscriber._moveHandle = node.on('MSPointerMove', this._onMove, this, node, subscriber, ce);
- subscriber._endHandle = node.on('MSPointerUp', this._onEnd, this, node, subscriber, ce);
- }
- else {
- subscriber._startHandle = node.on('gesturemovestart', this._onStart, null, this, node, subscriber, ce);
- subscriber._moveHandle = node.on('gesturemove', this._onMove, null, this, node, subscriber, ce);
- subscriber._endHandle = node.on('gesturemoveend', this._onEnd, { standAlone: true }, this, node, subscriber, ce);
- }
- },
- detach: function(node, subscriber, ce)
- {
- subscriber._startHandle.detach();
- subscriber._startHandle = null;
- subscriber._moveHandle.detach();
- subscriber._moveHandle = null;
- subscriber._endHandle.detach();
- subscriber._endHandle = null;
- },
- _onStart: function(e, node, subscriber, ce)
- {
- subscriber._doMove = null;
- subscriber._startX = e.pageX;
- subscriber._startY = e.pageY;
- },
- _onMove: function(e, node, subscriber, ce)
- {
- if(this._checkDirection(e, subscriber)) {
- subscriber._doMove = true;
- }
- else {
- subscriber._doMove = false;
- }
- if(subscriber._doMove && !this._isEndEvent) {
- ce.fire(e);
- }
- },
- _onEnd: function(e, node, subscriber, ce)
- {
- if(subscriber._doMove && this._isEndEvent) {
- e.startPageX = subscriber._startX;
- e.startPageY = subscriber._startY;
- ce.fire(e);
- }
- subscriber._doMove = null;
- },
- _checkDirection: function(e, subscriber)
- {
- var xDelta = Math.abs(subscriber._startX - e.pageX),
- yDelta = Math.abs(subscriber._startY - e.pageY);
- if(yDelta > xDelta && subscriber._startY > e.pageY && subscriber._direction == 'vertical') {
- return true;
- }
- else if(yDelta > xDelta && subscriber._startY < e.pageY && subscriber._direction == 'vertical') {
- return true;
- }
- else if(yDelta < xDelta && subscriber._startX > e.pageX && subscriber._direction == 'horizontal') {
- return true;
- }
- else if(yDelta < xDelta && subscriber._startX < e.pageX && subscriber._direction == 'horizontal') {
- return true;
- }
- return false;
- }
- };
- /**
- * @event gesturemovevertical
- * @param type {String} "gesturemovevertical"
- * @param fn {Function} The method the event invokes.
- * @param ctx {Object} Context for the method the event invokes.
- */
- Y.Event.define('gesturemovevertical', _eventBase);
- /**
- * @event gesturemoveverticalend
- * @param type {String} "gesturemoveverticalend"
- * @param fn {Function} The method the event invokes.
- * @param ctx {Object} Context for the method the event invokes.
- */
- Y.Event.define('gesturemoveverticalend', _eventBase);
- /**
- * @event gesturemovehorizontal
- * @param type {String} "gesturemovehorizontal"
- * @param fn {Function} The method the event invokes.
- * @param ctx {Object} Context for the method the event invokes.
- */
- Y.Event.define('gesturemovehorizontal', _eventBase);
- /**
- * @event gesturemovehorizontalend
- * @param type {String} "gesturemovehorizontalend"
- * @param fn {Function} The method the event invokes.
- * @param ctx {Object} Context for the method the event invokes.
- */
- Y.Event.define('gesturemovehorizontalend', _eventBase);
- }, '2.0.0' ,{requires:['event-move']});
- YUI.add('fl-slideshow', function(Y) {
- /**
- * @module fl-slideshow
- */
- /**
- * Caption widget used in slideshows.
- *
- * @namespace FL
- * @class SlideshowCaption
- * @constructor
- * @param config {Object} Configuration object
- * @extends Widget
- */
- Y.namespace('FL').SlideshowCaption = Y.Base.create('fl-slideshow-caption', Y.Widget, [Y.WidgetChild], {
- /**
- * Flag for whether the text has been
- * toggled or not.
- *
- * @property _textToggled
- * @type Boolean
- * @default false
- * @protected
- */
- _textToggled: false,
- /**
- * An anchor node used for the toggle link.
- *
- * @property _textToggleLink
- * @type Object
- * @default null
- * @protected
- */
- _textToggleLink: null,
- /**
- * @method renderUI
- * @protected
- */
- renderUI: function()
- {
- var root = this.get('root'),
- bb = this.get('boundingBox');
- this._textToggleLink = Y.Node.create('<a href="javascript:void(0);"></a>');
- this._textToggleLink.addClass('fl-slideshow-caption-toggle');
- this._textToggleLink.set('innerHTML', root.get('captionMoreLinkText'));
- bb.appendChild(this._textToggleLink);
- },
- /**
- * @method bindUI
- * @protected
- */
- bindUI: function()
- {
- this.get('root').on('imageLoadComplete', Y.bind(this._setText, this));
- this._textToggleLink.on('click', Y.bind(this._toggleText, this));
- },
- /**
- * Sets the caption text and displays the
- * toggle link if necessary.
- *
- * @method _setText
- * @protected
- */
- _setText: function()
- {
- var root = this.get('root'),
- text = root.imageInfo.caption,
- textLength = root.get('captionTextLength'),
- cb = this.get('contentBox');
- if(!root.imageInfo.caption || root.imageInfo.caption === '') {
- cb.set('innerHTML', '');
- this._textToggleLink.setStyle('display', 'none');
- return;
- }
- else if(textLength > -1) {
- if(!this._textToggled && textLength < text.length) {
- text = this._shortenText(text);
- this._textToggleLink.setStyle('display', 'inline-block');
- }
- else if(this._textToggled && textLength < text.length) {
- text = this._stripTags(text);
- this._textToggleLink.setStyle('display', 'inline-block');
- }
- else {
- text = this._stripTags(text);
- this._textToggleLink.setStyle('display', 'none');
- }
- }
- else {
- text = this._stripTags(text);
- }
- cb.set('innerHTML', text);
- },
- /**
- * Shows or hides the full text when the
- * toggle link is clicked.
- *
- * @method _toggleText
- * @protected
- */
- _toggleText: function()
- {
- var root = this.get('root'),
- text = root.imageInfo.caption,
- cb = this.get('contentBox');
- if(this._textToggled) {
- text = this._shortenText(text);
- this._textToggleLink.set('innerHTML', root.get('captionMoreLinkText'));
- this._textToggled = false;
- }
- else {
- text = this._stripTags(text);
- this._textToggleLink.set('innerHTML', root.get('captionLessLinkText'));
- this._textToggled = true;
- }
- cb.set('innerHTML', text);
- },
- /**
- * Strips out HTML tags from the caption text.
- *
- * @method _stripTags
- * @param text {String} The text to strip HTML tags from.
- * @param ignoreSettings {Boolean} If true, will strip tags even if
- * the stripTags attribute is set to false.
- * @protected
- */
- _stripTags: function(text, ignoreSettings)
- {
- var root = this.get('root'), textDiv;
- if(ignoreSettings || root.get('captionStripTags')) {
- textDiv = document.createElement('div');
- textDiv.innerHTML = text;
- text = textDiv.textContent || textDiv.innerText;
- }
- return text;
- },
- /**
- * Shortens the caption text to the length of
- * the textLength attribute.
- *
- * @method _shortenText
- * @protected
- */
- _shortenText: function(text)
- {
- var root = this.get('root');
- text = this._stripTags(text, true).substring(0, root.get('captionTextLength'));
- return Y.Lang.trim(text.substring(0, text.lastIndexOf(' '))) + ' ...';
- }
- }, {
- /**
- * Custom CSS class name for the widget.
- *
- * @property CSS_PREFIX
- * @type String
- * @protected
- * @static
- */
- CSS_PREFIX: 'fl-slideshow-caption',
- /**
- * Static property used to define the default attribute configuration of
- * the Widget.
- *
- * @property ATTRS
- * @type Object
- * @protected
- * @static
- */
- ATTRS: {
- }
- });
- /**
- * A widget for loading and transitioning between SlideshowImage
- * instances. Each SlideshowImage instance is a child widget of
- * SlideshowFrame. SlideshowFrame is a child widget of the main
- * slideshow widget.
- *
- * @namespace FL
- * @class SlideshowFrame
- * @constructor
- * @param config {Object} Configuration object
- * @extends Widget
- */
- Y.namespace('FL').SlideshowFrame = Y.Base.create('fl-slideshow-frame', Y.Widget, [Y.WidgetParent, Y.WidgetChild], {
- /**
- * The imageInfo object used to load the active image.
- *
- * @property info
- * @type Object
- * @default null
- * @protected
- */
- _imageInfo: null,
- /**
- * The active FL.SlideshowImage instance in the frame.
- *
- * @property _activeImage
- * @type FL.SlideshowImage
- * @default null
- * @protected
- */
- _activeImage: null,
- /**
- * A FL.SlideshowImage instance used to load the
- * next image and transition it into the frame.
- *
- * @property _nextImage
- * @type FL.SlideshowImage
- * @default null
- * @protected
- */
- _nextImage: null,
- /**
- * Used to store imageInfo if a load request is
- * made while the frame is transitioning. If not null
- * when the transition completes, a new image will
- * be loaded using the imageInfo.
- *
- * @property _loadQueue
- * @type Object
- * @default false
- * @protected
- */
- _loadQueue: null,
- /**
- * An instance of FL.SlideshowTransition used for
- * the current transition in progress.
- *
- * @property _transition
- * @type FL.SlideshowTransition
- * @default null
- * @protected
- */
- _transition: null,
- /**
- * A flag for whether the frame is currently transitioning or not.
- *
- * @property _transitioning
- * @type Boolean
- * @default false
- * @protected
- */
- _transitioning: false,
- /**
- * Flag for whether to resize when the current transition
- * completes. Set to true when a resize request is made
- * during a transition.
- *
- * @property _resizeAfterTransition
- * @type Boolean
- * @default false
- * @protected
- */
- _resizeAfterTransition: false,
- /**
- * Provides functionality for gesture based transitions
- * between the active and next images.
- *
- * @property _gestures
- * @type FL.SlideshowGestures
- * @default null
- * @protected
- */
- _gestures: null,
- /**
- * Creates new instances of FL.SlideshowImage used in the frame.
- *
- * @method initializer
- * @protected
- */
- initializer: function()
- {
- var imageConfig = this.get('imageConfig');
- this._activeImage = new Y.FL.SlideshowImage(imageConfig);
- this._nextImage = new Y.FL.SlideshowImage(imageConfig);
- },
- /**
- * Renders the FL.SlideshowImage instances used in the frame.
- *
- * @method renderUI
- * @protected
- */
- renderUI: function()
- {
- this.add(this._activeImage);
- this.add(this._nextImage);
- },
- /**
- * @method bindUI
- * @protected
- */
- bindUI: function()
- {
- var activeBB = this._activeImage.get('boundingBox'),
- nextBB = this._nextImage.get('boundingBox'),
- transition = this.get('transition');
- if(('ontouchstart' in window || window.navigator.msPointerEnabled) && this.get('touchSupport')) {
- this._gestures = new Y.FL.SlideshowGestures({
- direction: transition == 'slideVertical' ? 'vertical' : 'horizontal',
- activeItem: activeBB,
- nextItem: nextBB
- });
- this._gestures.on('moveStart', this._gesturesMoveStart, this);
- this._gestures.on('endComplete', this._gesturesEndComplete, this);
- }
- },
- /**
- * Functional styles for the UI.
- *
- * @method syncUI
- * @protected
- */
- syncUI: function()
- {
- var activeBB = this._activeImage.get('boundingBox'),
- nextBB = this._nextImage.get('boundingBox'),
- cb = this.get('contentBox');
- activeBB.setStyle('position', 'absolute');
- activeBB.setStyle('top', '0px');
- activeBB.setStyle('left', '-9999px');
- nextBB.setStyle('position', 'absolute');
- nextBB.setStyle('top', '0px');
- nextBB.setStyle('left', '-9999px');
- cb.setStyle('position', 'relative');
- cb.setStyle('overflow', 'hidden');
- },
- /**
- * Checks whether the imageInfo should be loaded or queued.
- * Initializes a new transition if loading is ok.
- *
- * @method load
- * @param imageInfo {Object} The image info to load.
- */
- load: function(imageInfo)
- {
- var activeInfo = this._activeImage._imageInfo;
- if(this._transitioning) {
- this._loadQueue = imageInfo;
- return;
- }
- else if(activeInfo && activeInfo.largeURL == imageInfo.largeURL) {
- return;
- }
- this._imageInfo = imageInfo;
- this._transitionInit(imageInfo);
- },
- /**
- * Preloads the next image using the provided imageInfo.
- *
- * @method preload
- * @param imageInfo {Object} The imageInfo to preload.
- * @param width {Number} The width to preload.
- * @param height {Number} The height to preload.
- */
- preload: function(imageInfo, width, height)
- {
- this._imageInfo = imageInfo;
- this._nextImage.preload(imageInfo, width, height);
- },
- /**
- * Unloads the active and next image instances.
- *
- * @method unload
- */
- unload: function()
- {
- this._imageInfo = null;
- this._loadQueue = null;
- this._transitioning = false;
- this._transition = null;
- this._activeImage.detachAll();
- this._activeImage.unload();
- this._activeImage.get('boundingBox').setStyle('left', '-9999px');
- this._nextImage.detachAll();
- this._nextImage.unload();
- this._nextImage.get('boundingBox').setStyle('left', '-9999px');
- },
- /**
- * Resizes the bounding box and active image.
- *
- * @method resize
- * @param width {Number} The width value.
- * @param height {Number} The height value.
- */
- resize: function(width, height)
- {
- if(!width || !height) {
- return;
- }
- var bb = this.get('boundingBox'),
- padding = [
- parseInt(bb.getComputedStyle('paddingTop'), 10),
- parseInt(bb.getComputedStyle('paddingRight'), 10),
- parseInt(bb.getComputedStyle('paddingBottom'), 10),
- parseInt(bb.getComputedStyle('paddingLeft'), 10)
- ];
- width = width - padding[1] - padding[3];
- height = height - padding[0] - padding[2];
- this.set('width', width);
- this.set('height', height);
- if(this._transitioning) {
- this._resizeAfterTransition = true;
- }
- else {
- this._activeImage.resize(width, height);
- this._nextImage.resize(width, height);
- }
- },
- /**
- * Gets the current transition to use.
- *
- * @method _getTransition
- * @protected
- */
- _getTransition: function()
- {
- var root = this.get('root'),
- lastIndex = root.albumInfo.images.length - 1,
- direction = 'next',
- transition = root.get('transition');
- if(root.lastImageIndex === null) {
- direction = '';
- }
- else if(root.imageIndex == lastIndex && root.lastImageIndex === 0) {
- direction = 'prev';
- }
- else if(root.imageIndex === 0 && root.lastImageIndex == lastIndex) {
- direction = 'next';
- }
- else if(root.lastImageIndex > root.imageIndex) {
- direction = 'prev';
- }
- else if(root.lastImageIndex < root.imageIndex) {
- direction = 'next';
- }
- if(direction == 'next') {
- transition = transition.replace('slideHorizontal', 'slideLeft');
- transition = transition.replace('slideVertical', 'slideUp');
- }
- else if(direction == 'prev') {
- transition = transition.replace('slideHorizontal', 'slideRight');
- transition = transition.replace('slideVertical', 'slideDown');
- }
- return transition;
- },
- /**
- * Fires the transitionInit event and loads the next image.
- * The transition starts when the image's loadComplete
- * event is fired.
- *
- * @method _transitionInit
- * @param imageInfo {Object} The imageInfo to load before transitioning.
- * @protected
- */
- _transitionInit: function(imageInfo)
- {
- this._transitioning = true;
- // Disable gestures if set.
- if(this._gestures) {
- this._gestures.disable();
- }
- /**
- * Fires when the next image is loading before a new transition.
- *
- * @event transitionInit
- */
- this.fire('transitionInit');
- if(imageInfo) {
- this._nextImage.once('loadComplete', this._transitionStart, this);
- this._nextImage.load(imageInfo);
- }
- else {
- this._transitionStart();
- }
- },
- /**
- * Fires the transitionStart event and starts the transition
- * using a new instance of FL.SlideshowTransition.
- *
- * @method _transitionStart
- * @protected
- */
- _transitionStart: function()
- {
- var root = this.get('root');
- /**
- * Fires when the next image has finished loading
- * and a new transition starts.
- *
- * @event transitionStart
- */
- this.fire('transitionStart');
- this._transition = new Y.FL.SlideshowTransition({
- itemIn: this._nextImage._imageInfo ? this._nextImage.get('boundingBox') : null,
- itemOut: this._activeImage._imageInfo ? this._activeImage.get('boundingBox') : null,
- type: this._getTransition(),
- duration: root.get('transitionDuration'),
- easing: root.get('transitionEasing'),
- kenBurnsDuration: root.get('speed')/1000,
- kenBurnsZoom: root.get('kenBurnsZoom')
- });
- if(this._nextImage._imageInfo) {
- this._nextImage.get('boundingBox').setStyle('left', '0px');
- }
- this._transition.once('complete', this._transitionComplete, this);
- this._transition.run();
- },
- /**
- * Switches the next and active image variables, unloads the
- * last image, fires the transitionComplete event and loads
- * or resizes if appropriate.
- *
- * @method _transitionComplete
- * @protected
- */
- _transitionComplete: function()
- {
- var root = this.get('root');
- // Swap image container references.
- this._swapImageRefs();
- /**
- * Fired when the current transition completes.
- *
- * @event transitionComplete
- */
- this.fire('transitionComplete');
- this._transition = null;
- this._transitioning = false;
- // Enable gestures if set.
- if(this._gestures) {
- if(root && root.albumInfo.images.length <= 1) {
- this._gestures.disable();
- }
- else {
- this._gestures.enable();
- }
- }
- // Load from the queue?
- if(this._loadQueue) {
- this.load(this._loadQueue);
- this._loadQueue = null;
- }
- // Resize the active image?
- else if(this._resizeAfterTransition) {
- this._resizeAfterTransition = false;
- this._activeImage.resize(this.get('width'), this.get('height'));
- this._nextImage.resize(this.get('width'), this.get('height'));
- }
- },
- /**
- * @method _gesturesMoveStart
- * @param e {Object} The event object.
- * @protected
- */
- _gesturesMoveStart: function(e)
- {
- var index = 0,
- root = this.get('root');
- index = e.direction == 'next' ? root.imageIndex + 1 : root.imageIndex - 1;
- index = index < 0 ? root.albumInfo.images.length - 1 : index;
- index = index >= root.albumInfo.images.length ? 0 : index;
- root.pause();
- root._hideLoadingImage();
- root._showLoadingImageWithDelay();
- Y.FL.SlideshowImageLoader.removeGroup(this._nextImage.get('loadGroup'));
- this._nextImage.once('loadComplete', root._hideLoadingImage, root);
- this._nextImage.load(root.albumInfo.images[index]);
- },
- /**
- * @method _gesturesEndComplete
- * @protected
- */
- _gesturesEndComplete: function()
- {
- var root = this.get('root'),
- index = 0;
- if(this._nextImage._imageInfo){
- index = this._nextImage._imageInfo.index;
- this._swapImageRefs();
- this._imageInfo = root.albumInfo.images[index];
- root.loadImage(index);
- }
- },
- /**
- * @method _swapImageRefs
- * @protected
- */
- _swapImageRefs: function()
- {
- var active = this._activeImage;
- this._activeImage = this._nextImage;
- this._nextImage = active;
- if(this._nextImage._imageInfo) {
- this._nextImage.unload();
- this._nextImage.get('boundingBox').setStyle('left', '-9999px');
- }
- if(this._gestures) {
- this._gestures.set('activeItem', this._activeImage.get('boundingBox'));
- this._gestures.set('nextItem', this._nextImage.get('boundingBox'));
- }
- }
- }, {
- /**
- * Custom CSS class name for the widget.
- * @property CSS_PREFIX
- * @type String
- * @protected
- * @static
- */
- CSS_PREFIX: 'fl-slideshow-frame',
- /**
- * Static property used to define the default attribute configuration of
- * the Widget.
- *
- * @property ATTRS
- * @type Object
- * @protected
- * @static
- */
- ATTRS: {
- /**
- * The configuration object used to create new instances of
- * FL.SlideshowImage. See the API docs for {@link FL.SlideshowImage}
- * for a complete list of configuration attributes.
- *
- * @attribute imageConfig
- * @type Object
- * @default null
- */
- imageConfig: {
- value: null
- },
- /**
- * Whether to use touch gestures, when available,
- * to transition between images or not.
- *
- * @attribute touchSupport
- * @type Boolean
- * @default false
- */
- touchSupport: {
- value: false
- }
- }
- });
- /**
- * A plugin for fullscreen slideshow functionality.
- *
- * @namespace FL
- * @class SlideshowFullscreen
- * @constructor
- * @param config {Object} Configuration object
- * @extends Plugin.Base
- */
- Y.namespace('FL').SlideshowFullscreen = Y.Base.create('fl-slideshow-fullscreen', Y.Plugin.Base, [], {
- /**
- * Flag for whether the slideshow is in
- * fullscreen mode.
- *
- * @property active
- * @type Boolean
- * @default false
- */
- active: false,
- /**
- * A div containing the close message.
- *
- * @property _closeMessage
- * @type Node
- * @default null
- * @protected
- */
- _closeMessage: null,
- /**
- * A timer for hiding the close message.
- *
- * @property _closeMessageTimer
- * @type Object
- * @default null
- * @protected
- */
- _closeMessageTimer: null,
- /**
- * The initial styles of the host's bounding box
- * before entering fullscreen mode.
- *
- * @property _initialStyles
- * @type Object
- * @protected
- */
- _initialStyles: {
- position: 'static',
- top: '0px',
- left: '0px'
- },
- /**
- * @method initializer
- * @protected
- */
- initializer: function()
- {
- var host = this.get('host'),
- bb = host.get('boundingBox'),
- self = this;
- bb.addClass('fl-fullscreen-enabled');
- if(Y.FL.SlideshowFullscreen.OS_SUPPORT) {
- document.addEventListener('fullscreenchange', function(){ self._osChange(); }, false);
- document.addEventListener('mozfullscreenchange', function(){ self._osChange(); }, false);
- document.addEventListener('webkitfullscreenchange', function(){ self._osChange(); }, false);
- }
- else {
- this._renderCloseMessage();
- }
- },
- /**
- * Exits fullscreen if it is currently active
- * otherwise it enters fullscreen.
- *
- * @method toggle
- */
- toggle: function()
- {
- if(this.active) {
- this.exit();
- }
- else {
- this.enter();
- }
- },
- /**
- * Enters OS fullscreen mode if supported, otherwise
- * the slideshow takes over the browser window.
- *
- * @method enter
- */
- enter: function()
- {
- if(Y.FL.SlideshowFullscreen.OS_SUPPORT) {
- this._osEnter();
- }
- else {
- this._browserEnter();
- }
- },
- /**
- * Exits fullscreen mode.
- *
- * @method exit
- */
- exit: function()
- {
- if(Y.FL.SlideshowFullscreen.OS_SUPPORT) {
- this._osExit();
- }
- else {
- this._browserExit();
- }
- },
- /**
- * Enters OS fullscreen mode.
- *
- * @method _osEnter
- * @protected
- */
- _osEnter: function()
- {
- var bbNode = this.get('host').get('boundingBox')._node;
- if(bbNode.webkitRequestFullScreen) {
- bbNode.webkitRequestFullScreen();
- }
- else if(bbNode.mozRequestFullScreen) {
- bbNode.mozRequestFullScreen();
- }
- else if(bbNode.requestFullScreen) {
- bbNode.requestFullScreen();
- }
- },
- /**
- * Exits OS fullscreen mode.
- *
- * @method _osExit
- * @protected
- */
- _osExit: function()
- {
- if(document.exitFullscreen) {
- document.exitFullscreen();
- }
- else if(document.mozCancelFullScreen) {
- document.mozCancelFullScreen();
- }
- else if(document.webkitCancelFullScreen) {
- document.webkitCancelFullScreen();
- }
- },
- /**
- * Called when the OS fullscreenchange event fires and enters
- * or exits standard fullscreen mode which positions and
- * resizes the slideshow.
- *
- * @method _osChange
- * @protected
- */
- _osChange: function()
- {
- var host = this.get('host');
- // Transitions break on Safari while entering and
- // exiting fullscreen. This fixes them!
- if(host.frame && host.frame._transitioning) {
- host.frame._transitionComplete();
- }
- if(this.active) {
- this._exit();
- }
- else {
- this._enter();
- }
- },
- /**
- * Enter browser fullscreen mode.
- *
- * @method _browserEnter
- * @protected
- */
- _browserEnter: function()
- {
- var bb = this.get('host').get('boundingBox');
- this._initialStyles = {
- position: bb.getStyle('position'),
- top: bb.getStyle('top'),
- left: bb.getStyle('left'),
- zIndex: bb.getStyle('zIndex')
- };
- bb.setStyles({
- position: 'fixed',
- top: '0px',
- left: '0px',
- zIndex: 10000
- });
- Y.Node.one('body').on('fl-fullscreen|keydown', Y.bind(this._onKey, this));
- this._showCloseMessage();
- this._enter();
- },
- /**
- * Exit browser fullscreen mode.
- *
- * @method _browserExit
- * @protected
- */
- _browserExit: function()
- {
- var bb = this.get('host').get('boundingBox');
- bb.setStyles({
- position: this._initialStyles.position,
- top: this._initialStyles.top,
- left: this._initialStyles.left,
- zIndex: this._initialStyles.zIndex
- });
- Y.Node.one('body').detach('fl-fullscreen|keydown');
- this._hideCloseMessage();
- this._exit();
- },
- /**
- * Enters fullscreen mode.
- *
- * @method _enter
- * @protected
- */
- _enter: function()
- {
- var host = this.get('host'),
- bb = host.get('boundingBox');
- bb.addClass('fl-fullscreen-active');
- this.active = true;
- host.resize();
- },
- /**
- * Exits fullscreen mode.
- *
- * @method _exit
- * @protected
- */
- _exit: function()
- {
- var host = this.get('host'),
- bb = host.get('boundingBox');
- bb.removeClass('fl-fullscreen-active');
- this.active = false;
- host.resize();
- },
- /**
- * Keyboard input for the esc button.
- *
- * @method _onKey
- * @protected
- */
- _onKey: function(e)
- {
- if(e.keyCode == 27) {
- this.exit();
- return false;
- }
- },
- /**
- * Creates the close message if one is
- * not already available in the document.
- *
- * @method _initCloseMessage
- * @protected
- */
- _renderCloseMessage: function()
- {
- this._closeMessage = Y.Node.create('<div class="fl-fullscreen-close-message"></div>');
- this._closeMessage.set('innerHTML', '<span>Press the "esc" button to exit fullscreen mode.</span>');
- this._closeMessage.setStyle('display', 'none');
- this.get('host').get('boundingBox').insert(this._closeMessage);
- },
- /**
- * Shows the close message.
- *
- * @method _showCloseMessage
- * @protected
- */
- _showCloseMessage: function()
- {
- if(this._closeMessageTimer) {
- this._closeMessageTimer.cancel();
- this._closeMessageTimer = null;
- }
- this._closeMessage.show(true);
- this._closeMessageTimer = Y.later(4000, this, this._hideCloseMessage);
- },
- /**
- * Hides the close message.
- *
- * @method _hideCloseMessage
- * @protected
- */
- _hideCloseMessage: function()
- {
- if(this._closeMessageTimer) {
- this._closeMessageTimer.cancel();
- this._closeMessageTimer = null;
- }
- this._closeMessage.hide(true);
- }
- }, {
- /**
- * Namespace for the plugin.
- *
- * @property NS
- * @type String
- * @protected
- * @static
- */
- NS: 'fullscreen',
- OS_SUPPORT: (function(){
- var doc = document.documentElement;
- return doc.webkitRequestFullScreen || doc.mozRequestFullScreen || doc.requestFullScreen;
- })()
- });
- /**
- * Provides functionality for gesture based transitions
- * between two slideshow components.
- *
- * @namespace FL
- * @class SlideshowGestures
- * @constructor
- * @param config {Object} Configuration object
- * @extends Base
- */
- Y.namespace('FL').SlideshowGestures = Y.Base.create('fl-slideshow-gestures', Y.Base, [], {
- /**
- * The x coordinate for where a gesture event starts.
- *
- * @property _startX
- * @type Number
- * @default null
- * @protected
- */
- _startX: null,
- /**
- * The y coordinate for where a gesture event starts.
- *
- * @property _startY
- * @type Number
- * @default null
- * @protected
- */
- _startY: null,
- /**
- * A flag for whether a gesture is moving or not.
- *
- * @property _moving
- * @type Boolean
- * @default false
- * @protected
- */
- _touchMoving: false,
- /**
- * Whether the gesture is moving or not.
- *
- * @property _moving
- * @type Boolean
- * @default false
- * @protected
- */
- _moving: false,
- /**
- * The direction the current gesture event
- * is moving in (either next or prev).
- *
- * @property _movingDirection
- * @type String
- * @default null
- * @protected
- */
- _movingDirection: null,
- /**
- * A flag for whether a gesture gesture is currently
- * transitioning or not.
- *
- * @property _transitioning
- * @type Boolean
- * @default false
- * @protected
- */
- _transitioning: false,
- /**
- * @method initializer
- * @protected
- */
- initializer: function()
- {
- this.enable();
- },
- /**
- * @method enable
- */
- enable: function()
- {
- var id = this.get('id'),
- direction = this.get('direction'),
- active = this.get('activeItem'),
- next = this.get('nextItem');
- active.on(id + '|gesturemovestart', Y.bind(this._onStart, this));
- next.on(id + '|gesturemovestart', Y.bind(this._onStart, this));
- next.on(id + '|transitionend', Y.bind(this._onEndComplete, this) );
- next.on(id + '|oTransitionEnd', Y.bind(this._onEndComplete, this) );
- next.on(id + '|webkitTransitionEnd', Y.bind(this._onEndComplete, this) );
- if(direction == 'horizontal') {
- active.on(id + '|gesturemovehorizontal', Y.bind(this._onMoveHorizontal, this));
- active.on(id + '|gesturemovehorizontalend', Y.bind(this._onEndHorizontal, this));
- next.on(id + '|gesturemovehorizontal', Y.bind(this._onMoveHorizontal, this));
- next.on(id + '|gesturemovehorizontalend', Y.bind(this._onEndHorizontal, this));
- }
- else {
- active.on(id + '|gesturemovevertical', Y.bind(this._onMoveVertical, this));
- active.on(id + '|gesturemoveverticalend', Y.bind(this._onEndVertical, this));
- next.on(id + '|gesturemovevertical', Y.bind(this._onMoveVertical, this));
- next.on(id + '|gesturemoveverticalend', Y.bind(this._onEndVertical, this));
- }
- },
- /**
- * @method disable
- */
- disable: function()
- {
- var id = this.get('id'),
- active = this.get('activeItem'),
- next = this.get('nextItem');
- active.detach(id + '|*');
- next.detach(id + '|*');
- },
- /**
- * @method _onStart
- * @param e {Object} The event object.
- * @protected
- */
- _onStart: function(e)
- {
- var direction = this.get('direction');
- if(this._transitioning) {
- this._onEndComplete();
- }
- if(direction == 'horizontal') {
- this._startX = e.pageX;
- }
- else {
- this._startY = e.pageY;
- }
- /**
- * @event start
- */
- this.fire('start');
- },
- /**
- * @method _onMoveHorizontal
- * @param e {Object} The event object.
- * @protected
- */
- _onMoveHorizontal: function(e)
- {
- var x = this._startX - e.pageX,
- active = this.get('activeItem'),
- next = this.get('nextItem'),
- width = parseInt(active.getComputedStyle('width'), 10),
- translate = x < 0 ? Math.abs(x) : -x,
- direction = x < 0 ? 'prev' : 'next';
- e.preventDefault();
- if(!this._moving || this._movingDirection != direction) {
- active.setStyle('left', 0);
- next.setStyles({
- 'opacity': 1,
- 'left': x < 0 ? -width : width
- });
- this._moving = true;
- this._movingDirection = direction;
- /**
- * @event moveStart
- */
- this.fire('moveStart', { direction: direction });
- }
- active.setStyle('-webkit-transform', 'translate('+ translate +'px, 0px) translateZ(0px)');
- active.setStyle('-ms-transform', 'translate('+ translate +'px, 0px) translateZ(0px)');
- next.setStyle('-webkit-transform', 'translate('+ translate +'px, 0px) translateZ(0px)');
- next.setStyle('-ms-transform', 'translate('+ translate +'px, 0px) translateZ(0px)');
- /**
- * @event move
- */
- this.fire('move');
- },
- /**
- * @method _onMoveVertical
- * @param e {Object} The event object.
- * @protected
- */
- _onMoveVertical: function(e)
- {
- var y = this._startY - e.pageY,
- active = this.get('activeItem'),
- next = this.get('nextItem'),
- height = parseInt(active.getComputedStyle('height'), 10),
- translate = y < 0 ? Math.abs(y) : -y,
- direction = y < 0 ? 'prev' : 'next';
- e.preventDefault();
- if(!this._moving || this._movingDirection != direction) {
- active.setStyle('top', 0);
- next.setStyles({
- 'opacity': 1,
- 'left' : 'auto',
- 'top': y < 0 ? -height : height
- });
- this._moving = true;
- this._movingDirection = direction;
- /**
- * @event moveStart
- */
- this.fire('moveStart', { direction: direction });
- }
- active.setStyle('-webkit-transform', 'translate(0px, '+ translate +'px) translateZ(0px)');
- active.setStyle('-ms-transform', 'translate(0px, '+ translate +'px) translateZ(0px)');
- next.setStyle('-webkit-transform', 'translate(0px, '+ translate +'px) translateZ(0px)');
- next.setStyle('-ms-transform', 'translate(0px, '+ translate +'px) translateZ(0px)');
- /**
- * @event move
- */
- this.fire('move');
- },
- /**
- * @method _onEndHorizontal
- * @param e {Object} The event object.
- * @protected
- */
- _onEndHorizontal: function(e)
- {
- if(!this._moving) {
- return;
- }
- var x = this._startX - e.pageX,
- active = this.get('activeItem'),
- next = this.get('nextItem'),
- width = parseInt(next.getComputedStyle('width'), 10),
- translate = x < 0 ? width : -width;
- active.transition({
- 'transform': 'translate('+ translate +'px, 0px)'
- });
- next.transition({
- 'transform': 'translate('+ translate +'px, 0px)'
- });
- this._transitioning = true;
- /**
- * @event end
- */
- this.fire('end');
- },
- /**
- * @method _onEndVertical
- * @param e {Object} The event object.
- * @protected
- */
- _onEndVertical: function(e)
- {
- if(!this._moving) {
- return;
- }
- var y = this._startY - e.pageY,
- active = this.get('activeItem'),
- next = this.get('nextItem'),
- height = parseInt(next.getComputedStyle('height'), 10),
- translate = y < 0 ? height : -height;
- active.transition({
- 'transform': 'translate(0px, '+ translate +'px)'
- });
- next.transition({
- 'transform': 'translate(0px, '+ translate +'px)'
- });
- this._transitioning = true;
- /**
- * @event end
- */
- this.fire('end');
- },
- /**
- * @method _onEndComplete
- * @protected
- */
- _onEndComplete: function()
- {
- var direction = this.get('direction'),
- active = this.get('activeItem'),
- next = this.get('nextItem');
- active.setStyles({
- 'opacity': 0,
- '-webkit-transform': '',
- '-webkit-transition': '',
- '-ms-transform': '',
- '-ms-transition': ''
- });
- next.setStyles({
- '-webkit-transform': '',
- '-webkit-transition': '',
- '-ms-transform': '',
- '-ms-transition': ''
- });
- if(direction == 'horizontal') {
- active.setStyle('left', '-9999px');
- next.setStyle('left', '0px');
- }
- else {
- active.setStyle('top', '-9999px');
- next.setStyle('top', '0px');
- }
- this.set('activeItem', next);
- this.set('nextItem', active);
- this._moving = false;
- this._movingDirection = null;
- this._transitioning = false;
- /**
- * @event endComplete
- */
- this.fire('endComplete');
- }
- }, {
- /**
- * Static property used to define the default attribute configuration of
- * the Widget.
- *
- * @property ATTRS
- * @type Object
- * @protected
- * @static
- */
- ATTRS: {
- /**
- * The gesture direction to use. Possible values are
- * horizontal and vertical.
- *
- * @attribute direction
- * @type String
- * @default horizontal
- */
- direction: {
- value: 'horizontal'
- },
- /**
- * The Node that is currently visible.
- *
- * @attribute activeItem
- * @type Node
- * @default null
- */
- activeItem: {
- value: null
- },
- /**
- * The Node that will be transitioned in.
- *
- * @attribute nextItem
- * @type Node
- * @default null
- */
- nextItem: {
- value: null
- }
- }
- });
- /**
- * A load queue for slideshow images.
- *
- * @namespace FL
- * @class SlideshowImageLoader
- * @static
- */
- Y.namespace('FL').SlideshowImageLoader = {
- /**
- * Whether an image is being loaded or not.
- *
- * @property _loading
- * @type Boolean
- * @default false
- * @protected
- */
- _loading: false,
- /**
- * An node for loading the next image.
- *
- * @property _currentImage
- * @type Node
- * @default null
- * @protected
- */
- _currentImage: null,
- /**
- * An object containing the group, src and callback
- * for the current image that is being loaded.
- *
- * @property _currentImageData
- * @type Object
- * @default null
- * @protected
- */
- _currentImageData: null,
- /**
- * An array of image data objects that contain the group,
- * src and callback for each image that will be loaded.
- *
- * @property _queue
- * @type Array
- * @default []
- * @protected
- */
- _queue: [],
- /**
- * Adds an image to the queue.
- *
- * @method add
- * @param group {String} The group this image is associated with.
- * Used to remove images in bulk.
- * @param src {String} The image url to load.
- * @param callback {Function} A function to call when the image
- * has finished loading.
- * @param bump {Boolean} If true, the image will be added to
- * the first position in the queue.
- */
- add: function(group, src, callback, bump)
- {
- var imgData = {
- group : group,
- src : src,
- callback : callback
- };
- if(bump) {
- this._queue.unshift(imgData);
- }
- else {
- this._queue.push(imgData);
- }
- if(!this._loading) {
- this._load();
- }
- },
- /**
- * Removes a group of images from the queue.
- *
- * @method removeGroup
- * @param group {String} The group to remove.
- */
- removeGroup: function(group)
- {
- var i = this._queue.length - 1;
- for( ; i > -1 ; i--) {
- if(this._queue[i].group == group) {
- this._queue.splice(i, 1);
- }
- }
- if(this._currentImageData && this._currentImageData.group == group) {
- this._currentImage.detachAll();
- this._currentImage = null;
- this._currentImageData = null;
- if(this._queue.length > 0) {
- this._load();
- }
- else {
- this._loading = false;
- }
- }
- },
- /**
- * Loads the next image in the queue.
- *
- * @method _load
- * @protected
- */
- _load: function()
- {
- this._loading = true;
- this._currentImageData = this._queue.shift();
- this._currentImage = Y.Node.create('<img />');
- this._currentImage.on('error', Y.bind(this._loadComplete, this));
- this._currentImage.on('load', Y.bind(this._loadComplete, this));
- this._currentImage.set('src', this._currentImageData.src);
- },
- /**
- * Calls the current image's callback function if set
- * and loads the next image if the queue is not empty.
- *
- * @method _loadComplete
- * @protected
- */
- _loadComplete: function()
- {
- if(this._currentImageData.callback) {
- this._currentImageData.callback(this._currentImage);
- }
- if(this._queue.length > 0) {
- this._load();
- }
- else {
- this._loading = false;
- this._currentImage = null;
- this._currentImageData = null;
- }
- }
- };
- /**
- * Loads an image or video using the provided imageInfo object.
- *
- * @namespace FL
- * @class SlideshowImage
- * @constructor
- * @param config {Object} Configuration object
- * @extends Widget
- */
- Y.namespace('FL').SlideshowImage = Y.Base.create('fl-slideshow-image', Y.Widget, [Y.WidgetChild], {
- /**
- * The imageInfo object used to load the image and
- * its various sizes.
- *
- * @property info
- * @type Object
- * @default null
- * @protected
- */
- _imageInfo: null,
- /**
- * A reference to the current image node in the bounding box.
- *
- * @property _image
- * @type Node
- * @default null
- * @protected
- */
- _image: null,
- /**
- * Whether or not new imageInfo is loading.
- *
- * @property _loading
- * @type Boolean
- * @default false
- * @protected
- */
- _loading: false,
- /**
- * The URL that is currently being loaded.
- *
- * @property _loadingURL
- * @type Boolean
- * @default null
- * @protected
- */
- _loadingURL: null,
- /**
- * An anchor node used for the video play button.
- *
- * @property _videoButton
- * @type Node
- * @default null
- * @protected
- */
- _videoButton: null,
- /**
- * A div node used to hold the video iframe.
- *
- * @property _videoBox
- * @type Node
- * @default null
- * @protected
- */
- _videoBox: null,
- /**
- * An iframe node used to render the video.
- *
- * @property _video
- * @type Node
- * @default null
- * @protected
- */
- _video: null,
- /**
- * The default content template for the image
- * inherited from Y.Widget. Set to null since
- * only the bounding box is needed.
- *
- * @property CONTENT_TEMPLATE
- * @type String
- * @default null
- * @protected
- */
- CONTENT_TEMPLATE: null,
- /**
- * Initial styling for the bounding box.
- *
- * @method syncUI
- * @protected
- */
- syncUI: function()
- {
- var bb = this.get('boundingBox');
- if(this.get('crop')) {
- bb.setStyle('overflow', 'hidden');
- bb.addClass('fl-slideshow-image-cropped');
- }
- },
- /**
- * Sets the imageInfo object and
- * loads the appropriate image size.
- *
- * @method load
- * @param imageInfo {Object} The imageInfo object.
- */
- load: function(imageInfo)
- {
- this._imageInfo = imageInfo;
- this._loading = true;
- this._load();
- },
- /**
- * Sets the width and height of the bounding box and
- * preloads an image using the provided imageInfo object.
- *
- * @method preload
- * @param imageInfo {Object} The imageInfo to preload.
- * @param width {Number} The width to preload.
- * @param height {Number} The height to preload.
- */
- preload: function(imageInfo, width, height)
- {
- var isVideo = this._isVideo(),
- loadVideos = this.get('loadVideos'),
- showVideoButton = this.get('showVideoButton');
- this.unload();
- this.set('width', width);
- this.set('height', height);
- this._imageInfo = imageInfo;
- if(!isVideo || !loadVideos || (isVideo && loadVideos && showVideoButton)) {
- Y.FL.SlideshowImageLoader.add(
- this.get('loadGroup'),
- this._getImageURL(),
- Y.bind(this._imagePreloaded, this),
- this.get('loadPriority')
- );
- }
- },
- /**
- * Called when preloading completes.
- *
- * @method _imagePreloaded
- * @param img {Object} The image that was preloaded.
- * @protected
- */
- _imagePreloaded: function(img)
- {
- this._image = img;
- },
- /**
- * Unloads the image if there is one loaded
- * and sets the imageInfo object to null.
- *
- * @method unload
- */
- unload: function()
- {
- if(this._image) {
- this._image.remove();
- this._image.detachAll();
- this._image.set('src', '');
- this._image = null;
- }
- if(this._video) {
- this._video.remove();
- this._video = null;
- }
- if(this._videoButton) {
- this._videoButton.remove();
- this._videoButton = null;
- }
- if(this._videoBox) {
- this._removeVideoBox();
- }
- this._imageInfo = null;
- this._loading = false;
- this._loadingURL = null;
- },
- /**
- * Resizes the bounding box and loads the
- * appropriate image size if necessary.
- *
- * @method resize
- * @param width {Number} The width value.
- * @param height {Number} The height value.
- */
- resize: function(width, height)
- {
- var borderWidth = parseInt(this.get('boundingBox').getComputedStyle('borderTopWidth'), 10) * 2,
- bb = this.get('boundingBox');
- this.set('width', width - borderWidth);
- this.set('height', height - borderWidth);
- bb.setStyle('width', width - borderWidth + 'px');
- bb.setStyle('height', height - borderWidth + 'px');
- if(this._videoButton) {
- this._positionVideoButton();
- }
- if(this._videoBox) {
- this._loadVideo();
- }
- if(!this._loading) {
- if(this._imageInfo) {
- this._load();
- }
- if(this._image) {
- this._positionImage();
- }
- }
- },
- /**
- * Loads (or reloads) the image or video.
- *
- * @method _load
- * @protected
- */
- _load: function()
- {
- var loadVideos = this.get('loadVideos'),
- showVideoButton = this.get('showVideoButton');
- if(this._isVideo() && loadVideos && !showVideoButton && !('ontouchstart' in window)) {
- this._loadVideo();
- }
- else {
- this._loadImage();
- }
- },
- /**
- * Loads the appropriate image size if
- * it is not already loading.
- *
- * @method _loadImage
- * @protected
- */
- _loadImage: function()
- {
- var url = this._getImageURL(),
- loadVideos = this.get('loadVideos');
- // Already loading.
- if(url == this._loadingURL) {
- return;
- }
- // New URL to load.
- this._loadingURL = url;
- // Load the new image.
- Y.FL.SlideshowImageLoader.add(
- this.get('loadGroup'),
- this._loadingURL,
- Y.bind(this._loadImageComplete, this),
- this.get('loadPriority')
- );
- // Initial load?
- if(this._loading) {
- if(this._isVideo() && loadVideos) {
- this._insertVideoButton();
- }
- /**
- * Only fires when a new image is being
- * loaded, not a different size.
- *
- * @event loadStart
- */
- this.fire('loadStart');
- }
- },
- /**
- * Fires when the image has finished loading.
- *
- * @method _loadImageComplete
- * @protected
- */
- _loadImageComplete: function(img)
- {
- var bb = this.get('boundingBox'),
- showVideoButton = this.get('showVideoButton'),
- showAria = this.get('root').get('bgslideshow')
- this._image = img;
- this._image.setStyle('visibility', 'hidden');
- this._image.addClass('fl-slideshow-image-img');
- if( showAria ) {
- this._image.set( 'aria-hidden', 'true')
- this._image.set( 'alt', "")
- }
- else {
- this._image.set( 'alt', this._imageInfo.alt )
- }
- // Remove load events.
- this._image.detachAll();
- // Remove previous videos.
- if(this._video && !showVideoButton) {
- this._video.remove();
- this._video = null;
- }
- // Remove the old image.
- bb.all('img').remove();
- // Append the new image.
- bb.append(this._image);
- // Setup, scale and position the new image.
- this._setupImage();
- this._resizeImage();
- this._positionImage();
- this._image.setStyle('visibility', 'visible');
- // Clear the loading url.
- this._loadingURL = null;
- // Finish an initial load?
- if(this._loading) {
- this._loading = false;
- /**
- * Only fires when a new image is being
- * loaded, not a different size.
- *
- * @event loadComplete
- */
- this.fire('loadComplete');
- }
- },
- /**
- * UI setup for the new image.
- *
- * @method _setupImage
- * @protected
- */
- _setupImage: function()
- {
- var bb = this.get('boundingBox');
- // IE interpolation
- if(typeof this._image._node.style.msInterpolationMode != 'undefined') {
- this._image._node.style.msInterpolationMode = 'bicubic';
- }
- // Protection
- if(this.get('protect')) {
- bb.delegate('contextmenu', this._protectImage, 'img');
- bb.delegate('mousedown', this._protectImage, 'img');
- }
- },
- /**
- * Fires on contextmenu or mousedown in attempt
- * to keep the image from being copied.
- *
- * @method _protectImage
- * @return {Boolean} Returns false to prevent the default event.
- * @protected
- */
- _protectImage: function(e)
- {
- e.preventDefault();
- return false;
- },
- /**
- * Resizes the image node.
- *
- * @method _resizeImage
- * @protected
- */
- _resizeImage: function()
- {
- var borderWidth = parseInt(this._image.getComputedStyle('borderTopWidth'), 10) * 2,
- imageWidth = this._image.get('width'),
- imageHeight = this._image.get('height'),
- targetWidth = parseInt(this.get('boundingBox').getComputedStyle('width'), 10),
- targetHeight = parseInt(this.get('boundingBox').getComputedStyle('height'), 10),
- newWidth = 0,
- newHeight = 0,
- xScale = 0,
- yScale = 0,
- cropHorizontalsOnly = this.get('cropHorizontalsOnly'),
- isHorizontal = imageHeight > imageWidth,
- noCrop = false;
- if(this._imageInfo && this.get('checkFilenamesForNoCrop')) {
- noCrop = this._imageInfo.filename.indexOf('nocrop') > -1;
- }
- if(this.get('crop') && !(cropHorizontalsOnly && isHorizontal) && !noCrop) {
- newWidth = targetWidth;
- newHeight = Math.round(imageHeight * targetWidth/imageWidth);
- if(newHeight < targetHeight) {
- newHeight = targetHeight;
- newWidth = Math.round(imageWidth * targetHeight/imageHeight);
- }
- }
- else {
- xScale = imageWidth/targetWidth;
- yScale = imageHeight/targetHeight;
- if (yScale > xScale){
- newWidth = Math.round(imageWidth * (1/yScale));
- newHeight = Math.round(imageHeight * (1/yScale));
- }
- else {
- newWidth = Math.round(imageWidth * (1/xScale));
- newHeight = Math.round(imageHeight * (1/xScale));
- }
- }
- // Don't resize past the original size?
- if(!this.get('crop') && !this.get('upsize') && (newWidth > imageWidth || newHeight > imageHeight)) {
- newWidth = imageWidth;
- newHeight = imageHeight;
- }
- // Compensate for borders.
- newWidth -= borderWidth;
- newHeight -= borderWidth;
- // Resize the image.
- this._image.setStyle('width', newWidth + 'px');
- this._image.setStyle('height', newHeight + 'px');
- // Constrain bounding box to image size.
- if(!this.get('crop') && this.get('constrainWidth')) {
- this.set('width', newWidth + 'px');
- }
- if(!this.get('crop') && this.get('constrainHeight')) {
- this.set('height', newHeight + 'px');
- }
- },
- /**
- * Positions the image within the bounding box.
- *
- * @method _positionImage
- * @protected
- */
- _positionImage: function()
- {
- var pos = this.get('position').split(' '),
- x = pos[0] === '' ? 'center' : pos[0],
- y = pos[1] === '' ? 'center' : pos[1],
- newX = 0,
- newY = 0,
- bbWidth = parseInt(this.get('boundingBox').getComputedStyle('width'), 10),
- bbHeight = parseInt(this.get('boundingBox').getComputedStyle('height'), 10),
- borderWidth = parseInt(this._image.getComputedStyle('borderTopWidth'), 10) * 2,
- imageWidth = parseInt(this._image.getComputedStyle('width'), 10) + borderWidth,
- imageHeight = parseInt(this._image.getComputedStyle('height'), 10) + borderWidth;
- if(isNaN(imageWidth) && isNaN(imageHeight)) {
- return;
- }
- if(x == 'left') {
- newX = 0;
- }
- if(x == 'center') {
- newX = (bbWidth - imageWidth)/2;
- }
- if(x == 'right') {
- newX = bbWidth - imageWidth;
- }
- if(y == 'top') {
- newY = 0;
- }
- if(y == 'center') {
- newY = (bbHeight - imageHeight)/2;
- }
- if(y == 'bottom') {
- newY = bbHeight - imageHeight;
- }
- this._image.setStyles({
- 'left': newX,
- 'top': newY
- });
- },
- /**
- * Gets the appropriate image url based
- * on the size of the bounding box.
- *
- * @method _getImageURL
- * @return {String} The url to load.
- * @protected
- */
- _getImageURL: function()
- {
- var imageWidth = 0,
- imageHeight = 0,
- size = 0,
- targetWidth = this.get('width'),
- targetHeight = this.get('height'),
- useThumbSizes = this.get('useThumbSizes'),
- i = this._imageInfo,
- sizes = [
- i.tinyURL || i.thumbURL || i.largeURL,
- i.thumbURL || i.largeURL,
- i.smallURL || i.largeURL,
- i.mediumURL || i.largeURL || i.smallURL,
- i.largeURL || i.mediumURL || i.smallURL,
- i.xlargeURL || i.largeURL || i.mediumURL || i.smallURL,
- i.x2largeURL || i.largeURL || i.mediumURL || i.smallURL,
- i.x3largeURL || i.x2largeURL || i.largeURL || i.mediumURL || i.smallURL
- ];
- // Width
- if(useThumbSizes && targetWidth <= 100) {
- imageWidth = 0;
- }
- else if(useThumbSizes && targetWidth <= 150) {
- imageWidth = 1;
- }
- else if(targetWidth <= 400) {
- imageWidth = 2;
- }
- else if(targetWidth >= 400 && targetWidth <= 600) {
- imageWidth = 3;
- }
- else if(targetWidth >= 600 && targetWidth <= 800) {
- imageWidth = 4;
- }
- else if(targetWidth >= 800 && targetWidth <= 1024) {
- imageWidth = 5;
- }
- else if(targetWidth >= 1024 && targetWidth <= 1280) {
- imageWidth = 6;
- }
- else {
- imageWidth = 7;
- }
- // Height
- if(useThumbSizes && targetHeight <= 100) {
- imageHeight = 0;
- }
- else if(useThumbSizes && targetHeight <= 150) {
- imageHeight = 1;
- }
- else if(targetHeight <= 300) {
- imageHeight = 2;
- }
- else if(targetHeight >= 300 && targetHeight <= 450) {
- imageHeight = 3;
- }
- else if(targetHeight >= 450 && targetHeight <= 600) {
- imageHeight = 4;
- }
- else if(targetHeight >= 600 && targetHeight <= 768) {
- imageHeight = 5;
- }
- else if(targetHeight >= 768 && targetHeight <= 960) {
- imageHeight = 6;
- }
- else {
- imageHeight = 7;
- }
- // Get the size number.
- size = Math.max(imageWidth, imageHeight);
- return sizes[size];
- },
- /**
- * Checks whether this is a video or not.
- *
- * @method _isVideo
- * @protected
- */
- _isVideo: function()
- {
- if(!this._imageInfo) {
- return false;
- }
- else if(this._imageInfo.format == 'mp4' && this._imageInfo.sourceType == 'smugmug') {
- return true;
- }
- else if(this._imageInfo.iframe !== '') {
- return true;
- }
- return false;
- },
- /**
- * @method _loadVideo
- * @protected
- */
- _loadVideo: function()
- {
- var bb = this.get('boundingBox'),
- showVideoButton = this.get('showVideoButton'),
- autoPlay = showVideoButton ? true : false;
- // Remove previous videos
- if(this._video) {
- this._video.remove();
- this._video = null;
- }
- // Get the video code
- if(this._imageInfo.format == 'mp4' && this._imageInfo.sourceType == 'smugmug') {
- this._video = this._getSmugMugVideoEmbed(this._imageInfo, autoPlay);
- }
- else if(this._imageInfo.iframe !== '') {
- this._video = this._getIframeVideoEmbed(this._imageInfo, autoPlay);
- }
- // Insert the video
- if(this._videoBox) {
- this._videoBox.one('.fl-slideshow-video-wrap').insert(this._video);
- }
- else {
- bb.all('img').remove();
- bb.append(this._video);
- }
- // Finish an initial load?
- if(this._loading) {
- this._loading = false;
- this.fire('loadComplete');
- }
- },
- /**
- * @method _insertVideoButton
- * @protected
- */
- _insertVideoButton: function()
- {
- var bb = this.get('boundingBox'),
- event = 'ontouchstart' in window ? 'touchstart' : 'click';
- this._videoButton = Y.Node.create('<a class="fl-slideshow-video-button" href="javascript:void(0);"></a>');
- this._videoButton.on(event, Y.bind(this._showVideoBox, this));
- bb.insert(this._videoButton);
- this._positionVideoButton();
- },
- /**
- * @method _positionVideoButton
- * @protected
- */
- _positionVideoButton: function()
- {
- var bbWidth = this.get('width'),
- bbHeight = this.get('height'),
- buttonWidth = parseInt(this._videoButton.getStyle('width'), 10),
- buttonHeight = parseInt(this._videoButton.getStyle('height'), 10);
- this._videoButton.setStyles({
- left: (bbWidth - buttonWidth)/2,
- top: (bbHeight - buttonHeight)/2
- });
- },
- /**
- * @method _showVideoBox
- * @protected
- */
- _showVideoBox: function()
- {
- var root = this.get('root'),
- wrap = Y.Node.create('<div class="fl-slideshow-video-wrap"></div>'),
- close = Y.Node.create('<a class="fl-slideshow-video-close" href="javascript:void(0);"></a>'),
- event = 'ontouchstart' in window ? 'touchstart' : 'click';
- this._videoBox = Y.Node.create('<div class="fl-slideshow-video"></div>');
- this._videoBox.setStyle('padding', root.get('boundingBox').getStyle('padding'));
- this._videoBox.insert(wrap);
- this._videoBox.insert(close);
- this._videoBox.on(event, Y.bind(this._removeVideoBox, this));
- close.on(event, Y.bind(this._removeVideoBox, this));
- if(typeof YUI.Env.mods['sm-fonticon'] !== 'undefined') {
- close.addClass('sm-fonticon sm-fonticon-XCrossEncircled sm-button-skin-default sm-button-nochrome');
- }
- Y.one('body').insert(this._videoBox);
- this._loadVideo();
- Y.one('body').on('fl-slideshow-image|keydown', this._onKey, this);
- },
- /**
- * Get the embed code for a SmugMug video.
- *
- * @method _getSmugMugVideoEmbed
- * @param imageInfo {Object} The image info for the embed.
- * @param autoPlay {Boolean} Whether to auto play videos or not.
- * @protected
- */
- _getSmugMugVideoEmbed: function(imageInfo, autoPlay)
- {
- var test = document.createElement('video'),
- width = 0,
- mp4 = '',
- vars = '',
- code = '';
- if(Y.UA.mobile !== null && !!test.canPlayType && test.canPlayType('video/mp4')) {
- width = this.get('width');
- mp4 = 'https://www.smugmug.com/photos/' + imageInfo.id + '_' + imageInfo.key + '-' + width + '.mp4';
- code += '<video width="100%" height="100%" poster="'+ this._getImageURL() +'" controls preload="none"';
- if(autoPlay) {
- code += ' autoplay';
- }
- code += '>';
- code += '<source src="'+ mp4 +'" type="video/mp4" />';
- code += '</video>';
- }
- else {
- vars = 'imageId=' + imageInfo.id;
- vars += '&imageKey=' + imageInfo.key;
- vars += '&albumId=' + imageInfo.albumId;
- vars += '&albumKey=' + imageInfo.albumKey;
- vars += '&apiURL=https://api.smugmug.com/&hostLevel=live&isPro=true';
- if(autoPlay) {
- vars += '&autoPlay=true';
- }
- else {
- vars += '&autoPlay=false';
- }
- code += '<object type="application/x-shockwave-flash" width="100%" height="100%" data="https://cdn.smugmug.com/img/ria/SmugPlayer/2012102601.swf">';
- code += '<param name="movie" value="https://cdn.smugmug.com/img/ria/SmugPlayer/2012102601.swf">';
- code += '<param name="allowFullScreen" value="true">';
- code += '<param name="wmode" value="transparent">';
- code += '<param name="flashVars" value="' + vars + '">';
- code += '<embed src="https://cdn.smugmug.com/img/ria/SmugPlayer/2012102601.swf" flashvars="'+ vars +'" width="100%" height="100%" type="application/x-shockwave-flash" allowfullscreen="true" wmode="transparent">';
- code += '</object>';
- }
- return Y.Node.create(code);
- },
- /**
- * Get the iframe video embed code.
- *
- * @method _getIframeVideoEmbed
- * @param imageInfo {Object} The image info for the embed.
- * @param autoPlay {Boolean} Whether to auto play videos or not.
- * @protected
- */
- _getIframeVideoEmbed: function(imageInfo, autoPlay)
- {
- var code = '<iframe width="100%" height="100%" allowfullscreen ',
- url = imageInfo.iframe;
- if(autoPlay) {
- url += url.indexOf('?') > -1 ? '&autoplay=1' : '?autoplay=1';
- }
- code += 'src="'+ url +'"></iframe>';
- return Y.Node.create(code);
- },
- /**
- * @method _removeVideoBox
- * @protected
- */
- _removeVideoBox: function(e)
- {
- if(typeof e !== 'undefined' && e.target) {
- if(e.target.get('className').indexOf('fl-slideshow-video') < 0) {
- return;
- }
- }
- if(this._videoBox !== null) {
- this._videoBox.remove();
- this._videoBox = null;
- this._video = null;
- }
- Y.one('body').detach('fl-slideshow-image|keydown', this._onKey);
- },
- /**
- * Keyboard input for the esc button.
- *
- * @method _onKey
- * @protected
- */
- _onKey: function(e)
- {
- if(e.keyCode == 27) {
- this._removeVideoBox();
- return false;
- }
- }
- }, {
- /**
- * Custom CSS class name for the widget.
- * @property CSS_PREFIX
- * @type String
- * @protected
- * @static
- */
- CSS_PREFIX: 'fl-slideshow-image',
- /**
- * Static property used to define the default attribute configuration of
- * the Widget.
- *
- * @property ATTRS
- * @type Object
- * @protected
- * @static
- */
- ATTRS: {
- /**
- * @attribute loadGroup
- * @type String
- * @default none
- */
- loadGroup: {
- value: 'none'
- },
- /**
- * @attribute loadPriority
- * @type Boolean
- * @default false
- */
- loadPriority: {
- value: false
- },
- /**
- * Whether to crop the image.
- *
- * @attribute crop
- * @type Boolean
- * @default false
- */
- crop: {
- value: false
- },
- /**
- * Checks whether the filename has nocrop in it or not.
- * If it does, the image will not be cropped.
- *
- * @attribute checkFilenamesForNoCrop
- * @type Boolean
- * @default true
- */
- checkFilenamesForNoCrop: {
- value: true
- },
- /**
- * Whether to only crop horizontal images or not.
- *
- * @attribute cropHorizontalsOnly
- * @type Boolean
- * @default false
- */
- cropHorizontalsOnly: {
- value: false
- },
- /**
- * The x and y position of the image
- * within the bounding box.
- *
- * @attribute position
- * @type String
- * @default center center
- */
- position: {
- value: 'center center'
- },
- /**
- * Whether to right click protect the image.
- *
- * @attribute protect
- * @type Boolean
- * @default true
- */
- protect: {
- value: true
- },
- /**
- * Whether to resize the image past
- * its original width and height.
- *
- * @attribute upsize
- * @type Boolean
- * @default true
- */
- upsize: {
- value: true
- },
- /**
- * Whether to load thumb sizes. Defaults
- * to false since thumb sizes are square.
- *
- * @attribute useThumbSizes
- * @type Boolean
- * @default false
- */
- useThumbSizes: {
- value: false
- },
- /**
- * Whether to constrain the width of the
- * bounding box to the width of the image.
- *
- * @attribute constrainWidth
- * @type Boolean
- * @default false
- */
- constrainWidth: {
- value: false
- },
- /**
- * Whether to constrain the height of the
- * bounding box to the height of the image.
- *
- * @attribute constrainHeight
- * @type Boolean
- * @default false
- */
- constrainHeight: {
- value: false
- },
- /**
- * Whether to load videos or not. The poster
- * image will be loaded if set to false.
- *
- * @attribute loadVideos
- * @type Boolean
- * @default true
- */
- loadVideos: {
- value: true
- },
- /**
- * Whether to show the video play button or not.
- * When clicked, videos will be displayed in a
- * lightbox instead of the slideshow itself.
- *
- * @attribute showVideoButton
- * @type Boolean
- * @default true
- */
- showVideoButton: {
- value: true
- }
- }
- });
- /**
- * A plugin that turns the cursor into a prev or next arrow when
- * it is over the left or right side of the slideshow.
- *
- * @namespace FL
- * @class SlideshowMouseNav
- * @constructor
- * @param config {Object} Configuration object
- * @extends Plugin.Base
- */
- Y.namespace('FL').SlideshowMouseNav = Y.Base.create('fl-slideshow-mouse-nav', Y.Plugin.Base, [], {
- /**
- * @method initializer
- * @protected
- */
- initializer: function()
- {
- var trigger = this.get('trigger');
- trigger.on('click', this._triggerClick, this);
- trigger.on('mousemove', this._showArrow, this);
- trigger.on('mouseleave', this._hideArrow, this);
- },
- /**
- * @method _triggerClick
- * @protected
- */
- _triggerClick: function(e)
- {
- var host = this.get('host'),
- trigger = this.get('trigger'),
- triggerWidth = parseInt(trigger.getStyle('width'), 10),
- triggerRegion = trigger.get('region'),
- layerX = e.pageX - triggerRegion.left + 5;
- if(layerX >= triggerWidth/2) {
- host.nextImage();
- }
- else {
- host.prevImage();
- }
- },
- /**
- * @method _showArrow
- * @protected
- */
- _showArrow: function(e)
- {
- var host = this.get('host'),
- trigger = this.get('trigger'),
- triggerWidth = parseInt(trigger.getStyle('width'), 10),
- triggerRegion = trigger.get('region'),
- layerX = e.pageX - triggerRegion.left + 5;
- if(host.albumInfo !== null && host.albumInfo.images.length > 1) {
- if(layerX >= triggerWidth/2) {
- trigger.removeClass('fl-slideshow-mouse-nav-prev');
- trigger.addClass('fl-slideshow-mouse-nav-next');
- }
- else {
- trigger.removeClass('fl-slideshow-mouse-nav-next');
- trigger.addClass('fl-slideshow-mouse-nav-prev');
- }
- }
- },
- /**
- * @method _hideArrow
- * @protected
- */
- _hideArrow: function()
- {
- var trigger = this.get('trigger');
- trigger.removeClass('fl-slideshow-mouse-nav-next');
- trigger.removeClass('fl-slideshow-mouse-nav-prev');
- }
- }, {
- /**
- * Namespace for the plugin.
- *
- * @property NS
- * @type String
- * @protected
- * @static
- */
- NS: 'mouseNav',
- /**
- * Static property used to define the default attribute configuration of
- * the Plugin.
- *
- * @property ATTRS
- * @type Object
- * @protected
- * @static
- */
- ATTRS: {
- /**
- * A Node that triggers the arrows.
- *
- * @attribute trigger
- * @type Node
- * @default null
- */
- trigger: {
- value: null
- }
- }
- });
- /**
- * Ken Burns effect for slideshow images.
- *
- * @namespace FL
- * @class SlideshowKenBurns
- * @constructor
- * @param config {Object} Configuration object
- * @extends Base
- */
- Y.namespace('FL').SlideshowKenBurns = Y.Base.create('fl-slideshow-ken-burns', Y.Base, [], {
- /**
- * Runs the Ken Burns effect.
- *
- * @method run
- */
- run: function()
- {
- var imageNode = null,
- transform = null;
- if(Y.FL.Utils.cssSupport('transform')) {
- // Image node
- imageNode = this.get('image').one('img');
- // Transform object
- transform = this._getTransform();
- // Apply the start transform
- imageNode.setStyles({
- '-webkit-transform-origin': transform.origin,
- '-moz-transform-origin': transform.origin,
- '-ms-transform-origin': transform.origin,
- 'transform-origin': transform.origin,
- 'transform': transform.start
- });
- // Transition to the end transform
- imageNode.transition({
- easing: 'ease-out',
- duration : this.get('duration'),
- 'transform' : transform.end
- });
- }
- },
- /**
- * @method _getTransform
- * @protected
- */
- _getTransform: function()
- {
- var zoom = this.get('zoom'),
- image = this.get('image'),
- i = 0,
- zoomDirection = null,
- transform = null;
- // Random zoom direction
- i = Math.floor(Math.random() * Y.FL.SlideshowKenBurns.ZOOM_DIRECTIONS.length);
- zoomDirection = Y.FL.SlideshowKenBurns.ZOOM_DIRECTIONS[i];
- // Random transform
- i = Math.floor(Math.random() * Y.FL.SlideshowKenBurns.TRANSFORMS.length);
- transform = Y.FL.SlideshowKenBurns.TRANSFORMS[i];
- // Get the start and end transforms
- if(!image.hasClass('fl-slideshow-image-cropped') && zoomDirection == 'in') {
- i = Math.floor(Math.random() * 2);
- transform.start = i === 0 ? 'scale(1) translate(100px, 0)' : 'scale(1) translate(-100px, 0)';
- transform.end = 'scale(' + zoom + ') translate(0, 0)';
- transform.origin = 'center center';
- }
- else if(zoomDirection == 'out') {
- transform.start = 'scale(' + zoom + ') ' + transform.translate;
- transform.end = 'scale(1) translate(0, 0)';
- }
- else {
- transform.start = 'scale(1) translate(0, 0)';
- transform.end = 'scale(' + zoom + ') ' + transform.translate;
- }
- return transform;
- }
- }, {
- /**
- * Static property used to define the default attribute configuration of
- * the Widget.
- *
- * @property ATTRS
- * @type Object
- * @protected
- * @static
- */
- ATTRS: {
- /**
- * An instance of FL.Slideshow image to apply the
- * Ken Burns effect on.
- *
- * @attribute image
- * @type FL.Slideshow
- * @default null
- */
- image: {
- value: null
- },
- /**
- * The amount to zoom the image. Zooming
- * in our out is done randomly by this class.
- *
- * @attribute scale
- * @type Number
- * @default 1.2
- */
- zoom: {
- value: 1.2
- },
- /**
- * The duration of the effect in seconds.
- *
- * @attribute duration
- * @type Number
- * @default 2
- */
- duration: {
- value: 2
- }
- },
- /**
- * The zoom directions that can be applied to an image.
- *
- * @property ZOOM_DIRECTIONS
- * @type Object
- * @readOnly
- * @protected
- * @static
- */
- ZOOM_DIRECTIONS: [
- 'in',
- 'out'
- ],
- /**
- * The types of transforms that can be applied to an image.
- *
- * @property TRANSFORMS
- * @type Object
- * @readOnly
- * @protected
- * @static
- */
- TRANSFORMS: [
- {
- origin : 'left top',
- translate : 'translate(-30px, -15px)'
- },{
- origin : 'left center',
- translate : 'translate(-30px, 0)'
- },{
- origin : 'left bottom',
- translate : 'translate(-30px, 15px)'
- },{
- origin : 'right top',
- translate : 'translate(30px, -15px)'
- },{
- origin : 'right center',
- translate : 'translate(30px, 0)'
- },{
- origin : 'right bottom',
- translate : 'translate(30px, 15px)'
- }
- ]
- });
- /**
- * Navigation buttons widget for controlling a slideshow instance
- * and its child widgets.
- *
- * @namespace FL
- * @class SlideshowNav
- * @constructor
- * @param config {Object} Configuration object
- * @extends Widget
- */
- Y.namespace('FL').SlideshowNav = Y.Base.create('fl-slideshow-nav', Y.Widget, [Y.WidgetChild], {
- /**
- * An object containing the anchor nodes for all buttons.
- *
- * @property _buttons
- * @type Object
- * @default null
- * @protected
- */
- _buttons: null,
- /**
- * An div node containing the anchor nodes for the main buttons.
- *
- * @property _buttonsContainer
- * @type Object
- * @default null
- * @protected
- */
- _buttonsContainer: null,
- /**
- * An div node containing the anchor nodes for the left buttons.
- *
- * @property _buttonsLeftContainer
- * @type Object
- * @default null
- * @protected
- */
- _buttonsLeftContainer: null,
- /**
- * An div node containing the anchor nodes for the right buttons.
- *
- * @property _buttonsRightContainer
- * @type Object
- * @default null
- * @protected
- */
- _buttonsRightContainer: null,
- /**
- * Property map for rendering SmugMug font icons.
- *
- * @property _fontIcons
- * @type Object
- * @protected
- */
- _fontIcons: {
- buy: 'Cart',
- caption: 'InfoEncircled',
- close: 'XCrossEncircled',
- fullscreen: 'ScreenExpand',
- next: 'ArrowRight',
- nextPage: 'ArrowRight',
- pause: 'PlayerPause',
- play: 'PlayerPlay',
- prev: 'ArrowLeft',
- prevPage: 'ArrowLeft',
- social: 'Heart',
- thumbs: 'ViewThumbGrid'
- },
- /**
- * The default content template for the nav
- * inherited from Y.Widget. Set to null since
- * only the bounding box is needed.
- *
- * @property CONTENT_TEMPLATE
- * @type String
- * @default null
- * @protected
- */
- CONTENT_TEMPLATE: null,
- /**
- * Renders the buttons.
- *
- * @method renderUI
- * @protected
- */
- renderUI: function()
- {
- this._renderContainers();
- this._renderButtons();
- this._renderFontIcons();
- },
- /**
- * Binds events to the root slideshow for each button.
- *
- * @method bindUI
- * @protected
- */
- bindUI: function()
- {
- var root = this.get('root'),
- id = this.get('id');
- if(this._buttons.prev) {
- this._buttons.prev.on('click', root.prevImage, root);
- }
- if(this._buttons.next) {
- this._buttons.next.on('click', root.nextImage, root);
- }
- if(this._buttons.play) {
- this._buttons.play.on('click', this._playClicked, this);
- root.on(id + '|played', this._showPauseButton, this);
- root.on(id + '|paused', this._showPlayButton, this);
- if(root._playing) {
- this._showPauseButton();
- }
- else {
- this._showPlayButton();
- }
- }
- if(this._buttons.buy) {
- root.on(id + '|albumLoadComplete', this._updateBuy, this);
- if(root.albumInfo !== null) {
- this._updateBuy();
- }
- }
- if(this._buttons.count) {
- root.on(id + '|imageLoadComplete', this._updateCount, this);
- }
- if(this._buttons.thumbs) {
- this._buttons.thumbs.on('click', root._toggleThumbs, root);
- }
- if(this._buttons.caption) {
- root.on(id + '|imageLoadComplete', this._updateCaption, this);
- this._updateCaption();
- }
- if(this._buttons.social) {
- this._buttons.social.on('click', root._toggleSocial, root);
- }
- if(this._buttons.fullscreen && root.fullscreen) {
- this._buttons.fullscreen.on('click', root.fullscreen.toggle, root.fullscreen);
- }
- if(this._buttons.close) {
- this._buttons.close.on('click', root.hide, root);
- }
- },
- /**
- * @method destructor
- * @protected
- */
- destructor: function()
- {
- var root = this.get('root'),
- id = this.get('id');
- root.detach(id + '|*');
- },
- /**
- * Renders the button left, right and main button containers.
- *
- * @method _renderContainers
- * @protected
- */
- _renderContainers: function()
- {
- var cb = this.get('contentBox'),
- buttonsLeft = this.get('buttonsLeft'),
- buttonsRight = this.get('buttonsRight');
- this._buttonsContainer = Y.Node.create('<div></div>');
- this._buttonsContainer.addClass('fl-slideshow-nav-buttons');
- cb.appendChild(this._buttonsContainer);
- if(buttonsLeft.length > 0) {
- this._buttonsLeftContainer = Y.Node.create('<div></div>');
- this._buttonsLeftContainer.addClass('fl-slideshow-nav-buttons-left');
- cb.appendChild(this._buttonsLeftContainer);
- }
- if(buttonsRight.length > 0) {
- this._buttonsRightContainer = Y.Node.create('<div></div>');
- this._buttonsRightContainer.addClass('fl-slideshow-nav-buttons-right');
- cb.appendChild(this._buttonsRightContainer);
- }
- },
- /**
- * Renders the buttons based on the buttons array
- * passed in the configuration object.
- *
- * @method _renderButtons
- * @protected
- */
- _renderButtons: function()
- {
- var name = '',
- i = 0,
- k = 0,
- b = [
- {
- names: this.get('buttons'),
- container: this._buttonsContainer
- },
- {
- names: this.get('buttonsLeft'),
- container: this._buttonsLeftContainer
- },
- {
- names: this.get('buttonsRight'),
- container: this._buttonsRightContainer
- }
- ];
- this._buttons = {};
- for( ; i < b.length; i++) {
- for(k = 0; k < b[i].names.length; k++) {
- name = b[i].names[k];
- if(name.indexOf('count') > -1) {
- this._buttons[name] = Y.Node.create('<span></span>');
- this._updateCount();
- }
- else {
- this._buttons[name] = Y.Node.create('<a href="javascript:void(0);"></a>');
- }
- if(name.indexOf('buy') > -1) {
- this._buttons[name].setStyle('display', 'none');
- }
- this._buttons[name].set('name', name);
- this._buttons[name].set('aria-label', name);
- this._buttons[name].addClass('fl-slideshow-nav-' + name);
- b[i].container.appendChild(this._buttons[name]);
- }
- }
- },
- /**
- * Renders SmugMug font icons for each button.
- *
- * @method _renderFontIcons
- * @protected
- */
- _renderFontIcons: function()
- {
- var name = null;
- if(this.get('useFontIcons') && typeof YUI.Env.mods['sm-fonticon'] !== 'undefined') {
- for(name in this._buttons) {
- if(typeof this._buttons[name] !== 'undefined' && typeof this._fontIcons[name] !== 'undefined') {
- this._buttons[name].addClass('sm-fonticon-' + this._fontIcons[name]);
- this._buttons[name].addClass('sm-fonticon sm-button-skin-default sm-button-nochrome');
- }
- else if(name.indexOf('count') > -1) {
- this._buttons[name].addClass('fonticons-enabled');
- }
- }
- }
- },
- /**
- * Updates the image count.
- *
- * @method _updateCount
- * @protected
- */
- _updateCount: function()
- {
- var html = '',
- countText = Y.FL.SlideshowNav.COUNT_TEXT,
- current = 1,
- total = 1;
- if(this.get('root').albumInfo) {
- current = this.get('root').imageInfo.index + 1;
- total = this.get('root').albumInfo.images.length;
- }
- html = countText.replace('{current}', current).replace('{total}', total);
- this._buttons.count.set('innerHTML', html);
- },
- /**
- * Shows the caption button if the current image
- * has a caption, hides it if the image does not
- * have a caption.
- *
- * @method _updateCaption
- * @protected
- */
- _updateCaption: function()
- {
- var root = this.get('root'),
- imageInfo = root.imageInfo;
- if(imageInfo && imageInfo.caption === '') {
- root.caption.slideshowOverlay.enable();
- root.caption.slideshowOverlay.hide();
- this._buttons.caption.detach('click');
- this._buttons.caption.addClass('fl-slideshow-nav-caption-disabled');
- }
- else {
- this._buttons.caption.on('click', root._toggleCaption, root);
- this._buttons.caption.removeClass('fl-slideshow-nav-caption-disabled');
- }
- },
- /**
- * Checks if buying has been enabled for the current album.
- *
- * @method _updateBuy
- * @protected
- */
- _updateBuy: function()
- {
- var sm = null,
- root = this.get('root'),
- rootSource = root.get('source')[root.albumIndex],
- albumIndex = root.albumIndex,
- source = root.get('source')[albumIndex];
- if(rootSource && rootSource.type == 'smugmug') {
- if(typeof root.albumInfo.printable !== 'undefined') {
- this._updateBuyComplete();
- }
- else {
- sm = new Y.FL.SmugMugAPI();
- sm.addParam('method', 'smugmug.albums.getInfo');
- sm.addParam('AlbumID', source.id);
- sm.addParam('AlbumKey', source.key);
- sm.on('complete', this._updateBuyComplete, this);
- sm.request();
- }
- }
- },
- /**
- * Shows the buy button and updates the buy url
- * if buying has been enabled.
- *
- * @method _updateBuyComplete
- * @param e {Object} The custom event object passed to this function.
- * @protected
- */
- _updateBuyComplete: function(e)
- {
- var root = this.get('root'),
- printable = typeof e == 'undefined' ? root.albumInfo.printable : e.Album.Printable,
- link = root.albumInfo.link;
- if(printable) {
- root.albumInfo.printable = true;
- this._buttons.buy.set('href', 'https://secure.smugmug.com/cart/batchadd/?url=' + encodeURIComponent(link));
- this._buttons.buy.setStyle('display', 'inline-block');
- }
- else {
- root.albumInfo.printable = false;
- this._buttons.buy.setStyle('display', 'none');
- }
- this.fire('resize');
- },
- /**
- * Pauses the slideshow if it is playing and
- * plays the slideshow if it is paused.
- *
- * @method _playClicked
- * @protected
- */
- _playClicked: function()
- {
- var root = this.get('root');
- if(root._playing) {
- root.pause();
- }
- else {
- root.play();
- }
- },
- /**
- * Toggles the button class for the play button
- * so pause is hidden and play is shown.
- *
- * @method _showPlayButton
- * @protected
- */
- _showPlayButton: function()
- {
- this._buttons.play.removeClass('fl-slideshow-nav-pause');
- this._buttons.play.addClass('fl-slideshow-nav-play');
- if(this.get('useFontIcons') && typeof YUI.Env.mods['sm-fonticon'] !== 'undefined') {
- this._buttons.play.removeClass('sm-fonticon-PlayerPause');
- this._buttons.play.addClass('sm-fonticon-PlayerPlay');
- }
- },
- /**
- * Toggles the button class for the play button
- * so pause is shown and play is hidden.
- *
- * @method _showPauseButton
- * @protected
- */
- _showPauseButton: function()
- {
- this._buttons.play.removeClass('fl-slideshow-nav-play');
- this._buttons.play.addClass('fl-slideshow-nav-pause');
- if(this.get('useFontIcons') && typeof YUI.Env.mods['sm-fonticon'] !== 'undefined') {
- this._buttons.play.removeClass('sm-fonticon-PlayerPlay');
- this._buttons.play.addClass('sm-fonticon-PlayerPause');
- }
- }
- }, {
- /**
- * Custom CSS class name for the widget.
- *
- * @property CSS_PREFIX
- * @type String
- * @protected
- * @static
- */
- CSS_PREFIX: 'fl-slideshow-nav',
- /**
- * Static string used for displaying the image count. Use {current}
- * for the current image and {total} for the total number of images.
- * Those placeholders will be replaced when the count node is created.
- *
- * @property COUNT_TEXT
- * @type String
- * @protected
- * @static
- */
- COUNT_TEXT: '{current} of {total}',
- /**
- * Static property used to define the default attribute configuration of
- * the Widget.
- *
- * @property ATTRS
- * @type Object
- * @protected
- * @static
- */
- ATTRS: {
- /**
- * An array of button names that is used to render the main buttons.
- *
- * @attribute buttons
- * @type Array
- * @default []
- * @writeOnce
- */
- buttons: {
- value: [],
- writeOnce: true
- },
- /**
- * An array of button names that is used to render the left buttons.
- *
- * @attribute buttonsLeft
- * @type Array
- * @default []
- * @writeOnce
- */
- buttonsLeft: {
- value: [],
- writeOnce: true
- },
- /**
- * An array of button names that is used to render the right buttons.
- *
- * @attribute buttonsRight
- * @type Array
- * @default []
- * @writeOnce
- */
- buttonsRight: {
- value: [],
- writeOnce: true
- },
- /**
- * Whether to use font icons when available.
- *
- * @attribute useFontIcons
- * @type Boolean
- * @default true
- * @writeOnce
- */
- useFontIcons: {
- value: true,
- writeOnce: true
- }
- }
- });
- /**
- * A plugin for overlaying widgets in a slideshow
- * with specialized show and hide functionality.
- *
- * @namespace FL
- * @class SlideshowOverlay
- * @constructor
- * @param config {Object} Configuration object
- * @extends Plugin.Base
- */
- Y.namespace('FL').SlideshowOverlay = Y.Base.create('fl-slideshow-overlay', Y.Plugin.Base, [], {
- /**
- * Flag for whether the mouse has entered
- * the host's bounding box.
- *
- * @property _focus
- * @type Boolean
- * @default false
- * @protected
- */
- _focus: false,
- /**
- * Flag for whether the host's bounding box is visible.
- *
- * @property _visible
- * @type Boolean
- * @default true
- * @protected
- */
- _visible: true,
- /**
- * Flag for whether show and hide functionality
- * has been disabled.
- *
- * @property _disabled
- * @type Boolean
- * @default false
- * @protected
- */
- _disabled: false,
- /**
- * An object containing properties for the show transition.
- *
- * @property _showProps
- * @type Object
- * @protected
- */
- _showProps: {
- duration: 0.5,
- easing: 'ease-out',
- opacity: 1
- },
- /**
- * An object containing properties for the hide transition.
- *
- * @property _hideProps
- * @type Object
- * @protected
- */
- _hideProps: {
- duration: 0.5,
- easing: 'ease-out',
- opacity: 0
- },
- /**
- * A timer object for delaying the hide transition.
- *
- * @property _hideTimer
- * @type Object
- * @default null
- * @protected
- */
- _hideTimer: null,
- /**
- * @method initializer
- * @protected
- */
- initializer: function()
- {
- var bb = this.get('host').get('boundingBox');
- this.afterHostEvent('render', this._initFocus);
- this.afterHostEvent('render', this._initVisibility);
- if(this.get('closeButton')) {
- this._initCloseButton();
- }
- bb.addClass('fl-slideshow-overlay');
- },
- /**
- * @method destructor
- * @protected
- */
- destructor: function()
- {
- this._hideTimerCancel();
- },
- /**
- * Binds the mouseenter and mouseleave events for setting focus.
- *
- * @method _initFocus
- * @protected
- */
- _initFocus: function()
- {
- var bb = this.get('host').get('boundingBox');
- bb.on('mouseenter', Y.bind(this._setFocusOnMouseenter, this));
- bb.on('mouseleave', Y.bind(this._setFocusOnMouseleave, this));
- },
- /**
- * Sets the initial visibility of the host's bounding box.
- *
- * @method _initVisibility
- * @protected
- */
- _initVisibility: function()
- {
- var bb = this.get('host').get('boundingBox'),
- hideStyle = this.get('hideStyle');
- if(!this.get('visible')) {
- if(hideStyle == 'display') {
- bb.setStyle('display', 'none');
- }
- else if(hideStyle == 'left') {
- bb.setStyle('left', '-99999px');
- }
- bb.setStyle('opacity', '0');
- this._visible = false;
- }
- },
- /**
- * Creates and inserts the close button.
- *
- * @method _initCloseButton
- * @protected
- */
- _initCloseButton: function()
- {
- var bb = this.get('host').get('boundingBox'),
- closeButton = null;
- closeButton = Y.Node.create('<a class="fl-slideshow-overlay-close" href="javascript:void(0);"></a>');
- closeButton.on('click', Y.bind(this._closeButtonClick, this));
- if(typeof YUI.Env.mods['sm-fonticon'] !== 'undefined') {
- closeButton.addClass('sm-fonticon sm-fonticon-XCrossEncircled sm-button-skin-default sm-button-nochrome');
- }
- bb.insert(closeButton);
- },
- /**
- * Hides the overlay when the close button is clicked.
- *
- * @method _closeButtonClick
- * @protected
- */
- _closeButtonClick: function()
- {
- var bb = this.get('host').get('boundingBox');
- bb.transition(this._hideProps, Y.bind(this._hideComplete, this));
- },
- /**
- * Sets the focus flag to true.
- *
- * @method _setFocusOnMouseenter
- * @protected
- */
- _setFocusOnMouseenter: function()
- {
- this._focus = true;
- },
- /**
- * Sets the focus flag to false.
- *
- * @method _setFocusOnMouseleave
- * @protected
- */
- _setFocusOnMouseleave: function()
- {
- this._focus = false;
- },
- /**
- * Disables show and hide functionality.
- *
- * @method disable
- * @public
- */
- disable: function()
- {
- this._disabled = true;
- },
- /**
- * Enables show and hide functionality.
- *
- * @method enable
- * @public
- */
- enable: function()
- {
- this._disabled = false;
- },
- /**
- * Shows the host's bounding box with a fade in transition.
- *
- * @method show
- * @public
- */
- show: function()
- {
- var bb = this.get('host').get('boundingBox'),
- hideStyle = this.get('hideStyle');
- if(this._disabled) {
- return;
- }
- if(hideStyle == 'display') {
- bb.setStyle('display', 'block');
- }
- else if(hideStyle == 'left') {
- bb.setStyle('left', 'auto');
- }
- bb.transition(this._showProps, Y.bind(this._showComplete, this));
- /**
- * @event hideStart
- */
- this.fire('showStart');
- },
- /**
- * @method _showComplete
- * @protected
- */
- _showComplete: function()
- {
- this._visible = true;
- this.hideWithTimer();
- /**
- * @event showComplete
- */
- this.fire('showComplete');
- },
- /**
- * Hides the host's bounding box with a fade out transition.
- *
- * @method hide
- * @public
- */
- hide: function()
- {
- if(this._focus || this._disabled) {
- return;
- }
- var bb = this.get('host').get('boundingBox');
- bb.transition(this._hideProps, Y.bind(this._hideComplete, this));
- /**
- * @event hideStart
- */
- this.fire('hideStart');
- },
- /**
- * Hides the host's bounding box with a fade out transition
- * after a timer completes.
- *
- * @method hideWithTimer
- * @public
- */
- hideWithTimer: function()
- {
- this._hideTimerCancel();
- this._hideTimer = Y.later(this.get('hideDelay'), this, this.hide);
- },
- /**
- * Cancels the hide timer.
- *
- * @method _hideTimerCancel
- * @protected
- */
- _hideTimerCancel: function()
- {
- if(this._hideTimer) {
- this._hideTimer.cancel();
- this._hideTimer = null;
- }
- },
- /**
- * @method _hideComplete
- * @protected
- */
- _hideComplete: function()
- {
- var bb = this.get('host').get('boundingBox'),
- hideStyle = this.get('hideStyle');
- if(hideStyle == 'display') {
- bb.setStyle('display', 'none');
- }
- else if(hideStyle == 'left') {
- bb.setStyle('left', '-99999px');
- }
- this._visible = false;
- /**
- * @event hideComplete
- */
- this.fire('hideComplete');
- }
- }, {
- /**
- * Namespace for the plugin.
- *
- * @property NS
- * @type String
- * @protected
- * @static
- */
- NS: 'slideshowOverlay',
- /**
- * Static property used to define the default attribute configuration of
- * the plugin.
- *
- * @property ATTRS
- * @type Object
- * @protected
- * @static
- */
- ATTRS: {
- /**
- * Whether to use the close button or not.
- *
- * @attribute closeButton
- * @type Boolean
- * @default false
- * @writeOnce
- */
- closeButton: {
- value: false,
- writeOnce: true
- },
- /**
- * The time to wait before hiding the host's bounding box.
- * Measured in milliseconds.
- *
- * @attribute hideDelay
- * @type Number
- * @default 3000
- * @writeOnce
- */
- hideDelay: {
- value: 3000,
- writeOnce: true
- },
- /**
- * The style to use for hiding the image. Possible
- * values are display and left.
- *
- * @attribute hideStyle
- * @type String
- * @default display
- * @writeOnce
- */
- hideStyle: {
- value: 'display',
- writeOnce: true
- },
- /**
- * Sets the initial visibility of the host's boudning box.
- *
- * @attribute visible
- * @type Boolean
- * @default true
- * @writeOnce
- */
- visible: {
- value: true,
- writeOnce: true
- }
- }
- });
- /**
- * Social buttons widget used in slideshows.
- *
- * @namespace FL
- * @class SlideshowSocial
- * @constructor
- * @param config {Object} Configuration object
- * @extends Widget
- */
- Y.namespace('FL').SlideshowSocial = Y.Base.create('fl-slideshow-social', Y.Widget, [Y.WidgetChild], {
- /**
- * An object containing the social button nodes.
- *
- * @property _buttons
- * @type Object
- * @default null
- * @protected
- */
- _buttons: null,
- /**
- * @method renderUI
- * @protected
- */
- renderUI: function()
- {
- this._buttons = {};
- },
- /**
- * @method bindUI
- * @protected
- */
- bindUI: function()
- {
- var root = this.get('root');
- if(root.get('likeButtonEnabled')) {
- root.on('imageLoadComplete', Y.bind(this._updateLikeButton, this));
- }
- if(root.get('tweetButtonEnabled')) {
- root.on('imageLoadComplete', Y.bind(this._updateTweetButton, this));
- }
- if(root.get('pinterestButtonEnabled')) {
- root.on('imageLoadComplete', Y.bind(this._updatePinterestButton, this));
- }
- },
- /**
- * @method _updateLikeButton
- * @protected
- */
- _updateLikeButton: function()
- {
- var src = null,
- cb = this.get('contentBox'),
- root = this.get('root'),
- albumIndex = root.albumIndex,
- rootSource = root.get('source')[albumIndex],
- imageInfo = root.imageInfo;
- if(this._buttons.like) {
- this._buttons.like.remove();
- this._buttons.like = null;
- }
- if(rootSource.type == 'smugmug') {
- src = 'https://www.facebook.com/plugins/like.php?';
- src += 'href=' + 'https://www.smugmug.com/services/graph/gallery/';
- src += rootSource.id + '_' + rootSource.key +'/' + imageInfo.id + '_' + imageInfo.key;
- }
- else {
- src = 'https://www.facebook.com/plugins/like.php?';
- src += 'href=' + encodeURIComponent(imageInfo.largeURL);
- }
- src += '&send=false';
- src += '&layout=button_count';
- src += '&width=90';
- src += '&show_faces=false';
- src += '&action=like';
- src += '&colorscheme=light';
- src += '&height=21';
- this._buttons.like = Y.Node.create('<iframe src="'+ src +'" scrolling="no" allowTransparency="true"></iframe>');
- this._buttons.like.setStyles({
- overflow: 'hidden',
- width: '90px',
- height: '21px'
- });
- cb.appendChild(this._buttons.like);
- },
- /**
- * @method _updateTweetButton
- * @protected
- */
- _updateTweetButton: function()
- {
- var src = null,
- imageInfo = this.get('root').imageInfo,
- cb = this.get('contentBox');
- if(this._buttons.tweet) {
- this._buttons.tweet.remove();
- this._buttons.tweet = null;
- }
- src = 'https://platform.twitter.com/widgets/tweet_button.html?';
- src += 'url=' + encodeURIComponent(imageInfo.largeURL);
- src += '&count=none';
- this._buttons.tweet = Y.Node.create('<iframe src="'+ src +'" scrolling="no" allowTransparency="true"></iframe>');
- this._buttons.tweet.setStyles({
- overflow: 'hidden',
- width: '90px',
- height: '21px'
- });
- cb.appendChild(this._buttons.tweet);
- },
- /**
- * @method _updatePinterestButton
- * @protected
- */
- _updatePinterestButton: function()
- {
- var href = 'https://pinterest.com/pin/create/button/',
- imageInfo = this.get('root').imageInfo,
- cb = this.get('contentBox');
- if(this._buttons.pin) {
- this._buttons.pin.remove();
- this._buttons.pin = null;
- }
- href += '?url=' + encodeURIComponent(window.location.href);
- href += '&media='+ encodeURIComponent(imageInfo.mediumURL);
- href += '&description='+ encodeURIComponent(imageInfo.caption);
- this._buttons.pin = Y.Node.create('<a></a>');
- this._buttons.pin.setAttribute('data-pin-config', 'none');
- this._buttons.pin.setAttribute('data-pin-do', 'buttonPin');
- this._buttons.pin.setAttribute('href', href);
- this._buttons.pin.setAttribute('target', '_blank');
- this._buttons.pin.set('innerHTML', '<img src="https://assets.pinterest.com/images/pidgets/pin_it_button.png" border="0" />');
- cb.appendChild(this._buttons.pin);
- }
- }, {
- /**
- * Custom CSS class name for the widget.
- *
- * @property CSS_PREFIX
- * @type String
- * @protected
- * @static
- */
- CSS_PREFIX: 'fl-slideshow-social',
- /**
- * Static property used to define the default attribute configuration of
- * the Widget.
- *
- * @property ATTRS
- * @type Object
- * @protected
- * @static
- */
- ATTRS: {
- }
- });
- /**
- * Creates a grid of FL.SlideshowImage instances.
- *
- * @namespace FL
- * @class SlideshowThumbs
- * @constructor
- * @param config {Object} Configuration object
- * @extends Widget
- */
- Y.namespace('FL').SlideshowThumbs = Y.Base.create('fl-slideshow-thumbs', Y.Widget, [Y.WidgetParent, Y.WidgetChild], {
- /**
- * A div node used to hide the overflow when
- * transitioning between pages.
- *
- * @property _clipBox
- * @type Object
- * @default null
- * @protected
- */
- _clipBox: null,
- /**
- * A div node used to hold the pages.
- *
- * @property _pagesBox
- * @type Object
- * @default null
- * @protected
- */
- _pagesBox: null,
- /**
- * A reference to the active page div node. Holds a grid
- * of FL.SlideshowImage instances.
- *
- * @property _activePageBox
- * @type Object
- * @default null
- * @protected
- */
- _activePageBox: null,
- /**
- * The index of the active page of thumbs.
- *
- * @property _activePageIndex
- * @type Number
- * @default 0
- * @protected
- */
- _activePageIndex: 0,
- /**
- * A reference to the next page div node. Holds a grid
- * of FL.SlideshowImage instances.
- *
- * @property _nextPageBox
- * @type Object
- * @default null
- * @protected
- */
- _nextPageBox: null,
- /**
- * An array of FL.SlideshowImage instances in the active page.
- *
- * @property _activeImages
- * @type Array
- * @default null
- * @protected
- */
- _activeImages: null,
- /**
- * An array of FL.SlideshowImage instances used to
- * preload the next page of images.
- *
- * @property _nextImages
- * @type Array
- * @default null
- * @protected
- */
- _nextImages: null,
- /**
- * An array of FL.SlideshowImage instances used to
- * preload the previous page of images.
- *
- * @property _prevImages
- * @type Array
- * @default null
- * @protected
- */
- _prevImages: null,
- /**
- * An instance of FL.SlideshowNav used for the left nav.
- *
- * @property _leftNav
- * @type Object
- * @default null
- * @protected
- */
- _leftNav: null,
- /**
- * An instance of FL.SlideshowNav used for the right nav.
- *
- * @property _rightNav
- * @type Object
- * @default null
- * @protected
- */
- _rightNav: null,
- /**
- * An instance of FL.SlideshowNav used for the top nav.
- *
- * @property _topNav
- * @type Object
- * @default null
- * @protected
- */
- _topNav: null,
- /**
- * An instance of FL.SlideshowNav used for the bottom nav.
- *
- * @property _bottomNav
- * @type Object
- * @default null
- * @protected
- */
- _bottomNav: null,
- /**
- * Height of the bounding box.
- *
- * @property _bbHeight
- * @type Number
- * @default 0
- * @protected
- */
- _bbHeight: 0,
- /**
- * Width of the bounding box.
- *
- * @property _bbWidth
- * @type Number
- * @default 0
- * @protected
- */
- _bbWidth: 0,
- /**
- * Width of the content box.
- *
- * @property _cbWidth
- * @type Number
- * @default 0
- * @protected
- */
- _cbWidth: 0,
- /**
- * Left margin of the clip box.
- *
- * @property _clipBoxMarginLeft
- * @type Number
- * @default 0
- * @protected
- */
- _clipBoxMarginLeft: 0,
- /**
- * Top position of the clip box.
- *
- * @property _clipBoxTop
- * @type Number
- * @default 0
- * @protected
- */
- _clipBoxTop: 0,
- /**
- * The number of columns per page.
- *
- * @property _colsPerPage
- * @type Number
- * @default 0
- * @protected
- */
- _colsPerPage: 0,
- /**
- * The number of rows per page.
- *
- * @property _rowsPerPage
- * @type Number
- * @default 0
- * @protected
- */
- _rowsPerPage: 0,
- /**
- * The number of images per page.
- *
- * @property _imagesPerPage
- * @type Number
- * @default 0
- * @protected
- */
- _imagesPerPage: 0,
- /**
- * The number of pages.
- *
- * @property _numPages
- * @type Number
- * @default 0
- * @protected
- */
- _numPages: 0,
- /**
- * Height of the pages.
- *
- * @property _pageHeight
- * @type Number
- * @default 0
- * @protected
- */
- _pageHeight: 0,
- /**
- * Width of the pages.
- *
- * @property _pageWidth
- * @type Number
- * @default 0
- * @protected
- */
- _pageWidth: 0,
- /**
- * The horizontal spacing between thumbs.
- *
- * @property _horizontalSpacing
- * @type Number
- * @default 0
- * @protected
- */
- _horizontalSpacing: 0,
- /**
- * The vertical spacing between thumbs.
- *
- * @property _verticalSpacing
- * @type Number
- * @default 0
- * @protected
- */
- _verticalSpacing: 0,
- /**
- * Width of the left nav.
- *
- * @property _leftNavWidth
- * @type Number
- * @default 0
- * @protected
- */
- _leftNavWidth: 0,
- /**
- * Width of the right nav.
- *
- * @property _rightNavWidth
- * @type Number
- * @default 0
- * @protected
- */
- _rightNavWidth: 0,
- /**
- * An instance of FL.SlideshowTransition for the current transition.
- *
- * @property _transition
- * @type FL.SlideshowTransition
- * @default null
- * @protected
- */
- _transition: null,
- /**
- * Whether the pages are currently transitioning or not.
- *
- * @property _verticalSpacing
- * @type Boolean
- * @default false
- * @protected
- */
- _transitioning: false,
- /**
- * Direction of the current transition.
- *
- * @property _transitionDirection
- * @type String
- * @default next
- * @protected
- */
- _transitionDirection: 'next',
- /**
- * Provides functionality for gesture based transitions
- * between the active and next pages.
- *
- * @property _gestures
- * @type FL.SlideshowGestures
- * @default null
- * @protected
- */
- _gestures: null,
- /**
- * Initialize image vars.
- *
- * @method initializer
- * @protected
- */
- initializer: function()
- {
- this._activeImages = [];
- this._nextImages = [];
- this._prevImages = [];
- },
- /**
- * Renders the UI boxes.
- *
- * @method renderUI
- * @protected
- */
- renderUI: function()
- {
- this._renderBoxes();
- this._renderNavs();
- },
- /**
- * Binds the UI events.
- *
- * @method bindUI
- * @protected
- */
- bindUI: function()
- {
- var root = this.get('root'),
- id = this.get('id'),
- transition = this.get('transition');
- root.on(id + '|albumLoadComplete', this._albumLoadComplete, this);
- if('ontouchstart' in window && this.get('touchSupport')) {
- this._gestures = new Y.FL.SlideshowGestures({
- direction: transition == 'slideVertical' ? 'vertical' : 'horizontal',
- activeItem: this._activePageBox,
- nextItem: this._nextPageBox
- });
- this._gestures.on('moveStart', this._gesturesMoveStart, this);
- this._gestures.on('endComplete', this._gesturesEndComplete, this);
- }
- },
- /**
- * Syncs the UI boxes.
- *
- * @method syncUI
- * @protected
- */
- syncUI: function()
- {
- this._syncBoxes();
- this._syncNavs();
- },
- /**
- * @method destructor
- * @protected
- */
- destructor: function()
- {
- var root = this.get('root'),
- id = this.get('id');
- root.detach(id + '|*');
- Y.FL.SlideshowImageLoader.removeGroup('thumbs');
- },
- /**
- * Unload all images.
- *
- * @method unload
- */
- unload: function()
- {
- var root = this.get('root'),
- id = this.get('id'),
- i = 0;
- root.detach(id + '|imageLoadComplete');
- Y.FL.SlideshowImageLoader.removeGroup('thumbs');
- for( ; i < this._activeImages.length; i++) {
- this._activeImages[i].unload();
- }
- },
- /**
- * Resizes the UI boxes.
- *
- * @method resize
- */
- resize: function()
- {
- this._setSizeInfo();
- this._togglePageButtons();
- this._resizeBoxes();
- this._resizeNavs();
- if(this.get('root').albumInfo) {
- Y.FL.SlideshowImageLoader.removeGroup('thumbs');
- this._renderActivePage();
- this._preloadNextPage();
- this._preloadPrevPage();
- }
- // Enable or disable gestures.
- if(this._gestures && this._numPages < 2) {
- this._gestures.disable();
- }
- else if(this._gestures) {
- this._gestures.enable();
- }
- },
- /**
- * Transitions to the previous page.
- *
- * @method prevPage
- * @protected
- */
- prevPage: function()
- {
- if(this._transitioning) {
- return;
- }
- this._transitionStart('prev');
- },
- /**
- * Transitions to the next page.
- *
- * @method nextPage
- * @protected
- */
- nextPage: function()
- {
- if(this._transitioning) {
- return;
- }
- this._transitionStart('next');
- },
- /**
- * Called when an album is loaded into the root slideshow widget.
- *
- * @method _albumLoadComplete
- * @protected
- */
- _albumLoadComplete: function()
- {
- var root = this.get('root'),
- id = this.get('id');
- root.once(id + '|imageLoadComplete', this.resize, this);
- root.on(id + '|imageLoadComplete', this._imageLoadComplete, this);
- },
- /**
- * Called when an image is loaded into the root slideshow widget.
- *
- * @method _imageLoadComplete
- * @protected
- */
- _imageLoadComplete: function()
- {
- var albumInfo = this.get('root').albumInfo,
- lastActive = Y.one('.fl-slideshow-image-active'),
- lastInfo = lastActive ? lastActive._imageInfo : null,
- nextActive = null,
- nextInfo = this.get('root').imageInfo;
- this._setActiveImage(this._activeImages);
- nextActive = Y.one('.fl-slideshow-image-active');
- if(lastActive && !nextActive) {
- if(nextInfo.index === 0 && lastInfo.index === albumInfo.images.length - 1) {
- this.nextPage();
- }
- else if(lastInfo.index === 0 && nextInfo.index === albumInfo.images.length - 1) {
- this.prevPage();
- }
- else if(lastInfo.index < nextInfo.index) {
- this.nextPage();
- }
- else if(lastInfo.index > nextInfo.index) {
- this.prevPage();
- }
- }
- },
- /**
- * Renders the boxes.
- *
- * @method _renderBoxes
- * @protected
- */
- _renderBoxes: function()
- {
- // Clip box
- this._clipBox = Y.Node.create('<div></div>');
- this._clipBox.addClass('fl-slideshow-thumbs-clip');
- this.get('contentBox').insert(this._clipBox);
- // Pages box
- this._pagesBox = Y.Node.create('<div></div>');
- this._pagesBox.addClass('fl-slideshow-thumbs-pages');
- this._clipBox.insert(this._pagesBox);
- // Active page box
- this._activePageBox = Y.Node.create('<div></div>');
- this._activePageBox.addClass('fl-slideshow-thumbs-page');
- this._pagesBox.insert(this._activePageBox);
- // Next page box
- this._nextPageBox = Y.Node.create('<div></div>');
- this._nextPageBox.addClass('fl-slideshow-thumbs-page');
- this._pagesBox.insert(this._nextPageBox);
- },
- /**
- * Syncs the boxes.
- *
- * @method _syncBoxes
- * @protected
- */
- _syncBoxes: function()
- {
- // Active page box
- this._activePageBox.setStyle('left', '0');
- // Next page box
- this._nextPageBox.setStyle('left', '-9999px');
- },
- /**
- * Resizes the boxes.
- *
- * @method _resizeBoxes
- * @protected
- */
- _resizeBoxes: function()
- {
- this.set('width', this._bbWidth);
- this.set('height', this._bbHeight);
- this.get('contentBox').setStyle('width', this._cbWidth + 'px');
- this._clipBox.setStyle('width', this._pageWidth + 'px');
- this._clipBox.setStyle('height', this._pageHeight + 'px');
- this._clipBox.setStyle('padding', this._verticalSpacing + 'px 0 0 ' + this._horizontalSpacing + 'px ');
- this._clipBox.setStyle('margin', '0 0 0 ' + this._clipBoxMarginLeft + 'px');
- this._clipBox.setStyle('top', this._clipBoxTop);
- this._pagesBox.setStyle('width', this._pageWidth + 'px');
- this._pagesBox.setStyle('height', this._pageHeight + 'px');
- this._activePageBox.setStyle('width', this._pageWidth + 'px');
- this._activePageBox.setStyle('height', this._pageHeight + 'px');
- this._nextPageBox.setStyle('width', this._pageWidth + 'px');
- this._nextPageBox.setStyle('height', this._pageHeight + 'px');
- },
- /**
- * Renders the active page of images.
- *
- * @method _renderActivePage
- * @protected
- */
- _renderActivePage: function()
- {
- var i = 0,
- root = this.get('root'),
- imageIndex = this._imagesPerPage * this._activePageIndex,
- endIndex = imageIndex + this._imagesPerPage,
- images = root.albumInfo.images;
- this._clearActiveImage();
- // Remove current images
- for( ; i < this._activeImages.length; i++) {
- this._activeImages[i].remove();
- this._activeImages[i].unload();
- this._activeImages[i].get('boundingBox')._imageInfo = null;
- this._activeImages[i].get('boundingBox').remove();
- }
- // Draw images
- for(i = 0; imageIndex < endIndex; imageIndex++) {
- if(!images[imageIndex]) {
- break;
- }
- this._renderImage(this._activeImages, i, this._activePageBox, images[imageIndex]);
- i++;
- }
- this._setActiveImage(this._activeImages);
- },
- /**
- * Renders the next page of images.
- *
- * @method _renderNextPage
- * @protected
- */
- _renderNextPage: function()
- {
- var i = 0,
- imageArray = this._transitionDirection == 'next' ? this._nextImages : this._prevImages;
- this._nextPageBox.get('children').remove();
- for( ; i < imageArray.length; i++) {
- if(imageArray[i]._imageInfo) {
- this._renderImage(imageArray, i, this._nextPageBox, imageArray[i]._imageInfo);
- }
- else {
- break;
- }
- }
- this._setActiveImage(imageArray);
- },
- /**
- * Preloads the next page of images.
- *
- * @method _preloadNextPage
- * @protected
- */
- _preloadNextPage: function()
- {
- var pageIndex = this._activePageIndex + 1 >= this._numPages ? 0 : this._activePageIndex + 1;
- this._preloadPage(pageIndex, this._nextImages);
- },
- /**
- * Preloads the previous page of images.
- *
- * @method _preloadPrevPage
- * @protected
- */
- _preloadPrevPage: function()
- {
- var pageIndex = this._activePageIndex - 1 < 0 ? this._numPages - 1 : this._activePageIndex - 1;
- this._preloadPage(pageIndex, this._prevImages);
- },
- /**
- * Preloads a page of images.
- *
- * @method _preloadPage
- * @param imageIndex {Number} The image index to start preloading from.
- * @param imageArray {Array} The array to store the preloaded images.
- * @protected
- */
- _preloadPage: function(pageIndex, imageArray)
- {
- var i = 0,
- root = this.get('root'),
- images = root.albumInfo.images,
- imageIndex = pageIndex * this._imagesPerPage,
- endIndex = imageIndex + this._imagesPerPage,
- imageConfig = this.get('imageConfig'),
- width = imageConfig.width,
- height = imageConfig.height;
- if(this._numPages > 1) {
- // Unload existing images
- for( ; i < imageArray.length; i++) {
- imageArray[i].remove();
- imageArray[i].unload();
- }
- // Preload the images
- for(i = 0; imageIndex < endIndex; imageIndex++) {
- if(!images[imageIndex]) {
- continue;
- }
- this._renderImage(imageArray, i);
- imageArray[i].preload(images[imageIndex], width, height);
- i++;
- }
- }
- },
- /**
- * Renders an image.
- *
- * @method _renderImage
- * @protected
- */
- _renderImage: function(imageArray, i, page, imageInfo)
- {
- var imageBB = null,
- imageConfig = this.get('imageConfig');
- // Create the image?
- if(typeof imageArray[i] == 'undefined') {
- imageConfig.loadGroup = 'thumbs';
- imageConfig.useThumbSizes = true;
- imageConfig.loadVideos = false;
- imageArray[i] = new Y.FL.SlideshowImage(imageConfig);
- imageBB = imageArray[i].get('boundingBox');
- imageBB.on('click', this._imageClick, this);
- imageBB.on('mouseover', this._imageMouseover, this);
- imageBB.on('mouseout', this._imageMouseout, this);
- }
- // Image bounding box
- imageBB = imageArray[i].get('boundingBox');
- imageBB.setStyle('margin', '0 ' + this._horizontalSpacing + 'px ' + this._verticalSpacing + 'px 0');
- // Add the image to a page?
- if(page) {
- this._childrenContainer = page;
- this.add(imageArray[i]);
- imageArray[i].resize(imageConfig.width, imageConfig.height);
- }
- // Load the image?
- if(imageInfo) {
- imageArray[i].load(imageInfo);
- imageBB._imageInfo = imageInfo;
- }
- },
- /**
- * Overrides the WidgetParent _uiAddChild method so _renderImage
- * will render to the appropriate page.
- *
- * @method _uiAddChild
- * @protected
- * @param child {Widget} The child Widget instance to render.
- * @param parentNode {Object} The Node under which the
- * child Widget is to be rendered. Set to the appropriate page
- * in the _renderImage method by setting _childrenContainer.
- */
- _uiAddChild: function (child, parentNode)
- {
- child.render(parentNode);
- parentNode.appendChild(child.get('boundingBox'));
- },
- /**
- * Called when an image is clicked.
- *
- * @method _imageClick
- * @protected
- */
- _imageClick: function(e)
- {
- var root = this.get('root');
- if(this.get('pauseOnClick')) {
- root.pause();
- }
- root.loadImage(e.currentTarget._imageInfo.index);
- /**
- * Fires when an image is clicked.
- *
- * @event imageClick
- */
- this.fire('imageClick');
- },
- /**
- * Sets the active image.
- *
- * @method _setActiveImage
- * @param imageArray {Array} The image array to check for the active image.
- * @protected
- */
- _setActiveImage: function(imageArray)
- {
- var i = 0;
- this._clearActiveImage();
- for( ; i < imageArray.length; i++) {
- if(imageArray[i]._imageInfo) {
- if(imageArray[i]._imageInfo.index == this.get('root').imageInfo.index) {
- imageArray[i].get('boundingBox').addClass('fl-slideshow-image-active');
- break;
- }
- }
- }
- },
- /**
- * Removes the class name 'fl-slideshow-image-active'
- * from the active image.
- *
- * @method _clearActiveImage
- * @protected
- */
- _clearActiveImage: function()
- {
- var active = Y.one('.fl-slideshow-image-active');
- if(active) {
- active.removeClass('fl-slideshow-image-active');
- }
- },
- /**
- * Gets the transition type.
- *
- * @method _getTransition
- * @protected
- */
- _getTransition: function()
- {
- var transition = this.get('transition');
- if(transition == 'slideHorizontal' && this._transitionDirection == 'next') {
- return 'slideLeft';
- }
- else if(transition == 'slideHorizontal' && this._transitionDirection == 'prev') {
- return 'slideRight';
- }
- else if(transition == 'slideVertical' && this._transitionDirection == 'next') {
- return 'slideUp';
- }
- else if(transition == 'slideVertical' && this._transitionDirection == 'prev') {
- return 'slideDown';
- }
- return transition;
- },
- /**
- * Starts the transition, moving in the provided direction.
- *
- * @method _transitionStart
- * @param direction {String} The direction to transition.
- * @protected
- */
- _transitionStart: function(direction)
- {
- if(this._numPages > 1) {
- Y.FL.SlideshowImageLoader.removeGroup('thumbs');
- this._transitionDirection = direction;
- this._transitioning = true;
- this._nextPageBox.setStyle('left', '0px');
- this._renderNextPage();
- this._transition = new Y.FL.SlideshowTransition({
- itemIn: this._nextPageBox,
- itemOut: this._activePageBox,
- type: this._getTransition(),
- duration: this.get('transitionDuration'),
- easing: this.get('transitionEasing')
- });
- this._transition.once('complete', this._transitionComplete, this);
- this._transition.run();
- // Disable gestures if set.
- if(this._gestures) {
- this._gestures.disable();
- }
- }
- },
- /**
- * Transition cleanup called when the current transition ends.
- *
- * @method _transitionComplete
- * @protected
- */
- _transitionComplete: function()
- {
- this._swapPageRefs();
- this._transitioning = false;
- this._transitionDirection = '';
- this._transition = null;
- // Enable gestures if set.
- if(this._gestures) {
- this._gestures.enable();
- }
- /**
- * Fires when a page transition completes.
- *
- * @event transitionComplete
- */
- this.fire('transitionComplete');
- },
- /**
- * @method _gesturesMoveStart
- * @param e {Object} The event object.
- * @protected
- */
- _gesturesMoveStart: function(e)
- {
- Y.FL.SlideshowImageLoader.removeGroup('thumbs');
- this._transitionDirection = e.direction;
- this._renderNextPage();
- },
- /**
- * @method _gesturesEndComplete
- * @protected
- */
- _gesturesEndComplete: function()
- {
- this._swapPageRefs();
- this._transitionDirection = '';
- this.fire('transitionComplete');
- },
- /**
- * Swaps the active page and next page references when
- * a transition completes and sets the active page index.
- *
- * @method _swapPageRefs
- * @protected
- */
- _swapPageRefs: function()
- {
- var lastBox = this._activePageBox,
- lastImages = this._activeImages;
- this._activePageBox = this._nextPageBox;
- this._nextPageBox = lastBox;
- this._nextPageBox.setStyle('left', '-9999px');
- if(this._transitionDirection == 'next') {
- this._activeImages = this._nextImages;
- this._nextImages = lastImages;
- }
- else {
- this._activeImages = this._prevImages;
- this._prevImages = lastImages;
- }
- // Active page index
- if(this._transitionDirection == 'next' && this._activePageIndex + 1 < this._numPages) {
- this._activePageIndex++;
- }
- else if(this._transitionDirection == 'next') {
- this._activePageIndex = 0;
- }
- else if(this._transitionDirection == 'prev' && this._activePageIndex - 1 > -1) {
- this._activePageIndex--;
- }
- else if(this._transitionDirection == 'prev') {
- this._activePageIndex = this._numPages - 1;
- }
- // Swap gesture refs
- if(this._gestures) {
- this._gestures.set('activeItem', this._activePageBox);
- this._gestures.set('nextItem', this._nextPageBox);
- }
- this._preloadNextPage();
- this._preloadPrevPage();
- },
- /**
- * Renders the enabled navs.
- *
- * @method _renderNavs
- * @protected
- */
- _renderNavs: function()
- {
- var topNavButtons = this.get('topNavButtons'),
- rightNavButtons = this.get('rightNavButtons'),
- bottomNavButtons = this.get('bottomNavButtons'),
- leftNavButtons = this.get('leftNavButtons');
- if(this.get('topNavEnabled') && topNavButtons.length > 0) {
- this._topNav = new Y.FL.SlideshowNav({ buttons: topNavButtons });
- this._topNav.get('boundingBox').addClass('fl-slideshow-thumbs-top-nav');
- this.add(this._topNav);
- this._topNav.render(this.get('contentBox'));
- this._clipBox.insert(this._topNav.get('boundingBox'), 'before');
- this._bindNavEvents(this._topNav);
- }
- if(this.get('rightNavEnabled') && rightNavButtons.length > 0) {
- this._rightNav = new Y.FL.SlideshowNav({ buttons: rightNavButtons });
- this._rightNav.get('boundingBox').addClass('fl-slideshow-thumbs-right-nav');
- this.add(this._rightNav);
- this._rightNav.render(this.get('contentBox'));
- this._bindNavEvents(this._rightNav);
- }
- if(this.get('bottomNavEnabled') && bottomNavButtons.length > 0) {
- this._bottomNav = new Y.FL.SlideshowNav({ buttons: bottomNavButtons });
- this._bottomNav.get('boundingBox').addClass('fl-slideshow-thumbs-bottom-nav');
- this.add(this._bottomNav);
- this._bottomNav.render(this.get('contentBox'));
- this._bindNavEvents(this._bottomNav);
- }
- if(this.get('leftNavEnabled') && leftNavButtons.length > 0) {
- this._leftNav = new Y.FL.SlideshowNav({ buttons: leftNavButtons });
- this._leftNav.get('boundingBox').addClass('fl-slideshow-thumbs-left-nav');
- this.add(this._leftNav);
- this._leftNav.render(this.get('contentBox'));
- this._bindNavEvents(this._leftNav);
- }
- },
- /**
- * Syncs the navs.
- *
- * @method _syncNavs
- * @protected
- */
- _syncNavs: function()
- {
- var rightNavBB, bottomNavBB, leftNavBB;
- if(this._rightNav) {
- rightNavBB = this._rightNav.get('boundingBox');
- rightNavBB.setStyle('position', 'absolute');
- rightNavBB.setStyle('top', '0px');
- rightNavBB.setStyle('right', '0px');
- }
- if(this._bottomNav) {
- bottomNavBB = this._bottomNav.get('boundingBox');
- bottomNavBB.setStyle('position', 'absolute');
- bottomNavBB.setStyle('bottom', '0px');
- bottomNavBB.setStyle('width', '100%');
- }
- if(this._leftNav) {
- leftNavBB = this._leftNav.get('boundingBox');
- leftNavBB.setStyle('position', 'absolute');
- leftNavBB.setStyle('top', '0px');
- leftNavBB.setStyle('left', '0px');
- }
- },
- /**
- * Resizes the navs.
- *
- * @method _resizeNavs
- * @protected
- */
- _resizeNavs: function()
- {
- var rightNavBB,
- leftNavBB,
- marginTop;
- if(this._rightNav) {
- rightNavBB = this._rightNav.get('boundingBox');
- marginTop = this._bbHeight/2 - parseInt(rightNavBB.getComputedStyle('height'), 10)/2;
- rightNavBB.setStyle('marginTop', marginTop + 'px');
- }
- if(this._leftNav) {
- leftNavBB = this._leftNav.get('boundingBox');
- marginTop = this._bbHeight/2 - parseInt(leftNavBB.getComputedStyle('height'), 10)/2;
- leftNavBB.setStyle('marginTop', marginTop + 'px');
- }
- },
- /**
- * Binds events to the provided nav.
- *
- * @method _bindNavEvents
- * @param nav {Object} The nav to bind to.
- * @protected
- */
- _bindNavEvents: function(nav)
- {
- if(nav._buttons.prevPage) {
- nav._buttons.prevPage.on('click', this.prevPage, this);
- }
- if(nav._buttons.nextPage) {
- nav._buttons.nextPage.on('click', this.nextPage, this);
- }
- nav.on('resize', this.resize, this);
- },
- /**
- * Hides the prev page and next page buttons
- * if there is only one page of thumbs.
- *
- * @method _togglePageButtons
- * @protected
- */
- _togglePageButtons: function()
- {
- var buttons = this.get('boundingBox').all('.fl-slideshow-nav-prevPage, .fl-slideshow-nav-nextPage'),
- display = buttons.getStyle('display')[0];
- if(this._numPages == 1 && display == 'inline-block') {
- buttons.setStyle('display', 'none');
- this._setSizeInfo();
- }
- else if(this._numPages > 1 && display == 'none') {
- buttons.setStyle('display', 'inline-block');
- this._setSizeInfo();
- }
- },
- /**
- * Sets the size info used when resizing and loading pages.
- *
- * @method _setSizeInfo
- * @protected
- */
- _setSizeInfo: function()
- {
- var root = this.get('root'),
- bb = this.get('boundingBox'),
- bbPosition = bb.getStyle('position'),
- bbLeftMargin = parseInt(bb.getStyle('marginLeft'), 10),
- bbRightMargin = parseInt(bb.getStyle('marginRight'), 10),
- bbTopMargin = parseInt(bb.getStyle('marginTop'), 10),
- bbBottomMargin = parseInt(bb.getStyle('marginBottom'), 10),
- bbLeftPadding = parseInt(bb.getStyle('paddingLeft'), 10),
- bbRightPadding = parseInt(bb.getStyle('paddingRight'), 10),
- bbTopPadding = parseInt(bb.getStyle('paddingTop'), 10),
- bbBottomPadding = parseInt(bb.getStyle('paddingBottom'), 10),
- parent = bb.get('parentNode'),
- parentWidth = parseInt(parent.getComputedStyle('width'), 10),
- parentHeight = parseInt(parent.getComputedStyle('height'), 10),
- bbWidth = parentWidth - bbLeftPadding - bbRightPadding - bbLeftMargin - bbRightMargin,
- bbHeight = parentHeight - bbTopPadding - bbBottomPadding - bbTopMargin - bbBottomMargin,
- cbWidth = bbWidth,
- pageWidth = bbWidth,
- pageHeight = bbHeight,
- columns = this.get('columns'),
- rows = this.get('rows'),
- imageConfig = this.get('imageConfig'),
- horizontalSpacing = this.get('horizontalSpacing'),
- verticalSpacing = this.get('verticalSpacing'),
- spaceEvenly = this.get('spaceEvenly'),
- centerSinglePage = this.get('centerSinglePage'),
- leftNavWidth = 0,
- rightNavWidth = 0,
- topNavHeight = 0,
- bottomNavHeight = 0,
- colsPerPage = columns,
- rowsPerPage = rows,
- imagesPerPage = 0,
- numPages = 1,
- clipBoxMarginLeft = 0,
- clipBoxTop = 0,
- availHorizSpace = 0,
- availVerticalSpace = 0;
- // Position absolute causes some resizing bugs.
- bb.setStyle('position', 'relative');
- // Bounding box width
- if(!isNaN(columns)) {
- bbWidth = pageWidth = columns * (imageConfig.width + horizontalSpacing) + horizontalSpacing;
- }
- // Bounding box height
- if(!isNaN(rows)) {
- bbHeight = pageHeight = rows * (imageConfig.height + verticalSpacing) + verticalSpacing;
- }
- // Compensate for the navs
- if(this._leftNav) {
- leftNavWidth = parseInt(this._leftNav.get('boundingBox').getComputedStyle('width'), 10);
- if(isNaN(columns)) {
- pageWidth -= leftNavWidth;
- }
- else {
- bbWidth += leftNavWidth;
- }
- }
- if(this._rightNav) {
- rightNavWidth = parseInt(this._rightNav.get('boundingBox').getComputedStyle('width'), 10);
- if(isNaN(columns)) {
- pageWidth -= rightNavWidth;
- }
- else {
- bbWidth += rightNavWidth;
- }
- }
- if(this._topNav) {
- topNavHeight = parseInt(this._topNav.get('boundingBox').getComputedStyle('height'), 10);
- if(isNaN(rows)) {
- pageHeight -= topNavHeight;
- }
- else {
- bbHeight += topNavHeight;
- }
- }
- if(this._bottomNav) {
- bottomNavHeight = parseInt(this._bottomNav.get('boundingBox').getComputedStyle('height'), 10);
- if(isNaN(rows)) {
- pageHeight -= bottomNavHeight;
- }
- else {
- bbHeight += bottomNavHeight;
- }
- }
- // Columns per page
- if(isNaN(columns)) {
- colsPerPage = Math.floor(pageWidth/(imageConfig.width + horizontalSpacing));
- colsPerPage = colsPerPage < 1 ? 1 : colsPerPage;
- }
- // Rows per page
- if(isNaN(rows)) {
- rowsPerPage = Math.floor(pageHeight/(imageConfig.height + verticalSpacing));
- rowsPerPage = rowsPerPage < 1 ? 1 : rowsPerPage;
- }
- // Images per page
- imagesPerPage = colsPerPage * rowsPerPage;
- // Number of pages
- if(root.albumInfo) {
- numPages = Math.ceil(root.albumInfo.images.length/imagesPerPage);
- }
- // Horizontal spacing
- if(isNaN(columns) && spaceEvenly) {
- horizontalSpacing = Math.floor((pageWidth - (imageConfig.width * colsPerPage))/(colsPerPage + 1));
- }
- // Vertical spacing
- if(isNaN(rows) && spaceEvenly) {
- verticalSpacing = Math.floor((pageHeight - (imageConfig.height * rowsPerPage))/(rowsPerPage + 1));
- }
- // Content container width
- if(root.albumInfo && centerSinglePage && numPages == 1 && rowsPerPage == 1) {
- cbWidth = root.albumInfo.images.length * imageConfig.width;
- cbWidth += horizontalSpacing * (root.albumInfo.images.length + 1);
- if(this._leftNav) {
- cbWidth += leftNavWidth;
- }
- if(this._rightNav) {
- cbWidth += rightNavWidth;
- }
- }
- else {
- cbWidth = bbWidth;
- }
- // Final page width and height
- if(root.albumInfo && centerSinglePage && numPages == 1 && rowsPerPage == 1) {
- pageWidth = root.albumInfo.images.length * imageConfig.width;
- pageWidth += horizontalSpacing * root.albumInfo.images.length;
- }
- else {
- pageWidth = colsPerPage * (imageConfig.width + horizontalSpacing);
- }
- pageHeight = rowsPerPage * (imageConfig.height + verticalSpacing);
- // Clip box margin left
- if(numPages < 2) {
- clipBoxMarginLeft = leftNavWidth;
- }
- else {
- availHorizSpace = bbWidth;
- if(this._rightNav) {
- availHorizSpace -= rightNavWidth;
- }
- if(this._leftNav) {
- availHorizSpace -= leftNavWidth;
- clipBoxMarginLeft = leftNavWidth + (availHorizSpace - pageWidth - horizontalSpacing)/2;
- }
- else {
- clipBoxMarginLeft = (availHorizSpace - pageWidth - horizontalSpacing)/2;
- }
- }
- // Clip box margin top
- if(numPages > 1 && !spaceEvenly) {
- availVerticalSpace = bbHeight;
- if(this._topNav) {
- availVerticalSpace -= topNavHeight;
- }
- if(this._bottomNav) {
- availVerticalSpace -= bottomNavHeight;
- }
- clipBoxTop = (availVerticalSpace - (verticalSpacing + pageHeight))/2;
- }
- // Set the info
- this._bbHeight = bbHeight;
- this._bbWidth = bbWidth;
- this._cbWidth = cbWidth;
- this._clipBoxMarginLeft = clipBoxMarginLeft;
- this._clipBoxTop = clipBoxTop;
- this._colsPerPage = colsPerPage;
- this._rowsPerPage = rowsPerPage;
- this._imagesPerPage = imagesPerPage;
- this._numPages = numPages;
- this._pageHeight = pageHeight;
- this._pageWidth = pageWidth;
- this._leftNavWidth = leftNavWidth;
- this._rightNavWidth = rightNavWidth;
- this._horizontalSpacing = horizontalSpacing;
- this._verticalSpacing = verticalSpacing;
- this._activePageIndex = Math.floor(root.imageIndex/this._imagesPerPage);
- // Set back to the initial position.
- bb.setStyle('position', bbPosition);
- }
- }, {
- /**
- * Custom CSS class name for the widget.
- *
- * @property CSS_PREFIX
- * @type String
- * @protected
- * @static
- */
- CSS_PREFIX: 'fl-slideshow-thumbs',
- /**
- * Static property used to define the default attribute configuration of
- * the Widget.
- *
- * @property ATTRS
- * @type Object
- * @protected
- * @static
- */
- ATTRS: {
- /**
- * The number of thumbnail columns. If set to auto, the number of
- * columns will be calculated based on the width of the parent node.
- *
- * @attribute columns
- * @type String or Number
- * @default auto
- */
- columns: {
- value: 'auto'
- },
- /**
- * The number of thumbnail rows. If set to auto, the number of
- * rows will be calculated based on the height of the parent node.
- *
- * @attribute rows
- * @type String or Number
- * @default auto
- */
- rows: {
- value: 'auto'
- },
- /**
- * The horizontal spacing between thumbs.
- *
- * @attribute horizontalSpacing
- * @type Number
- * @default 15
- */
- horizontalSpacing: {
- value: 15
- },
- /**
- * The vertical spacing between thumbs.
- *
- * @attribute verticalSpacing
- * @type Number
- * @default 15
- */
- verticalSpacing: {
- value: 15
- },
- /**
- * Whether to space the thumbs evenly within a page.
- *
- * @attribute spaceEvenly
- * @type Boolean
- * @default true
- */
- spaceEvenly: {
- value: true
- },
- /**
- * Whether to center single pages of thumbs.
- *
- * @attribute centerSinglePage
- * @type Boolean
- * @default false
- */
- centerSinglePage: {
- value: true
- },
- /**
- * Whether to pause the parent slideshow when a thumb is clicked.
- *
- * @attribute pauseOnClick
- * @type Boolean
- * @default false
- */
- pauseOnClick: {
- value: false
- },
- /**
- * The type of transition to use between pages.
- *
- * @attribute transition
- * @type String
- * @default slideHorizontal
- */
- transition: {
- value: 'slideHorizontal'
- },
- /**
- * The duration of the transition between pages.
- *
- * @attribute transitionDuration
- * @type Number
- * @default 0.8
- */
- transitionDuration: {
- value: 0.8
- },
- /**
- * The type of transition easing to use between pages.
- *
- * @attribute transitionEasing
- * @type String
- * @default ease-out
- */
- transitionEasing: {
- value: 'ease-out'
- },
- /**
- * The configuration object used to create new instances of
- * FL.SlideshowImage. See the API docs for {@link FL.SlideshowImage}
- * for a complete list of configuration attributes.
- *
- * @attribute imageConfig
- * @type Object
- * @default {}
- */
- imageConfig: {
- value: {
- crop: true,
- width: 50,
- height: 50
- }
- },
- /**
- * Whether to use the top nav or not.
- *
- * @attribute topNavEnabled
- * @type Boolean
- * @default false
- */
- topNavEnabled: {
- value: false
- },
- /**
- * An array of button names used to render the top nav buttons.
- *
- * @attribute topNavButtons
- * @type Array
- * @default prevPage, nextPage
- */
- topNavButtons: {
- value: ['prevPage', 'nextPage']
- },
- /**
- * Whether to use the right nav or not.
- *
- * @attribute rightNavEnabled
- * @type Boolean
- * @default true
- */
- rightNavEnabled: {
- value: true
- },
- /**
- * An array of button names used to render the right nav buttons.
- *
- * @attribute rightNavButtons
- * @type Array
- * @default nextPage
- */
- rightNavButtons: {
- value: ['nextPage']
- },
- /**
- * Whether to use the bottom nav or not.
- *
- * @attribute bottomNavEnabled
- * @type Boolean
- * @default false
- */
- bottomNavEnabled: {
- value: false
- },
- /**
- * An array of button names used to render the bottom nav buttons.
- *
- * @attribute bottomNavButtons
- * @type Array
- * @default prevPage, nextPage
- */
- bottomNavButtons:{
- value: ['prevPage', 'nextPage']
- },
- /**
- * Whether to use the left nav or not.
- *
- * @attribute leftNavEnabled
- * @type Boolean
- * @default true
- */
- leftNavEnabled: {
- value: true
- },
- /**
- * An array of button names used to render the left nav buttons.
- *
- * @attribute leftNavButtons
- * @type Array
- * @default prevPage
- */
- leftNavButtons:{
- value: ['prevPage']
- },
- /**
- * Whether to use touch gestures, when available,
- * to transition between pages or not.
- *
- * @attribute touchSupport
- * @type Boolean
- * @default false
- */
- touchSupport: {
- value: false
- }
- }
- });
- /**
- * Provides functionality for transitions between slideshow components.
- *
- * @namespace FL
- * @class SlideshowTransition
- * @constructor
- * @param config {Object} Configuration object
- * @extends Base
- */
- Y.namespace('FL').SlideshowTransition = Y.Base.create('fl-slideshow-transition', Y.Base, [], {
- /**
- * The transition function to use when run is called.
- *
- * @property _transitionFunction
- * @type String
- * @default _transitionFade
- * @protected
- */
- _transitionFunction: '_transitionFade',
- /**
- * The current transition type.
- *
- * @property _type
- * @type String
- * @default fade
- * @protected
- */
- _type: 'fade',
- /**
- * Parses the transition type and sets the _transitionFunction
- * used when run is called.
- *
- * @method initializer
- * @protected
- */
- initializer: function()
- {
- var type = this.get('type'),
- typeArray = [],
- types = Y.FL.SlideshowTransition.TYPES,
- slideshowImageTypes = Y.FL.SlideshowTransition.SLIDESHOW_IMAGE_TYPES,
- isSlideshowImageTransition = Y.Array.indexOf(slideshowImageTypes, type) > -1,
- isSlideshowImage = this._isSlideshowImage(),
- itemIn = this.get('itemIn'),
- itemOut = this.get('itemOut');
- // Check for random transitions.
- if(type.indexOf(',') > -1) {
- typeArray = type.split(',');
- typeArray.sort(function() { return 0.5 - Math.random(); });
- type = typeArray[0];
- }
- // Make sure we can run this transition, otherwise set a fallback.
- if(!isSlideshowImage && isSlideshowImageTransition) {
- type = 'fade';
- }
- else if(isSlideshowImage) {
- if((itemIn && itemIn.one('img') === null) || (itemOut && itemOut.one('img') === null)) {
- type = 'none';
- }
- else if(isSlideshowImageTransition) {
- if((Y.UA.gecko && Y.UA.gecko < 5) || Y.UA.opera > 0 || (Y.UA.ie > 0 && Y.UA.ie < 9)) {
- type = 'fade';
- }
- }
- }
- // Set the transition function and type.
- if(Y.FL.SlideshowTransition.TYPES[type]) {
- this._transitionFunction = types[type];
- this._type = type;
- }
- // Setup the items.
- this._setupItems();
- },
- /**
- * Fires the start event and calls the transition function.
- *
- * @method run
- */
- run: function()
- {
- /**
- * Fires when the transition starts.
- *
- * @event start
- */
- this.fire('start');
- this[this._transitionFunction].call(this);
- },
- /**
- * Set initial styles for the items.
- *
- * @method _setupItems
- * @protected
- */
- _setupItems: function()
- {
- var itemIn = this.get('itemIn'),
- itemOut = this.get('itemOut');
- if(itemIn) {
- itemIn.setStyle('zIndex', 2);
- itemIn.setStyle('opacity', 1);
- if(Y.FL.Utils.cssSupport('transform')) {
- itemIn.setStyle('transform', 'translate(0, 0)');
- }
- else {
- itemIn.setStyle('top', '0');
- itemIn.setStyle('left', '0');
- }
- }
- if(itemOut) {
- itemOut.setStyle('zIndex', 1);
- }
- },
- /**
- * Checks if the transition is being run
- * on an instance of FL.SlideshowImage or not.
- *
- * @method _isSlideshowImage
- * @protected
- */
- _isSlideshowImage: function()
- {
- var itemIn = this.get('itemIn'),
- itemOut = this.get('itemOut');
- if(itemIn && itemIn.hasClass('fl-slideshow-image')) {
- return true;
- }
- else if(itemOut && itemOut.hasClass('fl-slideshow-image')) {
- return true;
- }
- return false;
- },
- /**
- * Starts the transtion using the provided property objects.
- *
- * @method _transitionStart
- * @param propsIn {Object} The properties to animate in.
- * @param propsOut {Object} The properties to animate out.
- * @protected
- */
- _transitionStart: function(propsIn, propsOut)
- {
- var itemIn = this.get('itemIn'),
- itemOut = this.get('itemOut'),
- itemInCallback = Y.bind(this._transitionComplete, this),
- itemOutCallback = !itemIn ? itemInCallback : null,
- duration = this.get('duration'),
- easing = this.get('easing');
- if(itemIn) {
- propsIn.duration = propsIn.duration || duration;
- propsIn.easing = propsIn.easing || easing;
- itemIn.transition(propsIn);
- }
- if(itemOut) {
- propsOut.duration = propsOut.duration || duration;
- propsOut.easing = propsOut.easing || easing;
- itemOut.transition(propsOut);
- }
- if(itemInCallback) {
- Y.later(propsIn.duration * 1000 + 100, null, itemInCallback);
- }
- else if(itemOutCallback) {
- Y.later(propsOut.duration * 1000 + 100, null, itemOutCallback);
- }
- },
- /**
- * Clean up method called when the transition completes.
- *
- * @method _transitionComplete
- * @protected
- */
- _transitionComplete: function()
- {
- this._set('itemIn', null);
- this._set('itemOut', null);
- /**
- * Fires when the transition completes.
- *
- * @event complete
- */
- this.fire('complete');
- },
- /**
- * No transition.
- *
- * @method _transitionNone
- * @protected
- */
- _transitionNone: function()
- {
- var itemIn = this.get('itemIn'),
- itemOut = this.get('itemOut');
- if(itemIn) {
- itemIn.setStyle('opacity', 1);
- }
- if(itemOut) {
- itemOut.setStyle('opacity', 0);
- }
- this._transitionComplete();
- },
- /**
- * Fade transition.
- *
- * @method _transitionFade
- * @protected
- */
- _transitionFade: function()
- {
- var itemIn = this.get('itemIn');
- if(itemIn) {
- itemIn.setStyle('opacity', 0);
- }
- this._transitionStart({ opacity: 1 },{ opacity: 0 });
- },
- /**
- * Slide left transition.
- *
- * @method _transitionSlideLeft
- * @protected
- */
- _transitionSlideLeft: function()
- {
- if(Y.FL.Utils.cssSupport('transform')) {
- this._cssTransitionSlide({
- inStart: 'translate(100%, 0)',
- inEnd: 'translate(0, 0)',
- outStart: 'translate(0, 0)',
- outEnd: 'translate(-100%, 0)'
- });
- }
- else {
- this._jsTransitionSlide('left');
- }
- },
- /**
- * Slide right transition.
- *
- * @method _transitionSlideRight
- * @protected
- */
- _transitionSlideRight: function()
- {
- if(Y.FL.Utils.cssSupport('transform')) {
- this._cssTransitionSlide({
- inStart: 'translate(-100%, 0)',
- inEnd: 'translate(0, 0)',
- outStart: 'translate(0, 0)',
- outEnd: 'translate(100%, 0)'
- });
- }
- else {
- this._jsTransitionSlide('right');
- }
- },
- /**
- * Slide up transition.
- *
- * @method _transitionSlideUp
- * @protected
- */
- _transitionSlideUp: function()
- {
- if(Y.FL.Utils.cssSupport('transform')) {
- this._cssTransitionSlide({
- inStart: 'translate(0, 100%)',
- inEnd: 'translate(0, 0)',
- outStart: 'translate(0, 0)',
- outEnd: 'translate(0, -100%)'
- });
- }
- else {
- this._jsTransitionSlide('up');
- }
- },
- /**
- * Slide down transition.
- *
- * @method _transitionSlideDown
- * @protected
- */
- _transitionSlideDown: function()
- {
- if(Y.FL.Utils.cssSupport('transform')) {
- this._cssTransitionSlide({
- inStart: 'translate(0, -100%)',
- inEnd: 'translate(0, 0)',
- outStart: 'translate(0, 0)',
- outEnd: 'translate(0, 100%)'
- });
- }
- else {
- this._jsTransitionSlide('down');
- }
- },
- /**
- * JavaScript slide transition.
- *
- * @method _jsTransitionSlide
- * @protected
- */
- _jsTransitionSlide: function(direction)
- {
- var itemIn = this.get('itemIn'),
- itemOut = this.get('itemOut'),
- itemOutEnd = 0;
- // Item Out
- if(itemOut && direction == 'left') {
- itemOutEnd = -parseInt(itemOut.getStyle('width'), 10);
- }
- if(itemOut && direction == 'right') {
- itemOutEnd = parseInt(itemOut.getStyle('width'), 10);
- }
- if(itemOut && direction == 'up') {
- itemOutEnd = -parseInt(itemOut.getStyle('height'), 10);
- }
- if(itemOut && direction == 'down') {
- itemOutEnd = parseInt(itemOut.getStyle('height'), 10);
- }
- // Item In
- if(itemIn) {
- itemIn.setStyle('opacity', 1);
- }
- if(itemIn && direction == 'left') {
- itemIn.setStyle('left', itemIn.getStyle('width'));
- }
- if(itemIn && direction == 'right') {
- itemIn.setStyle('left', '-' + itemIn.getStyle('width'));
- }
- if(itemIn && direction == 'up') {
- itemIn.setStyle('top', itemIn.getStyle('height'));
- }
- if(itemIn && direction == 'down') {
- itemIn.setStyle('top', '-' + itemIn.getStyle('height'));
- }
- // Transition Start
- if(direction == 'left' || direction == 'right') {
- this._transitionStart({ left: 0 },{ left: itemOutEnd });
- }
- else {
- this._transitionStart({ top: 0 },{ top: itemOutEnd });
- }
- },
- /**
- * CSS slide transition.
- *
- * @method _cssTransitionSlide
- * @protected
- */
- _cssTransitionSlide: function(props)
- {
- var itemIn = this.get('itemIn'),
- itemOut = this.get('itemOut'),
- transformProp = Y.UA.chrome < 36 ? 'transform' : '-webkit-transform',
- inProps = {},
- outProps = {};
- inProps[transformProp] = props.inEnd;
- outProps[transformProp] = props.outEnd;
- if(itemIn) {
- itemIn.setStyle('transition', '');
- itemIn.setStyle('opacity', 1);
- itemIn.setStyle(transformProp, props.inStart);
- }
- if(itemOut) {
- itemOut.setStyle('transition', '');
- itemOut.setStyle(transformProp, props.outStart);
- }
- this._transitionStart(inProps, outProps);
- },
- /**
- * Bars and blinds transition.
- *
- * @method _transitionBars
- * @protected
- */
- _transitionBars: function()
- {
- // Hide the image until the slices have transitioned in.
- this.get('itemIn').one('.fl-slideshow-image-img').setStyle('opacity', 0);
- var numBars = this.get('bars'),
- slices = this._renderSlices(1, numBars),
- duration = this.get('duration'),
- delay = 0,
- increment = 100,
- last = false,
- i = 0,
- clone = null,
- props = {
- duration: duration,
- opacity: 1
- };
- // barsRandom
- if(this._type == 'barsRandom') {
- slices = this._randomizeSlices(slices);
- }
- // Transition the slices.
- for( ; i < slices.length; i++) {
- // Make a clone of our transition properties.
- clone = Y.clone(props);
- // blinds
- if(this._type == 'blinds') {
- clone.width = parseFloat(slices[i].getComputedStyle('width'), 10) + 'px';
- slices[i].setStyle('width', '0px');
- increment = 50;
- }
- // Run the transition.
- last = i == slices.length - 1 ? true : false;
- Y.later(delay, this, this._transitionSlice, [slices[i], clone, last]);
- delay += increment;
- }
- this._transitionSlicesFadeLast(delay);
- },
- /**
- * Boxes transition.
- *
- * @method _transitionBoxes
- * @protected
- */
- _transitionBoxes: function()
- {
- // Hide the image until the slices have transitioned in.
- this.get('itemIn').one('.fl-slideshow-image-img').setStyle('opacity', 0);
- var numCols = this.get('boxCols'),
- numRows = this.get('boxRows'),
- numSlices = numCols * numRows,
- multi = this._type != 'boxesRandom',
- slices = this._renderSlices(numRows, numCols, multi),
- duration = this.get('duration'),
- delay = 0,
- increment = 150,
- last = false,
- i = 0,
- row = 0,
- col = 0,
- startCol = -1,
- clone = null,
- props = {
- duration: duration,
- opacity: 1
- };
- // boxesRandom
- if(!multi) {
- slices = this._randomizeSlices(slices);
- increment = 30;
- for( ; i < slices.length; i++) {
- clone = Y.clone(props);
- last = i == slices.length - 1 ? true : false;
- Y.later(delay, this, this._transitionSlice, [slices[i], clone, last]);
- delay += increment;
- }
- }
- // boxes
- else {
- while(i < numSlices) {
- for(row = 0; row < numRows; row++) {
- if(row === 0) {
- startCol++;
- col = startCol;
- }
- if(col > -1 && col < numCols) {
- i++;
- clone = Y.clone(props);
- // boxesGrow
- if(this._type == 'boxesGrow') {
- clone.height = parseFloat(slices[row][col].getComputedStyle('height'), 10) + 'px';
- clone.width = parseFloat(slices[row][col].getComputedStyle('width'), 10) + 'px';
- slices[row][col].setStyle('height', '0px');
- slices[row][col].setStyle('width', '0px');
- increment = 50;
- }
- last = i == numSlices - 1 ? true : false;
- Y.later(delay, this, this._transitionSlice, [slices[row][col], clone, last]);
- }
- col--;
- }
- delay += increment;
- }
- }
- this._transitionSlicesFadeLast(delay);
- },
- /**
- * Renders the divs for slice based transitions.
- *
- * @method _renderSlices
- * @protected
- */
- _renderSlices: function(numRows, numCols, multidimensional)
- {
- var itemIn = this.get('itemIn'),
- itemHeight = parseFloat(itemIn.getComputedStyle('height'), 10),
- itemWidth = parseFloat(itemIn.getComputedStyle('width'), 10),
- img = itemIn.one('img'),
- imgSrc = img.get('src'),
- imgHeight = parseFloat(img.getComputedStyle('height'), 10),
- imgWidth = parseFloat(img.getComputedStyle('width'), 10),
- imgLeft = parseFloat(img.getComputedStyle('left'), 10),
- imgTop = parseFloat(img.getComputedStyle('top'), 10),
- col = 0,
- row = 0,
- sliceHeight = Math.round(itemHeight/numRows),
- sliceWidth = Math.round(itemWidth/numCols),
- slice = null,
- sliceImg = null,
- slices = [];
- for( ; row < numRows; row++) {
- if(typeof multidimensional !== 'undefined' && multidimensional) {
- slices[row] = [];
- }
- for(col = 0; col < numCols; col++) {
- slice = Y.Node.create('<div class="fl-slideshow-transition-slice"></div>');
- sliceImg = Y.Node.create('<img src="'+ imgSrc +'" />');
- slice.setStyles({
- left: (sliceWidth * col) + 'px',
- top: (sliceHeight * row) + 'px',
- width: col == numCols - 1 ? (itemWidth - (sliceWidth * col)) + 'px' : sliceWidth + 'px',
- height: row == numRows - 1 ? (itemHeight - (sliceHeight * row)) + 'px' : sliceHeight + 'px',
- opacity: 0
- });
- sliceImg.setStyles({
- height: imgHeight + 'px',
- width: imgWidth + 'px',
- top: imgTop - ((sliceHeight + (row * sliceHeight)) - sliceHeight) + 'px',
- left: imgLeft - ((sliceWidth + (col * sliceWidth)) - sliceWidth) + 'px'
- });
- slice.append(sliceImg);
- itemIn.append(slice);
- if(typeof multidimensional !== 'undefined' && multidimensional) {
- slices[row].push(slice);
- }
- else {
- slices.push(slice);
- }
- }
- }
- return slices;
- },
- /**
- * Fade the itemOut node.
- *
- * @method _transitionSlicesFadeLast
- * @protected
- */
- _transitionSlicesFadeLast: function(delay)
- {
- var itemOut = this.get('itemOut');
- if(itemOut && !itemOut.hasClass('fl-slideshow-image-cropped')) {
- itemOut.transition({
- duration: delay/1000 + this.get('duration'),
- opacity: 0
- });
- }
- },
- /**
- * Transitions a single slice.
- *
- * @method _transitionSlice
- * @protected
- */
- _transitionSlice: function(slice, props, last)
- {
- var callback = last ? Y.bind(this._transitionSlicesComplete, this) : null;
- slice.transition(props, callback);
- },
- /**
- * Complete callback for slice based transitions.
- *
- * @method _transitionSlicesComplete
- * @protected
- */
- _transitionSlicesComplete: function()
- {
- var itemIn = this.get('itemIn');
- itemIn.all('.fl-slideshow-transition-slice').remove();
- itemIn.one('.fl-slideshow-image-img').setStyle('opacity', 1);
- this._transitionComplete();
- },
- /**
- * Randomizes a slices array.
- *
- * @method _radomizeSlices
- * @protected
- */
- _randomizeSlices: function(slices)
- {
- var i = slices.length, j, temp;
- if(i === 0) {
- return;
- }
- while(--i) {
- j = Math.floor( Math.random() * ( i + 1 ) );
- temp = slices[i];
- slices[i] = slices[j];
- slices[j] = temp;
- }
- return slices;
- },
- _transitionKenBurns: function()
- {
- var kbDuration = this.get('kenBurnsDuration'),
- duration = this.get('duration'),
- itemIn = this.get('itemIn'),
- zoom = this.get('kenBurnsZoom');
- this._transitionFade();
- (new Y.FL.SlideshowKenBurns({
- duration: kbDuration + duration + 4,
- image: itemIn,
- zoom: zoom
- })).run();
- }
- }, {
- /**
- * Static property used to define the default attribute configuration of
- * the Widget.
- *
- * @property ATTRS
- * @type Object
- * @protected
- * @static
- */
- ATTRS: {
- /**
- * The Node to transition in.
- *
- * @attribute itemIn
- * @type Node
- * @default null
- */
- itemIn: {
- value: null
- },
- /**
- * The Node to transition out.
- *
- * @attribute itemOut
- * @type Node
- * @default null
- */
- itemOut: {
- value: null
- },
- /**
- * The duration of the transition in seconds.
- *
- * @attribute duration
- * @type Number
- * @default 0.5
- */
- duration: {
- value: 0.5
- },
- /**
- * The type of easing to use.
- *
- * @attribute easing
- * @type String
- * @default ease-out
- */
- easing: {
- value: 'ease-out'
- },
- /**
- * The type of transition to use.
- *
- * @attribute type
- * @type String
- * @default fade
- */
- type: {
- value: 'fade'
- },
- /**
- * The number of bars to use for
- * transitions such as blinds.
- *
- * @attribute bars
- * @type Number
- * @default 15
- */
- bars: {
- value: 15
- },
- /**
- * The number of columns to use for
- * transitions such as boxes.
- *
- * @attribute boxCols
- * @type Number
- * @default 8
- */
- boxCols: {
- value: 8
- },
- /**
- * The number of rows to use for
- * transitions such as boxes.
- *
- * @attribute boxRows
- * @type Number
- * @default 4
- */
- boxRows: {
- value: 4
- },
- /**
- * The duration the ken burns effect will
- * last, measured in seconds.
- *
- * @attribute kenBurnsDuration
- * @type Number
- * @default 4
- */
- kenBurnsDuration: {
- value: 4
- },
- /**
- * The amount of zoom to use for the Ken Burns effect.
- *
- * @attribute kenBurnsZoom
- * @type Number
- * @default 1.2
- */
- kenBurnsZoom: {
- value: 1.2
- }
- },
- /**
- * The types of transitions and associated functions.
- *
- * @property TYPES
- * @type Object
- * @readOnly
- * @protected
- * @static
- */
- TYPES: {
- fade: '_transitionFade',
- none: '_transitionNone',
- slideLeft: '_transitionSlideLeft',
- slideRight: '_transitionSlideRight',
- slideUp: '_transitionSlideUp',
- slideDown: '_transitionSlideDown',
- blinds: '_transitionBars',
- bars: '_transitionBars',
- barsRandom: '_transitionBars',
- boxes: '_transitionBoxes',
- boxesRandom: '_transitionBoxes',
- boxesGrow: '_transitionBoxes',
- kenBurns: '_transitionKenBurns'
- },
- /**
- * The types of transitions that can only be
- * run on FL.SlideshowImage widgets.
- *
- * @property SLIDESHOW_IMAGE_TYPES
- * @type Object
- * @readOnly
- * @protected
- * @static
- */
- SLIDESHOW_IMAGE_TYPES: [
- 'blinds',
- 'bars',
- 'barsRandom',
- 'boxes',
- 'boxesRandom',
- 'boxesGrow',
- 'kenBurns'
- ]
- });
- /**
- * A highly configurable slideshow widget.
- *
- * @namespace FL
- * @class Slideshow
- * @constructor
- * @param config {Object} Configuration object
- * @extends FL.SlideshowBase
- */
- Y.namespace('FL').Slideshow = Y.Base.create('fl-slideshow', Y.FL.SlideshowBase, [], {
- /**
- * A FL.SlideshowFrame instance used for the main image.
- *
- * @property frame
- * @type FL.SlideshowFrame
- * @default null
- */
- frame: null,
- /**
- * A FL.SlideshowNav instance used for the main nav.
- *
- * @property nav
- * @type FL.SlideshowNav
- * @default null
- */
- nav: null,
- /**
- * A FL.SlideshowNav instance used for the image nav's left button.
- *
- * @property imageNavLeft
- * @type FL.SlideshowNav
- * @default null
- */
- imageNavLeft: null,
- /**
- * A FL.SlideshowNav instance used for the image nav's right button.
- *
- * @property imageNavRight
- * @type FL.SlideshowNav
- * @default null
- */
- imageNavRight: null,
- /**
- * A FL.SlideshowThumbs instance used for the thumbnail grid.
- *
- * @property thumbs
- * @type FL.SlideshowThumbs
- * @default null
- */
- thumbs: null,
- /**
- * A FL.SlideshowThumbs instance used for the vertical thumbnail grid.
- *
- * @property verticalThumbs
- * @type FL.SlideshowThumbs
- * @default null
- */
- verticalThumbs: null,
- /**
- * A FL.SlideshowCaption instance.
- *
- * @property caption
- * @type FL.SlideshowCaption
- * @default null
- */
- caption: null,
- /**
- * A FL.SlideshowSocial instance.
- *
- * @property social
- * @type FL.SlideshowSocial
- * @default null
- */
- social: null,
- /**
- * A FL.SlideshowImage instance used to preload
- * the next image.
- *
- * @property _nextImagePreloader
- * @type FL.SlideshowImage
- * @default null
- * @protected
- */
- _nextImagePreloader: null,
- /**
- * An object that holds the initial nav settings
- * when the mini nav has been enabled for a responsive layout.
- *
- * @property _initialNavSettings
- * @type Object
- * @default null
- * @protected
- */
- _initialNavSettings: null,
- /**
- * Initializes the preloaders, nav buttons, fullscreen and captions.
- *
- * @method initializer
- * @protected
- */
- initializer: function()
- {
- // Preloader config
- var imageConfig = {
- loadGroup: 'main-preload',
- crop: this.get('crop'),
- position: this.get('position'),
- protect: this.get('protect'),
- upsize: this.get('upsize')
- };
- // Preloader
- this._nextImagePreloader = new Y.FL.SlideshowImage(imageConfig);
- // Nav buttons not needed for touch
- if(this._isMobile()) {
- this._removeNavButton('prevPage');
- this._removeNavButton('nextPage');
- this._removeNavButton('fullscreen');
- }
- // Fullscreen
- if(this._hasNavButton('fullscreen')) {
- if(Y.FL.SlideshowFullscreen.OS_SUPPORT) {
- this.plug(Y.FL.SlideshowFullscreen);
- }
- else {
- this._removeNavButton('fullscreen');
- }
- }
- },
- /**
- * Calls the FL.SlideshowBase superclass renderUI method
- * and renders the child widgets.
- *
- * @method renderUI
- * @protected
- */
- renderUI: function()
- {
- Y.FL.Slideshow.superclass.renderUI.apply(this, arguments);
- this._renderFrame();
- this._renderVerticalThumbs();
- this._renderNavAndThumbs();
- this._renderImageNav();
- this._renderMouseNav();
- this._renderCaption();
- this._renderSocial();
- },
- /**
- * Calls the FL.SlideshowBase superclass bindUI method, binds
- * _resizeChildWidgets to fire after the resize method inherited
- * from FL.SlideshowBase, shows the loading image, binds overlay events
- * and binds an event to load an image into the frame.
- *
- * @method bindUI
- * @protected
- */
- bindUI: function()
- {
- var ssBB = this.get('boundingBox'),
- frameBB = this.frame.get('boundingBox'),
- navOverlay = this.get('navOverlay'),
- navType = this.get('navType'),
- nav = this._getNav(),
- clickAction = this.get('clickAction');
- // Call superclass bindUI
- Y.FL.Slideshow.superclass.bindUI.apply(this, arguments);
- // Resize child widgets after the superclass resize method.
- Y.Do.after(this._resizeChildWidgets, this, 'resize');
- // Loading events
- this.on('albumLoadStart', this._albumLoadStart, this);
- this.on('albumLoadComplete', this._albumLoadComplete, this);
- this.on('imageLoadComplete', this._loadFrame, this);
- // Loading image
- if(this.get('loadingImageAlwaysEnabled')) {
- this.frame.on('transitionInit', Y.bind(this._showLoadingImageWithDelay, this));
- this.frame.on('transitionStart', Y.bind(this._hideLoadingImage, this));
- }
- // Overlay events
- if(this.get('overlayHideOnMousemove')) {
- if(nav && navOverlay) {
- this.frame.once('transitionComplete', nav.slideshowOverlay.hideWithTimer, nav.slideshowOverlay);
- ssBB.on('mousemove', Y.bind(this._toggleNav, this));
- }
- if(navType == 'buttons' || navType == 'thumbs' || navType == 'custom') {
- ssBB.on('mouseenter', Y.bind(this._checkOverlaysOnMouseenter, this));
- ssBB.on('mouseleave', Y.bind(this._hideAllOverlays, this));
- }
- }
- ssBB.delegate('click', Y.bind(this._overlayCloseClick, this), '.fl-slideshow-overlay-close');
- // Click action
- if(clickAction == 'gallery' || clickAction == 'url') {
- frameBB.delegate('click', Y.bind(this._frameClick, this), '.fl-slideshow-image-img');
- }
- },
- /**
- * Calls the FL.SlideshowBase superclass syncUI method
- * and makes the bounding box unselectable.
- *
- * @method syncUI
- * @protected
- */
- syncUI: function()
- {
- var bb = this.get('boundingBox');
- Y.FL.Slideshow.superclass.syncUI.apply(this, arguments);
- bb._node.onselectstart = function() { return false; };
- bb._node.unselectable = "on";
- bb._node.style.MozUserSelect = "none";
- if(this.get('clickAction') != 'none') {
- this.frame.get('boundingBox').addClass('fl-click-action-enabled');
- }
- },
- /**
- * Checks to see if the current device is mobile.
- *
- * @since 1.9.3
- * @access private
- * @method _isMobile
- * @return {Boolean}
- */
- _isMobile: function()
- {
- return /Mobile|Android|Silk\/|Kindle|BlackBerry|Opera Mini|Opera Mobi|webOS/i.test( navigator.userAgent );
- },
- /**
- * Unload all slideshow images and pause
- * the slideshow.
- *
- * @method unload
- */
- unload: function()
- {
- this.pause();
- this.frame.unload();
- if(this.thumbs !== null) {
- this.thumbs.unload();
- }
- },
- /**
- * @method _albumLoadStart
- * @protected
- */
- _albumLoadStart: function()
- {
- this._showLoadingImage();
- },
- /**
- * @method _albumLoadComplete
- * @protected
- */
- _albumLoadComplete: function()
- {
- this.frame.once('transitionStart', Y.bind(this._hideLoadingImage, this));
- },
- /**
- * Resizes all enabled child widgets.
- *
- * @method _resizeChildWidgets
- * @protected
- */
- _resizeChildWidgets: function()
- {
- var bb = this.get('boundingBox'),
- cb = this.get('contentBox'),
- imageNavEnabled = this.get('imageNavEnabled');
- this._renderNavAndThumbs();
- if(this.get('verticalThumbsOverlay')) {
- this._resizeFrame(cb.get('offsetWidth'), bb.get('offsetHeight'));
- this._resizeVerticalThumbs();
- }
- else {
- this._resizeVerticalThumbs();
- this._resizeFrame(cb.get('offsetWidth'), bb.get('offsetHeight'));
- }
- if(imageNavEnabled) {
- this._positionImageNav();
- }
- this._positionLoadingImage();
- },
- /**
- * @method _renderVerticalThumbs
- * @protected
- */
- _renderVerticalThumbs: function()
- {
- var threshold = this.get('responsiveThreshold'),
- ssBB = this.get('boundingBox'),
- bbWidth = ssBB.get('offsetWidth'),
- vtBB;
- if(this.get('verticalThumbsEnabled') && bbWidth > threshold) {
- this.verticalThumbs = new Y.FL.SlideshowThumbs(this._getVerticalThumbsConfig());
- this.add(this.verticalThumbs);
- this.verticalThumbs.render(ssBB);
- vtBB = this.verticalThumbs.get('boundingBox');
- vtBB.addClass('fl-slideshow-vertical-thumbs');
- vtBB.setStyle(this.get('verticalThumbsPosition'), 0);
- ssBB.append(vtBB);
- if(this.get('verticalThumbsOverlay')) {
- this.verticalThumbs.plug(Y.FL.SlideshowOverlay, {
- hideDelay: this.get('overlayHideDelay'),
- hideStyle: 'left'
- });
- this.frame.get('boundingBox').append(vtBB);
- this.verticalThumbs.resize();
- }
- else {
- this.verticalThumbs.resize();
- this._adjustContentForVerticalThumbs();
- }
- this._bindVerticalThumbs();
- }
- },
- /**
- * Prepares and returns the vertical thumbs config object.
- *
- * @method _getVerticalThumbsConfig
- * @protected
- * @returns Object
- */
- _getVerticalThumbsConfig: function()
- {
- var attrs = this.getAttrs(),
- config = {
- columns: attrs.verticalThumbsColumns,
- rows: 'auto',
- centerSinglePage: false,
- horizontalSpacing: attrs.verticalThumbsHorizontalSpacing,
- verticalSpacing: attrs.verticalThumbsVerticalSpacing,
- spaceEvenly: attrs.verticalThumbsSpaceEvenly,
- rightNavEnabled: false,
- leftNavEnabled: false,
- topNavEnabled: attrs.verticalThumbsTopNavEnabled,
- topNavButtons: attrs.verticalThumbsTopNavButtons,
- bottomNavEnabled: attrs.verticalThumbsBottomNavEnabled,
- bottomNavButtons: attrs.verticalThumbsBottomNavButtons,
- pauseOnClick: attrs.verticalThumbsPauseOnClick,
- transition: attrs.verticalThumbsTransition,
- transitionDirection: attrs.verticalThumbsTransitionDirection,
- transitionEasing: attrs.verticalThumbsTransitionEasing,
- touchSupport: true,
- imageConfig: {
- crop: attrs.verticalThumbsImageCrop,
- width: attrs.verticalThumbsImageWidth,
- height: attrs.verticalThumbsImageHeight
- }
- };
- return config;
- },
- _bindVerticalThumbs: function()
- {
- var ssBB = this.get('boundingBox'),
- hideOnMouse = this.get('overlayHideOnMousemove'),
- vtOverlay = this.get('verticalThumbsOverlay'),
- vt = this.verticalThumbs;
- if(vt && hideOnMouse && vtOverlay) {
- this.frame.once('transitionComplete', vt.slideshowOverlay.hideWithTimer, vt.slideshowOverlay);
- ssBB.on('mousemove', Y.bind(this._toggleVerticalThumbs, this));
- ssBB.on('mouseenter', Y.bind(this._toggleVerticalThumbs, this));
- }
- },
- /**
- * Resizes the vertical thumbs.
- *
- * @method _resizeVerticalThumbs
- * @protected
- */
- _resizeVerticalThumbs: function()
- {
- var vtEnabled = this.get('verticalThumbsEnabled'),
- vtOverlay,
- threshold,
- ssBB,
- bbWidth,
- navOverlay,
- navType,
- nav,
- navBB;
- if(vtEnabled) {
- vtOverlay = this.get('verticalThumbsOverlay');
- threshold = this.get('responsiveThreshold');
- ssBB = this.get('boundingBox');
- bbWidth = ssBB.get('offsetWidth');
- navOverlay = this.get('navOverlay');
- navType = this.get('navType');
- nav = this._getNav();
- if(this.verticalThumbs && bbWidth > threshold) {
- this.verticalThumbs.get('boundingBox').setStyle('display', 'block');
- this.verticalThumbs.resize();
- if(!vtOverlay) {
- this._adjustContentForVerticalThumbs();
- }
- else if(nav && navOverlay) {
- navBB = nav.get('boundingBox');
- if(navType == 'thumbs') {
- this._adjustOverlayForVerticalThumbs(navBB, true);
- this.thumbs.resize();
- }
- else {
- this._adjustOverlayForVerticalThumbs(navBB);
- }
- }
- }
- else if(!this.verticalThumbs && bbWidth > threshold) {
- this._renderVerticalThumbs();
- }
- else if(this.verticalThumbs && bbWidth <= threshold) {
- this.verticalThumbs.get('boundingBox').setStyle('display', 'none');
- if(!vtOverlay) {
- this.get('contentBox').setStyles({
- left: 'auto',
- position: 'relative',
- right: 'auto',
- width: 'auto'
- });
- }
- }
- }
- },
- /**
- * Toggles the visibility of the vertical thumbs.
- *
- * @method _toggleVerticalThumbs
- * @protected
- */
- _toggleVerticalThumbs: function()
- {
- if(this.verticalThumbs) {
- if(this.verticalThumbs.slideshowOverlay._visible) {
- this.verticalThumbs.slideshowOverlay.hideWithTimer();
- }
- else {
- this.verticalThumbs.slideshowOverlay.show();
- }
- }
- },
- /**
- * Adjusts the content position and width
- * for the vertical thumbs.
- *
- * @method _adjustContentForVerticalThumbs
- * @protected
- */
- _adjustContentForVerticalThumbs: function()
- {
- var ssBB = this.get('boundingBox'),
- vtBB = this.verticalThumbs.get('boundingBox'),
- vtPos = this.get('verticalThumbsPosition'),
- ssCB = this.get('contentBox'),
- cbPos = vtPos == 'left' ? 'right' : 'left',
- cbWidth = ssBB.get('offsetWidth') - vtBB.get('offsetWidth');
- ssCB.setStyle('position', 'absolute');
- ssCB.setStyle(cbPos, 0);
- ssCB.setStyle('width', cbWidth);
- },
- /**
- * Adjusts an overlay's position for the vertical
- * thumbs when they are overlaid as well.
- *
- * @method _adjustOverlayForVerticalThumbs
- * @protected
- */
- _adjustOverlayForVerticalThumbs: function(node, useMargin)
- {
- var vtEnabled = this.get('verticalThumbsEnabled'),
- vtOverlay = this.get('verticalThumbsOverlay'),
- vtBB = null,
- vtPos = null,
- margin = typeof useMargin === 'undefined' ? '' : 'margin-',
- vtWidth = 0;
- if(this.verticalThumbs && vtEnabled && vtOverlay) {
- vtBB = this.verticalThumbs.get('boundingBox');
- vtWidth = vtBB.get('offsetWidth');
- vtPos = this.get('verticalThumbsPosition');
- if(vtPos == 'left') {
- node.setStyle(margin + 'left', vtWidth + 'px');
- }
- else {
- node.setStyle(margin + 'right', vtWidth + 'px');
- }
- }
- },
- /**
- * Creates and renders a new instance of FL.SlideshowFrame
- * used for the main image.
- *
- * @method _renderFrame
- * @protected
- */
- _renderFrame: function()
- {
- this.frame = new Y.FL.SlideshowFrame({
- imageConfig: {
- loadGroup: 'main',
- loadPriority: true,
- crop: this.get('crop'),
- cropHorizontalsOnly: this.get('cropHorizontalsOnly'),
- position: this.get('position'),
- protect: this.get('protect'),
- upsize: this.get('upsize'),
- showVideoButton: this.get('navOverlay')
- },
- touchSupport: this.get('touchSupport')
- });
- this.add(this.frame);
- this.frame.render(this.get('contentBox'));
- this.frame.get('boundingBox').addClass('fl-slideshow-main-image');
- this._setPlayingTimerEvent(this.frame, 'transitionComplete');
- this._loadingImageContainer = this.frame.get('contentBox');
- },
- /**
- * Resizes the frame used for the main image.
- *
- * @method _resizeMainImage
- * @param width {Number} The width to resize to.
- * @param height {Number} The height to resize to.
- * @protected
- */
- _resizeFrame: function(width, height)
- {
- var navOverlay = this.get('navOverlay'),
- nav = this._getNav();
- if(nav && !navOverlay) {
- height -= parseInt(nav.get('boundingBox').getComputedStyle('height'), 10);
- }
- this.frame.resize(width, height);
- },
- /**
- * Called when the imageLoadComplete event fires.
- * Loads an image into the frame and preloads the next image.
- *
- * @method _loadFrame
- * @param e {Object} Event object containing the image info.
- * @protected
- */
- _loadFrame: function(e)
- {
- var activeIndex = this.imageInfo.index,
- images = this.albumInfo.images,
- nextIndex = activeIndex + 1 >= images.length ? 0 : activeIndex + 1,
- width = this.frame.get('width'),
- height = this.frame.get('height');
- // Load the frame.
- this.frame.load(e.imageInfo);
- // Remove main preload images from the load queue.
- Y.FL.SlideshowImageLoader.removeGroup('main-preload');
- // Preload the next image.
- this._nextImagePreloader.preload(images[nextIndex], width, height);
- },
- /**
- * Fired when the frame img tag is clicked.
- *
- * @method _frameClick
- * @protected
- */
- _frameClick: function()
- {
- var clickAction = this.get('clickAction'),
- clickActionUrl = this.get('clickActionUrl');
- if(clickAction == 'url') {
- window.location.href = clickActionUrl;
- }
- else if(clickAction == 'gallery') {
- window.location.href = this.imageInfo.link;
- }
- },
- /**
- * Sets attributes to display a compact nav
- * for responsive layouts.
- *
- * @method _initMiniNav
- * @protected
- */
- _initMiniNav: function()
- {
- var buttons = [];
- if(this._hasNavButton('prev')) {
- buttons.push('prev');
- }
- if(this._hasNavButton('thumbs') || this.get('navType') == 'thumbs') {
- buttons.push('thumbs');
- }
- if(this._hasNavButton('caption')) {
- buttons.push('caption');
- }
- if(this._hasNavButton('social')) {
- buttons.push('social');
- }
- if(this._hasNavButton('buy')) {
- buttons.push('buy');
- }
- if(this._hasNavButton('play')) {
- buttons.push('play');
- }
- if(this._hasNavButton('fullscreen') && !('ontouchstart' in window)) {
- buttons.push('fullscreen');
- }
- if(this._hasNavButton('next')) {
- buttons.push('next');
- }
- this._initialNavSettings = {
- buttons: this.get('navButtons'),
- buttonsLeft: this.get('navButtonsLeft'),
- buttonsRight: this.get('navButtonsRight'),
- type: this.get('navType')
- };
- this._set('navButtons', buttons);
- this._set('navButtonsLeft', []);
- this._set('navButtonsRight', []);
- this._set('navType', 'buttons');
- },
- /**
- * Renders the nav and thumbs layout based on the
- * current window size.
- *
- * @method _renderNavAndThumbs
- * @protected
- */
- _renderNavAndThumbs: function()
- {
- var navType = this.get('navType'),
- renderNav = false,
- bbWidth,
- threshold;
- if(navType == 'buttons' || navType == 'thumbs') {
- bbWidth = this.get('boundingBox').get('offsetWidth');
- threshold = this.get('responsiveThreshold');
- if(bbWidth <= threshold && this._initialNavSettings === null) {
- this._initMiniNav();
- renderNav = true;
- }
- else if(bbWidth > threshold && this._initialNavSettings !== null) {
- this._set('navButtons', this._initialNavSettings.buttons);
- this._set('navButtonsLeft', this._initialNavSettings.buttonsLeft);
- this._set('navButtonsRight', this._initialNavSettings.buttonsRight);
- this._set('navType', this._initialNavSettings.type);
- this._initialNavSettings = null;
- renderNav = true;
- }
- // Button nav
- if(renderNav || this.nav === null) {
- this._renderNav();
- }
- // Thumbs nav
- if(renderNav || this.thumbs === null) {
- this._renderThumbs();
- }
- else if(this._thumbsEnabled()) {
- this._resizeThumbs();
- }
- // Caption
- if(renderNav && this.caption !== null) {
- this._syncCaption();
- }
- // Social
- if(renderNav && this.social !== null) {
- this._syncSocial();
- }
- }
- },
- /**
- * Creates and renders a new instance of FL.SlideshowNav
- * used for the main nav.
- *
- * @method _renderNav
- * @protected
- */
- _renderNav: function()
- {
- var frameBB = this.frame.get('boundingBox'),
- navBB = null,
- navOverlay = this.get('navOverlay'),
- navPosition = this.get('navPosition');
- // Destroy old instances
- this._destroyNav();
- // Create a new instance
- if(this.get('navType') == 'buttons') {
- // Create the nav
- this.nav = new Y.FL.SlideshowNav({
- buttons: this.get('navButtons'),
- buttonsLeft: this.get('navButtonsLeft'),
- buttonsRight: this.get('navButtonsRight')
- });
- // Add to widget parent and render
- this.add(this.nav);
- this.nav.render(this.get('contentBox'));
- navBB = this.nav.get('boundingBox');
- // Plug overlay?
- if(navOverlay) {
- this.nav.plug(Y.FL.SlideshowOverlay, {
- hideDelay: this.get('overlayHideDelay')
- });
- navBB.setStyle('position', 'absolute');
- navBB.setStyle(navPosition, '0px');
- }
- // Insert
- if(navPosition == 'top') {
- frameBB.insert(navBB, 'before');
- }
- else {
- frameBB.insert(navBB, 'after');
- }
- // CSS class name
- navBB.addClass('fl-slideshow-main-nav');
- }
- },
- /**
- * Destroy the current nav instance.
- *
- * @method _destroyNav
- * @protected
- */
- _destroyNav: function()
- {
- if(this.nav !== null) {
- if(this.nav.slideshowOverlay) {
- this.nav.slideshowOverlay.destroy();
- }
- this.nav.get('boundingBox').remove();
- this.remove(this.nav);
- try { this.nav.destroy(true); } catch(e) {}
- this.nav = null;
- }
- },
- /**
- * Returns the nav object or null if navType is
- * set to none or custom.
- *
- * @method _getNav
- * @protected
- */
- _getNav: function()
- {
- var navType = this.get('navType');
- if(navType == 'buttons') {
- return this.nav;
- }
- else if(navType == 'thumbs') {
- return this.thumbs;
- }
- else {
- return null;
- }
- },
- /**
- * Toggles the visibility of the nav or thumbs nav
- * if navOverlay is set to true.
- *
- * @method _toggleNav
- * @protected
- */
- _toggleNav: function()
- {
- var nav = this._getNav();
- if(nav.slideshowOverlay) {
- if(nav.slideshowOverlay._visible) {
- nav.slideshowOverlay.hideWithTimer();
- }
- else {
- nav.slideshowOverlay.show();
- }
- }
- },
- /**
- * Creates and renders two instances of FL.SlideshowNav for the
- * prev and next button that will be overlaid on the main image.
- *
- * @method _renderImageNav
- * @protected
- */
- _renderImageNav: function()
- {
- var ssBB;
- if(this.get('imageNavEnabled')) {
- if(this._isMobile()) {
- this._set('imageNavEnabled', false);
- }
- else {
- ssBB = this.get('boundingBox');
- this.imageNavLeft = new Y.FL.SlideshowNav({
- buttons: ['prev'],
- useFontIcons: false
- });
- this.imageNavRight = new Y.FL.SlideshowNav({
- buttons: ['next'],
- useFontIcons: false
- });
- this.add(this.imageNavLeft);
- this.add(this.imageNavRight);
- this.imageNavLeft.render(this.frame.get('boundingBox'));
- this.imageNavRight.render(this.frame.get('boundingBox'));
- this.imageNavLeft.plug(Y.FL.SlideshowOverlay, { hideDelay: this.get('overlayHideDelay') });
- this.imageNavRight.plug(Y.FL.SlideshowOverlay, { hideDelay: this.get('overlayHideDelay') });
- if(this.get('overlayHideOnMousemove')) {
- this.frame.once('transitionComplete', this.imageNavLeft.slideshowOverlay.hideWithTimer, this.imageNavLeft.slideshowOverlay);
- this.frame.once('transitionComplete', this.imageNavRight.slideshowOverlay.hideWithTimer, this.imageNavRight.slideshowOverlay);
- ssBB.on('mousemove', Y.bind(this._toggleImageNav, this));
- ssBB.on('mouseenter', Y.bind(this._toggleImageNav, this));
- }
- this.imageNavLeft.get('boundingBox').addClass('fl-slideshow-image-nav-left');
- this.imageNavRight.get('boundingBox').addClass('fl-slideshow-image-nav-right');
- }
- }
- },
- /**
- * @method _positionImageNav
- * @protected
- */
- _positionImageNav: function()
- {
- var leftBB = this.imageNavLeft.get('boundingBox'),
- rightBB = this.imageNavRight.get('boundingBox'),
- imageNavHeight = leftBB.get('offsetHeight'),
- frameHeight = this.frame.get('boundingBox').get('offsetHeight'),
- top = frameHeight/2 - imageNavHeight/2,
- styles = {
- top: top + 'px',
- display: 'block'
- };
- leftBB.setStyles(styles);
- rightBB.setStyles(styles);
- this._adjustOverlayForVerticalThumbs(leftBB);
- this._adjustOverlayForVerticalThumbs(rightBB);
- },
- /**
- * Toggles the visibility of the image nav buttons.
- *
- * @method _toggleImageNav
- * @protected
- */
- _toggleImageNav: function()
- {
- if(this.imageNavLeft.slideshowOverlay._visible) {
- this.imageNavLeft.slideshowOverlay.hideWithTimer();
- }
- else {
- this.imageNavLeft.slideshowOverlay.show();
- }
- if(this.imageNavRight.slideshowOverlay._visible) {
- this.imageNavRight.slideshowOverlay.hideWithTimer();
- }
- else {
- this.imageNavRight.slideshowOverlay.show();
- }
- },
- /**
- * @method _renderMouseNav
- * @protected
- */
- _renderMouseNav: function()
- {
- if(this.get('mouseNavEnabled') && !('ontouchstart' in window) && !window.navigator.msPointerEnabled) {
- this.plug(Y.FL.SlideshowMouseNav, {
- trigger: this.frame.get('boundingBox')
- });
- }
- },
- /**
- * Checks whether the thumbs are enabled.
- *
- * @method _thumbsEnabled
- * @protected
- * @returns Boolean
- */
- _thumbsEnabled: function()
- {
- var navType = this.get('navType');
- if(navType == 'thumbs') {
- return true;
- }
- if((navType == 'buttons' || navType == 'custom') && this._hasNavButton('thumbs')) {
- return true;
- }
- else {
- return false;
- }
- },
- /**
- * Creates and renders a new instance of FL.SlideshowThumbs.
- *
- * @method _renderThumbs
- * @protected
- */
- _renderThumbs: function()
- {
- var frameBB, navOverlay, navPosition, navType;
- // Destroy old instances
- this._destroyThumbs();
- // Create a new instance
- if(this._thumbsEnabled()) {
- frameBB = this.frame.get('boundingBox');
- navOverlay = this.get('navOverlay');
- navPosition = this.get('navPosition');
- navType = this.get('navType');
- // Create the thumbs
- this.thumbs = new Y.FL.SlideshowThumbs(this._getThumbsConfig());
- // This breaks sometimes on SM Next. Try/catch bandaid for now.
- try { this.add(this.thumbs); } catch(e) {}
- // Overlay setup
- if(navType == 'buttons' || navType == 'custom') {
- this.thumbs.plug(Y.FL.SlideshowOverlay, {
- hideDelay: this.get('overlayHideDelay'),
- hideStyle: 'left',
- visible: false
- });
- }
- else if(navType == 'thumbs' && navOverlay) {
- this.thumbs.plug(Y.FL.SlideshowOverlay, {
- hideDelay: this.get('overlayHideDelay'),
- hideStyle: 'left'
- });
- }
- // Insert
- this.thumbs.render(this.get('contentBox'));
- if(navPosition == 'top') {
- frameBB.insert(this.thumbs.get('boundingBox'), 'before');
- }
- else {
- frameBB.insert(this.thumbs.get('boundingBox'), 'after');
- }
- // Hide overlay thumbs on click
- if(this.get('thumbsHideOnClick') && navType != 'thumbs') {
- this.thumbs.on('imageClick', Y.bind(this._hideThumbsOnImageClick, this));
- }
- this._syncThumbs();
- }
- },
- /**
- * Destroy the current thumbs instance.
- *
- * @method _destroyThumbs
- * @protected
- */
- _destroyThumbs: function()
- {
- if(this.thumbs !== null) {
- if(this.thumbs.slideshowOverlay) {
- this.thumbs.slideshowOverlay.destroy();
- }
- this.thumbs.get('boundingBox').remove();
- this.remove(this.thumbs);
- try { this.thumbs.destroy(true); } catch(e) {}
- this.thumbs = null;
- }
- },
- /**
- * Syncs the thumbs UI styles.
- *
- * @method _syncThumbs
- * @protected
- */
- _syncThumbs: function()
- {
- var thumbsBB = this.thumbs.get('boundingBox'),
- navOverlay = this.get('navOverlay'),
- navPosition = this.get('navPosition'),
- navType = this.get('navType'),
- paddingType = 'padding' + navPosition.charAt(0).toUpperCase() + navPosition.slice(1),
- navHeight = 0;
- if(navType == 'buttons') {
- navHeight = parseInt(this.nav.get('boundingBox').getComputedStyle('height'), 10);
- thumbsBB.setStyle('position', 'absolute');
- if(navOverlay) {
- thumbsBB.setStyle(paddingType, navHeight + 'px');
- thumbsBB.setStyle(navPosition, '0px');
- }
- else {
- thumbsBB.setStyle(navPosition, navHeight + 'px');
- }
- }
- if(navType == 'custom' || (navType == 'thumbs' && navOverlay)) {
- thumbsBB.setStyle('position', 'absolute');
- thumbsBB.setStyle(navPosition, '0px');
- }
- this.thumbs.resize();
- },
- /**
- * Prepares and returns the thumbs config object.
- *
- * @method _getThumbsConfig
- * @protected
- * @returns Object
- */
- _getThumbsConfig: function()
- {
- var attrs = this.getAttrs(),
- navType = this.get('navType'),
- imageConfig = {
- crop: attrs.thumbsImageCrop,
- width: attrs.thumbsImageWidth,
- height: attrs.thumbsImageHeight
- },
- config = {
- columns: 'auto',
- rows: 1,
- horizontalSpacing: attrs.thumbsHorizontalSpacing,
- verticalSpacing: attrs.thumbsVerticalSpacing,
- spaceEvenly: attrs.thumbsSpaceEvenly,
- centerSinglePage: attrs.thumbsCenterSinglePage,
- pauseOnClick: attrs.thumbsPauseOnClick,
- transition: attrs.thumbsTransition,
- transitionDirection: attrs.thumbsTransitionDirection,
- transitionEasing: attrs.thumbsTransitionEasing,
- leftNavButtons: attrs.navButtonsLeft,
- rightNavButtons: attrs.navButtonsRight,
- imageConfig: imageConfig,
- touchSupport: true
- };
- if(navType == 'buttons' || navType == 'custom') {
- if('ontouchstart' in window) {
- config.leftNavEnabled = false;
- config.rightNavEnabled = false;
- }
- else {
- config.centerSinglePage = false;
- config.leftNavButtons = ['prevPage'];
- config.rightNavButtons = ['nextPage'];
- }
- }
- return config;
- },
- /**
- * Resizes the thumbs.
- *
- * @method _resizeThumbs
- * @protected
- */
- _resizeThumbs: function()
- {
- if(this.thumbs) {
- this.thumbs.resize();
- }
- },
- /**
- * Shows or hides the thumbs.
- *
- * @method _toggleThumbs
- * @protected
- */
- _toggleThumbs: function()
- {
- this._toggleOverlay(this.thumbs.slideshowOverlay);
- },
- /**
- * Hides the thumbs when a thumb image is clicked.
- *
- * @method _hideThumbsOnImageClick
- * @protected
- */
- _hideThumbsOnImageClick: function()
- {
- if(this.thumbs.slideshowOverlay) {
- this.thumbs.slideshowOverlay._focus = false;
- this.thumbs.slideshowOverlay.enable();
- this.thumbs.slideshowOverlay.hide();
- if(this.nav && this.nav.slideshowOverlay) {
- this.nav.slideshowOverlay.enable();
- }
- }
- },
- /**
- * Creates and renders a new instance of FL.SlideshowCaption.
- *
- * @method _renderCaption
- * @protected
- */
- _renderCaption: function()
- {
- if(this._hasNavButton('caption')) {
- this.caption = new Y.FL.SlideshowCaption({
- lessLinkText: this.get('captionLessLinkText'),
- moreLinkText: this.get('captionMoreLinkText'),
- textLength: this.get('captionTextLength'),
- stripTags: this.get('captionStripTags')
- });
- this.add(this.caption);
- this.caption.plug(Y.FL.SlideshowOverlay, {
- hideDelay: this.get('overlayHideDelay'),
- visible: false,
- closeButton: true
- });
- this._syncCaption();
- }
- },
- /**
- * Syncs the caption UI styles.
- *
- * @method _syncCaption
- * @protected
- */
- _syncCaption: function()
- {
- var captionBB = this.caption.get('boundingBox'),
- navOverlay = this.get('navOverlay'),
- navPosition = this.get('navPosition'),
- nav = this._getNav(),
- paddingType = 'padding' + navPosition.charAt(0).toUpperCase() + navPosition.slice(1),
- navHeight = 0;
- captionBB.setStyle('position', 'absolute');
- if(nav) {
- navHeight = parseInt(nav.get('boundingBox').getComputedStyle('height'), 10);
- }
- if(nav && navOverlay) {
- captionBB.setStyle(paddingType, navHeight + 'px');
- captionBB.setStyle(navPosition, '0px');
- }
- else {
- captionBB.setStyle(navPosition, navHeight + 'px');
- }
- },
- /**
- * Shows or hides the caption.
- *
- * @method _toggleCaption
- * @protected
- */
- _toggleCaption: function()
- {
- this._toggleOverlay(this.caption.slideshowOverlay);
- },
- /**
- * Creates and renders a new instance of FL.SlideshowSocial.
- *
- * @method _renderSocial
- * @protected
- */
- _renderSocial: function()
- {
- if(this._hasNavButton('social')) {
- this.social = new Y.FL.SlideshowSocial();
- this.add(this.social);
- this.social.plug(Y.FL.SlideshowOverlay, {
- hideDelay: this.get('overlayHideDelay'),
- visible: false,
- closeButton: true
- });
- this._syncSocial();
- }
- },
- /**
- * Syncs the social UI styles.
- *
- * @method _syncSocial
- * @protected
- */
- _syncSocial: function()
- {
- var socialBB = this.social.get('boundingBox'),
- navOverlay = this.get('navOverlay'),
- navPosition = this.get('navPosition'),
- nav = this._getNav(),
- paddingType = 'padding' + navPosition.charAt(0).toUpperCase() + navPosition.slice(1),
- navHeight = 0;
- socialBB.setStyle('position', 'absolute');
- if(nav) {
- navHeight = parseInt(nav.get('boundingBox').getComputedStyle('height'), 10);
- }
- if(nav && navOverlay) {
- socialBB.setStyle(paddingType, navHeight + 'px');
- socialBB.setStyle(navPosition, '0px');
- }
- else {
- socialBB.setStyle(navPosition, navHeight + 'px');
- }
- },
- /**
- * Shows or hides the social buttons.
- *
- * @method _toggleSocial
- * @protected
- */
- _toggleSocial: function()
- {
- this._toggleOverlay(this.social.slideshowOverlay);
- // Refresh iframe to fix tweet button issue visibility inside hidden elements
- var iFrame = jQuery('.fl-slideshow-social-content').find('iframe');
- iFrame.remove();
- jQuery('.fl-slideshow-social-content').prepend(iFrame);
- },
- /**
- * Shows or hides an overlaid widget based
- * on its current visibility.
- *
- * @method _toggleOverlay
- * @param overlay {Object} The overlay to toggle.
- * @protected
- */
- _toggleOverlay: function(overlay)
- {
- var navType = this.get('navType'),
- nav = this._getNav();
- if(overlay._visible) {
- if(nav && nav.slideshowOverlay) {
- nav.slideshowOverlay.enable();
- }
- overlay.enable();
- overlay.hide();
- }
- else {
- if(nav && nav.slideshowOverlay) {
- nav.slideshowOverlay.disable();
- }
- overlay.show();
- overlay.disable();
- }
- if(this.thumbs && navType != 'thumbs' && this.thumbs.slideshowOverlay !== overlay) {
- this.thumbs.slideshowOverlay.enable();
- this.thumbs.slideshowOverlay.hide();
- }
- if(this.caption && this.caption.slideshowOverlay !== overlay) {
- this.caption.slideshowOverlay.enable();
- this.caption.slideshowOverlay.hide();
- }
- if(this.social && this.social.slideshowOverlay !== overlay) {
- this.social.slideshowOverlay.enable();
- this.social.slideshowOverlay.hide();
- }
- },
- /**
- * Called when an overlay's close button is clicked.
- *
- * @method _overlayCloseClick
- * @protected
- */
- _overlayCloseClick: function()
- {
- if(this.nav && this.nav.slideshowOverlay) {
- this.nav.slideshowOverlay.enable();
- }
- if(this.thumbs && this.thumbs.slideshowOverlay) {
- this.thumbs.slideshowOverlay.enable();
- }
- if(this.caption) {
- this.caption.slideshowOverlay.enable();
- }
- if(this.social) {
- this.social.slideshowOverlay.enable();
- }
- if(this.imageNavLeft) {
- this.imageNavLeft.slideshowOverlay.enable();
- this.imageNavRight.slideshowOverlay.enable();
- }
- },
- /**
- * Hides all overlaid widgets.
- *
- * @method _hideAllOverlays
- * @protected
- */
- _hideAllOverlays: function()
- {
- if(this.nav && this.nav.slideshowOverlay && this.nav.slideshowOverlay._visible) {
- this.nav.slideshowOverlay.enable();
- this.nav.slideshowOverlay.hideWithTimer();
- }
- if(this.thumbs && this.thumbs.slideshowOverlay && this.thumbs.slideshowOverlay._visible) {
- this.thumbs.slideshowOverlay.enable();
- this.thumbs.slideshowOverlay.hideWithTimer();
- }
- if(this.caption && this.caption.slideshowOverlay._visible) {
- this.caption.slideshowOverlay.enable();
- this.caption.slideshowOverlay.hideWithTimer();
- }
- if(this.social && this.social.slideshowOverlay._visible) {
- this.social.slideshowOverlay.enable();
- this.social.slideshowOverlay.hideWithTimer();
- }
- if(this.imageNavLeft) {
- this.imageNavLeft.slideshowOverlay.enable();
- this.imageNavLeft.slideshowOverlay.hideWithTimer();
- this.imageNavRight.slideshowOverlay.enable();
- this.imageNavRight.slideshowOverlay.hideWithTimer();
- }
- },
- /**
- * Checks if overlays are still visible when the mouse enters
- * the bounding box. If they are, overlay functionality is disabled
- * until the overlays are closed by a button or the mouse leaves
- * the bounding box. If only the nav overlay is visible, this
- * function does nothing.
- *
- * @method _checkOverlaysOnMouseenter
- * @protected
- */
- _checkOverlaysOnMouseenter: function()
- {
- var navType = this.get('navType'),
- navOverlay = this.get('navOverlay'),
- nav = this._getNav(),
- overlayVisible = false;
- if(this.thumbs && navType != 'thumbs' && this.thumbs.slideshowOverlay._visible) {
- overlayVisible = true;
- this.thumbs.slideshowOverlay.disable();
- }
- else if(this.caption && this.caption.slideshowOverlay._visible) {
- overlayVisible = true;
- this.caption.slideshowOverlay.disable();
- }
- else if(this.social && this.social.slideshowOverlay._visible) {
- overlayVisible = true;
- this.social.slideshowOverlay.disable();
- }
- if(nav && overlayVisible && navOverlay) {
- nav.slideshowOverlay.disable();
- }
- },
- /**
- * Checks whether a nav button is set or not.
- *
- * @method _hasNavButton
- * @protected
- * @param button {String} The button to look for.
- * @returns Boolean
- */
- _hasNavButton: function(button)
- {
- var navType = this.get('navType');
- if(navType == 'buttons' || navType == 'thumbs' || navType == 'custom') {
- if(Y.Array.indexOf(this.get('navButtons'), button) > -1) {
- return true;
- }
- else if(Y.Array.indexOf(this.get('navButtonsLeft'), button) > -1) {
- return true;
- }
- else if(Y.Array.indexOf(this.get('navButtonsRight'), button) > -1) {
- return true;
- }
- else {
- return false;
- }
- }
- else {
- return false;
- }
- },
- /**
- * @method _removeNavButton
- * @param button {String} The name of the button to remove.
- * @protected
- */
- _removeNavButton: function(button)
- {
- var buttons = this.get('navButtons'),
- buttonsLeft = this.get('navButtonsLeft'),
- buttonsRight = this.get('navButtonsRight'),
- vtTopNavButtons = this.get('verticalThumbsTopNavButtons'),
- vtBottomNavButtons = this.get('verticalThumbsBottomNavButtons');
- if(Y.Array.indexOf(buttons, button) > -1) {
- buttons.splice(Y.Array.indexOf(buttons, button), 1);
- }
- if(Y.Array.indexOf(buttonsLeft, button) > -1) {
- buttonsLeft.splice(Y.Array.indexOf(buttonsLeft, button), 1);
- }
- if(Y.Array.indexOf(buttonsRight, button) > -1) {
- buttonsRight.splice(Y.Array.indexOf(buttonsRight, button), 1);
- }
- if(Y.Array.indexOf(vtTopNavButtons, button) > -1) {
- vtTopNavButtons.splice(Y.Array.indexOf(vtTopNavButtons, button), 1);
- }
- if(Y.Array.indexOf(vtBottomNavButtons, button) > -1) {
- vtBottomNavButtons.splice(Y.Array.indexOf(vtBottomNavButtons, button), 1);
- }
- this._set('navButtons', buttons);
- this._set('navButtonsLeft', buttonsLeft);
- this._set('navButtonsRight', buttonsRight);
- this._set('verticalThumbsTopNavButtons', vtTopNavButtons);
- this._set('verticalThumbsBottomNavButtons', vtBottomNavButtons);
- }
- }, {
- /**
- * Custom CSS class name for the widget.
- *
- * @property CSS_PREFIX
- * @type String
- * @protected
- * @static
- */
- CSS_PREFIX: 'fl-slideshow',
- /**
- * Static property used to define the default attribute configuration of
- * the Widget.
- *
- * @property ATTRS
- * @type Object
- * @protected
- * @static
- */
- ATTRS: {
- /**
- * What should happen when the main image is clicked.
- * Options are none, gallery and url. If url is chosen,
- * clickActionUrl must be set.
- *
- * @attribute clickAction
- * @type String
- * @default none
- */
- clickAction: {
- value: 'none'
- },
- /**
- * The redirect url to use when clickAction is set to url.
- *
- * @attribute clickActionUrl
- * @type String
- * @default none
- */
- clickActionUrl: {
- value: ''
- },
- /**
- * Whether to crop the main image.
- *
- * @attribute crop
- * @type Boolean
- * @default false
- */
- crop: {
- value: false
- },
- /**
- * Whether to only crop horizontal images or not.
- *
- * @attribute cropHorizontalsOnly
- * @type Boolean
- * @default false
- */
- cropHorizontalsOnly: {
- value: false
- },
- /**
- * Whether to always use the loading image between images
- * or to only use it between albums.
- *
- * @attribute loadingImageAlwaysEnabled
- * @type Boolean
- * @default true
- */
- loadingImageAlwaysEnabled: {
- value: true
- },
- /**
- * The x and y position of the main image
- * within the bounding box.
- *
- * @attribute position
- * @type String
- * @default center center
- */
- position: {
- value: 'center center'
- },
- /**
- * Whether to right click protect the main image.
- *
- * @attribute protect
- * @type Boolean
- * @default true
- */
- protect: {
- value: true
- },
- /**
- * Whether to resize the main image past
- * its original width and height.
- *
- * @attribute upsize
- * @type Boolean
- * @default true
- */
- upsize: {
- value: true
- },
- /**
- * The type of transition to use. Possible values are
- * none, fade, slideHorizontal and slideVertical. The
- * value can also be a common seperated string of transitions
- * that will be randomly chosen for each image.
- *
- * @attribute transition
- * @type String
- * @default fade
- */
- transition: {
- value: 'fade'
- },
- /**
- * The duration of the transition, measured in seconds.
- *
- * @attribute transitionDuration
- * @type Number
- * @default 1
- */
- transitionDuration: {
- value: 1
- },
- /**
- * The type of transition easing to use.
- *
- * @attribute transitionEasing
- * @type String
- * @default ease-out
- */
- transitionEasing: {
- value: 'ease-out'
- },
- /**
- * The amount of zoom to use for the Ken Burns effect.
- *
- * @attribute kenBurnsZoom
- * @type Number
- * @default 1.2
- */
- kenBurnsZoom: {
- value: 1.2
- },
- /**
- * The type of navigation to use. Possible values are
- * buttons, thumbs, custon and none.
- *
- * @attribute navType
- * @type String
- * @default none
- */
- navType: {
- value: 'none'
- },
- /**
- * The position of the main nav. Possible values are top and bottom.
- *
- * @attribute navPosition
- * @type String
- * @default bottom
- */
- navPosition: {
- value: 'bottom'
- },
- /**
- * Whether to overlay the nav on top of the main image.
- *
- * @attribute navOverlay
- * @type Boolean
- * @default false
- */
- navOverlay: {
- value: false
- },
- /**
- * An array of button names used to render the main nav's buttons.
- *
- * @attribute navButtons
- * @type Array
- * @default []
- */
- navButtons: {
- value: []
- },
- /**
- * An array of button names used to render the main nav's left buttons.
- *
- * @attribute navButtonsLeft
- * @type Array
- * @default []
- */
- navButtonsLeft: {
- value: []
- },
- /**
- * An array of button names used to render the main nav's right buttons.
- *
- * @attribute navButtonsRight
- * @type Array
- * @default []
- */
- navButtonsRight: {
- value: []
- },
- /**
- * Whether to hide the overlays when the mouse moves or not.
- *
- * @attribute overlayHideOnMousemove
- * @type String
- * @default mouseover
- */
- overlayHideOnMousemove: {
- value: true
- },
- /**
- * How long to wait before hiding the overlays.
- * Measured in milliseconds.
- *
- * @attribute overlayHideDelay
- * @type Number
- * @default false
- */
- overlayHideDelay: {
- value: 3000
- },
- /**
- * Whether to use the image nav or not. If true, a prev
- * and next button will be overlaid on the main image.
- *
- * @attribute imageNavEnabled
- * @type Boolean
- * @default false
- */
- imageNavEnabled: {
- value: false
- },
- /**
- * Whether to use the mouse nav or not. If true, the cursor
- * will turn into a prev or next button when over the slideshow.
- *
- * @attribute mouseNavEnabled
- * @type Boolean
- * @default false
- */
- mouseNavEnabled: {
- value: false
- },
- /**
- * Whether to hide the thumbs when clicking on a thumbnail
- * image or not. Thumbs always hide navType is set to buttons.
- *
- * @attribute thumbsHideOnClick
- * @type Boolean
- * @default false
- */
- thumbsHideOnClick: {
- value: true
- },
- /**
- * The horizontal spacing between thumbs.
- *
- * @attribute thumbsHorizontalSpacing
- * @type Number
- * @default 15
- */
- thumbsHorizontalSpacing: {
- value: 15
- },
- /**
- * The vertical spacing between thumbs.
- *
- * @attribute thumbsVerticalSpacing
- * @type Number
- * @default 15
- */
- thumbsVerticalSpacing: {
- value: 15
- },
- /**
- * Whether to space the thumbs evenly within a page.
- *
- * @attribute thumbsSpaceEvenly
- * @type Boolean
- * @default true
- */
- thumbsSpaceEvenly: {
- value: true
- },
- /**
- * Whether to center single pages of thumbs.
- *
- * @attribute thumbsCenterSinglePage
- * @type Boolean
- * @default false
- */
- thumbsCenterSinglePage: {
- value: true
- },
- /**
- * Whether to pause the slideshow when a thumb is clicked.
- *
- * @attribute thumbsPauseOnClick
- * @type Boolean
- * @default false
- */
- thumbsPauseOnClick: {
- value: false
- },
- /**
- * The type of transition to use between pages of thumbs.
- *
- * @attribute thumbsTransition
- * @type String
- * @default slideHorizontal
- */
- thumbsTransition: {
- value: 'slideHorizontal'
- },
- /**
- * The duration of the transition between pages of thumbs.
- *
- * @attribute thumbsTransitionDuration
- * @type Number
- * @default 0.8
- */
- thumbsTransitionDuration: {
- value: 0.8
- },
- /**
- * The type of transition easing to use between pages of thumbs.
- *
- * @attribute thumbsTransitionEasing
- * @type String
- * @default ease-out
- */
- thumbsTransitionEasing: {
- value: 'ease-out'
- },
- /**
- * Whether to crop the thumbnails.
- *
- * @attribute thumbsImageCrop
- * @type Boolean
- * @default true
- */
- thumbsImageCrop: {
- value: true
- },
- /**
- * The width of each thumbnail.
- *
- * @attribute thumbsImageWidth
- * @type Number
- * @default 50
- */
- thumbsImageWidth: {
- value: 50
- },
- /**
- * The height of each thumbnail.
- *
- * @attribute thumbsImageHeight
- * @type Number
- * @default 50
- */
- thumbsImageHeight: {
- value: 50
- },
- /**
- * The text to use for the "read less" toggle link.
- *
- * @attribute captionLessLinkText
- * @type String
- * @default Read Less
- */
- captionLessLinkText: {
- value: 'Read Less'
- },
- /**
- * The text to use for the "read more" toggle link.
- *
- * @attribute captionMoreLinkText
- * @type String
- * @default Read More
- */
- captionMoreLinkText: {
- value: 'Read More'
- },
- /**
- * The length of the caption to show. If greater than -1,
- * the text will be truncated and a read more link will
- * be displayed. If set to -1, the entire caption will be shown.
- *
- * @attribute captionTextLength
- * @type Number
- * @default 200
- */
- captionTextLength: {
- value: 200
- },
- /**
- * Whether to strip out HTML tags in the caption
- * text or not.
- *
- * @attribute captionStripTags
- * @type Boolean
- * @default false
- */
- captionStripTags: {
- value: false
- },
- /**
- * Whether to use the vertical thumbs or not.
- *
- * @attribute verticalThumbsEnabled
- * @type Boolean
- * @default false
- */
- verticalThumbsEnabled: {
- value: false
- },
- /**
- * Position of the vertical thumbs. Possible values
- * are either left or right.
- *
- * @attribute verticalThumbsPosition
- * @type String
- * @default left
- */
- verticalThumbsPosition: {
- value: 'left'
- },
- /**
- * Whether to overlay the vertical thumbs
- * on the main image or not.
- *
- * @attribute verticalThumbsOverlay
- * @type Boolean
- * @default false
- */
- verticalThumbsOverlay: {
- value: false
- },
- /**
- * The number of columns for the vertical thumbs.
- *
- * @attribute verticalThumbsColumns
- * @type Number
- * @default 1
- */
- verticalThumbsColumns: {
- value: 1
- },
- /**
- * Whether to use the vertical thumbs top nav or not.
- *
- * @attribute verticalThumbsTopNavEnabled
- * @type Boolean
- * @default false
- */
- verticalThumbsTopNavEnabled: {
- value: false
- },
- /**
- * An array of button names used to render
- * the vertical thumbs top nav buttons.
- *
- * @attribute verticalThumbsTopNavButtons
- * @type Array
- * @default prevPage, nextPage
- */
- verticalThumbsTopNavButtons: {
- value: ['prevPage', 'nextPage']
- },
- /**
- * Whether to use the vertical thumbs bottom nav or not.
- *
- * @attribute verticalThumbsBottomNavEnabled
- * @type Boolean
- * @default false
- */
- verticalThumbsBottomNavEnabled: {
- value: true
- },
- /**
- * An array of button names used to render
- * the vertical thumbs top nav buttons.
- *
- * @attribute verticalThumbsBottomNavButtons
- * @type Array
- * @default prevPage, nextPage
- */
- verticalThumbsBottomNavButtons: {
- value: ['prevPage', 'nextPage']
- },
- /**
- * The horizontal spacing between vertical thumbs.
- *
- * @attribute verticalThumbsHorizontalSpacing
- * @type Number
- * @default 15
- */
- verticalThumbsHorizontalSpacing: {
- value: 15
- },
- /**
- * The vertical spacing between vertical thumbs.
- *
- * @attribute verticalThumbsVerticalSpacing
- * @type Number
- * @default 15
- */
- verticalThumbsVerticalSpacing: {
- value: 15
- },
- /**
- * Whether to space the vertical thumbs evenly within a page.
- *
- * @attribute verticalThumbsSpaceEvenly
- * @type Boolean
- * @default false
- */
- verticalThumbsSpaceEvenly: {
- value: false
- },
- /**
- * Whether to pause the slideshow when a vertical thumb is clicked.
- *
- * @attribute verticalThumbsPauseOnClick
- * @type Boolean
- * @default false
- */
- verticalThumbsPauseOnClick: {
- value: false
- },
- /**
- * Whether to crop the vertical thumbs or not.
- *
- * @attribute verticalThumbsImageCrop
- * @type Boolean
- * @default true
- */
- verticalThumbsImageCrop: {
- value: true
- },
- /**
- * The width of each vertical thumbnail.
- *
- * @attribute verticalThumbsImageWidth
- * @type Number
- * @default 75
- */
- verticalThumbsImageWidth: {
- value: 75
- },
- /**
- * The height of each vertical thumbnail.
- *
- * @attribute verticalThumbsImageHeight
- * @type Number
- * @default 75
- */
- verticalThumbsImageHeight: {
- value: 75
- },
- /**
- * The type of transition to use between pages of vertical thumbs.
- *
- * @attribute verticalThumbsTransition
- * @type String
- * @default slideVertical
- */
- verticalThumbsTransition: {
- value: 'slideVertical'
- },
- /**
- * The duration of the transition between pages of vertical thumbs.
- *
- * @attribute verticalThumbsTransitionDuration
- * @type Number
- * @default 0.8
- */
- verticalThumbsTransitionDuration: {
- value: 0.8
- },
- /**
- * The type of transition easing to use between pages of vertical thumbs.
- *
- * @attribute verticalThumbsTransitionEasing
- * @type String
- * @default ease-out
- */
- verticalThumbsTransitionEasing: {
- value: 'ease-out'
- },
- /**
- * Whether to use the Facebook like button or not.
- *
- * @attribute likeButtonEnabled
- * @type Boolean
- * @default true
- */
- likeButtonEnabled: {
- value: true
- },
- /**
- * Whether to use the Pinterest button or not.
- *
- * @attribute pinterestButtonEnabled
- * @type Boolean
- * @default true
- */
- pinterestButtonEnabled: {
- value: true
- },
- /**
- * Whether to use the Tweet button or not.
- *
- * @attribute tweetButtonEnabled
- * @type Boolean
- * @default true
- */
- tweetButtonEnabled: {
- value: true
- },
- /**
- * Whether to use touch gestures, when available,
- * to transition between images or not.
- *
- * @attribute touchSupport
- * @type Boolean
- * @default true
- */
- touchSupport: {
- value: true
- }
- }
- });
- }, '2.0.0' ,{requires:['anim', 'event-mouseenter', 'plugin', 'transition', 'fl-event-move', 'fl-slideshow-css', 'fl-slideshow-base', 'fl-utils', 'sm-fonticon']});
- YUI.add('fl-slideshow-album-loader', function(Y) {
- /**
- * @module fl-slideshow-album-loader
- */
- /**
- * Loads slideshow albums using a provided source object.
- *
- * @namespace FL
- * @class SlideshowAlbumLoader
- * @constructor
- * @param config {Object} Configuration object
- * @extends Base
- */
- Y.namespace('FL').SlideshowAlbumLoader = Y.Base.create('fl-slideshow-album-loader', Y.Base, [], {
- /**
- * The source object used for loading.
- *
- * @property _source
- * @type Object
- * @default null
- * @protected
- */
- _source: null,
- /**
- * Loads slideshow album data using the provided source object.
- *
- * @method load
- * @param source {Object} The source object to use for loading.
- */
- load: function(source)
- {
- this._source = source;
- /**
- * Fires before a new load request is made.
- *
- * @event start
- */
- this.fire('start');
- this[Y.FL.SlideshowAlbumLoader.TYPES[source.type]].call(this);
- },
- /**
- * Called when a source type completes loading
- * and fires the complete event.
- *
- * @method _loadComplete
- * @param o {Object} Passed to complete event subscribers.
- * @protected
- */
- _loadComplete: function(o)
- {
- o = this._randomize(o);
- /**
- * Fires after a new load request is made.
- *
- * @event complete
- */
- this.fire('complete', o);
- },
- /**
- * Randomizes images in an album.
- *
- * @method _randomize
- * @param album {Object} The album to randomize.
- * @protected
- */
- _randomize: function(o)
- {
- var i;
- if(this.get('randomize')) {
- o.albumInfo.images.sort(function() { return 0.5 - Math.random(); });
- for(i = 0; i < o.albumInfo.images.length; i++) {
- o.albumInfo.images[i].index = i;
- }
- }
- return o;
- },
- /**
- * Loads slideshow album data from SmugMug.
- *
- * @method _loadSmugMug
- * @protected
- */
- _loadSmugMug: function()
- {
- var sm = new Y.FL.SmugMugAPI();
- sm.on('complete', this._loadSmugMugSuccess, this);
- sm.addParam('method', 'smugmug.images.get');
- sm.addParam('AlbumID', this._source.id);
- sm.addParam('AlbumKey', this._source.key);
- sm.addParam('Extras', 'Caption,Format,FileName');
- // Gallery password
- if(this._source.password) {
- sm.addParam('Password', this._source.password);
- }
- // Site-wide password
- if(this._source.sp) {
- sm.addParam('SitePassword', this._source.sp);
- }
- sm.request();
- },
- /**
- * Processes slideshow album data loaded from SmugMug.
- *
- * @method _loadSmugMugSuccess
- * @param e {Object} The custom event object passed to this function.
- * @protected
- */
- _loadSmugMugSuccess: function(e)
- {
- var images = e.Album.Images,
- album = {},
- proxy = typeof this._source.proxy !== 'undefined' ? this._source.proxy : '',
- buyBase = '',
- baseURL = '',
- ext = '',
- format = '',
- i = 0,
- temp = null,
- iframe = null;
- album.index = this._source.index;
- album.id = e.Album.id;
- album.key = e.Album.Key;
- album.link = e.Album.URL;
- album.title = this._source.title ? this._source.title : '';
- album.images = [];
- buyBase = album.link.replace('https://', '').split('/').shift();
- buyBase = 'https://' + buyBase + '/buy/' + e.Album.id + '_' + e.Album.Key + '/';
- for(i = 0; i < images.length; i++)
- {
- baseURL = proxy + e.Album.URL + '/' + images[i].id + '_' + images[i].Key;
- format = images[i].Format.toLowerCase();
- ext = format == 'mp4' ? '.jpg' : '.' + format;
- album.images[i] = {};
- album.images[i].index = i;
- album.images[i].sourceType = 'smugmug';
- album.images[i].albumId = e.Album.id;
- album.images[i].albumKey = e.Album.Key;
- album.images[i].id = images[i].id;
- album.images[i].key = images[i].Key;
- album.images[i].filename = images[i].FileName;
- album.images[i].format = format;
- album.images[i].caption = images[i].Caption || '';
- album.images[i].link = e.Album.URL + '#' + images[i].id + '_' + images[i].Key;
- album.images[i].tinyURL = baseURL + '-Ti' + ext;
- album.images[i].thumbURL = baseURL + '-Th' + ext;
- album.images[i].smallURL = baseURL + '-S' + ext;
- album.images[i].mediumURL = baseURL + '-M' + ext;
- album.images[i].largeURL = baseURL + '-L' + ext;
- album.images[i].xlargeURL = baseURL + '-XL' + ext;
- album.images[i].x2largeURL = baseURL + '-X2' + ext;
- album.images[i].x3largeURL = baseURL + '-X3' + ext;
- album.images[i].buyURL = buyBase + images[i].id + '_' + images[i].Key;
- album.images[i].iframe = '';
- if(album.images[i].caption.indexOf('iframe')) {
- temp = Y.Node.create('<div>'+ album.images[i].caption +'</div>');
- iframe = temp.one('iframe');
- if(iframe) {
- album.images[i].iframe = iframe.getAttribute('src');
- album.images[i].caption = album.images[i].caption.replace(/<iframe.*>.*<\/iframe>/gi, '');
- }
- }
- }
- this._loadComplete({ 'albumInfo': album });
- },
- /**
- * Loads slideshow album data from an array of urls.
- *
- * NOTE: You must have a large URL.
- *
- * @method _loadUrls
- * @protected
- */
- _loadUrls: function()
- {
- var album = {},
- i = 0;
- album.index = this._source.index;
- album.title = this._source.title ? this._source.title : '';
- album.images = [];
- for( ; i < this._source.urls.length; i++)
- {
- album.images[i] = {};
- album.images[i].index = i;
- album.images[i].sourceType = 'urls';
- album.images[i].filename = this._source.urls[i].largeURL.split('/').pop();
- album.images[i].format = '';
- album.images[i].caption = this._source.urls[i].caption || '';
- album.images[i].alt = this._source.urls[i].alt || '';
- album.images[i].link = this._source.urls[i].largeURL;
- album.images[i].thumbURL = this._source.urls[i].thumbURL || this._source.urls[i].largeURL;
- album.images[i].smallURL = this._source.urls[i].smallURL || this._source.urls[i].largeURL;
- album.images[i].mediumURL = this._source.urls[i].mediumURL || this._source.urls[i].largeURL;
- album.images[i].largeURL = this._source.urls[i].largeURL; // Must have a large URL
- album.images[i].xlargeURL = this._source.urls[i].xlargeURL || this._source.urls[i].largeURL;
- album.images[i].x2largeURL = this._source.urls[i].x2largeURL || this._source.urls[i].largeURL;
- album.images[i].x3largeURL = this._source.urls[i].x3largeURL || this._source.urls[i].largeURL;
- album.images[i].buyURL = this._source.urls[i].buyURL || '';
- album.images[i].iframe = this._source.urls[i].iframe || '';
- }
- this._loadComplete({ 'albumInfo': album });
- }
- }, {
- /**
- * Static property used to define the default attribute configuration of
- * the Widget.
- *
- * @property ATTRS
- * @type Object
- * @protected
- * @static
- */
- ATTRS: {
- /**
- * If true, the images will be randomized after loading.
- *
- * @attribute randomize
- * @type Boolean
- * @default false
- */
- randomize: {
- value: false
- }
- },
- /**
- * The types of source data that can be loaded
- * and associated functions.
- *
- * @property TYPES
- * @type Object
- * @readOnly
- * @protected
- * @static
- */
- TYPES: {
- 'smugmug': '_loadSmugMug',
- 'flickr': '_loadFlickr',
- 'picasa': '_loadPicasa',
- 'urls': '_loadUrls',
- 'html': '_loadHtml'
- }
- });
- }, '2.0.0' ,{requires:['base', 'fl-smugmug-api']});
- YUI.add('fl-slideshow-base', function(Y) {
- /**
- * @module fl-slideshow-base
- */
- /**
- * The base class that gets extended when creating new
- * slideshow widgets. Manages loading, playing, and resizing.
- * <p>
- * While SlideshowBase can be instantiated, it is only meant to
- * be extended and does not display any images.
- *
- * @namespace FL
- * @class SlideshowBase
- * @constructor
- * @param config {Object} Configuration object
- * @extends Widget
- */
- Y.namespace('FL').SlideshowBase = Y.Base.create('fl-slideshow-base', Y.Widget, [Y.WidgetParent], {
- /**
- * FL.SlideshowAlbumLoader instance used to load albums.
- *
- * @property _loader
- * @type FL.SlideshowAlbumLoader
- * @default null
- * @protected
- */
- _albumLoader: null,
- /**
- * An array of albums loaded from the source attribute.
- * Each album is an array of objects containing image info.
- *
- * @property albums
- * @type Array
- * @default []
- */
- albums: [],
- /**
- * Info for the active album.
- *
- * @property albumInfo
- * @type Object
- * @default null
- */
- albumInfo: null,
- /**
- * A number that represents the index of the active
- * album in the albums array.
- *
- * @property albumIndex
- * @type Number
- * @default null
- */
- albumIndex: null,
- /**
- * Info for the active image.
- *
- * @property imageInfo
- * @type Object
- * @default null
- */
- imageInfo: null,
- /**
- * A number that represents the index of the active
- * image in the albumInfo array.
- *
- * @property imageIndex
- * @type Number
- * @default null
- */
- imageIndex: null,
- /**
- * A number that represents the index of the last
- * image that was loaded in the albumInfo array.
- *
- * @property lastImageIndex
- * @type Number
- * @default null
- */
- lastImageIndex: null,
- /**
- * Timer for the delay before resizing if one is set.
- *
- * @property _resizeTimer
- * @type Object
- * @default null
- * @protected
- */
- _resizeTimer: null,
- /**
- * Flag for whether the slideshow is currently playing or not.
- *
- * @property playing
- * @type Boolean
- * @default false
- * @protected
- */
- _playing: false,
- /**
- * Timer for the break in between images when
- * the slideshow is playing.
- *
- * @property _playingTimer
- * @type Object
- * @default null
- * @protected
- */
- _playingTimer: null,
- /**
- * If set, the slideshow will only auto start when
- * this event is fired.
- *
- * @property _playingTimerEvent
- * @type Object
- * @default null
- * @protected
- */
- _playingTimerEvent: null,
- /**
- * An instance of FL.Spinner that is shown and hidden
- * using _showLoadingImage and _hideLoadingImage when
- * a loading activity occurs.
- *
- * @property _loadingImage
- * @type FL.Spinner
- * @default null
- * @protected
- */
- _loadingImage: null,
- /**
- * An div node that wraps the loading image.
- *
- * @property _loadingImageWrap
- * @type Node
- * @default null
- * @protected
- */
- _loadingImageWrap: null,
- /**
- * Whether the loading image is visible or not.
- *
- * @property _loadingImageVisible
- * @type Boolean
- * @default false
- * @protected
- */
- _loadingImageVisible: false,
- /**
- * A timer to delay the display of the loading image.
- *
- * @property _loadingImageTimer
- * @type Object
- * @default null
- * @protected
- */
- _loadingImageTimer: null,
- /**
- * The container to insert the loading image into. If
- * no container is set, the loading image will be inserted
- * into the widget's bounding box.
- *
- * @property _loadingImageContainer
- * @type Object
- * @default null
- * @protected
- */
- _loadingImageContainer: null,
- /**
- * The intial height of the slideshow. Used to resize
- * back to the starting height when exiting stretchy.
- *
- * @property _initialHeight
- * @type Number
- * @default null
- * @protected
- */
- _initialHeight: null,
- /**
- * The intial width of the slideshow. Used to resize
- * back to the starting width when exiting stretchy.
- *
- * @property _initialWidth
- * @type Number
- * @default null
- * @protected
- */
- _initialWidth: null,
- /**
- * @method initializer
- * @protected
- */
- initializer: function()
- {
- // Loader
- this._albumLoader = new Y.FL.SlideshowAlbumLoader({
- randomize: this.get('randomize')
- });
- },
- /**
- * @method renderUI
- * @protected
- */
- renderUI: function()
- {
- this._renderLoadingImage();
- },
- /**
- * @method bindUI
- * @protected
- */
- bindUI: function()
- {
- // Album load complete
- this._albumLoader.on('complete', this._loadAlbumComplete, this);
- // Resize Events
- Y.one(window).on('fl-slideshow-base|resize', this._delayResize, this);
- Y.one(window).on('fl-slideshow-base|orientationchange', this._delayResize, this);
- // Key Events
- Y.Node.one('body').on('keydown', Y.bind(this._onKey, this));
- },
- /**
- * @method syncUI
- * @protected
- */
- syncUI: function()
- {
- this.get('boundingBox').addClass('fl-slideshow-' + this.get('color'));
- this.resize();
- if(this.get('loadOnRender')) {
- this.loadAlbum(this.get('defaultAlbum'), this.get('defaultImage'));
- }
- },
- /**
- * Add album data to the source object.
- *
- * @method addAlbum
- * @protected
- */
- addAlbum: function(data)
- {
- var source = this.get('source'),
- i = source.length;
- source[i] = data;
- source[i].index = i;
- this.set('source', source);
- },
- /**
- * Loads an album from the source array with the provided albumIndex.
- * If no albumIndex is provided, the first album in the array will be loaded.
- * An image to load can also be specified using imageIndex.
- *
- * @method loadAlbum
- * @param albumIndex {Number} The album index to load from the source array.
- * @param imageIndex {Number} The image index to load from the album array.
- */
- loadAlbum: function(albumIndex, imageIndex)
- {
- var source = this.get('source'),
- loadImageIndex = typeof imageIndex == 'undefined' ? 0 : imageIndex;
- // Reset internal image indexes.
- this.imageIndex = null;
- this.lastImageIndex = null;
- /**
- * Fires before a new album request is made.
- *
- * @event albumLoadStart
- */
- this.fire('albumLoadStart');
- // Load an image after the album.
- this.once('albumLoadComplete', Y.bind(this.loadImage, this, loadImageIndex));
- // Load data passed from another slideshow instance.
- if(source[albumIndex] && source[albumIndex].type == 'album-data') {
- this.albums[albumIndex] = source[albumIndex].data;
- this._loadAlbumComplete({albumInfo: this.albums[albumIndex]});
- }
- // Load the album from the albums array.
- else if(source[albumIndex] && this.albums[albumIndex]) {
- this._loadAlbumComplete({albumInfo: this.albums[albumIndex]});
- }
- // Load the album using the album loader.
- else {
- this._albumLoader.load(source[albumIndex] || source[0]);
- }
- },
- /**
- * Processes the loaded album and fires the albumLoadComplete event.
- *
- * @method _loadAlbumComplete
- * @param o {Object} The custom event object passed to this method.
- * @protected
- */
- _loadAlbumComplete: function(o)
- {
- this.albums[o.albumInfo.index] = o.albumInfo;
- this.albumInfo = o.albumInfo;
- this.albumIndex = o.albumInfo.index;
- /**
- * Fires after a new album request is made.
- *
- * @event albumLoadComplete
- */
- this.fire('albumLoadComplete');
- // Auto Play
- if(this.get('autoPlay')) {
- this._playingTimerStart();
- this.fire('played');
- this._playing = true;
- }
- },
- /**
- * Sets the active image index and fires the imageLoadComplete event.
- *
- * @method loadImage
- * @param index {Number} The image index to load.
- */
- loadImage: function(index)
- {
- if(this._playing) {
- this._playingTimerStart();
- }
- index = index < 0 ? this.albumInfo.images.length - 1 : index;
- index = index >= this.albumInfo.images.length ? 0 : index;
- this.lastImageIndex = this.imageIndex;
- this.imageIndex = index;
- this.imageInfo = this.albumInfo.images[index];
- /**
- * Fires after a new image index is set.
- *
- * @event imageLoadComplete
- */
- this.fire('imageLoadComplete', { 'imageInfo': this.imageInfo });
- },
- /**
- * Loads the previous image.
- *
- * @method prevImage
- */
- prevImage: function()
- {
- if(this.get('pauseOnNextOrPrev')) {
- this.pause();
- }
- this.loadImage(this.imageIndex - 1);
- /**
- * Fires when the previous image is loaded.
- *
- * @event prevImage
- */
- this.fire('prevImage');
- },
- /**
- * Loads the next image.
- *
- * @method nextImage
- */
- nextImage: function()
- {
- if(this.get('pauseOnNextOrPrev')) {
- this.pause();
- }
- this.loadImage(this.imageIndex + 1);
- /**
- * Fires when the next image is loaded.
- *
- * @event nextImage
- */
- this.fire('nextImage');
- },
- /**
- * Keyboard navigation for the next and prev images.
- *
- * @method _onKey
- * @protected
- */
- _onKey: function(e)
- {
- switch(e.keyCode) {
- case 37:
- this.prevImage();
- break;
- case 39:
- this.nextImage();
- break;
- }
- },
- /**
- * Resizes the slideshow using either the
- * stretchy or standard functions.
- *
- * @method resize
- */
- resize: function()
- {
- var stretchy = this.get('stretchy'),
- stretchyType = this.get('stretchyType'),
- width = parseInt(Y.one('body').get('winWidth'), 10),
- threshold = this.get('responsiveThreshold');
- // Stretchy resize to the window only if the parent width is greater
- // than the responsive threshold and stretchyType is set to window.
- if(width > threshold && stretchy && stretchyType == 'window') {
- this._stretchyWindowResize();
- }
- // Ratio resize if the parent width is less than the responsive
- // threshold or if stretchyType is set to ratio.
- else if((width <= threshold) || (stretchy && stretchyType == 'ratio')) {
- this._stretchyRatioResize();
- }
- // Do a standard resize based on the height and
- // width passed to the constructor function.
- else {
- this._standardResize();
- }
- /**
- * Fires when the slideshow is resized.
- *
- * @event resize
- */
- this.fire('resize');
- },
- /**
- * @method _standardResize
- * @protected
- */
- _standardResize: function()
- {
- var stretchy = this.get('stretchy'),
- stretchyType = this.get('stretchyType'),
- bb = this.get('boundingBox'),
- parent = bb.get('parentNode'),
- parentHeight = parseInt(parent.getComputedStyle('height'), 10),
- parentWidth = parseInt(parent.getComputedStyle('width'), 10),
- height = this.get('height'),
- width = this.get('width');
- // Window resize if we are in fullscreen.
- if(bb.hasClass('fl-fullscreen-active')) {
- this._stretchyWindowResize();
- return;
- }
- // Resize to the width and height of the parent.
- else if(stretchy && stretchyType == 'contain') {
- bb.setStyle('height', parentHeight + 'px');
- bb.setStyle('width', parentWidth + 'px');
- }
- // Ratio resize if we don't have a height defined.
- else if(!Y.Lang.isNumber(height)) {
- this._stretchyRatioResize();
- return;
- }
- // Resize to the defined width and height.
- else {
- bb.setStyle('height', height + 'px');
- if(width) {
- bb.setStyle('width', width + 'px');
- }
- else {
- bb.setStyle('width', parentWidth + 'px');
- }
- }
- },
- /**
- * Resizes to the height of the window, compensating
- * for any padding.
- *
- * @method _stretchyWindowResize
- * @protected
- */
- _stretchyWindowResize: function()
- {
- var bb = this.get('boundingBox'),
- verticalSpace = this.get('stretchyVerticalSpace'),
- paddingTop = parseInt(bb.getStyle('paddingTop'), 10),
- paddingBottom = parseInt(bb.getStyle('paddingBottom'), 10),
- height = parseInt(Y.one('body').get('winHeight'), 10),
- width = '';
- // Set the vertical space to 0 and width to the
- // window's width if we are in fullscreen mode.
- if(bb.hasClass('fl-fullscreen-active')) {
- verticalSpace = 0;
- width = parseInt(Y.one('body').get('winWidth'), 10) + 'px';
- }
- height = (height - paddingTop - paddingBottom - verticalSpace) + 'px';
- bb.setStyle('height', height);
- bb.setStyle('width', width);
- },
- /**
- * Resizes the height by multiplying the width and stretchyRatio value.
- *
- * @method _stretchyRatioResize
- * @protected
- */
- _stretchyRatioResize: function()
- {
- var bb = this.get('boundingBox'),
- parent = bb.get('parentNode'),
- verticalSpace = 0,
- stretchyRatio = this.get('stretchyRatio'),
- paddingTop = parseInt(bb.getStyle('paddingTop'), 10),
- paddingBottom = parseInt(bb.getStyle('paddingBottom'), 10),
- computedWidth = parseInt(parent.getComputedStyle('width'), 10),
- winHeight = parseInt(Y.one('body').get('winHeight'), 10),
- winWidth = parseInt(Y.one('body').get('winWidth'), 10),
- height = computedWidth * stretchyRatio,
- width = '';
- // Use the window's height and width if we are in fullscreen mode.
- if(bb.hasClass('fl-fullscreen-active')) {
- height = winHeight;
- width = winWidth;
- }
- height = (height - paddingTop - paddingBottom - verticalSpace) + 'px';
- bb.setStyle('height', height);
- bb.setStyle('width', width);
- },
- /**
- * Resizes the slideshow after the resize timer completes.
- *
- * @method _delayResize
- * @protected
- */
- _delayResize: function()
- {
- if(this._resizeTimer) {
- this._resizeTimer.cancel();
- }
- this._resizeTimer = Y.later(300, this, this.resize);
- },
- /**
- * Starts a new playing timer and fires the played event.
- *
- * @method play
- */
- play: function()
- {
- this._playingTimer = Y.later(this.get('speed'), this, this._playingTimerComplete);
- /**
- * Fires when the playing timer starts.
- *
- * @event played
- */
- this.fire('played');
- this._playing = true;
- },
- /**
- * Cancels the current playing timer and fires the paused event.
- *
- * @method pause
- */
- pause: function()
- {
- this._playingTimerCancel();
- /**
- * Fires when the playing timer is canceled.
- *
- * @event paused
- */
- this.fire('paused');
- this._playing = false;
- },
- /**
- * A new playing timer will start when this event is fired.
- *
- * @method _setPlayingTimerEvent
- * @param obj {Object} The event's host object.
- * @param e {String} The event to fire on the host object.
- * @protected
- */
- _setPlayingTimerEvent: function(obj, e)
- {
- this._playingTimerEvent = {
- 'obj': obj,
- 'e': e
- };
- },
- /**
- * Cancels the playing timer if it is running and starts a new one.
- * The next image is loaded when the timer completes.
- *
- * @method _playingTimerStart
- * @protected
- */
- _playingTimerStart: function(e)
- {
- this._playingTimerCancel();
- if(!e && this._playingTimerEvent !== null) {
- this._playingTimerEvent.obj.once('fl-slideshow-base|' + this._playingTimerEvent.e, Y.bind(this._playingTimerStart, this));
- }
- else {
- this._playingTimer = Y.later(this.get('speed'), this, this._playingTimerComplete);
- }
- },
- /**
- * Fires when the playing timer completes, starts a
- * new timer and loads the next image.
- *
- * @method _playingTimerComplete
- * @protected
- */
- _playingTimerComplete: function()
- {
- this.loadImage(this.imageIndex + 1);
- /**
- * Fires when the playing timer completes.
- *
- * @event albumLoadStart
- */
- this.fire('playingTimerComplete');
- },
- /**
- * Cancels the playing timer.
- *
- * @method _playingTimerCancel
- * @protected
- */
- _playingTimerCancel: function()
- {
- if(this._playingTimer) {
- this._playingTimer.cancel();
- }
- if(this._playingTimerEvent) {
- this._playingTimerEvent.obj.detach('fl-slideshow-base|' + this._playingTimerEvent.e);
- }
- },
- /**
- * Creates the loading image.
- *
- * @method _renderLoadingImage
- * @protected
- */
- _renderLoadingImage: function()
- {
- var defaults = {
- lines: 11, // The number of lines to draw
- length: 6, // The length of each line
- width: 2, // The line thickness
- radius: 7, // The radius of the inner circle
- color: '', // #rbg or #rrggbb
- speed: 1, // Rounds per second
- trail: 60, // Afterglow percentage
- shadow: false // Whether to render a shadow
- },
- settings = Y.merge(defaults, this.get('loadingImageSettings'));
- if(this.get('loadingImageEnabled')) {
- // Loading image
- if(settings.color === '') {
- settings.color = this._colorToHex(Y.one('body').getStyle('color'));
- }
- this._loadingImage = new Y.FL.Spinner(settings);
- // Loading image wrap
- this._loadingImageWrap = Y.Node.create('<div class="fl-loading-image"></div>');
- this._loadingImageWrap.setStyles({
- position : 'absolute',
- 'z-index' : '1000'
- });
- }
- },
- /**
- * Inserts the loading image.
- *
- * @method _showLoadingImage
- * @protected
- */
- _showLoadingImage: function()
- {
- if(this._loadingImage && !this._loadingImageVisible) {
- this._loadingImageVisible = true;
- this._loadingImage.spin();
- this._loadingImageWrap.insert(this._loadingImage.el);
- if(this._loadingImageContainer !== null) {
- this._loadingImageContainer.insert(this._loadingImageWrap);
- }
- else {
- this.get('contentBox').insert(this._loadingImageWrap);
- }
- this._positionLoadingImage();
- }
- },
- /**
- * Inserts the loading image div node after
- * a timer completes.
- *
- * @method _showLoadingImageWithDelay
- * @protected
- */
- _showLoadingImageWithDelay: function()
- {
- if(this._loadingImage) {
- this._loadingImageTimer = Y.later(1000, this, this._showLoadingImage);
- }
- },
- /**
- * Removes the loading image div node.
- *
- * @method _hideLoadingImage
- * @protected
- */
- _hideLoadingImage: function()
- {
- if(this._loadingImageTimer) {
- this._loadingImageTimer.cancel();
- this._loadingImageTimer = null;
- }
- if(this._loadingImage && this._loadingImageVisible) {
- this._loadingImageVisible = false;
- this._loadingImage.stop();
- this._loadingImageWrap.remove();
- }
- },
- /**
- * Centers the loading image in the content box.
- *
- * @method _positionLoadingImage
- * @protected
- */
- _positionLoadingImage: function()
- {
- if(this._loadingImage && this._loadingImageVisible) {
- var wrap = this._loadingImageWrap,
- wrapHeight = parseInt(wrap.getComputedStyle('height'), 10),
- wrapWidth = parseInt(wrap.getComputedStyle('width'), 10),
- parent = wrap.get('parentNode'),
- parentHeight = parseInt(parent.getComputedStyle('height'), 10),
- parentWidth = parseInt(parent.getComputedStyle('width'), 10),
- left = (parentWidth - wrapWidth)/2,
- top = (parentHeight - wrapHeight)/2;
- wrap.setStyles({
- left : left + 'px',
- top : top + 'px'
- });
- Y.one(this._loadingImage.el).setStyles({
- left : '50%',
- top : '50%'
- });
- }
- },
- /**
- * Convert RGB color value to a hex value.
- *
- * @method _colorToHex
- * @protected
- */
- _colorToHex: function(color)
- {
- var digits, red, green, blue, rgb;
- if(color.substr(0, 1) === '#') {
- return color;
- }
- digits = /(.*?)rgb\((\d+), (\d+), (\d+)\)/.exec(color);
- if ( null === digits ) {
- return '#000';
- }
- red = parseInt(digits[2], 10);
- green = parseInt(digits[3], 10);
- blue = parseInt(digits[4], 10);
- rgb = blue | (green << 8) | (red << 16);
- rgb = rgb.toString(16);
- if(rgb === '0') {
- rgb = '000';
- }
- return digits[1] + '#' + rgb;
- }
- }, {
- /**
- * Custom CSS class name for the widget.
- *
- * @property CSS_PREFIX
- * @type String
- * @protected
- * @static
- */
- CSS_PREFIX: 'fl-slideshow-base',
- /**
- * Static property used to define the default attribute configuration of
- * the Widget.
- *
- * @property ATTRS
- * @type Object
- * @protected
- * @static
- */
- ATTRS: {
- /**
- * Used to create the color class that gets added to the bounding box
- * when the widget is rendered. The color class is used to create new
- * CSS color themes. The default CSS provided includes dark and light themes.
- *
- * @attribute color
- * @type String
- * @default dark
- * @writeOnce
- */
- color: {
- value: 'dark',
- writeOnce: true
- },
- /**
- * An array of source objects used to load albums. Each object must have
- * a type property and can have a title property as well.
- * <p>
- * In addition to those properties, each object has additional required
- * properties specific to its type. The types currently supported are
- * smugmug and urls with planned support for flickr and picasa.
- * See the user guide for information on loading different types.
- *
- * @attribute source
- * @type Array
- * @default []
- * @writeOnce
- */
- source: {
- value: [],
- setter: function(source) {
- if(source.constructor == Object) {
- source = [source];
- }
- for(var i = 0; i < source.length; i++) {
- source[i].index = i;
- }
- return source;
- }
- },
- /**
- * The default album index to load.
- *
- * @attribute defaultAlbum
- * @type Number
- * @default 0
- */
- defaultAlbum: {
- value: 0
- },
- /**
- * The default image index to load.
- *
- * @attribute defaultImage
- * @type Number
- * @default 0
- */
- defaultImage: {
- value: 0
- },
- /**
- * If true, the slideshow will be loaded after rendering.
- *
- * @attribute loadOnRender
- * @type Boolean
- * @default true
- */
- loadOnRender: {
- value: true
- },
- /**
- * If true, the slideshow will start playing after loading.
- *
- * @attribute autoPlay
- * @type Boolean
- * @default true
- */
- autoPlay: {
- value: true
- },
- /**
- * Whether to pause when the next or previous image is loaded
- * using nextImage or prevImage. The slideshow will not be paused
- * if the next or previous image is loaded using loadImage as is the
- * case when the slideshow is playing.
- *
- * @attribute pauseOnNextOrPrev
- * @type Boolean
- * @default true
- */
- pauseOnNextOrPrev: {
- value: true
- },
- /**
- * If true, the images will be randomized after loading.
- *
- * @attribute randomize
- * @type Boolean
- * @default false
- */
- randomize: {
- value: false
- },
- /**
- * The time between images when playing, measured in milliseconds.
- *
- * @attribute speed
- * @type Number
- * @default 4000
- */
- speed: {
- value: 4000
- },
- /**
- * The minimum width of the parent node at which
- * responsive features are enabled. Set to 0 to
- * disable responsive features as they are enabled
- * whether stretchy is set to true or not.
- *
- * @attribute responsiveThreshold
- * @type Number
- * @default 600
- */
- responsiveThreshold: {
- value: 600
- },
- /**
- * Whether stretchy resizing should be enabled.
- *
- * @attribute stretchy
- * @type Boolean
- * @default false
- */
- stretchy: {
- value: false
- },
- /**
- * The type of stretchy logic to use. Possible values are
- * window and ratio. Both types resize the width of the
- * slideshow to the width of its parent node. With window, the
- * height of the slideshow is resized to the height of the window.
- * With ratio, the height of the slideshow is resized based
- * on the ratio set with stretchyRatio or the height of the window
- * if the ratio height is greater than the window height.
- *
- * @attribute stretchyType
- * @type String
- * @default ratio
- */
- stretchyType: {
- value: 'ratio'
- },
- /**
- * The number of pixels to subtract from the height of
- * the slideshow when stretchy is set to true.
- *
- * @attribute stretchyVerticalSpace
- * @type Number
- * @default 0
- */
- stretchyVerticalSpace: {
- value: 0
- },
- /**
- * Used to calculate the height of the slideshow when stretchyType
- * is set to ratio.
- *
- * @attribute stretchyRatio
- * @type Number
- * @default 0.7
- */
- stretchyRatio: {
- value: 0.7
- },
- /**
- * Whether to use the loading image or not.
- *
- * @attribute loadingImageEnabled
- * @type Boolean
- * @default true
- */
- loadingImageEnabled: {
- value: true
- },
- /**
- * Property object for setting up the spin.js loading image.
- * For a complete list of properties see:
- * http://effinroot.eiremedia.netdna-cdn.com/repo/plugins/misc/spin.js/index.html
- *
- * @attribute loadingImageSettings
- * @type Object
- */
- loadingImageSettings: {
- value: {}
- }
- }
- });
- }, '2.0.0' ,{requires:['node', 'base', 'widget', 'widget-parent', 'widget-child', 'fl-slideshow-album-loader', 'fl-spinner']});
- YUI.add('fl-smugmug-api', function(Y) {
- /**
- * @module fl-smugmug-api
- */
- /**
- * SmugMug API wrapper.
- *
- * NOTE: Only anonymous logins are currently supported.
- *
- * @namespace FL
- * @class SmugMugAPI
- * @constructor
- * @param config {Object} Configuration object
- * @extends Base
- */
- Y.namespace('FL').SmugMugAPI = Y.Base.create('fl-smugmug-api', Y.Base, [], {
- /**
- * ID for the current session.
- *
- * @property _sessionID
- * @type String
- * @default null
- * @protected
- */
- _sessionID: null,
- /**
- * URL with parameters for the next API request.
- * Reset after each request.
- *
- * @property _requestURL
- * @type String
- * @default null
- * @protected
- */
- _requestURL: null,
- /**
- * Lifecycle method. Initializes the request url.
- *
- * @method initializer
- * @protected
- */
- initializer: function()
- {
- this._resetRequestURL();
- },
- /**
- * Adds a key/value pair to the request url.
- *
- * @method addParam
- * @param key {String} The name of the parameter (example: key=val).
- * @param val {String} The value of the parameter (example: key=val).
- */
- addParam: function(key, val)
- {
- this._requestURL = this._requestURL + '&' + key + '=' + val;
- },
- /**
- * Requests an anonymous login session.
- *
- * @method loginAnon
- */
- loginAnon: function()
- {
- this.addParam('method', 'smugmug.login.anonymously');
- this.once('complete', this._loginAnonComplete);
- this.request();
- },
- /**
- * Anonymous login success handler.
- *
- * @method _loginAnonComplete
- * @param data {Object} A jsonp data object.
- * @protected
- */
- _loginAnonComplete: function(data)
- {
- if(data.Login) {
- this._sessionID = data.Login.Session.id;
- }
- },
- /**
- * Sends an API request using the request url.
- *
- * @method request
- */
- request: function()
- {
- this.addParam('Callback', '{callback}');
- Y.jsonp(this._requestURL, {
- on: {
- success: this._requestComplete,
- timeout: function(){} // TODO: Handle timeouts
- },
- context: this,
- timeout: 60000,
- args: []
- });
- },
- /**
- * API request complete handler.
- *
- * @method _requestComplete
- * @param data {Object} A jsonp data object.
- * @protected
- */
- _requestComplete: function(data)
- {
- this._resetRequestURL();
- /**
- * Fires when a request is complete.
- *
- * @event complete
- */
- this.fire('complete', data);
- },
- /**
- * Clears all parameters on the request url except
- * the API key and session ID.
- *
- * @method _resetRequestURL
- * @protected
- */
- _resetRequestURL: function()
- {
- this._requestURL = this.get('apiURL') + '?APIKey=' + this.get('apiKey');
- if(this._sessionID) {
- this.addParam('SessionID', this._sessionID);
- }
- }
- }, {
- /**
- * Static property used to define the default attribute configuration of
- * the Widget.
- *
- * @property ATTRS
- * @type Object
- * @protected
- * @static
- */
- ATTRS: {
- /**
- * SmugMug API url to use for requests.
- *
- * @attribute apiUrl
- * @type String
- * @default https://api.smugmug.com/services/api/json/1.3.0/
- */
- apiURL: {
- value: 'https://api.smugmug.com/services/api/json/1.3.0/'
- },
- /**
- * SmugMug API key.
- *
- * @attribute apiKey
- * @type String
- * @default 7w6kuU5Ee6KSgRRExf2KLgppdkez9JD2
- */
- apiKey: {
- value: '7w6kuU5Ee6KSgRRExf2KLgppdkez9JD2'
- }
- }
- });
- }, '2.0.0' ,{requires:['base', 'jsonp']});
- YUI.add('fl-spinner', function(Y) {
- (function(window,document,undefined){var width="width",length="length",radius="radius",lines="lines",trail="trail",color="color",opacity="opacity",speed="speed",shadow="shadow",style="style",height="height",left="left",top="top",px="px",childNodes="childNodes",firstChild="firstChild",parentNode="parentNode",position="position",relative="relative",absolute="absolute",animation="animation",transform="transform",Origin="Origin",Timeout="Timeout",coord="coord",black="#000",styleSheets=style+"Sheets",prefixes="webkit0Moz0ms0O".split(0),animations={},useCssAnimations;function eachPair(args,it){var end=~~((args[length]-1)/2);for(var i=1;i<=end;i++){it(args[i*2-1],args[i*2])}}function createEl(tag){var el=document.createElement(tag||"div");eachPair(arguments,function(prop,val){el[prop]=val});return el}function ins(parent,child1,child2){if(child2&&!child2[parentNode]){ins(parent,child2)}parent.insertBefore(child1,child2||null);return parent}ins(document.getElementsByTagName("head")[0],createEl(style));var sheet=document[styleSheets][document[styleSheets][length]-1];function addAnimation(to,end){var name=[opacity,end,~~(to*100)].join("-"),dest="{"+opacity+":"+to+"}",i;if(!animations[name]){for(i=0;i<prefixes[length];i++){try{sheet.insertRule("@"+(prefixes[i]&&"-"+prefixes[i].toLowerCase()+"-"||"")+"keyframes "+name+"{0%{"+opacity+":1}"+end+"%"+dest+"to"+dest+"}",sheet.cssRules[length])}catch(err){}}animations[name]=1}return name}function vendor(el,prop){var s=el[style],pp,i;if(s[prop]!==undefined){return prop}prop=prop.charAt(0).toUpperCase()+prop.slice(1);for(i=0;i<prefixes[length];i++){pp=prefixes[i]+prop;if(s[pp]!==undefined){return pp}}}function css(el){eachPair(arguments,function(n,val){el[style][vendor(el,n)||n]=val});return el}function defaults(obj){eachPair(arguments,function(prop,val){if(obj[prop]===undefined){obj[prop]=val}});return obj}var Spinner=function Spinner(o){this.opts=defaults(o||{},lines,12,trail,100,length,7,width,5,radius,10,color,black,opacity,1/4,speed,1)},proto=Spinner.prototype={spin:function(target){var self=this,el=self.el=self[lines](self.opts);if(target){ins(target,css(el,left,~~(target.offsetWidth/2)+px,top,~~(target.offsetHeight/2)+px),target[firstChild])}if(!useCssAnimations){var o=self.opts,i=0,f=20/o[speed],ostep=(1-o[opacity])/(f*o[trail]/100),astep=f/o[lines];(function anim(){i++;for(var s=o[lines];s;s--){var alpha=Math.max(1-(i+s*astep)%f*ostep,o[opacity]);self[opacity](el,o[lines]-s,alpha,o)}self[Timeout]=self.el&&window["set"+Timeout](anim,50)})()}return self},stop:function(){var self=this,el=self.el;window["clear"+Timeout](self[Timeout]);if(el&&el[parentNode]){el[parentNode].removeChild(el)}self.el=undefined;return self}};proto[lines]=function(o){var el=css(createEl(),position,relative),animationName=addAnimation(o[opacity],o[trail]),i=0,seg;function fill(color,shadow){return css(createEl(),position,absolute,width,(o[length]+o[width])+px,height,o[width]+px,"background",color,"boxShadow",shadow,transform+Origin,left,transform,"rotate("+~~(360/o[lines]*i)+"deg) translate("+o[radius]+px+",0)","borderRadius","100em")}for(;i<o[lines];i++){seg=css(createEl(),position,absolute,top,1+~(o[width]/2)+px,transform,"translate3d(0,0,0)",animation,animationName+" "+1/o[speed]+"s linear infinite "+(1/o[lines]/o[speed]*i-1/o[speed])+"s");if(o[shadow]){ins(seg,css(fill(black,"0 0 4px "+black),top,2+px))}ins(el,ins(seg,fill(o[color],"0 0 1px rgba(0,0,0,.1)")))}return el};proto[opacity]=function(el,i,val){el[childNodes][i][style][opacity]=val};var behavior="behavior",URL_VML="url(#default#VML)",tag="group0roundrect0fill0stroke".split(0);(function(){var s=css(createEl(tag[0]),behavior,URL_VML),i;if(!vendor(s,transform)&&s.adj){for(i=0;i<tag[length];i++){sheet.addRule(tag[i],behavior+":"+URL_VML)}proto[lines]=function(){var o=this.opts,r=o[length]+o[width],s=2*r;function grp(){return css(createEl(tag[0],coord+"size",s+" "+s,coord+Origin,-r+" "+-r),width,s,height,s)}var g=grp(),margin=~(o[length]+o[radius]+o[width])+px,i;function seg(i,dx,filter){ins(g,ins(css(grp(),"rotation",360/o[lines]*i+"deg",left,~~dx),ins(css(createEl(tag[1],"arcsize",1),width,r,height,o[width],left,o[radius],top,-o[width]/2,"filter",filter),createEl(tag[2],color,o[color],opacity,o[opacity]),createEl(tag[3],opacity,0))))}if(o[shadow]){for(i=1;i<=o[lines];i++){seg(i,-2,"progid:DXImage"+transform+".Microsoft.Blur(pixel"+radius+"=2,make"+shadow+"=1,"+shadow+opacity+"=.3)")}}for(i=1;i<=o[lines];i++){seg(i)}return ins(css(createEl(),"margin",margin+" 0 0 "+margin,position,relative),g)};proto[opacity]=function(el,i,val,o){o=o[shadow]&&o[lines]||0;el[firstChild][childNodes][i+o][firstChild][firstChild][opacity]=val}}else{useCssAnimations=vendor(s,animation)}})();Y.namespace('FL').Spinner=Spinner})(window,document);
- }, '2.0.0' );
- YUI.add('fl-utils', function(Y) {
- /**
- * @module fl-utils
- */
- /**
- * General helper functions for all FastLine modules.
- *
- * @namespace FL
- * @class Utils
- * @constructor
- * @static
- */
- Y.namespace('FL').Utils = {
- /**
- * Checks for support of the provided CSS property.
- * Method adapted from: https://gist.github.com/556448
- *
- * @method cssSupport
- * @param p {String} The property to check.
- * @returns Boolean
- */
- cssSupport: function(p)
- {
- var b = document.body || document.documentElement,
- s = b.style,
- v = ['Moz', 'Webkit', 'Khtml', 'O', 'ms', 'Icab'],
- i = 0;
- // Transform not working well in these browsers
- if(p == 'transform' && Y.UA.gecko && Y.UA.gecko < 4) { return false; }
- if(p == 'transform' && Y.UA.opera > 0) { return false; }
- if(p == 'transform' && Y.UA.ie > 0 && Y.UA.ie < 10) { return false; }
- if(p == 'transform' && navigator.userAgent.match(/Trident/)) { return false; }
- // No css support detected
- if(typeof s == 'undefined') { return false; }
- // Tests for standard prop
- if(typeof s[p] == 'string') { return true; }
- // Tests for vendor specific prop
- p = p.charAt(0).toUpperCase() + p.substr(1);
- for( ; i < v.length; i++) {
- if(typeof s[v[i] + p] == 'string') { return true; }
- }
- }
- };
- }, '2.0.0' );
|