jquery.cubeportfolio.js 197 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331
  1. (function($, window, document, undefined) {
  2. 'use strict';
  3. function CubePortfolio(obj, options, callback) {
  4. /*jshint validthis: true */
  5. var t = this;
  6. if ($.data(obj, 'cubeportfolio')) {
  7. throw new Error('cubeportfolio is already initialized. Destroy it before initialize again!');
  8. }
  9. // js element
  10. t.obj = obj;
  11. // jquery element
  12. t.$obj = $(obj);
  13. // attached this instance to obj
  14. $.data(t.obj, 'cubeportfolio', t);
  15. // rename options
  16. if (options.sortToPreventGaps !== undefined) {
  17. options.sortByDimension = options.sortToPreventGaps;
  18. delete options.sortToPreventGaps;
  19. }
  20. // extend options
  21. t.options = $.extend({}, $.fn.cubeportfolio.options, options, t.$obj.data('cbp-options'));
  22. // store the state of the animation used for filters
  23. t.isAnimating = true;
  24. // default filter for plugin
  25. t.defaultFilter = t.options.defaultFilter;
  26. // registered events (observator & publisher pattern)
  27. t.registeredEvents = [];
  28. // queue for this plugin
  29. t.queue = [];
  30. // has wrapper
  31. t.addedWrapp = false;
  32. // register callback function
  33. if ($.isFunction(callback)) {
  34. t.registerEvent('initFinish', callback, true);
  35. }
  36. // when there are no .cbp-item
  37. var children = t.$obj.children();
  38. t.$obj.addClass('cbp');
  39. if (children.length === 0 || children.first().hasClass('cbp-item')) {
  40. t.wrapInner(t.obj, 'cbp-wrapper');
  41. t.addedWrapp = true;
  42. }
  43. // jquery wrapper element
  44. t.$ul = t.$obj.children().addClass('cbp-wrapper');
  45. // wrap the $ul in a outside wrapper
  46. t.wrapInner(t.obj, 'cbp-wrapper-outer');
  47. t.wrapper = t.$obj.children('.cbp-wrapper-outer');
  48. t.blocks = t.$ul.children('.cbp-item');
  49. t.blocksOn = t.blocks;
  50. // wrap .cbp-item-wrap div inside .cbp-item
  51. t.wrapInner(t.blocks, 'cbp-item-wrapper');
  52. // register and initialize plugins
  53. t.plugins = {};
  54. $.each(CubePortfolio.plugins, function(key, value) {
  55. var fn = value(t);
  56. if (fn) {
  57. t.plugins[key] = fn;
  58. }
  59. });
  60. // used by the filters plugin. @todo - remove from here and create proper API with position for plugins
  61. t.triggerEvent('afterPlugins');
  62. // usful when width & height is defined for an image and to keep the same aspect ratio on all devices
  63. // on resize. e.g. from mobile to desktop
  64. t.removeAttrAfterStoreData = $.Deferred();
  65. // wait to load all images and then go further
  66. t.loadImages(t.$obj, t.display);
  67. }
  68. $.extend(CubePortfolio.prototype, {
  69. storeData: function(blocks, indexStart) {
  70. var t = this;
  71. indexStart = indexStart || 0; // used by loadMore
  72. blocks.each(function(index, el) {
  73. var item = $(el),
  74. width = item.width(),
  75. height = item.height();
  76. item.data('cbp', {
  77. index: indexStart + index, // used when I sort the items and I need them to revert that sorting
  78. indexInitial: indexStart + index, // used for sort.js @todo - move this to sort.js but be carefoul when I add new items to grid
  79. wrapper: item.children('.cbp-item-wrapper'),
  80. widthInitial: width,
  81. heightInitial: height,
  82. width: width, // used by drag & drop wp @todo - maybe I will use widthAndGap
  83. height: height,
  84. widthAndGap: width + t.options.gapVertical,
  85. heightAndGap: height + t.options.gapHorizontal,
  86. left: null,
  87. leftNew: null,
  88. top: null,
  89. topNew: null,
  90. pack: false,
  91. });
  92. });
  93. this.removeAttrAfterStoreData.resolve();
  94. },
  95. // http://bit.ly/pure-js-wrap
  96. wrapInner: function(items, classAttr) {
  97. var t = this,
  98. item, i, div;
  99. classAttr = classAttr || '';
  100. if (items.length && items.length < 1) {
  101. return; // there are no .cbp-item
  102. } else if (items.length === undefined) {
  103. items = [items];
  104. }
  105. for (i = items.length - 1; i >= 0; i--) {
  106. item = items[i];
  107. div = document.createElement('div');
  108. div.setAttribute('class', classAttr);
  109. while (item.childNodes.length) {
  110. div.appendChild(item.childNodes[0]);
  111. }
  112. item.appendChild(div);
  113. }
  114. },
  115. removeAttrImage: function(img) {
  116. this.removeAttrAfterStoreData.then(function() {
  117. img.removeAttribute('width');
  118. img.removeAttribute('height');
  119. img.removeAttribute('style');
  120. });
  121. },
  122. /**
  123. * Wait to load all images
  124. */
  125. loadImages: function(elems, callback) {
  126. var t = this;
  127. // wait a frame (Safari bug)
  128. requestAnimationFrame(function() {
  129. var imgs = elems.find('img').map(function(index, el) {
  130. // don't wait for images that have a width & height defined
  131. if (el.hasAttribute('width') && el.hasAttribute('height')) {
  132. el.style.width = el.getAttribute('width') + 'px';
  133. el.style.height = el.getAttribute('height') + 'px';
  134. if (el.hasAttribute('data-cbp-src')) {
  135. return null;
  136. }
  137. if (t.checkSrc(el) === null) {
  138. t.removeAttrImage(el);
  139. } else {
  140. var img = $('<img>');
  141. img.on('load.cbp error.cbp', function() {
  142. $(this).off('load.cbp error.cbp');
  143. t.removeAttrImage(el);
  144. });
  145. if (el.srcset) {
  146. img.attr('sizes', el.sizes || '100vw');
  147. img.attr('srcset', el.srcset);
  148. } else {
  149. img.attr('src', el.src);
  150. }
  151. }
  152. return null;
  153. } else {
  154. return t.checkSrc(el);
  155. }
  156. });
  157. var imgsLength = imgs.length;
  158. if (imgsLength === 0) {
  159. callback.call(t);
  160. return;
  161. }
  162. $.each(imgs, function(i, el) {
  163. var img = $('<img>');
  164. img.on('load.cbp error.cbp', function() {
  165. $(this).off('load.cbp error.cbp');
  166. imgsLength--;
  167. if (imgsLength === 0) {
  168. callback.call(t);
  169. }
  170. });
  171. // ie8 compatibility
  172. if (el.srcset) {
  173. img.attr('sizes', el.sizes);
  174. img.attr('srcset', el.srcset);
  175. } else {
  176. img.attr('src', el.src);
  177. }
  178. });
  179. });
  180. },
  181. checkSrc: function(el) {
  182. var srcset = el.srcset;
  183. var src = el.src;
  184. if (src === '') {
  185. return null;
  186. }
  187. var img = $('<img>');
  188. if (srcset) {
  189. img.attr('sizes', el.sizes || '100vw');
  190. img.attr('srcset', srcset);
  191. } else {
  192. img.attr('src', src);
  193. }
  194. var node = img[0];
  195. if (node.complete && node.naturalWidth !== undefined && node.naturalWidth !== 0) {
  196. return null;
  197. }
  198. return node;
  199. },
  200. /**
  201. * Show the plugin
  202. */
  203. display: function() {
  204. var t = this;
  205. // update the current grid width
  206. t.width = t.$obj.outerWidth();
  207. t.triggerEvent('initStartRead');
  208. t.triggerEvent('initStartWrite');
  209. if (t.width > 0) {
  210. // store to data values of t.blocks
  211. t.storeData(t.blocks);
  212. // make layout
  213. t.layoutAndAdjustment();
  214. }
  215. t.triggerEvent('initEndRead');
  216. t.triggerEvent('initEndWrite');
  217. // plugin is ready to show and interact
  218. t.$obj.addClass('cbp-ready');
  219. t.runQueue('delayFrame', t.delayFrame);
  220. },
  221. delayFrame: function() {
  222. var t = this;
  223. requestAnimationFrame(function() {
  224. t.resizeEvent();
  225. t.triggerEvent('initFinish');
  226. // animating is now false
  227. t.isAnimating = false;
  228. // trigger public event initComplete
  229. t.$obj.trigger('initComplete.cbp');
  230. });
  231. },
  232. /**
  233. * Add resize event when browser width changes
  234. */
  235. resizeEvent: function() {
  236. var t = this;
  237. CubePortfolio.private.resize.initEvent({
  238. instance: t,
  239. fn: function() {
  240. // used by wp fullWidth force option
  241. t.triggerEvent('beforeResizeGrid');
  242. var newWidth = t.$obj.outerWidth();
  243. if (newWidth && (t.width !== newWidth)) {
  244. // update the current grid width
  245. t.width = newWidth;
  246. if (t.options.gridAdjustment === 'alignCenter') {
  247. t.wrapper[0].style.maxWidth = '';
  248. }
  249. // reposition the blocks with gridAdjustment set to true
  250. t.layoutAndAdjustment();
  251. t.triggerEvent('resizeGrid');
  252. }
  253. t.triggerEvent('resizeWindow');
  254. }
  255. });
  256. },
  257. gridAdjust: function() {
  258. var t = this;
  259. // if responsive
  260. if (t.options.gridAdjustment === 'responsive') {
  261. t.responsiveLayout();
  262. } else {
  263. // reset the style attribute for all blocks so I can read a new width & height
  264. // for the current grid width. This is usefull for the styles defined in css
  265. // to create a custom responsive system.
  266. // Note: reset height if it was set for addHeightToBlocks
  267. t.blocks.removeAttr('style');
  268. t.blocks.each(function(index, el) {
  269. var data = $(el).data('cbp'),
  270. bound = el.getBoundingClientRect(),
  271. width = t.columnWidthTruncate(bound.right - bound.left),
  272. height = Math.round(bound.bottom - bound.top);
  273. data.height = height;
  274. data.heightAndGap = height + t.options.gapHorizontal;
  275. data.width = width;
  276. data.widthAndGap = width + t.options.gapVertical;
  277. });
  278. t.widthAvailable = t.width + t.options.gapVertical;
  279. }
  280. // used by slider layoutMode
  281. t.triggerEvent('gridAdjust');
  282. },
  283. layoutAndAdjustment: function(updateWidth) {
  284. var t = this;
  285. if (updateWidth) {
  286. // update the current grid width
  287. t.width = t.$obj.outerWidth();
  288. }
  289. t.gridAdjust();
  290. t.layout();
  291. },
  292. /**
  293. * Build the layout
  294. */
  295. layout: function() {
  296. var t = this;
  297. t.computeBlocks(t.filterConcat(t.defaultFilter));
  298. if (t.options.layoutMode === 'slider') {
  299. t.sliderLayoutReset();
  300. t.sliderLayout();
  301. } else {
  302. t.mosaicLayoutReset();
  303. t.mosaicLayout();
  304. }
  305. // positionate the blocks
  306. t.blocksOff.addClass('cbp-item-off');
  307. t.blocksOn.removeClass('cbp-item-off')
  308. .each(function(index, el) {
  309. var data = $(el).data('cbp');
  310. data.left = data.leftNew;
  311. data.top = data.topNew;
  312. el.style.left = data.left + 'px';
  313. el.style.top = data.top + 'px';
  314. });
  315. // resize main container height
  316. t.resizeMainContainer();
  317. },
  318. computeFilter: function(expression) {
  319. var t = this;
  320. t.computeBlocks(expression);
  321. t.mosaicLayoutReset();
  322. t.mosaicLayout();
  323. // filter call layout
  324. // this method is override by animation{PluginName}
  325. t.filterLayout();
  326. },
  327. /**
  328. * Default filter layout if nothing overrides
  329. */
  330. filterLayout: function() {
  331. var t = this;
  332. t.blocksOff.addClass('cbp-item-off');
  333. t.blocksOn.removeClass('cbp-item-off')
  334. .each(function(index, el) {
  335. var data = $(el).data('cbp');
  336. data.left = data.leftNew;
  337. data.top = data.topNew;
  338. el.style.left = data.left + 'px';
  339. el.style.top = data.top + 'px';
  340. });
  341. // resize main container height
  342. t.resizeMainContainer();
  343. t.filterFinish();
  344. },
  345. /**
  346. * Trigger when a filter is finished
  347. */
  348. filterFinish: function() {
  349. var t = this;
  350. t.isAnimating = false;
  351. t.$obj.trigger('filterComplete.cbp');
  352. t.triggerEvent('filterFinish');
  353. },
  354. computeBlocks: function(expression) {
  355. var t = this;
  356. // blocks that are visible before applying the filter
  357. t.blocksOnInitial = t.blocksOn;
  358. // blocks visible after applying the filter
  359. t.blocksOn = t.blocks.filter(expression);
  360. // blocks off after applying the filter
  361. t.blocksOff = t.blocks.not(expression);
  362. t.triggerEvent('computeBlocksFinish', expression);
  363. },
  364. /**
  365. * Make this plugin responsive
  366. */
  367. responsiveLayout: function() {
  368. var t = this;
  369. // calculate numbers of cols
  370. t.cols = t[($.isArray(t.options.mediaQueries) ? 'getColumnsBreakpoints' : 'getColumnsAuto')]();
  371. t.columnWidth = t.columnWidthTruncate((t.width + t.options.gapVertical) / t.cols);
  372. t.widthAvailable = t.columnWidth * t.cols;
  373. if (t.options.layoutMode === 'mosaic') {
  374. t.getMosaicWidthReference();
  375. }
  376. t.blocks.each(function(index, el) {
  377. var data = $(el).data('cbp'),
  378. cols = 1, // grid & slider layoutMode must be 1
  379. width;
  380. if (t.options.layoutMode === 'mosaic') {
  381. cols = t.getColsMosaic(data.widthInitial);
  382. }
  383. width = t.columnWidth * cols - t.options.gapVertical;
  384. el.style.width = width + 'px';
  385. data.width = width;
  386. data.widthAndGap = width + t.options.gapVertical;
  387. // reset height if it was set for addHeightToBlocks
  388. el.style.height = '';
  389. });
  390. var imgs = [];
  391. t.blocks.each(function(index, el) {
  392. $.each($(el).find('img').filter('[width][height]'), function(index, el) {
  393. var width = 0;
  394. $(el).parentsUntil('.cbp-item').each(function(index, el) {
  395. var currentWidth = $(el).width();
  396. if (currentWidth > 0) {
  397. width = currentWidth;
  398. return false;
  399. }
  400. });
  401. var imgWidth = parseInt(el.getAttribute('width'), 10);
  402. var imgHeight = parseInt(el.getAttribute('height'), 10);
  403. var ratio = parseFloat((imgWidth / imgHeight).toFixed(10));
  404. imgs.push({
  405. el: el,
  406. width: width,
  407. height: Math.round(width / ratio),
  408. });
  409. });
  410. });
  411. $.each(imgs, function(index, item) {
  412. item.el.width = item.width;
  413. item.el.height = item.height;
  414. item.el.style.width = item.width + 'px';
  415. item.el.style.height = item.height + 'px';
  416. });
  417. t.blocks.each(function(index, el) {
  418. var data = $(el).data('cbp'),
  419. bound = el.getBoundingClientRect(),
  420. height = Math.round(bound.bottom - bound.top);
  421. data.height = height;
  422. data.heightAndGap = height + t.options.gapHorizontal;
  423. });
  424. },
  425. getMosaicWidthReference: function() {
  426. var t = this,
  427. arrWidth = [];
  428. t.blocks.each(function(index, el) {
  429. var data = $(el).data('cbp');
  430. arrWidth.push(data.widthInitial);
  431. });
  432. arrWidth.sort(function(a, b) {
  433. return a - b;
  434. });
  435. if (arrWidth[0]) {
  436. t.mosaicWidthReference = arrWidth[0];
  437. } else {
  438. t.mosaicWidthReference = t.columnWidth;
  439. }
  440. },
  441. getColsMosaic: function(widthInitial) {
  442. var t = this;
  443. if (widthInitial === t.width) {
  444. return t.cols;
  445. }
  446. var ratio = widthInitial / t.mosaicWidthReference;
  447. if (ratio % 1 >= 0.79) {
  448. ratio = Math.ceil(ratio);
  449. } else {
  450. ratio = Math.floor(ratio);
  451. }
  452. return Math.min(Math.max(ratio, 1), t.cols);
  453. },
  454. /**
  455. * Get numbers of columns when t.options.mediaQueries is not an array
  456. */
  457. getColumnsAuto: function() {
  458. var t = this;
  459. if (t.blocks.length === 0) {
  460. return 1;
  461. }
  462. var columnWidth = t.blocks.first().data('cbp').widthInitial + t.options.gapVertical;
  463. return Math.max(Math.round(t.width / columnWidth), 1);
  464. },
  465. /**
  466. * Get numbers of columns if t.options.mediaQueries is an array
  467. */
  468. getColumnsBreakpoints: function() {
  469. var t = this,
  470. gridWidth = t.width,
  471. mediaQuery;
  472. $.each(t.options.mediaQueries, function(index, obj) {
  473. if (gridWidth >= obj.width) {
  474. mediaQuery = obj;
  475. return false;
  476. }
  477. });
  478. if (!mediaQuery) {
  479. mediaQuery = t.options.mediaQueries[t.options.mediaQueries.length - 1];
  480. }
  481. // the columns breakpoints is triggered
  482. t.triggerEvent('onMediaQueries', mediaQuery.options);
  483. return mediaQuery.cols;
  484. },
  485. /**
  486. * Defines how the columns dimension & position (width, left) will be truncated
  487. *
  488. * If you use `Math.*` there could be some issues with the items on the right side
  489. * that can have some pixels hidden(1 or 2, depends on the number of columns)
  490. * but this is a known limitation.
  491. *
  492. * If you don't use the built-in captions effects (overlay at hover over an item) returning
  493. * the possibly floated values may be a solution for the pixels hidden on the right side.
  494. *
  495. * The column width must be an integer because browsers have some visual issues
  496. * with transform properties for caption effects.
  497. *
  498. * The initial behaviour was return Math.floor
  499. *
  500. */
  501. columnWidthTruncate: function(value) {
  502. return Math.floor(value);
  503. },
  504. /**
  505. * Resize main container vertically
  506. */
  507. resizeMainContainer: function() {
  508. var t = this,
  509. height = Math.max(t.freeSpaces.slice(-1)[0].topStart - t.options.gapHorizontal, 0),
  510. maxWidth;
  511. // set max-width to center the grid if I need to
  512. if (t.options.gridAdjustment === 'alignCenter') {
  513. maxWidth = 0;
  514. t.blocksOn.each(function(index, el) {
  515. var data = $(el).data('cbp'),
  516. rightEdge = data.left + data.width;
  517. if (rightEdge > maxWidth) {
  518. maxWidth = rightEdge;
  519. }
  520. });
  521. t.wrapper[0].style.maxWidth = maxWidth + 'px';
  522. }
  523. // set container height for `overflow: hidden` to be applied
  524. if (height === t.height) {
  525. t.triggerEvent('resizeMainContainer');
  526. return;
  527. }
  528. t.obj.style.height = height + 'px';
  529. // if resizeMainContainer is called for the first time skip this event trigger
  530. if (t.height !== undefined) {
  531. if (CubePortfolio.private.modernBrowser) {
  532. t.$obj.one(CubePortfolio.private.transitionend, function() {
  533. t.$obj.trigger('pluginResize.cbp');
  534. });
  535. } else {
  536. t.$obj.trigger('pluginResize.cbp');
  537. }
  538. }
  539. t.height = height;
  540. t.triggerEvent('resizeMainContainer');
  541. },
  542. filterConcat: function(filter) {
  543. return filter.replace(/\|/gi, '');
  544. },
  545. pushQueue: function(name, deferred) {
  546. var t = this;
  547. t.queue[name] = t.queue[name] || [];
  548. t.queue[name].push(deferred);
  549. },
  550. runQueue: function(name, fn) {
  551. var t = this,
  552. queue = t.queue[name] || [];
  553. $.when.apply($, queue).then($.proxy(fn, t));
  554. },
  555. clearQueue: function(name) {
  556. var t = this;
  557. t.queue[name] = [];
  558. },
  559. /**
  560. * Register event
  561. */
  562. registerEvent: function(name, callbackFunction, oneTime) {
  563. var t = this;
  564. if (!t.registeredEvents[name]) {
  565. t.registeredEvents[name] = [];
  566. }
  567. t.registeredEvents[name].push({
  568. func: callbackFunction,
  569. oneTime: oneTime || false
  570. });
  571. },
  572. /**
  573. * Trigger event
  574. */
  575. triggerEvent: function(name, param) {
  576. var t = this,
  577. i, len;
  578. if (t.registeredEvents[name]) {
  579. for (i = 0, len = t.registeredEvents[name].length; i < len; i++) {
  580. t.registeredEvents[name][i].func.call(t, param);
  581. if (t.registeredEvents[name][i].oneTime) {
  582. t.registeredEvents[name].splice(i, 1);
  583. // function splice change the t.registeredEvents[name] array
  584. // if event is one time you must set the i to the same value
  585. // next time and set the length lower
  586. i--;
  587. len--;
  588. }
  589. }
  590. }
  591. },
  592. addItems: function(items, callback, position) {
  593. var t = this;
  594. // wrap .cbp-item-wrap div inside .cbp-item
  595. t.wrapInner(items, 'cbp-item-wrapper');
  596. t.$ul[position](items.addClass('cbp-item-loading').css({
  597. top: '100%',
  598. left: 0
  599. }));
  600. if (CubePortfolio.private.modernBrowser) {
  601. items.last().one(CubePortfolio.private.animationend, function() {
  602. t.addItemsFinish(items, callback);
  603. });
  604. } else {
  605. t.addItemsFinish(items, callback); // @todo - on ie8 & ie9 callback triggers to early
  606. }
  607. t.loadImages(items, function() {
  608. t.$obj.addClass('cbp-updateItems');
  609. if (position === 'append') {
  610. // push to data values of items
  611. t.storeData(items, t.blocks.length);
  612. $.merge(t.blocks, items);
  613. } else {
  614. // push to data values of items
  615. t.storeData(items);
  616. var itemsLen = items.length;
  617. t.blocks.each(function(index, el) {
  618. $(el).data('cbp').index = itemsLen + index;
  619. });
  620. // push the new items to t.blocks
  621. t.blocks = $.merge(items, t.blocks);
  622. }
  623. t.triggerEvent('addItemsToDOM', items);
  624. // trigger a sort before layout
  625. t.triggerEvent('triggerSort');
  626. t.layoutAndAdjustment(true);
  627. // if show count was actived, call show count function again
  628. if (t.elems) {
  629. CubePortfolio.public.showCounter.call(t.obj, t.elems);
  630. }
  631. });
  632. },
  633. addItemsFinish: function(items, callback) {
  634. var t = this;
  635. t.isAnimating = false;
  636. t.$obj.removeClass('cbp-updateItems');
  637. items.removeClass('cbp-item-loading');
  638. if ($.isFunction(callback)) {
  639. callback.call(t, items);
  640. }
  641. // trigger public event onAfterLoadMore
  642. t.$obj.trigger('onAfterLoadMore.cbp', [items]);
  643. },
  644. removeItems: function(items, callback) {
  645. var t = this;
  646. t.$obj.addClass('cbp-updateItems');
  647. if (CubePortfolio.private.modernBrowser) {
  648. items.last().one(CubePortfolio.private.animationend, function() {
  649. t.removeItemsFinish(items, callback);
  650. });
  651. } else {
  652. t.removeItemsFinish(items, callback); // @todo - on ie8 & ie9 callback triggers to early
  653. }
  654. items.each(function(index, el) {
  655. t.blocks.each(function(index2, el2) {
  656. if (el === el2) {
  657. var removeEl = $(el2);
  658. // remove element from blocks
  659. t.blocks.splice(index2, 1);
  660. if (CubePortfolio.private.modernBrowser) {
  661. removeEl.one(CubePortfolio.private.animationend, function() {
  662. removeEl.remove();
  663. });
  664. removeEl.addClass('cbp-removeItem');
  665. } else {
  666. removeEl.remove();
  667. }
  668. }
  669. });
  670. });
  671. t.blocks.each(function(index, el) {
  672. $(el).data('cbp').index = index;
  673. });
  674. // trigger a sort before layout
  675. t.triggerEvent('triggerSort');
  676. t.layoutAndAdjustment(true);
  677. // if show count was actived, call show count function again
  678. if (t.elems) {
  679. CubePortfolio.public.showCounter.call(t.obj, t.elems);
  680. }
  681. },
  682. removeItemsFinish: function(items, callback) {
  683. var t = this;
  684. t.isAnimating = false;
  685. t.$obj.removeClass('cbp-updateItems');
  686. if ($.isFunction(callback)) {
  687. callback.call(t, items);
  688. }
  689. },
  690. });
  691. /**
  692. * jQuery plugin initializer
  693. */
  694. $.fn.cubeportfolio = function(method, options, callback) {
  695. return this.each(function() {
  696. if (typeof method === 'object' || !method) {
  697. return CubePortfolio.public.init.call(this, method, options);
  698. } else if (CubePortfolio.public[method]) {
  699. return CubePortfolio.public[method].call(this, options, callback);
  700. }
  701. throw new Error('Method ' + method + ' does not exist on jquery.cubeportfolio.js');
  702. });
  703. };
  704. CubePortfolio.plugins = {};
  705. $.fn.cubeportfolio.constructor = CubePortfolio;
  706. })(jQuery, window, document);
  707. (function($, window, document, undefined) {
  708. 'use strict';
  709. var CubePortfolio = $.fn.cubeportfolio.constructor;
  710. $.extend(CubePortfolio.prototype, {
  711. mosaicLayoutReset: function() {
  712. var t = this;
  713. // flag to be set after the blocks sorting is done
  714. t.blocksAreSorted = false;
  715. // when I start the layout again all blocks must not be positionated
  716. // reset height if it was set for addHeightToBlocks
  717. t.blocksOn.each(function(index, el) {
  718. $(el).data('cbp').pack = false;
  719. if (t.options.sortByDimension) {
  720. el.style.height = '';
  721. }
  722. });
  723. // array of objects where I keep the spaces available in the grid
  724. t.freeSpaces = [{
  725. leftStart: 0,
  726. leftEnd: t.widthAvailable,
  727. topStart: 0,
  728. topEnd: Math.pow(2, 18) // @todo - optimize
  729. }];
  730. },
  731. mosaicLayout: function() {
  732. var t = this;
  733. for (var i = 0, blocksLen = t.blocksOn.length; i < blocksLen; i++) {
  734. var spaceIndexAndBlock = t.getSpaceIndexAndBlock();
  735. // if space or block are null then start sorting
  736. if (spaceIndexAndBlock === null) {
  737. t.mosaicLayoutReset();
  738. // sort blocks to prevent gaps set to true
  739. t.blocksAreSorted = true;
  740. // sort by the longer width first, followed by a comparison of the shorter height in descending order
  741. t.sortBlocks(t.blocksOn, 'widthAndGap', 'heightAndGap', true);
  742. // after the sort is finished start the layout again
  743. t.mosaicLayout();
  744. return;
  745. }
  746. t.generateF1F2(spaceIndexAndBlock.spaceIndex, spaceIndexAndBlock.dataBlock);
  747. t.generateG1G2G3G4(spaceIndexAndBlock.dataBlock);
  748. t.cleanFreeSpaces();
  749. t.addHeightToBlocks();
  750. }
  751. // sort blocksOn from top to bottom to add properly delay from animationType and displayType options
  752. if (t.blocksAreSorted) {
  753. t.sortBlocks(t.blocksOn, 'topNew', 'leftNew');
  754. }
  755. },
  756. /**
  757. * Chose from freeSpaces the best space available
  758. * Find block by verifying if it can fit in bestSpace(top-left space available)
  759. * If block doesn't fit in the first space available & t.options.sortByDimension
  760. * is set to true then sort the blocks and start the layout once again
  761. * Decide the free rectangle Fi from F to pack the rectangle R into.
  762. */
  763. getSpaceIndexAndBlock: function() {
  764. var t = this,
  765. spaceIndexAndBlock = null;
  766. $.each(t.freeSpaces, function(index1, space) {
  767. var widthSpace = space.leftEnd - space.leftStart,
  768. heightSpace = space.topEnd - space.topStart;
  769. t.blocksOn.each(function(index2, block) {
  770. var data = $(block).data('cbp');
  771. if (data.pack === true) {
  772. return;
  773. }
  774. if (data.widthAndGap <= widthSpace && data.heightAndGap <= heightSpace) {
  775. // now the rectagle can be positioned
  776. data.pack = true;
  777. spaceIndexAndBlock = {
  778. spaceIndex: index1,
  779. dataBlock: data
  780. };
  781. data.leftNew = space.leftStart;
  782. data.topNew = space.topStart;
  783. // if the block is founded => return from this loop
  784. return false;
  785. }
  786. });
  787. // if first space don't have a block and sortByDimension is true => return from loop
  788. if (!t.blocksAreSorted && t.options.sortByDimension && index1 > 0) {
  789. spaceIndexAndBlock = null;
  790. return false;
  791. }
  792. // if space & block is founded => return from loop
  793. if (spaceIndexAndBlock !== null) {
  794. return false;
  795. }
  796. });
  797. return spaceIndexAndBlock;
  798. },
  799. /**
  800. * Use the MAXRECTS split scheme to subdivide Fi(space) into F1 and F2 and
  801. * then remove that space from spaces
  802. * Insert F1 & F2 in F in place of Fi
  803. */
  804. generateF1F2: function(spaceIndex, block) {
  805. var t = this,
  806. space = t.freeSpaces[spaceIndex];
  807. var F1 = {
  808. leftStart: space.leftStart + block.widthAndGap,
  809. leftEnd: space.leftEnd,
  810. topStart: space.topStart,
  811. topEnd: space.topEnd
  812. };
  813. var F2 = {
  814. leftStart: space.leftStart,
  815. leftEnd: space.leftEnd,
  816. topStart: space.topStart + block.heightAndGap,
  817. topEnd: space.topEnd
  818. };
  819. // remove Fi from F
  820. t.freeSpaces.splice(spaceIndex, 1);
  821. if (F1.leftEnd > F1.leftStart && F1.topEnd > F1.topStart) {
  822. t.freeSpaces.splice(spaceIndex, 0, F1);
  823. spaceIndex++;
  824. }
  825. if (F2.leftEnd > F2.leftStart && F2.topEnd > F2.topStart) {
  826. t.freeSpaces.splice(spaceIndex, 0, F2);
  827. }
  828. },
  829. /**
  830. * Generate G1, G2, G3, G4 from intersaction of t.freeSpaces with block
  831. */
  832. generateG1G2G3G4: function(block) {
  833. var t = this;
  834. var spaces = [];
  835. $.each(t.freeSpaces, function(index, space) {
  836. var intersectSpace = t.intersectSpaces(space, block);
  837. // if block & space are the same push space in spaces and return
  838. if (intersectSpace === null) {
  839. spaces.push(space);
  840. return;
  841. }
  842. t.generateG1(space, intersectSpace, spaces);
  843. t.generateG2(space, intersectSpace, spaces);
  844. t.generateG3(space, intersectSpace, spaces);
  845. t.generateG4(space, intersectSpace, spaces);
  846. });
  847. t.freeSpaces = spaces;
  848. },
  849. /**
  850. * Return the intersected rectagle of Fi and block
  851. * If the two spaces don't intersect or are the same return null
  852. */
  853. intersectSpaces: function(space1, block) {
  854. var t = this,
  855. space2 = {
  856. leftStart: block.leftNew,
  857. leftEnd: block.leftNew + block.widthAndGap,
  858. topStart: block.topNew,
  859. topEnd: block.topNew + block.heightAndGap,
  860. };
  861. if (space1.leftStart === space2.leftStart &&
  862. space1.leftEnd === space2.leftEnd &&
  863. space1.topStart === space2.topStart &&
  864. space1.topEnd === space2.topEnd) {
  865. return null;
  866. }
  867. var leftStart = Math.max(space1.leftStart, space2.leftStart),
  868. leftEnd = Math.min(space1.leftEnd, space2.leftEnd),
  869. topStart = Math.max(space1.topStart, space2.topStart),
  870. topEnd = Math.min(space1.topEnd, space2.topEnd);
  871. if (leftEnd <= leftStart || topEnd <= topStart) {
  872. return null;
  873. }
  874. return {
  875. leftStart: leftStart,
  876. leftEnd: leftEnd,
  877. topStart: topStart,
  878. topEnd: topEnd
  879. };
  880. },
  881. /**
  882. * The top subdivide space
  883. */
  884. generateG1: function(space, intersectSpace, spaces) {
  885. if (space.topStart === intersectSpace.topStart) {
  886. return;
  887. }
  888. spaces.push({
  889. leftStart: space.leftStart,
  890. leftEnd: space.leftEnd,
  891. topStart: space.topStart,
  892. topEnd: intersectSpace.topStart
  893. });
  894. },
  895. /**
  896. * The right subdivide space
  897. */
  898. generateG2: function(space, intersectSpace, spaces) {
  899. if (space.leftEnd === intersectSpace.leftEnd) {
  900. return;
  901. }
  902. spaces.push({
  903. leftStart: intersectSpace.leftEnd,
  904. leftEnd: space.leftEnd,
  905. topStart: space.topStart,
  906. topEnd: space.topEnd
  907. });
  908. },
  909. /**
  910. * The bottom subdivide space
  911. */
  912. generateG3: function(space, intersectSpace, spaces) {
  913. if (space.topEnd === intersectSpace.topEnd) {
  914. return;
  915. }
  916. spaces.push({
  917. leftStart: space.leftStart,
  918. leftEnd: space.leftEnd,
  919. topStart: intersectSpace.topEnd,
  920. topEnd: space.topEnd
  921. });
  922. },
  923. /**
  924. * The left subdivide space
  925. */
  926. generateG4: function(space, intersectSpace, spaces) {
  927. if (space.leftStart === intersectSpace.leftStart) {
  928. return;
  929. }
  930. spaces.push({
  931. leftStart: space.leftStart,
  932. leftEnd: intersectSpace.leftStart,
  933. topStart: space.topStart,
  934. topEnd: space.topEnd
  935. });
  936. },
  937. /**
  938. * For every Fi check if is another Fj so Fj contains Fi
  939. * @todo - refactor
  940. */
  941. cleanFreeSpaces: function() {
  942. var t = this;
  943. // sort space from top to bottom and left to right
  944. t.freeSpaces.sort(function(space1, space2) {
  945. if (space1.topStart > space2.topStart) {
  946. return 1;
  947. } else if (space1.topStart < space2.topStart) {
  948. return -1;
  949. } else {
  950. if (space1.leftStart > space2.leftStart) {
  951. return 1;
  952. } else if (space1.leftStart < space2.leftStart) {
  953. return -1;
  954. } else {
  955. return 0;
  956. }
  957. }
  958. });
  959. t.correctSubPixelValues();
  960. t.removeNonMaximalFreeSpaces();
  961. },
  962. /**
  963. * If topStart values for spaces are <= 1px then align those spaces
  964. */
  965. correctSubPixelValues: function() {
  966. var t = this,
  967. i, len, diff, space1, space2;
  968. for (i = 0, len = t.freeSpaces.length - 1; i < len; i++) {
  969. space1 = t.freeSpaces[i];
  970. space2 = t.freeSpaces[i + 1];
  971. if ((space2.topStart - space1.topStart) <= 1) {
  972. space2.topStart = space1.topStart;
  973. }
  974. }
  975. },
  976. /**
  977. * Remove spaces that are not maximal
  978. * If Fi contains Fj then remove Fj from F
  979. */
  980. removeNonMaximalFreeSpaces: function() {
  981. var t = this;
  982. t.uniqueFreeSpaces();
  983. t.freeSpaces = $.map(t.freeSpaces, function(space1, index1) {
  984. $.each(t.freeSpaces, function(index2, space2) {
  985. // don't compare the same free spaces
  986. if (index1 === index2) {
  987. return;
  988. }
  989. if (space2.leftStart <= space1.leftStart &&
  990. space2.leftEnd >= space1.leftEnd &&
  991. space2.topStart <= space1.topStart &&
  992. space2.topEnd >= space1.topEnd) {
  993. space1 = null;
  994. return false;
  995. }
  996. });
  997. return space1;
  998. });
  999. },
  1000. /**
  1001. * Remove duplicates spaces from freeSpaces
  1002. */
  1003. uniqueFreeSpaces: function() {
  1004. var t = this,
  1005. result = [];
  1006. $.each(t.freeSpaces, function(index1, space1) {
  1007. $.each(result, function(index2, space2) {
  1008. if (space2.leftStart === space1.leftStart &&
  1009. space2.leftEnd === space1.leftEnd &&
  1010. space2.topStart === space1.topStart &&
  1011. space2.topEnd === space1.topEnd) {
  1012. space1 = null;
  1013. return false;
  1014. }
  1015. });
  1016. if (space1 !== null) {
  1017. result.push(space1);
  1018. }
  1019. });
  1020. t.freeSpaces = result;
  1021. },
  1022. /**
  1023. * If freeSpaces arrray has only one space and that space overlap the
  1024. * height of the bottom blocks with 1px cut those blocks
  1025. */
  1026. addHeightToBlocks: function() {
  1027. var t = this;
  1028. $.each(t.freeSpaces, function(indexSpace, space) {
  1029. t.blocksOn.each(function(indexBlock, block) {
  1030. var data = $(block).data('cbp');
  1031. if (data.pack !== true) {
  1032. return;
  1033. }
  1034. if (!t.intersectSpaces(space, data)) {
  1035. return;
  1036. }
  1037. var diff = space.topStart - data.topNew - data.heightAndGap;
  1038. if (diff === -1) {
  1039. block.style.height = (data.height - 1) + 'px';
  1040. }
  1041. });
  1042. });
  1043. },
  1044. /**
  1045. * Generic sort blocks
  1046. */
  1047. sortBlocks: function(blocks, compare1, compare2, order) {
  1048. compare2 = (compare2 === undefined)? 'leftNew' : compare2;
  1049. order = (order === undefined)? 1 : -1;
  1050. blocks.sort(function(block1, block2) {
  1051. var data1 = $(block1).data('cbp'),
  1052. data2 = $(block2).data('cbp');
  1053. if (data1[compare1] > data2[compare1]) {
  1054. return order;
  1055. } else if (data1[compare1] < data2[compare1]) {
  1056. return -order;
  1057. } else {
  1058. if (data1[compare2] > data2[compare2]) {
  1059. return order;
  1060. } else if (data1[compare2] < data2[compare2]) {
  1061. return -order;
  1062. } else {
  1063. // order asc by index
  1064. if (data1.index > data2.index) {
  1065. return order;
  1066. } else if (data1.index < data2.index) {
  1067. return -order;
  1068. }
  1069. }
  1070. }
  1071. });
  1072. }
  1073. });
  1074. })(jQuery, window, document);
  1075. // Plugin default options
  1076. jQuery.fn.cubeportfolio.options = {
  1077. /**
  1078. * Define the wrapper for filters
  1079. * Values: strings that represent the elements in the document (DOM selector).
  1080. */
  1081. filters: '',
  1082. /**
  1083. * Define the search input element
  1084. * Values: strings that represent the element in the document (DOM selector).
  1085. */
  1086. search: '',
  1087. /**
  1088. * Layout Mode for this instance
  1089. * Values: 'grid', 'mosaic' or 'slider'
  1090. */
  1091. layoutMode: 'grid',
  1092. /**
  1093. * Sort the items by dimension (bigger to smallest) if there are gaps in grid
  1094. * Option available only for `layoutMode: 'mosaic'`
  1095. * Values: true or false
  1096. */
  1097. sortByDimension: false,
  1098. /**
  1099. * Mouse and touch drag support
  1100. * Option available only for `layoutMode: 'slider'`
  1101. * Values: true or false
  1102. */
  1103. drag: true,
  1104. /**
  1105. * Autoplay the slider
  1106. * Option available only for `layoutMode: 'slider'`
  1107. * Values: true or false
  1108. */
  1109. auto: false,
  1110. /**
  1111. * Autoplay interval timeout. Time is set in milisecconds
  1112. * 1000 milliseconds equals 1 second.
  1113. * Option available only for `layoutMode: 'slider'`
  1114. * Values: only integers (ex: 1000, 2000, 5000)
  1115. */
  1116. autoTimeout: 5000,
  1117. /**
  1118. * Stops autoplay when user hover the slider
  1119. * Option available only for `layoutMode: 'slider'`
  1120. * Values: true or false
  1121. */
  1122. autoPauseOnHover: true,
  1123. /**
  1124. * Show `next` and `prev` buttons for slider
  1125. * Option available only for `layoutMode: 'slider'`
  1126. * Values: true or false
  1127. */
  1128. showNavigation: true,
  1129. /**
  1130. * Show pagination for slider
  1131. * Option available only for `layoutMode: 'slider'`
  1132. * Values: true or false
  1133. */
  1134. showPagination: true,
  1135. /**
  1136. * Enable slide to first item (last item)
  1137. * Option available only for `layoutMode: 'slider'`
  1138. * Values: true or false
  1139. */
  1140. rewindNav: true,
  1141. /**
  1142. * Scroll by page and not by item. This option affect next/prev buttons and drag support
  1143. * Option available only for `layoutMode: 'slider'`
  1144. * Values: true or false
  1145. */
  1146. scrollByPage: false,
  1147. /**
  1148. * Default filter for plugin
  1149. * Option available only for `layoutMode: 'grid'`
  1150. * Values: strings that represent the filter name(ex: *, .logo, .web-design, .design)
  1151. */
  1152. defaultFilter: '*',
  1153. /**
  1154. * Enable / disable the deeplinking feature when you click on filters
  1155. * Option available only for `layoutMode: 'grid'`
  1156. * Values: true or false
  1157. */
  1158. filterDeeplinking: false,
  1159. /**
  1160. * Defines which animation to use for items that will be shown or hidden after a filter has been activated.
  1161. * Option available only for `layoutMode: 'grid'`
  1162. * The plugin use the best browser features available (css3 transitions and transform, GPU acceleration).
  1163. * Values: - fadeOut
  1164. * - quicksand
  1165. * - bounceLeft
  1166. * - bounceTop
  1167. * - bounceBottom
  1168. * - moveLeft
  1169. * - slideLeft
  1170. * - fadeOutTop
  1171. * - sequentially
  1172. * - skew
  1173. * - slideDelay
  1174. * - rotateSides
  1175. * - flipOutDelay
  1176. * - flipOut
  1177. * - unfold
  1178. * - foldLeft
  1179. * - scaleDown
  1180. * - scaleSides
  1181. * - frontRow
  1182. * - flipBottom
  1183. * - rotateRoom
  1184. */
  1185. animationType: 'fadeOut',
  1186. /**
  1187. * Adjust the layout grid
  1188. * Values: - default (no adjustment applied)
  1189. * - alignCenter (align the grid on center of the page)
  1190. * - responsive (use a fluid algorithm to resize the grid)
  1191. */
  1192. gridAdjustment: 'responsive',
  1193. /**
  1194. * Define `media queries` for columns layout.
  1195. * Format: [{width: a, cols: d}, {width: b, cols: e}, {width: c, cols: f}],
  1196. * where a, b, c are the grid width and d, e, f are the columns displayed.
  1197. * e.g. [{width: 1100, cols: 4}, {width: 800, cols: 3}, {width: 480, cols: 2}] means
  1198. * if (gridWidth >= 1100) => show 4 columns,
  1199. * if (gridWidth >= 800 && gridWidth < 1100) => show 3 columns,
  1200. * if (gridWidth >= 480 && gridWidth < 800) => show 2 columns,
  1201. * if (gridWidth < 480) => show 2 columns
  1202. * Keep in mind that a > b > c
  1203. * This option is available only when `gridAdjustment: 'responsive'`
  1204. * Values: - array of objects of format: [{width: a, cols: d}, {width: b, cols: e}]
  1205. * - you can define as many objects as you want
  1206. * - if this option is `false` Cube Portfolio will adjust the items
  1207. * width automatically (default option for backward compatibility)
  1208. */
  1209. mediaQueries: false,
  1210. /**
  1211. * Horizontal gap between items
  1212. * Values: only integers (ex: 1, 5, 10)
  1213. */
  1214. gapHorizontal: 10,
  1215. /**
  1216. * Vertical gap between items
  1217. * Values: only integers (ex: 1, 5, 10)
  1218. */
  1219. gapVertical: 10,
  1220. /**
  1221. * Caption - the overlay that is shown when you put the mouse over an item
  1222. * NOTE: If you don't want to have captions set this option to an empty string ( caption: '')
  1223. * Values: - pushTop
  1224. * - pushDown
  1225. * - revealBottom
  1226. * - revealTop
  1227. * - revealLeft
  1228. * - moveRight
  1229. * - overlayBottom
  1230. * - overlayBottomPush
  1231. * - overlayBottomReveal
  1232. * - overlayBottomAlong
  1233. * - overlayRightAlong
  1234. * - minimal
  1235. * - fadeIn
  1236. * - zoom
  1237. * - opacity
  1238. * - ''
  1239. */
  1240. caption: 'pushTop',
  1241. /**
  1242. * The plugin will display his content based on the following values.
  1243. * Values: - default (the content will be displayed without any animation)
  1244. * - fadeIn (the plugin will fully preload the images before displaying the items with a fadeIn effect)
  1245. * - fadeInToTop (the plugin will fully preload the images before displaying the items with a fadeIn effect from bottom to top)
  1246. * - sequentially (the plugin will fully preload the images before displaying the items with a sequentially effect)
  1247. * - bottomToTop (the plugin will fully preload the images before displaying the items with an animation from bottom to top)
  1248. */
  1249. displayType: 'fadeIn',
  1250. /**
  1251. * Defines the speed of displaying the items (when `displayType: 'default'` this option will have no effect)
  1252. * Values: only integers, values in ms (ex: 200, 300, 500)
  1253. */
  1254. displayTypeSpeed: 400,
  1255. /**
  1256. * This is used to define any clickable elements you wish to use to trigger lightbox popup on click.
  1257. * Values: strings that represent the elements in the document (DOM selector)
  1258. */
  1259. lightboxDelegate: '.cbp-lightbox',
  1260. /**
  1261. * Enable / disable gallery mode
  1262. * Values: true or false
  1263. */
  1264. lightboxGallery: true,
  1265. /**
  1266. * Attribute of the delegate item that contains caption for lightbox
  1267. * Values: html atributte
  1268. */
  1269. lightboxTitleSrc: 'data-title',
  1270. /**
  1271. * Markup of the lightbox counter
  1272. * Values: html markup
  1273. */
  1274. lightboxCounter: '<div class="cbp-popup-lightbox-counter">{{current}} of {{total}}</div>',
  1275. /**
  1276. * This is used to define any clickable elements you wish to use to trigger singlePage popup on click.
  1277. * Values: strings that represent the elements in the document (DOM selector)
  1278. */
  1279. singlePageDelegate: '.cbp-singlePage',
  1280. /**
  1281. * Enable / disable the deeplinking feature for singlePage popup
  1282. * Values: true or false
  1283. */
  1284. singlePageDeeplinking: true,
  1285. /**
  1286. * Enable / disable the sticky navigation for singlePage popup
  1287. * Values: true or false
  1288. */
  1289. singlePageStickyNavigation: true,
  1290. /**
  1291. * Markup of the singlePage counter
  1292. * Values: html markup
  1293. */
  1294. singlePageCounter: '<div class="cbp-popup-singlePage-counter">{{current}} of {{total}}</div>',
  1295. /**
  1296. * Defines which animation to use when singlePage appear
  1297. * Values: - left
  1298. * - fade
  1299. * - right
  1300. */
  1301. singlePageAnimation: 'left',
  1302. /**
  1303. * Use this callback to update singlePage content.
  1304. * The callback will trigger after the singlePage popup is open.
  1305. * Values: function
  1306. */
  1307. singlePageCallback: null,
  1308. /**
  1309. * This is used to define any clickable elements you wish to use to trigger singlePageInline on click.
  1310. * Values: strings that represent the elements in the document (DOM selector)
  1311. */
  1312. singlePageInlineDelegate: '.cbp-singlePageInline',
  1313. /**
  1314. * Enable / disable the deeplinking feature for singlePageInline
  1315. * Values: true or false
  1316. */
  1317. singlePageInlineDeeplinking: false,
  1318. /**
  1319. * This is used to define the position of singlePageInline block
  1320. * Values: - above ( above current element )
  1321. * - below ( below current elemnet)
  1322. * - top ( positon top )
  1323. * - bottom ( positon bottom )
  1324. */
  1325. singlePageInlinePosition: 'top',
  1326. /**
  1327. * Push the open panel in focus and at close go back to the former stage
  1328. * Values: true or false
  1329. */
  1330. singlePageInlineInFocus: true,
  1331. /**
  1332. * Use this callback to update singlePageInline content.
  1333. * The callback will trigger after the singlePageInline is open.
  1334. * Values: function
  1335. */
  1336. singlePageInlineCallback: null,
  1337. /**
  1338. * Used by the plugins registered to set local options for the current instance
  1339. * Values: object
  1340. */
  1341. plugins: {},
  1342. };
  1343. (function($, window, document, undefined) {
  1344. 'use strict';
  1345. var CubePortfolio = $.fn.cubeportfolio.constructor;
  1346. var $window = $(window);
  1347. CubePortfolio.private = {
  1348. publicEvents: function(eventName, time, beforeEventCallback) {
  1349. var t = this;
  1350. // array of objects: {instance: instance, fn: fn}
  1351. t.events = [];
  1352. t.initEvent = function(obj) {
  1353. if (t.events.length === 0) {
  1354. t.scrollEvent();
  1355. }
  1356. t.events.push(obj);
  1357. };
  1358. t.destroyEvent = function(instance) {
  1359. t.events = $.map(t.events, function(val, index) {
  1360. if (val.instance !== instance) {
  1361. return val;
  1362. }
  1363. });
  1364. if (t.events.length === 0) {
  1365. // remove scroll event
  1366. $window.off(eventName);
  1367. }
  1368. };
  1369. t.scrollEvent = function() {
  1370. var timeout;
  1371. // resize
  1372. $window.on(eventName, function() {
  1373. clearTimeout(timeout);
  1374. timeout = setTimeout(function() {
  1375. if ($.isFunction(beforeEventCallback) && beforeEventCallback.call(t)) {
  1376. return;
  1377. }
  1378. $.each(t.events, function(index, val) {
  1379. val.fn.call(val.instance);
  1380. });
  1381. }, time);
  1382. });
  1383. };
  1384. },
  1385. /**
  1386. * Check if cubeportfolio instance exists on current element
  1387. */
  1388. checkInstance: function(method) {
  1389. var t = $.data(this, 'cubeportfolio');
  1390. if (!t) {
  1391. throw new Error('cubeportfolio is not initialized. Initialize it before calling ' + method + ' method!');
  1392. }
  1393. t.triggerEvent('publicMethod');
  1394. return t;
  1395. },
  1396. /**
  1397. * Get info about client browser
  1398. */
  1399. browserInfo: function() {
  1400. var t = CubePortfolio.private,
  1401. appVersion = navigator.appVersion,
  1402. transition, animation, perspective;
  1403. if (appVersion.indexOf('MSIE 8.') !== -1) { // ie8
  1404. t.browser = 'ie8';
  1405. } else if (appVersion.indexOf('MSIE 9.') !== -1) { // ie9
  1406. t.browser = 'ie9';
  1407. } else if (appVersion.indexOf('MSIE 10.') !== -1) { // ie10
  1408. t.browser = 'ie10';
  1409. } else if (window.ActiveXObject || 'ActiveXObject' in window) { // ie11
  1410. t.browser = 'ie11';
  1411. } else if ((/android/gi).test(appVersion)) { // android
  1412. t.browser = 'android';
  1413. } else if ((/iphone|ipad|ipod/gi).test(appVersion)) { // ios
  1414. t.browser = 'ios';
  1415. } else if ((/chrome/gi).test(appVersion)) {
  1416. t.browser = 'chrome';
  1417. } else {
  1418. t.browser = '';
  1419. }
  1420. // check if perspective is available
  1421. perspective = t.styleSupport('perspective');
  1422. // if perspective is not available => no modern browser
  1423. if (typeof perspective === undefined) {
  1424. return;
  1425. }
  1426. transition = t.styleSupport('transition');
  1427. t.transitionend = {
  1428. WebkitTransition: 'webkitTransitionEnd',
  1429. transition: 'transitionend'
  1430. }[transition];
  1431. animation = t.styleSupport('animation');
  1432. t.animationend = {
  1433. WebkitAnimation: 'webkitAnimationEnd',
  1434. animation: 'animationend'
  1435. }[animation];
  1436. t.animationDuration = {
  1437. WebkitAnimation: 'webkitAnimationDuration',
  1438. animation: 'animationDuration'
  1439. }[animation];
  1440. t.animationDelay = {
  1441. WebkitAnimation: 'webkitAnimationDelay',
  1442. animation: 'animationDelay'
  1443. }[animation];
  1444. t.transform = t.styleSupport('transform');
  1445. if (transition && animation && t.transform) {
  1446. t.modernBrowser = true;
  1447. }
  1448. },
  1449. /**
  1450. * Feature testing for css3
  1451. */
  1452. styleSupport: function(prop) {
  1453. var supportedProp,
  1454. // capitalize first character of the prop to test vendor prefix
  1455. webkitProp = 'Webkit' + prop.charAt(0).toUpperCase() + prop.slice(1),
  1456. div = document.createElement('div');
  1457. // browser supports standard CSS property name
  1458. if (prop in div.style) {
  1459. supportedProp = prop;
  1460. } else if (webkitProp in div.style) {
  1461. supportedProp = webkitProp;
  1462. }
  1463. // avoid memory leak in IE
  1464. div = null;
  1465. return supportedProp;
  1466. },
  1467. };
  1468. CubePortfolio.private.browserInfo();
  1469. CubePortfolio.private.resize = new CubePortfolio.private.publicEvents('resize.cbp', 50, function() {
  1470. if (window.innerHeight == screen.height) {
  1471. // this is fulll screen mode. don't need to trigger a resize
  1472. return true;
  1473. }
  1474. });
  1475. })(jQuery, window, document);
  1476. (function($, window, document, undefined) {
  1477. 'use strict';
  1478. var CubePortfolio = $.fn.cubeportfolio.constructor;
  1479. CubePortfolio.public = {
  1480. /*
  1481. * Init the plugin
  1482. */
  1483. init: function(options, callback) {
  1484. new CubePortfolio(this, options, callback);
  1485. },
  1486. /*
  1487. * Destroy the plugin
  1488. */
  1489. destroy: function(callback) {
  1490. var t = CubePortfolio.private.checkInstance.call(this, 'destroy');
  1491. t.triggerEvent('beforeDestroy');
  1492. // remove data
  1493. $.removeData(this, 'cubeportfolio');
  1494. // remove data from blocks
  1495. t.blocks.removeData('cbp');
  1496. // remove loading class and .cbp on container
  1497. t.$obj.removeClass('cbp-ready').removeAttr('style');
  1498. // remove class from ul
  1499. t.$ul.removeClass('cbp-wrapper');
  1500. // remove resize event
  1501. CubePortfolio.private.resize.destroyEvent(t);
  1502. t.$obj.off('.cbp');
  1503. // reset blocks
  1504. t.blocks.removeClass('cbp-item-off').removeAttr('style');
  1505. t.blocks.find('.cbp-item-wrapper').each(function(index, el) {
  1506. var elem = $(el),
  1507. children = elem.children();
  1508. if (children.length) {
  1509. children.unwrap();
  1510. } else {
  1511. elem.remove();
  1512. }
  1513. });
  1514. if (t.destroySlider) {
  1515. t.destroySlider();
  1516. }
  1517. // remove .cbp-wrapper-outer
  1518. t.$ul.unwrap();
  1519. // remove .cbp-wrapper
  1520. if (t.addedWrapp) {
  1521. t.blocks.unwrap();
  1522. }
  1523. if (t.blocks.length === 0) {
  1524. t.$ul.remove();
  1525. }
  1526. $.each(t.plugins, function(key, value) {
  1527. if (typeof value.destroy === 'function') {
  1528. value.destroy();
  1529. }
  1530. });
  1531. if ($.isFunction(callback)) {
  1532. callback.call(t);
  1533. }
  1534. t.triggerEvent('afterDestroy');
  1535. },
  1536. /*
  1537. * Filter the plugin by filterName
  1538. */
  1539. filter: function(param, callback) {
  1540. var t = CubePortfolio.private.checkInstance.call(this, 'filter'),
  1541. expression;
  1542. if (t.isAnimating) {
  1543. return;
  1544. }
  1545. t.isAnimating = true;
  1546. // register callback function
  1547. if ($.isFunction(callback)) {
  1548. t.registerEvent('filterFinish', callback, true);
  1549. }
  1550. if ($.isFunction(param)) {
  1551. expression = param.call(t, t.blocks);
  1552. if(expression === undefined) {
  1553. throw new Error('When you call cubeportfolio API `filter` method with a param of type function you must return the blocks that will be visible.');
  1554. }
  1555. } else {
  1556. if (t.options.filterDeeplinking) {
  1557. var url = location.href.replace(/#cbpf=(.*?)([#\?&]|$)/gi, '');
  1558. location.href = url + '#cbpf=' + encodeURIComponent(param);
  1559. if (t.singlePage && t.singlePage.url) {
  1560. t.singlePage.url = location.href;
  1561. }
  1562. }
  1563. t.defaultFilter = param;
  1564. expression = t.filterConcat(t.defaultFilter);
  1565. }
  1566. t.triggerEvent('filterStart', expression);
  1567. if (t.singlePageInline && t.singlePageInline.isOpen) {
  1568. t.singlePageInline.close('promise', {
  1569. callback: function() {
  1570. t.computeFilter(expression);
  1571. }
  1572. });
  1573. } else {
  1574. t.computeFilter(expression);
  1575. }
  1576. },
  1577. /*
  1578. * Show counter for filters
  1579. */
  1580. showCounter: function(elems, callback) {
  1581. var t = CubePortfolio.private.checkInstance.call(this, 'showCounter');
  1582. // register callback function
  1583. if ($.isFunction(callback)) {
  1584. t.registerEvent('showCounterFinish', callback, true);
  1585. }
  1586. t.elems = elems;
  1587. elems.each(function() {
  1588. var el = $(this);
  1589. var count = t.blocks.filter(el.data('filter')).length;
  1590. el.find('.cbp-filter-counter').text(count);
  1591. });
  1592. t.triggerEvent('showCounterFinish', elems);
  1593. },
  1594. // alias for append public method
  1595. appendItems: function(els, callback) {
  1596. CubePortfolio.public.append.call(this, els, callback);
  1597. },
  1598. /*
  1599. * Append elements
  1600. */
  1601. append: function(els, callback) {
  1602. var t = CubePortfolio.private.checkInstance.call(this, 'append'),
  1603. items = $(els).filter('.cbp-item');
  1604. if (t.isAnimating || items.length < 1) {
  1605. if ($.isFunction(callback)) {
  1606. callback.call(t, items);
  1607. }
  1608. return;
  1609. }
  1610. t.isAnimating = true;
  1611. if (t.singlePageInline && t.singlePageInline.isOpen) {
  1612. t.singlePageInline.close('promise', {
  1613. callback: function() {
  1614. t.addItems(items, callback, 'append');
  1615. }
  1616. });
  1617. } else {
  1618. t.addItems(items, callback, 'append');
  1619. }
  1620. },
  1621. /*
  1622. * Prepend elements
  1623. */
  1624. prepend: function(els, callback) {
  1625. var t = CubePortfolio.private.checkInstance.call(this, 'prepend'),
  1626. items = $(els).filter('.cbp-item');
  1627. if (t.isAnimating || items.length < 1) {
  1628. if ($.isFunction(callback)) {
  1629. callback.call(t, items);
  1630. }
  1631. return;
  1632. }
  1633. t.isAnimating = true;
  1634. if (t.singlePageInline && t.singlePageInline.isOpen) {
  1635. t.singlePageInline.close('promise', {
  1636. callback: function() {
  1637. t.addItems(items, callback, 'prepend');
  1638. }
  1639. });
  1640. } else {
  1641. t.addItems(items, callback, 'prepend');
  1642. }
  1643. },
  1644. /*
  1645. * Remove elements from the instance and DOM.
  1646. * els - jQuery DOM Object
  1647. */
  1648. remove: function(els, callback) {
  1649. var t = CubePortfolio.private.checkInstance.call(this, 'remove'),
  1650. items = $(els).filter('.cbp-item');
  1651. if (t.isAnimating || items.length < 1) {
  1652. if ($.isFunction(callback)) {
  1653. callback.call(t, items);
  1654. }
  1655. return;
  1656. }
  1657. t.isAnimating = true;
  1658. if (t.singlePageInline && t.singlePageInline.isOpen) {
  1659. t.singlePageInline.close('promise', {
  1660. callback: function() {
  1661. t.removeItems(items, callback);
  1662. }
  1663. });
  1664. } else {
  1665. t.removeItems(items, callback);
  1666. }
  1667. },
  1668. /*
  1669. * Relayout all elements in the current grid.
  1670. * Useful when all/some items need to be laid out again, or grid width is changed.
  1671. */
  1672. layout: function(callback) {
  1673. var t = CubePortfolio.private.checkInstance.call(this, 'layout');
  1674. // update the current grid width
  1675. t.width = t.$obj.outerWidth();
  1676. if (t.isAnimating || (t.width <= 0)) {
  1677. if ($.isFunction(callback)) {
  1678. callback.call(t);
  1679. }
  1680. return;
  1681. }
  1682. if (t.options.gridAdjustment === 'alignCenter') {
  1683. t.wrapper[0].style.maxWidth = '';
  1684. }
  1685. // store to data values of t.blocks
  1686. t.storeData(t.blocks);
  1687. // reposition the blocks
  1688. t.layoutAndAdjustment();
  1689. if ($.isFunction(callback)) {
  1690. callback.call(t);
  1691. }
  1692. },
  1693. };
  1694. })(jQuery, window, document);
  1695. (function($, window, document, undefined) {
  1696. 'use strict';
  1697. var CubePortfolio = $.fn.cubeportfolio.constructor;
  1698. // @todo - gandit cum ar trebui sa fac aici ca nu prea ar merge un plugin
  1699. // pt slider ca as extinde pe CubePortfolio.prototype la fiecare initializare
  1700. $.extend(CubePortfolio.prototype, {
  1701. updateSliderPagination: function() {
  1702. var t = this,
  1703. pages,
  1704. i;
  1705. if (t.options.showPagination) {
  1706. // get number of pages
  1707. pages = Math.ceil(t.blocksOn.length / t.cols);
  1708. t.navPagination.empty();
  1709. for (i = pages - 1; i >= 0; i--) {
  1710. $('<div/>', {
  1711. 'class': 'cbp-nav-pagination-item',
  1712. 'data-slider-action': 'jumpTo'
  1713. }).appendTo(t.navPagination);
  1714. }
  1715. t.navPaginationItems = t.navPagination.children();
  1716. }
  1717. // enable disable the nav
  1718. t.enableDisableNavSlider();
  1719. },
  1720. destroySlider: function() {
  1721. var t = this;
  1722. if (t.options.layoutMode !== 'slider') {
  1723. return;
  1724. }
  1725. t.$obj.removeClass('cbp-mode-slider');
  1726. t.$ul.removeAttr('style');
  1727. t.$ul.off('.cbp');
  1728. $(document).off('.cbp'); // @todo - don't interfer with the lightbox
  1729. if (t.options.auto) {
  1730. t.stopSliderAuto();
  1731. }
  1732. },
  1733. nextSlider: function(el) {
  1734. var t = this;
  1735. if (t.isEndSlider()) {
  1736. if (t.isRewindNav()) {
  1737. t.sliderActive = 0;
  1738. } else {
  1739. return;
  1740. }
  1741. } else {
  1742. if (t.options.scrollByPage) {
  1743. t.sliderActive = Math.min(t.sliderActive + t.cols, t.blocksOn.length - t.cols);
  1744. } else {
  1745. t.sliderActive += 1;
  1746. }
  1747. }
  1748. t.goToSlider();
  1749. },
  1750. prevSlider: function(el) {
  1751. var t = this;
  1752. if (t.isStartSlider()) {
  1753. if (t.isRewindNav()) {
  1754. t.sliderActive = t.blocksOn.length - t.cols;
  1755. } else {
  1756. return;
  1757. }
  1758. } else {
  1759. if (t.options.scrollByPage) {
  1760. t.sliderActive = Math.max(0, t.sliderActive - t.cols);
  1761. } else {
  1762. t.sliderActive -= 1;
  1763. }
  1764. }
  1765. t.goToSlider();
  1766. },
  1767. jumpToSlider: function(el) {
  1768. var t = this,
  1769. index = Math.min(el.index() * t.cols, t.blocksOn.length - t.cols);
  1770. if (index === t.sliderActive) {
  1771. return;
  1772. }
  1773. t.sliderActive = index;
  1774. t.goToSlider();
  1775. },
  1776. jumpDragToSlider: function(pos) {
  1777. var t = this,
  1778. jumpWidth,
  1779. offset,
  1780. condition,
  1781. index,
  1782. dragLeft = (pos > 0) ? true : false;
  1783. if (t.options.scrollByPage) {
  1784. jumpWidth = t.cols * t.columnWidth;
  1785. offset = t.cols;
  1786. } else {
  1787. jumpWidth = t.columnWidth;
  1788. offset = 1;
  1789. }
  1790. pos = Math.abs(pos);
  1791. index = Math.floor(pos / jumpWidth) * offset;
  1792. if (pos % jumpWidth > 20) {
  1793. index += offset;
  1794. }
  1795. if (dragLeft) { // drag to left
  1796. t.sliderActive = Math.min(t.sliderActive + index, t.blocksOn.length - t.cols);
  1797. } else { // drag to right
  1798. t.sliderActive = Math.max(0, t.sliderActive - index);
  1799. }
  1800. t.goToSlider();
  1801. },
  1802. isStartSlider: function() {
  1803. return this.sliderActive === 0;
  1804. },
  1805. isEndSlider: function() {
  1806. var t = this;
  1807. return (t.sliderActive + t.cols) > t.blocksOn.length - 1;
  1808. },
  1809. goToSlider: function() {
  1810. var t = this;
  1811. // enable disable the nav
  1812. t.enableDisableNavSlider();
  1813. t.updateSliderPosition();
  1814. },
  1815. startSliderAuto: function() {
  1816. var t = this;
  1817. if (t.isDrag) {
  1818. t.stopSliderAuto();
  1819. return;
  1820. }
  1821. t.timeout = setTimeout(function() {
  1822. // go to next slide
  1823. t.nextSlider();
  1824. // start auto
  1825. t.startSliderAuto();
  1826. }, t.options.autoTimeout);
  1827. },
  1828. stopSliderAuto: function() {
  1829. clearTimeout(this.timeout);
  1830. },
  1831. enableDisableNavSlider: function() {
  1832. var t = this,
  1833. page,
  1834. method;
  1835. if (!t.isRewindNav()) {
  1836. method = (t.isStartSlider()) ? 'addClass' : 'removeClass';
  1837. t.navPrev[method]('cbp-nav-stop');
  1838. method = (t.isEndSlider()) ? 'addClass' : 'removeClass';
  1839. t.navNext[method]('cbp-nav-stop');
  1840. }
  1841. if (t.options.showPagination) {
  1842. if (t.options.scrollByPage) {
  1843. page = Math.ceil(t.sliderActive / t.cols);
  1844. } else {
  1845. if (t.isEndSlider()) {
  1846. page = t.navPaginationItems.length - 1;
  1847. } else {
  1848. page = Math.floor(t.sliderActive / t.cols);
  1849. }
  1850. }
  1851. // add class active on pagination's items
  1852. t.navPaginationItems.removeClass('cbp-nav-pagination-active')
  1853. .eq(page)
  1854. .addClass('cbp-nav-pagination-active');
  1855. }
  1856. if (t.customPagination) {
  1857. if (t.options.scrollByPage) {
  1858. page = Math.ceil(t.sliderActive / t.cols);
  1859. } else {
  1860. if (t.isEndSlider()) {
  1861. page = t.customPaginationItems.length - 1;
  1862. } else {
  1863. page = Math.floor(t.sliderActive / t.cols);
  1864. }
  1865. }
  1866. // add class active on pagination's items
  1867. t.customPaginationItems.removeClass(t.customPaginationClass)
  1868. .eq(page)
  1869. .addClass(t.customPaginationClass);
  1870. }
  1871. },
  1872. /**
  1873. * If slider loop is enabled don't add classes to `next` and `prev` buttons
  1874. */
  1875. isRewindNav: function() {
  1876. var t = this;
  1877. if (!t.options.showNavigation) {
  1878. return true;
  1879. }
  1880. if (t.blocksOn.length <= t.cols) {
  1881. return false;
  1882. }
  1883. if (t.options.rewindNav) {
  1884. return true;
  1885. }
  1886. return false;
  1887. },
  1888. sliderItemsLength: function() {
  1889. return this.blocksOn.length <= this.cols;
  1890. },
  1891. /**
  1892. * Arrange the items in a slider layout
  1893. */
  1894. sliderLayout: function() {
  1895. var t = this;
  1896. t.blocksOn.each(function(index, el) {
  1897. var data = $(el).data('cbp');
  1898. // update the values with the new ones
  1899. data.leftNew = t.columnWidth * index;
  1900. data.topNew = 0;
  1901. t.sliderFreeSpaces.push({
  1902. topStart: data.heightAndGap
  1903. });
  1904. });
  1905. t.getFreeSpacesForSlider();
  1906. t.$ul.width(t.columnWidth * t.blocksOn.length - t.options.gapVertical);
  1907. },
  1908. getFreeSpacesForSlider: function() {
  1909. var t = this;
  1910. t.freeSpaces = t.sliderFreeSpaces.slice(t.sliderActive, t.sliderActive + t.cols);
  1911. t.freeSpaces.sort(function(space1, space2) {
  1912. if (space1.topStart > space2.topStart) {
  1913. return 1;
  1914. } else if (space1.topStart < space2.topStart) {
  1915. return -1;
  1916. }
  1917. });
  1918. },
  1919. updateSliderPosition: function() {
  1920. var t = this,
  1921. value = -t.sliderActive * t.columnWidth;
  1922. if (CubePortfolio.private.modernBrowser) {
  1923. t.$ul[0].style[CubePortfolio.private.transform] = 'translate3d(' + value + 'px, 0px, 0)';
  1924. } else {
  1925. t.$ul[0].style.left = value + 'px';
  1926. }
  1927. t.getFreeSpacesForSlider();
  1928. t.resizeMainContainer();
  1929. },
  1930. dragSlider: function() {
  1931. var t = this,
  1932. $document = $(document),
  1933. posInitial,
  1934. pos,
  1935. target,
  1936. ulPosition,
  1937. ulMaxWidth,
  1938. isAnimating = false,
  1939. events = {},
  1940. isTouch = false,
  1941. touchStartEvent,
  1942. isHover = false;
  1943. t.isDrag = false;
  1944. if (('ontouchstart' in window) ||
  1945. (navigator.maxTouchPoints > 0) ||
  1946. (navigator.msMaxTouchPoints > 0)) {
  1947. events = {
  1948. start: 'touchstart.cbp',
  1949. move: 'touchmove.cbp',
  1950. end: 'touchend.cbp'
  1951. };
  1952. isTouch = true;
  1953. } else {
  1954. events = {
  1955. start: 'mousedown.cbp',
  1956. move: 'mousemove.cbp',
  1957. end: 'mouseup.cbp'
  1958. };
  1959. }
  1960. function dragStart(e) {
  1961. if (t.sliderItemsLength()) {
  1962. return;
  1963. }
  1964. if (!isTouch) {
  1965. e.preventDefault();
  1966. } else {
  1967. touchStartEvent = e;
  1968. }
  1969. if (t.options.auto) {
  1970. t.stopSliderAuto();
  1971. }
  1972. if (isAnimating) {
  1973. $(target).one('click.cbp', function() {
  1974. return false;
  1975. });
  1976. return;
  1977. }
  1978. target = $(e.target);
  1979. posInitial = pointerEventToXY(e).x;
  1980. pos = 0;
  1981. ulPosition = -t.sliderActive * t.columnWidth;
  1982. ulMaxWidth = t.columnWidth * (t.blocksOn.length - t.cols);
  1983. $document.on(events.move, dragMove);
  1984. $document.on(events.end, dragEnd);
  1985. t.$obj.addClass('cbp-mode-slider-dragStart');
  1986. }
  1987. function dragEnd(e) {
  1988. t.$obj.removeClass('cbp-mode-slider-dragStart');
  1989. // put the state to animate
  1990. isAnimating = true;
  1991. if (pos !== 0) {
  1992. target.one('click.cbp', function(e) {
  1993. return false;
  1994. });
  1995. // wait a frame to be sure the .cbp-mode-slider-dragStart is removed from the dom
  1996. requestAnimationFrame(function() {
  1997. t.jumpDragToSlider(pos);
  1998. t.$ul.one(CubePortfolio.private.transitionend, afterDragEnd);
  1999. });
  2000. } else {
  2001. afterDragEnd.call(t);
  2002. }
  2003. $document.off(events.move);
  2004. $document.off(events.end);
  2005. }
  2006. function dragMove(e) {
  2007. pos = posInitial - pointerEventToXY(e).x;
  2008. if (pos > 8 || pos < -8) {
  2009. e.preventDefault();
  2010. }
  2011. t.isDrag = true;
  2012. var value = ulPosition - pos;
  2013. if (pos < 0 && pos < ulPosition) { // to right
  2014. value = (ulPosition - pos) / 5;
  2015. } else if (pos > 0 && (ulPosition - pos) < -ulMaxWidth) { // to left
  2016. value = -ulMaxWidth + (ulMaxWidth + ulPosition - pos) / 5;
  2017. }
  2018. if (CubePortfolio.private.modernBrowser) {
  2019. t.$ul[0].style[CubePortfolio.private.transform] = 'translate3d(' + value + 'px, 0px, 0)';
  2020. } else {
  2021. t.$ul[0].style.left = value + 'px';
  2022. }
  2023. }
  2024. function afterDragEnd() {
  2025. isAnimating = false;
  2026. t.isDrag = false;
  2027. if (t.options.auto) {
  2028. if (t.mouseIsEntered) {
  2029. return;
  2030. }
  2031. t.startSliderAuto();
  2032. }
  2033. }
  2034. function pointerEventToXY(e) {
  2035. if (e.originalEvent !== undefined && e.originalEvent.touches !== undefined) {
  2036. e = e.originalEvent.touches[0];
  2037. }
  2038. return {
  2039. x: e.pageX,
  2040. y: e.pageY
  2041. };
  2042. }
  2043. t.$ul.on(events.start, dragStart);
  2044. },
  2045. /**
  2046. * Reset the slider layout
  2047. */
  2048. sliderLayoutReset: function() {
  2049. var t = this;
  2050. t.freeSpaces = [];
  2051. t.sliderFreeSpaces = [];
  2052. },
  2053. });
  2054. })(jQuery, window, document);
  2055. if (typeof Object.create !== 'function') {
  2056. Object.create = function(obj) {
  2057. function F() {}
  2058. F.prototype = obj;
  2059. return new F();
  2060. };
  2061. }
  2062. // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
  2063. // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
  2064. // requestAnimationFrame polyfill by Erik M�ller. fixes from Paul Irish and Tino Zijdel
  2065. // MIT license
  2066. (function() {
  2067. var lastTime = 0;
  2068. var vendors = ['moz', 'webkit'];
  2069. for (var x = 0; x < vendors.length && !window.requestAnimationFrame; x++) {
  2070. window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
  2071. window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
  2072. }
  2073. if (!window.requestAnimationFrame) {
  2074. window.requestAnimationFrame = function(callback, element) {
  2075. var currTime = new Date().getTime();
  2076. var timeToCall = Math.max(0, 16 - (currTime - lastTime));
  2077. var id = window.setTimeout(function() {
  2078. callback(currTime + timeToCall);
  2079. },
  2080. timeToCall);
  2081. lastTime = currTime + timeToCall;
  2082. return id;
  2083. };
  2084. }
  2085. if (!window.cancelAnimationFrame) {
  2086. window.cancelAnimationFrame = function(id) {
  2087. clearTimeout(id);
  2088. };
  2089. }
  2090. }());
  2091. (function($, window, document, undefined) {
  2092. 'use strict';
  2093. var CubePortfolio = $.fn.cubeportfolio.constructor;
  2094. function Plugin(parent) {
  2095. var t = this;
  2096. t.parent = parent;
  2097. parent.filterLayout = t.filterLayout;
  2098. parent.registerEvent('computeBlocksFinish', function(expression) {
  2099. parent.blocksOn2On = parent.blocksOnInitial.filter(expression);
  2100. parent.blocksOn2Off = parent.blocksOnInitial.not(expression);
  2101. });
  2102. }
  2103. // here this value point to parent grid
  2104. Plugin.prototype.filterLayout = function() {
  2105. var t = this;
  2106. t.$obj.addClass('cbp-animation-' + t.options.animationType);
  2107. // [1] - blocks that are only moving with translate
  2108. t.blocksOn2On.addClass('cbp-item-on2on')
  2109. .each(function(index, el) {
  2110. var data = $(el).data('cbp');
  2111. el.style[CubePortfolio.private.transform] = 'translate3d(' + (data.leftNew - data.left) + 'px, ' + (data.topNew - data.top) + 'px, 0)';
  2112. });
  2113. // [2] - blocks than intialy are on but after applying the filter are off
  2114. t.blocksOn2Off.addClass('cbp-item-on2off');
  2115. // [3] - blocks that are off and it will be on
  2116. t.blocksOff2On = t.blocksOn
  2117. .filter('.cbp-item-off')
  2118. .removeClass('cbp-item-off')
  2119. .addClass('cbp-item-off2on')
  2120. .each(function(index, el) {
  2121. var data = $(el).data('cbp');
  2122. el.style.left = data.leftNew + 'px';
  2123. el.style.top = data.topNew + 'px';
  2124. });
  2125. if (t.blocksOn2Off.length) {
  2126. t.blocksOn2Off.last().data('cbp').wrapper.one(CubePortfolio.private.animationend, animationend);
  2127. } else if (t.blocksOff2On.length) {
  2128. t.blocksOff2On.last().data('cbp').wrapper.one(CubePortfolio.private.animationend, animationend);
  2129. } else if (t.blocksOn2On.length) { // this is used for sort feature to animate the items when sort API is triggered
  2130. t.blocksOn2On.last().one(CubePortfolio.private.transitionend, animationend);
  2131. } else {
  2132. animationend();
  2133. }
  2134. // resize main container height
  2135. t.resizeMainContainer();
  2136. function animationend() {
  2137. t.blocks.removeClass('cbp-item-on2off cbp-item-off2on cbp-item-on2on')
  2138. .each(function(index, el) {
  2139. var data = $(el).data('cbp');
  2140. data.left = data.leftNew;
  2141. data.top = data.topNew;
  2142. el.style.left = data.left + 'px';
  2143. el.style.top = data.top + 'px';
  2144. el.style[CubePortfolio.private.transform] = '';
  2145. });
  2146. t.blocksOff.addClass('cbp-item-off');
  2147. t.$obj.removeClass('cbp-animation-' + t.options.animationType);
  2148. t.filterFinish();
  2149. }
  2150. };
  2151. Plugin.prototype.destroy = function() {
  2152. var parent = this.parent;
  2153. parent.$obj.removeClass('cbp-animation-' + parent.options.animationType);
  2154. };
  2155. CubePortfolio.plugins.animationClassic = function(parent) {
  2156. if (!CubePortfolio.private.modernBrowser || $.inArray(parent.options.animationType, ['boxShadow', 'fadeOut', 'flipBottom', 'flipOut', 'quicksand', 'scaleSides', 'skew']) < 0) {
  2157. return null;
  2158. }
  2159. return new Plugin(parent);
  2160. };
  2161. })(jQuery, window, document);
  2162. (function($, window, document, undefined) {
  2163. 'use strict';
  2164. var CubePortfolio = $.fn.cubeportfolio.constructor;
  2165. function Plugin(parent) {
  2166. var t = this;
  2167. t.parent = parent;
  2168. parent.filterLayout = t.filterLayout;
  2169. }
  2170. // here this value point to parent grid
  2171. Plugin.prototype.filterLayout = function() {
  2172. var t = this,
  2173. ulClone = t.$ul[0].cloneNode(true);
  2174. ulClone.setAttribute('class', 'cbp-wrapper-helper');
  2175. t.wrapper[0].insertBefore(ulClone, t.$ul[0]);
  2176. requestAnimationFrame(function() {
  2177. t.$obj.addClass('cbp-animation-' + t.options.animationType);
  2178. t.blocksOff.addClass('cbp-item-off');
  2179. t.blocksOn.removeClass('cbp-item-off')
  2180. .each(function(index, el) {
  2181. var data = $(el).data('cbp');
  2182. data.left = data.leftNew;
  2183. data.top = data.topNew;
  2184. el.style.left = data.left + 'px';
  2185. el.style.top = data.top + 'px';
  2186. if (t.options.animationType === 'sequentially') {
  2187. data.wrapper[0].style[CubePortfolio.private.animationDelay] = (index * 60) + 'ms';
  2188. }
  2189. });
  2190. if (t.blocksOn.length) {
  2191. t.blocksOn.last().data('cbp').wrapper.one(CubePortfolio.private.animationend, animationend);
  2192. } else if (t.blocksOnInitial.length) {
  2193. t.blocksOnInitial.last().data('cbp').wrapper.one(CubePortfolio.private.animationend, animationend);
  2194. } else {
  2195. animationend();
  2196. }
  2197. // resize main container height
  2198. t.resizeMainContainer();
  2199. });
  2200. function animationend() {
  2201. t.wrapper[0].removeChild(ulClone);
  2202. if (t.options.animationType === 'sequentially') {
  2203. t.blocksOn.each(function(index, el) {
  2204. $(el).data('cbp').wrapper[0].style[CubePortfolio.private.animationDelay] = '';
  2205. });
  2206. }
  2207. t.$obj.removeClass('cbp-animation-' + t.options.animationType);
  2208. t.filterFinish();
  2209. }
  2210. };
  2211. Plugin.prototype.destroy = function() {
  2212. var parent = this.parent;
  2213. parent.$obj.removeClass('cbp-animation-' + parent.options.animationType);
  2214. };
  2215. CubePortfolio.plugins.animationClone = function(parent) {
  2216. if (!CubePortfolio.private.modernBrowser || $.inArray(parent.options.animationType, ['fadeOutTop', 'slideLeft', 'sequentially']) < 0) {
  2217. return null;
  2218. }
  2219. return new Plugin(parent);
  2220. };
  2221. })(jQuery, window, document);
  2222. (function($, window, document, undefined) {
  2223. 'use strict';
  2224. var CubePortfolio = $.fn.cubeportfolio.constructor;
  2225. function Plugin(parent) {
  2226. var t = this;
  2227. t.parent = parent;
  2228. parent.filterLayout = t.filterLayout;
  2229. }
  2230. // here this value point to parent grid
  2231. Plugin.prototype.filterLayout = function() {
  2232. var t = this,
  2233. ulCloned = t.$ul.clone(true, true);
  2234. ulCloned[0].setAttribute('class', 'cbp-wrapper-helper');
  2235. t.wrapper[0].insertBefore(ulCloned[0], t.$ul[0]);
  2236. // hack for safari osx because it doesn't want to work if I set animationDelay
  2237. // on cbp-item-wrapper before I clone the t.$ul
  2238. var itemsCloned = ulCloned.find('.cbp-item').not('.cbp-item-off');
  2239. if (t.blocksAreSorted) {
  2240. t.sortBlocks(itemsCloned, 'top', 'left');
  2241. }
  2242. itemsCloned.children('.cbp-item-wrapper').each(function(index, el) {
  2243. el.style[CubePortfolio.private.animationDelay] = (index * 50) + 'ms';
  2244. });
  2245. requestAnimationFrame(function() {
  2246. t.$obj.addClass('cbp-animation-' + t.options.animationType);
  2247. t.blocksOff.addClass('cbp-item-off');
  2248. t.blocksOn.removeClass('cbp-item-off')
  2249. .each(function(index, el) {
  2250. var data = $(el).data('cbp');
  2251. data.left = data.leftNew;
  2252. data.top = data.topNew;
  2253. el.style.left = data.left + 'px';
  2254. el.style.top = data.top + 'px';
  2255. data.wrapper[0].style[CubePortfolio.private.animationDelay] = (index * 50) + 'ms';
  2256. });
  2257. var onLength = t.blocksOn.length,
  2258. offLength = itemsCloned.length;
  2259. if (onLength === 0 && offLength === 0) {
  2260. animationend();
  2261. } else if (onLength < offLength) {
  2262. itemsCloned.last().children('.cbp-item-wrapper').one(CubePortfolio.private.animationend, animationend);
  2263. } else {
  2264. t.blocksOn.last().data('cbp').wrapper.one(CubePortfolio.private.animationend, animationend);
  2265. }
  2266. // resize main container height
  2267. t.resizeMainContainer();
  2268. });
  2269. function animationend() {
  2270. t.wrapper[0].removeChild(ulCloned[0]);
  2271. t.$obj.removeClass('cbp-animation-' + t.options.animationType);
  2272. t.blocks.each(function(index, el) {
  2273. $(el).data('cbp').wrapper[0].style[CubePortfolio.private.animationDelay] = '';
  2274. });
  2275. t.filterFinish();
  2276. }
  2277. };
  2278. Plugin.prototype.destroy = function() {
  2279. var parent = this.parent;
  2280. parent.$obj.removeClass('cbp-animation-' + parent.options.animationType);
  2281. };
  2282. CubePortfolio.plugins.animationCloneDelay = function(parent) {
  2283. if (!CubePortfolio.private.modernBrowser || $.inArray(parent.options.animationType, ['3dflip', 'flipOutDelay', 'foldLeft', 'frontRow', 'rotateRoom', 'rotateSides', 'scaleDown', 'slideDelay', 'unfold']) < 0) {
  2284. return null;
  2285. }
  2286. return new Plugin(parent);
  2287. };
  2288. })(jQuery, window, document);
  2289. (function($, window, document, undefined) {
  2290. 'use strict';
  2291. var CubePortfolio = $.fn.cubeportfolio.constructor;
  2292. function Plugin(parent) {
  2293. var t = this;
  2294. t.parent = parent;
  2295. parent.filterLayout = t.filterLayout;
  2296. }
  2297. // here this value point to parent grid
  2298. Plugin.prototype.filterLayout = function() {
  2299. var t = this,
  2300. ulCloned = t.$ul[0].cloneNode(true);
  2301. ulCloned.setAttribute('class', 'cbp-wrapper-helper');
  2302. t.wrapper[0].insertBefore(ulCloned, t.$ul[0]);
  2303. requestAnimationFrame(function() {
  2304. t.$obj.addClass('cbp-animation-' + t.options.animationType);
  2305. t.blocksOff.addClass('cbp-item-off');
  2306. t.blocksOn.removeClass('cbp-item-off')
  2307. .each(function(index, el) {
  2308. var data = $(el).data('cbp');
  2309. data.left = data.leftNew;
  2310. data.top = data.topNew;
  2311. el.style.left = data.left + 'px';
  2312. el.style.top = data.top + 'px';
  2313. });
  2314. if (t.blocksOn.length) {
  2315. t.$ul.one(CubePortfolio.private.animationend, animationend);
  2316. } else if (t.blocksOnInitial.length) {
  2317. $(ulCloned).one(CubePortfolio.private.animationend, animationend);
  2318. } else {
  2319. animationend();
  2320. }
  2321. // resize main container height
  2322. t.resizeMainContainer();
  2323. });
  2324. function animationend() {
  2325. t.wrapper[0].removeChild(ulCloned);
  2326. t.$obj.removeClass('cbp-animation-' + t.options.animationType);
  2327. t.filterFinish();
  2328. }
  2329. };
  2330. Plugin.prototype.destroy = function() {
  2331. var parent = this.parent;
  2332. parent.$obj.removeClass('cbp-animation-' + parent.options.animationType);
  2333. };
  2334. CubePortfolio.plugins.animationWrapper = function(parent) {
  2335. if (!CubePortfolio.private.modernBrowser || $.inArray(parent.options.animationType, ['bounceBottom', 'bounceLeft', 'bounceTop', 'moveLeft']) < 0) {
  2336. return null;
  2337. }
  2338. return new Plugin(parent);
  2339. };
  2340. })(jQuery, window, document);
  2341. (function($, window, document, undefined) {
  2342. 'use strict';
  2343. var CubePortfolio = $.fn.cubeportfolio.constructor;
  2344. function Plugin(parent) {
  2345. var t = this;
  2346. var options = parent.options;
  2347. t.parent = parent;
  2348. t.captionOn = options.caption;
  2349. parent.registerEvent('onMediaQueries', function(opt) {
  2350. if (opt && opt.hasOwnProperty('caption')) {
  2351. if (t.captionOn !== opt.caption) {
  2352. t.destroy();
  2353. t.captionOn = opt.caption;
  2354. t.init();
  2355. }
  2356. } else if (t.captionOn !== options.caption) {
  2357. t.destroy();
  2358. t.captionOn = options.caption;
  2359. t.init();
  2360. }
  2361. });
  2362. t.init();
  2363. }
  2364. Plugin.prototype.init = function() {
  2365. var t = this;
  2366. // if caption is active
  2367. if (t.captionOn == '') {
  2368. return;
  2369. }
  2370. if (t.captionOn !== 'expand' && !CubePortfolio.private.modernBrowser) {
  2371. t.parent.options.caption = t.captionOn = 'minimal';
  2372. }
  2373. // .cbp-caption-active is used only for css
  2374. // so it will not generate a big css from sass if a caption is set
  2375. t.parent.$obj.addClass('cbp-caption-active cbp-caption-' + t.captionOn);
  2376. };
  2377. Plugin.prototype.destroy = function() {
  2378. this.parent.$obj.removeClass('cbp-caption-active cbp-caption-' + this.captionOn);
  2379. };
  2380. CubePortfolio.plugins.caption = function(parent) {
  2381. return new Plugin(parent);
  2382. };
  2383. })(jQuery, window, document);
  2384. (function($, window, document, undefined) {
  2385. 'use strict';
  2386. var CubePortfolio = $.fn.cubeportfolio.constructor;
  2387. function Plugin(parent) {
  2388. var t = this;
  2389. t.parent = parent;
  2390. parent.registerEvent('initFinish', function() {
  2391. parent.$obj.on('click.cbp', '.cbp-caption-defaultWrap', function(e) {
  2392. e.preventDefault();
  2393. if (parent.isAnimating) {
  2394. return;
  2395. }
  2396. parent.isAnimating = true;
  2397. var defaultWrap = $(this),
  2398. activeWrap = defaultWrap.next(),
  2399. caption = defaultWrap.parent(),
  2400. endStyle = {
  2401. position: 'relative',
  2402. height: activeWrap.outerHeight(true)
  2403. },
  2404. startStyle = {
  2405. position: 'relative',
  2406. height: 0
  2407. };
  2408. parent.$obj.addClass('cbp-caption-expand-active');
  2409. // swap endStyle & startStyle
  2410. if (caption.hasClass('cbp-caption-expand-open')) {
  2411. var temp = startStyle;
  2412. startStyle = endStyle;
  2413. endStyle = temp;
  2414. caption.removeClass('cbp-caption-expand-open');
  2415. }
  2416. activeWrap.css(endStyle);
  2417. parent.$obj.one('pluginResize.cbp', function() {
  2418. parent.isAnimating = false;
  2419. parent.$obj.removeClass('cbp-caption-expand-active');
  2420. if (endStyle.height === 0) {
  2421. caption.removeClass('cbp-caption-expand-open');
  2422. activeWrap.attr('style', '');
  2423. }
  2424. });
  2425. // reposition the blocks and set param to update width of grid
  2426. parent.layoutAndAdjustment(true);
  2427. // set activeWrap to 0 so I can start animation in the next frame
  2428. activeWrap.css(startStyle);
  2429. // delay animation
  2430. requestAnimationFrame(function() {
  2431. caption.addClass('cbp-caption-expand-open');
  2432. activeWrap.css(endStyle);
  2433. // used by slider layoutMode
  2434. parent.triggerEvent('gridAdjust');
  2435. parent.triggerEvent('resizeGrid');
  2436. });
  2437. });
  2438. }, true);
  2439. }
  2440. Plugin.prototype.destroy = function() {
  2441. this.parent.$obj.find('.cbp-caption-defaultWrap').off('click.cbp').parent().removeClass('cbp-caption-expand-active');
  2442. };
  2443. CubePortfolio.plugins.captionExpand = function(parent) {
  2444. if (parent.options.caption !== 'expand') {
  2445. return null;
  2446. }
  2447. return new Plugin(parent);
  2448. };
  2449. })(jQuery, window, document);
  2450. (function($, window, document, undefined) {
  2451. 'use strict';
  2452. var CubePortfolio = $.fn.cubeportfolio.constructor;
  2453. function Plugin(parent) {
  2454. parent.registerEvent('initEndWrite', function() {
  2455. if (parent.width <= 0) {
  2456. return;
  2457. }
  2458. var deferred = $.Deferred();
  2459. parent.pushQueue('delayFrame', deferred);
  2460. parent.blocksOn.each(function(index, el) {
  2461. el.style[CubePortfolio.private.animationDelay] = (index * parent.options.displayTypeSpeed) + 'ms';
  2462. });
  2463. parent.$obj.addClass('cbp-displayType-bottomToTop');
  2464. // get last element
  2465. parent.blocksOn.last().one(CubePortfolio.private.animationend, function() {
  2466. parent.$obj.removeClass('cbp-displayType-bottomToTop');
  2467. parent.blocksOn.each(function(index, el) {
  2468. el.style[CubePortfolio.private.animationDelay] = '';
  2469. });
  2470. // resolve event after the animation is finished
  2471. deferred.resolve();
  2472. });
  2473. }, true);
  2474. }
  2475. CubePortfolio.plugins.displayBottomToTop = function(parent) {
  2476. if (!CubePortfolio.private.modernBrowser || parent.options.displayType !== 'bottomToTop' || parent.blocksOn.length === 0) {
  2477. return null;
  2478. }
  2479. return new Plugin(parent);
  2480. };
  2481. })(jQuery, window, document);
  2482. (function($, window, document, undefined) {
  2483. 'use strict';
  2484. var CubePortfolio = $.fn.cubeportfolio.constructor;
  2485. function Plugin(parent) {
  2486. parent.registerEvent('initEndWrite', function() {
  2487. if (parent.width <= 0) {
  2488. return;
  2489. }
  2490. var deferred = $.Deferred();
  2491. parent.pushQueue('delayFrame', deferred);
  2492. parent.obj.style[CubePortfolio.private.animationDuration] = parent.options.displayTypeSpeed + 'ms';
  2493. parent.$obj.addClass('cbp-displayType-fadeIn');
  2494. parent.$obj.one(CubePortfolio.private.animationend, function() {
  2495. parent.$obj.removeClass('cbp-displayType-fadeIn');
  2496. parent.obj.style[CubePortfolio.private.animationDuration] = '';
  2497. // resolve event after the animation is finished
  2498. deferred.resolve();
  2499. });
  2500. }, true);
  2501. }
  2502. CubePortfolio.plugins.displayFadeIn = function(parent) {
  2503. if (!CubePortfolio.private.modernBrowser || (parent.options.displayType !== 'lazyLoading' && parent.options.displayType !== 'fadeIn') || parent.blocksOn.length === 0) {
  2504. return null;
  2505. }
  2506. return new Plugin(parent);
  2507. };
  2508. })(jQuery, window, document);
  2509. (function($, window, document, undefined) {
  2510. 'use strict';
  2511. var CubePortfolio = $.fn.cubeportfolio.constructor;
  2512. function Plugin(parent) {
  2513. parent.registerEvent('initEndWrite', function() {
  2514. if (parent.width <= 0) {
  2515. return;
  2516. }
  2517. var deferred = $.Deferred();
  2518. parent.pushQueue('delayFrame', deferred);
  2519. parent.obj.style[CubePortfolio.private.animationDuration] = parent.options.displayTypeSpeed + 'ms';
  2520. parent.$obj.addClass('cbp-displayType-fadeInToTop');
  2521. parent.$obj.one(CubePortfolio.private.animationend, function() {
  2522. parent.$obj.removeClass('cbp-displayType-fadeInToTop');
  2523. parent.obj.style[CubePortfolio.private.animationDuration] = '';
  2524. // resolve event after the animation is finished
  2525. deferred.resolve();
  2526. });
  2527. }, true);
  2528. }
  2529. CubePortfolio.plugins.displayFadeInToTop = function(parent) {
  2530. if (!CubePortfolio.private.modernBrowser || parent.options.displayType !== 'fadeInToTop' || parent.blocksOn.length === 0) {
  2531. return null;
  2532. }
  2533. return new Plugin(parent);
  2534. };
  2535. })(jQuery, window, document);
  2536. (function($, window, document, undefined) {
  2537. 'use strict';
  2538. var CubePortfolio = $.fn.cubeportfolio.constructor;
  2539. function Plugin(parent) {
  2540. parent.registerEvent('initEndWrite', function() {
  2541. if (parent.width <= 0) {
  2542. return;
  2543. }
  2544. var deferred = $.Deferred();
  2545. parent.pushQueue('delayFrame', deferred);
  2546. parent.blocksOn.each(function(index, el) {
  2547. el.style[CubePortfolio.private.animationDelay] = (index * parent.options.displayTypeSpeed) + 'ms';
  2548. });
  2549. parent.$obj.addClass('cbp-displayType-sequentially');
  2550. // get last element
  2551. parent.blocksOn.last().one(CubePortfolio.private.animationend, function() {
  2552. parent.$obj.removeClass('cbp-displayType-sequentially');
  2553. parent.blocksOn.each(function(index, el) {
  2554. el.style[CubePortfolio.private.animationDelay] = '';
  2555. });
  2556. // resolve event after the animation is finished
  2557. deferred.resolve();
  2558. });
  2559. }, true);
  2560. }
  2561. CubePortfolio.plugins.displaySequentially = function(parent) {
  2562. if (!CubePortfolio.private.modernBrowser || parent.options.displayType !== 'sequentially' || parent.blocksOn.length === 0) {
  2563. return null;
  2564. }
  2565. return new Plugin(parent);
  2566. };
  2567. })(jQuery, window, document);
  2568. (function($, window, document, undefined) {
  2569. 'use strict';
  2570. var CubePortfolio = $.fn.cubeportfolio.constructor;
  2571. function Plugin(parent) {
  2572. var t = this;
  2573. t.parent = parent;
  2574. t.filters = $(parent.options.filters);
  2575. t.filterData = [];
  2576. parent.registerEvent('afterPlugins', function(elems) {
  2577. // set default filter if it's present in url
  2578. t.filterFromUrl();
  2579. t.registerFilter();
  2580. });
  2581. // reset filters active class after the search is used
  2582. parent.registerEvent('resetFiltersVisual', function() {
  2583. var arr = parent.options.defaultFilter.split('|');
  2584. t.filters.each(function(index, el) {
  2585. var items = $(el).find('.cbp-filter-item');
  2586. $.each(arr, function(index, val) {
  2587. var item = items.filter('[data-filter="' + val + '"]');
  2588. if (item.length) {
  2589. item.addClass('cbp-filter-item-active').siblings().removeClass('cbp-filter-item-active');
  2590. arr.splice(index, 1);
  2591. return false;
  2592. }
  2593. });
  2594. });
  2595. parent.defaultFilter = parent.options.defaultFilter;
  2596. });
  2597. }
  2598. Plugin.prototype.registerFilter = function() {
  2599. var t = this,
  2600. parent = t.parent,
  2601. filtersCallback,
  2602. arr = parent.defaultFilter.split('|');
  2603. t.wrap = t.filters.find('.cbp-l-filters-dropdownWrap')
  2604. .on({
  2605. 'mouseover.cbp': function() {
  2606. $(this).addClass('cbp-l-filters-dropdownWrap-open');
  2607. },
  2608. 'mouseleave.cbp': function() {
  2609. $(this).removeClass('cbp-l-filters-dropdownWrap-open');
  2610. }
  2611. });
  2612. t.filters.each(function(index, el) {
  2613. var filter = $(el),
  2614. filterName = '*',
  2615. items = filter.find('.cbp-filter-item'),
  2616. dropdown = {};
  2617. if (filter.hasClass('cbp-l-filters-dropdown')) {
  2618. dropdown.wrap = filter.find('.cbp-l-filters-dropdownWrap');
  2619. dropdown.header = filter.find('.cbp-l-filters-dropdownHeader');
  2620. dropdown.headerText = dropdown.header.text();
  2621. }
  2622. // activate counter for filters
  2623. parent.$obj.cubeportfolio('showCounter', items);
  2624. $.each(arr, function(index, val) {
  2625. if (items.filter('[data-filter="' + val + '"]').length) {
  2626. filterName = val;
  2627. arr.splice(index, 1);
  2628. return false;
  2629. }
  2630. });
  2631. $.data(el, 'filterName', filterName);
  2632. t.filterData.push(el);
  2633. t.filtersCallback(dropdown, items.filter('[data-filter="' + filterName + '"]'));
  2634. items.on('click.cbp', function() {
  2635. var item = $(this);
  2636. if (item.hasClass('cbp-filter-item-active') || parent.isAnimating) {
  2637. return;
  2638. }
  2639. t.filtersCallback(dropdown, item);
  2640. $.data(el, 'filterName', item.data('filter'));
  2641. var name = $.map(t.filterData, function(el, index) {
  2642. var f = $.data(el, 'filterName');
  2643. return (f !== "" && f !== '*') ? f : null;
  2644. });
  2645. if (name.length < 1) {
  2646. name = ['*'];
  2647. }
  2648. var filterJoin = name.join('|');
  2649. if (parent.defaultFilter !== filterJoin) {
  2650. // filter the items
  2651. parent.$obj.cubeportfolio('filter', filterJoin);
  2652. }
  2653. });
  2654. });
  2655. };
  2656. Plugin.prototype.filtersCallback = function(dropdown, item) {
  2657. if (!$.isEmptyObject(dropdown)) {
  2658. dropdown.wrap.trigger('mouseleave.cbp');
  2659. if (dropdown.headerText) {
  2660. dropdown.headerText = '';
  2661. } else {
  2662. dropdown.header.html(item.html());
  2663. }
  2664. }
  2665. item.addClass('cbp-filter-item-active').siblings().removeClass('cbp-filter-item-active');
  2666. };
  2667. /**
  2668. * Check if filters are present in url
  2669. */
  2670. Plugin.prototype.filterFromUrl = function() {
  2671. var match = /#cbpf=(.*?)([#\?&]|$)/gi.exec(location.href);
  2672. if (match !== null) {
  2673. this.parent.defaultFilter = decodeURIComponent(match[1]);
  2674. }
  2675. };
  2676. Plugin.prototype.destroy = function() {
  2677. var t = this;
  2678. t.filters.find('.cbp-filter-item').off('.cbp');
  2679. t.wrap.off('.cbp');
  2680. };
  2681. CubePortfolio.plugins.filters = function(parent) {
  2682. if (parent.options.filters === '') {
  2683. return null;
  2684. }
  2685. return new Plugin(parent);
  2686. };
  2687. })(jQuery, window, document);
  2688. (function($, window, document, undefined) {
  2689. 'use strict';
  2690. var CubePortfolio = $.fn.cubeportfolio.constructor;
  2691. function Plugin(parent) {
  2692. var gapVerticalInitial = parent.options.gapVertical;
  2693. var gapHorizontalInitial = parent.options.gapHorizontal;
  2694. parent.registerEvent('onMediaQueries', function(opt) {
  2695. parent.options.gapVertical = (opt && opt.hasOwnProperty('gapVertical'))? opt.gapVertical : gapVerticalInitial;
  2696. parent.options.gapHorizontal = (opt && opt.hasOwnProperty('gapHorizontal'))? opt.gapHorizontal : gapHorizontalInitial;
  2697. parent.blocks.each(function(index, el) {
  2698. var data = $(el).data('cbp');
  2699. data.widthAndGap = data.width + parent.options.gapVertical;
  2700. data.heightAndGap = data.height + parent.options.gapHorizontal;
  2701. });
  2702. });
  2703. }
  2704. CubePortfolio.plugins.changeGapOnMediaQueries = function(parent) {
  2705. return new Plugin(parent);
  2706. };
  2707. })(jQuery, window, document);
  2708. (function($, window, document, undefined) {
  2709. 'use strict';
  2710. var options = {};
  2711. var CubePortfolio = $.fn.cubeportfolio.constructor;
  2712. function Plugin(parent) {
  2713. var t = this;
  2714. t.parent = parent;
  2715. t.options = $.extend({}, options, t.parent.options.plugins.inlineSlider);
  2716. t.runInit();
  2717. parent.registerEvent('addItemsToDOM', function() {
  2718. t.runInit();
  2719. });
  2720. }
  2721. function InitSlider(slider) {
  2722. var t = this;
  2723. if (slider.hasClass('cbp-slider-inline-ready')) {
  2724. return;
  2725. }
  2726. slider.addClass('cbp-slider-inline-ready');
  2727. t.items = slider.find('.cbp-slider-wrapper').children('.cbp-slider-item');
  2728. t.active = t.items.filter('.cbp-slider-item--active').index();
  2729. t.total = t.items.length - 1;
  2730. t.updateLeft();
  2731. slider.find('.cbp-slider-next').on('click.cbp', function(e) {
  2732. e.preventDefault();
  2733. if (t.active < t.total) {
  2734. t.active++;
  2735. t.updateLeft();
  2736. } else if (t.active === t.total) {
  2737. t.active = 0;
  2738. t.updateLeft();
  2739. }
  2740. });
  2741. slider.find('.cbp-slider-prev').on('click.cbp', function(e) {
  2742. e.preventDefault();
  2743. if (t.active > 0) {
  2744. t.active--;
  2745. t.updateLeft();
  2746. } else if (t.active === 0) {
  2747. t.active = t.total;
  2748. t.updateLeft();
  2749. }
  2750. });
  2751. };
  2752. InitSlider.prototype.updateLeft = function() {
  2753. var t = this;
  2754. t.items.removeClass('cbp-slider-item--active');
  2755. t.items.eq(t.active).addClass('cbp-slider-item--active');
  2756. t.items.each(function(index, el) {
  2757. el.style.left = (index - t.active) + '00%';
  2758. });
  2759. };
  2760. Plugin.prototype.runInit = function() {
  2761. var t = this;
  2762. t.parent.$obj.find('.cbp-slider-inline').not('.cbp-slider-inline-ready').each(function(index, el) {
  2763. var slider = $(el);
  2764. var activeImage = slider.find('.cbp-slider-item--active').find('img')[0];
  2765. if (activeImage.hasAttribute('data-cbp-src')) {
  2766. t.parent.$obj.on('lazyLoad.cbp', function(e, image) {
  2767. if (image.src === activeImage.src) {
  2768. new InitSlider(slider);
  2769. }
  2770. });
  2771. } else {
  2772. new InitSlider(slider);
  2773. }
  2774. });
  2775. };
  2776. Plugin.prototype.destroy = function() {
  2777. var t = this;
  2778. t.parent.$obj.find('.cbp-slider-next').off('click.cbp');
  2779. t.parent.$obj.find('.cbp-slider-prev').off('click.cbp');
  2780. t.parent.$obj.off('lazyLoad.cbp');
  2781. t.parent.$obj.find('.cbp-slider-inline').each(function(index, el) {
  2782. var slider = $(el);
  2783. slider.removeClass('cbp-slider-inline-ready');
  2784. var items = slider.find('.cbp-slider-item');
  2785. items.removeClass('cbp-slider-item--active');
  2786. items.removeAttr('style');
  2787. items.eq(0).addClass('cbp-slider-item--active');
  2788. });
  2789. };
  2790. CubePortfolio.plugins.inlineSlider = function(parent) {
  2791. return new Plugin(parent);
  2792. };
  2793. })(jQuery, window, document);
  2794. (function($, window, document, undefined) {
  2795. 'use strict';
  2796. var options = {
  2797. loadingClass: 'cbp-lazyload',
  2798. threshold: 400, // loads images 150px before they're visible
  2799. };
  2800. var CubePortfolio = $.fn.cubeportfolio.constructor;
  2801. var $window = $(window);
  2802. // add scroll event to page for lazyLoad
  2803. CubePortfolio.private.lazyLoadScroll = new CubePortfolio.private.publicEvents('scroll.cbplazyLoad', 50);
  2804. function Plugin(parent) {
  2805. var t = this;
  2806. t.parent = parent;
  2807. t.options = $.extend({}, options, t.parent.options.plugins.lazyLoad);
  2808. parent.registerEvent('initFinish', function() {
  2809. t.loadImages();
  2810. parent.registerEvent('resizeMainContainer', function() {
  2811. t.loadImages();
  2812. });
  2813. parent.registerEvent('filterFinish', function() {
  2814. t.loadImages();
  2815. });
  2816. CubePortfolio.private.lazyLoadScroll.initEvent({
  2817. instance: t,
  2818. fn: t.loadImages
  2819. });
  2820. }, true);
  2821. }
  2822. Plugin.prototype.loadImages = function() {
  2823. var t = this;
  2824. var imgs = t.parent.$obj.find('img').filter('[data-cbp-src]');
  2825. if (imgs.length === 0) {
  2826. return;
  2827. }
  2828. t.screenHeight = $window.height();
  2829. imgs.each(function(index, el) {
  2830. var parentNode = $(el.parentNode);
  2831. if (!t.isElementInScreen(el)) {
  2832. parentNode.addClass(t.options.loadingClass);
  2833. return;
  2834. }
  2835. var dataSrc = el.getAttribute('data-cbp-src');
  2836. if (t.parent.checkSrc($('<img>').attr('src', dataSrc)) === null) {
  2837. t.removeLazyLoad(el, dataSrc);
  2838. parentNode.removeClass(t.options.loadingClass);
  2839. } else {
  2840. parentNode.addClass(t.options.loadingClass);
  2841. $('<img>').on('load.cbp error.cbp', function() {
  2842. t.removeLazyLoad(el, dataSrc, parentNode);
  2843. }).attr('src', dataSrc); // for ie8
  2844. }
  2845. });
  2846. };
  2847. Plugin.prototype.removeLazyLoad = function(el, dataSrc, parentNode) {
  2848. var t = this;
  2849. el.src = dataSrc;
  2850. el.removeAttribute('data-cbp-src');
  2851. t.parent.removeAttrImage(el);
  2852. // trigger public event
  2853. t.parent.$obj.trigger('lazyLoad.cbp', el);
  2854. if (parentNode) {
  2855. if (CubePortfolio.private.modernBrowser) {
  2856. $(el).one(CubePortfolio.private.transitionend, function() {
  2857. parentNode.removeClass(t.options.loadingClass);
  2858. });
  2859. } else {
  2860. parentNode.removeClass(t.options.loadingClass);
  2861. }
  2862. }
  2863. };
  2864. Plugin.prototype.isElementInScreen = function(el) {
  2865. var t = this;
  2866. var bound = el.getBoundingClientRect();
  2867. var bottom = bound.bottom + t.options.threshold;
  2868. var screenHeight = t.screenHeight + bottom - (bound.top - t.options.threshold);
  2869. return bottom >= 0 && bottom <= screenHeight;
  2870. };
  2871. Plugin.prototype.destroy = function() {
  2872. CubePortfolio.private.lazyLoadScroll.destroyEvent(this);
  2873. };
  2874. CubePortfolio.plugins.lazyLoad = function(parent) {
  2875. return new Plugin(parent);
  2876. };
  2877. })(jQuery, window, document);
  2878. (function($, window, document, undefined) {
  2879. 'use strict';
  2880. var options = {
  2881. /**
  2882. * Define the wrapper for loadMore
  2883. * Values: strings that represent the elements in the document (DOM selector).
  2884. */
  2885. element: '',
  2886. /**
  2887. * How the loadMore functionality should behave. Load on click on the button or
  2888. * automatically when you scroll the page
  2889. * Values: - click
  2890. * - auto
  2891. */
  2892. action: 'click',
  2893. /**
  2894. * How many items to load when you click on the loadMore button
  2895. * Values: positive integer
  2896. */
  2897. loadItems: 3,
  2898. };
  2899. var CubePortfolio = $.fn.cubeportfolio.constructor;
  2900. function Plugin(parent) {
  2901. var t = this;
  2902. t.parent = parent;
  2903. t.options = $.extend({}, options, t.parent.options.plugins.loadMore);
  2904. t.loadMore = $(t.options.element).find('.cbp-l-loadMore-link');
  2905. // load click or auto action
  2906. if (t.loadMore.length === 0) {
  2907. return;
  2908. }
  2909. t.loadItems = t.loadMore.find('.cbp-l-loadMore-loadItems');
  2910. if (t.loadItems.text() === '0') {
  2911. t.loadMore.addClass('cbp-l-loadMore-stop');
  2912. }
  2913. parent.registerEvent('filterStart', function(filter) {
  2914. t.populateItems().then(function() {
  2915. var itemsLen = t.items.filter(filter).length;
  2916. if (itemsLen > 0) {
  2917. t.loadMore.removeClass('cbp-l-loadMore-stop');
  2918. t.loadItems.html(itemsLen);
  2919. } else {
  2920. t.loadMore.addClass('cbp-l-loadMore-stop');
  2921. }
  2922. });
  2923. });
  2924. t[t.options.action]();
  2925. }
  2926. Plugin.prototype.populateItems = function() {
  2927. var t = this;
  2928. if (t.items) {
  2929. return $.Deferred().resolve();
  2930. }
  2931. t.items = $();
  2932. // perform ajax request
  2933. return $.ajax({
  2934. url: t.loadMore.attr('href'),
  2935. type: 'GET',
  2936. dataType: 'HTML'
  2937. }).done(function(result) {
  2938. var resultFlat = $.map(result.split(/\r?\n/), function(item, index) {
  2939. return $.trim(item);
  2940. }).join('');
  2941. if (resultFlat.length === 0) {
  2942. return;
  2943. }
  2944. $.each($.parseHTML(resultFlat), function(index, el) {
  2945. if ($(el).hasClass('cbp-item')) {
  2946. t.items = t.items.add(el);
  2947. } else {
  2948. $.each(el.children, function(index, el2) {
  2949. if ($(el2).hasClass('cbp-item')) {
  2950. t.items = t.items.add(el2);
  2951. }
  2952. });
  2953. }
  2954. });
  2955. }).fail(function() {
  2956. t.items = null;
  2957. t.loadMore.removeClass('cbp-l-loadMore-loading');
  2958. });
  2959. };
  2960. Plugin.prototype.populateInsertItems = function(callback) {
  2961. var t = this;
  2962. var insertItems = [];
  2963. var filter = t.parent.defaultFilter;
  2964. var foundItem = 0;
  2965. t.items.each(function(index, el) {
  2966. if (foundItem === t.options.loadItems) {
  2967. return false;
  2968. }
  2969. if (!filter || (filter === '*')) {
  2970. insertItems.push(el);
  2971. t.items[index] = null;
  2972. foundItem++;
  2973. } else {
  2974. if ($(el).filter(filter).length) {
  2975. insertItems.push(el);
  2976. t.items[index] = null;
  2977. foundItem++;
  2978. }
  2979. }
  2980. });
  2981. t.items = t.items.map(function(index, el) {
  2982. return el;
  2983. });
  2984. // stop the loadMore
  2985. if (insertItems.length === 0) {
  2986. t.loadMore.removeClass('cbp-l-loadMore-loading').addClass('cbp-l-loadMore-stop');
  2987. return;
  2988. }
  2989. t.parent.$obj.cubeportfolio('append', insertItems, callback);
  2990. }
  2991. Plugin.prototype.click = function() {
  2992. var t = this;
  2993. t.loadMore.on('click.cbp', function(e) {
  2994. e.preventDefault();
  2995. if (t.parent.isAnimating || t.loadMore.hasClass('cbp-l-loadMore-stop')) {
  2996. return;
  2997. }
  2998. // set loading status
  2999. t.loadMore.addClass('cbp-l-loadMore-loading');
  3000. t.populateItems().then(function() {
  3001. t.populateInsertItems(appendCallback);
  3002. });
  3003. });
  3004. function appendCallback() {
  3005. // remove class from t.loadMore
  3006. t.loadMore.removeClass('cbp-l-loadMore-loading');
  3007. var filter = t.parent.defaultFilter;
  3008. var itemsInLoadMore;
  3009. if (!filter || (filter === '*')) {
  3010. itemsInLoadMore = t.items.length;
  3011. } else {
  3012. itemsInLoadMore = t.items.filter(filter).length;
  3013. }
  3014. // check if we have more loadMore
  3015. if (itemsInLoadMore === 0) {
  3016. t.loadMore.addClass('cbp-l-loadMore-stop');
  3017. } else {
  3018. t.loadItems.html(itemsInLoadMore);
  3019. }
  3020. }
  3021. };
  3022. Plugin.prototype.auto = function() {
  3023. var t = this;
  3024. var $window = $(window);
  3025. var isActive = false;
  3026. // add scroll event to page for loadMore
  3027. CubePortfolio.private.loadMoreScroll = new CubePortfolio.private.publicEvents('scroll.loadMore', 100);
  3028. t.parent.$obj.one('initComplete.cbp', function() {
  3029. // add events for scroll
  3030. t.loadMore
  3031. .addClass('cbp-l-loadMore-loading')
  3032. .on('click.cbp', function(e) {
  3033. e.preventDefault();
  3034. });
  3035. CubePortfolio.private.loadMoreScroll.initEvent({
  3036. instance: t,
  3037. fn: function() {
  3038. if (!t.parent.isAnimating) {
  3039. // get new items on scroll
  3040. getNewItems();
  3041. }
  3042. }
  3043. });
  3044. // when the filter is completed
  3045. t.parent.$obj.on('filterComplete.cbp', function() {
  3046. getNewItems();
  3047. });
  3048. // trigger method
  3049. getNewItems();
  3050. });
  3051. function getNewItems() {
  3052. if (isActive || t.loadMore.hasClass('cbp-l-loadMore-stop')) {
  3053. return;
  3054. }
  3055. // add a treshold
  3056. var topLoadMore = t.loadMore.offset().top - 200;
  3057. var topWindow = $window.scrollTop() + $window.height();
  3058. if (topLoadMore > topWindow) {
  3059. return;
  3060. }
  3061. // this job is now busy
  3062. isActive = true;
  3063. t.populateItems().then(function() {
  3064. t.populateInsertItems(appendCallback);
  3065. }).fail(function() {
  3066. // make the job inactive
  3067. isActive = false;
  3068. });
  3069. }
  3070. function appendCallback() {
  3071. var itemsInLoadMore;
  3072. var filter = t.parent.defaultFilter;
  3073. if (!filter || (filter === '*')) {
  3074. itemsInLoadMore = t.items.length;
  3075. } else {
  3076. itemsInLoadMore = t.items.filter(filter).length;
  3077. }
  3078. // check if we have more loadMore
  3079. if (itemsInLoadMore === 0) {
  3080. t.loadMore.removeClass('cbp-l-loadMore-loading').addClass('cbp-l-loadMore-stop');
  3081. } else {
  3082. t.loadItems.html(itemsInLoadMore);
  3083. $window.trigger('scroll.loadMore');
  3084. }
  3085. // make the job inactive
  3086. isActive = false;
  3087. // remove events
  3088. if (t.items.length === 0) {
  3089. CubePortfolio.private.loadMoreScroll.destroyEvent(t);
  3090. t.parent.$obj.off('filterComplete.cbp');
  3091. }
  3092. }
  3093. };
  3094. Plugin.prototype.destroy = function() {
  3095. this.loadMore.off('.cbp');
  3096. if (CubePortfolio.private.loadMoreScroll) {
  3097. CubePortfolio.private.loadMoreScroll.destroyEvent(this);
  3098. }
  3099. };
  3100. CubePortfolio.plugins.loadMore = function(parent) {
  3101. var plugins = parent.options.plugins;
  3102. // backward compatibility
  3103. if (parent.options.loadMore) {
  3104. if (!plugins.loadMore) {
  3105. plugins.loadMore = {};
  3106. }
  3107. plugins.loadMore.element = parent.options.loadMore;
  3108. }
  3109. // backward compatibility
  3110. if (parent.options.loadMoreAction) {
  3111. if (!plugins.loadMore) {
  3112. plugins.loadMore = {};
  3113. }
  3114. plugins.loadMore.action = parent.options.loadMoreAction;
  3115. }
  3116. // rename options
  3117. if (plugins.loadMore && plugins.loadMore.selector !== undefined) {
  3118. plugins.loadMore.element = plugins.loadMore.selector;
  3119. delete plugins.loadMore.selector;
  3120. }
  3121. if (!plugins.loadMore || !plugins.loadMore.element) {
  3122. return null;
  3123. }
  3124. return new Plugin(parent);
  3125. };
  3126. })(jQuery, window, document);
  3127. (function($, window, document, undefined) {
  3128. 'use strict';
  3129. var CubePortfolio = $.fn.cubeportfolio.constructor;
  3130. var options = {
  3131. delay: 0,
  3132. };
  3133. var popup = {
  3134. /**
  3135. * init function for popup
  3136. * @param cubeportfolio = cubeportfolio instance
  3137. * @param type = 'lightbox' or 'singlePage'
  3138. */
  3139. init: function(cubeportfolio, type) {
  3140. var t = this,
  3141. currentBlock;
  3142. // remember cubeportfolio instance
  3143. t.cubeportfolio = cubeportfolio;
  3144. // remember if this instance is for lightbox or for singlePage
  3145. t.type = type;
  3146. // remember if the popup is open or not
  3147. t.isOpen = false;
  3148. t.options = t.cubeportfolio.options;
  3149. if (type === 'lightbox') {
  3150. t.cubeportfolio.registerEvent('resizeWindow', function() {
  3151. t.resizeImage();
  3152. });
  3153. t.localOptions = $.extend({}, options, t.cubeportfolio.options.plugins.lightbox);
  3154. }
  3155. if (type === 'singlePageInline') {
  3156. t.height = 0;
  3157. // create markup, css and add events for SinglePageInline
  3158. t.createMarkupSinglePageInline();
  3159. t.cubeportfolio.registerEvent('resizeGrid', function() {
  3160. if (t.isOpen) {
  3161. // @todo must add support for this features in the future
  3162. t.close(); // workaround
  3163. }
  3164. });
  3165. if (t.options.singlePageInlineDeeplinking) {
  3166. t.url = location.href;
  3167. if (t.url.slice(-1) === '#') {
  3168. t.url = t.url.slice(0, -1);
  3169. }
  3170. var links = t.url.split('#cbpi=');
  3171. var url = links.shift(); // remove first item
  3172. $.each(links, function(index, link) {
  3173. t.cubeportfolio.blocksOn.each(function(index1, el) {
  3174. var singlePageInline = $(el).find(t.options.singlePageInlineDelegate + '[href="' + link + '"]');
  3175. if (singlePageInline.length) {
  3176. currentBlock = singlePageInline;
  3177. return false;
  3178. }
  3179. });
  3180. if (currentBlock) {
  3181. return false;
  3182. }
  3183. });
  3184. if (currentBlock) {
  3185. t.cubeportfolio.registerEvent('initFinish', function() {
  3186. t.openSinglePageInline(t.cubeportfolio.blocksOn, currentBlock[0]);
  3187. }, true);
  3188. }
  3189. }
  3190. t.localOptions = $.extend({}, options, t.cubeportfolio.options.plugins.singlePageInline);
  3191. return;
  3192. }
  3193. // create markup, css and add events for lightbox and singlePage
  3194. t.createMarkup();
  3195. if (type === 'singlePage') {
  3196. t.cubeportfolio.registerEvent('resizeWindow', function() {
  3197. if (t.options.singlePageStickyNavigation) {
  3198. var width = t.contentWrap[0].clientWidth;
  3199. if (width > 0) {
  3200. t.navigationWrap.width(width);
  3201. // set navigation width='window width' to center the divs
  3202. t.navigation.width(width);
  3203. }
  3204. }
  3205. });
  3206. if (t.options.singlePageDeeplinking) {
  3207. t.url = location.href;
  3208. if (t.url.slice(-1) === '#') {
  3209. t.url = t.url.slice(0, -1);
  3210. }
  3211. var links = t.url.split('#cbp=');
  3212. var url = links.shift(); // remove first item
  3213. $.each(links, function(index, link) {
  3214. t.cubeportfolio.blocksOn.each(function(index1, el) {
  3215. var singlePage = $(el).find(t.options.singlePageDelegate + '[href="' + link + '"]');
  3216. if (singlePage.length) {
  3217. currentBlock = singlePage;
  3218. return false;
  3219. }
  3220. });
  3221. if (currentBlock) {
  3222. return false;
  3223. }
  3224. });
  3225. if (currentBlock) {
  3226. t.url = url;
  3227. var self = currentBlock,
  3228. gallery = self.attr('data-cbp-singlePage'),
  3229. blocks = [];
  3230. if (gallery) {
  3231. blocks = self.closest($('.cbp-item')).find('[data-cbp-singlePage="' + gallery + '"]');
  3232. } else {
  3233. t.cubeportfolio.blocksOn.each(function(index, el) {
  3234. var item = $(el);
  3235. if (item.not('.cbp-item-off')) {
  3236. item.find(t.options.singlePageDelegate).each(function(index2, el2) {
  3237. if (!$(el2).attr('data-cbp-singlePage')) {
  3238. blocks.push(el2);
  3239. }
  3240. });
  3241. }
  3242. });
  3243. }
  3244. t.openSinglePage(blocks, currentBlock[0]);
  3245. } else if (links.length) { // @todo - hack to load items from loadMore
  3246. var fakeLink = document.createElement('a');
  3247. fakeLink.setAttribute('href', links[0]);
  3248. t.openSinglePage([fakeLink], fakeLink);
  3249. }
  3250. }
  3251. t.localOptions = $.extend({}, options, t.cubeportfolio.options.plugins.singlePage);
  3252. }
  3253. },
  3254. /**
  3255. * Create markup, css and add events
  3256. */
  3257. createMarkup: function() {
  3258. var t = this,
  3259. animationCls = '';
  3260. if (t.type === 'singlePage') {
  3261. if (t.options.singlePageAnimation !== 'left') {
  3262. animationCls = ' cbp-popup-singlePage-' + t.options.singlePageAnimation;
  3263. }
  3264. }
  3265. // wrap element
  3266. t.wrap = $('<div/>', {
  3267. 'class': 'cbp-popup-wrap cbp-popup-' + t.type + animationCls,
  3268. 'data-action': (t.type === 'lightbox') ? 'close' : ''
  3269. }).on('click.cbp', function(e) {
  3270. if (t.stopEvents) {
  3271. return;
  3272. }
  3273. var action = $(e.target).attr('data-action');
  3274. if (t[action]) {
  3275. t[action]();
  3276. e.preventDefault();
  3277. }
  3278. });
  3279. if (t.type === 'singlePage') {
  3280. t.contentWrap = $('<div/>', {
  3281. 'class': 'cbp-popup-content-wrap'
  3282. }).appendTo(t.wrap);
  3283. if (CubePortfolio.private.browser === 'ios') {
  3284. t.contentWrap.css('overflow', 'auto');
  3285. }
  3286. // content element
  3287. t.content = $('<div/>', {
  3288. 'class': 'cbp-popup-content'
  3289. }).appendTo(t.contentWrap);
  3290. } else {
  3291. // content element
  3292. t.content = $('<div/>', {
  3293. 'class': 'cbp-popup-content'
  3294. }).appendTo(t.wrap);
  3295. }
  3296. // append loading div
  3297. $('<div/>', {
  3298. 'class': 'cbp-popup-loadingBox'
  3299. }).appendTo(t.wrap);
  3300. // add background only for ie8
  3301. if (CubePortfolio.private.browser === 'ie8') {
  3302. t.bg = $('<div/>', {
  3303. 'class': 'cbp-popup-ie8bg',
  3304. 'data-action': (t.type === 'lightbox') ? 'close' : ''
  3305. }).appendTo(t.wrap);
  3306. }
  3307. if (t.type === 'singlePage') {
  3308. if (t.options.singlePageStickyNavigation === false) {
  3309. // create navigation wrap
  3310. t.navigationWrap = $('<div/>', {
  3311. 'class': 'cbp-popup-navigation-wrap'
  3312. }).appendTo(t.contentWrap);
  3313. } else {
  3314. // create navigation wrap
  3315. t.navigationWrap = $('<div/>', {
  3316. 'class': 'cbp-popup-navigation-wrap'
  3317. }).appendTo(t.wrap);
  3318. }
  3319. } else {
  3320. // create navigation wrap
  3321. t.navigationWrap = $('<div/>', {
  3322. 'class': 'cbp-popup-navigation-wrap'
  3323. }).appendTo(t.wrap);
  3324. }
  3325. // create navigation block
  3326. t.navigation = $('<div/>', {
  3327. 'class': 'cbp-popup-navigation'
  3328. }).appendTo(t.navigationWrap);
  3329. // close
  3330. t.closeButton = $('<div/>', {
  3331. 'class': 'cbp-popup-close',
  3332. 'title': 'Close (Esc arrow key)',
  3333. 'data-action': 'close'
  3334. }).appendTo(t.navigation);
  3335. // next
  3336. t.nextButton = $('<div/>', {
  3337. 'class': 'cbp-popup-next',
  3338. 'title': 'Next (Right arrow key)',
  3339. 'data-action': 'next'
  3340. }).appendTo(t.navigation);
  3341. // prev
  3342. t.prevButton = $('<div/>', {
  3343. 'class': 'cbp-popup-prev',
  3344. 'title': 'Previous (Left arrow key)',
  3345. 'data-action': 'prev'
  3346. }).appendTo(t.navigation);
  3347. if (t.type === 'singlePage') {
  3348. if (t.options.singlePageCounter) {
  3349. // counter for singlePage
  3350. t.counter = $(t.options.singlePageCounter).appendTo(t.navigation);
  3351. t.counter.text('');
  3352. }
  3353. t.content.on('click.cbp', t.options.singlePageDelegate, function(e) {
  3354. e.preventDefault();
  3355. var i,
  3356. len = t.dataArray.length,
  3357. href = this.getAttribute('href'),
  3358. indexFound;
  3359. for (i = 0; i < len; i++) {
  3360. if (t.dataArray[i].url === href) {
  3361. indexFound = i;
  3362. break;
  3363. }
  3364. }
  3365. if (indexFound === undefined) {
  3366. var fakeLink = document.createElement('a');
  3367. fakeLink.setAttribute('href', href);
  3368. t.dataArray = [{
  3369. url: href,
  3370. element: fakeLink
  3371. }];
  3372. // total numbers of elements
  3373. t.counterTotal = 1;
  3374. t.nextButton.hide();
  3375. t.prevButton.hide();
  3376. t.singlePageJumpTo(0);
  3377. } else {
  3378. t.singlePageJumpTo(indexFound - t.current);
  3379. }
  3380. });
  3381. // Test via a getter in the options object to see if the passive property is accessed
  3382. // https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
  3383. var supportsOpts = false;
  3384. try {
  3385. var opts = Object.defineProperty({}, 'passive', {
  3386. get: function() {
  3387. supportsOpts = { passive: true };
  3388. }
  3389. });
  3390. window.addEventListener('testPassive', null, opts);
  3391. window.removeEventListener('testPassive', null, opts);
  3392. } catch (e) {}
  3393. // if there are some events than overrides the default wheel behaviour don't go to them
  3394. // https://developer.mozilla.org/en-US/docs/Web/Events/wheel
  3395. var wheel = 'onwheel' in document.createElement('div') ? 'wheel' : 'mousewheel';
  3396. t.contentWrap[0].addEventListener(wheel, function(e) {
  3397. e.stopImmediatePropagation();
  3398. }, supportsOpts);
  3399. }
  3400. $(document).on('keydown.cbp', function(e) {
  3401. // if is not open => return
  3402. if (!t.isOpen) {
  3403. return;
  3404. }
  3405. // if all events are stopped => return
  3406. if (t.stopEvents) {
  3407. return;
  3408. }
  3409. if (lightboxIsOpen) {
  3410. e.stopImmediatePropagation();
  3411. }
  3412. if (e.keyCode === 37) { // prev key
  3413. t.prev();
  3414. } else if (e.keyCode === 39) { // next key
  3415. t.next();
  3416. } else if (e.keyCode === 27) { //esc key
  3417. t.close();
  3418. }
  3419. });
  3420. },
  3421. createMarkupSinglePageInline: function() {
  3422. var t = this;
  3423. // wrap element
  3424. t.wrap = $('<div/>', {
  3425. 'class': 'cbp-popup-singlePageInline'
  3426. }).on('click.cbp', function(e) {
  3427. if (t.stopEvents) {
  3428. return;
  3429. }
  3430. var action = $(e.target).attr('data-action');
  3431. if (action && t[action]) {
  3432. t[action]();
  3433. e.preventDefault();
  3434. }
  3435. });
  3436. // content element
  3437. t.content = $('<div/>', {
  3438. 'class': 'cbp-popup-content'
  3439. }).appendTo(t.wrap);
  3440. // append loading div
  3441. // $('<div/>', {
  3442. // 'class': 'cbp-popup-loadingBox'
  3443. // }).appendTo(t.wrap);
  3444. // create navigation block
  3445. t.navigation = $('<div/>', {
  3446. 'class': 'cbp-popup-navigation'
  3447. }).appendTo(t.wrap);
  3448. // close
  3449. t.closeButton = $('<div/>', {
  3450. 'class': 'cbp-popup-close',
  3451. 'title': 'Close (Esc arrow key)',
  3452. 'data-action': 'close'
  3453. }).appendTo(t.navigation);
  3454. },
  3455. destroy: function() {
  3456. var t = this,
  3457. body = $('body');
  3458. // remove off key down
  3459. $(document).off('keydown.cbp');
  3460. // external lightbox and singlePageInline
  3461. body.off('click.cbp', t.options.lightboxDelegate);
  3462. body.off('click.cbp', t.options.singlePageDelegate);
  3463. t.content.off('click.cbp', t.options.singlePageDelegate);
  3464. t.cubeportfolio.$obj.off('click.cbp', t.options.singlePageInlineDelegate);
  3465. t.cubeportfolio.$obj.off('click.cbp', t.options.lightboxDelegate);
  3466. t.cubeportfolio.$obj.off('click.cbp', t.options.singlePageDelegate);
  3467. t.cubeportfolio.$obj.removeClass('cbp-popup-isOpening');
  3468. t.cubeportfolio.$obj.find('.cbp-item').removeClass('cbp-singlePageInline-active');
  3469. t.wrap.remove();
  3470. },
  3471. openLightbox: function(blocks, currentBlock) {
  3472. var t = this,
  3473. i = 0,
  3474. currentBlockHref, tempHref = [],
  3475. element;
  3476. if (t.isOpen) {
  3477. return;
  3478. }
  3479. lightboxIsOpen = true;
  3480. // remember that the lightbox is open now
  3481. t.isOpen = true;
  3482. // remember to stop all events after the lightbox has been shown
  3483. t.stopEvents = false;
  3484. // array with elements
  3485. t.dataArray = [];
  3486. // reset current
  3487. t.current = null;
  3488. currentBlockHref = currentBlock.getAttribute('href');
  3489. if (currentBlockHref === null) {
  3490. throw new Error('HEI! Your clicked element doesn\'t have a href attribute.');
  3491. }
  3492. $.each(blocks, function(index, item) {
  3493. var href = item.getAttribute('href'),
  3494. src = href, // default if element is image
  3495. type = 'isImage', // default if element is image
  3496. videoLink;
  3497. if ($.inArray(href, tempHref) === -1) {
  3498. if (currentBlockHref === href) {
  3499. t.current = i;
  3500. } else if (!t.options.lightboxGallery) {
  3501. return;
  3502. }
  3503. if (/youtu\.?be/i.test(href)) {
  3504. var indexVideo = href.lastIndexOf('v=') + 2;
  3505. if (indexVideo === 1) {
  3506. indexVideo = href.lastIndexOf('/') + 1;
  3507. }
  3508. videoLink = href.substring(indexVideo);
  3509. if (!(/autoplay=/i.test(videoLink))) {
  3510. videoLink += '&autoplay=1';
  3511. }
  3512. videoLink = videoLink.replace(/\?|&/, '?');
  3513. // create new href
  3514. src = '//www.youtube.com/embed/' + videoLink;
  3515. type = 'isYoutube';
  3516. } else if (/vimeo\.com/i.test(href)) {
  3517. videoLink = href.substring(href.lastIndexOf('/') + 1);
  3518. if (!(/autoplay=/i.test(videoLink))) {
  3519. videoLink += '&autoplay=1';
  3520. }
  3521. videoLink = videoLink.replace(/\?|&/, '?');
  3522. // create new href
  3523. src = '//player.vimeo.com/video/' + videoLink;
  3524. type = 'isVimeo';
  3525. } else if (/www\.ted\.com/i.test(href)) {
  3526. // create new href
  3527. src = 'http://embed.ted.com/talks/' + href.substring(href.lastIndexOf('/') + 1) + '.html';
  3528. type = 'isTed';
  3529. } else if (/soundcloud\.com/i.test(href)) {
  3530. // create new href
  3531. src = href;
  3532. type = 'isSoundCloud';
  3533. } else if (/(\.mp4)|(\.ogg)|(\.ogv)|(\.webm)/i.test(href)) {
  3534. if (href.indexOf('|') !== -1) {
  3535. // create new href
  3536. src = href.split('|');
  3537. } else {
  3538. // create new href
  3539. src = href.split('%7C');
  3540. }
  3541. type = 'isSelfHostedVideo';
  3542. } else if (/\.mp3$/i.test(href)) {
  3543. src = href;
  3544. type = 'isSelfHostedAudio';
  3545. }
  3546. t.dataArray.push({
  3547. src: src,
  3548. title: item.getAttribute(t.options.lightboxTitleSrc),
  3549. type: type
  3550. });
  3551. i++;
  3552. }
  3553. tempHref.push(href);
  3554. });
  3555. // total numbers of elements
  3556. t.counterTotal = t.dataArray.length;
  3557. if (t.counterTotal === 1) {
  3558. t.nextButton.hide();
  3559. t.prevButton.hide();
  3560. t.dataActionImg = '';
  3561. } else {
  3562. t.nextButton.show();
  3563. t.prevButton.show();
  3564. t.dataActionImg = 'data-action="next"';
  3565. }
  3566. // append to body
  3567. t.wrap.appendTo(document.body);
  3568. t.scrollTop = $(window).scrollTop();
  3569. t.originalStyle = $('html').attr('style');
  3570. $('html').css({
  3571. overflow: 'hidden',
  3572. marginRight: window.innerWidth - $(document).width()
  3573. });
  3574. t.wrap.addClass('cbp-popup-transitionend');
  3575. // show the wrapper (lightbox box)
  3576. t.wrap.show();
  3577. // get the current element
  3578. element = t.dataArray[t.current];
  3579. // call function if current element is image or video (iframe)
  3580. t[element.type](element);
  3581. },
  3582. openSinglePage: function(blocks, currentBlock) {
  3583. var t = this,
  3584. i = 0,
  3585. currentBlockHref, tempHref = [];
  3586. if (t.isOpen) {
  3587. return;
  3588. }
  3589. // check singlePageInline and close it
  3590. if (t.cubeportfolio.singlePageInline && t.cubeportfolio.singlePageInline.isOpen) {
  3591. t.cubeportfolio.singlePageInline.close();
  3592. }
  3593. // remember that the lightbox is open now
  3594. t.isOpen = true;
  3595. // remember to stop all events after the popup has been showing
  3596. t.stopEvents = false;
  3597. // array with elements
  3598. t.dataArray = [];
  3599. // reset current
  3600. t.current = null;
  3601. currentBlockHref = currentBlock.getAttribute('href');
  3602. if (currentBlockHref === null) {
  3603. throw new Error('HEI! Your clicked element doesn\'t have a href attribute.');
  3604. }
  3605. $.each(blocks, function(index, item) {
  3606. var href = item.getAttribute('href');
  3607. if ($.inArray(href, tempHref) === -1) {
  3608. if (currentBlockHref === href) {
  3609. t.current = i;
  3610. }
  3611. t.dataArray.push({
  3612. url: href,
  3613. element: item
  3614. });
  3615. i++;
  3616. }
  3617. tempHref.push(href);
  3618. });
  3619. // total numbers of elements
  3620. t.counterTotal = t.dataArray.length;
  3621. if (t.counterTotal === 1) {
  3622. t.nextButton.hide();
  3623. t.prevButton.hide();
  3624. } else {
  3625. t.nextButton.show();
  3626. t.prevButton.show();
  3627. }
  3628. // append to body
  3629. t.wrap.appendTo(document.body);
  3630. t.scrollTop = $(window).scrollTop();
  3631. // go to top of the page (reset scroll)
  3632. t.contentWrap.scrollTop(0);
  3633. // show the wrapper
  3634. t.wrap.show();
  3635. // finish the open animation
  3636. t.finishOpen = 2;
  3637. // if transitionend is not fulfilled
  3638. t.navigationMobile = $();
  3639. t.wrap.one(CubePortfolio.private.transitionend, function() {
  3640. $('html').css({
  3641. overflow: 'hidden',
  3642. marginRight: window.innerWidth - $(document).width()
  3643. });
  3644. t.wrap.addClass('cbp-popup-transitionend');
  3645. // make the navigation sticky
  3646. if (t.options.singlePageStickyNavigation) {
  3647. t.wrap.addClass('cbp-popup-singlePage-sticky');
  3648. t.navigationWrap.width(t.contentWrap[0].clientWidth);
  3649. }
  3650. t.finishOpen--;
  3651. if (t.finishOpen <= 0) {
  3652. t.updateSinglePageIsOpen.call(t);
  3653. }
  3654. });
  3655. if (CubePortfolio.private.browser === 'ie8' || CubePortfolio.private.browser === 'ie9') {
  3656. $('html').css({
  3657. overflow: 'hidden',
  3658. marginRight: window.innerWidth - $(document).width()
  3659. });
  3660. t.wrap.addClass('cbp-popup-transitionend');
  3661. // make the navigation sticky
  3662. if (t.options.singlePageStickyNavigation) {
  3663. t.navigationWrap.width(t.contentWrap[0].clientWidth);
  3664. setTimeout(function() {
  3665. t.wrap.addClass('cbp-popup-singlePage-sticky');
  3666. }, 1000);
  3667. }
  3668. t.finishOpen--;
  3669. }
  3670. t.wrap.addClass('cbp-popup-loading');
  3671. // force reflow and then add class
  3672. t.wrap.offset();
  3673. t.wrap.addClass('cbp-popup-singlePage-open');
  3674. // change link
  3675. if (t.options.singlePageDeeplinking) {
  3676. // ignore old #cbp from href
  3677. t.url = t.url.split('#cbp=')[0];
  3678. location.href = t.url + '#cbp=' + t.dataArray[t.current].url;
  3679. }
  3680. // run callback function
  3681. if ($.isFunction(t.options.singlePageCallback)) {
  3682. t.options.singlePageCallback.call(t, t.dataArray[t.current].url, t.dataArray[t.current].element);
  3683. }
  3684. // ios bug to prevent
  3685. // http://stackoverflow.com/questions/9280258/prevent-body-scrolling-but-allow-overlay-scrolling
  3686. if (CubePortfolio.private.browser === 'ios') {
  3687. var element = t.contentWrap[0];
  3688. element.addEventListener('touchstart', function() {
  3689. var top = element.scrollTop,
  3690. totalScroll = element.scrollHeight,
  3691. currentScroll = top + element.offsetHeight;
  3692. if (top === 0) {
  3693. element.scrollTop = 1;
  3694. } else if (currentScroll === totalScroll) {
  3695. element.scrollTop = top - 1;
  3696. }
  3697. });
  3698. }
  3699. },
  3700. openSinglePageInline: function(blocks, currentBlock, fromOpen) {
  3701. var t = this,
  3702. start = 0,
  3703. currentBlockHref,
  3704. tempCurrent,
  3705. cbpitem,
  3706. parentElement;
  3707. fromOpen = fromOpen || false;
  3708. t.fromOpen = fromOpen;
  3709. t.storeBlocks = blocks;
  3710. t.storeCurrentBlock = currentBlock;
  3711. // check singlePageInline and close it
  3712. if (t.isOpen) {
  3713. tempCurrent = t.cubeportfolio.blocksOn.index($(currentBlock).closest('.cbp-item'));
  3714. if ((t.dataArray[t.current].url !== currentBlock.getAttribute('href')) || (t.current !== tempCurrent)) {
  3715. t.cubeportfolio.singlePageInline.close('open', {
  3716. blocks: blocks,
  3717. currentBlock: currentBlock,
  3718. fromOpen: true
  3719. });
  3720. } else {
  3721. t.close();
  3722. }
  3723. return;
  3724. }
  3725. // remember that the lightbox is open now
  3726. t.isOpen = true;
  3727. // remember to stop all events after the popup has been showing
  3728. t.stopEvents = false;
  3729. // array with elements
  3730. t.dataArray = [];
  3731. // reset current
  3732. t.current = null;
  3733. currentBlockHref = currentBlock.getAttribute('href');
  3734. if (currentBlockHref === null) {
  3735. throw new Error('HEI! Your clicked element doesn\'t have a href attribute.');
  3736. }
  3737. cbpitem = $(currentBlock).closest('.cbp-item')[0];
  3738. blocks.each(function(index, el) {
  3739. if (cbpitem === el) {
  3740. t.current = index;
  3741. }
  3742. });
  3743. t.dataArray[t.current] = {
  3744. url: currentBlockHref,
  3745. element: currentBlock
  3746. };
  3747. parentElement = $(t.dataArray[t.current].element).parents('.cbp-item').addClass('cbp-singlePageInline-active');
  3748. // total numbers of elements
  3749. t.counterTotal = blocks.length;
  3750. t.wrap.insertBefore(t.cubeportfolio.wrapper);
  3751. t.topDifference = 0;
  3752. if (t.options.singlePageInlinePosition === 'top') {
  3753. t.blocksToMove = blocks;
  3754. t.top = 0;
  3755. } else if (t.options.singlePageInlinePosition === 'bottom') {
  3756. t.blocksToMove = $();
  3757. t.top = t.cubeportfolio.height;
  3758. } else if (t.options.singlePageInlinePosition === 'above') {
  3759. var currentEl = $(blocks[t.current]);
  3760. var top = currentEl.data('cbp').top;
  3761. var end = top + currentEl.height();
  3762. t.top = top;
  3763. t.blocksToMove = $();
  3764. blocks.each(function(index, el) {
  3765. var element = $(el);
  3766. var topEl = element.data('cbp').top;
  3767. var endEl = topEl + element.height();
  3768. if (endEl <= top) {
  3769. return;
  3770. }
  3771. if (topEl >= top) {
  3772. t.blocksToMove = t.blocksToMove.add(el);
  3773. }
  3774. if ((topEl < top) && (endEl > top)) {
  3775. t.top = endEl + t.options.gapHorizontal;
  3776. if ((endEl - top) > t.topDifference) {
  3777. t.topDifference = endEl - top + t.options.gapHorizontal;
  3778. }
  3779. }
  3780. });
  3781. t.top = Math.max(t.top - t.options.gapHorizontal, 0);
  3782. } else { // below
  3783. var currentEl = $(blocks[t.current]);
  3784. var top = currentEl.data('cbp').top;
  3785. var end = top + currentEl.height();
  3786. t.top = end;
  3787. t.blocksToMove = $();
  3788. blocks.each(function(index, el) {
  3789. var element = $(el);
  3790. var height = element.height();
  3791. var topEl = element.data('cbp').top;
  3792. var endEl = topEl + height;
  3793. if (endEl <= end) {
  3794. return;
  3795. }
  3796. if (topEl >= (end - height / 2)) {
  3797. t.blocksToMove = t.blocksToMove.add(el);
  3798. return;
  3799. }
  3800. if ((endEl > end) && (topEl < end)) {
  3801. if (endEl > t.top) {
  3802. t.top = endEl;
  3803. }
  3804. if ((endEl - end) > t.topDifference) {
  3805. t.topDifference = endEl - end;
  3806. }
  3807. }
  3808. });
  3809. }
  3810. t.wrap[0].style.height = t.wrap.outerHeight(true) + 'px';
  3811. // debouncer for inline content
  3812. t.deferredInline = $.Deferred();
  3813. if (t.options.singlePageInlineInFocus) {
  3814. t.scrollTop = $(window).scrollTop();
  3815. var goToScroll = t.cubeportfolio.$obj.offset().top + t.top - 100;
  3816. if (t.scrollTop !== goToScroll) {
  3817. $('html,body').animate({
  3818. scrollTop: goToScroll
  3819. }, 350)
  3820. .promise()
  3821. .then(function() {
  3822. t.resizeSinglePageInline();
  3823. t.deferredInline.resolve();
  3824. });
  3825. } else {
  3826. t.resizeSinglePageInline();
  3827. t.deferredInline.resolve();
  3828. }
  3829. } else {
  3830. t.resizeSinglePageInline();
  3831. t.deferredInline.resolve();
  3832. }
  3833. t.cubeportfolio.$obj.addClass('cbp-popup-singlePageInline-open');
  3834. t.wrap.css({
  3835. top: t.top
  3836. });
  3837. // change link
  3838. if (t.options.singlePageInlineDeeplinking) {
  3839. // ignore old #cbpi from href
  3840. t.url = t.url.split('#cbpi=')[0];
  3841. location.href = t.url + '#cbpi=' + t.dataArray[t.current].url;
  3842. }
  3843. // register callback function
  3844. if ($.isFunction(t.options.singlePageInlineCallback)) {
  3845. t.options.singlePageInlineCallback.call(t, t.dataArray[t.current].url, t.dataArray[t.current].element);
  3846. }
  3847. },
  3848. resizeSinglePageInline: function() {
  3849. var t = this;
  3850. t.height = ((t.top === 0) || (t.top === t.cubeportfolio.height)) ? t.wrap.outerHeight(true) : t.wrap.outerHeight(true) - t.options.gapHorizontal;
  3851. t.height += t.topDifference;
  3852. t.storeBlocks.each(function(index, el) {
  3853. if (CubePortfolio.private.modernBrowser) {
  3854. el.style[CubePortfolio.private.transform] = '';
  3855. } else {
  3856. el.style.marginTop = '';
  3857. }
  3858. });
  3859. t.blocksToMove.each(function(index, el) {
  3860. if (CubePortfolio.private.modernBrowser) {
  3861. el.style[CubePortfolio.private.transform] = 'translate3d(0px, ' + t.height + 'px, 0)';
  3862. } else {
  3863. el.style.marginTop = t.height + 'px';
  3864. }
  3865. });
  3866. t.cubeportfolio.obj.style.height = t.cubeportfolio.height + t.height + 'px';
  3867. },
  3868. revertResizeSinglePageInline: function() {
  3869. var t = this;
  3870. // reset deferred object
  3871. t.deferredInline = $.Deferred();
  3872. t.storeBlocks.each(function(index, el) {
  3873. if (CubePortfolio.private.modernBrowser) {
  3874. el.style[CubePortfolio.private.transform] = '';
  3875. } else {
  3876. el.style.marginTop = '';
  3877. }
  3878. });
  3879. t.cubeportfolio.obj.style.height = t.cubeportfolio.height + 'px';
  3880. },
  3881. appendScriptsToWrap: function(scripts) {
  3882. var t = this,
  3883. index = 0,
  3884. loadScripts = function(item) {
  3885. var script = document.createElement('script'),
  3886. src = item.src;
  3887. script.type = 'text/javascript';
  3888. if (script.readyState) { // ie
  3889. script.onreadystatechange = function() {
  3890. if (script.readyState == 'loaded' || script.readyState == 'complete') {
  3891. script.onreadystatechange = null;
  3892. index++;
  3893. if (scripts[index]) {
  3894. loadScripts(scripts[index]);
  3895. }
  3896. }
  3897. };
  3898. } else {
  3899. script.onload = function() {
  3900. index++;
  3901. if (scripts[index]) {
  3902. loadScripts(scripts[index]);
  3903. }
  3904. };
  3905. }
  3906. if (src) {
  3907. script.src = src;
  3908. } else {
  3909. script.text = item.text;
  3910. }
  3911. t.content[0].appendChild(script);
  3912. };
  3913. loadScripts(scripts[0]);
  3914. },
  3915. updateSinglePage: function(html, scripts, isWrap) {
  3916. var t = this,
  3917. counterMarkup,
  3918. animationFinish;
  3919. t.content.addClass('cbp-popup-content').removeClass('cbp-popup-content-basic');
  3920. if (isWrap === false) {
  3921. t.content.removeClass('cbp-popup-content').addClass('cbp-popup-content-basic');
  3922. }
  3923. // update counter navigation
  3924. if (t.counter) {
  3925. counterMarkup = $(t.getCounterMarkup(t.options.singlePageCounter, t.current + 1, t.counterTotal));
  3926. t.counter.text(counterMarkup.text());
  3927. }
  3928. t.fromAJAX = {
  3929. html: html,
  3930. scripts: scripts
  3931. };
  3932. t.finishOpen--;
  3933. if (t.finishOpen <= 0) {
  3934. t.updateSinglePageIsOpen.call(t);
  3935. }
  3936. },
  3937. updateSinglePageIsOpen: function() {
  3938. var t = this,
  3939. selectorSlider;
  3940. t.wrap.addClass('cbp-popup-ready');
  3941. t.wrap.removeClass('cbp-popup-loading');
  3942. t.content.html(t.fromAJAX.html);
  3943. if (t.fromAJAX.scripts) {
  3944. t.appendScriptsToWrap(t.fromAJAX.scripts);
  3945. }
  3946. t.fromAJAX = {};
  3947. // trigger public event
  3948. t.cubeportfolio.$obj.trigger('updateSinglePageStart.cbp');
  3949. // instantiate slider if exists
  3950. selectorSlider = t.content.find('.cbp-slider');
  3951. if (selectorSlider.length) {
  3952. selectorSlider.find('.cbp-slider-item').addClass('cbp-item');
  3953. t.slider = selectorSlider.cubeportfolio({
  3954. layoutMode: 'slider',
  3955. mediaQueries: [{
  3956. width: 1,
  3957. cols: 1
  3958. }],
  3959. gapHorizontal: 0,
  3960. gapVertical: 0,
  3961. caption: '',
  3962. coverRatio: '', // wp version only
  3963. });
  3964. } else {
  3965. t.slider = null;
  3966. }
  3967. // check for social share icons
  3968. t.checkForSocialLinks(t.content);
  3969. // trigger public event
  3970. t.cubeportfolio.$obj.trigger('updateSinglePageComplete.cbp');
  3971. },
  3972. checkForSocialLinks: function(content) {
  3973. var t = this;
  3974. t.createFacebookShare(content.find('.cbp-social-fb'));
  3975. t.createTwitterShare(content.find('.cbp-social-twitter'));
  3976. t.createGooglePlusShare(content.find('.cbp-social-googleplus'));
  3977. t.createPinterestShare(content.find('.cbp-social-pinterest'));
  3978. },
  3979. createFacebookShare: function(item) {
  3980. if (item.length && !item.attr('onclick')) {
  3981. item.attr('onclick', "window.open('http://www.facebook.com/sharer.php?u=" + encodeURIComponent(window.location.href) + "', '_blank', 'top=100,left=100,toolbar=0,status=0,width=620,height=400'); return false;");
  3982. }
  3983. },
  3984. createTwitterShare: function(item) {
  3985. if (item.length && !item.attr('onclick')) {
  3986. item.attr('onclick', "window.open('https://twitter.com/intent/tweet?source=" + encodeURIComponent(window.location.href) + "&text=" + encodeURIComponent(document.title) + "', '_blank', 'top=100,left=100,toolbar=0,status=0,width=620,height=300'); return false;");
  3987. }
  3988. },
  3989. createGooglePlusShare: function(item) {
  3990. if (item.length && !item.attr('onclick')) {
  3991. item.attr('onclick', "window.open('https://plus.google.com/share?url=" + encodeURIComponent(window.location.href) + "', '_blank', 'top=100,left=100,toolbar=0,status=0,width=620,height=450'); return false;");
  3992. }
  3993. },
  3994. createPinterestShare: function(item) {
  3995. if (item.length && !item.attr('onclick')) {
  3996. var media = '';
  3997. var firstImg = this.content.find('img')[0];
  3998. if (firstImg) {
  3999. media = firstImg.src;
  4000. }
  4001. item.attr('onclick', "window.open('http://pinterest.com/pin/create/button/?url=" + encodeURIComponent(window.location.href) + "&media=" + media + "', '_blank', 'top=100,left=100,toolbar=0,status=0,width=620,height=400'); return false;");
  4002. }
  4003. },
  4004. updateSinglePageInline: function(html, scripts) {
  4005. var t = this;
  4006. t.content.html(html);
  4007. if (scripts) {
  4008. t.appendScriptsToWrap(scripts);
  4009. }
  4010. // trigger public event
  4011. t.cubeportfolio.$obj.trigger('updateSinglePageInlineStart.cbp');
  4012. if (t.localOptions.delay !== 0) {
  4013. setTimeout(function() {
  4014. t.singlePageInlineIsOpen.call(t);
  4015. }, t.localOptions.delay)
  4016. } else {
  4017. t.singlePageInlineIsOpen.call(t);
  4018. }
  4019. },
  4020. singlePageInlineIsOpen: function() {
  4021. var t = this;
  4022. function finishLoading() {
  4023. t.wrap.addClass('cbp-popup-singlePageInline-ready');
  4024. t.wrap[0].style.height = '';
  4025. t.resizeSinglePageInline();
  4026. // trigger public event
  4027. t.cubeportfolio.$obj.trigger('updateSinglePageInlineComplete.cbp');
  4028. }
  4029. // wait to load all images
  4030. t.cubeportfolio.loadImages(t.wrap, function() {
  4031. // instantiate slider if exists
  4032. var selectorSlider = t.content.find('.cbp-slider');
  4033. if (selectorSlider.length) {
  4034. selectorSlider.find('.cbp-slider-item').addClass('cbp-item');
  4035. selectorSlider.one('initComplete.cbp', function() {
  4036. t.deferredInline.done(finishLoading);
  4037. });
  4038. selectorSlider.on('pluginResize.cbp', function() {
  4039. t.deferredInline.done(finishLoading);
  4040. });
  4041. t.slider = selectorSlider.cubeportfolio({
  4042. layoutMode: 'slider',
  4043. displayType: 'default',
  4044. mediaQueries: [{
  4045. width: 1,
  4046. cols: 1
  4047. }],
  4048. gapHorizontal: 0,
  4049. gapVertical: 0,
  4050. caption: '',
  4051. coverRatio: '', // wp version only
  4052. });
  4053. } else {
  4054. t.slider = null;
  4055. t.deferredInline.done(finishLoading);
  4056. }
  4057. // check for social share icons
  4058. t.checkForSocialLinks(t.content);
  4059. });
  4060. },
  4061. isImage: function(el) {
  4062. var t = this,
  4063. img = new Image();
  4064. t.tooggleLoading(true);
  4065. t.cubeportfolio.loadImages($('<div><img src="' + el.src + '"></div>'), function() {
  4066. t.updateImagesMarkup(el.src, el.title, t.getCounterMarkup(t.options.lightboxCounter, t.current + 1, t.counterTotal));
  4067. t.tooggleLoading(false);
  4068. });
  4069. },
  4070. isVimeo: function(el) {
  4071. var t = this;
  4072. t.updateVideoMarkup(el.src, el.title, t.getCounterMarkup(t.options.lightboxCounter, t.current + 1, t.counterTotal));
  4073. },
  4074. isYoutube: function(el) {
  4075. var t = this;
  4076. t.updateVideoMarkup(el.src, el.title, t.getCounterMarkup(t.options.lightboxCounter, t.current + 1, t.counterTotal));
  4077. },
  4078. isTed: function(el) {
  4079. var t = this;
  4080. t.updateVideoMarkup(el.src, el.title, t.getCounterMarkup(t.options.lightboxCounter, t.current + 1, t.counterTotal));
  4081. },
  4082. isSoundCloud: function(el) {
  4083. var t = this;
  4084. t.updateVideoMarkup(el.src, el.title, t.getCounterMarkup(t.options.lightboxCounter, t.current + 1, t.counterTotal));
  4085. },
  4086. isSelfHostedVideo: function(el) {
  4087. var t = this;
  4088. t.updateSelfHostedVideo(el.src, el.title, t.getCounterMarkup(t.options.lightboxCounter, t.current + 1, t.counterTotal));
  4089. },
  4090. isSelfHostedAudio: function(el) {
  4091. var t = this;
  4092. t.updateSelfHostedAudio(el.src, el.title, t.getCounterMarkup(t.options.lightboxCounter, t.current + 1, t.counterTotal));
  4093. },
  4094. getCounterMarkup: function(markup, current, total) {
  4095. if (!markup.length) {
  4096. return '';
  4097. }
  4098. var mapObj = {
  4099. current: current,
  4100. total: total
  4101. };
  4102. return markup.replace(/\{\{current}}|\{\{total}}/gi, function(matched) {
  4103. return mapObj[matched.slice(2, -2)];
  4104. });
  4105. },
  4106. updateSelfHostedVideo: function(src, title, counter) {
  4107. var t = this,
  4108. i;
  4109. t.wrap.addClass('cbp-popup-lightbox-isIframe');
  4110. var markup = '<div class="cbp-popup-lightbox-iframe">' +
  4111. '<video controls="controls" height="auto" style="width: 100%">';
  4112. for (i = 0; i < src.length; i++) {
  4113. if (/(\.mp4)/i.test(src[i])) {
  4114. markup += '<source src="' + src[i] + '" type="video/mp4">';
  4115. } else if (/(\.ogg)|(\.ogv)/i.test(src[i])) {
  4116. markup += '<source src="' + src[i] + '" type="video/ogg">';
  4117. } else if (/(\.webm)/i.test(src[i])) {
  4118. markup += '<source src="' + src[i] + '" type="video/webm">';
  4119. }
  4120. }
  4121. markup += 'Your browser does not support the video tag.' +
  4122. '</video>' +
  4123. '<div class="cbp-popup-lightbox-bottom">' +
  4124. ((title) ? '<div class="cbp-popup-lightbox-title">' + title + '</div>' : '') +
  4125. counter +
  4126. '</div>' +
  4127. '</div>';
  4128. t.content.html(markup);
  4129. t.wrap.addClass('cbp-popup-ready');
  4130. t.preloadNearbyImages();
  4131. },
  4132. updateSelfHostedAudio: function(src, title, counter) {
  4133. var t = this,
  4134. i;
  4135. t.wrap.addClass('cbp-popup-lightbox-isIframe');
  4136. var markup = '<div class="cbp-popup-lightbox-iframe">' +
  4137. '<div class="cbp-misc-video"><audio controls="controls" height="auto" style="width: 75%">' +
  4138. '<source src="' + src + '" type="audio/mpeg">' +
  4139. 'Your browser does not support the audio tag.' +
  4140. '</audio></div>' +
  4141. '<div class="cbp-popup-lightbox-bottom">' +
  4142. ((title) ? '<div class="cbp-popup-lightbox-title">' + title + '</div>' : '') +
  4143. counter +
  4144. '</div>' +
  4145. '</div>';
  4146. t.content.html(markup);
  4147. t.wrap.addClass('cbp-popup-ready');
  4148. t.preloadNearbyImages();
  4149. },
  4150. updateVideoMarkup: function(src, title, counter) {
  4151. var t = this;
  4152. t.wrap.addClass('cbp-popup-lightbox-isIframe');
  4153. var markup = '<div class="cbp-popup-lightbox-iframe">' +
  4154. '<iframe src="' + src + '" frameborder="0" allowfullscreen scrolling="no"></iframe>' +
  4155. '<div class="cbp-popup-lightbox-bottom">' +
  4156. ((title) ? '<div class="cbp-popup-lightbox-title">' + title + '</div>' : '') +
  4157. counter +
  4158. '</div>' +
  4159. '</div>';
  4160. t.content.html(markup);
  4161. t.wrap.addClass('cbp-popup-ready');
  4162. t.preloadNearbyImages();
  4163. },
  4164. updateImagesMarkup: function(src, title, counter) {
  4165. var t = this;
  4166. t.wrap.removeClass('cbp-popup-lightbox-isIframe');
  4167. var markup = '<div class="cbp-popup-lightbox-figure">' +
  4168. '<img src="' + src + '" class="cbp-popup-lightbox-img" ' + t.dataActionImg + ' />' +
  4169. '<div class="cbp-popup-lightbox-bottom">' +
  4170. ((title) ? '<div class="cbp-popup-lightbox-title">' + title + '</div>' : '') +
  4171. counter +
  4172. '</div>' +
  4173. '</div>';
  4174. t.content.html(markup);
  4175. t.wrap.addClass('cbp-popup-ready');
  4176. t.resizeImage();
  4177. t.preloadNearbyImages();
  4178. },
  4179. next: function() {
  4180. var t = this;
  4181. t[t.type + 'JumpTo'](1);
  4182. },
  4183. prev: function() {
  4184. var t = this;
  4185. t[t.type + 'JumpTo'](-1);
  4186. },
  4187. lightboxJumpTo: function(index) {
  4188. var t = this,
  4189. el;
  4190. t.current = t.getIndex(t.current + index);
  4191. // get the current element
  4192. el = t.dataArray[t.current];
  4193. // call function if current element is image or video (iframe)
  4194. t[el.type](el);
  4195. },
  4196. singlePageJumpTo: function(index) {
  4197. var t = this;
  4198. t.current = t.getIndex(t.current + index);
  4199. // register singlePageCallback function
  4200. if ($.isFunction(t.options.singlePageCallback)) {
  4201. t.resetWrap();
  4202. // go to top of the page (reset scroll)
  4203. t.contentWrap.scrollTop(0);
  4204. t.wrap.addClass('cbp-popup-loading');
  4205. if (t.slider) {
  4206. CubePortfolio.private.resize.destroyEvent($.data(t.slider[0], 'cubeportfolio'));
  4207. }
  4208. t.options.singlePageCallback.call(t, t.dataArray[t.current].url, t.dataArray[t.current].element);
  4209. if (t.options.singlePageDeeplinking) {
  4210. location.href = t.url + '#cbp=' + t.dataArray[t.current].url;
  4211. }
  4212. }
  4213. },
  4214. resetWrap: function() {
  4215. var t = this;
  4216. if (t.type === 'singlePage' && t.options.singlePageDeeplinking) {
  4217. location.href = t.url + '#';
  4218. }
  4219. if (t.type === 'singlePageInline' && t.options.singlePageInlineDeeplinking) {
  4220. location.href = t.url + '#';
  4221. }
  4222. },
  4223. getIndex: function(index) {
  4224. var t = this;
  4225. // go to interval [0, (+ or -)this.counterTotal.length - 1]
  4226. index = index % t.counterTotal;
  4227. // if index is less then 0 then go to interval (0, this.counterTotal - 1]
  4228. if (index < 0) {
  4229. index = t.counterTotal + index;
  4230. }
  4231. return index;
  4232. },
  4233. close: function(method, data) {
  4234. var t = this;
  4235. function finishClose() {
  4236. // remove resize event
  4237. if (t.slider) {
  4238. CubePortfolio.private.resize.destroyEvent($.data(t.slider[0], 'cubeportfolio'));
  4239. }
  4240. // reset content
  4241. t.content.html('');
  4242. // hide the wrap
  4243. t.wrap.detach();
  4244. t.cubeportfolio.$obj.removeClass('cbp-popup-singlePageInline-open cbp-popup-singlePageInline-close');
  4245. // now the popup is closed
  4246. t.isOpen = false;
  4247. if (method === 'promise') {
  4248. if ($.isFunction(data.callback)) {
  4249. data.callback.call(t.cubeportfolio);
  4250. }
  4251. }
  4252. }
  4253. function checkFocusInline() {
  4254. // add this to prevent the page to jump after the resetWrap
  4255. var scrollTop = $(window).scrollTop();
  4256. t.resetWrap();
  4257. $(window).scrollTop(scrollTop);
  4258. if (t.options.singlePageInlineInFocus && method !== 'promise') {
  4259. $('html,body').animate({
  4260. scrollTop: t.scrollTop
  4261. }, 350)
  4262. .promise()
  4263. .then(function() {
  4264. finishClose();
  4265. });
  4266. } else {
  4267. finishClose();
  4268. }
  4269. }
  4270. if (t.type === 'singlePageInline') {
  4271. if (method === 'open') {
  4272. t.wrap.removeClass('cbp-popup-singlePageInline-ready');
  4273. $(t.dataArray[t.current].element).closest('.cbp-item').removeClass('cbp-singlePageInline-active');
  4274. // now the popup is closed
  4275. t.isOpen = false;
  4276. t.openSinglePageInline(data.blocks, data.currentBlock, data.fromOpen);
  4277. } else {
  4278. t.height = 0;
  4279. t.revertResizeSinglePageInline();
  4280. t.wrap.removeClass('cbp-popup-singlePageInline-ready');
  4281. t.cubeportfolio.$obj.addClass('cbp-popup-singlePageInline-close');
  4282. t.cubeportfolio.$obj.find('.cbp-item').removeClass('cbp-singlePageInline-active');
  4283. if (CubePortfolio.private.modernBrowser) {
  4284. t.wrap.one(CubePortfolio.private.transitionend, function() {
  4285. checkFocusInline();
  4286. });
  4287. } else {
  4288. checkFocusInline();
  4289. }
  4290. }
  4291. } else if (t.type === 'singlePage') {
  4292. t.resetWrap();
  4293. $(window).scrollTop(t.scrollTop);
  4294. t.stopScroll = true;
  4295. t.wrap.removeClass('cbp-popup-ready cbp-popup-transitionend cbp-popup-singlePage-open cbp-popup-singlePage-sticky');
  4296. $('html').css({
  4297. overflow: '',
  4298. marginRight: '',
  4299. position: ''
  4300. });
  4301. if (CubePortfolio.private.browser === 'ie8' || CubePortfolio.private.browser === 'ie9') {
  4302. // remove resize event
  4303. if (t.slider) {
  4304. CubePortfolio.private.resize.destroyEvent($.data(t.slider[0], 'cubeportfolio'));
  4305. }
  4306. // reset content
  4307. t.content.html('');
  4308. // hide the wrap
  4309. t.wrap.detach();
  4310. // now the popup is closed
  4311. t.isOpen = false;
  4312. }
  4313. t.wrap.one(CubePortfolio.private.transitionend, function() {
  4314. // remove resize event
  4315. if (t.slider) {
  4316. CubePortfolio.private.resize.destroyEvent($.data(t.slider[0], 'cubeportfolio'));
  4317. }
  4318. // reset content
  4319. t.content.html('');
  4320. // hide the wrap
  4321. t.wrap.detach();
  4322. // now the popup is closed
  4323. t.isOpen = false;
  4324. });
  4325. } else {
  4326. lightboxIsOpen = false;
  4327. if (t.originalStyle) {
  4328. $('html').attr('style', t.originalStyle);
  4329. } else {
  4330. $('html').css({
  4331. overflow: '',
  4332. marginRight: ''
  4333. });
  4334. }
  4335. $(window).scrollTop(t.scrollTop);
  4336. // remove resize event
  4337. if (t.slider) {
  4338. CubePortfolio.private.resize.destroyEvent($.data(t.slider[0], 'cubeportfolio'));
  4339. }
  4340. // reset content
  4341. t.content.html('');
  4342. // hide the wrap
  4343. t.wrap.detach();
  4344. // now the popup is closed
  4345. t.isOpen = false;
  4346. }
  4347. },
  4348. tooggleLoading: function(state) {
  4349. var t = this;
  4350. t.stopEvents = state;
  4351. t.wrap[(state) ? 'addClass' : 'removeClass']('cbp-popup-loading');
  4352. },
  4353. resizeImage: function() {
  4354. // if lightbox is not open go out
  4355. if (!this.isOpen) {
  4356. return;
  4357. }
  4358. var img = this.content.find('img');
  4359. var figure = img.parent();
  4360. var height = $(window).height() - (figure.outerHeight(true) - figure.height()) - this.content.find('.cbp-popup-lightbox-bottom').outerHeight(true);
  4361. img.css('max-height', height + 'px');
  4362. },
  4363. preloadNearbyImages: function() {
  4364. var t = this;
  4365. var arr = [
  4366. t.getIndex(t.current + 1),
  4367. t.getIndex(t.current + 2),
  4368. t.getIndex(t.current + 3),
  4369. t.getIndex(t.current - 1),
  4370. t.getIndex(t.current - 2),
  4371. t.getIndex(t.current - 3),
  4372. ];
  4373. for (var i = arr.length - 1; i >= 0; i--) {
  4374. if (t.dataArray[arr[i]].type === 'isImage') {
  4375. t.cubeportfolio.checkSrc(t.dataArray[arr[i]]);
  4376. }
  4377. }
  4378. }
  4379. };
  4380. function Plugin(parent) {
  4381. var t = this;
  4382. t.parent = parent;
  4383. // if lightboxShowCounter is false, put lightboxCounter to ''
  4384. if (parent.options.lightboxShowCounter === false) {
  4385. parent.options.lightboxCounter = '';
  4386. }
  4387. // if singlePageShowCounter is false, put singlePageCounter to ''
  4388. if (parent.options.singlePageShowCounter === false) {
  4389. parent.options.singlePageCounter = '';
  4390. }
  4391. // @todo - schedule this in future
  4392. parent.registerEvent('initStartRead', function() {
  4393. t.run();
  4394. }, true);
  4395. }
  4396. // little hack for keydown issue when lightbox & singlePage is open
  4397. var lightboxIsOpen = false;
  4398. var lightboxInit = false;
  4399. var singlePageInit = false;
  4400. Plugin.prototype.run = function() {
  4401. var t = this,
  4402. p = t.parent,
  4403. body = $(document.body);
  4404. // default value for lightbox
  4405. p.lightbox = null;
  4406. // LIGHTBOX
  4407. if (p.options.lightboxDelegate && !lightboxInit) {
  4408. // init only one time @todo
  4409. lightboxInit = true;
  4410. p.lightbox = Object.create(popup);
  4411. p.lightbox.init(p, 'lightbox');
  4412. body.on('click.cbp', p.options.lightboxDelegate, function(e) {
  4413. e.preventDefault();
  4414. var self = $(this),
  4415. gallery = self.attr('data-cbp-lightbox'),
  4416. scope = t.detectScope(self),
  4417. cbp = scope.data('cubeportfolio'),
  4418. blocks = [];
  4419. // is inside a cbp
  4420. if (cbp) {
  4421. cbp.blocksOn.each(function(index, el) {
  4422. var item = $(el);
  4423. if (item.not('.cbp-item-off')) {
  4424. item.find(p.options.lightboxDelegate).each(function(index2, el2) {
  4425. if (gallery) {
  4426. if ($(el2).attr('data-cbp-lightbox') === gallery) {
  4427. blocks.push(el2);
  4428. }
  4429. } else {
  4430. blocks.push(el2);
  4431. }
  4432. });
  4433. }
  4434. });
  4435. } else {
  4436. if (gallery) {
  4437. blocks = scope.find(p.options.lightboxDelegate + '[data-cbp-lightbox=' + gallery + ']');
  4438. } else {
  4439. blocks = scope.find(p.options.lightboxDelegate);
  4440. }
  4441. }
  4442. p.lightbox.openLightbox(blocks, self[0]);
  4443. });
  4444. }
  4445. // default value for singlePage
  4446. p.singlePage = null;
  4447. // SINGLEPAGE
  4448. if (p.options.singlePageDelegate && !singlePageInit) {
  4449. // init only one time @todo
  4450. singlePageInit = true;
  4451. p.singlePage = Object.create(popup);
  4452. p.singlePage.init(p, 'singlePage');
  4453. body.on('click.cbp', p.options.singlePageDelegate, function(e) {
  4454. e.preventDefault();
  4455. var self = $(this),
  4456. gallery = self.attr('data-cbp-singlePage'),
  4457. scope = t.detectScope(self),
  4458. cbp = scope.data('cubeportfolio'),
  4459. blocks = [];
  4460. // is inside a cbp
  4461. if (cbp) {
  4462. cbp.blocksOn.each(function(index, el) {
  4463. var item = $(el);
  4464. if (item.not('.cbp-item-off')) {
  4465. item.find(p.options.singlePageDelegate).each(function(index2, el2) {
  4466. if (gallery) {
  4467. if ($(el2).attr('data-cbp-singlePage') === gallery) {
  4468. blocks.push(el2);
  4469. }
  4470. } else {
  4471. blocks.push(el2);
  4472. }
  4473. });
  4474. }
  4475. });
  4476. } else {
  4477. if (gallery) {
  4478. blocks = scope.find(p.options.singlePageDelegate + '[data-cbp-singlePage=' + gallery + ']');
  4479. } else {
  4480. blocks = scope.find(p.options.singlePageDelegate);
  4481. }
  4482. }
  4483. p.singlePage.openSinglePage(blocks, self[0]);
  4484. });
  4485. }
  4486. // default value for singlePageInline
  4487. p.singlePageInline = null;
  4488. // SINGLEPAGEINLINE
  4489. if (p.options.singlePageInlineDelegate) {
  4490. p.singlePageInline = Object.create(popup);
  4491. p.singlePageInline.init(p, 'singlePageInline');
  4492. p.$obj.on('click.cbp', p.options.singlePageInlineDelegate, function(e) {
  4493. e.preventDefault();
  4494. var oldDate = $.data(this, 'cbp-locked'),
  4495. newDate = $.data(this, 'cbp-locked', +new Date());
  4496. if (!oldDate || ((newDate - oldDate) > 300)) {
  4497. p.singlePageInline.openSinglePageInline(p.blocksOn, this);
  4498. }
  4499. });
  4500. }
  4501. };
  4502. Plugin.prototype.detectScope = function(item) {
  4503. var singlePageInline,
  4504. singlePage,
  4505. cbp;
  4506. singlePageInline = item.closest('.cbp-popup-singlePageInline');
  4507. if (singlePageInline.length) {
  4508. cbp = item.closest('.cbp', singlePageInline[0]);
  4509. return (cbp.length) ? cbp : singlePageInline;
  4510. }
  4511. singlePage = item.closest('.cbp-popup-singlePage');
  4512. if (singlePage.length) {
  4513. cbp = item.closest('.cbp', singlePage[0]);
  4514. return (cbp.length) ? cbp : singlePage;
  4515. }
  4516. cbp = item.closest('.cbp');
  4517. return (cbp.length) ? cbp : $(document.body);
  4518. };
  4519. Plugin.prototype.destroy = function() {
  4520. var p = this.parent;
  4521. $(document.body).off('click.cbp');
  4522. // @todo - remove these from here
  4523. lightboxInit = false;
  4524. singlePageInit = false;
  4525. // destroy lightbox if enabled
  4526. if (p.lightbox) {
  4527. p.lightbox.destroy();
  4528. }
  4529. // destroy singlePage if enabled
  4530. if (p.singlePage) {
  4531. p.singlePage.destroy();
  4532. }
  4533. // destroy singlePage inline if enabled
  4534. if (p.singlePageInline) {
  4535. p.singlePageInline.destroy();
  4536. }
  4537. };
  4538. CubePortfolio.plugins.popUp = function(parent) {
  4539. return new Plugin(parent);
  4540. };
  4541. })(jQuery, window, document);
  4542. (function($, window, document, undefined) {
  4543. 'use strict';
  4544. var CubePortfolio = $.fn.cubeportfolio.constructor;
  4545. function Plugin(parent) {
  4546. var t = this;
  4547. t.parent = parent;
  4548. t.searchInput = $(parent.options.search);
  4549. t.searchInput.each(function(index, el) {
  4550. var selector = el.getAttribute('data-search');
  4551. if (!selector) {
  4552. selector = '*';
  4553. }
  4554. $.data(el, 'searchData', {
  4555. value: el.value,
  4556. el: selector
  4557. });
  4558. });
  4559. var timeout = null;
  4560. t.searchInput.on('keyup.cbp paste.cbp', function(e) {
  4561. e.preventDefault();
  4562. var el = $(this);
  4563. clearTimeout(timeout);
  4564. timeout = setTimeout(function() {
  4565. t.runEvent.call(t, el);
  4566. }, 350);
  4567. });
  4568. t.searchNothing = t.searchInput.siblings('.cbp-search-nothing').detach();
  4569. t.searchNothingHeight = null;
  4570. t.searchNothingHTML = t.searchNothing.html();
  4571. t.searchInput.siblings('.cbp-search-icon').on('click.cbp', function(e) {
  4572. e.preventDefault();
  4573. t.runEvent.call(t, $(this).prev().val(''));
  4574. });
  4575. }
  4576. Plugin.prototype.runEvent = function(el) {
  4577. var t = this,
  4578. value = el.val(),
  4579. searchData = el.data('searchData'),
  4580. reg = new RegExp(value, 'i');
  4581. if (searchData.value === value || t.parent.isAnimating) {
  4582. return;
  4583. }
  4584. searchData.value = value;
  4585. if (value.length > 0) {
  4586. el.attr('value', value);
  4587. } else {
  4588. el.removeAttr('value');
  4589. }
  4590. t.parent.$obj.cubeportfolio('filter', function(blocks) {
  4591. var blocksNew = blocks.filter(function(index, block) {
  4592. var text = $(block).find(searchData.el).text();
  4593. if (text.search(reg) > -1) {
  4594. return true;
  4595. }
  4596. });
  4597. if (blocksNew.length === 0 && t.searchNothing.length) {
  4598. var innerText = t.searchNothingHTML.replace('{{query}}', value);
  4599. t.searchNothing.html(innerText);
  4600. t.searchNothing.appendTo(t.parent.$obj);
  4601. if (t.searchNothingHeight === null) {
  4602. t.searchNothingHeight = t.searchNothing.outerHeight(true);
  4603. }
  4604. t.parent.registerEvent('resizeMainContainer', function() {
  4605. t.parent.height = t.parent.height + t.searchNothingHeight;
  4606. t.parent.obj.style.height = t.parent.height + 'px';
  4607. }, true);
  4608. } else {
  4609. t.searchNothing.detach();
  4610. }
  4611. // reset filters active class after the search is used
  4612. t.parent.triggerEvent('resetFiltersVisual');
  4613. return blocksNew;
  4614. }, function() {
  4615. el.trigger('keyup.cbp');
  4616. });
  4617. };
  4618. Plugin.prototype.destroy = function() {
  4619. var t = this;
  4620. t.searchInput.off('.cbp');
  4621. t.searchInput.next('.cbp-search-icon').off('.cbp');
  4622. t.searchInput.each(function(index, el) {
  4623. $.removeData(el);
  4624. });
  4625. };
  4626. CubePortfolio.plugins.search = function(parent) {
  4627. if (parent.options.search === '') {
  4628. return null;
  4629. }
  4630. return new Plugin(parent);
  4631. };
  4632. })(jQuery, window, document);
  4633. (function($, window, document, undefined) {
  4634. 'use strict';
  4635. var options = {
  4636. /**
  4637. * Pagination custom selector
  4638. * Values: strings that represent the elements in the document (DOM selector).
  4639. */
  4640. pagination: '',
  4641. paginationClass: 'cbp-pagination-active',
  4642. };
  4643. var CubePortfolio = $.fn.cubeportfolio.constructor;
  4644. function Plugin(parent) {
  4645. var t = this;
  4646. t.parent = parent;
  4647. t.options = $.extend({}, options, t.parent.options.plugins.slider);
  4648. var customPagination = $(t.options.pagination);
  4649. if (customPagination.length > 0) {
  4650. t.parent.customPagination = customPagination;
  4651. t.parent.customPaginationItems = customPagination.children();
  4652. t.parent.customPaginationClass = t.options.paginationClass;
  4653. t.parent.customPaginationItems.on('click.cbp', function(e) {
  4654. e.preventDefault();
  4655. e.stopImmediatePropagation();
  4656. e.stopPropagation();
  4657. if (t.parent.sliderStopEvents) {
  4658. return;
  4659. }
  4660. t.parent.jumpToSlider($(this));
  4661. });
  4662. }
  4663. t.parent.registerEvent('gridAdjust', function() {
  4664. t.sliderMarkup.call(t.parent);
  4665. t.parent.registerEvent('gridAdjust', function() {
  4666. t.updateSlider.call(t.parent);
  4667. });
  4668. }, true);
  4669. }
  4670. /**
  4671. * Create mark-up for slider layout
  4672. */
  4673. Plugin.prototype.sliderMarkup = function() {
  4674. var t = this;
  4675. t.sliderStopEvents = false;
  4676. t.sliderActive = 0;
  4677. t.$obj.one('initComplete.cbp', function() {
  4678. t.$obj.addClass('cbp-mode-slider');
  4679. });
  4680. t.nav = $('<div/>', {
  4681. 'class': 'cbp-nav'
  4682. });
  4683. t.nav.on('click.cbp', '[data-slider-action]', function(e) {
  4684. e.preventDefault();
  4685. e.stopImmediatePropagation();
  4686. e.stopPropagation();
  4687. if (t.sliderStopEvents) {
  4688. return;
  4689. }
  4690. var el = $(this),
  4691. action = el.attr('data-slider-action');
  4692. if (t[action + 'Slider']) {
  4693. t[action + 'Slider'](el);
  4694. }
  4695. });
  4696. if (t.options.showNavigation) {
  4697. t.controls = $('<div/>', {
  4698. 'class': 'cbp-nav-controls'
  4699. });
  4700. t.navPrev = $('<div/>', {
  4701. 'class': 'cbp-nav-prev',
  4702. 'data-slider-action': 'prev'
  4703. }).appendTo(t.controls);
  4704. t.navNext = $('<div/>', {
  4705. 'class': 'cbp-nav-next',
  4706. 'data-slider-action': 'next'
  4707. }).appendTo(t.controls);
  4708. t.controls.appendTo(t.nav);
  4709. }
  4710. if (t.options.showPagination) {
  4711. t.navPagination = $('<div/>', {
  4712. 'class': 'cbp-nav-pagination'
  4713. }).appendTo(t.nav);
  4714. }
  4715. if (t.controls || t.navPagination) {
  4716. t.nav.appendTo(t.$obj);
  4717. }
  4718. t.updateSliderPagination();
  4719. if (t.options.auto) {
  4720. if (t.options.autoPauseOnHover) {
  4721. t.mouseIsEntered = false;
  4722. t.$obj.on('mouseenter.cbp', function(e) {
  4723. t.mouseIsEntered = true;
  4724. t.stopSliderAuto();
  4725. }).on('mouseleave.cbp', function(e) {
  4726. t.mouseIsEntered = false;
  4727. t.startSliderAuto();
  4728. });
  4729. }
  4730. t.startSliderAuto();
  4731. }
  4732. if (t.options.drag && CubePortfolio.private.modernBrowser) {
  4733. t.dragSlider();
  4734. }
  4735. };
  4736. Plugin.prototype.updateSlider = function() {
  4737. var t = this;
  4738. t.updateSliderPosition();
  4739. t.updateSliderPagination();
  4740. };
  4741. Plugin.prototype.destroy = function() {
  4742. var t = this;
  4743. if (t.parent.customPaginationItems) {
  4744. t.parent.customPaginationItems.off('.cbp');
  4745. }
  4746. if (t.parent.controls || t.parent.navPagination) {
  4747. t.parent.nav.off('.cbp');
  4748. t.parent.nav.remove();
  4749. }
  4750. };
  4751. CubePortfolio.plugins.slider = function(parent) {
  4752. if (parent.options.layoutMode !== 'slider') {
  4753. return null;
  4754. }
  4755. return new Plugin(parent);
  4756. };
  4757. })(jQuery, window, document);
  4758. (function($, window, document, undefined) {
  4759. 'use strict';
  4760. var options = {
  4761. /**
  4762. * Define the wrapper for sort
  4763. * Values: strings that represent the elements in the document (DOM selector).
  4764. */
  4765. element: '',
  4766. };
  4767. var CubePortfolio = $.fn.cubeportfolio.constructor;
  4768. function Plugin(parent) {
  4769. var t = this;
  4770. t.parent = parent;
  4771. t.options = $.extend({}, options, t.parent.options.plugins.sort);
  4772. t.element = $(t.options.element);
  4773. if (t.element.length === 0) {
  4774. return;
  4775. }
  4776. t.sort = '';
  4777. t.sortBy = 'string:asc';
  4778. t.element.on('click.cbp', '.cbp-sort-item', function(event) {
  4779. event.preventDefault();
  4780. t.target = event.target;
  4781. if ($(t.target).hasClass('cbp-l-dropdown-item--active') || parent.isAnimating) {
  4782. return;
  4783. }
  4784. t.processSort();
  4785. parent.$obj.cubeportfolio('filter', parent.defaultFilter);
  4786. });
  4787. // reset filters active class after the search is used
  4788. parent.registerEvent('triggerSort', function() {
  4789. if (t.target) {
  4790. t.processSort();
  4791. parent.$obj.cubeportfolio('filter', parent.defaultFilter);
  4792. }
  4793. });
  4794. t.dropdownWrap = t.element.find('.cbp-l-dropdown-wrap')
  4795. .on({
  4796. 'mouseover.cbp': function() {
  4797. $(this).addClass('cbp-l-dropdown-wrap--open');
  4798. },
  4799. 'mouseleave.cbp': function() {
  4800. $(this).removeClass('cbp-l-dropdown-wrap--open');
  4801. }
  4802. });
  4803. t.dropdownHeader = t.element.find('.cbp-l-dropdown-header');
  4804. }
  4805. Plugin.prototype.processSort = function() {
  4806. var t = this;
  4807. var parent = t.parent;
  4808. var target = t.target;
  4809. var hasSort = target.hasAttribute('data-sort');
  4810. var hasSortBy = target.hasAttribute('data-sortBy');
  4811. if (hasSort && hasSortBy) {
  4812. t.sort = target.getAttribute('data-sort');
  4813. t.sortBy = target.getAttribute('data-sortBy');
  4814. } else if (hasSort) {
  4815. t.sort = target.getAttribute('data-sort');
  4816. } else if (hasSortBy) {
  4817. t.sortBy = target.getAttribute('data-sortBy');
  4818. } else {
  4819. return;
  4820. }
  4821. var sortByArr = t.sortBy.split(':');
  4822. var sortByType = 'string';
  4823. var sortByDirection = 1;
  4824. if (sortByArr[0] === 'int') {
  4825. sortByType = 'int';
  4826. } else if (sortByArr[0] === 'float') {
  4827. sortByType = 'float';
  4828. }
  4829. if (sortByArr[1] === 'desc') {
  4830. sortByDirection = -1;
  4831. }
  4832. if (t.sort) {
  4833. var obj = [];
  4834. parent.blocks.each(function(index, el) {
  4835. var block = $(el);
  4836. var sortText = block.find(t.sort).text();
  4837. if (sortByType === 'int') {
  4838. sortText = parseInt(sortText, 10);
  4839. }
  4840. if (sortByType === 'float') {
  4841. sortText = parseFloat(sortText, 10);
  4842. }
  4843. obj.push({
  4844. sortText: sortText,
  4845. data: block.data('cbp'),
  4846. });
  4847. });
  4848. obj.sort(function(obj1, obj2) {
  4849. var sortText1 = obj1.sortText;
  4850. var sortText2 = obj2.sortText;
  4851. if (sortByType === 'string') {
  4852. sortText1 = sortText1.toUpperCase(); // ignore upper and lowercase
  4853. sortText2 = sortText2.toUpperCase(); // ignore upper and lowercase
  4854. }
  4855. if (sortText1 < sortText2) {
  4856. return -sortByDirection;
  4857. } else if (sortText1 > sortText2) {
  4858. return sortByDirection;
  4859. }
  4860. // names must be equal
  4861. return 0;
  4862. });
  4863. $.each(obj, function(index, val) {
  4864. val.data.index = index;
  4865. });
  4866. } else {
  4867. var sortInvers = [];
  4868. if (sortByDirection === -1) {
  4869. parent.blocks.each(function(index, el) {
  4870. sortInvers.push($(el).data('cbp').indexInitial);
  4871. });
  4872. // put sortInvers in inverse order
  4873. sortInvers.sort(function(a, b) {
  4874. return b - a;
  4875. });
  4876. }
  4877. parent.blocks.each(function(index, el) {
  4878. var data = $(el).data('cbp');
  4879. if (sortByDirection === -1) {
  4880. data.index = sortInvers[data.indexInitial];
  4881. } else {
  4882. data.index = data.indexInitial;
  4883. }
  4884. });
  4885. }
  4886. parent.sortBlocks(parent.blocks, 'index');
  4887. t.dropdownWrap.trigger('mouseleave.cbp');
  4888. var target = $(t.target);
  4889. var targetParent = $(t.target).parent();
  4890. if (targetParent.hasClass('cbp-l-dropdown-list')) {
  4891. t.dropdownHeader.html(target.html());
  4892. target.addClass('cbp-l-dropdown-item--active').siblings('.cbp-l-dropdown-item').removeClass('cbp-l-dropdown-item--active');
  4893. } else if (targetParent.hasClass('cbp-l-direction')) {
  4894. var index = target.index();
  4895. if (index === 0) {
  4896. targetParent.addClass('cbp-l-direction--second').removeClass('cbp-l-direction--first');
  4897. } else {
  4898. targetParent.addClass('cbp-l-direction--first').removeClass('cbp-l-direction--second');
  4899. }
  4900. }
  4901. };
  4902. Plugin.prototype.destroy = function() {
  4903. this.element.off('click.cbp');
  4904. };
  4905. CubePortfolio.plugins.sort = function(parent) {
  4906. return new Plugin(parent);
  4907. };
  4908. })(jQuery, window, document);